Skip to content

chat: rank title matches above description matches in customizations list#312516

Open
maruthang wants to merge 3 commits into
microsoft:mainfrom
maruthang:fix/issue-309423-title-before-description
Open

chat: rank title matches above description matches in customizations list#312516
maruthang wants to merge 3 commits into
microsoft:mainfrom
maruthang:fix/issue-309423-title-before-description

Conversation

@maruthang

Copy link
Copy Markdown
Contributor

Summary

Fixes #309423

Problem: In the Chat/Agent Customizations editor list, when a search query is active, items whose name (title) matched got ranked alphabetically interleaved with items whose match landed only in the description, filename, or badge. For example, a skill named agent-customization whose description contained "screen" was alphabetized in front of a skill named screenshot whose name actually matches the query.

Root cause: applySearchFilter records both nameMatches and descriptionMatches, but the subsequent sort() calls in aiCustomizationListWidget.ts (buildGroupedEntries, and the sync layout's remote and local sorts) used a.name.localeCompare(b.name) only — ignoring where the match actually landed.

Fix: Added a pure helper compareMatchedCustomizationItems in aiCustomizationListWidgetUtils.ts. While a search is active, items with nameMatches rank above items without; otherwise it falls back to localeCompare. Replaced the three sort callsites in aiCustomizationListWidget.ts. The local-items sort in the sync layout preserves its synced/unsynced primary key and uses the new comparator as the tiebreaker. When search is inactive (!this.searchQuery.trim()), behavior is identical to before.

Scope

Contained to the AICustomizationListWidget. Does not touch the shared fuzzyScorer.ts or quickAccess — blast radius is just this widget.

Changes

  • aiCustomizationListWidgetUtils.ts: new compareMatchedCustomizationItems helper.
  • aiCustomizationListWidget.ts: three sort callsites now use the new comparator; sync layout's local-items sort keeps synced/unsynced as primary key with the comparator as tiebreaker.
  • aiCustomizationListWidget.test.ts: 5 new unit tests covering title-vs-description, both-name-match, neither-name-match, search-inactive fallback, and a mixed-sort end-to-end.

Copilot AI review requested due to automatic review settings July 6, 2026 06:53

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adjusts sorting in the AI Customization list widget so that, when a search query is active, items with title/name matches are ranked above items whose matches are only in secondary fields (description/filename/badge), fixing the ranking issue reported in #309423.

Changes:

  • Added a shared comparator (compareMatchedCustomizationItems) to prioritize nameMatches when searching.
  • Updated in-widget grouping/sorting to use the comparator while preserving the existing alphabetical behavior when search is inactive.
  • Added unit tests to validate title-vs-description ranking and fallback behaviors.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/vs/workbench/contrib/chat/test/browser/aiCustomization/aiCustomizationListWidget.test.ts Adds unit tests for the new match-prioritizing comparator behavior.
src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationListWidgetUtils.ts Introduces the new comparator helper used for search-active sorting.
src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationListWidget.ts Switches group-item sorting to use the new comparator when search is active.

Comment on lines +73 to +97
/**
* Comparator for matched customization list items used while a search
* query is active. Items whose name (title) matched the query rank above
* items whose name did not match (e.g. only the description, filename or
* badge matched), so that title matches always appear before
* description-only matches. Items within the same rank fall back to
* alphabetical order by name.
*
* When `searchActive` is false this falls back to plain alphabetical
* order so that idle (unfiltered) views are not affected.
*/
export function compareMatchedCustomizationItems(
a: { name: string; nameMatches?: unknown },
b: { name: string; nameMatches?: unknown },
searchActive: boolean,
): number {
if (searchActive) {
const aNameMatched = !!a.nameMatches;
const bNameMatched = !!b.nameMatches;
if (aNameMatched !== bNameMatched) {
return aNameMatched ? -1 : 1;
}
}
return a.name.localeCompare(b.name);
}
Comment on lines +1309 to +1315
// Sort items within each group. While a search is active, items
// whose name (title) matched the query rank above items whose name
// did not match, so title matches appear before description-only
// matches. Falls back to alphabetical order otherwise.
const searchActive = !!this.searchQuery.trim();
for (const group of groups) {
group.items.sort((a, b) => a.name.localeCompare(b.name));
group.items.sort((a, b) => compareMatchedCustomizationItems(a, b, searchActive));
Comment on lines +195 to +196
// Even though `titleMatch` has nameMatches, with search inactive
// we should ignore that signal and just sort alphabetically.
…tle-before-description

# Conflicts:
#	src/vs/workbench/contrib/chat/test/browser/aiCustomization/aiCustomizationListWidget.test.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Sort order should sort title matches before description matches

3 participants