Skip to content
EspañolEnglish
All components (204)

Chat message

AI · ChatMessage

What it is and when to use it

A message in a chat with an assistant: the bubble, who says it, its footer and the usual actions -copy, regenerate, edit-.

When to use it

  • In the conversation with an assistant, one per turn, from the user and from the response.
  • With whatever content you want: text, markdown already rendered, a code block, a tool call.

When not to

  • For a thread between people (support, comments on an order): that is a Conversation.
  • For a system notice outside the thread: that is an Alert.

Keyboard: the actions are buttons and appear on hover or when focus is inside; on a touch screen they are always in view. Only the ones asked for exist (copyText, onRegenerate, onEdit), plus yours in actions (cancel, retry, save as template): they are grouped with the rest and appear the same way. actionsVisibility="always" keeps them always in view.

Editing in place: with editor the content is replaced by an editor (a TextArea with save and cancel) inside the same bubble, which becomes neutral and takes the full width; the actions hide while it lasts. Match of a search: highlighted marks the message with a fixed ring -not an animation, which would be lost with reduced motion- and announces it; whoever searches brings it into view and turns it off after a few seconds.

Accessibility: each message is an article named after who says it, "You" or "Assistant" (or the author that is passed); the avatar is decorative. While it is being written it is marked busy and says "Writing". The error is marked with data-tone and a border, not just with colour. Copying is announced with a status region.

Fine-tuning: CSS variables --amset-chat-message-max (maximum width of the bubble), -gap, -bubble, -ink and -border. Markdown is not interpreted here: whoever uses the component renders it.

What it looks like

Orders assistant
october-statement.csv18.4 kB

Which orders are pending this week?

listar_pedidos: Done

You have three pending orders: #1042, #1043 and #1047. The last one has an unreviewed payment.

<ChatMessage from="user" copyText={pregunta}>
  <Attachment name="october-statement.csv" size={18_400} status="done" compact />
  <p>{pregunta}</p>
</ChatMessage>

<ChatMessage
  from="assistant"
  avatar={<Avatar name="AMSET" size="sm" />}
  streaming={escribiendo}
  copyText={respuesta}
  onRegenerate={regenerar}
  meta={<UsageBadge tokens={1234} cost={0.03} />}
>
  <Reasoning durationMs={4200}>First I look at this week's orders…</Reasoning>
  <ToolCall name="listar_pedidos" status="success" input={consulta} output="3 orders" durationMs={850} />
  <p>{respuesta}</p>
</ChatMessage>

<Suggestions groups={sugerencias} onSelect={(respuestas) => enviar(respuestas[0].option)} />
<PromptInput label="Message to the assistant" busy={ocupado} onStop={parar} onSubmit={enviar} onFiles={adjuntar} />

Props

Import it with import { ChatMessage } from '@amset/ui'. Required props are marked.

PropTypeWhat it does
childrenrequiredReactNodeThe content. Markdown is not interpreted here: whatever arrives is painted.
fromrequiredChatMessageFromWho writes it. It decides the side, the colour and the name a reader hears.
actionsReactNodeMore actions, after the usual ones: cancel, retry, save as template, automate. They are yours: an `IconButton` with its `aria-label`. They are grouped with copy, regenerate and edit and appear the same way.
actionsVisibilityChatMessageActionsVisibilityWhen the actions are visible. By default on hover or when focus is inside; with a finger, always.
authorstringWhat the writer is called. Defaults to "You" or "Assistant".
avatarReactNodeTheir photo or orb. It is decorative: the author is said with text.
classNamestringMerged with the library classes; it does not replace them.
copyTextstringThe text that gets copied. With this the copy button appears.
editorReactNodeThe message is being edited: the editor goes here (a `TextArea` with save and cancel) INSTEAD of the content, inside the same bubble, without moving the message. The actions hide while it lasts.
highlightedbooleanIt is the match of a search: it is marked for a moment and announced. Whoever searches brings the message into view (`scrollIntoView` or `scrollTop`) and sets this to `true` for a few seconds.
metaReactNodeBelow: the time, the tokens, the engine.
onEdit() => voidWith this "Edit message" appears.
onRegenerate() => voidWith this "Regenerate response" appears.
streamingbooleanStill being written: it carries a cursor at the end and is marked busy.
toneChatMessageTone—

It also accepts the attributes of the element it renders: className, style, data-*, aria-* and its events.

In the test bench

Every state and variant, to try one at a time, on its page at ui.amset.tech: