@langchain/anthropic 1.5.10 → 1.5.11

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 CHANGED
@@ -1,5 +1,15 @@
1
1
  # @langchain/anthropic
2
2
 
3
+ ## 1.5.11
4
+
5
+ ### Patch Changes
6
+
7
+ - [#11669](https://github.com/langchain-ai/langchainjs/pull/11669) [`fb2a9f3`](https://github.com/langchain-ai/langchainjs/commit/fb2a9f378e752a2dddea4af14d9c33deb185f067) Thanks [@richardscarrott](https://github.com/richardscarrott)! - feat(anthropic): accept a `SystemMessage` anywhere in the message list. Previously only the first message could be a system message. Anything else threw.
8
+
9
+ A system message that isn't first is now sent at its own position. It applies from that point in the conversation onwards, and adding one leaves the prompt cache for the earlier turns intact.
10
+
11
+ Two smaller changes come with it. A leading run of two or more `SystemMessage`s now merges into the top-level `system` field instead of being rejected. System content built from standard content blocks no longer sends the internal block `id` to the provider.
12
+
3
13
  ## 1.5.10
4
14
 
5
15
  ### Patch Changes
@@ -665,7 +665,7 @@ var ChatAnthropicMessages = class extends _langchain_core_language_models_chat_m
665
665
  model: modelOrFields
666
666
  } : modelOrFields ?? {};
667
667
  super(fields ?? {});
