From dab86f23ef24f87077ddc2838fdc28c909dd0633 Mon Sep 17 00:00:00 2001 From: andy-xu-db <310751426+andy-xu-db@users.noreply.github.com> Date: Mon, 17 Aug 2026 20:04:19 +0000 Subject: [PATCH 1/3] claude: enable Claude Code native gateway model discovery Set CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1 in render_overlay so the /model picker lists every gateway Messages-API endpoint, not just the ANTHROPIC_DEFAULT_* family aliases. Skipped under a Model Provider Service: its routing header would send a discovered gateway id to a provider that can't resolve it. Co-authored-by: Isaac --- src/ucode/agents/claude.py | 5 +++++ tests/test_agent_claude.py | 11 +++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/ucode/agents/claude.py b/src/ucode/agents/claude.py index e818cdf..3046d15 100644 --- a/src/ucode/agents/claude.py +++ b/src/ucode/agents/claude.py @@ -302,6 +302,11 @@ def render_overlay( "ENABLE_TOOL_SEARCH": "1", "CLAUDE_CODE_USE_GATEWAY": "1", } + # Native /model discovery: picker lists every gateway Messages-API endpoint, + # not just the family aliases. Skipped under a provider (its routing header + # would send a discovered gateway id to a provider that can't resolve it). + if not provider: + env["CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY"] = "1" # Intentionally NOT setting ANTHROPIC_MODEL by default. Setting it produces a # duplicate catalog row in Claude Code's /model picker (e.g. "Opus 4.8 (1M # context) ✓") on top of the family-alias row from ANTHROPIC_DEFAULT_OPUS_MODEL. diff --git a/tests/test_agent_claude.py b/tests/test_agent_claude.py index b45b630..68a12be 100644 --- a/tests/test_agent_claude.py +++ b/tests/test_agent_claude.py @@ -127,6 +127,17 @@ def test_enables_use_gateway(self): overlay, _ = claude.render_overlay(WS, "s4") assert overlay["env"]["CLAUDE_CODE_USE_GATEWAY"] == "1" + def test_enables_gateway_model_discovery(self): + overlay, _ = claude.render_overlay(WS, "s4") + assert overlay["env"]["CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY"] == "1" + + def test_gateway_model_discovery_skipped_under_provider(self): + # A Model Provider Service routes every request to the external provider, + # so a discovered gateway endpoint id would reach a provider that can't + # resolve it — discovery must be off in that mode. + overlay, _ = claude.render_overlay(WS, "s4", provider="main.x.claude-svc") + assert "CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY" not in overlay["env"] + def test_sets_api_key_helper(self): overlay, _ = claude.render_overlay(WS, "s4") assert "apiKeyHelper" in overlay From a5eb90287643c56fa22bc3cac57d620784c21b1c Mon Sep 17 00:00:00 2001 From: andy-xu-db <310751426+andy-xu-db@users.noreply.github.com> Date: Thu, 20 Aug 2026 18:33:55 +0000 Subject: [PATCH 2/3] claude: gate gateway model discovery behind opt-in --- src/ucode/agents/claude.py | 9 ++++++++- tests/conftest.py | 1 + tests/test_agent_claude.py | 14 ++++++++++++-- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/ucode/agents/claude.py b/src/ucode/agents/claude.py index 3046d15..38fc127 100644 --- a/src/ucode/agents/claude.py +++ b/src/ucode/agents/claude.py @@ -40,6 +40,8 @@ from ucode.tracing import tracing_env from ucode.ui import print_err, print_note, print_success, print_warning +GATEWAY_MODEL_DISCOVERY_ENV_VAR = "ENABLE_CLAUDE_CODE_GATEWAY_MODEL_DISCOVERY" + CLAUDE_CONFIG_DIR = Path.home() / ".claude" CLAUDE_SETTINGS_PATH = CLAUDE_CONFIG_DIR / "ucode-settings.json" CLAUDE_BACKUP_PATH = APP_DIR / "claude-ucode-settings.backup.json" @@ -305,7 +307,12 @@ def render_overlay( # Native /model discovery: picker lists every gateway Messages-API endpoint, # not just the family aliases. Skipped under a provider (its routing header # would send a discovered gateway id to a provider that can't resolve it). - if not provider: + discovery_enabled = os.environ.get(GATEWAY_MODEL_DISCOVERY_ENV_VAR, "").strip().lower() in ( + "1", + "true", + "yes", + ) + if discovery_enabled and not provider: env["CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY"] = "1" # Intentionally NOT setting ANTHROPIC_MODEL by default. Setting it produces a # duplicate catalog row in Claude Code's /model picker (e.g. "Opus 4.8 (1M diff --git a/tests/conftest.py b/tests/conftest.py index 3e460ed..03d09ad 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -34,6 +34,7 @@ def _isolate_ucode_state(tmp_path, monkeypatch): # Isolate the managed-config opt-in from the developer's own shell: leaving it set changes what # `ucode`/`ucode configure` do mid-test. Tests that exercise the managed path set it explicitly. monkeypatch.delenv("ENABLE_MANAGED_AGENT_CONFIG", raising=False) + monkeypatch.delenv("ENABLE_CLAUDE_CODE_GATEWAY_MODEL_DISCOVERY", raising=False) # The model-services listing is memoized for the life of the process, so without this a cached # result would leak into the next test and make a stubbed listing look like it was never called. databricks_mod.clear_model_services_cache() diff --git a/tests/test_agent_claude.py b/tests/test_agent_claude.py index 68a12be..027ff26 100644 --- a/tests/test_agent_claude.py +++ b/tests/test_agent_claude.py @@ -127,14 +127,24 @@ def test_enables_use_gateway(self): overlay, _ = claude.render_overlay(WS, "s4") assert overlay["env"]["CLAUDE_CODE_USE_GATEWAY"] == "1" - def test_enables_gateway_model_discovery(self): + @pytest.mark.parametrize("env_value", [None, "", "0", "off", "no"]) + def test_gateway_model_discovery_disabled_unless_opted_in(self, monkeypatch, env_value): + if env_value is not None: + monkeypatch.setenv("ENABLE_CLAUDE_CODE_GATEWAY_MODEL_DISCOVERY", env_value) + overlay, _ = claude.render_overlay(WS, "s4") + assert "CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY" not in overlay["env"] + + @pytest.mark.parametrize("env_value", ["1", "true", "yes", " TRUE "]) + def test_enables_gateway_model_discovery(self, monkeypatch, env_value): + monkeypatch.setenv("ENABLE_CLAUDE_CODE_GATEWAY_MODEL_DISCOVERY", env_value) overlay, _ = claude.render_overlay(WS, "s4") assert overlay["env"]["CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY"] == "1" - def test_gateway_model_discovery_skipped_under_provider(self): + def test_gateway_model_discovery_skipped_under_provider(self, monkeypatch): # A Model Provider Service routes every request to the external provider, # so a discovered gateway endpoint id would reach a provider that can't # resolve it — discovery must be off in that mode. + monkeypatch.setenv("ENABLE_CLAUDE_CODE_GATEWAY_MODEL_DISCOVERY", "1") overlay, _ = claude.render_overlay(WS, "s4", provider="main.x.claude-svc") assert "CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY" not in overlay["env"] From 00d1a27d90bf691c3e825482b1906ece955c9253 Mon Sep 17 00:00:00 2001 From: andy-xu-db <310751426+andy-xu-db@users.noreply.github.com> Date: Thu, 20 Aug 2026 19:13:41 +0000 Subject: [PATCH 3/3] claude: simplify model discovery flag --- src/ucode/agents/claude.py | 7 +------ tests/test_agent_claude.py | 7 +++---- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/ucode/agents/claude.py b/src/ucode/agents/claude.py index 886d3d8..9f4df25 100644 --- a/src/ucode/agents/claude.py +++ b/src/ucode/agents/claude.py @@ -41,7 +41,6 @@ from ucode.ui import print_err, print_note, print_success, print_warning GATEWAY_MODEL_DISCOVERY_ENV_VAR = "ENABLE_CLAUDE_CODE_GATEWAY_MODEL_DISCOVERY" - CLAUDE_CONFIG_DIR = Path.home() / ".claude" CLAUDE_SETTINGS_PATH = CLAUDE_CONFIG_DIR / "ucode-settings.json" CLAUDE_BACKUP_PATH = APP_DIR / "claude-ucode-settings.backup.json" @@ -307,11 +306,7 @@ def render_overlay( # Native /model discovery: picker lists every gateway Messages-API endpoint, # not just the family aliases. Skipped under a provider (its routing header # would send a discovered gateway id to a provider that can't resolve it). - discovery_enabled = os.environ.get(GATEWAY_MODEL_DISCOVERY_ENV_VAR, "").strip().lower() in ( - "1", - "true", - "yes", - ) + discovery_enabled = os.environ.get(GATEWAY_MODEL_DISCOVERY_ENV_VAR) == "1" if discovery_enabled and not provider: env["CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY"] = "1" # Intentionally NOT setting ANTHROPIC_MODEL by default. Setting it produces a diff --git a/tests/test_agent_claude.py b/tests/test_agent_claude.py index 027ff26..37b7401 100644 --- a/tests/test_agent_claude.py +++ b/tests/test_agent_claude.py @@ -127,16 +127,15 @@ def test_enables_use_gateway(self): overlay, _ = claude.render_overlay(WS, "s4") assert overlay["env"]["CLAUDE_CODE_USE_GATEWAY"] == "1" - @pytest.mark.parametrize("env_value", [None, "", "0", "off", "no"]) + @pytest.mark.parametrize("env_value", [None, "", "0", "true", "yes"]) def test_gateway_model_discovery_disabled_unless_opted_in(self, monkeypatch, env_value): if env_value is not None: monkeypatch.setenv("ENABLE_CLAUDE_CODE_GATEWAY_MODEL_DISCOVERY", env_value) overlay, _ = claude.render_overlay(WS, "s4") assert "CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY" not in overlay["env"] - @pytest.mark.parametrize("env_value", ["1", "true", "yes", " TRUE "]) - def test_enables_gateway_model_discovery(self, monkeypatch, env_value): - monkeypatch.setenv("ENABLE_CLAUDE_CODE_GATEWAY_MODEL_DISCOVERY", env_value) + def test_enables_gateway_model_discovery(self, monkeypatch): + monkeypatch.setenv("ENABLE_CLAUDE_CODE_GATEWAY_MODEL_DISCOVERY", "1") overlay, _ = claude.render_overlay(WS, "s4") assert overlay["env"]["CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY"] == "1"