You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I want a native ChatGPT MultiAgentV2 parent to delegate spawn_agent, send_message, and followup_task messages to a routed third-party child without first producing backend ciphertext that the child cannot read.
The requested feature is an experimental configuration option that is unset in a fresh config and runs only when explicitly set to true. It changes eligible collaboration tool declarations before ChatGPT generates a call, so Codex can receive the message through its supported plaintext collaboration path. It does not decrypt an existing task, make an authenticated recovery request, change the default encrypted behavior, or claim to fix the upstream limitation tracked in #92.
What prevents this today?
Codex MultiAgentV2 declares message.encrypted: true on spawn_agent, send_message, and followup_task. A native ChatGPT parent can therefore return the assignment as backend ciphertext. OpenCodex cannot make that ciphertext readable to a third-party routed child.
The available alternatives have different costs:
V1 keeps heterogeneous delegation readable but gives up the V2 collaboration workflow.
Changing the reserved collaboration schema while retaining reserved child-tool names can still cause ChatGPT to return ciphertext.
OpenAI Codex has a receiving path for plaintext collaboration calls when encrypted_function_args: [] is present, added by openai/codex#35845. OpenCodex needs a narrowly limited request rewrite that selects that path before ciphertext exists and restores every client-facing identity before Codex receives the response.
What should OpenCodex do?
Add a boolean plaintextV2AgentMessages field. A fresh config should omit the field, and only the explicit value true should enable it.
Apply only when the caller uses the Responses wire, the final destination uses adapter: "openai-responses", authMode: "forward", and base URL https://chatgpt.com/backend-api/codex, and the request contains the default top-level collaboration MultiAgentV2 catalog.
Leave OpenAI API-key providers, custom compatible gateways, routes whose final parent destination is another provider, Anthropic-protocol callers, V1 tools, custom collaboration namespaces, and disabled configurations unchanged.
For an eligible request, assign fixed request-scoped aliases to the namespace and the spawn_agent, send_message, and followup_task function names. Remove only parameters.properties.message.encrypted: true from those declarations. Preserve every other schema field and leave the caller's object unchanged.
Refuse the entire rewrite if a fixed alias already appears in any top-level or nested declaration, additional_tools, tool-search result, tool choice, allowed-tool entry, or replayed function/custom call.
Restore the namespace and only the aliases that this request generated before JSON, SSE, WebSocket, snapshot, continuation state, or Codex history can consume the response. A fixed alias under a foreign namespace must remain unchanged. Preserve encrypted_function_args: [] so current Codex clients select structured plaintext delivery.
Keep all rewrite and restoration state within the request. An incremental WebSocket turn, a later option change, or a concurrent request must not reuse another request's alias metadata.
If a conflict, malformed payload, byte limit, 10,000-identity limit, or unsupported response type prevents safe restoration, do not retry the model request. Bounded JSON should return HTTP 502, streams should emit response.failed, private aliases should not reach Codex, and the refused response should not be cached for previous_response_id.
Emit a startup warning and document that task text can remain in Codex history, OpenCodex response state or debug files, and the selected provider. HTTPS transport encryption does not make the task application-layer ciphertext.
This proposal follows the prevention approach discussed in #92. Issue #92 later closed as an upstream tracker after recovery mitigations shipped. This proposal does not request reopening it and does not replace #1540, #1556, #1533, or #2113.
An earlier complete single-worker suite ran on c17bc94c2: 17,272 passed, 16 skipped, and 0 failed. After replaying onto current dev commit f84dbf91e, all 414 feature, adjacent, capacity, and capability tests passed with typecheck, privacy scan, and git diff --check. The only rebase conflict was tests/provider-quota.test.ts; current dev already contained the same #3198 expectation, so the redundant test-only commit was skipped and the file disappeared from the PR diff. GitHub reports the new head as mergeable and created exact-head Cross-platform CI and React Doctor runs for 1a4cb4aab; both require upstream maintainer approval before fork code can execute.
The last successful documentation build produced 409 pages before the conflict-only rebase. The final local attempt stopped before Astro loaded because the available Node runtime is 20.19.4 and current Astro requires >=22.12.0.
A captured rollout showed that namespace aliasing plus schema-marker removal was insufficient. ChatGPT still returned a Fernet-shaped gAAAA… value in spawn_agent.arguments.message, and the routed Fable task received an empty Payload:. The implementation now aliases all three reserved message-tool names and restores only identities authenticated by request-scoped metadata.
A post-fix isolated canary used Codex CLI 0.149.1, a source-built proxy on a separate port, temporary OpenCodex and Codex homes, a native gpt-5.5 parent, and a combo/fable child. The child returned the exact marker FABLE_ALIAS_CANARY_20260826. The available account did not advertise gpt-5.6-sol, so this evidence does not claim a GPT-5.6 run. The issue should remain open until PR #2496 is reviewed and merged.
Checks
I searched existing issues and documentation.
This request describes a concrete OpenCodex workflow rather than merely naming a desired technology.
Area
Proxy and routing
What are you trying to accomplish?
I want a native ChatGPT MultiAgentV2 parent to delegate
spawn_agent,send_message, andfollowup_taskmessages to a routed third-party child without first producing backend ciphertext that the child cannot read.The requested feature is an experimental configuration option that is unset in a fresh config and runs only when explicitly set to
true. It changes eligible collaboration tool declarations before ChatGPT generates a call, so Codex can receive the message through its supported plaintext collaboration path. It does not decrypt an existing task, make an authenticated recovery request, change the default encrypted behavior, or claim to fix the upstream limitation tracked in #92.What prevents this today?
Codex MultiAgentV2 declares
message.encrypted: trueonspawn_agent,send_message, andfollowup_task. A native ChatGPT parent can therefore return the assignment as backend ciphertext. OpenCodex cannot make that ciphertext readable to a third-party routed child.The available alternatives have different costs:
collaborationschema while retaining reserved child-tool names can still cause ChatGPT to return ciphertext.OpenAI Codex has a receiving path for plaintext collaboration calls when
encrypted_function_args: []is present, added by openai/codex#35845. OpenCodex needs a narrowly limited request rewrite that selects that path before ciphertext exists and restores every client-facing identity before Codex receives the response.What should OpenCodex do?
Add a boolean
plaintextV2AgentMessagesfield. A fresh config should omit the field, and only the explicit valuetrueshould enable it.adapter: "openai-responses",authMode: "forward", and base URLhttps://chatgpt.com/backend-api/codex, and the request contains the default top-levelcollaborationMultiAgentV2 catalog.spawn_agent,send_message, andfollowup_taskfunction names. Remove onlyparameters.properties.message.encrypted: truefrom those declarations. Preserve every other schema field and leave the caller's object unchanged.additional_tools, tool-search result, tool choice, allowed-tool entry, or replayed function/custom call.encrypted_function_args: []so current Codex clients select structured plaintext delivery.response.failed, private aliases should not reach Codex, and the refused response should not be cached forprevious_response_id.Example usage or interface
An eligible ChatGPT request would use a private namespace and a private name for a declared message tool:
{ "type": "namespace", "name": "collaboration-optimize", "tools": [ { "type": "function", "name": "start_delegated_task", "parameters": { "properties": { "message": { "type": "string" } } } } ] }Before Codex receives the response, OpenCodex restores the client-facing identity and retains the plaintext marker:
{ "type": "function_call", "namespace": "collaboration", "name": "spawn_agent", "encrypted_function_args": [], "arguments": "{...}" }Disabling the option for later requests is explicit:
Alternatives or workarounds
0.147.0-alpha.4: OpenAI parent still sends encrypted V2 task to non-OpenAI child after #35845 openai/codex#36376 reproduces the encrypted native-parent case after plaintext receiving support, and MultiAgentV2 plaintext support in 0.147.0-alpha.1 does not complete cross-provider task delivery openai/codex#37197 describes the missing sending policy.Additional context
This proposal follows the prevention approach discussed in #92. Issue #92 later closed as an upstream tracker after recovery mitigations shipped. This proposal does not request reopening it and does not replace #1540, #1556, #1533, or #2113.
Relevant upstream and prior-art references:
encrypted_function_args: [].0.147.0-alpha.4: OpenAI parent still sends encrypted V2 task to non-OpenAI child after #35845 openai/codex#36376 confirms that an OpenAI parent can still emit ciphertext for a third-party child.PR #2496 implements this scope on current
dev:1a4cb4aabCurrent verification:
An earlier complete single-worker suite ran on
c17bc94c2: 17,272 passed, 16 skipped, and 0 failed. After replaying onto currentdevcommitf84dbf91e, all 414 feature, adjacent, capacity, and capability tests passed with typecheck, privacy scan, andgit diff --check. The only rebase conflict wastests/provider-quota.test.ts; currentdevalready contained the same #3198 expectation, so the redundant test-only commit was skipped and the file disappeared from the PR diff. GitHub reports the new head as mergeable and created exact-head Cross-platform CI and React Doctor runs for1a4cb4aab; both require upstream maintainer approval before fork code can execute.The last successful documentation build produced 409 pages before the conflict-only rebase. The final local attempt stopped before Astro loaded because the available Node runtime is
20.19.4and current Astro requires>=22.12.0.A captured rollout showed that namespace aliasing plus schema-marker removal was insufficient. ChatGPT still returned a Fernet-shaped
gAAAA…value inspawn_agent.arguments.message, and the routed Fable task received an emptyPayload:. The implementation now aliases all three reserved message-tool names and restores only identities authenticated by request-scoped metadata.A post-fix isolated canary used Codex CLI
0.149.1, a source-built proxy on a separate port, temporary OpenCodex and Codex homes, a nativegpt-5.5parent, and acombo/fablechild. The child returned the exact markerFABLE_ALIAS_CANARY_20260826. The available account did not advertisegpt-5.6-sol, so this evidence does not claim a GPT-5.6 run. The issue should remain open until PR #2496 is reviewed and merged.Checks