Keep shared skill caches fresh across plugin loads (#37000)

## What changed

- Key cached skill snapshots by filesystem and plugin snapshot identity so compatible config and working-directory loads can share results without reusing stale plugin data.
- Coalesce concurrent loads for the same cache key and replace the cached entry on forced reload.
- Clear both plugin and skill caches when `skills/list` forces a reload, and bypass working-directory caching when effective plugin roots are present.

## Testing

- Cover concurrent cache sharing, filesystem isolation, forced reloads, and refreshed plugin skill metadata in host service and app server tests.

GitOrigin-RevId: 03fed3b40d45bb29206d5a3c3e78f06df04dbb1e
This commit is contained in:
chess authored and copyberry committed 2026-08-05 01:24:35 +00:00
1 parent 431c78eb9c
commit 5d89ab65dc
5 files changed
+251 -44

No files matched your search

+16
View File
@@ -1,6 +1,8 @@
use std::collections::HashMap;
use std::collections::HashSet;
use std::fmt;
use std::hash::Hash;
use std::hash::Hasher;
use std::sync::Arc;
use std::sync::Mutex;
@@ -33,6 +35,20 @@ impl PluginSkillSnapshots {
}
}
impl PartialEq for PluginSkillSnapshots {
fn eq(&self, other: &Self) -> bool {
Arc::ptr_eq(&self.snapshots_by_root, &other.snapshots_by_root)
}
}
impl Eq for PluginSkillSnapshots {}
impl Hash for PluginSkillSnapshots {
fn hash<H: Hasher>(&self, state: &mut H) {
Arc::as_ptr(&self.snapshots_by_root).hash(state);
}
}
impl fmt::Debug for PluginSkillSnapshots {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("PluginSkillSnapshots")