// Ported from the design of Cache Tax (MIT, Copyright (c) 2026 Karan Bansal, // https://github.com/karanb192/claude-code-mods, hooks/register.ts): bots run // Claude Code with project-only settings, so a person's own Claude Code // plugins never reach them. // // Only subscription (Pro/Max) logins are pinged: their prompt cache lives an hour. A metered API key's main cache lives // five minutes by default, so pinging it costs more than the re-write it avoids. Nothing is persisted: after a restart the // CLI relaunches with a fresh system prompt that misses the cache anyway. import type { CacheWarmPingResult } from "./contracts.ts"; import type { CacheKeepWarmStatus } from "../shared/wire.ts"; export const CACHE_TTL_MS = 60 * 60_000; export const PING_AFTER_MS = 50 * 60_000; export const BUSY_RETRY_MS = 60_000; export const MIN_CONTEXT_TOKENS = 50_000; export const DEFAULT_WINDOW_MINUTES = 180; export const MAX_WINDOW_MINUTES = 24 * 60; /** Cache Tax's stop rule: a warm ping writes only its own few tokens. */ export const MAX_WRITE_RATIO = 0.1; export interface KeepWarmTarget { threadId: string; botId: string; instanceId: string; } export type KeepWarmPingResult = CacheWarmPingResult; export type KeepWarmStatus = CacheKeepWarmStatus; export interface KeepWarmDeps { now: () => number; after: (ms: number, fn: () => void) => { cancel: () => void }; windowMs: (botId: string) => number | null; ineligible: (target: KeepWarmTarget) => string | null; busy: (target: KeepWarmTarget) => boolean; overBudget: () => boolean; ping: (target: KeepWarmTarget, signal: AbortSignal) => Promise; hold: (target: KeepWarmTarget, until: number | null) => void; book: (target: KeepWarmTarget, result: Extract) => void; changed: (target: KeepWarmTarget) => void; } interface Window { target: KeepWarmTarget; deadline: number; lastRequestAt: number; pending: { cancel: () => void } | null; nextPingAt: number | null; inflight: AbortController | null; paused: boolean; } export function fmtTokens(n: number): string { return n >= 1e6 ? `${(n / 1e6).toFixed(1)}M` : n >= 1000 ? `${Math.round(n / 1000)}k` : String(n); } /** A ping that read the prefix and wrote only its own message. */ export function pingWasWarm(read: number, write: number): boolean { return read > 0 && write < MAX_WRITE_RATIO * read; } export function createCacheKeepWarm(deps: KeepWarmDeps) { const windows = new Map(); const lastPing = new Map>(); const stoppedWhy = new Map(); let disposed = false; const disarm = (w: Window) => { w.pending?.cancel(); w.pending = null; w.nextPingAt = null; }; const end = (w: Window, why: string | null) => { disarm(w); w.inflight?.abort(); w.inflight = null; if (windows.get(w.target.threadId) === w) windows.delete(w.target.threadId); if (why) stoppedWhy.set(w.target.threadId, why); deps.hold(w.target, null); deps.changed(w.target); }; const arm = (w: Window) => { disarm(w); if (disposed || w.paused || windows.get(w.target.threadId) !== w) return; const now = deps.now(); if (now >= w.deadline) return end(w, null); // A cold cache is never pinged: that would pay the re-write it avoids. const untilCold = w.lastRequestAt + CACHE_TTL_MS - now; if (untilCold <= 0) return end(w, null); const due = Math.max(1000, w.lastRequestAt + PING_AFTER_MS - now); const delay = Math.min(w.deadline - now, untilCold, due); w.nextPingAt = now + due < w.deadline && due < untilCold ? now + due : null; w.pending = deps.after(delay, () => { void ping(w); }); deps.changed(w.target); }; const ping = async (w: Window) => { w.pending = null; if (disposed || w.paused || windows.get(w.target.threadId) !== w) return; const now = deps.now(); if (now >= w.deadline || now - w.lastRequestAt >= CACHE_TTL_MS) return end(w, null); if (now - w.lastRequestAt < PING_AFTER_MS - 1000) return arm(w); if (deps.windowMs(w.target.botId) === null) return end(w, null); const ineligible = deps.ineligible(w.target); if (ineligible) return end(w, ineligible); if (deps.overBudget()) return end(w, "the workspace's monthly spend limit is reached"); if (deps.busy(w.target)) return retryLater(w, now); const controller = new AbortController(); w.inflight = controller; let result: KeepWarmPingResult; try { result = await deps.ping(w.target, controller.signal); } catch (error) { result = { ok: false, reason: `the ping failed: ${error instanceof Error ? error.message : String(error)}` }; } if (w.inflight === controller) w.inflight = null; // Whatever happened to the window meanwhile, a ping that ran is booked. if (result.ok) { try { deps.book(w.target, result); } catch {} } if (disposed || windows.get(w.target.threadId) !== w || controller.signal.aborted) return; if (!result.ok) { if (result.busy) return retryLater(w, deps.now()); return end(w, result.reason); } const warm = pingWasWarm(result.cacheRead, result.cacheWrite); lastPing.set(w.target.threadId, { at: now, read: result.cacheRead, write: result.cacheWrite, costUsd: result.costUsd }); if (!warm) { return end(w, `the ping read ${fmtTokens(result.cacheRead)} and wrote ${fmtTokens(result.cacheWrite)} tokens: the cache was already gone`); } w.lastRequestAt = now; arm(w); }; const retryLater = (w: Window, now: number) => { disarm(w); const untilCold = w.lastRequestAt + CACHE_TTL_MS - now; if (untilCold <= BUSY_RETRY_MS || now + BUSY_RETRY_MS >= w.deadline) return end(w, null); w.nextPingAt = now + BUSY_RETRY_MS; w.pending = deps.after(BUSY_RETRY_MS, () => { void ping(w); }); deps.changed(w.target); }; return { noteTurnStarted(threadId: string): void { const w = windows.get(threadId); if (!w) return; w.paused = true; disarm(w); w.inflight?.abort(); w.inflight = null; deps.changed(w.target); }, noteTurnCompleted(target: KeepWarmTarget, turn: { ok: boolean; stopReason?: string | null; contextTokens?: number }): void { if (disposed) return; const existing = windows.get(target.threadId); const hadStopped = stoppedWhy.delete(target.threadId); const windowMs = deps.windowMs(target.botId); const quiet = (w: Window | undefined) => { const hadLast = lastPing.delete(target.threadId); if (w) end(w, null); else if (hadStopped || hadLast) deps.changed(target); }; if (windowMs === null || !turn.ok) return quiet(existing); if ((turn.contextTokens ?? 0) < MIN_CONTEXT_TOKENS) return quiet(existing); if (deps.ineligible(target)) return quiet(existing); const now = deps.now(); const w: Window = existing ?? { target, deadline: 0, lastRequestAt: now, pending: null, nextPingAt: null, inflight: null, paused: false }; w.target = target; w.deadline = now + windowMs; w.lastRequestAt = now; w.paused = false; windows.set(target.threadId, w); deps.hold(target, w.deadline); arm(w); }, cancelThread(threadId: string): void { stoppedWhy.delete(threadId); lastPing.delete(threadId); const w = windows.get(threadId); if (w) end(w, null); }, cancelBot(botId: string): void { for (const w of windows.values()) if (w.target.botId === botId) end(w, null); }, refresh(): void { for (const w of windows.values()) if (deps.windowMs(w.target.botId) === null) end(w, null); }, status(threadId: string): KeepWarmStatus | undefined { const w = windows.get(threadId); const last = lastPing.get(threadId); if (w) { return { state: "warm", until: w.deadline, ...(w.nextPingAt !== null && !w.paused ? { nextPingAt: w.nextPingAt } : {}), ...(last ? { last } : {}), }; } const why = stoppedWhy.get(threadId); return why ? { state: "stopped", stopped: why, ...(last ? { last } : {}) } : undefined; }, dispose(): void { disposed = true; for (const w of windows.values()) { disarm(w); w.inflight?.abort(); deps.hold(w.target, null); } windows.clear(); }, }; } export type CacheKeepWarm = ReturnType;