/** * KVFlow Early Warning — carousel-pattern detection and per-brain metrics. * * Extends the KVFlow cache manager's telemetry with: * 1. Per-brain (per-agent-step) hit-rate breakdowns * 2. Prefetch stall avoidance tracking (how many stalls were prevented by prefetch) * 3. Carousel-pattern detection (repeated eviction-then-reload cycles on the same * brain, indicating the eviction policy is out of sync with the workflow graph) * 4. Workflow-graph drift detection (when the agent step graph topology changes * but the eviction config hasn't been updated) * * Wired to /reflect and cost-dashboard via `checkCarouselEarlyWarning()`. * * @module @holoscript/llm-provider/kvflow * @version 0.1.0 */ import type { KVFlowTelemetry, KVFlowScope, StepNodeId } from './types'; /** * Per-brain (per-agent-step) cache metrics. Each brain corresponds to one * agent's role overlay or the shared team-board prefix. */ export interface BrainMetrics { /** Agent step ID this metrics bucket tracks. */ stepId: StepNodeId; /** Cache scope for this brain. */ scope: KVFlowScope; /** Number of cache hits for this brain. */ hits: number; /** Number of cache misses for this brain. */ misses: number; /** Hit rate (hits / (hits + misses)). 0 if no events. */ hitRate: number; /** Number of times this brain's KV was evicted and then reloaded. */ evictionReloadCycles: number; /** Number of prefetch operations that successfully loaded this brain's * KV before it was needed, avoiding a cache-miss stall. */ prefetchStallsAvoided: number; /** Number of cache-miss stalls that were NOT avoided (hit after miss * without a successful prefetch). */ stallsObserved: number; /** Current steps-to-execution value (lower = more imminent). */ stepsToExecution: number; /** Current residency of this brain's KV entry. */ residency: 'device' | 'host' | 'evicted' | 'unknown'; } /** * Severity level for carousel-pattern warnings. */ export type CarouselSeverity = 'none' | 'early_warning' | 'warning' | 'critical'; /** * A carousel-pattern warning. Emitted when a brain's KV cache shows signs * of eviction-then-reload cycling (the core KVFlow problem). */ export interface CarouselWarning { /** The brain (agent step) that triggered this warning. */ stepId: StepNodeId; /** Cache scope of the affected brain. */ scope: KVFlowScope; /** Severity of the carousel pattern. */ severity: CarouselSeverity; /** Human-readable explanation. */ message: string; /** Number of eviction-reload cycles detected for this brain. */ cycles: number; /** Hit rate for this brain (low hit rate = carousel indicator). */ hitRate: number; /** Recommended action. */ recommendation: string; } /** * Drift signal: when the workflow graph topology changes but the eviction * config hasn't been updated, this struct captures the divergence. */ export interface WorkflowDrift { /** Timestamp of the last graph topology change observed. */ lastGraphChange: string; /** Timestamp of the last eviction config update. */ lastConfigUpdate: string; /** Number of agent steps added since the last config update. */ stepsAdded: number; /** Number of agent steps removed since the last config update. */ stepsRemoved: number; /** Whether the drift is significant enough to warrant a config update. */ isStale: boolean; /** Human-readable summary. */ summary: string; } /** * Full early-warning report from the KVFlow carousel detector. */ export interface CarouselEarlyWarningReport { /** Timestamp of this report. */ generatedAt: string; /** Overall cache hit rate across all brains. */ overallHitRate: number; /** Overall prefetch stall avoidance rate (stalls avoided / total stalls). */ overallPrefetchEffectiveness: number; /** Per-brain metrics, keyed by step ID. */ brainMetrics: Map; /** Carousel-pattern warnings for brains with eviction-reload cycling. */ warnings: CarouselWarning[]; /** Workflow graph drift signal (null if no drift detected). */ drift: WorkflowDrift | null; /** Summary for /reflect and cost-dashboard surfaces. */ summary: CarouselSummary; } /** * Compact summary for /reflect and cost-dashboard surfaces. */ export interface CarouselSummary { /** Total brains tracked. */ totalBrains: number; /** Brains with hit rate >= 0.8 (healthy). */ healthyBrains: number; /** Brains with hit rate < 0.5 (concerning). */ atRiskBrains: number; /** Brains with carousel-pattern cycling detected. */ carouselBrains: number; /** Total prefetch stalls avoided across all brains. */ totalStallsAvoided: number; /** Total stalls observed (cache-miss without prefetch). */ totalStallsObserved: number; /** Whether workflow graph drift is detected. */ hasDrift: boolean; /** One-line status for dashboards. */ statusLine: string; } /** * Configuration for the carousel early-warning detector. */ export interface CarouselEarlyWarningConfig { /** * Minimum number of telemetry events before carousel detection activates. * Prevents false positives from sparse data. * Default: 5 */ minSampleSize: number; /** * Hit rate below which a brain is considered "at risk." * Default: 0.5 */ atRiskHitRateThreshold: number; /** * Hit rate above which a brain is considered "healthy." * Default: 0.8 */ healthyHitRateThreshold: number; /** * Number of eviction-reload cycles that triggers early_warning severity. * Default: 2 */ earlyWarningCycleThreshold: number; /** * Number of eviction-reload cycles that triggers warning severity. * Default: 4 */ warningCycleThreshold: number; /** * Number of eviction-reload cycles that triggers critical severity. * Default: 8 */ criticalCycleThreshold: number; /** * Whether workflow graph drift detection is enabled. * Default: true */ driftDetectionEnabled: boolean; /** * Maximum staleness in milliseconds before the eviction config is considered * stale relative to the last graph change. * Default: 300_000 (5 minutes) */ configStalenessThresholdMs: number; } /** * KVFlow Carousel Early Warning Detector. * * Analyzes telemetry from the KVFlowCacheManager to detect: * - Carousel patterns (eviction-then-reload cycles per brain) * - Low hit-rate brains (at-risk agents) * - Prefetch effectiveness (stalls avoided vs observed) * - Workflow graph drift (graph topology changed but config is stale) * * Usage: * ```ts * const detector = new KVFlowCarouselDetector(); * const report = detector.checkCarouselEarlyWarning(manager.getTelemetry(), { * brainEntries: manager.getAllEntries(), * graphChangeAt: lastGraphChange, * configUpdatedAt: lastConfigUpdate, * }); * ``` */ export declare class KVFlowCarouselDetector { private readonly config; constructor(config?: Partial); /** * Analyze KVFlow telemetry and produce a carousel early-warning report. * * @param telemetry - Recent telemetry events from the KVFlowCacheManager * @param context - Additional context: brain entries, graph change timestamps, etc. * @returns Full early-warning report with per-brain metrics and carousel warnings */ checkCarouselEarlyWarning(telemetry: KVFlowTelemetry[], context: { /** Current brain entries from the cache manager. */ brainEntries: Array<{ stepId: StepNodeId; scope: KVFlowScope; residency: string; stepsToExecution: number; }>; /** Timestamp of the last workflow graph topology change. */ graphChangeAt?: string; /** Timestamp of the last eviction config update. */ configUpdatedAt?: string; /** Steps added since last config update (from graph diff). */ stepsAddedSinceConfig?: number; /** Steps removed since last config update (from graph diff). */ stepsRemovedSinceConfig?: number; }): CarouselEarlyWarningReport; private computeBrainMetrics; private detectCarouselPatterns; private computeOverallHitRate; private computePrefetchEffectiveness; private detectWorkflowDrift; private buildStatusLine; } /** * Default instance with standard configuration. */ export declare const defaultCarouselDetector: KVFlowCarouselDetector; /** * Run the carousel early-warning check against KVFlow telemetry. * * Convenience function that creates a detector with default config and * runs the analysis. For custom thresholds, create a KVFlowCarouselDetector * instance directly. */ export declare function checkCarouselEarlyWarning(telemetry: KVFlowTelemetry[], context: Parameters[1]): CarouselEarlyWarningReport;