mirror of
https://github.com/openai/codex.git
synced 2026-11-02 16:20:35 +00:00
Scope runtime workspace roots to execution environments (#32952)
## Why Multi-environment turns can run against different filesystems, so a single thread-wide workspace-root list cannot accurately describe every selected environment. ## What changed - Add optional `runtimeWorkspaceRoots` to each app-server environment selection. Omitted roots default to that environment's `cwd`, while an empty list selects no roots. - Carry environment-native roots through turn selection, model-visible context, permission materialization, and tool sandboxing. - Keep the top-level `runtimeWorkspaceRoots` field as a compatibility input when constructing default environment selections; explicit selections use their own roots. ## Testing - Cover thread and turn API defaults, overrides, empty roots, and schema round-tripping. - Verify foreign roots remain model-visible and remote execution applies the target environment's roots before sandbox selection. GitOrigin-RevId: c6e7a62883c45c676c153055f46a55ee15a323a4
This commit is contained in:
1 parent
b019a5577c
commit
393f64565a
62 files changed
+769
-446
No files matched your search
@@ -22,6 +22,7 @@ use crate::shell_snapshot::ShellSnapshot;
|
||||
pub(crate) fn default_thread_environment_selections(
|
||||
environment_manager: &EnvironmentManager,
|
||||
cwd: &AbsolutePathBuf,
|
||||
workspace_roots: &[AbsolutePathBuf],
|
||||
) -> Vec<TurnEnvironmentSelection> {
|
||||
environment_manager
|
||||
.default_environment_ids()
|
||||
@@ -29,6 +30,7 @@ pub(crate) fn default_thread_environment_selections(
|
||||
.map(|environment_id| TurnEnvironmentSelection {
|
||||
environment_id,
|
||||
cwd: PathUri::from_abs_path(cwd),
|
||||
workspace_roots: workspace_roots.iter().map(PathUri::from_abs_path).collect(),
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
@@ -175,8 +177,13 @@ impl ThreadEnvironments {
|
||||
} else {
|
||||
Some(local_shell)
|
||||
};
|
||||
let mut turn_environment =
|
||||
TurnEnvironment::new(selection.environment_id, environment, selection.cwd, shell);
|
||||
let mut turn_environment = TurnEnvironment::new(
|
||||
selection.environment_id,
|
||||
environment,
|
||||
selection.cwd,
|
||||
selection.workspace_roots,
|
||||
shell,
|
||||
);
|
||||
let task = shell_snapshot
|
||||
.build(turn_environment.clone())
|
||||
.boxed()
|
||||
@@ -406,10 +413,11 @@ mod tests {
|
||||
.await;
|
||||
|
||||
assert_eq!(
|
||||
default_thread_environment_selections(&manager, &cwd),
|
||||
default_thread_environment_selections(&manager, &cwd, std::slice::from_ref(&cwd)),
|
||||
vec![TurnEnvironmentSelection {
|
||||
environment_id: REMOTE_ENVIRONMENT_ID.to_string(),
|
||||
cwd: cwd_uri,
|
||||
cwd: cwd_uri.clone(),
|
||||
workspace_roots: vec![cwd_uri],
|
||||
}]
|
||||
);
|
||||
}
|
||||
@@ -434,15 +442,17 @@ url = "ws://127.0.0.1:8765"
|
||||
.expect("environment manager");
|
||||
|
||||
assert_eq!(
|
||||
default_thread_environment_selections(&manager, &cwd),
|
||||
default_thread_environment_selections(&manager, &cwd, std::slice::from_ref(&cwd)),
|
||||
vec![
|
||||
TurnEnvironmentSelection {
|
||||
environment_id: LOCAL_ENVIRONMENT_ID.to_string(),
|
||||
cwd: cwd_uri.clone(),
|
||||
workspace_roots: vec![cwd_uri.clone()],
|
||||
},
|
||||
TurnEnvironmentSelection {
|
||||
environment_id: REMOTE_ENVIRONMENT_ID.to_string(),
|
||||
cwd: cwd_uri,
|
||||
cwd: cwd_uri.clone(),
|
||||
workspace_roots: vec![cwd_uri],
|
||||
},
|
||||
]
|
||||
);
|
||||
@@ -454,7 +464,7 @@ url = "ws://127.0.0.1:8765"
|
||||
let manager = EnvironmentManager::without_environments();
|
||||
|
||||
assert_eq!(
|
||||
default_thread_environment_selections(&manager, &cwd),
|
||||
default_thread_environment_selections(&manager, &cwd, std::slice::from_ref(&cwd)),
|
||||
Vec::<TurnEnvironmentSelection>::new()
|
||||
);
|
||||
}
|
||||
@@ -476,6 +486,7 @@ url = "ws://127.0.0.1:8765"
|
||||
turn_environments.update_selections(&[TurnEnvironmentSelection {
|
||||
environment_id: LOCAL_ENVIRONMENT_ID.to_string(),
|
||||
cwd: PathUri::from_abs_path(&cwd),
|
||||
workspace_roots: Vec::new(),
|
||||
}]);
|
||||
|
||||
let snapshot = turn_environments.snapshot().await;
|
||||
@@ -496,6 +507,7 @@ url = "ws://127.0.0.1:8765"
|
||||
let first = TurnEnvironmentSelection {
|
||||
environment_id: LOCAL_ENVIRONMENT_ID.to_string(),
|
||||
cwd: cwd_uri.clone(),
|
||||
workspace_roots: Vec::new(),
|
||||
};
|
||||
|
||||
let resolved = resolve_turn_environments(
|
||||
@@ -505,6 +517,7 @@ url = "ws://127.0.0.1:8765"
|
||||
TurnEnvironmentSelection {
|
||||
environment_id: LOCAL_ENVIRONMENT_ID.to_string(),
|
||||
cwd: cwd_uri.join("other").expect("other cwd URI"),
|
||||
workspace_roots: Vec::new(),
|
||||
},
|
||||
],
|
||||
)
|
||||
@@ -525,6 +538,7 @@ url = "ws://127.0.0.1:8765"
|
||||
&[TurnEnvironmentSelection {
|
||||
environment_id: "local".to_string(),
|
||||
cwd: selected_cwd_uri,
|
||||
workspace_roots: Vec::new(),
|
||||
}],
|
||||
)
|
||||
.await;
|
||||
@@ -562,6 +576,7 @@ url = "ws://127.0.0.1:8765"
|
||||
let local = TurnEnvironmentSelection {
|
||||
environment_id: LOCAL_ENVIRONMENT_ID.to_string(),
|
||||
cwd: cwd_uri.clone(),
|
||||
workspace_roots: Vec::new(),
|
||||
};
|
||||
|
||||
let resolved = resolve_turn_environments(
|
||||
@@ -570,6 +585,7 @@ url = "ws://127.0.0.1:8765"
|
||||
TurnEnvironmentSelection {
|
||||
environment_id: "missing".to_string(),
|
||||
cwd: cwd_uri,
|
||||
workspace_roots: Vec::new(),
|
||||
},
|
||||
local.clone(),
|
||||
],
|
||||
@@ -597,6 +613,7 @@ url = "ws://127.0.0.1:8765"
|
||||
let selection = TurnEnvironmentSelection {
|
||||
environment_id: REMOTE_ENVIRONMENT_ID.to_string(),
|
||||
cwd: PathUri::from_abs_path(&AbsolutePathBuf::current_dir().expect("cwd")),
|
||||
workspace_roots: Vec::new(),
|
||||
};
|
||||
let environments = Arc::new(ThreadEnvironments::new(
|
||||
manager,
|
||||
@@ -644,10 +661,12 @@ url = "ws://127.0.0.1:8765"
|
||||
let remote = TurnEnvironmentSelection {
|
||||
environment_id: REMOTE_ENVIRONMENT_ID.to_string(),
|
||||
cwd: cwd.clone(),
|
||||
workspace_roots: Vec::new(),
|
||||
};
|
||||
let local = TurnEnvironmentSelection {
|
||||
environment_id: LOCAL_ENVIRONMENT_ID.to_string(),
|
||||
cwd,
|
||||
workspace_roots: Vec::new(),
|
||||
};
|
||||
let turn_environments = ThreadEnvironments::new(
|
||||
manager,
|
||||
@@ -706,6 +725,7 @@ url = "ws://127.0.0.1:8765"
|
||||
let selection = TurnEnvironmentSelection {
|
||||
environment_id: REMOTE_ENVIRONMENT_ID.to_string(),
|
||||
cwd: PathUri::from_abs_path(&AbsolutePathBuf::current_dir().expect("cwd")),
|
||||
workspace_roots: Vec::new(),
|
||||
};
|
||||
let environments = ThreadEnvironments::new(
|
||||
Arc::clone(&manager),
|
||||
@@ -757,6 +777,7 @@ url = "ws://127.0.0.1:8765"
|
||||
let selection = TurnEnvironmentSelection {
|
||||
environment_id: REMOTE_ENVIRONMENT_ID.to_string(),
|
||||
cwd: PathUri::from_abs_path(&cwd),
|
||||
workspace_roots: Vec::new(),
|
||||
};
|
||||
let environments = ThreadEnvironments::new(
|
||||
Arc::clone(&manager),
|
||||
@@ -813,6 +834,7 @@ url = "ws://127.0.0.1:8765"
|
||||
let selection = TurnEnvironmentSelection {
|
||||
environment_id: REMOTE_ENVIRONMENT_ID.to_string(),
|
||||
cwd: PathUri::from_abs_path(&cwd),
|
||||
workspace_roots: Vec::new(),
|
||||
};
|
||||
let inherited_environment = Arc::new(
|
||||
Environment::create_for_tests(Some("ws://127.0.0.1:8765".to_string()))
|
||||
@@ -822,6 +844,7 @@ url = "ws://127.0.0.1:8765"
|
||||
selection.environment_id.clone(),
|
||||
Arc::clone(&inherited_environment),
|
||||
selection.cwd.clone(),
|
||||
Vec::new(),
|
||||
/*shell*/ None,
|
||||
);
|
||||
let manager = Arc::new(EnvironmentManager::without_environments());
|
||||
@@ -865,6 +888,7 @@ url = "ws://127.0.0.1:8765"
|
||||
&[TurnEnvironmentSelection {
|
||||
environment_id: LOCAL_ENVIRONMENT_ID.to_string(),
|
||||
cwd: cwd_uri.clone(),
|
||||
workspace_roots: Vec::new(),
|
||||
}],
|
||||
)
|
||||
.await;
|
||||
@@ -878,6 +902,7 @@ url = "ws://127.0.0.1:8765"
|
||||
REMOTE_ENVIRONMENT_ID.to_string(),
|
||||
remote_environment.clone(),
|
||||
cwd_uri.clone(),
|
||||
Vec::new(),
|
||||
/*shell*/ None,
|
||||
)],
|
||||
starting: Vec::new(),
|
||||
@@ -889,6 +914,7 @@ url = "ws://127.0.0.1:8765"
|
||||
REMOTE_ENVIRONMENT_ID.to_string(),
|
||||
remote_environment,
|
||||
cwd_uri,
|
||||
Vec::new(),
|
||||
/*shell*/ None,
|
||||
),
|
||||
],
|
||||
|
||||
Reference in new issue
Block a user