From a0f58c1128d59d653f3c28c7c714ce36079ccb3b Mon Sep 17 00:00:00 2001 From: Daniel Han Date: Thu, 23 Jul 2026 20:47:29 -0700 Subject: [PATCH] Unsloth start: keep Claude subagents on the local model (#7333) Add CLAUDE_CODE_SUBAGENT_MODEL=inherit to the session-only claude settings overlay so built-in subagents stay on the loaded local model. --- unsloth_cli/commands/start.py | 14 +++++++++++--- unsloth_cli/tests/test_start.py | 7 ++++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/unsloth_cli/commands/start.py b/unsloth_cli/commands/start.py index 7c768d16f5..3d407576f8 100644 --- a/unsloth_cli/commands/start.py +++ b/unsloth_cli/commands/start.py @@ -1422,10 +1422,18 @@ _DYNAMIC_SECTIONS_FLAG = "--exclude-dynamic-system-prompt-sections" def _claude_settings_overlay(model_id: str) -> str: # Session-only `claude --settings` overlay (command-line tier, no ~/.claude write): - # suppress the attribution header, and pin availableModels to the served model so a - # user allowlist can't reject it. The pin must be non-empty; [] is ignored. + # suppress the attribution header, keep every subagent on the served model (a user + # CLAUDE_CODE_SUBAGENT_MODEL pin would otherwise route delegated work off the local + # endpoint), and pin availableModels to the served model so a user allowlist can't + # reject it. The pin must be non-empty; [] is ignored. return json.dumps( - {"env": {"CLAUDE_CODE_ATTRIBUTION_HEADER": "0"}, "availableModels": [model_id]} + { + "env": { + "CLAUDE_CODE_ATTRIBUTION_HEADER": "0", + "CLAUDE_CODE_SUBAGENT_MODEL": "inherit", + }, + "availableModels": [model_id], + } ) diff --git a/unsloth_cli/tests/test_start.py b/unsloth_cli/tests/test_start.py index 36a5e51938..8ce0bcc0d4 100644 --- a/unsloth_cli/tests/test_start.py +++ b/unsloth_cli/tests/test_start.py @@ -127,6 +127,8 @@ def test_claude_settings_overlay_pins_served_model(): assert overlay["availableModels"] == [MODEL["id"]] # The attribution-header suppression is preserved alongside it. assert overlay["env"]["CLAUDE_CODE_ATTRIBUTION_HEADER"] == "0" + # Subagents fall through to the served model instead of a user's opus/sonnet pin. + assert overlay["env"]["CLAUDE_CODE_SUBAGENT_MODEL"] == "inherit" def test_install_agent_prompts_then_installs(monkeypatch): @@ -784,7 +786,10 @@ def test_connect_claude_no_launch(fake_studio): _assert_env_set(result.output, "CLAUDE_AUTOCOMPACT_PCT_OVERRIDE", "90") assert f"claude --model {MODEL['id']} --exclude-dynamic-system-prompt-sections" in result.output # Overlay is passed inline (session-only), not a path into the user's ~/.claude. - assert "--settings" in result.output + command = _launch_command(result.output) + settings = json.loads(command[command.index("--settings") + 1]) + assert settings["env"]["CLAUDE_CODE_SUBAGENT_MODEL"] == "inherit" + assert "--plugin-dir" not in command assert ".claude/settings.json" not in result.output