Components/AI Elements

AI Elements

Conversation and message primitives for AI chat surfaces.

VerifiedSince 0.3.9

Usage

Basic

showAvatar adds an avatar column; without avatar, it shows the name's initial.

Loading demo...

Best Practices

  • Keep provider-specific streaming state in the host and map it into status.
  • Use stable ids from the conversation store, not array indexes.
  • Keep markdown on for assistant output; sanitize untrusted Markdown at the data boundary.
  • Describe reasoning, tool calls, attachments, and sources with parts instead of custom HTML in content.

API Reference

TxAiConversation

Props

PropTypeDefaultDescription
messagesAiElementMessage[]requiredTranscript data, rendered in order.
markdownbooleantrueRenders bodies through TxMarkdownView.
compactbooleanfalseTightens message spacing.
emptyTextstring'No messages yet'Empty-state copy when no message is renderable.
showAvatarbooleanfalseShows an avatar column for every message.
typingLabelstring-Forwarded to each message: accessible name of the typing indicator.

Events

EventParamsDescription
open-source(source: AiSourceItem)Re-emitted from the message whose source was clicked.

Slots

SlotPropsDescription
empty-Replaces the built-in empty state.
default / avatar / markdown-renderer / tool-resultSame as TxAiMessageForwarded to every TxAiMessage.

TxAiMessage

Props

PropTypeDefaultDescription
messageAiElementMessagerequiredThe message to render.
markdownbooleantrueRenders the body through TxMarkdownView; false keeps plain text with its line breaks.
compactbooleanfalseCompact row density and a smaller avatar.
showAvatarbooleanfalseShows the avatar.
typingLabelstring'AI is typing'Accessible name of the typing indicator.

Events

EventParamsDescription
open-source(source: AiSourceItem)Fires when a source in a sources part is clicked; navigation is prevented.

Slots

SlotPropsDescription
default{ message }Replaces the content region; for tool cards, attachments, or custom renderers.
avatar{ message }Replaces the avatar when showAvatar is on.
markdown-renderer{ part, message, streaming }Replaces a text part's rendering; streaming is true only for the last text part of a streaming message.
tool-result{ part }Replaces the result area of a tool-call part once it is done.

Types

AiElementMessage

FieldTypeDefaultDescription
idstringrequiredStable key.
role'user' | 'assistant' | 'system' | 'tool'requiredVisual and semantic role.
contentstringrequiredText or Markdown source.
createdAtnumber | string | Date-The host's timestamp.
namestring-Display name; falls back to You / AI / Tool / System.
avatarstring-Avatar image URL.
status'pending' | 'streaming' | 'complete' | 'error'-Message lifecycle state.
partsAiMessagePart[]-When non-empty, these parts render in order instead of content.

AiMessagePart

EXAMPLE.TS
type AiMessagePart =
  | { type: 'text', text: string } // markdown-renderer slot or TxMarkdownView
  | { type: 'reasoning', text: string, done?: boolean, durationMs?: number } // TxReasoningDisclosure
  | AiToolCallPart // type: 'tool-call', rendered by TxToolCallCard
  | { type: 'attachment', attachments: AiAttachment[] } // read-only TxAttachmentTray
  | { type: 'sources', sources: AiSourceItem[] } // TxSources

Overview

  • A message with empty content is not rendered unless it has parts or its status is pending or streaming.
  • Such an empty message without parts shows a typing indicator.
  • TxAiConversation is an aria-live="polite" region: appended messages are announced without stealing focus.

Technologies

  • Source: packages/tuffex/packages/components/src/ai-elements/.
查看源码
packages/tuffex/packages/components/src/ai-elements/index.ts