From 2740b2be3ad213ce3ea9156228626d8a18d11fe9 Mon Sep 17 00:00:00 2001 From: Zamil Majdy Date: Thu, 16 Apr 2026 01:22:20 +0700 Subject: [PATCH] fix(backend/copilot): disable fallback model to fix prod CLI rejection (#12802) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Why / What / How **Why:** `fffbe0aad8` changed both `ChatConfig.model` and `ChatConfig.claude_agent_fallback_model` to `claude-sonnet-4-6`. The Claude Code CLI rejects this with `Error: Fallback model cannot be the same as the main model`, causing every standard-mode copilot turn to fail with exit code 1 — the session "completes" in ~30s but produces no response and drops the transcript. **What:** Set `claude_agent_fallback_model` default to `""`. `_resolve_fallback_model()` already returns `None` on empty string, which means the `--fallback-model` flag is simply not passed to the CLI. On 529 overload errors the turn will surface normally instead of silently retrying with a fallback. **How:** One-line config change + test update. ### Changes 🏗️ - `ChatConfig.claude_agent_fallback_model` default: `"claude-sonnet-4-6"` → `""` - Update `test_fallback_model_default` to assert the empty default ### Checklist 📋 #### For code changes: - [x] I have clearly listed my changes in the PR description - [x] I have made a test plan - [x] I have tested my changes according to the test plan: - [x] `poetry run pytest backend/copilot/sdk/p0_guardrails_test.py` #### For configuration changes: - [x] `.env.default` is updated or already compatible with my changes - [x] `docker-compose.yml` is updated or already compatible with my changes --- autogpt_platform/backend/backend/copilot/config.py | 5 +++-- .../backend/backend/copilot/sdk/p0_guardrails_test.py | 8 +++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/autogpt_platform/backend/backend/copilot/config.py b/autogpt_platform/backend/backend/copilot/config.py index 8792717cad..36644de680 100644 --- a/autogpt_platform/backend/backend/copilot/config.py +++ b/autogpt_platform/backend/backend/copilot/config.py @@ -156,9 +156,10 @@ class ChatConfig(BaseSettings): "history compression. Falls back to compression when unavailable.", ) claude_agent_fallback_model: str = Field( - default="claude-sonnet-4-6", + default="", description="Fallback model when the primary model is unavailable (e.g. 529 " - "overloaded). The SDK automatically retries with this cheaper model.", + "overloaded). The SDK automatically retries with this cheaper model. " + "Empty string disables the fallback (no --fallback-model flag passed to CLI).", ) claude_agent_max_turns: int = Field( default=50, diff --git a/autogpt_platform/backend/backend/copilot/sdk/p0_guardrails_test.py b/autogpt_platform/backend/backend/copilot/sdk/p0_guardrails_test.py index 9305320fea..17b54797b8 100644 --- a/autogpt_platform/backend/backend/copilot/sdk/p0_guardrails_test.py +++ b/autogpt_platform/backend/backend/copilot/sdk/p0_guardrails_test.py @@ -86,15 +86,14 @@ class TestResolveFallbackModel: assert result == "claude-sonnet-4.5-20250514" def test_default_value(self): - """Default fallback model resolves to a valid string.""" + """Default fallback model resolves to None (disabled by default).""" cfg = _make_config() with patch(f"{_SVC}.config", cfg): from backend.copilot.sdk.service import _resolve_fallback_model result = _resolve_fallback_model() - assert result is not None - assert "sonnet" in result.lower() or "claude" in result.lower() + assert result is None # --------------------------------------------------------------------------- @@ -198,8 +197,7 @@ class TestConfigDefaults: def test_fallback_model_default(self): cfg = _make_config() - assert cfg.claude_agent_fallback_model - assert "sonnet" in cfg.claude_agent_fallback_model.lower() + assert cfg.claude_agent_fallback_model == "" def test_max_turns_default(self): cfg = _make_config()