fix(auxiliary): anthropic_messages profiles keep /reasoning reachable on aux calls

commandcode-anthropic (api_mode=anthropic_messages, OpenAI-shaped base URL) lost
thinking control on compression/title/vision calls after #109530: once its class
overrides build_api_kwargs_extras, _project_provider_profile marks the profile as
handling reasoning and drops the generic extra_body.reasoning fallback that the
Anthropic adapter used to read — and the _reasoning_config gate only fired for
provider=anthropic, Portal /v1/messages ids, /anthropic URLs and MiniMax.

Carry the profile's api_mode on the projection and include it in that gate, so
any anthropic_messages profile reaches the adapter regardless of URL shape.
Chat-completions profiles are unchanged.

Before: _build_call_kwargs("commandcode-anthropic", claude-haiku, {"enabled": False})
        -> no _reasoning_config, no extra_body.reasoning; adapter defaults thinking.
After:  -> _reasoning_config={"enabled": False}.
This commit is contained in:
kshitijk4poor
2026-09-13 19:26:25 +05:30
committed by kshitij
parent db66b21ae4
commit 5dd8fa1daa
2 changed files with 28 additions and 3 deletions
+8 -3
View File
@@ -6052,6 +6052,7 @@ class _ProfileProjection(NamedTuple):
reasoning_extra: Dict[str, Any]
top_level: Dict[str, Any]
handles_reasoning: bool
messages_wire: bool = False
def _project_provider_profile(
@@ -6062,11 +6063,13 @@ def _project_provider_profile(
reasoning_extra: Dict[str, Any] = {}
top_level: Dict[str, Any] = {}
handles_reasoning = False
messages_wire = False
try:
from providers import get_provider_profile
from providers.base import ProviderProfile
profile = get_provider_profile(provider_norm)
if profile is not None:
messages_wire = profile.api_mode == "anthropic_messages"
body = profile.build_extra_body(model=model, base_url=effective_base, reasoning_config=reasoning_config) or {}
reasoning_extra, top_level = profile.build_api_kwargs_extras(
reasoning_config=reasoning_config, supports_reasoning=reasoning_config is not None,
@@ -6082,7 +6085,7 @@ def _project_provider_profile(
)
except Exception as exc:
logger.debug("_build_call_kwargs: provider profile projection failed for %s: %s", provider, exc)
return _ProfileProjection(body, reasoning_extra, top_level, handles_reasoning)
return _ProfileProjection(body, reasoning_extra, top_level, handles_reasoning, messages_wire)
def _merge_aux_extra_body(
@@ -6148,11 +6151,13 @@ def _build_call_kwargs(
kwargs["extra_body"] = merged_extra
# Anthropic Messages adapters take reasoning via a private kwarg that plain OpenAI SDK clients
# would reject; Portal Claude is dual-wire, so include it only when the catalog id selects
# /v1/messages.
# /v1/messages. A profile declaring api_mode=anthropic_messages (commandcode-anthropic) is on
# that wire regardless of URL shape — once it overrides build_api_kwargs_extras the generic
# ``extra_body.reasoning`` fallback the adapter used to read is gone, so this is its only path.
if reasoning_config and isinstance(reasoning_config, dict):
raw_base = base_url or ""
if (
provider_norm == "anthropic" or _nous_on_messages_wire(provider_norm, model)
provider_norm == "anthropic" or projection.messages_wire or _nous_on_messages_wire(provider_norm, model)
or _endpoint_speaks_anthropic_messages(raw_base) or _is_anthropic_compat_endpoint(provider_norm, raw_base)
):
kwargs["_reasoning_config"] = dict(reasoning_config)
+20
View File
@@ -2946,6 +2946,26 @@ class TestAnthropicAuxiliaryReasoningTranslation:
)
assert "_reasoning_config" not in openai_wire_kwargs
def test_anthropic_messages_profile_keeps_reasoning_reachable(self):
# commandcode-anthropic: OpenAI-shaped URL, anthropic_messages api_mode, and a profile
# class that overrides build_api_kwargs_extras (so the generic extra_body.reasoning
# fallback the adapter used to read is suppressed). The adapter must still be told.
import model_tools # noqa: F401 — triggers provider discovery
import providers
assert providers.get_provider_profile("commandcode-anthropic") is not None
rc = {"enabled": False}
kwargs = _build_call_kwargs(
"commandcode-anthropic", "claude-haiku-4-5-20251001", [{"role": "user", "content": "hi"}],
reasoning_config=rc, base_url="https://api.commandcode.ai/provider/v1",
)
assert kwargs["_reasoning_config"] == rc
chat_kwargs = _build_call_kwargs(
"commandcode", "Qwen/Qwen3.7-Max", [{"role": "user", "content": "hi"}],
reasoning_config=rc, base_url="https://api.commandcode.ai/provider/v1",
)
assert "_reasoning_config" not in chat_kwargs
class TestAuxiliaryProviderProfileReasoning:
"""Auxiliary calls must reuse provider-profile reasoning wire shapes."""