Skip to content

Conversation

@gspencergoog
Copy link
Collaborator

Description

A prototype implementation of supporting A2UI v0.9 while shifting to a "Bring your own LLM" model for the API.

Refactor message keys and tool usage to match the A2UI v0.9 specification:
- Rename `SurfaceUpdate` related handling to `UpdateComponents`.
- Rename `BeginRendering` related handling to `CreateSurface`.
- Update `A2uiAgentConnector` to recognize `updateComponents`, `updateDataModel`, `createSurface`.
- Update AI content generators (`dartantic`, `firebase_ai`, `google_generative_ai`) to use `UpdateComponentsTool` and `CreateSurfaceTool`.
- Fix tests and example app to reflect these changes.
- Implement  for two-way binding.
- Implement  for schema validation.
- Add  schema.
- Add tests for new functionality.
Fix schema generation for empty catalogs, clean up formatting, and update custom_backend test data to match v0.9 Component schema.
- Update Catalog definition to include `functions` schema property.
- Add standard client function definitions (required, regex, etc.) to A2uiSchemas.
- Add unit tests for A2uiMessage serialization/deserialization.
- Ensure all schema helper methods in A2uiSchemas are static.

Detailed changes:
- `packages/genui/lib/src/model/catalog.dart`: Added `functions` to `Catalog.definition`.
- `packages/genui/lib/src/model/a2ui_schemas.dart`: Implemented schemas for `required`, `regex`, `length`, `numeric`, `email`, `formatString`, `formatNumber`, `formatCurrency`, `formatDate`. Corrected missing static modifiers.
- `packages/genui/test/model/a2ui_message_test.dart`: New test file.
- Update all core widgets to use flattened properties and V0.9 schema.
- Implement  to replace .
- Implement  and standard client-side functions.
- Update  to support  resolution.
- Add  for ${...} expression evaluation.
- Update  with function definitions.
- Fix examples and tests to align with v0.9 specification.
- Remove legacy  widget.
- Update `Action` schema to v0.9 (event/functionCall).
- Implement `checks` support in `TextField` for client-side validation.
- Add `closeModal` client-side function support in `Button` and `TextField`.
- Fix `formatString` and implementation of `openUrl` in `FunctionRegistry`.
- Resolve checks and updates tests to new schema.
- Improve public API documentation across the package.
- Remove "stream of consciousness" comments.
- Remove references to specific spec versions (e.g. v0.9).
- Update README.md and DESIGN.md to reflect current architecture and naming.
- Update README.md for genui_a2ui, genui_firebase_ai, genui_dartantic, and genui_google_generative_ai.
- Improve public API documentation in all integration packages.
- Remove legacy terms and outdated comments.
- Fix legacy class references (e.g. GenUiManager -> A2uiMessageProcessor).
Updates READMEs, dartdocs, and removes legacy references (e.g. GenUiManager, v0.8) across genui_a2ui, genui_firebase_ai, genui_dartantic, and genui_google_generative_ai.
This commit addresses the remaining identified shortfalls for Phase 2 of the
GenUI v0.9 migration.

Key changes:
- Tabs: Added 'activeTab' support to the Tabs component, allowing bidirectional
  binding of the active tab index to the data model.
- TextField: Refined the 'checks' schema to use 'func' instead of 'call' and
  implemented robust validation triggering on initialization and external updates.
- ExpressionParser: Standardized on using 'func' as the key for function calls
  instead of 'call', ensuring consistency with the A2UI schema.
- A2uiSchemas: Added 'logicExpression' and 'validationCheck' schema definitions.
- WidgetUtilities: Added 'subscribeToNumber' extension method for cleaner
  numeric data binding.

Verified with new tests in 'tabs_test.dart' and 'text_field_test.dart'.
…t data model)

This commit completes Phase 3 of the GenUI v0.9 migration.

Key changes:
- `ContentGenerator`: Added `eventStream`, `addInterceptor`, `removeInterceptor`.
- `ContentGeneratorMixin`: New mixin for shared event/interceptor logic.
- `GenUiEvent`: Added `ToolStartEvent`, `ToolEndEvent`, etc.
- `GenUiConversation`: Exposes `processingEvents` and passes `clientDataModel` to generators.
- Generators: Updated `GoogleGenerativeAiContentGenerator`, `FirebaseAiContentGenerator`, `DartanticContentGenerator`, and `A2uiContentGenerator` to support the new API, emit events, and handle interceptors (including Mock and Cancel actions).
- `A2uiAgentConnector`: Updated to include `clientDataModel` in request metadata.

BREAKING CHANGE: `ContentGenerator.sendRequest` now requires a `clientDataModel` parameter (nullable) and `dispose` must call `disposeMixin` if using the mixin.
Updates Google, Firebase, and Dartantic providers to inject the A2UI v0.9 `standard_catalog.json` and rules directly into the system prompt.
This ensures models have the necessary schema and rules to generate valid v0.9 A2UI content.

