UNPKG

@langchain/community

Version:
307 lines (306 loc) 12.6 kB
require("../../_virtual/_rolldown/runtime.cjs"); let _langchain_core_messages = require("@langchain/core/messages"); let _langchain_core_utils_stream = require("@langchain/core/utils/stream"); //#region src/utils/bedrock/anthropic.ts function extractToolCalls(content) { const toolCalls = []; for (const block of content) if (block.type === "tool_use") toolCalls.push({ name: block.name, args: block.input, id: block.id, type: "tool_call" }); return toolCalls; } function _formatImage(imageUrl) { const match = imageUrl.match(/^data:(image\/.+);base64,(.+)$/); if (match === null) throw new Error(["Anthropic only supports base64-encoded images currently.", "Example: data:image/png;base64,/9j/4AAQSk..."].join("\n\n")); return { type: "base64", media_type: match[1] ?? "", data: match[2] ?? "" }; } function _ensureMessageContents(messages) { const updatedMsgs = []; for (const message of messages) if (_langchain_core_messages.ToolMessage.isInstance(message)) if (typeof message.content === "string") { const previousMessage = updatedMsgs[updatedMsgs.length - 1]; if (previousMessage?._getType() === "human" && Array.isArray(previousMessage.content) && "type" in previousMessage.content[0] && previousMessage.content[0].type === "tool_result") previousMessage.content.push({ type: "tool_result", content: message.content, tool_use_id: message.tool_call_id }); else updatedMsgs.push(new _langchain_core_messages.HumanMessage({ content: [{ type: "tool_result", content: message.content, tool_use_id: message.tool_call_id }] })); } else updatedMsgs.push(new _langchain_core_messages.HumanMessage({ content: [{ type: "tool_result", content: _formatContent(message.content), tool_use_id: message.tool_call_id }] })); else if (_langchain_core_messages.SystemMessage.isInstance(message) || _langchain_core_messages.HumanMessage.isInstance(message) || _langchain_core_messages.AIMessage.isInstance(message)) updatedMsgs.push(message); else throw new Error(`Message type "${message._getType()}" is not supported.`); return updatedMsgs; } function _convertLangChainToolCallToAnthropic(toolCall) { if (toolCall.id === void 0) throw new Error(`Anthropic requires all tool calls to have an "id".`); return { type: "tool_use", id: toolCall.id, name: toolCall.name, input: toolCall.args }; } function _formatContent(content) { if (typeof content === "string") return content; else return content.flatMap((contentPart) => { if ("source_type" in contentPart) { const sourceType = contentPart.source_type; const blockType = contentPart.type; if (sourceType === "base64" && blockType === "image") return { type: "image", source: { type: "base64", media_type: contentPart.mime_type ?? "", data: contentPart.data ?? "" } }; else if (sourceType === "base64" && blockType === "file") return { type: "document", source: { type: "base64", media_type: contentPart.mime_type ?? "", data: contentPart.data ?? "" } }; else if (sourceType === "url" && blockType === "file") return { type: "document", source: { type: "url", url: contentPart.url ?? "" } }; else if (sourceType === "text") return { type: "text", text: contentPart.text ?? "" }; return []; } else if (contentPart.type === "image_url") { let imageUrl; if (typeof contentPart.image_url === "string") imageUrl = contentPart.image_url; else if (typeof contentPart.image_url === "object" && contentPart.image_url !== null && "url" in contentPart.image_url && typeof contentPart.image_url.url === "string") imageUrl = contentPart.image_url.url; else return []; return { type: "image", source: _formatImage(imageUrl) }; } else if (contentPart.type === "image") { if ("url" in contentPart && typeof contentPart.url === "string") return { type: "image", source: _formatImage(contentPart.url) }; else if ("data" in contentPart && (typeof contentPart.data === "string" || contentPart.data instanceof Uint8Array)) return { type: "image", source: { type: "base64", media_type: "mimeType" in contentPart && typeof contentPart.mimeType === "string" ? contentPart.mimeType : "image/jpeg", data: typeof contentPart.data === "string" ? contentPart.data : Buffer.from(contentPart.data).toString("base64") } }; return []; } else if (contentPart.type === "file") { if ("url" in contentPart && typeof contentPart.url === "string") return { type: "document", source: { type: "url", url: contentPart.url } }; else if ("data" in contentPart && (typeof contentPart.data === "string" || contentPart.data instanceof Uint8Array)) return { type: "document", source: { type: "base64", media_type: "mimeType" in contentPart && typeof contentPart.mimeType === "string" ? contentPart.mimeType : "application/pdf", data: typeof contentPart.data === "string" ? contentPart.data : Buffer.from(contentPart.data).toString("base64") } }; return []; } else if (contentPart.type === "document") return { ...contentPart }; else if (contentPart.type === "text" || contentPart.type === "text_delta") { if (contentPart.text === "") return []; return { type: "text", text: contentPart.text }; } else if (contentPart.type === "tool_use" || contentPart.type === "tool_result") return { ...contentPart }; else if (contentPart.type === "input_json_delta") return []; else return []; }); } function formatMessagesForAnthropic(messages) { const mergedMessages = _ensureMessageContents(messages); let system; if (mergedMessages.length > 0 && mergedMessages[0]._getType() === "system") { if (typeof messages[0].content !== "string") throw new Error("System message content must be a string."); system = messages[0].content; } return { messages: (system !== void 0 ? mergedMessages.slice(1) : mergedMessages).map((message) => { let role; if (message._getType() === "human") role = "user"; else if (message._getType() === "ai") role = "assistant"; else if (message._getType() === "tool") role = "user"; else if (message._getType() === "system") throw new Error("System messages are only permitted as the first passed message."); else throw new Error(`Message type "${message._getType()}" is not supported.`); if ((0, _langchain_core_messages.isAIMessage)(message) && !!message.tool_calls?.length) if (typeof message.content === "string") if (message.content === "") return { role, content: message.tool_calls.map(_convertLangChainToolCallToAnthropic) }; else return { role, content: [{ type: "text", text: message.content }, ...message.tool_calls.map(_convertLangChainToolCallToAnthropic)] }; else { const formattedContent = _formatContent(message.content); if (Array.isArray(formattedContent)) { const formattedToolsContent = message.tool_calls.map(_convertLangChainToolCallToAnthropic); return { role, content: [...formattedContent, ...formattedToolsContent] }; } return { role, content: formattedContent }; } else return { role, content: _formatContent(message.content) }; }), system }; } function isAnthropicTool(tool) { if (typeof tool !== "object" || !tool) return false; return "input_schema" in tool; } function _makeMessageChunkFromAnthropicEvent(data, fields) { if (data.type === "message_start") { const { content, usage, ...additionalKwargs } = data.message; const filteredAdditionalKwargs = {}; for (const [key, value] of Object.entries(additionalKwargs)) if (value !== void 0 && value !== null) filteredAdditionalKwargs[key] = value; return new _langchain_core_messages.AIMessageChunk({ content: fields.coerceContentToString ? "" : [], additional_kwargs: filteredAdditionalKwargs }); } else if (data.type === "message_delta") { let usageMetadata; return new _langchain_core_messages.AIMessageChunk({ content: fields.coerceContentToString ? "" : [], additional_kwargs: { ...data.delta }, usage_metadata: usageMetadata }); } else if (data.type === "content_block_start" && data.content_block.type === "tool_use") return new _langchain_core_messages.AIMessageChunk({ content: fields.coerceContentToString ? "" : [{ index: data.index, ...data.content_block, input: "" }], additional_kwargs: {} }); else if (data.type === "content_block_delta" && data.delta.type === "text_delta") { const content = data.delta?.text; if (content !== void 0) return new _langchain_core_messages.AIMessageChunk({ content: fields.coerceContentToString ? content : [{ index: data.index, ...data.delta }], additional_kwargs: {} }); } else if (data.type === "content_block_delta" && data.delta.type === "input_json_delta") return new _langchain_core_messages.AIMessageChunk({ content: fields.coerceContentToString ? "" : [{ index: data.index, input: data.delta.partial_json, type: data.delta.type }], additional_kwargs: {} }); else if (data.type === "message_stop" && data["amazon-bedrock-invocationMetrics"] !== void 0) return new _langchain_core_messages.AIMessageChunk({ content: "", response_metadata: { "amazon-bedrock-invocationMetrics": data["amazon-bedrock-invocationMetrics"] }, usage_metadata: { input_tokens: data["amazon-bedrock-invocationMetrics"].inputTokenCount, output_tokens: data["amazon-bedrock-invocationMetrics"].outputTokenCount, total_tokens: data["amazon-bedrock-invocationMetrics"].inputTokenCount + data["amazon-bedrock-invocationMetrics"].outputTokenCount } }); return null; } function extractToolCallChunk(chunk) { let newToolCallChunk; const toolUseChunks = Array.isArray(chunk.content) ? chunk.content.find((c) => c.type === "tool_use") : void 0; if (toolUseChunks && "index" in toolUseChunks && typeof toolUseChunks.index === "number" && "name" in toolUseChunks && typeof toolUseChunks.name === "string" && "id" in toolUseChunks && typeof toolUseChunks.id === "string") newToolCallChunk = { args: "", id: toolUseChunks.id, name: toolUseChunks.name, index: toolUseChunks.index, type: "tool_call_chunk" }; const inputJsonDeltaChunks = Array.isArray(chunk.content) ? chunk.content.find((c) => c.type === "input_json_delta") : void 0; if (inputJsonDeltaChunks && "index" in inputJsonDeltaChunks && typeof inputJsonDeltaChunks.index === "number" && "input" in inputJsonDeltaChunks) if (typeof inputJsonDeltaChunks.input === "string") newToolCallChunk = { args: inputJsonDeltaChunks.input, index: inputJsonDeltaChunks.index, type: "tool_call_chunk" }; else newToolCallChunk = { args: JSON.stringify(inputJsonDeltaChunks.input, null, 2), index: inputJsonDeltaChunks.index, type: "tool_call_chunk" }; return newToolCallChunk; } function extractToken(chunk) { return typeof chunk.content === "string" && chunk.content !== "" ? chunk.content : void 0; } function extractToolUseContent(chunk, concatenatedChunks) { let newConcatenatedChunks = concatenatedChunks; let toolUseContent; if (!newConcatenatedChunks) newConcatenatedChunks = chunk; else newConcatenatedChunks = (0, _langchain_core_utils_stream.concat)(newConcatenatedChunks, chunk); if (Array.isArray(newConcatenatedChunks.content) && newConcatenatedChunks.content.find((c) => c.type === "tool_use")) try { const toolUseMsg = newConcatenatedChunks.content.find((c) => c.type === "tool_use"); if (!toolUseMsg || !("input" in toolUseMsg || "name" in toolUseMsg || "id" in toolUseMsg)) return; if (typeof toolUseMsg.id !== "string" || typeof toolUseMsg.name !== "string" || typeof toolUseMsg.input !== "string") return; const parsedArgs = JSON.parse(toolUseMsg.input); if (parsedArgs) toolUseContent = { type: "tool_use", id: toolUseMsg.id, name: toolUseMsg.name, input: parsedArgs }; } catch (_) {} return { toolUseContent, concatenatedChunks: newConcatenatedChunks }; } function _toolsInParams(params) { return !!(params.tools && params.tools.length > 0); } //#endregion exports._makeMessageChunkFromAnthropicEvent = _makeMessageChunkFromAnthropicEvent; exports._toolsInParams = _toolsInParams; exports.extractToken = extractToken; exports.extractToolCallChunk = extractToolCallChunk; exports.extractToolCalls = extractToolCalls; exports.extractToolUseContent = extractToolUseContent; exports.formatMessagesForAnthropic = formatMessagesForAnthropic; exports.isAnthropicTool = isAnthropicTool; //# sourceMappingURL=anthropic.cjs.map