Skip to content

fix(custom-profile): omit reasoning_effort="none" for remote endpoints - #65234

Closed
ajzrva-sys wants to merge 2 commits into
NousResearch:mainfrom
ajzrva-sys:fix/custom-profile-remote-reasoning-effort
Closed

fix(custom-profile): omit reasoning_effort="none" for remote endpoints#65234
ajzrva-sys wants to merge 2 commits into
NousResearch:mainfrom
ajzrva-sys:fix/custom-profile-remote-reasoning-effort

Conversation

@ajzrva-sys

@ajzrva-sys ajzrva-sys commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Fixes #65233
Related: #59660

Problem

CustomProfile.build_api_kwargs_extras() unconditionally sent reasoning_effort="none" + think=False when reasoning was disabled. Remote OpenAI-compatible APIs (ofox, Volcengine ARK, Doubao, etc.) reject reasoning_effort="none" as invalid — HTTP 400.

Fix

Only emit both fields for local endpoints. Remote endpoints get neither — server default applies.

Local endpoint detection (proper, not substring matching)

  1. urlparse for hostname extraction — avoids false positives like https://localhost.example.com being treated as local
  2. Exact hostname matches: localhost, ip6-localhost, ip6-loopback, 0.0.0.0, ::, ::1
  3. IPv6 loopback support: [::1], [::] recognized
  4. RFC1918 private/LAN ranges: 192.168.x.x, 10.x.x.x, 172.16-31.x.x via ipaddress module
  5. Link-local addresses: 169.254.x.x
  6. mDNS .local domains: Bonjour/Avahi (Ollama on other Macs, AirDrop)
  7. Fallback: no base_url → default to local (backward compat with legacy tests that don’t pass base_url)

Wire behavior

Scenario Fields emitted
disabled + local reasoning_effort="none", think=False
disabled + remote nothing
effort="none" + local reasoning_effort="none", think=False
effort="none" + remote nothing
effort=low/medium/high/max/xhigh reasoning_effort=<effort> (passed through)
enabled, no effort nothing

Testing

  • All 13 existing tests pass
  • 4 new tests added: remote-local split for both enabled=False and effort="none" paths
  • Valid effort levels (low/medium/high/max/xhigh) still pass through verbatim

@alt-glitch alt-glitch added type/bug Something isn't working comp/plugins Plugin system and bundled plugins area/config Config system, migrations, profiles P3 Low — cosmetic, nice to have labels Jul 15, 2026
@ajzrva-sys
ajzrva-sys force-pushed the fix/custom-profile-remote-reasoning-effort branch from 72e078b to fe41553 Compare July 15, 2026 22:17
CustomProfile.build_api_kwargs_extras() unconditionally sent
reasoning_effort="none" + think=False when reasoning was disabled.
This is correct for local Ollama but breaks remote OpenAI-compatible
APIs (ofox, Volcengine ARK, etc.) that reject "none" as invalid.

Only emit both fields for local endpoints (localhost/127.0.0.1).
Remote endpoints get neither — server default applies.

Fixes NousResearch#65233
Related: NousResearch#59660
@ajzrva-sys
ajzrva-sys force-pushed the fix/custom-profile-remote-reasoning-effort branch from fe41553 to 5ef4206 Compare July 15, 2026 22:21

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for isolating the current custom-profile wire regression; current main does unconditionally emit both disable fields at plugins/model-providers/custom/__init__.py:57-65.

Problems

  • plugins/model-providers/custom/__init__.py:126 uses endpoint locality as the capability test. The custom provider is documented to target any OpenAI-compatible endpoint (website/docs/integrations/providers.md:570), so locality does not establish whether an endpoint accepts reasoning_effort="none" or think. It also changes an explicit disabled setting into server-default behavior for every remote endpoint (PR lines 106-108), matching the concern raised in #65233's discussion.
  • The new remote assertions invoke the profile directly (tests/plugins/model_providers/test_custom_profile.py:73-78). The production wire path is assembled in agent/transports/chat_completions.py:582-611; add a transport-level regression test for the final kwargs.

Suggested changes

  • Model disabling support as an explicit custom-endpoint capability/profile decision rather than a hostname classification, retaining the Ollama-specific path where it is known to be required.
  • Cover both supported-disable and unsupported-disable endpoint cases through transport.build_kwargs.

Automated hermes-sweeper review.

# Only send reasoning_effort="none" + think=False to LOCAL
# endpoints (Ollama, local vLLM/llama.cpp). Remote endpoints
# reject "none" as invalid — omit entirely so server default applies.
if _is_local:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This branch infers API parameter support from network locality, but provider=custom is documented for arbitrary OpenAI-compatible endpoints (website/docs/integrations/providers.md:570). A local proxy can reject these fields and a remote endpoint can support them; please select this behavior through an explicit endpoint/provider capability instead, so enabled: false is not silently converted to an endpoint default based only on its hostname.

@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 16, 2026
…om locality

Replace the hostname-based locality heuristic with an explicit
per-provider config key reasoning_disable:

  "auto" (default) — locality heuristic (send to local, omit for remote)
  "none" — always send reasoning_effort="none" + think=False
  "omit" — never send the disable fields

A remote endpoint may accept reasoning_effort="none" (e.g. vLLM in
the cloud) and a local proxy may reject it (e.g. llama.cpp). The
locality heuristic is a guess — explicit config lets the user decide.

3 new tests: disable=none forces on remote, disable=omit suppresses
on local, disable=auto preserves existing locality behavior.

Fixes NousResearch#65233
@teknium1 teknium1 added the area/profiles Multi-profile isolation, HERMES_HOME scoping label Jul 19, 2026
@ajzrva-sys ajzrva-sys closed this Aug 1, 2026
@ajzrva-sys
ajzrva-sys deleted the fix/custom-profile-remote-reasoning-effort branch August 1, 2026 03:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/config Config system, migrations, profiles area/profiles Multi-profile isolation, HERMES_HOME scoping comp/plugins Plugin system and bundled plugins P3 Low — cosmetic, nice to have sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: CustomProfile sends reasoning_effort="none" to remote APIs, causing HTTP 400

3 participants