HextaAI
A complete AI chat app built from every HextaUI AI block. Chats in a sidebar, thinking with sources, tool calls with diffs and approvals, a plan you review before the agent runs, streamed Markdown and code, and silent voice mode, all driven by AI SDK message parts.
HextaAI is a complete AI chat app made from every HextaUI AI block. Chat Sidebar holds the history, Chat Thread holds the conversation, Prompt Input is the composer, and each reply is drawn from its parts: Thinking for reasoning, Tool Calls for what the agent did, Agent Todos for its plan, Code Block for diffs and terminals, and Streaming Markdown for the answer. Voice Mode opens from the composer and drops the conversation into the chat when you hang up.
The core is HextaMessageParts. It takes the same message parts the AI SDK’s useChat returns, groups neighbouring reasoning and tool calls, keeps one live plan at the top of the reply, and renders text with citations linked to the sources the model found. Reads, edits, writes, searches, web fetches and shell commands each get a fitting view, and you can add renderers for your own tools.
The demo runs on ScriptedChats, a small engine that streams realistic parts offline. Try a suggestion: research a question and watch sources come in, ask for a feature and review the plan before it runs, approve a test run that fails and gets fixed, or ask for an explanation with code and tables. Stop, regenerate, edit and switch chats while replies keep streaming in the background, then open voice mode and talk.
Add the Pro registry to components.json
components.json Add your token
Create a token on your account page and put it in
.env.localasHEXTAUI_PRO_TOKEN.Add the block
pnpm dlx shadcn@latest add @hextaui-pro/hexta-ai
With the AI SDK
Pass useChat messages straight to HextaMessageParts. Tool approvals and plan reviews answer through addToolApprovalResponse, and an edited plan goes back to the model as the approval reason.
Your own tools
Map a tool name to a renderer that returns its kind, subject and content. Tools you don't map fall back to built-in views or a JSON view.
Scripted demos
ScriptedChats streams AI SDK-shaped parts from a script, with real pacing, approvals and stop. Use it for product tours, onboarding and offline demos.
Anatomy
The parts you compose, from the outside in.
| Part | Description |
|---|---|
HextaMessageParts | Renders one assistant message from its parts, in order: reasoning, plan, tool calls and Markdown. |
defaultTools | Built-in renderers for read_file, list_files, grep, web_search, fetch, edit_file, write_file and bash. |
ScriptedChats, useScriptedChat | An offline engine that streams AI SDK-shaped parts from scripts, with stop, regenerate, edit, approvals and plan review. |
textOf, sourcesOf, toBlocks | Helpers that read text and sources from a message and group its parts the way the renderer does. |
HextaAIDemo | The full app: Chat Sidebar, Chat Thread, Prompt Input and Voice Mode wired to ScriptedChats. |
| Prop | Type | Default |
|---|---|---|
partsThe message’s parts: text, reasoning, source-url, file and tool parts, as useChat returns them. | MessagePart[] | – |
streamingWhether this message is still arriving. The last reasoning or text block animates, and running tools stay live. | boolean | false |
stoppedMarks running tools as cancelled and hides a pending plan review. | boolean | false |
toolsRenderers by tool name. Each returns kind, subject, title, meta, content, exitCode or error, and overrides the built-in view. | Record<string, ToolRenderer> | {} |
onApprovalCalled when someone allows or denies a tool call that is waiting for approval. | (toolCallId, { approved, reason?, always? }) => void | – |
onPlanApproveCalled with the edited plan when someone runs it from the review. | (toolCallId, todos) => void | – |
onPlanCancelCalled when the plan review is cancelled. | (toolCallId) => void | – |
reasoningDurationsSeconds spent on each reasoning block, so “Thought for” stays right after a reload. | number[] | – |
| Prop | Type | Default |
|---|---|---|
new ScriptedChats(respond)Picks the script that answers each message. | (prompt, files) => Script | – |
send(chatId, text, files?, options?)Adds a user message and streams the reply. options: model, thinking and instant, which skips all waiting. | Promise<void> | – |
stop, regenerate, edit, append, removeStop the reply, redo the last one, resend from an edited message, add finished messages, or drop a chat. | methods | – |
decide(toolCallId, decision)Answers a pending approval or plan review. Pass todos to run an edited plan. | void | – |
useScriptedChat(store, chatId)Subscribes a component to one chat. | { messages, status, pinned } | – |
| Prop | Type | Default |
|---|---|---|
think(text)Streams a reasoning part. Skipped when thinking is off. | Promise<void> | – |
say(markdown)Streams a text part in uneven chunks, like a real model. | Promise<void> | – |
tool(name, input, { stream? })Adds a tool call, optionally streaming one input field. The handle can approve, progress, finish or fail it. | Promise<ToolHandle> | – |
plan(todos)Shows a plan for review and waits. Returns the edited plan, or null if cancelled. | Promise<Todo[] | null> | – |
todos(todos), source(page), pause(ms)Update the plan, cite a source, or wait. | methods | – |
| Key | Action |
|---|---|
| ⌘K | Searches your chats. |
| ⌘⇧O | Starts a new chat. |
| ⌘B | Collapses the sidebar to icons, or opens it full screen on phones. |
| Enter | Sends the message. Shift+Enter adds a line. |
| ⌘↵ | Runs the plan while it’s being reviewed, or allows a tool call that is waiting. |
| ⌘⌫ | Denies the tool call that is waiting. |
| Esc | Stops the reply, closes a menu, or ends voice mode. |
- Every part keeps the accessibility of the block that draws it: the thread announces new replies politely, tool calls and plans expose their state in text, citations name their source, and approvals are real buttons with keyboard shortcuts.
- Nothing important is shown only by motion or color. Spinners have labels like “Replying”, finished chats in the background get an “Unread reply” label, and diffs mark added and removed lines with signs as well as color.
- Streaming, shader and sheet animations all respect reduced motion. Voice mode works without speaking replies aloud, shows captions, and plays a sample conversation when there’s no microphone.
Code
5 files, added to components/blocks/hexta-ai.