mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-07-09 17:19:02 +00:00
fix(cli): prefer command name match over alias match regardless of recentScore (#6504)
In compareRankedCommandMatches, recentScore was evaluated before nameVsAlias in the sort chain, causing recently-used alias matches to shadow name matches at the same matchStrength level. The fix swaps the order so nameVsAlias is checked before recentScore, ensuring that a command matched by its primary name always ranks above an alias match, with recency acting as a tie-breaker only within the same match-type bucket. Adds a regression test that gives an alias match a recentScore and verifies the name match still ranks first. Signed-off-by: Alex <alex.tech.lab@outlook.com>
This commit is contained in:
parent
65c0d36be3
commit
74ebb10e8b
2 changed files with 55 additions and 1 deletions
|
|
@ -31,6 +31,10 @@ function useTestHarnessForSlashCompletion(
|
|||
query: string | null,
|
||||
slashCommands: readonly SlashCommand[],
|
||||
commandContext: CommandContext,
|
||||
recentCommands?: ReadonlyMap<
|
||||
string,
|
||||
{ name: string; usedAt: number; count: number }
|
||||
>,
|
||||
) {
|
||||
const [suggestions, setSuggestions] = useState<Suggestion[]>([]);
|
||||
const [isLoadingSuggestions, setIsLoadingSuggestions] = useState(false);
|
||||
|
|
@ -41,6 +45,7 @@ function useTestHarnessForSlashCompletion(
|
|||
query,
|
||||
slashCommands,
|
||||
commandContext,
|
||||
recentCommands,
|
||||
setSuggestions,
|
||||
setIsLoadingSuggestions,
|
||||
setIsPerfectMatch,
|
||||
|
|
@ -169,4 +174,53 @@ describe('useSlashCompletion integration', () => {
|
|||
expect(resumeIndex).toBeLessThan(clearIndex);
|
||||
expect(recapIndex).toBeLessThan(clearIndex);
|
||||
});
|
||||
|
||||
it('prefers command name match over alias match even when alias has recentScore', async () => {
|
||||
// Regression test: recentScore should not shadow nameVsAlias dimension.
|
||||
// Real-world conflict: /re matches `resume` (name) and `reset` (alias of clear).
|
||||
// Even if `clear` was used recently (giving it a recentScore > 0), `resume`
|
||||
// (name match) should still rank first because name-vs-alias is checked before
|
||||
// recentScore in the sort chain.
|
||||
const now = Date.now();
|
||||
const slashCommands = [
|
||||
createTestCommand({
|
||||
name: 'clear',
|
||||
altNames: ['reset', 'new'],
|
||||
description: 'Clear conversation history',
|
||||
}),
|
||||
createTestCommand({
|
||||
name: 'resume',
|
||||
altNames: ['continue'],
|
||||
description: 'Resume a previous session',
|
||||
}),
|
||||
];
|
||||
|
||||
// Give `clear` a recentScore to simulate it was used recently
|
||||
const recentCommands = new Map([
|
||||
['clear', { name: 'clear', usedAt: now, count: 1 }],
|
||||
]);
|
||||
|
||||
const { result } = renderHook(() =>
|
||||
useTestHarnessForSlashCompletion(
|
||||
true,
|
||||
'/re',
|
||||
slashCommands,
|
||||
mockCommandContext,
|
||||
recentCommands,
|
||||
),
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.suggestions.length).toBeGreaterThan(1);
|
||||
});
|
||||
|
||||
// resume is a name match; reset is an alias match.
|
||||
// Even with recentScore boosting `clear`, name match must win.
|
||||
const names = result.current.suggestions.map((s) => s.value);
|
||||
const resumeIndex = names.indexOf('resume');
|
||||
const clearIndex = names.indexOf('clear');
|
||||
expect(resumeIndex).toBeGreaterThanOrEqual(0);
|
||||
expect(clearIndex).toBeGreaterThanOrEqual(0);
|
||||
expect(resumeIndex).toBeLessThan(clearIndex);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -247,8 +247,8 @@ function compareRankedCommandMatches(
|
|||
return (
|
||||
right.matchStrength - left.matchStrength ||
|
||||
right.completionPriority - left.completionPriority ||
|
||||
right.recentScore - left.recentScore ||
|
||||
nameVsAlias ||
|
||||
right.recentScore - left.recentScore ||
|
||||
right.score - left.score ||
|
||||
left.start - right.start ||
|
||||
left.itemLength - right.itemLength ||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue