mirror of
https://github.com/openai/codex.git
synced 2026-11-13 14:46:14 +00: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:
1 parent
fc8c6b7384
commit
7abfcf220b
46 files changed
+620
-36
No files matched your search
@@ -199,6 +199,7 @@ fn thread_resume_response_round_trips_initial_turns_page() {
|
||||
sandbox: SandboxPolicy::DangerFullAccess,
|
||||
active_permission_profile: None,
|
||||
reasoning_effort: None,
|
||||
multi_agent_mode: Default::default(),
|
||||
initial_turns_page: Some(TurnsPage {
|
||||
data: Vec::new(),
|
||||
next_cursor: Some("cursor_next".to_string()),
|
||||
@@ -3701,6 +3702,14 @@ fn thread_lifecycle_responses_default_missing_optional_fields() {
|
||||
assert_eq!(resume.active_permission_profile, None);
|
||||
assert_eq!(resume.initial_turns_page, None);
|
||||
assert_eq!(fork.active_permission_profile, None);
|
||||
assert_eq!(
|
||||
(
|
||||
start.multi_agent_mode,
|
||||
resume.multi_agent_mode,
|
||||
fork.multi_agent_mode,
|
||||
),
|
||||
(None, None, None)
|
||||
);
|
||||
|
||||
let foreign_source: LegacyAppPathString =
|
||||
serde_json::from_value(json!(r"C:\workspace\AGENTS.md")).expect("foreign source");
|
||||
@@ -3805,6 +3814,27 @@ fn turn_start_params_round_trip_multi_agent_mode() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn thread_start_params_round_trip_multi_agent_mode() {
|
||||
let params: ThreadStartParams = serde_json::from_value(json!({
|
||||
"multiAgentMode": "proactive"
|
||||
}))
|
||||
.expect("params should deserialize");
|
||||
|
||||
assert_eq!(
|
||||
params.multi_agent_mode,
|
||||
Some(codex_protocol::config_types::MultiAgentMode::Proactive)
|
||||
);
|
||||
assert_eq!(
|
||||
crate::experimental_api::ExperimentalApi::experimental_reason(¶ms),
|
||||
Some("thread/start.multiAgentMode")
|
||||
);
|
||||
assert_eq!(
|
||||
serde_json::to_value(params).expect("params should serialize")["multiAgentMode"],
|
||||
"proactive"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn thread_settings_update_params_preserve_explicit_null_service_tier() {
|
||||
let params: ThreadSettingsUpdateParams = serde_json::from_value(json!({
|
||||
|
||||
Reference in new issue
Block a user