mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
5b22a8e5b1
## 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:
```text
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:
```json
{
"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:
```text
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:
```json
{
"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:
```text
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:
```json
{
"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:
```text
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`
71 lines
3.5 KiB
Rust
71 lines
3.5 KiB
Rust
//! Context fragments injected into model input.
|
|
|
|
mod approved_command_prefix_saved;
|
|
mod apps_instructions;
|
|
mod available_plugins_instructions;
|
|
mod available_skills_instructions;
|
|
mod collaboration_mode_instructions;
|
|
mod contextual_user_message;
|
|
mod environment_context;
|
|
mod guardian_followup_review_reminder;
|
|
mod hook_additional_context;
|
|
mod image_generation_instructions;
|
|
mod inter_agent_completion_message;
|
|
mod internal_model_context;
|
|
mod legacy_apply_patch_exec_command_warning;
|
|
mod legacy_model_mismatch_warning;
|
|
mod legacy_unified_exec_process_limit_warning;
|
|
mod model_switch_instructions;
|
|
mod network_rule_saved;
|
|
mod permissions_instructions;
|
|
mod personality_spec_instructions;
|
|
mod plugin_instructions;
|
|
mod realtime_end_instructions;
|
|
mod realtime_start_instructions;
|
|
mod realtime_start_with_instructions;
|
|
mod subagent_notification;
|
|
mod token_budget_context;
|
|
mod turn_aborted;
|
|
mod user_instructions;
|
|
mod user_shell_command;
|
|
|
|
pub(crate) use approved_command_prefix_saved::ApprovedCommandPrefixSaved;
|
|
pub(crate) use apps_instructions::AppsInstructions;
|
|
pub(crate) use available_plugins_instructions::AvailablePluginsInstructions;
|
|
pub use available_skills_instructions::AvailableSkillsInstructions;
|
|
pub(crate) use codex_context_fragments::AdditionalContextDeveloperFragment;
|
|
pub(crate) use codex_context_fragments::AdditionalContextUserFragment;
|
|
pub use codex_context_fragments::ContextualUserFragment;
|
|
pub(crate) use codex_context_fragments::FragmentRegistration;
|
|
pub(crate) use codex_context_fragments::FragmentRegistrationProxy;
|
|
pub(crate) use codex_core_skills::SkillInstructions;
|
|
pub(crate) use collaboration_mode_instructions::CollaborationModeInstructions;
|
|
pub(crate) use contextual_user_message::is_contextual_user_fragment;
|
|
pub(crate) use contextual_user_message::parse_visible_hook_prompt_message;
|
|
pub(crate) use environment_context::EnvironmentContext;
|
|
pub(crate) use guardian_followup_review_reminder::GuardianFollowupReviewReminder;
|
|
pub(crate) use hook_additional_context::HookAdditionalContext;
|
|
pub(crate) use image_generation_instructions::ImageGenerationInstructions;
|
|
pub use image_generation_instructions::extension_image_generation_output_hint;
|
|
pub(crate) use inter_agent_completion_message::InterAgentCompletionMessage;
|
|
pub use internal_model_context::InternalContextSource;
|
|
pub use internal_model_context::InternalModelContextFragment;
|
|
pub use internal_model_context::InvalidInternalContextSource;
|
|
pub(crate) use legacy_apply_patch_exec_command_warning::LegacyApplyPatchExecCommandWarning;
|
|
pub(crate) use legacy_model_mismatch_warning::LegacyModelMismatchWarning;
|
|
pub(crate) use legacy_unified_exec_process_limit_warning::LegacyUnifiedExecProcessLimitWarning;
|
|
pub(crate) use model_switch_instructions::ModelSwitchInstructions;
|
|
pub(crate) use network_rule_saved::NetworkRuleSaved;
|
|
pub use permissions_instructions::PermissionsInstructions;
|
|
pub(crate) use personality_spec_instructions::PersonalitySpecInstructions;
|
|
pub(crate) use plugin_instructions::PluginInstructions;
|
|
pub(crate) use realtime_end_instructions::RealtimeEndInstructions;
|
|
pub(crate) use realtime_start_instructions::RealtimeStartInstructions;
|
|
pub(crate) use realtime_start_with_instructions::RealtimeStartWithInstructions;
|
|
pub(crate) use subagent_notification::SubagentNotification;
|
|
pub(crate) use token_budget_context::TokenBudgetContext;
|
|
pub(crate) use token_budget_context::TokenBudgetRemainingContext;
|
|
pub(crate) use turn_aborted::TurnAborted;
|
|
pub(crate) use user_instructions::UserInstructions;
|
|
pub(crate) use user_shell_command::UserShellCommand;
|