Changes:
- Adds `StandardCatalogEmbed` to `genui` package containing the standard catalog and rules.
- Updates `GoogleGenerativeAiContentGenerator` to append catalog/rules to system instructions.
- Updates `FirebaseAiContentGenerator` to append catalog/rules to system instructions.
- Updates `DartanticContentGenerator` to inject catalog/rules via extra instructions.
- Fixes `A2uiMessageProcessor` tests to align with `SurfaceAdded` -> `ComponentsUpdated` lifecycle events.
- Fixes `ui_tools_test.dart` to verify `ComponentsUpdated` events.

BREAKING-CHANGE: System prompts for all providers now include the A2UI Standard Catalog by default. This may affect token usage and model behavior.
- Add input validation `checks` support to `TextField` and `DateTimeInput`.
- Implement concurrency guards in `GenUiConversation`.
- Add surface ID validation to `A2uiMessageProcessor`.
- Fix duplicate tool registration in `GoogleGenerativeAiContentGenerator`.
- Enhance `GenUiSurfaceManager` and add `GenUiFallback` widget.
- Clean up lints and documentation comments.
The `Action` schema in A2UI v0.9 requires the action to be wrapped in an `event`
object (or `functionCall`). The examples in `Trailhead`, `TravelCarousel`, and
`InputGroup` were using a legacy flat structure. This change wraps them
correctly to pass validation tests.

Also includes a dev note in `GEMINI.md` about running tests efficiently.
… schema

- Remove hardcoded standardCatalogJson from StandardCatalogEmbed to support dynamic schemas.
- Update Google, Firebase, and Dartantic content generators to inject catalog.definition.toJson() into system prompts.
- Add JsonBlockParser to extract JSON from LLM text responses (prompt-first approach).
- Refactor content generators to parse JSON from text responses instead of tool calls.
- Fix DartanticContentGenerator to use Agent.send and parse text output.
…tors

- Conditionally set toolConfig in GoogleGenerativeAiContentGenerator and FirebaseAiContentGenerator only when tools are present.
- Prevents 'Function calling config is set without function_declarations' error from the API.
- Replace catalog.definition with A2uiMessage.a2uiMessageSchema(catalog) in content generators.
- Ensures LLM receives schema for top-level messages (createSurface, etc.) not just components.
- Fixes issues where LLM output was missing required fields like 'catalogId'.
- Add explicit JSON examples to StandardCatalogEmbed to guide LLM for createSurface/updateComponents.
- Add debug logging to A2uiMessage.fromJson to print JSON content when parsing fails.
- This helps diagnose and prevent JSON hallucination issues.
- Add JsonBlockParser.stripJsonBlock to strip JSON from text responses.
- Update content generators in genui_google_generative_ai, genui_firebase_ai, and genui_dartantic to use this.
- Update StandardCatalogEmbed examples to enforce 'id': 'root' for the top-level component, preventing 'no root component' errors.
- Verified that schema descriptions are correctly included in the JSON schema.
- Update JsonBlockParser to handle multiple JSON blocks in a single text response.
- Standardize extracting all JSON blocks and stripping them from the text in all content generators.
- Enable full prompt logging in GoogleGenerativeAiContentGenerator to aid debugging.
- This fixes issues where separate 'CreateSurface' and 'UpdateComponents' blocks were not both being processed or stripped.
…d with literal values

Updated standard catalog input components (TextField, CheckBox, ChoicePicker, DateTimeInput, Slider, Tabs) and travel_app components (OptionsFilterChipInput, TextInputChip, DateInputChip, CheckboxFilterChipsInput) to support implicit data binding.

When these components are initialized with a literal value (e.g., "value": "some string"), they now default to binding to '${context.id}.value' (or similar) in the DataModel.

This ensures that user interactions correctly update the DataModel and preserve state, which was previously failing for literal initializations.
gemini-code-assist[bot]

This comment was marked as resolved.

Replaced the unreliable Future.delayed(Duration.zero) call with await subscription.cancel() to ensure stream completion before proceeding, avoiding race conditions.

refactor(travel_app): implement AiClient interface for better extensibility

Introduces `AiClient` interface and updates `GoogleGenerativeAiClient` and `FakeAiClient` to implement it.
Refactors `TravelPlannerPage` to use `AiClient` instead of `Object` and removes type checks in wiring methods.
This simplifies `_wireClient` and `_sendRequest` and makes the client pluggable.
refactor(travel_app): use JsonBlockParser for JSON extraction

Replaces local `_parseJsonBlocks` and `_stripJsonBlock` helpers with `JsonBlockParser` from `package:genui` to remove duplication and use the centralized utility.
@gspencergoog gspencergoog force-pushed the feature/v0.9-migration-byo-llm branch from 22f0f2b to 66fd9ef Compare January 30, 2026 00:51
@gspencergoog gspencergoog force-pushed the feature/v0.9-migration-byo-llm branch from 05586c4 to 2da1643 Compare January 30, 2026 01:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant