/** * cache-first — Immutable prefix + append-only log for DeepSeek prefix-cache stability. * * Harvested from reasonix Pillar 1 (Cache-First Loop). * * DeepSeek's automatic prefix caching activates only when the exact byte prefix * of the previous request matches. Most agent loops reorder, rewrite, or inject * fresh timestamps each turn — cache hit rate in practice: <20%. * * This module tracks the system prefix and ensures messages are serialized in * append-only order so the prefix stays byte-stable across turns. */ import type { DeepSeekChatMessage } from "./types.js"; /** * Compute a stable hash for a value using a fast non-crypto algorithm. * DeepSeek's cache is byte-prefix based, so we just need a deterministic * fingerprint to detect changes. */ export declare function fastHash(value: string): string; /** * Detect whether a provider URL targets DeepSeek. */ export declare function isDeepSeekProvider(baseUrl: string): boolean; /** * Immutable prefix tracker. * * Tracks the prefix derived from the system prompt + tool definitions. * These are what determine DeepSeek's prefix-cache matching — the rest of * the conversation history just appends after the stable prefix. * * Message truncation (context window compaction) does NOT affect prefix * stability, because the prefix hash only considers: * 1. The system message content * 2. The tool-call definitions (assistant messages with tool_calls) * * If neither changes across turns, the prefix is "stable" and DeepSeek's * automatic disk cache will hit on every repeat of the same prefix bytes. */ export declare class PrefixGuard { private _systemHash; private _toolsHash; private _prevPrefixHash; private _prefixHash; private _stabiliseCount; /** Stabilise messages array: system first, stable prefix hash. */ stabilise(messages: DeepSeekChatMessage[]): { messages: DeepSeekChatMessage[]; prefixHash: string; }; /** Current prefix hash for cache-diagnostics headers. */ get prefixHash(): string; /** * True when the prefix hash is stable across at least 2 successive calls. * First call always returns false (no baseline for comparison). * Seed calls after reset return false until a second comparison. */ isStable(): boolean; /** Whether the guard has been initialized (computed at least once). */ isInitialized(): boolean; /** Times stabilise() has been called since last reset. */ get callCount(): number; /** Reset (new session or context cleared). */ reset(): void; } /** * Append-only log tracker. * * Ensures that conversation history is only ever appended, never mutated or * reordered. This preserves the prefix for subsequent turns. */ export declare class AppendOnlyLog { private _entryCount; /** Validate that the messages log has only grown (no deletions / reorders). */ validate(entries: DeepSeekChatMessage[]): boolean; reset(): void; }