UNPKG

@ai2070/l0

Version:

L0: The Missing Reliability Substrate for AI

369 lines (368 loc) 9.56 kB
import { EventType } from "../types/observability"; class L0Sentry { sentry; config; constructor(config) { this.sentry = config.sentry; this.config = { captureNetworkErrors: config.captureNetworkErrors ?? true, captureGuardrailViolations: config.captureGuardrailViolations ?? true, minGuardrailSeverity: config.minGuardrailSeverity ?? "error", breadcrumbsForTokens: config.breadcrumbsForTokens ?? false, enableTracing: config.enableTracing ?? true, tags: config.tags, environment: config.environment }; if (this.config.tags) { for (const [key, value] of Object.entries(this.config.tags)) { this.sentry.setTag(key, value); } } if (this.config.environment) { this.sentry.setTag("environment", this.config.environment); } } /** * Start tracking an L0 execution * Returns a span finish function if tracing is enabled */ startExecution(name = "l0.execution", metadata) { this.sentry.addBreadcrumb({ type: "info", category: "l0", message: "L0 execution started", data: metadata, level: "info", timestamp: Date.now() / 1e3 }); if (this.config.enableTracing && this.sentry.startSpan) { let finishSpan; this.sentry.startSpan( { name, op: "l0.execution", attributes: metadata }, (span) => { finishSpan = () => span?.end(); } ); return finishSpan; } return void 0; } /** * Start tracking stream consumption */ startStream() { this.sentry.addBreadcrumb({ type: "info", category: "l0.stream", message: "Stream started", level: "info", timestamp: Date.now() / 1e3 }); } /** * Record a token received */ recordToken(token) { if (this.config.breadcrumbsForTokens) { this.sentry.addBreadcrumb({ type: "debug", category: "l0.token", message: token ? `Token: ${token.slice(0, 50)}` : "Token received", level: "debug", timestamp: Date.now() / 1e3 }); } } /** * Record first token (TTFT) */ recordFirstToken(ttft) { this.sentry.addBreadcrumb({ type: "info", category: "l0.stream", message: `First token received`, data: { ttft_ms: ttft }, level: "info", timestamp: Date.now() / 1e3 }); } /** * Record a network error */ recordNetworkError(error, errorType, retried) { this.sentry.addBreadcrumb({ type: "error", category: "l0.network", message: `Network error: ${errorType}`, data: { error_type: errorType, message: error.message, retried }, level: "error", timestamp: Date.now() / 1e3 }); if (this.config.captureNetworkErrors && !retried) { this.sentry.captureException(error, { tags: { error_type: errorType, component: "l0.network" }, extra: { retried } }); } } /** * Record a retry attempt */ recordRetry(attempt, reason, isNetworkError) { this.sentry.addBreadcrumb({ type: "info", category: "l0.retry", message: `Retry attempt ${attempt}`, data: { attempt, reason, is_network_error: isNetworkError }, level: "warning", timestamp: Date.now() / 1e3 }); } /** * Record guardrail violations */ recordGuardrailViolations(violations) { for (const violation of violations) { this.sentry.addBreadcrumb({ type: "error", category: "l0.guardrail", message: `Guardrail violation: ${violation.rule}`, data: { rule: violation.rule, severity: violation.severity, message: violation.message, recoverable: violation.recoverable }, level: this.mapSeverity(violation.severity), timestamp: Date.now() / 1e3 }); if (this.config.captureGuardrailViolations && this.shouldCapture(violation.severity)) { this.sentry.captureMessage( `Guardrail violation: ${violation.message}`, this.mapSeverity(violation.severity) ); } } } /** * Record drift detection */ recordDrift(detected, types) { if (detected) { this.sentry.addBreadcrumb({ type: "error", category: "l0.drift", message: `Drift detected: ${types.join(", ")}`, data: { types }, level: "warning", timestamp: Date.now() / 1e3 }); } } /** * Complete stream tracking */ completeStream(tokenCount) { this.sentry.addBreadcrumb({ type: "info", category: "l0.stream", message: "Stream completed", data: { token_count: tokenCount }, level: "info", timestamp: Date.now() / 1e3 }); } /** * Complete execution tracking */ completeExecution(telemetry) { this.sentry.setContext("l0_telemetry", { session_id: telemetry.sessionId, duration_ms: telemetry.duration, tokens: telemetry.metrics.totalTokens, tokens_per_second: telemetry.metrics.tokensPerSecond, ttft_ms: telemetry.metrics.timeToFirstToken, retries: telemetry.metrics.totalRetries, network_errors: telemetry.network.errorCount, guardrail_violations: telemetry.guardrails?.violationCount ?? 0 }); this.sentry.addBreadcrumb({ type: "info", category: "l0", message: "L0 execution completed", data: { duration_ms: telemetry.duration, tokens: telemetry.metrics.totalTokens, retries: telemetry.metrics.totalRetries }, level: "info", timestamp: Date.now() / 1e3 }); } /** * Record execution failure */ recordFailure(error, telemetry) { if (telemetry) { this.sentry.setContext("l0_telemetry", { session_id: telemetry.sessionId, duration_ms: telemetry.duration, tokens: telemetry.metrics.totalTokens, retries: telemetry.metrics.totalRetries, network_errors: telemetry.network.errorCount }); } this.sentry.captureException(error, { tags: { component: "l0" }, extra: { telemetry: telemetry ? { session_id: telemetry.sessionId, duration_ms: telemetry.duration, tokens: telemetry.metrics.totalTokens } : void 0 } }); } /** * Record from L0Monitor */ recordFromMonitor(monitor) { const telemetry = monitor.getTelemetry(); if (telemetry) { this.completeExecution(telemetry); } } /** * Map guardrail severity to Sentry severity */ mapSeverity(severity) { switch (severity) { case "fatal": return "fatal"; case "error": return "error"; case "warning": return "warning"; default: return "info"; } } /** * Check if severity meets capture threshold */ shouldCapture(severity) { const levels = ["warning", "error", "fatal"]; const minIndex = levels.indexOf(this.config.minGuardrailSeverity); const currentIndex = levels.indexOf(severity); return currentIndex >= minIndex; } } function createSentryIntegration(config) { return new L0Sentry(config); } function createSentryHandler(config) { const integration = createSentryIntegration(config); let finishSpan; return (event) => { switch (event.type) { case EventType.SESSION_START: { const e = event; finishSpan = integration.startExecution("l0.execution", { attempt: e.attempt, isRetry: e.isRetry, isFallback: e.isFallback }); integration.startStream(); break; } case EventType.RETRY_ATTEMPT: { const e = event; integration.recordRetry(e.attempt, e.reason, e.isNetwork ?? false); break; } case EventType.NETWORK_ERROR: { const e = event; integration.recordNetworkError( new Error(e.error), e.category || "unknown", e.retryable ?? false ); break; } case EventType.ERROR: { const e = event; integration.recordNetworkError( new Error(e.error), e.failureType || "unknown", e.recoveryStrategy === "retry" ); break; } case EventType.GUARDRAIL_RULE_RESULT: { const e = event; if (e.violation) { integration.recordGuardrailViolations([e.violation]); } break; } case EventType.DRIFT_CHECK_RESULT: { const e = event; if (e.detected) { integration.recordDrift(true, e.types); } break; } case EventType.COMPLETE: { const e = event; integration.completeStream(e.tokenCount); finishSpan?.(); finishSpan = void 0; break; } default: break; } }; } async function withSentry(config, fn) { const integration = createSentryIntegration(config); integration.startExecution(); try { const result = await fn(); if (result.telemetry) { integration.completeExecution(result.telemetry); } return result; } catch (error) { integration.recordFailure( error instanceof Error ? error : new Error(String(error)) ); throw error; } } export { L0Sentry, createSentryHandler, createSentryIntegration, withSentry }; //# sourceMappingURL=sentry.js.map