668
- this._addVersion("@langchain/anthropic", "1.5.10");
668
+ this._addVersion("@langchain/anthropic", "1.5.11");
669
669
  const gatewayConfig = (0, _langchain_core_utils_gateway.resolveLangSmithGatewayConfig)({
670
670
  baseURL: fields.anthropicApiUrl ?? fields.clientOptions?.baseURL ?? ((0, _langchain_core_utils_env.getEnvironmentVariable)("ANTHROPIC_API_URL") || (0, _langchain_core_utils_env.getEnvironmentVariable)("ANTHROPIC_BASE_URL") || void 0),
671
671
  providerPath: "anthropic"
@@ -665,7 +665,7 @@ var ChatAnthropicMessages = class extends BaseChatModel {
665
665
  model: modelOrFields
666
666
  } : modelOrFields ?? {};
667
667
  super(fields ?? {});
668
- this._addVersion("@langchain/anthropic", "1.5.10");
668
+ this._addVersion("@langchain/anthropic", "1.5.11");
669
669
  const gatewayConfig = resolveLangSmithGatewayConfig({
670
670
  baseURL: fields.anthropicApiUrl ?? fields.clientOptions?.baseURL ?? (getEnvironmentVariable("ANTHROPIC_API_URL") || getEnvironmentVariable("ANTHROPIC_BASE_URL") || void 0),
671
671
  providerPath: "anthropic"
@@ -192,6 +192,25 @@ function _formatContent(message, toolCalls) {
192
192
  else return Array.from(_formatContentBlocks(content, toolCalls));
193
193
  }
194
194
  /**
195
+ * Normalizes the content of a system message for the wire.
196
+ *
197
+ * Shared by the hoisted top-level `system` field and by in-place
198
+ * `role: "system"` entries, so both strip the same framework-internal fields.
199
+ */
200
+ function _formatSystemContent(content) {
201
+ if (typeof content === "string") return content;
202
+ if (!Array.isArray(content)) return [];
203
+ return content.map((block) => {
204
+ if (block.type !== "text" || typeof block.text !== "string") return block;
205
+ return {
206
+ type: "text",
207
+ text: block.text,
208
+ ..."cache_control" in block && block.cache_control ? { cache_control: block.cache_control } : {},
209
+ ..."citations" in block && block.citations ? { citations: block.citations } : {}
210
+ };
211
+ });
212
+ }
213
+ /**
195
214
  * Formats messages as a prompt for the model.
196
215
  * Used in LangSmith, export is important here.
197
216
  * @param messages The base messages to format as a prompt.
@@ -199,15 +218,24 @@ function _formatContent(message, toolCalls) {
199
218
  */
200
219
  function _convertMessagesToAnthropicPayload(messages) {
201
220
  const mergedMessages = _ensureMessageContents(messages);
221
+ let leadingSystemCount = 0;
222
+ while (leadingSystemCount < mergedMessages.length && mergedMessages[leadingSystemCount]._getType() === "system") leadingSystemCount += 1;
202
223
  let system;
203
- if (mergedMessages.length > 0 && mergedMessages[0]._getType() === "system") system = messages[0].content;
224
+ if (leadingSystemCount === 1) system = _formatSystemContent(mergedMessages[0].content);
225
+ else if (leadingSystemCount > 1) system = mergedMessages.slice(0, leadingSystemCount).flatMap((message) => {
226
+ const content = _formatSystemContent(message.content);
227
+ return typeof content === "string" ? [{
228
+ type: "text",
229
+ text: content
230
+ }] : content;
231
+ });
204
232
  return {
205
- messages: mergeMessages((system !== void 0 ? mergedMessages.slice(1) : mergedMessages).map((message) => {
233
+ messages: mergeMessages(mergedMessages.slice(leadingSystemCount).map((message) => {
206
234
  let role;
207
235
  if (message._getType() === "human") role = "user";
208
236
  else if (message._getType() === "ai") role = "assistant";
209
237
  else if (message._getType() === "tool") role = "user";
210
- else if (message._getType() === "system") throw new Error("System messages are only permitted as the first passed message.");
238
+ else if (message._getType() === "system") role = "system";
211
239
  else throw new Error(`Message type "${message.type}" is not supported.`);
212
240
  if (_langchain_core_messages.AIMessage.isInstance(message) && message.response_metadata?.output_version === "v1") return {
213
241
  role,
@@ -239,7 +267,11 @@ function _convertMessagesToAnthropicPayload(messages) {
239
267
  content: [...formattedContentArr, ...missingToolCalls.map(_convertLangChainToolCallToAnthropic)]
240
268
  };
241
269
  }
242
- } else return {
270
+ } else if (role === "system") return {
271
+ role,
272
+ content: _formatSystemContent(message.content)
273
+ };
274
+ else return {
243
275
  role,
244
276
  content: _formatContent(message, _langchain_core_messages.AIMessage.isInstance(message) ? message.tool_calls : void 0)
245
277
  };
@@ -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 AnthropicImageBlockParam,\n AnthropicMessageCreateParams,\n AnthropicTextBlockParam,\n AnthropicToolResultBlockParam,\n AnthropicToolUseBlockParam,\n AnthropicDocumentBlockParam,\n AnthropicThinkingBlockParam,\n AnthropicRedactedThinkingBlockParam,\n AnthropicServerToolUseBlockParam,\n AnthropicWebSearchToolResultBlockParam,\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\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 let system;\n if (mergedMessages.length > 0 && mergedMessages[0]._getType() === \"system\") {\n system = messages[0].content;\n }\n const conversationMessages =\n system !== undefined ? mergedMessages.slice(1) : mergedMessages;\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 throw new Error(\n \"System messages are only permitted as the first passed message.\"\n );\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 {\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 as AnthropicMessageCreateParams[\"messages\"]\n ),\n system,\n } as AnthropicMessageCreateParams;\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:\n | string\n | Array<\n | AnthropicTextBlockParam\n | AnthropicImageBlockParam\n | AnthropicToolUseBlockParam\n | AnthropicToolResultBlockParam\n | AnthropicDocumentBlockParam\n | AnthropicThinkingBlockParam\n | AnthropicRedactedThinkingBlockParam\n | AnthropicServerToolUseBlockParam\n | AnthropicWebSearchToolResultBlockParam\n | AnthropicSearchResultBlockParam\n >\n ): Array<\n | AnthropicTextBlockParam\n | AnthropicImageBlockParam\n | AnthropicToolUseBlockParam\n | AnthropicToolResultBlockParam\n | AnthropicDocumentBlockParam\n | AnthropicThinkingBlockParam\n | AnthropicRedactedThinkingBlockParam\n | AnthropicServerToolUseBlockParam\n | AnthropicWebSearchToolResultBlockParam\n | AnthropicSearchResultBlockParam\n > => {\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 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\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 */\nfunction _formatSystemContent(\n content: BaseMessage[\"content\"]\n): string | Anthropic.Messages.ContentBlockParam[] {\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.map((block) => {\n if (block.type !== \"text\" || typeof block.text !== \"string\") {\n return block as Anthropic.Messages.ContentBlockParam;\n }\n return {\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: block.citations as AnthropicTextBlockParam[\"citations\"],\n }\n : {}),\n };\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 | Anthropic.Messages.ContentBlockParam[] | 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\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 return { role, content: _formatSystemContent(message.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 as AnthropicMessageCreateParams[\"messages\"]\n ),\n system,\n } as AnthropicMessageCreateParams;\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":";;;;AAoCA,SAAS,aAAa,UAAkB;CACtC,MAAM,UAAA,GAASA,yBAAAA,mBAAAA,CAAmB,EAAE,SAAS,SAAS,CAAC;CACvD,IAAI,QACF,OAAO;EACL,MAAM;EACN,YAAY,OAAO;EACnB,MAAM,OAAO;CACf;CAEF,IAAI;CAEJ,IAAI;EACF,YAAY,IAAI,IAAI,QAAQ;CAC9B,QAAQ;EACN,MAAM,IAAI,MACR;GACE,wBAAwB,KAAK,UAC3B,QACF,EAAE;GACF;GACA;EACF,CAAC,CAAC,KAAK,MAAM,CACf;CACF;CAEA,IAAI,UAAU,aAAa,WAAW,UAAU,aAAa,UAC3D,OAAO;EACL,MAAM;EACN,KAAK;CACP;CAGF,MAAM,IAAI,MACR;EACE,+BAA+B,KAAK,UAClC,UAAU,QACZ,EAAE;EACF;EACA;CACF,CAAC,CAAC,KAAK,MAAM,CACf;AACF;AAEA,SAAS,uBAAuB,UAAwC;CAEtE,MAAM,cAAc,CAAC;CACrB,KAAK,MAAM,WAAW,UACpB,IAAI,QAAQ,SAAS,MAAM,QAAQ;EACjC,IAAI,OAAO,QAAQ,YAAY,UAAU;GACvC,MAAM,kBAAkB,YAAY,YAAY,SAAS;GACzD,IACE,iBAAiB,SAAS,MAAM,WAChC,MAAM,QAAQ,gBAAgB,OAAO,KACrC,UAAU,gBAAgB,QAAQ,MAClC,gBAAgB,QAAQ,EAAE,CAAC,SAAS,eAGpC,gBAAiB,QAAoC,KAAK;IACxD,MAAM;IACN,SAAS,QAAQ;IACjB,aAAc,QAAwB;GACxC,CAAC;QAGD,YAAY,KACV,IAAIC,yBAAAA,aAAa,EACf,SAAS,CACP;IACE,MAAM;IACN,SAAS,QAAQ;IACjB,aAAc,QAAwB;GACxC,CACF,EACF,CAAC,CACH;EAEJ,OACE,YAAY,KACV,IAAIA,yBAAAA,aAAa,EACf,SAAS,CACP;GACE,MAAM;GAEN,GAAI,QAAQ,WAAW,OACnB,EAAE,SAAS,eAAe,OAAO,EAAE,IACnC,CAAC;GACL,aAAc,QAAwB;EACxC,CACF,EACF,CAAC,CACH;CAEJ,OACE,YAAY,KAAK,OAAO;CAG5B,OAAO;AACT;AAEA,SAAgB,qCACd,UACuB;CACvB,IAAI,SAAS,OAAO,KAAA,GAClB,MAAM,IAAI,MAAM,oDAAoD;CAEtE,OAAO;EACL,MAAM;EACN,IAAI,SAAS;EACb,MAAM,SAAS;EACf,OAAO,SAAS;CAClB;AACF;AAEA,UAAU,qBACR,SACA,WACiD;CACjD,MAAM,YAAY;EAChB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,MAAM,YAAY,CAAC,QAAQ,YAAY;CACvC,KAAK,MAAM,eAAe,SAAS;EACjC,KAAA,GAAIC,yBAAAA,mBAAAA,CAAmB,WAAW,GAChC,OAAA,GAAMC,yBAAAA,8BAAAA,CACJ,aACAC,gBAAAA,6BACF;EAGF,MAAM,eACJ,mBAAmB,cACd,YAAY,gBACb,KAAA;EAEN,IAAI,YAAY,SAAS,aAAa;GACpC,IAAI;GACJ,IAAI,OAAO,YAAY,cAAc,UACnC,SAAS,aAAa,YAAY,SAAS;QACtC,IACL,OAAO,YAAY,cAAc,YACjC,YAAY,cAAc,QAC1B,SAAS,YAAY,aACrB,OAAO,YAAY,UAAU,QAAQ,UAErC,SAAS,aAAa,YAAY,UAAU,GAAG;GAEjD,IAAI,QACF,MAAM;IACJ,MAAM;IACN;IACA,GAAI,eAAe,EAAE,eAAe,aAAa,IAAI,CAAC;GACxD;EAEJ,OAAO,IAAIC,gBAAAA,4BAA4B,WAAW,GAChD,MAAM;OACD,IAAI,YAAY,SAAS,SAAS;GAEvC,IAAI;GAEJ,IAAI,SAAS,eAAe,OAAO,YAAY,QAAQ,UAErD,SAAS,aAAa,YAAY,GAAG;QAChC,IACL,UAAU,gBACT,OAAO,YAAY,SAAS,YAE3B,YAAY,gBAAgB,aAW9B,SAAS;IACP,MAAM;IACN,YATA,cAAc,eAAe,OAAO,YAAY,aAAa,WACzD,YAAY,WACZ;IAYJ,MAVA,OAAO,YAAY,SAAS,WACxB,YAAY,OACZ,OAAO,KAAK,YAAY,IAAI,CAAC,CAAC,SAAS,QAAQ;GASrD;QACK,IACL,YAAY,eACZ,OAAO,YAAY,WAAW,UAK9B,SAAS;IACP,MAAM;IACN,SAAS,YAAY;GACvB;GAGF,IAAI,QACF,MAAM;IACJ,MAAM;IACN;IACA,GAAI,eAAe,EAAE,eAAe,aAAa,IAAI,CAAC;GACxD;EAEJ,OAAO,IAAI,YAAY,SAAS,QAAQ;GAEtC,IAAI;GAMJ,IAAI,SAAS,eAAe,OAAO,YAAY,QAAQ,UAErD,SAAS;IACP,MAAM;IACN,KAAK,YAAY;GACnB;QACK,IACL,UAAU,gBACT,OAAO,YAAY,SAAS,YAE3B,YAAY,gBAAgB,aAY9B,SAAS;IACP,MAAM;IACN,YAVA,cAAc,eAAe,OAAO,YAAY,aAAa,WACzD,YAAY,WACZ;IASJ,MAPA,OAAO,YAAY,SAAS,WACxB,YAAY,OACZ,OAAO,KAAK,YAAY,IAAI,CAAC,CAAC,SAAS,QAAQ;GAMrD;QACK,IACL,YAAY,eACZ,OAAO,YAAY,WAAW,UAI9B,SAAS;IACP,MAAM;IACN,SAAS,YAAY;GACvB;GAGF,IAAI,QACF,MAAM;IACJ,MAAM;IACN;IACA,GAAI,eAAe,EAAE,eAAe,aAAa,IAAI,CAAC;GACxD;EAEJ,OAAO,IAAI,YAAY,SAAS,YAE9B,MAAM;GACJ,GAAG;GACH,GAAI,eAAe,EAAE,eAAe,aAAa,IAAI,CAAC;EACxD;OACK,IAAIC,gBAAAA,0BAA0B,WAAW,GAO9C,MAAM;GALJ,MAAM;GACN,UAAU,YAAY;GACtB,WAAW,YAAY;GACvB,GAAI,eAAe,EAAE,eAAe,aAAa,IAAI,CAAC;EAE9C;OACL,IAAIC,gBAAAA,kCAAkC,WAAW,GAMtD,MAAM;GAJJ,MAAM;GACN,MAAM,YAAY;GAClB,GAAI,eAAe,EAAE,eAAe,aAAa,IAAI,CAAC;EAE9C;OACL,IAAIC,gBAAAA,4BAA4B,WAAW,GAMhD,MAAM;GAJJ,MAAM;GACN,SAAS,YAAY;GACrB,GAAI,eAAe,EAAE,eAAe,aAAa,IAAI,CAAC;EAE9C;OACL,IAAIC,gBAAAA,8BAA8B,WAAW,GAalD,MAAM;GAXJ,MAAM;GACN,OAAO,YAAY;GACnB,QAAQ,YAAY;GACpB,GAAI,mBAAmB,eAAe,YAAY,gBAC9C,EAAE,eAAe,YAAY,cAAc,IAC3C,CAAC;GACL,GAAI,eAAe,eAAe,YAAY,YAC1C,EAAE,WAAW,YAAY,UAAU,IACnC,CAAC;GACL,SAAS,YAAY;EAEb;OACL,IACL,UAAU,MAAM,MAAM,MAAM,YAAY,IAAI,KAC5C,UAAU,aAGV,MAAM;GACJ,MAAM;GACN,MAAM,YAAY;GAClB,GAAI,eAAe,EAAE,eAAe,aAAa,IAAI,CAAC;GACtD,GAAI,eAAe,eAAe,YAAY,YAC1C,EAAE,WAAW,YAAY,UAAU,IACnC,CAAC;EACP;OACK,IAAI,UAAU,MAAM,MAAM,MAAM,YAAY,IAAI,GAAG;GACxD,MAAM,kBAAkB,EAAE,GAAG,YAAY;GAEzC,IAAI,gBAAgB,SAAS,oBAK3B;GAGF,IACE,gBAAgB,SAAS,cACzB,OAAO,gBAAgB,UAAU,UACjC;IAIA,MAAM,mBAAmB,WAAW,MACjC,OAAO,GAAG,OAAO,gBAAgB,EACpC;IACA,IAAI,kBACF,gBAAgB,QAAQ,iBAAiB;SAazC,gBAAgB,QARI,QAAQ,QACzB,sBACC,kBAAkB,UAAU,gBAAgB,SAC5C,kBAAkB,SAAS,sBAC3B,OAAO,kBAAkB,UAAU,QAIL,CAAC,CAAC,QACjC,aAAa,sBACZ,cAAc,kBAAkB,OAClC,gBAAgB,KAClB;GAEJ;GAEA,IAAI,WAAW,iBAEb,OAAO,gBAAgB;GAGzB,IAAI,WAAW,iBAET;QAAA,OAAO,gBAAgB,UAAU,UACnC,IAAI;KACF,gBAAgB,QAAQ,KAAK,MAAM,gBAAgB,KAAK;IAC1D,QAAQ;KACN,gBAAgB,QAAQ,CAAC;IAC3B;;GAIJ,MAAM;IACJ,GAAG;IACH,GAAI,eAAe,EAAE,eAAe,aAAa,IAAI,CAAC;GAExD;EACF,OAAO,IAAI,YAAY,SAAS,oBAC9B,MAAM;GACJ,GAAG;GACH,GAAI,eAAe,EAAE,eAAe,aAAa,IAAI,CAAC;EACxD;CAQJ;AACF;AAEA,SAAS,eAAe,SAAsB,WAAwB;CACpE,MAAM,EAAE,YAAY;CAEpB,IAAI,OAAO,YAAY,UACrB,OAAO;MAEP,OAAO,MAAM,KAAK,qBAAqB,SAAS,SAAS,CAAC;AAE9D;;;;;;;AAQA,SAAS,qBACP,SACiD;CACjD,IAAI,OAAO,YAAY,UACrB,OAAO;CAET,IAAI,CAAC,MAAM,QAAQ,OAAO,GAExB,OAAO,CAAC;CAEV,OAAO,QAAQ,KAAK,UAAU;EAC5B,IAAI,MAAM,SAAS,UAAU,OAAO,MAAM,SAAS,UACjD,OAAO;EAET,OAAO;GACL,MAAM;GACN,MAAM,MAAM;GACZ,GAAI,mBAAmB,SAAS,MAAM,gBAClC,EACE,eACE,MAAM,cACV,IACA,CAAC;GACL,GAAI,eAAe,SAAS,MAAM,YAC9B,EACE,WAAW,MAAM,UACnB,IACA,CAAC;EACP;CACF,CAAC;AACH;;;;;;;AAQA,SAAgB,mCACd,UAC8B;CAC9B,MAAM,iBAAiB,uBAAuB,QAAQ;CAOtD,IAAI,qBAAqB;CACzB,OACE,qBAAqB,eAAe,UACpC,eAAe,mBAAmB,CAAC,SAAS,MAAM,UAElD,sBAAsB;CAGxB,IAAI;CACJ,IAAI,uBAAuB,GACzB,SAAS,qBAAqB,eAAe,EAAE,CAAC,OAAO;MAClD,IAAI,qBAAqB,GAC9B,SAAS,eAAe,MAAM,GAAG,kBAAkB,CAAC,CAAC,SAAS,YAAY;EACxE,MAAM,UAAU,qBAAqB,QAAQ,OAAO;EACpD,OAAO,OAAO,YAAY,WACtB,CAAC;GAAE,MAAM;GAAiB,MAAM;EAAQ,CAAC,IACzC;CACN,CAAC;CAgFH,OAAO;EACL,UAAU,cA9EiB,eAAe,MAAM,kBACL,CAAC,CAAC,KAAK,YAAY;GAC9D,IAAI;GACJ,IAAI,QAAQ,SAAS,MAAM,SACzB,OAAO;QACF,IAAI,QAAQ,SAAS,MAAM,MAChC,OAAO;QACF,IAAI,QAAQ,SAAS,MAAM,QAChC,OAAO;QACF,IAAI,QAAQ,SAAS,MAAM,UAChC,OAAO;QAEP,MAAM,IAAI,MAAM,iBAAiB,QAAQ,KAAK,oBAAoB;GAEpE,IACEC,yBAAAA,UAAU,WAAW,OAAO,KAC5B,QAAQ,mBAAmB,mBAAmB,MAE9C,OAAO;IACL;IACA,SAASC,iBAAAA,uBAAuB,OAAO;GACzC;GAEF,IAAID,yBAAAA,UAAU,WAAW,OAAO,KAAK,CAAC,CAAC,QAAQ,YAAY,QAAQ;IACjE,IAAI,OAAO,QAAQ,YAAY,UAAU;KACvC,IAAI,QAAQ,YAAY,IACtB,OAAO;MACL;MACA,SAAS,QAAQ,WAAW,IAC1B,oCACF;KACF;UAEA,OAAO;MACL;MACA,SAAS,CACP;OAAE,MAAM;OAAQ,MAAM,QAAQ;MAAQ,GACtC,GAAG,QAAQ,WAAW,IAAI,oCAAoC,CAChE;KACF;IAEJ,OAAO;KACL,MAAM,EAAE,YAAY;KACpB,MAAM,mBAAmB,eAAe,SAAS,QAAQ,UAAU;KACnE,MAAM,sBAAsB,MAAM,QAAQ,gBAAgB,IACtD,mBACA,CAAC;MAAE,MAAM;MAAiB,MAAM;KAAiB,CAAC;KACtD,MAAM,mBAAmB,QAAQ,WAAW,QACzC,aACC,CAAC,QAAQ,MACN,iBACE,YAAY,SAAS,cACpB,YAAY,SAAS,sBACrB,YAAY,SAAS,sBACvB,YAAY,OAAO,SAAS,EAChC,CACJ;KACA,OAAO;MACL;MACA,SAAS,CACP,GAAG,qBACH,GAAG,iBAAiB,IAAI,oCAAoC,CAC9D;KACF;IACF;GACF,OAAO,IAAI,SAAS,UAClB,OAAO;IAAE;IAAM,SAAS,qBAAqB,QAAQ,OAAO;GAAE;QAE9D,OAAO;IACL;IACA,SAAS,eACP,SACAA,yBAAAA,UAAU,WAAW,OAAO,IAAI,QAAQ,aAAa,KAAA,CACvD;GACF;EAEJ,CAGoB,CAClB;EACA;CACF;AACF;AAEA,SAAS,cAAc,UAAoD;CACzE,IAAI,CAAC,YAAY,SAAS,UAAU,GAClC,OAAO;CAGT,MAAM,SAAmD,CAAC;CAC1D,IAAI,iBAAiB,SAAS;CAE9B,MAAM,oBACJ,YACgD;EAChD,IAAI,OAAO,YAAY,UACrB,OAAO,CACL;GACE,MAAM;GACN,MAAM;EACR,CACF;EAEF,OAAO;CACT;CAEA,MAAM,uBAAuB,QAA8B;EACzD,IAAI,IAAI,SAAS,QAAQ,OAAO;EAEhC,IAAI,OAAO,IAAI,YAAY,UACzB,OAAO;EAGT,OACE,MAAM,QAAQ,IAAI,OAAO,KACzB,IAAI,QAAQ,OAAO,SAAS,KAAK,SAAS,aAAa;CAE3D;CAEA,KAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK,GAAG;EAC3C,MAAM,cAAc,SAAS;EAE7B,IACE,oBAAoB,cAAc,KAClC,oBAAoB,WAAW,GAG/B,iBAAiB;GACf,GAAG;GACH,SAAS,CACP,GAAG,iBAAiB,eAAe,OAAO,GAC1C,GAAG,iBAAiB,YAAY,OAAO,CACzC;EACF;OACK;GACL,OAAO,KAAK,cAAc;GAC1B,iBAAiB;EACnB;CACF;CAEA,OAAO,KAAK,cAAc;CAC1B,OAAO;AACT"}
@@ -192,6 +192,25 @@ function _formatContent(message, toolCalls) {
192
192
  else return Array.from(_formatContentBlocks(content, toolCalls));
193
193
  }
194
194
  /**
195
+ * Normalizes the content of a system message for the wire.
196
+ *
197
+ * Shared by the hoisted top-level `system` field and by in-place
198
+ * `role: "system"` entries, so both strip the same framework-internal fields.
199
+ */
200
+ function _formatSystemContent(content) {
201
+ if (typeof content === "string") return content;
202
+ if (!Array.isArray(content)) return [];
203
+ return content.map((block) => {
204
+ if (block.type !== "text" || typeof block.text !== "string") return block;
205
+ return {
206
+ type: "text",
207
+ text: block.text,
208
+ ..."cache_control" in block && block.cache_control ? { cache_control: block.cache_control } : {},
209
+ ..."citations" in block && block.citations ? { citations: block.citations } : {}
210
+ };
211
+ });
212
+ }
213
+ /**
195
214
  * Formats messages as a prompt for the model.
196
215
  * Used in LangSmith, export is important here.
197
216
  * @param messages The base messages to format as a prompt.
@@ -199,15 +218,24 @@ function _formatContent(message, toolCalls) {
199
218
  */
200
219
  function _convertMessagesToAnthropicPayload(messages) {
201
220
  const mergedMessages = _ensureMessageContents(messages);
221
+ let leadingSystemCount = 0;
222
+ while (leadingSystemCount < mergedMessages.length && mergedMessages[leadingSystemCount]._getType() === "system") leadingSystemCount += 1;
202
223
  let system;
203
- if (mergedMessages.length > 0 && mergedMessages[0]._getType() === "system") system = messages[0].content;
224
+ if (leadingSystemCount === 1) system = _formatSystemContent(mergedMessages[0].content);
225
+ else if (leadingSystemCount > 1) system = mergedMessages.slice(0, leadingSystemCount).flatMap((message) => {
226
+ const content = _formatSystemContent(message.content);
227
+ return typeof content === "string" ? [{
228
+ type: "text",
229
+ text: content
230
+ }] : content;
231
+ });
204
232
  return {
205
- messages: mergeMessages((system !== void 0 ? mergedMessages.slice(1) : mergedMessages).map((message) => {
233
+ messages: mergeMessages(mergedMessages.slice(leadingSystemCount).map((message) => {
206
234
  let role;
207
235
  if (message._getType() === "human") role = "user";
208
236
  else if (message._getType() === "ai") role = "assistant";
209
237
  else if (message._getType() === "tool") role = "user";
210
- else if (message._getType() === "system") throw new Error("System messages are only permitted as the first passed message.");
238
+ else if (message._getType() === "system") role = "system";
211
239
  else throw new Error(`Message type "${message.type}" is not supported.`);
212
240
  if (AIMessage.isInstance(message) && message.response_metadata?.output_version === "v1") return {
213
241
  role,
@@ -239,7 +267,11 @@ function _convertMessagesToAnthropicPayload(messages) {
239
267
  content: [...formattedContentArr, ...missingToolCalls.map(_convertLangChainToolCallToAnthropic)]
240
268
  };
241
269
  }
242
- } else return {
270
+ } else if (role === "system") return {
271
+ role,
272
+ content: _formatSystemContent(message.content)
273
+ };
274
+ else return {
243
275
  role,
244
276
  content: _formatContent(message, AIMessage.isInstance(message) ? message.tool_calls : void 0)
245
277
  };
@@ -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 AnthropicImageBlockParam,\n AnthropicMessageCreateParams,\n AnthropicTextBlockParam,\n AnthropicToolResultBlockParam,\n AnthropicToolUseBlockParam,\n AnthropicDocumentBlockParam,\n AnthropicThinkingBlockParam,\n AnthropicRedactedThinkingBlockParam,\n AnthropicServerToolUseBlockParam,\n AnthropicWebSearchToolResultBlockParam,\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\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 let system;\n if (mergedMessages.length > 0 && mergedMessages[0]._getType() === \"system\") {\n system = messages[0].content;\n }\n const conversationMessages =\n system !== undefined ? mergedMessages.slice(1) : mergedMessages;\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 throw new Error(\n \"System messages are only permitted as the first passed message.\"\n );\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 {\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 as AnthropicMessageCreateParams[\"messages\"]\n ),\n system,\n } as AnthropicMessageCreateParams;\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:\n | string\n | Array<\n | AnthropicTextBlockParam\n | AnthropicImageBlockParam\n | AnthropicToolUseBlockParam\n | AnthropicToolResultBlockParam\n | AnthropicDocumentBlockParam\n | AnthropicThinkingBlockParam\n | AnthropicRedactedThinkingBlockParam\n | AnthropicServerToolUseBlockParam\n | AnthropicWebSearchToolResultBlockParam\n | AnthropicSearchResultBlockParam\n >\n ): Array<\n | AnthropicTextBlockParam\n | AnthropicImageBlockParam\n | AnthropicToolUseBlockParam\n | AnthropicToolResultBlockParam\n | AnthropicDocumentBlockParam\n | AnthropicThinkingBlockParam\n | AnthropicRedactedThinkingBlockParam\n | AnthropicServerToolUseBlockParam\n | AnthropicWebSearchToolResultBlockParam\n | AnthropicSearchResultBlockParam\n > => {\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 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\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 */\nfunction _formatSystemContent(\n content: BaseMessage[\"content\"]\n): string | Anthropic.Messages.ContentBlockParam[] {\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.map((block) => {\n if (block.type !== \"text\" || typeof block.text !== \"string\") {\n return block as Anthropic.Messages.ContentBlockParam;\n }\n return {\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: block.citations as AnthropicTextBlockParam[\"citations\"],\n }\n : {}),\n };\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 | Anthropic.Messages.ContentBlockParam[] | 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\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 return { role, content: _formatSystemContent(message.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 as AnthropicMessageCreateParams[\"messages\"]\n ),\n system,\n } as AnthropicMessageCreateParams;\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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/anthropic",
3
- "version": "1.5.10",
3
+ "version": "1.5.11",
4
4
  "description": "Anthropic integrations for LangChain.js",
5
5
  "author": "LangChain",
6
6
  "license": "MIT",
@@ -18,7 +18,7 @@
18
18
  "zod": "^3.25.76 || ^4"
19
19
  },
20
20
  "peerDependencies": {
21
- "@langchain/core": "^1.2.10"
21
+ "@langchain/core": "^1.2.12"
22
22
  },
23
23
  "devDependencies": {
24
24
  "@anthropic-ai/vertex-sdk": "^0.19.6",
@@ -29,9 +29,9 @@
29
29
  "dpdm": "^4.3.0",
30
30
  "rimraf": "^6.1.3",
31
31
  "typescript": "~7.0.2",
32
- "vitest": "^4.1.8",
32
+ "vitest": "^4.1.11",
33
+ "@langchain/core": "^1.2.12",
33
34
  "@langchain/standard-tests": "0.0.23",
34
- "@langchain/core": "^1.2.10",
35
35
  "@langchain/tsconfig": "0.0.1"
36
36
  },
37
37
  "publishConfig": {