From fbb3a244b7432e1c7564e19a7e1f2f7cca164ccb Mon Sep 17 00:00:00 2001 From: liuhao1024 Date: Sat, 29 Aug 2026 00:08:28 +0800 Subject: [PATCH] fix(commandcode): degrade to no-op when the deepseek plugin shim is missing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The bundled-plugin loader pops half-registered modules when a plugin fails to load, so the lazy 'from plugins.model_providers.deepseek import deepseek' could raise ImportError on every DeepSeek-routed CommandCode turn — turning the soft 'thinking uncontrollable' bug into a hard crash. Catch ImportError, log, and return the pre-fix no-op (review feedback on #95241). --- plugins/model-providers/commandcode/__init__.py | 15 +++++++++++++-- .../model_providers/test_commandcode_profile.py | 17 +++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) 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 ────────────────────────────────────────────────