Skip to content

fix(agent): describe the Direct JSON part as an array of A2UI messages - #3721

Open
karolkulesza wants to merge 10 commits into
a2ui-project:mainfrom
karolkulesza:fix/direct-json-array-rule
Open

karolkulesza wants to merge 10 commits into
a2ui-project:mainfrom
karolkulesza:fix/direct-json-array-rule

Conversation

@karolkulesza

@karolkulesza karolkulesza commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Description

This is fix 1 from @polina-c's list in #3576. The Direct JSON prompt rule said:

The JSON part MUST be a single, raw JSON object (usually a list of A2UI messages) and MUST validate against the provided A2UI JSON SCHEMA.

A single object is not what the prompt's examples show, and in the video in #3576 the model's visible thinking spends time on that contradiction. The Python, TypeScript and Dart parsers accept either shape: they wrap a block that holds one message object in a list. Asking for an array is still the right instruction, because it's what the examples show and the only shape that holds several messages. The rule now reads:

The JSON part MUST be a JSON array of A2UI messages, each following the provided A2UI JSON SCHEMA.

The provided schema describes one message, so the rule says that each message follows it rather than the array.

This also softens "MUST validate" to "follow", as suggested in #3576, since the SDK parses and recovers the output itself.

Changed, with the same sentence everywhere:

  • python/a2ui_agent/src/a2ui/constants.py
  • typescript/agents/a2ui_agent/src/parser/constants.ts
  • dart/a2ui_agent/lib/src/inference_formats/direct_json/prompt_generator.dart
  • kotlin/agent_sdk_legacy/.../A2uiConstants.kt
  • the 9 expected prompts in conformance/test_data/prompts/direct_json/
  • CHANGELOG entries for the Python, TypeScript and Dart agent SDKs (Kotlin legacy has no CHANGELOG)

#3567 edits the same fixtures and constants but not this line. Whichever merges second may need a one-line rebase in each fixture, and #3567 adds cross_ref_catalogs_pruned.txt, which would need the new sentence too. I'm happy to rebase this onto #3567 if you prefer.

Part of #3576 (fixes 2 and 3 there are app-side experiments, not covered here).

Pre-launch Checklist

One time:

For this PR:

  • I have updated the relevant CHANGELOG.md file.
  • I updated/added relevant documentation. (No docs quote this rule.)
  • My code changes (if any) have tests. (The shared prompt fixtures are compared byte for byte by each SDK.)
  • If my branch is on a fork, I have verified that scripts/e2e_test.sh passes. (I ran each SDK's tests instead.)

Tests:

  • Python a2ui_agent: pytest, all prompt tests pass. The only failures are 6 in tests/express/test_cli_tools.py, which need the optional google-genai package.
  • TypeScript a2ui_agent: yarn test, 1164 passed, 68 skipped.
  • Dart a2ui_agent: dart test, all 1458 passed.
  • Kotlin legacy: string change only, not run locally.

The Direct JSON rule said the JSON part MUST be "a single, raw JSON
object (usually a list of A2UI messages)" and MUST validate against the
schema, while every parser requires a list. Say "a JSON array of A2UI
messages" that follows the schema instead, in the Python, TypeScript,
Dart and Kotlin legacy SDKs and the shared prompt fixtures.

Part of a2ui-project#3576

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

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.

Code Review

This pull request updates the Direct JSON prompt rules across Dart, Kotlin, Python, TypeScript, and conformance test data to clarify that the expected JSON output is a JSON array of A2UI messages rather than a single raw JSON object. The feedback suggests adding an issue reference to the Dart changelog entry to maintain consistency with the Python and TypeScript changelogs.

Comment thread dart/a2ui_agent/CHANGELOG.md Resolved
@github-actions github-actions Bot added the status: needs-triage auto-managed: https://github.com/a2ui-project/a2ui/blob/main/scripts/triage.mjs label Oct 28, 2026

@polina-c polina-c left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks, this removes a contradiction the model shouldn't have to resolve, and the sentence is the same in every SDK and fixture.

One correction to the description, since it becomes the commit message: the parsers don't require a list. All three compile a block that holds a single message object by wrapping it in a list: Python's compile, TypeScript's compile and Dart's parser.dart. Dart's "must be a list of message objects" comes from MessageReader.read, which checks each item after that wrapping, so it fires for an item that isn't an object. Asking for an array is still the right instruction: it's what the examples show, and it's the one shape that holds several messages.

🤖 Agent-generated

Comment thread python/a2ui_agent/src/a2ui/constants.py Resolved
@github-actions github-actions Bot removed the status: needs-triage auto-managed: https://github.com/a2ui-project/a2ui/blob/main/scripts/triage.mjs label Oct 29, 2026
@github-actions github-actions Bot added the status: needs-triage auto-managed: https://github.com/a2ui-project/a2ui/blob/main/scripts/triage.mjs label Oct 29, 2026
@Varun-S10 Varun-S10 self-assigned this Oct 30, 2026
@Varun-S10

Copy link
Copy Markdown
Collaborator

Hi @karolkulesza, Thanks for updating the wording across all four SDKs, the conformance fixtures, and the changelogs to address the review feedback! I verified the changes locally against the Python, TypeScript, and Dart conformance suites, and everything passes cleanly. I will escalate this to team to review. Thank you for your patience and understanding.
Hi @gspencergoog, could you please take a look?

@Varun-S10 Varun-S10 added status: needs review and removed status: needs-triage auto-managed: https://github.com/a2ui-project/a2ui/blob/main/scripts/triage.mjs labels Oct 30, 2026

This branch has not been deployed

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants