Skip to content

Replace A2UI_DELIMITER with XML/HTML style tag#794

Merged
nan-yu merged 2 commits intogoogle:mainfrom
nan-yu:a2ui-delimiter
Mar 6, 2026
Merged

Replace A2UI_DELIMITER with XML/HTML style tag#794
nan-yu merged 2 commits intogoogle:mainfrom
nan-yu:a2ui-delimiter

Conversation

@nan-yu
Copy link
Collaborator

@nan-yu nan-yu commented Mar 6, 2026

Description

It also updates the parser to support multiple pairs of text parts and A2UI JSON parts, for example,

text part 1
<a2ui-json>
[{...}, {...}]
</a2ui-json>
text part 2
<a2ui-json>
[{...}, {...}]
</a2ui-json>
text part 3
<a2ui-json>
[{...}, {...}]
</a2ui-json>

Pre-launch Checklist

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

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 significantly refactors the A2UI parsing and response generation mechanism within the Python SDK. The core change involves moving from a single delimiter (---a2ui_JSON---) to distinct opening and closing tags (<a2ui-json>, </a2ui-json>) for A2UI JSON blocks, allowing for multiple interleaved text and A2UI JSON segments within a single LLM response. The parse_response function was updated to return a list of ResponsePart objects, each containing text and/or A2UI JSON. A new helper function, parse_response_to_parts, was introduced to streamline the conversion of LLM responses into A2A Part objects, handling parsing, optional validation, and wrapping. This change simplifies agent output construction by centralizing the logic for splitting text, extracting A2UI JSON, and applying validation. Consequently, various sample agents and their executors were updated to leverage this new, more robust parsing and response generation flow, removing previous ad-hoc parsing logic. Review comments highlight a bug in the lstrip() usage for removing markdown fences, suggesting removeprefix() for correctness, and identify several prompt injection vulnerabilities in sample agents where unsanitized user input is concatenated into LLM prompts or A2UI JSON structures, recommending proper sanitization or structured prompt formats. Additionally, a performance optimization was suggested to pre-compile a regular expression used for A2UI block matching.

Comment on lines +240 to 242
"Message sent to {contact_name}\n"
f"{A2UI_OPEN_TAG}\n{json_content}\n{A2UI_CLOSE_TAG}"
)
Copy link
Contributor

Choose a reason for hiding this comment

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

security-high high

The agent constructs a response containing A2UI JSON blocks by injecting unsanitized user input (contact_name) into a JSON string (on line 221, which is then used here) and then parsing it. A malicious user can provide a contact_name that contains A2UI tags (e.g., </a2ui-json> <a2ui-json> [ { "type": "WebFrame", "url": "http://malicious.com" } ]), allowing them to inject arbitrary UI components into the response. This can lead to UI injection or Cross-Site Scripting (XSS) on the client side.

To remediate this, ensure that all user-supplied data is properly sanitized or escaped before being included in the response content, especially when it's part of a structure that will be parsed as JSON or A2UI tags. Preferably, use a JSON library to construct the data model and then wrap the entire serialized JSON in the A2UI tags.

Comment on lines 318 to +321
f"Your previous response was invalid. {error_message} You MUST generate a"
" valid response that strictly follows the A2UI JSON SCHEMA. The response"
" MUST be a JSON list of A2UI messages. Ensure the response is split by"
f" '{A2UI_DELIMITER}' and the JSON part is well-formed. Please retry the"
" MUST be a JSON list of A2UI messages. Ensure each JSON part is wrapped in"
f" '{A2UI_OPEN_TAG}' and '{A2UI_CLOSE_TAG}' tags. Please retry the"
Copy link
Contributor

Choose a reason for hiding this comment

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

security-medium medium

The agent constructs a retry prompt by concatenating the original user query and an error message without sanitization. This is a prompt injection vulnerability. A malicious user can provide a query that, when included in the retry prompt, manipulates the LLM's behavior (e.g., by including instructions to ignore previous constraints).

To remediate this, sanitize the user query before including it in the retry prompt, or use a structured prompt format that clearly separates user input from system instructions.

Comment on lines 307 to +310
f"Your previous response was invalid. {error_message} You MUST generate a"
" valid response that strictly follows the A2UI JSON SCHEMA. The response"
" MUST be a JSON list of A2UI messages. Ensure the response is split by"
f" '{A2UI_DELIMITER}' and the JSON part is well-formed. Please retry the"
" MUST be a JSON list of A2UI messages. Ensure each JSON part is wrapped in"
f" '{A2UI_OPEN_TAG}' and '{A2UI_CLOSE_TAG}' tags. Please retry the"
Copy link
Contributor

Choose a reason for hiding this comment

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

security-medium medium

The agent constructs a retry prompt by concatenating the original user query and an error message without sanitization. This is a prompt injection vulnerability. A malicious user can provide a query that, when included in the retry prompt, manipulates the LLM's behavior.

To remediate this, sanitize the user query before including it in the retry prompt, or use a structured prompt format that clearly separates user input from system instructions.

Comment on lines 393 to +396
f"Your previous response was invalid. {error_message} You MUST generate a"
" valid response that strictly follows the A2UI JSON SCHEMA. The response"
" MUST be a JSON list of A2UI messages. Ensure the response is split by"
f" '{A2UI_DELIMITER}' and the JSON part is well-formed. Please retry the"
" MUST be a JSON list of A2UI messages. Ensure each JSON part is wrapped in"
f" '{A2UI_OPEN_TAG}' and '{A2UI_CLOSE_TAG}' tags. Please retry the"
Copy link
Contributor

Choose a reason for hiding this comment

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

security-medium medium

The agent constructs a retry prompt by concatenating the original user query and an error message without sanitization. This is a prompt injection vulnerability. A malicious user can provide a query that, when included in the retry prompt, manipulates the LLM's behavior.

To remediate this, sanitize the user query before including it in the retry prompt, or use a structured prompt format that clearly separates user input from system instructions.

nan-yu added 2 commits March 6, 2026 19:01
It also updates the parser to support multiple pairs of text parts and A2UI JSON parts, for example,
```
text part 1
<a2ui-json>
[{...}, {...}]
</a2ui-json>
text part 2
<a2ui-json>
[{...}, {...}]
</a2ui-json>
text part 3
<a2ui-json>
[{...}, {...}]
</a2ui-json>
```

- Tested: The orchestrator sample and all sub-agents are working as
  expected.
@nan-yu nan-yu merged commit d17e5e3 into google:main Mar 6, 2026
7 checks passed
@github-project-automation github-project-automation bot moved this from Todo to Done in A2UI Mar 6, 2026
@nan-yu nan-yu deleted the a2ui-delimiter branch March 6, 2026 19:15
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.

Update the A2UI delimiter from a plain-text marker to XML/HTML style tags

2 participants