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:
@@ -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)
|
||||
|
||||
@@ -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."""
|
||||
|
||||
Reference in New Issue
Block a user