/** * Lightweight in-memory tool usage metrics. * * Tracks per-tool call counts, total latency, and empty-result counts. * Stats are logged to stderr periodically and exposed via getMetricsSnapshot(). * All state is in-process only — resets on server restart. */ /** Log a single tool call that ran long enough to be worth attributing. */ export declare function reportSlowCall(toolName: string, elapsedMs: number, args?: unknown): void; /** Call before dispatching a tool. Returns a finish() callback. */ export declare function recordToolStart(toolName: string): (isEmpty: boolean) => void; /** * Record a call in the sequence buffer and return the number of occurrences * of this exact tool+args combination within the recent window (including * the call just recorded). 1 = first occurrence, 3+ = likely loop. */ export declare function recordCallSequence(toolName: string, argsKey: string, epoch?: number): number; /** * Occurrences of this exact call within the recent window that ran under `epoch`. * * Repeating a read is only a LOOP when nothing changed underneath it. Once a write * has landed, re-issuing the same read is the correct thing to do — it is how an * agent sees its own edit. The loop advisory used to fire on the raw repeat count * and assert "the answer does not change between calls", which after the dedup * cache became write-invalidated was simply false: a live run (eval case * L2-entity-query-range-roundtrip, 2026-08-24) got correct, freshly-changed * content and that advisory attached to it, on occurrence #3 of a read whose * answer had changed twice through this server's own writes. * * That wording is the same class of hazard the invalidation fix was for: telling * an agent its re-read is pointless is how it gets talked out of trusting the * truth it just fetched. */ export declare function occurrencesInEpoch(toolName: string, argsKey: string, epoch: number): number; /** Test/maintenance helper — clears the sequence buffer. */ export declare function resetCallSequence(): void; /** Returns a snapshot of current metrics sorted by call count descending. */ export declare function getMetricsSnapshot(): Array<{ tool: string; calls: number; avgLatencyMs: number; emptyRatio: number; duplicateCalls: number; }>; /** * Start periodic logging of metrics to stderr. * Safe to call multiple times — only the first call starts the interval. * @param intervalMs default 5 minutes */ export declare function startMetricsLogging(intervalMs?: number): void; //# sourceMappingURL=toolMetrics.d.ts.map