Merge pull request #3971 from SillyTavern/ccllaauuddee Assorted Claude adjustments
Signed| @@ -1963,7 +1963,7 @@ | ||
| 1963 | 1963 | </span> |
| 1964 | 1964 | </div> |
| 1965 | 1965 | </div> |
| 1966 | 1966 | <div class="range-block" data-source="makersuite,openrouter,claude"> |
| 1967 | 1967 | <label for="openai_enable_web_search" class="checkbox_label flexWrap widthFreeExpand"> |
| 1968 | 1968 | <input id="openai_enable_web_search" type="checkbox" /> |
| 1969 | 1969 | <span data-i18n="Enable web search">Enable web search</span> |
| @@ -148,7 +148,8 @@ async function sendClaudeRequest(request, response) { | ||
| 148 | 148 | const useSystemPrompt = (request.body.model.startsWith('claude-2') || request.body.model.startsWith('claude-3')) && request.body.claude_use_sysprompt; |
| 149 | 149 | const convertedPrompt = convertClaudeMessages(request.body.messages, request.body.assistant_prefill, useSystemPrompt, useTools, getPromptNames(request)); |
| 150 | 150 | const useThinking = request.body.model.startsWith('claude-3-7') && Boolean(request.body.include_reasoning); |
| 151 | - let voidPrefill = false; | |
| 151 | + const useWebSearch = /^claude-3-(5|7)/.test(request.body.model) && Boolean(request.body.enable_web_search); | |
| 152 | + let fixThinkingPrefill = false; | |
| 152 | 153 | // Add custom stop sequences |
| 153 | 154 | const stopSequences = []; |
| 154 | 155 | if (Array.isArray(request.body.stop)) { |
| @@ -183,15 +184,19 @@ async function sendClaudeRequest(request, response) { | ||
| 183 | 184 | .map(tool => tool.function) |
| 184 | 185 | .map(fn => ({ name: fn.name, description: fn.description, input_schema: fn.parameters })); |
| 185 | 186 | |
| 186 | - if (requestBody.tools.length) { | |
| 187 | - // No prefill when using tools | |
| 188 | - voidPrefill = true; | |
| 189 | - } | |
| 190 | 187 | if (enableSystemPromptCache && requestBody.tools.length) { |
| 191 | 188 | requestBody.tools[requestBody.tools.length - 1]['cache_control'] = { type: 'ephemeral' }; |
| 192 | 189 | } |
| 193 | 190 | } |
| 194 | 191 | |
| 192 | + if (useWebSearch) { | |
| 193 | + const webSearchTool = [{ | |
| 194 | + 'type': 'web_search_20250305', | |
| 195 | + 'name': 'web_search', | |
| 196 | + }]; | |
| 197 | + requestBody.tools = [...(requestBody.tools || []), ...webSearchTool]; | |
| 198 | + } | |
| 199 | + | |
| 195 | 200 | if (cachingAtDepth !== -1) { |
| 196 | 201 | cachingAtDepthForClaude(convertedPrompt.messages, cachingAtDepth); |
| 197 | 202 | } |
| @@ -200,11 +205,12 @@ async function sendClaudeRequest(request, response) { | ||
| 200 | 205 | betaHeaders.push('prompt-caching-2024-07-31'); |
| 201 | 206 | } |
| 202 | 207 | |
| 203 | - if (useThinking) { | |
| 208 | + const reasoningEffort = request.body.reasoning_effort; | |
| 209 | + const budgetTokens = calculateClaudeBudgetTokens(requestBody.max_tokens, reasoningEffort, requestBody.stream); | |
| 210 | + | |
| 211 | + if (useThinking && Number.isInteger(budgetTokens)) { | |
| 204 | 212 | // No prefill when thinking |
| 205 | 213 | voidPrefillfixThinkingPrefill = true; |
| 206 | - const reasoningEffort = request.body.reasoning_effort; | |
| 207 | - const budgetTokens = calculateClaudeBudgetTokens(requestBody.max_tokens, reasoningEffort, requestBody.stream); | |
| 208 | 214 | const minThinkTokens = 1024; |
| 209 | 215 | if (requestBody.max_tokens <= minThinkTokens) { |
| 210 | 216 | const newValue = requestBody.max_tokens + minThinkTokens; |
| @@ -223,8 +229,8 @@ async function sendClaudeRequest(request, response) { | ||
| 223 | 229 | delete requestBody.top_k; |
| 224 | 230 | } |
| 225 | 231 | |
| 226 | 232 | if (voidPrefillfixThinkingPrefill && convertedPrompt.messages.length && convertedPrompt.messages[convertedPrompt.messages.length - 1].role === 'assistant') { |
| 227 | - convertedPrompt.messages.push({ role: 'user', content: [{ type: 'text', text: '\u200b' }] }); | |
| 233 | + convertedPrompt.messages[convertedPrompt.messages.length - 1].role = 'user'; | |
| 228 | 234 | } |
| 229 | 235 | |
| 230 | 236 | if (betaHeaders.length) { |
| @@ -917,19 +917,20 @@ export function cachingAtDepthForOpenRouterClaude(messages, cachingAtDepth) { | ||
| 917 | 917 | * @param {number} maxTokens Maximum tokens |
| 918 | 918 | * @param {string} reasoningEffort Reasoning effort |
| 919 | 919 | * @param {boolean} stream If streaming is enabled |
| 920 | 920 | * @returns {number?} Budget tokens |
| 921 | 921 | */ |
| 922 | 922 | export function calculateClaudeBudgetTokens(maxTokens, reasoningEffort, stream) { |
| 923 | 923 | let budgetTokens = 0; |
| 924 | 924 | |
| 925 | 925 | switch (reasoningEffort) { |
| 926 | + case REASONING_EFFORT.auto: | |
| 927 | + return null; | |
| 926 | 928 | case REASONING_EFFORT.min: |
| 927 | 929 | budgetTokens = 1024; |
| 928 | 930 | break; |
| 929 | 931 | case REASONING_EFFORT.low: |
| 930 | 932 | budgetTokens = Math.floor(maxTokens * 0.1); |
| 931 | 933 | break; |
| 932 | - case REASONING_EFFORT.auto: | |
| 933 | 934 | case REASONING_EFFORT.medium: |
| 934 | 935 | budgetTokens = Math.floor(maxTokens * 0.25); |
| 935 | 936 | break; |