Repository navigation
MultiAgentV2 plaintext support in 0.147.0-alpha.1 does not complete cross-provider task delivery #37197
Description
Summary
#35845, included in 0.147.0-alpha.1, added support for processing plaintext collaboration tool messages.
However, that change covers the receiving path only when plaintext has already been selected upstream. It does not provide an end-to-end way for an OpenAI parent to select plaintext delivery when spawning a child backed by a third-party provider.
As a result, the cross-provider failure reported in #34833 remains reproducible on a source baseline of 0.147.0-alpha.4: the child is created with the intended role, provider, and model, but cannot consume its initial task because the assignment is still delivered as provider-specific encrypted content.
Environment
- Windows
- Codex Desktop
- Source baseline:
codex-cli 0.147.0-alpha.4 - Parent: OpenAI provider
- Child: third-party provider using an OpenAI-compatible API
- Multi-agent implementation: V2
- Direct requests to the third-party provider succeed
Provider names, endpoints, credentials, account information, and third-party model identifiers have been intentionally omitted.
Observed behavior
- Enable MultiAgentV2.
- Configure a registered child role backed by a third-party provider.
- Start an OpenAI-backed parent.
- Invoke
spawn_agentfor that child role. - Codex resolves the intended child role, provider, and model and creates the child.
- The child cannot read the initial assignment and therefore cannot begin the task.
The same third-party provider succeeds when invoked directly, which isolates the failure to the MultiAgentV2 provider boundary rather than authentication, networking, or model availability.
Why the 0.147.0-alpha.1 fix is incomplete
The implementation added by #35845 preserves encrypted_function_args and introduces ToolCallSource::DirectPlaintextMessage. A collaboration call is classified as plaintext only when all of the following are true:
- the namespace is exactly
collaboration; - the tool is
spawn_agent,send_message, orfollowup_task; encrypted_function_args == Some([]).
When that marker is present, the handlers construct a structured plaintext agent message. Otherwise, they retain the existing encrypted path.
The remaining gap is that the MultiAgentV2 tool schemas still unconditionally apply .with_encrypted() to the message fields for spawn_agent, send_message, and followup_task. An OpenAI parent therefore normally produces actual encrypted arguments rather than the empty marker required by DirectPlaintextMessage. The call is classified as Direct, and the handler still uses:
InterAgentCommunication::new_encrypted(...)
The third-party child then receives content it cannot decrypt or interpret.
The alpha.1 implementation also has the following limitations for this topology:
- plaintext classification is hard-coded to the
collaborationnamespace; - a configured custom namespace cannot enter the plaintext branch;
- providers without namespace-tool support cannot match that condition;
- there is no provider-aware delivery selection;
- there is no explicit configuration to request plaintext delivery;
- encrypted delivery to a third-party child is not rejected before the unusable child is created.
The relevant schema, classification, and message-construction behavior remains materially unchanged between 0.147.0-alpha.1 and 0.147.0-alpha.4.
Simply removing .with_encrypted() is also insufficient. A modified plaintext schema under the reserved collaboration namespace is rejected by the OpenAI API because reserved collaboration functions must match the configured schema exactly. A complete fix therefore also needs a supported non-reserved namespace or an upstream-compatible schema mechanism.
Local source-level fix path
I implemented and validated an opt-in, backwards-compatible delivery policy across the following source paths.
Configuration and schema
codex-rs/features/src/feature_configs.rscodex-rs/features/src/lib.rscodex-rs/core/src/config/mod.rscodex-rs/core/config.schema.json
The local configuration shape is:
[features.multi_agent_v2]
enabled = true
message_delivery = "plaintext"
tool_namespace = "agents"encrypted remains the default.
Tool schemas
codex-rs/core/src/tools/handlers/multi_agents_spec.rs
The encrypted marker is applied conditionally to the message fields for spawn_agent, send_message, and followup_task.
Tool planning and call classification
codex-rs/core/src/tools/spec_plan.rscodex-rs/core/src/tools/router.rscodex-rs/core/src/tools/parallel.rs
Plaintext mode classifies the relevant calls as DirectPlaintextMessage using the configured tool namespace rather than only the hard-coded collaboration namespace.
MultiAgentV2 message handling
codex-rs/core/src/tools/handlers/multi_agents_v2.rscodex-rs/core/src/tools/handlers/multi_agents_v2/spawn.rscodex-rs/core/src/tools/handlers/multi_agents_v2/send_message.rscodex-rs/core/src/tools/handlers/multi_agents_v2/followup_task.rscodex-rs/core/src/stream_events_utils.rs
Plaintext mode reuses the structured input_text path. If an encrypted task is about to be delivered to a non-OpenAI child, the spawn fails before child creation with an actionable configuration error.
Validation results
- Feature configuration tests: 34/34 passed.
- Targeted MultiAgentV2 tests: 74/74 passed.
- Plaintext tool-schema tests passed.
- Custom and unnamespaced collaboration-tool tests passed.
- Structured parent-to-child
input_textdelivery tests passed. - Fail-closed tests for encrypted delivery to a third-party child passed.
- Release build succeeded.
- After fully restarting Codex Desktop with the local build, an OpenAI parent successfully spawned a third-party-provider child.
- The child received the assignment, executed it, and returned the expected fixed marker.
- The default encrypted behavior remains unchanged.
Expected upstream behavior
A complete upstream solution should:
- Keep encrypted delivery as the default.
- Provide an explicit plaintext delivery policy for providers that cannot consume OpenAI encrypted tool parameters.
- Apply the policy consistently across tool schemas, planning, routing, and message construction.
- Support a non-reserved tool namespace for plaintext collaboration schemas.
- Fail before spawning when encrypted delivery is incompatible with the selected child provider.
- Add an end-to-end integration test for an OpenAI parent spawning a third-party-provider child.
Activity
github-actions commentedon Aug 6, 2026
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
0.147.0-alpha.4: OpenAI parent still sends encrypted V2 task to non-OpenAI child after #35845 #36376Powered by Codex Action
NOirBRight commentedon Aug 13, 2026
CodexHub Beta4.1 status update (sanitized; no credentials or raw ciphertext included).
We independently confirmed that the plaintext receiving path alone does not complete cross-provider delivery. In the OpenAI-parent -> non-OpenAI-child case, the parent-side V2 handoff can still carry a real Fernet-like ciphertext in
encrypted_content; a downstream Gateway cannot decrypt it, so envelope rewrites or removal of theencryptedJSON-schema marker cannot recover the task text.Implemented in CodexHub Beta4.1 at the Gateway boundary:
This proves the protocol/tool-surface adapter direction, not full OpenAI-parent -> external-child delivery. The external model is not being treated as natively V2-capable; the Gateway is adapting ordinary tool-calling behavior into the Codex V2 lifecycle surface.
Requested upstream resolution:
Until that producer-side change exists, CodexHub can ship the tool-surface adapter separately but cannot honestly claim complete cross-provider V2 lifecycle support.
cgasgarth commentedon Oct 5, 2026
Verified a small producer-side plaintext V2 prototype on official Codex
0.160.0(October 4, 2026). Using an ordinaryagentsnamespace plus a two-file opt-in patch, real GPT → Fable/Opus/GPT tasks, Claude Opus → GPT tasks, follow-ups, proactive messages, and an app-server GPT → Opus → GPT chain all completed with independently verified files.This does not decrypt ciphertext or merely reclassify sealed bytes. The patch changes both message schemas and delivery selection so the generated tasks are readable from the start. All nine saved sessions recorded V2 and the requested models; their 34 inter-agent input records had no encrypted parts.
Full evidence and limits: #46939 (comment)
Source patch and reproducible probes: https://github.com/cgasgarth/skills/tree/e5b3134/patches/v2-plaintext
This is isolated CLI/app-server backend proof, not desktop UI acceptance or an upstream-supported configuration. Existing encrypted history and other providers remain outside the tested scope.
cgasgarth commentedon Oct 5, 2026
Update: verified both GPT Sol → Claude Opus and Claude Opus → GPT Sol in actual desktop-app chats with the official signed Codex 0.160.0 backend. Initial tasks, explicit parent-directed messages, and same-child follow-ups all passed.
VibeProxy's installed CLIProxyAPI 8.0.4 already supports
codex.optimize-multi-agent-v2: true. Codex also needs V2 enabled and V2 model catalog entries for the children's collaboration tools. No custom Codex build or app patch is needed for this setup.The previous local-build approach broke native app tools because of macOS peer code-signature checks (#34583). It has been removed.
Configuration, source links, results, and scope: #46939 (comment)