@ai2070/l0
Version:
L0: The Missing Reliability Substrate for AI
307 lines • 10.5 kB
JavaScript
import { EventType } from "../types/observability";
export 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);
}
}
startExecution(name = "l0.execution", metadata) {
this.sentry.addBreadcrumb({
type: "info",
category: "l0",
message: "L0 execution started",
data: metadata,
level: "info",
timestamp: Date.now() / 1000,
});
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 undefined;
}
startStream() {
this.sentry.addBreadcrumb({
type: "info",
category: "l0.stream",
message: "Stream started",
level: "info",
timestamp: Date.now() / 1000,
});
}
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() / 1000,
});
}
}
recordFirstToken(ttft) {
this.sentry.addBreadcrumb({
type: "info",
category: "l0.stream",
message: `First token received`,
data: { ttft_ms: ttft },
level: "info",
timestamp: Date.now() / 1000,
});
}
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() / 1000,
});
if (this.config.captureNetworkErrors && !retried) {
this.sentry.captureException(error, {
tags: {
error_type: errorType,
component: "l0.network",
},
extra: {
retried,
},
});
}
}
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() / 1000,
});
}
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() / 1000,
});
if (this.config.captureGuardrailViolations &&
this.shouldCapture(violation.severity)) {
this.sentry.captureMessage(`Guardrail violation: ${violation.message}`, this.mapSeverity(violation.severity));
}
}
}
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() / 1000,
});
}
}
completeStream(tokenCount) {
this.sentry.addBreadcrumb({
type: "info",
category: "l0.stream",
message: "Stream completed",
data: { token_count: tokenCount },
level: "info",
timestamp: Date.now() / 1000,
});
}
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() / 1000,
});
}
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,
}
: undefined,
},
});
}
recordFromMonitor(monitor) {
const telemetry = monitor.getTelemetry();
if (telemetry) {
this.completeExecution(telemetry);
}
}
mapSeverity(severity) {
switch (severity) {
case "fatal":
return "fatal";
case "error":
return "error";
case "warning":
return "warning";
default:
return "info";
}
}
shouldCapture(severity) {
const levels = ["warning", "error", "fatal"];
const minIndex = levels.indexOf(this.config.minGuardrailSeverity);
const currentIndex = levels.indexOf(severity);
return currentIndex >= minIndex;
}
}
export function createSentryIntegration(config) {
return new L0Sentry(config);
}
export 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 = undefined;
break;
}
default:
break;
}
};
}
export 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;
}
}
//# sourceMappingURL=sentry.js.map