Skip to content

feat: migrate to A2UI protocol v1.0#996

Open
sethgw wants to merge 4 commits into
flutter:mainfrom
layups-ai:a2ui-v1.0
Open

feat: migrate to A2UI protocol v1.0#996
sethgw wants to merge 4 commits into
flutter:mainfrom
layups-ai:a2ui-v1.0

Conversation

@sethgw

@sethgw sethgw commented Jul 8, 2026

Copy link
Copy Markdown

Summary

Tracking issue: a2ui-project/a2ui#1959. Also resolves a2ui-project/a2ui#1896 (explicit-null deletion in updateDataModel).

Migrates the repository's A2UI implementation from protocol v0.9/v0.9.1 to v1.0, following the v1.0 evolution guide and the specification/v1_0 schemas in google/A2UI.

Wire format (a2ui_core)

  • All envelopes now use (and require) version: "v1.0"; the version constant is exported as a2uiProtocolVersion.
  • createSurface: themesurfaceProperties, plus optional inline components and dataModel for single-message UI instantiation.
  • updateDataModel: explicit null deletion semantics — toJson() serializes "value": null instead of omitting it.
  • Wire-level returnType removed from FunctionCall payloads (and from the expression parser output); boundaries/return types live in catalog definitions and are checked at runtime.

New v1.0 RPC messages

  • Server → client: CallFunctionMessage (functionCallId, wantResponse, callFunction) and ActionResponseMessage (actionId, value XOR error).
  • Client → server: A2uiFunctionResponse; A2uiClientAction gains wantResponse/actionId (generated when a component action sets wantResponse: true, with actionResponse values written back to the data model at responsePath); A2uiClientError supports functionCallId XOR surfaceId.
  • The MessageProcessor executes remote calls with callableFrom boundary checks, rejecting clientOnly/unregistered functions with INVALID_FUNCTION_CALL, and exposes onFunctionResponse/onError channels (wired through SurfaceController to the outbound stream).

Catalogs

  • functions serialized as an object map keyed by function name (v1.0 FunctionDefinition shape: FunctionCall validation schema + static returnType/callableFrom).
  • $defs/surfaceProperties replaces theme (primaryColor removed); inline catalogs also emit $defs/anyComponent/$defs/anyFunction.
  • Optional instructions field (genui embeds systemPromptFragments there, replacing external rules text).
  • Catalog entity names validated against UAX Update GEMINI instructions for catalog items, add implementation descriptions. #31 identifier rules (isValidA2uiIdentifier).
  • ClientFunction.callableFrom added (defaults to clientOnly).

Components & evaluation

  • TextField.placeholder, Slider.steps, Video.posterUrl per the v1.0 basic catalog.
  • @index built-in system function (with optional offset) scoped to template instantiation loops, in both the a2ui_core binder and the genui List/Row/Column template builders; the @ prefix is reserved and errors outside Collection Scope.
  • basicCatalogId now points at https://a2ui.org/specification/v1_0/catalogs/basic/catalog.json.

Transport (genui_a2a)

  • A2A extension URI bumped to https://a2ui.org/a2a-extension/a2ui/v1.0; capabilities/data-model envelopes namespaced under v1.0.
  • Standardized application/a2ui+json MIME type constant.
  • Incoming callFunction/actionResponse data parts routed to the message stream; outgoing action events carry actionId/wantResponse.

Docs, samples, tooling

  • New migration guide: docs/usage/migration/migration_a2ui_v0.9_to_v1.0.md.
  • CHANGELOG entries for a2ui_core, genui, and genui_a2a.
  • All test fixtures, prompt-builder goldens, simple_chat integration samples, catalog_gallery samples (46), and composer constants updated to v1.0.

Not included (n/a to this codebase today)

  • svgPathpath rename: genui's Icon uses a Material icon-name enum and has no custom-SVG definition object.
  • Bridging genui ClientFunction execution into a2ui_core remote calls: all built-in genui functions are clientOnly, so remote calls to them are correctly rejected per spec; execution bridging can follow as a separate change.

Testing

  • ./tool/run_all_tests_and_fixes.sh (repo-wide analyze + format + tests) passes.
  • a2ui_core: 101 tests (was 69) — new coverage for callFunction/actionResponse round-trips, callableFrom rejection, explicit-null deletion, duplicate-surface errors, inline create, @index (offset, outside-scope error, nested inheritance), and UAX Update GEMINI instructions for catalog items, add implementation descriptions. #31 validation.
  • genui: 279 tests, genui_a2a: 234 tests, catalog_gallery: 55 tests.

🤖 Generated with Claude Code

sethgw and others added 4 commits July 8, 2026 00:34
- Bump protocol version to v1.0 in message envelopes and capabilities
- Rename createSurface 'theme' to 'surfaceProperties'; support inline
  'components' and 'dataModel' for single-message UI instantiation
- Add CallFunctionMessage/ActionResponseMessage (server-to-client) and
  A2uiFunctionResponse (client-to-server) with actionId correlation
- Add callableFrom execution boundaries with INVALID_FUNCTION_CALL
  rejection for remote calls to clientOnly/unregistered functions
- Serialize catalog functions as a map keyed by name with static
  returnType/callableFrom metadata; move surfaceProperties under $defs
- Remove wire-level returnType from FunctionCall payloads
- Serialize explicit null in updateDataModel for key deletion
- Add @index system function (with offset) scoped to template loops
- Enforce UAX flutter#31 identifier rules for catalog entity names
- Add optional catalog 'instructions' (replaces external rules text)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Emit v1.0 envelopes for actions, errors, and message schemas
- Rename theme to surfaceProperties in SurfaceDefinition and schemas
- Add createSurface inline components/dataModel to message schema
- Add callFunction/actionResponse message schemas for prompting
- Send functionResponse and processor errors from SurfaceController
- Serialize catalog functions as a v1.0 map with returnType/callableFrom;
  embed systemPromptFragments as catalog 'instructions'
- Add callableFrom to ClientFunction (default clientOnly)
- Add TextField.placeholder, Slider.steps, Video.posterUrl
- Support @index system function in template loops (list/row/column)
- Point basicCatalogId at the v1.0 basic catalog; refresh prompt goldens

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Bump A2A extension URI to a2ui/v1.0
- Define the standardized application/a2ui+json MIME type constant
- Send v1.0 client event envelopes with actionId/wantResponse
- Route incoming callFunction and actionResponse data parts

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Bump 46 catalog_gallery samples, simple_chat integration samples, and
  composer kProtocolVersion to v1.0 envelopes and the v1.0 basic catalog id
- Add migration guide docs/usage/migration/migration_a2ui_v0.9_to_v1.0.md
- Add CHANGELOG entries for a2ui_core, genui, and genui_a2a
- Update README and contributing docs version references

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@google-cla

google-cla Bot commented Jul 8, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

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.

UpdateDataModel doesn't distinguish between the value-omitted and value-null cases

1 participant