@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.
- package/dist/index.d.mts +249 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +984 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +52 -0
- package/src/agent-stream.ts +284 -0
- package/src/event-channel.ts +49 -0
- package/src/event-parser.ts +159 -0
- package/src/index.ts +8 -0
- package/src/markdown-view.ts +227 -0
- package/src/markdown.ts +58 -0
- package/src/sse.ts +161 -0
- package/src/text-stream.ts +202 -0
- package/src/type-guards.ts +3 -0
- package/src/types.ts +222 -0
|
@@ -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":";;;AAOA,SAAS,eAAe,OAAyB;CAC/C,MAAM,cAAuB;CAC7B,IACE,OAAO,gBAAgB,YACpB,gBAAgB,QAChB,EAAE,eAAe,gBACjB,OAAO,YAAY,cAAc,YAEpC,OAAO,MAAM,KAAK,KAAK;CAIzB,MAAM,YAAY,YAAY;CAI9B,OAAO,MAAM,KAAK,IAAI,UAAU,KAAA,GAAW,EAAE,aAAa,WAAW,CAAC,CAAC,CAAC,QAAQ,KAAK,IAAI,SAAS,KAAK,OAAO;AAChH;AAEA,SAAS,MAAM,OAAe,KAAa,KAAa;CACtD,OAAO,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,KAAK,CAAC;AAC3C;AAEA,SAAS,sBAAsB,UAA6B,CAAC,GAAyB;CACpF,MAAM,oBAAoB,KAAK,IAAI,GAAG,QAAQ,qBAAqB,EAAE;CACrE,MAAM,oBAAoB,KAAK,IAAI,mBAAmB,QAAQ,qBAAqB,GAAG;CACtF,MAAM,kBAAkB,KAAK,IAAI,IAAI,QAAQ,mBAAmB,GAAG;CACnE,MAAM,eAAe,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,QAAQ,gBAAgB,EAAE,CAAC;CACzE,MAAM,oBAAoB,KAAK,IAAI,GAAG,QAAQ,qBAAqB,EAAE;CACrE,MAAM,mBAAmB,KAAK,IAAI,GAAG,QAAQ,oBAAoB,GAAG;CACpE,MAAM,4BAAY,IAAI,IAAgB;CACtC,MAAM,UAAoB,CAAC;CAC3B,IAAI,gBAAgB;CACpB,IAAI,SAAS;CACb,IAAI,UAAU;CACd,IAAI,OAAO;CACX,IAAI,SAAS;CACb,IAAI,YAAY;CAChB,IAAI;CACJ,IAAI,WAAW,KAAK,IAAI;CACxB,IAAI,SAAS;CAEb,SAAS,eAAe;EACtB,OAAO,QAAQ,SAAS;CAC1B;CAEA,SAAS,WAA+B;EACtC,MAAM,eAAe,aAAa;EAClC,OAAO;GACL,UAAU,iBAAiB;GAC3B;GACA,OAAO,QAAQ,iBAAiB;GAChC;GACA;GACA;GACA;EACF;CACF;CAEA,SAAS,OAAO;EACd,UAAU,SAAS,aAAa,SAAS,CAAC;CAC5C;CAEA,SAAS,iBAAiB;EACxB,IAAI,gBAAgB,QAAQ,gBAAgB,IAAI,QAAQ,QAAQ;EAChE,QAAQ,OAAO,GAAG,aAAa;EAC/B,gBAAgB;CAClB;CAEA,SAAS,WAAW;EAClB,IAAI,aAAa,UAAU,SAAS,aAAa,MAAM,GAAG;EAC1D,QAAQ,WAAW,MAAM,KAAK,KAAK,MAAO,YAAY,CAAC;CACzD;CAEA,SAAS,OAAO;EACd,QAAQ,KAAA;EACR,IAAI,aAAa,QAAQ;EAEzB,MAAM,MAAM,KAAK,IAAI;EACrB,MAAM,UAAU,KAAK,IAAI,GAAG,MAAM,QAAQ;EAC1C,WAAW;EACX,MAAM,UAAU,aAAa;EAC7B,IAAI,YAAY,GAAG;GACjB,KAAK;GACL;EACF;EAIA,MAAM,MAAM,MAFQ,UAAU,MAAQ,mBACjB,WAAW,mBAAmB,MAAM,IACZ,mBAAmB,iBAAiB;EACjF,UAAW,MAAM,UAAW;EAC5B,MAAM,cAAc,KAAK,IAAI,SAAS,mBAAmB,KAAK,IAAI,GAAG,KAAK,MAAM,MAAM,CAAC,CAAC;EACxF,SAAS,KAAK,IAAI,GAAG,SAAS,WAAW;EACzC,WAAW,QAAQ,MAAM,eAAe,gBAAgB,WAAW,CAAC,CAAC,KAAK,EAAE;EAC5E,iBAAiB;EACjB,eAAe;EACf,KAAK;EACL,SAAS;CACX;CAEA,SAAS,cAAc;EACrB,aAAa,KAAK;EAClB,QAAQ,KAAA;CACV;CAEA,OAAO;EACL,UAAU;GACR,IAAI,WAAW;GACf,YAAY;GACZ,YAAY;GACZ,QAAQ,SAAS;GACjB,UAAU,MAAM;EAClB;EACA,QAAQ,OAAO;GACb,IAAI,aAAa,CAAC,OAAO;GACzB,IAAI,MAAM,OAAO;GACjB,UAAU;GACV,QAAQ,KAAK,GAAG,eAAe,KAAK,CAAC;GACrC,WAAW,KAAK,IAAI;GACpB,KAAK;GACL,SAAS;EACX;EACA,OAAO,gBAAgB,CAAC,GAAG;GACzB,IAAI,WAAW;GACf,OAAO;GACP,IAAI,cAAc,OAAO;IACvB,UAAU;IACV,QAAQ,SAAS;IACjB,gBAAgB;IAChB,YAAY;GACd;GACA,KAAK;GACL,SAAS;EACX;EACA,QAAQ;GACN,IAAI,WAAW;GACf,UAAU;GACV,QAAQ,SAAS;GACjB,gBAAgB;GAChB,SAAS;GACT,YAAY;GACZ,KAAK;EACP;EACA,aAAa;EACb,QAAQ;GACN,IAAI,aAAa,QAAQ;GACzB,SAAS;GACT,YAAY;GACZ,KAAK;EACP;EACA,MAAM,UAAU,IAAI;GAClB,YAAY;GACZ,SAAS;GACT,UAAU;GACV,QAAQ,SAAS;GACjB,gBAAgB;GAChB,OAAO;GACP,SAAS;GACT,SAAS;GACT,WAAW,KAAK,IAAI;GACpB,KAAK;EACP;EACA,SAAS;GACP,IAAI,aAAa,CAAC,QAAQ;GAC1B,SAAS;GACT,WAAW,KAAK,IAAI;GACpB,KAAK;GACL,SAAS;EACX;EACA,UAAU,UAAU;GAClB,IAAI,WAAW,aAAa,CAAC;GAC7B,UAAU,IAAI,QAAQ;GACtB,aAAa,UAAU,OAAO,QAAQ;EACxC;CACF;AACF;AAEA,SAAgB,iBAAiB,UAA6B,CAAC,GAAyB;CACtF,IAAI,OAAO,0BAA0B,cAAc,OAAO,yBAAyB,YACjF,OAAO,sBAAsB,OAAO;CAGtC,MAAM,aAAa,2BAA2B,OAAO;CACrD,OAAO;EACL,SAAS,WAAW;EACpB,SAAS,WAAW;EACpB,QAAQ,WAAW;EACnB,OAAO,WAAW;EAClB,aAAa,WAAW;EACxB,OAAO,WAAW;EAClB,OAAO,WAAW;EAClB,QAAQ,WAAW;EACnB,WAAW,WAAW;CACxB;AACF;;;ACzLA,SAAS,kBAAuC;CAC9C,OAAO;EACL,MAAM,CAAC;EACP,YAAY;EACZ,WAAW,CAAC;EACZ,QAAQ;EACR,OAAO,CAAC;CACV;AACF;AAEA,SAAgB,4BACd,UAAwC,CAAC,GAClB;CACvB,MAAM,OAAO,iBAAiB,QAAQ,IAAI;CAC1C,MAAM,4BAAY,IAAI,IAAgB;CACtC,IAAI,WAAW,gBAAgB;CAC/B,IAAI,YAAY;CAChB,IAAI,YAAY;CAChB,IAAI,gBAAgB;CACpB,IAAI,aAAa;CACjB,IAAI;CAEJ,SAAS,OAAO;EACd,UAAU,SAAS,aAAa,SAAS,CAAC;CAC5C;CAEA,SAAS,YAAY,QAAsC;EACzD,WAAW;GAAE,GAAG;GAAU,GAAG;EAAO;EACpC,KAAK;CACP;CAEA,SAAS,gBAAgB,IAAY,QAAqC;EACxE,YAAY,EACV,WAAW,SAAS,UAAU,KAAK,SAAU,KAAK,OAAO,KAAK;GAAE,GAAG;GAAM,GAAG;EAAO,IAAI,IAAK,EAC9F,CAAC;CACH;CAEA,SAAS,WAAW,IAAY,QAAgC;EAC9D,YAAY,EACV,OAAO,SAAS,MAAM,KAAK,SAAU,KAAK,OAAO,KAAK;GAAE,GAAG;GAAM,GAAG;EAAO,IAAI,IAAK,EACtF,CAAC;CACH;CAEA,SAAS,cAAc;EACrB,MAAM,eAAe,KAAK,YAAY;EACtC,IAAI,CAAC,iBAAiB,CAAC,aAAa,OAAO;EAC3C,YAAY,EAAE,QAAQ,SAAS,QAAQ,WAAW,YAAY,cAAc,YAAY,CAAC;CAC3F;CAEA,MAAM,kBAAkB,KAAK,gBAAgB;EAC3C,IAAI,aAAa,CAAC,SAAS,SAAS;EACpC,MAAM,eAAe,KAAK,YAAY;EACtC,WAAW;GACT,GAAG;GACH,SAAS;IACP,GAAG,SAAS;IACZ,OAAO,aAAa;IACpB,QAAQ,aAAa;IACrB,SAAS,aAAa;GACxB;EACF;EACA,KAAK;EACL,YAAY;CACd,CAAC;CAED,SAAS,KAAK,OAAyB;EACrC,IAAI,aAAa,WAAW;EAC5B,WAAW;GAAE,GAAG;GAAU,YAAY,SAAS,aAAa;EAAE;EAE9D,QAAQ,MAAM,MAAd;GACE,KAAK;IACH,gBAAgB;IAChB,KAAK,MAAM;IACX,YAAY;KACV,OAAO,KAAA;KACP,SAAS;MACP,OAAO;MACP,IAAI,MAAM;MACV,MAAM,MAAM;MACZ,QAAQ;MACR,SAAS;KACX;KACA,QAAQ;IACV,CAAC;IACD;GACF,KAAK;IACH,IAAI,SAAS,SAAS,OAAO,MAAM,WAAW,KAAK,QAAQ,MAAM,KAAK;IACtE;GACF,KAAK;IACH,IAAI,SAAS,SAAS,OAAO,MAAM,WAAW,KAAK,OAAO;IAC1D;GACF,KAAK;IACH,YAAY,EACV,WAAW,CACT,GAAG,SAAS,WACZ;KAAE,SAAS;KAAI,IAAI,MAAM;KAAI,QAAQ;KAAW,OAAO,MAAM;IAAM,CACrE,EACF,CAAC;IACD;GACF,KAAK,mBAAmB;IACtB,MAAM,OAAO,SAAS,UAAU,MAAM,SAAS,KAAK,OAAO,MAAM,EAAE;IACnE,IAAI,MAAM,gBAAgB,MAAM,IAAI,EAAE,SAAS,GAAG,KAAK,UAAU,MAAM,QAAQ,CAAC;IAChF;GACF;GACA,KAAK;IACH,gBAAgB,MAAM,IAAI;KAAE,YAAY,MAAM;KAAY,QAAQ;IAAY,CAAC;IAC/E;GACF,KAAK;IACH,YAAY,EACV,OAAO,CACL,GAAG,SAAS,OACZ;KACE,IAAI,MAAM;KACV,OAAO,MAAM;KACb,MAAM,MAAM;KACZ,QAAQ;KACR,SAAS,MAAM;IACjB,CACF,EACF,CAAC;IACD;GACF,KAAK;IACH,WAAW,MAAM,IAAI,EAAE,SAAS,MAAM,QAAQ,CAAC;IAC/C;GACF,KAAK;IACH,WAAW,MAAM,IAAI;KACnB,QAAQ,MAAM;KACd,QAAQ;KACR,SAAS,MAAM;IACjB,CAAC;IACD;GACF,KAAK;IACH,WAAW,MAAM,IAAI;KAAE,OAAO,MAAM;KAAO,QAAQ;IAAS,CAAC;IAC7D;GACF,KAAK;IAQH,YAAY;KAAE,UAAA;MANZ,SAAS,MAAM,WAAW,CAAC;MAC3B,aAAa,MAAM;MACnB,IAAI,MAAM;MACV,QAAQ;MACR,OAAO,MAAM;KAEM;KAAG,QAAQ;IAAU,CAAC;IAC3C;GAEF,KAAK;IACH,IAAI,SAAS,UAAU,OAAO,MAAM,IAClC,YAAY;KACV,UAAU;MACR,GAAG,SAAS;MACZ,eAAe,MAAM;MACrB,QAAQ;KACV;KACA,QAAQ;IACV,CAAC;IAEH;GACF,KAAK;IACH,YAAY,EAAE,MAAM,CAAC,GAAG,SAAS,MAAM;KAAE,MAAM,MAAM;KAAM,OAAO,MAAM;IAAM,CAAC,EAAE,CAAC;IAClF;GACF,KAAK;IACH,gBAAgB;IAChB,KAAK,OAAO,EAAE,OAAO,KAAK,CAAC;IAC3B,YAAY;KAAE,OAAO;KAAO,QAAQ;IAAS,CAAC;IAC9C;GACF,KAAK;IACH,gBAAgB;IAChB,KAAK,OAAO;IACZ,YAAY,EAAE,OAAO,MAAM,MAAM,CAAC;IAClC,IAAI,CAAC,SAAS,SAAS,YAAY,EAAE,QAAQ,YAAY,CAAC;IAC1D,YAAY;IACZ;EACJ;CACF;CAEA,eAAe,kBAAkB;EAC/B,IAAI,SAAS,WAAW,eAAe,SAAS,WAAW,YAAY,SAAS,WAAW,aACzF,OAAO;EAGT,OAAO,MAAM,IAAI,SAA8B,YAAY;GACzD,MAAM,cAAc,gBAAgB;IAClC,IAAI,SAAS,WAAW,eAAe,SAAS,WAAW,YAAY,SAAS,WAAW,aAAa;IACxG,YAAY;IACZ,QAAQ,QAAQ;GAClB,CAAC;EACH,CAAC;CACH;CAEA,SAAS,UAAU,UAAsB;EACvC,IAAI,WAAW,aAAa,CAAC;EAC7B,UAAU,IAAI,QAAQ;EACtB,aAAa,UAAU,OAAO,QAAQ;CACxC;CAEA,SAAS,QAAQ;EACf,KAAK,MAAM;EACX,WAAW,gBAAgB;EAC3B,YAAY;EACZ,gBAAgB;EAChB,KAAK;CACP;CAEA,SAAS,OAAO,SAAS,aAAa;EACpC,IAAI,aAAa,WAAW;EAC5B,YAAY;EACZ,gBAAgB;EAChB,KAAK,OAAO,EAAE,OAAO,KAAK,CAAC;EAE3B,YAAY;GAAE,OAAA;IADmB,MAAM;IAAa,SAAS;IAAQ,WAAW;IAAM,MAAM;GAC1E;GAAG,QAAQ;EAAY,CAAC;EAC1C,sBAAsB;CACxB;CAEA,OAAO;EACL;EACA,MAAM,QAAQ,QAAQ;GACpB,IAAI,YAAY,MAAM,IAAI,MAAM,8CAA8C;GAC9E,aAAa;GACb,MAAM;GACN,MAAM,WAAW,OAAO,OAAO,cAAc,CAAC;GAC9C,IAAI;GACJ,MAAM,eAAe,IAAI,SAAe,YAAY;IAClD,sBAAsB;GACxB,CAAC;GACD,sBAAsB;GAEtB,IAAI;IACF,IAAI;KACF,OAAO,CAAC,aAAa,CAAC,WAAW;MAC/B,MAAM,UAAU,MAAM,QAAQ,KAAK,CACjC,SAAS,KAAK,CAAC,CAAC,MAAM,YAAY;OAAE,MAAM;OAAkB;MAAO,EAAE,GACrE,aAAa,YAAY,EAAE,MAAM,YAAqB,EAAE,CAC1D,CAAC;MACD,IAAI,QAAQ,SAAS,eAAe,QAAQ,OAAO,MAAM;MACzD,KAAK,QAAQ,OAAO,KAAK;KAC3B;KACA,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAAC,WAAW,KAAK,EAAE,MAAM,OAAO,CAAC;IACvE,SAAS,OAAO;KACd,KAAK;MACH,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;MAC9D,WAAW;MACX,MAAM;KACR,CAAC;IACH,UAAU;KACR,IAAI,aAAa,WAAW,SAAc,SAAS;IACrD;IACA,OAAO,MAAM,gBAAgB;GAC/B,UAAU;IACR,aAAa;IACb,sBAAsB,KAAA;GACxB;EACF;EACA,UAAU;GACR,IAAI,WAAW;GACf,OAAO,mCAAmC;GAC1C,YAAY;GACZ,gBAAgB;GAChB,KAAK,QAAQ;GACb,UAAU,MAAM;EAClB;EACA,cAAc;GACZ,OAAO;EACT;EACA;EACA;EACA;CACF;AACF;;;ACzRA,SAAgB,0BAA6C;CAC3D,MAAM,QAA4B,CAAC;CACnC,IAAI,QAAQ;CACZ,IAAI;CACJ,IAAI;CAEJ,gBAAgB,UAA4C;EAC1D,OAAO,CAAC,SAAS,MAAM,SAAS,GAAG;GACjC,IAAI,SAAS,MAAM;GACnB,MAAM,QAAQ,MAAM,MAAM;GAC1B,IAAI,OAAO;IACT,MAAM;IACN;GACF;GAEA,MAAM,IAAI,SAAe,YAAY;IACnC,OAAO;GACT,CAAC;GACD,OAAO,KAAA;EACT;EACA,IAAI,SAAS,MAAM;CACrB;CAEA,SAAS,SAAS;EAChB,OAAO;CACT;CAEA,OAAO;EACL,MAAM;GACJ,QAAQ;GACR,OAAO;EACT;EACA,KAAK,OAAO;GACV,UAAU,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;GAClE,QAAQ;GACR,OAAO;EACT;EACA,KAAK,OAAO;GACV,IAAI,OAAO;GACX,MAAM,KAAK,KAAK;GAChB,OAAO;EACT;EACA,QAAQ,GACL,OAAO,gBAAgB,QAC1B;CACF;AACF;;;AChDA,SAAgB,gBAAgB,OAAkD;CAChF,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;;;ACEA,SAAS,eAAe,OAAgC,KAAqB;CAC3E,MAAM,QAAQ,MAAM;CACpB,IAAI,OAAO,UAAU,YAAY,MAAM,WAAW,GAChD,MAAM,IAAI,UAAU,6BAA6B,IAAI,6BAA6B;CAEpF,OAAO;AACT;AAEA,SAAS,eAAe,OAAgC,KAAiC;CACvF,MAAM,QAAQ,MAAM;CACpB,IAAI,UAAU,KAAA,GAAW,OAAO,KAAA;CAChC,IAAI,OAAO,UAAU,UAAU,MAAM,IAAI,UAAU,6BAA6B,IAAI,mBAAmB;CACvG,OAAO;AACT;AAEA,SAAS,gBAAgB,OAAgC,KAAkC;CACzF,MAAM,QAAQ,MAAM;CACpB,IAAI,UAAU,KAAA,GAAW,OAAO,KAAA;CAChC,IAAI,OAAO,UAAU,WAAW,MAAM,IAAI,UAAU,6BAA6B,IAAI,oBAAoB;CACzG,OAAO;AACT;AAEA,SAAS,eAAe,OAAgC,KAAiC;CACvF,MAAM,QAAQ,MAAM;CACpB,IAAI,UAAU,KAAA,GAAW,OAAO,KAAA;CAChC,IAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,GACrD,MAAM,IAAI,UAAU,6BAA6B,IAAI,0BAA0B;CAEjF,OAAO;AACT;AAEA,SAAS,aAAa,OAAuD;CAC3E,IAAI,UAAU,KAAA,GAAW,OAAO,KAAA;CAChC,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,MAAM,IAAI,UAAU,yCAAyC;CAExF,OAAO,MAAM,KAAK,WAAW;EAC3B,IAAI,CAAC,gBAAgB,MAAM,GAAG,MAAM,IAAI,UAAU,yCAAyC;EAC3F,OAAO;GACL,aAAa,eAAe,QAAQ,aAAa;GACjD,UAAU,gBAAgB,QAAQ,UAAU;GAC5C,OAAO,eAAe,QAAQ,OAAO;GACrC,OAAO,eAAe,QAAQ,OAAO;EACvC;CACF,CAAC;AACH;AAEA,SAAgB,sBAAsB,OAAkC;CACtE,IAAI,CAAC,gBAAgB,KAAK,KAAK,OAAO,MAAM,SAAS,UACnD,MAAM,IAAI,UAAU,yDAAyD;CAG/E,QAAQ,MAAM,MAAd;EACE,KAAK,iBAAiB;GACpB,MAAM,OAAO,eAAe,OAAO,MAAM;GACzC,IAAI,SAAS,eAAe,SAAS,YAAY,SAAS,QACxD,MAAM,IAAI,UAAU,mCAAmC,MAAM;GAE/D,OAAO;IAAE,WAAW,eAAe,OAAO,WAAW;IAAG;IAAM,MAAM,MAAM;GAAK;EACjF;EACA,KAAK,cACH,OAAO;GACL,OAAO,eAAe,OAAO,OAAO;GACpC,WAAW,eAAe,OAAO,WAAW;GAC5C,MAAM,MAAM;EACd;EACF,KAAK,eACH,OAAO;GAAE,WAAW,eAAe,OAAO,WAAW;GAAG,MAAM,MAAM;EAAK;EAC3E,KAAK,mBACH,OAAO;GACL,IAAI,eAAe,OAAO,IAAI;GAC9B,OAAO,eAAe,OAAO,OAAO;GACpC,MAAM,MAAM;EACd;EACF,KAAK,mBACH,OAAO;GACL,OAAO,eAAe,OAAO,OAAO;GACpC,IAAI,eAAe,OAAO,IAAI;GAC9B,MAAM,MAAM;EACd;EACF,KAAK,iBACH,OAAO;GACL,YAAY,eAAe,OAAO,YAAY;GAC9C,IAAI,eAAe,OAAO,IAAI;GAC9B,MAAM,MAAM;EACd;EACF,KAAK,cACH,OAAO;GACL,IAAI,eAAe,OAAO,IAAI;GAC9B,OAAO,MAAM;GACb,MAAM,eAAe,OAAO,MAAM;GAClC,SAAS,eAAe,OAAO,SAAS;GACxC,MAAM,MAAM;EACd;EACF,KAAK,eACH,OAAO;GACL,IAAI,eAAe,OAAO,IAAI;GAC9B,SAAS,eAAe,OAAO,SAAS;GACxC,MAAM,MAAM;EACd;EACF,KAAK,eACH,OAAO;GACL,IAAI,eAAe,OAAO,IAAI;GAC9B,QAAQ,MAAM;GACd,SAAS,eAAe,OAAO,SAAS;GACxC,MAAM,MAAM;EACd;EACF,KAAK,cACH,OAAO;GACL,OAAO,eAAe,OAAO,OAAO;GACpC,IAAI,eAAe,OAAO,IAAI;GAC9B,MAAM,MAAM;EACd;EACF,KAAK,qBACH,OAAO;GACL,SAAS,aAAa,MAAM,OAAO;GACnC,aAAa,eAAe,OAAO,aAAa;GAChD,IAAI,eAAe,OAAO,IAAI;GAC9B,OAAO,eAAe,OAAO,OAAO;GACpC,MAAM,MAAM;EACd;EACF,KAAK,qBACH,OAAO;GACL,IAAI,eAAe,OAAO,IAAI;GAC9B,MAAM,MAAM;GACZ,OAAO,eAAe,OAAO,OAAO;EACtC;EACF,KAAK;GACH,IAAI,EAAE,WAAW,QAAQ,MAAM,IAAI,UAAU,6CAA6C;GAC1F,OAAO;IAAE,MAAM,eAAe,OAAO,MAAM;IAAG,MAAM,MAAM;IAAM,OAAO,MAAM;GAAM;EACrF,KAAK,SACH,OAAO;GACL,MAAM,eAAe,OAAO,MAAM;GAClC,SAAS,eAAe,OAAO,SAAS;GACxC,WAAW,gBAAgB,OAAO,WAAW;GAC7C,MAAM,MAAM;EACd;EACF,KAAK,QAAQ;GACX,MAAM,QAAQ,MAAM;GACpB,IAAI,UAAU,KAAA,KAAa,CAAC,gBAAgB,KAAK,GAC/C,MAAM,IAAI,UAAU,oCAAoC;GAE1D,OAAO;IACL,MAAM,MAAM;IACZ,OAAO,QACH;KACE,aAAa,eAAe,OAAO,aAAa;KAChD,cAAc,eAAe,OAAO,cAAc;IACpD,IACA,KAAA;GACN;EACF;EACA,SACE,MAAM,IAAI,UAAU,wCAAwC,MAAM,MAAM;CAC5E;AACF;;;ACzIA,IAAI,WAAW;AAEf,SAAgB,8BACd,UAA0C,CAAC,GAClB;CACzB,YAAY;CACZ,MAAM,eAAe,QAAQ,kBAAkB,QAAgB,CAAC,gBAAgB,GAAG;CACnF,MAAM,WAAW,YAAY,cAAc,YAAY;EACrD,gBAAgB,QAAQ;EACxB,YAAY,QAAQ,cAAc;EAClC,mBAAmB;GACjB,QAAQ;GACR,MAAM;GACN,SAAS;GACT,GAAG,QAAQ;GACX;EACF;CACF,CAAC;CAED,OAAO;EACL,MAAM,SAAS,eAAe,CAAC,GAAG;GAChC,OAAO,yBAAyB,SAAS,UAAU;IACjD,gBAAgB,QAAQ;IACxB,OAAO,aAAa,SAAS;IAC7B,kBAAkB,QAAQ,oBAAoB;IAC9C,0BAA0B;IAC1B,aAAa;IACb;GACF,CAAC;EACH;EACA,QAAQ;GACN,SAAS,QAAQ,QAAQ;EAC3B;CACF;AACF;;;ACJA,SAAS,YAAY,OAAgB,WAAW,IAAI;CAClD,OAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;AAEA,SAAS,aAAa,OAAgB;CACpC,OAAO,OAAO,UAAU,YAAY,QAAQ,KAAA;AAC9C;AAEA,SAAS,YAAY,OAAgB;CACnC,OAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,IAAI,QAAQ,KAAA;AACvE;AAEA,SAAS,WAAW,OAAyD;CAC3E,OAAO,UAAU,YAAY,UAAU,UAAU,UAAU,UAAU,QAAQ,KAAA;AAC/E;AAEA,SAAS,UAAU,MAAkB,KAAsB;CACzD,OAAO,OAAO,OAAO,QAAQ,IAAI,MAAM,GAAG,IAAI,KAAA;AAChD;AAEA,SAAS,qBAAqB,OAAmD;CAC/E,IAAI,CAAC,gBAAgB,KAAK,KAAK,OAAO,MAAM,SAAS,YAAY,OAAO,MAAM,QAAQ,UAAU,OAAO,KAAA;CAGvG,OAAO,sBAAsBA,KAAI;AACnC;AAEA,SAAS,kBAAkB,OAAyC;CAClE,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,OAAO,CAAC;CACnC,MAAM,SAAkC,CAAC;CACzC,MAAM,SAAS,SAAS;EACtB,MAAM,aAAa,qBAAqB,IAAI;EAC5C,IAAI,YAAY,OAAO,KAAK,UAAU;CACxC,CAAC;CACD,OAAO;AACT;AAEA,SAAS,SAAS,MAAqC;CACrD,OAAO;EAAE,MAAM;EAAQ;CAAK;AAC9B;AAEA,SAAgB,sBAAsB,MAAyC;CAC7E,MAAM,WAAW,YAAY,KAAK,GAAG;CAErC,QAAQ,KAAK,MAAb;EACE,KAAK,QACH,OAAO,SAAS,YAAY,KAAK,SAAS,QAAQ,CAAC;EACrD,KAAK,WACH,OAAO;GACL,UAAU,kBAAkB,KAAK,QAAQ;GACzC,MAAM;GACN,OAAO,YAAY,UAAU,MAAM,OAAO,CAAC,KAAK;GAChD,MAAM,YAAY,UAAU,MAAM,MAAM,CAAC;EAC3C;EACF,KAAK;EACL,KAAK,UACH,OAAO;GAAE,UAAU,kBAAkB,KAAK,QAAQ;GAAG,MAAM;EAAY;EACzE,KAAK,QACH,OAAO;GACL,UAAU,kBAAkB,UAAU,MAAM,OAAO,CAAC;GACpD,MAAM;GACN,SAAS,aAAa,UAAU,MAAM,SAAS,CAAC,KAAK;GACrD,OAAO,YAAY,UAAU,MAAM,OAAO,CAAC;EAC7C;EACF,KAAK,aACH,OAAO;GAAE,UAAU,kBAAkB,KAAK,QAAQ;GAAG,MAAM;EAAY;EACzE,KAAK,cACH,OAAO;GACL,MAAM;GACN,UAAU,YAAY,UAAU,MAAM,UAAU,CAAC;GACjD,SAAS,aAAa,KAAK,OAAO;GAClC,MAAM,YAAY,KAAK,MAAM,QAAQ;EACvC;EACF,KAAK,eACH,OAAO;GAAE,MAAM;GAAe,MAAM,YAAY,KAAK,MAAM,QAAQ;EAAE;EACvE,KAAK,QACH,OAAO;GACL,UAAU,kBAAkB,KAAK,QAAQ;GACzC,MAAM,YAAY,UAAU,MAAM,MAAM,CAAC;GACzC,MAAM;GACN,MAAM,YAAY,UAAU,MAAM,MAAM,CAAC;GACzC,OAAO,YAAY,UAAU,MAAM,OAAO,CAAC;EAC7C;EACF,KAAK,SACH,OAAO;GACL,KAAK,YAAY,UAAU,MAAM,KAAK,CAAC;GACvC,MAAM,YAAY,UAAU,MAAM,KAAK,CAAC;GACxC,MAAM;GACN,OAAO,YAAY,UAAU,MAAM,OAAO,CAAC;EAC7C;EACF,KAAK,kBACH,OAAO,EAAE,MAAM,iBAAiB;EAClC,KAAK,cACH,OAAO;GAAE,UAAU,kBAAkB,KAAK,QAAQ;GAAG,MAAM;EAAa;EAC1E,KAAK,SAAS;GACZ,MAAM,SAAS,UAAU,MAAM,QAAQ;GACvC,MAAM,OAAO,UAAU,MAAM,MAAM;GACnC,OAAO;IACL,UAAU,kBAAkB,MAAM,QAAQ,IAAI,IAAI,CAAC,QAAQ,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC;IAC9E,MAAM;GACR;EACF;EACA,KAAK,aACH,OAAO;GAAE,UAAU,kBAAkB,UAAU,MAAM,OAAO,CAAC;GAAG,MAAM;EAAY;EACpF,KAAK,cACH,OAAO;GACL,OAAO,WAAW,UAAU,MAAM,OAAO,CAAC;GAC1C,UAAU,kBAAkB,KAAK,QAAQ;GACzC,QAAQ,aAAa,UAAU,MAAM,QAAQ,CAAC;GAC9C,MAAM;EACR;EACF,KAAK,UACH,OAAO;GAAE,UAAU,kBAAkB,KAAK,QAAQ;GAAG,MAAM;EAAS;EACtE,KAAK,YACH,OAAO;GAAE,UAAU,kBAAkB,KAAK,QAAQ;GAAG,MAAM;EAAW;EACxE,KAAK,iBACH,OAAO;GAAE,UAAU,kBAAkB,KAAK,QAAQ;GAAG,MAAM;EAAgB;EAC7E,KAAK,aACH,OAAO;GAAE,UAAU,kBAAkB,KAAK,QAAQ;GAAG,MAAM;EAAY;EACzE,KAAK,UACH,OAAO;GAAE,UAAU,kBAAkB,KAAK,QAAQ;GAAG,MAAM;EAAS;EACtE,KAAK,aACH,OAAO;GAAE,UAAU,kBAAkB,KAAK,QAAQ;GAAG,MAAM;EAAY;EACzE,KAAK,eACH,OAAO;GAAE,UAAU,kBAAkB,KAAK,QAAQ;GAAG,MAAM;EAAc;EAC3E,KAAK;EACL,KAAK,kBACH,OAAO;GAAE,SAAS,aAAa,UAAU,MAAM,SAAS,CAAC;GAAG,MAAM;EAAW;EAC/E,KAAK,SACH,OAAO,SAAS,YAAY,UAAU,MAAM,QAAQ,GAAG,QAAQ,CAAC;EAClE,KAAK,mBACH,OAAO;GAAE,UAAU,kBAAkB,UAAU,MAAM,OAAO,CAAC;GAAG,MAAM;EAAkB;EAC1F,KAAK,mBACH,OAAO;GACL,UAAU,CACR;IAAE,UAAU,kBAAkB,UAAU,MAAM,MAAM,CAAC;IAAG,QAAQ;IAAM,MAAM;GAAa,GACzF;IAAE,UAAU,kBAAkB,UAAU,MAAM,YAAY,CAAC;IAAG,MAAM;GAAa,CACnF;GACA,MAAM;EACR;EACF,KAAK,YACH,OAAO;GAAE,UAAU,kBAAkB,KAAK,QAAQ;GAAG,MAAM;GAAY,OAAO,YAAY,UAAU,MAAM,IAAI,CAAC;EAAE;EACnH,KAAK;EACL,KAAK,aACH,OAAO;GAAE,MAAM;GAAY,MAAM,YAAY,UAAU,MAAM,IAAI,CAAC;EAAE;EACtE,KAAK,cACH,OAAO;GACL,UAAU,kBAAkB,KAAK,QAAQ;GACzC,MAAM;GACN,MAAM,YAAY,UAAU,MAAM,MAAM,CAAC;GACzC,OAAO,YAAY,UAAU,MAAM,OAAO,CAAC;EAC7C;EACF,KAAK,iBACH,OAAO;GACL,UAAU,kBAAkB,KAAK,QAAQ;GACzC,MAAM;GACN,SAAS,aAAa,KAAK,OAAO;GAClC,OAAO,YAAY,UAAU,MAAM,MAAM,CAAC;EAC5C;EACF,KAAK,aACH,OAAO,EAAE,MAAM,YAAY;EAC7B,KAAK,eACH,OAAO;GAAE,MAAM;GAAe,MAAM,YAAY,KAAK,SAAS,QAAQ;EAAE;EAC1E,KAAK,cACH,OAAO;GAAE,MAAM;GAAc,MAAM,YAAY,KAAK,SAAS,QAAQ;EAAE;EACzE,KAAK;EACL,KAAK,eACH,OAAO,SAAS,YAAY,KAAK,SAAS,QAAQ,CAAC;EACrD,SACE,OAAO,SAAS,QAAQ;CAC5B;AACF;AAEA,SAAgB,uBAAuB,OAA8C;CACnF,OAAO,MAAM,IAAI,qBAAqB;AACxC;;;ACnNA,SAAS,4BAA8C;CACrD,IAAI,wBAAQ,IAAI,WAAW,CAAC;CAE5B,OAAO,EACL,OAAO,OAAO,QAAQ,OAAO;EAC3B,MAAM,QAAQ,IAAI,WAAW,MAAM,SAAS,MAAM,MAAM;EACxD,MAAM,IAAI,KAAK;EACf,MAAM,IAAI,OAAO,MAAM,MAAM;EAC7B,IAAI,SAAS;EACb,IAAI,SAAS;EAEb,OAAO,SAAS,MAAM,QAAQ;GAC5B,MAAM,QAAQ,MAAM;GACpB,IAAI,QAAQ,KAAM;IAChB,UAAU,OAAO,cAAc,KAAK;IACpC,UAAU;IACV;GACF;GAEA,MAAM,OAAO,SAAS,MAAO,IAAI,SAAS,MAAO,IAAI,SAAS,MAAO,IAAI;GACzE,IAAI,SAAS,GAAG;IACd,UAAU;IACV,UAAU;IACV;GACF;GACA,IAAI,SAAS,OAAO,MAAM,QAAQ;GAElC,IAAI,YAAY,SAAS,SAAS,IAAI,KAAO,SAAS,IAAI,KAAO;GACjE,IAAI,QAAQ;GACZ,KAAK,IAAI,QAAQ,GAAG,QAAQ,MAAM,SAAS,GAAG;IAC5C,MAAM,eAAe,MAAM,SAAS;IACpC,KAAK,eAAe,SAAU,KAAM;KAClC,QAAQ;KACR;IACF;IACA,YAAa,aAAa,IAAM,eAAe;GACjD;GAEA,IAAI,CAAC,SAAS,YAAY,SAAU;IAClC,UAAU;IACV,UAAU;IACV;GACF;GAEA,UAAU,OAAO,cAAc,SAAS;GACxC,UAAU;EACZ;EAEA,QAAQ,MAAM,MAAM,MAAM;EAC1B,IAAI,SAAS,MAAM,SAAS,GAAG;GAC7B,UAAU;GACV,wBAAQ,IAAI,WAAW,CAAC;EAC1B;EACA,OAAO;CACT,EACF;AACF;AAEA,SAAS,oBAAsC;CAC7C,IAAI,OAAO,gBAAgB,YAAY;EACrC,MAAM,UAAU,IAAI,YAAY;EAChC,OAAO,EACL,OAAO,OAAO,QAAQ,OAAO;GAC3B,OAAO,QAAQ,OAAO,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC;EACjD,EACF;CACF;CACA,OAAO,0BAA0B;AACnC;AAEA,SAAS,QAAQ,OAAiC;CAChD,OAAO,iBAAiB,aAAa,QAAQ,IAAI,WAAW,KAAK;AACnE;AAEA,SAAgB,4BAAiD;CAC/D,MAAM,UAAU,wBAAwB;CACxC,MAAM,UAAU,kBAAkB;CAClC,MAAM,YAAsB,CAAC;CAC7B,IAAI,aAAa;CACjB,IAAI,QAAQ;CAEZ,SAAS,WAAW;EAClB,IAAI,UAAU,WAAW,KAAK,OAAO;EACrC,MAAM,UAAU,UAAU,KAAK,IAAI;EACnC,UAAU,SAAS;EACnB,IAAI,YAAY,UAAU;GACxB,QAAQ,KAAK,EAAE,MAAM,OAAO,CAAC;GAC7B;EACF;EAEA,IAAI;GACF,QAAQ,KAAK,sBAAsB,KAAK,MAAM,OAAO,CAAC,CAAC;EACzD,SAAS,OAAO;GACd,QAAQ;GACR,QAAQ,KAAK,KAAK;EACpB;CACF;CAEA,SAAS,YAAY,MAAc;EACjC,MAAM,aAAa,KAAK,SAAS,IAAI,IAAI,KAAK,MAAM,GAAG,EAAE,IAAI;EAC7D,IAAI,WAAW,WAAW,GAAG;GAC3B,SAAS;GACT;EACF;EACA,IAAI,WAAW,WAAW,GAAG,GAAG;EAChC,IAAI,eAAe,QAAQ;GACzB,UAAU,KAAK,EAAE;GACjB;EACF;EACA,IAAI,WAAW,WAAW,OAAO,GAAG;GAClC,MAAM,QAAQ,WAAW,MAAM,CAAC;GAChC,UAAU,KAAK,MAAM,WAAW,GAAG,IAAI,MAAM,MAAM,CAAC,IAAI,KAAK;EAC/D;CACF;CAEA,SAAS,WAAW,OAAe;EACjC,cAAc;EACd,IAAI,UAAU,WAAW,QAAQ,IAAI;EACrC,OAAO,WAAW,GAAG;GACnB,YAAY,WAAW,MAAM,GAAG,OAAO,CAAC;GACxC,aAAa,WAAW,MAAM,UAAU,CAAC;GACzC,UAAU,WAAW,QAAQ,IAAI;EACnC;CACF;CAEA,OAAO;EACL,MAAM;GACJ,IAAI,OAAO;GACX,WAAW,QAAQ,uBAAO,IAAI,WAAW,CAAC,GAAG,IAAI,CAAC;GAClD,IAAI,WAAW,SAAS,GAAG,YAAY,UAAU;GACjD,SAAS;GACT,QAAQ;GACR,QAAQ,IAAI;EACd;EACA,KAAK,OAAO;GACV,IAAI,OAAO;GACX,QAAQ;GACR,QAAQ,KAAK,KAAK;EACpB;EACA,KAAK,OAAO;GACV,IAAI,OAAO;GACX,WAAW,OAAO,UAAU,WAAW,QAAQ,QAAQ,OAAO,QAAQ,KAAK,CAAC,CAAC;EAC/E;EACA,QAAQ,QAAQ;CAClB;AACF"}
|
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
|
+
}
|