import type { ConversationManager } from './conversation.js'; import type { ToolRegistry } from '../tools/registry.js'; import type { HookEvent, HookResult } from '../hooks/types.js'; import type { ContentPart } from '../providers/interface.js'; import type { PermissionManager } from '../permissions/manager.js'; import type { AcpManager } from '../acp/manager.js'; import { type ConversationFollowUpItem } from './conversation-follow-ups.js'; import { AgentManager } from '../tools/agent/index.js'; import { WrfcController } from '../agents/wrfc-controller.js'; import type { FeatureFlagManager } from '../runtime/feature-flags/manager.js'; import type { RuntimeEventBus, TurnInputOrigin } from '../runtime/events/index.js'; import { type OrchestratorCoreServices } from './orchestrator-runtime.js'; import { type TurnInjectionRecord } from '../agents/turn-knowledge-injection.js'; import type { OrchestratorUsageTotals } from './orchestrator-usage.js'; /** Minimal interface for hook dispatch, allows any hook dispatcher implementation */ interface HookDispatcherLike { fire(event: HookEvent): Promise; } interface LowPrioritySystemMessageSink { low(message: string): void; } export interface OrchestratorUserInputOptions { readonly origin?: TurnInputOrigin | undefined; } /** * Options for constructing an {@link Orchestrator}: the conversation, viewport * callbacks, tool registry, permission manager, system-prompt getter, hook * dispatcher, flag manager, render callback, runtime bus, and services * (agentManager, wrfcController). */ export interface OrchestratorOptions { /** Manages the conversation message history. */ conversation: ConversationManager; /** Returns the current viewport height in rows/px for scrolling calculations. */ getViewportHeight: () => number; /** Scrolls the UI to the given viewport height after a turn. */ scrollToEnd: (vHeight: number) => void; /** Registry of all available tools. */ toolRegistry: ToolRegistry; /** Manages tool-use permission grants and denials. */ permissionManager: PermissionManager; /** Returns the current system prompt text. Defaults to `() => ''`. */ getSystemPrompt?: (() => string) | undefined; /** Optional hook dispatcher for lifecycle events. */ hookDispatcher?: HookDispatcherLike | null | undefined; /** Optional capability-gate manager. */ flagManager?: FeatureFlagManager | null | undefined; /** Optional render request callback, called after state changes requiring a redraw. */ requestRender?: (() => void) | null | undefined; /** Optional runtime event bus for cross-system event propagation. */ runtimeBus?: RuntimeEventBus | null | undefined; /** * Stable session id used in runtime events, hook events, idempotency keys, * plans, and reply correlation. Defaults to a generated private id. */ sessionId?: string | undefined; /** * Per-turn passive-injection budget override for the main session, * mirroring agents/orchestrator-runner.ts's `passiveKnowledgeInjectionBudgetTokens`. * Omitted uses the derived default (defaultTurnKnowledgeBudgetTokens). `0` is a hard * no-op, independent of the capability gate's own state. */ passiveKnowledgeInjectionBudgetTokens?: number | undefined; /** * Per-turn passive-injection relevance-floor override for the main * session, mirroring agents/orchestrator-runner.ts's * `passiveKnowledgeInjectionRelevanceFloor`. Omitted uses DEFAULT_TURN_KNOWLEDGE_RELEVANCE_FLOOR. */ passiveKnowledgeInjectionRelevanceFloor?: number | undefined; /** Required runtime service dependencies. */ services: { readonly agentManager: Pick; readonly wrfcController: Pick; }; } /** * Orchestrator - Manages LLM turn lifecycle with full tool-use loop. * Supports multi-turn agent loops: call LLM -> execute tools -> send results -> repeat. */ export declare class Orchestrator { isThinking: boolean; thinkingFrame: number; usage: OrchestratorUsageTotals; /** * Input tokens from the most recent LLM response (incl. cache read/write), * current context-window usage; 0 before the first response. */ lastInputTokens: number; /** Fresh input tokens from the most recent turn (excluding cache-read reuse where applicable). */ lastRequestInputTokens: number; /** Approximate input tokens for the current streaming turn (from prior turn's response). */ streamingInputTokens: number; /** Output tokens received so far in the current streaming turn (one per delta chunk). */ streamingOutputTokens: number; messageQueue: { id: string; queuedAt: number; text: string; content?: ContentPart[] | undefined; options?: OrchestratorUserInputOptions | undefined; }[]; private animInterval; private abortController; /** Per-tool-call abort registry (per-call cancel; see orchestrator-live-turn.ts). */ private readonly toolCallAborts; /** Monotonic id source for queued-message ids. */ private queuedMessageSeq; private autoSpawnTimeout; private acpManager; /** Message count at the start of a turn, used to rollback on cancel. */ private turnStartMessageCount; /** Whether a streaming block is currently active (for cleanup on abort). */ private isStreaming; /** Last token warning bracket (multiples of 10%) to avoid repeat warnings at same level. */ private lastWarningBracket; /** Whether auto-compaction is currently in progress (prevents re-entry). */ private isCompacting; /** * Pending context-window warning reported by the model/provider itself * (stop reason, see isContextOverflowSignal). While set, the next preflight * or post-turn maintenance pass compacts immediately regardless of locally * estimated usage; cleared when that compaction starts. */ private modelContextWarning; /** Session ID for runtime and hook events. */ private readonly sessionId; /** * Submission key for the active turn: generated per runTurn, used as the * idempotency key of the turn-level dedup fence (a duplicate in-flight * runTurn with the same text is rejected), reset to null on completion. */ currentSubmissionKey: string | null; /** True when the turn failed (set in catch; read in finally for markComplete vs markFailed). */ private _turnFailed; /** Event replay queue, ensures model acknowledges significant events */ private readonly replayQueue; /** Cleanup function returned by the active replay queue attachment. */ private detachReplay; private readonly runtimeBus; private readonly agentManager; private readonly wrfcController; private coreServices; private readonly ownedSessionLineageTracker; private readonly ownedIdempotencyStore; private readonly ownedCacheHitTracker; /** * Optional capability-gate manager: the `tool-result-reconciliation` flag is * consulted at each turn end (enabled = full reconciliation); null defaults * to enabled, matching the flag's declared defaultState. */ private flagManager; /** * Tracks the last provider response's tool calls within the current turn * iteration so the reconciliation pass can detect unresolved calls when * the loop exits early. */ private _pendingToolCalls; private readonly requestRender; private systemMessageRouter; private readonly followUpRuntime; private conversation; private getViewportHeight; private scrollToEnd; private toolRegistry; private permissionManager; private getSystemPrompt; private hookDispatcher; /** * Per-turn passive-injection state for the MAIN interactive session, * see core/orchestrator-turn-loop.ts for the retrieval/budget wiring that reads and * mutates these. `turnKnowledgeIdsAlreadySurfaced` has no spawn-time baseline (unlike * an AgentRecord's `knowledgeInjections`) so it starts empty and grows monotonically * for the life of this Orchestrator. `turnInjectionRing` backs the public * `getTurnInjections()` accessor. */ private readonly turnKnowledgeIdsAlreadySurfaced; private turnInjectionRing; private turnKnowledgeSequence; private readonly passiveKnowledgeInjectionBudgetTokens; private readonly passiveKnowledgeInjectionRelevanceFloor; /** Construct an Orchestrator using a named-options object ({@link OrchestratorOptions}). */ constructor(options: OrchestratorOptions); setCoreServices(services: OrchestratorCoreServices): void; /** * Attach an AcpManager and register the 'delegate' tool into the ToolRegistry. * Call this after construction, before the first turn. */ registerDelegateTool(manager: AcpManager): void; getSpinner(): string; /** * Bounded ring of per-turn passive-injection honesty records for the * MAIN interactive session, the main-session counterpart to `AgentRecord.turnInjections` * on the agent path. There is no AgentRecord for the primary conversation, so this is the exact * accessor a `/recall`-style renderer should read as the main-session default when no * agent id is given. See agents/turn-knowledge-injection.ts for the record shape and * recordTurnInjection for the ring-eviction policy (same bounded size as the agent path). */ getTurnInjections(): readonly TurnInjectionRecord[]; setSystemMessageRouter(router: LowPrioritySystemMessageSink | null): void; enqueueConversationFollowUp(item: ConversationFollowUpItem): void; /** * Cancel ONE in-flight tool call by its callId, leaving the turn and any * other running calls untouched: the cancelled call settles as a structured * "cancelled by user" result the model adapts to in the same turn. */ cancelToolCall(callId: string): boolean; /** The callIds of tool calls currently in flight (cancellable via cancelToolCall). */ listRunningToolCalls(): readonly string[]; /** The pending (undelivered, still editable) mid-turn messages, in delivery order. */ listQueuedMessages(): ReadonlyArray<{ id: string; queuedAt: number; text: string; }>; /** Replace a still-queued message's text; false once delivered (immutable). */ editQueuedMessage(id: string, text: string): boolean; /** Remove a still-queued message before delivery; false once delivered. */ deleteQueuedMessage(id: string): boolean; /** Broadcast a pending-queue mutation as a runtime.session event (wire-honest). */ private emitQueueChange; /** Abort the current in-flight LLM request, if any. */ abort(): void; /** * Dispose long-lived runtime attachments owned by this orchestrator. * * Safe to call multiple times. Intended for process shutdown and tests that * construct transient orchestrators against a shared RuntimeEventBus. */ dispose(): void; /** * handleUserInput - Entry point for a user-submitted message. * Queues if already thinking, otherwise kicks off the LLM turn. * @param text - Plain text representation (for display and queuing). * @param content - Optional ContentPart[] for multimodal messages. * @param options - Optional origin metadata for external surfaces. */ handleUserInput(text: string, content?: ContentPart[], options?: OrchestratorUserInputOptions | undefined): Promise; /** * Drain queued user messages sequentially. Skips draining while a turn is in * flight or a background auto-compaction is running; in the latter case * setCompacting() re-triggers the drain once compaction settles, so no queued * message is lost. */ private drainMessageQueue; /** * Single funnel for mutating the compaction flag. On the true->false edge it * resumes draining any messages that were queued while compaction was in flight. */ private setCompacting; private startThinking; private stopThinking; private runTurn; /** Phase 1: Idempotency fence, event emission, adaptive planner, plan injection, thinking start. * Returns null when the turn is a duplicate in-flight submission that should not execute. */ private runTurnPreflight; /** Phase 2: Execute the LLM streaming loop and tool dispatch. */ private runTurnStream; /** Phase 3: Post-turn context maintenance (compaction, memory, plan updates). */ private runTurnReconcile; /** Catch handler: route to abort path or error path. */ private handleTurnError; /** Finally handler: tool-call reconciliation, submission key finalization, notifications, replay queue. */ private finalizeTurn; /** * Pre-flight context window check: estimate the pending request's tokens vs * the model's window; over-limit compacts first (when enabled), then errors * with specific counts. Returns 'ok' | 'compacted' | 'error'. */ private checkContextWindowPreflight; /** * Auto-spawn agents for a list of ready plan items under bounded orchestration policy. */ private autoSpawnPendingItems; /** * Returns `true` when the GC-ORCH-015 reconciliation feature is active. * * Defaults to `true` (flag `defaultState: 'enabled'`) when no flag manager * has been wired in, safe for tests that omit the optional constructor arg. */ /** The per-turn flag reads, and their differing defaults: ./orchestrator-turn-flags.ts. */ private get turnFlags(); private isReconciliationEnabled; private isPassiveKnowledgeInjectionEnabled; private isPassiveCodeInjectionEnabled; /** * Ids never to re-surface in a later per-turn knowledge block. The main * session has no spawn-time `AgentRecord.knowledgeInjections` baseline, so this starts * empty and grows monotonically for the life of the Orchestrator. */ private getAlreadyInjectedKnowledgeIds; /** Mark ids as surfaced so they are never listed twice this session. */ private addInjectedKnowledgeIds; /** Append one honesty record to the bounded ring behind {@link getTurnInjections}. */ private recordTurnKnowledgeInjection; /** Monotonic per-Orchestrator-lifetime sequence number for TurnInjectionRecord.turn. */ private nextTurnKnowledgeSequence; /** * Reconcile unresolved tool calls at turn end (non-empty _pendingToolCalls * or malformed provider response): inject synthetic error results, add a * system message, emit TOOL_RECONCILED. Gate-off logs and no-ops. */ private reconcileUnresolvedToolCalls; private executeToolCalls; } export {}; //# sourceMappingURL=orchestrator.d.ts.map