Skip to content

Created a new agent to showcase the list of components in the std catalog. Also fixed a few component bugs#596

Open
dmandar wants to merge 7 commits intomainfrom
md-componentslistagent
Open

Created a new agent to showcase the list of components in the std catalog. Also fixed a few component bugs#596
dmandar wants to merge 7 commits intomainfrom
md-componentslistagent

Conversation

@dmandar
Copy link
Collaborator

@dmandar dmandar commented Feb 4, 2026

Description

Replace this paragraph with a description of what this PR is changing or adding, and why. Consider including before/after screenshots.

List which issues are fixed by this PR. For larger changes, raising an issue first helps reduce redundant work.

Pre-launch Checklist

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

@github-project-automation github-project-automation bot moved this to Todo in A2UI Feb 4, 2026
@dmandar dmandar changed the title Created a new agent to showcase the list of components in the std catalog. Created a new agent to showcase the list of components in the std catalog. Aso fixed a few component bugs Feb 4, 2026
@dmandar dmandar changed the title Created a new agent to showcase the list of components in the std catalog. Aso fixed a few component bugs Created a new agent to showcase the list of components in the std catalog. Also fixed a few component bugs Feb 4, 2026
@dmandar
Copy link
Collaborator Author

dmandar commented Feb 4, 2026

Screenshot 2026-02-03 at 10 24 53 PM

Copy link
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 component gallery sample, which is a valuable addition for demonstrating A2UI capabilities. The changes include a new agent, a Lit-based client, and improvements to existing UI components, notably a much-improved MultipleChoice component. While this is a great feature, there are several areas for improvement. The new code appears to have been partially copied from another sample, resulting in confusing naming and some irrelevant files that should be cleaned up. The new agent code also has some Python style guide violations. Finally, this large addition of functionality lacks corresponding tests for the agent logic, which is something to address per the repository's contribution guidelines.

];

#setBoundValue(value: string[]) {
console.log(value);
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

This console.log statement seems to be for debugging purposes and should be removed before merging.

from starlette.middleware.cors import CORSMiddleware
from dotenv import load_dotenv

from agent import ComponentGalleryAgent
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The import ComponentGalleryAgent is not directly used in this file and can be removed to keep the imports clean.

Comment on lines +8 to +12
from google.adk.agents.llm_agent import LlmAgent
from google.adk.artifacts import InMemoryArtifactService
from google.adk.memory.in_memory_memory_service import InMemoryMemoryService
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

These imports appear to be unused and should be removed to improve code clarity.

Additionally, datetime and asyncio are imported inside the stream method on lines 42-43. According to PEP 8 style guidelines, all imports should be at the top of the file for better readability and consistency.

Comment on lines +58 to +72
if "---a2ui_JSON---" in content:
text_content, json_string = content.split("---a2ui_JSON---", 1)
if text_content.strip():
final_parts.append(Part(root=TextPart(text=text_content.strip())))

if json_string.strip():
try:
json_data = json.loads(json_string.strip())
if isinstance(json_data, list):
for msg in json_data:
final_parts.append(create_a2ui_part(msg))
else:
final_parts.append(create_a2ui_part(json_data))
except Exception as e:
logger.error(f"Failed to parse JSON: {e}")
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Using a custom string separator (---a2ui_JSON---) to embed JSON within a text response is fragile and not ideal. The A2A protocol is designed to handle mixed content by using multiple Part objects in a single message.

A more robust approach would be for the agent to yield a list of Part objects (e.g., a TextPart for text and one or more DataParts for the A2UI JSON). The executor could then process these parts directly without needing to perform string splitting and parsing, making the communication cleaner and less error-prone.

Comment on lines +80 to +119
if (isJson(originalBody)) {
console.log(
"[a2a-middleware] Received JSON UI event:",
originalBody
);

const clientEvent = JSON.parse(originalBody);
sendParams = {
message: {
messageId: uuidv4(),
role: "user",
parts: [
{
kind: "data",
data: clientEvent,
metadata: { 'mimeType': A2UI_MIME_TYPE },
} as Part,
],
kind: "message",
},
};
} else {
console.log(
"[a2a-middleware] Received text query:",
originalBody
);
sendParams = {
message: {
messageId: uuidv4(),
role: "user",
parts: [
{
kind: "text",
text: originalBody,
},
],
kind: "message",
},
};
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The current logic for determining if the request body is JSON is inefficient because it results in parsing the string twice: once in isJson() and again to get clientEvent.

A more idiomatic and efficient approach is to use a single try-catch block. Attempt to parse the body, and if it succeeds, treat it as a JSON UI event. If it fails, catch the exception and treat the body as a plain text query. This avoids the redundant parsing.

              try {
                const clientEvent = JSON.parse(originalBody);
                console.log(
                  "[a2a-middleware] Received JSON UI event:",
                  originalBody
                );
                sendParams = {
                  message: {
                    messageId: uuidv4(),
                    role: "user",
                    parts: [
                      {
                        kind: "data",
                        data: clientEvent,
                        metadata: { 'mimeType': A2UI_MIME_TYPE },
                      } as Part,
                    ],
                    kind: "message",
                  },
                };
              } catch (e) {
                console.log(
                  "[a2a-middleware] Received text query:",
                  originalBody
                );
                sendParams = {
                  message: {
                    messageId: uuidv4(),
                    role: "user",
                    parts: [
                      {
                        kind: "text",
                        text: originalBody,
                      },
                    ],
                    kind: "message",
                  },
                };
              }

@dmandar
Copy link
Collaborator Author

dmandar commented Feb 4, 2026

Will be overhauling docs for this and other changes in a followup PR

dmandar and others added 3 commits February 3, 2026 22:59
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Copy link
Collaborator

@jacobsimionato jacobsimionato left a comment

Choose a reason for hiding this comment

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

I'm wondering if we can tweak the structure of this to try to aim for consistency and reduce the overall side of the code we are maintaining.

There are already a couple of examples of galleries:

I do think it'd be nice to have a gallery for each renderer, so we can compare how they render. I believe the other two galleries use the React and Angular renderers, so there is value in creating a Lit sample. How about trying to follow the structure of the other apps, to aim for consistency? This might involve:

  • Building this as a client-only app rather than an agent + client. I'm not sure if the agent adds much value if it just outputs canned content.

  • Reusing the same sample content as the other gallery apps. I think AG-UI folk provided nice sample content. Maybe we can reuse that in the other galleries? Then it's easy to compare between them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

2 participants