import type { LlmProvider, LlmUsage } from './provider-base.js'; export interface CriticInput { /** The user's original prompt for the current turn. Optional but * highly recommended — the critic needs SOMETHING to anchor "what * was the goal" against. If both prompt AND goalTitle are empty, * the critic refuses to judge (returns onTrack=true). */ prompt?: string; /** The thread's active long-task goal title + body. Stronger anchor * than per-turn prompt when present — survives across turns. */ goalTitle?: string; goalBody?: string; /** Compact transcript of the latest tool calls. Capped at the last * ~10 by the caller; the critic prompt re-caps to 300 chars per * preview anyway. */ recentToolCalls: ReadonlyArray<{ name: string; isError: boolean; preview?: string; }>; } export interface CriticVerdict { onTrack: boolean; reason: string; /** When onTrack=false, the critic's one-line suggestion for what to * do differently. May be empty if the critic couldn't think of one. */ redirect?: string; /** Provider/model used for the critic call, for audit. */ modelUsed?: string; /** Token/cost usage from the critic provider call, when reported. */ usage?: LlmUsage; } export interface CompletionCriticInput { goalTitle: string; goalBody?: string; evidence: ReadonlyArray<{ name: string; preview: string; }>; } export interface CompletionCriticVerdict { completed: boolean; reason: string; modelUsed?: string; } /** v1.2.99 (CR finding A2): three-valued knob. * - `off` / `0` / `false` → hard kill, never fire critic * - `always` / `on` / `1` / `true` → fire whenever any anchor exists * (prompt OR active goal) * - anything else (incl. unset) → fire ONLY when an active long-task * goal exists. Per-turn prompts alone don't trigger. * * This matches the cost story documented in CHANGELOG: day-to-day * single-turn chats pay nothing; the critic is reserved for the * long-horizon work signalled by an explicit /long_task goal. */ export type CriticMode = 'off' | 'always' | 'goal-only'; export declare function resolveCriticMode(): CriticMode; /** Pick the critic provider: env-named role → cheap role → null. * Returns null when no usable provider — caller treats that as * "critic disabled this turn" and skips. */ export declare function pickCriticProvider(force?: boolean): { provider: LlmProvider; role: string; } | null; /** * Run one goal-critic check. ALWAYS returns a verdict — never throws. * Provider errors / unparseable JSON / no anchor → `onTrack=true` with * a reason explaining why we couldn't judge, so the caller treats them * as "no veto" rather than a misleading break. */ export declare function runGoalCritic(input: CriticInput, opts?: { signal?: AbortSignal; timeoutMs?: number; force?: boolean; }): Promise; /** Hard completion proof review. Evidence and recap are untrusted model/tool * data; malformed output and provider failures fail closed. */ export declare function runGoalCompletionCritic(input: CompletionCriticInput, opts?: { signal?: AbortSignal; timeoutMs?: number; }): Promise; //# sourceMappingURL=goal-critic.d.ts.map