{"version":3,"file":"message_inputs.cjs","names":["parseBase64DataUrl","HumanMessage","isDataContentBlock","convertToProviderContentBlock","standardContentBlockConverter","_isAnthropicImageBlockParam","_isAnthropicThinkingBlock","_isAnthropicRedactedThinkingBlock","_isAnthropicCompactionBlock","_isAnthropicSearchResultBlock","AIMessage","_formatStandardContent"],"sources":["../../src/utils/message_inputs.ts"],"sourcesContent":["/**\n * This util file contains functions for converting LangChain messages to Anthropic messages.\n */\nimport type Anthropic from \"@anthropic-ai/sdk\";\nimport {\n  type BaseMessage,\n  HumanMessage,\n  ToolMessage,\n  MessageContentComplex,\n  isDataContentBlock,\n  convertToProviderContentBlock,\n  parseBase64DataUrl,\n  ContentBlock,\n  AIMessage,\n} from \"@langchain/core/messages\";\nimport { ToolCall } from \"@langchain/core/messages/tool\";\nimport {\n  AnthropicMessageCreateParams,\n  AnthropicTextBlockParam,\n  AnthropicThinkingBlockParam,\n  AnthropicRedactedThinkingBlockParam,\n  AnthropicSearchResultBlockParam,\n  AnthropicToolResponse,\n  AnthropicContainerUploadBlockParam,\n  AnthropicCompactionBlockParam,\n} from \"../types.js\";\nimport {\n  _isAnthropicImageBlockParam,\n  _isAnthropicRedactedThinkingBlock,\n  _isAnthropicSearchResultBlock,\n  _isAnthropicThinkingBlock,\n  _isAnthropicCompactionBlock,\n  standardContentBlockConverter,\n} from \"./content.js\";\nimport { _formatStandardContent } from \"./standard.js\";\n\nfunction _formatImage(imageUrl: string) {\n  const parsed = parseBase64DataUrl({ dataUrl: imageUrl });\n  if (parsed) {\n    return {\n      type: \"base64\",\n      media_type: parsed.mime_type,\n      data: parsed.data,\n    };\n  }\n  let parsedUrl: URL;\n\n  try {\n    parsedUrl = new URL(imageUrl);\n  } catch {\n    throw new Error(\n      [\n        `Malformed image URL: ${JSON.stringify(\n          imageUrl\n        )}. Content blocks of type 'image_url' must be a valid http, https, or base64-encoded data URL.`,\n        \"Example: data:image/png;base64,/9j/4AAQSk...\",\n        \"Example: https://example.com/image.jpg\",\n      ].join(\"\\n\\n\")\n    );\n  }\n\n  if (parsedUrl.protocol === \"http:\" || parsedUrl.protocol === \"https:\") {\n    return {\n      type: \"url\",\n      url: imageUrl,\n    };\n  }\n\n  throw new Error(\n    [\n      `Invalid image URL protocol: ${JSON.stringify(\n        parsedUrl.protocol\n      )}. Anthropic only supports images as http, https, or base64-encoded data URLs on 'image_url' content blocks.`,\n      \"Example: data:image/png;base64,/9j/4AAQSk...\",\n      \"Example: https://example.com/image.jpg\",\n    ].join(\"\\n\\n\")\n  );\n}\n\nfunction _ensureMessageContents(messages: BaseMessage[]): BaseMessage[] {\n  // Merge runs of human/tool messages into single human messages with content blocks.\n  const updatedMsgs = [];\n  for (const message of messages) {\n    if (message._getType() === \"tool\") {\n      if (typeof message.content === \"string\") {\n        const previousMessage = updatedMsgs[updatedMsgs.length - 1];\n        if (\n          previousMessage?._getType() === \"human\" &&\n          Array.isArray(previousMessage.content) &&\n          \"type\" in previousMessage.content[0] &&\n          previousMessage.content[0].type === \"tool_result\"\n        ) {\n          // If the previous message was a tool result, we merge this tool message into it.\n          (previousMessage.content as MessageContentComplex[]).push({\n            type: \"tool_result\",\n            content: message.content,\n            tool_use_id: (message as ToolMessage).tool_call_id,\n          });\n        } else {\n          // If not, we create a new human message with the tool result.\n          updatedMsgs.push(\n            new HumanMessage({\n              content: [\n                {\n                  type: \"tool_result\",\n                  content: message.content,\n                  tool_use_id: (message as ToolMessage).tool_call_id,\n                },\n              ],\n            })\n          );\n        }\n      } else {\n        updatedMsgs.push(\n          new HumanMessage({\n            content: [\n              {\n                type: \"tool_result\",\n                // rare case: message.content could be undefined\n                ...(message.content != null\n                  ? { content: _formatContent(message) }\n                  : {}),\n                tool_use_id: (message as ToolMessage).tool_call_id,\n              },\n            ],\n          })\n        );\n      }\n    } else {\n      updatedMsgs.push(message);\n    }\n  }\n  return updatedMsgs;\n}\n\nexport function _convertLangChainToolCallToAnthropic(\n  toolCall: ToolCall\n): AnthropicToolResponse {\n  if (toolCall.id === undefined) {\n    throw new Error(`Anthropic requires all tool calls to have an \"id\".`);\n  }\n  return {\n    type: \"tool_use\",\n    id: toolCall.id,\n    name: toolCall.name,\n    input: toolCall.args,\n  };\n}\n\nfunction* _formatContentBlocks(\n  content: ContentBlock[],\n  toolCalls?: ToolCall[]\n): Generator<Anthropic.Beta.BetaContentBlockParam> {\n  const toolTypes = [\n    \"bash_code_execution_tool_result\",\n    \"input_json_delta\",\n    \"server_tool_use\",\n    \"text_editor_code_execution_tool_result\",\n    \"tool_result\",\n    \"tool_search_tool_result\",\n    \"tool_search_tool_bm25_tool_result\",\n    \"tool_search_tool_regex_tool_result\",\n    \"tool_use\",\n    \"web_search_result\",\n    \"web_search_tool_result\",\n  ];\n  const textTypes = [\"text\", \"text_delta\"];\n  for (const contentPart of content) {\n    if (isDataContentBlock(contentPart)) {\n      yield convertToProviderContentBlock(\n        contentPart,\n        standardContentBlockConverter\n      );\n    }\n\n    const cacheControl =\n      \"cache_control\" in contentPart\n        ? (contentPart.cache_control as Anthropic.Beta.BetaCacheControlEphemeral)\n        : undefined;\n\n    if (contentPart.type === \"image_url\") {\n      let source;\n      if (typeof contentPart.image_url === \"string\") {\n        source = _formatImage(contentPart.image_url);\n      } else if (\n        typeof contentPart.image_url === \"object\" &&\n        contentPart.image_url !== null &&\n        \"url\" in contentPart.image_url &&\n        typeof contentPart.image_url.url === \"string\"\n      ) {\n        source = _formatImage(contentPart.image_url.url);\n      }\n      if (source) {\n        yield {\n          type: \"image\" as const, // Explicitly setting the type as \"image\"\n          source,\n          ...(cacheControl ? { cache_control: cacheControl } : {}),\n        } as Anthropic.Messages.ImageBlockParam;\n      }\n    } else if (_isAnthropicImageBlockParam(contentPart)) {\n      yield contentPart;\n    } else if (contentPart.type === \"image\") {\n      // Handle new ContentBlock.Multimodal.Image format\n      let source;\n\n      if (\"url\" in contentPart && typeof contentPart.url === \"string\") {\n        // URL-based image\n        source = _formatImage(contentPart.url);\n      } else if (\n        \"data\" in contentPart &&\n        (typeof contentPart.data === \"string\" ||\n          // oxlint-disable-next-line no-instanceof/no-instanceof\n          contentPart.data instanceof Uint8Array)\n      ) {\n        // Base64-based image\n        const mimeType =\n          \"mimeType\" in contentPart && typeof contentPart.mimeType === \"string\"\n            ? contentPart.mimeType\n            : \"image/jpeg\";\n        const data =\n          typeof contentPart.data === \"string\"\n            ? contentPart.data\n            : Buffer.from(contentPart.data).toString(\"base64\");\n        source = {\n          type: \"base64\" as const,\n          media_type: mimeType as\n            | \"image/jpeg\"\n            | \"image/png\"\n            | \"image/gif\"\n            | \"image/webp\",\n          data,\n        };\n      } else if (\n        \"fileId\" in contentPart &&\n        typeof contentPart.fileId === \"string\"\n      ) {\n        // File ID-based image\n        // Note: Anthropic supports file IDs for images that have been uploaded\n        // to their servers via the Files API\n        source = {\n          type: \"file\" as const,\n          file_id: contentPart.fileId,\n        };\n      }\n\n      if (source) {\n        yield {\n          type: \"image\" as const,\n          source,\n          ...(cacheControl ? { cache_control: cacheControl } : {}),\n        } as Anthropic.Messages.ImageBlockParam;\n      }\n    } else if (contentPart.type === \"file\") {\n      // Handle new ContentBlock.Multimodal.File format\n      let source:\n        | { type: \"url\"; url: string }\n        | { type: \"base64\"; media_type: string; data: string }\n        | { type: \"file\"; file_id: string }\n        | undefined;\n\n      if (\"url\" in contentPart && typeof contentPart.url === \"string\") {\n        // File with URL\n        source = {\n          type: \"url\" as const,\n          url: contentPart.url,\n        };\n      } else if (\n        \"data\" in contentPart &&\n        (typeof contentPart.data === \"string\" ||\n          // oxlint-disable-next-line no-instanceof/no-instanceof\n          contentPart.data instanceof Uint8Array)\n      ) {\n        // File with base64 data (string or Uint8Array)\n        const media_type =\n          \"mimeType\" in contentPart && typeof contentPart.mimeType === \"string\"\n            ? contentPart.mimeType\n            : \"application/pdf\";\n        const data =\n          typeof contentPart.data === \"string\"\n            ? contentPart.data\n            : Buffer.from(contentPart.data).toString(\"base64\");\n\n        source = {\n          type: \"base64\" as const,\n          media_type,\n          data,\n        };\n      } else if (\n        \"fileId\" in contentPart &&\n        typeof contentPart.fileId === \"string\"\n      ) {\n        // File ID from Anthropic Files API\n        // https://platform.claude.com/docs/en/build-with-claude/pdf-support#option-3-files-api\n        source = {\n          type: \"file\" as const,\n          file_id: contentPart.fileId,\n        };\n      }\n\n      if (source) {\n        yield {\n          type: \"document\" as const,\n          source,\n          ...(cacheControl ? { cache_control: cacheControl } : {}),\n        } as Anthropic.Messages.DocumentBlockParam;\n      }\n    } else if (contentPart.type === \"document\") {\n      // PDF\n      yield {\n        ...contentPart,\n        ...(cacheControl ? { cache_control: cacheControl } : {}),\n      } as Anthropic.Messages.DocumentBlockParam;\n    } else if (_isAnthropicThinkingBlock(contentPart)) {\n      const block: AnthropicThinkingBlockParam = {\n        type: \"thinking\" as const, // Explicitly setting the type as \"thinking\"\n        thinking: contentPart.thinking,\n        signature: contentPart.signature,\n        ...(cacheControl ? { cache_control: cacheControl } : {}),\n      };\n      yield block;\n    } else if (_isAnthropicRedactedThinkingBlock(contentPart)) {\n      const block: AnthropicRedactedThinkingBlockParam = {\n        type: \"redacted_thinking\" as const, // Explicitly setting the type as \"redacted_thinking\"\n        data: contentPart.data,\n        ...(cacheControl ? { cache_control: cacheControl } : {}),\n      };\n      yield block;\n    } else if (_isAnthropicCompactionBlock(contentPart)) {\n      const block: AnthropicCompactionBlockParam = {\n        type: \"compaction\" as const,\n        content: contentPart.content,\n        ...(cacheControl ? { cache_control: cacheControl } : {}),\n      };\n      yield block;\n    } else if (_isAnthropicSearchResultBlock(contentPart)) {\n      const block: AnthropicSearchResultBlockParam = {\n        type: \"search_result\" as const, // Explicitly setting the type as \"search_result\"\n        title: contentPart.title,\n        source: contentPart.source,\n        ...(\"cache_control\" in contentPart && contentPart.cache_control\n          ? { cache_control: contentPart.cache_control }\n          : {}),\n        ...(\"citations\" in contentPart && contentPart.citations\n          ? { citations: contentPart.citations }\n          : {}),\n        content: contentPart.content,\n      };\n      yield block as Anthropic.Beta.BetaSearchResultBlockParam;\n    } else if (\n      textTypes.find((t) => t === contentPart.type) &&\n      \"text\" in contentPart\n    ) {\n      // Assuming contentPart is of type MessageContentText here\n      yield {\n        type: \"text\" as const, // Explicitly setting the type as \"text\"\n        text: contentPart.text,\n        ...(cacheControl ? { cache_control: cacheControl } : {}),\n        ...(\"citations\" in contentPart && contentPart.citations\n          ? { citations: contentPart.citations }\n          : {}),\n      } as Anthropic.Messages.TextBlockParam;\n    } else if (toolTypes.find((t) => t === contentPart.type)) {\n      const contentPartCopy = { ...contentPart };\n\n      if (contentPartCopy.type === \"input_json_delta\") {\n        // `input_json_delta` type only represents yielding partial tool inputs\n        // and is not a valid type for Anthropic messages.\n        // These blocks appear in streaming responses and should be skipped\n        // as their input data is already captured in tool_calls.\n        continue;\n      }\n\n      if (\n        contentPartCopy.type === \"tool_use\" &&\n        typeof contentPartCopy.input === \"string\"\n      ) {\n        // First, try to get the input from the corresponding tool_call.\n        // This is the most reliable source since tool_calls are properly\n        // consolidated from tool_call_chunks during streaming.\n        const matchingToolCall = toolCalls?.find(\n          (tc) => tc.id === contentPartCopy.id\n        );\n        if (matchingToolCall) {\n          contentPartCopy.input = matchingToolCall.args;\n        } else {\n          // Fallback: `tool_use` content part may be followed by `input_json_delta`\n          // content parts which are chunks of a stringified JSON input,\n          // so we need to collect them and merge their inputs.\n          const inputDeltas = content.filter(\n            (nestedContentPart) =>\n              nestedContentPart.index === contentPartCopy.index &&\n              nestedContentPart.type === \"input_json_delta\" &&\n              typeof nestedContentPart.input === \"string\"\n          );\n          // If no `input_json_delta` parts are found, this line will just\n          // return `contentPartCopy.input`, so no additional check is needed\n          contentPartCopy.input = inputDeltas.reduce(\n            (accumulator, nestedContentPart) =>\n              accumulator + nestedContentPart.input,\n            contentPartCopy.input\n          );\n        }\n      }\n\n      if (\"index\" in contentPartCopy) {\n        // Anthropic does not support passing the index field here, so we remove it.\n        delete contentPartCopy.index;\n      }\n\n      if (\"input\" in contentPartCopy) {\n        // Anthropic tool use inputs should be valid objects, when applicable.\n        if (typeof contentPartCopy.input === \"string\") {\n          try {\n            contentPartCopy.input = JSON.parse(contentPartCopy.input);\n          } catch {\n            contentPartCopy.input = {};\n          }\n        }\n      }\n      // TODO: Fix when SDK types are fixed\n      yield {\n        ...contentPartCopy,\n        ...(cacheControl ? { cache_control: cacheControl } : {}),\n        // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n      } as any;\n    } else if (contentPart.type === \"container_upload\") {\n      yield {\n        ...contentPart,\n        ...(cacheControl ? { cache_control: cacheControl } : {}),\n      } as AnthropicContainerUploadBlockParam;\n    }\n\n    // Note that we are intentionally dropping any blocks that we don't\n    // recognize. This is to allow for cross-compatibility between different\n    // providers that may have different block types. Ie if we take a message\n    // output from OpenAI and send it to Anthropic, we want to drop any blocks\n    // that Anthropic doesn't understand.\n  }\n}\n\nfunction _formatContent(message: BaseMessage, toolCalls?: ToolCall[]) {\n  const { content } = message;\n\n  if (typeof content === \"string\") {\n    return content;\n  } else {\n    return Array.from(_formatContentBlocks(content, toolCalls));\n  }\n}\n\ntype AnthropicToolChangeBlockParam =\n  | Anthropic.Beta.BetaRequestToolAdditionBlock\n  | Anthropic.Beta.BetaRequestToolRemovalBlock;\n\ntype AnthropicSystemContentBlockParam =\n  | Anthropic.Messages.ContentBlockParam\n  | AnthropicToolChangeBlockParam;\n\nconst TOOL_CHANGE_BLOCK_TYPES = [\"tool_addition\", \"tool_removal\"];\n\n/**\n * Returns the provider payload a block carries: the `value` of a\n * `non_standard` wrapper, or the block itself.\n */\nfunction _unwrapNonStandard(\n  block: MessageContentComplex\n): MessageContentComplex {\n  if (\n    block.type === \"non_standard\" &&\n    \"value\" in block &&\n    typeof block.value === \"object\" &&\n    block.value !== null\n  ) {\n    return block.value as MessageContentComplex;\n  }\n  return block;\n}\n\n/**\n * Normalizes the content of a system message for the wire.\n *\n * Shared by the hoisted top-level `system` field and by in-place\n * `role: \"system\"` entries, so both strip the same framework-internal fields.\n *\n * Blocks wrapped in core's `non_standard` escape hatch are unwrapped first, so\n * a provider-native block behaves the same whichever way it was written.\n */\nfunction _formatSystemContent(\n  content: BaseMessage[\"content\"]\n): string | AnthropicSystemContentBlockParam[] {\n  if (typeof content === \"string\") {\n    return content;\n  }\n  if (!Array.isArray(content)) {\n    // rare case: message.content could be undefined\n    return [];\n  }\n  return content.flatMap((rawBlock): AnthropicSystemContentBlockParam[] => {\n    if (typeof rawBlock !== \"object\" || rawBlock === null) {\n      return [{ type: \"text\" as const, text: String(rawBlock) }];\n    }\n    const block = _unwrapNonStandard(rawBlock);\n    if (TOOL_CHANGE_BLOCK_TYPES.includes(block.type as string)) {\n      return [block as AnthropicToolChangeBlockParam];\n    }\n    if (block.type === \"text\" && typeof block.text === \"string\") {\n      return [\n        {\n          type: \"text\" as const,\n          text: block.text,\n          ...(\"cache_control\" in block && block.cache_control\n            ? {\n                cache_control:\n                  block.cache_control as AnthropicTextBlockParam[\"cache_control\"],\n              }\n            : {}),\n          ...(\"citations\" in block && block.citations\n            ? {\n                citations:\n                  block.citations as AnthropicTextBlockParam[\"citations\"],\n              }\n            : {}),\n        },\n      ];\n    }\n    // Anthropic accepts a closed set of system content blocks, and rejects\n    // the whole request for anything else.\n    // Consider warning about the dropped block once we have a proper logging solution\n    return [];\n  });\n}\n\n/**\n * Formats messages as a prompt for the model.\n * Used in LangSmith, export is important here.\n * @param messages The base messages to format as a prompt.\n * @returns The formatted prompt.\n */\nexport function _convertMessagesToAnthropicPayload(\n  messages: BaseMessage[]\n): AnthropicMessageCreateParams {\n  const mergedMessages = _ensureMessageContents(messages);\n\n  // The contiguous run of system messages starting at index 0 is hoisted into\n  // the top-level `system` field. Every other system message keeps its\n  // position and is sent as a `role: \"system\"` entry, which the provider\n  // applies from that point in the conversation onwards. The run is identified\n  // after tool-message folding, because that is the sequence the provider sees.\n  let leadingSystemCount = 0;\n  while (\n    leadingSystemCount < mergedMessages.length &&\n    mergedMessages[leadingSystemCount]._getType() === \"system\"\n  ) {\n    leadingSystemCount += 1;\n  }\n\n  let system: string | AnthropicSystemContentBlockParam[] | undefined;\n  if (leadingSystemCount === 1) {\n    system = _formatSystemContent(mergedMessages[0].content);\n  } else if (leadingSystemCount > 1) {\n    system = mergedMessages.slice(0, leadingSystemCount).flatMap((message) => {\n      const content = _formatSystemContent(message.content);\n      return typeof content === \"string\"\n        ? [{ type: \"text\" as const, text: content }]\n        : content;\n    });\n  }\n  // The provider rejects empty system content, so system content that narrowed\n  // to nothing is omitted rather than sent.\n  if (Array.isArray(system) && system.length === 0) {\n    system = undefined;\n  }\n\n  const conversationMessages = mergedMessages.slice(leadingSystemCount);\n  const formattedMessages = conversationMessages.map((message) => {\n    let role;\n    if (message._getType() === \"human\") {\n      role = \"user\" as const;\n    } else if (message._getType() === \"ai\") {\n      role = \"assistant\" as const;\n    } else if (message._getType() === \"tool\") {\n      role = \"user\" as const;\n    } else if (message._getType() === \"system\") {\n      role = \"system\" as const;\n    } else {\n      throw new Error(`Message type \"${message.type}\" is not supported.`);\n    }\n    if (\n      AIMessage.isInstance(message) &&\n      message.response_metadata?.output_version === \"v1\"\n    ) {\n      return {\n        role,\n        content: _formatStandardContent(message),\n      };\n    }\n    if (AIMessage.isInstance(message) && !!message.tool_calls?.length) {\n      if (typeof message.content === \"string\") {\n        if (message.content === \"\") {\n          return {\n            role,\n            content: message.tool_calls.map(\n              _convertLangChainToolCallToAnthropic\n            ),\n          };\n        } else {\n          return {\n            role,\n            content: [\n              { type: \"text\", text: message.content },\n              ...message.tool_calls.map(_convertLangChainToolCallToAnthropic),\n            ],\n          };\n        }\n      } else {\n        const { content } = message;\n        const formattedContent = _formatContent(message, message.tool_calls);\n        const formattedContentArr = Array.isArray(formattedContent)\n          ? formattedContent\n          : [{ type: \"text\" as const, text: formattedContent }];\n        const missingToolCalls = message.tool_calls.filter(\n          (toolCall) =>\n            !content.find(\n              (contentPart) =>\n                (contentPart.type === \"tool_use\" ||\n                  contentPart.type === \"input_json_delta\" ||\n                  contentPart.type === \"server_tool_use\") &&\n                contentPart.id === toolCall.id\n            )\n        );\n        return {\n          role,\n          content: [\n            ...formattedContentArr,\n            ...missingToolCalls.map(_convertLangChainToolCallToAnthropic),\n          ],\n        };\n      }\n    } else if (role === \"system\") {\n      const content = _formatSystemContent(message.content);\n      return Array.isArray(content) && content.length === 0\n        ? undefined\n        : { role, content };\n    } else {\n      return {\n        role,\n        content: _formatContent(\n          message,\n          AIMessage.isInstance(message) ? message.tool_calls : undefined\n        ),\n      };\n    }\n  });\n  return {\n    messages: mergeMessages(\n      formattedMessages.filter(\n        (message) => message !== undefined\n      ) as AnthropicMessageCreateParams[\"messages\"]\n    ),\n    system,\n  } as AnthropicMessageCreateParams;\n}\n\n/**\n * Describes the tool changes in the system content of a converted payload:\n * `\"inline\"` if any `tool_addition` block defines a tool by value,\n * `\"reference\"` if tool changes only name tools declared elsewhere, or\n * `undefined` if there are none. The provider requires a different beta for\n * each.\n *\n * Reads the converted payload rather than the input messages, so a block that\n * was dropped during conversion never enables a beta.\n */\nexport function _getToolChangeKind(\n  payload: AnthropicMessageCreateParams\n): \"inline\" | \"reference\" | undefined {\n  const systemContents: unknown[] = [\n    payload.system,\n    ...payload.messages\n      .filter((message) => message.role === \"system\")\n      .map((message) => message.content),\n  ];\n  const toolChanges = systemContents.flatMap((content) =>\n    Array.isArray(content)\n      ? content.filter((block) => TOOL_CHANGE_BLOCK_TYPES.includes(block.type))\n      : []\n  );\n  if (toolChanges.some((block) => block.tool?.type === \"tool_definition\")) {\n    return \"inline\";\n  }\n  return toolChanges.length > 0 ? \"reference\" : undefined;\n}\n\nfunction mergeMessages(messages: AnthropicMessageCreateParams[\"messages\"]) {\n  if (!messages || messages.length <= 1) {\n    return messages;\n  }\n\n  const result: AnthropicMessageCreateParams[\"messages\"] = [];\n  let currentMessage = messages[0];\n\n  const normalizeContent = (\n    content: string | Array<Anthropic.Messages.ContentBlockParam>\n  ): Array<Anthropic.Messages.ContentBlockParam> => {\n    if (typeof content === \"string\") {\n      return [\n        {\n          type: \"text\",\n          text: content,\n        },\n      ];\n    }\n    return content;\n  };\n\n  const isToolResultMessage = (msg: (typeof messages)[0]) => {\n    if (msg.role !== \"user\") return false;\n\n    if (typeof msg.content === \"string\") {\n      return false;\n    }\n\n    return (\n      Array.isArray(msg.content) &&\n      msg.content.every((item) => item.type === \"tool_result\")\n    );\n  };\n\n  for (let i = 1; i < messages.length; i += 1) {\n    const nextMessage = messages[i];\n\n    if (\n      isToolResultMessage(currentMessage) &&\n      isToolResultMessage(nextMessage)\n    ) {\n      // Merge the messages by combining their content arrays\n      currentMessage = {\n        ...currentMessage,\n        content: [\n          ...normalizeContent(currentMessage.content),\n          ...normalizeContent(nextMessage.content),\n        ],\n      };\n    } else {\n      result.push(currentMessage);\n      currentMessage = nextMessage;\n    }\n  }\n\n  result.push(currentMessage);\n  return result;\n}\n"],"mappings":"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"}