mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
feat: preserve reasoning details for OpenRouter models between conversation turns
- Add preserveReasoning flag to ModelInfo for reasoning-capable models - Set preserveReasoning=true for OpenRouter models that support reasoning - Ensure reasoning content is included in conversation history for continuity - Add comprehensive tests for preserveReasoning functionality Fixes #9125
This commit is contained in:
parent
e98f4b9057
commit
894d70e24c
2 changed files with 138 additions and 0 deletions
|
|
@ -29,6 +29,7 @@ describe("OpenRouter API", () => {
|
|||
supportsReasoningBudget: false,
|
||||
supportsReasoningEffort: false,
|
||||
supportedParameters: ["max_tokens", "temperature", "reasoning", "include_reasoning"],
|
||||
preserveReasoning: true,
|
||||
})
|
||||
|
||||
expect(models["anthropic/claude-3.7-sonnet:thinking"]).toEqual({
|
||||
|
|
@ -45,6 +46,7 @@ describe("OpenRouter API", () => {
|
|||
requiredReasoningBudget: true,
|
||||
supportsReasoningEffort: true,
|
||||
supportedParameters: ["max_tokens", "temperature", "reasoning", "include_reasoning"],
|
||||
preserveReasoning: true,
|
||||
})
|
||||
|
||||
expect(models["google/gemini-2.5-flash-preview-05-20"].maxTokens).toEqual(65535)
|
||||
|
|
@ -97,6 +99,7 @@ describe("OpenRouter API", () => {
|
|||
description: undefined,
|
||||
supportsReasoningEffort: undefined,
|
||||
supportedParameters: undefined,
|
||||
preserveReasoning: true,
|
||||
},
|
||||
"google-ai-studio": {
|
||||
maxTokens: 65536,
|
||||
|
|
@ -111,6 +114,7 @@ describe("OpenRouter API", () => {
|
|||
description: undefined,
|
||||
supportsReasoningEffort: undefined,
|
||||
supportedParameters: undefined,
|
||||
preserveReasoning: true,
|
||||
},
|
||||
})
|
||||
|
||||
|
|
@ -236,5 +240,122 @@ describe("OpenRouter API", () => {
|
|||
expect(textResult.maxTokens).toBe(64000)
|
||||
expect(imageResult.maxTokens).toBe(64000)
|
||||
})
|
||||
|
||||
describe("preserveReasoning flag", () => {
|
||||
it("should set preserveReasoning to true for models with reasoning support", () => {
|
||||
const mockModel = {
|
||||
name: "Test Reasoning Model",
|
||||
context_length: 128000,
|
||||
max_completion_tokens: 8192,
|
||||
pricing: {
|
||||
prompt: "0.001",
|
||||
completion: "0.002",
|
||||
},
|
||||
}
|
||||
|
||||
const result = parseOpenRouterModel({
|
||||
id: "test/reasoning-model",
|
||||
model: mockModel,
|
||||
inputModality: ["text"],
|
||||
outputModality: ["text"],
|
||||
maxTokens: 8192,
|
||||
supportedParameters: ["reasoning", "temperature"],
|
||||
})
|
||||
|
||||
expect(result.preserveReasoning).toBe(true)
|
||||
})
|
||||
|
||||
it("should set preserveReasoning to true for models with include_reasoning support", () => {
|
||||
const mockModel = {
|
||||
name: "Test Include Reasoning Model",
|
||||
context_length: 128000,
|
||||
max_completion_tokens: 8192,
|
||||
pricing: {
|
||||
prompt: "0.001",
|
||||
completion: "0.002",
|
||||
},
|
||||
}
|
||||
|
||||
const result = parseOpenRouterModel({
|
||||
id: "test/include-reasoning-model",
|
||||
model: mockModel,
|
||||
inputModality: ["text"],
|
||||
outputModality: ["text"],
|
||||
maxTokens: 8192,
|
||||
supportedParameters: ["include_reasoning", "temperature"],
|
||||
})
|
||||
|
||||
expect(result.preserveReasoning).toBe(true)
|
||||
})
|
||||
|
||||
it("should set preserveReasoning to false for models without reasoning support", () => {
|
||||
const mockModel = {
|
||||
name: "Test Non-Reasoning Model",
|
||||
context_length: 128000,
|
||||
max_completion_tokens: 8192,
|
||||
pricing: {
|
||||
prompt: "0.001",
|
||||
completion: "0.002",
|
||||
},
|
||||
}
|
||||
|
||||
const result = parseOpenRouterModel({
|
||||
id: "test/non-reasoning-model",
|
||||
model: mockModel,
|
||||
inputModality: ["text"],
|
||||
outputModality: ["text"],
|
||||
maxTokens: 8192,
|
||||
supportedParameters: ["temperature", "max_tokens"],
|
||||
})
|
||||
|
||||
expect(result.preserveReasoning).toBe(false)
|
||||
})
|
||||
|
||||
it("should set preserveReasoning to true for claude-3.7-sonnet:thinking", () => {
|
||||
const mockModel = {
|
||||
name: "Claude 3.7 Sonnet Thinking",
|
||||
context_length: 200000,
|
||||
max_completion_tokens: 8192,
|
||||
pricing: {
|
||||
prompt: "0.003",
|
||||
completion: "0.015",
|
||||
},
|
||||
}
|
||||
|
||||
const result = parseOpenRouterModel({
|
||||
id: "anthropic/claude-3.7-sonnet:thinking",
|
||||
model: mockModel,
|
||||
inputModality: ["text"],
|
||||
outputModality: ["text"],
|
||||
maxTokens: 8192,
|
||||
supportedParameters: ["reasoning"],
|
||||
})
|
||||
|
||||
expect(result.preserveReasoning).toBe(true)
|
||||
})
|
||||
|
||||
it("should set preserveReasoning to true for claude-haiku-4.5", () => {
|
||||
const mockModel = {
|
||||
name: "Claude Haiku 4.5",
|
||||
context_length: 200000,
|
||||
max_completion_tokens: 8192,
|
||||
pricing: {
|
||||
prompt: "0.001",
|
||||
completion: "0.005",
|
||||
},
|
||||
}
|
||||
|
||||
const result = parseOpenRouterModel({
|
||||
id: "anthropic/claude-haiku-4.5",
|
||||
model: mockModel,
|
||||
inputModality: ["text"],
|
||||
outputModality: ["text"],
|
||||
maxTokens: 8192,
|
||||
supportedParameters: ["reasoning"],
|
||||
})
|
||||
|
||||
expect(result.preserveReasoning).toBe(true)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -205,6 +205,11 @@ export const parseOpenRouterModel = ({
|
|||
|
||||
const supportsPromptCache = typeof cacheReadsPrice !== "undefined" // some models support caching but don't charge a cacheWritesPrice, e.g. GPT-5
|
||||
|
||||
// Check if the model supports reasoning (either through include_reasoning or reasoning parameters)
|
||||
const supportsReasoning = supportedParameters
|
||||
? supportedParameters.includes("reasoning") || supportedParameters.includes("include_reasoning")
|
||||
: false
|
||||
|
||||
const modelInfo: ModelInfo = {
|
||||
maxTokens: maxTokens || Math.ceil(model.context_length * 0.2),
|
||||
contextWindow: model.context_length,
|
||||
|
|
@ -217,6 +222,8 @@ export const parseOpenRouterModel = ({
|
|||
description: model.description,
|
||||
supportsReasoningEffort: supportedParameters ? supportedParameters.includes("reasoning") : undefined,
|
||||
supportedParameters: supportedParameters ? supportedParameters.filter(isModelParameter) : undefined,
|
||||
// Preserve reasoning in conversation history for models that support reasoning
|
||||
preserveReasoning: supportsReasoning,
|
||||
}
|
||||
|
||||
if (OPEN_ROUTER_REASONING_BUDGET_MODELS.has(id)) {
|
||||
|
|
@ -239,6 +246,8 @@ export const parseOpenRouterModel = ({
|
|||
|
||||
if (id === "anthropic/claude-3.7-sonnet:thinking") {
|
||||
modelInfo.maxTokens = anthropicModels["claude-3-7-sonnet-20250219:thinking"].maxTokens
|
||||
// Ensure reasoning is preserved for thinking models
|
||||
modelInfo.preserveReasoning = true
|
||||
}
|
||||
|
||||
// Set claude-opus-4.1 model to use the correct configuration
|
||||
|
|
@ -251,6 +260,14 @@ export const parseOpenRouterModel = ({
|
|||
if (id === "anthropic/claude-haiku-4.5") {
|
||||
modelInfo.supportsReasoningBudget = true
|
||||
modelInfo.supportsReasoningEffort = false
|
||||
// Preserve reasoning for Claude Haiku 4.5
|
||||
modelInfo.preserveReasoning = true
|
||||
}
|
||||
|
||||
// Ensure reasoning preservation for models that support reasoning budget
|
||||
// This includes models like MiniMax-M2 and other reasoning-capable models
|
||||
if (modelInfo.supportsReasoningBudget || modelInfo.requiredReasoningBudget) {
|
||||
modelInfo.preserveReasoning = true
|
||||
}
|
||||
|
||||
// Set horizon-alpha model to 32k max tokens
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue