@ai2070/l0
Version:
L0: The Missing Reliability Substrate for AI
210 lines • 5.84 kB
JavaScript
export function normalizeStreamEvent(chunk) {
if (!chunk) {
return {
type: "error",
error: new Error("Received null or undefined chunk"),
timestamp: Date.now(),
};
}
if (isL0Event(chunk)) {
return chunk;
}
if (chunk.type) {
switch (chunk.type) {
case "text-delta":
case "content-delta":
return {
type: "token",
value: chunk.textDelta || chunk.delta || chunk.content || "",
timestamp: Date.now(),
};
case "finish":
case "complete":
case "message_stop":
case "content_block_stop":
return {
type: "complete",
timestamp: Date.now(),
};
case "error":
return {
type: "error",
error: chunk.error || new Error(chunk.message || "Stream error"),
timestamp: Date.now(),
};
case "tool-call":
case "function-call":
return {
type: "message",
value: JSON.stringify(chunk),
role: "assistant",
timestamp: Date.now(),
};
default:
const text = extractTextFromChunk(chunk);
if (text) {
return {
type: "token",
value: text,
timestamp: Date.now(),
};
}
return {
type: "error",
error: new Error(`Unknown chunk type: ${chunk.type}`),
timestamp: Date.now(),
};
}
}
if (chunk.choices && Array.isArray(chunk.choices)) {
const choice = chunk.choices[0];
if (choice?.delta?.content) {
return {
type: "token",
value: choice.delta.content,
timestamp: Date.now(),
};
}
if (choice?.finish_reason) {
return {
type: "complete",
timestamp: Date.now(),
};
}
}
if (chunk.delta?.text) {
return {
type: "token",
value: chunk.delta.text,
timestamp: Date.now(),
};
}
if (chunk.type === "message_stop" || chunk.type === "content_block_stop") {
return {
type: "complete",
timestamp: Date.now(),
};
}
if (typeof chunk === "string") {
return {
type: "token",
value: chunk,
timestamp: Date.now(),
};
}
const text = extractTextFromChunk(chunk);
if (text) {
return {
type: "token",
value: text,
timestamp: Date.now(),
};
}
return {
type: "error",
error: new Error(`Unable to normalize chunk: ${JSON.stringify(chunk)}`),
timestamp: Date.now(),
};
}
function isL0Event(obj) {
return (obj &&
typeof obj === "object" &&
"type" in obj &&
(obj.type === "token" ||
obj.type === "message" ||
obj.type === "data" ||
obj.type === "progress" ||
obj.type === "error" ||
obj.type === "complete"));
}
function extractTextFromChunk(chunk) {
if (!chunk || typeof chunk !== "object") {
return null;
}
const textFields = [
"text",
"content",
"delta",
"textDelta",
"token",
"message",
"data",
];
for (const field of textFields) {
if (chunk[field] && typeof chunk[field] === "string") {
return chunk[field];
}
}
if (chunk.delta && typeof chunk.delta === "object") {
for (const field of textFields) {
if (chunk.delta[field] && typeof chunk.delta[field] === "string") {
return chunk.delta[field];
}
}
}
return null;
}
export function normalizeError(error) {
const err = error instanceof Error ? error : new Error(String(error));
return {
type: "error",
error: err,
timestamp: Date.now(),
};
}
export function createTokenEvent(value) {
return {
type: "token",
value,
timestamp: Date.now(),
};
}
export function createMessageEvent(value, role) {
return {
type: "message",
value,
role,
timestamp: Date.now(),
};
}
export function createCompleteEvent() {
return {
type: "complete",
timestamp: Date.now(),
};
}
export function createErrorEvent(error) {
return {
type: "error",
error,
timestamp: Date.now(),
};
}
export function normalizeStreamEvents(chunks) {
return chunks.map((chunk) => normalizeStreamEvent(chunk));
}
export function filterEventsByType(events, type) {
return events.filter((event) => event.type === type);
}
export function extractTokens(events) {
return events
.filter((event) => event.type === "token" && event.value)
.map((event) => event.value);
}
export function reconstructText(events) {
return extractTokens(events).join("");
}
export function isErrorEvent(event) {
return event.type === "error";
}
export function isCompleteEvent(event) {
return event.type === "complete";
}
export function isTokenEvent(event) {
return event.type === "token";
}
export function getFirstError(events) {
const errorEvent = events.find((event) => event.type === "error");
return errorEvent?.error || null;
}
//# sourceMappingURL=events.js.map