mirror of
https://github.com/openai/codex.git
synced 2026-10-29 19:08:43 +00:00
Cache empty remote skill discovery with filesystem watches (#57598)
## Why Repeated repository skill discovery performs remote metadata requests even when no `.agents/skills` directories exist. Reuse verified empty results to avoid those round trips while watching for changes that require a new scan. ## What changed - Add the Linux executor capability `fs_watch_missing`, the `fs/watchMissing` request, and `fs/missingChanged` notifications. - Register watches in the background and reuse empty results only after the executor acknowledges coverage. Key reuse by filesystem, working directory, and project root markers. - Invalidate observations on relevant filesystem or mount changes, watch supersession, or connection loss. Clear cached observations on forced reloads and cache resets. - Retain live discovery while registration is pending or watching is unsupported, unavailable, or cannot verify the observation. ## Testing Add tests for empty-result reuse and invalidation, skill directory creation before watch acknowledgement, unsupported executors, idle WebSocket notifications, reconnection, case aliases, and bind mounts and unmounts. Include an ignored manual latency comparison for repeated empty remote scans. GitOrigin-RevId: 3ad499decefb184a99c068afa01d0dcdd8605c7f
This commit is contained in:
@@ -42,6 +42,8 @@ pub const FS_CLOSE_METHOD: &str = "fs/close";
|
||||
pub const FS_WRITE_FILE_METHOD: &str = "fs/writeFile";
|
||||
pub const FS_CREATE_DIRECTORY_METHOD: &str = "fs/createDirectory";
|
||||
pub const FS_GET_METADATA_METHOD: &str = "fs/getMetadata";
|
||||
pub const FS_WATCH_MISSING_METHOD: &str = "fs/watchMissing";
|
||||
pub const FS_MISSING_CHANGED_METHOD: &str = "fs/missingChanged";
|
||||
pub const FS_CANONICALIZE_METHOD: &str = "fs/canonicalize";
|
||||
pub const FS_READ_DIRECTORY_METHOD: &str = "fs/readDirectory";
|
||||
pub const FS_WALK_METHOD: &str = "fs/walk";
|
||||
@@ -165,6 +167,9 @@ pub struct EnvironmentCapabilities {
|
||||
/// Whether capability discovery applies the filesystem sandbox sent with each root.
|
||||
#[serde(default)]
|
||||
pub capability_discovery_sandbox: bool,
|
||||
/// Whether missing metadata paths can be watched on this physical connection.
|
||||
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
|
||||
pub fs_watch_missing: bool,
|
||||
/// Whether this executor supports V2 capability discovery.
|
||||
#[serde(default)]
|
||||
pub capability_discovery_v2: bool,
|
||||
@@ -321,6 +326,7 @@ impl EnvironmentInfo {
|
||||
credential_masking,
|
||||
credential_masking_custom_providers: credential_masking,
|
||||
capability_discovery_sandbox: true,
|
||||
fs_watch_missing: cfg!(target_os = "linux"),
|
||||
capability_discovery_v2: true,
|
||||
environment_config_read: true,
|
||||
http_header_env_vars: true,
|
||||
@@ -756,6 +762,27 @@ pub struct FsGetMetadataParams {
|
||||
pub sandbox: Option<FileSystemSandboxContext>,
|
||||
}
|
||||
|
||||
/// One unsandboxed metadata observation per connection. A newer id supersedes the prior watch.
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct FsWatchMissingParams {
|
||||
pub watch_id: u64,
|
||||
pub missing: Vec<PathUri>,
|
||||
pub present: Option<PathUri>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct FsWatchMissingResponse {
|
||||
pub watching: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct FsMissingChangedNotification {
|
||||
pub watch_id: u64,
|
||||
}
|
||||
|
||||
/// Filesystem RPC wire request with legacy optional sandbox policy cwd.
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
@@ -1274,6 +1301,7 @@ mod tests {
|
||||
fn discovery_v2_support_defaults_off_for_older_executors() -> serde_json::Result<()> {
|
||||
let legacy: super::EnvironmentCapabilities = serde_json::from_value(serde_json::json!({}))?;
|
||||
assert!(!legacy.capability_discovery_v2);
|
||||
assert!(!legacy.fs_watch_missing);
|
||||
let capabilities = super::EnvironmentInfo::local().capabilities;
|
||||
assert_eq!(
|
||||
serde_json::from_value::<super::EnvironmentCapabilities>(serde_json::to_value(
|
||||
@@ -1547,6 +1575,7 @@ mod tests {
|
||||
credential_masking: false,
|
||||
credential_masking_custom_providers: false,
|
||||
capability_discovery_sandbox: true,
|
||||
fs_watch_missing: false,
|
||||
capability_discovery_v2: false,
|
||||
environment_config_read: false,
|
||||
http_header_env_vars: false,
|
||||
|
||||
Reference in New Issue
Block a user