import type { MonitorState } from "@mono-agent/agent-contracts"; import type { PreparedSandboxCommand } from "./sandbox.js"; /** * One coalesced batch of monitor stdout lines, or one terminal transition, * handed from the kernel-owned watcher process to the host service. */ export interface MonitorProcessHandle { readonly pid: number | null; readonly pgid: number | null; readonly startedAt: string; /** Resolves once the watched process group has been waited on. */ readonly completion: Promise; /** Release the gated target only after PID/PGID/incarnation ownership is durable. */ readonly release: () => Promise; /** Send SIGTERM to the owned group and escalate to SIGKILL after one second. */ readonly cancel: () => void; } /** * Exactly what `startPreparedProcess` resolves with. It is deliberately the * runner's own shape rather than a monitor-specific one: a hand-written subset * silently diverges the first time the runner changes, and the host then reads * a field the kernel never sets. */ export interface MonitorProcessResult { readonly code: number | null; readonly signal: NodeJS.Signals | null; readonly aborted: boolean; readonly timedOut: boolean; readonly spawnError: Error | null; /** False only when bounded termination settled without proof the owned group exited. */ readonly groupExitConfirmed?: boolean; readonly durationMs: number; /** * Bounded raw stderr the runner buffered. Under `outputMode: "stream"` stdout * is never stored, so this is the only retained output. It is raw: the host * redacts and bounds it before it reaches any prompt or projection. */ readonly stderr?: string; } export interface MonitorLaunchOptions { readonly timeoutMs?: number; /** Invoked for each raw stdout chunk; the host owns line splitting and bounds. */ readonly onStdout?: (chunk: Buffer) => void; readonly onStderr?: (chunk: Buffer) => void; } export interface MonitorStartRequest { /** * Exact sandbox-prepared command, prepared through the identical seam Bash * uses. The controller takes ownership before start() can settle and must call * cleanup after the owned process group exits on every path. */ readonly prepared: PreparedSandboxCommand; /** Kernel-produced summary that contains no argument/command values. */ readonly summary: string; /** Model-authored purpose; the host bounds and redacts it before retaining it. */ readonly description: string; /** Explicit per-call runtime budget in milliseconds. Ignored when persistent. */ readonly timeoutMs?: number; /** Run until MonitorStop, agent restart, or the host persistent ceiling. */ readonly persistent?: boolean; readonly wakeOn?: "batch" | "exit"; readonly dedupe?: "none" | "batch"; readonly minWakeIntervalMs?: number; /** One-shot launcher bound to the exact prepared command and POSIX group wait. */ readonly launch: (options?: MonitorLaunchOptions) => MonitorProcessHandle; } export interface MonitorStartResult { /** Effective policy after the host clamps the requested interval. */ readonly wakeOn: "batch" | "exit"; readonly dedupe: "none" | "batch"; readonly minWakeIntervalMs: number; readonly monitorId: string; readonly state: Extract; readonly startedAt: string; /** * Runtime budget the host actually granted after its own ceiling was applied. * `0` means the monitor is persistent and has no timed deadline. */ readonly maxRuntimeMs: number; readonly persistent: boolean; } export interface MonitorStopResult { readonly monitorId: string; readonly state: MonitorState; /** False when the monitor was already terminal; stop stays idempotent. */ readonly stopped: boolean; } /** Host budgets a monitor is bounded by, independent of any one request. */ export interface MonitorControllerLimits { /** Ceiling for a timed monitor. */ readonly maxRuntimeMs: number; /** Ceiling for a persistent monitor. */ readonly persistentMaxRuntimeMs: number; readonly maxActivePerConversation: number; readonly maxWakeIntervalMs?: number; } /** Request-scoped host controller injected only into the Pi-native Monitor tools. */ export interface MonitorsController { /** The host's standing ceilings, published so the tool schema can state them. */ readonly limits?: MonitorControllerLimits; start(request: MonitorStartRequest): Promise; stop(monitorId: string): Promise; } /** Bridge the typed host controller to agent-runtime's dependency-free seam. */ export declare function bridgeMonitorsController(controller: MonitorsController): MonitorsController; //# sourceMappingURL=monitors.d.ts.map