UNPKG

assistant-stream

Version:

Streaming utilities for AI assistants

77 lines (66 loc) • 1.86 kB
import type { AssistantStreamChunk } from "../../AssistantStreamChunk"; import { Counter } from "../Counter"; export class PathAppendEncoder extends TransformStream< AssistantStreamChunk, AssistantStreamChunk > { constructor( idx: number | { value: number | undefined; promise: Promise<number> }, ) { super({ transform(chunk, controller) { const append = (partIndex: number) => controller.enqueue({ ...chunk, path: [partIndex, ...chunk.path], }); if (typeof idx === "number") { return append(idx); } else if (idx.value !== undefined) { return append(idx.value); } else { return idx.promise.then(append); } }, }); } } export class PathAppendDecoder extends TransformStream< AssistantStreamChunk, AssistantStreamChunk > { constructor(idx: number) { super({ transform(chunk, controller) { const { path: [idx2, ...path], } = chunk; if (idx !== idx2) throw new Error(`Path mismatch: expected ${idx}, got ${idx2}`); controller.enqueue({ ...chunk, path, }); }, }); } } export const createPathMergeMapper = ( nextPartIndex: () => number, ): ((chunk: AssistantStreamChunk) => AssistantStreamChunk) => { const innerCounter = new Counter(); const mapping = new Map<number, number>(); return (chunk) => { if (chunk.type === "part-start" && chunk.path.length === 0) { mapping.set(innerCounter.up(), nextPartIndex()); } const [idx, ...path] = chunk.path; if (idx === undefined) return chunk; const mappedIdx = mapping.get(idx); if (mappedIdx === undefined) throw new Error("Path not found"); return { ...chunk, path: [mappedIdx, ...path], }; }; };