Skip to content
Back to archipelago.banuacoder.com

Feature SDKs

How to add an AI chat screen to a Flutter app ​

Pro Reference for ai_chat_sdk: every variable, option and package it generates. Command: archipelago generate ai_chat_sdk

Generate the AI Chat SDK with OpenAI, Anthropic or both, set API keys without committing them, and drive the chat from your own code.

What you'll learn ​

  • Generating the AI Chat SDK with OpenAI, Anthropic, or both
  • Understanding the packages the brick creates
  • Setting API keys without committing them
  • Driving the chat from your own code

Prerequisites ​

ai_chat_sdk needs storage_sdk for chat history. The brick generates storage_sdk for you if it is missing. You do not install it first.

Step 1: Generate the AI Chat SDK ​

bash
archipelago generate ai_chat_sdk

The prompts are:

  • aiChatProvider: openai, anthropic or both (default openai)
  • defaultModel: the model ID sent to the provider (default gpt-4o-mini)
  • uiKitPackageName: read from archipelago.yaml

Or use a config file:

json
{
  "aiChatProvider": "both",
  "defaultModel": "gpt-4o-mini"
}
bash
archipelago generate ai_chat_sdk --config ai_chat_config.json

Step 2: Understand the Generated Structure ​

The chat contract lives in ai_chat_api. Each provider is its own package. The post-generation hook deletes the providers you did not select.

text
features/ai_chat/
├── ai_chat_api/
│   └── lib/src/
│       ├── models/                  # ChatMessage, ChatRequest, ChatStreamEvent, ...
│       ├── utils/                   # AiChatInjectorKey
│       └── ai_chat_sdk.dart         # AiChatSDK contract
├── ai_chat_impl/
│   └── lib/src/
│       ├── data/                    # ChatHistoryStorage
│       ├── di/                      # AiChatImplGlobalModule
│       ├── presentation/widgets/    # Chat screen, bubbles, input bar
│       ├── router/
│       └── ai_chat_sdk_impl.dart
├── ai_chat_openai_impl/             # If openai or both
└── ai_chat_anthropic_impl/          # If anthropic or both

Step 3: Check the Wiring ​

AiChatImplGlobalModule registers an AiChatManifest with the /ai-chat route. It registers AiChatSDK as a lazy singleton. Boot does not read the history or build the providers.

Both providers can be active at once. Each registers AiChatProvider under a distinct @Named key. The orchestrator finds them with getAll<AiChatProvider>() on first use.

Step 4: Configure Your API Key ​

Each provider package reads its key from String.fromEnvironment. A request fails while the placeholder key is in place. The dependency graph still resolves without a key.

dart
// ai_chat_openai_impl/lib/src/di/register_module.dart
const key = String.fromEnvironment('OPENAI_API_KEY', defaultValue: 'YOUR_OPENAI_API_KEY');

Pass the key at build time:

bash
flutter run --dart-define=OPENAI_API_KEY=sk-...

In GitHub Actions:

yaml
- name: Build
  run: flutter build apk --dart-define=OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY }}

You can also set OPENAI_API_KEY or ANTHROPIC_API_KEY in .env and run melos run env:generate. Then follow the TODO(user) in each register_module.dart to read the generated Env value.

Step 5: Open the Chat or Drive It from Code ​

dart
final chat = getIt<AiChatSDK>();

await chat.launch(context); // opens /ai-chat

await chat.sendMessage('Hello!'); // returns the request id
chat.conversationStream.listen((messages) => setState(() => _messages = messages));

chat.cancelInflight();
await chat.clearConversation();
await chat.retryLastFailed();

sendMessage streams the assistant reply into conversationStream. The stream holds the full message list each time.

Step 6: Switch Providers ​

dart
chat.setProvider(AiChatProviderId.anthropic); // throws if not registered

Read chat.availableProviders to list what is registered.

Step 7: History ​

The SDK stores history with StorageProvider.forNamespace('ai_chat') at application scope. A logout does not clear it. Call clearConversation() on logout if you want an empty chat.

History loads in the background after the SDK is built. Send, clear and retry wait for the load.

Key Configuration Points ​

CustomizationWhere to Change
Default modelThe defaultModel variable, or AiChatConfig
Add a providerA new package that implements AiChatProvider and registers under its own @Named key
Storage backendThe storage_sdk implementation you installed
Chat widgetsai_chat_impl/lib/src/presentation/widgets/

Known Limitations ​

  • The provider packages talk to Dio directly. Interceptors from network_sdk do not apply.
  • No integration tests ship for the streaming parsers. Add a live-API test before you ship.

Next Steps ​