Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

feat: Add Ollama reasoning mode support for deepseek-r1 and similar models #916

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

Merged
tombii merged 6 commits into dev from ollama_thinking
Oct 11, 2025

Conversation

Copy link
Collaborator

@tombii tombii commented Oct 10, 2025

Summary

Adds support for Ollama's reasoning parameter to properly handle reasoning/thinking models like deepseek-r1.

Changes

  • New setting: llm.ollama.reasoning (checkbox, default: true)

    • When enabled, separates thinking/reasoning content from the main response
    • Reasoning content is stored in additional_kwargs["reasoning_content"]
    • Prevents reasoning blocks from appearing in final answers
  • Code changes:

    • Updated llm_config.py to pass reasoning parameter to ChatOllama
    • Added setting definition to default_settings.json
  • Bug fix:

    • Capped progress display at 100% in page title (prevents "Research (102%)" displays)

Why This Matters

Models like deepseek-r1 output structured thinking blocks (chain-of-thought reasoning) that should be excluded from final answers. Without this parameter, the thinking blocks appear in research results, making them verbose and harder to read.

With reasoning=True (recommended default), the thinking is separated and the user gets clean, concise answers.

Test Plan

  • Verify new setting appears in LLM settings UI
  • Test with deepseek-r1 model and confirm thinking is excluded
  • Test with regular Ollama models to ensure no regression
  • Verify progress display caps at 100%

🤖 Generated with Claude Code

- Add llm.ollama.reasoning setting (checkbox, default: true)
- When enabled, separates thinking/reasoning content from main response
- Reasoning content is stored in additional_kwargs["reasoning_content"]
- Fix progress display to cap at 100% in page title
This enables proper handling of reasoning models like deepseek-r1 that
output structured thinking blocks that should be excluded from final answers.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Copy link

claude bot commented Oct 10, 2025
edited
Loading

Claude finished @tombii's task —— View job


Pull Request Review

Reviewing PR #916: feat: Add Ollama reasoning mode support for deepseek-r1 and similar models

Todo List:

  • Read repository guidelines (CLAUDE.md)
  • Analyze version file changes
  • Review LLM config implementation
  • Examine default settings structure
  • Review progress display fix
  • Check for potential bugs and security issues
  • Assess performance considerations
  • Evaluate test coverage needs
  • Provide comprehensive feedback

Review Feedback

Code Quality & Implementation

Strong Points:

  • Clean, well-documented implementation that follows existing patterns
  • Proper error handling with debug logging in llm_config.py:719-721
  • Consistent with existing Ollama parameter handling
  • Good separation of concerns - reasoning logic is contained to the Ollama provider

Settings Structure:

  • New llm.ollama.reasoning setting follows the established pattern in default_settings.json
  • Appropriate UI element (checkbox) and sensible default (true)
  • Good description explaining the feature's purpose

🔧 Technical Implementation

LLM Config Changes (src/local_deep_research/config/llm_config.py:709-721):

reasoning_mode = get_setting_from_snapshot(
 "llm.ollama.reasoning",
 True, # Default to True to exclude thinking from responses
 settings_snapshot=settings_snapshot,
)
if reasoning_mode is not None:
 ollama_params["reasoning"] = reasoning_mode
  • Implementation is correct and follows existing parameter handling patterns
  • Good default value (True) to prevent verbose thinking blocks in responses
  • Proper integration with the settings system

Progress Display Fix (src/local_deep_research/web/static/js/components/progress.js:592-593):

const cappedProgress = Math.max(0, Math.min(100, Math.floor(data.progress)));
  • Simple and effective fix for the progress display bug
  • Prevents display values exceeding 100%

🚨 Potential Issues

  1. Missing Category in Settings: The new setting has "category": null in default_settings.json. Consider adding it to a relevant category like "llm" for better organization in the UI.

  2. No Input Validation: While reasoning_mode is checked for None, there's no validation that it's a boolean value. Consider adding type validation.

  3. Test Coverage: No tests are included for the new functionality. Consider adding:

    • Unit tests for the reasoning parameter being passed correctly
    • Integration tests with a mock Ollama response containing reasoning content

🔒 Security Considerations

  • Low Risk: The reasoning parameter is a boolean setting that doesn't involve user input or file operations
  • Settings are properly retrieved through the established get_setting_from_snapshot mechanism
  • No new attack vectors introduced

Performance Considerations

  • Minimal Impact: Adding one boolean parameter to Ollama requests has negligible performance impact
  • Positive Impact: When enabled, this actually improves performance by reducing response size (excluding thinking content)
  • Settings retrieval is cached appropriately

