mirror of
https://github.com/openai/codex.git
synced 2026-09-08 15:50:34 +00:00
Ignore generated system skills in the skills watcher (#35408)
## What changed - Exclude `SkillScope::System` roots from watcher registration because generated system skills are installed before the watcher starts. - Ignore events under the system skill cache that arrive through the recursively watched legacy user-skills root, avoiding unnecessary cache clears and `SkillsChanged` notifications. GitOrigin-RevId: ce8ba28ba873372b638950b676e4d09172a5c688
This commit is contained in:
@@ -309,7 +309,11 @@ impl MessageProcessor {
|
||||
thread_manager
|
||||
.plugins_manager()
|
||||
.set_analytics_events_client(analytics_events_client.clone());
|
||||
let skills_watcher = SkillsWatcher::new(thread_manager.skills_service(), outgoing.clone());
|
||||
let skills_watcher = SkillsWatcher::new(
|
||||
thread_manager.skills_service(),
|
||||
&config.codex_home,
|
||||
outgoing.clone(),
|
||||
);
|
||||
|
||||
let pending_thread_unloads = Arc::new(Mutex::new(HashSet::new()));
|
||||
let thread_watch_manager =
|
||||
|
||||
@@ -15,7 +15,9 @@ use codex_file_watcher::Receiver;
|
||||
use codex_file_watcher::ThrottledWatchReceiver;
|
||||
use codex_file_watcher::WatchPath;
|
||||
use codex_file_watcher::WatchRegistration;
|
||||
use codex_protocol::protocol::SkillScope;
|
||||
use codex_protocol::protocol::TurnEnvironmentSelection;
|
||||
use codex_skills::system_cache_root_dir;
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use tokio_util::sync::DropGuard;
|
||||
@@ -36,6 +38,7 @@ pub(crate) struct SkillsWatcher {
|
||||
impl SkillsWatcher {
|
||||
pub(crate) fn new(
|
||||
skills_service: Arc<SkillsService>,
|
||||
codex_home: &AbsolutePathBuf,
|
||||
outgoing: Arc<OutgoingMessageSender>,
|
||||
) -> Arc<Self> {
|
||||
let file_watcher = match FileWatcher::new() {
|
||||
@@ -48,7 +51,14 @@ impl SkillsWatcher {
|
||||
let (subscriber, rx) = file_watcher.add_subscriber();
|
||||
let shutdown_token = CancellationToken::new();
|
||||
let shutdown_drop_guard = shutdown_token.clone().drop_guard();
|
||||
Self::spawn_event_loop(rx, skills_service, outgoing, shutdown_token.child_token());
|
||||
let system_skills_root = system_cache_root_dir(codex_home);
|
||||
Self::spawn_event_loop(
|
||||
rx,
|
||||
skills_service,
|
||||
system_skills_root,
|
||||
outgoing,
|
||||
shutdown_token.child_token(),
|
||||
);
|
||||
Arc::new(Self {
|
||||
subscriber,
|
||||
runtime_extra_roots_registration: Mutex::new(WatchRegistration::default()),
|
||||
@@ -114,8 +124,9 @@ impl SkillsWatcher {
|
||||
.skill_roots_for_config(&skills_input, Some(environment.get_filesystem()))
|
||||
.await
|
||||
.into_iter()
|
||||
// Plugin roots are invalidated by plugin lifecycle operations.
|
||||
.filter(|root| root.plugin_identity.is_none())
|
||||
// Plugin roots have explicit lifecycle invalidation; generated system skills are
|
||||
// installed before this watcher starts.
|
||||
.filter(|root| root.plugin_identity.is_none() && root.scope != SkillScope::System)
|
||||
.map(|root| WatchPath {
|
||||
path: root.path.into_path_buf(),
|
||||
recursive: true,
|
||||
@@ -127,6 +138,7 @@ impl SkillsWatcher {
|
||||
fn spawn_event_loop(
|
||||
rx: Receiver,
|
||||
skills_service: Arc<SkillsService>,
|
||||
system_skills_root: AbsolutePathBuf,
|
||||
outgoing: Arc<OutgoingMessageSender>,
|
||||
shutdown_token: CancellationToken,
|
||||
) {
|
||||
@@ -141,8 +153,16 @@ impl SkillsWatcher {
|
||||
_ = shutdown_token.cancelled() => break,
|
||||
event = rx.recv() => event,
|
||||
};
|
||||
if event.is_none() {
|
||||
let Some(event) = event else {
|
||||
break;
|
||||
};
|
||||
// The legacy user-skills root contains `.system` and is watched recursively.
|
||||
if event
|
||||
.paths
|
||||
.iter()
|
||||
.all(|path| path.starts_with(system_skills_root.as_path()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
skills_service.clear_cache();
|
||||
outgoing
|
||||
|
||||
Reference in New Issue
Block a user