Repository navigation
[Feature]: FastWire — generalize Fast mode across providers (umbrella) #1886
Description
Area
Multiple areas
What are you trying to accomplish?
Use Codex Fast mode against any provider whose API offers an accelerated processing tier — with the catalog only advertising Fast where the route can actually honor it, the wire request using each provider's own dialect, and usage/cost reporting reflecting what each attempt actually did.
This is the umbrella tracking issue for FastWire, the design that generalizes Fast mode across providers. It sequences the refactor phases and links the per-provider delivery units (starting with #1875 for xAI). The design went through a five-round adversarial review against the current code and was accepted as the implementation basis.
What prevents this today?
Fast mode is currently a single-dialect feature, with three hardwired assumptions:
- The only wire shape OpenCodex can emit is
service_tier: "priority", and only on the two OpenAI adapters (openai-chat,openai-responses). Anthropic'sspeed: "fast"+ beta header, Groq'sservice_tier: "performance", and Azure's deployment-scoped priority cannot be expressed at all. - The catalog Fast blurb is the OpenAI one ("1.5x speed, increased usage") for every provider, even where the provider's actual terms differ (xAI Priority Processing bills at 2× the standard token price).
chatServiceTiercouples chat serialization into capability resolution (serviceTierSupportForModel()inlinescanSerializeServiceTierForChatModel()), so one flag simultaneously influences catalog publication, routing-profilerequire.serviceTiereligibility, compatibility fingerprints, injection, and the gate.
Additionally, cost attribution reads top-level request fields rather than per-attempt outcomes, which mis-prices combo/fallback attempts, and there is no way to express "this provider's fast tier exists but is entitlement-gated" without either lying in the catalog or blocking the capability entirely.
What should OpenCodex do?
Separate three concerns that are currently entangled (existing config field names unchanged):
- FastCapability — may this provider/model/auth route offer Fast at all? Existing tri-state fields:
supportsServiceTier(provider-level,falseis fail-closed),modelSupportsServiceTier(exact-match), auth-mode overlay. - CallerTierForward — may caller-supplied foreign tiers (
flex, unknown strings) be forwarded? This becomeschatServiceTier's sole duty after migration. - FastWire — how does canonical Fast serialize on this route? A new registry descriptor:
kind: "service-tier" | "anthropic-speed", acanonicalToWiremap,foreignCallerTiers: "verbatim" | "drop", optionalbetas.
Key behaviors:
- The Codex-side contract never changes. The catalog always publishes
service_tiers: [{id: "priority", name: "Fast"}]; the internal canonical tier stays"priority"; translation to the provider dialect happens only at the final serialization step. FastPolicyAuthority+ one pure resolver. Catalog flights capture an immutable authority before takeoff (declaration tri-statefastWire: FastWire | null | undefined, precomputedmodelWireOverrideAllowedcovering the canonical-OpenAI-forward wire-override guard, auth transport, capability maps, model adapters, hard pins, route pins).resolveFastPolicy(authority, modelId, inbound)is shared by catalog and runtime.capability(pure tri-state) stays separate fromeligibility(eligible | capability-unsupported | unclassified | wire-unavailable | pin-unavailable); catalog, routing, and injection consume onlyeligibility === "eligible".- The outbound decision honors the existing three-state contract.
support === false: fail-closed strip.support === undefined: full passthrough —fastModedoes not intervene, no translation, no injection (today's behavior, preserved). Onlysupport === true ∧ fastWire ≠ nullenters theforce-fast / force-default / inheritstate machine. - Billing truth moves per attempt. Each attempt records an
AttemptTierOutcome(canonical tier, wire kind/value,fastOutcome: not-requested | applied | downgraded | unknown, confirmation, response echo). Pricing becomes an explicit(provider, model, tierBand)matrix; a missing cell with no per-entrypriceRelation: "gte-standard"evidence yieldscost unavailable ("unpriced-tier")rather than a guessed multiplier. - Fast is a routing preference, not a requirement. A route that cannot express Fast strips it and records
fastOutcome: "downgraded"; it never filters candidates.
Provider defaults (registry):
| Provider | fastWire | capability default |
|---|---|---|
| OpenAI / ChatGPT | derived default (service-tier / priority) |
true (status quo) |
| xAI (API key) | service-tier / priority |
key-auth overlay true — #1875, held until pricing verified |
| Azure OpenAI | service-tier / priority |
undefined (never false); per-deployment exact-model opt-in |
| OpenRouter | service-tier / priority |
provider undefined; verified slugs exact-true, each with an atomic route pin (final only ⊆ pin ∧ allow_fallbacks: false; conflict downgrades Fast instead of overriding user routing) |
| Groq | service-tier / performance |
false; enterprise users opt in explicitly |
| Cerebras | service-tier / priority |
false; dedicated-endpoint users opt in |
| Anthropic | anthropic-speed / fast + betas |
undefined; verified in Phase C |
explicit null |
deferred — no Interactions wire path yet | |
Kimi / MiniMax -highspeed |
excluded | separate model IDs, not a request tier; the Fast toggle must never silently swap models |
Delivery phases:
- A0 — characterization only (zero production changes): lock the current three-state
fastModecontract, thesupport undefined × fastMode × caller {priority, fast, flex}matrix, exact-model foreign-tier forwarding,requestedServiceTierrecording timing, routing-profilerequire.serviceTierevidence, fingerprint projection, raw-body observation points, catalog byte goldens, and the two known bugs below as current behavior. - A1 — pure refactor (zero outbound-wire bytes, zero catalog bytes):
FastWire/FastPolicyAuthority/ResolvedFastPolicy/ tier-decision state machine land; kind→adapter table contains only the existing two adapters; inbound normalization produces internal markers only. - B0 — observability (zero upstream-wire change; intentional new logging): per-attempt outcomes,
callerServiceTierraw evidence, value-aware gate, fingerprint projection, dashboard per-attempt display. - B1 — capability semantic migration (one complete delivery):
fastCapabilityForModel()replaces the resolver's inline chat-serializer coupling. Three precisely-scoped behavior changes: (a) provider-true∧ chat adapter ∧chatServiceTier ≠ true∧ no exact-true→ injection starts working; (b) caller"fast"on supported routes → serialized as the canonical translation; (c) exact-true∧chatServiceTier ≠ true∧ caller foreign tier → dropped instead of forwarded. - Bug fixes (independent units): native chat path ignores model-level
false; chat→responses converter dropsservice_tier. - B2 — xAI ([Feature]: enable xAI API-key Priority Processing in Codex Fast mode #1875): capability + catalog description + pricing-matrix entry in one merge unit.
- B2+ — OpenRouter / Azure OpenAI / Groq / Cerebras: one unit each.
- C —
anthropic-speedwire kind, after live verification on both auth entries.
Out of scope: Google Interactions API, requirement-mode routing, multi-tier UI beyond Fast, model-swap "highspeed" variants.
Example usage or interface
A Groq enterprise user with Performance-tier entitlement opts in with one line:
{
"providers": {
"groq": { "supportsServiceTier": true }
},
"fastMode": true
}Because the registry already declares Groq's wire shape (canonicalToWire: { priority: "performance" }), the effective Chat Completions body becomes:
{
"model": "llama-3.3-70b-versatile",
"service_tier": "performance"
}while the Codex catalog row advertises the same priority/Fast tier it does everywhere else, and the usage log records wireValue: "performance" with canonical "priority". On an Anthropic route (Phase C), the same Fast selection would instead produce "speed": "fast" plus the documented beta header, and never a service_tier field.
Alternatives or workarounds
- Keep adding per-provider booleans to the current
supportsServiceTier/chatServiceTiermachinery. Rejected: it cannot express non-OpenAI dialects (Anthropic, Groq values), keeps the capability/serialization coupling, and forces every entitlement-gated provider into "lie in the catalog or block entirely". - Users can already hand-declare
modelSupportsServiceTier/chatServiceTieron custom providers, but that only works for OpenAI-dialect upstreams and silently mis-prices attempts because cost reads top-level request fields. - Treating "fast" model variants (Kimi/MiniMax
-highspeed) as the Fast toggle. Rejected: that silently swaps model IDs and billing; those stay separate catalog models.
Additional context
- Capability framework lineage: [Feature]: expose speed/service-tier capabilities for eligible custom providers and routed models #1436, fix(openai-chat): forward caller-selected service tier #1512, feat: land four rebuilt heavy drafts (service tiers, request pacing, native chat, empty-completion guard) #1752.
- xAI delivery unit: [Feature]: enable xAI API-key Priority Processing in Codex Fast mode #1875 (implementation branch exists, held unmerged until the pricing-matrix entry and catalog description land in the same unit).
- History: Phase 90 deliberately stripped inherited Fast metadata from every routed provider pending per-transport verification; FastWire restores it only where the final transport is verified, and makes the verification unit (shape vs. capability vs. pricing) explicit.
- Design provenance: five review rounds against the live code preceded this issue; the review-driven corrections (three-state passthrough preservation, per-attempt billing, atomic OpenRouter pins,
modelWireOverrideAllowed) are folded into the text above.
Checks
- I searched existing issues and documentation.
- This request describes a concrete OpenCodex workflow rather than merely naming a desired technology.
- I removed secrets and personal data.
Activity
coderabbitai commentedon Aug 17, 2026
🔗 Related PRs
#652 - feat(providers): add bounded model discovery contract [merged]
#746 - fix(providers): route GitHub Copilot Responses-only models off chat completions [open]
#860 - fix(responses): gate service tiers by provider capability [open]
#889 - fix(providers): Copilot mixed-wire routing, DeepSeek service_tier + reasoning replay, Claude 4.6/4.7 1M windows [open]
#892 - fix: bound the six remaining retained-state leaks (
#820wave 2) [merged]#1512 - fix(openai-chat): forward caller-selected service tier [merged]
#1606 - docs(devlog): routed tool-discovery profile plan with landing verification [open]
#1752 - feat: land four rebuilt heavy drafts (service tiers, request pacing, native chat, empty-completion guard) [merged]
📝 Issue Planner
Check the box below or use the
@coderabbitai plancommand to generate an implementation plan and prompts that you can use with your favorite coding assistant.🧪 Issue enrichment is currently in open beta.
To disable automatic issue enrichment, add the following to your
.coderabbit.yaml:💬 Have feedback or questions? Drop into our discord!
github-actions commentedon Aug 17, 2026
Issue reopened
The report now contains the information required by the automated check. Thanks for updating it.
[-][Design]: FastWire — generalize Fast mode across providers (umbrella)[/-][+][Feature]: FastWire — generalize Fast mode across providers (umbrella)[/+]refactor(fastwire): land FastWire policy resolution behind byte-ident…
test(fastwire): lock current service-tier behavior before the A1 refa…
Merge pull request #1892 from olddonkey/codex/fastwire-a0-characteriz…
Merge pull request #1893 from olddonkey/codex/fastwire-a1-refactor
feat(fastwire): record per-attempt tier outcomes and price from them
feat(fastwire): separate Fast capability from caller-tier forwarding
Merge pull request #1965 from olddonkey/codex/fastwire-b1-capability-…
fix(chat): forward caller service_tier through the chat-to-responses …
Merge pull request #1904 from olddonkey/codex/fastwire-chat-tier-copy
9 remaining items
test(fastwire): lock current service-tier behavior before the A1 refa…
refactor(fastwire): land FastWire policy resolution behind byte-ident…
feat(fastwire): record per-attempt tier outcomes and price from them
Merge pull request lidge-jun#1892 from olddonkey/codex/fastwire-a0-ch…
feat(fastwire): separate Fast capability from caller-tier forwarding
Merge pull request lidge-jun#1893 from olddonkey/codex/fastwire-a1-re…
Merge pull request lidge-jun#1965 from olddonkey/codex/fastwire-b1-ca…
fix(chat): forward caller service_tier through the chat-to-responses …
Merge pull request lidge-jun#1904 from olddonkey/codex/fastwire-chat-…
feat(openrouter): enable Fast on the OpenAI-backed slugs, without rou…
Merge pull request lidge-jun#2080 from olddonkey/codex/fastwire-b2-op…
fix(xai): stream OAuth Grok through Responses
fix(chat): apply the Fast capability gate to the native passthrough
feat(xai): enable Priority Processing on the API-key transport
Merge pull request lidge-jun#2072 from olddonkey/codex/fastwire-b2-xai