diff --git a/README.md b/README.md index f52f481c0..f46e40640 100644 --- a/README.md +++ b/README.md @@ -227,7 +227,7 @@ shows an **Output Tokens Saved** card next to input compression, labelled |--------------|:---------------:|----------------------------------| | Claude Code | ✅ | `--memory` · `--code-graph` · `--1m` · `--tool-search` | | Codex | ✅ | shares memory with Claude | -| Grok CLI | ✅ | routes via `GROK_CLI_CHAT_PROXY_BASE_URL` | +| Grok CLI | ✅ | routes via `GROK_MODELS_BASE_URL` | | Cursor | Manual setup | starts proxy and prints base URLs for Cursor settings | | Aider | ✅ | starts proxy + launches | | Copilot CLI | ✅ | starts proxy + launches | diff --git a/headroom/cli/wrap.py b/headroom/cli/wrap.py index 29b706744..5c5f37a79 100644 --- a/headroom/cli/wrap.py +++ b/headroom/cli/wrap.py @@ -6381,9 +6381,10 @@ def grok( """Launch Grok CLI through Headroom proxy. \b - Sets ``GROK_CLI_CHAT_PROXY_BASE_URL`` so Grok routes inference traffic - through Headroom. Registers the headroom MCP server in ``~/.grok/config.toml`` - so Grok can call ``headroom_retrieve`` on compression markers. + Sets ``GROK_MODELS_BASE_URL`` so Grok routes inference traffic through + Headroom while preserving native settings and authentication routing. + Registers the headroom MCP server in ``~/.grok/config.toml`` so Grok can + call ``headroom_retrieve`` on compression markers. \b Examples: @@ -8210,10 +8211,11 @@ def unwrap_omp(port: int, no_stop_proxy: bool) -> None: def unwrap_grok(port: int, no_stop_proxy: bool) -> None: """Undo durable ``headroom wrap grok`` MCP and guidance edits. - Grok API routing is session-scoped via ``GROK_CLI_CHAT_PROXY_BASE_URL`` and - does not require config restoration. This command removes Headroom MCP - servers from ``~/.grok/config.toml`` and strips injected RTK guidance from - the project ``AGENTS.md``. + Grok inference routing is session-scoped via ``GROK_MODELS_BASE_URL`` and + does not require config restoration. Native settings and authentication + routing stay unchanged. This command removes Headroom MCP servers from + ``~/.grok/config.toml`` and strips injected RTK guidance from the project + ``AGENTS.md``. """ click.echo() click.echo(" ╔═══════════════════════════════════════════════╗") diff --git a/headroom/providers/grok/runtime.py b/headroom/providers/grok/runtime.py index eb9480312..2f4e150fb 100644 --- a/headroom/providers/grok/runtime.py +++ b/headroom/providers/grok/runtime.py @@ -8,7 +8,7 @@ from collections.abc import Mapping from headroom.proxy.project_context import with_project_prefix DEFAULT_API_URL = "https://api.x.ai" -PROXY_ENV_KEY = "GROK_CLI_CHAT_PROXY_BASE_URL" +PROXY_ENV_KEY = "GROK_MODELS_BASE_URL" def proxy_base_url(port: int) -> str: @@ -23,9 +23,9 @@ def build_launch_env( ) -> tuple[dict[str, str], list[str]]: """Build environment variables for Grok CLI through the local proxy. - Grok routes inference traffic through ``GROK_CLI_CHAT_PROXY_BASE_URL`` - when set (see Grok CLI auth/custom-models docs). The proxy forwards - OpenAI-compatible chat requests upstream to xAI. + Grok routes inference traffic through ``GROK_MODELS_BASE_URL`` when set. + The proxy forwards OpenAI-compatible chat requests upstream to xAI while + Grok keeps its native settings and authentication routing. ``project`` (the wrap launch directory) is encoded as a ``/p/`` base-URL prefix because Grok cannot send custom attribution headers; diff --git a/tests/test_cli/test_wrap_grok.py b/tests/test_cli/test_wrap_grok.py index 1cd278809..03053be81 100644 --- a/tests/test_cli/test_wrap_grok.py +++ b/tests/test_cli/test_wrap_grok.py @@ -44,6 +44,7 @@ def test_wrap_grok_sets_proxy_env( env = captured["env"] assert isinstance(env, dict) assert env[PROXY_ENV_KEY] == f"http://127.0.0.1:8787{_expected_project_prefix()}/v1" + assert "GROK_CLI_CHAT_PROXY_BASE_URL" not in env assert captured["tool_label"] == "GROK" assert captured["agent_type"] == "grok" assert captured["args"] == ("-p", "hello") diff --git a/tests/test_provider_grok.py b/tests/test_provider_grok.py index 08793332d..3af357ccd 100644 --- a/tests/test_provider_grok.py +++ b/tests/test_provider_grok.py @@ -8,10 +8,11 @@ def test_grok_proxy_base_url_uses_local_headroom_proxy() -> None: assert proxy_base_url(8787) == "http://127.0.0.1:8787/v1" -def test_grok_build_launch_env_sets_chat_proxy_base_url() -> None: +def test_grok_build_launch_env_sets_models_base_url() -> None: env, display = build_launch_env(9999, environ={}) assert env[PROXY_ENV_KEY] == "http://127.0.0.1:9999/v1" + assert "GROK_CLI_CHAT_PROXY_BASE_URL" not in env assert display == [f"{PROXY_ENV_KEY}=http://127.0.0.1:9999/v1"] @@ -19,6 +20,7 @@ def test_grok_build_launch_env_applies_project_prefix() -> None: env, _display = build_launch_env(8787, environ={}, project="frontend") assert env[PROXY_ENV_KEY] == "http://127.0.0.1:8787/p/frontend/v1" + assert "GROK_CLI_CHAT_PROXY_BASE_URL" not in env def test_grok_build_install_env_returns_proxy_url() -> None: