Skip to content

Introduce A2UI Express package and express_chat example application#932

Draft
gspencergoog wants to merge 23 commits into
flutter:mainfrom
gspencergoog:a2ui_express
Draft

Introduce A2UI Express package and express_chat example application#932
gspencergoog wants to merge 23 commits into
flutter:mainfrom
gspencergoog:a2ui_express

Conversation

@gspencergoog
Copy link
Copy Markdown
Collaborator

@gspencergoog gspencergoog commented May 26, 2026

Description

This change introduces the new genui_express Flutter plugin package alongside a new demonstration application, express_chat, to provide offline local generative UI compilation and on-device LLM execution in the monorepo.


Key changes

New package: genui_express

Introduced /packages/genui_express as a standalone, shareable Flutter plugin package providing offline generative UI capabilities:

  • Layout DSL scanner: Implemented tokenization and lexical scanning for A2UI Express positional expressions in token.dart.
  • Recursive-descent parser: Developed the AST recursive parser in parser.dart to process positional expressions.
  • Compact signatures compiler: Implemented ExpressCompiler and CatalogSchemaHelper to dynamically map catalog component arguments to layout definitions and compile them into valid standard A2UI JSON specifications.
  • Express prompt builder: Implemented ExpressPromptBuilder (conforming to GenUI's PromptBuilder contract) to format compact positional component signatures optimized for local models.
  • Genkit local models: Registered three built-in local models in on_device_plugins.dart using the Genkit framework: Apple Intelligence local/apple-foundation-models (macOS/iOS), Google AI Edge SDK local/android-ai-edge (Android), and Ollama completions local/http-completion.
  • Stateful local transport: Developed ExpressLocalTransport (conforming to GenUI's Transport contract) to manage conversation session history, intercept LLM output streams, isolate layout blocks, trigger compiler updates, and emit A2UI specifications. Added resilient support to parse standard JSON maps and arrays.

New example app: express_chat

Introduced /examples/express_chat as a rich demonstration application showing offline generative UI in action:

  • Local run loops: Configured chat_session.dart and main.dart to coordinate local chat sessions and handle progressive text bubbles and surface rendering.
  • Chrome AI integration: Added genkit_chrome: ^0.0.8 as an application dependency. Implemented compile-safe conditional import stubs (chrome_plugin_stub.dart and chrome_plugin_web.dart) to register the Chrome AI Gemini Nano plugin when running in the browser while preventing compiler errors on native mobile/desktop platforms.
  • Dynamic platform defaults: Defaults model execution to Chrome's built-in Gemini Nano Prompt API (chrome/gemini-nano) when running on Web, and to your local completions server (local/http-completion on port 8080 running Gemma 4) when running natively on macOS.

Native compilation configurations

  • Deployment targets: Enforced macOS 15.0 and iOS 18.0 deployment baselines across package podspecs, Swift Package Manager manifests, and the host application CocoaPods Podfile to support Swift LanguageModeling modules.
  • SDK compatibility: Implemented #if canImport(LanguageModeling) compiler blocks to allow compilation inside sandboxed developer containers while loading the native Neural Engine session at runtime.

Workspace maintenance

  • Monorepo workspace: Updated the root pubspec.yaml to include both packages/genui_express and packages/genui_express/example inside the monorepo workspace member list.
  • Analyzer upgrades: Updated /tool/test_and_fix/pubspec.yaml to require analyzer: ">=10.0.0 <14.0.0", resolving package resolution conflicts across the monorepo.

Verification

All changes have been verified using static analysis, compiler suites, and integration tests:

  • Static analysis: All packages and examples compile with zero errors or warnings.
  • Package tests: Created 10 unit and streaming transport integration tests in packages/genui_express. All tests pass.
  • Example app smoke tests: Verified that the new express_chat app boots successfully.
  • Example app integration tests: Executed integration tests on macOS. The test runner successfully compiled and rendered button, form, hello, and mixed layout surfaces.

- Implement direct data path assignments compiler parsing and evaluation
- Structuredly accumulate deep nested path maps and include in returned envelope
- Extract and sequentially emit dataModel as an UpdateDataModel message
- Support <a2ui> and </a2ui> sentinel tags for robust, leak-free layout extraction
- Statefully filter DSL lines in real-time streaming chat bubble streams
- Support format-spanning multi-line statements in compiler parsers
- Rethrow programming Error types in handleMessage to prevent LLM debugging loops
- Add comprehensive multi-line and path assignment unit tests
…piler, prompt builder, and local Genkit models

- Create packages/genui_express as a shareable Flutter plugin package.
- Port A2UI Express lexer, token scanner, parser, and catalog schema helper.
- Implement ExpressPromptBuilder extending GenUI's PromptBuilder with compact signature contracts optimized for on-device LLMs.
- Develop GenuiExpressLocalModels registering Apple Intelligence (FoundationModels), Android AI Edge (Gemini Nano), and Ollama HTTP completions directly with Genkit.
- Expose ExpressLocalTransport implementing the core Transport interface to coordinate local streaming and compilation pipelines.
- Add comprehensive compiler parser and transport streaming tests.
…enui_express package

- Delete local hand-rolled express compiler, transport, and custom agent loop files inside examples/express_chat.
- Update express_chat/pubspec.yaml to depend on genui_express and genkit.
- Refactor ChatSession and ChatScreen widgets to accept Genkit engine and ModelRef parameters in place of custom AiClient.
- Convert TextOnlyChatSession and A2uiChatSession to coordinate via ExpressLocalTransport and Genkit.
- Rewrite integration test and fake client to instantiate Genkit models and verify layouts using A2uiMessage subtype pattern casts.
- Verify standard A2UI JSON array envelope resolution under Postel's Law in ExpressLocalTransport.
- Confirm that all smoke and integration tests pass successfully.
…nfigurable

- Update local/http-completion model to read baseUrl and model from Genkit request configuration map.
- Change default completions endpoint to http://localhost:8080/v1 and model name to mlx-community/gemma-4-e2b-it-4bit, matching the monorepo local MLX server.
…ple Intelligence on-device LLM

- Connect genui_express MethodChannel and EventChannel handlers to Swift on macOS and iOS.
- Use NaturalLanguage.LanguageModelSession to stream hardware-accelerated response chunks.
- Support checkAvailability call and handle asynchronous task cancellation.
…enforce compile-safe LanguageModeling imports

- Override MACOSX_DEPLOYMENT_TARGET to 15.0 for all native targets inside CocoaPods post_install block in examples/express_chat/macos/Podfile.
- Increase minimum platform versions to macOS 15.0 and iOS 18.0 in all package podspecs and SPM Package manifests.
- Integrate #if canImport(LanguageModeling) conditional compilation block inside native Apple plugins to bypass module resolution errors on simulated/sandboxed build servers.
- Update examples/express_chat to default to local/apple-foundation-models session in chat_session.dart.
…ons for gMac compatibility

- Default A2uiChatSession and TextOnlyChatSession model reference to local/http-completion in chat_session.dart.
- Remove unused package:genkit/src/core/action.dart import.
- Simplify stream variable definition with type inference.
…ndation-models

- Set default model reference back to local/apple-foundation-models in chat_session.dart for production open-source Apple Silicon Neural Engine deployment.
- Keep dynamic local/http-completion completions model active for local gMac completions testing.
…ocal developer testing

- Default A2uiChatSession and TextOnlyChatSession model reference back to local/http-completion in chat_session.dart, enabling plug-and-play local gMac completions.
- Keep Swift plugins clean and Sequoia-compliant.
…conditional imports for Chrome built-in AI

- Add genkit_chrome dependency to packages/genui_express.
- Implement on_device_plugins_stub.dart and on_device_plugins_web.dart to isolate web-only js_interop imports.
- Conditionally register ChromeAIPlugin on Genkit when compiling for web.
- Use kIsWeb in examples/express_chat to dynamically default to 'chrome/gemini-nano' on Chrome and 'local/http-completion' on native platforms.
…ore required web plugin registrant

- Restore required packages/genui_express/lib/genui_express_web.dart to resolve web compilation entrypoint registrant error.
- Remove package genkit_chrome from packages/genui_express dependencies and add it to examples/express_chat dependencies.
- Implement chrome_plugin_stub.dart and chrome_plugin_web.dart in examples/express_chat using package:genkit/plugin.dart.
- Pass getPlatformPlugins() conditionally to the Genkit constructor list inside chat_session.dart.
- Clean up packages/genui_express plugin stubs.
@gspencergoog gspencergoog changed the title Introduce A2UI Express compilation and local on-device model integration Introduce A2UI Express package and express_chat example application May 26, 2026
@gspencergoog gspencergoog changed the title Introduce A2UI Express package and express_chat example application Introduce A2UI Express package and express_chat example application May 26, 2026
gemini-code-assist[bot]

This comment was marked as resolved.

…nd genui_express

- Add mounted checks before and inside postFrameCallback in main.dart to avoid disposed ScrollController crashes.
- Correct integration test README path reference to express_chat.
- Remove list allocation overhead in messages getter, and specify return Stream types.
- Implement dynamic type safety checks on climbing location identifiers.
- Replace assert checks with runtime nullable checks for SurfaceHost, using local variable promotion.
@gspencergoog gspencergoog marked this pull request as draft May 26, 2026 17:11
…xample

- Exclude web-only files (*_web.dart) from ephemeral coverage test generation in test_and_fix.dart to prevent VM compilation errors.
- Replace genui_express/README.md with a detailed package description, usage instructions, and a concrete implementation code sample.
…c variables

- Resolved all Dart analyzer warnings, style/info violations, and line length issues.
- Replaced generic 'dynamic' references with 'Object?' in model reference, generateStream API, and A2UI layout DSL JSON maps.
- Added explicit generic type arguments to raw 'List' and 'Map' type checks and casts.
- Formatted all modified files and confirmed everything compiles cleanly and passes all unit and integration tests.
…odel constants

- Restricted public library exports in `genui_express.dart` to strictly keep tokenizer, parsing, and schema helper internals hidden.
- Defined public static const string references for local model names (`appleFoundationModels`, `androidAiEdge`, `httpCompletion`) inside `GenuiExpressLocalModels`.
- Updated the local models registration logic to use these public constants.
- Refactored model instantiation in `chat_session.dart` (express_chat example) to leverage the new type-safe model constants.
- Updated imports in `compiler_test.dart` to directly reference compiler internals package-relatively.
- Exclude all `*_web.dart` files (e.g., `genui_express_web.dart`, `chrome_plugin_web.dart`) in `test_and_fix.dart` from being imported in the autogenerated `ephemeral_coverage_all_test.dart` file.
- This prevents compiler crashes on native VM test environments caused by missing `dart:ui_web` and `dart:js_interop` libraries.
- Updated `coverage_policy.yaml` to globally exclude `**/*_web.dart` and set explicit policies for the new packages (genui_express threshold of 60% and disabled express_chat).
- Updated `coverage_baseline.yaml` high-water marks.
…example

- Enabled coverage verification for `examples/express_chat` in `coverage_policy.yaml` with a threshold of 30.0%.
- Updated `coverage_baseline.yaml` to record its high-water mark (35.8%).
…ample

- Enabled coverage verification for `examples/simple_chat` in `coverage_policy.yaml` with a threshold of 30.0%.
- Updated `coverage_baseline.yaml` to record its high-water mark (37.3%).
- Note: examples/verdure/client remains disabled since it does not contain a 'test/' directory.
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