Spaces:
Sleeping
Sleeping
| /** | |
| * callBudgetForecastBlock.ts — S-FORECAST: pre-turn budget forecast | |
| * | |
| * Prima di qualsiasi acquireExtraCall, analizza il task classificato e | |
| * RISERVA ogni slot (HIGH/LOW) per la capability più utile in quel contesto. | |
| * | |
| * Problema risolto (on-demand race condition): | |
| * reflection arriva all'iter 4 → prende LOW slot → verify alla fine non trova | |
| * slot → output di codice mai verificato. Non era un problema di logica, era | |
| * un problema di TIMING: chi arrivava prima vinceva. | |
| * | |
| * Con forecast: LOW è pre-riservato per verify su task di codice → reflection | |
| * è bloccata dalla riserva, non dal timing fortuito. Garanzia strutturale. | |
| * | |
| * Design: | |
| * - Zero LLM calls, < 0.1ms, deterministic, pure function | |
| * - BudgetForecast importato da callBudgetCoordinator (nessun circular import) | |
| * - null = nessuna restrizione (backward-compatible con on-demand) | |
| * - Stringa specifica = solo quella capability può acquisire lo slot | |
| * | |
| * Regole (priorità decrescente): | |
| * 1. isDirectAnswer → HIGH: null, LOW: 'verify' fast path | |
| * 2. code + complex/err → HIGH: 'thinking', LOW: 'verify' qualità codice | |
| * 3. code semplice → HIGH: null, LOW: 'verify' verify essenziale | |
| * 4. reasoning=high+text → HIGH: 'debate', LOW: 'reflection' testo complesso | |
| * 5. medium + errors → HIGH: 'thinking', LOW: 'verify' recovery boost | |
| * 6. default → HIGH: null, LOW: null no restriction | |
| * | |
| * @module callBudgetForecastBlock | |
| */ | |
| import type { BudgetForecast } from './callBudgetCoordinator'; | |
| export interface BudgetForecastInput { | |
| preCls: { type?: string; isDirectAnswer?: boolean; complexity?: number } | null; | |
| isCodeTask: boolean; | |
| reasoningDepth: 'low' | 'medium' | 'high'; | |
| hasRecentErrors: boolean; | |
| } | |
| /** | |
| * Calcola la previsione ottimale di allocazione budget per questo turno. | |
| * Chiamare DOPO la classificazione del task e PRIMA di runPreLoopFinalizer. | |
| * Risultato passato a callBudget.setForecast() per attivare la riserva. | |
| */ | |
| export function forecastBudget(input: BudgetForecastInput): BudgetForecast { | |
| const { preCls, isCodeTask, reasoningDepth, hasRecentErrors } = input; | |
| const _complexity = preCls?.complexity ?? 5; | |
| const _isDirectAns = preCls?.isDirectAnswer ?? false; | |
| // 1. Risposta diretta → nessun HIGH necessario, LOW riservato per verify | |
| if (_isDirectAns) { | |
| return { | |
| highReserved: null, | |
| lowReserved: 'verify', | |
| rationale: 'isDirectAnswer → LOW:verify (fast path, solo check completezza)', | |
| }; | |
| } | |
| // 2. Codice complesso o con errori → thinking garantito + verify garantito | |
| if (isCodeTask && (_complexity >= 7 || hasRecentErrors)) { | |
| return { | |
| highReserved: 'thinking', | |
| lowReserved: 'verify', | |
| rationale: `code+${_complexity >= 7 ? 'complexity' + _complexity : 'errors'} → HIGH:thinking LOW:verify`, | |
| }; | |
| } | |
| // 3. Codice semplice → solo verify garantito (thinking non necessario) | |
| if (isCodeTask) { | |
| return { | |
| highReserved: null, | |
| lowReserved: 'verify', | |
| rationale: 'code+simple → LOW:verify (nessun ragionamento avanzato; verify essenziale)', | |
| }; | |
| } | |
| // 4. Ragionamento alto + testo → debate + reflection (multi-prospettiva + validazione) | |
| if (reasoningDepth === 'high') { | |
| return { | |
| highReserved: 'debate', | |
| lowReserved: 'reflection', | |
| rationale: 'reasoning=high+text → HIGH:debate LOW:reflection', | |
| }; | |
| } | |
| // 5. Ragionamento medio con errori → thinking per recovery + verify output | |
| if (hasRecentErrors && reasoningDepth !== 'low') { | |
| return { | |
| highReserved: 'thinking', | |
| lowReserved: 'verify', | |
| rationale: 'medium+errors → HIGH:thinking LOW:verify (recovery boost)', | |
| }; | |
| } | |
| // 6. Default — nessuna restrizione (comportamento backward-compatible on-demand) | |
| return { | |
| highReserved: null, | |
| lowReserved: null, | |
| rationale: 'default → no restriction (on-demand fallback)', | |
| }; | |
| } | |