Chatbot

new 7.4 kB
<hk-chatbot>

A complete assistant surface with the vendor left out. The engine is plain TypeScript: it owns the transcript, streams tokens into the current message, runs whatever tools you registered and feeds the results back for another round. What talks to a model is a single function you supply, so the demo runs on a local transport with no key and no network, and going live is one swap. Voice is both directions — dictation into the composer, synthesis out of it — and both are feature-detected, so a browser without them simply does not show the button.

#ai#chat#assistant#voice#tools

Live demo

Running in this page — interact with it.

Inputs

NameTypeDefaultDescription
transportHkChatTransportTurns a request into an async stream of chunks. The only thing that knows about a model.
systemPromptstring''Seeded as the first message and restored on reset(). Never rendered as a bubble.
toolsHkTool[][]Initial tool registry. Add to it later with registerTool().
maxToolRoundsnumber3How many tool rounds one turn may take, so a model that keeps calling itself cannot loop forever.
speakRepliesbooleanfalseRead replies aloud as they stream, a sentence at a time.

Outputs

  • onChange(messages: HkChatMessage[]) => void

    Fires on every mutation with a fresh array, so a signal can hold it.

  • onToolCall(call: HkToolCall) => void

    Fires per finished call, with args, result and elapsed ms.

Methods

  • send(text)(text: string) => Promise<void>

    Runs a full turn: stream, tool calls, and the rounds they trigger.

  • registerTool(tool)(tool: HkTool) => void

    Add or replace a tool, including mid-conversation.

  • abort()() => void

    Cancels the in-flight turn and keeps whatever already streamed.

  • reset()() => void

    Clears the transcript back to the system prompt.

Keyboard

  • Enter Send
  • Shift + Enter Newline
  • Esc Stop the in-flight reply

Theming

Component tokens, each falling back to a global one:

PropertyDefaultControls
--hk-chat-bubble-uservar(--hk-accent)User bubble fill.
--hk-chat-bubble-botvar(--hk-surface)Assistant bubble fill.
--hk-chat-log-height20remTranscript height before it scrolls.

Accessibility

  • The transcript is role="log" with aria-live="polite", so a reply is announced without interrupting.
  • Dictation and speech are feature-detected: an unsupported browser gets no dead button.
  • Recording is signalled by colour, an animated ring and aria-pressed together, never colour alone.
  • Every animation here — the caret, the tool spinner, the mic ring — stops under prefers-reduced-motion.