mirror of
https://github.com/openai/codex.git
synced 2026-11-10 21:00:47 +00:00
core: move workspace roots onto environments
This commit is contained in:
@@ -368,7 +368,6 @@ use codex_core_plugins::remote::RemotePluginShareContext as RemoteCatalogPluginS
|
||||
use codex_core_plugins::remote::RemotePluginShareSummary as RemoteCatalogPluginShareSummary;
|
||||
use codex_core_plugins::remote::RemotePluginSummary as RemoteCatalogPluginSummary;
|
||||
use codex_exec_server::EnvironmentManager;
|
||||
use codex_exec_server::LOCAL_ENVIRONMENT_ID;
|
||||
use codex_exec_server::LOCAL_FS;
|
||||
use codex_features::FEATURES;
|
||||
use codex_features::Feature;
|
||||
@@ -465,6 +464,7 @@ use codex_thread_store::ThreadSortKey as StoreThreadSortKey;
|
||||
use codex_thread_store::ThreadStore;
|
||||
use codex_thread_store::ThreadStoreError;
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
use codex_utils_path_uri::PathUri;
|
||||
use codex_utils_pty::DEFAULT_OUTPUT_BYTES_CAP;
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::HashMap;
|
||||
@@ -564,6 +564,7 @@ fn resolve_request_cwd(cwd: Option<PathBuf>) -> Result<Option<AbsolutePathBuf>,
|
||||
fn resolve_turn_environment_selections(
|
||||
thread_manager: &ThreadManager,
|
||||
environments: Option<Vec<TurnEnvironmentParams>>,
|
||||
fallback_workspace_roots: &[AbsolutePathBuf],
|
||||
) -> Result<Option<Vec<TurnEnvironmentSelection>>, JSONRPCErrorError> {
|
||||
let Some(environments) = environments else {
|
||||
return Ok(None);
|
||||
@@ -580,9 +581,33 @@ fn resolve_turn_environment_selections(
|
||||
environment.cwd
|
||||
))
|
||||
})?;
|
||||
let workspace_roots = environment
|
||||
.runtime_workspace_roots
|
||||
.map(|roots| {
|
||||
let mut resolved_roots = Vec::new();
|
||||
for root in roots {
|
||||
let root = root.to_inferred_path_uri().ok_or_else(|| {
|
||||
invalid_request(format!(
|
||||
"invalid runtime workspace root for environment `{environment_id}`: path `{root}` does not use absolute POSIX or Windows path syntax"
|
||||
))
|
||||
})?;
|
||||
if !resolved_roots.contains(&root) {
|
||||
resolved_roots.push(root);
|
||||
}
|
||||
}
|
||||
Ok::<_, JSONRPCErrorError>(resolved_roots)
|
||||
})
|
||||
.transpose()?
|
||||
.unwrap_or_else(|| {
|
||||
fallback_workspace_roots
|
||||
.iter()
|
||||
.map(PathUri::from_abs_path)
|
||||
.collect()
|
||||
});
|
||||
selections.push(TurnEnvironmentSelection {
|
||||
environment_id,
|
||||
cwd,
|
||||
workspace_roots,
|
||||
});
|
||||
}
|
||||
thread_manager
|
||||
|
||||
@@ -968,8 +968,6 @@ impl ThreadRequestProcessor {
|
||||
"`permissions` cannot be combined with `sandbox`",
|
||||
));
|
||||
}
|
||||
let environment_selections =
|
||||
resolve_turn_environment_selections(self.thread_manager.as_ref(), environments)?;
|
||||
let runtime_workspace_roots = runtime_workspace_roots.map(resolve_runtime_workspace_roots);
|
||||
let mut typesafe_overrides = self.build_thread_config_overrides(
|
||||
model,
|
||||
@@ -1017,7 +1015,7 @@ impl ThreadRequestProcessor {
|
||||
history_mode.map(Into::into),
|
||||
session_start_source,
|
||||
thread_source.map(Into::into),
|
||||
environment_selections,
|
||||
environments,
|
||||
service_name,
|
||||
allow_provider_model_fallback,
|
||||
experimental_raw_events,
|
||||
@@ -1094,7 +1092,7 @@ impl ThreadRequestProcessor {
|
||||
history_mode: Option<ThreadHistoryMode>,
|
||||
session_start_source: Option<codex_app_server_protocol::ThreadStartSource>,
|
||||
thread_source: Option<codex_protocol::protocol::ThreadSource>,
|
||||
environments: Option<Vec<TurnEnvironmentSelection>>,
|
||||
environments: Option<Vec<codex_app_server_protocol::TurnEnvironmentParams>>,
|
||||
service_name: Option<String>,
|
||||
allow_provider_model_fallback: bool,
|
||||
experimental_raw_events: bool,
|
||||
@@ -1188,10 +1186,15 @@ impl ThreadRequestProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
let environments = environments.unwrap_or_else(|| {
|
||||
let environments = resolve_turn_environment_selections(
|
||||
listener_task_context.thread_manager.as_ref(),
|
||||
environments,
|
||||
&config.workspace_roots,
|
||||
)?
|
||||
.unwrap_or_else(|| {
|
||||
listener_task_context
|
||||
.thread_manager
|
||||
.default_environment_selections(&config.cwd)
|
||||
.default_environment_selections(&config.cwd, &config.workspace_roots)
|
||||
});
|
||||
let dynamic_tools = dynamic_tools.unwrap_or_default();
|
||||
if !dynamic_tools.is_empty() {
|
||||
|
||||
@@ -481,8 +481,18 @@ impl TurnRequestProcessor {
|
||||
))
|
||||
})?;
|
||||
|
||||
let environment_selections =
|
||||
resolve_turn_environment_selections(self.thread_manager.as_ref(), params.environments)?;
|
||||
let runtime_workspace_roots = params
|
||||
.runtime_workspace_roots
|
||||
.map(resolve_runtime_workspace_roots);
|
||||
let fallback_workspace_roots = match runtime_workspace_roots.as_ref() {
|
||||
Some(workspace_roots) => workspace_roots.clone(),
|
||||
None => thread.config_snapshot().await.workspace_roots,
|
||||
};
|
||||
let environment_selections = resolve_turn_environment_selections(
|
||||
self.thread_manager.as_ref(),
|
||||
params.environments,
|
||||
&fallback_workspace_roots,
|
||||
)?;
|
||||
|
||||
// Map v2 input items to core input items.
|
||||
let mapped_items: Vec<CoreInputItem> = params
|
||||
@@ -495,7 +505,12 @@ impl TurnRequestProcessor {
|
||||
let turn_has_input = !mapped_items.is_empty();
|
||||
let cwd = resolve_request_cwd(params.cwd)?;
|
||||
let environments = self
|
||||
.build_environment_override(thread.as_ref(), cwd, environment_selections)
|
||||
.build_environment_override(
|
||||
thread.as_ref(),
|
||||
cwd,
|
||||
runtime_workspace_roots.clone(),
|
||||
environment_selections,
|
||||
)
|
||||
.await;
|
||||
let thread_settings = self
|
||||
.build_thread_settings_overrides(
|
||||
@@ -503,7 +518,7 @@ impl TurnRequestProcessor {
|
||||
ThreadSettingsBuildParams {
|
||||
method: "turn/start",
|
||||
environments,
|
||||
runtime_workspace_roots: params.runtime_workspace_roots,
|
||||
runtime_workspace_roots,
|
||||
approval_policy: params.approval_policy,
|
||||
approvals_reviewer: params.approvals_reviewer,
|
||||
sandbox_policy: params.sandbox_policy,
|
||||
@@ -572,33 +587,25 @@ impl TurnRequestProcessor {
|
||||
&self,
|
||||
thread: &CodexThread,
|
||||
cwd: Option<AbsolutePathBuf>,
|
||||
workspace_roots: Option<Vec<AbsolutePathBuf>>,
|
||||
environment_selections: Option<Vec<TurnEnvironmentSelection>>,
|
||||
) -> Option<TurnEnvironmentSelections> {
|
||||
match (cwd, environment_selections) {
|
||||
(None, None) => None,
|
||||
(Some(cwd), None) => {
|
||||
let environment_selections =
|
||||
self.thread_manager.default_environment_selections(&cwd);
|
||||
Some(TurnEnvironmentSelections::new(cwd, environment_selections))
|
||||
}
|
||||
(cwd, Some(environment_selections)) => {
|
||||
let legacy_fallback_cwd = match cwd {
|
||||
Some(cwd) => cwd,
|
||||
None => {
|
||||
let snapshot = thread.config_snapshot().await;
|
||||
environment_selections
|
||||
.iter()
|
||||
.find(|selection| selection.environment_id == LOCAL_ENVIRONMENT_ID)
|
||||
.and_then(|selection| selection.cwd.to_abs_path().ok())
|
||||
.unwrap_or_else(|| snapshot.cwd().clone())
|
||||
}
|
||||
};
|
||||
Some(TurnEnvironmentSelections::new(
|
||||
legacy_fallback_cwd,
|
||||
environment_selections,
|
||||
))
|
||||
}
|
||||
if cwd.is_none() && workspace_roots.is_none() && environment_selections.is_none() {
|
||||
return None;
|
||||
}
|
||||
let snapshot = thread.config_snapshot().await;
|
||||
let legacy_fallback_cwd = cwd.unwrap_or_else(|| snapshot.cwd().clone());
|
||||
let legacy_fallback_workspace_roots = workspace_roots.unwrap_or(snapshot.workspace_roots);
|
||||
let environment_selections = environment_selections.unwrap_or_else(|| {
|
||||
self.thread_manager.default_environment_selections(
|
||||
&legacy_fallback_cwd,
|
||||
&legacy_fallback_workspace_roots,
|
||||
)
|
||||
});
|
||||
Some(TurnEnvironmentSelections::new(
|
||||
legacy_fallback_cwd,
|
||||
environment_selections,
|
||||
))
|
||||
}
|
||||
|
||||
async fn build_thread_settings_overrides(
|
||||
@@ -654,8 +661,7 @@ impl TurnRequestProcessor {
|
||||
|| collaboration_mode.is_some()
|
||||
|| personality.is_some();
|
||||
|
||||
let runtime_workspace_roots =
|
||||
runtime_workspace_roots_request.map(resolve_runtime_workspace_roots);
|
||||
let runtime_workspace_roots = runtime_workspace_roots_request;
|
||||
let approval_policy =
|
||||
approval_policy.map(codex_app_server_protocol::AskForApproval::to_core);
|
||||
let approvals_reviewer =
|
||||
@@ -715,7 +721,6 @@ impl TurnRequestProcessor {
|
||||
thread
|
||||
.preview_thread_settings_overrides(CodexThreadSettingsOverrides {
|
||||
environments: environments.clone(),
|
||||
workspace_roots: runtime_workspace_roots.clone(),
|
||||
approval_policy,
|
||||
approvals_reviewer,
|
||||
sandbox_policy: sandbox_policy.clone(),
|
||||
@@ -738,7 +743,6 @@ impl TurnRequestProcessor {
|
||||
|
||||
Ok(codex_protocol::protocol::ThreadSettingsOverrides {
|
||||
environments,
|
||||
workspace_roots: runtime_workspace_roots,
|
||||
profile_workspace_roots,
|
||||
approval_policy,
|
||||
approvals_reviewer,
|
||||
@@ -763,7 +767,12 @@ impl TurnRequestProcessor {
|
||||
let (_, thread) = self.load_thread(¶ms.thread_id).await?;
|
||||
let cwd = resolve_request_cwd(params.cwd)?;
|
||||
let environments = self
|
||||
.build_environment_override(thread.as_ref(), cwd, /*environment_selections*/ None)
|
||||
.build_environment_override(
|
||||
thread.as_ref(),
|
||||
cwd,
|
||||
/*workspace_roots*/ None,
|
||||
/*environment_selections*/ None,
|
||||
)
|
||||
.await;
|
||||
let thread_settings = self
|
||||
.build_thread_settings_overrides(
|
||||
|
||||
Reference in New Issue
Block a user