/** * intelligence.ts — Detección de loops y scoring de eficiencia * * Módulo puro: solo recibe datos y retorna análisis. * Sin efectos secundarios, sin acceso a DB. * Esto lo hace fácil de testear y reutilizar. */ import type { EventRow } from './db'; export interface LoopAlert { toolName: string; count: number; windowMs: number; ts: number; context: LoopContext; } export interface LoopContext { repeatedFiles: string[]; repeatedCommands: string[]; estimatedCostUsd: number; } export interface IntelligenceReport { loops: LoopAlert[]; efficiencyScore: number; summary: string; exactRetries: number; errorRate: number; fileChurnScore: number; seqCycleCount: number; } /** * Detecta loops: cuando el mismo tool se llama ≥ threshold veces * dentro de windowMs. Evita alertas duplicadas con COOLDOWN_MS = windowMs. * * Algoritmo: ventana deslizante sobre eventos ordenados por timestamp. * Captura contexto (archivos repetidos, comandos Bash repetidos) para cada alerta. */ export declare function detectLoops(events: EventRow[], threshold?: number, windowMs?: number): LoopAlert[]; /** * Calcula un score de 0-100 basado en: * - Loops detectados → -10 por loop, cap -25 * - Tool calls excesivos → -5 por cada 50 calls sobre el umbral (150), cap -20 * - Coste alto → -5 si >$2, -10 si >$10, -20 si >$30 * * Principio: una sesión de coding larga y productiva (88-200 tools) NO debería * llegar a 0. El score 0 se reserva para sesiones con loops masivos + coste alto. * * Ejemplos calibrados: * 88 tools, 5 loops, $6.49 → 100 - 25 - 0 - 5 = 70 * 236 tools, 2 loops, $25.34 → 100 - 20 - 9 - 10 = 61 * 20 tools, 0 loops, $0.30 → 100 - 0 - 0 - 0 = 100 */ export declare function calcEfficiencyScore(events: EventRow[], loops: LoopAlert[], costUsd: number): number; /** * Counts exact duplicate tool calls: same tool_name + same tool_input. * Only Done events with non-null tool_name are considered. */ export declare function detectExactRetries(events: EventRow[]): number; /** * Fraction of Done calls whose tool_response matches an error pattern. * Returns 0 if there are no Done calls with a response. */ export declare function computeErrorRate(events: EventRow[]): number; /** * Diversity of file access: unique_files / total_file_calls. * Returns 1.0 when there are no file tool calls (no penalty). * Lower values indicate the agent is revisiting the same files repeatedly. */ export declare function computeFileChurn(events: EventRow[]): number; /** * Counts A→B→A triplets in the Done event sequence within a 5-minute window. * Indicates the agent oscillates between two tools without making progress. */ export declare function detectSeqCycles(events: EventRow[]): number; export interface SemanticLoop { type: 'tool_sequence' | 'error_persistence'; turn_start: number; count: number; detail: string; } interface TurnLike { turn_index: number; tool_calls?: string[]; error_count: number; } /** * Detects two kinds of semantic loops using assistant_turns data: * - tool_sequence: same tool_calls signature repeated in ≥2 of the last 5 turns * - error_persistence: ≥3 consecutive turns with error_count > 0 */ export declare function analyzeSemanticLoops(turns: TurnLike[]): SemanticLoop[]; export interface SaturationPrediction { minutesLeft: number; pctPerMin: number; } /** * Linear regression over context_used samples → predicts minutes until 90% of context_window. * Returns null if insufficient data or trend is flat/negative. */ export declare function predictSaturation(samples: Array<{ ts: number; context_used: number; }>, contextWindow: number): SaturationPrediction | null; /** * Genera el reporte completo de inteligencia para una sesión. */ export declare function analyzeSession(events: EventRow[], costUsd: number, threshold?: number, windowMs?: number): IntelligenceReport; export {};