From bc7a162f57e41f202ac1cadfea82220c87df0a3e Mon Sep 17 00:00:00 2001 From: Karol Kulesza Date: Wed, 28 Oct 2026 21:42:13 +0100 Subject: [PATCH 1/3] fix(agent): describe the Direct JSON part as an array of A2UI messages 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 #3576 --- conformance/test_data/prompts/direct_json/allowed_messages.txt | 2 +- .../test_data/prompts/direct_json/multi_catalog_examples.txt | 2 +- .../test_data/prompts/direct_json/pruned_components.txt | 2 +- conformance/test_data/prompts/direct_json/pruned_functions.txt | 2 +- .../test_data/prompts/direct_json/simplified_catalog.txt | 2 +- conformance/test_data/prompts/direct_json/single_example.txt | 2 +- conformance/test_data/prompts/direct_json/two_catalogs.txt | 2 +- .../test_data/prompts/direct_json/two_catalogs_pruned.txt | 2 +- .../prompts/direct_json/two_catalogs_single_example.txt | 2 +- dart/a2ui_agent/CHANGELOG.md | 3 +++ .../src/inference_formats/direct_json/prompt_generator.dart | 2 +- .../src/main/kotlin/com/google/a2ui/schema/A2uiConstants.kt | 2 +- python/a2ui_agent/CHANGELOG.md | 1 + python/a2ui_agent/src/a2ui/constants.py | 2 +- typescript/agents/a2ui_agent/CHANGELOG.md | 1 + typescript/agents/a2ui_agent/src/parser/constants.ts | 2 +- 16 files changed, 18 insertions(+), 13 deletions(-) diff --git a/conformance/test_data/prompts/direct_json/allowed_messages.txt b/conformance/test_data/prompts/direct_json/allowed_messages.txt index 7d343febda..c6f9f34401 100644 --- a/conformance/test_data/prompts/direct_json/allowed_messages.txt +++ b/conformance/test_data/prompts/direct_json/allowed_messages.txt @@ -4,7 +4,7 @@ The generated response MUST follow these rules: - The response can contain one or more A2UI JSON blocks. - Each A2UI JSON block MUST be wrapped in literal `` and `` tags (always include both the opening and closing tags; do NOT wrap the tags in backticks or replace the opening tag with a markdown code fence such as ```json). - Between or around these blocks, you can provide conversational text. -- 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. +- The JSON part MUST be a JSON array of A2UI messages and follow the provided A2UI JSON SCHEMA. - Top-Down Component Ordering: Within the `components` list of a message: - The 'root' component MUST be the FIRST element. - Parent components MUST appear before their child components. diff --git a/conformance/test_data/prompts/direct_json/multi_catalog_examples.txt b/conformance/test_data/prompts/direct_json/multi_catalog_examples.txt index 09297808c3..9a0b385fae 100644 --- a/conformance/test_data/prompts/direct_json/multi_catalog_examples.txt +++ b/conformance/test_data/prompts/direct_json/multi_catalog_examples.txt @@ -4,7 +4,7 @@ The generated response MUST follow these rules: - The response can contain one or more A2UI JSON blocks. - Each A2UI JSON block MUST be wrapped in literal `` and `` tags (always include both the opening and closing tags; do NOT wrap the tags in backticks or replace the opening tag with a markdown code fence such as ```json). - Between or around these blocks, you can provide conversational text. -- 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. +- The JSON part MUST be a JSON array of A2UI messages and follow the provided A2UI JSON SCHEMA. - Top-Down Component Ordering: Within the `components` list of a message: - The 'root' component MUST be the FIRST element. - Parent components MUST appear before their child components. diff --git a/conformance/test_data/prompts/direct_json/pruned_components.txt b/conformance/test_data/prompts/direct_json/pruned_components.txt index 522a7e16f5..8ecb5bbe4f 100644 --- a/conformance/test_data/prompts/direct_json/pruned_components.txt +++ b/conformance/test_data/prompts/direct_json/pruned_components.txt @@ -4,7 +4,7 @@ The generated response MUST follow these rules: - The response can contain one or more A2UI JSON blocks. - Each A2UI JSON block MUST be wrapped in literal `` and `` tags (always include both the opening and closing tags; do NOT wrap the tags in backticks or replace the opening tag with a markdown code fence such as ```json). - Between or around these blocks, you can provide conversational text. -- 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. +- The JSON part MUST be a JSON array of A2UI messages and follow the provided A2UI JSON SCHEMA. - Top-Down Component Ordering: Within the `components` list of a message: - The 'root' component MUST be the FIRST element. - Parent components MUST appear before their child components. diff --git a/conformance/test_data/prompts/direct_json/pruned_functions.txt b/conformance/test_data/prompts/direct_json/pruned_functions.txt index e67c213b4e..0dd24a04ee 100644 --- a/conformance/test_data/prompts/direct_json/pruned_functions.txt +++ b/conformance/test_data/prompts/direct_json/pruned_functions.txt @@ -4,7 +4,7 @@ The generated response MUST follow these rules: - The response can contain one or more A2UI JSON blocks. - Each A2UI JSON block MUST be wrapped in literal `` and `` tags (always include both the opening and closing tags; do NOT wrap the tags in backticks or replace the opening tag with a markdown code fence such as ```json). - Between or around these blocks, you can provide conversational text. -- 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. +- The JSON part MUST be a JSON array of A2UI messages and follow the provided A2UI JSON SCHEMA. - Top-Down Component Ordering: Within the `components` list of a message: - The 'root' component MUST be the FIRST element. - Parent components MUST appear before their child components. diff --git a/conformance/test_data/prompts/direct_json/simplified_catalog.txt b/conformance/test_data/prompts/direct_json/simplified_catalog.txt index 1c1533e4ae..c8315943f6 100644 --- a/conformance/test_data/prompts/direct_json/simplified_catalog.txt +++ b/conformance/test_data/prompts/direct_json/simplified_catalog.txt @@ -4,7 +4,7 @@ The generated response MUST follow these rules: - The response can contain one or more A2UI JSON blocks. - Each A2UI JSON block MUST be wrapped in literal `` and `` tags (always include both the opening and closing tags; do NOT wrap the tags in backticks or replace the opening tag with a markdown code fence such as ```json). - Between or around these blocks, you can provide conversational text. -- 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. +- The JSON part MUST be a JSON array of A2UI messages and follow the provided A2UI JSON SCHEMA. - Top-Down Component Ordering: Within the `components` list of a message: - The 'root' component MUST be the FIRST element. - Parent components MUST appear before their child components. diff --git a/conformance/test_data/prompts/direct_json/single_example.txt b/conformance/test_data/prompts/direct_json/single_example.txt index 86d68e0f44..89e6635d9a 100644 --- a/conformance/test_data/prompts/direct_json/single_example.txt +++ b/conformance/test_data/prompts/direct_json/single_example.txt @@ -4,7 +4,7 @@ The generated response MUST follow these rules: - The response can contain one or more A2UI JSON blocks. - Each A2UI JSON block MUST be wrapped in literal `` and `` tags (always include both the opening and closing tags; do NOT wrap the tags in backticks or replace the opening tag with a markdown code fence such as ```json). - Between or around these blocks, you can provide conversational text. -- 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. +- The JSON part MUST be a JSON array of A2UI messages and follow the provided A2UI JSON SCHEMA. - Top-Down Component Ordering: Within the `components` list of a message: - The 'root' component MUST be the FIRST element. - Parent components MUST appear before their child components. diff --git a/conformance/test_data/prompts/direct_json/two_catalogs.txt b/conformance/test_data/prompts/direct_json/two_catalogs.txt index 2f84dcc43f..16c64de340 100644 --- a/conformance/test_data/prompts/direct_json/two_catalogs.txt +++ b/conformance/test_data/prompts/direct_json/two_catalogs.txt @@ -4,7 +4,7 @@ The generated response MUST follow these rules: - The response can contain one or more A2UI JSON blocks. - Each A2UI JSON block MUST be wrapped in literal `` and `` tags (always include both the opening and closing tags; do NOT wrap the tags in backticks or replace the opening tag with a markdown code fence such as ```json). - Between or around these blocks, you can provide conversational text. -- 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. +- The JSON part MUST be a JSON array of A2UI messages and follow the provided A2UI JSON SCHEMA. - Top-Down Component Ordering: Within the `components` list of a message: - The 'root' component MUST be the FIRST element. - Parent components MUST appear before their child components. diff --git a/conformance/test_data/prompts/direct_json/two_catalogs_pruned.txt b/conformance/test_data/prompts/direct_json/two_catalogs_pruned.txt index 48ab50abf8..35d88fbb63 100644 --- a/conformance/test_data/prompts/direct_json/two_catalogs_pruned.txt +++ b/conformance/test_data/prompts/direct_json/two_catalogs_pruned.txt @@ -4,7 +4,7 @@ The generated response MUST follow these rules: - The response can contain one or more A2UI JSON blocks. - Each A2UI JSON block MUST be wrapped in literal `` and `` tags (always include both the opening and closing tags; do NOT wrap the tags in backticks or replace the opening tag with a markdown code fence such as ```json). - Between or around these blocks, you can provide conversational text. -- 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. +- The JSON part MUST be a JSON array of A2UI messages and follow the provided A2UI JSON SCHEMA. - Top-Down Component Ordering: Within the `components` list of a message: - The 'root' component MUST be the FIRST element. - Parent components MUST appear before their child components. diff --git a/conformance/test_data/prompts/direct_json/two_catalogs_single_example.txt b/conformance/test_data/prompts/direct_json/two_catalogs_single_example.txt index 78467538d2..e52076c596 100644 --- a/conformance/test_data/prompts/direct_json/two_catalogs_single_example.txt +++ b/conformance/test_data/prompts/direct_json/two_catalogs_single_example.txt @@ -4,7 +4,7 @@ The generated response MUST follow these rules: - The response can contain one or more A2UI JSON blocks. - Each A2UI JSON block MUST be wrapped in literal `` and `` tags (always include both the opening and closing tags; do NOT wrap the tags in backticks or replace the opening tag with a markdown code fence such as ```json). - Between or around these blocks, you can provide conversational text. -- 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. +- The JSON part MUST be a JSON array of A2UI messages and follow the provided A2UI JSON SCHEMA. - Top-Down Component Ordering: Within the `components` list of a message: - The 'root' component MUST be the FIRST element. - Parent components MUST appear before their child components. diff --git a/dart/a2ui_agent/CHANGELOG.md b/dart/a2ui_agent/CHANGELOG.md index 4c7c14f7e7..fa052af157 100644 --- a/dart/a2ui_agent/CHANGELOG.md +++ b/dart/a2ui_agent/CHANGELOG.md @@ -284,6 +284,9 @@ as part of a string or comment. - An Express integer too large for `int` compiles to a double instead of throwing `FormatException`. +- The Direct JSON prompt rule says the JSON part is a JSON array of A2UI + messages that follows the schema, instead of "a single, raw JSON object + (usually a list of A2UI messages)" that "MUST validate" against it. ## 0.0.1-wip005 diff --git a/dart/a2ui_agent/lib/src/inference_formats/direct_json/prompt_generator.dart b/dart/a2ui_agent/lib/src/inference_formats/direct_json/prompt_generator.dart index a6ed6c01e0..2e8618fdd2 100644 --- a/dart/a2ui_agent/lib/src/inference_formats/direct_json/prompt_generator.dart +++ b/dart/a2ui_agent/lib/src/inference_formats/direct_json/prompt_generator.dart @@ -27,7 +27,7 @@ The generated response MUST follow these rules: - The response can contain one or more A2UI JSON blocks. - Each A2UI JSON block MUST be wrapped in literal `` and `` tags (always include both the opening and closing tags; do NOT wrap the tags in backticks or replace the opening tag with a markdown code fence such as ```json). - Between or around these blocks, you can provide conversational text. -- 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. +- The JSON part MUST be a JSON array of A2UI messages and follow the provided A2UI JSON SCHEMA. - Top-Down Component Ordering: Within the `components` list of a message: - The 'root' component MUST be the FIRST element. - Parent components MUST appear before their child components. diff --git a/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/schema/A2uiConstants.kt b/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/schema/A2uiConstants.kt index a3745aa80e..011e168523 100644 --- a/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/schema/A2uiConstants.kt +++ b/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/schema/A2uiConstants.kt @@ -61,6 +61,6 @@ object A2uiConstants { 1. The response can contain one or more A2UI JSON blocks. 2. Each A2UI JSON block MUST be wrapped in $A2UI_OPEN_TAG and $A2UI_CLOSE_TAG tags. 3. Between or around these blocks, you can provide conversational text. - 4. 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. + 4. The JSON part MUST be a JSON array of A2UI messages and follow the provided A2UI JSON SCHEMA. """ } diff --git a/python/a2ui_agent/CHANGELOG.md b/python/a2ui_agent/CHANGELOG.md index 49c7245767..81b671985c 100644 --- a/python/a2ui_agent/CHANGELOG.md +++ b/python/a2ui_agent/CHANGELOG.md @@ -11,6 +11,7 @@ `generate_base_rules()` with `schema_to_prompt()` (such as `SendA2uiToClientToolset` users) should use `DEFAULT_WORKFLOW_RULES` instead. [#3559](https://github.com/a2ui-project/a2ui/pull/3559) +- The Direct JSON prompt rule says the JSON part is a JSON array of A2UI messages that follows the schema, instead of "a single, raw JSON object (usually a list of A2UI messages)" that "MUST validate" against it. [#3576](https://github.com/a2ui-project/a2ui/issues/3576) - Introduce typesafe fluent builder package for A2UI Protocol v1.0 (`a2ui.builder.v1_0`), re-exporting v1.0 common types (`DataBinding`, `FunctionCall`, `AccessibilityAttributes`, `ActionEvent`, and `CheckRule`) from diff --git a/python/a2ui_agent/src/a2ui/constants.py b/python/a2ui_agent/src/a2ui/constants.py index c0affabe95..e7df76c753 100644 --- a/python/a2ui_agent/src/a2ui/constants.py +++ b/python/a2ui_agent/src/a2ui/constants.py @@ -75,7 +75,7 @@ - The response can contain one or more A2UI JSON blocks. - Each A2UI JSON block MUST be wrapped in literal `{A2UI_OPEN_TAG}` and `{A2UI_CLOSE_TAG}` tags (always include both the opening and closing tags; do NOT wrap the tags in backticks or replace the opening tag with a markdown code fence such as ```json). - Between or around these blocks, you can provide conversational text. -- 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. +- The JSON part MUST be a JSON array of A2UI messages and follow the provided A2UI JSON SCHEMA. - Top-Down Component Ordering: Within the `components` list of a message: - The 'root' component MUST be the FIRST element. - Parent components MUST appear before their child components. diff --git a/typescript/agents/a2ui_agent/CHANGELOG.md b/typescript/agents/a2ui_agent/CHANGELOG.md index 75714dc6f8..d8f0f809c2 100644 --- a/typescript/agents/a2ui_agent/CHANGELOG.md +++ b/typescript/agents/a2ui_agent/CHANGELOG.md @@ -4,6 +4,7 @@ - **BREAKING CHANGE**: When `ResponseStream.feed` or `close` throws, the error's `partialResults` holds the parts the call made ready before the failure, as for `parseResponse`, and they stay applied to the stream's `RendererState`. Before, a chunk that finished a block and then failed in the next one threw without those parts and rolled them back. Recommended migration: show `error.partialResults` before ending the stream. [#3597](https://github.com/a2ui-project/a2ui/issues/3597) - **BREAKING CHANGE**: `ResponseStream` has an `isInBlock` getter, so a custom implementation must add one, and takes a type parameter for the parts it returns (`ResponseStream` for a stream that reads past rejected blocks, `ResponseStream` by default). `DirectJsonResponseStream`'s constructor takes `(parser, {wrapped, state, afterRejectedBlock})` instead of `(parser, wrapped, state)`; `DirectJsonParser.openStream` builds it as before. [#3597](https://github.com/a2ui-project/a2ui/issues/3597) - **BREAKING CHANGE**: Remove cross-catalog `$ref` resolution across peer catalogs, which shipped in 0.0.1. `resolveCatalogs` returns the active catalogs as is instead of copies linked to each other and to the registered catalogs, and `DirectJsonFormat`, `DirectJsonPromptGenerator`, `DirectJsonParser`, payload validation and the Express schema helpers no longer link the catalogs they are given (`linkCatalogs`, `inlinePeerAndLocalRefs` and `Catalog.withPeerCatalogs` are removed from `@a2ui/web_core`). A catalog's `$ref`s resolve only against its own document and `common_types.json`, and loading a v1.0 catalog with a `$ref` to any other document, such as another catalog, throws `A2uiCatalogError` from `Catalog.fromJson`. Recommended migration: copy the referenced definitions into each catalog that uses them. [#3232](https://github.com/a2ui-project/a2ui/issues/3232), [#3575](https://github.com/a2ui-project/a2ui/pull/3575) +- The Direct JSON prompt rule says the JSON part is a JSON array of A2UI messages that follows the schema, instead of "a single, raw JSON object (usually a list of A2UI messages)" that "MUST validate" against it. [#3576](https://github.com/a2ui-project/a2ui/issues/3576) - `openStream` takes `afterRejectedBlock: 'continue'` (`StreamOptions`, `ContinuingStreamOptions`) to read past a rejected block. The stream then returns an `ErrorPart` (`{type: 'error', error}`) in its place, skips the rest of the block, and reads the text and blocks after it; the messages the block emitted before it was rejected stay in the state. A block still open when the response ends is returned as an `ErrorPart` too. `feed` and `close` of such a stream return `StreamPart`s (`ResponsePart | ErrorPart`); by default the first rejected block still ends the stream. [#3597](https://github.com/a2ui-project/a2ui/issues/3597) - Add `ResponseStream.isInBlock`, which tells whether the response read so far ends inside a block, so a client that joins the chunks of a paused and resumed response can tell whether a space between them could break a block. [#3597](https://github.com/a2ui-project/a2ui/issues/3597) - Add `RendererState.of(processor)`, a renderer state that checks messages by its own rules and applies them to the `MessageProcessor` an app renders from, for an app that is both agent and renderer. A rollback takes a message back out of the processor's model. Every `RendererState` now hands a `callRendererFunction` to its processor only once the outermost `apply` or transaction it was applied in succeeds. [#3597](https://github.com/a2ui-project/a2ui/issues/3597) diff --git a/typescript/agents/a2ui_agent/src/parser/constants.ts b/typescript/agents/a2ui_agent/src/parser/constants.ts index f98ce424ee..87cafc2e5e 100644 --- a/typescript/agents/a2ui_agent/src/parser/constants.ts +++ b/typescript/agents/a2ui_agent/src/parser/constants.ts @@ -42,7 +42,7 @@ The generated response MUST follow these rules: - The response can contain one or more A2UI JSON blocks. - Each A2UI JSON block MUST be wrapped in literal \`${A2UI_OPEN_TAG}\` and \`${A2UI_CLOSE_TAG}\` tags (always include both the opening and closing tags; do NOT wrap the tags in backticks or replace the opening tag with a markdown code fence such as \`\`\`json). - Between or around these blocks, you can provide conversational text. -- 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. +- The JSON part MUST be a JSON array of A2UI messages and follow the provided A2UI JSON SCHEMA. - Top-Down Component Ordering: Within the \`components\` list of a message: - The 'root' component MUST be the FIRST element. - Parent components MUST appear before their child components. From f4a2e76cab8c3716bcaadd71636433c9cfee0953 Mon Sep 17 00:00:00 2001 From: Karol Kulesza Date: Wed, 28 Oct 2026 21:49:30 +0100 Subject: [PATCH 2/3] docs(agent): link the changelog entries to #3721 --- dart/a2ui_agent/CHANGELOG.md | 3 ++- python/a2ui_agent/CHANGELOG.md | 2 +- typescript/agents/a2ui_agent/CHANGELOG.md | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/dart/a2ui_agent/CHANGELOG.md b/dart/a2ui_agent/CHANGELOG.md index fa052af157..395d2a7a21 100644 --- a/dart/a2ui_agent/CHANGELOG.md +++ b/dart/a2ui_agent/CHANGELOG.md @@ -286,7 +286,8 @@ throwing `FormatException`. - The Direct JSON prompt rule says the JSON part is a JSON array of A2UI messages that follows the schema, instead of "a single, raw JSON object - (usually a list of A2UI messages)" that "MUST validate" against it. + (usually a list of A2UI messages)" that "MUST validate" against it + ([#3721](https://github.com/a2ui-project/a2ui/pull/3721)). ## 0.0.1-wip005 diff --git a/python/a2ui_agent/CHANGELOG.md b/python/a2ui_agent/CHANGELOG.md index 81b671985c..c3f50fef16 100644 --- a/python/a2ui_agent/CHANGELOG.md +++ b/python/a2ui_agent/CHANGELOG.md @@ -11,7 +11,7 @@ `generate_base_rules()` with `schema_to_prompt()` (such as `SendA2uiToClientToolset` users) should use `DEFAULT_WORKFLOW_RULES` instead. [#3559](https://github.com/a2ui-project/a2ui/pull/3559) -- The Direct JSON prompt rule says the JSON part is a JSON array of A2UI messages that follows the schema, instead of "a single, raw JSON object (usually a list of A2UI messages)" that "MUST validate" against it. [#3576](https://github.com/a2ui-project/a2ui/issues/3576) +- The Direct JSON prompt rule says the JSON part is a JSON array of A2UI messages that follows the schema, instead of "a single, raw JSON object (usually a list of A2UI messages)" that "MUST validate" against it. [#3721](https://github.com/a2ui-project/a2ui/pull/3721) - Introduce typesafe fluent builder package for A2UI Protocol v1.0 (`a2ui.builder.v1_0`), re-exporting v1.0 common types (`DataBinding`, `FunctionCall`, `AccessibilityAttributes`, `ActionEvent`, and `CheckRule`) from diff --git a/typescript/agents/a2ui_agent/CHANGELOG.md b/typescript/agents/a2ui_agent/CHANGELOG.md index d8f0f809c2..1dac19c65b 100644 --- a/typescript/agents/a2ui_agent/CHANGELOG.md +++ b/typescript/agents/a2ui_agent/CHANGELOG.md @@ -4,7 +4,7 @@ - **BREAKING CHANGE**: When `ResponseStream.feed` or `close` throws, the error's `partialResults` holds the parts the call made ready before the failure, as for `parseResponse`, and they stay applied to the stream's `RendererState`. Before, a chunk that finished a block and then failed in the next one threw without those parts and rolled them back. Recommended migration: show `error.partialResults` before ending the stream. [#3597](https://github.com/a2ui-project/a2ui/issues/3597) - **BREAKING CHANGE**: `ResponseStream` has an `isInBlock` getter, so a custom implementation must add one, and takes a type parameter for the parts it returns (`ResponseStream` for a stream that reads past rejected blocks, `ResponseStream` by default). `DirectJsonResponseStream`'s constructor takes `(parser, {wrapped, state, afterRejectedBlock})` instead of `(parser, wrapped, state)`; `DirectJsonParser.openStream` builds it as before. [#3597](https://github.com/a2ui-project/a2ui/issues/3597) - **BREAKING CHANGE**: Remove cross-catalog `$ref` resolution across peer catalogs, which shipped in 0.0.1. `resolveCatalogs` returns the active catalogs as is instead of copies linked to each other and to the registered catalogs, and `DirectJsonFormat`, `DirectJsonPromptGenerator`, `DirectJsonParser`, payload validation and the Express schema helpers no longer link the catalogs they are given (`linkCatalogs`, `inlinePeerAndLocalRefs` and `Catalog.withPeerCatalogs` are removed from `@a2ui/web_core`). A catalog's `$ref`s resolve only against its own document and `common_types.json`, and loading a v1.0 catalog with a `$ref` to any other document, such as another catalog, throws `A2uiCatalogError` from `Catalog.fromJson`. Recommended migration: copy the referenced definitions into each catalog that uses them. [#3232](https://github.com/a2ui-project/a2ui/issues/3232), [#3575](https://github.com/a2ui-project/a2ui/pull/3575) -- The Direct JSON prompt rule says the JSON part is a JSON array of A2UI messages that follows the schema, instead of "a single, raw JSON object (usually a list of A2UI messages)" that "MUST validate" against it. [#3576](https://github.com/a2ui-project/a2ui/issues/3576) +- The Direct JSON prompt rule says the JSON part is a JSON array of A2UI messages that follows the schema, instead of "a single, raw JSON object (usually a list of A2UI messages)" that "MUST validate" against it. [#3721](https://github.com/a2ui-project/a2ui/pull/3721) - `openStream` takes `afterRejectedBlock: 'continue'` (`StreamOptions`, `ContinuingStreamOptions`) to read past a rejected block. The stream then returns an `ErrorPart` (`{type: 'error', error}`) in its place, skips the rest of the block, and reads the text and blocks after it; the messages the block emitted before it was rejected stay in the state. A block still open when the response ends is returned as an `ErrorPart` too. `feed` and `close` of such a stream return `StreamPart`s (`ResponsePart | ErrorPart`); by default the first rejected block still ends the stream. [#3597](https://github.com/a2ui-project/a2ui/issues/3597) - Add `ResponseStream.isInBlock`, which tells whether the response read so far ends inside a block, so a client that joins the chunks of a paused and resumed response can tell whether a space between them could break a block. [#3597](https://github.com/a2ui-project/a2ui/issues/3597) - Add `RendererState.of(processor)`, a renderer state that checks messages by its own rules and applies them to the `MessageProcessor` an app renders from, for an app that is both agent and renderer. A rollback takes a message back out of the processor's model. Every `RendererState` now hands a `callRendererFunction` to its processor only once the outermost `apply` or transaction it was applied in succeeds. [#3597](https://github.com/a2ui-project/a2ui/issues/3597) From c800d96aa21210cde106f1beb7bba62fb7d90c50 Mon Sep 17 00:00:00 2001 From: Karol Kulesza Date: Thu, 29 Oct 2026 20:34:57 +0100 Subject: [PATCH 3/3] fix(agent): say each message in the Direct JSON array follows the schema --- conformance/test_data/prompts/direct_json/allowed_messages.txt | 2 +- .../test_data/prompts/direct_json/multi_catalog_examples.txt | 2 +- conformance/test_data/prompts/direct_json/pruned_components.txt | 2 +- conformance/test_data/prompts/direct_json/pruned_functions.txt | 2 +- .../test_data/prompts/direct_json/simplified_catalog.txt | 2 +- conformance/test_data/prompts/direct_json/single_example.txt | 2 +- conformance/test_data/prompts/direct_json/two_catalogs.txt | 2 +- .../test_data/prompts/direct_json/two_catalogs_pruned.txt | 2 +- .../prompts/direct_json/two_catalogs_single_example.txt | 2 +- dart/a2ui_agent/CHANGELOG.md | 2 +- .../lib/src/inference_formats/direct_json/prompt_generator.dart | 2 +- .../src/main/kotlin/com/google/a2ui/schema/A2uiConstants.kt | 2 +- python/a2ui_agent/CHANGELOG.md | 2 +- python/a2ui_agent/src/a2ui/constants.py | 2 +- typescript/agents/a2ui_agent/CHANGELOG.md | 2 +- typescript/agents/a2ui_agent/src/parser/constants.ts | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/conformance/test_data/prompts/direct_json/allowed_messages.txt b/conformance/test_data/prompts/direct_json/allowed_messages.txt index 1c446f0feb..2d561ab6f9 100644 --- a/conformance/test_data/prompts/direct_json/allowed_messages.txt +++ b/conformance/test_data/prompts/direct_json/allowed_messages.txt @@ -4,7 +4,7 @@ The generated response MUST follow these rules: - The response can contain one or more A2UI JSON blocks. - Each A2UI JSON block MUST be wrapped in literal `` and `` tags (always include both the opening and closing tags; do NOT wrap the tags in backticks or replace the opening tag with a markdown code fence such as ```json). - Between or around these blocks, you can provide conversational text. -- The JSON part MUST be a JSON array of A2UI messages and follow the provided A2UI JSON SCHEMA. +- The JSON part MUST be a JSON array of A2UI messages, each following the provided A2UI JSON SCHEMA. - Top-Down Component Ordering: Within the `components` list of a message: - The 'root' component MUST be the FIRST element. - Parent components MUST appear before their child components. diff --git a/conformance/test_data/prompts/direct_json/multi_catalog_examples.txt b/conformance/test_data/prompts/direct_json/multi_catalog_examples.txt index 1299923e7e..dfde2b8d57 100644 --- a/conformance/test_data/prompts/direct_json/multi_catalog_examples.txt +++ b/conformance/test_data/prompts/direct_json/multi_catalog_examples.txt @@ -4,7 +4,7 @@ The generated response MUST follow these rules: - The response can contain one or more A2UI JSON blocks. - Each A2UI JSON block MUST be wrapped in literal `` and `` tags (always include both the opening and closing tags; do NOT wrap the tags in backticks or replace the opening tag with a markdown code fence such as ```json). - Between or around these blocks, you can provide conversational text. -- The JSON part MUST be a JSON array of A2UI messages and follow the provided A2UI JSON SCHEMA. +- The JSON part MUST be a JSON array of A2UI messages, each following the provided A2UI JSON SCHEMA. - Top-Down Component Ordering: Within the `components` list of a message: - The 'root' component MUST be the FIRST element. - Parent components MUST appear before their child components. diff --git a/conformance/test_data/prompts/direct_json/pruned_components.txt b/conformance/test_data/prompts/direct_json/pruned_components.txt index 1542e66bc3..e6d2525c42 100644 --- a/conformance/test_data/prompts/direct_json/pruned_components.txt +++ b/conformance/test_data/prompts/direct_json/pruned_components.txt @@ -4,7 +4,7 @@ The generated response MUST follow these rules: - The response can contain one or more A2UI JSON blocks. - Each A2UI JSON block MUST be wrapped in literal `` and `` tags (always include both the opening and closing tags; do NOT wrap the tags in backticks or replace the opening tag with a markdown code fence such as ```json). - Between or around these blocks, you can provide conversational text. -- The JSON part MUST be a JSON array of A2UI messages and follow the provided A2UI JSON SCHEMA. +- The JSON part MUST be a JSON array of A2UI messages, each following the provided A2UI JSON SCHEMA. - Top-Down Component Ordering: Within the `components` list of a message: - The 'root' component MUST be the FIRST element. - Parent components MUST appear before their child components. diff --git a/conformance/test_data/prompts/direct_json/pruned_functions.txt b/conformance/test_data/prompts/direct_json/pruned_functions.txt index 9bd9141ffe..8e96e161d6 100644 --- a/conformance/test_data/prompts/direct_json/pruned_functions.txt +++ b/conformance/test_data/prompts/direct_json/pruned_functions.txt @@ -4,7 +4,7 @@ The generated response MUST follow these rules: - The response can contain one or more A2UI JSON blocks. - Each A2UI JSON block MUST be wrapped in literal `` and `` tags (always include both the opening and closing tags; do NOT wrap the tags in backticks or replace the opening tag with a markdown code fence such as ```json). - Between or around these blocks, you can provide conversational text. -- The JSON part MUST be a JSON array of A2UI messages and follow the provided A2UI JSON SCHEMA. +- The JSON part MUST be a JSON array of A2UI messages, each following the provided A2UI JSON SCHEMA. - Top-Down Component Ordering: Within the `components` list of a message: - The 'root' component MUST be the FIRST element. - Parent components MUST appear before their child components. diff --git a/conformance/test_data/prompts/direct_json/simplified_catalog.txt b/conformance/test_data/prompts/direct_json/simplified_catalog.txt index dc6e9b44cc..a5286d34c1 100644 --- a/conformance/test_data/prompts/direct_json/simplified_catalog.txt +++ b/conformance/test_data/prompts/direct_json/simplified_catalog.txt @@ -4,7 +4,7 @@ The generated response MUST follow these rules: - The response can contain one or more A2UI JSON blocks. - Each A2UI JSON block MUST be wrapped in literal `` and `` tags (always include both the opening and closing tags; do NOT wrap the tags in backticks or replace the opening tag with a markdown code fence such as ```json). - Between or around these blocks, you can provide conversational text. -- The JSON part MUST be a JSON array of A2UI messages and follow the provided A2UI JSON SCHEMA. +- The JSON part MUST be a JSON array of A2UI messages, each following the provided A2UI JSON SCHEMA. - Top-Down Component Ordering: Within the `components` list of a message: - The 'root' component MUST be the FIRST element. - Parent components MUST appear before their child components. diff --git a/conformance/test_data/prompts/direct_json/single_example.txt b/conformance/test_data/prompts/direct_json/single_example.txt index 17a0cfa29c..7634c3588e 100644 --- a/conformance/test_data/prompts/direct_json/single_example.txt +++ b/conformance/test_data/prompts/direct_json/single_example.txt @@ -4,7 +4,7 @@ The generated response MUST follow these rules: - The response can contain one or more A2UI JSON blocks. - Each A2UI JSON block MUST be wrapped in literal `` and `` tags (always include both the opening and closing tags; do NOT wrap the tags in backticks or replace the opening tag with a markdown code fence such as ```json). - Between or around these blocks, you can provide conversational text. -- The JSON part MUST be a JSON array of A2UI messages and follow the provided A2UI JSON SCHEMA. +- The JSON part MUST be a JSON array of A2UI messages, each following the provided A2UI JSON SCHEMA. - Top-Down Component Ordering: Within the `components` list of a message: - The 'root' component MUST be the FIRST element. - Parent components MUST appear before their child components. diff --git a/conformance/test_data/prompts/direct_json/two_catalogs.txt b/conformance/test_data/prompts/direct_json/two_catalogs.txt index a268eaf9cc..ef58d537b9 100644 --- a/conformance/test_data/prompts/direct_json/two_catalogs.txt +++ b/conformance/test_data/prompts/direct_json/two_catalogs.txt @@ -4,7 +4,7 @@ The generated response MUST follow these rules: - The response can contain one or more A2UI JSON blocks. - Each A2UI JSON block MUST be wrapped in literal `` and `` tags (always include both the opening and closing tags; do NOT wrap the tags in backticks or replace the opening tag with a markdown code fence such as ```json). - Between or around these blocks, you can provide conversational text. -- The JSON part MUST be a JSON array of A2UI messages and follow the provided A2UI JSON SCHEMA. +- The JSON part MUST be a JSON array of A2UI messages, each following the provided A2UI JSON SCHEMA. - Top-Down Component Ordering: Within the `components` list of a message: - The 'root' component MUST be the FIRST element. - Parent components MUST appear before their child components. diff --git a/conformance/test_data/prompts/direct_json/two_catalogs_pruned.txt b/conformance/test_data/prompts/direct_json/two_catalogs_pruned.txt index 9231bcd580..d385846620 100644 --- a/conformance/test_data/prompts/direct_json/two_catalogs_pruned.txt +++ b/conformance/test_data/prompts/direct_json/two_catalogs_pruned.txt @@ -4,7 +4,7 @@ The generated response MUST follow these rules: - The response can contain one or more A2UI JSON blocks. - Each A2UI JSON block MUST be wrapped in literal `` and `` tags (always include both the opening and closing tags; do NOT wrap the tags in backticks or replace the opening tag with a markdown code fence such as ```json). - Between or around these blocks, you can provide conversational text. -- The JSON part MUST be a JSON array of A2UI messages and follow the provided A2UI JSON SCHEMA. +- The JSON part MUST be a JSON array of A2UI messages, each following the provided A2UI JSON SCHEMA. - Top-Down Component Ordering: Within the `components` list of a message: - The 'root' component MUST be the FIRST element. - Parent components MUST appear before their child components. diff --git a/conformance/test_data/prompts/direct_json/two_catalogs_single_example.txt b/conformance/test_data/prompts/direct_json/two_catalogs_single_example.txt index eeaa012c8a..9f98b7142f 100644 --- a/conformance/test_data/prompts/direct_json/two_catalogs_single_example.txt +++ b/conformance/test_data/prompts/direct_json/two_catalogs_single_example.txt @@ -4,7 +4,7 @@ The generated response MUST follow these rules: - The response can contain one or more A2UI JSON blocks. - Each A2UI JSON block MUST be wrapped in literal `` and `` tags (always include both the opening and closing tags; do NOT wrap the tags in backticks or replace the opening tag with a markdown code fence such as ```json). - Between or around these blocks, you can provide conversational text. -- The JSON part MUST be a JSON array of A2UI messages and follow the provided A2UI JSON SCHEMA. +- The JSON part MUST be a JSON array of A2UI messages, each following the provided A2UI JSON SCHEMA. - Top-Down Component Ordering: Within the `components` list of a message: - The 'root' component MUST be the FIRST element. - Parent components MUST appear before their child components. diff --git a/dart/a2ui_agent/CHANGELOG.md b/dart/a2ui_agent/CHANGELOG.md index 32b617e84d..12fc32054b 100644 --- a/dart/a2ui_agent/CHANGELOG.md +++ b/dart/a2ui_agent/CHANGELOG.md @@ -349,7 +349,7 @@ - An Express integer too large for `int` compiles to a double instead of throwing `FormatException`. - The Direct JSON prompt rule says the JSON part is a JSON array of A2UI - messages that follows the schema, instead of "a single, raw JSON object + messages, each following the schema, instead of "a single, raw JSON object (usually a list of A2UI messages)" that "MUST validate" against it ([#3721](https://github.com/a2ui-project/a2ui/pull/3721)). diff --git a/dart/a2ui_agent/lib/src/inference_formats/direct_json/prompt_generator.dart b/dart/a2ui_agent/lib/src/inference_formats/direct_json/prompt_generator.dart index 2e8618fdd2..26d5a31280 100644 --- a/dart/a2ui_agent/lib/src/inference_formats/direct_json/prompt_generator.dart +++ b/dart/a2ui_agent/lib/src/inference_formats/direct_json/prompt_generator.dart @@ -27,7 +27,7 @@ The generated response MUST follow these rules: - The response can contain one or more A2UI JSON blocks. - Each A2UI JSON block MUST be wrapped in literal `` and `` tags (always include both the opening and closing tags; do NOT wrap the tags in backticks or replace the opening tag with a markdown code fence such as ```json). - Between or around these blocks, you can provide conversational text. -- The JSON part MUST be a JSON array of A2UI messages and follow the provided A2UI JSON SCHEMA. +- The JSON part MUST be a JSON array of A2UI messages, each following the provided A2UI JSON SCHEMA. - Top-Down Component Ordering: Within the `components` list of a message: - The 'root' component MUST be the FIRST element. - Parent components MUST appear before their child components. diff --git a/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/schema/A2uiConstants.kt b/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/schema/A2uiConstants.kt index 011e168523..ca67c42314 100644 --- a/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/schema/A2uiConstants.kt +++ b/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/schema/A2uiConstants.kt @@ -61,6 +61,6 @@ object A2uiConstants { 1. The response can contain one or more A2UI JSON blocks. 2. Each A2UI JSON block MUST be wrapped in $A2UI_OPEN_TAG and $A2UI_CLOSE_TAG tags. 3. Between or around these blocks, you can provide conversational text. - 4. The JSON part MUST be a JSON array of A2UI messages and follow the provided A2UI JSON SCHEMA. + 4. The JSON part MUST be a JSON array of A2UI messages, each following the provided A2UI JSON SCHEMA. """ } diff --git a/python/a2ui_agent/CHANGELOG.md b/python/a2ui_agent/CHANGELOG.md index f122db6436..80c087c409 100644 --- a/python/a2ui_agent/CHANGELOG.md +++ b/python/a2ui_agent/CHANGELOG.md @@ -33,7 +33,7 @@ `generate_base_rules()` with `schema_to_prompt()` (such as `SendA2uiToClientToolset` users) should use `DEFAULT_WORKFLOW_RULES` instead. [#3559](https://github.com/a2ui-project/a2ui/pull/3559) -- The Direct JSON prompt rule says the JSON part is a JSON array of A2UI messages that follows the schema, instead of "a single, raw JSON object (usually a list of A2UI messages)" that "MUST validate" against it. [#3721](https://github.com/a2ui-project/a2ui/pull/3721) +- The Direct JSON prompt rule says the JSON part is a JSON array of A2UI messages, each following the schema, instead of "a single, raw JSON object (usually a list of A2UI messages)" that "MUST validate" against it. [#3721](https://github.com/a2ui-project/a2ui/pull/3721) - `open_stream` takes `after_rejected_block="continue"` to read past a rejected block. The stream then returns an `ErrorPart` in its place, skips the rest of the block, and reads the text and blocks after it; the messages diff --git a/python/a2ui_agent/src/a2ui/constants.py b/python/a2ui_agent/src/a2ui/constants.py index e7df76c753..02c1c2bb11 100644 --- a/python/a2ui_agent/src/a2ui/constants.py +++ b/python/a2ui_agent/src/a2ui/constants.py @@ -75,7 +75,7 @@ - The response can contain one or more A2UI JSON blocks. - Each A2UI JSON block MUST be wrapped in literal `{A2UI_OPEN_TAG}` and `{A2UI_CLOSE_TAG}` tags (always include both the opening and closing tags; do NOT wrap the tags in backticks or replace the opening tag with a markdown code fence such as ```json). - Between or around these blocks, you can provide conversational text. -- The JSON part MUST be a JSON array of A2UI messages and follow the provided A2UI JSON SCHEMA. +- The JSON part MUST be a JSON array of A2UI messages, each following the provided A2UI JSON SCHEMA. - Top-Down Component Ordering: Within the `components` list of a message: - The 'root' component MUST be the FIRST element. - Parent components MUST appear before their child components. diff --git a/typescript/agents/a2ui_agent/CHANGELOG.md b/typescript/agents/a2ui_agent/CHANGELOG.md index 269667626e..01f23e53e9 100644 --- a/typescript/agents/a2ui_agent/CHANGELOG.md +++ b/typescript/agents/a2ui_agent/CHANGELOG.md @@ -5,7 +5,7 @@ - **BREAKING CHANGE**: When `ResponseStream.feed` or `close` throws, the error's `partialResults` holds the parts the call made ready before the failure, as for `parseResponse`, and they stay applied to the stream's `RendererState`. Before, a chunk that finished a block and then failed in the next one threw without those parts and rolled them back. Recommended migration: show `error.partialResults` before ending the stream. [#3597](https://github.com/a2ui-project/a2ui/issues/3597) - **BREAKING CHANGE**: `ResponseStream` has an `isInBlock` getter, so a custom implementation must add one, and takes a type parameter for the parts it returns (`ResponseStream` for a stream that reads past rejected blocks, `ResponseStream` by default). `DirectJsonResponseStream`'s constructor takes `(parser, {wrapped, state, afterRejectedBlock})` instead of `(parser, wrapped, state)`; `DirectJsonParser.openStream` builds it as before. [#3597](https://github.com/a2ui-project/a2ui/issues/3597) - **BREAKING CHANGE**: Remove cross-catalog `$ref` resolution across peer catalogs, which shipped in 0.0.1. `resolveCatalogs` returns the active catalogs as is instead of copies linked to each other and to the registered catalogs, and `DirectJsonFormat`, `DirectJsonPromptGenerator`, `DirectJsonParser`, payload validation and the Express schema helpers no longer link the catalogs they are given (`linkCatalogs`, `inlinePeerAndLocalRefs` and `Catalog.withPeerCatalogs` are removed from `@a2ui/web_core`). A catalog's `$ref`s resolve only against its own document and `common_types.json`, and loading a v1.0 catalog with a `$ref` to any other document, such as another catalog, throws `A2uiCatalogError` from `Catalog.fromJson`. Recommended migration: copy the referenced definitions into each catalog that uses them. [#3232](https://github.com/a2ui-project/a2ui/issues/3232), [#3575](https://github.com/a2ui-project/a2ui/pull/3575) -- The Direct JSON prompt rule says the JSON part is a JSON array of A2UI messages that follows the schema, instead of "a single, raw JSON object (usually a list of A2UI messages)" that "MUST validate" against it. [#3721](https://github.com/a2ui-project/a2ui/pull/3721) +- The Direct JSON prompt rule says the JSON part is a JSON array of A2UI messages, each following the schema, instead of "a single, raw JSON object (usually a list of A2UI messages)" that "MUST validate" against it. [#3721](https://github.com/a2ui-project/a2ui/pull/3721) - `openStream` takes `afterRejectedBlock: 'continue'` (`StreamOptions`, `ContinuingStreamOptions`) to read past a rejected block. The stream then returns an `ErrorPart` (`{type: 'error', error}`) in its place, skips the rest of the block, and reads the text and blocks after it; the messages the block emitted before it was rejected stay in the state. A block still open when the response ends is returned as an `ErrorPart` too. `feed` and `close` of such a stream return `StreamPart`s (`ResponsePart | ErrorPart`); by default the first rejected block still ends the stream. [#3597](https://github.com/a2ui-project/a2ui/issues/3597) - Add `ResponseStream.isInBlock`, which tells whether the response read so far ends inside a block, so a client that joins the chunks of a paused and resumed response can tell whether a space between them could break a block. [#3597](https://github.com/a2ui-project/a2ui/issues/3597) - Add `RendererState.of(processor)`, a renderer state that checks messages by its own rules and applies them to the `MessageProcessor` an app renders from, for an app that is both agent and renderer. A rollback takes a message back out of the processor's model. Every `RendererState` now hands a `callRendererFunction` to its processor only once the outermost `apply` or transaction it was applied in succeeds. [#3597](https://github.com/a2ui-project/a2ui/issues/3597) diff --git a/typescript/agents/a2ui_agent/src/parser/constants.ts b/typescript/agents/a2ui_agent/src/parser/constants.ts index 87cafc2e5e..65379666c1 100644 --- a/typescript/agents/a2ui_agent/src/parser/constants.ts +++ b/typescript/agents/a2ui_agent/src/parser/constants.ts @@ -42,7 +42,7 @@ The generated response MUST follow these rules: - The response can contain one or more A2UI JSON blocks. - Each A2UI JSON block MUST be wrapped in literal \`${A2UI_OPEN_TAG}\` and \`${A2UI_CLOSE_TAG}\` tags (always include both the opening and closing tags; do NOT wrap the tags in backticks or replace the opening tag with a markdown code fence such as \`\`\`json). - Between or around these blocks, you can provide conversational text. -- The JSON part MUST be a JSON array of A2UI messages and follow the provided A2UI JSON SCHEMA. +- The JSON part MUST be a JSON array of A2UI messages, each following the provided A2UI JSON SCHEMA. - Top-Down Component Ordering: Within the \`components\` list of a message: - The 'root' component MUST be the FIRST element. - Parent components MUST appear before their child components.