Claude: Use multi-part system prompt, cache tools

6185974e17a77d7d5caacd3ff2853413283b5ac7

Cohee <18619528+Cohee1207@users.noreply.github.com>

2 files changed, +14 -8Showing whitespace changes
src/endpoints/backends/chat-completions.js+11 -5
@@ -87,7 +87,7 @@ async function sendClaudeRequest(request, response) {
8787 const apiUrl = new URL(request.body.reverse_proxy || API_CLAUDE).toString();
8888 const apiKey = request.body.reverse_proxy ? request.body.proxy_password : readSecret(request.user.directories, SECRET_KEYS.CLAUDE);
8989 const divider = '-'.repeat(process.stdout.columns);
9090 const enableSystemPromptCache = getConfigValue('claude.enableSystemPromptCache', false) && request.body.model.startsWith('claude-3');
9191
9292 if (!apiKey) {
9393 console.log(color.red(`Claude API key is missing.\n${divider}`));
@@ -110,7 +110,7 @@ async function sendClaudeRequest(request, response) {
110110 }
111111
112112 const requestBody = {
113113 /** @type {any} */ system: ''[],
114114 messages: convertedPrompt.messages,
115115 model: request.body.model,
116116 max_tokens: request.body.max_tokens,
@@ -121,9 +121,11 @@ async function sendClaudeRequest(request, response) {
121121 stream: request.body.stream,
122122 };
123123 if (useSystemPrompt) {
124- requestBody.system = enableSystemPromptCache
124+ if (enableSystemPromptCache && Array.isArray(convertedPrompt.systemPrompt) && convertedPrompt.systemPrompt.length) {
125125 ? convertedPrompt.systemPrompt[{ type: 'text', text: convertedPrompt.systemPrompt,.length - 1]['cache_control:'] = { type: 'ephemeral' } }];
126- : convertedPrompt.systemPrompt;
126+ }
127+
128+ requestBody.system = convertedPrompt.systemPrompt;
127129 } else {
128130 delete requestBody.system;
129131 }
@@ -138,6 +140,10 @@ async function sendClaudeRequest(request, response) {
138140 .filter(tool => tool.type === 'function')
139141 .map(tool => tool.function)
140142 .map(fn => ({ name: fn.name, description: fn.description, input_schema: fn.parameters }));
143+
144+ if (enableSystemPromptCache && requestBody.tools.length) {
145+ requestBody.tools[requestBody.tools.length - 1]['cache_control'] = { type: 'ephemeral' };
146+ }
141147 }
142148 if (enableSystemPromptCache) {
143149 additionalHeaders['anthropic-beta'] = 'prompt-caching-2024-07-31';
src/prompt-converters.js+3 -3
@@ -95,7 +95,7 @@ function convertClaudePrompt(messages, addAssistantPostfix, addAssistantPrefill,
9595 * @param {string} userName User name
9696 */
9797function convertClaudeMessages(messages, prefillString, useSysPrompt, humanMsgFix, charName = '', userName = '') {
9898 let systemPrompt = ''[];
9999 if (useSysPrompt) {
100100 // Collect all the system messages up until the first instance of a non-system message, and then remove them from the messages array.
101101 let i;
@@ -114,7 +114,7 @@ function convertClaudeMessages(messages, prefillString, useSysPrompt, humanMsgFi
114114 messages[i].content = `${charName}: ${messages[i].content}`;
115115 }
116116 }
117- systemPrompt += `${messages[i].content}\n\n`;
117+ systemPrompt.push({ type: 'text', text: messages[i].content });
118118 }
119119
120120 messages.splice(0, i);
@@ -246,7 +246,7 @@ function convertClaudeMessages(messages, prefillString, useSysPrompt, humanMsgFi
246246 }
247247 });
248248
249249 return { messages: mergedMessages, systemPrompt: systemPrompt.trim() };
250250}
251251
252252/**