mirror of
https://github.com/openai/codex.git
synced 2026-04-28 02:11:08 +03:00
wip
This commit is contained in:
@@ -173,6 +173,30 @@ pub fn discover_project_doc_paths(config: &Config) -> std::io::Result<Vec<PathBu
|
||||
Ok(found)
|
||||
}
|
||||
|
||||
/// Discover every source of user instructions that will be sent to the model.
|
||||
///
|
||||
/// This includes the global `CODEX_HOME/AGENTS.md` file (when present and
|
||||
/// non-empty) followed by the project docs located via
|
||||
/// [`discover_project_doc_paths`]. The resulting list mirrors the order used
|
||||
/// when composing the final instruction string.
|
||||
pub fn discover_user_instruction_paths(config: &Config) -> std::io::Result<Vec<PathBuf>> {
|
||||
let mut paths: Vec<PathBuf> = Vec::new();
|
||||
|
||||
if config.user_instructions.is_some() {
|
||||
let candidate = config.codex_home.join("AGENTS.md");
|
||||
if let Ok(md) = std::fs::symlink_metadata(&candidate) {
|
||||
let ft = md.file_type();
|
||||
if ft.is_file() || ft.is_symlink() {
|
||||
paths.push(candidate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
paths.extend(discover_project_doc_paths(config)?);
|
||||
|
||||
Ok(paths)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@@ -347,4 +371,62 @@ mod tests {
|
||||
let res = get_user_instructions(&cfg).await.expect("doc expected");
|
||||
assert_eq!(res, "root doc\n\ncrate doc");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn discover_user_instruction_paths_includes_codex_home_doc() {
|
||||
let codex_home = tempfile::tempdir().expect("codex_home");
|
||||
fs::write(codex_home.path().join("AGENTS.md"), "codex home doc").unwrap();
|
||||
|
||||
let workspace = tempfile::tempdir().expect("workspace");
|
||||
|
||||
let mut config = Config::load_from_base_config_with_overrides(
|
||||
ConfigToml::default(),
|
||||
ConfigOverrides::default(),
|
||||
codex_home.path().to_path_buf(),
|
||||
)
|
||||
.expect("config");
|
||||
|
||||
config.cwd = workspace.path().to_path_buf();
|
||||
config.project_doc_max_bytes = 4096;
|
||||
|
||||
let paths = discover_user_instruction_paths(&config).expect("paths");
|
||||
assert_eq!(paths, vec![codex_home.path().join("AGENTS.md")]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn discover_user_instruction_paths_preserves_ordering() {
|
||||
let codex_home = tempfile::tempdir().expect("codex_home");
|
||||
fs::write(codex_home.path().join("AGENTS.md"), "codex home doc").unwrap();
|
||||
|
||||
let repo = tempfile::tempdir().expect("repo");
|
||||
std::fs::write(
|
||||
repo.path().join(".git"),
|
||||
"gitdir: /path/to/actual/git/dir\n",
|
||||
)
|
||||
.unwrap();
|
||||
fs::write(repo.path().join("AGENTS.md"), "root doc").unwrap();
|
||||
|
||||
let nested = repo.path().join("crate");
|
||||
std::fs::create_dir_all(&nested).unwrap();
|
||||
fs::write(nested.join("AGENTS.md"), "nested doc").unwrap();
|
||||
|
||||
let mut config = Config::load_from_base_config_with_overrides(
|
||||
ConfigToml::default(),
|
||||
ConfigOverrides::default(),
|
||||
codex_home.path().to_path_buf(),
|
||||
)
|
||||
.expect("config");
|
||||
config.cwd = nested.clone();
|
||||
config.project_doc_max_bytes = 4096;
|
||||
|
||||
let paths = discover_user_instruction_paths(&config).expect("paths");
|
||||
assert_eq!(
|
||||
paths,
|
||||
vec![
|
||||
codex_home.path().join("AGENTS.md"),
|
||||
repo.path().join("AGENTS.md"),
|
||||
nested.join("AGENTS.md"),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ use codex_core::config_types::ReasoningSummaryFormat;
|
||||
use codex_core::plan_tool::PlanItemArg;
|
||||
use codex_core::plan_tool::StepStatus;
|
||||
use codex_core::plan_tool::UpdatePlanArgs;
|
||||
use codex_core::project_doc::discover_project_doc_paths;
|
||||
use codex_core::project_doc::discover_user_instruction_paths;
|
||||
use codex_core::protocol::FileChange;
|
||||
use codex_core::protocol::McpInvocation;
|
||||
use codex_core::protocol::RateLimitSnapshotEvent;
|
||||
@@ -1159,45 +1159,11 @@ pub(crate) fn new_status_output(
|
||||
lines.push(vec![" • Sandbox: ".into(), sandbox_name.into()].into());
|
||||
|
||||
// AGENTS.md files discovered via core's project_doc logic
|
||||
let agents_list = {
|
||||
match discover_project_doc_paths(config) {
|
||||
Ok(paths) => {
|
||||
let mut rels: Vec<String> = Vec::new();
|
||||
for p in paths {
|
||||
let display = if let Some(parent) = p.parent() {
|
||||
if parent == config.cwd {
|
||||
"AGENTS.md".to_string()
|
||||
} else {
|
||||
let mut cur = config.cwd.as_path();
|
||||
let mut ups = 0usize;
|
||||
let mut reached = false;
|
||||
while let Some(c) = cur.parent() {
|
||||
if cur == parent {
|
||||
reached = true;
|
||||
break;
|
||||
}
|
||||
cur = c;
|
||||
ups += 1;
|
||||
}
|
||||
if reached {
|
||||
let up = format!("..{}", std::path::MAIN_SEPARATOR);
|
||||
format!("{}AGENTS.md", up.repeat(ups))
|
||||
} else if let Ok(stripped) = p.strip_prefix(&config.cwd) {
|
||||
stripped.display().to_string()
|
||||
} else {
|
||||
p.display().to_string()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
p.display().to_string()
|
||||
};
|
||||
rels.push(display);
|
||||
}
|
||||
rels
|
||||
}
|
||||
Err(_) => Vec::new(),
|
||||
}
|
||||
};
|
||||
let agents_paths = discover_user_instruction_paths(config).unwrap_or_default();
|
||||
let agents_list: Vec<String> = agents_paths
|
||||
.into_iter()
|
||||
.map(|path| format_agent_path(config, &path))
|
||||
.collect();
|
||||
if agents_list.is_empty() {
|
||||
lines.push(" • AGENTS files: (none)".into());
|
||||
} else {
|
||||
@@ -1286,6 +1252,23 @@ pub(crate) fn new_status_output(
|
||||
PlainHistoryCell { lines }
|
||||
}
|
||||
|
||||
fn format_agent_path(config: &Config, path: &Path) -> String {
|
||||
if let Ok(relative) = path.strip_prefix(&config.cwd) {
|
||||
return relative.display().to_string();
|
||||
}
|
||||
|
||||
if let Some(rel) = relativize_to_home(path) {
|
||||
if rel.as_os_str().is_empty() {
|
||||
return "~".to_string();
|
||||
}
|
||||
|
||||
let sep = std::path::MAIN_SEPARATOR;
|
||||
return format!("~{sep}{}", rel.display());
|
||||
}
|
||||
|
||||
path.display().to_string()
|
||||
}
|
||||
|
||||
/// Render a summary of configured MCP servers from the current `Config`.
|
||||
pub(crate) fn empty_mcp_output() -> PlainHistoryCell {
|
||||
let lines: Vec<Line<'static>> = vec![
|
||||
|
||||
Reference in New Issue
Block a user