/** * SDK isolation spawner — runs child agent in-process via createAgentSession. * Spec: §4.2 — SDK Isolation */ import { SessionManager } from "@earendil-works/pi-coding-agent"; import type { AgentSession } from "@earendil-works/pi-coding-agent"; import type { Heartbeat, AgentLifecycle } from "@pi-orca/core"; import type { ResolvedAgentTemplate } from "../template.js"; /** * Respawn directive for the recover flow. * When set: open the existing child session file instead of creating a new * one, skip appendCustomEntry (instance entry already exists), and de-dupe * the originalTask before sendUserMessage. */ export interface SpawnRespawnSpec { agentId: string; sessionFile: string; skipTaskIfPresent?: boolean; } /** * Per-agent SDK record retained for the lifetime of the agent. * Spec: §4.2.1 — round-3 finding C10 */ export interface SdkAgentRecord { session: AgentSession; unsubscribe: () => void; heartbeat: Heartbeat; instanceEntryId: string; /** * "one-shot" (default) → `agent_end` writes terminal status and unregisters. * "persistent" → `agent_end` writes `status: idle` and keeps the record * registered so `sendPromptToSdkAgent` can drive the next turn. * Spec §5.13. */ lifecycle: AgentLifecycle; /** * Persistent-mode turn guard. Replaces the closure-local `completed` flag * so `sendPromptToSdkAgent` can reset it between turns. False = currently * mid-turn (running); true = current turn's `agent_end` was processed. */ turnCompleted: boolean; /** Parent session path captured at spawn so the prompt helper can write status. */ parentSessionPath: string; /** Capture worktree-cleanup config so persistent-mode stop paths can honor it. */ worktreeForceCleanupOnTerminal: boolean; /** Notify hook captured for worktree cleanup messages. */ notifyWorktree?: (message: string, type?: "info" | "warning" | "error") => void; } export declare function getSdkAgent(agentId: string): SdkAgentRecord | undefined; export declare function listSdkAgents(): ReadonlyMap; /** * Clear all SDK agent records. Called on session_before_switch/fork * since AgentSession handles cannot legally cross a session boundary. * Spec: §4.5.2 reset block (W3+W11) */ export declare function clearSdkAgents(): void; export interface SpawnSdkParams { agentId: string; resolved: ResolvedAgentTemplate; task?: string; /** * Parent session's relative path (canonical form, portable across hosts). * Used for `.orca/agents/` layout and as the cross-machine fallback when * `parentSessionFile` doesn't exist locally. Empty for SDK in-memory * sessions. Spec §2.6.1. */ parentSessionPath: string; /** * Parent session's absolute file path on the host that wrote the status. * Preferred for `SessionManager.forkFrom` when it still exists locally; * otherwise we resolve `parentSessionPath` under the local sessions root. * Omit or pass "" when the parent has no on-disk file (in-memory * SDK sessions). Spec §2.6.1. */ parentSessionFile?: string; parentSessionId: string; rootSessionPath: string; parentNotifySockPath?: string; /** Heartbeat interval in ms */ heartbeatIntervalMs: number; /** Threshold for fork-bloat warning (bytes); 0 disables. */ forkSizeWarnBytes: number; /** * Parent's session entries (for fork-bloat pre-check). * Pass `ctx.sessionManager.getEntries()` from caller. */ parentEntries: any[]; /** Hook for notifying user of fork bloat (best-effort) */ notifyWarning?: (message: string) => void; /** Optional cwd override */ cwd?: string; /** Optional Pi session directory override (for forkFrom/inMemory) */ sessionDir?: string; /** When set, open an existing session file instead of fork/fresh. */ respawn?: SpawnRespawnSpec; /** * When true, the terminal-status worktree cleanup bypasses the W9 * uncommitted-work safeguard. Driven by `agents.worktreeForceCleanupOnTerminal`. * Defaults to false (safeguard active). */ worktreeForceCleanupOnTerminal?: boolean; /** Notify hook reused for worktree cleanup messages (W9 safeguard). */ notifyWorktree?: (message: string, type?: "info" | "warning" | "error") => void; /** * Test-only override for SessionManager static methods. Production calls * the real `SessionManager.{inMemory,forkFrom,open}` directly. */ sessionManagerFactory?: { inMemory?: (cwd: string) => SessionManager; forkFrom?: (sourcePath: string, cwd: string, sessionDir?: string) => Promise; open?: (sessionFile: string, sessionDir?: string, cwdOverride?: string) => SessionManager; }; } export interface SpawnSdkResult { agentId: string; status: "running"; isolation: "sdk"; sessionPath: string; } /** * Spawn an SDK agent (fire-and-forget). * Returns immediately after the subscription is registered and the initial * task has been dispatched. Completion is handled asynchronously via the * event subscription. * * @param params - Spawn parameters * @returns Result with agentId, status, isolation, sessionPath */ export declare function spawnSdkAgent(params: SpawnSdkParams): Promise; /** * Stop an SDK agent (called by §5.1.1 stopAllAgents and /agents stop). * Aborts the session and writes terminal status with exitReason: "aborted". * * @param agentId - Agent ID to stop * @param parentSessionPath - Parent's session path (for writing terminal status) * @returns True if agent was found and stopped */ export declare function stopSdkAgent(agentId: string, parentSessionPath: string): Promise; /** * Stop all SDK agents in parallel. * Spec: §5.1.1 stopAllAgents dispatcher * * @param parentSessionPath - Parent's session path */ export declare function stopAllSdkAgents(parentSessionPath: string): Promise; /** * Drive the next prompt cycle of a persistent SDK agent. * Spec §5.13. * * Flips status idle → running, resets the per-turn completion guard, and * dispatches `task` to the live `AgentSession`. Returns `false` when the * agent isn't registered or isn't persistent. * * @param agentId - Agent id * @param parentSessionPath - Parent session path (unused; signature parity with * the RPC/tmux helpers and lets future status-flip writes route correctly) * @param task - Prompt body */ export declare function sendPromptToSdkAgent(agentId: string, parentSessionPath: string, task: string): Promise; //# sourceMappingURL=sdk.d.ts.map