mirror of
https://github.com/openai/codex.git
synced 2026-10-28 18:58:46 +00:00
Persist selected capability roots
This commit is contained in:
@@ -215,6 +215,7 @@ impl ExternalAgentSessionImporter {
|
||||
.unwrap_or_else(|| model_info.get_model_instructions(config.personality)),
|
||||
},
|
||||
dynamic_tools: Vec::new(),
|
||||
selected_capability_roots: Vec::new(),
|
||||
multi_agent_version: Some(MultiAgentVersion::V1),
|
||||
initial_window_id: uuid::Uuid::now_v7().to_string(),
|
||||
metadata: ThreadPersistenceMetadata {
|
||||
|
||||
@@ -200,6 +200,7 @@ fn create_fake_rollout_with_source_and_parent_thread_id(
|
||||
model_provider: model_provider.map(str::to_string),
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
selected_capability_roots: Vec::new(),
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
context_window: None,
|
||||
@@ -288,6 +289,7 @@ pub fn create_fake_rollout_with_text_elements(
|
||||
model_provider: model_provider.map(str::to_string),
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
selected_capability_roots: Vec::new(),
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
context_window: None,
|
||||
|
||||
@@ -131,6 +131,7 @@ async fn get_conversation_summary_by_thread_id_reads_pathless_store_thread() ->
|
||||
originator: "test_originator".to_string(),
|
||||
base_instructions: BaseInstructions::default(),
|
||||
dynamic_tools: Vec::new(),
|
||||
selected_capability_roots: Vec::new(),
|
||||
multi_agent_version: None,
|
||||
initial_window_id: Uuid::now_v7().to_string(),
|
||||
metadata: ThreadPersistenceMetadata {
|
||||
|
||||
@@ -158,6 +158,7 @@ async fn thread_delete_with_non_local_thread_store_does_not_create_local_persist
|
||||
originator: "test_originator".to_string(),
|
||||
base_instructions: BaseInstructions::default(),
|
||||
dynamic_tools: Vec::new(),
|
||||
selected_capability_roots: Vec::new(),
|
||||
multi_agent_version: None,
|
||||
initial_window_id: Uuid::now_v7().to_string(),
|
||||
metadata: ThreadPersistenceMetadata {
|
||||
|
||||
@@ -1369,6 +1369,7 @@ async fn seed_pathless_store_thread(
|
||||
originator: "test_originator".to_string(),
|
||||
base_instructions: BaseInstructions::default(),
|
||||
dynamic_tools: Vec::new(),
|
||||
selected_capability_roots: Vec::new(),
|
||||
multi_agent_version: None,
|
||||
initial_window_id: Uuid::now_v7().to_string(),
|
||||
metadata: ThreadPersistenceMetadata {
|
||||
|
||||
@@ -2070,6 +2070,7 @@ stream_max_retries = 0
|
||||
model_provider: Some("mock_provider".to_string()),
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
selected_capability_roots: Vec::new(),
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
context_window: None,
|
||||
|
||||
@@ -218,6 +218,7 @@ async fn thread_unarchive_preserves_pathless_store_metadata() -> Result<()> {
|
||||
originator: "test_originator".to_string(),
|
||||
base_instructions: BaseInstructions::default(),
|
||||
dynamic_tools: Vec::new(),
|
||||
selected_capability_roots: Vec::new(),
|
||||
multi_agent_version: None,
|
||||
initial_window_id: Uuid::now_v7().to_string(),
|
||||
metadata: ThreadPersistenceMetadata {
|
||||
|
||||
@@ -59,6 +59,7 @@ async fn write_rollout_with_user_event(dir: &Path, thread_id: ThreadId) -> io::R
|
||||
model_provider: None,
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
selected_capability_roots: Vec::new(),
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
context_window: None,
|
||||
|
||||
@@ -10,6 +10,7 @@ use crate::state::ActiveTurn;
|
||||
use codex_extension_api::ExtensionDataInit;
|
||||
use codex_login::auth::AgentIdentityAuthPolicy;
|
||||
use codex_protocol::SessionId;
|
||||
use codex_protocol::capabilities::SelectedCapabilityRoot;
|
||||
use codex_protocol::config_types::SERVICE_TIER_DEFAULT_REQUEST_VALUE;
|
||||
use codex_protocol::config_types::ServiceTier;
|
||||
use codex_protocol::permissions::FileSystemPath;
|
||||
@@ -555,6 +556,10 @@ impl Session {
|
||||
config.current_time_reminder.as_ref(),
|
||||
external_time_provider,
|
||||
)?;
|
||||
let selected_capability_roots = thread_extension_init
|
||||
.get::<Vec<SelectedCapabilityRoot>>()
|
||||
.map(|roots| roots.as_ref().clone())
|
||||
.unwrap_or_else(|| initial_history.get_selected_capability_roots());
|
||||
let mcp_thread_init = thread_extension_init.clone();
|
||||
let thread_extension_data = codex_extension_api::ExtensionData::new_with_init(
|
||||
thread_id.to_string(),
|
||||
@@ -584,6 +589,7 @@ impl Session {
|
||||
text: session_configuration.base_instructions.clone(),
|
||||
},
|
||||
dynamic_tools: session_configuration.dynamic_tools.clone(),
|
||||
selected_capability_roots: selected_capability_roots.clone(),
|
||||
multi_agent_version: initial_multi_agent_version,
|
||||
initial_window_id: initial_auto_compact_window_ids
|
||||
.window_id
|
||||
|
||||
@@ -4043,6 +4043,7 @@ async fn attach_thread_persistence(session: &mut Session) -> PathBuf {
|
||||
originator: "test_originator".to_string(),
|
||||
base_instructions: BaseInstructions::default(),
|
||||
dynamic_tools: Vec::new(),
|
||||
selected_capability_roots: Vec::new(),
|
||||
multi_agent_version: None,
|
||||
initial_window_id: Uuid::now_v7().to_string(),
|
||||
metadata: ThreadPersistenceMetadata {
|
||||
@@ -6919,6 +6920,7 @@ async fn shutdown_complete_does_not_append_to_thread_store_after_shutdown() {
|
||||
originator: "test_originator".to_string(),
|
||||
base_instructions: BaseInstructions::default(),
|
||||
dynamic_tools: Vec::new(),
|
||||
selected_capability_roots: Vec::new(),
|
||||
multi_agent_version: None,
|
||||
initial_window_id: Uuid::now_v7().to_string(),
|
||||
metadata: ThreadPersistenceMetadata {
|
||||
|
||||
@@ -20,6 +20,8 @@ use codex_protocol::protocol::AgentMessageEvent;
|
||||
use codex_protocol::protocol::InitialHistory;
|
||||
use codex_protocol::protocol::InternalSessionSource;
|
||||
use codex_protocol::protocol::ResumedHistory;
|
||||
use codex_protocol::protocol::SessionMeta;
|
||||
use codex_protocol::protocol::SessionMetaLine;
|
||||
use codex_protocol::protocol::SessionSource;
|
||||
use codex_protocol::protocol::ThreadSource;
|
||||
use codex_protocol::protocol::TurnStartedEvent;
|
||||
@@ -610,6 +612,110 @@ async fn start_thread_seeds_extension_data_for_mcp_and_lifecycle_contributors()
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn selected_capability_roots_round_trip_through_fork_and_explicit_empty_wins() {
|
||||
let temp_dir = tempdir().expect("tempdir");
|
||||
let mut config = test_config().await;
|
||||
config.codex_home = temp_dir.path().join("codex-home").abs();
|
||||
config.cwd = config.codex_home.abs();
|
||||
std::fs::create_dir_all(&config.codex_home).expect("create codex home");
|
||||
|
||||
let manager = ThreadManager::with_models_provider_and_home_for_tests(
|
||||
CodexAuth::from_api_key("dummy"),
|
||||
config.model_provider.clone(),
|
||||
config.codex_home.to_path_buf(),
|
||||
Arc::new(codex_exec_server::EnvironmentManager::default_for_tests()),
|
||||
);
|
||||
let selected_roots = vec![SelectedCapabilityRoot {
|
||||
id: "demo@1".to_string(),
|
||||
location: CapabilityRootLocation::Environment {
|
||||
environment_id: "build".to_string(),
|
||||
path: PathUri::parse("file:///plugins/demo").expect("plugin root URI"),
|
||||
},
|
||||
}];
|
||||
let fork_history = || {
|
||||
InitialHistory::Forked(vec![RolloutItem::SessionMeta(SessionMetaLine {
|
||||
meta: SessionMeta {
|
||||
selected_capability_roots: selected_roots.clone(),
|
||||
..SessionMeta::default()
|
||||
},
|
||||
git: None,
|
||||
})])
|
||||
};
|
||||
|
||||
let inherited = manager
|
||||
.start_thread_with_options(StartThreadOptions {
|
||||
config: config.clone(),
|
||||
initial_history: fork_history(),
|
||||
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
|
||||
.expect("start inherited fork");
|
||||
inherited.thread.ensure_rollout_materialized().await;
|
||||
inherited
|
||||
.thread
|
||||
.flush_rollout()
|
||||
.await
|
||||
.expect("flush inherited fork");
|
||||
let inherited_history = RolloutRecorder::get_rollout_history(
|
||||
&inherited
|
||||
.thread
|
||||
.rollout_path()
|
||||
.expect("inherited fork rollout path"),
|
||||
)
|
||||
.await
|
||||
.expect("read inherited fork rollout");
|
||||
|
||||
assert_eq!(
|
||||
inherited_history.get_selected_capability_roots(),
|
||||
selected_roots
|
||||
);
|
||||
|
||||
let mut explicit_empty = codex_extension_api::ExtensionDataInit::new();
|
||||
explicit_empty.insert(Vec::<SelectedCapabilityRoot>::new());
|
||||
let overridden = manager
|
||||
.start_thread_with_options(StartThreadOptions {
|
||||
config,
|
||||
initial_history: fork_history(),
|
||||
session_source: None,
|
||||
thread_source: None,
|
||||
dynamic_tools: Vec::new(),
|
||||
metrics_service_name: None,
|
||||
parent_trace: None,
|
||||
environments: Vec::new(),
|
||||
thread_extension_init: explicit_empty,
|
||||
supports_openai_form_elicitation: false,
|
||||
})
|
||||
.await
|
||||
.expect("start explicitly empty fork");
|
||||
overridden.thread.ensure_rollout_materialized().await;
|
||||
overridden
|
||||
.thread
|
||||
.flush_rollout()
|
||||
.await
|
||||
.expect("flush explicitly empty fork");
|
||||
let overridden_history = RolloutRecorder::get_rollout_history(
|
||||
&overridden
|
||||
.thread
|
||||
.rollout_path()
|
||||
.expect("explicitly empty fork rollout path"),
|
||||
)
|
||||
.await
|
||||
.expect("read explicitly empty fork rollout");
|
||||
|
||||
assert_eq!(
|
||||
overridden_history.get_selected_capability_roots(),
|
||||
Vec::new()
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn resume_and_fork_do_not_restore_thread_environments_from_rollout() {
|
||||
let temp_dir = tempdir().expect("tempdir");
|
||||
|
||||
@@ -75,6 +75,7 @@ async fn write_rollout_with_user_event(dir: &Path, thread_id: ThreadId) -> io::R
|
||||
model_provider: None,
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
selected_capability_roots: Vec::new(),
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
context_window: None,
|
||||
@@ -127,6 +128,7 @@ async fn write_rollout_with_meta_only(dir: &Path, thread_id: ThreadId) -> io::Re
|
||||
model_provider: None,
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
selected_capability_roots: Vec::new(),
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
context_window: None,
|
||||
|
||||
@@ -372,6 +372,7 @@ async fn backfill_scans_existing_rollouts() -> Result<()> {
|
||||
model_provider: None,
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
selected_capability_roots: Vec::new(),
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
context_window: None,
|
||||
|
||||
@@ -19,6 +19,7 @@ use crate::AgentPath;
|
||||
use crate::SessionId;
|
||||
use crate::ThreadId;
|
||||
use crate::approvals::ElicitationRequestEvent;
|
||||
use crate::capabilities::SelectedCapabilityRoot;
|
||||
use crate::config_types::ApprovalsReviewer;
|
||||
use crate::config_types::CollaborationMode;
|
||||
use crate::config_types::ModeKind;
|
||||
@@ -2570,6 +2571,12 @@ impl InitialHistory {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_selected_capability_roots(&self) -> Vec<SelectedCapabilityRoot> {
|
||||
self.get_session_meta()
|
||||
.map(|meta| meta.selected_capability_roots.clone())
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
pub fn get_multi_agent_version(&self) -> Option<MultiAgentVersion> {
|
||||
match self {
|
||||
InitialHistory::New | InitialHistory::Cleared => None,
|
||||
@@ -3003,6 +3010,9 @@ pub struct SessionMeta {
|
||||
skip_serializing_if = "Option::is_none"
|
||||
)]
|
||||
pub dynamic_tools: Option<Vec<DynamicToolSpec>>,
|
||||
/// Capability roots selected for this thread by the hosting platform.
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub selected_capability_roots: Vec<SelectedCapabilityRoot>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub memory_mode: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
@@ -3032,6 +3042,7 @@ impl Default for SessionMeta {
|
||||
model_provider: None,
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
selected_capability_roots: Vec::new(),
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
context_window: None,
|
||||
|
||||
@@ -472,6 +472,7 @@ fn write_rollout(path: &std::path::Path, thread_id: ThreadId, message: &str) ->
|
||||
model_provider: None,
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
selected_capability_roots: Vec::new(),
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
context_window: None,
|
||||
|
||||
@@ -49,6 +49,7 @@ async fn extract_metadata_from_rollout_uses_session_meta() {
|
||||
model_provider: Some("openai".to_string()),
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
selected_capability_roots: Vec::new(),
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
context_window: None,
|
||||
@@ -106,6 +107,7 @@ async fn extract_metadata_from_rollout_returns_latest_memory_mode() {
|
||||
model_provider: Some("openai".to_string()),
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
selected_capability_roots: Vec::new(),
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
context_window: None,
|
||||
@@ -375,6 +377,7 @@ fn write_rollout_in_sessions_with_cwd(
|
||||
model_provider: Some("test-provider".to_string()),
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
selected_capability_roots: Vec::new(),
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
context_window: None,
|
||||
|
||||
@@ -12,6 +12,7 @@ use std::sync::Mutex;
|
||||
use chrono::SecondsFormat;
|
||||
use codex_protocol::SessionId;
|
||||
use codex_protocol::ThreadId;
|
||||
use codex_protocol::capabilities::SelectedCapabilityRoot;
|
||||
use codex_protocol::dynamic_tools::DynamicToolSpec;
|
||||
use codex_protocol::models::BaseInstructions;
|
||||
use serde_json::Value;
|
||||
@@ -91,6 +92,7 @@ pub enum RolloutRecorderParams {
|
||||
originator: String,
|
||||
base_instructions: BaseInstructions,
|
||||
dynamic_tools: Vec<DynamicToolSpec>,
|
||||
selected_capability_roots: Vec<SelectedCapabilityRoot>,
|
||||
multi_agent_version: Option<MultiAgentVersion>,
|
||||
initial_window_id: Option<String>,
|
||||
},
|
||||
@@ -182,6 +184,7 @@ impl RolloutRecorderParams {
|
||||
originator,
|
||||
base_instructions,
|
||||
dynamic_tools,
|
||||
selected_capability_roots: Vec::new(),
|
||||
multi_agent_version: None,
|
||||
initial_window_id: None,
|
||||
}
|
||||
@@ -194,6 +197,20 @@ impl RolloutRecorderParams {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_selected_capability_roots(
|
||||
mut self,
|
||||
selected_capability_roots: Vec<SelectedCapabilityRoot>,
|
||||
) -> Self {
|
||||
if let Self::Create {
|
||||
selected_capability_roots: roots,
|
||||
..
|
||||
} = &mut self
|
||||
{
|
||||
*roots = selected_capability_roots;
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_multi_agent_version(
|
||||
mut self,
|
||||
multi_agent_version: Option<MultiAgentVersion>,
|
||||
@@ -732,6 +749,7 @@ impl RolloutRecorder {
|
||||
originator,
|
||||
base_instructions,
|
||||
dynamic_tools,
|
||||
selected_capability_roots,
|
||||
multi_agent_version,
|
||||
initial_window_id,
|
||||
} => {
|
||||
@@ -769,6 +787,7 @@ impl RolloutRecorder {
|
||||
} else {
|
||||
Some(dynamic_tools)
|
||||
},
|
||||
selected_capability_roots,
|
||||
memory_mode: (!config.generate_memories()).then_some("disabled".to_string()),
|
||||
multi_agent_version,
|
||||
context_window: initial_window_id.map(SessionContextWindow::new),
|
||||
|
||||
@@ -101,6 +101,7 @@ async fn state_db_init_backfills_before_returning() -> anyhow::Result<()> {
|
||||
model_provider: None,
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
selected_capability_roots: Vec::new(),
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
context_window: None,
|
||||
|
||||
@@ -41,6 +41,7 @@ fn write_rollout_with_metadata(path: &Path, thread_id: ThreadId) -> std::io::Res
|
||||
model_provider: Some("test-provider".into()),
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
selected_capability_roots: Vec::new(),
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
context_window: None,
|
||||
|
||||
@@ -174,6 +174,7 @@ fn write_rollout_with_user_message(
|
||||
model_provider: Some("test-provider".to_string()),
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
selected_capability_roots: Vec::new(),
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
context_window: None,
|
||||
|
||||
@@ -1288,6 +1288,7 @@ async fn test_updated_at_uses_file_mtime() -> Result<()> {
|
||||
model_provider: Some("test-provider".into()),
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
selected_capability_roots: Vec::new(),
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
context_window: None,
|
||||
|
||||
@@ -343,6 +343,7 @@ mod tests {
|
||||
model_provider: Some("openai".to_string()),
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
selected_capability_roots: Vec::new(),
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
context_window: None,
|
||||
@@ -535,6 +536,7 @@ mod tests {
|
||||
model_provider: Some("openai".to_string()),
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
selected_capability_roots: Vec::new(),
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
context_window: None,
|
||||
|
||||
@@ -2148,6 +2148,7 @@ mod tests {
|
||||
model_provider: None,
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
selected_capability_roots: Vec::new(),
|
||||
memory_mode: Some("polluted".to_string()),
|
||||
multi_agent_version: None,
|
||||
context_window: None,
|
||||
@@ -2211,6 +2212,7 @@ mod tests {
|
||||
model_provider: None,
|
||||
base_instructions: None,
|
||||
dynamic_tools: None,
|
||||
selected_capability_roots: Vec::new(),
|
||||
memory_mode: None,
|
||||
multi_agent_version: None,
|
||||
context_window: None,
|
||||
|
||||
@@ -126,6 +126,7 @@ mod tests {
|
||||
originator: "test_originator".to_string(),
|
||||
base_instructions: BaseInstructions::default(),
|
||||
dynamic_tools: Vec::new(),
|
||||
selected_capability_roots: Vec::new(),
|
||||
multi_agent_version: None,
|
||||
initial_window_id: uuid::Uuid::now_v7().to_string(),
|
||||
metadata: ThreadPersistenceMetadata {
|
||||
@@ -281,6 +282,7 @@ impl InMemoryThreadStore {
|
||||
model_provider: Some(params.metadata.model_provider.clone()),
|
||||
base_instructions: Some(params.base_instructions.clone()),
|
||||
dynamic_tools: (!params.dynamic_tools.is_empty()).then(|| params.dynamic_tools.clone()),
|
||||
selected_capability_roots: params.selected_capability_roots.clone(),
|
||||
memory_mode: matches!(params.metadata.memory_mode, ThreadMemoryMode::Disabled)
|
||||
.then_some("disabled".to_string()),
|
||||
multi_agent_version: params.multi_agent_version,
|
||||
|
||||
@@ -38,6 +38,7 @@ pub(super) async fn create_thread(
|
||||
params.dynamic_tools,
|
||||
)
|
||||
.with_session_id(params.session_id)
|
||||
.with_selected_capability_roots(params.selected_capability_roots)
|
||||
.with_multi_agent_version(params.multi_agent_version)
|
||||
.with_initial_window_id(params.initial_window_id),
|
||||
)
|
||||
|
||||
@@ -1133,6 +1133,7 @@ mod tests {
|
||||
originator: "test_originator".to_string(),
|
||||
base_instructions: BaseInstructions::default(),
|
||||
dynamic_tools: Vec::new(),
|
||||
selected_capability_roots: Vec::new(),
|
||||
multi_agent_version: None,
|
||||
initial_window_id: uuid::Uuid::now_v7().to_string(),
|
||||
metadata: thread_metadata(),
|
||||
|
||||
@@ -5,6 +5,7 @@ use chrono::DateTime;
|
||||
use chrono::Utc;
|
||||
use codex_protocol::SessionId;
|
||||
use codex_protocol::ThreadId;
|
||||
use codex_protocol::capabilities::SelectedCapabilityRoot;
|
||||
use codex_protocol::dynamic_tools::DynamicToolSpec;
|
||||
use codex_protocol::models::BaseInstructions;
|
||||
use codex_protocol::models::PermissionProfile;
|
||||
@@ -85,6 +86,9 @@ pub struct CreateThreadParams {
|
||||
pub base_instructions: BaseInstructions,
|
||||
/// Dynamic tools available to the thread at startup.
|
||||
pub dynamic_tools: Vec<DynamicToolSpec>,
|
||||
/// Environment-qualified capability roots selected for this thread.
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub selected_capability_roots: Vec<SelectedCapabilityRoot>,
|
||||
/// Multi-agent runtime selected when the thread was created.
|
||||
pub multi_agent_version: Option<MultiAgentVersion>,
|
||||
/// Initial context-window identity captured when the thread was created.
|
||||
|
||||
Reference in New Issue
Block a user