📋 Suggested Improvements

  1. Add setting category:
"llm.ollama.reasoning": {
 "category": "llm", // Add this
 "description": "...",
 // ... rest of config
}
  1. Add type validation in llm_config.py:
reasoning_mode = get_setting_from_snapshot(
 "llm.ollama.reasoning",
 True,
 settings_snapshot=settings_snapshot,
)
if reasoning_mode is not None and isinstance(reasoning_mode, bool):
 ollama_params["reasoning"] = reasoning_mode
  1. Consider adding tests for the new functionality, especially testing that:
    • The reasoning parameter is correctly passed to ChatOllama
    • The setting appears in the UI as expected
    • Default behavior works correctly

🎯 Overall Assessment

This is a well-implemented feature that addresses a specific need for reasoning models like deepseek-r1. The code is clean, follows existing patterns, and includes a useful bug fix for progress display.

Recommendation: ✅ Approve with minor suggestions

The implementation is solid and ready for merge. The suggested improvements are minor enhancements that could be addressed in follow-up PRs if desired.


- Add category "llm" to llm.ollama.reasoning setting for proper UI grouping
- Add type validation to ensure reasoning_mode is boolean before use
This prevents potential type errors if the setting gets corrupted or set to an unexpected value type.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
@tombii tombii changed the base branch from main to dev October 10, 2025 12:07
Copy link
Owner

Isnt this done in the wrapper already?

"""Create a wrapper class that processes LLM outputs with remove_think_tags and token counting"""

Copy link
Owner

the PR is still draft or?

@LearningCircuit LearningCircuit marked this pull request as draft October 10, 2025 16:21
@LearningCircuit LearningCircuit linked an issue Oct 10, 2025 that may be closed by this pull request
tombii and others added 2 commits October 10, 2025 22:01
Add checkbox setting to enable/disable thinking for Ollama reasoning models
like deepseek-r1 and qwen3. When enabled, models perform reasoning but
thinking content is automatically discarded - only final answers are shown.
Changes:
- Add llm.ollama.enable_thinking checkbox setting (default: true)
- Pass reasoning parameter to ChatOllama based on user setting
- LangChain converts reasoning=true to think=true in Ollama API
- Thinking separated to additional_kwargs["reasoning_content"] (discarded)
- Enhanced remove_think_tags() to clean orphaned <think> tags from answers
When thinking enabled (default):
- Model performs reasoning for smarter responses
- Thinking content automatically discarded
- Users only see clean final answers
When thinking disabled:
- Model gives direct answers without reasoning
- Faster but potentially less thorough responses
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Update the description for llm.ollama.enable_thinking setting to accurately reflect its behavior:
- Clarify that reasoning content is automatically separated and excluded from final response
- Explain the accuracy vs speed trade-off between enabled/disabled modes
- Update model reference from qwen3 to qwen2.5
- Add recommendation to enable for better accuracy
The previous description incorrectly stated that the model "shows its reasoning process" when enabled, but the reasoning is actually discarded by LDR and only the final answer is returned.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Copy link
Collaborator Author

tombii commented Oct 10, 2025
edited
Loading

Isnt this done in the wrapper already?

"""Create a wrapper class that processes LLM outputs with remove_think_tags and token counting"""

Yes you are right but Ollama I was still seeing </think> that we need to filter out.

@tombii tombii added the claude-review Request code review by claude label Oct 10, 2025
@tombii tombii marked this pull request as ready for review October 10, 2025 20:31
return text
# Remove paired <think>...</think> tags
text = re.sub(r"<think>.*?</think>", "", text, flags=re.DOTALL)
# Remove any orphaned opening or closing think tags
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a thing that can happen?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it came up in one of my tests, where I could see answer (line 9 was already there, I only added the remove orphaned tags).

@tombii tombii merged commit 00f6a0b into dev Oct 11, 2025
37 of 41 checks passed
@tombii tombii deleted the ollama_thinking branch October 11, 2025 06:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@djpetti djpetti djpetti approved these changes

@LearningCircuit LearningCircuit Awaiting requested review from LearningCircuit LearningCircuit is a code owner

@HashedViking HashedViking Awaiting requested review from HashedViking HashedViking is a code owner

Assignees

No one assigned

Labels

claude-review Request code review by claude

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Allow /nothink for qwen 3 models

AltStyle によって変換されたページ (->オリジナル) /