Use ChatKit in Dart
This guide explains where chatkit_dart fits in the full Dart / Flutter stack and how it works together with agentos_sdk.
If you are coding with Claude, Codex, Cursor, or ChatGPT, this page can also act as an execution brief for ChatKit integration.
Recommended prompts
Add ChatKit to an existing Flutter app
Help me integrate AgentOS ChatKit into an existing Flutter app while preserving as much of my current page structure and state management as possible.
You must keep these responsibilities separate:
- agentos_sdk handles gateway access, bundle registration, token management, and capability-layer calls
- chatkit_dart handles chat UI, runtime, session controller, and host integration
- Do not treat ChatKit as a replacement for the underlying SDK
- If I already have business pages, only add AgentSidebar where chat UI is actually needed
Return:
1. Which integration mode fits better: shared runtime or managed controller
2. Minimal implementation code
3. Host-side decision points for config save, logout, and system-call handling
4. A manual verification checklistTool injection and system-call bridging
Design how my Flutter host app should handle tool injection and system-call bridging around AgentOS ChatKit.
Requirements:
- Be explicit about which logic belongs in the host app versus the ChatKit UI layer
- Provide a safety decision point for callApp events instead of allowing everything by default
- If a tool should be injected, include the minimal skeleton code
- Stay close to AgentSidebar, ChatKitRuntime, and ChatKitSessionController patternsGood fit
- You want a chat UI quickly
- You want less custom message-rendering work
- You want a more complete Flutter integration on top of the Dart SDK
Not a good fit
- You only need capability calls and do not need a chat UI
- You already own a mature message list, input box, and session orchestration layer
- You want full control over the UI interactions and do not want to bring in a ready-made sidebar
Core roles
agentos_sdk
Handles gateway access, bundle registration, token management, and calls to modules such as ModelKit, AgentKit, and RagKit.
chatkit_dart
Handles the Flutter-side chat UI and host integration. The core objects usually include:
AgentSidebarChatKitRuntimeChatKitSessionControllerAgentSidebarController
In simple terms: the SDK is responsible for “connecting to AgentOS and sending requests,” while ChatKit is responsible for “turning those capabilities into a usable chat experience.”
Minimal fact checklist
agentos_sdkis the capability-layer SDK andchatkit_dartis the Flutter chat UI layerAgentSidebaris the chat UI entry point, not a replacement for gateway accessChatKitRuntimeis the recommended place for shared message flow, background preconnect, and host integrationChatKitSessionControlleris where system-call and session-level decisions can be coordinatedonConfigSavedandonLogoutshould still be owned by the host apponSystemCallAppshould not blindly allow all system calls; the host app should make trust decisions
Recommended integration modes
Mode 1: shared runtime
This is the recommended default when the host app needs sidebar reuse and background preconnect.
late final ChatKitRuntime runtime;
@override
void initState() {
super.initState();
runtime = ChatKitRuntime(
config: config,
onSystemCallApp: (event) async {
return const SystemCallAction.injectText('Handle system event');
},
);
unawaited(runtime.start());
}
AgentSidebar(
runtime: runtime,
config: config,
onConfigSaved: (next) async {
runtime.updateConfig(next);
},
onLogout: () async {
await runtime.stop();
},
);Advantages:
- the host app and the sidebar share the same message flow
- the connection can stay alive in the background
- it is a better fit for apps with system-event or bridge logic
Mode 2: managed controller
If you want the host to write as little chat-state code as possible, you can let ChatKit own most message and state management.
final managedController = AgentSidebarController();
AgentSidebar(
controller: managedController,
config: config,
onConfigSaved: (next) async {},
onLogout: () async {},
);If the host app wants to trigger a request directly:
await managedController.chat('Run this task');Auto-connect behavior
AgentSidebar already handles the basic connection UX states:
idlecheckingconnectedfailedneedsConfig
When config.baseUrl and config.bundleId are already present, opening the sidebar can automatically test connectivity, register, and subscribe.
Config and theme customization
Config persistence
At minimum, the host app still needs to do two things:
- save configuration in
onConfigSaved - clear local configuration or sessions in
onLogout
Theme
final theme = AgentSidebarThemeData(
colors: AgentSidebarColors.fromTheme(Theme.of(context)),
);Strings
const strings = AgentSidebarStrings(
title: 'AI Assistant',
clearTooltip: 'Clear',
);Tool injection and system-call bridging
Injecting a tool
AgentSidebar(
controller: managedController,
config: const AgentOsConfig(bundleId: 'com.example.app'),
capability: Capability(systemPrompt: 'You are ChatKit assistant.'),
tool: MockCrudTool(),
onConfigSaved: (next) async {},
onLogout: () async {},
);Handling callApp
ChatKit can bridge callApp events into chat input, but the final policy should stay in the host app:
ChatKitSessionController(
onSystemCallApp: (event) async {
if (event.bundleId != 'com.example.trusted') {
return const SystemCallAction.ignore();
}
return SystemCallAction.injectText('Run system task');
},
);Practical advice
- Validate the network path and model calls with
agentos_sdkbefore you add ChatKit - If you want the smallest host-side change, prefer the
runtimemode first - If you already own message persistence, listen to controller changes and sync them into your own storage
- ChatKit is responsible for UI experience, but it should not replace your app's decisions around permissions, system events, or business state
Manual verification checklist
- Did the AI clearly separate the responsibilities of
agentos_sdkandchatkit_dart? - Did it recommend validating the SDK path before layering ChatKit on top?
- Did it preserve host ownership over
onConfigSaved,onLogout, andonSystemCallApp? - Did it leave room for trust checks and policy decisions around
callAppinstead of auto-executing everything? - Did it choose
shared runtimeormanaged controllerintentionally instead of mixing both loosely? - Is the boundary between ChatKit and the SDK explicit, keeping gateway access, token and bundle management, and capability calls inside
agentos_sdk, while keeping chat UI, session runtime, and sidebar interaction insidechatkit_dart? - Does it provide a copy-pastable minimal integration snippet with a working
AgentSidebarmount point plus host callback skeletons foronConfigSavedandonLogout? - Does it cover common UI extension paths such as theme customization, strings customization, embedding the sidebar in an existing page, and host-controlled open/close behavior without forking ChatKit internals?
- Does it explain
idle,checking,connected,failed, andneedsConfigclearly enough for the host app to present proper UX and fallbacks?
