@langchain/langgraph-sdk
Version:
Client library for interacting with the LangGraph API
1 lines • 53.8 kB
Source Map (JSON)
{"version":3,"file":"messages.cjs","names":["#events","MultiCursorBuffer","#textPromise","#reasoningPromise","#resolveText","#resolveReasoning","#textChunks","#textWaiters","#textDone","#reasoningChunks","#reasoningWaiters","#reasoningDone","#usageIterator","#assembleMessage","AIMessage","#assembler","#activeStreaming"],"sources":["../../../src/client/stream/messages.ts"],"sourcesContent":["import {\n AIMessage,\n type ContentBlock as CoreContentBlock,\n type UsageMetadata,\n} from \"@langchain/core/messages\";\nimport type { ChatModelStreamEvent } from \"@langchain/core/language_models/event\";\nimport type {\n ContentBlock,\n ContentBlockDelta,\n FinalizedContentBlock,\n MessageMetadata,\n MessagesEvent,\n UsageInfo,\n} from \"@langchain/protocol\";\n\nimport { MultiCursorBuffer } from \"./multi-cursor-buffer.js\";\n\ntype TextContentStream = AsyncIterable<string> &\n PromiseLike<string> & { full: AsyncIterable<string> };\n\ntype UsageMetadataStream = AsyncIterable<UsageMetadata> &\n PromiseLike<UsageMetadata | undefined>;\n\ntype ToolCallsStream = AsyncIterable<CoreContentBlock.Tools.ToolCall> &\n PromiseLike<Array<CoreContentBlock.Tools.ToolCall>> & {\n full: AsyncIterable<Array<CoreContentBlock.Tools.ToolCall>>;\n };\n\n// Deltas are typed by the protocol, not `@langchain/core`, whose union\n// doesn't include `tool-call-delta` yet.\ntype ContentBlockDeltaEvent = Omit<\n Extract<ChatModelStreamEvent, { event: \"content-block-delta\" }>,\n \"delta\"\n> & { delta: ContentBlockDelta; content?: CoreContentBlock };\n\ntype ToolCallChunkBlock =\n | CoreContentBlock.Tools.ToolCallChunk\n | CoreContentBlock.Tools.ServerToolCallChunk;\n\nfunction isToolCallChunk(\n block: CoreContentBlock | undefined\n): block is ToolCallChunkBlock {\n return (\n block?.type === \"tool_call_chunk\" ||\n block?.type === \"server_tool_call_chunk\"\n );\n}\n\nfunction applyCoreContentDelta(\n target: CoreContentBlock,\n delta: CoreContentBlock\n): CoreContentBlock {\n if (target.type !== delta.type) {\n return structuredClone(delta);\n }\n\n switch (delta.type) {\n case \"text\":\n return {\n ...target,\n ...delta,\n text: `${\"text\" in target ? target.text : \"\"}${delta.text}`,\n } as CoreContentBlock;\n case \"reasoning\":\n return {\n ...target,\n ...delta,\n reasoning: `${\"reasoning\" in target ? target.reasoning : \"\"}${delta.reasoning}`,\n } as CoreContentBlock;\n case \"tool_call_chunk\":\n case \"server_tool_call_chunk\": {\n const merged = { ...target, ...delta } as Record<string, unknown>;\n if (delta.id == null && \"id\" in target && target.id != null) {\n merged.id = target.id;\n }\n if (delta.name == null && \"name\" in target && target.name != null) {\n merged.name = target.name;\n }\n merged.args = `${(\"args\" in target ? target.args : \"\") ?? \"\"}${delta.args ?? \"\"}`;\n return merged as unknown as CoreContentBlock;\n }\n default:\n return { ...target, ...delta } as CoreContentBlock;\n }\n}\n\nfunction coreContentBlockFromDelta(\n delta: ContentBlockDelta,\n current?: CoreContentBlock\n): CoreContentBlock | undefined {\n switch (delta.type) {\n case \"text-delta\":\n return { type: \"text\", text: delta.text } as CoreContentBlock;\n case \"reasoning-delta\":\n return {\n type: \"reasoning\",\n reasoning: delta.reasoning,\n } as CoreContentBlock;\n case \"data-delta\": {\n const merged = { ...(current ?? {}), data: delta.data } as Record<\n string,\n unknown\n >;\n if (delta.encoding) merged.encoding = delta.encoding;\n return merged as unknown as CoreContentBlock;\n }\n case \"block-delta\":\n return delta.fields as CoreContentBlock;\n case \"tool-call-delta\":\n // Without the block's start there's no id or name to attach the\n // slice to; `content-block-finish` delivers the complete call.\n return isToolCallChunk(current)\n ? { type: current.type, args: delta.args }\n : undefined;\n default:\n // Unknown variants are ignored.\n return undefined;\n }\n}\n\nfunction applyCoreEventDelta(\n current: CoreContentBlock | undefined,\n event: ContentBlockDeltaEvent\n): CoreContentBlock | undefined {\n if (event.content) {\n return current\n ? applyCoreContentDelta(current, event.content)\n : event.content;\n }\n\n switch (event.delta.type) {\n case \"text-delta\":\n if (current?.type === \"text\") {\n return {\n ...current,\n text: `${\"text\" in current ? current.text : \"\"}${event.delta.text}`,\n } as CoreContentBlock;\n }\n return coreContentBlockFromDelta(event.delta, current);\n case \"reasoning-delta\":\n if (current?.type === \"reasoning\") {\n return {\n ...current,\n reasoning: `${\"reasoning\" in current ? current.reasoning : \"\"}${event.delta.reasoning}`,\n } as CoreContentBlock;\n }\n return coreContentBlockFromDelta(event.delta, current);\n case \"data-delta\": {\n const merged = { ...(current ?? {}) } as Record<string, unknown>;\n merged.data = `${(merged.data as string | undefined) ?? \"\"}${event.delta.data}`;\n if (event.delta.encoding) merged.encoding = event.delta.encoding;\n return merged as unknown as CoreContentBlock;\n }\n case \"block-delta\":\n return {\n ...(current ?? {}),\n ...event.delta.fields,\n } as CoreContentBlock;\n case \"tool-call-delta\":\n if (!isToolCallChunk(current)) return current;\n return {\n ...current,\n args: `${current.args ?? \"\"}${event.delta.args}`,\n };\n default:\n return current;\n }\n}\n\nfunction normalizeUsage(\n usage: UsageInfo | Partial<UsageMetadata> | undefined\n): UsageMetadata | undefined {\n if (!usage) return undefined;\n return {\n ...usage,\n input_tokens: usage.input_tokens ?? 0,\n output_tokens: usage.output_tokens ?? 0,\n total_tokens: usage.total_tokens ?? 0,\n };\n}\n\nfunction readRunId(data: object): string | undefined {\n const record = data as Record<string, unknown>;\n return typeof record.run_id === \"string\" ? record.run_id : undefined;\n}\n\nfunction readUsage(data: object): UsageInfo | undefined {\n const usage = (data as Record<string, unknown>).usage;\n return usage != null && typeof usage === \"object\" && !Array.isArray(usage)\n ? (usage as UsageInfo)\n : undefined;\n}\n\nfunction readFinishMetadata(data: object): Record<string, unknown> | undefined {\n const record = data as Record<string, unknown>;\n const isRecord = (value: unknown): value is Record<string, unknown> =>\n value != null && typeof value === \"object\" && !Array.isArray(value);\n const merged = {\n ...(isRecord(record.responseMetadata) ? record.responseMetadata : {}),\n ...(isRecord(record.metadata) ? record.metadata : {}),\n };\n return Object.keys(merged).length > 0 ? merged : undefined;\n}\n\n/**\n * Mutable view of a streamed message as message and content-block events are\n * assembled into a single structure.\n */\nexport interface AssembledMessage {\n id: string;\n namespace: string[];\n blocks: ContentBlock[];\n node?: string;\n runId?: string;\n usage?: UsageInfo;\n metadata?: MessageMetadata;\n finishMetadata?: Record<string, any>;\n finishReason?: string;\n error?: {\n message: string;\n code?: string;\n };\n}\n\n/**\n * Symbol keys for assembler → StreamingMessage communication.\n * Module-private: invisible to external consumers, accessible to\n * {@link StreamingMessageAssembler} within this file.\n */\nconst PUSH_TEXT: unique symbol = Symbol(\"pushText\");\nconst PUSH_REASONING: unique symbol = Symbol(\"pushReasoning\");\nconst PUSH_EVENT: unique symbol = Symbol(\"pushEvent\");\nconst UPDATE_CONTEXT: unique symbol = Symbol(\"updateContext\");\nconst FINISH: unique symbol = Symbol(\"finish\");\nconst ERROR: unique symbol = Symbol(\"error\");\n\n/**\n * Live streaming view of a single message lifecycle, matching the\n * in-process `ChatModelStream` dual-interface pattern.\n *\n * - `text` / `reasoning`: iterate for streaming deltas, or await for\n * the full concatenated string after the message completes.\n * - `usage`: promise that resolves with token usage on message-finish.\n * - `blocks`: the assembled content blocks (updated as deltas arrive).\n *\n * Created by {@link StreamingMessageAssembler} and yielded by\n * the `session.messages` lazy getter.\n */\nexport class StreamingMessage\n implements AsyncIterable<ChatModelStreamEvent>, PromiseLike<AIMessage>\n{\n readonly id: string;\n readonly namespace: string[];\n node: string | undefined;\n readonly metadata: MessageMetadata | undefined;\n readonly assembled: AssembledMessage;\n readonly #events = new MultiCursorBuffer<ChatModelStreamEvent>();\n\n #textChunks: string[] = [];\n #reasoningChunks: string[] = [];\n #textWaiters: Array<() => void> = [];\n #reasoningWaiters: Array<() => void> = [];\n #textDone = false;\n #reasoningDone = false;\n\n #resolveText!: (v: string) => void;\n #resolveReasoning!: (v: string) => void;\n readonly #textPromise: Promise<string>;\n readonly #reasoningPromise: Promise<string>;\n\n constructor(assembled: AssembledMessage) {\n this.id = assembled.id;\n this.assembled = assembled;\n this.namespace = assembled.namespace;\n this.node = assembled.node;\n this.metadata = assembled.metadata;\n this.#textPromise = new Promise<string>((r) => {\n this.#resolveText = r;\n });\n this.#reasoningPromise = new Promise<string>((r) => {\n this.#resolveReasoning = r;\n });\n }\n\n get text(): TextContentStream {\n const chunks = this.#textChunks;\n const waiters = this.#textWaiters;\n const getDone = () => this.#textDone;\n let cursor = 0;\n return {\n [Symbol.asyncIterator]() {\n return {\n async next(): Promise<IteratorResult<string>> {\n while (true) {\n if (cursor < chunks.length) {\n return { done: false, value: chunks[cursor++] };\n }\n if (getDone()) {\n return { done: true, value: undefined };\n }\n await new Promise<void>((resolve) => {\n waiters.push(resolve);\n });\n }\n },\n };\n },\n then: this.#textPromise.then.bind(this.#textPromise),\n full: {\n async *[Symbol.asyncIterator]() {\n let accumulated = \"\";\n for await (const chunk of {\n [Symbol.asyncIterator]: () =>\n ({\n next: async (): Promise<IteratorResult<string>> => {\n while (true) {\n if (cursor < chunks.length) {\n return { done: false, value: chunks[cursor++] };\n }\n if (getDone()) {\n return { done: true, value: undefined };\n }\n await new Promise<void>((resolve) => {\n waiters.push(resolve);\n });\n }\n },\n }) satisfies AsyncIterator<string>,\n }) {\n accumulated += chunk;\n yield accumulated;\n }\n },\n },\n };\n }\n\n get reasoning(): TextContentStream {\n const chunks = this.#reasoningChunks;\n const waiters = this.#reasoningWaiters;\n const getDone = () => this.#reasoningDone;\n let cursor = 0;\n return {\n [Symbol.asyncIterator]() {\n return {\n async next(): Promise<IteratorResult<string>> {\n while (true) {\n if (cursor < chunks.length) {\n return { done: false, value: chunks[cursor++] };\n }\n if (getDone()) {\n return { done: true, value: undefined };\n }\n await new Promise<void>((resolve) => {\n waiters.push(resolve);\n });\n }\n },\n };\n },\n then: this.#reasoningPromise.then.bind(this.#reasoningPromise),\n full: {\n async *[Symbol.asyncIterator]() {\n let accumulated = \"\";\n for await (const chunk of {\n [Symbol.asyncIterator]: () =>\n ({\n next: async (): Promise<IteratorResult<string>> => {\n while (true) {\n if (cursor < chunks.length) {\n return { done: false, value: chunks[cursor++] };\n }\n if (getDone()) {\n return { done: true, value: undefined };\n }\n await new Promise<void>((resolve) => {\n waiters.push(resolve);\n });\n }\n },\n }) satisfies AsyncIterator<string>,\n }) {\n accumulated += chunk;\n yield accumulated;\n }\n },\n },\n };\n }\n\n get usage(): UsageMetadataStream {\n const promise = (async () => {\n let usage: UsageMetadata | undefined;\n for await (const snapshot of this.#usageIterator()) {\n usage = snapshot;\n }\n return usage;\n })();\n return {\n [Symbol.asyncIterator]: () => this.#usageIterator(),\n then: promise.then.bind(promise),\n };\n }\n\n get toolCalls(): ToolCallsStream {\n const events = this.#events;\n const iterator = async function* () {\n for await (const event of events) {\n if (\n event.event === \"content-block-finish\" &&\n event.content.type === \"tool_call\"\n ) {\n yield event.content as CoreContentBlock.Tools.ToolCall;\n }\n }\n };\n return {\n [Symbol.asyncIterator]: iterator,\n then: async (onfulfilled, onrejected) => {\n try {\n const calls: CoreContentBlock.Tools.ToolCall[] = [];\n for await (const call of iterator()) calls.push(call);\n return onfulfilled ? onfulfilled(calls) : (calls as never);\n } catch (err) {\n if (onrejected) return onrejected(err);\n throw err;\n }\n },\n full: {\n async *[Symbol.asyncIterator]() {\n const calls: CoreContentBlock.Tools.ToolCall[] = [];\n for await (const call of iterator()) {\n calls.push(call);\n yield [...calls];\n }\n },\n },\n };\n }\n\n get output(): PromiseLike<AIMessage> {\n return { then: (onf, onr) => this.#assembleMessage().then(onf, onr) };\n }\n\n get blocks(): ContentBlock[] {\n return this.assembled.blocks;\n }\n\n [Symbol.asyncIterator](): AsyncIterator<ChatModelStreamEvent> {\n return this.#events[Symbol.asyncIterator]();\n }\n\n then<TResult1 = AIMessage, TResult2 = never>(\n onfulfilled?:\n | ((value: AIMessage) => TResult1 | PromiseLike<TResult1>)\n | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null\n ): PromiseLike<TResult1 | TResult2> {\n return this.#assembleMessage().then(onfulfilled, onrejected);\n }\n\n async *#usageIterator(): AsyncGenerator<UsageMetadata> {\n for await (const event of this.#events) {\n if (event.event === \"message-start\" && event.usage) {\n yield normalizeUsage(event.usage)!;\n } else if (event.event === \"message-finish\" && event.usage) {\n yield normalizeUsage(event.usage)!;\n }\n }\n }\n\n async #assembleMessage(): Promise<AIMessage> {\n const contentBlocks: Array<CoreContentBlock | undefined> = [];\n let id: string | undefined = this.id;\n let usage = normalizeUsage(this.assembled.usage);\n let metadata: Record<string, unknown> = {\n ...(this.assembled.finishMetadata ?? {}),\n };\n let finishReason: string | undefined = this.assembled.finishReason;\n\n for await (const event of this.#events) {\n switch (event.event) {\n case \"message-start\":\n id = event.id ?? id;\n if (event.usage) usage = normalizeUsage(event.usage);\n break;\n case \"content-block-start\":\n contentBlocks[event.index] = event.content;\n break;\n case \"content-block-delta\": {\n const current = contentBlocks[event.index];\n contentBlocks[event.index] = applyCoreEventDelta(current, event);\n break;\n }\n case \"content-block-finish\":\n contentBlocks[event.index] = event.content;\n break;\n case \"message-finish\": {\n finishReason = event.reason;\n if (event.usage) usage = normalizeUsage(event.usage);\n const finishMetadata = readFinishMetadata(event);\n if (finishMetadata != null) {\n metadata = { ...metadata, ...finishMetadata };\n }\n break;\n }\n default:\n break;\n }\n }\n\n return new AIMessage({\n id,\n content: contentBlocks.filter(\n (block): block is CoreContentBlock => block != null\n ),\n usage_metadata: usage,\n additional_kwargs: {\n namespace: this.namespace,\n ...(this.node != null ? { node: this.node } : {}),\n ...(this.assembled.runId != null\n ? { run_id: this.assembled.runId }\n : {}),\n ...(this.metadata != null ? { metadata: this.metadata } : {}),\n ...(this.assembled.usage != null\n ? { usage: this.assembled.usage }\n : {}),\n },\n response_metadata: {\n ...(finishReason != null ? { finish_reason: finishReason } : {}),\n ...metadata,\n output_version: \"v1\" as const,\n },\n });\n }\n\n [PUSH_EVENT](event: ChatModelStreamEvent): void {\n this.#events.push(event);\n }\n\n [UPDATE_CONTEXT](event: MessagesEvent): void {\n this.node = event.params.node ?? this.node;\n }\n\n [PUSH_TEXT](delta: string): void {\n this.#textChunks.push(delta);\n // Wake every caught-up iterator so each one advances its own cursor.\n // Iterators re-check `chunks.length` before delivering, which keeps\n // the cursor the single source of truth for what a consumer has seen.\n const pending = this.#textWaiters.splice(0, this.#textWaiters.length);\n for (const waiter of pending) waiter();\n }\n\n [PUSH_REASONING](delta: string): void {\n this.#reasoningChunks.push(delta);\n const pending = this.#reasoningWaiters.splice(\n 0,\n this.#reasoningWaiters.length\n );\n for (const waiter of pending) waiter();\n }\n\n [FINISH](): void {\n this.#textDone = true;\n this.#reasoningDone = true;\n this.#resolveText(this.#textChunks.join(\"\"));\n this.#resolveReasoning(this.#reasoningChunks.join(\"\"));\n const textPending = this.#textWaiters.splice(0, this.#textWaiters.length);\n for (const waiter of textPending) waiter();\n const reasoningPending = this.#reasoningWaiters.splice(\n 0,\n this.#reasoningWaiters.length\n );\n for (const waiter of reasoningPending) waiter();\n this.#events.close();\n }\n\n [ERROR](): void {\n this[FINISH]();\n }\n}\n\n/**\n * Public view yielded by message projections.\n *\n * `StreamingMessage` is PromiseLike so callers can still `await` a message\n * object directly, but TypeScript applies `Awaited<T>` to values produced by\n * `for await`. Exposing a non-thenable view keeps loop variables typed as the\n * streaming handle instead of as the finalized `AIMessage`.\n */\nexport type StreamingMessageHandle = Omit<StreamingMessage, \"then\">;\n\nexport function toStreamingMessageHandle(\n message: StreamingMessage\n): StreamingMessageHandle {\n return new Proxy(message, {\n get(target, prop) {\n if (prop === \"then\") return undefined;\n const value = Reflect.get(target, prop, target);\n return typeof value === \"function\" ? value.bind(target) : value;\n },\n has(target, prop) {\n if (prop === \"then\") return false;\n return prop in target;\n },\n }) as StreamingMessageHandle;\n}\n\n/**\n * Emitted by `MessageAssembler.consume()` to describe how a message changed in\n * response to a single protocol event.\n */\nexport type MessageAssemblyUpdate =\n | {\n kind: \"message-start\";\n key: string;\n message: AssembledMessage;\n event: MessagesEvent;\n }\n | {\n kind: \"content-block-start\" | \"content-block-delta\";\n key: string;\n message: AssembledMessage;\n index: number;\n block: ContentBlock;\n event: MessagesEvent;\n }\n | {\n kind: \"content-block-finish\";\n key: string;\n message: AssembledMessage;\n index: number;\n block: FinalizedContentBlock;\n event: MessagesEvent;\n }\n | {\n kind: \"usage\";\n key: string;\n message: AssembledMessage;\n event: MessagesEvent;\n }\n | {\n kind: \"message-finish\";\n key: string;\n message: AssembledMessage;\n event: MessagesEvent;\n }\n | {\n kind: \"message-error\";\n key: string;\n message: AssembledMessage;\n event: MessagesEvent;\n };\n\nfunction cloneBlock<T extends ContentBlock>(block: T): T {\n return structuredClone(block);\n}\n\nfunction blockFromDelta(\n delta: ContentBlockDelta,\n current?: ContentBlock\n): ContentBlock | undefined {\n return coreContentBlockFromDelta(\n delta,\n current as unknown as CoreContentBlock | undefined\n ) as unknown as ContentBlock | undefined;\n}\n\nfunction applyContentDelta(\n target: ContentBlock,\n delta: ContentBlock\n): ContentBlock {\n if (target.type !== delta.type) {\n return cloneBlock(delta);\n }\n\n switch (delta.type) {\n case \"text\":\n return {\n ...target,\n ...delta,\n text: `${\"text\" in target ? target.text : \"\"}${delta.text}`,\n } as ContentBlock;\n case \"reasoning\":\n return {\n ...target,\n ...delta,\n reasoning: `${\"reasoning\" in target ? target.reasoning : \"\"}${delta.reasoning}`,\n } as ContentBlock;\n case \"tool_call_chunk\":\n case \"server_tool_call_chunk\": {\n // Spread target first, then delta — but preserve target's\n // ``id``/``name`` when the delta explicitly sets them to\n // null/undefined. Some providers (notably Anthropic via the\n // langchain-core compat bridge) only attach the tool-call\n // identifiers to the first ``content-block-start`` chunk; every\n // subsequent ``input_json_delta`` chunk carries ``id=null,\n // name=null``. A naive ``{...target, ...delta}`` spread\n // overwrites the captured identifiers with null, which in turn\n // makes downstream consumers (e.g. ``extractToolCallChunks`` in\n // ``assembled-to-message.ts``) drop the chunk on the floor until\n // the final ``content-block-finish`` event promotes it to a\n // finalized ``tool_call`` — causing tool-call cards to appear\n // all-at-once at the end of the turn instead of incrementally.\n const merged = { ...target, ...delta } as Record<string, unknown>;\n if (delta.id == null && \"id\" in target && target.id != null) {\n merged.id = target.id;\n }\n if (delta.name == null && \"name\" in target && target.name != null) {\n merged.name = target.name;\n }\n merged.args = `${(\"args\" in target ? target.args : \"\") ?? \"\"}${delta.args ?? \"\"}`;\n return merged as unknown as ContentBlock;\n }\n default:\n return {\n ...target,\n ...delta,\n } as ContentBlock;\n }\n}\n\nfunction messageKeyFor(event: MessagesEvent): string {\n const { namespace, node, data } = event.params;\n const namespaceKey = namespace.join(\"/\");\n const runId = readRunId(data);\n const messageId = data.event === \"message-start\" ? (data.id ?? \"\") : \"\";\n return `${namespaceKey}::${node ?? \"\"}::${runId ?? messageId}`;\n}\n\nfunction toChatModelStreamEvent(event: MessagesEvent): ChatModelStreamEvent {\n return event.params.data as unknown as ChatModelStreamEvent;\n}\n\n/**\n * Incrementally assembles `messages` events into complete message objects.\n */\nexport class MessageAssembler {\n private readonly activeMessages = new Map<string, AssembledMessage>();\n private readonly activeByNamespaceNode = new Map<string, string>();\n private readonly blockIndexByProtocolIndexAndType = new Map<string, number>();\n\n /**\n * Applies a single message event and returns the resulting assembly update.\n *\n * Returns `undefined` when the event changes nothing, such as a delta\n * variant this version doesn't recognise. Those are ignored so that a\n * newer producer can't break the stream; `content-block-finish` still\n * carries the complete block.\n *\n * @param event - Incoming `messages` event to fold into the assembler state.\n */\n consume(event: MessagesEvent): MessageAssemblyUpdate | undefined {\n const data = event.params.data;\n const namespaceNodeKey = `${event.params.namespace.join(\"/\")}::${event.params.node ?? \"\"}`;\n const runId = readRunId(data);\n\n if (data.event === \"message-start\") {\n const key = messageKeyFor(event);\n this.activeByNamespaceNode.set(namespaceNodeKey, key);\n const message: AssembledMessage = {\n id: data.id,\n namespace: [...event.params.namespace],\n node: event.params.node,\n runId,\n usage: readUsage(data),\n metadata: data.metadata,\n blocks: [],\n };\n this.activeMessages.set(key, message);\n return { kind: \"message-start\", key, message, event };\n }\n\n const runKey = runId != null ? `${namespaceNodeKey}::${runId}` : undefined;\n const fallbackKey = this.activeByNamespaceNode.get(namespaceNodeKey);\n const fallbackMessage =\n fallbackKey != null ? this.activeMessages.get(fallbackKey) : undefined;\n const activeKey =\n (runKey != null && this.activeMessages.has(runKey)\n ? runKey\n : undefined) ??\n (runId == null || fallbackMessage?.runId == null\n ? fallbackKey\n : undefined);\n if (!activeKey) {\n // A continuation event (delta/finish/error) arrived without a\n // prior `message-start`. This can happen on late-attaching\n // subscriptions when the server has already trimmed the\n // `message-start` from its replay buffer. Synthesize a minimal\n // active message so the assembler can still fold subsequent\n // events instead of hard-failing the caller.\n const syntheticKey = runKey ?? `${namespaceNodeKey}::`;\n this.activeByNamespaceNode.set(namespaceNodeKey, syntheticKey);\n const synthetic: AssembledMessage = {\n id: data.id,\n namespace: [...event.params.namespace],\n node: event.params.node,\n runId,\n blocks: [],\n };\n this.activeMessages.set(syntheticKey, synthetic);\n return this.consume(event);\n }\n\n const message = this.activeMessages.get(activeKey);\n if (!message) {\n throw new Error(`No active message state found for key ${activeKey}`);\n }\n\n if ((data as { event?: string }).event === \"usage\") {\n message.usage = (data as { usage?: UsageInfo }).usage;\n return {\n kind: \"usage\",\n key: activeKey,\n message,\n event,\n };\n }\n\n switch (data.event) {\n case \"content-block-start\": {\n message.blocks[data.index] = cloneBlock(data.content);\n this.blockIndexByProtocolIndexAndType.set(\n blockIndexKey(activeKey, data.index, data.content.type),\n data.index\n );\n return {\n kind: \"content-block-start\",\n key: activeKey,\n message,\n index: data.index,\n block: data.content,\n event,\n };\n }\n case \"content-block-delta\": {\n const deltaEvent = data as typeof data & {\n content?: ContentBlock;\n delta?: ContentBlockDelta;\n };\n if (deltaEvent.content == null && deltaEvent.delta == null) {\n throw new Error(\"Received content-block-delta without content\");\n }\n const deltaBlock =\n deltaEvent.content ??\n blockFromDelta(deltaEvent.delta!, message.blocks[data.index]);\n if (deltaBlock == null) return undefined;\n const targetIndex = this.resolveBlockIndex(\n activeKey,\n message.blocks,\n data.index,\n deltaBlock.type\n );\n const current = message.blocks[targetIndex];\n message.blocks[targetIndex] =\n deltaEvent.content != null\n ? current == null\n ? cloneBlock(deltaEvent.content)\n : applyContentDelta(current, deltaEvent.content)\n : (applyCoreEventDelta(\n current as CoreContentBlock | undefined,\n data as unknown as ContentBlockDeltaEvent\n ) as unknown as ContentBlock);\n return {\n kind: \"content-block-delta\",\n key: activeKey,\n message,\n index: targetIndex,\n block: deltaBlock,\n event,\n };\n }\n case \"content-block-finish\": {\n const targetIndex = this.resolveFinishBlockIndex(\n activeKey,\n data.index,\n data.content.type\n );\n message.blocks[targetIndex] = cloneBlock(data.content);\n return {\n kind: \"content-block-finish\",\n key: activeKey,\n message,\n index: targetIndex,\n block: data.content,\n event,\n };\n }\n case \"message-finish\": {\n message.usage = readUsage(data) ?? message.usage;\n message.finishMetadata = readFinishMetadata(data);\n message.finishReason = data.reason;\n this.clearActiveMessage(activeKey, namespaceNodeKey);\n this.clearBlockIndexAliases(activeKey);\n return {\n kind: \"message-finish\",\n key: activeKey,\n message: structuredClone(message),\n event,\n };\n }\n case \"error\": {\n message.error = { message: data.message, code: data.code };\n this.clearActiveMessage(activeKey, namespaceNodeKey);\n this.clearBlockIndexAliases(activeKey);\n return {\n kind: \"message-error\",\n key: activeKey,\n message: structuredClone(message),\n event,\n };\n }\n }\n }\n\n /**\n * Drop every message that started but never got `message-finish` or\n * `error`, e.g. because the run was cancelled mid-stream.\n *\n * @param namespace - Only abandon messages at or below this namespace.\n * @returns The abandoned messages.\n */\n abandonActive(namespace?: readonly string[]): AssembledMessage[] {\n const abandoned: AssembledMessage[] = [];\n for (const [key, message] of this.activeMessages) {\n if (\n namespace != null &&\n !hasNamespacePrefix(message.namespace, namespace)\n )\n continue;\n abandoned.push(message);\n this.activeMessages.delete(key);\n this.clearBlockIndexAliases(key);\n for (const [nsNode, activeKey] of this.activeByNamespaceNode) {\n if (activeKey === key) this.activeByNamespaceNode.delete(nsNode);\n }\n }\n return abandoned;\n }\n\n private clearActiveMessage(\n activeKey: string,\n namespaceNodeKey: string\n ): void {\n this.activeMessages.delete(activeKey);\n if (this.activeByNamespaceNode.get(namespaceNodeKey) === activeKey) {\n this.activeByNamespaceNode.delete(namespaceNodeKey);\n }\n }\n\n private resolveBlockIndex(\n activeKey: string,\n blocks: ContentBlock[],\n protocolIndex: number,\n blockType: string\n ): number {\n const current = blocks[protocolIndex];\n if (\n current == null ||\n current.type === blockType ||\n areCompatibleBlockTypes(current.type, blockType)\n ) {\n this.blockIndexByProtocolIndexAndType.set(\n blockIndexKey(activeKey, protocolIndex, blockType),\n protocolIndex\n );\n return protocolIndex;\n }\n\n const key = blockIndexKey(activeKey, protocolIndex, blockType);\n const existing = this.blockIndexByProtocolIndexAndType.get(key);\n if (existing != null) return existing;\n\n const nextIndex = blocks.length;\n this.blockIndexByProtocolIndexAndType.set(key, nextIndex);\n return nextIndex;\n }\n\n private resolveFinishBlockIndex(\n activeKey: string,\n protocolIndex: number,\n blockType: string\n ): number {\n const key = blockIndexKey(activeKey, protocolIndex, blockType);\n const existing = this.blockIndexByProtocolIndexAndType.get(key);\n if (existing != null) return existing;\n\n this.blockIndexByProtocolIndexAndType.set(key, protocolIndex);\n return protocolIndex;\n }\n\n private clearBlockIndexAliases(activeKey: string): void {\n const prefix = `${activeKey}::`;\n for (const key of this.blockIndexByProtocolIndexAndType.keys()) {\n if (key.startsWith(prefix))\n this.blockIndexByProtocolIndexAndType.delete(key);\n }\n }\n}\n\nfunction hasNamespacePrefix(\n namespace: readonly string[],\n prefix: readonly string[]\n): boolean {\n return prefix.every((segment, i) => namespace[i] === segment);\n}\n\nfunction blockIndexKey(\n activeKey: string,\n protocolIndex: number,\n blockType: string\n): string {\n return `${activeKey}::${protocolIndex}::${blockType}`;\n}\n\nfunction areCompatibleBlockTypes(\n currentType: string,\n nextType: string\n): boolean {\n const toolCallTypes = new Set([\n \"tool_call\",\n \"tool_call_chunk\",\n \"tool_use\",\n \"input_json_delta\",\n ]);\n const serverToolCallTypes = new Set([\n \"server_tool_call\",\n \"server_tool_call_chunk\",\n ]);\n\n return (\n (toolCallTypes.has(currentType) && toolCallTypes.has(nextType)) ||\n (serverToolCallTypes.has(currentType) && serverToolCallTypes.has(nextType))\n );\n}\n\n/**\n * Assembles `messages` events into {@link StreamingMessage} instances\n * with live text/reasoning delta streams, matching the in-process\n * `ChatModelStream` dual-interface pattern.\n */\nexport class StreamingMessageAssembler {\n readonly #assembler = new MessageAssembler();\n readonly #activeStreaming = new Map<string, StreamingMessage>();\n\n /**\n * Folds a single event and returns a new {@link StreamingMessage}\n * when a `message-start` is seen, or `undefined` for continuation\n * events (deltas, finish, error).\n */\n consume(event: MessagesEvent): StreamingMessage | undefined {\n const update = this.#assembler.consume(event);\n if (update == null) return undefined;\n\n switch (update.kind) {\n case \"message-start\": {\n const streaming = new StreamingMessage(update.message);\n streaming[UPDATE_CONTEXT](update.event);\n streaming[PUSH_EVENT](toChatModelStreamEvent(update.event));\n this.#activeStreaming.set(update.key, streaming);\n return streaming;\n }\n case \"content-block-start\": {\n const streaming = this.#activeStreaming.get(update.key);\n if (streaming) {\n streaming[UPDATE_CONTEXT](update.event);\n streaming[PUSH_EVENT](toChatModelStreamEvent(update.event));\n }\n if (\n streaming &&\n update.block.type === \"text\" &&\n \"text\" in update.block &&\n update.block.text\n ) {\n streaming[PUSH_TEXT](update.block.text);\n }\n if (\n streaming &&\n update.block.type === \"reasoning\" &&\n \"reasoning\" in update.block &&\n update.block.reasoning\n ) {\n streaming[PUSH_REASONING](update.block.reasoning);\n }\n return undefined;\n }\n case \"content-block-delta\": {\n const streaming = this.#activeStreaming.get(update.key);\n if (!streaming) return undefined;\n streaming[UPDATE_CONTEXT](update.event);\n streaming[PUSH_EVENT](toChatModelStreamEvent(update.event));\n if (update.block.type === \"text\" && \"text\" in update.block) {\n streaming[PUSH_TEXT](update.block.text);\n }\n if (update.block.type === \"reasoning\" && \"reasoning\" in update.block) {\n streaming[PUSH_REASONING](update.block.reasoning);\n }\n return undefined;\n }\n case \"content-block-finish\": {\n const streaming = this.#activeStreaming.get(update.key);\n if (streaming) {\n streaming[UPDATE_CONTEXT](update.event);\n streaming[PUSH_EVENT](toChatModelStreamEvent(update.event));\n }\n return undefined;\n }\n case \"usage\": {\n const streaming = this.#activeStreaming.get(update.key);\n if (streaming) {\n streaming[UPDATE_CONTEXT](update.event);\n streaming[PUSH_EVENT](toChatModelStreamEvent(update.event));\n }\n return undefined;\n }\n case \"message-finish\": {\n const streaming = this.#activeStreaming.get(update.key);\n if (streaming) {\n streaming[UPDATE_CONTEXT](update.event);\n streaming[PUSH_EVENT](toChatModelStreamEvent(update.event));\n streaming[FINISH]();\n this.#activeStreaming.delete(update.key);\n }\n return undefined;\n }\n case \"message-error\": {\n const streaming = this.#activeStreaming.get(update.key);\n if (streaming) {\n streaming[UPDATE_CONTEXT](update.event);\n streaming[PUSH_EVENT](toChatModelStreamEvent(update.event));\n streaming[ERROR]();\n this.#activeStreaming.delete(update.key);\n }\n return undefined;\n }\n }\n }\n\n /**\n * Settle every message that never finished, marking it with an\n * `aborted` error so awaiting consumers don't hang.\n *\n * @param namespace - Only abandon messages at or below this namespace.\n * @returns The abandoned messages.\n */\n abandonActive(namespace?: readonly string[]): StreamingMessage[] {\n this.#assembler.abandonActive(namespace);\n const abandoned: StreamingMessage[] = [];\n for (const [key, streaming] of this.#activeStreaming) {\n if (\n namespace != null &&\n !hasNamespacePrefix(streaming.namespace, namespace)\n )\n continue;\n streaming.assembled.error = {\n message: \"Message stream ended before message-finish\",\n code: \"aborted\",\n };\n streaming[ERROR]();\n this.#activeStreaming.delete(key);\n abandoned.push(streaming);\n }\n return abandoned;\n }\n}\n"],"mappings":"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"}