import type { FollowupRun, QueueDropPolicy, QueueMode, QueueSettings } from "./types.js"; export type FollowupQueueState = { items: FollowupRun[]; draining: boolean; lastEnqueuedAt: number; mode: QueueMode; debounceMs: number; cap: number; dropPolicy: QueueDropPolicy; droppedCount: number; summaryLines: string[]; lastRun?: FollowupRun["run"]; }; export const DEFAULT_QUEUE_DEBOUNCE_MS = 1000; export const DEFAULT_QUEUE_CAP = 20; export const DEFAULT_QUEUE_DROP: QueueDropPolicy = "summarize"; export const FOLLOWUP_QUEUES = new Map(); export function getFollowupQueue(key: string, settings: QueueSettings): FollowupQueueState { const existing = FOLLOWUP_QUEUES.get(key); if (existing) { existing.mode = settings.mode; existing.debounceMs = typeof settings.debounceMs === "number" ? Math.max(0, settings.debounceMs) : existing.debounceMs; existing.cap = typeof settings.cap === "number" && settings.cap > 0 ? Math.floor(settings.cap) : existing.cap; existing.dropPolicy = settings.dropPolicy ?? existing.dropPolicy; return existing; } const created: FollowupQueueState = { items: [], draining: false, lastEnqueuedAt: 0, mode: settings.mode, debounceMs: typeof settings.debounceMs === "number" ? Math.max(0, settings.debounceMs) : DEFAULT_QUEUE_DEBOUNCE_MS, cap: typeof settings.cap === "number" && settings.cap > 0 ? Math.floor(settings.cap) : DEFAULT_QUEUE_CAP, dropPolicy: settings.dropPolicy ?? DEFAULT_QUEUE_DROP, droppedCount: 0, summaryLines: [], }; FOLLOWUP_QUEUES.set(key, created); return created; } export function clearFollowupQueue(key: string): number { const cleaned = key.trim(); if (!cleaned) return 0; const queue = FOLLOWUP_QUEUES.get(cleaned); if (!queue) return 0; const cleared = queue.items.length + queue.droppedCount; queue.items.length = 0; queue.droppedCount = 0; queue.summaryLines = []; queue.lastRun = undefined; queue.lastEnqueuedAt = 0; FOLLOWUP_QUEUES.delete(cleaned); return cleared; }