mirror of
https://github.com/openai/codex.git
synced 2026-11-15 21:50:46 +00:00
Consolidate thread startup around StartThreadOptions (#34814)
## What changed - Add `StartThreadOptions::new` to provide the standard configuration for a new thread. - Make `ThreadManager::start_thread` the single thread-start entry point and migrate callers from the previous convenience methods. - Derive default environment selections when `environments` is `None`, while preserving explicit selections, including an empty list. GitOrigin-RevId: 8977dc11aed54c5e1215a81eaed2b2cf5fc6087a
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
use crate::StartThreadOptions;
|
||||
use crate::ThreadManager;
|
||||
use crate::agent::AgentControl;
|
||||
use crate::codex_thread::CodexThread;
|
||||
@@ -33,7 +34,7 @@ async fn residency_slot_reservation_unloads_oldest_idle_v2_agent() {
|
||||
Arc::new(codex_exec_server::EnvironmentManager::default_for_tests()),
|
||||
);
|
||||
let root = manager
|
||||
.start_thread(config.clone())
|
||||
.start_thread(StartThreadOptions::new(config.clone()))
|
||||
.await
|
||||
.expect("start root thread");
|
||||
let control = manager.agent_control();
|
||||
@@ -79,7 +80,7 @@ async fn interrupted_v2_agent_is_lost_after_residency_eviction() {
|
||||
Arc::new(codex_exec_server::EnvironmentManager::default_for_tests()),
|
||||
);
|
||||
let root = manager
|
||||
.start_thread(config.clone())
|
||||
.start_thread(StartThreadOptions::new(config.clone()))
|
||||
.await
|
||||
.expect("start root thread");
|
||||
let control = manager.agent_control();
|
||||
|
||||
@@ -36,7 +36,6 @@ use codex_protocol::protocol::AskForApproval;
|
||||
use codex_protocol::protocol::CompactedItem;
|
||||
use codex_protocol::protocol::ErrorEvent;
|
||||
use codex_protocol::protocol::EventMsg;
|
||||
use codex_protocol::protocol::InitialHistory;
|
||||
use codex_protocol::protocol::InterAgentCommunication;
|
||||
use codex_protocol::protocol::ItemCompletedEvent;
|
||||
use codex_protocol::protocol::RolloutItem;
|
||||
@@ -160,7 +159,7 @@ impl AgentControlHarness {
|
||||
async fn start_thread(&self) -> (ThreadId, Arc<CodexThread>) {
|
||||
let new_thread = self
|
||||
.manager
|
||||
.start_thread(self.config.clone())
|
||||
.start_thread(StartThreadOptions::new(self.config.clone()))
|
||||
.await
|
||||
.expect("start thread");
|
||||
(new_thread.thread_id, new_thread.thread)
|
||||
@@ -169,19 +168,10 @@ impl AgentControlHarness {
|
||||
async fn start_paginated_thread(&self) -> (ThreadId, Arc<CodexThread>) {
|
||||
let new_thread = self
|
||||
.manager
|
||||
.start_thread_with_options(StartThreadOptions {
|
||||
config: self.config.clone(),
|
||||
allow_provider_model_fallback: false,
|
||||
initial_history: InitialHistory::New,
|
||||
.start_thread(StartThreadOptions {
|
||||
history_mode: Some(ThreadHistoryMode::Paginated),
|
||||
session_source: None,
|
||||
thread_source: None,
|
||||
dynamic_tools: Vec::new(),
|
||||
metrics_service_name: None,
|
||||
parent_trace: None,
|
||||
environments: Vec::new(),
|
||||
thread_extension_init: ExtensionDataInit::default(),
|
||||
supports_openai_form_elicitation: false,
|
||||
environments: Some(Vec::new()),
|
||||
..StartThreadOptions::new(self.config.clone())
|
||||
})
|
||||
.await
|
||||
.expect("start paginated thread");
|
||||
@@ -1219,7 +1209,7 @@ async fn spawn_agent_can_fork_parent_thread_history_with_sanitized_items() {
|
||||
Some("Child subagent guidance.".to_string());
|
||||
let new_thread = harness
|
||||
.manager
|
||||
.start_thread(parent_config.clone())
|
||||
.start_thread(StartThreadOptions::new(parent_config.clone()))
|
||||
.await
|
||||
.expect("start parent thread");
|
||||
let parent_thread_id = new_thread.thread_id;
|
||||
@@ -1445,7 +1435,7 @@ async fn spawn_agent_fork_strips_parent_usage_hints_from_compacted_history() {
|
||||
Some("Child subagent guidance.".to_string());
|
||||
let new_thread = harness
|
||||
.manager
|
||||
.start_thread(parent_config)
|
||||
.start_thread(StartThreadOptions::new(parent_config))
|
||||
.await
|
||||
.expect("start parent thread");
|
||||
let parent_thread_id = new_thread.thread_id;
|
||||
@@ -1750,19 +1740,10 @@ async fn spawn_agent_fork_last_n_turns_drops_parent_startup_prefix_when_under_li
|
||||
thread_extension_init.insert(selected_capability_roots.clone());
|
||||
let parent = harness
|
||||
.manager
|
||||
.start_thread_with_options(StartThreadOptions {
|
||||
config: harness.config.clone(),
|
||||
allow_provider_model_fallback: false,
|
||||
initial_history: InitialHistory::New,
|
||||
history_mode: None,
|
||||
session_source: None,
|
||||
thread_source: None,
|
||||
dynamic_tools: Vec::new(),
|
||||
metrics_service_name: None,
|
||||
parent_trace: None,
|
||||
environments: Vec::new(),
|
||||
.start_thread(StartThreadOptions {
|
||||
environments: Some(Vec::new()),
|
||||
thread_extension_init,
|
||||
supports_openai_form_elicitation: false,
|
||||
..StartThreadOptions::new(harness.config.clone())
|
||||
})
|
||||
.await
|
||||
.expect("start parent thread");
|
||||
@@ -1876,7 +1857,7 @@ async fn spawn_agent_fork_last_n_turns_strips_parent_usage_hints() {
|
||||
Some("Child subagent guidance.".to_string());
|
||||
let new_thread = harness
|
||||
.manager
|
||||
.start_thread(parent_config)
|
||||
.start_thread(StartThreadOptions::new(parent_config))
|
||||
.await
|
||||
.expect("start parent thread");
|
||||
let parent_thread_id = new_thread.thread_id;
|
||||
@@ -1976,7 +1957,7 @@ async fn spawn_agent_respects_legacy_max_threads_alias() {
|
||||
let control = manager.agent_control();
|
||||
|
||||
let _ = manager
|
||||
.start_thread(config.clone())
|
||||
.start_thread(StartThreadOptions::new(config.clone()))
|
||||
.await
|
||||
.expect("start thread");
|
||||
|
||||
@@ -2227,7 +2208,7 @@ async fn multi_agent_v2_completion_ignores_dead_direct_parent() {
|
||||
let _ = config.features.enable(Feature::MultiAgentV2);
|
||||
let root = harness
|
||||
.manager
|
||||
.start_thread(config.clone())
|
||||
.start_thread(StartThreadOptions::new(config.clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
let root_thread_id = root.thread_id;
|
||||
@@ -2339,7 +2320,7 @@ async fn multi_agent_v2_completion_queues_message_for_direct_parent() {
|
||||
let _ = tester_config.features.enable(Feature::MultiAgentV2);
|
||||
let tester_thread_id = harness
|
||||
.manager
|
||||
.start_thread(tester_config.clone())
|
||||
.start_thread(StartThreadOptions::new(tester_config.clone()))
|
||||
.await
|
||||
.expect("tester thread should start")
|
||||
.thread_id;
|
||||
@@ -2521,19 +2502,10 @@ async fn spawn_thread_subagents_persist_parent_originator_across_new_and_truncat
|
||||
let harness = AgentControlHarness::new().await;
|
||||
let parent = harness
|
||||
.manager
|
||||
.start_thread_with_options(StartThreadOptions {
|
||||
config: harness.config.clone(),
|
||||
allow_provider_model_fallback: false,
|
||||
initial_history: InitialHistory::New,
|
||||
history_mode: None,
|
||||
session_source: None,
|
||||
thread_source: None,
|
||||
dynamic_tools: Vec::new(),
|
||||
.start_thread(StartThreadOptions {
|
||||
metrics_service_name: Some("codex_work_desktop".to_string()),
|
||||
parent_trace: None,
|
||||
environments: Vec::new(),
|
||||
thread_extension_init: ExtensionDataInit::default(),
|
||||
supports_openai_form_elicitation: false,
|
||||
environments: Some(Vec::new()),
|
||||
..StartThreadOptions::new(harness.config.clone())
|
||||
})
|
||||
.await
|
||||
.expect("parent thread should start");
|
||||
@@ -3044,7 +3016,7 @@ async fn list_agent_subtree_thread_ids_finds_live_descendants_of_unloaded_root()
|
||||
);
|
||||
let control = manager.agent_control();
|
||||
let parent_thread_id = manager
|
||||
.start_thread(config.clone())
|
||||
.start_thread(StartThreadOptions::new(config.clone()))
|
||||
.await
|
||||
.expect("parent should start")
|
||||
.thread_id;
|
||||
|
||||
@@ -17,6 +17,7 @@ use crate::session::session::Session;
|
||||
use crate::session::turn::build_prompt;
|
||||
use crate::session::turn::built_tools;
|
||||
use crate::state_db_bridge::StateDbHandle;
|
||||
use crate::thread_manager::StartThreadOptions;
|
||||
use crate::thread_manager::ThreadManager;
|
||||
use crate::thread_manager::thread_store_from_config;
|
||||
use codex_extension_api::empty_extension_registry;
|
||||
@@ -64,7 +65,9 @@ pub async fn build_prompt_input(
|
||||
/*attestation_provider*/ None,
|
||||
/*external_time_provider*/ None,
|
||||
);
|
||||
let thread = thread_manager.start_thread(config).await?;
|
||||
let thread = thread_manager
|
||||
.start_thread(StartThreadOptions::new(config))
|
||||
.await?;
|
||||
|
||||
let output = build_prompt_input_from_session(&thread.thread.session, input).await;
|
||||
let shutdown = thread.thread.shutdown_and_wait().await;
|
||||
|
||||
@@ -198,11 +198,30 @@ pub struct StartThreadOptions {
|
||||
pub dynamic_tools: Vec<codex_protocol::dynamic_tools::DynamicToolSpec>,
|
||||
pub metrics_service_name: Option<String>,
|
||||
pub parent_trace: Option<W3cTraceContext>,
|
||||
pub environments: Vec<TurnEnvironmentSelection>,
|
||||
pub environments: Option<Vec<TurnEnvironmentSelection>>,
|
||||
pub thread_extension_init: ExtensionDataInit,
|
||||
pub supports_openai_form_elicitation: bool,
|
||||
}
|
||||
|
||||
impl StartThreadOptions {
|
||||
pub fn new(config: Config) -> Self {
|
||||
Self {
|
||||
config,
|
||||
allow_provider_model_fallback: false,
|
||||
initial_history: InitialHistory::New,
|
||||
history_mode: None,
|
||||
session_source: None,
|
||||
thread_source: None,
|
||||
dynamic_tools: Vec::new(),
|
||||
metrics_service_name: None,
|
||||
parent_trace: None,
|
||||
environments: None,
|
||||
thread_extension_init: ExtensionDataInit::default(),
|
||||
supports_openai_form_elicitation: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn originator_from_service_name(service_name: Option<&str>) -> Option<String> {
|
||||
let service_name = service_name?.trim();
|
||||
for originator in [
|
||||
@@ -662,52 +681,22 @@ impl ThreadManager {
|
||||
Ok(subtree_thread_ids)
|
||||
}
|
||||
|
||||
pub async fn start_thread(&self, config: Config) -> CodexResult<NewThread> {
|
||||
// Box delegated thread-spawn futures so these convenience wrappers do
|
||||
// not inline the full spawn path into every caller's async state.
|
||||
Box::pin(self.start_thread_with_tools(config, Vec::new())).await
|
||||
pub async fn start_thread(&self, options: StartThreadOptions) -> CodexResult<NewThread> {
|
||||
Box::pin(self.start_thread_inner(options, /*forked_from_thread_id*/ None)).await
|
||||
}
|
||||
|
||||
pub async fn start_thread_with_tools(
|
||||
&self,
|
||||
config: Config,
|
||||
dynamic_tools: Vec<codex_protocol::dynamic_tools::DynamicToolSpec>,
|
||||
) -> CodexResult<NewThread> {
|
||||
let environments = default_thread_environment_selections(
|
||||
self.state.environment_manager.as_ref(),
|
||||
&config.cwd,
|
||||
&config.workspace_roots,
|
||||
);
|
||||
Box::pin(self.start_thread_with_options(StartThreadOptions {
|
||||
config,
|
||||
allow_provider_model_fallback: false,
|
||||
initial_history: InitialHistory::New,
|
||||
history_mode: None,
|
||||
session_source: None,
|
||||
thread_source: None,
|
||||
dynamic_tools,
|
||||
metrics_service_name: None,
|
||||
parent_trace: None,
|
||||
environments,
|
||||
thread_extension_init: ExtensionDataInit::default(),
|
||||
supports_openai_form_elicitation: false,
|
||||
}))
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn start_thread_with_options(
|
||||
&self,
|
||||
options: StartThreadOptions,
|
||||
) -> CodexResult<NewThread> {
|
||||
self.start_thread_with_options_and_fork_source(options, /*forked_from_thread_id*/ None)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn start_thread_with_options_and_fork_source(
|
||||
async fn start_thread_inner(
|
||||
&self,
|
||||
options: StartThreadOptions,
|
||||
forked_from_thread_id: Option<ThreadId>,
|
||||
) -> CodexResult<NewThread> {
|
||||
let environments = options.environments.unwrap_or_else(|| {
|
||||
default_thread_environment_selections(
|
||||
self.state.environment_manager.as_ref(),
|
||||
&options.config.cwd,
|
||||
&options.config.workspace_roots,
|
||||
)
|
||||
});
|
||||
let agent_control = self.agent_control_for_config(&options.config);
|
||||
let (resumed_session_source, resumed_thread_source) = options
|
||||
.initial_history
|
||||
@@ -731,7 +720,7 @@ impl ThreadManager {
|
||||
/*inherited_environments*/ None,
|
||||
/*inherited_exec_policy*/ None,
|
||||
options.parent_trace,
|
||||
options.environments,
|
||||
environments,
|
||||
options.thread_extension_init,
|
||||
options.supports_openai_form_elicitation,
|
||||
/*user_shell_override*/ None,
|
||||
@@ -772,7 +761,7 @@ impl ThreadManager {
|
||||
inherited_multi_agent_version,
|
||||
),
|
||||
);
|
||||
self.start_thread_with_options_and_fork_source(options, Some(forked_from_thread_id))
|
||||
self.start_thread_inner(options, Some(forked_from_thread_id))
|
||||
.await
|
||||
}
|
||||
|
||||
|
||||
@@ -398,12 +398,12 @@ async fn shutdown_all_threads_bounded_submits_shutdown_to_every_thread() {
|
||||
Arc::new(codex_exec_server::EnvironmentManager::default_for_tests()),
|
||||
);
|
||||
let thread_1 = manager
|
||||
.start_thread(config.clone())
|
||||
.start_thread(StartThreadOptions::new(config.clone()))
|
||||
.await
|
||||
.expect("start first thread")
|
||||
.thread_id;
|
||||
let thread_2 = manager
|
||||
.start_thread(config.clone())
|
||||
.start_thread(StartThreadOptions::new(config.clone()))
|
||||
.await
|
||||
.expect("start second thread")
|
||||
.thread_id;
|
||||
@@ -435,11 +435,11 @@ async fn code_mode_session_provider_is_shared_across_threads() {
|
||||
Arc::new(codex_exec_server::EnvironmentManager::default_for_tests()),
|
||||
);
|
||||
let first = manager
|
||||
.start_thread(config.clone())
|
||||
.start_thread(StartThreadOptions::new(config.clone()))
|
||||
.await
|
||||
.expect("start first thread");
|
||||
let second = manager
|
||||
.start_thread(config)
|
||||
.start_thread(StartThreadOptions::new(config))
|
||||
.await
|
||||
.expect("start second thread");
|
||||
|
||||
@@ -491,21 +491,12 @@ async fn start_thread_keeps_internal_threads_hidden_from_normal_lookups() {
|
||||
Arc::new(codex_exec_server::EnvironmentManager::default_for_tests()),
|
||||
);
|
||||
let thread = manager
|
||||
.start_thread_with_options(StartThreadOptions {
|
||||
config,
|
||||
allow_provider_model_fallback: false,
|
||||
initial_history: InitialHistory::New,
|
||||
history_mode: None,
|
||||
.start_thread(StartThreadOptions {
|
||||
session_source: Some(SessionSource::Internal(
|
||||
InternalSessionSource::MemoryConsolidation,
|
||||
)),
|
||||
thread_source: None,
|
||||
dynamic_tools: Vec::new(),
|
||||
metrics_service_name: None,
|
||||
parent_trace: None,
|
||||
environments: Vec::new(),
|
||||
thread_extension_init: Default::default(),
|
||||
supports_openai_form_elicitation: false,
|
||||
environments: Some(Vec::new()),
|
||||
..StartThreadOptions::new(config)
|
||||
})
|
||||
.await
|
||||
.expect("internal thread should start");
|
||||
@@ -644,36 +635,19 @@ async fn start_thread_seeds_extension_data_for_mcp_and_lifecycle_contributors()
|
||||
};
|
||||
|
||||
let first_thread = manager
|
||||
.start_thread_with_options(StartThreadOptions {
|
||||
config: config.clone(),
|
||||
allow_provider_model_fallback: false,
|
||||
initial_history: InitialHistory::New,
|
||||
history_mode: None,
|
||||
session_source: None,
|
||||
thread_source: None,
|
||||
dynamic_tools: Vec::new(),
|
||||
.start_thread(StartThreadOptions {
|
||||
metrics_service_name: Some("codex_work_desktop".to_string()),
|
||||
parent_trace: None,
|
||||
environments: Vec::new(),
|
||||
environments: Some(Vec::new()),
|
||||
thread_extension_init: selected_root_init("selected-a", "env-a"),
|
||||
supports_openai_form_elicitation: false,
|
||||
..StartThreadOptions::new(config.clone())
|
||||
})
|
||||
.await
|
||||
.expect("start first thread");
|
||||
let second_thread = manager
|
||||
.start_thread_with_options(StartThreadOptions {
|
||||
config: config.clone(),
|
||||
allow_provider_model_fallback: false,
|
||||
initial_history: InitialHistory::New,
|
||||
history_mode: None,
|
||||
session_source: None,
|
||||
thread_source: None,
|
||||
dynamic_tools: Vec::new(),
|
||||
metrics_service_name: None,
|
||||
parent_trace: None,
|
||||
environments: Vec::new(),
|
||||
.start_thread(StartThreadOptions {
|
||||
environments: Some(Vec::new()),
|
||||
thread_extension_init: selected_root_init("selected-b", "env-b"),
|
||||
supports_openai_form_elicitation: false,
|
||||
..StartThreadOptions::new(config.clone())
|
||||
})
|
||||
.await
|
||||
.expect("start second thread");
|
||||
@@ -783,9 +757,7 @@ async fn selected_capability_roots_round_trip_through_fork() {
|
||||
},
|
||||
}];
|
||||
let inherited = manager
|
||||
.start_thread_with_options(StartThreadOptions {
|
||||
config,
|
||||
allow_provider_model_fallback: false,
|
||||
.start_thread(StartThreadOptions {
|
||||
initial_history: InitialHistory::Forked(vec![RolloutItem::SessionMeta(
|
||||
SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
@@ -795,15 +767,8 @@ async fn selected_capability_roots_round_trip_through_fork() {
|
||||
git: None,
|
||||
},
|
||||
)]),
|
||||
history_mode: None,
|
||||
session_source: None,
|
||||
thread_source: None,
|
||||
dynamic_tools: Vec::new(),
|
||||
metrics_service_name: None,
|
||||
parent_trace: None,
|
||||
environments: Vec::new(),
|
||||
thread_extension_init: Default::default(),
|
||||
supports_openai_form_elicitation: false,
|
||||
environments: Some(Vec::new()),
|
||||
..StartThreadOptions::new(config)
|
||||
})
|
||||
.await
|
||||
.expect("start inherited fork");
|
||||
@@ -866,19 +831,9 @@ async fn resume_and_fork_do_not_restore_thread_environments_from_rollout() {
|
||||
let mut source_config = config.clone();
|
||||
source_config.cwd = selected_cwd.clone();
|
||||
let source = manager
|
||||
.start_thread_with_options(StartThreadOptions {
|
||||
config: source_config,
|
||||
allow_provider_model_fallback: false,
|
||||
initial_history: InitialHistory::New,
|
||||
history_mode: None,
|
||||
session_source: None,
|
||||
thread_source: None,
|
||||
dynamic_tools: Vec::new(),
|
||||
metrics_service_name: None,
|
||||
parent_trace: None,
|
||||
environments: environments.clone(),
|
||||
thread_extension_init: Default::default(),
|
||||
supports_openai_form_elicitation: false,
|
||||
.start_thread(StartThreadOptions {
|
||||
environments: Some(environments.clone()),
|
||||
..StartThreadOptions::new(source_config)
|
||||
})
|
||||
.await
|
||||
.expect("start source thread");
|
||||
@@ -999,7 +954,7 @@ async fn explicit_installation_id_skips_codex_home_file() {
|
||||
);
|
||||
|
||||
let thread = manager
|
||||
.start_thread(config.clone())
|
||||
.start_thread(StartThreadOptions::new(config.clone()))
|
||||
.await
|
||||
.expect("start thread with explicit installation id");
|
||||
|
||||
@@ -1042,7 +997,7 @@ async fn resume_active_thread_from_rollout_returns_running_thread() {
|
||||
);
|
||||
|
||||
let source = manager
|
||||
.start_thread(config.clone())
|
||||
.start_thread(StartThreadOptions::new(config.clone()))
|
||||
.await
|
||||
.expect("start source thread");
|
||||
source.thread.ensure_rollout_materialized().await;
|
||||
@@ -1104,7 +1059,7 @@ async fn resume_stopped_thread_from_rollout_spawns_new_thread() {
|
||||
);
|
||||
|
||||
let source = manager
|
||||
.start_thread(config.clone())
|
||||
.start_thread(StartThreadOptions::new(config.clone()))
|
||||
.await
|
||||
.expect("start source thread");
|
||||
source.thread.ensure_rollout_materialized().await;
|
||||
@@ -1173,19 +1128,10 @@ async fn resume_stopped_thread_from_rollout_preserves_thread_source() {
|
||||
);
|
||||
|
||||
let source = manager
|
||||
.start_thread_with_options(StartThreadOptions {
|
||||
config: config.clone(),
|
||||
allow_provider_model_fallback: false,
|
||||
initial_history: InitialHistory::New,
|
||||
history_mode: None,
|
||||
session_source: None,
|
||||
.start_thread(StartThreadOptions {
|
||||
thread_source: Some(ThreadSource::User),
|
||||
dynamic_tools: Vec::new(),
|
||||
metrics_service_name: None,
|
||||
parent_trace: None,
|
||||
environments: Vec::new(),
|
||||
thread_extension_init: Default::default(),
|
||||
supports_openai_form_elicitation: false,
|
||||
environments: Some(Vec::new()),
|
||||
..StartThreadOptions::new(config.clone())
|
||||
})
|
||||
.await
|
||||
.expect("start source thread");
|
||||
@@ -1314,7 +1260,7 @@ async fn rollout_path_resume_and_fork_read_history_through_thread_store() {
|
||||
);
|
||||
|
||||
let source = manager
|
||||
.start_thread(config.clone())
|
||||
.start_thread(StartThreadOptions::new(config.clone()))
|
||||
.await
|
||||
.expect("start source thread");
|
||||
source
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use super::*;
|
||||
use crate::StartThreadOptions;
|
||||
use crate::ThreadManager;
|
||||
use crate::config::AgentRoleConfig;
|
||||
use crate::config::DEFAULT_AGENT_MAX_DEPTH;
|
||||
@@ -316,7 +317,7 @@ async fn spawn_agent_fork_context_rejects_agent_type_override() {
|
||||
let role_name = install_role_with_model_override(&mut turn).await;
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -350,7 +351,7 @@ async fn multi_agent_v2_spawn_fork_turns_all_rejects_agent_type_override() {
|
||||
let role_name = install_role_with_model_override(&mut turn).await;
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -436,7 +437,7 @@ async fn spawn_agent_service_tier_override_validates_the_effective_child_model()
|
||||
let (mut session, turn) = make_session_and_context().await;
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -541,7 +542,7 @@ async fn spawn_agent_service_tier_inheritance_preserves_supported_or_configured_
|
||||
turn.config = Arc::new(config);
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -582,7 +583,7 @@ async fn spawn_agent_service_tier_inheritance_preserves_supported_or_configured_
|
||||
turn.config = Arc::new(config);
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -645,7 +646,7 @@ service_tier = "priority"
|
||||
turn.config = Arc::new(config);
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -718,7 +719,7 @@ service_tier = "turbo"
|
||||
turn.config = Arc::new(config);
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -815,7 +816,7 @@ async fn spawn_agent_full_history_fork_accepts_explicit_service_tier() {
|
||||
.await;
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -869,7 +870,7 @@ async fn multi_agent_v2_full_history_fork_accepts_explicit_service_tier() {
|
||||
set_turn_config(&mut turn, config);
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -922,7 +923,7 @@ async fn multi_agent_v2_spawn_partial_fork_turns_allows_agent_type_override() {
|
||||
let role_name = install_role_with_model_override(&mut turn).await;
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -1006,7 +1007,7 @@ async fn multi_agent_v2_spawn_requires_task_name() {
|
||||
let (mut session, mut turn) = make_session_and_context().await;
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -1040,7 +1041,7 @@ async fn multi_agent_v2_spawn_rejects_legacy_items_field() {
|
||||
let (mut session, mut turn) = make_session_and_context().await;
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -1100,7 +1101,7 @@ async fn multi_agent_v2_spawn_returns_path_and_send_message_accepts_relative_pat
|
||||
let (mut session, mut turn) = make_session_and_context().await;
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -1195,7 +1196,7 @@ async fn multi_agent_v2_spawn_rejects_legacy_fork_context() {
|
||||
let (mut session, mut turn) = make_session_and_context().await;
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -1235,7 +1236,7 @@ async fn multi_agent_v2_spawn_rejects_invalid_fork_turns_string() {
|
||||
let (mut session, mut turn) = make_session_and_context().await;
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -1275,7 +1276,7 @@ async fn multi_agent_v2_spawn_rejects_zero_fork_turns() {
|
||||
let (mut session, mut turn) = make_session_and_context().await;
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -1321,7 +1322,7 @@ async fn multi_agent_v2_send_message_accepts_root_target_from_child() {
|
||||
.expect("test config should allow feature update");
|
||||
set_turn_config(&mut turn, config);
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -1397,7 +1398,7 @@ async fn multi_agent_v2_followup_task_rejects_root_target_from_child() {
|
||||
.expect("test config should allow feature update");
|
||||
set_turn_config(&mut turn, config);
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -1473,7 +1474,7 @@ async fn multi_agent_v2_list_agents_returns_completed_status() {
|
||||
let (mut session, mut turn) = make_session_and_context().await;
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -1561,7 +1562,7 @@ async fn multi_agent_v2_list_agents_filters_by_relative_path_prefix() {
|
||||
let _ = config.features.enable(Feature::MultiAgentV2);
|
||||
set_turn_config(&mut turn, config.clone());
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -1642,7 +1643,7 @@ async fn multi_agent_v2_list_agents_omits_closed_agents() {
|
||||
let (mut session, mut turn) = make_session_and_context().await;
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -1702,7 +1703,7 @@ async fn multi_agent_v2_list_agents_keeps_interrupted_resident_agents() {
|
||||
let (mut session, mut turn) = make_session_and_context().await;
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -1774,7 +1775,7 @@ async fn multi_agent_v2_send_message_rejects_legacy_items_field() {
|
||||
let (mut session, mut turn) = make_session_and_context().await;
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -1830,7 +1831,7 @@ async fn multi_agent_v2_send_message_rejects_interrupt_parameter() {
|
||||
let (mut session, mut turn) = make_session_and_context().await;
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -1907,7 +1908,7 @@ async fn multi_agent_v2_followup_task_completion_notifies_parent_on_every_turn()
|
||||
let _ = config.features.enable(Feature::MultiAgentV2);
|
||||
set_turn_config(&mut turn, config);
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
// Production spawn_agent calls happen after the parent turn has resolved
|
||||
@@ -2060,7 +2061,7 @@ async fn multi_agent_v2_followup_task_rejects_legacy_items_field() {
|
||||
let (mut session, mut turn) = make_session_and_context().await;
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -2113,7 +2114,7 @@ async fn multi_agent_v2_interrupted_turn_does_not_notify_parent() {
|
||||
let (mut session, mut turn) = make_session_and_context().await;
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -2190,7 +2191,7 @@ async fn multi_agent_v2_spawn_omits_agent_id_when_named() {
|
||||
let (mut session, mut turn) = make_session_and_context().await;
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -2229,7 +2230,7 @@ async fn multi_agent_v2_spawn_surfaces_task_name_validation_errors() {
|
||||
let (mut session, mut turn) = make_session_and_context().await;
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -2449,7 +2450,7 @@ async fn multi_agent_v2_spawn_agent_ignores_configured_max_depth() {
|
||||
.enable(Feature::MultiAgentV2)
|
||||
.expect("test config should allow feature update");
|
||||
let root = manager
|
||||
.start_thread(config.clone())
|
||||
.start_thread(StartThreadOptions::new(config.clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -2574,7 +2575,7 @@ async fn send_input_interrupts_before_prompt() {
|
||||
session.services.agent_control = manager.agent_control();
|
||||
let config = turn.config.as_ref().clone();
|
||||
let thread = manager
|
||||
.start_thread(config.clone())
|
||||
.start_thread(StartThreadOptions::new(config.clone()))
|
||||
.await
|
||||
.expect("start thread");
|
||||
let agent_id = thread.thread_id;
|
||||
@@ -2616,7 +2617,7 @@ async fn send_input_accepts_structured_items() {
|
||||
session.services.agent_control = manager.agent_control();
|
||||
let config = turn.config.as_ref().clone();
|
||||
let thread = manager
|
||||
.start_thread(config.clone())
|
||||
.start_thread(StartThreadOptions::new(config.clone()))
|
||||
.await
|
||||
.expect("start thread");
|
||||
let agent_id = thread.thread_id;
|
||||
@@ -2712,7 +2713,7 @@ async fn resume_agent_noops_for_active_agent() {
|
||||
session.services.agent_control = manager.agent_control();
|
||||
let config = turn.config.as_ref().clone();
|
||||
let thread = manager
|
||||
.start_thread(config.clone())
|
||||
.start_thread(StartThreadOptions::new(config.clone()))
|
||||
.await
|
||||
.expect("start thread");
|
||||
let agent_id = thread.thread_id;
|
||||
@@ -2918,7 +2919,7 @@ async fn multi_agent_v2_wait_agent_accepts_timeout_only_argument() {
|
||||
let (mut session, mut turn) = make_session_and_context().await;
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -3270,7 +3271,7 @@ async fn wait_agent_times_out_when_status_is_not_final() {
|
||||
session.services.agent_control = manager.agent_control();
|
||||
let config = turn.config.as_ref().clone();
|
||||
let thread = manager
|
||||
.start_thread(config.clone())
|
||||
.start_thread(StartThreadOptions::new(config.clone()))
|
||||
.await
|
||||
.expect("start thread");
|
||||
let agent_id = thread.thread_id;
|
||||
@@ -3313,7 +3314,7 @@ async fn wait_agent_clamps_short_timeouts_to_minimum() {
|
||||
session.services.agent_control = manager.agent_control();
|
||||
let config = turn.config.as_ref().clone();
|
||||
let thread = manager
|
||||
.start_thread(config.clone())
|
||||
.start_thread(StartThreadOptions::new(config.clone()))
|
||||
.await
|
||||
.expect("start thread");
|
||||
let agent_id = thread.thread_id;
|
||||
@@ -3351,7 +3352,7 @@ async fn wait_agent_returns_final_status_without_timeout() {
|
||||
session.services.agent_control = manager.agent_control();
|
||||
let config = turn.config.as_ref().clone();
|
||||
let thread = manager
|
||||
.start_thread(config.clone())
|
||||
.start_thread(StartThreadOptions::new(config.clone()))
|
||||
.await
|
||||
.expect("start thread");
|
||||
let agent_id = thread.thread_id;
|
||||
@@ -3401,7 +3402,7 @@ async fn multi_agent_v2_wait_agent_returns_summary_for_mailbox_activity() {
|
||||
let (mut session, mut turn) = make_session_and_context().await;
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -3491,7 +3492,7 @@ async fn multi_agent_v2_wait_agent_returns_for_already_queued_mail() {
|
||||
let (mut session, mut turn) = make_session_and_context().await;
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -3572,7 +3573,7 @@ async fn multi_agent_v2_wait_agent_wakes_on_any_mailbox_notification() {
|
||||
let (mut session, mut turn) = make_session_and_context().await;
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -3663,7 +3664,7 @@ async fn multi_agent_v2_wait_agent_does_not_return_completed_content() {
|
||||
let (mut session, mut turn) = make_session_and_context().await;
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -3752,7 +3753,7 @@ async fn multi_agent_v2_interrupt_agent_accepts_task_name_target() {
|
||||
let (mut session, mut turn) = make_session_and_context().await;
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -3878,7 +3879,7 @@ async fn multi_agent_v2_interrupt_agent_accepts_unloaded_task_name_target() {
|
||||
Some(state_db.clone()),
|
||||
);
|
||||
let root = manager
|
||||
.start_thread(config.clone())
|
||||
.start_thread(StartThreadOptions::new(config.clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -3969,7 +3970,7 @@ async fn multi_agent_v2_interrupt_agent_rejects_root_target_and_id() {
|
||||
let (mut session, mut turn) = make_session_and_context().await;
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -4025,7 +4026,7 @@ async fn multi_agent_v2_interrupt_agent_rejects_self_target_by_id() {
|
||||
.expect("test config should allow feature update");
|
||||
set_turn_config(&mut turn, config);
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -4092,7 +4093,7 @@ async fn multi_agent_v2_interrupt_agent_rejects_self_target_by_task_name() {
|
||||
.expect("test config should allow feature update");
|
||||
set_turn_config(&mut turn, config);
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
@@ -4155,7 +4156,7 @@ async fn close_agent_submits_shutdown_and_returns_previous_status() {
|
||||
session.services.agent_control = manager.agent_control();
|
||||
let config = turn.config.as_ref().clone();
|
||||
let thread = manager
|
||||
.start_thread(config.clone())
|
||||
.start_thread(StartThreadOptions::new(config.clone()))
|
||||
.await
|
||||
.expect("start thread");
|
||||
let agent_id = thread.thread_id;
|
||||
@@ -4216,7 +4217,7 @@ async fn tool_handlers_cascade_close_and_resume_and_keep_explicitly_closed_subtr
|
||||
);
|
||||
|
||||
let parent = manager
|
||||
.start_thread(config.clone())
|
||||
.start_thread(StartThreadOptions::new(config.clone()))
|
||||
.await
|
||||
.expect("parent thread should start");
|
||||
let parent_thread_id = parent.thread_id;
|
||||
@@ -4348,7 +4349,7 @@ async fn tool_handlers_cascade_close_and_resume_and_keep_explicitly_closed_subtr
|
||||
);
|
||||
|
||||
let operator = manager
|
||||
.start_thread(config.clone())
|
||||
.start_thread(StartThreadOptions::new(config.clone()))
|
||||
.await
|
||||
.expect("operator thread should start");
|
||||
let operator_session = operator.thread.session.clone();
|
||||
|
||||
Reference in New Issue
Block a user