-
Notifications
You must be signed in to change notification settings - Fork 87
Add Dartantic Content Generator #583
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
… use. Here's a summary: ## Summary The `genui_dartantic` package and example app are now complete: ### Package Structure ``` packages/genui_dartantic/ ├── lib/ │ ├── genui_dartantic.dart # Public exports │ └── src/ │ ├── dartantic_content_generator.dart # Main ContentGenerator │ ├── dartantic_content_converter.dart # Message conversion │ └── dartantic_schema_adapter.dart # Schema adaptation ├── test/ # 44 passing tests ├── example/ │ ├── lib/main.dart # Example Flutter app │ └── pubspec.yaml # Dependencies ├── pubspec.yaml └── README.md ``` ### Example App Located at `packages/genui_dartantic/example/`, it demonstrates: - Using `DartanticContentGenerator` with `Providers.google` - Chat interface with surface navigation - GenUI widget rendering ### Running the Example ```bash export GOOGLE_API_KEY=your-key-here cd packages/genui_dartantic/example flutter run ``` You can also use other providers by changing the code: - `Providers.openai` (requires `OPENAI_API_KEY`) - `Providers.anthropic` (requires `ANTHROPIC_API_KEY`) - `Providers.ollama` (local, no API key required)
…are the most important to fix: 1. **warning** at line 153: Unnecessary type check (always true) 2. **warning** at line 158: Unnecessary null comparison (condition always true) Most of the info issues are style-related (specifying types for variables, line length, import ordering). I'm in plan mode, so I can't make edits. Would you like me to: 1. Exit plan mode so I can fix these warnings and info issues? 2. Just leave the warnings as-is since the code works? The warnings don't affect functionality - the tests all pass - but they indicate code that could be cleaner. The info-level issues are style guidelines that could also be cleaned up.
## Analysis Summary **Warnings fixed (2):** - Fixed unnecessary type check at line 153 (`result.output is Map` was always true) - Fixed unnecessary null comparison at line 158 (`result.output != null` was always true) **Info-level issues fixed (13):** - Fixed line lengths exceeding 80 chars - Fixed import ordering in test file - Fixed comment references in library doc - Added type annotations where required - Removed type annotations where they were obvious **Remaining (45 info-level):** All remaining issues are in test files and are style hints (`specify_nonobvious_local_variable_types`) that don't affect code correctness. The warnings are gone and all 44 tests pass.
…ic example:
**Changes made:**
1. **`.vscode/launch.json`** - Added new configuration:
```json
{
"name": "genui_dartantic_example",
"cwd": "packages/genui_dartantic/example",
"request": "launch",
"type": "dart",
"args": [
"--dart-define=GOOGLE_API_KEY=${env:GEMINI_API_KEY}"
]
}
```
2. **Example app (`main.dart`)** - Updated to read API key from dart-define:
- Reads `GOOGLE_API_KEY` from `String.fromEnvironment`
- Passes it to `GoogleProvider(apiKey: _googleApiKey)`
- Falls back to environment variable if dart-define is empty (dartantic's default behavior)
To run: Set `GEMINI_API_KEY` in your environment, then select "genui_dartantic_example" from VS Code's Run and Debug menu.
## Summary I've refactored `DartanticContentGenerator` to be **stateless** and properly integrate with GenUI's conversation history: ### Changes Made 1. **`dartantic_content_converter.dart`** - Added `toHistory()` method: - Converts GenUI `ChatMessage` history to dartantic `ChatMessage` list - Maps `UserMessage`/`UserUiInteractionMessage` → `ChatMessage.user()` - Maps `AiTextMessage`/`AiUiMessage` → `ChatMessage.model()` - Prepends system instruction as `ChatMessage.system()` if provided - Skips `InternalMessage` and `ToolResponseMessage` (handled internally by dartantic) 2. **`dartantic_content_generator.dart`** - Replaced `Chat` with `Agent`: - Removed `_chat` field, now uses `_agent` field - Removed `_hasWarnedAboutHistory` flag - `sendRequest()` now converts GenUI history via `_converter.toHistory()` and passes it to `_agent.sendFor<T>()` - Updated class docstring to document the stateless design 3. **`dartantic_content_converter_test.dart`** - Added 9 new tests for `toHistory()`: - Tests for null/empty history - Tests for system instruction - Tests for each message type conversion - Tests for skipping internal/tool messages - Tests for full conversation with system instruction ### Results - All **53 tests** pass - No analysis issues in source code - The generator now properly uses the history provided by `GenUiConversation` instead of maintaining its own internal state
## Summary I've replaced the simple genui_dartantic example with a full travel planner example based on `examples/travel_app/`. ### What was done: 1. **Copied from travel_app:** - `lib/src/catalog/` - 12 custom catalog items (travelCarousel, itinerary, inputGroup, etc.) - `lib/src/catalog.dart` - catalog definition - `lib/src/tools/` - booking service and `ListHotelsTool` - `lib/src/widgets/` - `Conversation` widget - `lib/src/utils.dart` - utility functions (MarkdownWidget) - `assets/travel_images/` and `assets/booking_service/` - images 2. **Created new main.dart:** - Uses `DartanticContentGenerator` with `GoogleProvider` - Includes the full travel planner system prompt - Uses `travelAppCatalog` with all 12 custom catalog items - Includes `ListHotelsTool` for hotel search functionality - API key passed via `--dart-define=GOOGLE_API_KEY` 3. **Updated pubspec.yaml:** - Added `gpt_markdown`, `intl`, `json_schema_builder` dependencies - Added asset paths for travel images 4. **Updated .vscode/launch.json:** - Renamed launch config to "travel_app (dartantic)" ### Results: - `dart analyze` shows no issues - All 53 tests pass - Web build succeeds - Ready to run with VS Code launch configuration "travel_app (dartantic)"
…ly, I realize `sendFor` **should** work with tools - the documentation explicitly shows: ```dart // Typed output + tool calls in one request final result = await agent.sendFor<Recipe>( 'Get grandma\'s recipe for cookies', outputSchema: recipeSchema, outputFromJson: Recipe.fromJson, tools: [recipeLookupTool], ); ``` The issue might not be `sendFor` vs `send`, but something else. Let me reconsider: 1. **Tools ARE registered** with the Agent at construction time 2. **sendFor with outputSchema** should still execute tools - dartantic handles tool loops internally 3. The `return_result` pseudo-tool is added **in addition to** existing tools, not replacing them I may have misdiagnosed the problem. Let me investigate further - the actual issue could be: - The system instruction isn't being passed correctly - The tools aren't being converted properly to dartantic format - Google's native `responseSchema` mode conflicts with tool calling (provider-specific) - Something else in the tool execution loop Should I explore deeper to find the real root cause rather than making this change?
## Summary **Root cause**: The example prompt told the model to "call the provideFinalOutput tool" but dartantic_ai doesn't have that tool - it handles typed output internally via `return_result`. **Changes made**: 1. **`packages/genui_dartantic/lib/src/dartantic_content_generator.dart`**: - Restored `json_schema` import - Restored `_outputSchema` static field - Kept using `sendFor` with `outputSchema` (typed output works correctly with dartantic) 2. **`packages/genui_dartantic/example/lib/main.dart`**: - Removed the reference to `provideFinalOutput` tool from the prompt (line 388) - Changed "conversation turn is complete, and you should call the provideFinalOutput tool." to "conversation turn is complete." **Results**: - All 53 tests pass - Web build succeeds - The model should now properly call the GenUI tools (surfaceUpdate, beginRendering) and dartantic will handle the typed output automatically
**Changes made to `packages/genui_dartantic/example/lib/main.dart`:**
1. **Added tabs structure** - `DefaultTabController` with 2 tabs ("Travel" and "Widget Catalog")
2. **Added proper AppBar** - menu icon, airplane icon + centered title, person icon, TabBar at bottom
3. **Added `CatalogTab` widget** - displays `DebugCatalogView` with `travelAppCatalog`
4. **Updated title** - "Agentic Travel Inc (Dartantic)" to distinguish from the original
5. **Removed `provideFinalOutput` reference** from the prompt (dartantic uses `return_result` internally)
The app structure now matches the working `examples/travel_app/`:
- Tab 1: "Travel" → `TravelPlannerPage` with the AI chat interface
- Tab 2: "Widget Catalog" → `CatalogTab` showing all available catalog items in `DebugCatalogView`
The build succeeded. You can now run the app with VS Code launch config "travel_app (dartantic)" or:
```bash
cd packages/genui_dartantic/example && flutter run --dart-define=GEMINI_API_KEY=$GEMINI_API_KEY
```
## Summary **Files created:** - `packages/genui_dartantic/example/lib/src/asset_images.dart` - identical to travel_app - `packages/genui_dartantic/example/lib/src/travel_planner_page.dart` - adapted from travel_app **Files modified:** - `packages/genui_dartantic/example/lib/main.dart` - reduced from 646 lines to 117 lines **Key differences between travel_app and dartantic example:** | File | Difference | |------|------------| | `main.dart` | No Firebase init, teal color, "(Dartantic)" in title, const actions | | `travel_planner_page.dart` | Uses `DartanticContentGenerator` + `dartantic.GoogleProvider`, no AiBackend switch, prompt says "conversation turn is complete" instead of "call provideFinalOutput" | | `asset_images.dart` | Identical | The dartantic example now has the same modular structure as travel_app, with the only meaningful differences being the content generator and prompt - exactly as you requested.
- Updated `DartanticContentConverter` to include a new method `toPromptAndParts` that converts GenUI messages into a prompt string along with associated parts for better handling of multimodal content. - Adjusted `DartanticContentGenerator` to utilize the new conversion method, ensuring that both text and tool content are preserved in requests. - Modified tests to validate the new functionality, ensuring proper conversion and handling of various message types, including tool calls and results. - Cleaned up code and comments for clarity and consistency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces the genui_dartantic package, which is a significant and well-executed addition. It integrates genui with dartantic_ai to enable support for multiple AI providers, and includes a comprehensive example app to demonstrate its capabilities. The code is well-structured, documented, and tested. My review focuses on improving code robustness, type safety, and fixing a few minor issues in the example application to further enhance its quality.
packages/genui_dartantic/example/lib/src/catalog/date_input_chip.dart
Outdated
Show resolved
Hide resolved
packages/genui_dartantic/example/lib/src/catalog/itinerary.dart
Outdated
Show resolved
Hide resolved
packages/genui_dartantic/example/lib/src/catalog/listings_booker.dart
Outdated
Show resolved
Hide resolved
packages/genui_dartantic/example/lib/src/travel_planner_page.dart
Outdated
Show resolved
Hide resolved
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
…ip.dart Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
…el.dart Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
…er.dart Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
|
Exciting @csells! :D I'm not familiar with the setup here, but should this be separate from this repo so we can point to it as an exemplary example of a community-maintained provider/generator? |
|
Seth and Greg asked for a PR but making this an external repo works for me, too. |
|
thanks @csells ! I think it's OK to keep in this repo now. We might split it out later, once APIs stabilize. |
|
Keeping it here sounds good to me! Thanks for clarifying :) |
|
/gemini summary |
Summary of ChangesThis pull request significantly enhances GenUI by introducing the Highlights
Changelog
Activity
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure it makes sense to duplicate the entire travel_app example here. It would probably make more sense to have a separate, simpler, example for dartantic. Something that doesn't require lots of assets, with less code to maintain would be ideal. The idea isn't to have an example of GenUI (that's what the top level examples are for), but rather to have an example of what is different about using Dartantic from the other content generators.
…one typed json schema package to another.
Adds
genui_dartanticpackage - a newContentGeneratorimplementation that enables GenUI to work with multiple AI providers (OpenAI, Anthropic, Google, Mistral, Cohere, Ollama) via the dartantic_ai package.Issues fixed
Elements of the package
Pre-launch Checklist
///).