@ai2070/l0
Version:
L0: The Missing Reliability Substrate for AI
897 lines (896 loc) • 68.5 kB
JavaScript
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 = {