This document outlines the design for the genui_a2a package, an integration layer connecting the genui framework with servers implementing the A2UI Streaming UI Protocol. Its primary purpose is to enable Flutter applications to dynamically render UIs and handle interactions based on messages received from an A2A (Agent-to-Agent) server.
To provide a seamless and robust way for Flutter applications using genui to consume A2UI streams, leveraging genui's existing capabilities for UI rendering and state management, without tightly coupling the core genui package to the A2A protocol specifics.
The architecture of genui_a2a revolves around two main classes:
A2uiAgentConnector: This class encapsulates the low-level details of the A2A protocol, using thepackage:a2aclient library.- Handles WebSocket connection management.
- Constructs and sends A2A messages (including user input and UI events).
- Receives
A2AStreamEvents from the server. - Parses
A2ADataParts within the events to extract JSON-encoded A2UI messages. - Exposes streams of
A2uiMessageand text events that can be piped into aSurfaceController. - Manages conversation state like
taskIdandcontextIdas provided by the A2A server.
graph TD
User --> FlutterApp[Flutter Application]
FlutterApp --> Conversation[Conversation \n genui]
Conversation -- onSend --> A2uiAgentConnector
A2uiAgentConnector -- A2AClient --> A2AServer[A2A Server]
A2AServer -- A2AStreamEvent --> A2uiAgentConnector
A2uiAgentConnector -- A2uiMessage --> FlutterApp
FlutterApp -- pipes to --> SurfaceController[SurfaceController \n genui]
SurfaceController -- update state --> Surface[Surface \n genui]
Surface --> FlutterApp
Surface -- UiEvent --> SurfaceController
SurfaceController -- client event --> Conversation
- User input is sent via
Conversation.sendRequest, which triggers theonSendcallback. - The callback delegates to
A2uiAgentConnectorto send the message to the A2A Server. - The server streams back
A2AStreamEvents containing A2UI messages. A2uiAgentConnectorparses these intoA2uiMessageobjects.- The application (via manual piping) forwards these messages to
SurfaceController. SurfaceControllerprocesses the message and updates the surface state.- The state change causes
Surfaceto re-render. - User interactions on
SurfacegenerateUiEvents, which are captured bySurfaceController, passed toConversation, and then sent back to the server viaA2uiAgentConnectorin theonSendcallback.
- Embedding A2A logic directly in
genui: Rejected to keep the core framework decoupled from specific communication protocols. - Re-implementing rendering logic: Rejected in favor of leveraging
genui's establishedSurfaceControllerandSurfacefor UI rendering and state management.
The chosen approach of a separate integration package (genui_a2a) provides the best separation of concerns.
genui_a2a provides the A2uiAgentConnector which acts as a transport bridge between an A2A server and the genui framework. By piping its output streams into SurfaceController, developers can drive a dynamic Flutter UI from an A2A backend.