mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
[codex] Add Ultra reasoning effort (#29899)
## Why Ultra should be one user-facing reasoning selection for work that benefits from both maximum reasoning and proactive multi-agent delegation. Without it, clients must coordinate maximum reasoning with the experimental `multiAgentMode` setting, even though the inference backend still expects its existing `max` effort value. This change makes reasoning effort the source of truth: clients select `ultra`, core derives proactive multi-agent behavior when the turn is eligible for multi-agent V2, and inference requests continue to use the backend-compatible `max` value. ## What changed - Add `ultra` as a first-class reasoning effort and preserve model-catalog ordering when exposing it to clients. - Convert `ultra` to `max` at the inference request boundary, including Responses HTTP/WebSocket requests, startup prewarm, compaction, and memory summarization. - Derive effective multi-agent mode per turn from effective reasoning effort: - eligible multi-agent V2 + `ultra` → `proactive` - eligible multi-agent V2 + any other effort → `explicitRequestOnly` - V1 or otherwise ineligible sessions → no multi-agent mode instruction - Keep the derived effective mode in turn context history so successive turns can emit a developer-message update only when the effective mode changes. - Remove selected multi-agent mode from core session configuration, turn construction, thread settings, resume/fork restoration, and subagent spawn plumbing. Subagents inherit reasoning effort and derive their own effective mode. - Retain the experimental app-server `multiAgentMode` fields for wire compatibility while marking them deprecated. Request values are accepted but ignored; compatibility response fields report `explicitRequestOnly`. - Display Ultra in the TUI using the order supplied by `model/list`. ## Validation - `just test -p codex-core ultra_reasoning_uses_max_for_requests` - `just test -p codex-tui model_reasoning_selection_popup`
This commit is contained in:
committed by
GitHub
Unverified
parent
fa036d39aa
commit
df1199fddb
@@ -40,7 +40,6 @@ use codex_models_manager::manager::RefreshStrategy;
|
||||
use codex_models_manager::manager::SharedModelsManager;
|
||||
use codex_protocol::ThreadId;
|
||||
use codex_protocol::config_types::CollaborationModeMask;
|
||||
use codex_protocol::config_types::MultiAgentMode;
|
||||
use codex_protocol::error::CodexErr;
|
||||
use codex_protocol::error::Result as CodexResult;
|
||||
use codex_protocol::openai_models::ModelPreset;
|
||||
@@ -188,7 +187,6 @@ pub struct StartThreadOptions {
|
||||
pub thread_source: Option<ThreadSource>,
|
||||
pub dynamic_tools: Vec<codex_protocol::dynamic_tools::DynamicToolSpec>,
|
||||
pub metrics_service_name: Option<String>,
|
||||
pub multi_agent_mode: Option<MultiAgentMode>,
|
||||
pub parent_trace: Option<W3cTraceContext>,
|
||||
pub environments: Vec<TurnEnvironmentSelection>,
|
||||
pub thread_extension_init: ExtensionDataInit,
|
||||
@@ -639,7 +637,6 @@ impl ThreadManager {
|
||||
thread_source: None,
|
||||
dynamic_tools,
|
||||
metrics_service_name: None,
|
||||
multi_agent_mode: None,
|
||||
parent_trace: None,
|
||||
environments,
|
||||
thread_extension_init: ExtensionDataInit::default(),
|
||||
@@ -679,7 +676,6 @@ impl ThreadManager {
|
||||
thread_source,
|
||||
options.dynamic_tools,
|
||||
options.metrics_service_name,
|
||||
options.multi_agent_mode,
|
||||
/*inherited_environments*/ None,
|
||||
/*inherited_exec_policy*/ None,
|
||||
options.parent_trace,
|
||||
@@ -764,7 +760,6 @@ impl ThreadManager {
|
||||
let (session_source, thread_source) = initial_history
|
||||
.get_resumed_session_sources()
|
||||
.unwrap_or_else(|| (self.state.session_source.clone(), None));
|
||||
let initial_multi_agent_mode = initial_history.get_latest_effective_multi_agent_mode();
|
||||
Box::pin(self.state.spawn_thread_with_source(
|
||||
config,
|
||||
initial_history,
|
||||
@@ -776,7 +771,6 @@ impl ThreadManager {
|
||||
thread_source,
|
||||
Vec::new(),
|
||||
/*metrics_service_name*/ None,
|
||||
initial_multi_agent_mode,
|
||||
/*inherited_environments*/ None,
|
||||
/*inherited_exec_policy*/ None,
|
||||
parent_trace,
|
||||
@@ -809,7 +803,6 @@ impl ThreadManager {
|
||||
/*thread_source*/ None,
|
||||
Vec::new(),
|
||||
/*metrics_service_name*/ None,
|
||||
/*initial_multi_agent_mode*/ None,
|
||||
/*parent_trace*/ None,
|
||||
environments,
|
||||
/*thread_extension_init*/ ExtensionDataInit::default(),
|
||||
@@ -836,7 +829,6 @@ impl ThreadManager {
|
||||
let (session_source, thread_source) = initial_history
|
||||
.get_resumed_session_sources()
|
||||
.unwrap_or_else(|| (self.state.session_source.clone(), None));
|
||||
let initial_multi_agent_mode = initial_history.get_latest_effective_multi_agent_mode();
|
||||
Box::pin(self.state.spawn_thread_with_source(
|
||||
config,
|
||||
initial_history,
|
||||
@@ -848,7 +840,6 @@ impl ThreadManager {
|
||||
thread_source,
|
||||
Vec::new(),
|
||||
/*metrics_service_name*/ None,
|
||||
initial_multi_agent_mode,
|
||||
/*inherited_environments*/ None,
|
||||
/*inherited_exec_policy*/ None,
|
||||
/*parent_trace*/ None,
|
||||
@@ -1004,13 +995,6 @@ impl ThreadManager {
|
||||
InitialHistory::Forked(_) => history.forked_from_id(),
|
||||
InitialHistory::New | InitialHistory::Cleared => None,
|
||||
};
|
||||
let initial_multi_agent_mode = match source_thread_id {
|
||||
Some(thread_id) => match self.get_thread(thread_id).await {
|
||||
Ok(thread) => Some(thread.config_snapshot().await.multi_agent_mode),
|
||||
Err(_) => history.get_latest_effective_multi_agent_mode(),
|
||||
},
|
||||
None => history.get_latest_effective_multi_agent_mode(),
|
||||
};
|
||||
let multi_agent_version = self
|
||||
.state
|
||||
.effective_multi_agent_version_for_spawn(
|
||||
@@ -1039,7 +1023,6 @@ impl ThreadManager {
|
||||
thread_source,
|
||||
Vec::new(),
|
||||
/*metrics_service_name*/ None,
|
||||
initial_multi_agent_mode,
|
||||
parent_trace,
|
||||
environments,
|
||||
/*thread_extension_init*/ ExtensionDataInit::default(),
|
||||
@@ -1322,7 +1305,6 @@ impl ThreadManagerState {
|
||||
/*forked_from_thread_id*/ None,
|
||||
/*thread_source*/ None,
|
||||
/*metrics_service_name*/ None,
|
||||
/*initial_multi_agent_mode*/ None,
|
||||
/*inherited_environments*/ None,
|
||||
/*inherited_exec_policy*/ None,
|
||||
/*environments*/ None,
|
||||
@@ -1340,7 +1322,6 @@ impl ThreadManagerState {
|
||||
forked_from_thread_id: Option<ThreadId>,
|
||||
thread_source: Option<ThreadSource>,
|
||||
metrics_service_name: Option<String>,
|
||||
initial_multi_agent_mode: Option<MultiAgentMode>,
|
||||
inherited_environments: Option<TurnEnvironmentSnapshot>,
|
||||
inherited_exec_policy: Option<Arc<crate::exec_policy::ExecPolicyManager>>,
|
||||
environments: Option<Vec<TurnEnvironmentSelection>>,
|
||||
@@ -1359,7 +1340,6 @@ impl ThreadManagerState {
|
||||
thread_source,
|
||||
Vec::new(),
|
||||
metrics_service_name,
|
||||
initial_multi_agent_mode,
|
||||
inherited_environments,
|
||||
inherited_exec_policy,
|
||||
/*parent_trace*/ None,
|
||||
@@ -1387,7 +1367,6 @@ impl ThreadManagerState {
|
||||
let environments =
|
||||
default_thread_environment_selections(self.environment_manager.as_ref(), &config.cwd);
|
||||
let thread_source = initial_history.get_resumed_thread_source();
|
||||
let initial_multi_agent_mode = initial_history.get_latest_effective_multi_agent_mode();
|
||||
Box::pin(self.spawn_thread_with_source(
|
||||
config,
|
||||
initial_history,
|
||||
@@ -1399,7 +1378,6 @@ impl ThreadManagerState {
|
||||
thread_source,
|
||||
Vec::new(),
|
||||
/*metrics_service_name*/ None,
|
||||
initial_multi_agent_mode,
|
||||
inherited_environments,
|
||||
inherited_exec_policy,
|
||||
/*parent_trace*/ None,
|
||||
@@ -1421,7 +1399,6 @@ impl ThreadManagerState {
|
||||
thread_source: Option<ThreadSource>,
|
||||
parent_thread_id: Option<ThreadId>,
|
||||
forked_from_thread_id: Option<ThreadId>,
|
||||
initial_multi_agent_mode: Option<MultiAgentMode>,
|
||||
inherited_environments: Option<TurnEnvironmentSnapshot>,
|
||||
inherited_exec_policy: Option<Arc<crate::exec_policy::ExecPolicyManager>>,
|
||||
environments: Option<Vec<TurnEnvironmentSelection>>,
|
||||
@@ -1440,7 +1417,6 @@ impl ThreadManagerState {
|
||||
thread_source,
|
||||
Vec::new(),
|
||||
/*metrics_service_name*/ None,
|
||||
initial_multi_agent_mode,
|
||||
inherited_environments,
|
||||
inherited_exec_policy,
|
||||
/*parent_trace*/ None,
|
||||
@@ -1465,7 +1441,6 @@ impl ThreadManagerState {
|
||||
thread_source: Option<ThreadSource>,
|
||||
dynamic_tools: Vec<codex_protocol::dynamic_tools::DynamicToolSpec>,
|
||||
metrics_service_name: Option<String>,
|
||||
initial_multi_agent_mode: Option<MultiAgentMode>,
|
||||
parent_trace: Option<W3cTraceContext>,
|
||||
environments: Vec<TurnEnvironmentSelection>,
|
||||
thread_extension_init: ExtensionDataInit,
|
||||
@@ -1483,7 +1458,6 @@ impl ThreadManagerState {
|
||||
thread_source,
|
||||
dynamic_tools,
|
||||
metrics_service_name,
|
||||
initial_multi_agent_mode,
|
||||
/*inherited_environments*/ None,
|
||||
/*inherited_exec_policy*/ None,
|
||||
parent_trace,
|
||||
@@ -1508,7 +1482,6 @@ impl ThreadManagerState {
|
||||
thread_source: Option<ThreadSource>,
|
||||
dynamic_tools: Vec<codex_protocol::dynamic_tools::DynamicToolSpec>,
|
||||
metrics_service_name: Option<String>,
|
||||
initial_multi_agent_mode: Option<MultiAgentMode>,
|
||||
inherited_environments: Option<TurnEnvironmentSnapshot>,
|
||||
inherited_exec_policy: Option<Arc<crate::exec_policy::ExecPolicyManager>>,
|
||||
parent_trace: Option<W3cTraceContext>,
|
||||
@@ -1598,7 +1571,6 @@ impl ThreadManagerState {
|
||||
attestation_provider: self.attestation_provider.clone(),
|
||||
external_time_provider: self.external_time_provider.clone(),
|
||||
inherited_multi_agent_version: multi_agent_version,
|
||||
initial_multi_agent_mode,
|
||||
}))
|
||||
.await?;
|
||||
let new_thread = self
|
||||
|
||||
Reference in New Issue
Block a user