mirror of
https://github.com/openai/codex.git
synced 2026-11-03 16:23:51 +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 parent
06782eded7
commit
08ae0fc0ce
25 files changed
+237
-399
No files matched your search
@@ -2663,7 +2663,9 @@ mod tests {
|
|||||||
thread_id: conversation_id,
|
thread_id: conversation_id,
|
||||||
thread: conversation,
|
thread: conversation,
|
||||||
..
|
..
|
||||||
} = thread_manager.start_thread(config.clone()).await?;
|
} = thread_manager
|
||||||
|
.start_thread(codex_core::StartThreadOptions::new(config.clone()))
|
||||||
|
.await?;
|
||||||
let thread_state = new_thread_state();
|
let thread_state = new_thread_state();
|
||||||
let thread_watch_manager = ThreadWatchManager::new();
|
let thread_watch_manager = ThreadWatchManager::new();
|
||||||
let (tx, mut rx) = mpsc::channel(CHANNEL_CAPACITY);
|
let (tx, mut rx) = mpsc::channel(CHANNEL_CAPACITY);
|
||||||
@@ -3241,7 +3243,9 @@ mod tests {
|
|||||||
thread_id: conversation_id,
|
thread_id: conversation_id,
|
||||||
thread: conversation,
|
thread: conversation,
|
||||||
..
|
..
|
||||||
} = thread_manager.start_thread(config.clone()).await?;
|
} = thread_manager
|
||||||
|
.start_thread(codex_core::StartThreadOptions::new(config.clone()))
|
||||||
|
.await?;
|
||||||
let thread_state = new_thread_state();
|
let thread_state = new_thread_state();
|
||||||
{
|
{
|
||||||
let mut state = thread_state.lock().await;
|
let mut state = thread_state.lock().await;
|
||||||
@@ -3329,7 +3333,9 @@ mod tests {
|
|||||||
thread_id: conversation_id,
|
thread_id: conversation_id,
|
||||||
thread: conversation,
|
thread: conversation,
|
||||||
..
|
..
|
||||||
} = thread_manager.start_thread(config).await?;
|
} = thread_manager
|
||||||
|
.start_thread(codex_core::StartThreadOptions::new(config))
|
||||||
|
.await?;
|
||||||
let child_thread_id = ThreadId::new();
|
let child_thread_id = ThreadId::new();
|
||||||
let child_thread_id_string = child_thread_id.to_string();
|
let child_thread_id_string = child_thread_id.to_string();
|
||||||
let thread_watch_manager = ThreadWatchManager::new();
|
let thread_watch_manager = ThreadWatchManager::new();
|
||||||
@@ -3419,7 +3425,9 @@ mod tests {
|
|||||||
thread_id: conversation_id,
|
thread_id: conversation_id,
|
||||||
thread: conversation,
|
thread: conversation,
|
||||||
..
|
..
|
||||||
} = thread_manager.start_thread(config).await?;
|
} = thread_manager
|
||||||
|
.start_thread(codex_core::StartThreadOptions::new(config))
|
||||||
|
.await?;
|
||||||
let (tx, mut rx) = mpsc::channel(CHANNEL_CAPACITY);
|
let (tx, mut rx) = mpsc::channel(CHANNEL_CAPACITY);
|
||||||
let outgoing = Arc::new(OutgoingMessageSender::new(
|
let outgoing = Arc::new(OutgoingMessageSender::new(
|
||||||
tx,
|
tx,
|
||||||
|
|||||||
@@ -198,7 +198,10 @@ mod tests {
|
|||||||
Some(temp_dir.path().join("good")),
|
Some(temp_dir.path().join("good")),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
let thread = thread_manager.start_thread(thread_config).await?.thread;
|
let thread = thread_manager
|
||||||
|
.start_thread(codex_core::StartThreadOptions::new(thread_config))
|
||||||
|
.await?
|
||||||
|
.thread;
|
||||||
std::fs::write(
|
std::fs::write(
|
||||||
temp_dir.path().join(codex_config::CONFIG_TOML_FILE),
|
temp_dir.path().join(codex_config::CONFIG_TOML_FILE),
|
||||||
r#"
|
r#"
|
||||||
@@ -337,8 +340,12 @@ enabled = false
|
|||||||
/*external_time_provider*/ None,
|
/*external_time_provider*/ None,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
thread_manager.start_thread(good_config).await?;
|
thread_manager
|
||||||
thread_manager.start_thread(bad_config).await?;
|
.start_thread(codex_core::StartThreadOptions::new(good_config))
|
||||||
|
.await?;
|
||||||
|
thread_manager
|
||||||
|
.start_thread(codex_core::StartThreadOptions::new(bad_config))
|
||||||
|
.await?;
|
||||||
|
|
||||||
let loader = Arc::new(CountingThreadConfigLoader {
|
let loader = Arc::new(CountingThreadConfigLoader {
|
||||||
good_cwd: AbsolutePathBuf::try_from(good_cwd)?,
|
good_cwd: AbsolutePathBuf::try_from(good_cwd)?,
|
||||||
|
|||||||
@@ -1228,8 +1228,7 @@ impl ThreadRequestProcessor {
|
|||||||
..
|
..
|
||||||
} = listener_task_context
|
} = listener_task_context
|
||||||
.thread_manager
|
.thread_manager
|
||||||
.start_thread_with_options(StartThreadOptions {
|
.start_thread(StartThreadOptions {
|
||||||
config,
|
|
||||||
allow_provider_model_fallback,
|
allow_provider_model_fallback,
|
||||||
initial_history: match session_start_source
|
initial_history: match session_start_source
|
||||||
.unwrap_or(codex_app_server_protocol::ThreadStartSource::Startup)
|
.unwrap_or(codex_app_server_protocol::ThreadStartSource::Startup)
|
||||||
@@ -1238,14 +1237,14 @@ impl ThreadRequestProcessor {
|
|||||||
codex_app_server_protocol::ThreadStartSource::Clear => InitialHistory::Cleared,
|
codex_app_server_protocol::ThreadStartSource::Clear => InitialHistory::Cleared,
|
||||||
},
|
},
|
||||||
history_mode,
|
history_mode,
|
||||||
session_source: None,
|
|
||||||
thread_source,
|
thread_source,
|
||||||
dynamic_tools,
|
dynamic_tools,
|
||||||
metrics_service_name: service_name,
|
metrics_service_name: service_name,
|
||||||
parent_trace: request_trace,
|
parent_trace: request_trace,
|
||||||
environments,
|
environments: Some(environments),
|
||||||
thread_extension_init,
|
thread_extension_init,
|
||||||
supports_openai_form_elicitation,
|
supports_openai_form_elicitation,
|
||||||
|
..StartThreadOptions::new(config)
|
||||||
})
|
})
|
||||||
.instrument(tracing::info_span!(
|
.instrument(tracing::info_span!(
|
||||||
"app_server.thread_start.create_thread",
|
"app_server.thread_start.create_thread",
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use crate::StartThreadOptions;
|
||||||
use crate::ThreadManager;
|
use crate::ThreadManager;
|
||||||
use crate::agent::AgentControl;
|
use crate::agent::AgentControl;
|
||||||
use crate::codex_thread::CodexThread;
|
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()),
|
Arc::new(codex_exec_server::EnvironmentManager::default_for_tests()),
|
||||||
);
|
);
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread(config.clone())
|
.start_thread(StartThreadOptions::new(config.clone()))
|
||||||
.await
|
.await
|
||||||
.expect("start root thread");
|
.expect("start root thread");
|
||||||
let control = manager.agent_control();
|
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()),
|
Arc::new(codex_exec_server::EnvironmentManager::default_for_tests()),
|
||||||
);
|
);
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread(config.clone())
|
.start_thread(StartThreadOptions::new(config.clone()))
|
||||||
.await
|
.await
|
||||||
.expect("start root thread");
|
.expect("start root thread");
|
||||||
let control = manager.agent_control();
|
let control = manager.agent_control();
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ use codex_protocol::protocol::AskForApproval;
|
|||||||
use codex_protocol::protocol::CompactedItem;
|
use codex_protocol::protocol::CompactedItem;
|
||||||
use codex_protocol::protocol::ErrorEvent;
|
use codex_protocol::protocol::ErrorEvent;
|
||||||
use codex_protocol::protocol::EventMsg;
|
use codex_protocol::protocol::EventMsg;
|
||||||
use codex_protocol::protocol::InitialHistory;
|
|
||||||
use codex_protocol::protocol::InterAgentCommunication;
|
use codex_protocol::protocol::InterAgentCommunication;
|
||||||
use codex_protocol::protocol::ItemCompletedEvent;
|
use codex_protocol::protocol::ItemCompletedEvent;
|
||||||
use codex_protocol::protocol::RolloutItem;
|
use codex_protocol::protocol::RolloutItem;
|
||||||
@@ -160,7 +159,7 @@ impl AgentControlHarness {
|
|||||||
async fn start_thread(&self) -> (ThreadId, Arc<CodexThread>) {
|
async fn start_thread(&self) -> (ThreadId, Arc<CodexThread>) {
|
||||||
let new_thread = self
|
let new_thread = self
|
||||||
.manager
|
.manager
|
||||||
.start_thread(self.config.clone())
|
.start_thread(StartThreadOptions::new(self.config.clone()))
|
||||||
.await
|
.await
|
||||||
.expect("start thread");
|
.expect("start thread");
|
||||||
(new_thread.thread_id, new_thread.thread)
|
(new_thread.thread_id, new_thread.thread)
|
||||||
@@ -169,19 +168,10 @@ impl AgentControlHarness {
|
|||||||
async fn start_paginated_thread(&self) -> (ThreadId, Arc<CodexThread>) {
|
async fn start_paginated_thread(&self) -> (ThreadId, Arc<CodexThread>) {
|
||||||
let new_thread = self
|
let new_thread = self
|
||||||
.manager
|
.manager
|
||||||
.start_thread_with_options(StartThreadOptions {
|
.start_thread(StartThreadOptions {
|
||||||
config: self.config.clone(),
|
|
||||||
allow_provider_model_fallback: false,
|
|
||||||
initial_history: InitialHistory::New,
|
|
||||||
history_mode: Some(ThreadHistoryMode::Paginated),
|
history_mode: Some(ThreadHistoryMode::Paginated),
|
||||||
session_source: None,
|
environments: Some(Vec::new()),
|
||||||
thread_source: None,
|
..StartThreadOptions::new(self.config.clone())
|
||||||
dynamic_tools: Vec::new(),
|
|
||||||
metrics_service_name: None,
|
|
||||||
parent_trace: None,
|
|
||||||
environments: Vec::new(),
|
|
||||||
thread_extension_init: ExtensionDataInit::default(),
|
|
||||||
supports_openai_form_elicitation: false,
|
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.expect("start paginated thread");
|
.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());
|
Some("Child subagent guidance.".to_string());
|
||||||
let new_thread = harness
|
let new_thread = harness
|
||||||
.manager
|
.manager
|
||||||
.start_thread(parent_config.clone())
|
.start_thread(StartThreadOptions::new(parent_config.clone()))
|
||||||
.await
|
.await
|
||||||
.expect("start parent thread");
|
.expect("start parent thread");
|
||||||
let parent_thread_id = new_thread.thread_id;
|
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());
|
Some("Child subagent guidance.".to_string());
|
||||||
let new_thread = harness
|
let new_thread = harness
|
||||||
.manager
|
.manager
|
||||||
.start_thread(parent_config)
|
.start_thread(StartThreadOptions::new(parent_config))
|
||||||
.await
|
.await
|
||||||
.expect("start parent thread");
|
.expect("start parent thread");
|
||||||
let parent_thread_id = new_thread.thread_id;
|
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());
|
thread_extension_init.insert(selected_capability_roots.clone());
|
||||||
let parent = harness
|
let parent = harness
|
||||||
.manager
|
.manager
|
||||||
.start_thread_with_options(StartThreadOptions {
|
.start_thread(StartThreadOptions {
|
||||||
config: harness.config.clone(),
|
environments: Some(Vec::new()),
|
||||||
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(),
|
|
||||||
thread_extension_init,
|
thread_extension_init,
|
||||||
supports_openai_form_elicitation: false,
|
..StartThreadOptions::new(harness.config.clone())
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.expect("start parent thread");
|
.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());
|
Some("Child subagent guidance.".to_string());
|
||||||
let new_thread = harness
|
let new_thread = harness
|
||||||
.manager
|
.manager
|
||||||
.start_thread(parent_config)
|
.start_thread(StartThreadOptions::new(parent_config))
|
||||||
.await
|
.await
|
||||||
.expect("start parent thread");
|
.expect("start parent thread");
|
||||||
let parent_thread_id = new_thread.thread_id;
|
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 control = manager.agent_control();
|
||||||
|
|
||||||
let _ = manager
|
let _ = manager
|
||||||
.start_thread(config.clone())
|
.start_thread(StartThreadOptions::new(config.clone()))
|
||||||
.await
|
.await
|
||||||
.expect("start thread");
|
.expect("start thread");
|
||||||
|
|
||||||
@@ -2227,7 +2208,7 @@ async fn multi_agent_v2_completion_ignores_dead_direct_parent() {
|
|||||||
let _ = config.features.enable(Feature::MultiAgentV2);
|
let _ = config.features.enable(Feature::MultiAgentV2);
|
||||||
let root = harness
|
let root = harness
|
||||||
.manager
|
.manager
|
||||||
.start_thread(config.clone())
|
.start_thread(StartThreadOptions::new(config.clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
let root_thread_id = root.thread_id;
|
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_config.features.enable(Feature::MultiAgentV2);
|
||||||
let tester_thread_id = harness
|
let tester_thread_id = harness
|
||||||
.manager
|
.manager
|
||||||
.start_thread(tester_config.clone())
|
.start_thread(StartThreadOptions::new(tester_config.clone()))
|
||||||
.await
|
.await
|
||||||
.expect("tester thread should start")
|
.expect("tester thread should start")
|
||||||
.thread_id;
|
.thread_id;
|
||||||
@@ -2521,19 +2502,10 @@ async fn spawn_thread_subagents_persist_parent_originator_across_new_and_truncat
|
|||||||
let harness = AgentControlHarness::new().await;
|
let harness = AgentControlHarness::new().await;
|
||||||
let parent = harness
|
let parent = harness
|
||||||
.manager
|
.manager
|
||||||
.start_thread_with_options(StartThreadOptions {
|
.start_thread(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: Some("codex_work_desktop".to_string()),
|
metrics_service_name: Some("codex_work_desktop".to_string()),
|
||||||
parent_trace: None,
|
environments: Some(Vec::new()),
|
||||||
environments: Vec::new(),
|
..StartThreadOptions::new(harness.config.clone())
|
||||||
thread_extension_init: ExtensionDataInit::default(),
|
|
||||||
supports_openai_form_elicitation: false,
|
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.expect("parent thread should start");
|
.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 control = manager.agent_control();
|
||||||
let parent_thread_id = manager
|
let parent_thread_id = manager
|
||||||
.start_thread(config.clone())
|
.start_thread(StartThreadOptions::new(config.clone()))
|
||||||
.await
|
.await
|
||||||
.expect("parent should start")
|
.expect("parent should start")
|
||||||
.thread_id;
|
.thread_id;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ use crate::session::session::Session;
|
|||||||
use crate::session::turn::build_prompt;
|
use crate::session::turn::build_prompt;
|
||||||
use crate::session::turn::built_tools;
|
use crate::session::turn::built_tools;
|
||||||
use crate::state_db_bridge::StateDbHandle;
|
use crate::state_db_bridge::StateDbHandle;
|
||||||
|
use crate::thread_manager::StartThreadOptions;
|
||||||
use crate::thread_manager::ThreadManager;
|
use crate::thread_manager::ThreadManager;
|
||||||
use crate::thread_manager::thread_store_from_config;
|
use crate::thread_manager::thread_store_from_config;
|
||||||
use codex_extension_api::empty_extension_registry;
|
use codex_extension_api::empty_extension_registry;
|
||||||
@@ -64,7 +65,9 @@ pub async fn build_prompt_input(
|
|||||||
/*attestation_provider*/ None,
|
/*attestation_provider*/ None,
|
||||||
/*external_time_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 output = build_prompt_input_from_session(&thread.thread.session, input).await;
|
||||||
let shutdown = thread.thread.shutdown_and_wait().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 dynamic_tools: Vec<codex_protocol::dynamic_tools::DynamicToolSpec>,
|
||||||
pub metrics_service_name: Option<String>,
|
pub metrics_service_name: Option<String>,
|
||||||
pub parent_trace: Option<W3cTraceContext>,
|
pub parent_trace: Option<W3cTraceContext>,
|
||||||
pub environments: Vec<TurnEnvironmentSelection>,
|
pub environments: Option<Vec<TurnEnvironmentSelection>>,
|
||||||
pub thread_extension_init: ExtensionDataInit,
|
pub thread_extension_init: ExtensionDataInit,
|
||||||
pub supports_openai_form_elicitation: bool,
|
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> {
|
fn originator_from_service_name(service_name: Option<&str>) -> Option<String> {
|
||||||
let service_name = service_name?.trim();
|
let service_name = service_name?.trim();
|
||||||
for originator in [
|
for originator in [
|
||||||
@@ -662,52 +681,22 @@ impl ThreadManager {
|
|||||||
Ok(subtree_thread_ids)
|
Ok(subtree_thread_ids)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn start_thread(&self, config: Config) -> CodexResult<NewThread> {
|
pub async fn start_thread(&self, options: StartThreadOptions) -> CodexResult<NewThread> {
|
||||||
// Box delegated thread-spawn futures so these convenience wrappers do
|
Box::pin(self.start_thread_inner(options, /*forked_from_thread_id*/ None)).await
|
||||||
// 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_with_tools(
|
async fn start_thread_inner(
|
||||||
&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(
|
|
||||||
&self,
|
&self,
|
||||||
options: StartThreadOptions,
|
options: StartThreadOptions,
|
||||||
forked_from_thread_id: Option<ThreadId>,
|
forked_from_thread_id: Option<ThreadId>,
|
||||||
) -> CodexResult<NewThread> {
|
) -> 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 agent_control = self.agent_control_for_config(&options.config);
|
||||||
let (resumed_session_source, resumed_thread_source) = options
|
let (resumed_session_source, resumed_thread_source) = options
|
||||||
.initial_history
|
.initial_history
|
||||||
@@ -731,7 +720,7 @@ impl ThreadManager {
|
|||||||
/*inherited_environments*/ None,
|
/*inherited_environments*/ None,
|
||||||
/*inherited_exec_policy*/ None,
|
/*inherited_exec_policy*/ None,
|
||||||
options.parent_trace,
|
options.parent_trace,
|
||||||
options.environments,
|
environments,
|
||||||
options.thread_extension_init,
|
options.thread_extension_init,
|
||||||
options.supports_openai_form_elicitation,
|
options.supports_openai_form_elicitation,
|
||||||
/*user_shell_override*/ None,
|
/*user_shell_override*/ None,
|
||||||
@@ -772,7 +761,7 @@ impl ThreadManager {
|
|||||||
inherited_multi_agent_version,
|
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
|
.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()),
|
Arc::new(codex_exec_server::EnvironmentManager::default_for_tests()),
|
||||||
);
|
);
|
||||||
let thread_1 = manager
|
let thread_1 = manager
|
||||||
.start_thread(config.clone())
|
.start_thread(StartThreadOptions::new(config.clone()))
|
||||||
.await
|
.await
|
||||||
.expect("start first thread")
|
.expect("start first thread")
|
||||||
.thread_id;
|
.thread_id;
|
||||||
let thread_2 = manager
|
let thread_2 = manager
|
||||||
.start_thread(config.clone())
|
.start_thread(StartThreadOptions::new(config.clone()))
|
||||||
.await
|
.await
|
||||||
.expect("start second thread")
|
.expect("start second thread")
|
||||||
.thread_id;
|
.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()),
|
Arc::new(codex_exec_server::EnvironmentManager::default_for_tests()),
|
||||||
);
|
);
|
||||||
let first = manager
|
let first = manager
|
||||||
.start_thread(config.clone())
|
.start_thread(StartThreadOptions::new(config.clone()))
|
||||||
.await
|
.await
|
||||||
.expect("start first thread");
|
.expect("start first thread");
|
||||||
let second = manager
|
let second = manager
|
||||||
.start_thread(config)
|
.start_thread(StartThreadOptions::new(config))
|
||||||
.await
|
.await
|
||||||
.expect("start second thread");
|
.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()),
|
Arc::new(codex_exec_server::EnvironmentManager::default_for_tests()),
|
||||||
);
|
);
|
||||||
let thread = manager
|
let thread = manager
|
||||||
.start_thread_with_options(StartThreadOptions {
|
.start_thread(StartThreadOptions {
|
||||||
config,
|
|
||||||
allow_provider_model_fallback: false,
|
|
||||||
initial_history: InitialHistory::New,
|
|
||||||
history_mode: None,
|
|
||||||
session_source: Some(SessionSource::Internal(
|
session_source: Some(SessionSource::Internal(
|
||||||
InternalSessionSource::MemoryConsolidation,
|
InternalSessionSource::MemoryConsolidation,
|
||||||
)),
|
)),
|
||||||
thread_source: None,
|
environments: Some(Vec::new()),
|
||||||
dynamic_tools: Vec::new(),
|
..StartThreadOptions::new(config)
|
||||||
metrics_service_name: None,
|
|
||||||
parent_trace: None,
|
|
||||||
environments: Vec::new(),
|
|
||||||
thread_extension_init: Default::default(),
|
|
||||||
supports_openai_form_elicitation: false,
|
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.expect("internal thread should start");
|
.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
|
let first_thread = manager
|
||||||
.start_thread_with_options(StartThreadOptions {
|
.start_thread(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: Some("codex_work_desktop".to_string()),
|
metrics_service_name: Some("codex_work_desktop".to_string()),
|
||||||
parent_trace: None,
|
environments: Some(Vec::new()),
|
||||||
environments: Vec::new(),
|
|
||||||
thread_extension_init: selected_root_init("selected-a", "env-a"),
|
thread_extension_init: selected_root_init("selected-a", "env-a"),
|
||||||
supports_openai_form_elicitation: false,
|
..StartThreadOptions::new(config.clone())
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.expect("start first thread");
|
.expect("start first thread");
|
||||||
let second_thread = manager
|
let second_thread = manager
|
||||||
.start_thread_with_options(StartThreadOptions {
|
.start_thread(StartThreadOptions {
|
||||||
config: config.clone(),
|
environments: Some(Vec::new()),
|
||||||
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(),
|
|
||||||
thread_extension_init: selected_root_init("selected-b", "env-b"),
|
thread_extension_init: selected_root_init("selected-b", "env-b"),
|
||||||
supports_openai_form_elicitation: false,
|
..StartThreadOptions::new(config.clone())
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.expect("start second thread");
|
.expect("start second thread");
|
||||||
@@ -783,9 +757,7 @@ async fn selected_capability_roots_round_trip_through_fork() {
|
|||||||
},
|
},
|
||||||
}];
|
}];
|
||||||
let inherited = manager
|
let inherited = manager
|
||||||
.start_thread_with_options(StartThreadOptions {
|
.start_thread(StartThreadOptions {
|
||||||
config,
|
|
||||||
allow_provider_model_fallback: false,
|
|
||||||
initial_history: InitialHistory::Forked(vec![RolloutItem::SessionMeta(
|
initial_history: InitialHistory::Forked(vec![RolloutItem::SessionMeta(
|
||||||
SessionMetaLine {
|
SessionMetaLine {
|
||||||
meta: SessionMeta {
|
meta: SessionMeta {
|
||||||
@@ -795,15 +767,8 @@ async fn selected_capability_roots_round_trip_through_fork() {
|
|||||||
git: None,
|
git: None,
|
||||||
},
|
},
|
||||||
)]),
|
)]),
|
||||||
history_mode: None,
|
environments: Some(Vec::new()),
|
||||||
session_source: None,
|
..StartThreadOptions::new(config)
|
||||||
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,
|
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.expect("start inherited fork");
|
.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();
|
let mut source_config = config.clone();
|
||||||
source_config.cwd = selected_cwd.clone();
|
source_config.cwd = selected_cwd.clone();
|
||||||
let source = manager
|
let source = manager
|
||||||
.start_thread_with_options(StartThreadOptions {
|
.start_thread(StartThreadOptions {
|
||||||
config: source_config,
|
environments: Some(environments.clone()),
|
||||||
allow_provider_model_fallback: false,
|
..StartThreadOptions::new(source_config)
|
||||||
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,
|
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.expect("start source thread");
|
.expect("start source thread");
|
||||||
@@ -999,7 +954,7 @@ async fn explicit_installation_id_skips_codex_home_file() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let thread = manager
|
let thread = manager
|
||||||
.start_thread(config.clone())
|
.start_thread(StartThreadOptions::new(config.clone()))
|
||||||
.await
|
.await
|
||||||
.expect("start thread with explicit installation id");
|
.expect("start thread with explicit installation id");
|
||||||
|
|
||||||
@@ -1042,7 +997,7 @@ async fn resume_active_thread_from_rollout_returns_running_thread() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let source = manager
|
let source = manager
|
||||||
.start_thread(config.clone())
|
.start_thread(StartThreadOptions::new(config.clone()))
|
||||||
.await
|
.await
|
||||||
.expect("start source thread");
|
.expect("start source thread");
|
||||||
source.thread.ensure_rollout_materialized().await;
|
source.thread.ensure_rollout_materialized().await;
|
||||||
@@ -1104,7 +1059,7 @@ async fn resume_stopped_thread_from_rollout_spawns_new_thread() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let source = manager
|
let source = manager
|
||||||
.start_thread(config.clone())
|
.start_thread(StartThreadOptions::new(config.clone()))
|
||||||
.await
|
.await
|
||||||
.expect("start source thread");
|
.expect("start source thread");
|
||||||
source.thread.ensure_rollout_materialized().await;
|
source.thread.ensure_rollout_materialized().await;
|
||||||
@@ -1173,19 +1128,10 @@ async fn resume_stopped_thread_from_rollout_preserves_thread_source() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let source = manager
|
let source = manager
|
||||||
.start_thread_with_options(StartThreadOptions {
|
.start_thread(StartThreadOptions {
|
||||||
config: config.clone(),
|
|
||||||
allow_provider_model_fallback: false,
|
|
||||||
initial_history: InitialHistory::New,
|
|
||||||
history_mode: None,
|
|
||||||
session_source: None,
|
|
||||||
thread_source: Some(ThreadSource::User),
|
thread_source: Some(ThreadSource::User),
|
||||||
dynamic_tools: Vec::new(),
|
environments: Some(Vec::new()),
|
||||||
metrics_service_name: None,
|
..StartThreadOptions::new(config.clone())
|
||||||
parent_trace: None,
|
|
||||||
environments: Vec::new(),
|
|
||||||
thread_extension_init: Default::default(),
|
|
||||||
supports_openai_form_elicitation: false,
|
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.expect("start source thread");
|
.expect("start source thread");
|
||||||
@@ -1314,7 +1260,7 @@ async fn rollout_path_resume_and_fork_read_history_through_thread_store() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let source = manager
|
let source = manager
|
||||||
.start_thread(config.clone())
|
.start_thread(StartThreadOptions::new(config.clone()))
|
||||||
.await
|
.await
|
||||||
.expect("start source thread");
|
.expect("start source thread");
|
||||||
source
|
source
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::StartThreadOptions;
|
||||||
use crate::ThreadManager;
|
use crate::ThreadManager;
|
||||||
use crate::config::AgentRoleConfig;
|
use crate::config::AgentRoleConfig;
|
||||||
use crate::config::DEFAULT_AGENT_MAX_DEPTH;
|
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 role_name = install_role_with_model_override(&mut turn).await;
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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 role_name = install_role_with_model_override(&mut turn).await;
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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 (mut session, turn) = make_session_and_context().await;
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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);
|
turn.config = Arc::new(config);
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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);
|
turn.config = Arc::new(config);
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
session.services.agent_control = manager.agent_control();
|
||||||
@@ -645,7 +646,7 @@ service_tier = "priority"
|
|||||||
turn.config = Arc::new(config);
|
turn.config = Arc::new(config);
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
session.services.agent_control = manager.agent_control();
|
||||||
@@ -718,7 +719,7 @@ service_tier = "turbo"
|
|||||||
turn.config = Arc::new(config);
|
turn.config = Arc::new(config);
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
session.services.agent_control = manager.agent_control();
|
||||||
@@ -815,7 +816,7 @@ async fn spawn_agent_full_history_fork_accepts_explicit_service_tier() {
|
|||||||
.await;
|
.await;
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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);
|
set_turn_config(&mut turn, config);
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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 role_name = install_role_with_model_override(&mut turn).await;
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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 (mut session, mut turn) = make_session_and_context().await;
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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 (mut session, mut turn) = make_session_and_context().await;
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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 (mut session, mut turn) = make_session_and_context().await;
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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 (mut session, mut turn) = make_session_and_context().await;
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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 (mut session, mut turn) = make_session_and_context().await;
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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 (mut session, mut turn) = make_session_and_context().await;
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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");
|
.expect("test config should allow feature update");
|
||||||
set_turn_config(&mut turn, config);
|
set_turn_config(&mut turn, config);
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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");
|
.expect("test config should allow feature update");
|
||||||
set_turn_config(&mut turn, config);
|
set_turn_config(&mut turn, config);
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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 (mut session, mut turn) = make_session_and_context().await;
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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);
|
let _ = config.features.enable(Feature::MultiAgentV2);
|
||||||
set_turn_config(&mut turn, config.clone());
|
set_turn_config(&mut turn, config.clone());
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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 (mut session, mut turn) = make_session_and_context().await;
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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 (mut session, mut turn) = make_session_and_context().await;
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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 (mut session, mut turn) = make_session_and_context().await;
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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 (mut session, mut turn) = make_session_and_context().await;
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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);
|
let _ = config.features.enable(Feature::MultiAgentV2);
|
||||||
set_turn_config(&mut turn, config);
|
set_turn_config(&mut turn, config);
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
// Production spawn_agent calls happen after the parent turn has resolved
|
// 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 (mut session, mut turn) = make_session_and_context().await;
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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 (mut session, mut turn) = make_session_and_context().await;
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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 (mut session, mut turn) = make_session_and_context().await;
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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 (mut session, mut turn) = make_session_and_context().await;
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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)
|
.enable(Feature::MultiAgentV2)
|
||||||
.expect("test config should allow feature update");
|
.expect("test config should allow feature update");
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread(config.clone())
|
.start_thread(StartThreadOptions::new(config.clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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();
|
session.services.agent_control = manager.agent_control();
|
||||||
let config = turn.config.as_ref().clone();
|
let config = turn.config.as_ref().clone();
|
||||||
let thread = manager
|
let thread = manager
|
||||||
.start_thread(config.clone())
|
.start_thread(StartThreadOptions::new(config.clone()))
|
||||||
.await
|
.await
|
||||||
.expect("start thread");
|
.expect("start thread");
|
||||||
let agent_id = thread.thread_id;
|
let agent_id = thread.thread_id;
|
||||||
@@ -2616,7 +2617,7 @@ async fn send_input_accepts_structured_items() {
|
|||||||
session.services.agent_control = manager.agent_control();
|
session.services.agent_control = manager.agent_control();
|
||||||
let config = turn.config.as_ref().clone();
|
let config = turn.config.as_ref().clone();
|
||||||
let thread = manager
|
let thread = manager
|
||||||
.start_thread(config.clone())
|
.start_thread(StartThreadOptions::new(config.clone()))
|
||||||
.await
|
.await
|
||||||
.expect("start thread");
|
.expect("start thread");
|
||||||
let agent_id = thread.thread_id;
|
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();
|
session.services.agent_control = manager.agent_control();
|
||||||
let config = turn.config.as_ref().clone();
|
let config = turn.config.as_ref().clone();
|
||||||
let thread = manager
|
let thread = manager
|
||||||
.start_thread(config.clone())
|
.start_thread(StartThreadOptions::new(config.clone()))
|
||||||
.await
|
.await
|
||||||
.expect("start thread");
|
.expect("start thread");
|
||||||
let agent_id = thread.thread_id;
|
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 (mut session, mut turn) = make_session_and_context().await;
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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();
|
session.services.agent_control = manager.agent_control();
|
||||||
let config = turn.config.as_ref().clone();
|
let config = turn.config.as_ref().clone();
|
||||||
let thread = manager
|
let thread = manager
|
||||||
.start_thread(config.clone())
|
.start_thread(StartThreadOptions::new(config.clone()))
|
||||||
.await
|
.await
|
||||||
.expect("start thread");
|
.expect("start thread");
|
||||||
let agent_id = thread.thread_id;
|
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();
|
session.services.agent_control = manager.agent_control();
|
||||||
let config = turn.config.as_ref().clone();
|
let config = turn.config.as_ref().clone();
|
||||||
let thread = manager
|
let thread = manager
|
||||||
.start_thread(config.clone())
|
.start_thread(StartThreadOptions::new(config.clone()))
|
||||||
.await
|
.await
|
||||||
.expect("start thread");
|
.expect("start thread");
|
||||||
let agent_id = thread.thread_id;
|
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();
|
session.services.agent_control = manager.agent_control();
|
||||||
let config = turn.config.as_ref().clone();
|
let config = turn.config.as_ref().clone();
|
||||||
let thread = manager
|
let thread = manager
|
||||||
.start_thread(config.clone())
|
.start_thread(StartThreadOptions::new(config.clone()))
|
||||||
.await
|
.await
|
||||||
.expect("start thread");
|
.expect("start thread");
|
||||||
let agent_id = thread.thread_id;
|
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 (mut session, mut turn) = make_session_and_context().await;
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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 (mut session, mut turn) = make_session_and_context().await;
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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 (mut session, mut turn) = make_session_and_context().await;
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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 (mut session, mut turn) = make_session_and_context().await;
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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 (mut session, mut turn) = make_session_and_context().await;
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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()),
|
Some(state_db.clone()),
|
||||||
);
|
);
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread(config.clone())
|
.start_thread(StartThreadOptions::new(config.clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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 (mut session, mut turn) = make_session_and_context().await;
|
||||||
let manager = thread_manager();
|
let manager = thread_manager();
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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");
|
.expect("test config should allow feature update");
|
||||||
set_turn_config(&mut turn, config);
|
set_turn_config(&mut turn, config);
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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");
|
.expect("test config should allow feature update");
|
||||||
set_turn_config(&mut turn, config);
|
set_turn_config(&mut turn, config);
|
||||||
let root = manager
|
let root = manager
|
||||||
.start_thread((*turn.config).clone())
|
.start_thread(StartThreadOptions::new((*turn.config).clone()))
|
||||||
.await
|
.await
|
||||||
.expect("root thread should start");
|
.expect("root thread should start");
|
||||||
session.services.agent_control = manager.agent_control();
|
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();
|
session.services.agent_control = manager.agent_control();
|
||||||
let config = turn.config.as_ref().clone();
|
let config = turn.config.as_ref().clone();
|
||||||
let thread = manager
|
let thread = manager
|
||||||
.start_thread(config.clone())
|
.start_thread(StartThreadOptions::new(config.clone()))
|
||||||
.await
|
.await
|
||||||
.expect("start thread");
|
.expect("start thread");
|
||||||
let agent_id = thread.thread_id;
|
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
|
let parent = manager
|
||||||
.start_thread(config.clone())
|
.start_thread(StartThreadOptions::new(config.clone()))
|
||||||
.await
|
.await
|
||||||
.expect("parent thread should start");
|
.expect("parent thread should start");
|
||||||
let parent_thread_id = parent.thread_id;
|
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
|
let operator = manager
|
||||||
.start_thread(config.clone())
|
.start_thread(StartThreadOptions::new(config.clone()))
|
||||||
.await
|
.await
|
||||||
.expect("operator thread should start");
|
.expect("operator thread should start");
|
||||||
let operator_session = operator.thread.session.clone();
|
let operator_session = operator.thread.session.clone();
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ use codex_protocol::openai_models::ModelInfo;
|
|||||||
use codex_protocol::openai_models::ModelsResponse;
|
use codex_protocol::openai_models::ModelsResponse;
|
||||||
use codex_protocol::protocol::AskForApproval;
|
use codex_protocol::protocol::AskForApproval;
|
||||||
use codex_protocol::protocol::EventMsg;
|
use codex_protocol::protocol::EventMsg;
|
||||||
use codex_protocol::protocol::InitialHistory;
|
|
||||||
use codex_protocol::protocol::Op;
|
use codex_protocol::protocol::Op;
|
||||||
use codex_protocol::protocol::RealtimeConversationVersion as RealtimeWsVersion;
|
use codex_protocol::protocol::RealtimeConversationVersion as RealtimeWsVersion;
|
||||||
use codex_protocol::protocol::SandboxPolicy;
|
use codex_protocol::protocol::SandboxPolicy;
|
||||||
@@ -696,24 +695,11 @@ impl TestCodexBuilder {
|
|||||||
.await?
|
.await?
|
||||||
}
|
}
|
||||||
(None, None) => {
|
(None, None) => {
|
||||||
let environments = thread_manager
|
Box::pin(thread_manager.start_thread(StartThreadOptions {
|
||||||
.default_environment_selections(&config.cwd, &config.workspace_roots);
|
history_mode: self.history_mode,
|
||||||
Box::pin(
|
supports_openai_form_elicitation: self.supports_openai_form_elicitation,
|
||||||
thread_manager.start_thread_with_options(StartThreadOptions {
|
..StartThreadOptions::new(config.clone())
|
||||||
config: config.clone(),
|
}))
|
||||||
allow_provider_model_fallback: false,
|
|
||||||
initial_history: InitialHistory::New,
|
|
||||||
history_mode: self.history_mode,
|
|
||||||
session_source: None,
|
|
||||||
thread_source: None,
|
|
||||||
dynamic_tools: Vec::new(),
|
|
||||||
metrics_service_name: None,
|
|
||||||
parent_trace: None,
|
|
||||||
environments,
|
|
||||||
thread_extension_init: Default::default(),
|
|
||||||
supports_openai_form_elicitation: self.supports_openai_form_elicitation,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.await?
|
.await?
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ use codex_exec_server::REMOTE_ENVIRONMENT_ID;
|
|||||||
use codex_features::Feature;
|
use codex_features::Feature;
|
||||||
use codex_home::CodexHomeUserInstructionsProvider;
|
use codex_home::CodexHomeUserInstructionsProvider;
|
||||||
use codex_protocol::protocol::EventMsg;
|
use codex_protocol::protocol::EventMsg;
|
||||||
use codex_protocol::protocol::InitialHistory;
|
|
||||||
use codex_protocol::protocol::Op;
|
use codex_protocol::protocol::Op;
|
||||||
use codex_protocol::protocol::RolloutItem;
|
use codex_protocol::protocol::RolloutItem;
|
||||||
use codex_protocol::protocol::RolloutLine;
|
use codex_protocol::protocol::RolloutLine;
|
||||||
@@ -484,19 +483,9 @@ async fn loads_user_instructions_without_a_primary_environment() -> Result<()> {
|
|||||||
|
|
||||||
let no_environment_thread = test
|
let no_environment_thread = test
|
||||||
.thread_manager
|
.thread_manager
|
||||||
.start_thread_with_options(StartThreadOptions {
|
.start_thread(StartThreadOptions {
|
||||||
config: test.config.clone(),
|
environments: Some(Vec::new()),
|
||||||
allow_provider_model_fallback: false,
|
..StartThreadOptions::new(test.config.clone())
|
||||||
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(),
|
|
||||||
thread_extension_init: Default::default(),
|
|
||||||
supports_openai_form_elicitation: false,
|
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
assert_eq!(provider.load_count(), 2);
|
assert_eq!(provider.load_count(), 2);
|
||||||
@@ -691,17 +680,8 @@ async fn multi_environment_thread_loads_every_project_and_keeps_creation_snapsho
|
|||||||
let remote_source = test.config.cwd.join(GLOBAL_AGENTS_FILENAME);
|
let remote_source = test.config.cwd.join(GLOBAL_AGENTS_FILENAME);
|
||||||
let thread = test
|
let thread = test
|
||||||
.thread_manager
|
.thread_manager
|
||||||
.start_thread_with_options(StartThreadOptions {
|
.start_thread(StartThreadOptions {
|
||||||
config: test.config.clone(),
|
environments: Some(vec![
|
||||||
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![
|
|
||||||
TurnEnvironmentSelection {
|
TurnEnvironmentSelection {
|
||||||
environment_id: REMOTE_ENVIRONMENT_ID.to_string(),
|
environment_id: REMOTE_ENVIRONMENT_ID.to_string(),
|
||||||
cwd: PathUri::from_abs_path(&test.config.cwd),
|
cwd: PathUri::from_abs_path(&test.config.cwd),
|
||||||
@@ -712,9 +692,8 @@ async fn multi_environment_thread_loads_every_project_and_keeps_creation_snapsho
|
|||||||
cwd: PathUri::from_host_native_path(local_root.path())?,
|
cwd: PathUri::from_host_native_path(local_root.path())?,
|
||||||
workspace_roots: vec![PathUri::from_host_native_path(local_root.path())?],
|
workspace_roots: vec![PathUri::from_host_native_path(local_root.path())?],
|
||||||
},
|
},
|
||||||
],
|
]),
|
||||||
thread_extension_init: Default::default(),
|
..StartThreadOptions::new(test.config.clone())
|
||||||
supports_openai_form_elicitation: false,
|
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
assert_eq!(provider.load_count(), 2);
|
assert_eq!(provider.load_count(), 2);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use base64::Engine;
|
use base64::Engine;
|
||||||
use base64::engine::general_purpose::STANDARD as BASE64_STANDARD;
|
use base64::engine::general_purpose::STANDARD as BASE64_STANDARD;
|
||||||
|
use codex_core::StartThreadOptions;
|
||||||
use codex_protocol::dynamic_tools::DynamicToolCallOutputContentItem;
|
use codex_protocol::dynamic_tools::DynamicToolCallOutputContentItem;
|
||||||
use codex_protocol::dynamic_tools::DynamicToolFunctionSpec;
|
use codex_protocol::dynamic_tools::DynamicToolFunctionSpec;
|
||||||
use codex_protocol::dynamic_tools::DynamicToolNamespaceSpec;
|
use codex_protocol::dynamic_tools::DynamicToolNamespaceSpec;
|
||||||
@@ -94,7 +95,10 @@ async fn dynamic_tool_audio_exceeding_the_output_budget_is_omitted() -> Result<(
|
|||||||
});
|
});
|
||||||
let new_thread = base_test
|
let new_thread = base_test
|
||||||
.thread_manager
|
.thread_manager
|
||||||
.start_thread_with_tools(base_test.config.clone(), vec![dynamic_tool])
|
.start_thread(StartThreadOptions {
|
||||||
|
dynamic_tools: vec![dynamic_tool],
|
||||||
|
..StartThreadOptions::new(base_test.config.clone())
|
||||||
|
})
|
||||||
.await?;
|
.await?;
|
||||||
let mut test = base_test;
|
let mut test = base_test;
|
||||||
test.codex = new_thread.thread;
|
test.codex = new_thread.thread;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use codex_core::ModelClient;
|
|||||||
use codex_core::NewThread;
|
use codex_core::NewThread;
|
||||||
use codex_core::Prompt;
|
use codex_core::Prompt;
|
||||||
use codex_core::ResponseEvent;
|
use codex_core::ResponseEvent;
|
||||||
|
use codex_core::StartThreadOptions;
|
||||||
use codex_core::ThreadManager;
|
use codex_core::ThreadManager;
|
||||||
use codex_core::resolve_installation_id;
|
use codex_core::resolve_installation_id;
|
||||||
use codex_core::thread_store_from_config;
|
use codex_core::thread_store_from_config;
|
||||||
@@ -1741,7 +1742,7 @@ async fn prefers_apikey_when_config_prefers_apikey_even_with_chatgpt_tokens() {
|
|||||||
/*external_time_provider*/ None,
|
/*external_time_provider*/ None,
|
||||||
);
|
);
|
||||||
let NewThread { thread: codex, .. } = thread_manager
|
let NewThread { thread: codex, .. } = thread_manager
|
||||||
.start_thread(config.clone())
|
.start_thread(StartThreadOptions::new(config.clone()))
|
||||||
.await
|
.await
|
||||||
.expect("create new conversation");
|
.expect("create new conversation");
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use base64::Engine;
|
|||||||
use base64::engine::general_purpose::STANDARD as BASE64_STANDARD;
|
use base64::engine::general_purpose::STANDARD as BASE64_STANDARD;
|
||||||
use codex_config::types::McpServerConfig;
|
use codex_config::types::McpServerConfig;
|
||||||
use codex_config::types::McpServerTransportConfig;
|
use codex_config::types::McpServerTransportConfig;
|
||||||
|
use codex_core::StartThreadOptions;
|
||||||
use codex_core::config::Config;
|
use codex_core::config::Config;
|
||||||
use codex_core::config::CurrentTimeReminderConfig;
|
use codex_core::config::CurrentTimeReminderConfig;
|
||||||
use codex_extension_api::ExtensionRegistryBuilder;
|
use codex_extension_api::ExtensionRegistryBuilder;
|
||||||
@@ -3628,9 +3629,8 @@ async fn code_mode_can_call_hidden_dynamic_tools() -> Result<()> {
|
|||||||
let base_test = builder.build(&server).await?;
|
let base_test = builder.build(&server).await?;
|
||||||
let new_thread = base_test
|
let new_thread = base_test
|
||||||
.thread_manager
|
.thread_manager
|
||||||
.start_thread_with_tools(
|
.start_thread(StartThreadOptions {
|
||||||
base_test.config.clone(),
|
dynamic_tools: vec![DynamicToolSpec::Namespace(DynamicToolNamespaceSpec {
|
||||||
vec![DynamicToolSpec::Namespace(DynamicToolNamespaceSpec {
|
|
||||||
name: "codex_app".to_string(),
|
name: "codex_app".to_string(),
|
||||||
description: "Codex app tools.".to_string(),
|
description: "Codex app tools.".to_string(),
|
||||||
tools: vec![DynamicToolNamespaceTool::Function(
|
tools: vec![DynamicToolNamespaceTool::Function(
|
||||||
@@ -3649,7 +3649,8 @@ async fn code_mode_can_call_hidden_dynamic_tools() -> Result<()> {
|
|||||||
},
|
},
|
||||||
)],
|
)],
|
||||||
})],
|
})],
|
||||||
)
|
..StartThreadOptions::new(base_test.config.clone())
|
||||||
|
})
|
||||||
.await?;
|
.await?;
|
||||||
let mut test = base_test;
|
let mut test = base_test;
|
||||||
test.codex = new_thread.thread;
|
test.codex = new_thread.thread;
|
||||||
@@ -3797,9 +3798,8 @@ async fn code_mode_excludes_configured_nested_tool_namespaces() -> Result<()> {
|
|||||||
let base_test = builder.build(&server).await?;
|
let base_test = builder.build(&server).await?;
|
||||||
let new_thread = base_test
|
let new_thread = base_test
|
||||||
.thread_manager
|
.thread_manager
|
||||||
.start_thread_with_tools(
|
.start_thread(StartThreadOptions {
|
||||||
base_test.config.clone(),
|
dynamic_tools: vec![DynamicToolSpec::Namespace(DynamicToolNamespaceSpec {
|
||||||
vec![DynamicToolSpec::Namespace(DynamicToolNamespaceSpec {
|
|
||||||
name: "excluded".to_string(),
|
name: "excluded".to_string(),
|
||||||
description: "Excluded tools.".to_string(),
|
description: "Excluded tools.".to_string(),
|
||||||
tools: vec![DynamicToolNamespaceTool::Function(
|
tools: vec![DynamicToolNamespaceTool::Function(
|
||||||
@@ -3815,7 +3815,8 @@ async fn code_mode_excludes_configured_nested_tool_namespaces() -> Result<()> {
|
|||||||
},
|
},
|
||||||
)],
|
)],
|
||||||
})],
|
})],
|
||||||
)
|
..StartThreadOptions::new(base_test.config.clone())
|
||||||
|
})
|
||||||
.await?;
|
.await?;
|
||||||
let mut test = base_test;
|
let mut test = base_test;
|
||||||
test.codex = new_thread.thread;
|
test.codex = new_thread.thread;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use std::fs;
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use base64::Engine;
|
use base64::Engine;
|
||||||
use base64::engine::general_purpose::STANDARD as BASE64_STANDARD;
|
use base64::engine::general_purpose::STANDARD as BASE64_STANDARD;
|
||||||
|
use codex_core::StartThreadOptions;
|
||||||
use codex_core::compact::SUMMARY_PREFIX;
|
use codex_core::compact::SUMMARY_PREFIX;
|
||||||
use codex_features::Feature;
|
use codex_features::Feature;
|
||||||
use codex_login::CodexAuth;
|
use codex_login::CodexAuth;
|
||||||
@@ -1287,7 +1288,10 @@ async fn remote_compact_filters_deferred_dynamic_tools() -> Result<()> {
|
|||||||
})];
|
})];
|
||||||
let new_thread = test
|
let new_thread = test
|
||||||
.thread_manager
|
.thread_manager
|
||||||
.start_thread_with_tools(test.config.clone(), dynamic_tools)
|
.start_thread(StartThreadOptions {
|
||||||
|
dynamic_tools,
|
||||||
|
..StartThreadOptions::new(test.config.clone())
|
||||||
|
})
|
||||||
.await?;
|
.await?;
|
||||||
test.codex = new_thread.thread;
|
test.codex = new_thread.thread;
|
||||||
test.session_configured = new_thread.session_configured;
|
test.session_configured = new_thread.session_configured;
|
||||||
@@ -1403,7 +1407,10 @@ async fn remote_compact_does_not_charge_inline_audio_payload_as_text() -> Result
|
|||||||
});
|
});
|
||||||
let new_thread = test
|
let new_thread = test
|
||||||
.thread_manager
|
.thread_manager
|
||||||
.start_thread_with_tools(test.config.clone(), vec![dynamic_tool])
|
.start_thread(StartThreadOptions {
|
||||||
|
dynamic_tools: vec![dynamic_tool],
|
||||||
|
..StartThreadOptions::new(test.config.clone())
|
||||||
|
})
|
||||||
.await?;
|
.await?;
|
||||||
test.codex = new_thread.thread;
|
test.codex = new_thread.thread;
|
||||||
test.session_configured = new_thread.session_configured;
|
test.session_configured = new_thread.session_configured;
|
||||||
@@ -2045,7 +2052,10 @@ async fn remote_compact_trims_tool_search_output_to_empty_tools_array() -> Resul
|
|||||||
let mut test = builder.build(&server).await?;
|
let mut test = builder.build(&server).await?;
|
||||||
let new_thread = test
|
let new_thread = test
|
||||||
.thread_manager
|
.thread_manager
|
||||||
.start_thread_with_tools(test.config.clone(), vec![dynamic_tool])
|
.start_thread(StartThreadOptions {
|
||||||
|
dynamic_tools: vec![dynamic_tool],
|
||||||
|
..StartThreadOptions::new(test.config.clone())
|
||||||
|
})
|
||||||
.await?;
|
.await?;
|
||||||
test.codex = new_thread.thread;
|
test.codex = new_thread.thread;
|
||||||
test.session_configured = new_thread.session_configured;
|
test.session_configured = new_thread.session_configured;
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ use codex_protocol::config_types::ApprovalsReviewer;
|
|||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
use codex_protocol::protocol::AskForApproval;
|
use codex_protocol::protocol::AskForApproval;
|
||||||
use codex_protocol::protocol::EventMsg;
|
use codex_protocol::protocol::EventMsg;
|
||||||
use codex_protocol::protocol::InitialHistory;
|
|
||||||
use codex_protocol::protocol::Op;
|
use codex_protocol::protocol::Op;
|
||||||
use codex_protocol::protocol::ThreadSource;
|
use codex_protocol::protocol::ThreadSource;
|
||||||
use codex_protocol::user_input::UserInput;
|
use codex_protocol::user_input::UserInput;
|
||||||
@@ -257,24 +256,11 @@ async fn ephemeral_system_thread_prewarm_skips_and_turn_observes_fresh_state() -
|
|||||||
|
|
||||||
let mut config = test.config.clone();
|
let mut config = test.config.clone();
|
||||||
config.ephemeral = true;
|
config.ephemeral = true;
|
||||||
let environments = test
|
|
||||||
.thread_manager
|
|
||||||
.default_environment_selections(&config.cwd, &config.workspace_roots);
|
|
||||||
let system_thread = test
|
let system_thread = test
|
||||||
.thread_manager
|
.thread_manager
|
||||||
.start_thread_with_options(StartThreadOptions {
|
.start_thread(StartThreadOptions {
|
||||||
config,
|
|
||||||
allow_provider_model_fallback: false,
|
|
||||||
initial_history: InitialHistory::New,
|
|
||||||
history_mode: None,
|
|
||||||
session_source: None,
|
|
||||||
thread_source: Some(ThreadSource::Feature("system".to_string())),
|
thread_source: Some(ThreadSource::Feature("system".to_string())),
|
||||||
dynamic_tools: Vec::new(),
|
..StartThreadOptions::new(config)
|
||||||
metrics_service_name: None,
|
|
||||||
parent_trace: None,
|
|
||||||
environments,
|
|
||||||
thread_extension_init: Default::default(),
|
|
||||||
supports_openai_form_elicitation: false,
|
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
let prewarm = tokio::time::timeout(
|
let prewarm = tokio::time::timeout(
|
||||||
@@ -386,47 +372,21 @@ async fn concurrent_turns_keep_distinct_worktree_and_repository_metadata() -> Re
|
|||||||
|
|
||||||
let mut worktree_config = test.config.clone();
|
let mut worktree_config = test.config.clone();
|
||||||
worktree_config.cwd = worktree.abs();
|
worktree_config.cwd = worktree.abs();
|
||||||
let worktree_environments = test
|
|
||||||
.thread_manager
|
|
||||||
.default_environment_selections(&worktree_config.cwd, &worktree_config.workspace_roots);
|
|
||||||
let worktree_thread = test
|
let worktree_thread = test
|
||||||
.thread_manager
|
.thread_manager
|
||||||
.start_thread_with_options(StartThreadOptions {
|
.start_thread(StartThreadOptions {
|
||||||
config: worktree_config,
|
|
||||||
allow_provider_model_fallback: false,
|
|
||||||
initial_history: InitialHistory::New,
|
|
||||||
history_mode: None,
|
|
||||||
session_source: None,
|
|
||||||
thread_source: Some(ThreadSource::User),
|
thread_source: Some(ThreadSource::User),
|
||||||
dynamic_tools: Vec::new(),
|
..StartThreadOptions::new(worktree_config)
|
||||||
metrics_service_name: None,
|
|
||||||
parent_trace: None,
|
|
||||||
environments: worktree_environments,
|
|
||||||
thread_extension_init: Default::default(),
|
|
||||||
supports_openai_form_elicitation: false,
|
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let mut other_config = test.config.clone();
|
let mut other_config = test.config.clone();
|
||||||
other_config.cwd = other_repo.path().to_path_buf().abs();
|
other_config.cwd = other_repo.path().to_path_buf().abs();
|
||||||
let other_environments = test
|
|
||||||
.thread_manager
|
|
||||||
.default_environment_selections(&other_config.cwd, &other_config.workspace_roots);
|
|
||||||
let other_thread = test
|
let other_thread = test
|
||||||
.thread_manager
|
.thread_manager
|
||||||
.start_thread_with_options(StartThreadOptions {
|
.start_thread(StartThreadOptions {
|
||||||
config: other_config,
|
|
||||||
allow_provider_model_fallback: false,
|
|
||||||
initial_history: InitialHistory::New,
|
|
||||||
history_mode: None,
|
|
||||||
session_source: None,
|
|
||||||
thread_source: Some(ThreadSource::User),
|
thread_source: Some(ThreadSource::User),
|
||||||
dynamic_tools: Vec::new(),
|
..StartThreadOptions::new(other_config)
|
||||||
metrics_service_name: None,
|
|
||||||
parent_trace: None,
|
|
||||||
environments: other_environments,
|
|
||||||
thread_extension_init: Default::default(),
|
|
||||||
supports_openai_form_elicitation: false,
|
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ use codex_protocol::models::ResponseItem;
|
|||||||
use codex_protocol::permissions::NetworkSandboxPolicy;
|
use codex_protocol::permissions::NetworkSandboxPolicy;
|
||||||
use codex_protocol::protocol::AskForApproval;
|
use codex_protocol::protocol::AskForApproval;
|
||||||
use codex_protocol::protocol::EventMsg;
|
use codex_protocol::protocol::EventMsg;
|
||||||
use codex_protocol::protocol::InitialHistory;
|
|
||||||
use codex_protocol::protocol::Op;
|
use codex_protocol::protocol::Op;
|
||||||
use codex_protocol::protocol::RolloutItem;
|
use codex_protocol::protocol::RolloutItem;
|
||||||
use codex_protocol::protocol::RolloutLine;
|
use codex_protocol::protocol::RolloutLine;
|
||||||
@@ -1415,19 +1414,10 @@ async fn session_end_skips_subagents() -> Result<()> {
|
|||||||
] {
|
] {
|
||||||
let subagent = test
|
let subagent = test
|
||||||
.thread_manager
|
.thread_manager
|
||||||
.start_thread_with_options(StartThreadOptions {
|
.start_thread(StartThreadOptions {
|
||||||
config: test.config.clone(),
|
|
||||||
allow_provider_model_fallback: false,
|
|
||||||
initial_history: InitialHistory::New,
|
|
||||||
history_mode: None,
|
|
||||||
session_source: Some(SessionSource::SubAgent(source)),
|
session_source: Some(SessionSource::SubAgent(source)),
|
||||||
thread_source: None,
|
environments: Some(Vec::new()),
|
||||||
dynamic_tools: Vec::new(),
|
..StartThreadOptions::new(test.config.clone())
|
||||||
metrics_service_name: None,
|
|
||||||
parent_trace: None,
|
|
||||||
environments: Vec::new(),
|
|
||||||
thread_extension_init: Default::default(),
|
|
||||||
supports_openai_form_elicitation: false,
|
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use std::time::Duration;
|
|||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use codex_core::NewThread;
|
use codex_core::NewThread;
|
||||||
|
use codex_core::StartThreadOptions;
|
||||||
use codex_exec_server::ExecutorFileSystem;
|
use codex_exec_server::ExecutorFileSystem;
|
||||||
use codex_exec_server::RemoveOptions;
|
use codex_exec_server::RemoveOptions;
|
||||||
use codex_protocol::models::PermissionProfile;
|
use codex_protocol::models::PermissionProfile;
|
||||||
@@ -183,7 +184,7 @@ async fn regular_mcp_definition_cache_preserves_live_session_state() -> anyhow::
|
|||||||
..
|
..
|
||||||
} = fixture
|
} = fixture
|
||||||
.thread_manager
|
.thread_manager
|
||||||
.start_thread(fixture.config.clone())
|
.start_thread(StartThreadOptions::new(fixture.config.clone()))
|
||||||
.await?;
|
.await?;
|
||||||
let second_pid = wait_for_new_pid(fs.as_ref(), &pid_file, Some(&first_pid)).await?;
|
let second_pid = wait_for_new_pid(fs.as_ref(), &pid_file, Some(&first_pid)).await?;
|
||||||
let second_process = process_label(&second_pid);
|
let second_process = process_label(&second_pid);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use codex_config::types::McpServerConfig;
|
use codex_config::types::McpServerConfig;
|
||||||
use codex_config::types::McpServerTransportConfig;
|
use codex_config::types::McpServerTransportConfig;
|
||||||
|
use codex_core::StartThreadOptions;
|
||||||
use codex_login::CodexAuth;
|
use codex_login::CodexAuth;
|
||||||
use codex_protocol::dynamic_tools::DynamicToolCallOutputContentItem;
|
use codex_protocol::dynamic_tools::DynamicToolCallOutputContentItem;
|
||||||
use codex_protocol::dynamic_tools::DynamicToolFunctionSpec;
|
use codex_protocol::dynamic_tools::DynamicToolFunctionSpec;
|
||||||
@@ -939,7 +940,10 @@ async fn tool_search_returns_deferred_dynamic_tool_and_routes_follow_up_call() -
|
|||||||
let base_test = builder.build(&server).await?;
|
let base_test = builder.build(&server).await?;
|
||||||
let new_thread = base_test
|
let new_thread = base_test
|
||||||
.thread_manager
|
.thread_manager
|
||||||
.start_thread_with_tools(base_test.config.clone(), vec![dynamic_tool])
|
.start_thread(StartThreadOptions {
|
||||||
|
dynamic_tools: vec![dynamic_tool],
|
||||||
|
..StartThreadOptions::new(base_test.config.clone())
|
||||||
|
})
|
||||||
.await?;
|
.await?;
|
||||||
let mut test = base_test;
|
let mut test = base_test;
|
||||||
test.codex = new_thread.thread;
|
test.codex = new_thread.thread;
|
||||||
@@ -1571,7 +1575,10 @@ async fn tool_search_matches_dynamic_tools_by_name_description_namespace_and_sch
|
|||||||
let base_test = builder.build(&server).await?;
|
let base_test = builder.build(&server).await?;
|
||||||
let new_thread = base_test
|
let new_thread = base_test
|
||||||
.thread_manager
|
.thread_manager
|
||||||
.start_thread_with_tools(base_test.config.clone(), vec![dynamic_tool])
|
.start_thread(StartThreadOptions {
|
||||||
|
dynamic_tools: vec![dynamic_tool],
|
||||||
|
..StartThreadOptions::new(base_test.config.clone())
|
||||||
|
})
|
||||||
.await?;
|
.await?;
|
||||||
let mut test = base_test;
|
let mut test = base_test;
|
||||||
test.codex = new_thread.thread;
|
test.codex = new_thread.thread;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use codex_config::types::McpServerConfig;
|
use codex_config::types::McpServerConfig;
|
||||||
use codex_config::types::McpServerTransportConfig;
|
use codex_config::types::McpServerTransportConfig;
|
||||||
|
use codex_core::StartThreadOptions;
|
||||||
use codex_core::config::Config;
|
use codex_core::config::Config;
|
||||||
use codex_extension_api::ExtensionRegistryBuilder;
|
use codex_extension_api::ExtensionRegistryBuilder;
|
||||||
use codex_features::Feature;
|
use codex_features::Feature;
|
||||||
@@ -154,7 +155,10 @@ async fn resume_restores_dynamic_tools_from_rollout_with_sqlite_enabled() -> Res
|
|||||||
let base_test = builder.build(&server).await?;
|
let base_test = builder.build(&server).await?;
|
||||||
let started = base_test
|
let started = base_test
|
||||||
.thread_manager
|
.thread_manager
|
||||||
.start_thread_with_tools(base_test.config.clone(), vec![dynamic_tool])
|
.start_thread(StartThreadOptions {
|
||||||
|
dynamic_tools: vec![dynamic_tool],
|
||||||
|
..StartThreadOptions::new(base_test.config.clone())
|
||||||
|
})
|
||||||
.await?;
|
.await?;
|
||||||
let rollout_path = started
|
let rollout_path = started
|
||||||
.session_configured
|
.session_configured
|
||||||
@@ -251,7 +255,7 @@ async fn resume_restores_legacy_dynamic_tools_from_rollout_with_sqlite_enabled()
|
|||||||
let base_test = builder.build(&server).await?;
|
let base_test = builder.build(&server).await?;
|
||||||
let started = base_test
|
let started = base_test
|
||||||
.thread_manager
|
.thread_manager
|
||||||
.start_thread_with_tools(base_test.config.clone(), Vec::new())
|
.start_thread(StartThreadOptions::new(base_test.config.clone()))
|
||||||
.await?;
|
.await?;
|
||||||
let rollout_path = started
|
let rollout_path = started
|
||||||
.session_configured
|
.session_configured
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ use codex_protocol::models::PermissionProfile;
|
|||||||
use codex_protocol::openai_models::ReasoningEffort;
|
use codex_protocol::openai_models::ReasoningEffort;
|
||||||
use codex_protocol::protocol::AskForApproval;
|
use codex_protocol::protocol::AskForApproval;
|
||||||
use codex_protocol::protocol::EventMsg;
|
use codex_protocol::protocol::EventMsg;
|
||||||
use codex_protocol::protocol::InitialHistory;
|
|
||||||
use codex_protocol::protocol::Op;
|
use codex_protocol::protocol::Op;
|
||||||
use codex_protocol::protocol::SessionSource;
|
use codex_protocol::protocol::SessionSource;
|
||||||
use codex_protocol::protocol::SubAgentSource;
|
use codex_protocol::protocol::SubAgentSource;
|
||||||
@@ -797,19 +796,10 @@ async fn subagent_stop_replaces_stop_and_skips_internal_subagents() -> Result<()
|
|||||||
// because the SubagentStop hook above intentionally matches all agent types.
|
// because the SubagentStop hook above intentionally matches all agent types.
|
||||||
let internal_thread = test
|
let internal_thread = test
|
||||||
.thread_manager
|
.thread_manager
|
||||||
.start_thread_with_options(StartThreadOptions {
|
.start_thread(StartThreadOptions {
|
||||||
config: test.config.clone(),
|
|
||||||
allow_provider_model_fallback: false,
|
|
||||||
initial_history: InitialHistory::New,
|
|
||||||
history_mode: None,
|
|
||||||
session_source: Some(SessionSource::SubAgent(SubAgentSource::Review)),
|
session_source: Some(SessionSource::SubAgent(SubAgentSource::Review)),
|
||||||
thread_source: None,
|
environments: Some(Vec::new()),
|
||||||
dynamic_tools: Vec::new(),
|
..StartThreadOptions::new(test.config.clone())
|
||||||
metrics_service_name: None,
|
|
||||||
parent_trace: None,
|
|
||||||
environments: Vec::new(),
|
|
||||||
thread_extension_init: Default::default(),
|
|
||||||
supports_openai_form_elicitation: false,
|
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ use codex_core::config::Config;
|
|||||||
use codex_protocol::ThreadId;
|
use codex_protocol::ThreadId;
|
||||||
use codex_protocol::error::CodexErr;
|
use codex_protocol::error::CodexErr;
|
||||||
use codex_protocol::error::Result as CodexResult;
|
use codex_protocol::error::Result as CodexResult;
|
||||||
use codex_protocol::protocol::InitialHistory;
|
|
||||||
use codex_protocol::protocol::W3cTraceContext;
|
use codex_protocol::protocol::W3cTraceContext;
|
||||||
use codex_protocol::user_input::UserInput;
|
use codex_protocol::user_input::UserInput;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@@ -61,26 +60,14 @@ impl AgentRunner {
|
|||||||
.thread_manager
|
.thread_manager
|
||||||
.upgrade()
|
.upgrade()
|
||||||
.ok_or_else(|| CodexErr::UnsupportedOperation("thread manager dropped".to_string()))?;
|
.ok_or_else(|| CodexErr::UnsupportedOperation("thread manager dropped".to_string()))?;
|
||||||
let environments =
|
|
||||||
thread_manager.default_environment_selections(&config.cwd, &config.workspace_roots);
|
|
||||||
let NewThread {
|
let NewThread {
|
||||||
thread_id, thread, ..
|
thread_id, thread, ..
|
||||||
} = thread_manager
|
} = thread_manager
|
||||||
.spawn_subagent(
|
.spawn_subagent(
|
||||||
parent_thread_id,
|
parent_thread_id,
|
||||||
StartThreadOptions {
|
StartThreadOptions {
|
||||||
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: parent_trace.clone(),
|
parent_trace: parent_trace.clone(),
|
||||||
environments,
|
..StartThreadOptions::new(config)
|
||||||
thread_extension_init: Default::default(),
|
|
||||||
supports_openai_form_elicitation: false,
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use crate::outgoing_message::OutgoingNotificationMeta;
|
|||||||
use crate::patch_approval::handle_patch_approval_request;
|
use crate::patch_approval::handle_patch_approval_request;
|
||||||
use codex_core::CodexThread;
|
use codex_core::CodexThread;
|
||||||
use codex_core::NewThread;
|
use codex_core::NewThread;
|
||||||
|
use codex_core::StartThreadOptions;
|
||||||
use codex_core::ThreadManager;
|
use codex_core::ThreadManager;
|
||||||
use codex_core::config::Config as CodexConfig;
|
use codex_core::config::Config as CodexConfig;
|
||||||
use codex_protocol::ThreadId;
|
use codex_protocol::ThreadId;
|
||||||
@@ -66,7 +67,10 @@ pub async fn run_codex_tool_session(
|
|||||||
thread_id,
|
thread_id,
|
||||||
thread,
|
thread,
|
||||||
session_configured,
|
session_configured,
|
||||||
} = match thread_manager.start_thread(config.clone()).await {
|
} = match thread_manager
|
||||||
|
.start_thread(StartThreadOptions::new(config.clone()))
|
||||||
|
.await
|
||||||
|
{
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let result = CallToolResult::error(vec![Content::text(format!(
|
let result = CallToolResult::error(vec![Content::text(format!(
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ use codex_protocol::ThreadId;
|
|||||||
use codex_protocol::config_types::ReasoningSummary;
|
use codex_protocol::config_types::ReasoningSummary;
|
||||||
use codex_protocol::openai_models::ModelInfo;
|
use codex_protocol::openai_models::ModelInfo;
|
||||||
use codex_protocol::openai_models::ReasoningEffort;
|
use codex_protocol::openai_models::ReasoningEffort;
|
||||||
use codex_protocol::protocol::InitialHistory;
|
|
||||||
use codex_protocol::protocol::InternalSessionSource;
|
use codex_protocol::protocol::InternalSessionSource;
|
||||||
use codex_protocol::protocol::Op;
|
use codex_protocol::protocol::Op;
|
||||||
use codex_protocol::protocol::SessionSource;
|
use codex_protocol::protocol::SessionSource;
|
||||||
@@ -321,28 +320,16 @@ impl MemoryStartupContext {
|
|||||||
config: Config,
|
config: Config,
|
||||||
prompt: Vec<UserInput>,
|
prompt: Vec<UserInput>,
|
||||||
) -> anyhow::Result<SpawnedConsolidationAgent> {
|
) -> anyhow::Result<SpawnedConsolidationAgent> {
|
||||||
let environments = self
|
|
||||||
.thread_manager
|
|
||||||
.default_environment_selections(&config.cwd, &config.workspace_roots);
|
|
||||||
let NewThread {
|
let NewThread {
|
||||||
thread_id, thread, ..
|
thread_id, thread, ..
|
||||||
} = self
|
} = self
|
||||||
.thread_manager
|
.thread_manager
|
||||||
.start_thread_with_options(StartThreadOptions {
|
.start_thread(StartThreadOptions {
|
||||||
config,
|
|
||||||
allow_provider_model_fallback: false,
|
|
||||||
initial_history: InitialHistory::New,
|
|
||||||
history_mode: None,
|
|
||||||
session_source: Some(SessionSource::Internal(
|
session_source: Some(SessionSource::Internal(
|
||||||
InternalSessionSource::MemoryConsolidation,
|
InternalSessionSource::MemoryConsolidation,
|
||||||
)),
|
)),
|
||||||
thread_source: Some(ThreadSource::MemoryConsolidation),
|
thread_source: Some(ThreadSource::MemoryConsolidation),
|
||||||
dynamic_tools: Vec::new(),
|
..StartThreadOptions::new(config)
|
||||||
metrics_service_name: None,
|
|
||||||
parent_trace: None,
|
|
||||||
environments,
|
|
||||||
thread_extension_init: Default::default(),
|
|
||||||
supports_openai_form_elicitation: false,
|
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ use codex_core_api::RealtimeAudioConfig;
|
|||||||
use codex_core_api::RealtimeConfig;
|
use codex_core_api::RealtimeConfig;
|
||||||
use codex_core_api::SessionPickerViewMode;
|
use codex_core_api::SessionPickerViewMode;
|
||||||
use codex_core_api::SessionSource;
|
use codex_core_api::SessionSource;
|
||||||
|
use codex_core_api::StartThreadOptions;
|
||||||
use codex_core_api::TerminalResizeReflowConfig;
|
use codex_core_api::TerminalResizeReflowConfig;
|
||||||
use codex_core_api::ThreadManager;
|
use codex_core_api::ThreadManager;
|
||||||
use codex_core_api::ThreadStoreConfig;
|
use codex_core_api::ThreadStoreConfig;
|
||||||
@@ -152,7 +153,7 @@ async fn run_main(arg0_paths: Arg0DispatchPaths) -> anyhow::Result<()> {
|
|||||||
let NewThread {
|
let NewThread {
|
||||||
thread_id, thread, ..
|
thread_id, thread, ..
|
||||||
} = thread_manager
|
} = thread_manager
|
||||||
.start_thread(config)
|
.start_thread(StartThreadOptions::new(config))
|
||||||
.await
|
.await
|
||||||
.context("start Codex thread")?;
|
.context("start Codex thread")?;
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user