Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions src/content/ai/genui/components.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ The [`genui`][] package is built around the following main components:

`GenUiConversation`
: The primary facade and entry point for the package.
It includes the `GenUiManager` and `ContentGenerator` classes,
It includes the `A2uiMessageProcessor` and `ContentGenerator` classes,
manages the conversation history,
and orchestrates the entire generative UI process.

`Catalog`
: A collection of `CatalogItem` objects that defines
the set of widgets that the AI is allowed to use.
The `A2uiMessageProcessor` supports multiple catalogs,
allowing you to organize your widgets into logical groups.
Each `CatalogItem` specifies a widget's name (for the AI
to reference), a data schema for its properties, and a
builder function to render the Flutter widget.
Expand All @@ -50,6 +52,10 @@ The [`genui`][] package is built around the following main components:
instructing it to perform actions like `beginRendering`,
`surfaceUpdate`, `dataModelUpdate`, or `deleteSurface`.

`A2uiMessageProcessor`
: Handles the processing of `A2uiMessage`s,
manages the `DataModel`, and maintains the state of UI surfaces.

## How it works

The `GenUiConversation` manages the interaction cycle:
Expand Down Expand Up @@ -77,12 +83,12 @@ The `GenUiConversation` manages the interaction cycle:
5. **UI state update**

`GenUiConversation` listens to these streams.
`A2uiMessages` are passed to `GenUiManager.handleMessage()`,
`A2uiMessages` are passed to `A2uiMessageProcessor.handleMessage()`,
which updates the UI state and `DataModel`.

6. **UI rendering**

The `GenUiManager` broadcasts an update,
The `A2uiMessageProcessor` broadcasts an update,
and any `GenUiSurface` widgets listening for that surface ID will rebuild.
Widgets are bound to the `DataModel`, so they update automatically
when their data changes.
Expand All @@ -98,7 +104,7 @@ The `GenUiConversation` manages the interaction cycle:
(for example, by typing in a text field). This interaction directly
updates the `DataModel`. If the interaction is an action (like a button click),
the `GenUiSurface` captures the event and forwards it to the
`GenUiConversation`'s `GenUiManager`, which automatically creates
`GenUiConversation`'s `A2uiMessageProcessor`, which automatically creates
a new `UserMessage` containing the current state of the data model
and restarts the cycle.

Expand Down
47 changes: 25 additions & 22 deletions src/content/ai/genui/get-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ consider using Firebase AI Logic instead.
// ...
]);

final messageProcessor = A2uiMessageProcessor(catalogs: [catalog]);

