Skip to content

AgentManager

Category: Agent

Source: agent_manager.dart

Classes

SubagentUpdate

An update from a running subagent, forwarded to the UI.

Constructor

dart
SubagentUpdate({
    required this.task,
    this.index,
    this.total,
    required this.event,
  })
dart
SubagentUpdate(task: task, index: index, total: total, event: event)

Properties

PropertyTypeDescription
taskStringShort description of the subagent's task.
indexint?Index within a parallel batch (null for single subagent).
totalint?Total number of parallel subagents (null for single).
eventAgentEventThe underlying agent event.
toolsMap<String, Tool>
llmFactoryLlmClientFactory
configGlueConfig
systemPromptString
allowedSubagentToolsSet<String>
obsObservability?
onPersistEventSubagentEventSink?Optional sink for persisting subagent activity onto the parent session log. Surfaces wire this to SessionManager.logEvent so subagent transcripts survive resume and feed /share. When null, subagent activity remains live-only (the legacy behavior).
subagentStatsUsageStatsCumulative usage across every subagent this manager has spawned. Surfaces (CLI status bar, ACP usage endpoint) read this to attribute subagent cost separately from the parent agent's own LLM calls.
updatesStream<SubagentUpdate> getStream of updates from running subagents.
updatesStream<SubagentUpdate> getStream of updates from running subagents.

Methods

void Function(UsageStats)

Optional callback invoked when a subagent finishes, with that subagent's [UsageStats]. Surfaces wire this to SessionManager.recordUsage(stats, role: 'subagent') so the rollup is also persisted.

`Future<String> spawnSubagent({
required String task,
ModelRef? modelOverride,
int currentDepth = 0,
int? index,
int? total,
String? parentSubagentId,

})`

Spawns a single subagent to complete a [task].

Optionally override [modelOverride] to switch model for this subagent. [currentDepth] tracks recursion to prevent infinite nesting. [index] and [total] are set when spawned as part of a parallel batch. [parentSubagentId] is the id of the subagent that initiated this spawn (null when spawned by the top-level agent). Persisted on the subagent_spawned row so transcript reconstruction can attach the new group to the correct parent even when sibling subagents run in parallel and emit interleaved events.

AgentManager

Orchestrates subagent spawning using the manager pattern.

Creates independent [AgentCore] instances with their own conversation history but shared tool registry. Subagents run headlessly via [AgentRunner] with an allowlist-based approval policy (read-only tools by default).

Constructor

dart
AgentManager({
    required this.tools,
    required this.llmFactory,
    required this.config,
    required this.systemPrompt,
    Set<String>? allowedSubagentTools,
    this.obs,
    this.onPersistEvent,
  })

Properties

PropertyTypeDescription
toolsMap&lt;String, Tool&gt;
llmFactoryLlmClientFactory
configGlueConfig
systemPromptString
allowedSubagentToolsSet&lt;String&gt;
obsObservability?
onPersistEventSubagentEventSink?Optional sink for persisting subagent activity onto the parent session log. Surfaces wire this to SessionManager.logEvent so subagent transcripts survive resume and feed /share. When null, subagent activity remains live-only (the legacy behavior).
subagentStatsUsageStatsCumulative usage across every subagent this manager has spawned. Surfaces (CLI status bar, ACP usage endpoint) read this to attribute subagent cost separately from the parent agent's own LLM calls.
updatesStream&lt;SubagentUpdate&gt; getStream of updates from running subagents.
updatesStream&lt;SubagentUpdate&gt; getStream of updates from running subagents.

Methods

void Function(UsageStats)

Optional callback invoked when a subagent finishes, with that subagent's [UsageStats]. Surfaces wire this to SessionManager.recordUsage(stats, role: 'subagent') so the rollup is also persisted.

`Future<String> spawnSubagent({
required String task,
ModelRef? modelOverride,
int currentDepth = 0,
int? index,
int? total,
String? parentSubagentId,

})`

Spawns a single subagent to complete a [task].

Optionally override [modelOverride] to switch model for this subagent. [currentDepth] tracks recursion to prevent infinite nesting. [index] and [total] are set when spawned as part of a parallel batch. [parentSubagentId] is the id of the subagent that initiated this spawn (null when spawned by the top-level agent). Persisted on the subagent_spawned row so transcript reconstruction can attach the new group to the correct parent even when sibling subagents run in parallel and emit interleaved events.

`Future<List<String>> spawnParallel({
required List&lt;String&gt; tasks,
ModelRef? modelOverride,
int currentDepth = 0,
String? parentSubagentId,

})`

Spawns [tasks] in parallel, each as independent subagents.

All subagents run concurrently and results are returned in order.

Note: Parallel subagents share the same file system. Avoid tasks that write to the same files concurrently, as this can cause race conditions.

return switch (event)

Functions

Map&lt;String, dynamic&gt; serializeAgentEvent(AgentEvent event)

Serialises an [AgentEvent] into a JSON-compatible map for persistence in the parent session log under subagent_event.inner. The shape mirrors the top-level conversation event types where they overlap (tool_call, tool_result, assistant_message) so the same normaliser can recurse into either.

Released under the MIT License.