Skip to content

[FEATURE] headroom wrap claude should preserve the 1M context window (Claude Code drops context-1m behind a custom ANTHROPIC_BASE_URL) #1158

Description

@pcamarajr

Problem Statement

headroom wrap claude is the recommended Claude Code integration, but it silently caps the usable context at 200k for subscription users who are entitled to the 1M window. Plain claude gives 1M; the same config through wrap claude drops to 200k (status line and auto-compaction both assume 200k).

This is not a headroom bug — the root cause is in Claude Code: when ANTHROPIC_BASE_URL points at a custom host (the headroom proxy), Claude Code does not send the context-1m-2025-08-07 beta header, and treats the window as 200k. I verified this from headroom's own inbound proxy log (~/.headroom/logs/proxy.log): while wrapped, the anthropic-beta header Claude Code sends omits context-1m entirely, e.g.

anthropic-beta: claude-code-20250219,oauth-2025-04-20,interleaved-thinking-2025-05-14,
                context-management-2025-06-27,token-counting-2024-11-01

headroom itself is fine: it forwards anthropic-beta, doesn't intercept /v1/models, and already sizes Opus 4.8 at 1M internally via LiteLLM. Upstream tracking issue: anthropics/claude-code#68522.

The reason to handle it here: wrap claude owns the launched claude process's environment, and it's the documented Claude Code path — so users will hit this and (understandably) blame headroom first.

Proposed Solution

On the wrap claude path, optionally preserve the 1M window. The workaround that works is forcing the model suffix via env on the launched process:

ANTHROPIC_MODEL='claude-opus-4-8[1m]' claude

With that, Claude Code sends context-1m-2025-08-07 and the 1M window activates through the proxy. (Note: CLAUDE_CODE_AUTO_COMPACT_WINDOW=1000000 alone does not lift the cap, and relying on the saved /model opus[1m] picker selection does not survive a custom base URL.)

Preferred shape — an opt-in flag:

headroom wrap claude --1m        # sets ANTHROPIC_MODEL='<resolved-opus-model>[1m]' for the launched process

Opt-in is safer than auto-enabling, because sonnet[1m] bills usage credits on every plan and Opus[1m] needs usage credits on Pro — so silently appending [1m] could cost users money unexpectedly.

At minimum, a docs note on the wrap page describing the gotcha and the env workaround (linking claude-code#68522) would already save users a long debugging session.

Use Case

  • Daily driver: Claude Code on a Max plan via headroom wrap claude, working in large codebases where the 1M window matters.
  • Without this, you must choose per-session between compression (wrap claude, capped at 200k) and the full 1M window (plain claude, no compression) — you can't get both, even though the wire and the proxy both support 1M.
  • Token impact: lets long sessions use the full 1M window and headroom compression together, instead of being forced to 200k.

Alternatives Considered

  • Inject context-1m into the outbound anthropic-beta at the proxy. Ineffective: even if the wire then allows 1M, Claude Code's local accounting still assumes 200k and auto-compacts there, so usable context wouldn't change. The fix has to make Claude Code itself treat the window as 1M, which the ANTHROPIC_MODEL='...[1m]' env does.
  • CLAUDE_CODE_AUTO_COMPACT_WINDOW=1000000. Tested, no effect behind a custom base URL.
  • Leave it entirely to the upstream Claude Code fix (claude-code#68522). Reasonable long-term, but the env workaround is available now and wrap claude is the natural place to apply it.

Example API (Optional)

# Opt-in flag on the wrap path
headroom wrap claude --1m

# Equivalent to what wrap would set for the launched process:
ANTHROPIC_MODEL='claude-opus-4-8[1m]' claude

Environment

  • headroom-ai 0.26.0 (installed via pipx), macOS (arm64)
  • Claude Code 2.1.183 (native), Max plan, model opus[1m] (claude-opus-4-8)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions