perf(chat): avoid repeated skill catalog scans while building the picker (#31936)

* perf(chat): remove repeated scans and array copies from the skill picker

* perf(chat): keep picker grouping within the module line limit

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
This commit is contained in:
OrcaWin
2026-10-22 13:20:06 -07:00
committed by GitHub
co-authored by OrcaWin
parent 5dbd23364b
commit c8059ee3c0
2 changed files with 21 additions and 2 deletions
@@ -456,6 +456,19 @@ describe('native skill and command picker', () => {
expect(items[1]).toMatchObject({ kind: 'skill', description: null, sources: [] })
})
it('keeps the first reported description for duplicate unlocated skill names', () => {
const items = buildNativeChatPickerItems([], [], '', '/', [
{ name: 'missing' },
{ name: 'missing', description: 'Later description' },
{ name: 'present', description: 'First description' },
{ name: 'present', description: 'Later description' }
])
expect(items).toMatchObject([
{ name: 'missing', description: null },
{ name: 'present', description: 'First description' }
])
})
it('keeps the disk scan only when a session report is absent', () => {
const items = buildNativeChatPickerItems(
[],
+8 -2
View File
@@ -156,7 +156,9 @@ function mergeNativeChatSkills(
if (!safeName) {
continue
}
byName.set(safeName, [...(byName.get(safeName) ?? []), { ...skill, name: safeName }])
const namedSkills = byName.get(safeName) ?? []
namedSkills.push({ ...skill, name: safeName })
byName.set(safeName, namedSkills)
}
const discovered = new Map(
[...byName.entries()].map(([name, namedSkills]) => [
@@ -172,8 +174,12 @@ function mergeNativeChatSkills(
// A reported skill with its file is its own row: two skills may share a name, and the pick
// tells the agent which file it means.
const nameCounts = new Map<string, number>()
const firstReportedByName = new Map<string, NativeChatSessionSkill>()
for (const skill of sessionSkills ?? []) {
nameCounts.set(skill.name, (nameCounts.get(skill.name) ?? 0) + 1)
if (!firstReportedByName.has(skill.name)) {
firstReportedByName.set(skill.name, skill)
}
}
const located = (sessionSkills ?? []).flatMap((skill) =>
skill.path && isTokenSafe(skill.name)
@@ -202,7 +208,7 @@ function mergeNativeChatSkills(
...located,
...[...new Set(names)].map((name) => {
const skill = discovered.get(name) ?? pickerSkill(name, [], skillSigil)
const reported = sessionSkills?.find((entry) => entry.name === name)?.description
const reported = firstReportedByName.get(name)?.description
return skill.description === null && reported
? { ...skill, description: sanitizePickerText(reported, 240) }
: skill