Add per-turn multi-agent mode (#28685)

## Why

Multi-agent v2 currently carries an explicit-request-only delegation
rule in its static usage hint. That provides a safe default, but it
prevents clients from selecting proactive delegation per turn without
changing static guidance or rewriting prior model context.

This change makes delegation mode a session selection that can be
updated through `turn/start`, while deriving the effective model-visible
mode separately for each turn. Eligible multi-agent v2 turns remain
explicit-request-only unless proactive mode is both selected and
enabled.

## What changed

- Add the experimental `turn/start.multiAgentMode` parameter with
`explicitRequestOnly` and `proactive` values. Omission retains the
loaded session's current optional selection.
- Add the default-off `features.multi_agent_mode` feature gate. Eligible
multi-agent v2 turns use the selected mode when enabled; an unset
selection or disabled gate resolves to `explicitRequestOnly`.
- Treat mode prompting as inapplicable for multi-agent v1 and other
unsupported session configurations, producing no multi-agent mode
developer message rather than rejecting the turn.
- Move the explicit-request-only rule out of the static v2 usage hint
and into a bounded, tagged developer context fragment.
- Emit the effective mode in initial context and only when that
effective mode changes on later turns.
- Persist the effective mode in `TurnContextItem` as the durable
baseline for resume and context-update comparisons.

Historical rollout items are not rewritten. Later mode developer
messages establish the current rule incrementally.

## Not covered

- Initial selection through `thread/start` and selected-mode reporting
from thread lifecycle/settings APIs; those are isolated in the stacked
#28792.
- A TUI control or slash command for selecting the mode.
- Persisting a preferred mode to `config.toml`; selection remains
session/turn scoped.
- Changes to multi-agent concurrency limits, tool availability, or model
catalog capability declarations.
- Rewriting historical rollout prompt items. Cold resume restores the
latest persisted effective mode when available while leaving historical
developer messages intact.

## Verification

- `CARGO_INCREMENTAL=0 just test -p codex-core multi_agent_mode`
- Focused app-server coverage verifies that `turn/start.multiAgentMode`
produces proactive developer instructions for an eligible v2 turn.

## Stack

Followed by #28792, which adds `thread/start` initialization and
lifecycle/settings observability.
This commit is contained in:
Shijie Rao authored and GitHub committed 2026-06-18 22:47:51 -07:00
1 parent f886e33e5a
commit fc8c6b7384
41 files changed
+779 -8

No files matched your search

+10
View File
@@ -125,6 +125,7 @@ pub struct TurnContext {
pub(crate) developer_instructions: Option<String>,
pub(crate) user_instructions: Option<String>,
pub(crate) collaboration_mode: CollaborationMode,
pub(crate) multi_agent_mode: Option<MultiAgentMode>,
pub(crate) multi_agent_version: MultiAgentVersion,
pub(crate) personality: Option<Personality>,
pub(crate) approval_policy: Constrained<AskForApproval>,
@@ -276,6 +277,7 @@ impl TurnContext {
developer_instructions: self.developer_instructions.clone(),
user_instructions: self.user_instructions.clone(),
collaboration_mode,
multi_agent_mode: self.multi_agent_mode,
multi_agent_version: self.multi_agent_version,
personality: self.personality,
approval_policy: self.approval_policy.clone(),
@@ -381,6 +383,13 @@ impl TurnContext {
personality: self.personality,
collaboration_mode: Some(self.collaboration_mode.clone()),
multi_agent_version: Some(self.multi_agent_version),
multi_agent_mode: super::multi_agents::effective_multi_agent_mode(
self.multi_agent_version,
&self.config.multi_agent_v2,
&self.session_source,
self.multi_agent_mode,
self.features.enabled(Feature::MultiAgentMode),
),
realtime_active: Some(self.realtime_active),
effort: self.reasoning_effort.clone(),
summary: ReasoningSummaryConfig::Auto,
@@ -562,6 +571,7 @@ impl Session {
.as_ref()
.map(LoadedAgentsMd::render),
collaboration_mode: session_configuration.collaboration_mode.clone(),
multi_agent_mode: session_configuration.multi_agent_mode,
multi_agent_version,
personality: session_configuration.personality,
approval_policy: session_configuration.approval_policy.clone(),