/** * LLM-role verdict invocation for the copilot turn-end decision pipeline. * * This module is the LLM BRANCH of the decision pipeline (used when a * copilot rule has not already short-circuited the decision). It asks a * configured role for a { advance, replyText } verdict on whether to inject * a user message into an idle session, or hand control back to the human. * * The exchange happens on a FRESH CHILD SESSION (parentID = origin sid) — * the loop-worker precedent at src/loop/dispatch-adapter.ts:88-107. The * origin session's transcript is NEVER touched: `prompt`/`promptSync` are * only ever called on the child session id. * * Failure contract: returns null on ANY failure (unknown role, launch * failure, timeout, empty/non-text response, unparseable or type-invalid * JSON). Null means "skip this idle" — cheaper heuristic sources already * declined, and a failed LLM ask must never block the pipeline. * * No guardrail / pattern-enforcement logic lives here (user decision: the * role acts freely). No retry loops — a single attempt per idle. */ import type { ISessionClient } from "../platform/ports/session-client.ts"; /** Dependencies for the verdict invocation. */ export interface VerdictDeps { /** Platform session client (OpenCode SDK, Pi process spawn, etc.). */ client: ISessionClient; /** * Resolved subagent registry keyed by subagent id — the map built by * `buildSubagentLineage` (src/dispatch/factory.ts:78-113). The configured * `llm.role` must be a key of this map to be invocable. */ resolvedSubagents: Map; /** Working directory used when creating the fresh child session. */ directory: string; } /** Parameters for a single verdict request. */ export interface VerdictRequestOptions { /** Origin session id — used ONLY as the child's parentID, never prompted. */ sid: string; /** Configured `llm.role` id; must be a resolved subagent. */ roleId: string; /** Assembled verdict-request prompt (src/copilot/prompt.ts). */ prompt: string; /** Hard timeout in ms (`max_verdict_timeout_ms` from the copilot config). */ timeoutMs: number; } /** A successfully parsed LLM verdict. */ export interface Verdict { /** true -> inject `replyText` into the origin session; false -> hand control back. */ advance: boolean; /** User-message text to inject when `advance` is true. */ replyText: string; } /** * Ask the configured LLM role for a turn-end verdict. * * Flow: * 1. Resolve `roleId` against `resolvedSubagents` — unknown role warns * once (per role id) and returns null. * 2. Create a FRESH child session (`client.create({ directory, agent, * parentID: sid })`), then `client.promptSync(childSid, …)` with an * AbortSignal that fires after `timeoutMs`. The agent is forwarded on * promptSync because the OpenCode adapter does not carry `agent` on * create (src/platform/adapters/opencode/session.ts:271-282). * 3. Parse the verdict from the LAST text part of the response: exactly * one JSON object `{ "advance": boolean, "replyText": string }`, * possibly wrapped in a fenced block or surrounding text. * 4. Returns `{ advance, replyText }` on success; null on ANY failure * (timeout, launch failure, empty/non-text response, unparseable or * type-invalid JSON). The child session is aborted best-effort in all * cases. */ export declare function requestVerdict(deps: VerdictDeps, opts: VerdictRequestOptions): Promise; //# sourceMappingURL=llm.d.ts.map