diff --git a/pkg/memory/store/queue.go b/pkg/memory/store/queue.go index cb5cc997c..b2d580709 100644 --- a/pkg/memory/store/queue.go +++ b/pkg/memory/store/queue.go @@ -148,6 +148,12 @@ func (q *QueueManager) EvictOldest(ctx context.Context, agentID, sessionKey stri evicted++ } + // DB trigger cascades chunk deletion, but the in-memory vecCache + // doesn't know about it. Force a reload on next search. + if evicted > 0 { + q.store.invalidateVecCache() + } + summary := "" if evicted > 0 { summary = fmt.Sprintf("[Memory compaction: %d items archived]\nEvicted topics: %s", diff --git a/pkg/skills/loader.go b/pkg/skills/loader.go index 7d8ba7856..da8356b58 100644 --- a/pkg/skills/loader.go +++ b/pkg/skills/loader.go @@ -77,8 +77,9 @@ func NewSkillsLoader(primarySkillsDir string, globalSkills string, builtinSkills } } -// DirsMtime returns the latest modification time across all skill directories. -// Used for cache invalidation — if no directories exist, returns zero time. +// DirsMtime returns the latest modification time across all skill directories +// and their immediate children. Catches both file additions (directory mtime) +// and in-place edits of existing skill files (file mtime). func (sl *SkillsLoader) DirsMtime() time.Time { var latest time.Time for _, dir := range []string{sl.primarySkills, sl.globalSkills, sl.builtinSkills} { @@ -92,6 +93,19 @@ func (sl *SkillsLoader) DirsMtime() time.Time { if mt := info.ModTime(); mt.After(latest) { latest = mt } + entries, err := os.ReadDir(dir) + if err != nil { + continue + } + for _, e := range entries { + fi, err := e.Info() + if err != nil { + continue + } + if mt := fi.ModTime(); mt.After(latest) { + latest = mt + } + } } return latest }