/** * Subagent execution. * * Runs each subagent on its home thread (a pooled worker when worker mode is on, see * `../thread/services/executor`; else the calling thread) and forwards AgentEvents for * progress tracking. */ import type { AgentTelemetryConfig } from "@oh-my-pi/pi-agent-core"; import type { ServiceTierByFamily } from "@oh-my-pi/pi-ai"; import { type AsyncJobManagerApi } from "../async/index.js"; import type { Rule } from "../capability/rule.js"; import type { EffectiveExtensionRoots } from "../capability/types.js"; import { ModelRegistry } from "../config/model-registry.js"; import type { PromptTemplate } from "../config/prompt-templates.js"; import { type ServiceTierInheritSettingValue } from "../config/service-tier.js"; import type { CompactionThresholdPair } from "../config/compaction-threshold.js"; import { type OAuthAccountPools } from "../config/account-pools.js"; import { Settings } from "../config/settings.js"; import type { ToolPathWithSource } from "../extensibility/custom-tools/index.js"; import type { CustomTool } from "../extensibility/custom-tools/types.js"; import type { PreparedExtension } from "../extensibility/extensions/types.js"; import { type Skill } from "../extensibility/skills.js"; import type { HindsightSessionStateApi } from "../hindsight/state.js"; import type { LocalProtocolOptions } from "../internal-urls/index.js"; import type { MCPManagerApi, MCPToolScope } from "../mcp/manager.js"; import type { MnemopiSessionStateApi } from "../mnemopi/state.js"; import { type AgentReviver } from "../registry/agent-lifecycle.js"; import { type AgentRegistryApi } from "../registry/agent-registry.js"; import { type CreateAgentSessionOptions } from "../sdk.js"; import { type AgentSession } from "../session/agent-session.js"; import { type ArtifactManagerApi } from "../session/artifacts.js"; import type { AuthStorage } from "../session/auth-storage.js"; import { type CostGateApi } from "../session/cost-gate.js"; import { type ConfiguredThinkingLevel, type TaskEffort } from "@oh-my-pi/pi-tui/thinking"; import type { ContextFileEntry } from "../tools/index.js"; import { type EventBus } from "../utils/event-bus.js"; import type { WorkspaceTree } from "../workspace-tree.js"; import type { WorkPoolYieldItem } from "./workpool-yield.js"; import { type AgentDefinition } from "./types.js"; import type { PreparedSeanceSession } from "./seance.js"; import { type AgentProgress, type SingleResult, type StructuredSubagentOutput, type StructuredSubagentSchemaMode, type StructuredSubagentSchemaSource, type YieldItem } from "@oh-my-pi/pi-tui/tools/task"; import { type PerCallModelGrants } from "./model-approval.js"; export type { YieldItem } from "@oh-my-pi/pi-tui/tools/task"; /** * Soft per-agent request budgets (assistant requests per run). Crossing the * budget injects a wrap-up steering notice (`task.softRequestBudgetNotice`, * on by default). At 1.5x the budget the free-running turn is stopped and the * agent is driven to one forced final `yield` so partial findings come back * as a real report; only if it still refuses to yield within * {@link BUDGET_STOP_GRACE_REQUESTS} more requests is the run hard-aborted. * Entries are ceilings, not fixed values: the `default` key applies to agents * without an explicit entry, and the `task.softRequestBudget` setting can only * lower an agent's budget, never raise it above its bundled entry (0 disables * the guard entirely). An agent's `task.agentSoftRequestBudget` entry replaces * both. */ export declare const SOFT_REQUEST_BUDGET: Record; /** * Resolves the effective soft request budget for an agent. Its exact-name * `task.agentSoftRequestBudget` entry wins as given (0 disables its guard). * Otherwise the configured `task.softRequestBudget` and the agent's bundled * entry are both upper bounds, so the tighter one wins; a configured budget of * 0 disables the guard regardless of the bundled entry. */ export declare function resolveSoftRequestBudget(agentName: string, configuredBudget: number, agentBudgets?: Readonly>): number; /** `agentName`'s soft request budget and notice switch from `settings`: every run, wake, revival and workpool turn. */ export declare function softRequestBudgetFor(agentName: string, settings: Settings): { softRequestBudget: number; softRequestBudgetNotice: boolean; }; /** Extra requests allowed after a budget stop for the forced yield to land before the run is hard-aborted. */ export declare const BUDGET_STOP_GRACE_REQUESTS = 5; /** Steering notice injected when a subagent crosses its soft request budget. */ export declare function buildBudgetNotice(requests: number, budget: number): string; /** Session-scoped role owning subagent `id`'s retry fallback chain; cold revival reinstalls it under this name. */ export declare function subagentRetryFallbackRole(id: string): string; export interface IrcPeerRosterRow { id: string; displayName: string; kind: string; status: string; activity?: string; } export interface IrcPeerRosterData { /** Live (running+idle) peer rows, bounded at DEFAULT_PEER_ROSTER_LIMIT. */ peers: IrcPeerRosterRow[]; /** Current-root parked refs, counted but never named. */ parkedCount: number; /** Live rows dropped by the bound; the prompt reports them truthfully. */ omittedCount: number; } export declare function collectIrcPeerRoster(registry: AgentRegistryApi, selfId: string, rootSessionFile?: string): IrcPeerRosterData; /** Options for subagent execution */ export interface ExecutorOptions { cwd: string; /** Cost gate of the parent session tree; the subagent's requests count toward it. */ costGate?: CostGateApi; /** Additional workspace directories to seed on the subagent session (multi-root). */ additionalDirectories?: string[]; /** Exact provider credential resolver inherited from the parent session. */ getApiKey?: CreateAgentSessionOptions["getApiKey"]; /** Parent session's manager; the child and its revived turns use this exact delivery scope. */ asyncJobManager?: AsyncJobManagerApi; /** Parent session whose stored credential affinities seed the child session. */ credentialSourceSessionId?: string; worktree?: string; agent: AgentDefinition; task: string; assignment?: string; preparedSession?: PreparedSeanceSession; /** Shared background from the task call (`task.batch`), rendered into the subagent's system prompt. */ context?: string; /** * The session's active overall plan, handed off so subagents spawned during * plan execution share the same plan context as the main agent. Omitted when * the session did not start with a plan (or while plan mode is still active). */ planReference?: { path: string; content: string; }; /** Pre-set UI label (e.g. eval bridge label). When absent, a tiny-model label is generated from the assignment. */ description?: string; index: number; id: string; parentToolCallId?: string; /** * Spawn runs as a detached background job (parent turn not blocked on it). * Rides the subagent lifecycle/progress payloads so HUD-style surfaces can * skip spawns the transcript already renders inline. See * {@link SubagentLifecyclePayload.detached}. */ detached?: boolean; modelOverride?: string | string[]; /** Explicit pre-expansion model role alias selected for this run. */ modelRole?: string; /** Extension routing note for the chosen model; surfaced as `resolvedModelRoute`. */ modelRoute?: 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; /** Set for a per-call `model`; every model the child sends to must stay approved by these grants. */ perCallModelGrants?: PerCallModelGrants; thinkingLevel?: ConfiguredThinkingLevel; /** Caller-requested coarse effort (`lo`/`med`/`hi`); maps onto the resolved model's supported thinking range and wins over {@link thinkingLevel}. */ effort?: TaskEffort; /** Caller's description of how open-ended the work is; rides the initial prompt into the child's `auto` thinking classifier. */ solutionSpace?: string; /** * `false` = the child has no `yield` tool and its final assistant message is * the result (`task.structured` off); callers then supply no {@link outputSchema}. * Default `true`. */ structured?: boolean; /** Schema used to validate the final structured completion. */ outputSchema?: unknown; /** Enforcement policy for {@link outputSchema}; defaults to legacy permissive behavior. */ outputSchemaMode?: StructuredSubagentSchemaMode; /** Origin of the selected schema, preserved in {@link SingleResult.structuredOutput}. */ outputSchemaSource?: StructuredSubagentSchemaSource; /** * Caller supplied a schema that supersedes the agent's native output prompt. * Eval `agent(..., schema=...)` sets this so built-in agents ignore stale yield labels. */ outputSchemaOverridesAgent?: boolean; /** Parent task recursion depth (0 = top-level, 1 = first child, etc.) */ taskDepth?: number; /** * Override the `task.maxRuntimeMs` wall-clock cap for this run. When provided * it wins over the settings value; `0` disables the per-subagent wall-clock * limit entirely. Used by the eval `agent()` bridge, whose parent cell * watchdog is already suspended for the call's duration. */ maxRuntimeMs?: number; /** Include IRC only when the invocation policy permits collaboration. */ enableIrc?: boolean; enableLsp?: boolean; /** * Enable MCP capabilities for this child. `false` suppresses both inherited * MCP proxy tools and session MCP discovery; it never consults the * process-global MCP manager. Defaults to `true`. */ enableMCP?: boolean; /** Kernel-defined tools explicitly exposed by the parent eval session. */ customTools?: CustomTool[]; /** Workpool items accepted by the child yield tool during this turn. */ workPoolYieldItems?: WorkPoolYieldItem[]; /** * Limit the child to its explicit host tool names and the required yield * tool, suppressing discovered and always-included capabilities. */ restrictToolNames?: boolean; signal?: AbortSignal; onProgress?: (progress: AgentProgress) => void; /** Receives each tool call the subagent finishes, with its result text; feeds the task job's widget. */ onToolResult?: (result: SubagentToolResult) => void; /** * Epochs (ms, `Date.now()`) bracketing the concurrency-semaphore wait: * `invokedAt` is stamped at the spawn boundary before `acquire()`, * `acquiredAt` immediately after. {@link runSubprocess} reports true queue * wait (`acquiredAt - invokedAt`) and pre-run setup (`startTime - acquiredAt`) * separately in the launch-timing debug log. Undefined for callers that * bypass the semaphore path. */ invokedAt?: number; acquiredAt?: number; sessionFile?: string | null; persistArtifacts?: boolean; artifactsDir?: string; eventBus?: EventBus; subagentEventBus?: EventBus; contextFiles?: ContextFileEntry[]; noContextFiles?: boolean; skills?: Skill[]; promptTemplates?: PromptTemplate[]; workspaceTree?: WorkspaceTree; /** Parent-discovered rules, forwarded to skip rule discovery in the subagent. */ rules?: Rule[]; /** * Parent session's live extension-root policy. Forwarded separately from * `preloadedExtensionPaths`, which only controls extension module loading. */ extensionRoots?: () => EffectiveExtensionRoots; /** * Parent's discovered extension source paths. Forwarded to skip the * extension FS scan in the subagent; the subagent then re-binds each * extension against its own `ExtensionAPI` (cwd, eventBus, runtime). */ preloadedExtensionPaths?: string[]; /** Parent-imported extension factories rebound to the child runtime. */ preloadedPreparedExtensions?: readonly PreparedExtension[]; /** * Parent's discovered custom-tool source paths. Forwarded to skip the * `.omp/tools/` FS scan in the subagent; the subagent then re-binds each * tool against its own `CustomToolAPI` (cwd, exec, pushPendingAction, UI). */ preloadedCustomToolPaths?: ToolPathWithSource[]; mcpManager?: MCPManagerApi; /** The spawning session's view of {@link mcpManager}; the child's view starts from it. */ mcpToolScope?: MCPToolScope; /** User-authorized model agents available to this child and its descendants. */ inheritedSessionAgents?: CreateAgentSessionOptions["inheritedSessionAgents"]; authStorage?: AuthStorage; modelRegistry?: ModelRegistry; settings?: Settings; /** * Parent session's live per-family service tiers, the source of truth for a * subagent whose `tier.subagent` is `"inherit"`. `null` = the parent * explicitly has no tier (e.g. `/fast off`); omitted = no live session, so * inherit falls back to the subagent's configured `tier.*` settings. */ parentServiceTier?: ServiceTierByFamily | null; /** * Exact-name `task.agentServiceTierOverrides` entry that task/eval dispatch * resolved for this agent, applied after model resolution. Spawns that keep * `tier.subagent` (Vibe workers) omit it. */ serviceTierOverride?: ServiceTierInheritSettingValue; /** Exact-name `task.agentCompactionThresholdOverrides` pair selected by dispatch. */ compactionThresholdOverride?: CompactionThresholdPair; /** Exact-name `task.agentAccountPools` entry selected by dispatch; see `CreateAgentSessionOptions.oauthAccountPools`. */ oauthAccountPools?: OAuthAccountPools; /** 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?: ArtifactManagerApi; parentHindsightSessionState?: HindsightSessionStateApi; parentMnemopiSessionState?: MnemopiSessionStateApi; /** * 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[]; /** * Registry id of the spawning agent, recorded as this subagent's parent. * Forwarded verbatim to the SDK; the executor never derives it (the spawner * passes its own `getAgentId()`). */ parentAgentId?: string; /** Same-type siblings share a cache route without sharing conversation state. */ parentPromptCacheKey?: string; /** * Keep the finished subagent addressable in the registry for IRC/revival. * Defaults to true. Eval bridge agents are programmatic one-shot helpers and * set this false so disposal unregisters them instead of leaving idle peers. */ keepAlive?: boolean; /** Internal ownership handoff for cleanup that outlives the visible Task result. */ onCleanupDeferred?: (completion: Promise) => void; /** Releases resources retained for a kept-alive agent when its lifecycle ends. */ onRelease?: () => Promise; /** * Takes over releasing the run's IRC wake hold (see `AgentSession.holdIrcWakes`), * for a caller that must finish with the agent's workspace before a held * message wakes a turn in it. Without it the hold ends once the result is published. */ deferIrcWakeRelease?: (release: () => void) => void; /** Internal cleanup grace override for deterministic lifecycle tests. */ cleanupGraceMs?: number; } interface FinalizeSubprocessOutputArgs { rawOutput: string; exitCode: number; stderr: string; doneAborted: boolean; signalAborted: boolean; yieldItems?: YieldItem[]; outputSchema: unknown; outputSchemaMode?: StructuredSubagentSchemaMode; outputSchemaSource?: StructuredSubagentSchemaSource; lastAssistantText?: string; /** `false` = no `yield` tool: `rawOutput` is the final assistant message, returned verbatim. Default `true`. */ structured?: boolean; } interface FinalizeSubprocessOutputResult { rawOutput: string; exitCode: number; stderr: string; abortedViaYield: boolean; hasYield: boolean; structuredOutput?: StructuredSubagentOutput; } export declare const SUBAGENT_WARNING_SCHEMA_OVERRIDDEN = "SYSTEM WARNING: Subagent exhausted schema-retry budget; result was accepted despite failing the output schema."; 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_EMPTY_MESSAGE = "SYSTEM WARNING: Subagent ended without a final message."; export declare function finalizeSubprocessOutput(args: FinalizeSubprocessOutputArgs): FinalizeSubprocessOutputResult; /** * Create proxy tools that reuse the parent's MCP connections, as `scope` sees them. * * Each proxy delegates to the current source `MCPTool`/`DeferredMCPTool` rather * than rebuilding a raw `tools/call` request, so the Task/subagent path shares * the source tool's authoritative outbound boundary: harness-intent (`i`) * stripping, optional-placeholder pruning, local-URL resolution, reconnect * retry, abort handling, and result/provider metadata. The source tool is * re-resolved on every call by raw MCP server/tool metadata (not the normalized * display name), so a reconnect that swaps the instance in `getTools()` is * always honored. The source transport owns the configured MCP deadline, * including timeout=0; a second Task deadline would silently cap longer calls. * The proxy only races caller cancellation around source execution. */ export declare function createMCPProxyTools(mcpManager: MCPManagerApi, scope: MCPToolScope): CustomTool[]; /** Session surface {@link followMCPTools} drives: the child's MCP rebind plus its teardown hook. */ export type MCPToolFollowerSession = Pick; /** Subscription created by {@link followMCPTools}; bind it to the session the proxies went into. */ export interface MCPToolFollower { /** The child's view of the manager; sessions it spawns start from it. */ readonly scope: MCPToolScope; /** Mint the child's proxy tools from its own view of the manager. */ proxyTools(): CustomTool[]; /** Attach the created session; replays any change seen since subscribing, then follows later ones. */ bind(session: MCPToolFollowerSession): void; /** Drop the subscription when the session was never created. */ dispose(): void; } /** Which view of the shared manager a child session gets. */ export interface MCPToolView { /** The child session's id: a revived session reopens the view it had. */ scope: MCPToolScope; /** View a newly opened one starts from: the spawning session's (default: the owner's). */ seed?: MCPToolScope; } /** * Give a child session its own view of the parent's shared manager and keep * its MCP proxy tools in step with it. A child gets a spawn-time * {@link MCPToolFollower.proxyTools} snapshot and never owns the manager's * single-slot tool callback, so without this a `/mcp reload` — or a server * added, removed, or reconnected later — only reaches the owning session and * every live subagent keeps its stale set. Tools another session's calls make * a server add stay out of this view (see {@link MCPManagerApi.getTools}). * * Subscribe BEFORE building the child's proxies: a change landing while the * session is still being created is recorded and replayed on {@link * MCPToolFollower.bind}, so no window exists where an update is lost. Bursts * (a reload re-placing every server) coalesce into one rebind per tick. * * `reservedNames` are the child's explicitly supplied tool names (e.g. * kernel-defined `mcp__…` tools): `createAgentSession` drops same-named proxies * so those tools win, and every rebind must keep dropping them, or the first * reload would replace the child's own tool with the MCP capability. */ export declare function followMCPTools(mcpManager: MCPManagerApi, view: MCPToolView, reservedNames?: ReadonlySet): MCPToolFollower; /** * Compaction thresholds of the root (non-subagent) settings a subagent chain * started from. Per-agent `task.agentCompactionThresholdOverrides` entries * replace `compaction.threshold*` and switch off `compaction.modelThresholds` * only for the agent they name; every other descendant resolves against these * root values, not an ancestor's override. */ declare const kRootCompactionThresholds: unique symbol; /** Root compaction thresholds a subagent chain pins (see {@link kRootCompactionThresholds}). */ export interface RootCompactionThresholds extends CompactionThresholdPair { modelThresholdsEnabled: boolean; } /** Settings from {@link createSubagentSettings}, tagged with its chain's root compaction thresholds. */ interface SubagentChainSettings extends Settings { [kRootCompactionThresholds]?: RootCompactionThresholds; } /** * Settings overrides applying an exact-name compaction threshold entry to one * subagent. The agent entry outranks `compaction.modelThresholds`, including * entries added while the agent runs, so model entries are switched off for it. */ export declare function compactionThresholdSettings(threshold: CompactionThresholdPair | undefined): Readonly> | undefined; export declare function createSubagentSettings(baseSettings: SubagentChainSettings, overrides?: Readonly>, inheritedServiceTier?: ServiceTierByFamily | null): Settings; export type AbortReason = "signal" | "shutdown" | "terminate" | "timeout" | "budget"; /** A tool call a subagent finished, as {@link ExecutorOptions.onToolResult} reports it. */ export interface SubagentToolResult { tool: string; /** Intent the model attached to the call, when it carried one. */ intent?: string; /** The result's text parts, joined by newlines; empty when it had none. */ text: string; isError: boolean; } /** Inputs for {@link attachIrcWakeTurnMonitor}. */ export interface IrcWakeTurnMonitorOptions { /** Registry id of the kept-alive subagent whose undriven turns are monitored. */ id: string; index?: number; agent: AgentDefinition; description?: string; modelOverride?: string | string[]; /** Explicit pre-expansion model role alias selected for this run. */ modelRole?: string; eventBus?: EventBus; subagentEventBus?: EventBus; parentToolCallId?: string; /** Fallback session file when the registry ref carries none. */ sessionFile?: string; maxRuntimeMs?: number; /** * Whether a turn the owner's own message woke asks for completion estimates * (see {@link isCompletionProbeEnabled}); a peer-woken turn never does. */ completionProbe?: boolean; softRequestBudget?: number; softRequestBudgetNotice?: boolean; /** `false` = the session has no `yield` tool; see {@link ExecutorOptions.structured}. */ structured?: boolean; outputSchema?: unknown; outputSchemaMode?: StructuredSubagentSchemaMode; outputSchemaSource?: StructuredSubagentSchemaSource; artifactsDir?: string; } /** * Body for a wake-turn relay, distinguishing the terminal outcomes a waiter * would otherwise see as the same generic "stopped without replying" note: * a real answer (yield summary or turn text), a provider failure carrying the * attributed `[provider/model] `, a cancellation with its reason, a * finalization throw, a completed turn whose only output was an IRC message * (`alreadyMessaged`, reached from the parent-owned wake job), or a turn that * ran and produced nothing. A turn that yielded an artifact before failing is * reported via that artifact's summary rather than contradicted with a "no * output" claim; on a failed turn, an `alreadyMessaged` waker is told the * earlier message was not the answer. Every * non-answer notice carries a `history://` pointer so the peer can inspect * the transcript. Exported for a focused contract test of the yielded-failure * branch, which the observer seam cannot drive. */ export declare function buildWakeRelayBody(args: { id: string; yielded: boolean; result: SingleResult | undefined; turnText: string; error: string | undefined; aborted: boolean; abortReason: string | undefined; finalizeError: unknown; alreadyMessaged: boolean; }): string; /** * Bracket a kept-alive subagent's undriven turns — autonomous IRC wakes, * focused-session prompts and bare queued/async continuations — with a task * run monitor so RPC/collab subscribers see lifecycle/progress frames and * accepted results rewrite the artifact. Shared by the live executor reviver * and the persisted cold-revive path; the observer finishes after the session * has flushed its post-prompt settle (see {@link AgentSession.setIrcWakeTurnObserver}). * * The turn's output reaches the parent as an async job when its message woke * the turn, its mid-turn request was consumed, the turn yielded, or a user * prompt completed a message result, and the other waking peers via * {@link relayWakeTurnOutput}; the relay is registered as a pending reply on * the session up front so a `send await:true` waiter holds its "stopped * without replying" verdict until the relay has been delivered. */ export declare function attachIrcWakeTurnMonitor(session: AgentSession, options: IrcWakeTurnMonitorOptions): void; /** * Settle a subagent's registry lifecycle after a run: unregister for one-shot * helpers, idle + lifecycle adoption for kept-alive agents. An aborted run * (caller cancel, user interrupt, wall-clock timeout, soft budget) only stops * the run: a kept-alive, revivable agent stays interrogable and resumable * (IRC wake / revival) from its transcript. Terminal teardown is reserved for * explicit kills and agents nothing can revive. */ export declare function finalizeSubagentLifecycle(args: { id: string; session: AgentSession; aborted: boolean; /** Which watchdog (if any) requested the abort; `shutdown` releases instead of adopting. */ abortKind?: AbortReason; keepAlive: boolean; isolated: boolean; agentIdleTtlMs: number; reviveSession: AgentReviver | null; cleanupDeadlineAt?: number; onCleanupDeferred?: (completion: Promise) => void; onRelease?: () => Promise; }): Promise; /** Options for {@link runSubagentFollowUpTurn}. */ export interface FollowUpTurnOptions { /** Registry id of the (live or parked) subagent to continue. */ id: string; /** Agent definition the session was originally spawned with (drives progress labels + finalize). */ agent: AgentDefinition; /** The follow-up message; sent as the turn's user prompt (with {@link restore}, only the run's label). */ message: string; /** * Go on with the turn the previous process left unfinished instead of sending * `message` (`omp --restore`: {@link AgentSession.restoreInterruptedTurn}). */ restore?: boolean; index?: number; description?: string; /** Explicit pre-expansion model role alias retained from the original run. */ modelRole?: string; /** Structured-output state retained from the original invocation; see {@link ExecutorOptions.structured}. */ structured?: boolean; outputSchema?: unknown; outputSchemaMode?: StructuredSubagentSchemaMode; outputSchemaSource?: StructuredSubagentSchemaSource; signal?: AbortSignal; onProgress?: (progress: AgentProgress) => void; eventBus?: EventBus; subagentEventBus?: EventBus; parentToolCallId?: string; /** * When set, a turn that yields or completes a successful, non-empty message * result when requested by the parent (re)writes `/.md` so * `agent://` tracks the latest completion. Structured turns without a * yield and failed, empty, or cancelled message-result turns leave the * existing artifact intact. */ artifactsDir?: string; /** Wall-clock cap in ms for this turn; 0 disables. */ maxRuntimeMs?: number; /** Periodically ask for a completion estimate during this turn; see {@link isCompletionProbeEnabled}. */ completionProbe?: boolean; softRequestBudget?: number; softRequestBudgetNotice?: boolean; /** Workpool items accepted by the child yield tool during this turn. */ workPoolYieldItems?: WorkPoolYieldItem[]; } /** * Continue a previously spawned (keep-alive) subagent with one more monitored * turn: revive it if parked, send `message` as a real prompt (or, with * `restore`, go on with its interrupted turn), drive it to * `yield`, and finalize a {@link SingleResult} exactly like a first run. * * The session's full conversation history is retained (live session, or JSONL * replay through the lifecycle reviver), so the turn sees all prior context. * Unlike {@link runSubprocess}, the session is NOT torn down afterwards — it * stays adopted by the {@link AgentLifecycleManager} (idle → TTL park → * revive), and an aborted turn only aborts the in-flight turn. * * The turn runs on the session's home thread: a session homed on another thread * (a worker-homed child seen from main, or any non-local one seen from a worker) * is routed there. */ export declare function runSubagentFollowUpTurn(options: FollowUpTurnOptions): Promise; /** * {@link runSubagentFollowUpTurn} on the session's home thread, where its live session is * the local {@link AgentSession}. Entry point of follow-up turns routed into a worker. */ export declare function runFollowUpTurnOnThisThread(options: FollowUpTurnOptions): Promise; /** * Runs `before_agent_start` once on a revived subagent's rebuilt extensions. Its wake turns are * agent-initiated and skip the hook, so a tool an extension registers from it, as it did at the * parked session's first prompt, would never come back. The result is dropped: the transcript * already holds what the parked session's turns added. */ export declare function replayRevivedAgentStart(session: AgentSession): Promise; /** * Run a single agent. On the main thread with worker mode on, the pool places the whole run * on this thread or in a pooled subagent worker (the child session is homed where it runs), * by how many subagents run at once; otherwise — worker mode off, or already inside a * worker, so nested spawns stay in their worker — it runs on this thread. Worker mode is * read from `options.settings`; a call without settings runs here. */ export declare function runSubprocess(options: ExecutorOptions): Promise; /** A routed {@link runSubprocess} call as it crosses into a worker. */ export interface SubagentRunRequest { /** The caller's options, after `bridgeIntegrationOptions`. */ readonly options: ExecutorOptions; /** Root compaction thresholds tagged on `options.settings` (a symbol property, which never crosses). */ readonly rootThresholds: RootCompactionThresholds | undefined; } /** Package `options` for a worker, carrying what the settings' symbol tag holds explicitly. */ export declare function subagentRunRequest(options: ExecutorOptions): SubagentRunRequest; /** Worker entry of a routed run: re-tag the settings mirror, then run here. */ export declare function runSubagentRunRequest(request: SubagentRunRequest): Promise;