UNPKG

@langchain/core

Version:
1 lines • 32.9 kB
{"version":3,"file":"openai.cjs","names":["_isString","isOpenAIDataBlock","convertToV1FromOpenAIDataBlock","_isArray","_isObject","_isContentBlock","iife"],"sources":["../../../src/messages/block_translators/openai.ts"],"sourcesContent":["import type { ContentBlock } from \"../content/index.js\";\nimport type { AIMessageChunk, AIMessage } from \"../ai.js\";\nimport type { StandardContentBlockTranslator } from \"./index.js\";\nimport { convertToV1FromOpenAIDataBlock, isOpenAIDataBlock } from \"./data.js\";\nimport {\n _isArray,\n _isContentBlock,\n _isObject,\n _isString,\n iife,\n} from \"./utils.js\";\n\n/** The refusal Chat Completions and Responses keep in `additional_kwargs`. */\nfunction refusalFromAdditionalKwargs(\n message: AIMessage\n): ContentBlock.Refusal | undefined {\n const refusal = message.additional_kwargs.refusal;\n return _isString(refusal) && refusal.length > 0\n ? { type: \"refusal\", refusal }\n : undefined;\n}\n\n/**\n * Converts a ChatOpenAICompletions message to an array of v1 standard content blocks.\n *\n * This function processes an AI message from ChatOpenAICompletions API format\n * and converts it to the standardized v1 content block format. It handles both\n * string content and structured content blocks, as well as tool calls.\n *\n * @param message - The AI message containing ChatOpenAICompletions formatted content\n * @returns Array of content blocks in v1 standard format\n *\n * @example\n * ```typescript\n * const message = new AIMessage(\"Hello world\");\n * const standardBlocks = convertToV1FromChatCompletions(message);\n * // Returns: [{ type: \"text\", text: \"Hello world\" }]\n * ```\n *\n * @example\n * ```typescript\n * const message = new AIMessage([\n * { type: \"text\", text: \"Hello\" },\n * { type: \"image_url\", image_url: { url: \"https://example.com/image.png\" } }\n * ]);\n * message.tool_calls = [\n * { id: \"call_123\", name: \"calculator\", args: { a: 1, b: 2 } }\n * ];\n *\n * const standardBlocks = convertToV1FromChatCompletions(message);\n * // Returns:\n * // [\n * // { type: \"text\", text: \"Hello\" },\n * // { type: \"image\", url: \"https://example.com/image.png\" },\n * // { type: \"tool_call\", id: \"call_123\", name: \"calculator\", args: { a: 1, b: 2 } }\n * // ]\n * ```\n */\nexport function convertToV1FromChatCompletions(\n message: AIMessage\n): Array<ContentBlock.Standard> {\n const blocks: Array<ContentBlock.Standard> = [];\n if (typeof message.content === \"string\") {\n // Only add text block if content is non-empty\n if (message.content.length > 0) {\n blocks.push({\n type: \"text\",\n text: message.content,\n });\n }\n } else {\n blocks.push(...convertToV1FromChatCompletionsInput(message.content));\n }\n for (const toolCall of message.tool_calls ?? []) {\n blocks.push({\n type: \"tool_call\",\n id: toolCall.id,\n name: toolCall.name,\n args: toolCall.args,\n });\n }\n const refusal = refusalFromAdditionalKwargs(message);\n if (refusal) blocks.push(refusal);\n return blocks;\n}\n\n/**\n * Converts a ChatOpenAICompletions message chunk to an array of v1 standard content blocks.\n *\n * This function processes an AI message chunk from OpenAI's chat completions API and converts\n * it to the standardized v1 content block format. It handles both string and array content,\n * as well as tool calls that may be present in the chunk.\n *\n * @param message - The AI message chunk containing OpenAI-formatted content blocks\n * @returns Array of content blocks in v1 standard format\n *\n * @example\n * ```typescript\n * const chunk = new AIMessage(\"Hello\");\n * const standardBlocks = convertToV1FromChatCompletionsChunk(chunk);\n * // Returns: [{ type: \"text\", text: \"Hello\" }]\n * ```\n *\n * @example\n * ```typescript\n * const chunk = new AIMessage([\n * { type: \"text\", text: \"Processing...\" }\n * ]);\n * chunk.tool_calls = [\n * { id: \"call_456\", name: \"search\", args: { query: \"test\" } }\n * ];\n *\n * const standardBlocks = convertToV1FromChatCompletionsChunk(chunk);\n * // Returns:\n * // [\n * // { type: \"text\", text: \"Processing...\" },\n * // { type: \"tool_call\", id: \"call_456\", name: \"search\", args: { query: \"test\" } }\n * // ]\n * ```\n */\nexport function convertToV1FromChatCompletionsChunk(\n message: AIMessage\n): Array<ContentBlock.Standard> {\n const blocks: Array<ContentBlock.Standard> = [];\n if (typeof message.content === \"string\") {\n // Only add text block if content is non-empty\n if (message.content.length > 0) {\n blocks.push({\n type: \"text\",\n text: message.content,\n });\n }\n } else {\n blocks.push(...convertToV1FromChatCompletionsInput(message.content));\n }\n\n // TODO: parse chunk position information\n for (const toolCall of message.tool_calls ?? []) {\n blocks.push({\n type: \"tool_call\",\n id: toolCall.id,\n name: toolCall.name,\n args: toolCall.args,\n });\n }\n const refusal = refusalFromAdditionalKwargs(message);\n if (refusal) blocks.push(refusal);\n return blocks;\n}\n\n/**\n * Converts an array of ChatOpenAICompletions content blocks to v1 standard content blocks.\n *\n * This function processes content blocks from OpenAI's Chat Completions API format\n * and converts them to the standardized v1 content block format. It handles both\n * OpenAI-specific data blocks (which require conversion) and standard blocks\n * (which are passed through with type assertion).\n *\n * @param blocks - Array of content blocks in ChatOpenAICompletions format\n * @returns Array of content blocks in v1 standard format\n *\n * @example\n * ```typescript\n * const openaiBlocks = [\n * { type: \"text\", text: \"Hello world\" },\n * { type: \"image_url\", image_url: { url: \"https://example.com/image.png\" } }\n * ];\n *\n * const standardBlocks = convertToV1FromChatCompletionsInput(openaiBlocks);\n * // Returns:\n * // [\n * // { type: \"text\", text: \"Hello world\" },\n * // { type: \"image\", url: \"https://example.com/image.png\" }\n * // ]\n * ```\n */\nexport function convertToV1FromChatCompletionsInput(\n blocks: Array<ContentBlock>\n): Array<ContentBlock.Standard> {\n const convertedBlocks: Array<ContentBlock.Standard> = [];\n for (const block of blocks) {\n if (isOpenAIDataBlock(block)) {\n convertedBlocks.push(convertToV1FromOpenAIDataBlock(block));\n } else {\n convertedBlocks.push(block as ContentBlock.Standard);\n }\n }\n return convertedBlocks;\n}\n\nfunction convertResponsesAnnotation(\n annotation: ContentBlock\n): ContentBlock | ContentBlock.Citation {\n if (annotation.type === \"url_citation\") {\n const { url, title, start_index, end_index } = annotation;\n return {\n type: \"citation\",\n url,\n title,\n startIndex: start_index,\n endIndex: end_index,\n };\n }\n if (annotation.type === \"file_citation\") {\n const { file_id, filename, index } = annotation;\n return {\n type: \"citation\",\n title: filename,\n startIndex: index,\n endIndex: index,\n fileId: file_id,\n };\n }\n return annotation;\n}\n\n/** Builds a reasoning content block, including id/encrypted_content when present. */\nfunction mapReasoningItemToV1(\n item: Record<string, unknown>\n): ContentBlock.Standard | undefined {\n if (!_isArray(item.summary)) return undefined;\n const summary = item.summary.reduce<string>((acc, part) => {\n if (_isObject(part) && _isString(part.text)) {\n return `${acc}${part.text}`;\n }\n return acc;\n }, \"\");\n return {\n type: \"reasoning\",\n reasoning: summary,\n ...(_isString(item.id) ? { id: item.id } : {}),\n ...(_isString(item.encrypted_content)\n ? { encrypted_content: item.encrypted_content }\n : {}),\n } as ContentBlock.Standard;\n}\n\n// Converts a single built-in tool call/result entry into v1 content blocks.\nfunction* mapToolOutputToV1Blocks(\n toolOutput: unknown\n): Iterable<ContentBlock.Standard> {\n if (_isContentBlock(toolOutput, \"web_search_call\")) {\n const webSearchArgs: Record<string, unknown> = {};\n if (_isObject(toolOutput.action) && _isString(toolOutput.action.query)) {\n webSearchArgs.query = toolOutput.action.query;\n }\n yield {\n id: toolOutput.id,\n type: \"server_tool_call\",\n name: \"web_search\",\n args: webSearchArgs,\n };\n // Emit a server_tool_call_result when the search has completed or failed\n if (toolOutput.status === \"completed\" || toolOutput.status === \"failed\") {\n const output: Record<string, unknown> = {};\n if (_isObject(toolOutput.action)) {\n output.action = toolOutput.action;\n }\n yield {\n type: \"server_tool_call_result\",\n toolCallId: _isString(toolOutput.id) ? toolOutput.id : \"\",\n status: toolOutput.status === \"completed\" ? \"success\" : \"error\",\n output,\n };\n }\n return;\n }\n if (_isContentBlock(toolOutput, \"file_search_call\")) {\n yield {\n id: toolOutput.id,\n type: \"server_tool_call\",\n name: \"file_search\",\n args: {\n queries: _isArray(toolOutput.queries) ? toolOutput.queries : [],\n },\n };\n // Emit a server_tool_call_result when results are available\n if (toolOutput.status === \"completed\" || toolOutput.status === \"failed\") {\n yield {\n type: \"server_tool_call_result\",\n toolCallId: _isString(toolOutput.id) ? toolOutput.id : \"\",\n status: toolOutput.status === \"completed\" ? \"success\" : \"error\",\n output: _isArray(toolOutput.results)\n ? { results: toolOutput.results }\n : {},\n };\n }\n return;\n }\n if (_isContentBlock(toolOutput, \"computer_call\")) {\n yield { type: \"non_standard\", value: toolOutput };\n return;\n }\n if (_isContentBlock(toolOutput, \"code_interpreter_call\")) {\n if (_isString(toolOutput.code)) {\n yield {\n id: toolOutput.id,\n type: \"server_tool_call\",\n name: \"code_interpreter\",\n args: { code: toolOutput.code },\n };\n }\n if (_isArray(toolOutput.outputs)) {\n const returnCode = iife(() => {\n if (toolOutput.status === \"in_progress\") return undefined;\n if (toolOutput.status === \"completed\") return 0;\n if (toolOutput.status === \"incomplete\") return 127;\n if (toolOutput.status === \"interpreting\") return undefined;\n if (toolOutput.status === \"failed\") return 1;\n return undefined;\n });\n for (const output of toolOutput.outputs) {\n if (_isContentBlock(output, \"logs\")) {\n yield {\n type: \"server_tool_call_result\",\n toolCallId: toolOutput.id ?? \"\",\n status: \"success\",\n output: {\n type: \"code_interpreter_output\",\n returnCode: returnCode ?? 0,\n stderr: [0, undefined].includes(returnCode)\n ? undefined\n : String(output.logs),\n stdout: [0, undefined].includes(returnCode)\n ? String(output.logs)\n : undefined,\n },\n };\n }\n }\n }\n return;\n }\n if (_isContentBlock(toolOutput, \"mcp_call\")) {\n yield {\n id: toolOutput.id,\n type: \"server_tool_call\",\n name: \"mcp_call\",\n args: toolOutput.input,\n };\n return;\n }\n if (_isContentBlock(toolOutput, \"mcp_list_tools\")) {\n yield {\n id: toolOutput.id,\n type: \"server_tool_call\",\n name: \"mcp_list_tools\",\n args: toolOutput.input,\n };\n return;\n }\n if (_isContentBlock(toolOutput, \"mcp_approval_request\")) {\n yield { type: \"non_standard\", value: toolOutput };\n return;\n }\n if (_isContentBlock(toolOutput, \"tool_search_call\")) {\n const toolSearchArgs: Record<string, unknown> = {};\n if (_isObject(toolOutput.arguments)) {\n Object.assign(toolSearchArgs, toolOutput.arguments);\n }\n const toolSearchCallExtras: Record<string, unknown> = {};\n if (_isString(toolOutput.execution)) {\n toolSearchCallExtras.execution = toolOutput.execution;\n }\n if (_isString(toolOutput.status)) {\n toolSearchCallExtras.status = toolOutput.status;\n }\n if (_isString(toolOutput.call_id)) {\n toolSearchCallExtras.call_id = toolOutput.call_id;\n }\n yield {\n id: _isString(toolOutput.id) ? toolOutput.id : \"\",\n type: \"server_tool_call\",\n name: \"tool_search\",\n args: toolSearchArgs,\n ...(Object.keys(toolSearchCallExtras).length > 0\n ? { extras: toolSearchCallExtras }\n : {}),\n };\n return;\n }\n if (_isContentBlock(toolOutput, \"tool_search_output\")) {\n const toolSearchOutputExtras: Record<string, unknown> = {\n name: \"tool_search\",\n };\n if (_isString(toolOutput.execution)) {\n toolSearchOutputExtras.execution = toolOutput.execution;\n }\n yield {\n type: \"server_tool_call_result\",\n toolCallId: _isString(toolOutput.id) ? toolOutput.id : \"\",\n status:\n toolOutput.status === \"completed\"\n ? \"success\"\n : toolOutput.status === \"failed\"\n ? \"error\"\n : \"success\",\n output: {\n tools: _isArray(toolOutput.tools) ? toolOutput.tools : [],\n },\n extras: toolSearchOutputExtras,\n };\n return;\n }\n if (_isContentBlock(toolOutput, \"image_generation_call\")) {\n // Convert image_generation_call to proper image content block if result is available\n if (_isString(toolOutput.result)) {\n yield {\n type: \"image\",\n mimeType: \"image/png\",\n data: toolOutput.result,\n id: _isString(toolOutput.id) ? toolOutput.id : undefined,\n metadata: {\n status: _isString(toolOutput.status) ? toolOutput.status : undefined,\n },\n };\n }\n // Also yield as non_standard for backwards compatibility\n yield { type: \"non_standard\", value: toolOutput };\n return;\n }\n if (_isObject(toolOutput)) {\n yield { type: \"non_standard\", value: toolOutput };\n }\n}\n\n/**\n * Converts a ChatOpenAIResponses message to an array of v1 standard content blocks.\n *\n * This function processes an AI message containing OpenAI Responses-specific content blocks\n * and converts them to the standardized v1 content block format. It handles reasoning summaries,\n * text content with annotations, tool calls, and various tool outputs including code interpreter,\n * web search, file search, computer calls, and MCP-related blocks.\n *\n * A response can hold more than one reasoning item (e.g. multiple tool calls\n * in one turn, common on GPT-5.6-class models). When `response_metadata.output`\n * is available, each item's own `id`/`encrypted_content` is preserved and\n * blocks are sorted back into original order, so replay under Zero Data\n * Retention interleaves reasoning and tool calls correctly. Without it (e.g.\n * a hand-built message), falls back to a single reasoning block from\n * `additional_kwargs.reasoning`, as before.\n *\n * @param message - The AI message containing OpenAI Responses-formatted content blocks\n * @returns Array of content blocks in v1 standard format\n *\n * @example\n * ```typescript\n * const message = new AIMessage({\n * content: [{ type: \"text\", text: \"Hello world\", annotations: [] }],\n * tool_calls: [{ id: \"123\", name: \"calculator\", args: { a: 1, b: 2 } }],\n * additional_kwargs: {\n * reasoning: { summary: [{ text: \"Let me calculate this...\" }] },\n * tool_outputs: [\n * {\n * type: \"code_interpreter_call\",\n * code: \"print('hello')\",\n * outputs: [{ type: \"logs\", logs: \"hello\" }]\n * }\n * ]\n * }\n * });\n *\n * const standardBlocks = convertToV1FromResponses(message);\n * // Returns:\n * // [\n * // { type: \"reasoning\", reasoning: \"Let me calculate this...\" },\n * // { type: \"text\", text: \"Hello world\", annotations: [] },\n * // { type: \"tool_call\", id: \"123\", name: \"calculator\", args: { a: 1, b: 2 } },\n * // { type: \"server_tool_call\", name: \"code_interpreter\", args: { code: \"print('hello')\" } },\n * // { type: \"server_tool_call_result\", toolCallId: \"\", status: \"success\", output: { type: \"code_interpreter_output\", returnCode: 0, stdout: \"hello\" } }\n * // ]\n * ```\n */\nexport function convertToV1FromResponses(\n message: AIMessage\n): Array<ContentBlock.Standard> {\n const rawOutput = message.response_metadata?.output;\n const hasRawOutput = _isArray(rawOutput) && rawOutput.length > 0;\n\n // Maps a per-item key (namespaced by type, since ids aren't globally unique) to its original response.output position.\n const positionByKey = new Map<string, number>();\n let messageItemCount = 0;\n let onlyMessageItemIndex: number | undefined;\n if (hasRawOutput) {\n (rawOutput as unknown[]).forEach((rawItem, index) => {\n if (!_isObject(rawItem) || !_isString(rawItem.type)) return;\n if (rawItem.type === \"reasoning\" && _isString(rawItem.id)) {\n positionByKey.set(`reasoning:${rawItem.id}`, index);\n } else if (\n // These three types all become tool_call blocks keyed by call_id.\n (rawItem.type === \"function_call\" ||\n rawItem.type === \"custom_tool_call\" ||\n rawItem.type === \"computer_call\") &&\n _isString(rawItem.call_id)\n ) {\n positionByKey.set(`tool_call:${rawItem.call_id}`, index);\n } else if (rawItem.type === \"message\") {\n messageItemCount += 1;\n onlyMessageItemIndex = index;\n } else if (_isString(rawItem.id)) {\n positionByKey.set(`other:${rawItem.type}:${rawItem.id}`, index);\n }\n });\n }\n // Text isn't keyed to a specific \"message\" item, so only position it when exactly one exists (an unambiguous match).\n const textBlockKey =\n messageItemCount === 1 && onlyMessageItemIndex != null\n ? `message:${onlyMessageItemIndex}`\n : undefined;\n if (textBlockKey != null) {\n positionByKey.set(textBlockKey, onlyMessageItemIndex as number);\n }\n\n function* iterateContent(): Iterable<\n [block: ContentBlock.Standard, key: string | undefined]\n > {\n if (hasRawOutput) {\n for (const rawItem of rawOutput as unknown[]) {\n if (_isObject(rawItem) && rawItem.type === \"reasoning\") {\n const block = mapReasoningItemToV1(rawItem);\n if (block) {\n yield [\n block,\n _isString(rawItem.id) ? `reasoning:${rawItem.id}` : undefined,\n ];\n }\n }\n }\n } else if (\n _isObject(message.additional_kwargs?.reasoning) &&\n _isArray(message.additional_kwargs.reasoning.summary)\n ) {\n const block = mapReasoningItemToV1(message.additional_kwargs.reasoning);\n if (block) yield [block, undefined];\n }\n\n const content =\n typeof message.content === \"string\"\n ? [{ type: \"text\", text: message.content }]\n : message.content;\n for (const block of content) {\n if (_isContentBlock(block, \"text\")) {\n const {\n text,\n annotations,\n phase,\n extras: existingExtras,\n ...rest\n } = block;\n const extras: Record<string, unknown> = _isObject(existingExtras)\n ? { ...(existingExtras as Record<string, unknown>) }\n : {};\n if (_isString(phase)) {\n extras.phase = phase;\n }\n const extrasSpread = Object.keys(extras).length > 0 ? { extras } : {};\n yield [\n {\n ...rest,\n ...extrasSpread,\n type: \"text\",\n text: String(text),\n ...(Array.isArray(annotations)\n ? { annotations: annotations.map(convertResponsesAnnotation) }\n : {}),\n },\n textBlockKey,\n ];\n }\n }\n let hasRefusalPart = false;\n for (const block of content) {\n if (_isContentBlock(block, \"refusal\") && _isString(block.refusal)) {\n hasRefusalPart = true;\n yield [\n {\n type: \"refusal\",\n refusal: block.refusal,\n ...(_isString(block.id) ? { id: block.id } : {}),\n },\n textBlockKey,\n ];\n }\n }\n if (!hasRefusalPart) {\n const refusal = refusalFromAdditionalKwargs(message);\n if (refusal) yield [refusal, textBlockKey];\n }\n for (const toolCall of message.tool_calls ?? []) {\n yield [\n {\n type: \"tool_call\",\n id: toolCall.id,\n name: toolCall.name,\n args: toolCall.args,\n },\n toolCall.id ? `tool_call:${toolCall.id}` : undefined,\n ];\n }\n if (\n _isObject(message.additional_kwargs) &&\n _isArray(message.additional_kwargs.tool_outputs)\n ) {\n for (const toolOutput of message.additional_kwargs.tool_outputs) {\n // All blocks from one tool output share this key -- fine since the API returns a call and its result as one item.\n const key =\n _isObject(toolOutput) &&\n _isString(toolOutput.type) &&\n _isString(toolOutput.id)\n ? `other:${toolOutput.type}:${toolOutput.id}`\n : undefined;\n for (const block of mapToolOutputToV1Blocks(toolOutput)) {\n yield [block, key];\n }\n }\n }\n }\n\n const withKeys = Array.from(iterateContent());\n if (!hasRawOutput) {\n return withKeys.map(([block]) => block);\n }\n // Stable sort by original position; unkeyed blocks sort last, in push order.\n return withKeys\n .map(([block, key], pushIndex) => ({\n block,\n pushIndex,\n position: key != null ? positionByKey.get(key) : undefined,\n }))\n .sort((a, b) => {\n const aPos = a.position ?? Number.POSITIVE_INFINITY;\n const bPos = b.position ?? Number.POSITIVE_INFINITY;\n if (aPos !== bPos) return aPos - bPos;\n return a.pushIndex - b.pushIndex;\n })\n .map((entry) => entry.block);\n}\n\n/**\n * Converts a ChatOpenAIResponses message chunk to an array of v1 standard content blocks.\n *\n * This function processes an AI message chunk containing OpenAI-specific content blocks\n * and converts them to the standardized v1 content block format. It handles both the\n * regular message content and tool call chunks that are specific to streaming responses.\n *\n * @param message - The AI message chunk containing OpenAI-formatted content blocks\n * @returns Array of content blocks in v1 standard format\n *\n * @example\n * ```typescript\n * const messageChunk = new AIMessageChunk({\n * content: [{ type: \"text\", text: \"Hello\" }],\n * tool_call_chunks: [\n * { id: \"call_123\", name: \"calculator\", args: '{\"a\": 1' }\n * ]\n * });\n *\n * const standardBlocks = convertToV1FromResponsesChunk(messageChunk);\n * // Returns:\n * // [\n * // { type: \"text\", text: \"Hello\" },\n * // { type: \"tool_call_chunk\", id: \"call_123\", name: \"calculator\", args: '{\"a\": 1' }\n * // ]\n * ```\n */\nexport function convertToV1FromResponsesChunk(\n message: AIMessageChunk\n): Array<ContentBlock.Standard> {\n function* iterateContent(): Iterable<ContentBlock.Standard> {\n yield* convertToV1FromResponses(message);\n for (const toolCallChunk of message.tool_call_chunks ?? []) {\n yield {\n type: \"tool_call_chunk\",\n id: toolCallChunk.id,\n name: toolCallChunk.name,\n args: toolCallChunk.args,\n };\n }\n }\n return Array.from(iterateContent());\n}\n\nexport const ChatOpenAITranslator: StandardContentBlockTranslator = {\n translateContent: (message) => {\n if (typeof message.content === \"string\") {\n return convertToV1FromChatCompletions(message);\n }\n return convertToV1FromResponses(message);\n },\n translateContentChunk: (message) => {\n if (typeof message.content === \"string\") {\n return convertToV1FromChatCompletionsChunk(message);\n }\n return convertToV1FromResponsesChunk(message);\n },\n};\n"],"mappings":"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"}