diff --git a/agent/auxiliary_client.py b/agent/auxiliary_client.py index 91b4fd5d20..34966ae0fa 100644 --- a/agent/auxiliary_client.py +++ b/agent/auxiliary_client.py @@ -6157,7 +6157,14 @@ def _merge_aux_extra_body( if reasoning_config.get("enabled") is False: merged_extra["reasoning"] = {"enabled": False} else: - merged_extra["reasoning"] = {"enabled": True, "effort": reasoning_config.get("effort") or "medium"} + # This fallback uses the OpenAI-compatible chat-completions wire. Hermes' + # internal ``ultra`` tier is not accepted there, including for MoA slots. + from agent.reasoning_effort import OPENAI_COMPAT_WIRE_EFFORTS, clamp_effort + effort = reasoning_config.get("effort") or "medium" + merged_extra["reasoning"] = { + "enabled": True, + "effort": clamp_effort(effort, OPENAI_COMPAT_WIRE_EFFORTS), + } # Portal tags + sticky session_id fallback when the profile didn't supply them; session_id # keeps aux calls on the main turn's upstream instance (cache warmth) — tags alone are not # enough on /v1/messages. diff --git a/tests/agent/test_auxiliary_client.py b/tests/agent/test_auxiliary_client.py index 0d11dfe2d5..3e51216365 100644 --- a/tests/agent/test_auxiliary_client.py +++ b/tests/agent/test_auxiliary_client.py @@ -2499,6 +2499,26 @@ class TestStaleBaseUrlWarning: class TestAuxiliaryTaskExtraBody: + @pytest.mark.parametrize("task", ["session_search", "moa_reference", "moa_aggregator"]) + def test_generic_reasoning_fallback_clamps_ultra_for_auxiliary_and_moa_calls(self, task, monkeypatch): + """The OpenAI-compatible fallback must never put Hermes-only ``ultra`` on the wire.""" + from agent.auxiliary_client import _ProfileProjection, _build_call_kwargs + + monkeypatch.setattr( + "agent.auxiliary_client._project_provider_profile", + lambda *_args: _ProfileProjection({}, {}, {}, False), + ) + + kwargs = _build_call_kwargs( + provider="custom", + model="test-model", + messages=[{"role": "user", "content": "hello"}], + reasoning_config={"enabled": True, "effort": "ultra"}, + task=task, + ) + + assert kwargs["extra_body"]["reasoning"] == {"enabled": True, "effort": "max"} + def test_sync_call_merges_task_extra_body_from_config(self): client = MagicMock() client.base_url = "https://api.example.com/v1"