Client or integration
Other
Area
Catalog / models
Summary
A chained client (single provider hub pointing at a remote hub data plane, liveModels: true — the provider-based chained setup, not ocx connect) materializes every hub-routed row with context_window: 128000 — the parser's compatibility fallback — even though the hub already serves correct per-model windows on two surfaces. Effect: Codex compacts at ~121.6k effective tokens on 1M-class models (cursor GPT-5.6, zai GLM-5.3), silently discarding ~87% of usable context on chained machines.
Reproduction
- Hub 2.48.0,
runtimeRole: hub, per-provider modelContextWindows configured. The hub's own surfaces carry the truth:
GET /v1/catalog (the shared serializer used by the dashboard and the data-plane route): all 436 entries have context_window > 0, e.g. "slug":"cursor/gpt-5.6-sol","context_window":1000000, "slug":"zai/glm-5.3-flash","context_window":1000000, "slug":"alibaba-token-plan-intl/qwen3.8-max","context_window":983616.
GET /v1/models: "id":"cursor/gpt-5.6-sol","capabilities":{"context_length":922000,"max_output_tokens":128000,...} — per-model metadata is present here too.
- Client 2.48.0: single provider
hub (baseUrl → hub data plane /v1, liveModels: true, allowPrivateNetwork: true), ocx service install + ocx sync.
- Client catalog
~/.codex/opencodex-catalog.json: every hub/* row = "context_window": 128000, "max_context_window": 128000. hub/cursor-gpt-5.6-sol 128000 (real 1,000,000), hub/zai-glm-5.3-flash 128000 (real 1,000,000), hub/alibaba-token-plan-intl-qwen3.8-max 128000 (real 983,616). Only rows backed by the client's own local openai forward provider keep real roster values (272000) — the loss is specific to routed rows.
- Where it drops: routed-row assembly never maps the hub-served metadata into the discovered window (
applyProviderConfigHints in src/codex/catalog/provider-fetch.ts sees no discovered value), so src/codex/catalog/parsing.ts applies its 128000 compatibility fallback at materialization.
- Workaround we run today (effective, but per-client and manual): set
providers.hub.modelContextWindows on each client, keyed by the /v1/models id space, plus modelMaxInputTokens. configuredContextWindow() fills the value because discovery is absent, and the gather fingerprint (providerCatalogFingerprint includes ctxW) invalidates the cache so the next ocx sync picks it up. Result: 227/449 rows corrected on one client, 220/441 on another; a streamed call through hub/gpt-5.6-luna completes.
Papercut discovered while keying that map: the two hub surfaces disagree on id shape for nested vendors — catalog slugs are single-slash (zenmux/openai-gpt-5.6-sol) while /v1/models ids are multi-slash (zenmux/openai/gpt-5.6-sol), and the client flattens all slashes to -. Any cross-referencing code (or operator) has to collapse both sides to match.
Version
2.48.0 (hub and clients)
Operating system
Hub: Ubuntu 24.04 (Contabo VPS); clients: macOS 26 and Ubuntu VPS
Provider and model
Any hub-routed provider. Observed: cursor/gpt-5.6-sol (1,000,000 → 128,000), zai/glm-5.3-flash (1,000,000 → 128,000), alibaba-token-plan-intl/qwen3.8-max (983,616 → 128,000)
Logs or error output
No error — silent metadata loss. Verified comparison:
model hub /v1/catalog hub /v1/models capabilities client catalog after sync
cursor/gpt-5.6-sol 1,000,000 context_length 922,000 128,000
zai/glm-5.3-flash 1,000,000 — 128,000
alibaba-token-plan-intl/qwen3.8-max 983,616 — 128,000
gpt-5.6-sol (hub's own openai roster row) 272,000 context_length 922,000 128,000 (routed) vs 272,000 (local native row — correct)
Screenshots and supporting files
No response
Redacted configuration
Client (chained setup):
{
"providers": {
"hub": {
"adapter": "openai-responses",
"baseUrl": "http://<hub-tailnet-ip>:10100/v1",
"allowPrivateNetwork": true,
"authMode": "key",
"liveModels": true
}
},
"defaultProvider": "hub"
}
Workaround added per client (keys in /v1/models id space):
{
"providers": {
"hub": {
"modelContextWindows": {
"cursor/gpt-5.6-sol": 1050000,
"zenmux/openai/gpt-5.6-sol": 1050000,
"zai/glm-5.3-flash": 1000000
},
"modelMaxInputTokens": { "cursor/gpt-5.6-sol": 922000 }
}
}
}
Suggested fix
- When assembling routed rows for a provider whose listing carries per-model metadata, map
capabilities.context_length / max_output_tokens from GET /v1/models into the discovered window instead of dropping it — that alone fixes provider-based chained clients with zero operator config.
- Alternatively (or additionally), have the provider-based sync path consume the same
GET /v1/catalog payload the connect flow already downloads — it carries the operator-curated modelContextWindows truth byte-for-byte.
- Worth preserving while fixing: bare native rows correctly keep the roster's plan-effective window today (e.g. 272000 for GPT-5.6 via a ChatGPT plan, where
pricing.overrides.min_prompt_tokens: 272000 applies); routed API-billed rows should get the API truth instead of the 128k floor.
- Papercut: unify catalog-slug vs
/v1/models-id shape for nested vendors (single- vs multi-slash) so the two surfaces can be cross-referenced without collapsing separators.
Client or integration
Other
Area
Catalog / models
Summary
A chained client (single provider
hubpointing at a remote hub data plane,liveModels: true— the provider-based chained setup, notocx connect) materializes every hub-routed row withcontext_window: 128000— the parser's compatibility fallback — even though the hub already serves correct per-model windows on two surfaces. Effect: Codex compacts at ~121.6k effective tokens on 1M-class models (cursor GPT-5.6, zai GLM-5.3), silently discarding ~87% of usable context on chained machines.Reproduction
runtimeRole: hub, per-providermodelContextWindowsconfigured. The hub's own surfaces carry the truth:GET /v1/catalog(the shared serializer used by the dashboard and the data-plane route): all 436 entries havecontext_window > 0, e.g."slug":"cursor/gpt-5.6-sol","context_window":1000000,"slug":"zai/glm-5.3-flash","context_window":1000000,"slug":"alibaba-token-plan-intl/qwen3.8-max","context_window":983616.GET /v1/models:"id":"cursor/gpt-5.6-sol","capabilities":{"context_length":922000,"max_output_tokens":128000,...}— per-model metadata is present here too.hub(baseUrl→ hub data plane/v1,liveModels: true,allowPrivateNetwork: true),ocx service install+ocx sync.~/.codex/opencodex-catalog.json: everyhub/*row ="context_window": 128000, "max_context_window": 128000.hub/cursor-gpt-5.6-sol128000 (real 1,000,000),hub/zai-glm-5.3-flash128000 (real 1,000,000),hub/alibaba-token-plan-intl-qwen3.8-max128000 (real 983,616). Only rows backed by the client's own localopenaiforward provider keep real roster values (272000) — the loss is specific to routed rows.applyProviderConfigHintsinsrc/codex/catalog/provider-fetch.tssees no discovered value), sosrc/codex/catalog/parsing.tsapplies its128000compatibility fallback at materialization.providers.hub.modelContextWindowson each client, keyed by the/v1/modelsid space, plusmodelMaxInputTokens.configuredContextWindow()fills the value because discovery is absent, and the gather fingerprint (providerCatalogFingerprintincludesctxW) invalidates the cache so the nextocx syncpicks it up. Result: 227/449 rows corrected on one client, 220/441 on another; a streamed call throughhub/gpt-5.6-lunacompletes.Papercut discovered while keying that map: the two hub surfaces disagree on id shape for nested vendors — catalog slugs are single-slash (
zenmux/openai-gpt-5.6-sol) while/v1/modelsids are multi-slash (zenmux/openai/gpt-5.6-sol), and the client flattens all slashes to-. Any cross-referencing code (or operator) has to collapse both sides to match.Version
2.48.0 (hub and clients)
Operating system
Hub: Ubuntu 24.04 (Contabo VPS); clients: macOS 26 and Ubuntu VPS
Provider and model
Any hub-routed provider. Observed: cursor/gpt-5.6-sol (1,000,000 → 128,000), zai/glm-5.3-flash (1,000,000 → 128,000), alibaba-token-plan-intl/qwen3.8-max (983,616 → 128,000)
Logs or error output
No error — silent metadata loss. Verified comparison:
Screenshots and supporting files
No response
Redacted configuration
Client (chained setup):
{ "providers": { "hub": { "adapter": "openai-responses", "baseUrl": "http://<hub-tailnet-ip>:10100/v1", "allowPrivateNetwork": true, "authMode": "key", "liveModels": true } }, "defaultProvider": "hub" }Workaround added per client (keys in
/v1/modelsid space):{ "providers": { "hub": { "modelContextWindows": { "cursor/gpt-5.6-sol": 1050000, "zenmux/openai/gpt-5.6-sol": 1050000, "zai/glm-5.3-flash": 1000000 }, "modelMaxInputTokens": { "cursor/gpt-5.6-sol": 922000 } } } }Suggested fix
capabilities.context_length/max_output_tokensfromGET /v1/modelsinto the discovered window instead of dropping it — that alone fixes provider-based chained clients with zero operator config.GET /v1/catalogpayload theconnectflow already downloads — it carries the operator-curatedmodelContextWindowstruth byte-for-byte.pricing.overrides.min_prompt_tokens: 272000applies); routed API-billed rows should get the API truth instead of the 128k floor./v1/models-id shape for nested vendors (single- vs multi-slash) so the two surfaces can be cross-referenced without collapsing separators.