@copilotkit/runtime
Version:
<img src="https://github.com/user-attachments/assets/0a6b64d9-e193-4940-a3f6-60334ac34084" alt="banner" style="border-radius: 12px; border: 2px solid #d6d4fa;" />
1 lines • 8.91 kB
Source Map (JSON)
{"version":3,"file":"utils.mjs","names":[],"sources":["../../../src/service-adapters/anthropic/utils.ts"],"sourcesContent":["import { Anthropic } from \"@anthropic-ai/sdk\";\nimport { ActionInput } from \"../../graphql/inputs/action.input\";\nimport { Message } from \"../../graphql/types/converted\";\n\nexport function limitMessagesToTokenCount(\n messages: any[],\n tools: any[],\n model: string,\n maxTokens?: number,\n): any[] {\n maxTokens ||= MAX_TOKENS;\n\n const result: any[] = [];\n const toolsNumTokens = countToolsTokens(model, tools);\n if (toolsNumTokens > maxTokens) {\n throw new Error(\n `Too many tokens in function definitions: ${toolsNumTokens} > ${maxTokens}`,\n );\n }\n maxTokens -= toolsNumTokens;\n\n for (const message of messages) {\n if (message.role === \"system\") {\n const numTokens = countMessageTokens(model, message);\n maxTokens -= numTokens;\n\n if (maxTokens < 0) {\n throw new Error(\"Not enough tokens for system message.\");\n }\n }\n }\n\n let cutoff: boolean = false;\n\n const reversedMessages = [...messages].toReversed();\n for (const message of reversedMessages) {\n if (message.role === \"system\") {\n result.unshift(message);\n continue;\n } else if (cutoff) {\n continue;\n }\n let numTokens = countMessageTokens(model, message);\n if (maxTokens < numTokens) {\n cutoff = true;\n continue;\n }\n result.unshift(message);\n maxTokens -= numTokens;\n }\n\n // Post-process: remove orphaned tool_result and tool_use blocks.\n // Token trimming may have removed the assistant message containing tool_use\n // while keeping the user message with tool_result (or vice versa),\n // which Anthropic rejects.\n\n // Collect all tool_use IDs from assistant messages\n const toolUseIds = new Set<string>();\n for (const msg of result) {\n if (msg.role === \"assistant\" && Array.isArray(msg.content)) {\n for (const block of msg.content) {\n if (block.type === \"tool_use\") {\n toolUseIds.add(block.id);\n }\n }\n }\n }\n\n // Collect all tool_result IDs from user messages\n const toolResultIds = new Set<string>();\n for (const msg of result) {\n if (msg.role === \"user\" && Array.isArray(msg.content)) {\n for (const block of msg.content) {\n if (block.type === \"tool_result\") {\n toolResultIds.add(block.tool_use_id);\n }\n }\n }\n }\n\n // Filter orphaned blocks without mutating the original messages\n const filtered: any[] = [];\n for (const msg of result) {\n if (msg.role === \"user\" && Array.isArray(msg.content)) {\n const remaining = msg.content.filter(\n (block: any) =>\n block.type !== \"tool_result\" || toolUseIds.has(block.tool_use_id),\n );\n if (remaining.length === 0) continue;\n if (remaining.length !== msg.content.length) {\n filtered.push({ ...msg, content: remaining });\n } else {\n filtered.push(msg);\n }\n } else if (msg.role === \"assistant\" && Array.isArray(msg.content)) {\n const remaining = msg.content.filter(\n (block: any) =>\n block.type !== \"tool_use\" || toolResultIds.has(block.id),\n );\n if (remaining.length === 0) continue;\n if (remaining.length !== msg.content.length) {\n filtered.push({ ...msg, content: remaining });\n } else {\n filtered.push(msg);\n }\n } else {\n filtered.push(msg);\n }\n }\n\n return filtered;\n}\n\nconst MAX_TOKENS = 128000;\n\nfunction countToolsTokens(model: string, tools: any[]): number {\n if (tools.length === 0) {\n return 0;\n }\n const json = JSON.stringify(tools);\n return countTokens(model, json);\n}\n\nfunction countMessageTokens(model: string, message: any): number {\n return countTokens(model, JSON.stringify(message.content) || \"\");\n}\n\nfunction countTokens(model: string, text: string): number {\n return text.length / 3;\n}\n\nexport function convertActionInputToAnthropicTool(\n action: ActionInput,\n): Anthropic.Messages.Tool {\n return {\n name: action.name,\n description: action.description,\n input_schema: JSON.parse(action.jsonSchema),\n };\n}\n\nexport function convertMessageToAnthropicMessage(\n message: Message,\n): Anthropic.Messages.MessageParam {\n if (message.isTextMessage()) {\n if (message.role === \"system\") {\n return {\n role: \"assistant\",\n content: [\n {\n type: \"text\",\n text:\n \"THE FOLLOWING MESSAGE IS A SYSTEM MESSAGE: \" + message.content,\n },\n ],\n };\n } else {\n return {\n role: message.role === \"user\" ? \"user\" : \"assistant\",\n content: [{ type: \"text\", text: message.content }],\n };\n }\n } else if (message.isImageMessage()) {\n let mediaType: \"image/jpeg\" | \"image/png\" | \"image/webp\" | \"image/gif\";\n switch (message.format) {\n case \"jpeg\":\n mediaType = \"image/jpeg\";\n break;\n case \"png\":\n mediaType = \"image/png\";\n break;\n case \"webp\":\n mediaType = \"image/webp\";\n break;\n case \"gif\":\n mediaType = \"image/gif\";\n break;\n default:\n throw new Error(`Unsupported image format: ${message.format}`);\n }\n\n return {\n role: \"user\",\n content: [\n {\n type: \"image\",\n source: {\n type: \"base64\",\n media_type: mediaType,\n data: message.bytes,\n },\n },\n ],\n };\n } else if (message.isActionExecutionMessage()) {\n return {\n role: \"assistant\",\n content: [\n {\n id: message.id,\n type: \"tool_use\",\n input: message.arguments,\n name: message.name,\n },\n ],\n };\n } else if (message.isResultMessage()) {\n return {\n role: \"user\",\n content: [\n {\n type: \"tool_result\",\n content: message.result || \"Action completed successfully\",\n tool_use_id: message.actionExecutionId,\n },\n ],\n };\n }\n}\n"],"mappings":"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"}