Skip to content

[Feature]: allow an explicit routed compaction provider when canonical OpenAI quota is exhausted #5012

Closed

Description

@1395490241lhj-code

Area

Proxy and routing

What are you trying to accomplish?

Continue a long Codex Desktop thread through an explicitly selected routed provider even when the native ChatGPT/Codex quota is exhausted.

The concrete workflow is:

  • the existing thread is opened/forked and the execution model is changed to an independently credentialed provider, e.g. agent-space/gpt-5.6-sol;
  • fresh threads through that provider work;
  • the long existing thread needs a pre-sampling compaction before the next turn;
  • I want that compaction to be handled by an explicitly selected routed provider, rather than being blocked by an unrelated exhausted canonical OpenAI quota.

This is not a request to bypass or modify OpenAI quota enforcement. The routed provider has its own credentials, billing/quota, and data-sharing boundary.

What prevents this today?

The current compaction routing keeps the canonical OpenAI reservation whenever an enabled openai provider exists.

In my reproduced case, the thread itself was recorded as routed through OpenCodex with model agent-space/gpt-5.6-sol, but resuming it caused Codex to enter PreCompact. The request then failed after five reconnect attempts with a 429.

The proxy log identified the failing request as:

provider: openai
model: gpt-5.6-luna
requestedModel: gpt-5.6-luna
errorCode: rate_limit_exceeded
upstreamError: The usage limit has been reached.

At the same time, fresh requests through agent-space succeeded.

This matches the current router behavior: routeCompactionModel() only falls back to defaultProvider for a bare OpenAI-family compaction model when canonical openai is absent or disabled. If openai is enabled but quota-exhausted, the compact request remains bound to it.

#2901 fixed the no-canonical-OpenAI case and explicitly invited a follow-up if an explicit compaction-provider override was still needed. This is that concrete case.

What should OpenCodex do?

Please provide an explicit, opt-in way for compaction to use a routed provider/model even when canonical openai is configured.

Observable requirements:

  1. A user can select a qualified provider/model for compaction independently of ordinary canonical OpenAI availability.
  2. The selection applies to both POST /v1/responses/compact and compaction_trigger paths.
  3. If a routed long-running thread requires compaction while native OpenAI quota is exhausted, compaction can complete through the explicitly selected provider instead of failing before the routed turn begins.
  4. Existing behavior remains unchanged when no override is configured.
  5. Account-qualified routes and provider credentials remain isolated; no native ChatGPT bearer or account state is forwarded to the external provider.
  6. The UI/CLI should make the privacy and billing consequence explicit because compaction may send a large portion of conversation history to the selected provider.

An implementation could reuse the qualified model selector mechanism discussed in #2901, but the exact config/API shape is up to the project.

Example usage or interface

One possible interface, using the selector shape previously discussed in #2901:

{
  "responsesCompactionModel": "agent-space/gpt-5.6-luna"
}

Equivalent CLI/UI behavior could be:

Compaction route: agent-space/gpt-5.6-luna
Ordinary thread route: agent-space/gpt-5.6-sol
Canonical OpenAI provider: still configured, but not required for this compact turn

Expected result:

long routed thread -> PreCompact
                   -> explicit compaction provider
                   -> compact succeeds
                   -> next routed turn continues

Without the setting, current routing should remain unchanged.

Alternatives or workarounds

  • Wait for native OpenAI quota to reset, let the pre-sampling compact finish there, and then continue the routed thread. This preserves current behavior but keeps long external-provider threads dependent on native quota.
  • Start a fresh routed thread and manually carry forward a summary. This works but loses the existing thread continuity.
  • Temporarily make the routed provider the OpenCodex default and disable canonical openai, which activates the No way to set compaction provider. #2901 default-provider compaction fallback. This is a global configuration workaround with unnecessary blast radius and requires careful restoration afterward.
  • Automatically fall back on every 429. That may have privacy/billing implications, so an explicit selector/opt-in is preferable.

Additional context

Related issues:

Observed client: Codex Desktop / CLI 0.153.4 on macOS. Secrets, request credentials, and account identifiers are intentionally omitted.

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

  1. added
    enhancementNew feature or request
    account-poolOAuth, credentials, Codex pool, quota, failover, plans
    proxyHTTP proxy, routing, reverse-proxy / management auth
    on Sep 18, 2026
  2. Ingwannu commented on Sep 18, 2026

    @Ingwannu
    Owner

    Confirmed: this is a real remaining product gap, not a request to bypass canonical quota.

    Current dev still reserves a bare native compaction model for an enabled canonical openai provider. The already-open #4872 is the implementation candidate for this exact opt-in: it adds a qualified manual-compaction selector, applies it to both native POST /v1/responses/compact and manual compaction_trigger turns, keeps automatic compaction unchanged, and explicitly discloses that the selected provider receives the conversation history for summarization.

    I am linking this issue to #4872 rather than opening a duplicate implementation. That PR remains draft and is not merge-approved yet: it must be current with dev, have its review threads resolved, and complete exact-head CI. Keeping this issue open until that implementation lands or is replaced.

  3. lidge-jun commented on Sep 19, 2026

    @lidge-jun
    Owner

    Closed by #5202, squash-merged into dev as b52bf57454.

    The lane found that the PR this was expected to ride on could not close it, and that finding shaped the design, so it belongs in the record.

    #4872 gated its override on compaction.trigger == "manual". The request that actually takes the 429 in your report is the automatic PreCompact on thread resume. In codex-rs, run_inline_remote_auto_compact_task builds that one with CompactionTrigger::Auto and then goes through the same run_remote_compact_task_inner as a manual CompactTask, so the surface is identical and only the string differs. Splitting the setting in two would have made an operator configure the same thing twice, so the two collapsed into one triggers field.

    There is upstream precedent for treating the automatic path as the one that needs a fallback: should_retry_with_current_model in compact_model_fallback includes UsageLimitReached, and fallback_step_context is passed only on the automatic path — the manual path passes None.

    The opt-in boundary holds. With no compactionRouting configured, not one line of the data plane changes. With compactionRouting present but no triggers, the default is ["manual"], which is exactly #4872's behaviour. The one visible difference is that GET /api/settings now also returns compactionRouting: null and the empty-PUT error text names the key, which the dashboard needs in order to distinguish unset from unsupported — the same treatment the other settings in that response already get.

    Carried from #4872 with the author credited.

    Evidence is exact-head hosted CI at bedbd1250229f8...: test 1/4 through 4/4 and gates successful. test 1/4 is the one to note — the carried handler block from #4872 failed 13 cases there before this lane repaired them, which is what the final two commits do. No local suite was run in this lane.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    account-poolOAuth, credentials, Codex pool, quota, failover, plansenhancementNew feature or requestproxyHTTP proxy, routing, reverse-proxy / management auth

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions