Skip to content

[Bug][High impact] Routed Fast mode is hidden and openai-chat silently drops service_tier #1504

Description

@str0203

Client or integration

Codex App

Provider or upstream service

Custom OpenAI-compatible relay providers that expose GPT-5.6 models and support OpenAI Fast mode / priority processing.

OpenCodex version

2.11.1 locally; current repository default branch also inspected on 2026-08-12.

Codex App runtime observed: 0.147.0-alpha.6.5.

Endpoint or capability

  • Codex routed model catalog speed/service-tier metadata
  • /v1/responses
  • /v1/chat/completions
  • OpenAI Fast mode via service_tier: "fast" or service_tier: "priority"

Current behaviour

Severity: high user impact / silent capability loss.

This is not only a missing cosmetic control. OpenCodex currently makes a paid latency feature unavailable for routed OpenAI-compatible providers, even when the upstream explicitly supports Fast mode. The failure is silent: the user sees no selector, receives no warning, and the upstream request may omit service_tier entirely.

A native gpt-5.6-sol catalog entry exposes the Codex App Standard / Fast speed selector. The same model routed through a custom OpenAI-compatible provider does not.

There are two independent OpenCodex behaviours causing this:

  1. normalizeRoutedCatalogEntry() unconditionally removes all speed/service-tier metadata from every routed catalog row:

    • additional_speed_tiers
    • service_tier
    • service_tiers
    • default_service_tier
  2. The Responses request parser captures service_tier into parsed.options.serviceTier, but the openai-chat adapter does not serialize that value into the upstream /v1/chat/completions body.

The generated catalog and the request pipeline therefore suppress the same capability at two different boundaries:

Native GPT-5.6 model
  -> catalog advertises Fast
  -> Codex App shows Standard / Fast
  -> service_tier can reach upstream

Routed GPT-5.6 model
  -> OpenCodex deletes Fast catalog metadata
  -> Codex App cannot offer the choice
  -> openai-chat does not serialize parsed serviceTier
  -> a Fast-capable relay cannot receive the user's choice

Typical relay onboarding provides only an API base URL and API key. Relay operators do not provide an OpenCodex-specific fragment such as:

{ "supportsServiceTier": true }

Nor should normal users need to discover and hand-edit an internal capability flag. Even after a provider has been configured as openai-responses, current routed-catalog normalization still removes the metadata required for Codex App to render the selector. The existing flag is therefore not an end-to-end user-accessible opt-in.

For latency-sensitive interactive coding sessions, this removes one of the main reasons to use a Fast-enabled relay.

Expected behaviour

A user who adds a normal OpenAI-compatible provider with a URL and key should have a supported, visible path to use Fast mode when the upstream supports it. OpenCodex should not require every relay vendor to publish OpenCodex-specific configuration.

OpenCodex should:

  1. expose Standard / Fast for a routed model when its effective provider/model route supports or has opted into Fast;
  2. forward the selected tier through both openai-responses and openai-chat, because the OpenAI protocol supports Fast mode on both APIs;
  3. provide a normal Dashboard/provider-onboarding setting or automatic capability probe rather than requiring raw JSON edits;
  4. keep catalog publication and runtime forwarding consistent by using one effective capability decision;
  5. record the effective response tier:
    • priority / fast: confirmed Fast;
    • default: confirmed downgrade;
    • missing: requested but unverified;
  6. handle an explicitly rejected service_tier safely, for example by retrying once without the parameter and marking that provider/model unsupported or unverified;
  7. never claim that Fast was active solely because it was requested.

An unknown relay may accept the field, ignore it, or reject it. That should lead to observability and safe fallback, not global suppression of the feature for every routed provider.

Minimal redacted request or reproduction

1. Configure OpenCodex and sync its model catalog into Codex App.

2. Select native gpt-5.6-sol.

3. Observe:
   - reasoning-effort selector is present;
   - speed selector with Standard / Fast is present.

4. Add a custom OpenAI-compatible provider using only its base URL and API key.
   Expose the same model as custom-provider/gpt-5.6-sol.

5. Sync/restart the Codex model catalog.

6. Select custom-provider/gpt-5.6-sol.

7. Observe:
   - reasoning-effort selector is present;
   - speed selector is absent.

8. Inspect the generated catalog:
   - native gpt-5.6-sol contains service_tiers / additional_speed_tiers;
   - custom-provider/gpt-5.6-sol contains neither.

9. Route a request over the openai-chat adapter with a parsed Fast tier.

10. Inspect the serialized upstream /v1/chat/completions body.

