{"version":3,"file":"message_outputs.cjs","names":["AIMessageChunk","_isAnthropicCompactionBlock","AIMessage","extractToolCalls"],"sources":["../../src/utils/message_outputs.ts"],"sourcesContent":["/**\n * This util file contains functions for converting Anthropic messages to LangChain messages.\n */\nimport Anthropic from \"@anthropic-ai/sdk\";\nimport {\n  AIMessage,\n  AIMessageChunk,\n  UsageMetadata,\n} from \"@langchain/core/messages\";\nimport type { ToolCallChunk } from \"@langchain/core/messages/tool\";\nimport { ChatGeneration } from \"@langchain/core/outputs\";\nimport { AnthropicMessageResponse } from \"../types.js\";\nimport { extractToolCalls } from \"../output_parsers.js\";\nimport { _isAnthropicCompactionBlock } from \"./content.js\";\n\nexport function _makeMessageChunkFromAnthropicEvent(\n  data: Anthropic.Beta.Messages.BetaRawMessageStreamEvent,\n  fields: {\n    streamUsage: boolean;\n    coerceContentToString: boolean;\n  }\n): {\n  chunk: AIMessageChunk;\n} | null {\n  const response_metadata = { model_provider: \"anthropic\" };\n  if (data.type === \"message_start\") {\n    const { content, usage, ...additionalKwargs } = data.message;\n    // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n    const filteredAdditionalKwargs: Record<string, any> = {};\n    for (const [key, value] of Object.entries(additionalKwargs)) {\n      if (value !== undefined && value !== null) {\n        filteredAdditionalKwargs[key] = value;\n      }\n    }\n    // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n    const { input_tokens, output_tokens, ...rest }: Record<string, any> =\n      usage ?? {};\n    const usageMetadata = buildUsageMetadata(usage);\n    return {\n      chunk: new AIMessageChunk({\n        content: fields.coerceContentToString ? \"\" : [],\n        additional_kwargs: filteredAdditionalKwargs,\n        usage_metadata: fields.streamUsage ? usageMetadata : undefined,\n        response_metadata: {\n          ...response_metadata,\n          usage: {\n            ...rest,\n          },\n        },\n        id: data.message.id,\n      }),\n    };\n  } else if (data.type === \"message_delta\") {\n    const usageMetadata: UsageMetadata = {\n      input_tokens: 0,\n      output_tokens: data.usage.output_tokens,\n      total_tokens: data.usage.output_tokens,\n    };\n    const responseMetadata =\n      \"context_management\" in data.delta\n        ? { context_management: data.delta.context_management }\n        : undefined;\n    return {\n      chunk: new AIMessageChunk({\n        content: fields.coerceContentToString ? \"\" : [],\n        response_metadata: responseMetadata,\n        additional_kwargs: { ...data.delta },\n        usage_metadata: fields.streamUsage ? usageMetadata : undefined,\n      }),\n    };\n  } else if (\n    data.type === \"content_block_start\" &&\n    [\n      \"tool_use\",\n      \"document\",\n      \"server_tool_use\",\n      \"web_search_tool_result\",\n    ].includes(data.content_block.type)\n  ) {\n    const contentBlock = data.content_block;\n    let toolCallChunks: ToolCallChunk[];\n    if (contentBlock.type === \"tool_use\") {\n      toolCallChunks = [\n        {\n          id: contentBlock.id,\n          index: data.index,\n          name: contentBlock.name,\n          args: \"\",\n        },\n      ];\n    } else {\n      toolCallChunks = [];\n    }\n    return {\n      chunk: new AIMessageChunk({\n        content: fields.coerceContentToString\n          ? \"\"\n          : [\n              {\n                index: data.index,\n                ...data.content_block,\n                input:\n                  contentBlock.type === \"server_tool_use\" ||\n                  contentBlock.type === \"tool_use\"\n                    ? \"\"\n                    : undefined,\n              },\n            ],\n        response_metadata,\n        additional_kwargs: {},\n        tool_call_chunks: toolCallChunks,\n      }),\n    };\n  } else if (\n    data.type === \"content_block_delta\" &&\n    [\n      \"text_delta\",\n      \"citations_delta\",\n      \"thinking_delta\",\n      \"signature_delta\",\n    ].includes(data.delta.type)\n  ) {\n    if (fields.coerceContentToString && \"text\" in data.delta) {\n      return {\n        chunk: new AIMessageChunk({\n          content: data.delta.text,\n        }),\n      };\n    } else {\n      // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n      const contentBlock: Record<string, any> = data.delta;\n      if (\"citation\" in contentBlock) {\n        contentBlock.citations = [contentBlock.citation];\n        delete contentBlock.citation;\n      }\n      if (\n        contentBlock.type === \"thinking_delta\" ||\n        contentBlock.type === \"signature_delta\"\n      ) {\n        return {\n          chunk: new AIMessageChunk({\n            content: [{ index: data.index, ...contentBlock, type: \"thinking\" }],\n            response_metadata,\n          }),\n        };\n      }\n\n      return {\n        chunk: new AIMessageChunk({\n          content: [{ index: data.index, ...contentBlock, type: \"text\" }],\n          response_metadata,\n        }),\n      };\n    }\n  } else if (\n    data.type === \"content_block_delta\" &&\n    data.delta.type === \"input_json_delta\"\n  ) {\n    return {\n      chunk: new AIMessageChunk({\n        content: fields.coerceContentToString\n          ? \"\"\n          : [\n              {\n                index: data.index,\n                input: data.delta.partial_json,\n                type: data.delta.type,\n              },\n            ],\n        response_metadata,\n        additional_kwargs: {},\n        tool_call_chunks: [\n          {\n            index: data.index,\n            args: data.delta.partial_json,\n          },\n        ],\n      }),\n    };\n  } else if (\n    data.type === \"content_block_start\" &&\n    data.content_block.type === \"text\"\n  ) {\n    const content = data.content_block?.text;\n    if (content !== undefined) {\n      return {\n        chunk: new AIMessageChunk({\n          content: fields.coerceContentToString\n            ? content\n            : [\n                {\n                  index: data.index,\n                  ...data.content_block,\n                },\n              ],\n          response_metadata,\n          additional_kwargs: {},\n        }),\n      };\n    }\n  } else if (\n    data.type === \"content_block_start\" &&\n    data.content_block.type === \"redacted_thinking\"\n  ) {\n    return {\n      chunk: new AIMessageChunk({\n        content: fields.coerceContentToString\n          ? \"\"\n          : [{ index: data.index, ...data.content_block }],\n        response_metadata,\n      }),\n    };\n  } else if (\n    data.type === \"content_block_start\" &&\n    data.content_block.type === \"thinking\"\n  ) {\n    const content = data.content_block.thinking;\n    return {\n      chunk: new AIMessageChunk({\n        content: fields.coerceContentToString\n          ? content\n          : [{ index: data.index, ...data.content_block }],\n        response_metadata,\n      }),\n    };\n  } else if (\n    data.type === \"content_block_start\" &&\n    _isAnthropicCompactionBlock(data.content_block)\n  ) {\n    return {\n      chunk: new AIMessageChunk({\n        content: fields.coerceContentToString\n          ? \"\"\n          : [{ index: data.index, ...data.content_block }],\n        response_metadata,\n      }),\n    };\n  } else if (\n    data.type === \"content_block_delta\" &&\n    data.delta.type === \"compaction_delta\"\n  ) {\n    return {\n      chunk: new AIMessageChunk({\n        content: fields.coerceContentToString\n          ? \"\"\n          : [\n              {\n                index: data.index,\n                ...data.delta,\n                type: \"compaction\",\n              },\n            ],\n        response_metadata,\n      }),\n    };\n  }\n  return null;\n}\n\nexport function anthropicResponseToChatMessages(\n  messages: AnthropicMessageResponse[],\n  additionalKwargs: Record<string, unknown>\n): ChatGeneration[] {\n  const response_metadata = {\n    ...additionalKwargs,\n    model_provider: \"anthropic\",\n  };\n  const usage: Record<string, number> | null | undefined =\n    additionalKwargs.usage as Record<string, number> | null | undefined;\n  const usageMetadata = usage != null ? buildUsageMetadata(usage) : undefined;\n  if (messages.length === 1 && messages[0].type === \"text\") {\n    return [\n      {\n        text: messages[0].text,\n        message: new AIMessage({\n          content: messages[0].text,\n          additional_kwargs: additionalKwargs,\n          usage_metadata: usageMetadata,\n          response_metadata,\n          id: additionalKwargs.id as string,\n        }),\n      },\n    ];\n  } else {\n    const toolCalls = extractToolCalls(messages);\n    const generations: ChatGeneration[] = [\n      {\n        text: \"\",\n        message: new AIMessage({\n          // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n          content: messages as any,\n          additional_kwargs: additionalKwargs,\n          tool_calls: toolCalls,\n          usage_metadata: usageMetadata,\n          response_metadata,\n          id: additionalKwargs.id as string,\n        }),\n      },\n    ];\n    return generations;\n  }\n}\n\nfunction buildUsageMetadata(\n  usage: Anthropic.Messages.Usage | Record<string, number>\n): UsageMetadata {\n  const cacheCreationInputTokens = usage.cache_creation_input_tokens ?? 0;\n  const cacheReadInputTokens = usage.cache_read_input_tokens ?? 0;\n  // Total input tokens in a Claude API request is the summation of `input_tokens`, `cache_creation_input_tokens`, and `cache_read_input_tokens`.\n  // ref: https://platform.claude.com/docs/en/api/messages\n  const totalInputTokens =\n    usage.input_tokens + cacheCreationInputTokens + cacheReadInputTokens;\n  return {\n    input_tokens: totalInputTokens,\n    output_tokens: usage.output_tokens,\n    total_tokens: totalInputTokens + usage.output_tokens,\n    input_token_details: {\n      cache_creation: cacheCreationInputTokens,\n      cache_read: cacheReadInputTokens,\n    },\n  };\n}\n"],"mappings":"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"}