/**
 * ReplyWatchdog — fires the fast responder if the primary agent hasn't
 * called notify_user within a timeout window.
 *
 * Extracted from loop.ts to isolate the watchdog timer lifecycle.
 */
import { isFastResponseEligible } from "./fast-response-eligibility.js";
import { logger } from "../logger.js";
const REPLY_WATCHDOG_MS = 30_000;
export class ReplyWatchdog {
    timer = null;
    interruptHandler;
    getAgentState;
    constructor(interruptHandler, getAgentState) {
        this.interruptHandler = interruptHandler;
        this.getAgentState = getAgentState;
    }
    /**
     * Arm the watchdog for the current wake cycle. If the agent hasn't
     * replied within REPLY_WATCHDOG_MS, fires the fast responder.
     *
     * Only arms when:
     *  - trigger is "message"
     *  - at least one message is fast-response-eligible (i.e. has a real
     *    reply-capable channel adapter — see isFastResponseEligible).
     *    Otherwise fireWatchdog would just no-op on the same predicate.
     */
    arm(trigger, messages) {
        if (trigger !== "message")
            return;
        if (!messages.some(isFastResponseEligible))
            return;
        this.timer = setTimeout(() => {
            this.timer = null;
            if (this.getAgentState().hasRepliedInCycle)
                return;
            logger.system(`Reply watchdog fired after ${REPLY_WATCHDOG_MS / 1000}s — running fast responder`);
            void this.interruptHandler.fireWatchdog(messages).catch((err) => {
                logger.warn(`Watchdog fast responder failed: ${err instanceof Error ? err.message : String(err)}`);
            });
        }, REPLY_WATCHDOG_MS);
    }
    /** Cancel the watchdog timer if still pending. */
    cancel() {
        if (this.timer !== null) {
            clearTimeout(this.timer);
            this.timer = null;
        }
    }
}
//# sourceMappingURL=reply-watchdog.js.map