@langchain/core
Version:
Core LangChain.js abstractions and schemas
1 lines • 23.6 kB
Source Map (JSON)
{"version":3,"file":"compat.cjs","names":["AIMessageChunk"],"sources":["../../src/language_models/compat.ts"],"sourcesContent":["/**\n * Compatibility bridge: converts legacy `_streamResponseChunks`\n * (`ChatGenerationChunk` / `AIMessageChunk`) output to the new\n * `ChatModelStreamEvent` protocol.\n *\n * @module\n */\n\nimport { AIMessageChunk } from \"../messages/ai.js\";\nimport type { ContentBlock } from \"../messages/content/index.js\";\nimport type { ChatGenerationChunk } from \"../outputs.js\";\nimport type { ChatModelStreamEvent, ContentBlockDelta } from \"./event.js\";\n\nconst MIME_TYPE_BY_AUDIO_FORMAT: Record<string, string> = {\n wav: \"audio/wav\",\n mp3: \"audio/mpeg\",\n flac: \"audio/flac\",\n opus: \"audio/opus\",\n aac: \"audio/aac\",\n pcm16: \"audio/pcm\",\n};\n\nconst MIME_TYPE_BY_IMAGE_FORMAT: Record<string, string> = {\n png: \"image/png\",\n jpeg: \"image/jpeg\",\n jpg: \"image/jpeg\",\n webp: \"image/webp\",\n gif: \"image/gif\",\n};\n\ntype AudioStreamState = {\n index: number;\n id?: string;\n mimeType: string;\n transcript: string;\n};\n\nfunction nextBlockIndex(activeBlocks: Map<number, unknown>): number {\n let next = 0;\n for (const index of activeBlocks.keys()) {\n if (index >= next) next = index + 1;\n }\n return next;\n}\n\nfunction getAdditionalKwargs(message: unknown): Record<string, unknown> {\n const additional = (message as { additional_kwargs?: unknown })\n .additional_kwargs;\n return additional != null && typeof additional === \"object\"\n ? (additional as Record<string, unknown>)\n : {};\n}\n\nfunction extractImageBlocksFromToolOutputs(message: unknown): ContentBlock[] {\n const toolOutputs = getAdditionalKwargs(message).tool_outputs;\n if (!Array.isArray(toolOutputs)) return [];\n\n const blocks: ContentBlock[] = [];\n for (const entry of toolOutputs) {\n if (entry == null || typeof entry !== \"object\") continue;\n const record = entry as Record<string, unknown>;\n if (record.type !== \"image_generation_call\") continue;\n\n const data = typeof record.result === \"string\" ? record.result : undefined;\n const url = typeof record.url === \"string\" ? record.url : undefined;\n if (data == null && url == null) continue;\n\n const outputFormat =\n typeof record.output_format === \"string\"\n ? record.output_format.toLowerCase()\n : undefined;\n const mimeType =\n (outputFormat != null\n ? MIME_TYPE_BY_IMAGE_FORMAT[outputFormat]\n : undefined) ?? \"image/png\";\n\n blocks.push({\n type: \"image\",\n ...(typeof record.id === \"string\" ? { id: record.id } : {}),\n ...(url != null ? { url } : {}),\n ...(data != null ? { data } : {}),\n mimeType,\n } as ContentBlock);\n }\n return blocks;\n}\n\n/**\n * Get the audio payload from the message.\n *\n * This handles the OpenAI-shaped `additional_kwargs.audio` payload used by\n * legacy chunk streams; other providers must normalize into this shape first.\n *\n * @param message - The message to get the audio payload from.\n * @returns The audio payload.\n * @internal\n */\nfunction getAudioPayload(message: unknown):\n | {\n id?: string;\n data?: string;\n url?: string;\n transcript?: string;\n mimeType: string;\n }\n | undefined {\n const audio = getAdditionalKwargs(message).audio;\n if (audio == null || typeof audio !== \"object\") return undefined;\n const record = audio as Record<string, unknown>;\n\n const data = typeof record.data === \"string\" ? record.data : undefined;\n const url = typeof record.url === \"string\" ? record.url : undefined;\n const transcript =\n typeof record.transcript === \"string\" ? record.transcript : undefined;\n if (data == null && url == null && transcript == null) return undefined;\n\n const explicitMimeType =\n typeof record.mime_type === \"string\"\n ? record.mime_type\n : typeof record.mimeType === \"string\"\n ? record.mimeType\n : undefined;\n const format =\n typeof record.format === \"string\" ? record.format.toLowerCase() : undefined;\n const mimeType =\n explicitMimeType ??\n (format != null ? MIME_TYPE_BY_AUDIO_FORMAT[format] : undefined) ??\n (data != null ? \"audio/wav\" : \"audio/pcm\");\n\n return {\n ...(typeof record.id === \"string\" ? { id: record.id } : {}),\n ...(data != null ? { data } : {}),\n ...(url != null ? { url } : {}),\n ...(transcript != null ? { transcript } : {}),\n mimeType,\n };\n}\n\n/**\n * Convert an async iterable of legacy `ChatGenerationChunk`s into\n * `ChatModelStreamEvent`s with typed deltas.\n */\nexport async function* convertChunksToEvents(\n chunks: AsyncIterable<ChatGenerationChunk>,\n options?: { signal?: AbortSignal }\n): AsyncGenerator<ChatModelStreamEvent> {\n const activeBlocks = new Map<\n number,\n { type: string; accumulated: ContentBlock }\n >();\n let messageStarted = false;\n let lastUsage:\n | { input_tokens: number; output_tokens: number; total_tokens: number }\n | undefined;\n let audioStream: AudioStreamState | undefined;\n const emittedImageKeys = new Set<string>();\n\n for await (const chunk of chunks) {\n options?.signal?.throwIfAborted();\n\n const msg = chunk.message;\n\n // Message start\n let usageHandledInStart = false;\n if (!messageStarted) {\n messageStarted = true;\n const startEvent: ChatModelStreamEvent = {\n event: \"message-start\" as const,\n id: msg.id ?? undefined,\n };\n if (AIMessageChunk.isInstance(msg) && msg.usage_metadata) {\n (startEvent as { usage?: unknown }).usage = msg.usage_metadata;\n lastUsage = { ...msg.usage_metadata };\n usageHandledInStart = true;\n }\n yield startEvent;\n }\n\n // Process content\n const content = msg.content;\n if (typeof content === \"string\") {\n if (content !== \"\") {\n const blockIndex = 0;\n if (!activeBlocks.has(blockIndex)) {\n const initial: ContentBlock.Text = { type: \"text\", text: \"\" };\n activeBlocks.set(blockIndex, {\n type: \"text\",\n accumulated: initial,\n });\n yield {\n event: \"content-block-start\" as const,\n index: blockIndex,\n content: initial,\n };\n }\n const block = activeBlocks.get(blockIndex)!;\n block.accumulated = {\n ...block.accumulated,\n text: ((block.accumulated as { text?: string }).text ?? \"\") + content,\n };\n yield {\n event: \"content-block-delta\" as const,\n index: blockIndex,\n delta: { type: \"text-delta\" as const, text: content },\n };\n }\n } else if (Array.isArray(content)) {\n for (const part of content) {\n const blockIndex =\n typeof part.index === \"number\" ? part.index : activeBlocks.size;\n\n if (!activeBlocks.has(blockIndex)) {\n activeBlocks.set(blockIndex, {\n type: part.type,\n accumulated: { ...part },\n });\n yield {\n event: \"content-block-start\" as const,\n index: blockIndex,\n content: { ...part },\n };\n } else {\n const block = activeBlocks.get(blockIndex)!;\n const delta = contentBlockToDelta(part);\n block.accumulated = applyDeltaToBlock(block.accumulated, delta);\n yield {\n event: \"content-block-delta\" as const,\n index: blockIndex,\n delta,\n };\n }\n }\n }\n\n // Tool call chunks\n if (\n AIMessageChunk.isInstance(msg) &&\n msg.tool_call_chunks &&\n msg.tool_call_chunks.length > 0\n ) {\n for (const toolChunk of msg.tool_call_chunks) {\n const blockIndex =\n typeof toolChunk.index === \"number\"\n ? toolChunk.index\n : activeBlocks.size;\n\n if (!activeBlocks.has(blockIndex)) {\n const initial: ContentBlock = {\n type: \"tool_call_chunk\" as const,\n id: toolChunk.id,\n name: toolChunk.name,\n args: \"\",\n index: blockIndex,\n };\n activeBlocks.set(blockIndex, {\n type: \"tool_call_chunk\",\n accumulated: initial,\n });\n yield {\n event: \"content-block-start\" as const,\n index: blockIndex,\n content: initial,\n };\n }\n\n // Accumulate tool call args internally, emit incremental content chunks.\n const block = activeBlocks.get(blockIndex)!;\n const acc = block.accumulated as {\n args?: string;\n id?: string;\n name?: string;\n };\n if (toolChunk.id != null) acc.id = toolChunk.id;\n if (toolChunk.name != null) acc.name = toolChunk.name;\n acc.args = (acc.args ?? \"\") + (toolChunk.args ?? \"\");\n yield {\n event: \"content-block-delta\" as const,\n index: blockIndex,\n delta: {\n type: \"block-delta\" as const,\n fields: {\n type: \"tool_call_chunk\",\n ...(\"id\" in acc && acc.id != null ? { id: acc.id } : {}),\n ...(\"name\" in acc && acc.name != null ? { name: acc.name } : {}),\n args: acc.args,\n },\n },\n };\n }\n }\n\n const audioPayload = getAudioPayload(msg);\n if (audioPayload != null) {\n if (audioStream == null) {\n const index = nextBlockIndex(activeBlocks);\n audioStream = {\n index,\n id: audioPayload.id,\n mimeType: audioPayload.mimeType,\n transcript: \"\",\n };\n const initial = {\n type: \"audio\",\n ...(audioPayload.id != null ? { id: audioPayload.id } : {}),\n ...(audioPayload.url != null ? { url: audioPayload.url } : {}),\n data: \"\",\n mimeType: audioPayload.mimeType,\n } as ContentBlock;\n activeBlocks.set(index, {\n type: \"audio\",\n accumulated: initial,\n });\n yield {\n event: \"content-block-start\" as const,\n index,\n content: initial,\n };\n }\n\n const activeAudio = activeBlocks.get(audioStream.index);\n if (activeAudio != null) {\n const accumulated = activeAudio.accumulated as ContentBlock & {\n data?: string;\n transcript?: string;\n };\n if (audioPayload.id != null && audioStream.id == null) {\n audioStream.id = audioPayload.id;\n (accumulated as { id?: string }).id = audioPayload.id;\n }\n if (audioPayload.transcript != null) {\n audioStream.transcript += audioPayload.transcript;\n accumulated.transcript = audioStream.transcript;\n yield {\n event: \"content-block-delta\" as const,\n index: audioStream.index,\n delta: {\n type: \"block-delta\" as const,\n fields: {\n type: \"audio\",\n transcript: audioStream.transcript,\n },\n },\n };\n }\n if (audioPayload.data != null && audioPayload.data.length > 0) {\n accumulated.data = (accumulated.data ?? \"\") + audioPayload.data;\n yield {\n event: \"content-block-delta\" as const,\n index: audioStream.index,\n delta: {\n type: \"data-delta\" as const,\n data: audioPayload.data,\n encoding: \"base64\" as const,\n },\n };\n }\n }\n }\n\n for (const imageBlock of extractImageBlocksFromToolOutputs(msg)) {\n const imageRecord = imageBlock as ContentBlock & {\n id?: string;\n url?: string;\n data?: string;\n };\n const imageKey =\n imageRecord.id ??\n imageRecord.url ??\n (imageRecord.data != null\n ? `${imageRecord.data.length}:${imageRecord.data.slice(0, 32)}`\n : undefined);\n if (imageKey != null && emittedImageKeys.has(imageKey)) continue;\n if (imageKey != null) emittedImageKeys.add(imageKey);\n\n const index = nextBlockIndex(activeBlocks);\n activeBlocks.set(index, {\n type: \"image\",\n accumulated: imageBlock,\n });\n yield {\n event: \"content-block-start\" as const,\n index,\n content: imageBlock,\n };\n }\n\n // Usage\n if (\n !usageHandledInStart &&\n AIMessageChunk.isInstance(msg) &&\n msg.usage_metadata\n ) {\n const chunkUsage = msg.usage_metadata;\n if (!lastUsage) {\n lastUsage = { ...chunkUsage };\n } else {\n lastUsage = {\n input_tokens: lastUsage.input_tokens + chunkUsage.input_tokens,\n output_tokens: lastUsage.output_tokens + chunkUsage.output_tokens,\n total_tokens: lastUsage.total_tokens + chunkUsage.total_tokens,\n };\n }\n yield { event: \"usage\" as const, usage: { ...lastUsage } };\n }\n }\n\n // Finish all blocks\n for (const [index, block] of activeBlocks) {\n const finalized = finalizeContentBlock(block.accumulated);\n yield {\n event: \"content-block-finish\" as const,\n index,\n content: finalized,\n };\n }\n\n yield {\n event: \"message-finish\" as const,\n reason: \"stop\" as const,\n ...(lastUsage ? { usage: lastUsage } : {}),\n };\n}\n\n/**\n * Apply a typed delta to an accumulated content block.\n * @internal\n */\nfunction applyDeltaToBlock(\n block: ContentBlock,\n delta: ContentBlockDelta\n): ContentBlock {\n switch (delta.type) {\n case \"text-delta\":\n if (block.type === \"text\") {\n return {\n ...block,\n text: (block.text ?? \"\") + delta.text,\n };\n }\n return block;\n case \"reasoning-delta\":\n if (block.type === \"thinking\") {\n return {\n ...block,\n thinking: (block.thinking ?? \"\") + delta.reasoning,\n };\n }\n if (block.type === \"reasoning\") {\n return {\n ...block,\n reasoning: (block.reasoning ?? \"\") + delta.reasoning,\n };\n }\n return block;\n case \"data-delta\":\n return {\n ...block,\n data: (block.data ?? \"\") + delta.data,\n };\n case \"block-delta\":\n return { ...block, ...delta.fields } as ContentBlock;\n default:\n throw new Error(`Unknown delta type: ${JSON.stringify(delta)}`);\n }\n}\n\nfunction contentBlockToDelta(block: ContentBlock): ContentBlockDelta {\n if (block.type === \"text\") {\n return { type: \"text-delta\", text: (block as ContentBlock.Text).text };\n }\n if (block.type === \"reasoning\") {\n return {\n type: \"reasoning-delta\",\n reasoning: (block as ContentBlock.Reasoning).reasoning,\n };\n }\n if (block.type === \"thinking\" && typeof block.thinking === \"string\") {\n return {\n type: \"reasoning-delta\",\n reasoning: block.thinking,\n };\n }\n if (typeof block.data === \"string\") {\n return {\n type: \"data-delta\",\n data: block.data,\n encoding: \"base64\",\n };\n }\n if (typeof block.type === \"string\") {\n return {\n type: \"block-delta\",\n fields: {\n ...(block as unknown as { type: string } & Record<string, unknown>),\n },\n };\n }\n\n throw new Error(`Unsupported content block delta: ${JSON.stringify(block)}`);\n}\n\n/**\n * Finalize a content block for the finish event.\n * For tool calls, parse the accumulated JSON args string.\n */\nexport function finalizeContentBlock(block: ContentBlock): ContentBlock {\n if (block.type === \"tool_call_chunk\") {\n const chunk = block as ContentBlock.Tools.ToolCallChunk;\n let parsedArgs: unknown;\n try {\n parsedArgs = JSON.parse(chunk.args ?? \"{}\");\n } catch {\n return {\n type: \"invalid_tool_call\" as const,\n id: chunk.id,\n name: chunk.name,\n args: chunk.args,\n error: \"Failed to parse tool call arguments as JSON\",\n } as ContentBlock.Tools.InvalidToolCall;\n }\n return {\n type: \"tool_call\" as const,\n id: chunk.id,\n name: chunk.name!,\n args: parsedArgs,\n } as ContentBlock.Tools.ToolCall;\n }\n\n return block;\n}\n"],"mappings":"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"}