Repository navigation
[Feature]: expose speed/service-tier capabilities for eligible custom providers and routed models #1436
Description
Client or integration
Codex Desktop using the OpenCodex-generated model catalog
Area
Custom providers / routed model catalog / Responses API / service tier
OpenCodex version
2.11.1
Summary
Models routed through a custom OpenAI-compatible provider cannot expose the Codex Desktop Standard / Fast speed selector, even when the upstream provider may support a priority or fast service tier.
The native ChatGPT/Codex account-pool route for the same model family exposes both reasoning effort and speed, while the routed custom-provider model exposes reasoning effort only.
This appears to be a capability-publication and provider-adaptation gap rather than a Codex Desktop rendering bug: the client displays the speed selector when the generated catalog contains service-tier metadata.
Current behaviour
For a native account-pool model, the generated catalog contains speed metadata similar to:
{
"slug": "gpt-5.6-sol",
"service_tiers": [
{
"id": "priority",
"name": "Fast",
"description": "1.5x speed, increased usage"
}
],
"additional_speed_tiers": ["fast"]
}Codex Desktop consequently offers:
Reasoning effort: Low / Medium / High / ...
Speed: Standard / Fast
For the same model routed through a custom provider, the catalog entry is namespaced but does not contain speed metadata:
{
"slug": "custom-provider/gpt-5.6-sol",
"service_tiers": null,
"additional_speed_tiers": null
}Codex Desktop then offers reasoning effort only.
The current routed-catalog normalization removes fields including:
additional_speed_tiers
service_tier
service_tiers
default_service_tier
Request-time OpenAI service_tier: "priority" injection is also restricted to an openai-responses route with supportsServiceTier: true.
This is safe as a default, but there is no supported opt-in path for a custom provider/model whose upstream capability has been verified.
Expected behaviour
Allow custom providers or individual routed models to explicitly declare a verified speed/service-tier capability.
When that capability is enabled, OpenCodex should:
- preserve or generate the appropriate
service_tierscatalog metadata; - expose the speed selector to compatible clients such as Codex Desktop;
- map the selected tier to the verified upstream parameter;
- keep the capability disabled for unknown or unsupported providers;
- avoid inferring support from the model name alone.
Suggested configuration contract
A provider-level capability could reuse the existing safety boundary:
{
"adapter": "openai-responses",
"supportsServiceTier": true
}A per-model capability would be safer when only some upstream models support it:
{
"models": {
"gpt-5.6-sol": {
"supportsServiceTier": true,
"serviceTiers": ["default", "priority"]
}
}
}The exact public schema can follow existing provider/model capability conventions.
For providers that use a proprietary fast-mode parameter rather than OpenAI service_tier, support should require an explicit provider-specific mapping. OpenCodex should not create a UI-only switch that has no runtime effect.
Minimal reproduction
- Configure the native ChatGPT/Codex account pool and start OpenCodex.
- Open Codex Desktop and select the native
gpt-5.6-solcatalog entry. - Observe both reasoning-effort and
Standard / Fastcontrols. - Configure a custom OpenAI-compatible provider that exposes a routed
gpt-5.6-solmodel. - Refresh the generated catalog and select
custom-provider/gpt-5.6-sol. - Observe that reasoning effort is available but the speed control is absent.
- Inspect the catalog and compare
service_tiers/additional_speed_tiersbetween the two entries.
No credentials or upstream URLs are required to demonstrate the catalog difference.
Safety requirements
- Do not infer speed-tier support from
gpt-5.6-solor any other model name. - Do not inject
service_tierinto providers with false or unknown capability. - Do not advertise
Fastunless selecting it changes the effective upstream request. - Preserve provider/model namespacing so capability does not leak across providers exposing the same model ID.
- Expose unsupported or unknown capability clearly in the dashboard rather than silently accepting an ineffective setting.
Acceptance criteria
- A custom provider can explicitly opt into OpenAI-compatible service-tier support.
- A custom provider can opt in per model rather than only globally.
- Eligible routed catalog entries retain or generate speed-tier metadata.
- Codex Desktop displays
Standard / Fastfor an eligible routed model. - Selecting
Fastproduces the verified upstream parameter, such asservice_tier: "priority". - Unsupported and unknown providers continue to omit the parameter and speed metadata.
- Model-name similarity alone never enables the capability.
- Catalog behavior and request-time routing use the same effective capability decision.
- Regression tests cover native, supported custom, unsupported custom, and mixed-capability provider models.
Relationship to existing work
Related to #1086, which tracks per-model service-tier override policy after provider capability is already known.
This request covers the preceding gap: allowing an eligible custom provider/model to declare that capability and publish it through the routed catalog. It does not request bypassing the existing supportsServiceTier safety gate.
Checks
- I searched existing service-tier and custom-provider issues.
- The reproduction contains no API keys, credentials, account identifiers, or upstream URLs.
- The proposal preserves capability gating and does not assume that every OpenAI-compatible provider supports priority service tiers.
Activity
github-actions commentedon Aug 10, 2026
Maintainer decision respected
A maintainer has reopened this issue. The automated closure has been deactivated.
Ingwannu commentedon Aug 11, 2026
Confirmed against current
dev@849ab5e35: this is a real capability-publication gap, not a Codex Desktop rendering defect.normalizeRoutedCatalogEntry()currently deletesadditional_speed_tiers,service_tier,service_tiers, anddefault_service_tierfrom every routed row. Separately, the request path only forces the global Fast value when the final route isopenai-responsesand the provider resolvessupportsServiceTier === true; the later gate strips explicitly unsupported providers and does not infer capability from the model name. There is therefore no supported contract that can both advertise Fast for one verified routed model and map that selection to its effective upstream wire.This is related to, but not a duplicate of, #1086. #1436 owns capability declaration, catalog publication, and any provider-specific wire mapping. #1086 owns per-model Auto/Default/Priority policy after the route is already known to support the capability.
A safe implementation should use one effective capability resolver at both boundaries:
service_tieronly for verified compatible Responses routes, with separate explicit mappings for proprietary speed knobs;The runtime/config portion should land and be validated independently of broader GUI changes. I am leaving this open as a valid enhancement; it is not a current request-loss regression and should not be bundled into unrelated picker/UI cleanup.
lidge-jun commentedon Aug 15, 2026
Implemented on
devand verified at 02728d2 — closing.Service-tier capability resolves provider-locally with exact-model overrides winning and an explicit
falsefailing closed (src/providers/service-tier.ts:24,:44), and the final wire compatibility check is part of the same decision (:128). Both the catalog metadata (src/codex/catalog/effort.ts:142) and the runtime injection (src/server/responses/core.ts:1093) require the effective capability to be exactlytrue, so an unknown provider neither advertises a tier nor gets one injected upstream.Smoke evidence on the remote validation host:
bun test tests/service-tier-capability.test.ts tests/codex-catalog.test.ts→ 204 pass / 0 fail, 884 expect() calls, including the undeclared-model case and the supported/unknown/blocked provider matrix.