Skip to content

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.

Add ChatKit to an existing Flutter app

text
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 checklist

Tool injection and system-call bridging

text
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 patterns

Good 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:

  • AgentSidebar
  • ChatKitRuntime
  • ChatKitSessionController
  • AgentSidebarController

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_sdk is the capability-layer SDK and chatkit_dart is the Flutter chat UI layer
  • AgentSidebar is the chat UI entry point, not a replacement for gateway access
  • ChatKitRuntime is the recommended place for shared message flow, background preconnect, and host integration
  • ChatKitSessionController is where system-call and session-level decisions can be coordinated
  • onConfigSaved and onLogout should still be owned by the host app
  • onSystemCallApp should not blindly allow all system calls; the host app should make trust decisions

Mode 1: shared runtime

This is the recommended default when the host app needs sidebar reuse and background preconnect.

dart
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.

dart
final managedController = AgentSidebarController();

AgentSidebar(
  controller: managedController,
  config: config,
  onConfigSaved: (next) async {},
  onLogout: () async {},
);

If the host app wants to trigger a request directly:

dart
await managedController.chat('Run this task');

Auto-connect behavior

AgentSidebar already handles the basic connection UX states:

  • idle
  • checking
  • connected
  • failed
  • needsConfig

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

dart
final theme = AgentSidebarThemeData(
  colors: AgentSidebarColors.fromTheme(Theme.of(context)),
);

Strings

dart
const strings = AgentSidebarStrings(
  title: 'AI Assistant',
  clearTooltip: 'Clear',
);

Tool injection and system-call bridging

Injecting a tool

dart
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:

dart
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_sdk before you add ChatKit
  • If you want the smallest host-side change, prefer the runtime mode 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_sdk and chatkit_dart?
  • Did it recommend validating the SDK path before layering ChatKit on top?
  • Did it preserve host ownership over onConfigSaved, onLogout, and onSystemCallApp?
  • Did it leave room for trust checks and policy decisions around callApp instead of auto-executing everything?
  • Did it choose shared runtime or managed controller intentionally 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 inside chatkit_dart?
  • Does it provide a copy-pastable minimal integration snippet with a working AgentSidebar mount point plus host callback skeletons for onConfigSaved and onLogout?
  • 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, and needsConfig clearly enough for the host app to present proper UX and fallbacks?