mirror of
https://github.com/openai/codex.git
synced 2026-10-18 17:18:52 +00:00
## What changed - Skip project-scoped `AGENTS.md` discovery when the active project is untrusted, while preserving user-level instructions. - Include the active project trust level in the instruction cache key so runtime trust changes reload the applicable instructions. - Preserve updated project trust metadata during runtime configuration refreshes. ## Testing Add coverage for initially untrusted projects and for switching between trusted and untrusted states at runtime. GitOrigin-RevId: 284bf7693943f585013fb5fe4b6aa3309bc50cf3
86 lines
2.9 KiB
Rust
86 lines
2.9 KiB
Rust
use crate::agents_md::LoadedAgentsMd;
|
|
use crate::agents_md::load_project_instructions;
|
|
use crate::config::Config;
|
|
use crate::environment_selection::TurnEnvironmentSnapshot;
|
|
use codex_extension_api::UserInstructions;
|
|
use codex_protocol::config_types::TrustLevel;
|
|
use codex_protocol::config_types::WindowsSandboxLevel;
|
|
use codex_protocol::protocol::TurnEnvironmentSelection;
|
|
use std::io;
|
|
use std::sync::Arc;
|
|
use tokio::sync::Mutex;
|
|
|
|
/// Owns the inputs and cached result of AGENTS.md discovery for a session.
|
|
pub(crate) struct AgentsMdManager {
|
|
user_instructions: Option<UserInstructions>,
|
|
cache: Mutex<AgentsMdCache>,
|
|
}
|
|
|
|
#[derive(Default)]
|
|
struct AgentsMdCache {
|
|
selections: Option<Vec<TurnEnvironmentSelection>>,
|
|
active_project_trust_level: Option<TrustLevel>,
|
|
windows_sandbox_level: Option<WindowsSandboxLevel>,
|
|
loaded: Option<Arc<LoadedAgentsMd>>,
|
|
}
|
|
|
|
impl AgentsMdManager {
|
|
pub(crate) fn new(user_instructions: Option<UserInstructions>) -> Self {
|
|
Self {
|
|
user_instructions: user_instructions
|
|
.filter(|instructions| !instructions.text.trim().is_empty()),
|
|
cache: Mutex::new(AgentsMdCache::default()),
|
|
}
|
|
}
|
|
|
|
#[tracing::instrument(name = "agents_md.refresh", skip_all)]
|
|
pub(crate) async fn refresh(
|
|
&self,
|
|
config: &Config,
|
|
environments: &TurnEnvironmentSnapshot,
|
|
windows_sandbox_level: WindowsSandboxLevel,
|
|
) -> io::Result<()> {
|
|
let selections = environments
|
|
.turn_environments()
|
|
.map(|environment| environment.selection.clone())
|
|
.collect::<Vec<_>>();
|
|
let active_project_trust_level = config.active_project.trust_level;
|
|
{
|
|
let mut cache = self.cache.lock().await;
|
|
if cache.selections.as_ref() == Some(&selections)
|
|
&& cache.active_project_trust_level == active_project_trust_level
|
|
&& cache.windows_sandbox_level == Some(windows_sandbox_level)
|
|
{
|
|
return Ok(());
|
|
}
|
|
cache.selections = None;
|
|
cache.active_project_trust_level = None;
|
|
cache.windows_sandbox_level = None;
|
|
cache.loaded = None;
|
|
}
|
|
|
|
let loaded = load_project_instructions(
|
|
config,
|
|
self.user_instructions.clone(),
|
|
environments,
|
|
windows_sandbox_level,
|
|
)
|
|
.await?
|
|
.map(Arc::new);
|
|
let mut cache = self.cache.lock().await;
|
|
cache.selections = Some(selections);
|
|
cache.active_project_trust_level = active_project_trust_level;
|
|
cache.windows_sandbox_level = Some(windows_sandbox_level);
|
|
cache.loaded = loaded;
|
|
Ok(())
|
|
}
|
|
|
|
pub(crate) async fn get_loaded(&self) -> Option<Arc<LoadedAgentsMd>> {
|
|
self.cache.lock().await.loaded.clone()
|
|
}
|
|
|
|
pub(crate) fn user_instructions(&self) -> Option<UserInstructions> {
|
|
self.user_instructions.clone()
|
|
}
|
|
}
|