mirror of
https://github.com/openai/codex.git
synced 2026-09-20 12:47:38 +00:00
codex: fail open unavailable skill env probes
This commit is contained in:
@@ -435,7 +435,9 @@ async fn repo_agents_skill_roots(
|
||||
// Discover repo `.agents/skills` folders by walking from the selected environment's project
|
||||
// root to its cwd; this must never consult the local filesystem for remote workspaces.
|
||||
let project_root_markers = project_root_markers_from_stack(config_layer_stack);
|
||||
let project_root = find_project_root(&env_path.path, &project_root_markers).await;
|
||||
let Some(project_root) = find_project_root(&env_path.path, &project_root_markers).await else {
|
||||
return Vec::new();
|
||||
};
|
||||
let dirs = dirs_between_project_root_and_cwd(env_path.path.path(), project_root.path());
|
||||
let mut roots = Vec::new();
|
||||
for dir in dirs {
|
||||
@@ -488,28 +490,29 @@ fn project_root_markers_from_stack(config_layer_stack: &ConfigLayerStack) -> Vec
|
||||
async fn find_project_root(
|
||||
cwd: &EnvironmentPathRef,
|
||||
project_root_markers: &[String],
|
||||
) -> EnvironmentPathRef {
|
||||
) -> Option<EnvironmentPathRef> {
|
||||
if project_root_markers.is_empty() {
|
||||
return cwd.clone();
|
||||
return Some(cwd.clone());
|
||||
}
|
||||
|
||||
for ancestor in cwd.path().ancestors() {
|
||||
for marker in project_root_markers {
|
||||
let marker_path = cwd.with_path(ancestor.join(marker));
|
||||
match marker_path.metadata(/*sandbox*/ None).await {
|
||||
Ok(_) => return cwd.with_path(ancestor),
|
||||
Ok(_) => return Some(cwd.with_path(ancestor)),
|
||||
Err(err) if err.kind() == io::ErrorKind::NotFound => {}
|
||||
Err(err) => {
|
||||
tracing::warn!(
|
||||
"failed to stat project root marker {}: {err:#}",
|
||||
marker_path.path().display()
|
||||
);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cwd.clone()
|
||||
Some(cwd.clone())
|
||||
}
|
||||
|
||||
fn dirs_between_project_root_and_cwd(
|
||||
|
||||
@@ -18,6 +18,8 @@ use std::fs;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use std::time::Instant;
|
||||
use tempfile::TempDir;
|
||||
use toml::Value as TomlValue;
|
||||
|
||||
@@ -394,6 +396,35 @@ async fn skill_roots_bind_project_config_roots_to_primary_environment_only() ->
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn skill_roots_stop_repo_agents_walk_when_environment_probe_fails() -> anyhow::Result<()> {
|
||||
let codex_home = tempfile::tempdir()?;
|
||||
let cfg = make_config(&codex_home).await;
|
||||
let remote_environment =
|
||||
codex_exec_server::Environment::create_for_tests(Some("ws://127.0.0.1:1".to_string()))?;
|
||||
let started = Instant::now();
|
||||
|
||||
let roots = super::skill_roots(
|
||||
&[super::SkillEnvironment {
|
||||
environment_id: "remote".to_string(),
|
||||
path: EnvironmentPathRef::new(remote_environment.get_filesystem(), cfg.cwd.clone()),
|
||||
}],
|
||||
/*local_file_system*/ None,
|
||||
&cfg.config_layer_stack,
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
)
|
||||
.await;
|
||||
|
||||
assert!(roots.is_empty());
|
||||
assert!(
|
||||
started.elapsed() < Duration::from_secs(4),
|
||||
"repo agents discovery should stop after the first unavailable environment probe"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn loads_skills_from_home_agents_dir_for_user_scope() -> anyhow::Result<()> {
|
||||
let tmp = tempfile::tempdir()?;
|
||||
|
||||
Reference in New Issue
Block a user