buildAgentStack method

WiredAgentStack buildAgentStack({
  1. required AgentWiringSpec spec,
  2. required StreamFunction streamFunction,
  3. List<AgentTool> additionalTools = const [],
  4. void onDuplicate(
    1. String message
    )?,
})

Assembles the ToolRegistry (core tools first, then the gated task surface, then additionalTools — any residual host surface) and the Agent over it. The model-reading tool closures resolve against the constructed agent, exactly like the host shells' own () => _agent.state.model today.

Implementation

WiredAgentStack buildAgentStack({
  required AgentWiringSpec spec,
  required StreamFunction streamFunction,
  List<AgentTool> additionalTools = const [],
  void Function(String note)? onDuplicate,
}) {
  // ---- issue #1322 host seams ----
  // Key-slot drift (Gap 2): when the host supplied a resolver, the run's
  // model gets the same boot-time canonical-vs-pinned check the CLI
  // prints — one visible warning instead of a silently empty slot.
  final keyResolver = services.keyResolver;
  if (keyResolver != null) {
    final resolution = keyResolver.resolveKey(
      provider: spec.model.provider,
      baseUrl: spec.model.baseUrl,
    );
    final hint = resolution.driftHint;
    if (hint != null) services.onKeySlotDrift?.call(hint);
  }
  // Telemetry (Gap 3): the adapter subscribes the sink to the agent and
  // wraps the provider leg (requestStart / firstToken / HTTP status on
  // error). Null sink → byte-identical to the pre-telemetry wiring.
  var wiredStream = streamFunction;
  AgentTelemetry? telemetryAdapter;
  final sink = services.telemetry;
  if (sink != null) {
    telemetryAdapter = AgentTelemetry(sink);
    wiredStream = telemetryAdapter.wrapStreamFunction(streamFunction);
  }
  final registry = ToolRegistry([
    ...tools,
    ...taskSurface,
    ...additionalTools,
  ], onDuplicate);
  final agent = _agent = Agent(
    model: spec.model,
    systemPrompt: spec.systemPrompt,
    streamFunction: wiredStream,
    toolRegistry: registry,
    maxEmptyRetries: spec.maxEmptyRetries,
    onRunIdleTimeout: spec.onRunIdleTimeout,
    onRunWatchdogPaused: spec.onRunWatchdogPaused,
    contextWindowCap: spec.contextWindowCap,
    stuckTool: spec.stuckTool,
    wireDump: spec.wireDump,
    overWindowRelief: spec.overWindowRelief,
    toolMisuseBreaker: spec.toolMisuseBreaker,
  );
  telemetryAdapter?.attach(agent);
  return WiredAgentStack(registry: registry, agent: agent);
}