/** * In-process execution for subagents. * * Runs each subagent on the main thread and forwards AgentEvents for progress tracking. */ import type { AgentTelemetryConfig, ThinkingLevel } from "@gajae-code/agent-core"; import { type Model, type ServiceTier } from "@gajae-code/ai/core"; import { AsyncJobManager } from "../async"; import { type AutoroutingReasonCode } from "../config/autorouting-contract"; import { ModelRegistry } from "../config/model-registry"; import type { PromptTemplate } from "../config/prompt-templates"; import { Settings } from "../config/settings"; import { type Skill } from "../extensibility/skills"; import type { HindsightSessionState } from "../hindsight/state"; import type { LocalProtocolOptions } from "../internal-urls"; import { AgentRegistry } from "../registry/agent-registry"; import type { ForkContextSeed } from "../session/agent-session"; import { ArtifactManager } from "../session/artifacts"; import type { AuthStorage } from "../session/auth-storage"; import { SessionManager, type SessionMemoryMode } from "../session/session-manager"; import "../tools/yield"; import type { ContextFileEntry } from "../tools"; import type { EventBus } from "../utils/event-bus"; import type { WorkspaceTree } from "../workspace-tree"; import { type AgentDefinition, type AgentProgress, type AutoroutingPreflightFailure, type SingleResult, type TaskRoutingEvidence } from "./types"; export type { AutoroutingPreflightFailure } from "./types"; import { type ExecutorExecutionMode } from "./ultragoal-redteam-activation"; export declare function trimForkContextSeedForModel(seed: ForkContextSeed, model: Model | undefined): ForkContextSeed; /** Options for subagent execution */ export interface ExecutorOptions { cwd: string; worktree?: string; agent: AgentDefinition; task: string; assignment?: string; /** * Typed executor execution mode. When set, overrides assignment-text heuristics * for ultragoal red-team prompt injection (#2698 / #2456). */ executionMode?: ExecutorExecutionMode; context?: string; description?: string; routing?: TaskRoutingEvidence; /** Ordered, normalized autorouting candidates for the cross-phase preflight ledger. */ autoroutingCandidates?: string[]; autoroutingSkips?: Array<{ selector: string; code: AutoroutingReasonCode; }>; autoroutingPreflightErrors?: Map; autoroutingPreflight?: boolean; autoroutingAttemptId?: string; preflightProbe?: boolean; preflightDurable?: boolean; preflightFenceCallback?: () => void; index: number; id: string; modelOverride?: string | string[]; runMode?: "initial" | "resume" | "message"; resumeMessage?: string; subagentId?: string; /** * Active model selector of the parent session, used as an auth-aware fallback * if the resolved subagent model has no working credentials. See #985. */ parentActiveModelPattern?: string; /** * Whether the live parent session has an active model profile. When set, * persisted `task.agentModelOverrides` may resolve through preset-equivalent * aliases (bare profile aliases re-resolve to an equivalent provider variant). * Manual/direct parents (no active profile) keep exact resolution. */ parentActiveModelProfile?: string; parentSessionId?: string; parentCredentialSessionId?: string; thinkingLevel?: ThinkingLevel; outputSchema?: unknown; /** Parent task recursion depth (0 = top-level, 1 = first child, etc.) */ taskDepth?: number; enableLsp?: boolean; signal?: AbortSignal; onProgress?: (progress: AgentProgress) => void; sessionFile?: string | null; persistArtifacts?: boolean; artifactsDir?: string; /** Path to parent conversation context file */ contextFile?: string; /** Whether the parent runtime actually exposes IRC coordination. */ ircAvailable?: boolean; eventBus?: EventBus; contextFiles?: ContextFileEntry[]; skills?: Skill[]; promptTemplates?: PromptTemplate[]; workspaceTree?: WorkspaceTree; authStorage?: AuthStorage; modelRegistry?: ModelRegistry; settings?: Settings; /** Parent session's registry; shared by child sessions for IRC routing and roster visibility. */ agentRegistry?: AgentRegistry; /** * Parent service-tier intent captured when the child is spawned. Used when * `task.serviceTier === "inherit"` so request serialization and reporting use * the same immutable child settings snapshot. */ inheritedServiceTier?: ServiceTier; /** Override local:// protocol options so subagent shares parent's local:// root */ localProtocolOptions?: LocalProtocolOptions; /** * Parent session's ArtifactManager. Subagent adopts it so artifact IDs are * unique across the whole agent tree and all artifacts land in the parent's * artifacts directory (no per-subagent subdir). */ parentArtifactManager?: ArtifactManager; managedPersistence?: ManagedTaskPersistence; /** * The parent session's ENDPOINT-owned AsyncJobManager (resolved by the * TaskTool via forEndpoint(sessionId) ?? instance()). Model metadata and * live-handle state for THIS subagent are recorded in the SAME manager the * task job runs in — with concurrent top-level sessions the process-global * instance belongs to a different session and would surface this subagent * under the wrong session's record (review thread P1). */ asyncJobManager?: AsyncJobManager; parentHindsightSessionState?: HindsightSessionState; /** * Parent agent's OpenTelemetry configuration. When defined, the subagent's * loop is started with the same tracer/hooks but its own agent identity * stamped, so its `invoke_agent` / `chat` / `execute_tool` spans appear as * a sub-tree under the parent's active `execute_tool task` span. A * `handoff` span is emitted on dispatch to mark the parent → subagent * transition explicitly. */ parentTelemetry?: AgentTelemetryConfig; /** Skills to autoload via sendCustomMessage before the first prompt */ autoloadSkills?: Skill[]; forkContextSeed?: ForkContextSeed; /** * W6b: the parent's scope-held MCP facade, forwarded so the subagent inherits * always-on MCP tools without the removed process-global singleton. */ parentMcpManager?: import("../runtime-mcp/manager").MCPManager; } export declare class ManagedTaskPersistence { #private; constructor(artifacts: ArtifactManager, taskId: string); openSession(cwd: string, sessionMemoryMode?: SessionMemoryMode): Promise; openStagedSession(attemptId?: string): Promise; publishOutput(rawOutput: string, metadata: Uint8Array): Promise; } export declare function createManagedTaskPersistence(artifacts: ArtifactManager, taskId: string): ManagedTaskPersistence; export declare function renderSubagentUserPrompt(assignment: string, independentMode: boolean): string; export interface YieldItem { data?: unknown; status?: "success" | "aborted"; error?: string; } interface FinalizeSubprocessOutputArgs { rawOutput: string; exitCode: number; stderr: string; terminalFailure?: boolean; doneAborted: boolean; signalAborted: boolean; yieldItems?: YieldItem[]; outputSchema: unknown; } interface FinalizeSubprocessOutputResult { rawOutput: string; exitCode: number; stderr: string; abortedViaYield: boolean; hasYield: boolean; } export declare const SUBAGENT_WARNING_NULL_YIELD = "SYSTEM WARNING: Subagent called yield with null data."; export declare const SUBAGENT_WARNING_MISSING_YIELD = "SYSTEM WARNING: Subagent exited without calling yield tool after 3 reminders."; export declare const SUBAGENT_WARNING_PLACEHOLDER_YIELD = "SYSTEM WARNING: Subagent yield data contains a placeholder instead of the actual result."; export declare function finalizeSubprocessOutput(args: FinalizeSubprocessOutputArgs): FinalizeSubprocessOutputResult; export declare function createSubagentSettings(baseSettings: Settings, inheritedServiceTier?: ServiceTier): Settings; /** * Finalize routing evidence at the executor return boundary: the effective * model is the terminal provider-reported model when present, otherwise the * auth-resolved model; substitution causes are appended in order. */ export declare function finalizeRoutingEvidence(routing: TaskRoutingEvidence | undefined, state: { resolvedModelString: string | undefined; lastAssistantModelString: string | undefined; authFallbackUsed: boolean; assistantModelMismatch: boolean; }): TaskRoutingEvidence | undefined; export declare function classifyAutoroutingPreflightFailure(error: unknown, op: Extract["op"]): AutoroutingPreflightFailure; export declare function runSubprocessOnce(options: ExecutorOptions): Promise; export declare function boundedSelector(value: string): string; export declare function buildBoundedRoutingSkips(skips: ExecutorOptions["autoroutingSkips"]): Pick; /** Run routed initial tasks through the bounded probe/durable candidate ledger. */ export declare function runSubprocess(options: ExecutorOptions): Promise;