An in-app AI assistant that ships inside your Flutter app

The most common reason teams reach for agentlib: they want a real agent — one that can call tools, keep context, and stream — living inside the app, not behind a server round-trip for every turn. agentlib is pure Dart, so the same AgentSpec runs on the device that renders your UI.

AgentSpec + RunnerSkillsMCP21 Hooks

Why in-app instead of server-side

A server-side agent adds a network hop to every tool call and can't touch on-device state — contacts, the current screen, local files — without exfiltrating it. An in-app agent keeps the loop next to the UI. agentlib gives you the streaming Runner event loop (TextDelta, ToolCalled, Finished) so you can render tokens as they arrive and drive Flutter widgets directly from tool results.

Tools are your app's own functions

Register Dart functions as CLIs in the Vfs and the model composes them through the Sh mini-shell — contacts grep 'Mom' | jq -r .number | xargs whatsapp send. No JSON-RPC ceremony, no subprocess. Every high-impact tool auto-snapshots first, so a mistaken send is one revert() away.

Consent and audit come free

Wrap sensitive actions with the PermissionRequestHook to surface a native consent sheet, and PostToolUse to write an audit line. That's how you ship an assistant that can act on the user's behalf without hard-coding a permission dialog into every call site.

lib/assistant.dart
final agent = AgentSpec(
  name: 'assistant',
  instructions: 'Help the user with tasks in this app.',
  model: AnthropicProvider(
    apiKey: const String.fromEnvironment('ANTHROPIC_API_KEY'),
  ),
);

final run = Runner.runStreamed(
  agent.toRunConfig(vfs: appVfs, threadId: 'chat'),
  input: userMessage,
);
await for (final e in run.events) {
  if (e is TextDelta) appendToBubble(e.delta);
}

Related use cases

See how these fit together in the architecture overview, or browse all eight primitives in depth.

build it

Ship this on your users' phones.

agentlib is open source, MIT, and on pub.dev. Add one pubspec line to get started.