mirror of
https://github.com/openai/codex.git
synced 2026-11-14 21:40:39 +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:
@@ -2,6 +2,7 @@ use super::*;
|
||||
use crate::error_code::method_not_found;
|
||||
use codex_app_server_protocol::SelectedCapabilityRoot;
|
||||
use codex_extension_api::ExtensionDataInit;
|
||||
use codex_protocol::config_types::MultiAgentMode;
|
||||
use codex_protocol::models::BUILT_IN_PERMISSION_PROFILE_DANGER_FULL_ACCESS;
|
||||
use codex_protocol::models::BUILT_IN_PERMISSION_PROFILE_WORKSPACE;
|
||||
|
||||
@@ -902,6 +903,7 @@ impl ThreadRequestProcessor {
|
||||
mock_experimental_field: _mock_experimental_field,
|
||||
experimental_raw_events,
|
||||
personality,
|
||||
multi_agent_mode,
|
||||
ephemeral,
|
||||
session_start_source,
|
||||
thread_source,
|
||||
@@ -955,6 +957,7 @@ impl ThreadRequestProcessor {
|
||||
supports_openai_form_elicitation,
|
||||
config,
|
||||
typesafe_overrides,
|
||||
multi_agent_mode,
|
||||
dynamic_tools,
|
||||
selected_capability_roots.unwrap_or_default(),
|
||||
session_start_source,
|
||||
@@ -1029,6 +1032,7 @@ impl ThreadRequestProcessor {
|
||||
supports_openai_form_elicitation: bool,
|
||||
config_overrides: Option<HashMap<String, serde_json::Value>>,
|
||||
typesafe_overrides: ConfigOverrides,
|
||||
multi_agent_mode: Option<MultiAgentMode>,
|
||||
dynamic_tools: Option<Vec<DynamicToolSpec>>,
|
||||
selected_capability_roots: Vec<SelectedCapabilityRoot>,
|
||||
session_start_source: Option<codex_app_server_protocol::ThreadStartSource>,
|
||||
@@ -1152,6 +1156,7 @@ impl ThreadRequestProcessor {
|
||||
thread_source,
|
||||
dynamic_tools,
|
||||
metrics_service_name: service_name,
|
||||
multi_agent_mode,
|
||||
parent_trace: request_trace,
|
||||
environments,
|
||||
thread_extension_init,
|
||||
@@ -1257,6 +1262,7 @@ impl ThreadRequestProcessor {
|
||||
sandbox,
|
||||
active_permission_profile,
|
||||
reasoning_effort: config_snapshot.reasoning_effort,
|
||||
multi_agent_mode: config_snapshot.multi_agent_mode,
|
||||
};
|
||||
let notif = thread_started_notification(thread);
|
||||
listener_task_context
|
||||
@@ -2787,6 +2793,7 @@ impl ThreadRequestProcessor {
|
||||
sandbox,
|
||||
active_permission_profile,
|
||||
reasoning_effort: session_configured.reasoning_effort,
|
||||
multi_agent_mode: config_snapshot.multi_agent_mode,
|
||||
initial_turns_page,
|
||||
};
|
||||
|
||||
@@ -3508,6 +3515,7 @@ impl ThreadRequestProcessor {
|
||||
sandbox,
|
||||
active_permission_profile,
|
||||
reasoning_effort: session_configured.reasoning_effort,
|
||||
multi_agent_mode: config_snapshot.multi_agent_mode,
|
||||
};
|
||||
|
||||
let notif = thread_started_notification(thread);
|
||||
|
||||
Reference in New Issue
Block a user