final contentGenerator = GoogleGenerativeAiContentGenerator(
catalog: catalog,
systemInstruction: 'You are a helpful assistant.',
Expand All @@ -97,6 +99,7 @@ consider using Firebase AI Logic instead.

final conversation = GenUiConversation(
contentGenerator: contentGenerator,
a2uiMessageProcessor: messageProcessor,
);
```

Expand Down Expand Up @@ -172,7 +175,7 @@ The main components in this package include:
* `A2uiContentGenerator`:
Implements the `ContentGenerator` that manages the connection
to the A2A server and processes incoming A2UI messages,
updating the `GenUiManager`.
updating the `A2uiMessageProcessor`.
* `A2uiAgentConnector`:
Handles the low-level web socket communication with the
A2A server, including sending messages and parsing stream events.
Expand All @@ -189,8 +192,8 @@ Follow these instructions:
$ dart pub add genui genui_a2ui a2a
```

2. Initialize `GenUIManager`:
Set up `GenUiManager` with your widget `Catalog`.
2. Initialize `A2uiMessageProcessor`:
Set up `A2uiMessageProcessor` with your widget `Catalog`s.

3. Create `A2uiContentGenerator`:
Instantiate `A2uiContentGenerator`, providing the A2A server URI.
Expand Down Expand Up @@ -252,8 +255,8 @@ Follow these instructions:

class _ChatScreenState extends State<ChatScreen> {
final TextEditingController _textController = TextEditingController();
final GenUiManager _genUiManager =
GenUiManager(catalog: CoreCatalogItems.asCatalog());
final A2uiMessageProcessor _a2uiMessageProcessor =
A2uiMessageProcessor(catalogs: [CoreCatalogItems.asCatalog()]);
late final A2uiContentGenerator _contentGenerator;
late final GenUiConversation _uiAgent;
final List<ChatMessage> _messages = [];
Expand All @@ -267,7 +270,7 @@ Follow these instructions:
);
_uiAgent = GenUiConversation(
contentGenerator: _contentGenerator,
genUiManager: _genUiManager,
a2uiMessageProcessor: _a2uiMessageProcessor,
);

// Listen for text responses from the agent.
Expand All @@ -288,7 +291,7 @@ Follow these instructions:
void dispose() {
_textController.dispose();
_uiAgent.dispose();
_genUiManager.dispose();
_a2uiMessageProcessor.dispose();
_contentGenerator.dispose();
super.dispose();
}
Expand Down Expand Up @@ -329,7 +332,7 @@ Follow these instructions:
SizedBox(
height: 300,
child: GenUiSurface(
host: _genUiManager,
host: _a2uiMessageProcessor,
surfaceId: 'main_surface',
),
),
Expand Down Expand Up @@ -439,48 +442,48 @@ to enable outbound network requests:
Next, use the following instructions to connect your app
to your chosen agent provider.

1. Create a `GenUiManager`, and provide it with the catalog
1. Create a `A2uiMessageProcessor`, and provide it with the catalogs
of widgets that you want to make available to the agent.

2. Create a `ContentGenerator`, and provide it with a
system instruction and a set of tools (functions
you want the agent to be able to invoke).
You should always include those provided by `GenUiManager`,
You should always include those provided by `A2uiMessageProcessor`,
but feel free to include others.

3. Create a `GenUiConversation` using the instances of
`ContentGenerator` and `GenUiManager`. Your app will
`ContentGenerator` and `A2uiMessageProcessor`. Your app will
primarily interact with this object to get things done.

For example:

```dart
class _MyHomePageState extends State<MyHomePage> {
late final GenUiManager _genUiManager;
late final A2uiMessageProcessor _a2uiMessageProcessor;
late final GenUiConversation _genUiConversation;

@override
void initState() {
super.initState();

// Create a GenUiManager with a widget catalog.
// Create a A2uiMessageProcessor with a widget catalog.
// The CoreCatalogItems contain basic widgets for text, markdown, and images.
_genUiManager = GenUiManager(catalog: CoreCatalogItems.asCatalog());
_a2uiMessageProcessor = A2uiMessageProcessor(catalogs: [CoreCatalogItems.asCatalog()]);

// Create a ContentGenerator to communicate with the LLM.
// Provide system instructions and the tools from the GenUiManager.
// Provide system instructions and the tools from the A2uiMessageProcessor.
final contentGenerator = FirebaseAiContentGenerator(
systemInstruction: '''
You are an expert in creating funny riddles. Every time I give you a word,
you should generate UI that displays one new riddle related to that word.
Each riddle should have both a question and an answer.
''',
tools: _genUiManager.getTools(),
additionalTools: _a2uiMessageProcessor.getTools(),
);

// Create the GenUiConversation to orchestrate everything.
_genUiConversation = GenUiConversation(
genUiManager: _genUiManager,
a2uiMessageProcessor: _a2uiMessageProcessor,
contentGenerator: contentGenerator,
onSurfaceAdded: _onSurfaceAdded, // Added in the next step.
onSurfaceDeleted: _onSurfaceDeleted, // Added in the next step.
Expand Down Expand Up @@ -674,11 +677,11 @@ To add your own widgets, use the following instructions.

4. Add the `CatalogItem` to the catalog

Include your catalog items when instantiating `GenUiManager`.
Include your catalog items when instantiating `A2uiMessageProcessor`.

```dart
_genUiManager = GenUiManager(
catalog: CoreCatalogItems.asCatalog().copyWith([riddleCard]),
_a2uiMessageProcessor = A2uiMessageProcessor(
catalogs: [CoreCatalogItems.asCatalog().copyWith([riddleCard])],
);
```

Expand All @@ -695,7 +698,7 @@ To add your own widgets, use the following instructions.
generate a RiddleCard that displays one new riddle related to that word.
Each riddle should have both a question and an answer.
''',
tools: _genUiManager.getTools(),
additionalTools: _a2uiMessageProcessor.getTools(),
);
```

Expand Down Expand Up @@ -788,7 +791,7 @@ final contentGenerator = FirebaseAiContentGenerator(
displays one new riddle related to that word.
Each riddle should have both a question and an answer.
''',
tools: _genUiManager.getTools(),
additionalTools: _a2uiMessageProcessor.getTools(),
);
```

Expand Down
Loading