mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
Expose thread-level multi-agent mode (#28792)
## Why Once multi-agent mode can be selected per turn, clients also need to choose the initial selection when creating a thread and observe that selection through lifecycle and settings APIs. The selected value is intentionally distinct from the effective model-visible value: no client selection is represented as `null`, even though an eligible multi-agent v2 turn derives `explicitRequestOnly` as its effective default. ## What changed - Add the optional experimental `thread/start.multiAgentMode` parameter and pass it through thread creation. - Preserve an omitted initial value as an unset selection rather than eagerly storing `explicitRequestOnly`. - Apply an explicit `thread/start` selection to the first turn through the session configuration established at thread creation. - Restore the latest persisted effective mode as the selected baseline on cold resume when rollout history contains one. - Inherit the optional selected mode from a loaded parent when creating related runtime threads. - Return the current selected `multiAgentMode` from `thread/start`, `thread/resume`, `thread/fork`, and thread settings, using `null` when no mode is selected. - Keep lifecycle reporting independent from model capability and feature eligibility; core turn construction remains responsible for calculating and persisting the effective mode. ## Not covered - Clearing an existing loaded-session selection back to unset through `turn/start`; omitted or `null` currently retains the session's selection. - A TUI control, slash command, or `config.toml` preference. ## Verification - `CARGO_INCREMENTAL=0 just test -p codex-app-server-protocol` - `CARGO_INCREMENTAL=0 just test -p codex-app-server multi_agent_mode` The focused app-server coverage verifies explicit `thread/start` initialization, first-turn prompting, nullable reporting for an omitted selection, and retention of selections that are not currently runtime-eligible. ## Stack Stacked on #28685. This PR contains only the thread initialization and lifecycle/settings API layer.
This commit is contained in:
committed by
GitHub
Unverified
parent
fc8c6b7384
commit
7abfcf220b
@@ -132,6 +132,7 @@ async fn handle_spawn_agent(
|
||||
fork_mode: args.fork_context.then_some(SpawnAgentForkMode::FullHistory),
|
||||
parent_thread_id: Some(session.thread_id),
|
||||
environments: Some(turn.environments.to_selections()),
|
||||
initial_multi_agent_mode: None,
|
||||
},
|
||||
))
|
||||
.await
|
||||
|
||||
@@ -24,6 +24,7 @@ use codex_model_provider_info::built_in_model_providers;
|
||||
use codex_protocol::AgentPath;
|
||||
use codex_protocol::ThreadId;
|
||||
use codex_protocol::config_types::ApprovalsReviewer;
|
||||
use codex_protocol::config_types::MultiAgentMode;
|
||||
use codex_protocol::config_types::ServiceTier;
|
||||
use codex_protocol::config_types::ShellEnvironmentPolicy;
|
||||
use codex_protocol::models::BaseInstructions;
|
||||
@@ -1147,6 +1148,11 @@ async fn multi_agent_v2_spawn_returns_path_and_send_message_accepts_relative_pat
|
||||
.features
|
||||
.enable(Feature::MultiAgentV2)
|
||||
.expect("test config should allow feature update");
|
||||
config
|
||||
.features
|
||||
.enable(Feature::MultiAgentMode)
|
||||
.expect("test config should allow feature update");
|
||||
turn.multi_agent_mode = Some(MultiAgentMode::Proactive);
|
||||
set_turn_config(&mut turn, config);
|
||||
|
||||
let session = Arc::new(session);
|
||||
@@ -1185,6 +1191,10 @@ async fn multi_agent_v2_spawn_returns_path_and_send_message_accepts_relative_pat
|
||||
child_snapshot.session_source.get_agent_path().as_deref(),
|
||||
Some("/root/test_process")
|
||||
);
|
||||
assert_eq!(
|
||||
child_snapshot.multi_agent_mode,
|
||||
Some(MultiAgentMode::Proactive)
|
||||
);
|
||||
assert!(manager.captured_ops().iter().any(|(id, op)| {
|
||||
*id == child_thread_id
|
||||
&& matches!(
|
||||
|
||||
@@ -50,6 +50,15 @@ async fn handle_spawn_agent(
|
||||
let arguments = function_arguments(payload)?;
|
||||
let args: SpawnAgentArgs = parse_arguments(&arguments)?;
|
||||
let fork_mode = args.fork_mode()?;
|
||||
let multi_agent_mode = crate::session::multi_agents::effective_multi_agent_mode(
|
||||
turn.multi_agent_version,
|
||||
&turn.config.multi_agent_v2,
|
||||
&turn.session_source,
|
||||
turn.multi_agent_mode,
|
||||
turn.config
|
||||
.features
|
||||
.enabled(codex_features::Feature::MultiAgentMode),
|
||||
);
|
||||
let role_name = args
|
||||
.agent_type
|
||||
.as_deref()
|
||||
@@ -134,6 +143,7 @@ async fn handle_spawn_agent(
|
||||
fork_mode,
|
||||
parent_thread_id: Some(session.thread_id),
|
||||
environments: Some(turn.environments.to_selections()),
|
||||
initial_multi_agent_mode: multi_agent_mode,
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user