Skip to content

Commit 59ddcf4

Browse files
committed
feat(command-suggestion): enhance command filtering and sorting logic
1 parent 08eb913 commit 59ddcf4

2 files changed

Lines changed: 38 additions & 10 deletions

File tree

dashboard/src/components/chat/ChatInput.vue

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,10 @@ const showCommandSuggestion = ref(false);
407407
const selectedCommandIndex = ref(0);
408408
const commandSuggestionLoading = ref(false);
409409
410+
function normalizeCommandSearchText(value: string) {
411+
return value.trim().replace(/^\/+/, "").toLowerCase();
412+
}
413+
410414
/** 从所有指令中展平获取启用的普通指令和子指令 */
411415
const enabledCommands = computed(() => {
412416
const result: SuggestionCommand[] = [];
@@ -431,6 +435,7 @@ const enabledCommands = computed(() => {
431435
description: cmd.description,
432436
plugin_display_name: cmd.plugin_display_name,
433437
enabled: cmd.enabled,
438+
reserved: cmd.reserved,
434439
});
435440
}
436441
// 同时加入别名(别名也需要加上 / 前缀)
@@ -449,6 +454,7 @@ const enabledCommands = computed(() => {
449454
description: cmd.description,
450455
plugin_display_name: cmd.plugin_display_name,
451456
enabled: cmd.enabled,
457+
reserved: cmd.reserved,
452458
});
453459
}
454460
});
@@ -458,15 +464,40 @@ const enabledCommands = computed(() => {
458464
return result;
459465
});
460466
467+
function sortSystemPluginCommandsFirst(commands: SuggestionCommand[]) {
468+
return [...commands].sort((a, b) => Number(b.reserved) - Number(a.reserved));
469+
}
470+
461471
/** 根据当前输入过滤候选指令 */
462472
const filteredCommands = computed(() => {
463473
const text = props.prompt;
464474
if (!text || !text.startsWith("/")) return [];
465475
466-
const prefix = text.toLowerCase();
467-
return enabledCommands.value
468-
.filter((cmd) => cmd.effective_command.toLowerCase().startsWith(prefix))
469-
.slice(0, 8); // 最多显示8条
476+
const query = normalizeCommandSearchText(text);
477+
if (!query) return sortSystemPluginCommandsFirst(enabledCommands.value);
478+
479+
const startsWithMatches: SuggestionCommand[] = [];
480+
const containsMatches: SuggestionCommand[] = [];
481+
482+
for (const cmd of enabledCommands.value) {
483+
const commandText = normalizeCommandSearchText(cmd.effective_command);
484+
const pluginText = normalizeCommandSearchText(cmd.plugin_display_name || "");
485+
const descriptionText = normalizeCommandSearchText(cmd.description || "");
486+
const matchesCommand = commandText.includes(query);
487+
const matchesMetadata =
488+
pluginText.includes(query) || descriptionText.includes(query);
489+
490+
if (commandText.startsWith(query)) {
491+
startsWithMatches.push(cmd);
492+
} else if (matchesCommand || matchesMetadata) {
493+
containsMatches.push(cmd);
494+
}
495+
}
496+
497+
return [
498+
...sortSystemPluginCommandsFirst(startsWithMatches),
499+
...sortSystemPluginCommandsFirst(containsMatches),
500+
];
470501
});
471502
472503
const localPrompt = computed({
@@ -659,11 +690,7 @@ function handleKeyDown(e: KeyboardEvent) {
659690
function handleInput() {
660691
const text = props.prompt;
661692
if (text && text.startsWith("/") && !isComposing.value) {
662-
const prefix = text.toLowerCase();
663-
const hasMatch = enabledCommands.value.some((cmd) =>
664-
cmd.effective_command.toLowerCase().startsWith(prefix),
665-
);
666-
showCommandSuggestion.value = hasMatch;
693+
showCommandSuggestion.value = filteredCommands.value.length > 0;
667694
selectedCommandIndex.value = 0;
668695
} else {
669696
showCommandSuggestion.value = false;

dashboard/src/components/chat/CommandSuggestion.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<div class="command-suggestion-list">
99
<div
1010
v-for="(cmd, index) in filteredCommands"
11-
:key="cmd.handler_full_name"
11+
:key="`${cmd.handler_full_name}:${cmd.effective_command}`"
1212
class="command-suggestion-item"
1313
:class="{ active: index === selectedIndex }"
1414
@click="handleSelect(index)"
@@ -43,6 +43,7 @@ export interface SuggestionCommand {
4343
description: string;
4444
plugin_display_name: string | null;
4545
enabled: boolean;
46+
reserved: boolean;
4647
}
4748
4849
interface Props {

0 commit comments

Comments
 (0)