Skip to content
Open
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
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes
File renamed without changes.
File renamed without changes.
File renamed without changes.
155 changes: 155 additions & 0 deletions examples/examples.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
# Examples

This directory contains example applications demonstrating the `genui` SDK capabilities.

## Overview

| Example | Complexity | Backend | Description |
|---------|------------|---------|-------------|
| [catalog_gallery](#catalog_gallery) | Simple | None | Visual reference for core catalog widgets |
| [custom_backend](#custom_backend) | Intermediate | Custom/Saved | Demonstrates custom backend integration |
| [travel_app](#travel_app) | Advanced | Firebase/Google AI | Full travel planning assistant with custom catalog |
| [verdure](#verdure) | Advanced | Python A2A Server | Full-stack landscape design agent |

## Running Examples

Most examples support multiple AI backends. The default is typically Google Generative AI which requires an API key:

```bash
# Get API key from https://aistudio.google.com/app/apikey
flutter run --dart-define=GEMINI_API_KEY=YOUR_API_KEY
```

---

## catalog_gallery

A developer tool for visualizing and testing the core widget catalog. Displays all available `CoreCatalogItems` widgets and allows interaction testing.

**Key Features:**
- Browse all core catalog widgets
- Interactive widget testing with event logging
- Sample file loading support

**Run:**
```bash
cd examples/catalog_gallery
flutter run
```

---

## custom_backend

Demonstrates integrating genui with a custom backend without using predefined provider packages (`genui_firebase_ai`, `genui_google_generative_ai`).

**Key Features:**
- Direct integration with `A2uiMessageProcessor`
- Manual tool call parsing and handling
- Saved response testing for development without API calls
- Shows how to build `UiSchemaDefinition` and `catalogToFunctionDeclaration`

**Key Files:**
- `lib/backend.dart` - Custom backend implementation
- `lib/gemini_client.dart` - Direct Gemini API client
- `assets/data/saved-response-*.json` - Pre-recorded responses for testing

**Run:**
```bash
cd examples/custom_backend
flutter run --dart-define=GEMINI_API_KEY=YOUR_API_KEY
```

---

## travel_app

A full-featured travel planning assistant demonstrating advanced genui capabilities with a custom domain-specific widget catalog.

**Key Features:**
- Custom widget catalog with travel-specific components (carousel, itinerary, filter chips)
- Tool use (`ListHotelsTool` for fetching hotel data)
- System prompt engineering for AI behavior
- Dynamic UI generation based on conversation
- Supports Firebase AI and Google Generative AI backends

**Key Files:**
- `lib/src/catalog.dart` - Custom travel widgets catalog
- `lib/src/catalog/` - Individual widget implementations
- `lib/src/travel_planner_page.dart` - Main page with system prompt
- `lib/src/tools/booking/` - AI tool implementations
- `lib/src/config/configuration.dart` - Backend configuration

**Custom Widgets:**
- `TravelCarousel` - Image carousel for destinations
- `OptionsFilterChipInput` / `CheckboxFilterChipsInput` - User preference inputs
- `Itinerary` / `ItineraryEntry` - Trip planning display
- `ListingsBooker` - Hotel booking interface
- `Trailhead` - Suggested follow-up questions
- `TabbedSections` - Tabbed content display

**Run:**
```bash
cd examples/travel_app
flutter run --dart-define=GEMINI_API_KEY=YOUR_API_KEY
```

**Switch to Firebase:**
1. Edit `lib/src/config/configuration.dart`: set `aiBackend = AiBackend.firebase`
2. Uncomment Firebase imports in `lib/main.dart`
3. Run `flutterfire configure` to generate Firebase options

---

## verdure

A full-stack example with a Python server and Flutter client demonstrating the A2A (Agent-to-Agent) protocol for landscape design.

**Prerequisites:**
- Python 3.13+
- [UV](https://docs.astral.sh/uv/) package manager
- Gemini API key

**Architecture:**
```
verdure/
├── server/ # Python A2A server
│ └── verdure/ # Agent implementation
└── client/ # Flutter client app
```

**Run Server:**
```bash
cd examples/verdure/server/verdure
echo "GEMINI_API_KEY=YOUR_API_KEY" > .env
uv run .
# Server starts on http://localhost:10002
```

**Run Client:**
```bash
cd examples/verdure/client
flutter run
```

**Android Emulator:**
The emulator uses `10.0.2.2` as localhost alias. Start server with:
```bash
uv run . --base-url="http://10.0.2.2:10002"
```

**Key Files:**
- `server/verdure/agent.py` - AI agent logic
- `server/verdure/a2ui_schema.py` - A2UI protocol schema
- `client/lib/features/ai/ai_provider.dart` - Client AI integration

---

## Choosing an Example

| Goal | Recommended Example |
|------|---------------------|
| Understand core widgets | `catalog_gallery` |
| Build custom backend integration | `custom_backend` |
| Build a production-like app with custom catalog | `travel_app` |
| Implement client-server architecture with A2A | `verdure` |
2 changes: 2 additions & 0 deletions packages/genui/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# `genui` Changelog

## 0.6.1 (in progress)
- Moved simple chat example to example so that pub.dev recognizes examples are provided.
- Documented some variable for better dartcode documentation.

## 0.6.0

Expand Down
3 changes: 3 additions & 0 deletions packages/genui/lib/src/model/a2ui_schemas.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import 'tools.dart';
/// Provides a set of pre-defined, reusable schema objects for common
/// A2UI patterns, simplifying the creation of CatalogItem definitions.
class A2uiSchemas {
/// This class is not meant to be instantiated.
A2uiSchemas._();

/// Schema for a value that can be either a literal string or a
/// data-bound path to a string in the DataModel. If both path and
/// literal are provided, the value at the path will be initialized
Expand Down
25 changes: 25 additions & 0 deletions packages/genui/lib/src/model/catalog_item.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,17 @@ typedef ExampleBuilderCallback = String Function();
/// A callback that builds a widget for a catalog item.
typedef CatalogWidgetBuilder = Widget Function(CatalogItemContext itemContext);

/// Context provided to a [CatalogItem]'s widget builder.
///
/// This class encapsulates all the information and callbacks needed to build
/// a catalog widget, including access to the widget's data, its position in
/// the component tree, and mechanisms for building children and dispatching
/// events.
class CatalogItemContext {
/// Creates a [CatalogItemContext] with the required parameters.
///
/// All parameters are required to ensure the widget builder has complete
/// context for rendering and interaction.
CatalogItemContext({
required this.data,
required this.id,
Expand All @@ -37,13 +47,28 @@ class CatalogItemContext {
required this.surfaceId,
});

/// The parsed data for this component from the AI-generated definition.
final Object data;

/// The unique identifier for this component instance.
final String id;

/// Callback to build a child widget by its component ID.
final ChildBuilderCallback buildChild;

/// Callback to dispatch UI events (e.g., button taps) back to the system.
final DispatchEventCallback dispatchEvent;

/// The Flutter [BuildContext] for this widget.
final BuildContext buildContext;

/// The [DataContext] for accessing and modifying the data model.
final DataContext dataContext;

/// Callback to retrieve a component definition by its ID.
final GetComponentCallback getComponent;

/// The ID of the surface this component belongs to.
final String surfaceId;
}

Expand Down
4 changes: 4 additions & 0 deletions packages/genui/lib/src/model/chat_message.dart
Original file line number Diff line number Diff line change
Expand Up @@ -243,5 +243,9 @@ final class AiUiMessage extends ChatMessage {

final String surfaceId;

/// The parts of this message, containing a text description of the UI.
///
/// This is automatically generated from the [definition] and provides
/// context for the AI about the current UI state.
final List<MessagePart> parts;
}
14 changes: 14 additions & 0 deletions packages/genui/lib/test/fake_content_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,28 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/// A fake implementation of [ContentGenerator] for testing purposes.
///
/// This library provides [FakeContentGenerator], which allows tests to
/// simulate AI responses without making actual API calls.
library fake_content_generator;

import 'dart:async';

import 'package:flutter/foundation.dart';

import '../genui.dart';

/// A fake [ContentGenerator] for use in tests.
///
/// This implementation allows tests to control AI responses by:
/// - Tracking calls to [sendRequest] via [sendRequestCallCount]
/// - Capturing the last message and history via [lastMessage] and [lastHistory]
/// - Emitting fake A2UI messages via [addA2uiMessage]
/// - Emitting fake text responses via [addTextResponse]
/// - Pausing execution via [sendRequestCompleter]
class FakeContentGenerator implements ContentGenerator {
/// Creates a new [FakeContentGenerator] instance.
FakeContentGenerator();

final _a2uiMessageController = StreamController<A2uiMessage>.broadcast();
Expand Down