Skip to content

Document / gate Ultra multi-agent features when using API-key custom model_providers #37859

Open

Description

@RaviTharuma

What version of Codex CLI is running?

0.147.0 (CLI + Desktop)

What subscription do you have?

ChatGPT Pro for account features; inference often via custom model_providers with API key (wire_api = "responses", env_key, requires_openai_auth = false).

Which model were you using?

gpt-5.6-sol with model_reasoning_effort = "ultra" on a custom API provider.

What platform is your computer?

macOS (applies generally)

What issue are you seeing?

Codex currently advertises or accepts Ultra-related settings for sessions that use a regular API-key model provider, but several Ultra product capabilities only work on the ChatGPT / first-party backend path.

Concretely:

Capability ChatGPT-auth / first-party provider Regular API-key model_providers.*
Reasoning effort ultra works often works (effort enum only)
Server-side multi-agent / Responses multi_agent works fails (Unsupported parameter: multi_agent or no multi-agent tree)
Native Ultra-style parallel subagent product works incomplete / broken (see #17598, #37858)
Client multi_agent_v2 / spawn_agent works partial; known custom-provider bugs

Users reasonably assume that:

model_provider = "my_api"   # API key provider
model = "gpt-5.6-sol"
model_reasoning_effort = "ultra"
[features]
multi_agent_v2 = true

means they get the same Ultra multi-agent experience as ChatGPT-signed-in Codex. They do not. There is no clear in-product warning, and docs do not draw a hard line between:

  1. Ultra as reasoning effort (portable to many providers), vs
  2. Ultra as multi-agent product (ChatGPT-backend / first-party only today).

What steps can reproduce the bug?

  1. Configure any working custom Responses API provider with API key auth.
  2. Set Sol + model_reasoning_effort = "ultra" + enable multi-agent features.
  3. Use Desktop/CLI as if Ultra multi-agent were fully available (spawn parallel subagents, multi-agent coordination).
  4. Observe failures or silent single-agent answers; switch to ChatGPT-auth default provider and see full behavior.

What is the expected behavior?

Please do one or both of:

  1. Document in config reference / subagents / models docs:
    • which Ultra capabilities require ChatGPT authentication / first-party backend
    • which work with arbitrary Responses-compatible API providers
  2. Gate or label in UI/CLI when model_provider is a custom API-key provider:
    • show that multi-agent Ultra is unavailable or degraded
    • avoid implying that effort=ultra alone enables full Ultra multi-agent

Without this, power users waste time debugging config when the limit is product architecture.

Additional information

Related:

This issue is specifically about honest product surface + docs, not only the protocol fix requested in #37858.

Activity

  1. added
    enhancementNew feature or request
    CLIIssues related to the Codex CLI
    subagentIssues involving subagents or multi-agent features
    custom-modelIssues related to custom model providers (including local models)
    configIssues involving config.toml, config keys, config merging, or config updates
    on Aug 10, 2026
  2. github-actions commented on Aug 10, 2026

    @github-actions
    Contributor

    Potential duplicates detected. Please review them and close your issue if it is a duplicate.

    Powered by Codex Action

  3. jdcodes1 commented on Aug 18, 2026

    @jdcodes1

    Supporting this documentation/gating request with the client-side mechanism (detailed in #37858 and #37822): inter-agent task payloads are transported as encrypted_content blobs that only the originating ChatGPT-backed session can have decrypted server-side — the client never decrypts them (InterAgentCommunication::to_model_input_item, protocol/src/protocol.rs#L813-L846). With requires_openai_auth = false API-key providers there is no decrypting backend, so sub-agents receive an empty payload and idle. That's why the failure is silent and partial rather than a clean error: the spawn machinery works, only the message content evaporates.

    Which means the gate you're asking for has a precise, checkable condition: at spawn time, if the thread's provider isn't the first-party ChatGPT-auth backend (or once a plaintext fallback lands, whenever sender/receiver providers differ), fail the multi-agent tool call with an explicit "multi-agent requires ChatGPT auth on the first-party provider" — and the docs statement falls out of the same condition. Fixing the transport (plaintext path exists: InterAgentCommunication::new) would eventually lift the restriction, but documenting + gating is worth shipping first since it converts hours of silent debugging into one clear message.

  4. RaviTharuma commented on Sep 3, 2026

    @RaviTharuma
    Author

    Dug into where your proposed gate would actually have to live, since "if provider isn't first-party ChatGPT-auth" turns out not to be the real branch condition. I traced the encrypt/plaintext split for details (posted the full trace on #37858) — the short version relevant to this issue's gating ask:

    The client doesn't decide encrypted vs. plaintext from model_providers/requires_openai_auth at all. ToolCall::direct_source (codex-rs/core/src/tools/router.rs) sets ToolCallSource::DirectPlaintextMessage only when the upstream response's encrypted_function_args for that spawn_agent/send_message/followup_task call came back empty; otherwise communication_from_tool_message (codex-rs/core/src/tools/handlers/multi_agents_v2.rs) takes the InterAgentCommunication::new_encrypted(...) branch, which is the one only a ChatGPT-auth backend can expand. So a static "provider != first-party ChatGPT-auth → fail at spawn" gate would produce false failures for any custom backend whose Responses-compatible endpoint happens to return empty encrypted_function_args for those tool calls (there's an existing report of exactly that working, non-OpenAI-to-non-OpenAI, over on #37858).

    That changes what a correct spawn-time gate needs to check: not "is auth mode ChatGPT" but "did this session's first collaboration tool call round-trip with a non-empty encrypted_function_args" — i.e. detect the failure mode after the first turn resolves it, not before spawn, since the client can't know in advance what a custom Responses-compatible server will populate. A pre-spawn static check on provider type would either over-block backends that work today or under-block ones a maintainer hasn't audited.

    What's still needed from a maintainer: confirm whether encrypted_function_args non-emptiness is intended to be the authoritative provider-capability signal here, or whether there's a model_providers-level capability field (separate from requires_openai_auth) that's supposed to be authoritative instead — and if the latter, that field doesn't appear to be threaded into ToolCall::direct_source today, which would itself be the gap to close before "document + gate" is implementable as a one-condition check.

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

    CLIIssues related to the Codex CLIconfigIssues involving config.toml, config keys, config merging, or config updatescustom-modelIssues related to custom model providers (including local models)enhancementNew feature or requestsubagentIssues involving subagents or multi-agent features

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions