Skip to main content
@personaai/ui exports two full widgets and a set of standalone building blocks. The widgets compose the building blocks internally — use the widgets when you want a complete chat experience, and the building blocks when you need to assemble your own layout.

Full widgets

PersonaChatView

The complete, self-contained chat widget — sidebar, message feed, composer, files drawer, interrupt card, and toolbar. All behavior wiring (thread creation, lazy message loading, file upload, present_file auto-open) is handled by usePersonaChatWidget internally.

Props

Layout structure

The widget handles

  • Thread selection and lazy creation (first message creates a thread automatically)
  • History loading when switching threads
  • Sidebar/files-drawer toggle state
  • Auto-closing sidebar on mobile viewport mount
  • Present_file auto-opening the files drawer

When to use instead of building blocks

Use PersonaChatView when you want a standard chat layout with sidebar + main area + files drawer. If you need a different layout (composer at the top, sidebar on the right, no sidebar, a floating widget), compose the building blocks yourself.

PersonaChatLauncher

A floating action button (FAB) that toggles a PersonaChatView panel — for mounting a chat widget on any page rather than a dedicated chat route. Accepts every PersonaChatViewProps and passes them through.

Additional props (beyond PersonaChatViewProps)

Container-query responsive behavior

The launcher’s root is a named CSS container (@container/persona-chat). PersonaSidebar and PersonaFilesDrawer key their dock-vs-overlay breakpoints off @3xl/persona-chat (768px) and @5xl/persona-chat (1024px) — the same pixel thresholds as the normal md:/lg:, but measured against the widget’s own width instead of the browser viewport. This means sidebar and drawer correctly stay in overlay mode inside the launcher’s narrow floating panel even on a wide desktop.

Theme propagation

The FAB button is a sibling of PersonaChatView’s subtree, not a descendant — it can’t inherit CSS variables PersonaChatView sets on its own root. The launcher computes buildThemeStyles once and applies it to a common ancestor of both the FAB and the panel, so primaryColor correctly reaches the FAB button.

Standalone building blocks

PersonaMessageFeed

The scrollable message list — renders messages, tool call cards, reasoning blocks, avatars, markdown, streaming indicators, and copy/reload buttons.

Props

Standalone usage

Rendering behavior

  • User messages: plain text with whitespace-pre-wrap, right-aligned, bubble background.
  • Assistant messages: Markdown-rendered (tables, LaTeX, fenced code blocks with copy button), left-aligned, full-width, no bubble background (since v0.7.1).
  • Tool calls: rendered as PersonaToolTrace cards, optionally grouped into PersonaToolGroup clusters.
  • Reasoning: collapsible “Thinking…” block above the answer.
  • Streaming: pulsing blue dot after the content.

PersonaComposer

The message input area — auto-resizing textarea, send/stop button, file upload button, and starter prompt badges.

Props

Behavior

  • Auto-resizes textarea height based on content (max 180px).
  • Enter sends (Shift+Enter for newline).
  • File upload button triggers a hidden <input type="file">.
  • Starter prompts appear as pill badges above the input, only when input is empty.

PersonaSidebar

Thread list sidebar — search, date-grouped threads, inline rename, delete, and new-chat button.

Props

Responsive behavior

  • Below @3xl/persona-chat (768px): full-screen overlay with backdrop.
  • Above: docked inline panel.
  • Auto-closes on mobile mount (handled by usePersonaChatWidget).
  • Thread search appears when there are >5 threads.

Date grouping

Threads are grouped into: Today, Yesterday, Previous 7 Days, Older — based on updatedAt.

PersonaFilesDrawer

Three-tab drawer: Files (uploads), Workspace (agent’s virtual filesystem + plan), Memory (persistent memory files).

Props

Responsive behavior

  • Below @5xl/persona-chat (1024px): full-screen overlay with backdrop.
  • Above: docked inline panel (80 wide).

PersonaToolTrace

A single tool call card — expandable accordion showing arguments, result, status, and subagent activity timeline. Special-cases present_file into a compact “Open this file” card, and write_todos into a checklist.

Props

Rendering behavior

  • present_file: Compact card with file icon, name, description, and Open button.
  • write_todos: Checklist with completed/in-progress/pending icons, title shows “Plan (x/y)”.
  • task (subagent): Nested timeline showing the subagent’s text output and tool calls.
  • Custom tool renderer: If toolRenderers[toolCall.toolName] exists and the result is ready, delegates to that component instead.
  • Generic: Expandable accordion with JSON-formatted args and result.

PersonaToolGroup

Clusters 2+ consecutive tool calls into one collapsible card with a semantic title derived from what the cluster is doing (memory, file, search, task, plan, or mixed).

Props

Auto-open behavior

Auto-opens the moment any tool in the group starts running. Never auto-closes once opened — a card the user expanded stays open after completion.

PersonaMarkdown

Renders assistant message content as Markdown — tables (GFM), LaTeX ($inline$ / $$block$$ via KaTeX), and fenced code blocks with a copy button. Used internally by PersonaMessageFeed for assistant messages.

Props

Note on user messages

User messages are deliberately rendered as plain text — rendering their literal input as Markdown could surprise them with formatting they didn’t intend.

PersonaInterruptCard

Renders HITL approval requests (approve/reject buttons for tool actions) and clarification questions (option buttons or free-text input). Displayed between the message feed and composer when useChat’s interrupt is set.

Props


PersonaSkeleton

Skeleton loading primitives — shimmering placeholders used internally by PersonaMessageFeed, PersonaSidebar, and PersonaFilesDrawer when isLoading is true.
These are internal components — you’re unlikely to need them directly unless you’re building a custom loading state that matches the widget’s visual style.

Custom tool renderers

Pass a toolRenderers map to render specific tools with your own component:
The renderer receives parsed args and result (if available), plus isExecuting (true while the tool is still running) and isError (true if the tool returned an error).

usePersonaChatWidget

The behavioral hook that PersonaChatView is built on — every stateful piece (thread selection, lazy creation, sidebar/drawer state, present_file auto-open) extracted into its own hook. PersonaChatView is just one layout built on top of it.

Options

When to use

Use usePersonaChatWidget when you’re building a completely custom layout (not PersonaChatView) but want the same behavior wiring — thread management, lazy creation, sidebar state, present_file auto-open — without reimplementing it against the raw useChat/useThreads hooks.

Return value

Returns every field from useChat plus:
  • activeThreadId, setActiveThread — thread selection
  • sidebarOpen, setSidebarOpen — sidebar state
  • filesDrawerOpen, setFilesDrawerOpen — drawer state
  • threads, deleteThread, renameThread, threadsLoading — thread management
  • files, deleteFile, filesLoading — uploaded files
  • memory, getMemoryFile, deleteMemoryFile, memoryLoading — memory
  • workspaceFiles — agent workspace files (renamed from useChat’s files to avoid collision)
  • handleSelectThread, handleNewChat, handleSend, handleUploadFile — composed handlers

Name collision

useFiles() and useChat() both name their very different files field the same thing. The hook exposes them as files (uploads) and workspaceFiles (agent workspace) respectively.