@langchain/anthropic 1.6.0 → 1.6.1
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/CHANGELOG.md +6 -0
- package/dist/_virtual/_rolldown/runtime.cjs +1 -2
- package/dist/chat_models.cjs +2 -3
- package/dist/chat_models.d.cts +2 -8
- package/dist/chat_models.d.cts.map +1 -1
- package/dist/chat_models.d.ts +2 -8
- package/dist/chat_models.d.ts.map +1 -1
- package/dist/chat_models.js +2 -3
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/output_parsers.cjs +1 -2
- package/dist/output_parsers.js +1 -2
- package/dist/profiles.cjs +1 -2
- package/dist/profiles.js +1 -2
- package/dist/tools/bash.cjs +1 -2
- package/dist/tools/bash.d.cts +0 -2
- package/dist/tools/bash.d.cts.map +1 -1
- package/dist/tools/bash.d.ts +0 -2
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +1 -2
- package/dist/tools/codeExecution.cjs +1 -2
- package/dist/tools/codeExecution.d.cts +0 -2
- package/dist/tools/codeExecution.d.cts.map +1 -1
- package/dist/tools/codeExecution.d.ts +0 -2
- package/dist/tools/codeExecution.d.ts.map +1 -1
- package/dist/tools/codeExecution.js +1 -2
- package/dist/tools/computer.cjs +1 -2
- package/dist/tools/computer.d.cts +0 -2
- package/dist/tools/computer.d.cts.map +1 -1
- package/dist/tools/computer.d.ts +0 -2
- package/dist/tools/computer.d.ts.map +1 -1
- package/dist/tools/computer.js +1 -2
- package/dist/tools/index.cjs +1 -2
- package/dist/tools/index.d.cts +1 -3
- package/dist/tools/index.d.cts.map +1 -1
- package/dist/tools/index.d.ts +1 -3
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +1 -2
- package/dist/tools/mcpToolset.cjs +1 -2
- package/dist/tools/mcpToolset.d.cts +0 -2
- package/dist/tools/mcpToolset.d.cts.map +1 -1
- package/dist/tools/mcpToolset.d.ts +0 -2
- package/dist/tools/mcpToolset.d.ts.map +1 -1
- package/dist/tools/mcpToolset.js +1 -2
- package/dist/tools/memory.cjs +1 -2
- package/dist/tools/memory.d.cts +0 -2
- package/dist/tools/memory.d.cts.map +1 -1
- package/dist/tools/memory.d.ts +0 -2
- package/dist/tools/memory.d.ts.map +1 -1
- package/dist/tools/memory.js +1 -2
- package/dist/tools/textEditor.cjs +1 -2
- package/dist/tools/textEditor.d.cts +0 -2
- package/dist/tools/textEditor.d.cts.map +1 -1
- package/dist/tools/textEditor.d.ts +0 -2
- package/dist/tools/textEditor.d.ts.map +1 -1
- package/dist/tools/textEditor.js +1 -2
- package/dist/tools/toolSearch.cjs +1 -2
- package/dist/tools/toolSearch.d.cts +0 -2
- package/dist/tools/toolSearch.d.cts.map +1 -1
- package/dist/tools/toolSearch.d.ts +0 -2
- package/dist/tools/toolSearch.d.ts.map +1 -1
- package/dist/tools/toolSearch.js +1 -2
- package/dist/tools/types.cjs +1 -2
- package/dist/tools/types.d.cts +0 -2
- package/dist/tools/types.d.cts.map +1 -1
- package/dist/tools/types.d.ts +0 -2
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/types.js +1 -2
- package/dist/tools/webFetch.cjs +1 -2
- package/dist/tools/webFetch.d.cts +0 -2
- package/dist/tools/webFetch.d.cts.map +1 -1
- package/dist/tools/webFetch.d.ts +0 -2
- package/dist/tools/webFetch.d.ts.map +1 -1
- package/dist/tools/webFetch.js +1 -2
- package/dist/tools/webSearch.cjs +1 -2
- package/dist/tools/webSearch.d.cts +0 -2
- package/dist/tools/webSearch.d.cts.map +1 -1
- package/dist/tools/webSearch.d.ts +0 -2
- package/dist/tools/webSearch.d.ts.map +1 -1
- package/dist/tools/webSearch.js +1 -2
- package/dist/types.d.cts +0 -2
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.ts +0 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/content.cjs +1 -2
- package/dist/utils/content.js +1 -2
- package/dist/utils/errors.cjs +1 -2
- package/dist/utils/errors.js +1 -2
- package/dist/utils/index.cjs +1 -2
- package/dist/utils/index.js +1 -2
- package/dist/utils/message_inputs.cjs +2 -3
- package/dist/utils/message_inputs.cjs.map +1 -1
- package/dist/utils/message_inputs.js +2 -3
- package/dist/utils/message_inputs.js.map +1 -1
- package/dist/utils/message_outputs.cjs +1 -2
- package/dist/utils/message_outputs.js +1 -2
- package/dist/utils/params.cjs +1 -2
- package/dist/utils/params.js +1 -2
- package/dist/utils/prompts.cjs +1 -2
- package/dist/utils/prompts.d.cts +0 -2
- package/dist/utils/prompts.d.cts.map +1 -1
- package/dist/utils/prompts.d.ts +0 -2
- package/dist/utils/prompts.d.ts.map +1 -1
- package/dist/utils/prompts.js +1 -2
- package/dist/utils/standard.cjs +1 -2
- package/dist/utils/standard.js +1 -2
- package/dist/utils/stream_events.cjs +1 -2
- package/dist/utils/stream_events.js +1 -2
- package/dist/utils/tools.cjs +1 -2
- package/dist/utils/tools.js +1 -2
- package/package.json +11 -11
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const require_content = require("./content.cjs");
|
|
2
2
|
const require_standard = require("./standard.cjs");
|
|
3
3
|
let _langchain_core_messages = require("@langchain/core/messages");
|
|
4
|
-
|
|
4
|
+
// src/utils/message_inputs.ts
|
|
5
5
|
function _formatImage(imageUrl) {
|
|
6
6
|
const parsed = (0, _langchain_core_messages.parseBase64DataUrl)({ dataUrl: imageUrl });
|
|
7
7
|
if (parsed) return {
|
|
@@ -163,7 +163,7 @@ function* _formatContentBlocks(content, toolCalls) {
|
|
|
163
163
|
else if (toolTypes.find((t) => t === contentPart.type)) {
|
|
164
164
|
const contentPartCopy = { ...contentPart };
|
|
165
165
|
if (contentPartCopy.type === "input_json_delta") continue;
|
|
166
|
-
if (contentPartCopy.type === "tool_use" && typeof contentPartCopy.input === "string") {
|
|
166
|
+
if ((contentPartCopy.type === "tool_use" || contentPartCopy.type === "server_tool_use") && typeof contentPartCopy.input === "string") {
|
|
167
167
|
const matchingToolCall = toolCalls?.find((tc) => tc.id === contentPartCopy.id);
|
|
168
168
|
if (matchingToolCall) contentPartCopy.input = matchingToolCall.args;
|
|
169
169
|
else contentPartCopy.input = content.filter((nestedContentPart) => nestedContentPart.index === contentPartCopy.index && nestedContentPart.type === "input_json_delta" && typeof nestedContentPart.input === "string").reduce((accumulator, nestedContentPart) => accumulator + nestedContentPart.input, contentPartCopy.input);
|
|
@@ -345,7 +345,6 @@ function mergeMessages(messages) {
|
|
|
345
345
|
result.push(currentMessage);
|
|
346
346
|
return result;
|
|
347
347
|
}
|
|
348
|
-
//#endregion
|
|
349
348
|
exports._convertLangChainToolCallToAnthropic = _convertLangChainToolCallToAnthropic;
|
|
350
349
|
exports._convertMessagesToAnthropicPayload = _convertMessagesToAnthropicPayload;
|
|
351
350
|
exports._getToolChangeKind = _getToolChangeKind;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message_inputs.cjs","names":["parseBase64DataUrl","HumanMessage","isDataContentBlock","convertToProviderContentBlock","standardContentBlockConverter","_isAnthropicImageBlockParam","_isAnthropicThinkingBlock","_isAnthropicRedactedThinkingBlock","_isAnthropicCompactionBlock","_isAnthropicSearchResultBlock","AIMessage","_formatStandardContent"],"sources":["../../src/utils/message_inputs.ts"],"sourcesContent":["/**\n * This util file contains functions for converting LangChain messages to Anthropic messages.\n */\nimport type Anthropic from \"@anthropic-ai/sdk\";\nimport {\n type BaseMessage,\n HumanMessage,\n ToolMessage,\n MessageContentComplex,\n isDataContentBlock,\n convertToProviderContentBlock,\n parseBase64DataUrl,\n ContentBlock,\n AIMessage,\n} from \"@langchain/core/messages\";\nimport { ToolCall } from \"@langchain/core/messages/tool\";\nimport {\n AnthropicMessageCreateParams,\n AnthropicTextBlockParam,\n AnthropicThinkingBlockParam,\n AnthropicRedactedThinkingBlockParam,\n AnthropicSearchResultBlockParam,\n AnthropicToolResponse,\n AnthropicContainerUploadBlockParam,\n AnthropicCompactionBlockParam,\n} from \"../types.js\";\nimport {\n _isAnthropicImageBlockParam,\n _isAnthropicRedactedThinkingBlock,\n _isAnthropicSearchResultBlock,\n _isAnthropicThinkingBlock,\n _isAnthropicCompactionBlock,\n standardContentBlockConverter,\n} from \"./content.js\";\nimport { _formatStandardContent } from \"./standard.js\";\n\nfunction _formatImage(imageUrl: string) {\n const parsed = parseBase64DataUrl({ dataUrl: imageUrl });\n if (parsed) {\n return {\n type: \"base64\",\n media_type: parsed.mime_type,\n data: parsed.data,\n };\n }\n let parsedUrl: URL;\n\n try {\n parsedUrl = new URL(imageUrl);\n } catch {\n throw new Error(\n [\n `Malformed image URL: ${JSON.stringify(\n imageUrl\n )}. Content blocks of type 'image_url' must be a valid http, https, or base64-encoded data URL.`,\n \"Example: data:image/png;base64,/9j/4AAQSk...\",\n \"Example: https://example.com/image.jpg\",\n ].join(\"\\n\\n\")\n );\n }\n\n if (parsedUrl.protocol === \"http:\" || parsedUrl.protocol === \"https:\") {\n return {\n type: \"url\",\n url: imageUrl,\n };\n }\n\n throw new Error(\n [\n `Invalid image URL protocol: ${JSON.stringify(\n parsedUrl.protocol\n )}. Anthropic only supports images as http, https, or base64-encoded data URLs on 'image_url' content blocks.`,\n \"Example: data:image/png;base64,/9j/4AAQSk...\",\n \"Example: https://example.com/image.jpg\",\n ].join(\"\\n\\n\")\n );\n}\n\nfunction _ensureMessageContents(messages: BaseMessage[]): BaseMessage[] {\n // Merge runs of human/tool messages into single human messages with content blocks.\n const updatedMsgs = [];\n for (const message of messages) {\n if (message._getType() === \"tool\") {\n if (typeof message.content === \"string\") {\n const previousMessage = updatedMsgs[updatedMsgs.length - 1];\n if (\n previousMessage?._getType() === \"human\" &&\n Array.isArray(previousMessage.content) &&\n \"type\" in previousMessage.content[0] &&\n previousMessage.content[0].type === \"tool_result\"\n ) {\n // If the previous message was a tool result, we merge this tool message into it.\n (previousMessage.content as MessageContentComplex[]).push({\n type: \"tool_result\",\n content: message.content,\n tool_use_id: (message as ToolMessage).tool_call_id,\n });\n } else {\n // If not, we create a new human message with the tool result.\n updatedMsgs.push(\n new HumanMessage({\n content: [\n {\n type: \"tool_result\",\n content: message.content,\n tool_use_id: (message as ToolMessage).tool_call_id,\n },\n ],\n })\n );\n }\n } else {\n updatedMsgs.push(\n new HumanMessage({\n content: [\n {\n type: \"tool_result\",\n // rare case: message.content could be undefined\n ...(message.content != null\n ? { content: _formatContent(message) }\n : {}),\n tool_use_id: (message as ToolMessage).tool_call_id,\n },\n ],\n })\n );\n }\n } else {\n updatedMsgs.push(message);\n }\n }\n return updatedMsgs;\n}\n\nexport function _convertLangChainToolCallToAnthropic(\n toolCall: ToolCall\n): AnthropicToolResponse {\n if (toolCall.id === undefined) {\n throw new Error(`Anthropic requires all tool calls to have an \"id\".`);\n }\n return {\n type: \"tool_use\",\n id: toolCall.id,\n name: toolCall.name,\n input: toolCall.args,\n };\n}\n\nfunction* _formatContentBlocks(\n content: ContentBlock[],\n toolCalls?: ToolCall[]\n): Generator<Anthropic.Beta.BetaContentBlockParam> {\n const toolTypes = [\n \"bash_code_execution_tool_result\",\n \"input_json_delta\",\n \"server_tool_use\",\n \"text_editor_code_execution_tool_result\",\n \"tool_result\",\n \"tool_search_tool_result\",\n \"tool_search_tool_bm25_tool_result\",\n \"tool_search_tool_regex_tool_result\",\n \"tool_use\",\n \"web_search_result\",\n \"web_search_tool_result\",\n ];\n const textTypes = [\"text\", \"text_delta\"];\n for (const contentPart of content) {\n if (isDataContentBlock(contentPart)) {\n yield convertToProviderContentBlock(\n contentPart,\n standardContentBlockConverter\n );\n }\n\n const cacheControl =\n \"cache_control\" in contentPart\n ? (contentPart.cache_control as Anthropic.Beta.BetaCacheControlEphemeral)\n : undefined;\n\n if (contentPart.type === \"image_url\") {\n let source;\n if (typeof contentPart.image_url === \"string\") {\n source = _formatImage(contentPart.image_url);\n } else if (\n typeof contentPart.image_url === \"object\" &&\n contentPart.image_url !== null &&\n \"url\" in contentPart.image_url &&\n typeof contentPart.image_url.url === \"string\"\n ) {\n source = _formatImage(contentPart.image_url.url);\n }\n if (source) {\n yield {\n type: \"image\" as const, // Explicitly setting the type as \"image\"\n source,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n } as Anthropic.Messages.ImageBlockParam;\n }\n } else if (_isAnthropicImageBlockParam(contentPart)) {\n yield contentPart;\n } else if (contentPart.type === \"image\") {\n // Handle new ContentBlock.Multimodal.Image format\n let source;\n\n if (\"url\" in contentPart && typeof contentPart.url === \"string\") {\n // URL-based image\n source = _formatImage(contentPart.url);\n } else if (\n \"data\" in contentPart &&\n (typeof contentPart.data === \"string\" ||\n // oxlint-disable-next-line no-instanceof/no-instanceof\n contentPart.data instanceof Uint8Array)\n ) {\n // Base64-based image\n const mimeType =\n \"mimeType\" in contentPart && typeof contentPart.mimeType === \"string\"\n ? contentPart.mimeType\n : \"image/jpeg\";\n const data =\n typeof contentPart.data === \"string\"\n ? contentPart.data\n : Buffer.from(contentPart.data).toString(\"base64\");\n source = {\n type: \"base64\" as const,\n media_type: mimeType as\n | \"image/jpeg\"\n | \"image/png\"\n | \"image/gif\"\n | \"image/webp\",\n data,\n };\n } else if (\n \"fileId\" in contentPart &&\n typeof contentPart.fileId === \"string\"\n ) {\n // File ID-based image\n // Note: Anthropic supports file IDs for images that have been uploaded\n // to their servers via the Files API\n source = {\n type: \"file\" as const,\n file_id: contentPart.fileId,\n };\n }\n\n if (source) {\n yield {\n type: \"image\" as const,\n source,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n } as Anthropic.Messages.ImageBlockParam;\n }\n } else if (contentPart.type === \"file\") {\n // Handle new ContentBlock.Multimodal.File format\n let source:\n | { type: \"url\"; url: string }\n | { type: \"base64\"; media_type: string; data: string }\n | { type: \"file\"; file_id: string }\n | undefined;\n\n if (\"url\" in contentPart && typeof contentPart.url === \"string\") {\n // File with URL\n source = {\n type: \"url\" as const,\n url: contentPart.url,\n };\n } else if (\n \"data\" in contentPart &&\n (typeof contentPart.data === \"string\" ||\n // oxlint-disable-next-line no-instanceof/no-instanceof\n contentPart.data instanceof Uint8Array)\n ) {\n // File with base64 data (string or Uint8Array)\n const media_type =\n \"mimeType\" in contentPart && typeof contentPart.mimeType === \"string\"\n ? contentPart.mimeType\n : \"application/pdf\";\n const data =\n typeof contentPart.data === \"string\"\n ? contentPart.data\n : Buffer.from(contentPart.data).toString(\"base64\");\n\n source = {\n type: \"base64\" as const,\n media_type,\n data,\n };\n } else if (\n \"fileId\" in contentPart &&\n typeof contentPart.fileId === \"string\"\n ) {\n // File ID from Anthropic Files API\n // https://platform.claude.com/docs/en/build-with-claude/pdf-support#option-3-files-api\n source = {\n type: \"file\" as const,\n file_id: contentPart.fileId,\n };\n }\n\n if (source) {\n yield {\n type: \"document\" as const,\n source,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n } as Anthropic.Messages.DocumentBlockParam;\n }\n } else if (contentPart.type === \"document\") {\n // PDF\n yield {\n ...contentPart,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n } as Anthropic.Messages.DocumentBlockParam;\n } else if (_isAnthropicThinkingBlock(contentPart)) {\n const block: AnthropicThinkingBlockParam = {\n type: \"thinking\" as const, // Explicitly setting the type as \"thinking\"\n thinking: contentPart.thinking,\n signature: contentPart.signature,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n };\n yield block;\n } else if (_isAnthropicRedactedThinkingBlock(contentPart)) {\n const block: AnthropicRedactedThinkingBlockParam = {\n type: \"redacted_thinking\" as const, // Explicitly setting the type as \"redacted_thinking\"\n data: contentPart.data,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n };\n yield block;\n } else if (_isAnthropicCompactionBlock(contentPart)) {\n const block: AnthropicCompactionBlockParam = {\n type: \"compaction\" as const,\n content: contentPart.content,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n };\n yield block;\n } else if (_isAnthropicSearchResultBlock(contentPart)) {\n const block: AnthropicSearchResultBlockParam = {\n type: \"search_result\" as const, // Explicitly setting the type as \"search_result\"\n title: contentPart.title,\n source: contentPart.source,\n ...(\"cache_control\" in contentPart && contentPart.cache_control\n ? { cache_control: contentPart.cache_control }\n : {}),\n ...(\"citations\" in contentPart && contentPart.citations\n ? { citations: contentPart.citations }\n : {}),\n content: contentPart.content,\n };\n yield block as Anthropic.Beta.BetaSearchResultBlockParam;\n } else if (\n textTypes.find((t) => t === contentPart.type) &&\n \"text\" in contentPart\n ) {\n // Assuming contentPart is of type MessageContentText here\n yield {\n type: \"text\" as const, // Explicitly setting the type as \"text\"\n text: contentPart.text,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n ...(\"citations\" in contentPart && contentPart.citations\n ? { citations: contentPart.citations }\n : {}),\n } as Anthropic.Messages.TextBlockParam;\n } else if (toolTypes.find((t) => t === contentPart.type)) {\n const contentPartCopy = { ...contentPart };\n\n if (contentPartCopy.type === \"input_json_delta\") {\n // `input_json_delta` type only represents yielding partial tool inputs\n // and is not a valid type for Anthropic messages.\n // These blocks appear in streaming responses and should be skipped\n // as their input data is already captured in tool_calls.\n continue;\n }\n\n if (\n contentPartCopy.type === \"tool_use\" &&\n typeof contentPartCopy.input === \"string\"\n ) {\n // First, try to get the input from the corresponding tool_call.\n // This is the most reliable source since tool_calls are properly\n // consolidated from tool_call_chunks during streaming.\n const matchingToolCall = toolCalls?.find(\n (tc) => tc.id === contentPartCopy.id\n );\n if (matchingToolCall) {\n contentPartCopy.input = matchingToolCall.args;\n } else {\n // Fallback: `tool_use` content part may be followed by `input_json_delta`\n // content parts which are chunks of a stringified JSON input,\n // so we need to collect them and merge their inputs.\n const inputDeltas = content.filter(\n (nestedContentPart) =>\n nestedContentPart.index === contentPartCopy.index &&\n nestedContentPart.type === \"input_json_delta\" &&\n typeof nestedContentPart.input === \"string\"\n );\n // If no `input_json_delta` parts are found, this line will just\n // return `contentPartCopy.input`, so no additional check is needed\n contentPartCopy.input = inputDeltas.reduce(\n (accumulator, nestedContentPart) =>\n accumulator + nestedContentPart.input,\n contentPartCopy.input\n );\n }\n }\n\n if (\"index\" in contentPartCopy) {\n // Anthropic does not support passing the index field here, so we remove it.\n delete contentPartCopy.index;\n }\n\n if (\"input\" in contentPartCopy) {\n // Anthropic tool use inputs should be valid objects, when applicable.\n if (typeof contentPartCopy.input === \"string\") {\n try {\n contentPartCopy.input = JSON.parse(contentPartCopy.input);\n } catch {\n contentPartCopy.input = {};\n }\n }\n }\n // TODO: Fix when SDK types are fixed\n yield {\n ...contentPartCopy,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n } as any;\n } else if (contentPart.type === \"container_upload\") {\n yield {\n ...contentPart,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n } as AnthropicContainerUploadBlockParam;\n }\n\n // Note that we are intentionally dropping any blocks that we don't\n // recognize. This is to allow for cross-compatibility between different\n // providers that may have different block types. Ie if we take a message\n // output from OpenAI and send it to Anthropic, we want to drop any blocks\n // that Anthropic doesn't understand.\n }\n}\n\nfunction _formatContent(message: BaseMessage, toolCalls?: ToolCall[]) {\n const { content } = message;\n\n if (typeof content === \"string\") {\n return content;\n } else {\n return Array.from(_formatContentBlocks(content, toolCalls));\n }\n}\n\ntype AnthropicToolChangeBlockParam =\n | Anthropic.Beta.BetaRequestToolAdditionBlock\n | Anthropic.Beta.BetaRequestToolRemovalBlock;\n\ntype AnthropicSystemContentBlockParam =\n | Anthropic.Messages.ContentBlockParam\n | AnthropicToolChangeBlockParam;\n\nconst TOOL_CHANGE_BLOCK_TYPES = [\"tool_addition\", \"tool_removal\"];\n\n/**\n * Returns the provider payload a block carries: the `value` of a\n * `non_standard` wrapper, or the block itself.\n */\nfunction _unwrapNonStandard(\n block: MessageContentComplex\n): MessageContentComplex {\n if (\n block.type === \"non_standard\" &&\n \"value\" in block &&\n typeof block.value === \"object\" &&\n block.value !== null\n ) {\n return block.value as MessageContentComplex;\n }\n return block;\n}\n\n/**\n * Normalizes the content of a system message for the wire.\n *\n * Shared by the hoisted top-level `system` field and by in-place\n * `role: \"system\"` entries, so both strip the same framework-internal fields.\n *\n * Blocks wrapped in core's `non_standard` escape hatch are unwrapped first, so\n * a provider-native block behaves the same whichever way it was written.\n */\nfunction _formatSystemContent(\n content: BaseMessage[\"content\"]\n): string | AnthropicSystemContentBlockParam[] {\n if (typeof content === \"string\") {\n return content;\n }\n if (!Array.isArray(content)) {\n // rare case: message.content could be undefined\n return [];\n }\n return content.flatMap((rawBlock): AnthropicSystemContentBlockParam[] => {\n if (typeof rawBlock !== \"object\" || rawBlock === null) {\n return [{ type: \"text\" as const, text: String(rawBlock) }];\n }\n const block = _unwrapNonStandard(rawBlock);\n if (TOOL_CHANGE_BLOCK_TYPES.includes(block.type as string)) {\n return [block as AnthropicToolChangeBlockParam];\n }\n if (block.type === \"text\" && typeof block.text === \"string\") {\n return [\n {\n type: \"text\" as const,\n text: block.text,\n ...(\"cache_control\" in block && block.cache_control\n ? {\n cache_control:\n block.cache_control as AnthropicTextBlockParam[\"cache_control\"],\n }\n : {}),\n ...(\"citations\" in block && block.citations\n ? {\n citations:\n block.citations as AnthropicTextBlockParam[\"citations\"],\n }\n : {}),\n },\n ];\n }\n // Anthropic accepts a closed set of system content blocks, and rejects\n // the whole request for anything else.\n // Consider warning about the dropped block once we have a proper logging solution\n return [];\n });\n}\n\n/**\n * Formats messages as a prompt for the model.\n * Used in LangSmith, export is important here.\n * @param messages The base messages to format as a prompt.\n * @returns The formatted prompt.\n */\nexport function _convertMessagesToAnthropicPayload(\n messages: BaseMessage[]\n): AnthropicMessageCreateParams {\n const mergedMessages = _ensureMessageContents(messages);\n\n // The contiguous run of system messages starting at index 0 is hoisted into\n // the top-level `system` field. Every other system message keeps its\n // position and is sent as a `role: \"system\"` entry, which the provider\n // applies from that point in the conversation onwards. The run is identified\n // after tool-message folding, because that is the sequence the provider sees.\n let leadingSystemCount = 0;\n while (\n leadingSystemCount < mergedMessages.length &&\n mergedMessages[leadingSystemCount]._getType() === \"system\"\n ) {\n leadingSystemCount += 1;\n }\n\n let system: string | AnthropicSystemContentBlockParam[] | undefined;\n if (leadingSystemCount === 1) {\n system = _formatSystemContent(mergedMessages[0].content);\n } else if (leadingSystemCount > 1) {\n system = mergedMessages.slice(0, leadingSystemCount).flatMap((message) => {\n const content = _formatSystemContent(message.content);\n return typeof content === \"string\"\n ? [{ type: \"text\" as const, text: content }]\n : content;\n });\n }\n // The provider rejects empty system content, so system content that narrowed\n // to nothing is omitted rather than sent.\n if (Array.isArray(system) && system.length === 0) {\n system = undefined;\n }\n\n const conversationMessages = mergedMessages.slice(leadingSystemCount);\n const formattedMessages = conversationMessages.map((message) => {\n let role;\n if (message._getType() === \"human\") {\n role = \"user\" as const;\n } else if (message._getType() === \"ai\") {\n role = \"assistant\" as const;\n } else if (message._getType() === \"tool\") {\n role = \"user\" as const;\n } else if (message._getType() === \"system\") {\n role = \"system\" as const;\n } else {\n throw new Error(`Message type \"${message.type}\" is not supported.`);\n }\n if (\n AIMessage.isInstance(message) &&\n message.response_metadata?.output_version === \"v1\"\n ) {\n return {\n role,\n content: _formatStandardContent(message),\n };\n }\n if (AIMessage.isInstance(message) && !!message.tool_calls?.length) {\n if (typeof message.content === \"string\") {\n if (message.content === \"\") {\n return {\n role,\n content: message.tool_calls.map(\n _convertLangChainToolCallToAnthropic\n ),\n };\n } else {\n return {\n role,\n content: [\n { type: \"text\", text: message.content },\n ...message.tool_calls.map(_convertLangChainToolCallToAnthropic),\n ],\n };\n }\n } else {\n const { content } = message;\n const formattedContent = _formatContent(message, message.tool_calls);\n const formattedContentArr = Array.isArray(formattedContent)\n ? formattedContent\n : [{ type: \"text\" as const, text: formattedContent }];\n const missingToolCalls = message.tool_calls.filter(\n (toolCall) =>\n !content.find(\n (contentPart) =>\n (contentPart.type === \"tool_use\" ||\n contentPart.type === \"input_json_delta\" ||\n contentPart.type === \"server_tool_use\") &&\n contentPart.id === toolCall.id\n )\n );\n return {\n role,\n content: [\n ...formattedContentArr,\n ...missingToolCalls.map(_convertLangChainToolCallToAnthropic),\n ],\n };\n }\n } else if (role === \"system\") {\n const content = _formatSystemContent(message.content);\n return Array.isArray(content) && content.length === 0\n ? undefined\n : { role, content };\n } else {\n return {\n role,\n content: _formatContent(\n message,\n AIMessage.isInstance(message) ? message.tool_calls : undefined\n ),\n };\n }\n });\n return {\n messages: mergeMessages(\n formattedMessages.filter(\n (message) => message !== undefined\n ) as AnthropicMessageCreateParams[\"messages\"]\n ),\n system,\n } as AnthropicMessageCreateParams;\n}\n\n/**\n * Describes the tool changes in the system content of a converted payload:\n * `\"inline\"` if any `tool_addition` block defines a tool by value,\n * `\"reference\"` if tool changes only name tools declared elsewhere, or\n * `undefined` if there are none. The provider requires a different beta for\n * each.\n *\n * Reads the converted payload rather than the input messages, so a block that\n * was dropped during conversion never enables a beta.\n */\nexport function _getToolChangeKind(\n payload: AnthropicMessageCreateParams\n): \"inline\" | \"reference\" | undefined {\n const systemContents: unknown[] = [\n payload.system,\n ...payload.messages\n .filter((message) => message.role === \"system\")\n .map((message) => message.content),\n ];\n const toolChanges = systemContents.flatMap((content) =>\n Array.isArray(content)\n ? content.filter((block) => TOOL_CHANGE_BLOCK_TYPES.includes(block.type))\n : []\n );\n if (toolChanges.some((block) => block.tool?.type === \"tool_definition\")) {\n return \"inline\";\n }\n return toolChanges.length > 0 ? \"reference\" : undefined;\n}\n\nfunction mergeMessages(messages: AnthropicMessageCreateParams[\"messages\"]) {\n if (!messages || messages.length <= 1) {\n return messages;\n }\n\n const result: AnthropicMessageCreateParams[\"messages\"] = [];\n let currentMessage = messages[0];\n\n const normalizeContent = (\n content: string | Array<Anthropic.Messages.ContentBlockParam>\n ): Array<Anthropic.Messages.ContentBlockParam> => {\n if (typeof content === \"string\") {\n return [\n {\n type: \"text\",\n text: content,\n },\n ];\n }\n return content;\n };\n\n const isToolResultMessage = (msg: (typeof messages)[0]) => {\n if (msg.role !== \"user\") return false;\n\n if (typeof msg.content === \"string\") {\n return false;\n }\n\n return (\n Array.isArray(msg.content) &&\n msg.content.every((item) => item.type === \"tool_result\")\n );\n };\n\n for (let i = 1; i < messages.length; i += 1) {\n const nextMessage = messages[i];\n\n if (\n isToolResultMessage(currentMessage) &&\n isToolResultMessage(nextMessage)\n ) {\n // Merge the messages by combining their content arrays\n currentMessage = {\n ...currentMessage,\n content: [\n ...normalizeContent(currentMessage.content),\n ...normalizeContent(nextMessage.content),\n ],\n };\n } else {\n result.push(currentMessage);\n currentMessage = nextMessage;\n }\n }\n\n result.push(currentMessage);\n return result;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"message_inputs.cjs","names":["parseBase64DataUrl","HumanMessage","isDataContentBlock","convertToProviderContentBlock","standardContentBlockConverter","_isAnthropicImageBlockParam","_isAnthropicThinkingBlock","_isAnthropicRedactedThinkingBlock","_isAnthropicCompactionBlock","_isAnthropicSearchResultBlock","AIMessage","_formatStandardContent"],"sources":["../../src/utils/message_inputs.ts"],"sourcesContent":["/**\n * This util file contains functions for converting LangChain messages to Anthropic messages.\n */\nimport type Anthropic from \"@anthropic-ai/sdk\";\nimport {\n type BaseMessage,\n HumanMessage,\n ToolMessage,\n MessageContentComplex,\n isDataContentBlock,\n convertToProviderContentBlock,\n parseBase64DataUrl,\n ContentBlock,\n AIMessage,\n} from \"@langchain/core/messages\";\nimport { ToolCall } from \"@langchain/core/messages/tool\";\nimport {\n AnthropicMessageCreateParams,\n AnthropicTextBlockParam,\n AnthropicThinkingBlockParam,\n AnthropicRedactedThinkingBlockParam,\n AnthropicSearchResultBlockParam,\n AnthropicToolResponse,\n AnthropicContainerUploadBlockParam,\n AnthropicCompactionBlockParam,\n} from \"../types.js\";\nimport {\n _isAnthropicImageBlockParam,\n _isAnthropicRedactedThinkingBlock,\n _isAnthropicSearchResultBlock,\n _isAnthropicThinkingBlock,\n _isAnthropicCompactionBlock,\n standardContentBlockConverter,\n} from \"./content.js\";\nimport { _formatStandardContent } from \"./standard.js\";\n\nfunction _formatImage(imageUrl: string) {\n const parsed = parseBase64DataUrl({ dataUrl: imageUrl });\n if (parsed) {\n return {\n type: \"base64\",\n media_type: parsed.mime_type,\n data: parsed.data,\n };\n }\n let parsedUrl: URL;\n\n try {\n parsedUrl = new URL(imageUrl);\n } catch {\n throw new Error(\n [\n `Malformed image URL: ${JSON.stringify(\n imageUrl\n )}. Content blocks of type 'image_url' must be a valid http, https, or base64-encoded data URL.`,\n \"Example: data:image/png;base64,/9j/4AAQSk...\",\n \"Example: https://example.com/image.jpg\",\n ].join(\"\\n\\n\")\n );\n }\n\n if (parsedUrl.protocol === \"http:\" || parsedUrl.protocol === \"https:\") {\n return {\n type: \"url\",\n url: imageUrl,\n };\n }\n\n throw new Error(\n [\n `Invalid image URL protocol: ${JSON.stringify(\n parsedUrl.protocol\n )}. Anthropic only supports images as http, https, or base64-encoded data URLs on 'image_url' content blocks.`,\n \"Example: data:image/png;base64,/9j/4AAQSk...\",\n \"Example: https://example.com/image.jpg\",\n ].join(\"\\n\\n\")\n );\n}\n\nfunction _ensureMessageContents(messages: BaseMessage[]): BaseMessage[] {\n // Merge runs of human/tool messages into single human messages with content blocks.\n const updatedMsgs = [];\n for (const message of messages) {\n if (message._getType() === \"tool\") {\n if (typeof message.content === \"string\") {\n const previousMessage = updatedMsgs[updatedMsgs.length - 1];\n if (\n previousMessage?._getType() === \"human\" &&\n Array.isArray(previousMessage.content) &&\n \"type\" in previousMessage.content[0] &&\n previousMessage.content[0].type === \"tool_result\"\n ) {\n // If the previous message was a tool result, we merge this tool message into it.\n (previousMessage.content as MessageContentComplex[]).push({\n type: \"tool_result\",\n content: message.content,\n tool_use_id: (message as ToolMessage).tool_call_id,\n });\n } else {\n // If not, we create a new human message with the tool result.\n updatedMsgs.push(\n new HumanMessage({\n content: [\n {\n type: \"tool_result\",\n content: message.content,\n tool_use_id: (message as ToolMessage).tool_call_id,\n },\n ],\n })\n );\n }\n } else {\n updatedMsgs.push(\n new HumanMessage({\n content: [\n {\n type: \"tool_result\",\n // rare case: message.content could be undefined\n ...(message.content != null\n ? { content: _formatContent(message) }\n : {}),\n tool_use_id: (message as ToolMessage).tool_call_id,\n },\n ],\n })\n );\n }\n } else {\n updatedMsgs.push(message);\n }\n }\n return updatedMsgs;\n}\n\nexport function _convertLangChainToolCallToAnthropic(\n toolCall: ToolCall\n): AnthropicToolResponse {\n if (toolCall.id === undefined) {\n throw new Error(`Anthropic requires all tool calls to have an \"id\".`);\n }\n return {\n type: \"tool_use\",\n id: toolCall.id,\n name: toolCall.name,\n input: toolCall.args,\n };\n}\n\nfunction* _formatContentBlocks(\n content: ContentBlock[],\n toolCalls?: ToolCall[]\n): Generator<Anthropic.Beta.BetaContentBlockParam> {\n const toolTypes = [\n \"bash_code_execution_tool_result\",\n \"input_json_delta\",\n \"server_tool_use\",\n \"text_editor_code_execution_tool_result\",\n \"tool_result\",\n \"tool_search_tool_result\",\n \"tool_search_tool_bm25_tool_result\",\n \"tool_search_tool_regex_tool_result\",\n \"tool_use\",\n \"web_search_result\",\n \"web_search_tool_result\",\n ];\n const textTypes = [\"text\", \"text_delta\"];\n for (const contentPart of content) {\n if (isDataContentBlock(contentPart)) {\n yield convertToProviderContentBlock(\n contentPart,\n standardContentBlockConverter\n );\n }\n\n const cacheControl =\n \"cache_control\" in contentPart\n ? (contentPart.cache_control as Anthropic.Beta.BetaCacheControlEphemeral)\n : undefined;\n\n if (contentPart.type === \"image_url\") {\n let source;\n if (typeof contentPart.image_url === \"string\") {\n source = _formatImage(contentPart.image_url);\n } else if (\n typeof contentPart.image_url === \"object\" &&\n contentPart.image_url !== null &&\n \"url\" in contentPart.image_url &&\n typeof contentPart.image_url.url === \"string\"\n ) {\n source = _formatImage(contentPart.image_url.url);\n }\n if (source) {\n yield {\n type: \"image\" as const, // Explicitly setting the type as \"image\"\n source,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n } as Anthropic.Messages.ImageBlockParam;\n }\n } else if (_isAnthropicImageBlockParam(contentPart)) {\n yield contentPart;\n } else if (contentPart.type === \"image\") {\n // Handle new ContentBlock.Multimodal.Image format\n let source;\n\n if (\"url\" in contentPart && typeof contentPart.url === \"string\") {\n // URL-based image\n source = _formatImage(contentPart.url);\n } else if (\n \"data\" in contentPart &&\n (typeof contentPart.data === \"string\" ||\n // oxlint-disable-next-line no-instanceof/no-instanceof\n contentPart.data instanceof Uint8Array)\n ) {\n // Base64-based image\n const mimeType =\n \"mimeType\" in contentPart && typeof contentPart.mimeType === \"string\"\n ? contentPart.mimeType\n : \"image/jpeg\";\n const data =\n typeof contentPart.data === \"string\"\n ? contentPart.data\n : Buffer.from(contentPart.data).toString(\"base64\");\n source = {\n type: \"base64\" as const,\n media_type: mimeType as\n | \"image/jpeg\"\n | \"image/png\"\n | \"image/gif\"\n | \"image/webp\",\n data,\n };\n } else if (\n \"fileId\" in contentPart &&\n typeof contentPart.fileId === \"string\"\n ) {\n // File ID-based image\n // Note: Anthropic supports file IDs for images that have been uploaded\n // to their servers via the Files API\n source = {\n type: \"file\" as const,\n file_id: contentPart.fileId,\n };\n }\n\n if (source) {\n yield {\n type: \"image\" as const,\n source,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n } as Anthropic.Messages.ImageBlockParam;\n }\n } else if (contentPart.type === \"file\") {\n // Handle new ContentBlock.Multimodal.File format\n let source:\n | { type: \"url\"; url: string }\n | { type: \"base64\"; media_type: string; data: string }\n | { type: \"file\"; file_id: string }\n | undefined;\n\n if (\"url\" in contentPart && typeof contentPart.url === \"string\") {\n // File with URL\n source = {\n type: \"url\" as const,\n url: contentPart.url,\n };\n } else if (\n \"data\" in contentPart &&\n (typeof contentPart.data === \"string\" ||\n // oxlint-disable-next-line no-instanceof/no-instanceof\n contentPart.data instanceof Uint8Array)\n ) {\n // File with base64 data (string or Uint8Array)\n const media_type =\n \"mimeType\" in contentPart && typeof contentPart.mimeType === \"string\"\n ? contentPart.mimeType\n : \"application/pdf\";\n const data =\n typeof contentPart.data === \"string\"\n ? contentPart.data\n : Buffer.from(contentPart.data).toString(\"base64\");\n\n source = {\n type: \"base64\" as const,\n media_type,\n data,\n };\n } else if (\n \"fileId\" in contentPart &&\n typeof contentPart.fileId === \"string\"\n ) {\n // File ID from Anthropic Files API\n // https://platform.claude.com/docs/en/build-with-claude/pdf-support#option-3-files-api\n source = {\n type: \"file\" as const,\n file_id: contentPart.fileId,\n };\n }\n\n if (source) {\n yield {\n type: \"document\" as const,\n source,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n } as Anthropic.Messages.DocumentBlockParam;\n }\n } else if (contentPart.type === \"document\") {\n // PDF\n yield {\n ...contentPart,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n } as Anthropic.Messages.DocumentBlockParam;\n } else if (_isAnthropicThinkingBlock(contentPart)) {\n const block: AnthropicThinkingBlockParam = {\n type: \"thinking\" as const, // Explicitly setting the type as \"thinking\"\n thinking: contentPart.thinking,\n signature: contentPart.signature,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n };\n yield block;\n } else if (_isAnthropicRedactedThinkingBlock(contentPart)) {\n const block: AnthropicRedactedThinkingBlockParam = {\n type: \"redacted_thinking\" as const, // Explicitly setting the type as \"redacted_thinking\"\n data: contentPart.data,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n };\n yield block;\n } else if (_isAnthropicCompactionBlock(contentPart)) {\n const block: AnthropicCompactionBlockParam = {\n type: \"compaction\" as const,\n content: contentPart.content,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n };\n yield block;\n } else if (_isAnthropicSearchResultBlock(contentPart)) {\n const block: AnthropicSearchResultBlockParam = {\n type: \"search_result\" as const, // Explicitly setting the type as \"search_result\"\n title: contentPart.title,\n source: contentPart.source,\n ...(\"cache_control\" in contentPart && contentPart.cache_control\n ? { cache_control: contentPart.cache_control }\n : {}),\n ...(\"citations\" in contentPart && contentPart.citations\n ? { citations: contentPart.citations }\n : {}),\n content: contentPart.content,\n };\n yield block as Anthropic.Beta.BetaSearchResultBlockParam;\n } else if (\n textTypes.find((t) => t === contentPart.type) &&\n \"text\" in contentPart\n ) {\n // Assuming contentPart is of type MessageContentText here\n yield {\n type: \"text\" as const, // Explicitly setting the type as \"text\"\n text: contentPart.text,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n ...(\"citations\" in contentPart && contentPart.citations\n ? { citations: contentPart.citations }\n : {}),\n } as Anthropic.Messages.TextBlockParam;\n } else if (toolTypes.find((t) => t === contentPart.type)) {\n const contentPartCopy = { ...contentPart };\n\n if (contentPartCopy.type === \"input_json_delta\") {\n // `input_json_delta` type only represents yielding partial tool inputs\n // and is not a valid type for Anthropic messages.\n // These blocks appear in streaming responses and should be skipped\n // as their input data is already captured in tool_calls.\n continue;\n }\n\n if (\n (contentPartCopy.type === \"tool_use\" ||\n contentPartCopy.type === \"server_tool_use\") &&\n typeof contentPartCopy.input === \"string\"\n ) {\n // First, try to get the input from the corresponding tool_call.\n // This is the most reliable source since tool_calls are properly\n // consolidated from tool_call_chunks during streaming.\n // `server_tool_use` blocks have no tool_call, so they always take\n // the fallback below.\n const matchingToolCall = toolCalls?.find(\n (tc) => tc.id === contentPartCopy.id\n );\n if (matchingToolCall) {\n contentPartCopy.input = matchingToolCall.args;\n } else {\n // Fallback: `tool_use` and `server_tool_use` content parts may be\n // followed by `input_json_delta` content parts which are chunks of\n // a stringified JSON input, so we need to collect them and merge\n // their inputs.\n const inputDeltas = content.filter(\n (nestedContentPart) =>\n nestedContentPart.index === contentPartCopy.index &&\n nestedContentPart.type === \"input_json_delta\" &&\n typeof nestedContentPart.input === \"string\"\n );\n // If no `input_json_delta` parts are found, this line will just\n // return `contentPartCopy.input`, so no additional check is needed\n contentPartCopy.input = inputDeltas.reduce(\n (accumulator, nestedContentPart) =>\n accumulator + nestedContentPart.input,\n contentPartCopy.input\n );\n }\n }\n\n if (\"index\" in contentPartCopy) {\n // Anthropic does not support passing the index field here, so we remove it.\n delete contentPartCopy.index;\n }\n\n if (\"input\" in contentPartCopy) {\n // Anthropic tool use inputs should be valid objects, when applicable.\n if (typeof contentPartCopy.input === \"string\") {\n try {\n contentPartCopy.input = JSON.parse(contentPartCopy.input);\n } catch {\n contentPartCopy.input = {};\n }\n }\n }\n // TODO: Fix when SDK types are fixed\n yield {\n ...contentPartCopy,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n } as any;\n } else if (contentPart.type === \"container_upload\") {\n yield {\n ...contentPart,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n } as AnthropicContainerUploadBlockParam;\n }\n\n // Note that we are intentionally dropping any blocks that we don't\n // recognize. This is to allow for cross-compatibility between different\n // providers that may have different block types. Ie if we take a message\n // output from OpenAI and send it to Anthropic, we want to drop any blocks\n // that Anthropic doesn't understand.\n }\n}\n\nfunction _formatContent(message: BaseMessage, toolCalls?: ToolCall[]) {\n const { content } = message;\n\n if (typeof content === \"string\") {\n return content;\n } else {\n return Array.from(_formatContentBlocks(content, toolCalls));\n }\n}\n\ntype AnthropicToolChangeBlockParam =\n | Anthropic.Beta.BetaRequestToolAdditionBlock\n | Anthropic.Beta.BetaRequestToolRemovalBlock;\n\ntype AnthropicSystemContentBlockParam =\n | Anthropic.Messages.ContentBlockParam\n | AnthropicToolChangeBlockParam;\n\nconst TOOL_CHANGE_BLOCK_TYPES = [\"tool_addition\", \"tool_removal\"];\n\n/**\n * Returns the provider payload a block carries: the `value` of a\n * `non_standard` wrapper, or the block itself.\n */\nfunction _unwrapNonStandard(\n block: MessageContentComplex\n): MessageContentComplex {\n if (\n block.type === \"non_standard\" &&\n \"value\" in block &&\n typeof block.value === \"object\" &&\n block.value !== null\n ) {\n return block.value as MessageContentComplex;\n }\n return block;\n}\n\n/**\n * Normalizes the content of a system message for the wire.\n *\n * Shared by the hoisted top-level `system` field and by in-place\n * `role: \"system\"` entries, so both strip the same framework-internal fields.\n *\n * Blocks wrapped in core's `non_standard` escape hatch are unwrapped first, so\n * a provider-native block behaves the same whichever way it was written.\n */\nfunction _formatSystemContent(\n content: BaseMessage[\"content\"]\n): string | AnthropicSystemContentBlockParam[] {\n if (typeof content === \"string\") {\n return content;\n }\n if (!Array.isArray(content)) {\n // rare case: message.content could be undefined\n return [];\n }\n return content.flatMap((rawBlock): AnthropicSystemContentBlockParam[] => {\n if (typeof rawBlock !== \"object\" || rawBlock === null) {\n return [{ type: \"text\" as const, text: String(rawBlock) }];\n }\n const block = _unwrapNonStandard(rawBlock);\n if (TOOL_CHANGE_BLOCK_TYPES.includes(block.type as string)) {\n return [block as AnthropicToolChangeBlockParam];\n }\n if (block.type === \"text\" && typeof block.text === \"string\") {\n return [\n {\n type: \"text\" as const,\n text: block.text,\n ...(\"cache_control\" in block && block.cache_control\n ? {\n cache_control:\n block.cache_control as AnthropicTextBlockParam[\"cache_control\"],\n }\n : {}),\n ...(\"citations\" in block && block.citations\n ? {\n citations:\n block.citations as AnthropicTextBlockParam[\"citations\"],\n }\n : {}),\n },\n ];\n }\n // Anthropic accepts a closed set of system content blocks, and rejects\n // the whole request for anything else.\n // Consider warning about the dropped block once we have a proper logging solution\n return [];\n });\n}\n\n/**\n * Formats messages as a prompt for the model.\n * Used in LangSmith, export is important here.\n * @param messages The base messages to format as a prompt.\n * @returns The formatted prompt.\n */\nexport function _convertMessagesToAnthropicPayload(\n messages: BaseMessage[]\n): AnthropicMessageCreateParams {\n const mergedMessages = _ensureMessageContents(messages);\n\n // The contiguous run of system messages starting at index 0 is hoisted into\n // the top-level `system` field. Every other system message keeps its\n // position and is sent as a `role: \"system\"` entry, which the provider\n // applies from that point in the conversation onwards. The run is identified\n // after tool-message folding, because that is the sequence the provider sees.\n let leadingSystemCount = 0;\n while (\n leadingSystemCount < mergedMessages.length &&\n mergedMessages[leadingSystemCount]._getType() === \"system\"\n ) {\n leadingSystemCount += 1;\n }\n\n let system: string | AnthropicSystemContentBlockParam[] | undefined;\n if (leadingSystemCount === 1) {\n system = _formatSystemContent(mergedMessages[0].content);\n } else if (leadingSystemCount > 1) {\n system = mergedMessages.slice(0, leadingSystemCount).flatMap((message) => {\n const content = _formatSystemContent(message.content);\n return typeof content === \"string\"\n ? [{ type: \"text\" as const, text: content }]\n : content;\n });\n }\n // The provider rejects empty system content, so system content that narrowed\n // to nothing is omitted rather than sent.\n if (Array.isArray(system) && system.length === 0) {\n system = undefined;\n }\n\n const conversationMessages = mergedMessages.slice(leadingSystemCount);\n const formattedMessages = conversationMessages.map((message) => {\n let role;\n if (message._getType() === \"human\") {\n role = \"user\" as const;\n } else if (message._getType() === \"ai\") {\n role = \"assistant\" as const;\n } else if (message._getType() === \"tool\") {\n role = \"user\" as const;\n } else if (message._getType() === \"system\") {\n role = \"system\" as const;\n } else {\n throw new Error(`Message type \"${message.type}\" is not supported.`);\n }\n if (\n AIMessage.isInstance(message) &&\n message.response_metadata?.output_version === \"v1\"\n ) {\n return {\n role,\n content: _formatStandardContent(message),\n };\n }\n if (AIMessage.isInstance(message) && !!message.tool_calls?.length) {\n if (typeof message.content === \"string\") {\n if (message.content === \"\") {\n return {\n role,\n content: message.tool_calls.map(\n _convertLangChainToolCallToAnthropic\n ),\n };\n } else {\n return {\n role,\n content: [\n { type: \"text\", text: message.content },\n ...message.tool_calls.map(_convertLangChainToolCallToAnthropic),\n ],\n };\n }\n } else {\n const { content } = message;\n const formattedContent = _formatContent(message, message.tool_calls);\n const formattedContentArr = Array.isArray(formattedContent)\n ? formattedContent\n : [{ type: \"text\" as const, text: formattedContent }];\n const missingToolCalls = message.tool_calls.filter(\n (toolCall) =>\n !content.find(\n (contentPart) =>\n (contentPart.type === \"tool_use\" ||\n contentPart.type === \"input_json_delta\" ||\n contentPart.type === \"server_tool_use\") &&\n contentPart.id === toolCall.id\n )\n );\n return {\n role,\n content: [\n ...formattedContentArr,\n ...missingToolCalls.map(_convertLangChainToolCallToAnthropic),\n ],\n };\n }\n } else if (role === \"system\") {\n const content = _formatSystemContent(message.content);\n return Array.isArray(content) && content.length === 0\n ? undefined\n : { role, content };\n } else {\n return {\n role,\n content: _formatContent(\n message,\n AIMessage.isInstance(message) ? message.tool_calls : undefined\n ),\n };\n }\n });\n return {\n messages: mergeMessages(\n formattedMessages.filter(\n (message) => message !== undefined\n ) as AnthropicMessageCreateParams[\"messages\"]\n ),\n system,\n } as AnthropicMessageCreateParams;\n}\n\n/**\n * Describes the tool changes in the system content of a converted payload:\n * `\"inline\"` if any `tool_addition` block defines a tool by value,\n * `\"reference\"` if tool changes only name tools declared elsewhere, or\n * `undefined` if there are none. The provider requires a different beta for\n * each.\n *\n * Reads the converted payload rather than the input messages, so a block that\n * was dropped during conversion never enables a beta.\n */\nexport function _getToolChangeKind(\n payload: AnthropicMessageCreateParams\n): \"inline\" | \"reference\" | undefined {\n const systemContents: unknown[] = [\n payload.system,\n ...payload.messages\n .filter((message) => message.role === \"system\")\n .map((message) => message.content),\n ];\n const toolChanges = systemContents.flatMap((content) =>\n Array.isArray(content)\n ? content.filter((block) => TOOL_CHANGE_BLOCK_TYPES.includes(block.type))\n : []\n );\n if (toolChanges.some((block) => block.tool?.type === \"tool_definition\")) {\n return \"inline\";\n }\n return toolChanges.length > 0 ? \"reference\" : undefined;\n}\n\nfunction mergeMessages(messages: AnthropicMessageCreateParams[\"messages\"]) {\n if (!messages || messages.length <= 1) {\n return messages;\n }\n\n const result: AnthropicMessageCreateParams[\"messages\"] = [];\n let currentMessage = messages[0];\n\n const normalizeContent = (\n content: string | Array<Anthropic.Messages.ContentBlockParam>\n ): Array<Anthropic.Messages.ContentBlockParam> => {\n if (typeof content === \"string\") {\n return [\n {\n type: \"text\",\n text: content,\n },\n ];\n }\n return content;\n };\n\n const isToolResultMessage = (msg: (typeof messages)[0]) => {\n if (msg.role !== \"user\") return false;\n\n if (typeof msg.content === \"string\") {\n return false;\n }\n\n return (\n Array.isArray(msg.content) &&\n msg.content.every((item) => item.type === \"tool_result\")\n );\n };\n\n for (let i = 1; i < messages.length; i += 1) {\n const nextMessage = messages[i];\n\n if (\n isToolResultMessage(currentMessage) &&\n isToolResultMessage(nextMessage)\n ) {\n // Merge the messages by combining their content arrays\n currentMessage = {\n ...currentMessage,\n content: [\n ...normalizeContent(currentMessage.content),\n ...normalizeContent(nextMessage.content),\n ],\n };\n } else {\n result.push(currentMessage);\n currentMessage = nextMessage;\n }\n }\n\n result.push(currentMessage);\n return result;\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { _isAnthropicCompactionBlock, _isAnthropicImageBlockParam, _isAnthropicRedactedThinkingBlock, _isAnthropicSearchResultBlock, _isAnthropicThinkingBlock, standardContentBlockConverter } from "./content.js";
|
|
2
2
|
import { _formatStandardContent } from "./standard.js";
|
|
3
3
|
import { AIMessage, HumanMessage, convertToProviderContentBlock, isDataContentBlock, parseBase64DataUrl } from "@langchain/core/messages";
|
|
4
|
-
|
|
4
|
+
// src/utils/message_inputs.ts
|
|
5
5
|
function _formatImage(imageUrl) {
|
|
6
6
|
const parsed = parseBase64DataUrl({ dataUrl: imageUrl });
|
|
7
7
|
if (parsed) return {
|
|
@@ -163,7 +163,7 @@ function* _formatContentBlocks(content, toolCalls) {
|
|
|
163
163
|
else if (toolTypes.find((t) => t === contentPart.type)) {
|
|
164
164
|
const contentPartCopy = { ...contentPart };
|
|
165
165
|
if (contentPartCopy.type === "input_json_delta") continue;
|
|
166
|
-
if (contentPartCopy.type === "tool_use" && typeof contentPartCopy.input === "string") {
|
|
166
|
+
if ((contentPartCopy.type === "tool_use" || contentPartCopy.type === "server_tool_use") && typeof contentPartCopy.input === "string") {
|
|
167
167
|
const matchingToolCall = toolCalls?.find((tc) => tc.id === contentPartCopy.id);
|
|
168
168
|
if (matchingToolCall) contentPartCopy.input = matchingToolCall.args;
|
|
169
169
|
else contentPartCopy.input = content.filter((nestedContentPart) => nestedContentPart.index === contentPartCopy.index && nestedContentPart.type === "input_json_delta" && typeof nestedContentPart.input === "string").reduce((accumulator, nestedContentPart) => accumulator + nestedContentPart.input, contentPartCopy.input);
|
|
@@ -345,7 +345,6 @@ function mergeMessages(messages) {
|
|
|
345
345
|
result.push(currentMessage);
|
|
346
346
|
return result;
|
|
347
347
|
}
|
|
348
|
-
//#endregion
|
|
349
348
|
export { _convertLangChainToolCallToAnthropic, _convertMessagesToAnthropicPayload, _getToolChangeKind };
|
|
350
349
|
|
|
351
350
|
//# sourceMappingURL=message_inputs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message_inputs.js","names":[],"sources":["../../src/utils/message_inputs.ts"],"sourcesContent":["/**\n * This util file contains functions for converting LangChain messages to Anthropic messages.\n */\nimport type Anthropic from \"@anthropic-ai/sdk\";\nimport {\n type BaseMessage,\n HumanMessage,\n ToolMessage,\n MessageContentComplex,\n isDataContentBlock,\n convertToProviderContentBlock,\n parseBase64DataUrl,\n ContentBlock,\n AIMessage,\n} from \"@langchain/core/messages\";\nimport { ToolCall } from \"@langchain/core/messages/tool\";\nimport {\n AnthropicMessageCreateParams,\n AnthropicTextBlockParam,\n AnthropicThinkingBlockParam,\n AnthropicRedactedThinkingBlockParam,\n AnthropicSearchResultBlockParam,\n AnthropicToolResponse,\n AnthropicContainerUploadBlockParam,\n AnthropicCompactionBlockParam,\n} from \"../types.js\";\nimport {\n _isAnthropicImageBlockParam,\n _isAnthropicRedactedThinkingBlock,\n _isAnthropicSearchResultBlock,\n _isAnthropicThinkingBlock,\n _isAnthropicCompactionBlock,\n standardContentBlockConverter,\n} from \"./content.js\";\nimport { _formatStandardContent } from \"./standard.js\";\n\nfunction _formatImage(imageUrl: string) {\n const parsed = parseBase64DataUrl({ dataUrl: imageUrl });\n if (parsed) {\n return {\n type: \"base64\",\n media_type: parsed.mime_type,\n data: parsed.data,\n };\n }\n let parsedUrl: URL;\n\n try {\n parsedUrl = new URL(imageUrl);\n } catch {\n throw new Error(\n [\n `Malformed image URL: ${JSON.stringify(\n imageUrl\n )}. Content blocks of type 'image_url' must be a valid http, https, or base64-encoded data URL.`,\n \"Example: data:image/png;base64,/9j/4AAQSk...\",\n \"Example: https://example.com/image.jpg\",\n ].join(\"\\n\\n\")\n );\n }\n\n if (parsedUrl.protocol === \"http:\" || parsedUrl.protocol === \"https:\") {\n return {\n type: \"url\",\n url: imageUrl,\n };\n }\n\n throw new Error(\n [\n `Invalid image URL protocol: ${JSON.stringify(\n parsedUrl.protocol\n )}. Anthropic only supports images as http, https, or base64-encoded data URLs on 'image_url' content blocks.`,\n \"Example: data:image/png;base64,/9j/4AAQSk...\",\n \"Example: https://example.com/image.jpg\",\n ].join(\"\\n\\n\")\n );\n}\n\nfunction _ensureMessageContents(messages: BaseMessage[]): BaseMessage[] {\n // Merge runs of human/tool messages into single human messages with content blocks.\n const updatedMsgs = [];\n for (const message of messages) {\n if (message._getType() === \"tool\") {\n if (typeof message.content === \"string\") {\n const previousMessage = updatedMsgs[updatedMsgs.length - 1];\n if (\n previousMessage?._getType() === \"human\" &&\n Array.isArray(previousMessage.content) &&\n \"type\" in previousMessage.content[0] &&\n previousMessage.content[0].type === \"tool_result\"\n ) {\n // If the previous message was a tool result, we merge this tool message into it.\n (previousMessage.content as MessageContentComplex[]).push({\n type: \"tool_result\",\n content: message.content,\n tool_use_id: (message as ToolMessage).tool_call_id,\n });\n } else {\n // If not, we create a new human message with the tool result.\n updatedMsgs.push(\n new HumanMessage({\n content: [\n {\n type: \"tool_result\",\n content: message.content,\n tool_use_id: (message as ToolMessage).tool_call_id,\n },\n ],\n })\n );\n }\n } else {\n updatedMsgs.push(\n new HumanMessage({\n content: [\n {\n type: \"tool_result\",\n // rare case: message.content could be undefined\n ...(message.content != null\n ? { content: _formatContent(message) }\n : {}),\n tool_use_id: (message as ToolMessage).tool_call_id,\n },\n ],\n })\n );\n }\n } else {\n updatedMsgs.push(message);\n }\n }\n return updatedMsgs;\n}\n\nexport function _convertLangChainToolCallToAnthropic(\n toolCall: ToolCall\n): AnthropicToolResponse {\n if (toolCall.id === undefined) {\n throw new Error(`Anthropic requires all tool calls to have an \"id\".`);\n }\n return {\n type: \"tool_use\",\n id: toolCall.id,\n name: toolCall.name,\n input: toolCall.args,\n };\n}\n\nfunction* _formatContentBlocks(\n content: ContentBlock[],\n toolCalls?: ToolCall[]\n): Generator<Anthropic.Beta.BetaContentBlockParam> {\n const toolTypes = [\n \"bash_code_execution_tool_result\",\n \"input_json_delta\",\n \"server_tool_use\",\n \"text_editor_code_execution_tool_result\",\n \"tool_result\",\n \"tool_search_tool_result\",\n \"tool_search_tool_bm25_tool_result\",\n \"tool_search_tool_regex_tool_result\",\n \"tool_use\",\n \"web_search_result\",\n \"web_search_tool_result\",\n ];\n const textTypes = [\"text\", \"text_delta\"];\n for (const contentPart of content) {\n if (isDataContentBlock(contentPart)) {\n yield convertToProviderContentBlock(\n contentPart,\n standardContentBlockConverter\n );\n }\n\n const cacheControl =\n \"cache_control\" in contentPart\n ? (contentPart.cache_control as Anthropic.Beta.BetaCacheControlEphemeral)\n : undefined;\n\n if (contentPart.type === \"image_url\") {\n let source;\n if (typeof contentPart.image_url === \"string\") {\n source = _formatImage(contentPart.image_url);\n } else if (\n typeof contentPart.image_url === \"object\" &&\n contentPart.image_url !== null &&\n \"url\" in contentPart.image_url &&\n typeof contentPart.image_url.url === \"string\"\n ) {\n source = _formatImage(contentPart.image_url.url);\n }\n if (source) {\n yield {\n type: \"image\" as const, // Explicitly setting the type as \"image\"\n source,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n } as Anthropic.Messages.ImageBlockParam;\n }\n } else if (_isAnthropicImageBlockParam(contentPart)) {\n yield contentPart;\n } else if (contentPart.type === \"image\") {\n // Handle new ContentBlock.Multimodal.Image format\n let source;\n\n if (\"url\" in contentPart && typeof contentPart.url === \"string\") {\n // URL-based image\n source = _formatImage(contentPart.url);\n } else if (\n \"data\" in contentPart &&\n (typeof contentPart.data === \"string\" ||\n // oxlint-disable-next-line no-instanceof/no-instanceof\n contentPart.data instanceof Uint8Array)\n ) {\n // Base64-based image\n const mimeType =\n \"mimeType\" in contentPart && typeof contentPart.mimeType === \"string\"\n ? contentPart.mimeType\n : \"image/jpeg\";\n const data =\n typeof contentPart.data === \"string\"\n ? contentPart.data\n : Buffer.from(contentPart.data).toString(\"base64\");\n source = {\n type: \"base64\" as const,\n media_type: mimeType as\n | \"image/jpeg\"\n | \"image/png\"\n | \"image/gif\"\n | \"image/webp\",\n data,\n };\n } else if (\n \"fileId\" in contentPart &&\n typeof contentPart.fileId === \"string\"\n ) {\n // File ID-based image\n // Note: Anthropic supports file IDs for images that have been uploaded\n // to their servers via the Files API\n source = {\n type: \"file\" as const,\n file_id: contentPart.fileId,\n };\n }\n\n if (source) {\n yield {\n type: \"image\" as const,\n source,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n } as Anthropic.Messages.ImageBlockParam;\n }\n } else if (contentPart.type === \"file\") {\n // Handle new ContentBlock.Multimodal.File format\n let source:\n | { type: \"url\"; url: string }\n | { type: \"base64\"; media_type: string; data: string }\n | { type: \"file\"; file_id: string }\n | undefined;\n\n if (\"url\" in contentPart && typeof contentPart.url === \"string\") {\n // File with URL\n source = {\n type: \"url\" as const,\n url: contentPart.url,\n };\n } else if (\n \"data\" in contentPart &&\n (typeof contentPart.data === \"string\" ||\n // oxlint-disable-next-line no-instanceof/no-instanceof\n contentPart.data instanceof Uint8Array)\n ) {\n // File with base64 data (string or Uint8Array)\n const media_type =\n \"mimeType\" in contentPart && typeof contentPart.mimeType === \"string\"\n ? contentPart.mimeType\n : \"application/pdf\";\n const data =\n typeof contentPart.data === \"string\"\n ? contentPart.data\n : Buffer.from(contentPart.data).toString(\"base64\");\n\n source = {\n type: \"base64\" as const,\n media_type,\n data,\n };\n } else if (\n \"fileId\" in contentPart &&\n typeof contentPart.fileId === \"string\"\n ) {\n // File ID from Anthropic Files API\n // https://platform.claude.com/docs/en/build-with-claude/pdf-support#option-3-files-api\n source = {\n type: \"file\" as const,\n file_id: contentPart.fileId,\n };\n }\n\n if (source) {\n yield {\n type: \"document\" as const,\n source,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n } as Anthropic.Messages.DocumentBlockParam;\n }\n } else if (contentPart.type === \"document\") {\n // PDF\n yield {\n ...contentPart,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n } as Anthropic.Messages.DocumentBlockParam;\n } else if (_isAnthropicThinkingBlock(contentPart)) {\n const block: AnthropicThinkingBlockParam = {\n type: \"thinking\" as const, // Explicitly setting the type as \"thinking\"\n thinking: contentPart.thinking,\n signature: contentPart.signature,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n };\n yield block;\n } else if (_isAnthropicRedactedThinkingBlock(contentPart)) {\n const block: AnthropicRedactedThinkingBlockParam = {\n type: \"redacted_thinking\" as const, // Explicitly setting the type as \"redacted_thinking\"\n data: contentPart.data,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n };\n yield block;\n } else if (_isAnthropicCompactionBlock(contentPart)) {\n const block: AnthropicCompactionBlockParam = {\n type: \"compaction\" as const,\n content: contentPart.content,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n };\n yield block;\n } else if (_isAnthropicSearchResultBlock(contentPart)) {\n const block: AnthropicSearchResultBlockParam = {\n type: \"search_result\" as const, // Explicitly setting the type as \"search_result\"\n title: contentPart.title,\n source: contentPart.source,\n ...(\"cache_control\" in contentPart && contentPart.cache_control\n ? { cache_control: contentPart.cache_control }\n : {}),\n ...(\"citations\" in contentPart && contentPart.citations\n ? { citations: contentPart.citations }\n : {}),\n content: contentPart.content,\n };\n yield block as Anthropic.Beta.BetaSearchResultBlockParam;\n } else if (\n textTypes.find((t) => t === contentPart.type) &&\n \"text\" in contentPart\n ) {\n // Assuming contentPart is of type MessageContentText here\n yield {\n type: \"text\" as const, // Explicitly setting the type as \"text\"\n text: contentPart.text,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n ...(\"citations\" in contentPart && contentPart.citations\n ? { citations: contentPart.citations }\n : {}),\n } as Anthropic.Messages.TextBlockParam;\n } else if (toolTypes.find((t) => t === contentPart.type)) {\n const contentPartCopy = { ...contentPart };\n\n if (contentPartCopy.type === \"input_json_delta\") {\n // `input_json_delta` type only represents yielding partial tool inputs\n // and is not a valid type for Anthropic messages.\n // These blocks appear in streaming responses and should be skipped\n // as their input data is already captured in tool_calls.\n continue;\n }\n\n if (\n contentPartCopy.type === \"tool_use\" &&\n typeof contentPartCopy.input === \"string\"\n ) {\n // First, try to get the input from the corresponding tool_call.\n // This is the most reliable source since tool_calls are properly\n // consolidated from tool_call_chunks during streaming.\n const matchingToolCall = toolCalls?.find(\n (tc) => tc.id === contentPartCopy.id\n );\n if (matchingToolCall) {\n contentPartCopy.input = matchingToolCall.args;\n } else {\n // Fallback: `tool_use` content part may be followed by `input_json_delta`\n // content parts which are chunks of a stringified JSON input,\n // so we need to collect them and merge their inputs.\n const inputDeltas = content.filter(\n (nestedContentPart) =>\n nestedContentPart.index === contentPartCopy.index &&\n nestedContentPart.type === \"input_json_delta\" &&\n typeof nestedContentPart.input === \"string\"\n );\n // If no `input_json_delta` parts are found, this line will just\n // return `contentPartCopy.input`, so no additional check is needed\n contentPartCopy.input = inputDeltas.reduce(\n (accumulator, nestedContentPart) =>\n accumulator + nestedContentPart.input,\n contentPartCopy.input\n );\n }\n }\n\n if (\"index\" in contentPartCopy) {\n // Anthropic does not support passing the index field here, so we remove it.\n delete contentPartCopy.index;\n }\n\n if (\"input\" in contentPartCopy) {\n // Anthropic tool use inputs should be valid objects, when applicable.\n if (typeof contentPartCopy.input === \"string\") {\n try {\n contentPartCopy.input = JSON.parse(contentPartCopy.input);\n } catch {\n contentPartCopy.input = {};\n }\n }\n }\n // TODO: Fix when SDK types are fixed\n yield {\n ...contentPartCopy,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n } as any;\n } else if (contentPart.type === \"container_upload\") {\n yield {\n ...contentPart,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n } as AnthropicContainerUploadBlockParam;\n }\n\n // Note that we are intentionally dropping any blocks that we don't\n // recognize. This is to allow for cross-compatibility between different\n // providers that may have different block types. Ie if we take a message\n // output from OpenAI and send it to Anthropic, we want to drop any blocks\n // that Anthropic doesn't understand.\n }\n}\n\nfunction _formatContent(message: BaseMessage, toolCalls?: ToolCall[]) {\n const { content } = message;\n\n if (typeof content === \"string\") {\n return content;\n } else {\n return Array.from(_formatContentBlocks(content, toolCalls));\n }\n}\n\ntype AnthropicToolChangeBlockParam =\n | Anthropic.Beta.BetaRequestToolAdditionBlock\n | Anthropic.Beta.BetaRequestToolRemovalBlock;\n\ntype AnthropicSystemContentBlockParam =\n | Anthropic.Messages.ContentBlockParam\n | AnthropicToolChangeBlockParam;\n\nconst TOOL_CHANGE_BLOCK_TYPES = [\"tool_addition\", \"tool_removal\"];\n\n/**\n * Returns the provider payload a block carries: the `value` of a\n * `non_standard` wrapper, or the block itself.\n */\nfunction _unwrapNonStandard(\n block: MessageContentComplex\n): MessageContentComplex {\n if (\n block.type === \"non_standard\" &&\n \"value\" in block &&\n typeof block.value === \"object\" &&\n block.value !== null\n ) {\n return block.value as MessageContentComplex;\n }\n return block;\n}\n\n/**\n * Normalizes the content of a system message for the wire.\n *\n * Shared by the hoisted top-level `system` field and by in-place\n * `role: \"system\"` entries, so both strip the same framework-internal fields.\n *\n * Blocks wrapped in core's `non_standard` escape hatch are unwrapped first, so\n * a provider-native block behaves the same whichever way it was written.\n */\nfunction _formatSystemContent(\n content: BaseMessage[\"content\"]\n): string | AnthropicSystemContentBlockParam[] {\n if (typeof content === \"string\") {\n return content;\n }\n if (!Array.isArray(content)) {\n // rare case: message.content could be undefined\n return [];\n }\n return content.flatMap((rawBlock): AnthropicSystemContentBlockParam[] => {\n if (typeof rawBlock !== \"object\" || rawBlock === null) {\n return [{ type: \"text\" as const, text: String(rawBlock) }];\n }\n const block = _unwrapNonStandard(rawBlock);\n if (TOOL_CHANGE_BLOCK_TYPES.includes(block.type as string)) {\n return [block as AnthropicToolChangeBlockParam];\n }\n if (block.type === \"text\" && typeof block.text === \"string\") {\n return [\n {\n type: \"text\" as const,\n text: block.text,\n ...(\"cache_control\" in block && block.cache_control\n ? {\n cache_control:\n block.cache_control as AnthropicTextBlockParam[\"cache_control\"],\n }\n : {}),\n ...(\"citations\" in block && block.citations\n ? {\n citations:\n block.citations as AnthropicTextBlockParam[\"citations\"],\n }\n : {}),\n },\n ];\n }\n // Anthropic accepts a closed set of system content blocks, and rejects\n // the whole request for anything else.\n // Consider warning about the dropped block once we have a proper logging solution\n return [];\n });\n}\n\n/**\n * Formats messages as a prompt for the model.\n * Used in LangSmith, export is important here.\n * @param messages The base messages to format as a prompt.\n * @returns The formatted prompt.\n */\nexport function _convertMessagesToAnthropicPayload(\n messages: BaseMessage[]\n): AnthropicMessageCreateParams {\n const mergedMessages = _ensureMessageContents(messages);\n\n // The contiguous run of system messages starting at index 0 is hoisted into\n // the top-level `system` field. Every other system message keeps its\n // position and is sent as a `role: \"system\"` entry, which the provider\n // applies from that point in the conversation onwards. The run is identified\n // after tool-message folding, because that is the sequence the provider sees.\n let leadingSystemCount = 0;\n while (\n leadingSystemCount < mergedMessages.length &&\n mergedMessages[leadingSystemCount]._getType() === \"system\"\n ) {\n leadingSystemCount += 1;\n }\n\n let system: string | AnthropicSystemContentBlockParam[] | undefined;\n if (leadingSystemCount === 1) {\n system = _formatSystemContent(mergedMessages[0].content);\n } else if (leadingSystemCount > 1) {\n system = mergedMessages.slice(0, leadingSystemCount).flatMap((message) => {\n const content = _formatSystemContent(message.content);\n return typeof content === \"string\"\n ? [{ type: \"text\" as const, text: content }]\n : content;\n });\n }\n // The provider rejects empty system content, so system content that narrowed\n // to nothing is omitted rather than sent.\n if (Array.isArray(system) && system.length === 0) {\n system = undefined;\n }\n\n const conversationMessages = mergedMessages.slice(leadingSystemCount);\n const formattedMessages = conversationMessages.map((message) => {\n let role;\n if (message._getType() === \"human\") {\n role = \"user\" as const;\n } else if (message._getType() === \"ai\") {\n role = \"assistant\" as const;\n } else if (message._getType() === \"tool\") {\n role = \"user\" as const;\n } else if (message._getType() === \"system\") {\n role = \"system\" as const;\n } else {\n throw new Error(`Message type \"${message.type}\" is not supported.`);\n }\n if (\n AIMessage.isInstance(message) &&\n message.response_metadata?.output_version === \"v1\"\n ) {\n return {\n role,\n content: _formatStandardContent(message),\n };\n }\n if (AIMessage.isInstance(message) && !!message.tool_calls?.length) {\n if (typeof message.content === \"string\") {\n if (message.content === \"\") {\n return {\n role,\n content: message.tool_calls.map(\n _convertLangChainToolCallToAnthropic\n ),\n };\n } else {\n return {\n role,\n content: [\n { type: \"text\", text: message.content },\n ...message.tool_calls.map(_convertLangChainToolCallToAnthropic),\n ],\n };\n }\n } else {\n const { content } = message;\n const formattedContent = _formatContent(message, message.tool_calls);\n const formattedContentArr = Array.isArray(formattedContent)\n ? formattedContent\n : [{ type: \"text\" as const, text: formattedContent }];\n const missingToolCalls = message.tool_calls.filter(\n (toolCall) =>\n !content.find(\n (contentPart) =>\n (contentPart.type === \"tool_use\" ||\n contentPart.type === \"input_json_delta\" ||\n contentPart.type === \"server_tool_use\") &&\n contentPart.id === toolCall.id\n )\n );\n return {\n role,\n content: [\n ...formattedContentArr,\n ...missingToolCalls.map(_convertLangChainToolCallToAnthropic),\n ],\n };\n }\n } else if (role === \"system\") {\n const content = _formatSystemContent(message.content);\n return Array.isArray(content) && content.length === 0\n ? undefined\n : { role, content };\n } else {\n return {\n role,\n content: _formatContent(\n message,\n AIMessage.isInstance(message) ? message.tool_calls : undefined\n ),\n };\n }\n });\n return {\n messages: mergeMessages(\n formattedMessages.filter(\n (message) => message !== undefined\n ) as AnthropicMessageCreateParams[\"messages\"]\n ),\n system,\n } as AnthropicMessageCreateParams;\n}\n\n/**\n * Describes the tool changes in the system content of a converted payload:\n * `\"inline\"` if any `tool_addition` block defines a tool by value,\n * `\"reference\"` if tool changes only name tools declared elsewhere, or\n * `undefined` if there are none. The provider requires a different beta for\n * each.\n *\n * Reads the converted payload rather than the input messages, so a block that\n * was dropped during conversion never enables a beta.\n */\nexport function _getToolChangeKind(\n payload: AnthropicMessageCreateParams\n): \"inline\" | \"reference\" | undefined {\n const systemContents: unknown[] = [\n payload.system,\n ...payload.messages\n .filter((message) => message.role === \"system\")\n .map((message) => message.content),\n ];\n const toolChanges = systemContents.flatMap((content) =>\n Array.isArray(content)\n ? content.filter((block) => TOOL_CHANGE_BLOCK_TYPES.includes(block.type))\n : []\n );\n if (toolChanges.some((block) => block.tool?.type === \"tool_definition\")) {\n return \"inline\";\n }\n return toolChanges.length > 0 ? \"reference\" : undefined;\n}\n\nfunction mergeMessages(messages: AnthropicMessageCreateParams[\"messages\"]) {\n if (!messages || messages.length <= 1) {\n return messages;\n }\n\n const result: AnthropicMessageCreateParams[\"messages\"] = [];\n let currentMessage = messages[0];\n\n const normalizeContent = (\n content: string | Array<Anthropic.Messages.ContentBlockParam>\n ): Array<Anthropic.Messages.ContentBlockParam> => {\n if (typeof content === \"string\") {\n return [\n {\n type: \"text\",\n text: content,\n },\n ];\n }\n return content;\n };\n\n const isToolResultMessage = (msg: (typeof messages)[0]) => {\n if (msg.role !== \"user\") return false;\n\n if (typeof msg.content === \"string\") {\n return false;\n }\n\n return (\n Array.isArray(msg.content) &&\n msg.content.every((item) => item.type === \"tool_result\")\n );\n };\n\n for (let i = 1; i < messages.length; i += 1) {\n const nextMessage = messages[i];\n\n if (\n isToolResultMessage(currentMessage) &&\n isToolResultMessage(nextMessage)\n ) {\n // Merge the messages by combining their content arrays\n currentMessage = {\n ...currentMessage,\n content: [\n ...normalizeContent(currentMessage.content),\n ...normalizeContent(nextMessage.content),\n ],\n };\n } else {\n result.push(currentMessage);\n currentMessage = nextMessage;\n }\n }\n\n result.push(currentMessage);\n return result;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"message_inputs.js","names":[],"sources":["../../src/utils/message_inputs.ts"],"sourcesContent":["/**\n * This util file contains functions for converting LangChain messages to Anthropic messages.\n */\nimport type Anthropic from \"@anthropic-ai/sdk\";\nimport {\n type BaseMessage,\n HumanMessage,\n ToolMessage,\n MessageContentComplex,\n isDataContentBlock,\n convertToProviderContentBlock,\n parseBase64DataUrl,\n ContentBlock,\n AIMessage,\n} from \"@langchain/core/messages\";\nimport { ToolCall } from \"@langchain/core/messages/tool\";\nimport {\n AnthropicMessageCreateParams,\n AnthropicTextBlockParam,\n AnthropicThinkingBlockParam,\n AnthropicRedactedThinkingBlockParam,\n AnthropicSearchResultBlockParam,\n AnthropicToolResponse,\n AnthropicContainerUploadBlockParam,\n AnthropicCompactionBlockParam,\n} from \"../types.js\";\nimport {\n _isAnthropicImageBlockParam,\n _isAnthropicRedactedThinkingBlock,\n _isAnthropicSearchResultBlock,\n _isAnthropicThinkingBlock,\n _isAnthropicCompactionBlock,\n standardContentBlockConverter,\n} from \"./content.js\";\nimport { _formatStandardContent } from \"./standard.js\";\n\nfunction _formatImage(imageUrl: string) {\n const parsed = parseBase64DataUrl({ dataUrl: imageUrl });\n if (parsed) {\n return {\n type: \"base64\",\n media_type: parsed.mime_type,\n data: parsed.data,\n };\n }\n let parsedUrl: URL;\n\n try {\n parsedUrl = new URL(imageUrl);\n } catch {\n throw new Error(\n [\n `Malformed image URL: ${JSON.stringify(\n imageUrl\n )}. Content blocks of type 'image_url' must be a valid http, https, or base64-encoded data URL.`,\n \"Example: data:image/png;base64,/9j/4AAQSk...\",\n \"Example: https://example.com/image.jpg\",\n ].join(\"\\n\\n\")\n );\n }\n\n if (parsedUrl.protocol === \"http:\" || parsedUrl.protocol === \"https:\") {\n return {\n type: \"url\",\n url: imageUrl,\n };\n }\n\n throw new Error(\n [\n `Invalid image URL protocol: ${JSON.stringify(\n parsedUrl.protocol\n )}. Anthropic only supports images as http, https, or base64-encoded data URLs on 'image_url' content blocks.`,\n \"Example: data:image/png;base64,/9j/4AAQSk...\",\n \"Example: https://example.com/image.jpg\",\n ].join(\"\\n\\n\")\n );\n}\n\nfunction _ensureMessageContents(messages: BaseMessage[]): BaseMessage[] {\n // Merge runs of human/tool messages into single human messages with content blocks.\n const updatedMsgs = [];\n for (const message of messages) {\n if (message._getType() === \"tool\") {\n if (typeof message.content === \"string\") {\n const previousMessage = updatedMsgs[updatedMsgs.length - 1];\n if (\n previousMessage?._getType() === \"human\" &&\n Array.isArray(previousMessage.content) &&\n \"type\" in previousMessage.content[0] &&\n previousMessage.content[0].type === \"tool_result\"\n ) {\n // If the previous message was a tool result, we merge this tool message into it.\n (previousMessage.content as MessageContentComplex[]).push({\n type: \"tool_result\",\n content: message.content,\n tool_use_id: (message as ToolMessage).tool_call_id,\n });\n } else {\n // If not, we create a new human message with the tool result.\n updatedMsgs.push(\n new HumanMessage({\n content: [\n {\n type: \"tool_result\",\n content: message.content,\n tool_use_id: (message as ToolMessage).tool_call_id,\n },\n ],\n })\n );\n }\n } else {\n updatedMsgs.push(\n new HumanMessage({\n content: [\n {\n type: \"tool_result\",\n // rare case: message.content could be undefined\n ...(message.content != null\n ? { content: _formatContent(message) }\n : {}),\n tool_use_id: (message as ToolMessage).tool_call_id,\n },\n ],\n })\n );\n }\n } else {\n updatedMsgs.push(message);\n }\n }\n return updatedMsgs;\n}\n\nexport function _convertLangChainToolCallToAnthropic(\n toolCall: ToolCall\n): AnthropicToolResponse {\n if (toolCall.id === undefined) {\n throw new Error(`Anthropic requires all tool calls to have an \"id\".`);\n }\n return {\n type: \"tool_use\",\n id: toolCall.id,\n name: toolCall.name,\n input: toolCall.args,\n };\n}\n\nfunction* _formatContentBlocks(\n content: ContentBlock[],\n toolCalls?: ToolCall[]\n): Generator<Anthropic.Beta.BetaContentBlockParam> {\n const toolTypes = [\n \"bash_code_execution_tool_result\",\n \"input_json_delta\",\n \"server_tool_use\",\n \"text_editor_code_execution_tool_result\",\n \"tool_result\",\n \"tool_search_tool_result\",\n \"tool_search_tool_bm25_tool_result\",\n \"tool_search_tool_regex_tool_result\",\n \"tool_use\",\n \"web_search_result\",\n \"web_search_tool_result\",\n ];\n const textTypes = [\"text\", \"text_delta\"];\n for (const contentPart of content) {\n if (isDataContentBlock(contentPart)) {\n yield convertToProviderContentBlock(\n contentPart,\n standardContentBlockConverter\n );\n }\n\n const cacheControl =\n \"cache_control\" in contentPart\n ? (contentPart.cache_control as Anthropic.Beta.BetaCacheControlEphemeral)\n : undefined;\n\n if (contentPart.type === \"image_url\") {\n let source;\n if (typeof contentPart.image_url === \"string\") {\n source = _formatImage(contentPart.image_url);\n } else if (\n typeof contentPart.image_url === \"object\" &&\n contentPart.image_url !== null &&\n \"url\" in contentPart.image_url &&\n typeof contentPart.image_url.url === \"string\"\n ) {\n source = _formatImage(contentPart.image_url.url);\n }\n if (source) {\n yield {\n type: \"image\" as const, // Explicitly setting the type as \"image\"\n source,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n } as Anthropic.Messages.ImageBlockParam;\n }\n } else if (_isAnthropicImageBlockParam(contentPart)) {\n yield contentPart;\n } else if (contentPart.type === \"image\") {\n // Handle new ContentBlock.Multimodal.Image format\n let source;\n\n if (\"url\" in contentPart && typeof contentPart.url === \"string\") {\n // URL-based image\n source = _formatImage(contentPart.url);\n } else if (\n \"data\" in contentPart &&\n (typeof contentPart.data === \"string\" ||\n // oxlint-disable-next-line no-instanceof/no-instanceof\n contentPart.data instanceof Uint8Array)\n ) {\n // Base64-based image\n const mimeType =\n \"mimeType\" in contentPart && typeof contentPart.mimeType === \"string\"\n ? contentPart.mimeType\n : \"image/jpeg\";\n const data =\n typeof contentPart.data === \"string\"\n ? contentPart.data\n : Buffer.from(contentPart.data).toString(\"base64\");\n source = {\n type: \"base64\" as const,\n media_type: mimeType as\n | \"image/jpeg\"\n | \"image/png\"\n | \"image/gif\"\n | \"image/webp\",\n data,\n };\n } else if (\n \"fileId\" in contentPart &&\n typeof contentPart.fileId === \"string\"\n ) {\n // File ID-based image\n // Note: Anthropic supports file IDs for images that have been uploaded\n // to their servers via the Files API\n source = {\n type: \"file\" as const,\n file_id: contentPart.fileId,\n };\n }\n\n if (source) {\n yield {\n type: \"image\" as const,\n source,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n } as Anthropic.Messages.ImageBlockParam;\n }\n } else if (contentPart.type === \"file\") {\n // Handle new ContentBlock.Multimodal.File format\n let source:\n | { type: \"url\"; url: string }\n | { type: \"base64\"; media_type: string; data: string }\n | { type: \"file\"; file_id: string }\n | undefined;\n\n if (\"url\" in contentPart && typeof contentPart.url === \"string\") {\n // File with URL\n source = {\n type: \"url\" as const,\n url: contentPart.url,\n };\n } else if (\n \"data\" in contentPart &&\n (typeof contentPart.data === \"string\" ||\n // oxlint-disable-next-line no-instanceof/no-instanceof\n contentPart.data instanceof Uint8Array)\n ) {\n // File with base64 data (string or Uint8Array)\n const media_type =\n \"mimeType\" in contentPart && typeof contentPart.mimeType === \"string\"\n ? contentPart.mimeType\n : \"application/pdf\";\n const data =\n typeof contentPart.data === \"string\"\n ? contentPart.data\n : Buffer.from(contentPart.data).toString(\"base64\");\n\n source = {\n type: \"base64\" as const,\n media_type,\n data,\n };\n } else if (\n \"fileId\" in contentPart &&\n typeof contentPart.fileId === \"string\"\n ) {\n // File ID from Anthropic Files API\n // https://platform.claude.com/docs/en/build-with-claude/pdf-support#option-3-files-api\n source = {\n type: \"file\" as const,\n file_id: contentPart.fileId,\n };\n }\n\n if (source) {\n yield {\n type: \"document\" as const,\n source,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n } as Anthropic.Messages.DocumentBlockParam;\n }\n } else if (contentPart.type === \"document\") {\n // PDF\n yield {\n ...contentPart,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n } as Anthropic.Messages.DocumentBlockParam;\n } else if (_isAnthropicThinkingBlock(contentPart)) {\n const block: AnthropicThinkingBlockParam = {\n type: \"thinking\" as const, // Explicitly setting the type as \"thinking\"\n thinking: contentPart.thinking,\n signature: contentPart.signature,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n };\n yield block;\n } else if (_isAnthropicRedactedThinkingBlock(contentPart)) {\n const block: AnthropicRedactedThinkingBlockParam = {\n type: \"redacted_thinking\" as const, // Explicitly setting the type as \"redacted_thinking\"\n data: contentPart.data,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n };\n yield block;\n } else if (_isAnthropicCompactionBlock(contentPart)) {\n const block: AnthropicCompactionBlockParam = {\n type: \"compaction\" as const,\n content: contentPart.content,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n };\n yield block;\n } else if (_isAnthropicSearchResultBlock(contentPart)) {\n const block: AnthropicSearchResultBlockParam = {\n type: \"search_result\" as const, // Explicitly setting the type as \"search_result\"\n title: contentPart.title,\n source: contentPart.source,\n ...(\"cache_control\" in contentPart && contentPart.cache_control\n ? { cache_control: contentPart.cache_control }\n : {}),\n ...(\"citations\" in contentPart && contentPart.citations\n ? { citations: contentPart.citations }\n : {}),\n content: contentPart.content,\n };\n yield block as Anthropic.Beta.BetaSearchResultBlockParam;\n } else if (\n textTypes.find((t) => t === contentPart.type) &&\n \"text\" in contentPart\n ) {\n // Assuming contentPart is of type MessageContentText here\n yield {\n type: \"text\" as const, // Explicitly setting the type as \"text\"\n text: contentPart.text,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n ...(\"citations\" in contentPart && contentPart.citations\n ? { citations: contentPart.citations }\n : {}),\n } as Anthropic.Messages.TextBlockParam;\n } else if (toolTypes.find((t) => t === contentPart.type)) {\n const contentPartCopy = { ...contentPart };\n\n if (contentPartCopy.type === \"input_json_delta\") {\n // `input_json_delta` type only represents yielding partial tool inputs\n // and is not a valid type for Anthropic messages.\n // These blocks appear in streaming responses and should be skipped\n // as their input data is already captured in tool_calls.\n continue;\n }\n\n if (\n (contentPartCopy.type === \"tool_use\" ||\n contentPartCopy.type === \"server_tool_use\") &&\n typeof contentPartCopy.input === \"string\"\n ) {\n // First, try to get the input from the corresponding tool_call.\n // This is the most reliable source since tool_calls are properly\n // consolidated from tool_call_chunks during streaming.\n // `server_tool_use` blocks have no tool_call, so they always take\n // the fallback below.\n const matchingToolCall = toolCalls?.find(\n (tc) => tc.id === contentPartCopy.id\n );\n if (matchingToolCall) {\n contentPartCopy.input = matchingToolCall.args;\n } else {\n // Fallback: `tool_use` and `server_tool_use` content parts may be\n // followed by `input_json_delta` content parts which are chunks of\n // a stringified JSON input, so we need to collect them and merge\n // their inputs.\n const inputDeltas = content.filter(\n (nestedContentPart) =>\n nestedContentPart.index === contentPartCopy.index &&\n nestedContentPart.type === \"input_json_delta\" &&\n typeof nestedContentPart.input === \"string\"\n );\n // If no `input_json_delta` parts are found, this line will just\n // return `contentPartCopy.input`, so no additional check is needed\n contentPartCopy.input = inputDeltas.reduce(\n (accumulator, nestedContentPart) =>\n accumulator + nestedContentPart.input,\n contentPartCopy.input\n );\n }\n }\n\n if (\"index\" in contentPartCopy) {\n // Anthropic does not support passing the index field here, so we remove it.\n delete contentPartCopy.index;\n }\n\n if (\"input\" in contentPartCopy) {\n // Anthropic tool use inputs should be valid objects, when applicable.\n if (typeof contentPartCopy.input === \"string\") {\n try {\n contentPartCopy.input = JSON.parse(contentPartCopy.input);\n } catch {\n contentPartCopy.input = {};\n }\n }\n }\n // TODO: Fix when SDK types are fixed\n yield {\n ...contentPartCopy,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n } as any;\n } else if (contentPart.type === \"container_upload\") {\n yield {\n ...contentPart,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n } as AnthropicContainerUploadBlockParam;\n }\n\n // Note that we are intentionally dropping any blocks that we don't\n // recognize. This is to allow for cross-compatibility between different\n // providers that may have different block types. Ie if we take a message\n // output from OpenAI and send it to Anthropic, we want to drop any blocks\n // that Anthropic doesn't understand.\n }\n}\n\nfunction _formatContent(message: BaseMessage, toolCalls?: ToolCall[]) {\n const { content } = message;\n\n if (typeof content === \"string\") {\n return content;\n } else {\n return Array.from(_formatContentBlocks(content, toolCalls));\n }\n}\n\ntype AnthropicToolChangeBlockParam =\n | Anthropic.Beta.BetaRequestToolAdditionBlock\n | Anthropic.Beta.BetaRequestToolRemovalBlock;\n\ntype AnthropicSystemContentBlockParam =\n | Anthropic.Messages.ContentBlockParam\n | AnthropicToolChangeBlockParam;\n\nconst TOOL_CHANGE_BLOCK_TYPES = [\"tool_addition\", \"tool_removal\"];\n\n/**\n * Returns the provider payload a block carries: the `value` of a\n * `non_standard` wrapper, or the block itself.\n */\nfunction _unwrapNonStandard(\n block: MessageContentComplex\n): MessageContentComplex {\n if (\n block.type === \"non_standard\" &&\n \"value\" in block &&\n typeof block.value === \"object\" &&\n block.value !== null\n ) {\n return block.value as MessageContentComplex;\n }\n return block;\n}\n\n/**\n * Normalizes the content of a system message for the wire.\n *\n * Shared by the hoisted top-level `system` field and by in-place\n * `role: \"system\"` entries, so both strip the same framework-internal fields.\n *\n * Blocks wrapped in core's `non_standard` escape hatch are unwrapped first, so\n * a provider-native block behaves the same whichever way it was written.\n */\nfunction _formatSystemContent(\n content: BaseMessage[\"content\"]\n): string | AnthropicSystemContentBlockParam[] {\n if (typeof content === \"string\") {\n return content;\n }\n if (!Array.isArray(content)) {\n // rare case: message.content could be undefined\n return [];\n }\n return content.flatMap((rawBlock): AnthropicSystemContentBlockParam[] => {\n if (typeof rawBlock !== \"object\" || rawBlock === null) {\n return [{ type: \"text\" as const, text: String(rawBlock) }];\n }\n const block = _unwrapNonStandard(rawBlock);\n if (TOOL_CHANGE_BLOCK_TYPES.includes(block.type as string)) {\n return [block as AnthropicToolChangeBlockParam];\n }\n if (block.type === \"text\" && typeof block.text === \"string\") {\n return [\n {\n type: \"text\" as const,\n text: block.text,\n ...(\"cache_control\" in block && block.cache_control\n ? {\n cache_control:\n block.cache_control as AnthropicTextBlockParam[\"cache_control\"],\n }\n : {}),\n ...(\"citations\" in block && block.citations\n ? {\n citations:\n block.citations as AnthropicTextBlockParam[\"citations\"],\n }\n : {}),\n },\n ];\n }\n // Anthropic accepts a closed set of system content blocks, and rejects\n // the whole request for anything else.\n // Consider warning about the dropped block once we have a proper logging solution\n return [];\n });\n}\n\n/**\n * Formats messages as a prompt for the model.\n * Used in LangSmith, export is important here.\n * @param messages The base messages to format as a prompt.\n * @returns The formatted prompt.\n */\nexport function _convertMessagesToAnthropicPayload(\n messages: BaseMessage[]\n): AnthropicMessageCreateParams {\n const mergedMessages = _ensureMessageContents(messages);\n\n // The contiguous run of system messages starting at index 0 is hoisted into\n // the top-level `system` field. Every other system message keeps its\n // position and is sent as a `role: \"system\"` entry, which the provider\n // applies from that point in the conversation onwards. The run is identified\n // after tool-message folding, because that is the sequence the provider sees.\n let leadingSystemCount = 0;\n while (\n leadingSystemCount < mergedMessages.length &&\n mergedMessages[leadingSystemCount]._getType() === \"system\"\n ) {\n leadingSystemCount += 1;\n }\n\n let system: string | AnthropicSystemContentBlockParam[] | undefined;\n if (leadingSystemCount === 1) {\n system = _formatSystemContent(mergedMessages[0].content);\n } else if (leadingSystemCount > 1) {\n system = mergedMessages.slice(0, leadingSystemCount).flatMap((message) => {\n const content = _formatSystemContent(message.content);\n return typeof content === \"string\"\n ? [{ type: \"text\" as const, text: content }]\n : content;\n });\n }\n // The provider rejects empty system content, so system content that narrowed\n // to nothing is omitted rather than sent.\n if (Array.isArray(system) && system.length === 0) {\n system = undefined;\n }\n\n const conversationMessages = mergedMessages.slice(leadingSystemCount);\n const formattedMessages = conversationMessages.map((message) => {\n let role;\n if (message._getType() === \"human\") {\n role = \"user\" as const;\n } else if (message._getType() === \"ai\") {\n role = \"assistant\" as const;\n } else if (message._getType() === \"tool\") {\n role = \"user\" as const;\n } else if (message._getType() === \"system\") {\n role = \"system\" as const;\n } else {\n throw new Error(`Message type \"${message.type}\" is not supported.`);\n }\n if (\n AIMessage.isInstance(message) &&\n message.response_metadata?.output_version === \"v1\"\n ) {\n return {\n role,\n content: _formatStandardContent(message),\n };\n }\n if (AIMessage.isInstance(message) && !!message.tool_calls?.length) {\n if (typeof message.content === \"string\") {\n if (message.content === \"\") {\n return {\n role,\n content: message.tool_calls.map(\n _convertLangChainToolCallToAnthropic\n ),\n };\n } else {\n return {\n role,\n content: [\n { type: \"text\", text: message.content },\n ...message.tool_calls.map(_convertLangChainToolCallToAnthropic),\n ],\n };\n }\n } else {\n const { content } = message;\n const formattedContent = _formatContent(message, message.tool_calls);\n const formattedContentArr = Array.isArray(formattedContent)\n ? formattedContent\n : [{ type: \"text\" as const, text: formattedContent }];\n const missingToolCalls = message.tool_calls.filter(\n (toolCall) =>\n !content.find(\n (contentPart) =>\n (contentPart.type === \"tool_use\" ||\n contentPart.type === \"input_json_delta\" ||\n contentPart.type === \"server_tool_use\") &&\n contentPart.id === toolCall.id\n )\n );\n return {\n role,\n content: [\n ...formattedContentArr,\n ...missingToolCalls.map(_convertLangChainToolCallToAnthropic),\n ],\n };\n }\n } else if (role === \"system\") {\n const content = _formatSystemContent(message.content);\n return Array.isArray(content) && content.length === 0\n ? undefined\n : { role, content };\n } else {\n return {\n role,\n content: _formatContent(\n message,\n AIMessage.isInstance(message) ? message.tool_calls : undefined\n ),\n };\n }\n });\n return {\n messages: mergeMessages(\n formattedMessages.filter(\n (message) => message !== undefined\n ) as AnthropicMessageCreateParams[\"messages\"]\n ),\n system,\n } as AnthropicMessageCreateParams;\n}\n\n/**\n * Describes the tool changes in the system content of a converted payload:\n * `\"inline\"` if any `tool_addition` block defines a tool by value,\n * `\"reference\"` if tool changes only name tools declared elsewhere, or\n * `undefined` if there are none. The provider requires a different beta for\n * each.\n *\n * Reads the converted payload rather than the input messages, so a block that\n * was dropped during conversion never enables a beta.\n */\nexport function _getToolChangeKind(\n payload: AnthropicMessageCreateParams\n): \"inline\" | \"reference\" | undefined {\n const systemContents: unknown[] = [\n payload.system,\n ...payload.messages\n .filter((message) => message.role === \"system\")\n .map((message) => message.content),\n ];\n const toolChanges = systemContents.flatMap((content) =>\n Array.isArray(content)\n ? content.filter((block) => TOOL_CHANGE_BLOCK_TYPES.includes(block.type))\n : []\n );\n if (toolChanges.some((block) => block.tool?.type === \"tool_definition\")) {\n return \"inline\";\n }\n return toolChanges.length > 0 ? \"reference\" : undefined;\n}\n\nfunction mergeMessages(messages: AnthropicMessageCreateParams[\"messages\"]) {\n if (!messages || messages.length <= 1) {\n return messages;\n }\n\n const result: AnthropicMessageCreateParams[\"messages\"] = [];\n let currentMessage = messages[0];\n\n const normalizeContent = (\n content: string | Array<Anthropic.Messages.ContentBlockParam>\n ): Array<Anthropic.Messages.ContentBlockParam> => {\n if (typeof content === \"string\") {\n return [\n {\n type: \"text\",\n text: content,\n },\n ];\n }\n return content;\n };\n\n const isToolResultMessage = (msg: (typeof messages)[0]) => {\n if (msg.role !== \"user\") return false;\n\n if (typeof msg.content === \"string\") {\n return false;\n }\n\n return (\n Array.isArray(msg.content) &&\n msg.content.every((item) => item.type === \"tool_result\")\n );\n };\n\n for (let i = 1; i < messages.length; i += 1) {\n const nextMessage = messages[i];\n\n if (\n isToolResultMessage(currentMessage) &&\n isToolResultMessage(nextMessage)\n ) {\n // Merge the messages by combining their content arrays\n currentMessage = {\n ...currentMessage,\n content: [\n ...normalizeContent(currentMessage.content),\n ...normalizeContent(nextMessage.content),\n ],\n };\n } else {\n result.push(currentMessage);\n currentMessage = nextMessage;\n }\n }\n\n result.push(currentMessage);\n return result;\n}\n"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ const require_output_parsers = require("../output_parsers.cjs");
|
|
|
2
2
|
const require_content = require("./content.cjs");
|
|
3
3
|
const require_index = require("./index.cjs");
|
|
4
4
|
let _langchain_core_messages = require("@langchain/core/messages");
|
|
5
|
-
|
|
5
|
+
// src/utils/message_outputs.ts
|
|
6
6
|
function _makeMessageChunkFromAnthropicEvent(data, fields) {
|
|
7
7
|
const response_metadata = { model_provider: "anthropic" };
|
|
8
8
|
if (data.type === "message_start") {
|
|
@@ -199,7 +199,6 @@ function buildUsageMetadata(usage) {
|
|
|
199
199
|
}
|
|
200
200
|
};
|
|
201
201
|
}
|
|
202
|
-
//#endregion
|
|
203
202
|
exports._makeMessageChunkFromAnthropicEvent = _makeMessageChunkFromAnthropicEvent;
|
|
204
203
|
exports.anthropicResponseToChatMessages = anthropicResponseToChatMessages;
|
|
205
204
|
|
|
@@ -2,7 +2,7 @@ import { extractToolCalls } from "../output_parsers.js";
|
|
|
2
2
|
import { _isAnthropicCompactionBlock } from "./content.js";
|
|
3
3
|
import { iife } from "./index.js";
|
|
4
4
|
import { AIMessage, AIMessageChunk } from "@langchain/core/messages";
|
|
5
|
-
|
|
5
|
+
// src/utils/message_outputs.ts
|
|
6
6
|
function _makeMessageChunkFromAnthropicEvent(data, fields) {
|
|
7
7
|
const response_metadata = { model_provider: "anthropic" };
|
|
8
8
|
if (data.type === "message_start") {
|
|
@@ -199,7 +199,6 @@ function buildUsageMetadata(usage) {
|
|
|
199
199
|
}
|
|
200
200
|
};
|
|
201
201
|
}
|
|
202
|
-
//#endregion
|
|
203
202
|
export { _makeMessageChunkFromAnthropicEvent, anthropicResponseToChatMessages };
|
|
204
203
|
|
|
205
204
|
//# sourceMappingURL=message_outputs.js.map
|
package/dist/utils/params.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// src/utils/params.ts
|
|
2
2
|
const ADAPTIVE_ONLY_MODEL_PREFIXES = [
|
|
3
3
|
"claude-opus-4-7",
|
|
4
4
|
"claude-opus-4-8",
|
|
@@ -54,7 +54,6 @@ function getSamplingParams(fields) {
|
|
|
54
54
|
if (topP !== void 0) output.top_p = topP;
|
|
55
55
|
return output;
|
|
56
56
|
}
|
|
57
|
-
//#endregion
|
|
58
57
|
exports.getSamplingParams = getSamplingParams;
|
|
59
58
|
exports.getTaskBudgetBetas = getTaskBudgetBetas;
|
|
60
59
|
exports.isAdaptiveOnlyModel = isAdaptiveOnlyModel;
|
package/dist/utils/params.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// src/utils/params.ts
|
|
2
2
|
const ADAPTIVE_ONLY_MODEL_PREFIXES = [
|
|
3
3
|
"claude-opus-4-7",
|
|
4
4
|
"claude-opus-4-8",
|
|
@@ -54,7 +54,6 @@ function getSamplingParams(fields) {
|
|
|
54
54
|
if (topP !== void 0) output.top_p = topP;
|
|
55
55
|
return output;
|
|
56
56
|
}
|
|
57
|
-
//#endregion
|
|
58
57
|
export { getSamplingParams, getTaskBudgetBetas, isAdaptiveOnlyModel, isOpus47Model, validateInvocationParamCompatibility };
|
|
59
58
|
|
|
60
59
|
//# sourceMappingURL=params.js.map
|
package/dist/utils/prompts.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_message_inputs = require("./message_inputs.cjs");
|
|
2
|
-
|
|
2
|
+
// src/utils/prompts.ts
|
|
3
3
|
/**
|
|
4
4
|
* Convert a formatted LangChain prompt (e.g. pulled from the hub) into
|
|
5
5
|
* a format expected by Anthropic's JS SDK.
|
|
@@ -42,7 +42,6 @@ function convertPromptToAnthropic(formattedPrompt) {
|
|
|
42
42
|
if (anthropicBody.messages === void 0) anthropicBody.messages = [];
|
|
43
43
|
return anthropicBody;
|
|
44
44
|
}
|
|
45
|
-
//#endregion
|
|
46
45
|
exports.convertPromptToAnthropic = convertPromptToAnthropic;
|
|
47
46
|
|
|
48
47
|
//# sourceMappingURL=prompts.cjs.map
|
package/dist/utils/prompts.d.cts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import Anthropic$1 from "@anthropic-ai/sdk";
|
|
2
2
|
import { BasePromptValue } from "@langchain/core/prompt_values";
|
|
3
|
-
//#region src/utils/prompts.d.ts
|
|
4
3
|
/**
|
|
5
4
|
* Convert a formatted LangChain prompt (e.g. pulled from the hub) into
|
|
6
5
|
* a format expected by Anthropic's JS SDK.
|
|
@@ -38,5 +37,4 @@ import { BasePromptValue } from "@langchain/core/prompt_values";
|
|
|
38
37
|
* @returns A partial Anthropic payload.
|
|
39
38
|
*/
|
|
40
39
|
export declare function convertPromptToAnthropic(formattedPrompt: BasePromptValue): Anthropic$1.Messages.MessageCreateParams;
|
|
41
|
-
//#endregion
|
|
42
40
|
//# sourceMappingURL=prompts.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.d.cts","names":["Anthropic"],"sources":["../../src/utils/prompts.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"prompts.d.cts","names":["Anthropic"],"sources":["../../src/utils/prompts.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAyCgB,yBACd,iBAAiB,kBAChBA,YAAU,SAAS"}
|
package/dist/utils/prompts.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import Anthropic$1 from "@anthropic-ai/sdk";
|
|
2
2
|
import { BasePromptValue } from "@langchain/core/prompt_values";
|
|
3
|
-
//#region src/utils/prompts.d.ts
|
|
4
3
|
/**
|
|
5
4
|
* Convert a formatted LangChain prompt (e.g. pulled from the hub) into
|
|
6
5
|
* a format expected by Anthropic's JS SDK.
|
|
@@ -38,5 +37,4 @@ import { BasePromptValue } from "@langchain/core/prompt_values";
|
|
|
38
37
|
* @returns A partial Anthropic payload.
|
|
39
38
|
*/
|
|
40
39
|
export declare function convertPromptToAnthropic(formattedPrompt: BasePromptValue): Anthropic$1.Messages.MessageCreateParams;
|
|
41
|
-
//#endregion
|
|
42
40
|
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.d.ts","names":["Anthropic"],"sources":["../../src/utils/prompts.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","names":["Anthropic"],"sources":["../../src/utils/prompts.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAyCgB,yBACd,iBAAiB,kBAChBA,YAAU,SAAS"}
|
package/dist/utils/prompts.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { _convertMessagesToAnthropicPayload } from "./message_inputs.js";
|
|
2
|
-
|
|
2
|
+
// src/utils/prompts.ts
|
|
3
3
|
/**
|
|
4
4
|
* Convert a formatted LangChain prompt (e.g. pulled from the hub) into
|
|
5
5
|
* a format expected by Anthropic's JS SDK.
|
|
@@ -42,7 +42,6 @@ function convertPromptToAnthropic(formattedPrompt) {
|
|
|
42
42
|
if (anthropicBody.messages === void 0) anthropicBody.messages = [];
|
|
43
43
|
return anthropicBody;
|
|
44
44
|
}
|
|
45
|
-
//#endregion
|
|
46
45
|
export { convertPromptToAnthropic };
|
|
47
46
|
|
|
48
47
|
//# sourceMappingURL=prompts.js.map
|
package/dist/utils/standard.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_index = require("./index.cjs");
|
|
2
|
-
|
|
2
|
+
// src/utils/standard.ts
|
|
3
3
|
function _isStandardAnnotation(annotation) {
|
|
4
4
|
return typeof annotation === "object" && annotation !== null && "type" in annotation && annotation.type === "citation";
|
|
5
5
|
}
|
|
@@ -277,7 +277,6 @@ function _formatStandardContent(message) {
|
|
|
277
277
|
} else if (block.type === "non_standard" && isAnthropicMessage) result.push(block.value);
|
|
278
278
|
return result;
|
|
279
279
|
}
|
|
280
|
-
//#endregion
|
|
281
280
|
exports._formatStandardContent = _formatStandardContent;
|
|
282
281
|
|
|
283
282
|
//# sourceMappingURL=standard.cjs.map
|
package/dist/utils/standard.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { iife } from "./index.js";
|
|
2
|
-
|
|
2
|
+
// src/utils/standard.ts
|
|
3
3
|
function _isStandardAnnotation(annotation) {
|
|
4
4
|
return typeof annotation === "object" && annotation !== null && "type" in annotation && annotation.type === "citation";
|
|
5
5
|
}
|
|
@@ -277,7 +277,6 @@ function _formatStandardContent(message) {
|
|
|
277
277
|
} else if (block.type === "non_standard" && isAnthropicMessage) result.push(block.value);
|
|
278
278
|
return result;
|
|
279
279
|
}
|
|
280
|
-
//#endregion
|
|
281
280
|
export { _formatStandardContent };
|
|
282
281
|
|
|
283
282
|
//# sourceMappingURL=standard.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// src/utils/stream_events.ts
|
|
2
2
|
/**
|
|
3
3
|
* Convert an async iterable of raw Anthropic stream events into
|
|
4
4
|
* LangChain `ChatModelStreamEvent`s with typed deltas.
|
|
@@ -312,7 +312,6 @@ function finalizeBlock(accumulated) {
|
|
|
312
312
|
const { index: _index, ...rest } = accumulated;
|
|
313
313
|
return rest;
|
|
314
314
|
}
|
|
315
|
-
//#endregion
|
|
316
315
|
exports.convertAnthropicStream = convertAnthropicStream;
|
|
317
316
|
|
|
318
317
|
//# sourceMappingURL=stream_events.cjs.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// src/utils/stream_events.ts
|
|
2
2
|
/**
|
|
3
3
|
* Convert an async iterable of raw Anthropic stream events into
|
|
4
4
|
* LangChain `ChatModelStreamEvent`s with typed deltas.
|
|
@@ -312,7 +312,6 @@ function finalizeBlock(accumulated) {
|
|
|
312
312
|
const { index: _index, ...rest } = accumulated;
|
|
313
313
|
return rest;
|
|
314
314
|
}
|
|
315
|
-
//#endregion
|
|
316
315
|
export { convertAnthropicStream };
|
|
317
316
|
|
|
318
317
|
//# sourceMappingURL=stream_events.js.map
|