/* * Veskslop Phase 0 spike — global query pacing. * * Current policy: every command sent to the client is spaced by a random * 500-2800 ms. Commands are serialized through one queue, and identical * concurrent queries are coalesced so the total query count stays minimal. * * The long-term human-emulation policy (snappy first action, slower bulk * actions, risky fast mode) lives in AGENTS.md and is not active yet. */ export function sleep(ms: number): Promise { return new Promise(resolve => setTimeout(resolve, ms)); } /** Current per-query delay: 500-2800 ms. */ export function queryDelay(): number { return 500 + Math.floor(Math.random() * 2301); } let queue: Promise = Promise.resolve(); let queryCount = 0; /** Serialize a REST query behind the queue with the configured delay. */ export function paced(task: () => Promise): Promise { const delay = queryDelay(); const run = queue.then(async () => { await sleep(delay); queryCount++; if (process.env.DEBUG === "1") { console.error(`[rest] query #${queryCount} (+${delay}ms)`); } return task(); }); queue = run.then( () => undefined, () => undefined ); return run; } export function getQueryCount(): number { return queryCount; } const inFlight = new Map>(); /** Coalesce identical concurrent queries into a single request. */ export function dedupe(key: string, task: () => Promise): Promise { const existing = inFlight.get(key); if (existing) return existing as Promise; const promise = task().finally(() => inFlight.delete(key)); inFlight.set(key, promise); return promise; }