fix(wrap/claude): keep --1m effective when an explicit --model is passed through

Ensure explicit Claude model arguments retain the 1M context suffix (#2915).
This commit is contained in:
Abhay Singh
2026-08-12 06:45:40 +05:30
committed by GitHub
parent ae384862a4
commit c093bf11eb
3 changed files with 108 additions and 4 deletions
+39 -4
View File
@@ -303,6 +303,33 @@ def _resolve_1m_model(current: str | None) -> str:
return base if base.endswith(_CONTEXT_1M_SUFFIX) else f"{base}{_CONTEXT_1M_SUFFIX}"
def _apply_1m_to_claude_args(args: tuple[str, ...]) -> tuple[tuple[str, ...], str | None]:
"""Add the ``[1m]`` suffix to an explicit ``--model`` in pass-through args.
Claude Code gives the ``--model`` CLI flag precedence over the
``ANTHROPIC_MODEL`` env var, so when a user passes both ``--1m`` and
``--model X`` the env-var suffix is silently shadowed and the session caps at
200k (#2915). Rewriting the flag's value the same way ``_resolve_1m_model``
rewrites the env var keeps ``--1m`` effective on the higher-precedence flag.
Handles ``--model VALUE`` and ``--model=VALUE`` (the first occurrence only, as
Claude Code honours the first). Idempotent via ``_resolve_1m_model``. Returns
``(new_args, rewritten_value)``; ``rewritten_value`` is ``None`` when no
``--model`` was present (the env-var path already covers that case).
"""
out = list(args)
for i, arg in enumerate(out):
if arg == "--model" and i + 1 < len(out):
rewritten = _resolve_1m_model(out[i + 1])
out[i + 1] = rewritten
return tuple(out), rewritten
if arg.startswith("--model="):
rewritten = _resolve_1m_model(arg.split("=", 1)[1])
out[i] = f"--model={rewritten}"
return tuple(out), rewritten
return tuple(out), None
def _normalize_tool_search_mode(value: str) -> str:
"""Validate an ``ENABLE_TOOL_SEARCH`` value and return it normalized.
@@ -4728,10 +4755,18 @@ def claude(
# force it via ANTHROPIC_MODEL on the launched process.
if context_1m:
env[_ANTHROPIC_MODEL_ENV] = _resolve_1m_model(env.get(_ANTHROPIC_MODEL_ENV))
click.echo(
f" {_ANTHROPIC_MODEL_ENV}={env[_ANTHROPIC_MODEL_ENV]} "
"(1M context window; issue #1158)"
)
# An explicit pass-through --model outranks ANTHROPIC_MODEL in Claude
# Code, so add the suffix there too or the env var is silently
# shadowed and the window stays 200k (#2915). Report what will
# actually take effect rather than the shadowed env value.
claude_args, _model_flag_1m = _apply_1m_to_claude_args(claude_args)
if _model_flag_1m is not None:
click.echo(f" --model {_model_flag_1m} (1M context window; issue #1158)")
else:
click.echo(
f" {_ANTHROPIC_MODEL_ENV}={env[_ANTHROPIC_MODEL_ENV]} "
"(1M context window; issue #1158)"
)
result = subprocess.run([claude_bin, *claude_args], env=env)
raise SystemExit(result.returncode)
@@ -160,6 +160,46 @@ def test_wrap_claude_sibling_note_accurate_under_1m_and_tool_search_optouts(
assert "kept on" not in output
def test_wrap_claude_1m_adds_suffix_to_passthrough_model_flag(
runner: CliRunner, monkeypatch: pytest.MonkeyPatch
) -> None:
# #2915: Claude Code's --model CLI flag outranks ANTHROPIC_MODEL, so with
# both --1m and an explicit --model the env-var [1m] suffix is shadowed and
# the window silently caps at 200k. The wrapper must add the suffix to the
# pass-through flag so the 1M window actually activates.
captured, output = _invoke_wrap_claude(
runner,
monkeypatch,
env={},
extra_args=("--1m", "--model", "opusplan"),
)
assert captured["child_cmd"] == ["/usr/bin/claude", "--model", "opusplan[1m]"]
# The banner reports what actually takes effect, not the shadowed env value.
assert "--model opusplan[1m]" in output
def test_wrap_claude_1m_adds_suffix_to_equals_model_flag(
runner: CliRunner, monkeypatch: pytest.MonkeyPatch
) -> None:
captured, _output = _invoke_wrap_claude(
runner,
monkeypatch,
env={},
extra_args=("--1m", "--model=opusplan"),
)
assert captured["child_cmd"] == ["/usr/bin/claude", "--model=opusplan[1m]"]
def test_wrap_claude_1m_without_model_flag_still_uses_env(
runner: CliRunner, monkeypatch: pytest.MonkeyPatch
) -> None:
# No pass-through --model: ANTHROPIC_MODEL carries the suffix as before, and
# the launched command is untouched.
captured, _output = _invoke_wrap_claude(runner, monkeypatch, env={}, extra_args=("--1m",))
assert captured["child_cmd"] == ["/usr/bin/claude"]
assert captured["child_env"]["ANTHROPIC_MODEL"].endswith("[1m]")
def test_wrap_claude_tool_search_banner_line_still_accurate_when_active(
runner: CliRunner, monkeypatch: pytest.MonkeyPatch
) -> None:
+29
View File
@@ -109,6 +109,35 @@ def test_wrap_claude_allows_claude_print_short_flag_in_passthrough_args() -> Non
assert result.exit_code == 0, result.output
# ---------------------------------------------------------------------------
# _apply_1m_to_claude_args — add the [1m] suffix to an explicit pass-through
# --model so it survives Claude Code's CLI-over-env precedence (#2915).
# ---------------------------------------------------------------------------
def test_apply_1m_rewrites_model_flag_value() -> None:
args, rewritten = wrap_mod._apply_1m_to_claude_args(("--model", "opusplan"))
assert args == ("--model", "opusplan[1m]")
assert rewritten == "opusplan[1m]"
def test_apply_1m_rewrites_equals_model_flag() -> None:
args, rewritten = wrap_mod._apply_1m_to_claude_args(("--model=opusplan",))
assert args == ("--model=opusplan[1m]",)
assert rewritten == "opusplan[1m]"
def test_apply_1m_is_idempotent_on_already_suffixed_model() -> None:
args, rewritten = wrap_mod._apply_1m_to_claude_args(("--model", "opusplan[1m]"))
assert args == ("--model", "opusplan[1m]")
assert rewritten == "opusplan[1m]"
def test_apply_1m_noop_without_model_flag() -> None:
original = ("--permission-mode", "auto", "--resume")
args, rewritten = wrap_mod._apply_1m_to_claude_args(original)
assert args == original
assert rewritten is None
# ---------------------------------------------------------------------------
# _run_proxy_only_watcher — must print banner, call setup callback, install
# signal handlers, and clean up. Heavily mocked since the real watcher