Skip to content

feat: add raw HTML component support and unify sandbox iframe impleme…#985

Merged
sugoi-yuzuru merged 3 commits intomainfrom
raw_html
Mar 25, 2026
Merged

feat: add raw HTML component support and unify sandbox iframe impleme…#985
sugoi-yuzuru merged 3 commits intomainfrom
raw_html

Conversation

@sugoi-yuzuru
Copy link
Copy Markdown
Collaborator

@sugoi-yuzuru sugoi-yuzuru commented Mar 25, 2026

…ntation

Description

This PR introduces a responsive "Neon Pong" game and implements the pattern for serving self-contained HTML applications via the ADK agent. It leverages the McpApp component with literalString content for robust, server-less application delivery.

Key Changes:

  • Neon Pong implementation: Created a high-quality, responsive Pong game (pong_app.html) featuring an AI opponent, proportional scaling with ResizeObserver, and keyboard/mouse controls.
  • Agent integration:
    Added get_pong_app tool to mcp_app_proxy to serve HTML content.
    Updated agent.py to register the new tool and defined the "Open Pong" skill for the agent.
  • Frontend enhancements: Added an "Open Pong" suggestion chip to the MCP Calculator sample to improve feature discovery.
  • Architecture: Unified the sandbox iframe implementation support for raw HTML components.
  • Verification: https://screencast.googleplex.com/cast/NTU0NjM4MjU3OTQ2NjI0MHwzYWRiYjljNi0wOA

Pre-launch Checklist

If you need help, consider asking for advice on the discussion board.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new Pong game application, integrating it into the agent and client. The review highlights several issues: invalid HTML in pong_app.html due to duplicate closing tags, an inline style attribute that should be moved to CSS, a magic number in the CPU AI logic that needs to be a named constant, and the use of setInterval instead of requestAnimationFrame for the game loop. Additionally, a redundant import os statement was found in tools.py, and new tests are required for the get_pong_app tool as per the style guide.

</div>
</div>

<div style="position: relative; width: 100%; display: flex; justify-content: center; flex: 1; min-height: 0;">
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This div uses an inline style attribute. To improve maintainability and separate structure from presentation, it's better to move these styles to a dedicated CSS class in the <style> block.

You can then add the following class to your CSS:

.canvas-container {
  position: relative;
  width: 100%;
  display: flex;
  justify-content: center;
  flex: 1;
  min-height: 0;
}
        <div class="canvas-container">


// CPU AI
let targetY = ball.y - cpu.height / 2;
cpu.y += (targetY - cpu.y) * 0.1;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The value 0.1 used for the CPU AI's movement speed is a "magic number". Using hardcoded values like this makes the code harder to understand and maintain. Please define it as a named constant at the top of the <script> block (e.g., const CPU_AI_SPEED = 0.1;) and use the constant here.

            cpu.y += (targetY - cpu.y) * CPU_AI_SPEED;

Comment on lines +482 to +483
const framePerSecond = 50;
setInterval(game, 1000 / framePerSecond);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The game loop uses setInterval, which is not ideal for animations. requestAnimationFrame is more efficient, provides smoother rendering by syncing with the browser's repaint cycle, and pauses automatically when the tab is not visible, saving resources.

I'd suggest refactoring the game loop to use it.

        function gameLoop() {
            game();
            requestAnimationFrame(gameLoop);
        }
        requestAnimationFrame(gameLoop);

return f"Error connecting to MCP server: {e}"


async def get_pong_app(tool_context: ToolContext):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The repository style guide states that 'If there are code changes, code should have tests.' This pull request introduces a new get_pong_app tool and the corresponding Pong game, but no new tests have been added to verify this functionality. Please add tests for the new tool.

References
  1. The style guide requires that new code changes are accompanied by tests. (link)


async def get_pong_app(tool_context: ToolContext):
"""Fetches the Pong game app."""
import os
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This import os statement is redundant because os is already imported at the top of the file (line 14). It can be removed.

@sugoi-yuzuru sugoi-yuzuru merged commit 9f167d5 into main Mar 25, 2026
11 checks passed
@sugoi-yuzuru sugoi-yuzuru deleted the raw_html branch March 25, 2026 22:23
@github-project-automation github-project-automation bot moved this from Todo to Done in A2UI Mar 25, 2026
peterblazejewicz pushed a commit to peterblazejewicz/A2UI that referenced this pull request Apr 5, 2026
google#985)

* feat: add raw HTML component support and unify sandbox iframe implementation

* refactor: rename get_pong_app to get_pong_app_a2ui_json for clarity

* chore: add license header to pong_app.html and clean up agent code formatting
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants