@langchain/community
Version:
Third-party integrations for LangChain.js
1 lines • 20.3 kB
Source Map (JSON)
{"version":3,"file":"anthropic.cjs","names":["content: Record<string, any>[]","toolCalls: ToolCall[]","imageUrl: string","messages: BaseMessage[]","HumanMessage","toolCall: ToolCall","content: MessageContent","system: string | undefined","tool: unknown","data: Record<string, any>","fields: {\n coerceContentToString?: boolean;\n }","filteredAdditionalKwargs: Record<string, any>","AIMessageChunk","usageMetadata: UsageMetadata | undefined","chunk: AIMessageChunk","newToolCallChunk: ToolCallChunk | undefined","concatenatedChunks: AIMessageChunk | undefined","toolUseContent:\n | {\n id: string;\n type: \"tool_use\";\n name: string;\n input: Record<string, unknown>;\n }\n | undefined","params: Record<string, any>"],"sources":["../../../src/utils/bedrock/anthropic.ts"],"sourcesContent":["import {\n AIMessage,\n AIMessageChunk,\n BaseMessage,\n HumanMessage,\n MessageContent,\n SystemMessage,\n ToolMessage,\n UsageMetadata,\n isAIMessage,\n} from \"@langchain/core/messages\";\nimport { ToolCall, ToolCallChunk } from \"@langchain/core/messages/tool\";\nimport { concat } from \"@langchain/core/utils/stream\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function extractToolCalls(content: Record<string, any>[]) {\n const toolCalls: ToolCall[] = [];\n for (const block of content) {\n if (block.type === \"tool_use\") {\n toolCalls.push({\n name: block.name,\n args: block.input,\n id: block.id,\n type: \"tool_call\",\n });\n }\n }\n return toolCalls;\n}\n\nfunction _formatImage(imageUrl: string) {\n const regex = /^data:(image\\/.+);base64,(.+)$/;\n const match = imageUrl.match(regex);\n if (match === null) {\n throw new Error(\n [\n \"Anthropic only supports base64-encoded images currently.\",\n \"Example: data:image/png;base64,/9j/4AAQSk...\",\n ].join(\"\\n\\n\")\n );\n }\n return {\n type: \"base64\",\n media_type: match[1] ?? \"\",\n data: match[2] ?? \"\",\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } as any;\n}\n\nfunction _ensureMessageContents(\n messages: BaseMessage[]\n): (SystemMessage | HumanMessage | AIMessage)[] {\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.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 content: _formatContent(message.content),\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 // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): Record<string, any> {\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 _formatContent(content: MessageContent) {\n if (typeof content === \"string\") {\n return content;\n } else {\n const contentBlocks = content.flatMap((contentPart) => {\n if (contentPart.type === \"image_url\") {\n let source;\n if (typeof contentPart.image_url === \"string\") {\n source = _formatImage(contentPart.image_url);\n } else {\n source = _formatImage(contentPart.image_url.url);\n }\n return {\n type: \"image\" as const, // Explicitly setting the type as \"image\"\n source,\n };\n } else if (\n contentPart.type === \"text\" ||\n contentPart.type === \"text_delta\"\n ) {\n if (contentPart.text === \"\") {\n return [];\n }\n // Assuming contentPart is of type MessageContentText here\n return {\n type: \"text\" as const, // Explicitly setting the type as \"text\"\n text: contentPart.text,\n };\n } else if (\n contentPart.type === \"tool_use\" ||\n contentPart.type === \"tool_result\"\n ) {\n // TODO: Fix when SDK types are fixed\n return {\n ...contentPart,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } as any;\n } else if (contentPart.type === \"input_json_delta\") {\n return [];\n } else {\n throw new Error(\"Unsupported message content format\");\n }\n });\n return contentBlocks;\n }\n}\n\nexport function formatMessagesForAnthropic(messages: BaseMessage[]): {\n system?: string;\n messages: Record<string, unknown>[];\n} {\n const mergedMessages = _ensureMessageContents(messages);\n let system: string | undefined;\n if (mergedMessages.length > 0 && mergedMessages[0]._getType() === \"system\") {\n if (typeof messages[0].content !== \"string\") {\n throw new Error(\"System message content must be a string.\");\n }\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._getType()}\" is not supported.`);\n }\n if (isAIMessage(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 formattedContent = _formatContent(message.content);\n if (Array.isArray(formattedContent)) {\n const formattedToolsContent = message.tool_calls.map(\n _convertLangChainToolCallToAnthropic\n );\n return {\n role,\n content: [...formattedContent, ...formattedToolsContent],\n };\n }\n\n return {\n role,\n content: formattedContent,\n };\n }\n } else {\n return {\n role,\n content: _formatContent(message.content),\n };\n }\n });\n return {\n messages: formattedMessages,\n system,\n };\n}\n\nexport function isAnthropicTool(\n tool: unknown\n): tool is Record<string, unknown> {\n if (typeof tool !== \"object\" || !tool) return false;\n return \"input_schema\" in tool;\n}\n\nexport function _makeMessageChunkFromAnthropicEvent(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n data: Record<string, any>,\n fields: {\n coerceContentToString?: boolean;\n }\n): AIMessageChunk | null {\n if (data.type === \"message_start\") {\n const { content, usage, ...additionalKwargs } = data.message;\n // eslint-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 return new AIMessageChunk({\n content: fields.coerceContentToString ? \"\" : [],\n additional_kwargs: filteredAdditionalKwargs,\n });\n } else if (data.type === \"message_delta\") {\n let usageMetadata: UsageMetadata | undefined;\n return new AIMessageChunk({\n content: fields.coerceContentToString ? \"\" : [],\n additional_kwargs: { ...data.delta },\n usage_metadata: usageMetadata,\n });\n } else if (\n data.type === \"content_block_start\" &&\n data.content_block.type === \"tool_use\"\n ) {\n return new AIMessageChunk({\n content: fields.coerceContentToString\n ? \"\"\n : [\n {\n index: data.index,\n ...data.content_block,\n input: \"\",\n },\n ],\n additional_kwargs: {},\n });\n } else if (\n data.type === \"content_block_delta\" &&\n data.delta.type === \"text_delta\"\n ) {\n const content = data.delta?.text;\n if (content !== undefined) {\n return new AIMessageChunk({\n content: fields.coerceContentToString\n ? content\n : [\n {\n index: data.index,\n ...data.delta,\n },\n ],\n additional_kwargs: {},\n });\n }\n } else if (\n data.type === \"content_block_delta\" &&\n data.delta.type === \"input_json_delta\"\n ) {\n return 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 additional_kwargs: {},\n });\n } else if (\n data.type === \"message_stop\" &&\n data[\"amazon-bedrock-invocationMetrics\"] !== undefined\n ) {\n return new AIMessageChunk({\n content: \"\",\n response_metadata: {\n \"amazon-bedrock-invocationMetrics\":\n data[\"amazon-bedrock-invocationMetrics\"],\n },\n usage_metadata: {\n input_tokens: data[\"amazon-bedrock-invocationMetrics\"].inputTokenCount,\n output_tokens:\n data[\"amazon-bedrock-invocationMetrics\"].outputTokenCount,\n total_tokens:\n data[\"amazon-bedrock-invocationMetrics\"].inputTokenCount +\n data[\"amazon-bedrock-invocationMetrics\"].outputTokenCount,\n },\n });\n }\n\n return null;\n}\n\nexport function extractToolCallChunk(\n chunk: AIMessageChunk\n): ToolCallChunk | undefined {\n let newToolCallChunk: ToolCallChunk | undefined;\n\n // Initial chunk for tool calls from anthropic contains identifying information like ID and name.\n // This chunk does not contain any input JSON.\n const toolUseChunks = Array.isArray(chunk.content)\n ? chunk.content.find((c) => c.type === \"tool_use\")\n : undefined;\n if (\n toolUseChunks &&\n \"index\" in toolUseChunks &&\n \"name\" in toolUseChunks &&\n \"id\" in toolUseChunks\n ) {\n newToolCallChunk = {\n args: \"\",\n id: toolUseChunks.id,\n name: toolUseChunks.name,\n index: toolUseChunks.index,\n type: \"tool_call_chunk\",\n };\n }\n\n // Chunks after the initial chunk only contain the index and partial JSON.\n const inputJsonDeltaChunks = Array.isArray(chunk.content)\n ? chunk.content.find((c) => c.type === \"input_json_delta\")\n : undefined;\n if (\n inputJsonDeltaChunks &&\n \"index\" in inputJsonDeltaChunks &&\n \"input\" in inputJsonDeltaChunks\n ) {\n if (typeof inputJsonDeltaChunks.input === \"string\") {\n newToolCallChunk = {\n args: inputJsonDeltaChunks.input,\n index: inputJsonDeltaChunks.index,\n type: \"tool_call_chunk\",\n };\n } else {\n newToolCallChunk = {\n args: JSON.stringify(inputJsonDeltaChunks.input, null, 2),\n index: inputJsonDeltaChunks.index,\n type: \"tool_call_chunk\",\n };\n }\n }\n\n return newToolCallChunk;\n}\n\nexport function extractToken(chunk: AIMessageChunk): string | undefined {\n return typeof chunk.content === \"string\" && chunk.content !== \"\"\n ? chunk.content\n : undefined;\n}\n\nexport function extractToolUseContent(\n chunk: AIMessageChunk,\n concatenatedChunks: AIMessageChunk | undefined\n) {\n let newConcatenatedChunks = concatenatedChunks;\n // Remove `tool_use` content types until the last chunk.\n let toolUseContent:\n | {\n id: string;\n type: \"tool_use\";\n name: string;\n input: Record<string, unknown>;\n }\n | undefined;\n if (!newConcatenatedChunks) {\n newConcatenatedChunks = chunk;\n } else {\n newConcatenatedChunks = concat(newConcatenatedChunks, chunk);\n }\n if (\n Array.isArray(newConcatenatedChunks.content) &&\n newConcatenatedChunks.content.find((c) => c.type === \"tool_use\")\n ) {\n try {\n const toolUseMsg = newConcatenatedChunks.content.find(\n (c) => c.type === \"tool_use\"\n );\n if (\n !toolUseMsg ||\n !(\"input\" in toolUseMsg || \"name\" in toolUseMsg || \"id\" in toolUseMsg)\n )\n return;\n const parsedArgs = JSON.parse(toolUseMsg.input);\n if (parsedArgs) {\n toolUseContent = {\n type: \"tool_use\",\n id: toolUseMsg.id,\n name: toolUseMsg.name,\n input: parsedArgs,\n };\n }\n } catch (_) {\n // no-op\n }\n }\n\n return {\n toolUseContent,\n concatenatedChunks: newConcatenatedChunks,\n };\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function _toolsInParams(params: Record<string, any>): boolean {\n return !!(params.tools && params.tools.length > 0);\n}\n"],"mappings":"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"}