codex: represent disabled multi-agent runtime explicitly

This commit is contained in:
Ahmed Ibrahim
2026-06-01 13:13:18 -07:00
parent 297548de78
commit 98f67c8a2c
8 changed files with 55 additions and 21 deletions
+2 -2
View File
@@ -1288,7 +1288,7 @@ impl Config {
} else if self.features.enabled(Feature::Collab) {
Some(MultiAgentVersion::V1)
} else {
None
Some(MultiAgentVersion::Disabled)
}
}
@@ -1310,7 +1310,7 @@ impl Config {
.saturating_sub(1),
))
}
None | Some(MultiAgentVersion::V1) => {
None | Some(MultiAgentVersion::Disabled | MultiAgentVersion::V1) => {
Ok(self.agent_max_threads.or(DEFAULT_AGENT_MAX_THREADS))
}
}
+2 -1
View File
@@ -19,6 +19,7 @@ use codex_protocol::protocol::Event;
use codex_protocol::protocol::EventMsg;
use codex_protocol::protocol::ForkedHistory;
use codex_protocol::protocol::InitialHistory;
use codex_protocol::protocol::MultiAgentVersion;
use codex_protocol::protocol::Op;
use codex_protocol::protocol::RolloutItem;
use codex_protocol::protocol::SandboxPolicy;
@@ -610,7 +611,7 @@ async fn spawn_guardian_review_session(
cancel_token.clone(),
SubAgentSource::Other(GUARDIAN_REVIEWER_NAME.to_string()),
initial_history,
/*multi_agent_version*/ None,
/*multi_agent_version*/ Some(MultiAgentVersion::Disabled),
))
.await?;
+1 -1
View File
@@ -128,7 +128,7 @@ pub(super) async fn spawn_review_thread(
user_instructions: None,
compact_prompt: parent_turn_context.compact_prompt.clone(),
collaboration_mode: parent_turn_context.collaboration_mode.clone(),
multi_agent_version: None,
multi_agent_version: Some(MultiAgentVersion::Disabled),
personality: parent_turn_context.personality,
approval_policy: parent_turn_context.approval_policy.clone(),
permission_profile: parent_turn_context.permission_profile(),
+2 -1
View File
@@ -12,6 +12,7 @@ use codex_protocol::protocol::Event;
use codex_protocol::protocol::EventMsg;
use codex_protocol::protocol::ExitedReviewModeEvent;
use codex_protocol::protocol::ItemCompletedEvent;
use codex_protocol::protocol::MultiAgentVersion;
use codex_protocol::protocol::ReviewOutputEvent;
use codex_protocol::protocol::SubAgentSource;
use tokio_util::sync::CancellationToken;
@@ -132,7 +133,7 @@ async fn start_review_conversation(
SubAgentSource::Review,
/*final_output_json_schema*/ None,
/*initial_history*/ None,
/*multi_agent_version*/ None,
/*multi_agent_version*/ Some(MultiAgentVersion::Disabled),
)
.await)
.ok()
+15 -8
View File
@@ -113,19 +113,26 @@ async fn build_runner_options(
turn: &Arc<TurnContext>,
requested_concurrency: Option<usize>,
) -> Result<JobRunnerOptions, FunctionCallError> {
let session_source = turn.session_source.clone();
let child_depth = next_thread_spawn_depth(&session_source);
let max_depth = turn.config.agent_max_depth;
if exceeds_thread_spawn_depth_limit(child_depth, max_depth) {
return Err(FunctionCallError::RespondToModel(
"agent depth limit reached; this session cannot spawn more subagents".to_string(),
));
}
let multi_agent_version = turn.multi_agent_version.ok_or_else(|| {
FunctionCallError::RespondToModel(
"multi-agent version is unresolved; this session cannot spawn workers".to_string(),
)
})?;
if multi_agent_version == MultiAgentVersion::Disabled {
return Err(FunctionCallError::RespondToModel(
"multi-agent runtime is disabled; this session cannot spawn workers".to_string(),
));
}
let session_source = turn.session_source.clone();
let child_depth = next_thread_spawn_depth(&session_source);
let max_depth = turn.config.agent_max_depth;
if multi_agent_version == MultiAgentVersion::V1
&& exceeds_thread_spawn_depth_limit(child_depth, max_depth)
{
return Err(FunctionCallError::RespondToModel(
"agent depth limit reached; this session cannot spawn more subagents".to_string(),
));
}
let agent_max_threads = turn
.config
.effective_agent_max_threads(Some(multi_agent_version))
+2 -7
View File
@@ -294,7 +294,7 @@ fn multi_agent_v2_enabled(turn_context: &TurnContext) -> bool {
fn collab_tools_enabled(turn_context: &TurnContext) -> bool {
match turn_context.multi_agent_version {
None => false,
None | Some(MultiAgentVersion::Disabled) => false,
Some(MultiAgentVersion::V1) => !exceeds_thread_spawn_depth_limit(
next_thread_spawn_depth(&turn_context.session_source),
turn_context.config.agent_max_depth,
@@ -312,12 +312,7 @@ fn goal_tools_enabled(turn_context: &TurnContext) -> bool {
}
fn agent_jobs_tools_enabled(turn_context: &TurnContext) -> bool {
turn_context.features.get().enabled(Feature::SpawnCsv)
&& turn_context.multi_agent_version.is_some()
&& !exceeds_thread_spawn_depth_limit(
next_thread_spawn_depth(&turn_context.session_source),
turn_context.config.agent_max_depth,
)
turn_context.features.get().enabled(Feature::SpawnCsv) && collab_tools_enabled(turn_context)
}
fn agent_jobs_worker_tools_enabled(turn_context: &TurnContext) -> bool {
+30 -1
View File
@@ -44,7 +44,10 @@ async fn legacy_resume_seeds_multi_agent_version_for_later_forks() {
.build(&server)
.await
.expect("create legacy source thread");
assert_eq!(initial.codex.multi_agent_version(), None);
assert_eq!(
initial.codex.multi_agent_version(),
Some(MultiAgentVersion::Disabled)
);
initial.codex.ensure_rollout_materialized().await;
initial
.codex
@@ -58,6 +61,11 @@ async fn legacy_resume_seeds_multi_agent_version_for_later_forks() {
.shutdown_and_wait()
.await
.expect("shutdown source thread");
remove_multi_agent_version(&rollout_path);
assert_eq!(
latest_multi_agent_version(&rollout_path, source_thread_id),
None
);
let mut resume_builder = test_codex().with_config(|config| {
config
@@ -385,3 +393,24 @@ fn latest_multi_agent_version(
})
.flatten()
}
fn remove_multi_agent_version(path: &std::path::Path) {
let text = std::fs::read_to_string(path)
.unwrap_or_else(|err| panic!("failed to read rollout file {}: {err}", path.display()));
let lines = text
.lines()
.filter(|line| !line.trim().is_empty())
.map(|line| {
let mut line = serde_json::from_str::<RolloutLine>(line)
.unwrap_or_else(|err| panic!("failed to parse rollout line `{line}`: {err}"));
if let RolloutItem::SessionMeta(meta_line) = &mut line.item {
meta_line.meta.multi_agent_version = None;
}
serde_json::to_string(&line)
.unwrap_or_else(|err| panic!("failed to serialize rollout line: {err}"))
})
.collect::<Vec<_>>()
.join("\n");
std::fs::write(path, format!("{lines}\n"))
.unwrap_or_else(|err| panic!("failed to write rollout file {}: {err}", path.display()));
}
+1
View File
@@ -2752,6 +2752,7 @@ fn multi_agent_version_from_items(
#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, JsonSchema, TS)]
#[serde(rename_all = "snake_case")]
pub enum MultiAgentVersion {
Disabled,
V1,
V2,
}