Skip to content

[Bug]: think=False incorrectly sent to all provider=custom endpoints, not just Ollama #11237

@wyan-r

Description

@wyan-r

Bug Description

Summary

When a user sets reasoning_effort: none (or disables reasoning via /reasoning none),
Hermes Agent sends extra_body["think"] = false to every custom provider endpoint. The
think parameter is Ollama-specific and is rejected with HTTP 422 by any non-Ollama provider
that validates its request body.

Acceptance Criteria

  • think=False is sent to Ollama/local endpoints when reasoning is disabled.
  • think=False is not sent to cloud custom providers (Mistral, Fireworks, Together.ai, vLLM remote, etc.).
  • OpenRouter and Anthropic reasoning paths are unaffected.
  • python -m pytest tests/ -q passes with no regressions.

Labels

bug provider-compat reasoning ollama

Steps to Reproduce

  1. Configure any non-Ollama endpoint as a custom provider, e.g. Mistral AI, Fireworks,
    Together.ai, or a vLLM server:
    provider: custom
    base_url: https://api.mistral.ai/v1
    model: mistral-large-latest
  2. Disable reasoning in the CLI or config:
    /reasoning none
    
    or in config.yaml:
    reasoning_effort: none
  3. Send any message.

Expected Behavior

The unknown 'think' field should not have been sent to the provider.

Actual Behavior

Result: The provider returns HTTP 422 because it received an unknown think field:

{
  "detail": [
    {
      "type": "extra_forbidden",
      "loc": ["body", "think"],
      "msg": "Extra inputs are not permitted"
    }
  ]
}

Affected Component

Agent Core (conversation loop, context compression, memory)

Messaging Platform (if gateway-related)

No response

Debug Report

.

Operating System

Linux 6.12.74+deb13+1-amd64 x86_64

Python Version

3.11.15

Hermes Version

0.9.0

Additional Logs / Traceback (optional)

Root Cause Analysis (optional)

File: run_agent.py_build_api_kwargs()

The guard condition checks only provider == "custom", which matches all custom providers
regardless of their URL:

if self.provider == "custom" and self.reasoning_config and isinstance(self.reasoning_config, dict):
    _effort = (self.reasoning_config.get("effort") or "").strip().lower()
    _enabled = self.reasoning_config.get("enabled", True)
    if _effort == "none" or _enabled is False:
        extra_body["think"] = False  # sent to ALL custom providers

The think parameter is an Ollama-native API extension. It is not part of the OpenAI
Chat Completions specification and is not recognised by any cloud provider.

Proposed Fix (optional)

Fix

Replace the provider == "custom" guard with an Ollama-specific URL check:

# Only send think=False to Ollama/local endpoints — it is an Ollama-native parameter
# and is rejected by cloud custom providers (Mistral, Fireworks, vLLM, etc.).
_is_ollama_endpoint = (
    "ollama" in self._base_url_lower
    or ":11434" in self._base_url_lower
    or is_local_endpoint(self.base_url or "")
)
if _is_ollama_endpoint and self.reasoning_config and isinstance(self.reasoning_config, dict):
    _effort = (self.reasoning_config.get("effort") or "").strip().lower()
    _enabled = self.reasoning_config.get("enabled", True)
    if _effort == "none" or _enabled is False:
        extra_body["think"] = False

is_local_endpoint() is already imported in run_agent.py and returns True for
localhost, 127.0.0.1, and 0.0.0.0 addresses — which covers all local Ollama setups
regardless of port.


Impact

  • Affected: Any user with provider=custom pointing to a non-Ollama endpoint who has
    reasoning_effort set to none or has disabled reasoning.
  • Not affected: Ollama users (fix preserves existing behaviour).
  • Not affected: OpenRouter, Anthropic, AWS Bedrock — these use separate code paths.

Files Changed

File Change
run_agent.py Replace provider == "custom" guard with Ollama URL detection

Are you willing to submit a PR for this?

  • I'd like to fix this myself and submit a PR

Metadata

Metadata

Assignees

No one assigned

    Labels

    type/bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions