/**
 * In-process execution for subagents.
 *
 * Runs each subagent on the main thread and forwards AgentEvents for progress tracking.
 */
import type { AgentTelemetryConfig, ThinkingLevel } from "@oh-my-pi/pi-agent-core";
import type { ServiceTierByFamily } from "@oh-my-pi/pi-ai";
import type { Rule } from "../capability/rule.js";
import { ModelRegistry } from "../config/model-registry.js";
import type { PromptTemplate } from "../config/prompt-templates.js";
import { Settings } from "../config/settings.js";
import { type SettingPath } from "../config/settings-schema.js";
import type { ToolPathWithSource } from "../extensibility/custom-tools/index.js";
import type { CustomTool } from "../extensibility/custom-tools/types.js";
import { type Skill } from "../extensibility/skills.js";
import type { HindsightSessionState } from "../hindsight/state.js";
import type { LocalProtocolOptions } from "../internal-urls/index.js";
import type { MCPManager } from "../mcp/manager.js";
import type { MnemopiSessionState } from "../mnemopi/state.js";
import type { AgentSession } from "../session/agent-session.js";
import type { ArtifactManager } from "../session/artifacts.js";
import type { AuthStorage } from "../session/auth-storage.js";
import type { ContextFileEntry } from "../tools/index.js";
import type { EventBus } from "../utils/event-bus.js";
import type { WorkspaceTree } from "../workspace-tree.js";
import { type AgentDefinition, type AgentProgress, type ReviewFinding, type SingleResult, type YieldItem } from "./types.js";
export type { YieldItem } from "./types.js";
/**
 * Soft per-agent request budgets (assistant requests per run). When a subagent
 * crosses its budget it can receive an optional steering notice asking it to
 * wrap up; at 1.5x the budget the run is aborted gracefully so partial output is
 * salvaged. The `default` key applies to agents without an explicit entry and
 * can be overridden via the `task.softRequestBudget` setting (0 disables the
 * guard). The notice is off by default and controlled separately by
 * `task.softRequestBudgetNotice`.
 */
export declare const SOFT_REQUEST_BUDGET: Record<string, number>;
/** Optional steering notice injected when a subagent crosses its soft request budget. */
export declare function buildBudgetNotice(requests: number): string;
/** Options for subagent execution */
export interface ExecutorOptions {
    cwd: string;
    worktree?: string;
    agent: AgentDefinition;
    task: string;
    assignment?: string;
    /** 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;
    };
    description?: string;
    /** Specialist role/expertise for this spawn; drives the system-prompt preamble, display name, and telemetry identity. */
    role?: 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[];
    /**
     * 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;
    thinkingLevel?: ThinkingLevel;
    outputSchema?: unknown;
    /**
     * 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;
    enableLsp?: boolean;
    signal?: AbortSignal;
    onProgress?: (progress: AgentProgress) => 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;
    contextFiles?: ContextFileEntry[];
    skills?: Skill[];
    promptTemplates?: PromptTemplate[];
    workspaceTree?: WorkspaceTree;
    /** Parent-discovered rules, forwarded to skip rule discovery in the subagent. */
    rules?: Rule[];
    /**
     * 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'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?: MCPManager;
    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;
    /** 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;
    parentHindsightSessionState?: HindsightSessionState;
    parentMnemopiSessionState?: MnemopiSessionState;
    /** Parent agent's eval executor session id. Subagents reuse it so eval state is shared. */
    parentEvalSessionId?: string;
    /**
     * 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;
    /**
     * 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;
}
interface FinalizeSubprocessOutputArgs {
    rawOutput: string;
    exitCode: number;
    stderr: string;
    doneAborted: boolean;
    signalAborted: boolean;
    yieldItems?: YieldItem[];
    reportFindings?: ReviewFinding[];
    outputSchema: unknown;
    lastAssistantText?: string;
}
interface FinalizeSubprocessOutputResult {
    rawOutput: string;
    exitCode: number;
    stderr: string;
    abortedViaYield: boolean;
    hasYield: boolean;
}
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 function finalizeSubprocessOutput(args: FinalizeSubprocessOutputArgs): FinalizeSubprocessOutputResult;
/**
 * Create proxy tools that reuse the parent's MCP connections.
 */
export declare function createMCPProxyTools(mcpManager: MCPManager): CustomTool[];
export declare function createSubagentSettings(baseSettings: Settings, overrides?: Partial<Record<SettingPath, unknown>>, inheritedServiceTier?: ServiceTierByFamily | null): Settings;
export declare function finalizeSubagentLifecycle(args: {
    id: string;
    session: AgentSession;
    aborted: boolean;
    keepAlive: boolean;
    isolated: boolean;
    agentIdleTtlMs: number;
    reviveSession: (() => Promise<AgentSession>) | null;
}): Promise<void>;
/**
 * Run a single agent in-process.
 */
export declare function runSubprocess(options: ExecutorOptions): Promise<SingleResult>;
