logoassistant-ui
API Reference/Radix UI Primitives

MessagePartPrimitive

Each message can have any number of message parts.
Message parts are usually one of text, reasoning, audio or tool-call.

Message part Types

Text

Standard text content, used for both user and assistant messages.

Reasoning

Exposes the assistant's reasoning process, showing how it arrived at its responses. This is typically used only in assistant messages.

Audio

Audio content that can be played back.

Tool Call

Interactive elements that represent tool operations.

Anatomy

import { MessagePartPrimitive } from "@assistant-ui/react";

const TextMessagePart = () => {
  return <MessagePartPrimitive.Text />;
};

Primitives

Plain Text

import { MessagePartPrimitive } from "@assistant/react";

<MessagePartPrimitive.Text />;

Markdown Text

Renders the message's text as Markdown.

import { MarkdownTextPrimitive } from "@assistant-ui/react-markdown";

<MarkdownTextPrimitive />;

Audio

Coming soon.

InProgress

Renders children only if the message part is in progress.

import { MessagePartPrimitive } from "@assistant/react";

<MessagePartPrimitive.InProgress>
  <LoadingIndicator />
</MessagePartPrimitive.InProgress>;

Tool UI

You can map tool calls to UI components. We provide a few utility functions to make this easier, such as makeAssistantToolUI.

const MyWeatherToolUI = makeAssistantToolUI({
  toolName: "get_weather",
  render: function MyWeatherToolUI({ args, result }) {
    return (
      <div className="mb-4 flex flex-col items-center">
        <pre className="whitespace-pre-wrap break-all text-center">
          get_weather({JSON.stringify(args)})
        </pre>
        {"result" in result && (
          <pre className="whitespace-pre-wrap break-all text-center">
            {JSON.stringify(result.result)}
          </pre>
        )}
      </div>
    );
  },
});

Context Provider

Message part context is provided by MessagePrimitive.Parts or TextMessagePartProvider

MessagePrimitive.Parts

import { MessagePrimitive } from "@assistant/react";

<MessagePrimitive.Parts
  components={{
    Text: MyText,
    Reasoning: MyReasoning,
    Audio: MyAudio,
    tools: {
      by_name: {
        get_weather: MyWeatherToolUI,
      },
      Fallback: MyFallbackToolUI,
    },
  }}
/>;

TextMessagePartProvider

This is a helper context provider to allow you to reuse the message part components outside a message message part.

import { TextMessagePartProvider } from "@assistant-ui/react";

<TextMessagePartProvider text="Hello world" isRunning={false}>
  <MessagePart.Text />
</TextMessagePartProvider>;

Runtime API

useMessagePartRuntime

import { useMessagePartRuntime } from "@assistant-ui/react";

const MessagePartRuntime = useMessagePartRuntime();

MessagePartRuntime

addToolResult:

(result: any) => void

Add tool result to a tool call message part that has no tool result yet. This is useful when you are collecting a tool result via user input ("human tool calls").

path:

MessagePartRuntimePath

getState:

() => MessagePartState

subscribe:

(callback: () => void) => Unsubscribe

useMessagePart

import { useMessagePart } from "@assistant-ui/react";

const MessagePart = useMessagePart();

TextMessagePartState

type:

"text"

text:

string

status:

{ readonly type: "running"; } | { readonly type: "complete"; } | { readonly type: "incomplete"; readonly reason: "length" | "cancelled" | "content-filter" | "other" | "error"; readonly error?: unknown; } | { readonly type: "requires-action"; readonly reason: "tool-calls"; }

AudioMessagePartState

type:

"audio"

audio:

{ readonly data: string; readonly format: "mp3" | "wav"; }

status:

{ readonly type: "running"; } | { readonly type: "complete"; } | { readonly type: "incomplete"; readonly reason: "length" | "cancelled" | "content-filter" | "other" | "error"; readonly error?: unknown; } | { readonly type: "requires-action"; readonly reason: "tool-calls"; }

ToolCallMessagePartState

type:

"tool-call"

toolCallId:

string

toolName:

string

args:

ReadonlyJSONObject

result?:

unknown

isError?:

boolean | undefined

argsText:

string

artifact?:

unknown

status:

{ readonly type: "running"; } | { readonly type: "complete"; } | { readonly type: "incomplete"; readonly reason: "length" | "cancelled" | "content-filter" | "other" | "error"; readonly error?: unknown; } | { readonly type: "requires-action"; readonly reason: "tool-calls"; }

useMessagePartText

import { useMessagePartText } from "@assistant-ui/react";

const MessagePartText = useMessagePartText();

TextMessagePartState

type:

"text"

text:

string

status:

{ readonly type: "running"; } | { readonly type: "complete"; } | { readonly type: "incomplete"; readonly reason: "length" | "cancelled" | "content-filter" | "other" | "error"; readonly error?: unknown; } | { readonly type: "requires-action"; readonly reason: "tool-calls"; }