diff --git a/src/endpoints/backends/chat-completions.js b/src/endpoints/backends/chat-completions.js index 4836a9f8b..d2f963007 100644 --- a/src/endpoints/backends/chat-completions.js +++ b/src/endpoints/backends/chat-completions.js @@ -101,8 +101,9 @@ async function sendClaudeRequest(request, response) { controller.abort(); }); const additionalHeaders = {}; + const useTools = request.body.model.startsWith('claude-3') && Array.isArray(request.body.tools) && request.body.tools.length > 0; const useSystemPrompt = (request.body.model.startsWith('claude-2') || request.body.model.startsWith('claude-3')) && request.body.claude_use_sysprompt; - const convertedPrompt = convertClaudeMessages(request.body.messages, request.body.assistant_prefill, useSystemPrompt, request.body.human_sysprompt_message, request.body.char_name, request.body.user_name); + const convertedPrompt = convertClaudeMessages(request.body.messages, request.body.assistant_prefill, useSystemPrompt, useTools, request.body.human_sysprompt_message, request.body.char_name, request.body.user_name); // Add custom stop sequences const stopSequences = []; if (Array.isArray(request.body.stop)) { @@ -129,7 +130,7 @@ async function sendClaudeRequest(request, response) { } else { delete requestBody.system; } - if (Array.isArray(request.body.tools) && request.body.tools.length > 0) { + if (useTools) { // Claude doesn't do prefills on function calls, and doesn't allow empty messages if (convertedPrompt.messages.length && convertedPrompt.messages[convertedPrompt.messages.length - 1].role === 'assistant') { convertedPrompt.messages.push({ role: 'user', content: '.' }); diff --git a/src/prompt-converters.js b/src/prompt-converters.js index 19afabbaf..38a6854a9 100644 --- a/src/prompt-converters.js +++ b/src/prompt-converters.js @@ -91,11 +91,12 @@ function convertClaudePrompt(messages, addAssistantPostfix, addAssistantPrefill, * @param {object[]} messages Array of messages * @param {string} prefillString User determined prefill string * @param {boolean} useSysPrompt See if we want to use a system prompt + * @param {boolean} useTools See if we want to use tools * @param {string} humanMsgFix Add Human message between system prompt and assistant. * @param {string} charName Character name * @param {string} userName User name */ -function convertClaudeMessages(messages, prefillString, useSysPrompt, humanMsgFix, charName = '', userName = '') { +function convertClaudeMessages(messages, prefillString, useSysPrompt, useTools, humanMsgFix, charName = '', userName = '') { let systemPrompt = []; if (useSysPrompt) { // Collect all the system messages up until the first instance of a non-system message, and then remove them from the messages array. @@ -248,6 +249,26 @@ function convertClaudeMessages(messages, prefillString, useSysPrompt, humanMsgFi } }); + if (!useTools) { + mergedMessages.forEach((message) => { + message.content.forEach((content) => { + if (content.type === 'tool_use') { + content.type = 'text'; + content.text = JSON.stringify(content.input); + delete content.id; + delete content.name; + delete content.input; + } + if (content.type === 'tool_result') { + content.type = 'text'; + content.text = content.content; + delete content.tool_use_id; + delete content.content; + } + }); + }); + } + return { messages: mergedMessages, systemPrompt: systemPrompt }; }