UNPKG

assistant-stream

Version:

Streaming utilities for AI assistants

83 lines (77 loc) • 2.28 kB
import type { AssistantStreamChunk, PartInit, } from "../../AssistantStreamChunk"; /** * For chunk types that are associated with a part, * we require a non‑nullable meta field. */ export type AssistantMetaStreamChunk = | (AssistantStreamChunk & { type: "text-delta" | "part-finish"; meta: PartInit; }) | (AssistantStreamChunk & { type: "result" | "tool-call-args-text-finish" | "tool-call-approval"; meta: PartInit & { type: "tool-call" }; }) | (AssistantStreamChunk & { type: Exclude< AssistantStreamChunk["type"], | "text-delta" | "result" | "tool-call-args-text-finish" | "tool-call-approval" | "part-finish" >; }); export class AssistantMetaTransformStream extends TransformStream< AssistantStreamChunk, AssistantMetaStreamChunk > { constructor() { // We use an array to record parts as they are introduced. const parts: PartInit[] = []; super({ transform(chunk, controller) { // For chunks that introduce a new part. if (chunk.type === "part-start") { if (chunk.path.length !== 0) { controller.error(new Error("Nested parts are not supported")); return; } parts.push(chunk.part); controller.enqueue(chunk); return; } // For chunks that expect an associated part. if ( chunk.type === "text-delta" || chunk.type === "result" || chunk.type === "part-finish" || chunk.type === "tool-call-args-text-finish" || chunk.type === "tool-call-approval" ) { if (chunk.path.length !== 1) { controller.error( new Error(`${chunk.type} chunks must have a path of length 1`), ); return; } const idx = chunk.path[0]!; if (idx < 0 || idx >= parts.length) { controller.error(new Error(`Invalid path index: ${idx}`)); return; } const part = parts[idx]!; controller.enqueue({ ...chunk, meta: part as any, // TODO }); return; } controller.enqueue(chunk); }, }); } }