logoassistant-ui
API ReferenceRadix UI Primitives

ContentPartPrimitive

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

Content 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 { ContentPartPrimitive } from "@assistant-ui/react";
 
const TextContentPart = () => {
  return <ContentPartPrimitive.Text />;
};

Primitives

Plain Text

import { ContentPartPrimitive } from "@assistant/react";
 
<ContentPartPrimitive.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 content part is in progress.

import { ContentPartPrimitive } from "@assistant/react";
 
<ContentPartPrimitive.InProgress>
  <LoadingIndicator />
</ContentPartPrimitive.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

Content part context is provided by MessagePrimitive.Content or TextContentPartProvider

MessagePrimitive.Content

import { MessagePrimitive } from "@assistant/react";
 
<MessagePrimitive.Content
  components={{
    Text: MyText,
    Reasoning: MyReasoning,
    Audio: MyAudio,
    tools: {
      by_name: {
        get_weather: MyWeatherToolUI,
      },
      Fallback: MyFallbackToolUI,
    },
  }}
/>;

TextContentPartProvider

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

import { TextContentPartProvider } from "@assistant-ui/react";
 
<TextContentPartProvider text="Hello world" isRunning={false}>
  <ContentPart.Text />
</TextContentPartProvider>;

Runtime API

useContentPartRuntime

import { useContentPartRuntime } from "@assistant-ui/react";
 
const contentPartRuntime = useContentPartRuntime();

ContentPartRuntime

addToolResult:

(result: any) => void

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

path:

ContentPartRuntimePath

getState:

() => ContentPartState

subscribe:

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

useContentPart

import { useContentPart } from "@assistant-ui/react";
 
const contentPart = useContentPart();

TextContentPartState

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"; }

AudioContentPartState

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"; }

ToolCallContentPartState

type:

"tool-call"

toolCallId:

string

toolName:

string

args:

ReadonlyJSONObject

result?:

unknown

isError?:

boolean | undefined

argsText:

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"; }

useContentPartText

import { useContentPartText } from "@assistant-ui/react";
 
const contentPartText = useContentPartText();

TextContentPartState

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"; }

On this page

Edit on Github