Skip to content

[Critical][Codex App] GPT-5.6 Sol is catalog-capped at 372K (353.4K effective) vs the 1.05M model spec #31860

Description

@violet-go

What version of the Codex App are you using (From “About Codex” dialog)?

Codex App 26.707.30751 (bundle build 5018), bundled CLI codex-cli 0.144.0-alpha.4, model catalog client version 0.144.0.

What subscription do you have?

ChatGPT Pro.

What platform is your computer?

Darwin 27.0.0 arm64 arm

macOS 27.0 (26A5378j), Apple Silicon.

What issue are you seeing?

Codex currently gives gpt-5.6-sol threads a 353,400-token effective context window even though the public GPT-5.6 Sol API model specification advertises a 1,050,000-token context window.

This is not only a UI rounding problem. The freshly fetched, server-provided Codex model catalog contains the following metadata for gpt-5.6-sol:

{
  "context_window": 372000,
  "max_context_window": 372000,
  "effective_context_window_percent": 95,
  "auto_compact_token_limit": null
}

Codex core therefore computes and uses this effective window:

372,000 * 0.95 = 353,400

App Server exposes model_context_window: 353400 in the thread's task_started and subsequent token-usage events, and the Codex App displays a total window of approximately 353k.

With auto_compact_token_limit absent, Codex derives the default compaction threshold from 90% of the raw catalog window:

372,000 * 0.90 = 334,800

No context-window, auto-compaction, project-level, environment-variable, or provider override is configured locally. The catalog was freshly fetched with a current ETag, so this does not appear to be stale local metadata.

The current evidence establishes a Codex catalog/runtime cap. It does not claim that the upstream model endpoint itself rejects inputs above 372,000 tokens.

What steps can reproduce the bug?

  1. Use the Codex App version above with the official openai provider and a ChatGPT Pro account.
  2. Select gpt-5.6-sol and start a fresh local thread.
  3. Open the context-window indicator. Codex reports a total usable window of approximately 353k tokens.
  4. Inspect the gpt-5.6-sol entry in ~/.codex/models_cache.json; observe context_window: 372000, max_context_window: 372000, and effective_context_window_percent: 95.
  5. Inspect the sanitized thread metadata; observe task_started.model_context_window: 353400 and the same value in subsequent token-usage events.

What is the expected behavior?

The public API model specification lists a 1,050,000-token context window for GPT-5.6 Sol:

https://developers.openai.com/api/docs/models/gpt-5.6-sol

Absent a documented Codex-specific preview cap, the Codex catalog should match that raw model window or clearly disclose the product-specific limit. With the same 95% effective-window policy, a 1,050,000-token raw window would imply approximately 997,500 usable tokens:

1,050,000 * 0.95 = 997,500

The current 353,400-token effective budget is only about 35.4% of the effective window implied by the published API model specification, a reduction of about 64.6%. The derived 334,800-token default compaction threshold is only about 31.9% of the published 1.05M raw window.

Additional information

Codex computes the effective window from the resolved catalog metadata and effective_context_window_percent:

pub(crate) fn model_context_window(&self) -> Option<i64> {
let effective_context_window_percent = self.model_info.effective_context_window_percent;
self.model_info
.resolved_context_window()
.map(|context_window| {
context_window.saturating_mul(effective_context_window_percent) / 100
})
}

The protocol defines the effective percentage and derives the default compaction limit when no explicit limit is supplied:

const fn default_effective_context_window_percent() -> i64 {
95
}
/// Model metadata returned by the Codex backend `/models` endpoint.
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, TS, JsonSchema)]
pub struct ModelInfo {
pub slug: String,
pub display_name: String,
pub description: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub default_reasoning_level: Option<ReasoningEffort>,
pub supported_reasoning_levels: Vec<ReasoningEffortPreset>,
pub shell_type: ConfigShellToolType,
pub visibility: ModelVisibility,
pub supported_in_api: bool,
pub priority: i32,
#[serde(default)]
pub additional_speed_tiers: Vec<String>,
#[serde(default)]
pub service_tiers: Vec<ModelServiceTier>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub default_service_tier: Option<String>,
pub availability_nux: Option<ModelAvailabilityNux>,
pub upgrade: Option<ModelInfoUpgrade>,
pub base_instructions: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub model_messages: Option<ModelMessages>,
#[serde(default)]
pub include_skills_usage_instructions: bool,
pub supports_reasoning_summaries: bool,
#[serde(default)]
pub default_reasoning_summary: ReasoningSummary,
pub support_verbosity: bool,
pub default_verbosity: Option<Verbosity>,
pub apply_patch_tool_type: Option<ApplyPatchToolType>,
#[serde(default)]
pub web_search_tool_type: WebSearchToolType,
pub truncation_policy: TruncationPolicyConfig,
pub supports_parallel_tool_calls: bool,
#[serde(default)]
pub supports_image_detail_original: bool,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub context_window: Option<i64>,
/// Maximum context window allowed for config overrides.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub max_context_window: Option<i64>,
/// Token threshold for automatic compaction. When omitted, core derives it
/// from `context_window` (90%). When provided, core clamps it to 90% of the
/// context window when available.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub auto_compact_token_limit: Option<i64>,
/// Opaque identifier for compaction-compatible model configurations.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub comp_hash: Option<String>,
/// Percentage of the context window considered usable for inputs, after
/// reserving headroom for system prompts, tool overhead, and model output.
#[serde(default = "default_effective_context_window_percent")]
pub effective_context_window_percent: i64,

impl ModelInfo {
pub fn resolved_context_window(&self) -> Option<i64> {
self.context_window.or(self.max_context_window)
}
pub fn auto_compact_token_limit(&self) -> Option<i64> {
let context_limit = self
.resolved_context_window()
.map(|context_window| (context_window * 9) / 10);
let config_limit = self.auto_compact_token_limit;
if let Some(context_limit) = context_limit {
return Some(
config_limit.map_or(context_limit, |limit| std::cmp::min(limit, context_limit)),
);
}
config_limit

App Server exposes the computed model context window through the thread token-usage protocol:

pub struct ThreadTokenUsageUpdatedNotification {
pub thread_id: String,
pub turn_id: String,
pub token_usage: ThreadTokenUsage,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
pub struct ThreadTokenUsage {
pub total: TokenUsageBreakdown,
pub last: TokenUsageBreakdown,
// TODO(aibrahim): make this not optional
#[ts(type = "number | null")]
pub model_context_window: Option<i64>,
}
impl From<CoreTokenUsageInfo> for ThreadTokenUsage {
fn from(value: CoreTokenUsageInfo) -> Self {
Self {
total: value.total_token_usage.into(),
last: value.last_token_usage.into(),
model_context_window: value.model_context_window,
}

The practical impact is severe for repository-scale analysis, long-running agentic coding sessions, large specifications, tool-heavy workflows, and multi-agent coordination because Codex begins managing context pressure at roughly one third of the published raw model capacity.

Related but not duplicate reports:

Please confirm whether the 372,000-token Codex cap is intentional. If it is not, the gpt-5.6-sol catalog metadata should expose the correct raw and maximum context window. If it is intentional, Codex should document the product-specific limit clearly instead of presenting 353,400 as the model's context window without explanation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    appIssues related to the Codex desktop appbugSomething isn't workingcontextIssues related to context management (including compaction)

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions