UNPKG

@ai2070/l0

Version:

L0: The Missing Reliability Substrate for AI

897 lines (896 loc) 68.5 kB
import { GuardrailEngine } from "../guardrails/engine"; import { RetryManager } from "./retry"; import { detectZeroToken } from "./zeroToken"; import { normalizeStreamEvent } from "./events"; import { detectOverlap } from "../utils/tokens"; import { isNetworkError, L0Error, ErrorCategory, L0ErrorCodes, } from "../utils/errors"; import { EventDispatcher } from "./event-dispatcher"; import { registerCallbackWrappers } from "./callback-wrappers"; import { EventType, } from "../types/observability"; let _driftDetectorFactory = null; let _monitorFactory = null; let _interceptorManagerFactory = null; let _adapterRegistry = null; export function enableDriftDetection(factory) { _driftDetectorFactory = factory; } export function enableMonitoring(factory) { _monitorFactory = factory; } export function enableInterceptors(factory) { _interceptorManagerFactory = factory; } export function enableAdapterRegistry(registry) { _adapterRegistry = registry; } import { createInitialState, resetStateForRetry } from "./state"; import { validateCheckpointForContinuation } from "./checkpoint"; import { safeInvokeCallback } from "./callbacks"; import { StateMachine, RuntimeStates } from "./state-machine"; import { Metrics } from "./metrics"; export { getText, consumeStream } from "./helpers"; export { StateMachine, RuntimeStates } from "./state-machine"; export { Metrics } from "./metrics"; function getFailureType(error, signal) { if (signal?.aborted || error.name === "AbortError") { return "abort"; } if (error instanceof L0Error) { switch (error.code) { case L0ErrorCodes.INITIAL_TOKEN_TIMEOUT: case L0ErrorCodes.INTER_TOKEN_TIMEOUT: return "timeout"; case L0ErrorCodes.ZERO_OUTPUT: return "zero_output"; case L0ErrorCodes.NETWORK_ERROR: return "network"; case L0ErrorCodes.GUARDRAIL_VIOLATION: case L0ErrorCodes.FATAL_GUARDRAIL_VIOLATION: case L0ErrorCodes.DRIFT_DETECTED: return "model"; default: break; } } if (isNetworkError(error)) { return "network"; } const message = error.message.toLowerCase(); if (message.includes("timeout") || message.includes("timed out") || message.includes("deadline exceeded")) { return "timeout"; } if (message.includes("tool") || message.includes("function call") || error.toolCallId) { return "tool"; } return "unknown"; } function getRecoveryStrategy(willRetry, willFallback) { if (willRetry) return "retry"; if (willFallback) return "fallback"; return "halt"; } export async function l0(options) { const { signal: externalSignal, interceptors = [] } = options; let interceptorManager = null; let processedOptions = options; if (interceptors.length > 0) { if (!_interceptorManagerFactory) { throw new L0Error("Interceptors require enableInterceptors() to be called first. " + 'Import and call: import { enableInterceptors } from "@ai2070/l0"; enableInterceptors();', { code: L0ErrorCodes.FEATURE_NOT_ENABLED, context: options.context }); } interceptorManager = _interceptorManagerFactory(interceptors); try { processedOptions = (await interceptorManager.executeBefore(options)); } catch (error) { const err = error instanceof Error ? error : new Error(String(error)); await interceptorManager.executeError(err, options); throw err; } } const { stream: processedStream, fallbackStreams: processedFallbackStreams = [], guardrails: processedGuardrails = [], retry: processedRetry = {}, timeout: processedTimeout = {}, signal: processedSignal, monitoring: processedMonitoring, detectDrift: processedDetectDrift = false, detectZeroTokens: processedDetectZeroTokens = true, checkIntervals: processedCheckIntervals = {}, onEvent: processedOnEvent, continueFromLastKnownGoodToken: processedContinueFromCheckpoint = false, buildContinuationPrompt: processedBuildContinuationPrompt, deduplicateContinuation: processedDeduplicateContinuation, deduplicationOptions: processedDeduplicationOptions = {}, context: processedContext = {}, } = processedOptions; const dispatcher = new EventDispatcher(processedContext); if (processedOnEvent) { dispatcher.onEvent(processedOnEvent); } registerCallbackWrappers(dispatcher, processedOptions); const shouldDeduplicateContinuation = processedDeduplicateContinuation ?? processedContinueFromCheckpoint; const guardrailCheckInterval = processedCheckIntervals.guardrails ?? 5; const driftCheckInterval = processedCheckIntervals.drift ?? 10; const checkpointInterval = processedCheckIntervals.checkpoint ?? 10; const state = createInitialState(); const errors = []; const abortController = new AbortController(); const signal = processedSignal || externalSignal || abortController.signal; let monitor = null; if (processedMonitoring?.enabled) { if (!_monitorFactory) { throw new L0Error("Monitoring requires enableMonitoring() to be called first. " + 'Import and call: import { enableMonitoring } from "@ai2070/l0"; enableMonitoring();', { code: L0ErrorCodes.FEATURE_NOT_ENABLED, context: processedContext, }); } monitor = _monitorFactory({ enabled: true, sampleRate: processedMonitoring?.sampleRate ?? 1.0, includeNetworkDetails: processedMonitoring?.includeNetworkDetails ?? true, includeTimings: processedMonitoring?.includeTimings ?? true, metadata: processedMonitoring?.metadata, }); monitor.start(); monitor.recordContinuation(processedContinueFromCheckpoint, false); } const guardrailEngine = processedGuardrails.length > 0 ? new GuardrailEngine({ rules: processedGuardrails, stopOnFatal: true, enableStreaming: true, onPhaseStart: (contextSize, ruleCount) => { dispatcher.emit(EventType.GUARDRAIL_PHASE_START, { contextSize, ruleCount, }); }, onPhaseEnd: (ruleCount, violationCount) => { dispatcher.emit(EventType.GUARDRAIL_PHASE_END, { ruleCount, violationCount, }); }, onRuleStart: (index, ruleId) => { dispatcher.emit(EventType.GUARDRAIL_RULE_START, { index, ruleId, }); }, onRuleEnd: (index, ruleId) => { dispatcher.emit(EventType.GUARDRAIL_RULE_END, { index, ruleId, }); }, }) : null; const retryManager = new RetryManager({ attempts: processedRetry.attempts ?? 2, maxRetries: processedRetry.maxRetries, baseDelay: processedRetry.baseDelay ?? 1000, maxDelay: processedRetry.maxDelay ?? 10000, backoff: processedRetry.backoff ?? "fixed-jitter", retryOn: processedRetry.retryOn ?? [ "zero_output", "guardrail_violation", "drift", "incomplete", "network_error", "timeout", "rate_limit", "server_error", ], }); let driftDetector = null; if (processedDetectDrift) { if (!_driftDetectorFactory) { throw new L0Error("Drift detection requires enableDriftDetection() to be called first. " + 'Import and call: import { enableDriftDetection } from "@ai2070/l0"; enableDriftDetection();', { code: L0ErrorCodes.FEATURE_NOT_ENABLED, context: processedContext, }); } driftDetector = _driftDetectorFactory(); } const stateMachine = new StateMachine(); const metrics = new Metrics(); metrics.requests++; const streamGenerator = async function* () { let fallbackIndex = 0; const allStreams = [processedStream, ...processedFallbackStreams]; let tokenBuffer = []; let checkpointForContinuation = ""; let overlapBuffer = ""; let overlapResolved = false; dispatcher.emit(EventType.SESSION_START, { attempt: 1, isRetry: false, isFallback: false, }); while (fallbackIndex < allStreams.length) { const currentStreamFactory = allStreams[fallbackIndex]; let retryAttempt = 0; let isRetryAttempt = false; const modelRetryLimit = processedRetry.attempts ?? 2; state.fallbackIndex = fallbackIndex; while (retryAttempt <= modelRetryLimit) { stateMachine.transition(RuntimeStates.INIT); try { if (retryAttempt > 0 || isRetryAttempt) { if (processedContinueFromCheckpoint && state.checkpoint.length > 0) { checkpointForContinuation = state.checkpoint; stateMachine.transition(RuntimeStates.CHECKPOINT_VERIFYING); const validation = validateCheckpointForContinuation(checkpointForContinuation, guardrailEngine, driftDetector); if (validation.violations.length > 0) { state.violations.push(...validation.violations); monitor?.recordGuardrailViolations(validation.violations); } if (validation.driftDetected) { state.driftDetected = true; monitor?.recordDrift(true, validation.driftTypes); dispatcher.emit(EventType.GUARDRAIL_RULE_RESULT, { index: 0, ruleId: "drift", passed: false, violation: { rule: "drift", severity: "warning", message: `Drift detected in checkpoint: ${validation.driftTypes.join(", ")}`, }, }); } if (validation.skipContinuation) { tokenBuffer = []; resetStateForRetry(state); continue; } state.resumed = true; state.resumePoint = checkpointForContinuation; state.resumeFrom = checkpointForContinuation.length; overlapBuffer = ""; overlapResolved = false; dispatcher.emit(EventType.CONTINUATION_START, { checkpoint: checkpointForContinuation, tokenCount: state.tokenCount, }); dispatcher.emit(EventType.RESUME_START, { checkpoint: checkpointForContinuation, tokenCount: state.tokenCount, }); if (processedBuildContinuationPrompt) { processedBuildContinuationPrompt(checkpointForContinuation); } monitor?.recordContinuation(true, true, checkpointForContinuation); const checkpointEvent = { type: "token", value: checkpointForContinuation, timestamp: Date.now(), }; safeInvokeCallback(processedOnEvent, checkpointEvent, monitor, "onEvent"); yield checkpointEvent; tokenBuffer = [checkpointForContinuation]; state.content = checkpointForContinuation; state.tokenCount = 1; resetStateForRetry(state, { checkpoint: state.checkpoint, resumed: true, resumePoint: checkpointForContinuation, resumeFrom: checkpointForContinuation.length, }); state.content = checkpointForContinuation; state.tokenCount = 1; } else { tokenBuffer = []; resetStateForRetry(state); } } dispatcher.emit(EventType.STREAM_INIT, {}); const streamResult = await currentStreamFactory(); let sourceStream; let detectedAdapterName; dispatcher.emit(EventType.ADAPTER_WRAP_START, {}); if (processedOptions.adapter) { let adapter; if (typeof processedOptions.adapter === "string") { if (!_adapterRegistry) { throw new L0Error("String adapter names require enableAdapterRegistry() to be called first. " + 'Import and call: import { enableAdapterRegistry } from "@ai2070/l0"; enableAdapterRegistry();', { code: L0ErrorCodes.FEATURE_NOT_ENABLED, context: processedContext, }); } adapter = _adapterRegistry.getAdapter(processedOptions.adapter); if (!adapter) { throw new L0Error(`Adapter "${processedOptions.adapter}" not found. ` + `Use registerAdapter() to register it first.`, { code: L0ErrorCodes.ADAPTER_NOT_FOUND, modelRetryCount: state.modelRetryCount, networkRetryCount: state.networkRetryCount, fallbackIndex, context: processedContext, }); } } else { adapter = processedOptions.adapter; } detectedAdapterName = adapter.name; sourceStream = adapter.wrap(streamResult, processedOptions.adapterOptions); } else if (_adapterRegistry?.hasMatchingAdapter(streamResult)) { const adapter = _adapterRegistry.detectAdapter(streamResult); detectedAdapterName = adapter.name; sourceStream = adapter.wrap(streamResult, processedOptions.adapterOptions); } else if (streamResult.textStream) { detectedAdapterName = "textStream"; sourceStream = streamResult.textStream; } else if (streamResult.fullStream) { detectedAdapterName = "fullStream"; sourceStream = streamResult.fullStream; } else if (Symbol.asyncIterator in streamResult) { detectedAdapterName = "asyncIterable"; sourceStream = streamResult; } else { throw new L0Error("Invalid stream result - no iterable stream found and no adapter matched. " + "Use explicit `adapter: myAdapter` or register an adapter with detect().", { code: L0ErrorCodes.INVALID_STREAM, modelRetryCount: state.modelRetryCount, networkRetryCount: state.networkRetryCount, fallbackIndex, context: processedContext, }); } dispatcher.emit(EventType.ADAPTER_DETECTED, { adapter: detectedAdapterName, }); dispatcher.emit(EventType.ADAPTER_WRAP_END, {}); dispatcher.emit(EventType.STREAM_READY, {}); const startTime = Date.now(); state.firstTokenAt = undefined; state.lastTokenAt = undefined; let firstTokenReceived = false; stateMachine.transition(RuntimeStates.WAITING_FOR_TOKEN); let lastTokenEmissionTime = startTime; const defaultInitialTokenTimeout = 5000; const initialTimeout = processedTimeout.initialToken ?? defaultInitialTokenTimeout; let initialTimeoutId = null; let initialTimeoutReached = false; if (!signal?.aborted) { dispatcher.emit(EventType.TIMEOUT_START, { timeoutType: "initial_token", durationMs: initialTimeout, }); initialTimeoutId = setTimeout(() => { initialTimeoutReached = true; }, initialTimeout); } for await (const chunk of sourceStream) { if (signal?.aborted) { dispatcher.emit(EventType.ABORT_COMPLETED, { tokenCount: state.tokenCount, contentLength: state.content.length, }); throw new L0Error("Stream aborted by signal", { code: L0ErrorCodes.STREAM_ABORTED, checkpoint: state.checkpoint, tokenCount: state.tokenCount, contentLength: state.content.length, modelRetryCount: state.modelRetryCount, networkRetryCount: state.networkRetryCount, fallbackIndex, context: processedContext, }); } if (firstTokenReceived) { const interTimeout = processedTimeout.interToken ?? 10000; const timeSinceLastToken = Date.now() - lastTokenEmissionTime; if (timeSinceLastToken > interTimeout) { metrics.timeouts++; dispatcher.emit(EventType.TIMEOUT_TRIGGERED, { timeoutType: "inter", elapsedMs: timeSinceLastToken, }); throw new L0Error("Inter-token timeout reached", { code: L0ErrorCodes.INTER_TOKEN_TIMEOUT, checkpoint: state.checkpoint, tokenCount: state.tokenCount, contentLength: state.content.length, modelRetryCount: state.modelRetryCount, networkRetryCount: state.networkRetryCount, fallbackIndex, context: processedContext, metadata: { timeout: interTimeout, timeSinceLastToken }, }); } } if (initialTimeoutId && !firstTokenReceived) { clearTimeout(initialTimeoutId); initialTimeoutId = null; initialTimeoutReached = false; } if (initialTimeoutReached && !firstTokenReceived) { metrics.timeouts++; const elapsedMs = processedTimeout.initialToken ?? defaultInitialTokenTimeout; dispatcher.emit(EventType.TIMEOUT_TRIGGERED, { timeoutType: "initial", elapsedMs, }); throw new L0Error("Initial token timeout reached", { code: L0ErrorCodes.INITIAL_TOKEN_TIMEOUT, checkpoint: state.checkpoint, tokenCount: 0, contentLength: 0, modelRetryCount: state.modelRetryCount, networkRetryCount: state.networkRetryCount, fallbackIndex, context: processedContext, metadata: { timeout: processedTimeout.initialToken ?? defaultInitialTokenTimeout, }, }); } let event; try { event = normalizeStreamEvent(chunk); } catch (normalizeError) { const errMsg = normalizeError instanceof Error ? normalizeError.message : String(normalizeError); monitor?.logEvent({ type: "warning", message: `Failed to normalize stream chunk: ${errMsg}`, chunk: typeof chunk === "object" ? JSON.stringify(chunk) : chunk, }); continue; } if (event.type === "token" && event.value) { let token = event.value; if (!firstTokenReceived) { firstTokenReceived = true; state.firstTokenAt = Date.now(); stateMachine.transition(RuntimeStates.STREAMING); const interTimeout = processedTimeout.interToken ?? 10000; dispatcher.emit(EventType.TIMEOUT_RESET, { timeoutType: "inter_token", durationMs: interTimeout, }); } metrics.tokens++; if (state.resumed && shouldDeduplicateContinuation && checkpointForContinuation.length > 0 && !overlapResolved) { if (overlapBuffer.length === 0) { stateMachine.transition(RuntimeStates.CONTINUATION_MATCHING); } overlapBuffer += token; const overlapResult = detectOverlap(checkpointForContinuation, overlapBuffer, { minOverlap: processedDeduplicationOptions.minOverlap ?? 2, maxOverlap: processedDeduplicationOptions.maxOverlap ?? 500, caseSensitive: processedDeduplicationOptions.caseSensitive ?? true, normalizeWhitespace: processedDeduplicationOptions.normalizeWhitespace ?? false, }); const maxOverlapLen = processedDeduplicationOptions.maxOverlap ?? 500; const shouldFinalize = (overlapResult.hasOverlap && overlapResult.deduplicatedContinuation.length > 0) || overlapBuffer.length > maxOverlapLen; if (shouldFinalize) { overlapResolved = true; stateMachine.transition(RuntimeStates.STREAMING); if (overlapResult.hasOverlap) { token = overlapResult.deduplicatedContinuation; if (token.length === 0) { continue; } } else { token = overlapBuffer; } } else { continue; } } tokenBuffer.push(token); state.tokenCount++; state.lastTokenAt = Date.now(); const needsCheckpoint = processedContinueFromCheckpoint && state.tokenCount % checkpointInterval === 0; const needsContent = (guardrailEngine && state.tokenCount % guardrailCheckInterval === 0) || (driftDetector && state.tokenCount % driftCheckInterval === 0) || needsCheckpoint; if (needsContent) { state.content = tokenBuffer.join(""); } monitor?.recordToken(state.lastTokenAt); if (needsCheckpoint) { state.checkpoint = state.content; dispatcher.emit(EventType.CHECKPOINT_SAVED, { checkpoint: state.checkpoint, tokenCount: state.tokenCount, }); } if (guardrailEngine && state.tokenCount % guardrailCheckInterval === 0) { const context = { content: state.content, checkpoint: state.checkpoint, delta: token, tokenCount: state.tokenCount, completed: false, }; const result = guardrailEngine.check(context); if (result.violations.length > 0) { state.violations.push(...result.violations); monitor?.recordGuardrailViolations(result.violations); for (let i = 0; i < result.violations.length; i++) { const violation = result.violations[i]; dispatcher.emit(EventType.GUARDRAIL_RULE_RESULT, { index: i, ruleId: violation.rule, passed: false, violation, }); } } if (result.shouldHalt) { throw new L0Error(`Fatal guardrail violation: ${result.violations[0]?.message}`, { code: L0ErrorCodes.FATAL_GUARDRAIL_VIOLATION, checkpoint: state.checkpoint, tokenCount: state.tokenCount, contentLength: state.content.length, modelRetryCount: state.modelRetryCount, networkRetryCount: state.networkRetryCount, fallbackIndex, context: processedContext, metadata: { violation: result.violations[0] }, }); } } if (driftDetector && state.tokenCount % driftCheckInterval === 0) { const drift = driftDetector.check(state.content, token); if (drift.detected) { state.driftDetected = true; monitor?.recordDrift(true, drift.types); dispatcher.emit(EventType.DRIFT_CHECK_RESULT, { detected: true, types: drift.types, confidence: drift.confidence, }); } } const l0Event = { type: "token", value: token, timestamp: Date.now(), }; safeInvokeCallback(processedOnEvent, l0Event, monitor, "onEvent"); yield l0Event; lastTokenEmissionTime = Date.now(); } else if (event.type === "message") { const messageEvent = { type: "message", value: event.value, role: event.role, timestamp: Date.now(), }; if (event.value) { try { const parsed = JSON.parse(event.value); const emitToolCall = (toolCallId, toolName, args) => { stateMachine.transition(RuntimeStates.TOOL_CALL_DETECTED); state.toolCallStartTimes = state.toolCallStartTimes || new Map(); state.toolCallStartTimes.set(toolCallId, Date.now()); state.toolCallNames = state.toolCallNames || new Map(); state.toolCallNames.set(toolCallId, toolName); dispatcher.emit(EventType.TOOL_REQUESTED, { toolName, toolCallId, arguments: args, }); dispatcher.emit(EventType.TOOL_START, { toolCallId, toolName, }); }; const parseArgs = (args) => { if (typeof args === "string") { try { return JSON.parse(args); } catch { return {}; } } return args || {}; }; const emitToolResult = (toolCallId, result, error) => { const startTime = state.toolCallStartTimes?.get(toolCallId); const durationMs = startTime ? Date.now() - startTime : 0; if (error) { dispatcher.emit(EventType.TOOL_ERROR, { toolCallId, error, errorType: "EXECUTION_ERROR", durationMs, }); dispatcher.emit(EventType.TOOL_COMPLETED, { toolCallId, status: "error", }); } else { dispatcher.emit(EventType.TOOL_RESULT, { toolCallId, result, durationMs, }); dispatcher.emit(EventType.TOOL_COMPLETED, { toolCallId, status: "success", }); } state.toolCallStartTimes?.delete(toolCallId); state.toolCallNames?.delete(toolCallId); if (!state.toolCallStartTimes?.size) { stateMachine.transition(RuntimeStates.STREAMING); } }; if (parsed.type === "tool_call" && parsed.id && parsed.name) { emitToolCall(parsed.id, parsed.name, parseArgs(parsed.arguments)); } else if (parsed.type === "tool_calls" && Array.isArray(parsed.tool_calls)) { for (const tc of parsed.tool_calls) { emitToolCall(tc.id, tc.name, parseArgs(tc.arguments)); } } else if (parsed.type === "function_call" && parsed.function_call) { emitToolCall(`fn_${Date.now()}`, parsed.function_call.name, parseArgs(parsed.function_call.arguments)); } else if (parsed.type === "tool_use" && parsed.tool_use) { emitToolCall(parsed.tool_use.id, parsed.tool_use.name, parseArgs(parsed.tool_use.input)); } else if (parsed.type === "tool_call" && parsed.tool_call) { emitToolCall(parsed.tool_call.id, parsed.tool_call.name, parseArgs(parsed.tool_call.arguments)); } else if (parsed.type === "tool_result" && parsed.id) { emitToolResult(parsed.id, parsed.result, parsed.error); } else if (parsed.type === "tool_result" && parsed.tool_result) { emitToolResult(parsed.tool_result.id, parsed.tool_result.result, parsed.tool_result.error); } } catch { } } safeInvokeCallback(processedOnEvent, messageEvent, monitor, "onEvent"); yield messageEvent; } else if (event.type === "data") { if (event.data) { state.dataOutputs.push(event.data); } const dataEvent = { type: "data", data: event.data, timestamp: Date.now(), }; safeInvokeCallback(processedOnEvent, dataEvent, monitor, "onEvent"); yield dataEvent; } else if (event.type === "progress") { state.lastProgress = event.progress; const progressEvent = { type: "progress", progress: event.progress, timestamp: Date.now(), }; safeInvokeCallback(processedOnEvent, progressEvent, monitor, "onEvent"); yield progressEvent; } else if (event.type === "error") { throw event.error || new Error("Stream error"); } else if (event.type === "complete") { break; } } if (initialTimeoutId) { clearTimeout(initialTimeoutId); } if (state.resumed && shouldDeduplicateContinuation && !overlapResolved && overlapBuffer.length > 0) { const overlapResult = detectOverlap(checkpointForContinuation, overlapBuffer, { minOverlap: processedDeduplicationOptions.minOverlap ?? 2, maxOverlap: processedDeduplicationOptions.maxOverlap ?? 500, caseSensitive: processedDeduplicationOptions.caseSensitive ?? true, normalizeWhitespace: processedDeduplicationOptions.normalizeWhitespace ?? false, }); let flushedToken; if (overlapResult.hasOverlap) { flushedToken = overlapResult.deduplicatedContinuation; } else { flushedToken = overlapBuffer; } if (flushedToken.length > 0) { tokenBuffer.push(flushedToken); state.tokenCount++; state.content = tokenBuffer.join(""); if (guardrailEngine) { const context = { content: state.content, checkpoint: state.checkpoint, delta: flushedToken, tokenCount: state.tokenCount, completed: false, }; const result = guardrailEngine.check(context); if (result.violations.length > 0) { state.violations.push(...result.violations); monitor?.recordGuardrailViolations(result.violations); for (let i = 0; i < result.violations.length; i++) { const violation = result.violations[i]; dispatcher.emit(EventType.GUARDRAIL_RULE_RESULT, { index: i, ruleId: violation.rule, passed: false, violation, }); } } if (result.shouldHalt) { throw new L0Error(`Fatal guardrail violation: ${result.violations[0]?.message}`, { code: L0ErrorCodes.FATAL_GUARDRAIL_VIOLATION, checkpoint: state.checkpoint, tokenCount: state.tokenCount, contentLength: state.content.length, modelRetryCount: state.modelRetryCount, networkRetryCount: state.networkRetryCount, fallbackIndex, context: processedContext, metadata: { violation: result.violations[0] }, }); } } if (driftDetector) { const drift = driftDetector.check(state.content, flushedToken); if (drift.detected) { state.driftDetected = true; monitor?.recordDrift(true, drift.types); dispatcher.emit(EventType.DRIFT_CHECK_RESULT, { detected: true, types: drift.types, confidence: drift.confidence, }); } } const flushedEvent = { type: "token", value: flushedToken, timestamp: Date.now(), }; safeInvokeCallback(processedOnEvent, flushedEvent, monitor, "onEvent"); yield flushedEvent; } overlapResolved = true; } state.content = tokenBuffer.join(""); if (processedDetectZeroTokens && detectZeroToken(state.content)) { throw new L0Error("Zero output detected - no meaningful content", { code: L0ErrorCodes.ZERO_OUTPUT, checkpoint: state.checkpoint, tokenCount: state.tokenCount, contentLength: state.content.length, modelRetryCount: state.modelRetryCount, networkRetryCount: state.networkRetryCount, fallbackIndex, context: processedContext, }); } if (guardrailEngine) { const context = { content: state.content, checkpoint: state.checkpoint, tokenCount: state.tokenCount, completed: true, }; const result = guardrailEngine.check(context); if (result.violations.length > 0) { state.violations.push(...result.violations); monitor?.recordGuardrailViolations(result.violations); for (let i = 0; i < result.violations.length; i++) { const violation = result.violations[i]; dispatcher.emit(EventType.GUARDRAIL_RULE_RESULT, { index: i, ruleId: violation.rule, passed: false, violation, }); } } if (result.shouldRetry && retryAttempt < modelRetryLimit) { const violation = result.violations[0]; const reason = `Guardrail violation: ${violation?.message}`; dispatcher.emit(EventType.RETRY_ATTEMPT, { attempt: retryAttempt + 1, maxAttempts: modelRetryLimit, reason, delayMs: 0, countsTowardLimit: true, isNetwork: false, isModelIssue: true, }); retryAttempt++; state.modelRetryCount++; dispatcher.emit(EventType.ATTEMPT_START, { attempt: retryAttempt + 1, isRetry: true, isFallback: fallbackIndex > 0, }); continue; } if (result.shouldHalt) { throw new L0Error(`Fatal guardrail violation: ${result.violations[0]?.message}`, { code: L0ErrorCodes.FATAL_GUARDRAIL_VIOLATION, checkpoint: state.checkpoint, tokenCount: state.tokenCount, contentLength: state.content.length, modelRetryCount: state.modelRetryCount, networkRetryCount: state.networkRetryCount, fallbackIndex, context: processedContext, metadata: { violation: result.violations[0] }, }); } } if (driftDetector) { const finalDrift = driftDetector.check(state.content); if (finalDrift.detected && retryAttempt < modelRetryLimit) { state.driftDetected = true; monitor?.recordDrift(true, finalDrift.types); dispatcher.emit(EventType.DRIFT_CHECK_RESULT, { detected: true, types: finalDrift.types, confidence: finalDrift.confidence, }); dispatcher.emit(EventType.RETRY_ATTEMPT, { attempt: retryAttempt + 1, maxAttempts: modelRetryLimit, reason: "Drift detected", delayMs: 0, countsTowardLimit: true, isNetwork: false, isModelIssue: true, }); monitor?.recordRetry(false); retryAttempt++; state.modelRetryCount++; dispatcher.emit(EventType.ATTEMPT_START, { attempt: retryAttempt + 1, isRetry: true, isFallback: fallbackIndex > 0, }); continue; } } stateMachine.transition(RuntimeStates.FINALIZING); state.completed = true; monitor?.complete(); metrics.completions++; if (state.firstTokenAt) { state.duration = Date.now() - state.firstTokenAt; } const completeEvent = {