Skip to content

Conversation

@viktorxhzj
Copy link

@viktorxhzj viktorxhzj commented Nov 8, 2025

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:

  1. Reasoning Details Collection: Added handling in OpenRouterHandler to capture reasoning_details from streaming responses and yield them as ApiStreamReasoningDetailsChunk.

  2. Reasoning Details Consolidation: Implemented consolidateReasoningDetails() function in openai-format.ts that groups and merges reasoning detail chunks by index, concatenating text parts and preserving encrypted data, signatures, and format information.

  3. Conversation History Preservation: Modified Task.ts to collect reasoning details during streaming and attach them to assistant messages in conversation history, enabling models to reference previous reasoning in follow-up requests.

  4. Model-Specific Filtering: Added shouldSkipReasoningForModel() utility to exclude models like Grok-4 that only display "thinking" without useful reasoning content.

  5. Type Safety: Added ApiStreamReasoningDetailsChunk type to stream definitions and extended message content with optional reasoning_details field (with TypeScript ignore comments as it's not in the standard Anthropic types).

Design Trade-offs:

  • Used @ts-ignore comments for reasoning_details fields since they're OpenRouter-specific and not part of standard Anthropic message types
  • Reasoning details are only preserved for OpenRouter provider (cline/openrouter)
  • Format consolidation handles multiple streaming chunk patterns from OpenRouter's API

Reference Documentation:

Test Procedure

Manual Testing Steps:

  1. Configure Roo Code to use OpenRouter as the API provider
  2. Select a reasoning-capable model (e.g., DeepSeek R1, o1, etc.)
  3. Start a conversation that triggers reasoning (e.g., complex coding task)
  4. Verify reasoning content is displayed in the UI during streaming
  5. Check that subsequent requests in the same conversation maintain context (reasoning details are preserved)
  6. Test with Grok-4 model to verify reasoning is skipped (as expected)

Expected Results:

  • Reasoning content streams and displays correctly
  • Reasoning details are attached to assistant messages in conversation history
  • Follow-up requests can reference previous reasoning
  • Grok-4 models skip reasoning details collection

Testing Environment:

  • OpenRouter API with reasoning-capable models
  • VSCode extension environment

Pre-Submission Checklist

  • Issue Linked: This PR is linked to an approved GitHub Issue (see "Related GitHub Issue" above).
  • Scope: My changes are focused on the linked issue (one major feature/fix per PR).
  • Self-Review: I have performed a thorough self-review of my code.
  • Testing: New and/or updated tests have been added to cover my changes (if applicable).
  • Documentation Impact: I have considered if my changes require documentation updates (see "Documentation Updates" section below).
  • Contribution Guidelines: I have read and agree to the Contributor Guidelines.

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).

-->

  • No documentation updates are required for core functionality (internal API enhancement).
  • Optional: Could add documentation about OpenRouter reasoning details support for advanced users.

Additional Notes

Technical Notes:

  • The reasoning_details field follows OpenRouter's format specification and includes support for multiple types: reasoning.text, reasoning.encrypted, and reasoning.summary
  • The consolidation logic handles both array and single object formats from OpenRouter's streaming API
  • This feature is backward compatible and only activates when reasoning_details are present in responses

Future Considerations:

  • Could extend support to other providers if they implement similar reasoning trace features
  • May want to add user-facing toggle for reasoning details preservation
  • Consider adding metrics/telemetry for reasoning details usage

Important

Adds support for OpenRouter's reasoning details, enabling reasoning trace preservation and reuse across API requests.

  • Behavior:
    • OpenRouterHandler in openrouter.ts captures reasoning_details from streaming responses and yields them as ApiStreamReasoningDetailsChunk.
    • Task.ts collects reasoning details during streaming and attaches them to assistant messages in conversation history.
    • shouldSkipReasoningForModel() utility added to skip reasoning for models like Grok-4.
  • Transformations:
    • consolidateReasoningDetails() in openai-format.ts consolidates reasoning detail chunks by index.
    • convertToOpenAiMessages() in openai-format.ts processes reasoning details.
  • Types:
    • Adds ApiStreamReasoningDetailsChunk type in stream.ts.
    • Extends message content with optional reasoning_details field in Task.ts.

This description was created by Ellipsis for 1052d38. You can customize this summary. It will automatically update as commits are pushed.

@viktorxhzj viktorxhzj requested review from cte, jr and mrubens as code owners November 8, 2025 12:05
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. Enhancement New feature or request labels Nov 8, 2025
@roomote
Copy link
Contributor

roomote bot commented Nov 8, 2025

Rooviewer Clock   See task on Roo Cloud

Re-review completed. The previously flagged issue has been resolved:

  • Fix reasoning_details format handling in openrouter.ts to support both array and object formats

No new issues found in this commit.

Previous reviews

Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues.

Comment on lines 192 to 198
if (
"reasoning_details" in delta &&
delta.reasoning_details &&
// @ts-ignore-next-line
delta.reasoning_details.length && // exists and non-0
!shouldSkipReasoningForModel(this.options.openRouterModelId)
) {
Copy link
Contributor

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.

@hannesrudolph hannesrudolph added the Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. label Nov 8, 2025
@hannesrudolph
Copy link
Collaborator

Closed in favor of clone PR #9389 due to persistent merge conflict issues.

@github-project-automation github-project-automation bot moved this from New to Done in Roo Code Roadmap Nov 19, 2025
@github-project-automation github-project-automation bot moved this from Triage to Done in Roo Code Roadmap Nov 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Enhancement New feature or request Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. size:L This PR changes 100-499 lines, ignoring generated files.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants