feat(web): /skill slash command with autocomplete

Trigger /<name>, dropdown lists all skills filtered by name prefix,
arg passthrough sends the rest as the user message. Synthetic
skill_use tool_use renders identically to model-invoked skills.
This commit is contained in:
2026-05-18 01:10:51 +00:00
parent eaacd432e8
commit 80fd3d9fa9
4 changed files with 282 additions and 2 deletions

View File

@@ -96,6 +96,18 @@ export function ChatPane({ sessionId, chatId, projectId, agentId, onAgentChange,
}
}, [chatId]);
// Batch 9.6: slash-command dispatch. Sent regardless of streaming state —
// matches the existing /compact precedent (which also fires immediately).
// Empty args go to the server as null; the server fills in a default user
// message ("Apply this skill.") so the model has something to act on.
const handleSlashCommand = useCallback(async (skillName: string, userMessage: string) => {
try {
await api.chats.skillInvoke(chatId, skillName, userMessage.length > 0 ? userMessage : null);
} catch (err) {
toast.error(err instanceof Error ? err.message : `/${skillName} failed`);
}
}, [chatId]);
function removeQueued(idx: number) {
setQueue((prev) => prev.filter((_, i) => i !== idx));
}
@@ -183,6 +195,7 @@ export function ChatPane({ sessionId, chatId, projectId, agentId, onAgentChange,
webSearchEnabled={webSearchEnabled}
onSend={handleSend}
onForceSend={streaming ? handleForceSend : undefined}
onSlashCommand={handleSlashCommand}
/>
</div>
</div>