import type { Judge } from "pi-typesafe"; import type { SubagentConfig } from "./config.js"; /** * Custom message types pi-subagents injects into the main session. Pi appends each one to the agent's context itself; * warden cannot suppress that, so the decision here is only whether the agent must be woken about it. */ export declare const NOTIFY_TYPES: readonly ["subagent-notify", "subagent-incremental-child-notify", "subagent_control_notice", "subagent_supervisor_request", "subagent-compaction-resume"]; export declare function isNotifyType(customType: string): boolean; export interface SubagentReport { /** Session entry id: the same report is triaged once, however often the branch is read. */ id: string; customType: string; /** A progress line rather than a result: never worth a wake. */ incremental: boolean; text: string; } /** The part of a session entry this module reads; the branch type is wider and not worth importing. */ export interface SubagentEntry { id?: unknown; type?: unknown; customType?: unknown; content?: unknown; } /** Reports in `entries` that warden has not seen yet, oldest first, bounded to the newest `limit`. */ export declare function newReports(entries: readonly SubagentEntry[], seen: ReadonlySet, limit?: number): SubagentReport[]; export declare function mentionsTrouble(text: string): boolean; export declare const triageQuestion: { wake: import("pi-typesafe").NoulQuestion; }; /** A bounded, redacted view of the report. Status and failure lines sit at the end, so the tail is kept. */ export declare function reportDigest(text: string): string; export declare function buildTriageRequest(report: SubagentReport, task: string | undefined): { state: { kind: string; incremental: boolean; chars: number; task: string; report: string; }; questions: { wake: import("pi-typesafe").NoulQuestion; }; }; export interface TriageOptions { config: SubagentConfig; judge?: Judge | undefined; timeoutMs: number; signal?: AbortSignal | undefined; task?: string | undefined; } export interface TriageResult { wake: boolean; /** `offline` decided in code, `jev` asked the model, `error` could not ask and stayed quiet. */ source: "offline" | "jev" | "error"; reason: string; probability?: number; } /** * Silent-append or wake. The offline layer answers the cheap cases, and only a report that names trouble reaches Jev. * A failed request stays quiet: the report is already in the agent's context, and a wake is the interruption. */ export declare function triageReport(report: SubagentReport, options: TriageOptions): Promise; /** The first non-empty line of a report, redacted and clipped: enough to point the agent at the right one. */ export declare function reportLabel(report: SubagentReport): string; /** * One steer per cooldown window, not one per child: several reports arriving while the agent is busy become one * interruption. A wake-worthy report that arrives inside the window waits for the next flush. */ export declare class WakePolicy { cooldownMs: number; private pending; private lastWakeAt; /** The window is settable because the config can change mid-session; the extension keeps one instance per session. */ constructor(cooldownMs: number); /** Queue a wake-worthy report. Returns the lines to send now, or undefined while the window holds it back. */ offer(line: string, at?: number): string[] | undefined; /** The batch to send now, and the start of a new window. Undefined when nothing is waiting. */ flush(at?: number): string[] | undefined; waiting(): number; reset(): void; } /** The wake itself: a pointer to which reports need attention, never a summary that would double the context. */ export declare function formatWake(batch: readonly string[]): string;