| |
| |
|
|
| import memoryManager, { MemoryPressure } from './memoryManager.js'; |
|
|
| const reasoningSignatureCache = new Map(); |
| const toolSignatureCache = new Map(); |
|
|
| |
| const MAX_REASONING_ENTRIES = 256; |
| const MAX_TOOL_ENTRIES = 256; |
|
|
| |
| const ENTRY_TTL_MS = 30 * 60 * 1000; |
| const CLEAN_INTERVAL_MS = 10 * 60 * 1000; |
|
|
| function makeKey(sessionId, model) { |
| return `${sessionId || ''}::${model || ''}`; |
| } |
|
|
| function pruneMap(map, targetSize) { |
| if (map.size <= targetSize) return; |
| const removeCount = map.size - targetSize; |
| let removed = 0; |
| for (const key of map.keys()) { |
| map.delete(key); |
| removed++; |
| if (removed >= removeCount) break; |
| } |
| } |
|
|
| function pruneExpired(map, now) { |
| for (const [key, entry] of map.entries()) { |
| if (!entry || typeof entry.ts !== 'number') continue; |
| if (now - entry.ts > ENTRY_TTL_MS) { |
| map.delete(key); |
| } |
| } |
| } |
|
|
| |
| memoryManager.registerCleanup((pressure) => { |
| if (pressure === MemoryPressure.MEDIUM) { |
| |
| pruneMap(reasoningSignatureCache, Math.floor(MAX_REASONING_ENTRIES / 2)); |
| pruneMap(toolSignatureCache, Math.floor(MAX_TOOL_ENTRIES / 2)); |
| } else if (pressure === MemoryPressure.HIGH) { |
| |
| pruneMap(reasoningSignatureCache, Math.floor(MAX_REASONING_ENTRIES / 4)); |
| pruneMap(toolSignatureCache, Math.floor(MAX_TOOL_ENTRIES / 4)); |
| } else if (pressure === MemoryPressure.CRITICAL) { |
| |
| reasoningSignatureCache.clear(); |
| toolSignatureCache.clear(); |
| } |
| }); |
|
|
| |
| setInterval(() => { |
| const now = Date.now(); |
| pruneExpired(reasoningSignatureCache, now); |
| pruneExpired(toolSignatureCache, now); |
| }, CLEAN_INTERVAL_MS).unref?.(); |
|
|
| export function setReasoningSignature(sessionId, model, signature) { |
| if (!signature) return; |
| const key = makeKey(sessionId, model); |
| reasoningSignatureCache.set(key, { signature, ts: Date.now() }); |
| |
| pruneMap(reasoningSignatureCache, MAX_REASONING_ENTRIES); |
| } |
|
|
| export function getReasoningSignature(sessionId, model) { |
| const key = makeKey(sessionId, model); |
| const entry = reasoningSignatureCache.get(key); |
| if (!entry) return null; |
| const now = Date.now(); |
| if (typeof entry.ts === 'number' && now - entry.ts > ENTRY_TTL_MS) { |
| reasoningSignatureCache.delete(key); |
| return null; |
| } |
| return entry.signature || null; |
| } |
|
|
| export function setToolSignature(sessionId, model, signature) { |
| if (!signature) return; |
| const key = makeKey(sessionId, model); |
| toolSignatureCache.set(key, { signature, ts: Date.now() }); |
| pruneMap(toolSignatureCache, MAX_TOOL_ENTRIES); |
| } |
|
|
| export function getToolSignature(sessionId, model) { |
| const key = makeKey(sessionId, model); |
| const entry = toolSignatureCache.get(key); |
| if (!entry) return null; |
| const now = Date.now(); |
| if (typeof entry.ts === 'number' && now - entry.ts > ENTRY_TTL_MS) { |
| toolSignatureCache.delete(key); |
| return null; |
| } |
| return entry.signature || null; |
| } |
|
|
| |
| export function clearThoughtSignatureCaches() { |
| reasoningSignatureCache.clear(); |
| toolSignatureCache.clear(); |
| } |
|
|