import { ToolRegistry } from '../tools/registry.js'; import type { ConfigManager } from '../config/manager.js'; import type { ConversationMessageSnapshot } from '../core/conversation.js'; import type { ProviderRegistry } from '../providers/registry.js'; import { AgentMessageBus } from './message-bus.js'; import type { ChannelPluginRegistry } from '../channels/index.js'; import { FileStateCache } from '../state/file-cache.js'; import { ProjectIndex } from '../state/project-index.js'; import type { AgentRecord } from '../tools/agent/index.js'; import type { ToolLLM } from '../config/tool-llm.js'; import type { FeatureFlagManager } from '../runtime/feature-flags/manager.js'; import type { RuntimeEventBus } from '../runtime/events/index.js'; export { summarizeToolArgs } from './orchestrator-utils.js'; /** * Conversation-snapshot bridge (Part C6): where AgentOrchestrator forwards a running agent's * live conversation-snapshot accessor. In production this is AgentManager's * registerConversationSource/releaseConversationSource, wired post- * construction in runtime/services.ts (AgentOrchestrator is constructed * before AgentManager there, so this is a setter rather than a constructor * dependency, same pattern as setRuntimeBus). */ export interface AgentConversationSink { readonly register: (agentId: string, source: () => ConversationMessageSnapshot[]) => void; readonly release: (agentId: string) => void; } /** * Cooperative cancellation bridge: where AgentOrchestrator * looks up a per-agent AbortSignal registered by an orchestration engine's * work-item run. Same shape/wiring precedent as AgentConversationSink, a * setter rather than a constructor dependency, wired post-construction in * runtime/services.ts (production backing is * AgentManager.registerCancellationSignal/getCancellationSignal). */ export interface AgentCancellationSource { readonly get: (agentId: string) => AbortSignal | undefined; } type AgentOrchestratorToolDeps = { readonly fileCache: FileStateCache; readonly projectIndex: ProjectIndex; readonly workingDirectory: string; readonly surfaceRoot: string; readonly fileUndoManager: import('../state/file-undo.js').FileUndoManager; readonly modeManager: import('../state/mode-manager.js').ModeManager; readonly processManager: import('../tools/shared/process-manager.js').ProcessManager; readonly agentMessageBus: AgentMessageBus; readonly webSearchService?: import('../web-search/index.js').WebSearchService | undefined; readonly channelRegistry?: import('../channels/index.js').ChannelPluginRegistry | null | undefined; readonly remoteRunnerRegistry?: import('../runtime/remote/index.js').RemoteRunnerRegistry | undefined; readonly knowledgeService?: import('../knowledge/index.js').KnowledgeService | undefined; readonly memoryRegistry?: import('../state/index.js').MemoryRegistry | undefined; /** Supplying it registers the `profile` capture tool. See registerAllTools. */ readonly personalCapture?: import('../personal-capture/index.js').PersonalCaptureHolder | undefined; readonly codeIndex?: import('./turn-knowledge-injection.js').TurnCodeIndexSource | undefined; readonly isCodeInjectionSettingEnabled?: (() => boolean) | undefined; readonly codeIndexReindexScheduler?: Pick | undefined; /** Additional per-tool-execution tap (e.g. CI auto-watch minting); composed with the reindex scheduler, never blocking. */ readonly toolExecutionObserver?: ((toolName: string, args: Record, success: boolean) => void) | undefined; readonly sessionOrchestration: import('../sessions/orchestration/index.js').CrossSessionTaskRegistry; readonly archetypeLoader?: import('./archetypes.js').ArchetypeLoader | undefined; readonly configManager?: ConfigManager | undefined; readonly providerRegistry?: ProviderRegistry | undefined; readonly providerOptimizer?: import('../providers/optimizer.js').ProviderOptimizer | undefined; readonly toolLLM?: ToolLLM | undefined; readonly serviceRegistry?: import('../config/service-registry.js').ServiceRegistry | undefined; readonly secretsManager?: Pick | null | undefined; readonly featureFlags?: Pick | null | undefined; readonly overflowHandler?: import('../tools/shared/overflow.js').OverflowHandler | undefined; readonly sandboxSessionRegistry: import('../runtime/sandbox/session-registry.js').SandboxSessionRegistry; readonly workflowServices: ReturnType; /** * Permission gate applied to this orchestrator's background/subagent tool * calls (see AgentOrchestratorRunContext.permissionManager). Optional, when * omitted, background runs are ungated exactly as before background * permission enforcement existed. */ readonly permissionManager?: Pick | undefined; /** * Settable holder for the context_accounting tool's session source. Threaded * through so the tool is registered on the shared roster; the interactive * session binds its Orchestrator-backed source after construction. */ readonly contextAccountingHolder?: import('../tools/context-accounting/index.js').ContextAccountingHolder | undefined; /** * Broker a per-command exec-sandbox host-access escalation through the * approval broker before the command runs. Threaded to registerAllTools so * the exec tool's sandbox raises named escalation asks. Omitted → escalations * are not asked (today's behavior). */ readonly sandboxEscalationHandler?: ((input: { readonly command: string; readonly escalations: readonly string[]; readonly boundary: string; readonly policyReasons: readonly string[]; readonly workingDirectory?: string | undefined; }) => Promise) | undefined; /** * Broker the one-tap "allow localhost fetches for this project" ask through * the approval broker. Threaded to registerAllTools so the fetch tool can * ask once and persist the per-project approval. Omitted → unapproved * localhost fetches are refused with an honest reason. */ readonly localhostFetchApproval?: ((input: { url: string; host: string; }) => Promise) | undefined; /** Reports each contained (sandboxed) command run for the announce-once containment receipt. */ readonly onSandboxedRun?: (() => void) | undefined; /** * Broker an exec PTY terminal-prompt answer through the approval broker * while the command keeps running. Threaded to registerAllTools so the exec * tool can answer prompts (host-key confirmations, credential asks) instead * of hanging to timeout. Omitted → the PTY path is not engaged. */ readonly execPromptAnswerHandler?: ((ask: import('../tools/exec/interactive.js').ExecPromptAsk) => Promise) | undefined; }; /** * AgentOrchestrator, runs AgentRecord tasks in-process. * * Each agent gets its own scoped ToolRegistry containing only the tools * listed in record.tools. The execution loop itself now lives in * `orchestrator-runner.ts`; this class owns shared registry/state wiring. */ export declare class AgentOrchestrator { /** * Keyed by working directory. A ToolRegistry is permanently bound to one * cwd at construction (every tool factory closes over it, see * tools/index.ts registerAllTools), so a distinct cwd genuinely needs its * own registry, not a mutable field. The default cwd * (`this.toolDeps.workingDirectory`) is cached under its own key exactly * like the single `fullRegistry` field this replaces, same lazy-build, * same channel-version invalidation, same object identity once built. */ private fullRegistries; /** * The ProjectIndex instances this orchestrator OWNS, keyed by the same cwd. * * A non-default cwd is given no index to share, so `registerAllTools` builds * one for it. Every reference to that index then lives inside the tool * closures of a registry we are about to drop, and it holds a debounced flush * timer, so nothing could flush or release it and it went out with the * garbage collector at best. The shared index for the DEFAULT cwd is never * in here: that one belongs to the composition root, and disposing a * borrowed object is how a live session loses its index. */ private ownedProjectIndexes; private fullRegistryChannelVersion; private toolDeps; private featureFlagManager; private runtimeBus; private conversationSink; private cancellationSource; private readonly channelRegistry; private readonly messageBus; constructor(config?: { channelRegistry?: ChannelPluginRegistry | null | undefined; messageBus: import('./message-bus.js').AgentMessageBus; }); setRuntimeBus(runtimeBus: RuntimeEventBus | null): void; /** Set the FeatureFlagManager for context-window awareness gating. */ setFeatureFlagManager(manager: FeatureFlagManager): void; /** * Wire the conversation-snapshot bridge (Part C6; see * AgentConversationSink). Pass null to detach, createRunContext() then * omits the register/release callbacks entirely and orchestrator-runner's * `?.()` calls become no-ops. */ setConversationSink(sink: AgentConversationSink | null): void; /** * Wire the cancellation bridge (see AgentCancellationSource). Pass * null to detach, createRunContext() then omits getCancellationSignal * entirely and orchestrator-runner's `?.()` call becomes a no-op, so every * tool call runs with `opts` undefined exactly as before this change. */ setCancellationSource(source: AgentCancellationSource | null): void; private emitterContext; /** * `audience` is required rather than defaulted so a new caller has to answer * "who is this for" at the call site. See agents/progress-audience.ts: an * unanswered one used to mean "everyone", and the tool trace ended up on the * owner's phone. */ private emitAgentProgress; private emitOrchestrationProgress; private emitAgentStarted; private emitAgentCancelledEvent; private emitOrchestrationCancelled; private emitAgentFailedEvent; private emitOrchestrationFailed; private emitAgentCompletedEvent; private emitOrchestrationCompleted; private emitStreamDelta; /** * Inject shared file-cache and project-index so agent tools share state with main session. * Call once during application startup, before any agents are spawned. */ setDependencies(toolDeps: AgentOrchestratorToolDeps): void; /** * Release everything this orchestrator started that outlives a turn: today * that is the ProjectIndex it builds for each non-default working directory, * each holding a debounced 5s flush timer. Called by the runtime graph's * disposal scope. Idempotent. */ dispose(): void; /** * Cancel each owned index's pending flush and write out what it holds. * * Fire-and-forget on purpose: the disposal scope is synchronous, and one * index whose final write fails must not strand the owners queued behind it. * The timer, the part that leaks, is cancelled synchronously inside * `ProjectIndex.dispose()` before the flush it awaits, so the leak is closed * whether or not the write lands. */ private releaseOwnedProjectIndexes; /** * Returns the fully-populated ToolRegistry for this orchestrator's DEFAULT * working directory. Used by companion chat to execute tool calls emitted * by the LLM, companion chat has no per-call cwd override, so this always * resolves to `this.toolDeps.workingDirectory`. Delegates to the * lazy-initialized internal registry cache. */ getToolRegistry(): ToolRegistry; /** * Lazily build and cache the full ToolRegistry for `workingDirectory` * (default: `this.toolDeps.workingDirectory`, unchanged from before this * cache became keyed). A non-default cwd, a spawned agent's dedicated * worktree (AgentRecord.workingDirectory, see AgentInput.workingDirectory) *, gets its OWN fresh fileCache/projectIndex rather than reusing the * shared session's: those are scoped to the default cwd and would * otherwise silently index/search the wrong directory. */ private getFullRegistry; /** * Build a ToolRegistry containing only the tools whose names appear in * the allowedNames list. Filters the provided full registry into a fresh * scoped registry. */ private buildScopedRegistry; private resolveProviderForRecord; private resolveOptimizedProviderRoute; private buildOptimizerRequestProfile; private resolveProviderRouting; private normalizeRequestedModelId; private resolveChatModelId; private resolveFallbackModelRoutes; /** * @param workingDirectory Per-call cwd override (AgentRecord.workingDirectory). * Absent ⇒ `this.toolDeps.workingDirectory`, byte-identical to every run * context built before this parameter existed. */ private createRunContext; /** * Run an agent task described by the given record. Honors * `record.workingDirectory` when set (see AgentInput.workingDirectory), * every tool this run's registry exposes is bound to that cwd instead of * the orchestrator's default. */ runAgent(record: AgentRecord): Promise; } //# sourceMappingURL=orchestrator.d.ts.map