/**
 * Smart alarm evaluator — uses a fast model to decide whether a long-running
 * non-browser tool call should be aborted or allowed to continue.
 *
 * Called by the ToolCallWatchdog when a non-browser tool exceeds the alarm
 * threshold (default 30s).  The evaluator sees the tool name, its input,
 * elapsed time, and a summary of recent agent activity, then returns a
 * binary "continue" or "abort" decision.
 */
import { z } from "zod";
import { logger } from "../logger.js";
import { runSideCall } from "./model-provider.js";
const MAX_TOKENS = 256;
const AlarmDecisionSchema = z.object({
    decision: z
        .enum(["continue", "abort"])
        .describe("'continue' if the tool is likely making progress and should keep running. " +
        "'abort' if the tool appears stuck or the wait is unreasonable."),
    reason: z
        .string()
        .describe("One-sentence reasoning for the decision."),
});
const SYSTEM_PROMPT = [
    "You are a watchdog process monitoring a tool call inside an AI agent.",
    "A tool has been running for longer than expected. Your job is to decide whether the agent should keep waiting or abort the call.",
    "",
    "Guidelines by tool type:",
    "",
    "**Bash / Shell commands**:",
    "- Commands like `npm install`, `pnpm install`, `pip install`, compilation (`make`, `cargo build`, `gcc`), `git clone`, large downloads, or data processing can legitimately run for minutes or even tens of minutes.",
    "- Look at the command in the input: if it's a build/install/compile/download, lean strongly toward 'continue' even at several minutes.",
    "- Short commands like `ls`, `cat`, `echo`, `pwd` should be instant; >30s means something is wrong.",
    "- Interactive commands that wait for stdin (e.g. `read`, `python` without a script) will hang forever — abort these.",
    "",
    "**WebFetch / web requests**: reasonable up to ~60s for complex pages, but >90s usually means the target is unresponsive.",
    "",
    "**API calls (email, calendar, drive)**: usually complete in <15s; >30s likely means a network issue.",
    "",
    "**Memory / database operations**: usually instant; >30s is abnormal.",
    "",
    "**Task / subagent calls**: these run a child agent and can take minutes — lean toward 'continue' unless it has been running for an unusually long time (>10 min).",
    "",
    "General principles:",
    "- If this is alarm #1 and the tool could plausibly still be working, lean toward 'continue'.",
    "- Consider the elapsed time relative to what the operation is doing. 2 minutes for `npm install` is normal; 2 minutes for a memory lookup is not.",
    "- When in doubt, 'continue' is safer than 'abort' — the agent can always retry an aborted call, but aborting a nearly-complete long operation wastes all progress.",
    "",
    "Respond with your decision and a brief reason.",
].join("\n");
/**
 * Evaluate whether a long-running tool call should be aborted.
 *
 * Returns `null` on failure (caller should treat as "continue" to be safe).
 */
export async function evaluateToolAlarm(context, config) {
    const userMessage = [
        `## Stalled Tool Call`,
        `- **Tool**: ${context.toolName}`,
        `- **Input**: ${context.toolInput.length > 500 ? context.toolInput.substring(0, 500) + "…" : context.toolInput}`,
        `- **Elapsed**: ${context.elapsedSeconds}s`,
        `- **Alarm**: #${context.alarmCount} (checked every 30s; absolute ceiling: ${Math.round(context.absoluteTimeoutSeconds / 60)} min)`,
        context.alarmCount > 1 ? `- **Note**: The evaluator has already decided to continue ${context.alarmCount - 1} time(s). Consider whether the operation is truly making progress.` : "",
        "",
        "## Recent Agent Activity",
        context.activitySummary || "(no activity recorded)",
        "",
        "Should the agent keep waiting or abort this tool call?",
    ].join("\n");
    try {
        return await runSideCall(config, {
            systemPrompt: SYSTEM_PROMPT,
            userMessage,
            schema: AlarmDecisionSchema,
            schemaName: "tool_alarm_decision",
            maxTokens: MAX_TOKENS,
            useCase: "tool_alarm",
        });
    }
    catch (err) {
        logger.warn(`Tool alarm evaluator failed: ${err instanceof Error ? err.message : String(err)}`);
        return null;
    }
}
//# sourceMappingURL=tool-alarm-evaluator.js.map