-
Notifications
You must be signed in to change notification settings - Fork 2.7k
feat: support openrouter reasoning_details #9127
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Re-review completed. The previously flagged issue has been resolved:
No new issues found in this commit. Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues. |
| if ( | ||
| "reasoning_details" in delta && | ||
| delta.reasoning_details && | ||
| // @ts-ignore-next-line | ||
| delta.reasoning_details.length && // exists and non-0 | ||
| !shouldSkipReasoningForModel(this.options.openRouterModelId) | ||
| ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The .length check on line 196 assumes reasoning_details is always an array, but according to the PR description and the handling in Task.ts (lines 2003-2009), OpenRouter can return reasoning details as either an array or a single object. If reasoning_details is a single object, .length will be undefined, causing the condition to fail and reasoning details to be skipped even when they exist.
The check should handle both formats:
(Array.isArray(delta.reasoning_details) ? delta.reasoning_details.length > 0 : true)Or simply remove the .length check since the subsequent handling in Task.ts correctly handles both cases.
Fix it with Roo Code or mention @roomote and request a fix.
|
Closed in favor of clone PR #9389 due to persistent merge conflict issues. |
Related GitHub Issue
Issue 9125
Roo Code Task Context (Optional)
Description
This PR implements support for OpenRouter's reasoning details feature, which allows preserving and reusing reasoning traces across API requests for reasoning-capable models.
Key Implementation Details:
Reasoning Details Collection: Added handling in
OpenRouterHandlerto capturereasoning_detailsfrom streaming responses and yield them asApiStreamReasoningDetailsChunk.Reasoning Details Consolidation: Implemented
consolidateReasoningDetails()function inopenai-format.tsthat groups and merges reasoning detail chunks by index, concatenating text parts and preserving encrypted data, signatures, and format information.Conversation History Preservation: Modified
Task.tsto collect reasoning details during streaming and attach them to assistant messages in conversation history, enabling models to reference previous reasoning in follow-up requests.Model-Specific Filtering: Added
shouldSkipReasoningForModel()utility to exclude models like Grok-4 that only display "thinking" without useful reasoning content.Type Safety: Added
ApiStreamReasoningDetailsChunktype to stream definitions and extended message content with optionalreasoning_detailsfield (with TypeScript ignore comments as it's not in the standard Anthropic types).Design Trade-offs:
@ts-ignorecomments for reasoning_details fields since they're OpenRouter-specific and not part of standard Anthropic message typesReference Documentation:
Test Procedure
Manual Testing Steps:
Expected Results:
Testing Environment:
Pre-Submission Checklist
Screenshots / Videos
N/A - Backend feature with no UI changes (reasoning display already existed)
Documentation Updates
Does this PR necessitate updates to user-facing documentation?
No documentation updates are required.
Yes, documentation updates are required. (Please describe what needs to be updated or link to a PR in the docs repository).
-->
Additional Notes
Technical Notes:
reasoning.text,reasoning.encrypted, andreasoning.summaryFuture Considerations:
Important
Adds support for OpenRouter's reasoning details, enabling reasoning trace preservation and reuse across API requests.
OpenRouterHandlerinopenrouter.tscapturesreasoning_detailsfrom streaming responses and yields them asApiStreamReasoningDetailsChunk.Task.tscollects reasoning details during streaming and attaches them to assistant messages in conversation history.shouldSkipReasoningForModel()utility added to skip reasoning for models like Grok-4.consolidateReasoningDetails()inopenai-format.tsconsolidates reasoning detail chunks by index.convertToOpenAiMessages()inopenai-format.tsprocesses reasoning details.ApiStreamReasoningDetailsChunktype instream.ts.reasoning_detailsfield inTask.ts.This description was created by
for 1052d38. You can customize this summary. It will automatically update as commits are pushed.