Skip to content

feat: render typed envelopes for multi-agent v2 messages#28368

Merged
jif-oai merged 2 commits into
mainfrom
jif/better-message-rendering
Jun 16, 2026
Merged

feat: render typed envelopes for multi-agent v2 messages#28368
jif-oai merged 2 commits into
mainfrom
jif/better-message-rendering

Conversation

@jif-oai

@jif-oai jif-oai commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Why

Multi-agent v2 messages need a consistent, model-visible envelope that identifies what kind of interaction occurred, who sent it, and which agent it targets. Previously, encrypted deliveries exposed only encrypted_content, while child completion used the legacy <subagent_notification> shape. That meant the client could not consistently present NEW_TASK, MESSAGE, and FINAL_ANSWER using the same format.

This change adds the routing envelope as plaintext while keeping task and message payloads encrypted. No new Responses API field is required: an encrypted delivery is represented as an input_text header immediately followed by its existing encrypted_content item.

Every envelope now follows this shape:

Message Type: <NEW_TASK | MESSAGE | FINAL_ANSWER>
Task name: <recipient agent path>
Sender: <author agent path>
Payload:
<message payload>

Message types

NEW_TASK

NEW_TASK is used when the recipient should begin a new turn, including an initial spawn_agent task and a later followup_task.

For a root agent spawning /root/worker, the request contains a plaintext envelope followed by the encrypted task:

{
  "type": "agent_message",
  "author": "/root",
  "recipient": "/root/worker",
  "content": [
    {
      "type": "input_text",
      "text": "Message Type: NEW_TASK\nTask name: /root/worker\nSender: /root\nPayload:\n"
    },
    {
      "type": "encrypted_content",
      "encrypted_content": "<encrypted task payload>"
    }
  ]
}

Conceptually, the model receives:

Message Type: NEW_TASK
Task name: /root/worker
Sender: /root
Payload:
Review the authentication changes and report any regressions.

MESSAGE

MESSAGE is used for a queued send_message delivery. It communicates with an existing agent without starting a new turn.

For /root/worker reporting progress to the root agent, the request contains:

{
  "type": "agent_message",
  "author": "/root/worker",
  "recipient": "/root",
  "content": [
    {
      "type": "input_text",
      "text": "Message Type: MESSAGE\nTask name: /root\nSender: /root/worker\nPayload:\n"
    },
    {
      "type": "encrypted_content",
      "encrypted_content": "<encrypted message payload>"
    }
  ]
}

Conceptually, the model receives:

Message Type: MESSAGE
Task name: /root
Sender: /root/worker
Payload:
The protocol tests pass; I am checking the resume path now.

FINAL_ANSWER

FINAL_ANSWER is emitted when a child agent reaches a terminal state and reports its result to its parent. Completion payloads are already available locally, so the complete envelope is represented as plaintext rather than as a plaintext header plus encrypted content.

For /root/worker completing work for the root agent, the request contains:

{
  "type": "agent_message",
  "author": "/root/worker",
  "recipient": "/root",
  "content": [
    {
      "type": "input_text",
      "text": "Message Type: FINAL_ANSWER\nTask name: /root\nSender: /root/worker\nPayload:\nNo regressions found."
    }
  ]
}

The model-visible form is:

Message Type: FINAL_ANSWER
Task name: /root
Sender: /root/worker
Payload:
No regressions found.

Errored, shut down, and missing agents also use FINAL_ANSWER, with a terminal-status description in the payload.

What changed

  • Render NEW_TASK or MESSAGE in InterAgentCommunication::to_model_input_item, based on whether the encrypted delivery starts a turn.
  • Replace the multi-agent v2 <subagent_notification> completion payload with a model-visible FINAL_ANSWER envelope.
  • Document Task name, Sender, and Payload consistently in the multi-agent developer instructions.
  • Prevent local-only history projections from treating an encrypted message's plaintext header as the complete assistant message.
  • Preserve rollout-trace interaction edges when an agent message contains both plaintext and encrypted content.

Legacy multi-agent behavior remains unchanged.

Verification

  • just test -p codex-protocol
  • just test -p codex-rollout-trace
  • just test -p codex-web-search-extension
  • just test -p codex-core encrypted_multi_agent_v2_spawn_sends_agent_message_to_child
  • just test -p codex-core plaintext_multi_agent_v2_completion_sends_agent_message
  • just test -p codex-core multi_agent_v2_followup_task_completion_notifies_parent_on_every_turn
  • just test -p codex-core multi_agent_v2_completion_queues_message_for_direct_parent

@jif-oai
jif-oai requested a review from a team as a code owner June 15, 2026 18:19
@jif-oai jif-oai changed the title feat: better MAv2 message rendering feat: render typed envelopes for multi-agent v2 messages Jun 15, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a0e1e3ca2b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread codex-rs/core/src/context/inter_agent_completion_message.rs
Comment thread codex-rs/protocol/src/protocol.rs
…ndering

# Conflicts:
#	codex-rs/core/src/session/mod.rs
#	codex-rs/protocol/src/protocol.rs
@jif-oai
jif-oai merged commit 5b22a8e into main Jun 16, 2026
42 of 47 checks passed
@jif-oai
jif-oai deleted the jif/better-message-rendering branch June 16, 2026 09:47
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 16, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant