Skip to content

[Bug] Claude Code shows 200k context for native OpenAI models (gpt-5.6/5.5): model-info.ts omits contextWindow; NATIVE_GPT56_CONTEXT_WINDOW stale at 372k #1218

Description

@yhong91

Symptom

When routing Claude Code through opencodex (OCX) to native OpenAI models (gpt-5.6-sol / gpt-5.6-terra / gpt-5.6-luna / gpt-5.5), Claude Code displays a 200k context window for these models instead of their real ChatGPT-subscription-channel value of 272k (confirmed for gpt-5.6 by Codex rust-v0.144.6, see PR openai/codex#34009; gpt-5.5 is also 272k).

200k is Claude Code's built-in fallback when a model entry carries no max_input_tokens. The effect is that auto-compact triggers ~72k too early on these models, wasting real context budget.

Root cause

src/claude/model-info.ts:137 - the native-model discovery row is built without passing contextWindow to modelInfo():

for (const slug of nativeSlugs) {
  const id = idStyle === "readable" ? claudeCodeNativeAlias(slug) : aliasForRoute("native", slug);
  if (seen.has(id)) continue;
  seen.add(id);
  const info = modelInfo(id, `${slug} (native)`, nativeEffectiveLadder(slug), true);   // <-- 4 args, no contextWindow
  out.push(info);
  push1mVariant(info, nativeOpenAiContextWindow(slug));   // <-- uses nativeOpenAiContextWindow here
}

modelInfo() (line 84-94) treats a missing 5th contextWindow arg as undefined, which becomes max_input_tokens: null:

function modelInfo(id, displayName, ladder, imageInput, contextWindow?: number): AnthropicModelInfo {
  return {
    ...
    max_input_tokens: typeof contextWindow === "number" && contextWindow > 0 ? contextWindow : null,
    max_tokens: null,
  };
}

Compare the routed-model row at line 147, which does pass it:

const info = modelInfo(id, `${m.id} (${m.provider})`, ladder, imageInput, m.contextWindow);   // routed: passes contextWindow ✓

So native OpenAI models return max_input_tokens: null to Claude Code while routed models (claude-ocx-volcengine-coding-plan--glm-5.2, etc.) correctly carry their value.

Reproduction

OCX 2.10.2, Claude Code 2.1.220, ANTHROPIC_BASE_URL=http://127.0.0.1:10100.

$ curl -s "http://127.0.0.1:10100/v1/models?ids=cli" -H "anthropic-version: 2023-06-01" | jq '.data[] | select(.id|test("native--gpt-5")) | {id, max_input_tokens, max_tokens}'
{
  "id": "claude-ocx-native--gpt-5.6-sol",
  "max_input_tokens": null,
  "max_tokens": null
}
{
  "id": "claude-ocx-native--gpt-5.6-terra",
  "max_input_tokens": null,
  "max_tokens": null
}
{
  "id": "claude-ocx-native--gpt-5.6-luna",
  "max_input_tokens": null,
  "max_tokens": null
}

Same call for a routed model returns the real window (e.g. claude-ocx-volcengine-coding-plan--glm-5.2 -> max_input_tokens: 1000000), confirming only the native path is affected.

Evidence this is a known value that should be reported

The codebase already injects the gpt-5.6 context window for other clients to avoid exactly this 200k fallback - just not for the Claude Code /v1/models path:

  • src/codex/catalog/metadata.ts:56 - export const NATIVE_GPT56_CONTEXT_WINDOW = 372_000; (see "Caveat" below — this value is now stale).
  • src/grok/sync.ts:37-43 - comment: "Without it Grok falls back to its own default (200k) and understates models like gpt-5.6-sol, which is 372k." -> injects nativeOpenAiContextWindow(id) for Grok.
  • src/server/management/native-integration-routes.ts:412-413 - same comment + same fix for the management/native integration path.

The Grok path (#511) and the native-integration path were both fixed to carry contextWindow; the Claude Code discovery path in model-info.ts appears to have been missed.

Caveat — NATIVE_GPT56_CONTEXT_WINDOW is itself stale (372k → 272k)

While drafting this report I verified the current authoritative value against upstream Codex:

So src/codex/catalog/metadata.ts:56 (NATIVE_GPT56_CONTEXT_WINDOW = 372_000) is now stale. The gpt-5.5 entry on line 59 is already 272k and correct; only the gpt-5.6 constant lags. This means the one-line model-info.ts fix below would, as written, inject the stale 372k. The constant should be updated to 272_000 in the same change so the injected value matches the upstream-enforced window.

Suggested fix

Two changes, mirroring line 147 and reusing the same accessor already used on line 139:

-    const info = modelInfo(id, `${slug} (native)`, nativeEffectiveLadder(slug), true);
+    const info = modelInfo(id, `${slug} (native)`, nativeEffectiveLadder(slug), true, nativeOpenAiContextWindow(slug));

plus updating the stale constant:

- export const NATIVE_GPT56_CONTEXT_WINDOW = 372_000;
+ export const NATIVE_GPT56_CONTEXT_WINDOW = 272_000;

nativeOpenAiContextWindow is already imported at line 18. After both changes, /v1/models?ids=cli returns max_input_tokens: 272000 for gpt-5.6-* and 272000 for gpt-5.5, and Claude Code will account the real window instead of the 200k fallback. (Applying only the model-info.ts line without the constant update would inject the stale 372k; the constant fix is required for the value to be correct.)

(No [1m] variant is generated for gpt-5.6 since 272k < 1M - push1mVariant already guards on contextWindow < ONE_MILLION, so this change does not surface a spurious 1M row.)

Environment

  • opencodex @bitkyc08/opencodex 2.10.2
  • Claude Code 2.1.220 (model = "claude-ocx-native--gpt-5.6-sol", ANTHROPIC_BASE_URL=http://127.0.0.1:10100)
  • macOS Darwin 25.5.0

Happy to open a PR if a maintainer confirms the fix direction.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions