GetPinnedSkills resolves every pinned name against the persona manager and returns the matching skills sorted alphabetically (stable order keeps the system-prompt injection block cache-friendly). Stale pins — skills that were uninstalled or renamed — are pruned silently from the set.
()
| 1316 | // system-prompt injection block cache-friendly). Stale pins — skills that |
| 1317 | // were uninstalled or renamed — are pruned silently from the set. |
| 1318 | func (sh *SkillHandler) GetPinnedSkills() []*persona.Skill { |
| 1319 | if sh.personaMgr == nil { |
| 1320 | return nil |
| 1321 | } |
| 1322 | sh.pinnedSkillsMu.RLock() |
| 1323 | names := make([]string, 0, len(sh.pinnedSkillNames)) |
| 1324 | for n := range sh.pinnedSkillNames { |
| 1325 | names = append(names, n) |
| 1326 | } |
| 1327 | sh.pinnedSkillsMu.RUnlock() |
| 1328 | if len(names) == 0 { |
| 1329 | return nil |
| 1330 | } |
| 1331 | sort.Strings(names) |
| 1332 | |
| 1333 | out := make([]*persona.Skill, 0, len(names)) |
| 1334 | var stale []string |
| 1335 | for _, n := range names { |
| 1336 | s, err := sh.personaMgr.GetSkillByName(n) |
| 1337 | if err != nil || s == nil { |
| 1338 | stale = append(stale, n) |
| 1339 | continue |
| 1340 | } |
| 1341 | out = append(out, s) |
| 1342 | } |
| 1343 | |
| 1344 | if len(stale) > 0 { |
| 1345 | sh.pinnedSkillsMu.Lock() |
| 1346 | for _, n := range stale { |
| 1347 | delete(sh.pinnedSkillNames, n) |
| 1348 | } |
| 1349 | sh.pinnedSkillsMu.Unlock() |
| 1350 | sh.logger.Info("pruned stale pinned skills", |
| 1351 | zap.Strings("skills", stale)) |
| 1352 | } |
| 1353 | return out |
| 1354 | } |
| 1355 | |
| 1356 | // shortenRegistryError returns a concise error description for display. |
| 1357 | func shortenRegistryError(err error) string { |