diff --git a/plugins/model-providers/commandcode/__init__.py b/plugins/model-providers/commandcode/__init__.py index 1b737644ac..01584c7802 100644 --- a/plugins/model-providers/commandcode/__init__.py +++ b/plugins/model-providers/commandcode/__init__.py @@ -66,8 +66,19 @@ class CommandCodeAnthropicProfile(CommandCodeProfile): m = (model or "").strip() if not m.lower().startswith("deepseek/") or len(m) <= len("deepseek/"): return {}, {} - from plugins.model_providers.deepseek import deepseek as _deepseek_profile - + try: + from plugins.model_providers.deepseek import deepseek as _deepseek_profile + except ImportError: + # The bundled-plugin loader tolerates a plugin failing to load + # (it pops the half-registered module and continues), so the + # shim may be absent. Degrade to the pre-fix no-op instead of + # crashing every DeepSeek-routed CommandCode turn. + logger.warning( + "DeepSeek provider plugin unavailable; CommandCode cannot " + "forward reasoning controls (#95232)", + exc_info=True, + ) + return {}, {} return _deepseek_profile.build_api_kwargs_extras( reasoning_config=reasoning_config, model=m.split("/", 1)[1], diff --git a/tests/plugins/model_providers/test_commandcode_profile.py b/tests/plugins/model_providers/test_commandcode_profile.py index 36d3efb625..5edfa5e7e0 100644 --- a/tests/plugins/model_providers/test_commandcode_profile.py +++ b/tests/plugins/model_providers/test_commandcode_profile.py @@ -145,6 +145,23 @@ class TestCommandCodeProfileNoThinkingInterference: assert extra_body == {} assert top_level == {} + def test_missing_deepseek_plugin_degrades_to_noop( + self, commandcode_profile, monkeypatch, caplog + ): + # The bundled-plugin loader pops half-registered modules when a + # plugin fails to load, so the deepseek shim can be absent at + # runtime; the delegation must degrade to the pre-fix no-op + # instead of crashing every DeepSeek-routed CommandCode turn. + import sys + + monkeypatch.setitem(sys.modules, "plugins.model_providers.deepseek", None) + extra_body, top_level = commandcode_profile.build_api_kwargs_extras( + reasoning_config={"enabled": False}, + model="deepseek/deepseek-v4-flash", + ) + assert extra_body == {} + assert top_level == {} + # ── Anthropic Messages profile ────────────────────────────────────────────────