Claude: map Reasoning Effort to adaptive thinking config (#5219)
Supersedes #5105
This commit is contained in:
@@ -2182,6 +2182,9 @@
|
||||
<div class="toggle-description justifyLeft marginBot5" data-i18n="Constrains the verbosity of the model's response.">
|
||||
Constrains the verbosity of the model's response.
|
||||
</div>
|
||||
<strong class="toggle-description justifyLeft marginBot5" data-source="claude">
|
||||
On Opus 4.6 / Sonnet 4.6, a non-automatic Reasoning Effort takes precedence over Verbosity.
|
||||
</strong>
|
||||
</div>
|
||||
</div>
|
||||
<div class="range-block" data-source="claude">
|
||||
|
||||
@@ -228,6 +228,7 @@ async function sendClaudeRequest(request, response) {
|
||||
const isLimitedSampling = /^claude-(opus-4-1|sonnet-4-5|haiku-4-5|opus-4-5|opus-4-6|sonnet-4-6)/.test(request.body.model);
|
||||
const useVerbosity = /^claude-(opus-4-5|opus-4-6|sonnet-4-6)/.test(request.body.model);
|
||||
const noPrefillModel = /^claude-(opus-4-6|sonnet-4-6)/.test(request.body.model);
|
||||
const isAdaptiveModel = /^claude-(opus-4-6|sonnet-4-6)/.test(request.body.model);
|
||||
let fixThinkingPrefill = false;
|
||||
// Add custom stop sequences
|
||||
const stopSequences = [];
|
||||
@@ -305,10 +306,18 @@ async function sendClaudeRequest(request, response) {
|
||||
}
|
||||
|
||||
const reasoningEffort = request.body.reasoning_effort;
|
||||
const budgetTokens = calculateClaudeBudgetTokens(requestBody.max_tokens, reasoningEffort, requestBody.stream);
|
||||
const budgetTokens = calculateClaudeBudgetTokens(requestBody.max_tokens, reasoningEffort, requestBody.stream, isAdaptiveModel);
|
||||
|
||||
if (useThinking && Number.isInteger(budgetTokens)) {
|
||||
// No prefill when thinking
|
||||
// Adaptive thinking: returns a string effort level (like Gemini 3)
|
||||
if (useThinking && typeof budgetTokens === 'string') {
|
||||
fixThinkingPrefill = true;
|
||||
requestBody.thinking = { type: 'adaptive' };
|
||||
requestBody.output_config ??= {};
|
||||
requestBody.output_config.effort = budgetTokens;
|
||||
// top_k is not allowed in adaptive mode
|
||||
delete requestBody.top_k;
|
||||
} else if (useThinking && Number.isInteger(budgetTokens)) {
|
||||
// Traditional thinking: returns a numeric budget
|
||||
fixThinkingPrefill = true;
|
||||
const minThinkTokens = 1024;
|
||||
if (requestBody.max_tokens <= minThinkTokens) {
|
||||
@@ -332,8 +341,8 @@ async function sendClaudeRequest(request, response) {
|
||||
convertedPrompt.messages[convertedPrompt.messages.length - 1].role = 'user';
|
||||
}
|
||||
|
||||
// Verbosity = 'effort' (same values as OpenAI)
|
||||
if (useVerbosity && request.body.verbosity) {
|
||||
// Verbosity = 'effort' (same values as OpenAI) - only if not already set by adaptive thinking
|
||||
if (useVerbosity && request.body.verbosity && !requestBody.output_config?.effort) {
|
||||
betaHeaders.push('effort-2025-11-24');
|
||||
requestBody.output_config ??= {};
|
||||
requestBody.output_config.effort = request.body.verbosity;
|
||||
|
||||
@@ -1110,12 +1110,33 @@ export function cachingSystemPromptForOpenRouter(messages, ttl = undefined) {
|
||||
|
||||
/**
|
||||
* Calculate the Claude budget tokens for a given reasoning effort.
|
||||
* Returns a string effort level for adaptive thinking (Opus 4.6+), a number for traditional thinking, or null for auto.
|
||||
* @param {number} maxTokens Maximum tokens
|
||||
* @param {string} reasoningEffort Reasoning effort
|
||||
* @param {boolean} stream If streaming is enabled
|
||||
* @returns {number?} Budget tokens
|
||||
* @param {boolean} isAdaptiveModel If the model supports adaptive thinking (Opus 4.6+)
|
||||
* @returns {number|string|null} Budget tokens, effort string, or null
|
||||
*/
|
||||
export function calculateClaudeBudgetTokens(maxTokens, reasoningEffort, stream) {
|
||||
export function calculateClaudeBudgetTokens(maxTokens, reasoningEffort, stream, isAdaptiveModel) {
|
||||
// Adaptive thinking for Opus 4.6+: return effort string (like Gemini 3)
|
||||
if (isAdaptiveModel) {
|
||||
switch (reasoningEffort) {
|
||||
case REASONING_EFFORT.auto:
|
||||
return null;
|
||||
case REASONING_EFFORT.min:
|
||||
return 'low';
|
||||
case REASONING_EFFORT.low:
|
||||
return 'low';
|
||||
case REASONING_EFFORT.medium:
|
||||
return 'medium';
|
||||
case REASONING_EFFORT.high:
|
||||
return 'high';
|
||||
case REASONING_EFFORT.max:
|
||||
return 'max';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
let budgetTokens = 0;
|
||||
|
||||
switch (reasoningEffort) {
|
||||
|
||||
Reference in New Issue
Block a user