Skip to content
kitn AI/UI

Skills & slash commands

An assistant that surfaces its capabilities as slash commands. Type / in the composer to open the palette, pick a command like /summarize or /code-review, and send it to get a reply tailored to that capability. The badges above the thread show the same skills as <kai-skills>.

<kai-chat> owns the thread and the composer. Pass a slashCommands array as a property — typing / opens the palette, and choosing a command sets the composer to its label (for example /summarize ) ready to send. The chat fires kai-slash-select the moment a command is chosen, and kai-submit when the message is sent. <kai-skills> renders the same capabilities as badges from a separate skills property.

<kai-skills id="skills"></kai-skills>
<kai-chat id="chat" chat-title="Workspace assistant"></kai-chat>
<script type="module">
import '@kitn.ai/ui/elements';
const chat = document.getElementById('chat');
const skills = document.getElementById('skills');
// Each command: { id, label, description?, category? }
chat.slashCommands = [
{ id: 'summarize', label: '/summarize', description: 'Condense a thread into key points', category: 'Writing' },
{ id: 'translate', label: '/translate', description: 'Translate text into another language', category: 'Writing' },
{ id: 'code-review', label: '/code-review', description: 'Review a diff for bugs and style', category: 'Engineering' },
{ id: 'search-docs', label: '/search-docs', description: 'Search the knowledge base', category: 'Engineering' },
];
// Skill badges: { id, name }
skills.skills = [
{ id: 'summarize', name: 'Summarize' },
{ id: 'translate', name: 'Translate' },
{ id: 'code-review', name: 'Code Review' },
{ id: 'search-docs', name: 'Search Docs' },
];
// Highlight the chosen command as active in the palette.
chat.addEventListener('kai-slash-select', (e) => {
chat.slashActiveIds = [e.detail.command.id];
});
// Route the submitted prompt by its leading /command token.
chat.addEventListener('kai-submit', async (e) => {
const prompt = e.detail.value;
const command = prompt.trim().match(/^\/(\S+)/)?.[1];
const aId = crypto.randomUUID();
chat.messages = [
...chat.messages,
{ id: crypto.randomUUID(), role: 'user', content: prompt },
{ id: aId, role: 'assistant', content: '' },
];
chat.loading = true;
// Dispatch to the matching capability on your backend.
const reply = await runCapability(command, prompt);
for await (const token of reply) {
chat.messages = chat.messages.map((m) =>
m.id === aId ? { ...m, content: m.content + token } : m,
);
}
chat.loading = false;
});
</script>

slashCommands shape — each item in the array:

fieldtypenotes
idstringStable identifier; carried on kai-slash-select
labelstringPalette label and what fills the composer (for example /summarize)
descriptionstring?Secondary text shown beside the label
categorystring?Groups commands under a heading in the palette

slashActiveIds highlights commands as active in the palette, and slashCompact switches to a single-line layout. Set slashCommands on <kai-prompt-input> directly when you compose the composer yourself instead of using the full <kai-chat>.

  • kai-chat reference — the slashCommands, slashActiveIds, and slashCompact props plus the kai-slash-select and kai-submit events.
  • kai-skills reference — the skills property and the declarative <kai-skill> children path.
  • Streaming recipe — parsing SSE from your backend and driving the token loop.
  • Agentic assistant — tools and multi-step reasoning rendered inline in the thread.