import type { SwarmTracer } from "./tracer.js"; export interface ScalingConfig { /** Minimum number of agents to maintain (default: 1) */ minAgents?: number; /** Maximum number of agents allowed (default: 10) */ maxAgents?: number; /** * Clock function returning current time in milliseconds (default: Date.now). * Injectable for testing with synthetic/replayed traces so evaluation windows * are computed relative to the trace timeline rather than wall-clock time. */ clockFn?: () => number; /** * Error rate threshold to trigger scale-up (0-1, default: 0.25 = 25%). * Rationale: 25% catches systemic issues (API degradation, bad prompts) * early without over-reacting to transient single-agent failures. * Lower than 20% would trigger on 1-of-5 agents failing once. */ scaleUpErrorRate?: number; /** * Max latency (ms) before triggering scale-up (default: 15000). * Rationale: multi-turn LLM agents (think→act→observe cycles) typically * take 15-120s per full lifecycle. Opus inference alone is ~10s/call. * 5s was far too aggressive — normal Opus agents would constantly trigger. */ scaleUpLatencyMs?: number; /** * Seconds of no activity before triggering scale-down (default: 60). * Rationale: agents actively running may go 30-60s between tracer events * (no events emitted mid-execution). 30s caused false scale-downs while * agents were still working. 60s gives a full agent lifecycle to complete. */ scaleDownIdleSeconds?: number; /** * Minimum ms between scaling decisions (default: 10000). * Rationale: 10s prevents oscillation in reactive mode where error * and complete events fire in rapid succession. 5s was too short when * multiple agents complete simultaneously. */ cooldownMs?: number; } export interface ScalingDecision { /** What action to take */ action: "scale_up" | "scale_down" | "idle"; /** Number of agents to add (scale_up) or remove (scale_down) */ count: number; /** Human-readable reason for the decision */ reason: string; } export interface ScalingHistoryEntry { decision: ScalingDecision; timestamp: number; } type ScalingCallback = (decision: ScalingDecision) => void; type ScalingConfigCore = Required>; export declare class DynamicScalingMonitor { private readonly tracer; private readonly config; private readonly clockFn; private currentAgentCount; private lastDecision; private lastDecisionTime; private history; private static readonly MAX_HISTORY; private callbacks; private unsubscribeTracer; private _evaluating; constructor(tracer: SwarmTracer, config?: ScalingConfig); getConfig(): Readonly; setCurrentAgentCount(count: number): void; getState(): { currentAgentCount: number; lastDecision: ScalingDecision | null; }; /** * Evaluate current tracer metrics and return a scaling decision. * Call this periodically or after significant events. */ evaluate(): ScalingDecision; private checkScaleUp; private checkScaleDown; /** * Record a decision (for cooldown tracking and history). * Call this after applying the decision from evaluate(). */ recordDecision(decision: ScalingDecision): void; getHistory(): ScalingHistoryEntry[]; /** * Register a callback that fires on non-idle scaling decisions. */ onScaleDecision(callback: ScalingCallback): () => void; /** * Enable reactive mode: subscribe to tracer events and auto-evaluate * on error events. Non-idle decisions fire registered callbacks. */ enableReactive(): void; /** * Disable reactive mode. Stops listening to tracer events. */ disableReactive(): void; /** Clean up — disables reactive mode. */ dispose(): void; } export {}; //# sourceMappingURL=scaling.d.ts.map