@varo-ui/ai 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["node"],"sources":["../src/text-stream.ts","../src/agent-stream.ts","../src/event-channel.ts","../src/type-guards.ts","../src/event-parser.ts","../src/markdown.ts","../src/markdown-view.ts","../src/sse.ts"],"sourcesContent":["import { createSmoothMarkdownStream } from 'markstream-core'\nimport type { TextStreamController, TextStreamOptions, TextStreamSnapshot } from './types'\n\ninterface SegmenterLike {\n segment: (value: string) => Iterable<{ segment: string }>\n}\n\nfunction splitGraphemes(value: string): string[] {\n const intlRuntime: unknown = Intl\n if (\n typeof intlRuntime !== 'object'\n || intlRuntime === null\n || !('Segmenter' in intlRuntime)\n || typeof intlRuntime.Segmenter !== 'function'\n ) {\n return Array.from(value)\n }\n\n // Runtime constructor shape is checked above; TypeScript's configured Intl lib omits Segmenter.\n const Segmenter = intlRuntime.Segmenter as new (\n locale?: string,\n options?: { granularity: 'grapheme' }\n ) => SegmenterLike\n return Array.from(new Segmenter(undefined, { granularity: 'grapheme' }).segment(value), (item) => item.segment)\n}\n\nfunction clamp(value: number, min: number, max: number) {\n return Math.min(max, Math.max(min, value))\n}\n\nfunction createTimerTextStream(options: TextStreamOptions = {}): TextStreamController {\n const minCharsPerSecond = Math.max(1, options.minCharsPerSecond ?? 40)\n const maxCharsPerSecond = Math.max(minCharsPerSecond, options.maxCharsPerSecond ?? 800)\n const targetLatencyMs = Math.max(50, options.targetLatencyMs ?? 700)\n const maxCommitFps = Math.max(1, Math.min(30, options.maxCommitFps ?? 20))\n const maxCharsPerCommit = Math.max(1, options.maxCharsPerCommit ?? 64)\n const catchUpThreshold = Math.max(1, options.catchUpThreshold ?? 320)\n const listeners = new Set<() => void>()\n const pending: string[] = []\n let pendingOffset = 0\n let source = ''\n let visible = ''\n let done = false\n let paused = false\n let destroyed = false\n let timer: ReturnType<typeof setTimeout> | undefined\n let lastTick = Date.now()\n let budget = 0\n\n function pendingCount() {\n return pending.length - pendingOffset\n }\n\n function snapshot(): TextStreamSnapshot {\n const pendingChars = pendingCount()\n return {\n caughtUp: pendingChars === 0,\n done,\n final: done && pendingChars === 0,\n paused,\n pendingChars,\n source,\n visible\n }\n }\n\n function emit() {\n listeners.forEach((listener) => listener())\n }\n\n function compactPending() {\n if (pendingOffset < 1024 || pendingOffset * 2 < pending.length) return\n pending.splice(0, pendingOffset)\n pendingOffset = 0\n }\n\n function schedule() {\n if (destroyed || paused || timer || pendingCount() === 0) return\n timer = setTimeout(tick, Math.ceil(1000 / maxCommitFps))\n }\n\n function tick() {\n timer = undefined\n if (destroyed || paused) return\n\n const now = Date.now()\n const deltaMs = Math.max(1, now - lastTick)\n lastTick = now\n const backlog = pendingCount()\n if (backlog === 0) {\n emit()\n return\n }\n\n const latencyCps = (backlog * 1000) / targetLatencyMs\n const catchUpBoost = backlog >= catchUpThreshold ? 1.8 : 1\n const cps = clamp(latencyCps * catchUpBoost, minCharsPerSecond, maxCharsPerSecond)\n budget += (cps * deltaMs) / 1000\n const commitCount = Math.min(backlog, maxCharsPerCommit, Math.max(1, Math.floor(budget)))\n budget = Math.max(0, budget - commitCount)\n visible += pending.slice(pendingOffset, pendingOffset + commitCount).join('')\n pendingOffset += commitCount\n compactPending()\n emit()\n schedule()\n }\n\n function cancelTimer() {\n clearTimeout(timer)\n timer = undefined\n }\n\n return {\n destroy() {\n if (destroyed) return\n destroyed = true\n cancelTimer()\n pending.length = 0\n listeners.clear()\n },\n enqueue(chunk) {\n if (destroyed || !chunk) return\n if (done) done = false\n source += chunk\n pending.push(...splitGraphemes(chunk))\n lastTick = Date.now()\n emit()\n schedule()\n },\n finish(finishOptions = {}) {\n if (destroyed) return\n done = true\n if (finishOptions.flush) {\n visible = source\n pending.length = 0\n pendingOffset = 0\n cancelTimer()\n }\n emit()\n schedule()\n },\n flush() {\n if (destroyed) return\n visible = source\n pending.length = 0\n pendingOffset = 0\n budget = 0\n cancelTimer()\n emit()\n },\n getSnapshot: snapshot,\n pause() {\n if (destroyed || paused) return\n paused = true\n cancelTimer()\n emit()\n },\n reset(content = '') {\n cancelTimer()\n source = content\n visible = content\n pending.length = 0\n pendingOffset = 0\n done = false\n paused = false\n budget = 0\n lastTick = Date.now()\n emit()\n },\n resume() {\n if (destroyed || !paused) return\n paused = false\n lastTick = Date.now()\n emit()\n schedule()\n },\n subscribe(listener) {\n if (destroyed) return () => {}\n listeners.add(listener)\n return () => listeners.delete(listener)\n }\n }\n}\n\nexport function createTextStream(options: TextStreamOptions = {}): TextStreamController {\n if (typeof requestAnimationFrame !== 'function' || typeof cancelAnimationFrame !== 'function') {\n return createTimerTextStream(options)\n }\n\n const controller = createSmoothMarkdownStream(options)\n return {\n destroy: controller.destroy,\n enqueue: controller.enqueue,\n finish: controller.finish,\n flush: controller.flush,\n getSnapshot: controller.getSnapshot,\n pause: controller.pause,\n reset: controller.reset,\n resume: controller.resume,\n subscribe: controller.subscribe\n }\n}\n","import { createTextStream } from './text-stream'\nimport type {\n AgentApprovalPart,\n AgentErrorEvent,\n AgentReasoningPart,\n AgentStreamController,\n AgentStreamEvent,\n AgentStreamSnapshot,\n AgentToolPart,\n TextStreamOptions\n} from './types'\n\nexport interface AgentStreamControllerOptions {\n text?: TextStreamOptions\n}\n\nfunction initialSnapshot(): AgentStreamSnapshot {\n return {\n data: [],\n eventCount: 0,\n reasoning: [],\n status: 'idle',\n tools: []\n }\n}\n\nexport function createAgentStreamController(\n options: AgentStreamControllerOptions = {}\n): AgentStreamController {\n const text = createTextStream(options.text)\n const listeners = new Set<() => void>()\n let snapshot = initialSnapshot()\n let destroyed = false\n let cancelled = false\n let transportDone = false\n let connecting = false\n let cancelActiveConnect: (() => void) | undefined\n\n function emit() {\n listeners.forEach((listener) => listener())\n }\n\n function setSnapshot(update: Partial<AgentStreamSnapshot>) {\n snapshot = { ...snapshot, ...update }\n emit()\n }\n\n function updateReasoning(id: string, update: Partial<AgentReasoningPart>) {\n setSnapshot({\n reasoning: snapshot.reasoning.map((part) => (part.id === id ? { ...part, ...update } : part))\n })\n }\n\n function updateTool(id: string, update: Partial<AgentToolPart>) {\n setSnapshot({\n tools: snapshot.tools.map((part) => (part.id === id ? { ...part, ...update } : part))\n })\n }\n\n function finalStatus() {\n const textSnapshot = text.getSnapshot()\n if (!transportDone || !textSnapshot.final) return\n setSnapshot({ status: snapshot.error ? 'failed' : cancelled ? 'cancelled' : 'completed' })\n }\n\n const unsubscribeText = text.subscribe(() => {\n if (destroyed || !snapshot.message) return\n const textSnapshot = text.getSnapshot()\n snapshot = {\n ...snapshot,\n message: {\n ...snapshot.message,\n final: textSnapshot.final,\n source: textSnapshot.source,\n visible: textSnapshot.visible\n }\n }\n emit()\n finalStatus()\n })\n\n function push(event: AgentStreamEvent) {\n if (destroyed || cancelled) return\n snapshot = { ...snapshot, eventCount: snapshot.eventCount + 1 }\n\n switch (event.type) {\n case 'message.start':\n transportDone = false\n text.reset()\n setSnapshot({\n error: undefined,\n message: {\n final: false,\n id: event.messageId,\n role: event.role,\n source: '',\n visible: ''\n },\n status: 'streaming'\n })\n break\n case 'text.delta':\n if (snapshot.message?.id === event.messageId) text.enqueue(event.delta)\n break\n case 'message.end':\n if (snapshot.message?.id === event.messageId) text.finish()\n break\n case 'reasoning.start':\n setSnapshot({\n reasoning: [\n ...snapshot.reasoning,\n { content: '', id: event.id, status: 'running', title: event.title }\n ]\n })\n break\n case 'reasoning.delta': {\n const part = snapshot.reasoning.find((item) => item.id === event.id)\n if (part) updateReasoning(event.id, { content: `${part.content}${event.delta}` })\n break\n }\n case 'reasoning.end':\n updateReasoning(event.id, { durationMs: event.durationMs, status: 'completed' })\n break\n case 'tool.start':\n setSnapshot({\n tools: [\n ...snapshot.tools,\n {\n id: event.id,\n input: event.input,\n name: event.name,\n status: 'running',\n summary: event.summary\n }\n ]\n })\n break\n case 'tool.update':\n updateTool(event.id, { summary: event.summary })\n break\n case 'tool.result':\n updateTool(event.id, {\n output: event.output,\n status: 'completed',\n summary: event.summary\n })\n break\n case 'tool.error':\n updateTool(event.id, { error: event.error, status: 'failed' })\n break\n case 'approval.required': {\n const approval: AgentApprovalPart = {\n choices: event.choices ?? [],\n description: event.description,\n id: event.id,\n status: 'waiting',\n title: event.title\n }\n setSnapshot({ approval, status: 'waiting' })\n break\n }\n case 'approval.resolved':\n if (snapshot.approval?.id === event.id) {\n setSnapshot({\n approval: {\n ...snapshot.approval,\n resolvedValue: event.value,\n status: 'completed'\n },\n status: 'streaming'\n })\n }\n break\n case 'data':\n setSnapshot({ data: [...snapshot.data, { name: event.name, value: event.value }] })\n break\n case 'error':\n transportDone = true\n text.finish({ flush: true })\n setSnapshot({ error: event, status: 'failed' })\n break\n case 'done':\n transportDone = true\n text.finish()\n setSnapshot({ usage: event.usage })\n if (!snapshot.message) setSnapshot({ status: 'completed' })\n finalStatus()\n break\n }\n }\n\n async function waitForTerminal() {\n if (snapshot.status === 'completed' || snapshot.status === 'failed' || snapshot.status === 'cancelled') {\n return snapshot\n }\n\n return await new Promise<AgentStreamSnapshot>((resolve) => {\n const unsubscribe = subscribe(() => {\n if (snapshot.status !== 'completed' && snapshot.status !== 'failed' && snapshot.status !== 'cancelled') return\n unsubscribe()\n resolve(snapshot)\n })\n })\n }\n\n function subscribe(listener: () => void) {\n if (destroyed) return () => {}\n listeners.add(listener)\n return () => listeners.delete(listener)\n }\n\n function reset() {\n text.reset()\n snapshot = initialSnapshot()\n cancelled = false\n transportDone = false\n emit()\n }\n\n function cancel(reason = 'Cancelled') {\n if (destroyed || cancelled) return\n cancelled = true\n transportDone = true\n text.finish({ flush: true })\n const error: AgentErrorEvent = { code: 'cancelled', message: reason, retryable: true, type: 'error' }\n setSnapshot({ error, status: 'cancelled' })\n cancelActiveConnect?.()\n }\n\n return {\n cancel,\n async connect(events) {\n if (connecting) throw new Error('Agent stream controller is already connected')\n connecting = true\n reset()\n const iterator = events[Symbol.asyncIterator]()\n let resolveCancellation: (() => void) | undefined\n const cancellation = new Promise<void>((resolve) => {\n resolveCancellation = resolve\n })\n cancelActiveConnect = resolveCancellation\n\n try {\n try {\n while (!cancelled && !destroyed) {\n const outcome = await Promise.race([\n iterator.next().then((result) => ({ kind: 'event' as const, result })),\n cancellation.then(() => ({ kind: 'cancelled' as const }))\n ])\n if (outcome.kind === 'cancelled' || outcome.result.done) break\n push(outcome.result.value)\n }\n if (!transportDone && !cancelled && !destroyed) push({ type: 'done' })\n } catch (error) {\n push({\n message: error instanceof Error ? error.message : String(error),\n retryable: true,\n type: 'error'\n })\n } finally {\n if (cancelled || destroyed) void iterator.return?.()\n }\n return await waitForTerminal()\n } finally {\n connecting = false\n cancelActiveConnect = undefined\n }\n },\n destroy() {\n if (destroyed) return\n cancel('Agent stream controller destroyed')\n destroyed = true\n unsubscribeText()\n text.destroy()\n listeners.clear()\n },\n getSnapshot() {\n return snapshot\n },\n push,\n reset,\n subscribe\n }\n}\n","import type { AgentEventChannel, AgentStreamEvent } from './types'\n\nexport function createAgentEventChannel(): AgentEventChannel {\n const queue: AgentStreamEvent[] = []\n let ended = false\n let failure: Error | undefined\n let wake: (() => void) | undefined\n\n async function* iterate(): AsyncGenerator<AgentStreamEvent> {\n while (!ended || queue.length > 0) {\n if (failure) throw failure\n const event = queue.shift()\n if (event) {\n yield event\n continue\n }\n\n await new Promise<void>((resolve) => {\n wake = resolve\n })\n wake = undefined\n }\n if (failure) throw failure\n }\n\n function notify() {\n wake?.()\n }\n\n return {\n end() {\n ended = true\n notify()\n },\n fail(error) {\n failure = error instanceof Error ? error : new Error(String(error))\n ended = true\n notify()\n },\n push(event) {\n if (ended) return\n queue.push(event)\n notify()\n },\n source: {\n [Symbol.asyncIterator]: iterate\n }\n }\n}\n","export function isUnknownRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n","import { isUnknownRecord } from './type-guards'\nimport type { AgentApprovalRequiredEvent, AgentStreamEvent } from './types'\n\n\nfunction requiredString(value: Record<string, unknown>, key: string): string {\n const field = value[key]\n if (typeof field !== 'string' || field.length === 0) {\n throw new TypeError(`Agent stream event field \"${key}\" must be a non-empty string`)\n }\n return field\n}\n\nfunction optionalString(value: Record<string, unknown>, key: string): string | undefined {\n const field = value[key]\n if (field === undefined) return undefined\n if (typeof field !== 'string') throw new TypeError(`Agent stream event field \"${key}\" must be a string`)\n return field\n}\n\nfunction optionalBoolean(value: Record<string, unknown>, key: string): boolean | undefined {\n const field = value[key]\n if (field === undefined) return undefined\n if (typeof field !== 'boolean') throw new TypeError(`Agent stream event field \"${key}\" must be a boolean`)\n return field\n}\n\nfunction optionalNumber(value: Record<string, unknown>, key: string): number | undefined {\n const field = value[key]\n if (field === undefined) return undefined\n if (typeof field !== 'number' || !Number.isFinite(field)) {\n throw new TypeError(`Agent stream event field \"${key}\" must be a finite number`)\n }\n return field\n}\n\nfunction parseChoices(value: unknown): AgentApprovalRequiredEvent['choices'] {\n if (value === undefined) return undefined\n if (!Array.isArray(value)) throw new TypeError('Agent approval choices must be an array')\n\n return value.map((choice) => {\n if (!isUnknownRecord(choice)) throw new TypeError('Agent approval choice must be an object')\n return {\n description: optionalString(choice, 'description'),\n disabled: optionalBoolean(choice, 'disabled'),\n label: requiredString(choice, 'label'),\n value: requiredString(choice, 'value')\n }\n })\n}\n\nexport function parseAgentStreamEvent(value: unknown): AgentStreamEvent {\n if (!isUnknownRecord(value) || typeof value.type !== 'string') {\n throw new TypeError('Agent stream event must be an object with a string type')\n }\n\n switch (value.type) {\n case 'message.start': {\n const role = requiredString(value, 'role')\n if (role !== 'assistant' && role !== 'system' && role !== 'user') {\n throw new TypeError(`Unsupported agent message role: ${role}`)\n }\n return { messageId: requiredString(value, 'messageId'), role, type: value.type }\n }\n case 'text.delta':\n return {\n delta: requiredString(value, 'delta'),\n messageId: requiredString(value, 'messageId'),\n type: value.type\n }\n case 'message.end':\n return { messageId: requiredString(value, 'messageId'), type: value.type }\n case 'reasoning.start':\n return {\n id: requiredString(value, 'id'),\n title: requiredString(value, 'title'),\n type: value.type\n }\n case 'reasoning.delta':\n return {\n delta: requiredString(value, 'delta'),\n id: requiredString(value, 'id'),\n type: value.type\n }\n case 'reasoning.end':\n return {\n durationMs: optionalNumber(value, 'durationMs'),\n id: requiredString(value, 'id'),\n type: value.type\n }\n case 'tool.start':\n return {\n id: requiredString(value, 'id'),\n input: value.input,\n name: requiredString(value, 'name'),\n summary: optionalString(value, 'summary'),\n type: value.type\n }\n case 'tool.update':\n return {\n id: requiredString(value, 'id'),\n summary: optionalString(value, 'summary'),\n type: value.type\n }\n case 'tool.result':\n return {\n id: requiredString(value, 'id'),\n output: value.output,\n summary: optionalString(value, 'summary'),\n type: value.type\n }\n case 'tool.error':\n return {\n error: requiredString(value, 'error'),\n id: requiredString(value, 'id'),\n type: value.type\n }\n case 'approval.required':\n return {\n choices: parseChoices(value.choices),\n description: optionalString(value, 'description'),\n id: requiredString(value, 'id'),\n title: requiredString(value, 'title'),\n type: value.type\n }\n case 'approval.resolved':\n return {\n id: requiredString(value, 'id'),\n type: value.type,\n value: requiredString(value, 'value')\n }\n case 'data':\n if (!('value' in value)) throw new TypeError('Agent data event must include a value field')\n return { name: requiredString(value, 'name'), type: value.type, value: value.value }\n case 'error':\n return {\n code: optionalString(value, 'code'),\n message: requiredString(value, 'message'),\n retryable: optionalBoolean(value, 'retryable'),\n type: value.type\n }\n case 'done': {\n const usage = value.usage\n if (usage !== undefined && !isUnknownRecord(usage)) {\n throw new TypeError('Agent done usage must be an object')\n }\n return {\n type: value.type,\n usage: usage\n ? {\n inputTokens: optionalNumber(usage, 'inputTokens'),\n outputTokens: optionalNumber(usage, 'outputTokens')\n }\n : undefined\n }\n }\n default:\n throw new TypeError(`Unsupported agent stream event type: ${value.type}`)\n }\n}\n","import {\n getMarkdown,\n isUnsafeHtmlUrl,\n parseMarkdownToStructure,\n type GetMarkdownOptions,\n type ParsedNode\n} from 'stream-markdown-parser'\n\nexport interface StreamingMarkdownParserOptions {\n customHtmlTags?: readonly string[]\n enableMath?: boolean\n includeSourceMap?: boolean\n markdownItOptions?: GetMarkdownOptions['markdownItOptions']\n validateLink?: (url: string) => boolean\n}\n\nexport interface StreamingMarkdownParser {\n parse: (content: string, options?: { final?: boolean }) => ParsedNode[]\n reset: () => void\n}\n\nlet parserId = 0\n\nexport function createStreamingMarkdownParser(\n options: StreamingMarkdownParserOptions = {}\n): StreamingMarkdownParser {\n parserId += 1\n const validateLink = options.validateLink ?? ((url: string) => !isUnsafeHtmlUrl(url))\n const markdown = getMarkdown(`varo-agent-${parserId}`, {\n customHtmlTags: options.customHtmlTags,\n enableMath: options.enableMath ?? true,\n markdownItOptions: {\n breaks: true,\n html: false,\n linkify: true,\n ...options.markdownItOptions,\n validateLink\n }\n })\n\n return {\n parse(content, parseOptions = {}) {\n return parseMarkdownToStructure(content, markdown, {\n customHtmlTags: options.customHtmlTags,\n final: parseOptions.final ?? false,\n includeSourceMap: options.includeSourceMap ?? false,\n reuseStableTopLevelNodes: true,\n streamParse: 'auto',\n validateLink\n })\n },\n reset() {\n markdown.stream?.reset?.()\n }\n }\n}\n\nexport type { ParsedNode } from 'stream-markdown-parser'\n","import { isUnknownRecord } from './type-guards'\nimport type { ParsedNode } from 'stream-markdown-parser'\n\nexport type AgentMarkdownNodeKind =\n | 'admonition'\n | 'blockquote'\n | 'checkbox'\n | 'code-block'\n | 'definition'\n | 'definition-list'\n | 'emphasis'\n | 'footnote'\n | 'hardbreak'\n | 'heading'\n | 'highlight'\n | 'image'\n | 'inline-code'\n | 'insert'\n | 'link'\n | 'list'\n | 'list-item'\n | 'math-block'\n | 'math-inline'\n | 'paragraph'\n | 'strikethrough'\n | 'strong'\n | 'subscript'\n | 'superscript'\n | 'table'\n | 'table-cell'\n | 'table-row'\n | 'text'\n | 'thematic-break'\n\nexport interface AgentMarkdownViewNode {\n align?: 'center' | 'left' | 'right'\n alt?: string\n checked?: boolean\n children?: AgentMarkdownViewNode[]\n header?: boolean\n href?: string\n kind: AgentMarkdownNodeKind\n language?: string\n level?: number\n loading?: boolean\n ordered?: boolean\n start?: number\n text?: string\n title?: string\n}\n\nfunction stringValue(value: unknown, fallback = '') {\n return typeof value === 'string' ? value : fallback\n}\n\nfunction booleanValue(value: unknown) {\n return typeof value === 'boolean' ? value : undefined\n}\n\nfunction numberValue(value: unknown) {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined\n}\n\nfunction alignValue(value: unknown): 'center' | 'left' | 'right' | undefined {\n return value === 'center' || value === 'left' || value === 'right' ? value : undefined\n}\n\nfunction nodeField(node: ParsedNode, key: string): unknown {\n return key in node ? Reflect.get(node, key) : undefined\n}\n\nfunction normalizeUnknownNode(value: unknown): AgentMarkdownViewNode | undefined {\n if (!isUnknownRecord(value) || typeof value.type !== 'string' || typeof value.raw !== 'string') return undefined\n // The required BaseNode fields are validated above; extension fields stay runtime-checked.\n const node = value as ParsedNode\n return normalizeMarkdownNode(node)\n}\n\nfunction normalizeChildren(value: unknown): AgentMarkdownViewNode[] {\n if (!Array.isArray(value)) return []\n const result: AgentMarkdownViewNode[] = []\n value.forEach((item) => {\n const normalized = normalizeUnknownNode(item)\n if (normalized) result.push(normalized)\n })\n return result\n}\n\nfunction textNode(text: string): AgentMarkdownViewNode {\n return { kind: 'text', text }\n}\n\nexport function normalizeMarkdownNode(node: ParsedNode): AgentMarkdownViewNode {\n const fallback = stringValue(node.raw)\n\n switch (node.type) {\n case 'text':\n return textNode(stringValue(node.content, fallback))\n case 'heading':\n return {\n children: normalizeChildren(node.children),\n kind: 'heading',\n level: numberValue(nodeField(node, 'level')) ?? 2,\n text: stringValue(nodeField(node, 'text'))\n }\n case 'paragraph':\n case 'inline':\n return { children: normalizeChildren(node.children), kind: 'paragraph' }\n case 'list':\n return {\n children: normalizeChildren(nodeField(node, 'items')),\n kind: 'list',\n ordered: booleanValue(nodeField(node, 'ordered')) ?? false,\n start: numberValue(nodeField(node, 'start'))\n }\n case 'list_item':\n return { children: normalizeChildren(node.children), kind: 'list-item' }\n case 'code_block':\n return {\n kind: 'code-block',\n language: stringValue(nodeField(node, 'language')),\n loading: booleanValue(node.loading),\n text: stringValue(node.code, fallback)\n }\n case 'inline_code':\n return { kind: 'inline-code', text: stringValue(node.code, fallback) }\n case 'link':\n return {\n children: normalizeChildren(node.children),\n href: stringValue(nodeField(node, 'href')),\n kind: 'link',\n text: stringValue(nodeField(node, 'text')),\n title: stringValue(nodeField(node, 'title'))\n }\n case 'image':\n return {\n alt: stringValue(nodeField(node, 'alt')),\n href: stringValue(nodeField(node, 'src')),\n kind: 'image',\n title: stringValue(nodeField(node, 'title'))\n }\n case 'thematic_break':\n return { kind: 'thematic-break' }\n case 'blockquote':\n return { children: normalizeChildren(node.children), kind: 'blockquote' }\n case 'table': {\n const header = nodeField(node, 'header')\n const rows = nodeField(node, 'rows')\n return {\n children: normalizeChildren(Array.isArray(rows) ? [header, ...rows] : [header]),\n kind: 'table'\n }\n }\n case 'table_row':\n return { children: normalizeChildren(nodeField(node, 'cells')), kind: 'table-row' }\n case 'table_cell':\n return {\n align: alignValue(nodeField(node, 'align')),\n children: normalizeChildren(node.children),\n header: booleanValue(nodeField(node, 'header')),\n kind: 'table-cell'\n }\n case 'strong':\n return { children: normalizeChildren(node.children), kind: 'strong' }\n case 'emphasis':\n return { children: normalizeChildren(node.children), kind: 'emphasis' }\n case 'strikethrough':\n return { children: normalizeChildren(node.children), kind: 'strikethrough' }\n case 'highlight':\n return { children: normalizeChildren(node.children), kind: 'highlight' }\n case 'insert':\n return { children: normalizeChildren(node.children), kind: 'insert' }\n case 'subscript':\n return { children: normalizeChildren(node.children), kind: 'subscript' }\n case 'superscript':\n return { children: normalizeChildren(node.children), kind: 'superscript' }\n case 'checkbox':\n case 'checkbox_input':\n return { checked: booleanValue(nodeField(node, 'checked')), kind: 'checkbox' }\n case 'emoji':\n return textNode(stringValue(nodeField(node, 'markup'), fallback))\n case 'definition_list':\n return { children: normalizeChildren(nodeField(node, 'items')), kind: 'definition-list' }\n case 'definition_item':\n return {\n children: [\n { children: normalizeChildren(nodeField(node, 'term')), header: true, kind: 'definition' },\n { children: normalizeChildren(nodeField(node, 'definition')), kind: 'definition' }\n ],\n kind: 'definition'\n }\n case 'footnote':\n return { children: normalizeChildren(node.children), kind: 'footnote', title: stringValue(nodeField(node, 'id')) }\n case 'footnote_reference':\n case 'reference':\n return { kind: 'footnote', text: stringValue(nodeField(node, 'id')) }\n case 'admonition':\n return {\n children: normalizeChildren(node.children),\n kind: 'admonition',\n text: stringValue(nodeField(node, 'kind')),\n title: stringValue(nodeField(node, 'title'))\n }\n case 'vmr_container':\n return {\n children: normalizeChildren(node.children),\n kind: 'admonition',\n loading: booleanValue(node.loading),\n title: stringValue(nodeField(node, 'name'))\n }\n case 'hardbreak':\n return { kind: 'hardbreak' }\n case 'math_inline':\n return { kind: 'math-inline', text: stringValue(node.content, fallback) }\n case 'math_block':\n return { kind: 'math-block', text: stringValue(node.content, fallback) }\n case 'html_block':\n case 'html_inline':\n return textNode(stringValue(node.content, fallback))\n default:\n return textNode(fallback)\n }\n}\n\nexport function normalizeMarkdownNodes(nodes: ParsedNode[]): AgentMarkdownViewNode[] {\n return nodes.map(normalizeMarkdownNode)\n}\n","import { createAgentEventChannel } from './event-channel'\nimport { parseAgentStreamEvent } from './event-parser'\nimport type { AgentStreamEvent } from './types'\n\nexport interface AgentSseEventSource {\n end: () => void\n fail: (error: unknown) => void\n feed: (chunk: string | ArrayBuffer | Uint8Array) => void\n source: AsyncIterable<AgentStreamEvent>\n}\n\ninterface Utf8ChunkDecoder {\n decode: (chunk: Uint8Array, final?: boolean) => string\n}\n\nfunction createFallbackUtf8Decoder(): Utf8ChunkDecoder {\n let carry = new Uint8Array(0)\n\n return {\n decode(chunk, final = false) {\n const bytes = new Uint8Array(carry.length + chunk.length)\n bytes.set(carry)\n bytes.set(chunk, carry.length)\n let cursor = 0\n let result = ''\n\n while (cursor < bytes.length) {\n const first = bytes[cursor]\n if (first < 0x80) {\n result += String.fromCodePoint(first)\n cursor += 1\n continue\n }\n\n const size = first >= 0xf0 ? 4 : first >= 0xe0 ? 3 : first >= 0xc0 ? 2 : 1\n if (size === 1) {\n result += '\\uFFFD'\n cursor += 1\n continue\n }\n if (cursor + size > bytes.length) break\n\n let codePoint = first & (size === 2 ? 0x1f : size === 3 ? 0x0f : 0x07)\n let valid = true\n for (let index = 1; index < size; index += 1) {\n const continuation = bytes[cursor + index]\n if ((continuation & 0xc0) !== 0x80) {\n valid = false\n break\n }\n codePoint = (codePoint << 6) | (continuation & 0x3f)\n }\n\n if (!valid || codePoint > 0x10ffff) {\n result += '\\uFFFD'\n cursor += 1\n continue\n }\n\n result += String.fromCodePoint(codePoint)\n cursor += size\n }\n\n carry = bytes.slice(cursor)\n if (final && carry.length > 0) {\n result += '\\uFFFD'\n carry = new Uint8Array(0)\n }\n return result\n }\n }\n}\n\nfunction createUtf8Decoder(): Utf8ChunkDecoder {\n if (typeof TextDecoder === 'function') {\n const decoder = new TextDecoder()\n return {\n decode(chunk, final = false) {\n return decoder.decode(chunk, { stream: !final })\n }\n }\n }\n return createFallbackUtf8Decoder()\n}\n\nfunction toBytes(chunk: ArrayBuffer | Uint8Array) {\n return chunk instanceof Uint8Array ? chunk : new Uint8Array(chunk)\n}\n\nexport function createAgentSseEventSource(): AgentSseEventSource {\n const channel = createAgentEventChannel()\n const decoder = createUtf8Decoder()\n const dataLines: string[] = []\n let textBuffer = ''\n let ended = false\n\n function dispatch() {\n if (dataLines.length === 0 || ended) return\n const payload = dataLines.join('\\n')\n dataLines.length = 0\n if (payload === '[DONE]') {\n channel.push({ type: 'done' })\n return\n }\n\n try {\n channel.push(parseAgentStreamEvent(JSON.parse(payload)))\n } catch (error) {\n ended = true\n channel.fail(error)\n }\n }\n\n function processLine(line: string) {\n const normalized = line.endsWith('\\r') ? line.slice(0, -1) : line\n if (normalized.length === 0) {\n dispatch()\n return\n }\n if (normalized.startsWith(':')) return\n if (normalized === 'data') {\n dataLines.push('')\n return\n }\n if (normalized.startsWith('data:')) {\n const value = normalized.slice(5)\n dataLines.push(value.startsWith(' ') ? value.slice(1) : value)\n }\n }\n\n function appendText(value: string) {\n textBuffer += value\n let lineEnd = textBuffer.indexOf('\\n')\n while (lineEnd >= 0) {\n processLine(textBuffer.slice(0, lineEnd))\n textBuffer = textBuffer.slice(lineEnd + 1)\n lineEnd = textBuffer.indexOf('\\n')\n }\n }\n\n return {\n end() {\n if (ended) return\n appendText(decoder.decode(new Uint8Array(0), true))\n if (textBuffer.length > 0) processLine(textBuffer)\n dispatch()\n ended = true\n channel.end()\n },\n fail(error) {\n if (ended) return\n ended = true\n channel.fail(error)\n },\n feed(chunk) {\n if (ended) return\n appendText(typeof chunk === 'string' ? chunk : decoder.decode(toBytes(chunk)))\n },\n source: channel.source\n }\n}\n"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@varo-ui/ai",
3
+ "version": "1.0.0",
4
+ "description": "Shared event protocol, streaming controller, and safe Markdown primitives for Varo Agent UI.",
5
+ "license": "MIT",
6
+ "homepage": "https://daguanren21.github.io/Varo/",
7
+ "type": "module",
8
+ "sideEffects": false,
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/daguanren21/Varo.git",
12
+ "directory": "packages/agent-core"
13
+ },
14
+ "publishConfig": {
15
+ "access": "public",
16
+ "registry": "https://registry.npmjs.org/"
17
+ },
18
+ "main": "./dist/index.mjs",
19
+ "module": "./dist/index.mjs",
20
+ "types": "./dist/index.d.mts",
21
+ "files": [
22
+ "dist",
23
+ "src"
24
+ ],
25
+ "exports": {
26
+ ".": {
27
+ "types": "./dist/index.d.mts",
28
+ "import": "./dist/index.mjs"
29
+ },
30
+ "./source": {
31
+ "types": "./src/index.ts",
32
+ "import": "./src/index.ts"
33
+ }
34
+ },
35
+ "scripts": {
36
+ "build": "tsdown",
37
+ "clean": "rimraf dist",
38
+ "dev": "tsdown --watch",
39
+ "lint": "echo agent-core lint pending",
40
+ "typecheck": "tsc -p tsconfig.json --noEmit",
41
+ "test": "vitest run --passWithNoTests",
42
+ "test:e2e": "echo agent-core has no e2e"
43
+ },
44
+ "dependencies": {
45
+ "markstream-core": "^2.0.0",
46
+ "stream-markdown-parser": "^1.2.8"
47
+ },
48
+ "bugs": {
49
+ "url": "https://github.com/daguanren21/Varo/issues"
50
+ },
51
+ "author": "daguanren21 <1363917353@qq.com>"
52
+ }
@@ -0,0 +1,284 @@
1
+ import { createTextStream } from './text-stream'
2
+ import type {
3
+ AgentApprovalPart,
4
+ AgentErrorEvent,
5
+ AgentReasoningPart,
6
+ AgentStreamController,
7
+ AgentStreamEvent,
8
+ AgentStreamSnapshot,
9
+ AgentToolPart,
10
+ TextStreamOptions
11
+ } from './types'
12
+
13
+ export interface AgentStreamControllerOptions {
14
+ text?: TextStreamOptions
15
+ }
16
+
17
+ function initialSnapshot(): AgentStreamSnapshot {
18
+ return {
19
+ data: [],
20
+ eventCount: 0,
21
+ reasoning: [],
22
+ status: 'idle',
23
+ tools: []
24
+ }
25
+ }
26
+
27
+ export function createAgentStreamController(
28
+ options: AgentStreamControllerOptions = {}
29
+ ): AgentStreamController {
30
+ const text = createTextStream(options.text)
31
+ const listeners = new Set<() => void>()
32
+ let snapshot = initialSnapshot()
33
+ let destroyed = false
34
+ let cancelled = false
35
+ let transportDone = false
36
+ let connecting = false
37
+ let cancelActiveConnect: (() => void) | undefined
38
+
39
+ function emit() {
40
+ listeners.forEach((listener) => listener())
41
+ }
42
+
43
+ function setSnapshot(update: Partial<AgentStreamSnapshot>) {
44
+ snapshot = { ...snapshot, ...update }
45
+ emit()
46
+ }
47
+
48
+ function updateReasoning(id: string, update: Partial<AgentReasoningPart>) {
49
+ setSnapshot({
50
+ reasoning: snapshot.reasoning.map((part) => (part.id === id ? { ...part, ...update } : part))
51
+ })
52
+ }
53
+
54
+ function updateTool(id: string, update: Partial<AgentToolPart>) {
55
+ setSnapshot({
56
+ tools: snapshot.tools.map((part) => (part.id === id ? { ...part, ...update } : part))
57
+ })
58
+ }
59
+
60
+ function finalStatus() {
61
+ const textSnapshot = text.getSnapshot()
62
+ if (!transportDone || !textSnapshot.final) return
63
+ setSnapshot({ status: snapshot.error ? 'failed' : cancelled ? 'cancelled' : 'completed' })
64
+ }
65
+
66
+ const unsubscribeText = text.subscribe(() => {
67
+ if (destroyed || !snapshot.message) return
68
+ const textSnapshot = text.getSnapshot()
69
+ snapshot = {
70
+ ...snapshot,
71
+ message: {
72
+ ...snapshot.message,
73
+ final: textSnapshot.final,
74
+ source: textSnapshot.source,
75
+ visible: textSnapshot.visible
76
+ }
77
+ }
78
+ emit()
79
+ finalStatus()
80
+ })
81
+
82
+ function push(event: AgentStreamEvent) {
83
+ if (destroyed || cancelled) return
84
+ snapshot = { ...snapshot, eventCount: snapshot.eventCount + 1 }
85
+
86
+ switch (event.type) {
87
+ case 'message.start':
88
+ transportDone = false
89
+ text.reset()
90
+ setSnapshot({
91
+ error: undefined,
92
+ message: {
93
+ final: false,
94
+ id: event.messageId,
95
+ role: event.role,
96
+ source: '',
97
+ visible: ''
98
+ },
99
+ status: 'streaming'
100
+ })
101
+ break
102
+ case 'text.delta':
103
+ if (snapshot.message?.id === event.messageId) text.enqueue(event.delta)
104
+ break
105
+ case 'message.end':
106
+ if (snapshot.message?.id === event.messageId) text.finish()
107
+ break
108
+ case 'reasoning.start':
109
+ setSnapshot({
110
+ reasoning: [
111
+ ...snapshot.reasoning,
112
+ { content: '', id: event.id, status: 'running', title: event.title }
113
+ ]
114
+ })
115
+ break
116
+ case 'reasoning.delta': {
117
+ const part = snapshot.reasoning.find((item) => item.id === event.id)
118
+ if (part) updateReasoning(event.id, { content: `${part.content}${event.delta}` })
119
+ break
120
+ }
121
+ case 'reasoning.end':
122
+ updateReasoning(event.id, { durationMs: event.durationMs, status: 'completed' })
123
+ break
124
+ case 'tool.start':
125
+ setSnapshot({
126
+ tools: [
127
+ ...snapshot.tools,
128
+ {
129
+ id: event.id,
130
+ input: event.input,
131
+ name: event.name,
132
+ status: 'running',
133
+ summary: event.summary
134
+ }
135
+ ]
136
+ })
137
+ break
138
+ case 'tool.update':
139
+ updateTool(event.id, { summary: event.summary })
140
+ break
141
+ case 'tool.result':
142
+ updateTool(event.id, {
143
+ output: event.output,
144
+ status: 'completed',
145
+ summary: event.summary
146
+ })
147
+ break
148
+ case 'tool.error':
149
+ updateTool(event.id, { error: event.error, status: 'failed' })
150
+ break
151
+ case 'approval.required': {
152
+ const approval: AgentApprovalPart = {
153
+ choices: event.choices ?? [],
154
+ description: event.description,
155
+ id: event.id,
156
+ status: 'waiting',
157
+ title: event.title
158
+ }
159
+ setSnapshot({ approval, status: 'waiting' })
160
+ break
161
+ }
162
+ case 'approval.resolved':
163
+ if (snapshot.approval?.id === event.id) {
164
+ setSnapshot({
165
+ approval: {
166
+ ...snapshot.approval,
167
+ resolvedValue: event.value,
168
+ status: 'completed'
169
+ },
170
+ status: 'streaming'
171
+ })
172
+ }
173
+ break
174
+ case 'data':
175
+ setSnapshot({ data: [...snapshot.data, { name: event.name, value: event.value }] })
176
+ break
177
+ case 'error':
178
+ transportDone = true
179
+ text.finish({ flush: true })
180
+ setSnapshot({ error: event, status: 'failed' })
181
+ break
182
+ case 'done':
183
+ transportDone = true
184
+ text.finish()
185
+ setSnapshot({ usage: event.usage })
186
+ if (!snapshot.message) setSnapshot({ status: 'completed' })
187
+ finalStatus()
188
+ break
189
+ }
190
+ }
191
+
192
+ async function waitForTerminal() {
193
+ if (snapshot.status === 'completed' || snapshot.status === 'failed' || snapshot.status === 'cancelled') {
194
+ return snapshot
195
+ }
196
+
197
+ return await new Promise<AgentStreamSnapshot>((resolve) => {
198
+ const unsubscribe = subscribe(() => {
199
+ if (snapshot.status !== 'completed' && snapshot.status !== 'failed' && snapshot.status !== 'cancelled') return
200
+ unsubscribe()
201
+ resolve(snapshot)
202
+ })
203
+ })
204
+ }
205
+
206
+ function subscribe(listener: () => void) {
207
+ if (destroyed) return () => {}
208
+ listeners.add(listener)
209
+ return () => listeners.delete(listener)
210
+ }
211
+
212
+ function reset() {
213
+ text.reset()
214
+ snapshot = initialSnapshot()
215
+ cancelled = false
216
+ transportDone = false
217
+ emit()
218
+ }
219
+
220
+ function cancel(reason = 'Cancelled') {
221
+ if (destroyed || cancelled) return
222
+ cancelled = true
223
+ transportDone = true
224
+ text.finish({ flush: true })
225
+ const error: AgentErrorEvent = { code: 'cancelled', message: reason, retryable: true, type: 'error' }
226
+ setSnapshot({ error, status: 'cancelled' })
227
+ cancelActiveConnect?.()
228
+ }
229
+
230
+ return {
231
+ cancel,
232
+ async connect(events) {
233
+ if (connecting) throw new Error('Agent stream controller is already connected')
234
+ connecting = true
235
+ reset()
236
+ const iterator = events[Symbol.asyncIterator]()
237
+ let resolveCancellation: (() => void) | undefined
238
+ const cancellation = new Promise<void>((resolve) => {
239
+ resolveCancellation = resolve
240
+ })
241
+ cancelActiveConnect = resolveCancellation
242
+
243
+ try {
244
+ try {
245
+ while (!cancelled && !destroyed) {
246
+ const outcome = await Promise.race([
247
+ iterator.next().then((result) => ({ kind: 'event' as const, result })),
248
+ cancellation.then(() => ({ kind: 'cancelled' as const }))
249
+ ])
250
+ if (outcome.kind === 'cancelled' || outcome.result.done) break
251
+ push(outcome.result.value)
252
+ }
253
+ if (!transportDone && !cancelled && !destroyed) push({ type: 'done' })
254
+ } catch (error) {
255
+ push({
256
+ message: error instanceof Error ? error.message : String(error),
257
+ retryable: true,
258
+ type: 'error'
259
+ })
260
+ } finally {
261
+ if (cancelled || destroyed) void iterator.return?.()
262
+ }
263
+ return await waitForTerminal()
264
+ } finally {
265
+ connecting = false
266
+ cancelActiveConnect = undefined
267
+ }
268
+ },
269
+ destroy() {
270
+ if (destroyed) return
271
+ cancel('Agent stream controller destroyed')
272
+ destroyed = true
273
+ unsubscribeText()
274
+ text.destroy()
275
+ listeners.clear()
276
+ },
277
+ getSnapshot() {
278
+ return snapshot
279
+ },
280
+ push,
281
+ reset,
282
+ subscribe
283
+ }
284
+ }
@@ -0,0 +1,49 @@
1
+ import type { AgentEventChannel, AgentStreamEvent } from './types'
2
+
3
+ export function createAgentEventChannel(): AgentEventChannel {
4
+ const queue: AgentStreamEvent[] = []
5
+ let ended = false
6
+ let failure: Error | undefined
7
+ let wake: (() => void) | undefined
8
+
9
+ async function* iterate(): AsyncGenerator<AgentStreamEvent> {
10
+ while (!ended || queue.length > 0) {
11
+ if (failure) throw failure
12
+ const event = queue.shift()
13
+ if (event) {
14
+ yield event
15
+ continue
16
+ }
17
+
18
+ await new Promise<void>((resolve) => {
19
+ wake = resolve
20
+ })
21
+ wake = undefined
22
+ }
23
+ if (failure) throw failure
24
+ }
25
+
26
+ function notify() {
27
+ wake?.()
28
+ }
29
+
30
+ return {
31
+ end() {
32
+ ended = true
33
+ notify()
34
+ },
35
+ fail(error) {
36
+ failure = error instanceof Error ? error : new Error(String(error))
37
+ ended = true
38
+ notify()
39
+ },
40
+ push(event) {
41
+ if (ended) return
42
+ queue.push(event)
43
+ notify()
44
+ },
45
+ source: {
46
+ [Symbol.asyncIterator]: iterate
47
+ }
48
+ }
49
+ }
@@ -0,0 +1,159 @@
1
+ import { isUnknownRecord } from './type-guards'
2
+ import type { AgentApprovalRequiredEvent, AgentStreamEvent } from './types'
3
+
4
+
5
+ function requiredString(value: Record<string, unknown>, key: string): string {
6
+ const field = value[key]
7
+ if (typeof field !== 'string' || field.length === 0) {
8
+ throw new TypeError(`Agent stream event field "${key}" must be a non-empty string`)
9
+ }
10
+ return field
11
+ }
12
+
13
+ function optionalString(value: Record<string, unknown>, key: string): string | undefined {
14
+ const field = value[key]
15
+ if (field === undefined) return undefined
16
+ if (typeof field !== 'string') throw new TypeError(`Agent stream event field "${key}" must be a string`)
17
+ return field
18
+ }
19
+
20
+ function optionalBoolean(value: Record<string, unknown>, key: string): boolean | undefined {
21
+ const field = value[key]
22
+ if (field === undefined) return undefined
23
+ if (typeof field !== 'boolean') throw new TypeError(`Agent stream event field "${key}" must be a boolean`)
24
+ return field
25
+ }
26
+
27
+ function optionalNumber(value: Record<string, unknown>, key: string): number | undefined {
28
+ const field = value[key]
29
+ if (field === undefined) return undefined
30
+ if (typeof field !== 'number' || !Number.isFinite(field)) {
31
+ throw new TypeError(`Agent stream event field "${key}" must be a finite number`)
32
+ }
33
+ return field
34
+ }
35
+
36
+ function parseChoices(value: unknown): AgentApprovalRequiredEvent['choices'] {
37
+ if (value === undefined) return undefined
38
+ if (!Array.isArray(value)) throw new TypeError('Agent approval choices must be an array')
39
+
40
+ return value.map((choice) => {
41
+ if (!isUnknownRecord(choice)) throw new TypeError('Agent approval choice must be an object')
42
+ return {
43
+ description: optionalString(choice, 'description'),
44
+ disabled: optionalBoolean(choice, 'disabled'),
45
+ label: requiredString(choice, 'label'),
46
+ value: requiredString(choice, 'value')
47
+ }
48
+ })
49
+ }
50
+
51
+ export function parseAgentStreamEvent(value: unknown): AgentStreamEvent {
52
+ if (!isUnknownRecord(value) || typeof value.type !== 'string') {
53
+ throw new TypeError('Agent stream event must be an object with a string type')
54
+ }
55
+
56
+ switch (value.type) {
57
+ case 'message.start': {
58
+ const role = requiredString(value, 'role')
59
+ if (role !== 'assistant' && role !== 'system' && role !== 'user') {
60
+ throw new TypeError(`Unsupported agent message role: ${role}`)
61
+ }
62
+ return { messageId: requiredString(value, 'messageId'), role, type: value.type }
63
+ }
64
+ case 'text.delta':
65
+ return {
66
+ delta: requiredString(value, 'delta'),
67
+ messageId: requiredString(value, 'messageId'),
68
+ type: value.type
69
+ }
70
+ case 'message.end':
71
+ return { messageId: requiredString(value, 'messageId'), type: value.type }
72
+ case 'reasoning.start':
73
+ return {
74
+ id: requiredString(value, 'id'),
75
+ title: requiredString(value, 'title'),
76
+ type: value.type
77
+ }
78
+ case 'reasoning.delta':
79
+ return {
80
+ delta: requiredString(value, 'delta'),
81
+ id: requiredString(value, 'id'),
82
+ type: value.type
83
+ }
84
+ case 'reasoning.end':
85
+ return {
86
+ durationMs: optionalNumber(value, 'durationMs'),
87
+ id: requiredString(value, 'id'),
88
+ type: value.type
89
+ }
90
+ case 'tool.start':
91
+ return {
92
+ id: requiredString(value, 'id'),
93
+ input: value.input,
94
+ name: requiredString(value, 'name'),
95
+ summary: optionalString(value, 'summary'),
96
+ type: value.type
97
+ }
98
+ case 'tool.update':
99
+ return {
100
+ id: requiredString(value, 'id'),
101
+ summary: optionalString(value, 'summary'),
102
+ type: value.type
103
+ }
104
+ case 'tool.result':
105
+ return {
106
+ id: requiredString(value, 'id'),
107
+ output: value.output,
108
+ summary: optionalString(value, 'summary'),
109
+ type: value.type
110
+ }
111
+ case 'tool.error':
112
+ return {
113
+ error: requiredString(value, 'error'),
114
+ id: requiredString(value, 'id'),
115
+ type: value.type
116
+ }
117
+ case 'approval.required':
118
+ return {
119
+ choices: parseChoices(value.choices),
120
+ description: optionalString(value, 'description'),
121
+ id: requiredString(value, 'id'),
122
+ title: requiredString(value, 'title'),
123
+ type: value.type
124
+ }
125
+ case 'approval.resolved':
126
+ return {
127
+ id: requiredString(value, 'id'),
128
+ type: value.type,
129
+ value: requiredString(value, 'value')
130
+ }
131
+ case 'data':
132
+ if (!('value' in value)) throw new TypeError('Agent data event must include a value field')
133
+ return { name: requiredString(value, 'name'), type: value.type, value: value.value }
134
+ case 'error':
135
+ return {
136
+ code: optionalString(value, 'code'),
137
+ message: requiredString(value, 'message'),
138
+ retryable: optionalBoolean(value, 'retryable'),
139
+ type: value.type
140
+ }
141
+ case 'done': {
142
+ const usage = value.usage
143
+ if (usage !== undefined && !isUnknownRecord(usage)) {
144
+ throw new TypeError('Agent done usage must be an object')
145
+ }
146
+ return {
147
+ type: value.type,
148
+ usage: usage
149
+ ? {
150
+ inputTokens: optionalNumber(usage, 'inputTokens'),
151
+ outputTokens: optionalNumber(usage, 'outputTokens')
152
+ }
153
+ : undefined
154
+ }
155
+ }
156
+ default:
157
+ throw new TypeError(`Unsupported agent stream event type: ${value.type}`)
158
+ }
159
+ }