11. Observe that service_tier is not written into the Chat Completions request.

No provider URL or credential is required to reproduce either code-path defect.

Representative catalog difference:

[
  {
    "slug": "gpt-5.6-sol",
    "service_tiers": [
      {
        "id": "priority",
        "name": "Fast"
      }
    ],
    "additional_speed_tiers": ["fast"]
  },
  {
    "slug": "custom-provider/gpt-5.6-sol",
    "service_tiers": null,
    "additional_speed_tiers": null
  }
]

Actual response or error

There is no visible HTTP error. The defect is silent.

Redacted request/runtime metadata from a routed GPT-5.6 request:

{
  "requestedModel": "custom-provider/gpt-5.6-sol",
  "configuredServiceTier": "priority",
  "requestedServiceTier": null,
  "adapter": "openai-chat",
  "status": 200,
  "responseServiceTier": null
}

Result:
- global Fast is configured;
- the routed catalog does not display the speed selector;
- the routed request does not carry a requested tier;
- no effective tier can be verified.

Upstream documentation

OpenAI Fast mode:

https://developers.openai.com/api/docs/guides/fast-mode

The current OpenAI specification states that:

  • Fast mode can be selected with service_tier: "fast";
  • service_tier: "priority" provides the same behaviour for supported models;
  • Fast mode can be configured for both the Responses API and Chat Completions API;
  • the response object's service_tier identifies the processing tier actually used.

This means omitting service_tier from the OpenAI Chat Completions adapter is not required by the upstream protocol.

Suggested mapping or implementation notes

A robust implementation could combine the following:

  1. Automatic capability probe during provider setup/sync, cached per provider/model.
  2. First-class Dashboard control such as Fast mode: Auto / Supported / Unsupported.
  3. Optimistic OpenAI-compatible forwarding for eligible routes, with one safe retry without service_tier only after a clear unsupported-parameter response.
  4. Preserve or generate routed catalog service_tiers metadata whenever the same effective capability resolver will forward the selected tier at runtime.
  5. Serialize parsed.options.serviceTier in:
    • the openai-responses adapter;
    • the openai-chat adapter.
  6. Parse and log the response's effective service_tier as confirmed Fast, downgraded, or unverified.
  7. Scope capability state by exact namespaced provider/model identity so identically named models on different providers do not leak state.

Suggested acceptance criteria:

  • Routed catalog rows can expose Standard / Fast when the effective upstream route supports or opts into Fast.
  • URL + API key onboarding can reach this configuration through normal UI; raw JSON editing is not required.
  • openai-chat forwards the selected service_tier under a safe capability policy.
  • openai-responses uses the same effective capability decision.
  • Catalog publication and runtime forwarding cannot disagree.
  • Clear unsupported-parameter responses can downgrade once without failing the entire coding turn.
  • Effective tier is surfaced as confirmed Fast, downgraded, or unverified.
  • Tests cover supported Chat, supported Responses, ignored field, rejected field with fallback, and unsupported provider/model.
  • Identically named models on different providers remain isolated.

Additional context and attachments

This should be treated as a bug rather than only a feature request because:

  • the OpenAI-compatible Chat adapter accepts a parsed request option that it silently fails to serialize even though the upstream protocol supports it;
  • global Fast configuration can appear enabled while routed requests remain standard/unknown;
  • providers that genuinely support Fast are indistinguishable from unsupported providers in Codex App;
  • users cannot solve it through the normal URL-and-key onboarding flow;
  • functionality is silently removed rather than failing visibly.

Related issues:

This report adds a narrower protocol defect and user-accessibility requirement:

  • OpenAI Chat Completions also supports service_tier;
  • openai-chat currently does not serialize it;
  • normal URL + key onboarding needs an end-to-end path to expose and verify Fast without hand-editing internal JSON.

If maintainers prefer one tracking issue, please merge these acceptance criteria into #1436 rather than treating the behaviour as a cosmetic duplicate.

Security and privacy:

  • No API keys, account identifiers, provider URLs, or private request contents are included.
  • Any automatic probe should avoid user content and use a minimal synthetic request or provider metadata endpoint.

Checks

  • I searched existing provider and compatibility issues.
  • The request and response were redacted.
  • The expected behaviour is based on an upstream specification or a concrete client requirement.

Metadata

Metadata

Assignees

No one assigned

    Labels

    catalogModel catalog, slugs, visibility, routed entriesduplicateThis issue or pull request already existsproviderProvider adapters, OpenAI-compat presets, upstream API quirksprovider-compatibilityProvider compatibility reports

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions