Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
118 changes: 118 additions & 0 deletions .agents/skills/assistant-ui/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
---
name: assistant-ui
description: Guide for assistant-ui library - AI chat UI components. Use when asking about architecture, debugging, or understanding the codebase.
version: 0.0.1
license: MIT
---

# assistant-ui

**Always consult [assistant-ui.com/llms.txt](https://assistant-ui.com/llms.txt) for latest API.**

React library for building AI chat interfaces with composable primitives.

## References

- [./references/architecture.md](./references/architecture.md) -- Core architecture and layered system
- [./references/packages.md](./references/packages.md) -- Package overview and selection guide

## When to Use

| Use Case | Best For |
|----------|----------|
| Chat UI from scratch | Full control over UX |
| Existing AI backend | Connects to any streaming backend |
| Custom message types | Tools, images, files, custom parts |
| Multi-thread apps | Built-in thread list management |
| Production apps | Cloud persistence, auth, analytics |

## Architecture

```
┌─────────────────────────────────────────────────────────┐
│ UI Components (Primitives) │
│ ThreadPrimitive, MessagePrimitive, ComposerPrimitive │
└─────────────────────────┬───────────────────────────────┘
┌─────────────────────────▼───────────────────────────────┐
│ Context Hooks │
│ useAui, useAuiState, useAuiEvent │
└─────────────────────────┬───────────────────────────────┘
┌─────────────────────────▼───────────────────────────────┐
│ Runtime Layer │
│ AssistantRuntime → ThreadRuntime → MessageRuntime │
└─────────────────────────┬───────────────────────────────┘
┌─────────────────────────▼───────────────────────────────┐
│ Adapters/Backend │
│ AI SDK · LangGraph · Custom · Cloud Persistence │
└─────────────────────────────────────────────────────────┘
```

## Pick a Runtime

```
Using AI SDK?
├─ Yes → useChatRuntime (recommended)
└─ No
├─ External state (Redux/Zustand)? → useExternalStoreRuntime
├─ LangGraph agent? → useLangGraphRuntime
├─ AG-UI protocol? → useAgUiRuntime
├─ A2A protocol? → useA2ARuntime
└─ Custom API → useLocalRuntime
```

## Core Packages

| Package | Purpose |
|---------|---------|
| `@assistant-ui/react` | UI primitives & hooks |
| `@assistant-ui/react-ai-sdk` | Vercel AI SDK v6 adapter |
| `@assistant-ui/react-langgraph` | LangGraph adapter |
| `@assistant-ui/react-markdown` | Markdown rendering |
| `assistant-stream` | Streaming protocol |
| `assistant-cloud` | Cloud persistence |

## Quick Start

```tsx
import { AssistantRuntimeProvider } from "@assistant-ui/react";
import { Thread } from "@/components/assistant-ui/thread";
import { useChatRuntime, AssistantChatTransport } from "@assistant-ui/react-ai-sdk";

function App() {
const runtime = useChatRuntime({
transport: new AssistantChatTransport({ api: "/api/chat" }),
});
return (
<AssistantRuntimeProvider runtime={runtime}>
<Thread />
</AssistantRuntimeProvider>
);
}
```

## State Access

```tsx
import { useAui, useAuiState } from "@assistant-ui/react";

const api = useAui();
api.thread().append({ role: "user", content: [{ type: "text", text: "Hi" }] });
api.thread().cancelRun();

const messages = useAuiState(s => s.thread.messages);
const isRunning = useAuiState(s => s.thread.isRunning);
```

## Related Skills

- `/setup` - Installation and configuration
- `/primitives` - UI component customization
- `/runtime` - State management deep dive
- `/tools` - Tool registration and UI
- `/streaming` - Streaming protocols
- `/cloud` - Persistence and auth
- `/thread-list` - Multi-thread management
- `/update` - Version updates and migrations
175 changes: 175 additions & 0 deletions .agents/skills/assistant-ui/references/architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
# assistant-ui Architecture

## Layered System

assistant-ui follows a 4-layer architecture where each layer depends only on layers below it.

### Layer 1: RuntimeCore (Internal)

Internal implementations that manage state:

- `LocalRuntimeCore` - In-browser state
- `ExternalStoreRuntimeCore` - External state sync
- `ThreadListRuntimeCore` - Thread management

```typescript
// Internal - not directly used
interface ThreadRuntimeCore {
readonly messages: readonly ThreadMessage[];
readonly isRunning: boolean;
append(message: AppendMessage): void;
cancelRun(): void;
subscribe(callback: () => void): Unsubscribe;
}
```

### Layer 2: Runtime (Public API)

Public API exposed via hooks:

```typescript
type AssistantRuntime = {
thread(): ThreadRuntime;
threads(): ThreadListRuntime;
getState(): AssistantState;
subscribe(callback: () => void): Unsubscribe;
};

type ThreadRuntime = {
getState(): ThreadState;
append(message: AppendMessage): void;
cancelRun(): void;
message(index: number): MessageRuntime;
composer(): ComposerRuntime;
};

type MessageRuntime = {
getState(): MessageState;
edit(message: EditMessage): void;
reload(): void;
part(index: number): MessagePartRuntime;
};
```

### Layer 3: Context Hooks

React hooks for accessing runtime:

```tsx
// Modern API (recommended)
import { useAui, useAuiState, useAuiEvent } from "@assistant-ui/react";

// Get API for imperative actions
const api = useAui();

// Subscribe to state changes
const messages = useAuiState(s => s.thread.messages);

// Listen to events
useAuiEvent("composer.send", (e) => console.log(e));
```

### Layer 4: Primitives (UI)

Composable UI components:

```tsx
import {
ThreadPrimitive,
ComposerPrimitive,
MessagePrimitive,
ActionBarPrimitive,
} from "@assistant-ui/react";
```

## Data Flow

```
User Action (send message)
Primitive captures event
Calls runtime API (thread.append)
RuntimeCore processes action
State updates
Subscribers notified
Primitives re-render with new state
```

## Message Model

```typescript
type ThreadMessage =
| ThreadUserMessage
| ThreadAssistantMessage
| ThreadSystemMessage;

interface ThreadUserMessage {
id: string;
role: "user";
content: MessagePart[];
attachments?: Attachment[];
createdAt: Date;
}

interface ThreadAssistantMessage {
id: string;
role: "assistant";
content: MessagePart[];
status: "running" | "complete" | "incomplete" | "requires-action";
createdAt: Date;
}

type MessagePart =
| { type: "text"; text: string }
| { type: "image"; image: string }
| {
type: "tool-call";
toolCallId: string;
toolName: string;
args: unknown;
argsText: string;
result?: unknown;
isError?: boolean;
artifact?: unknown;
}
| { type: "reasoning"; text: string }
| {
type: "source";
sourceType: "url";
id: string;
url: string;
title?: string;
}
| {
type: "file";
filename?: string;
data: string;
mimeType: string;
};
```

## Branching Model

Messages form a tree structure supporting edits:

```
User: "Hello"
└─ Assistant: "Hi there!"
└─ User: "Tell me a joke" ← Current branch
└─ Assistant: "Why did..."
└─ User: "Tell me a fact" (edit) ← Alternative branch
└─ Assistant: "The sun..."
```

Navigate branches with `BranchPickerPrimitive` or runtime API.
Loading
Loading