@assistant-ui/mcp-docs-server 0.1.23 → 0.1.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.docs/organized/code-examples/waterfall.md +5 -3
- package/.docs/organized/code-examples/with-a2a.md +676 -0
- package/.docs/organized/code-examples/with-ag-ui.md +7 -8
- package/.docs/organized/code-examples/with-ai-sdk-v6.md +28 -16
- package/.docs/organized/code-examples/with-artifacts.md +5 -5
- package/.docs/organized/code-examples/with-assistant-transport.md +3 -3
- package/.docs/organized/code-examples/with-chain-of-thought.md +34 -26
- package/.docs/organized/code-examples/with-cloud-standalone.md +10 -8
- package/.docs/organized/code-examples/with-cloud.md +5 -5
- package/.docs/organized/code-examples/with-custom-thread-list.md +7 -7
- package/.docs/organized/code-examples/with-elevenlabs-scribe.md +8 -8
- package/.docs/organized/code-examples/with-expo.md +571 -539
- package/.docs/organized/code-examples/with-external-store.md +3 -4
- package/.docs/organized/code-examples/with-ffmpeg.md +5 -5
- package/.docs/organized/code-examples/with-google-adk.md +353 -0
- package/.docs/organized/code-examples/with-heat-graph.md +304 -0
- package/.docs/organized/code-examples/with-langgraph.md +25 -23
- package/.docs/organized/code-examples/with-parent-id-grouping.md +4 -4
- package/.docs/organized/code-examples/with-react-hook-form.md +6 -9
- package/.docs/organized/code-examples/with-react-ink.md +265 -0
- package/.docs/organized/code-examples/with-react-router.md +10 -11
- package/.docs/organized/code-examples/with-store.md +29 -18
- package/.docs/organized/code-examples/with-tanstack.md +7 -7
- package/.docs/organized/code-examples/with-tap-runtime.md +6 -4
- package/.docs/raw/blog/2025-01-31-changelog/index.mdx +1 -1
- package/.docs/raw/blog/2026-03-launch-week/index.mdx +227 -0
- package/.docs/raw/docs/(docs)/architecture.mdx +1 -1
- package/.docs/raw/docs/(docs)/cli.mdx +14 -9
- package/.docs/raw/docs/(docs)/copilots/make-assistant-tool-ui.mdx +8 -3
- package/.docs/raw/docs/(docs)/copilots/make-assistant-tool.mdx +5 -1
- package/.docs/raw/docs/(docs)/copilots/{make-assistant-readable.mdx → make-assistant-visible.mdx} +14 -5
- package/.docs/raw/docs/(docs)/copilots/model-context.mdx +11 -11
- package/.docs/raw/docs/(docs)/copilots/motivation.mdx +2 -2
- package/.docs/raw/docs/(docs)/devtools.mdx +3 -2
- package/.docs/raw/docs/(docs)/guides/attachments.mdx +9 -11
- package/.docs/raw/docs/(docs)/guides/branching.mdx +11 -6
- package/.docs/raw/docs/(docs)/guides/chain-of-thought.mdx +18 -16
- package/.docs/raw/docs/(docs)/guides/context-api.mdx +81 -43
- package/.docs/raw/docs/(docs)/guides/dictation.mdx +5 -5
- package/.docs/raw/docs/(docs)/guides/editing.mdx +16 -7
- package/.docs/raw/docs/(docs)/guides/latex.mdx +3 -0
- package/.docs/raw/docs/(docs)/guides/message-timing.mdx +2 -1
- package/.docs/raw/docs/(docs)/guides/multi-agent.mdx +173 -0
- package/.docs/raw/docs/(docs)/guides/quoting.mdx +55 -206
- package/.docs/raw/docs/(docs)/guides/speech.mdx +1 -4
- package/.docs/raw/docs/(docs)/guides/suggestions.mdx +9 -15
- package/.docs/raw/docs/(docs)/guides/tool-ui.mdx +17 -7
- package/.docs/raw/docs/(docs)/guides/tools.mdx +24 -9
- package/.docs/raw/docs/(docs)/index.mdx +3 -3
- package/.docs/raw/docs/(docs)/installation.mdx +69 -46
- package/.docs/raw/docs/(reference)/api-reference/context-providers/text-message-part-provider.mdx +20 -6
- package/.docs/raw/docs/(reference)/api-reference/integrations/react-data-stream.mdx +24 -4
- package/.docs/raw/docs/(reference)/api-reference/integrations/react-hook-form.mdx +1 -1
- package/.docs/raw/docs/(reference)/api-reference/integrations/vercel-ai-sdk.mdx +20 -19
- package/.docs/raw/docs/(reference)/api-reference/overview.mdx +28 -53
- package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar.mdx +4 -4
- package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-modal.mdx +7 -1
- package/.docs/raw/docs/(reference)/api-reference/primitives/attachment.mdx +20 -14
- package/.docs/raw/docs/(reference)/api-reference/primitives/branch-picker.mdx +1 -1
- package/.docs/raw/docs/(reference)/api-reference/primitives/composer.mdx +99 -45
- package/.docs/raw/docs/(reference)/api-reference/primitives/message-part.mdx +52 -40
- package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +343 -23
- package/.docs/raw/docs/(reference)/api-reference/primitives/suggestion.mdx +4 -6
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list-item.mdx +4 -2
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list.mdx +3 -5
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread.mdx +169 -22
- package/.docs/raw/docs/(reference)/api-reference/runtimes/assistant-runtime.mdx +14 -4
- package/.docs/raw/docs/(reference)/api-reference/runtimes/attachment-runtime.mdx +15 -26
- package/.docs/raw/docs/(reference)/api-reference/runtimes/composer-runtime.mdx +39 -21
- package/.docs/raw/docs/(reference)/api-reference/runtimes/message-part-runtime.mdx +33 -9
- package/.docs/raw/docs/(reference)/api-reference/runtimes/message-runtime.mdx +48 -21
- package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-item-runtime.mdx +36 -7
- package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-runtime.mdx +30 -10
- package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-runtime.mdx +12 -10
- package/.docs/raw/docs/(reference)/migrations/deprecation-policy.mdx +1 -1
- package/.docs/raw/docs/(reference)/migrations/react-langgraph-v0-7.mdx +9 -4
- package/.docs/raw/docs/(reference)/migrations/v0-11.mdx +7 -5
- package/.docs/raw/docs/(reference)/migrations/v0-12.mdx +9 -7
- package/.docs/raw/docs/(reference)/migrations/v0-14.mdx +159 -0
- package/.docs/raw/docs/(reference)/react-compatibility.mdx +5 -134
- package/.docs/raw/docs/cloud/ai-sdk-assistant-ui.mdx +89 -7
- package/.docs/raw/docs/cloud/ai-sdk.mdx +19 -5
- package/.docs/raw/docs/cloud/langgraph.mdx +13 -3
- package/.docs/raw/docs/ink/adapters.mdx +41 -0
- package/.docs/raw/docs/ink/custom-backend.mdx +203 -0
- package/.docs/raw/docs/ink/hooks.mdx +448 -0
- package/.docs/raw/docs/ink/index.mdx +239 -0
- package/.docs/raw/docs/ink/migration.mdx +140 -0
- package/.docs/raw/docs/ink/primitives.mdx +699 -0
- package/.docs/raw/docs/react-native/adapters.mdx +63 -87
- package/.docs/raw/docs/react-native/custom-backend.mdx +11 -14
- package/.docs/raw/docs/react-native/hooks.mdx +214 -232
- package/.docs/raw/docs/react-native/index.mdx +118 -159
- package/.docs/raw/docs/react-native/migration.mdx +144 -0
- package/.docs/raw/docs/react-native/primitives.mdx +431 -302
- package/.docs/raw/docs/runtimes/a2a/index.mdx +294 -0
- package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +9 -9
- package/.docs/raw/docs/runtimes/ai-sdk/v5-legacy.mdx +14 -3
- package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +53 -0
- package/.docs/raw/docs/runtimes/assistant-transport.mdx +59 -25
- package/.docs/raw/docs/runtimes/custom/custom-thread-list.mdx +13 -6
- package/.docs/raw/docs/runtimes/custom/external-store.mdx +138 -38
- package/.docs/raw/docs/runtimes/custom/local.mdx +184 -42
- package/.docs/raw/docs/runtimes/data-stream.mdx +92 -19
- package/.docs/raw/docs/runtimes/google-adk/index.mdx +624 -0
- package/.docs/raw/docs/runtimes/helicone.mdx +6 -6
- package/.docs/raw/docs/runtimes/langgraph/index.mdx +38 -27
- package/.docs/raw/docs/runtimes/langgraph/tutorial/introduction.mdx +1 -1
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-1.mdx +15 -20
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +7 -11
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-3.mdx +8 -11
- package/.docs/raw/docs/runtimes/langserve.mdx +6 -7
- package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +18 -3
- package/.docs/raw/docs/ui/context-display.mdx +147 -0
- package/.docs/raw/docs/ui/file.mdx +5 -4
- package/.docs/raw/docs/ui/image.mdx +5 -4
- package/.docs/raw/docs/ui/markdown.mdx +3 -1
- package/.docs/raw/docs/ui/model-selector.mdx +8 -8
- package/.docs/raw/docs/ui/part-grouping.mdx +7 -10
- package/.docs/raw/docs/ui/quote.mdx +210 -0
- package/.docs/raw/docs/ui/reasoning.mdx +12 -11
- package/.docs/raw/docs/ui/sources.mdx +88 -17
- package/.docs/raw/docs/ui/streamdown.mdx +16 -7
- package/.docs/raw/docs/ui/thread-list.mdx +11 -13
- package/.docs/raw/docs/ui/thread.mdx +28 -33
- package/.docs/raw/docs/ui/tool-fallback.mdx +5 -6
- package/.docs/raw/docs/ui/tool-group.mdx +9 -8
- package/.docs/raw/docs/utilities/heat-graph.mdx +236 -0
- package/.docs/raw/docs/utilities/tw-shimmer.mdx +211 -0
- package/package.json +4 -4
- package/.docs/raw/docs/(reference)/legacy/styled/assistant-modal.mdx +0 -77
- package/.docs/raw/docs/(reference)/legacy/styled/decomposition.mdx +0 -635
- package/.docs/raw/docs/(reference)/legacy/styled/markdown.mdx +0 -77
- package/.docs/raw/docs/(reference)/legacy/styled/scrollbar.mdx +0 -72
- package/.docs/raw/docs/(reference)/legacy/styled/thread-width.mdx +0 -22
- package/.docs/raw/docs/(reference)/legacy/styled/thread.mdx +0 -77
- /package/.docs/raw/docs/cloud/{overview.mdx → index.mdx} +0 -0
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Hooks
|
|
3
|
+
description: Reactive hooks for accessing runtime state in React Ink.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## State Hooks
|
|
7
|
+
|
|
8
|
+
### useAuiState
|
|
9
|
+
|
|
10
|
+
The primary hook for accessing reactive state. It accepts a selector function for fine-grained re-renders — the component only re-renders when the selected value changes (shallow equality).
|
|
11
|
+
|
|
12
|
+
```tsx
|
|
13
|
+
import { useAuiState } from "@assistant-ui/react-ink";
|
|
14
|
+
|
|
15
|
+
// Thread state
|
|
16
|
+
const messages = useAuiState((s) => s.thread.messages);
|
|
17
|
+
const isRunning = useAuiState((s) => s.thread.isRunning);
|
|
18
|
+
const isEmpty = useAuiState((s) => s.thread.isEmpty);
|
|
19
|
+
|
|
20
|
+
// Composer state
|
|
21
|
+
const text = useAuiState((s) => s.composer.text);
|
|
22
|
+
const composerIsEmpty = useAuiState((s) => s.composer.isEmpty);
|
|
23
|
+
const attachments = useAuiState((s) => s.composer.attachments);
|
|
24
|
+
|
|
25
|
+
// Message state (inside a message context)
|
|
26
|
+
const role = useAuiState((s) => s.message.role);
|
|
27
|
+
const isLast = useAuiState((s) => s.message.isLast);
|
|
28
|
+
|
|
29
|
+
// Thread list item state
|
|
30
|
+
const threadId = useAuiState((s) => s.threadListItem.id);
|
|
31
|
+
const title = useAuiState((s) => s.threadListItem.title);
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### useAui
|
|
35
|
+
|
|
36
|
+
Access the store methods for imperative actions.
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
import { useAui } from "@assistant-ui/react-ink";
|
|
40
|
+
|
|
41
|
+
const aui = useAui();
|
|
42
|
+
|
|
43
|
+
// Composer actions
|
|
44
|
+
aui.composer().setText("Hello");
|
|
45
|
+
aui.composer().send();
|
|
46
|
+
|
|
47
|
+
// Thread actions
|
|
48
|
+
aui.thread().cancelRun();
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### useAuiEvent
|
|
52
|
+
|
|
53
|
+
Subscribe to events without causing re-renders.
|
|
54
|
+
|
|
55
|
+
```tsx
|
|
56
|
+
import { useAuiEvent } from "@assistant-ui/react-ink";
|
|
57
|
+
|
|
58
|
+
useAuiEvent("thread.runStart", (payload) => {
|
|
59
|
+
console.log("Run started:", payload);
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Runtime Hooks
|
|
64
|
+
|
|
65
|
+
### useLocalRuntime
|
|
66
|
+
|
|
67
|
+
Create an `AssistantRuntime` with a `ChatModelAdapter`.
|
|
68
|
+
|
|
69
|
+
```tsx
|
|
70
|
+
import { useLocalRuntime } from "@assistant-ui/react-ink";
|
|
71
|
+
|
|
72
|
+
const runtime = useLocalRuntime(chatModel, {
|
|
73
|
+
initialMessages: [],
|
|
74
|
+
});
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
| Option | Type | Description |
|
|
78
|
+
|--------|------|-------------|
|
|
79
|
+
| `initialMessages` | `ThreadMessageLike[]` | Messages to pre-populate the thread with |
|
|
80
|
+
| `maxSteps` | `number` | Maximum number of agentic steps before stopping |
|
|
81
|
+
| `adapters.history` | `ThreadHistoryAdapter` | Adapter for persisting thread history |
|
|
82
|
+
| `adapters.attachments` | `AttachmentAdapter` | Adapter for handling file attachments |
|
|
83
|
+
| `adapters.speech` | `SpeechSynthesisAdapter` | Adapter for text-to-speech output |
|
|
84
|
+
| `adapters.dictation` | `DictationAdapter` | Adapter for speech-to-text input |
|
|
85
|
+
| `adapters.feedback` | `FeedbackAdapter` | Adapter for message feedback (thumbs up/down) |
|
|
86
|
+
| `adapters.suggestion` | `SuggestionAdapter` | Adapter for suggested prompts |
|
|
87
|
+
| `cloud` | `AssistantCloud` | Cloud instance for thread persistence via `@assistant-ui/cloud` |
|
|
88
|
+
| `unstable_humanToolNames` | `string[]` | Tool names that trigger a run interruption to wait for human/external approval |
|
|
89
|
+
|
|
90
|
+
### useRemoteThreadListRuntime
|
|
91
|
+
|
|
92
|
+
Create an `AssistantRuntime` backed by a `RemoteThreadListAdapter` for multi-thread persistence. The `runtimeHook` is called for each thread to produce the per-thread runtime (typically `useLocalRuntime`).
|
|
93
|
+
|
|
94
|
+
```tsx
|
|
95
|
+
import { useRemoteThreadListRuntime, useLocalRuntime } from "@assistant-ui/react-ink";
|
|
96
|
+
|
|
97
|
+
const runtime = useRemoteThreadListRuntime({
|
|
98
|
+
adapter: myRemoteAdapter,
|
|
99
|
+
runtimeHook: () => useLocalRuntime(chatModel),
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
| Option | Type | Description |
|
|
104
|
+
|--------|------|-------------|
|
|
105
|
+
| `runtimeHook` | `() => AssistantRuntime` | Hook called to produce the per-thread runtime |
|
|
106
|
+
| `adapter` | `RemoteThreadListAdapter` | Adapter implementing thread list persistence |
|
|
107
|
+
| `allowNesting` | `boolean` | When true, becomes a no-op if nested inside another `RemoteThreadListRuntime` |
|
|
108
|
+
|
|
109
|
+
## Model Context Hooks
|
|
110
|
+
|
|
111
|
+
### useAssistantTool
|
|
112
|
+
|
|
113
|
+
Register a tool with an optional UI renderer. The tool definition is forwarded to the model, and when the model calls it, the `execute` function runs and the `render` component displays the result.
|
|
114
|
+
|
|
115
|
+
```tsx
|
|
116
|
+
import { useAssistantTool } from "@assistant-ui/react-ink";
|
|
117
|
+
import { Text } from "ink";
|
|
118
|
+
|
|
119
|
+
useAssistantTool({
|
|
120
|
+
toolName: "get_weather",
|
|
121
|
+
description: "Get the current weather for a city",
|
|
122
|
+
parameters: {
|
|
123
|
+
type: "object",
|
|
124
|
+
properties: {
|
|
125
|
+
city: { type: "string" },
|
|
126
|
+
},
|
|
127
|
+
required: ["city"],
|
|
128
|
+
},
|
|
129
|
+
execute: async ({ city }) => {
|
|
130
|
+
const res = await fetch(`https://api.weather.example/${city}`);
|
|
131
|
+
return res.json();
|
|
132
|
+
},
|
|
133
|
+
render: ({ args, result }) => (
|
|
134
|
+
<Text>{args.city}: {result?.temperature}°F</Text>
|
|
135
|
+
),
|
|
136
|
+
});
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### useAssistantToolUI
|
|
140
|
+
|
|
141
|
+
Register only a UI renderer for a tool (without tool definition or execute function).
|
|
142
|
+
|
|
143
|
+
```tsx
|
|
144
|
+
import { useAssistantToolUI } from "@assistant-ui/react-ink";
|
|
145
|
+
import { Text } from "ink";
|
|
146
|
+
|
|
147
|
+
useAssistantToolUI({
|
|
148
|
+
toolName: "get_weather",
|
|
149
|
+
render: ({ args, result, status }) => (
|
|
150
|
+
<Text>
|
|
151
|
+
{status?.type === "running"
|
|
152
|
+
? `Loading weather for ${args.city}...`
|
|
153
|
+
: `${args.city}: ${result?.temperature}°F`}
|
|
154
|
+
</Text>
|
|
155
|
+
),
|
|
156
|
+
});
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### useAssistantInstructions
|
|
160
|
+
|
|
161
|
+
Register system instructions in the model context.
|
|
162
|
+
|
|
163
|
+
```tsx
|
|
164
|
+
import { useAssistantInstructions } from "@assistant-ui/react-ink";
|
|
165
|
+
|
|
166
|
+
useAssistantInstructions("You are a helpful terminal assistant.");
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### useAssistantDataUI
|
|
170
|
+
|
|
171
|
+
Register a UI renderer for a named data part type. When a message contains a data part with the given `name`, the `render` component is used.
|
|
172
|
+
|
|
173
|
+
```tsx
|
|
174
|
+
import { useAssistantDataUI } from "@assistant-ui/react-ink";
|
|
175
|
+
import { Text } from "ink";
|
|
176
|
+
|
|
177
|
+
useAssistantDataUI({
|
|
178
|
+
name: "weather_card",
|
|
179
|
+
render: ({ data }) => (
|
|
180
|
+
<Text>{data.city}: {data.temperature}°F</Text>
|
|
181
|
+
),
|
|
182
|
+
});
|
|
183
|
+
```
|
|
184
|
+
### makeAssistantTool
|
|
185
|
+
|
|
186
|
+
Create a component that registers a tool when mounted.
|
|
187
|
+
|
|
188
|
+
```tsx
|
|
189
|
+
import { makeAssistantTool } from "@assistant-ui/react-ink";
|
|
190
|
+
import { Text } from "ink";
|
|
191
|
+
|
|
192
|
+
const WeatherTool = makeAssistantTool({
|
|
193
|
+
toolName: "get_weather",
|
|
194
|
+
description: "Get weather",
|
|
195
|
+
parameters: { type: "object", properties: { city: { type: "string" } }, required: ["city"] },
|
|
196
|
+
execute: async ({ city }) => ({ temperature: 72 }),
|
|
197
|
+
render: ({ args, result }) => <Text>{args.city}: {result?.temperature}°F</Text>,
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// Mount inside AssistantRuntimeProvider to register
|
|
201
|
+
<WeatherTool />
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### makeAssistantToolUI
|
|
205
|
+
|
|
206
|
+
Create a component that registers only a tool UI renderer (no tool definition or execute) when mounted.
|
|
207
|
+
|
|
208
|
+
```tsx
|
|
209
|
+
import { makeAssistantToolUI } from "@assistant-ui/react-ink";
|
|
210
|
+
import { Text } from "ink";
|
|
211
|
+
|
|
212
|
+
const WeatherToolUI = makeAssistantToolUI({
|
|
213
|
+
toolName: "get_weather",
|
|
214
|
+
render: ({ args, result, status }) => (
|
|
215
|
+
<Text>
|
|
216
|
+
{status?.type === "running"
|
|
217
|
+
? `Loading weather for ${args.city}...`
|
|
218
|
+
: `${args.city}: ${result?.temperature}°F`}
|
|
219
|
+
</Text>
|
|
220
|
+
),
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
// Mount inside AssistantRuntimeProvider to register
|
|
224
|
+
<WeatherToolUI />
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### makeAssistantDataUI
|
|
228
|
+
|
|
229
|
+
Create a component that registers a data UI renderer when mounted.
|
|
230
|
+
|
|
231
|
+
```tsx
|
|
232
|
+
import { makeAssistantDataUI } from "@assistant-ui/react-ink";
|
|
233
|
+
import { Text } from "ink";
|
|
234
|
+
|
|
235
|
+
const WeatherCardUI = makeAssistantDataUI({
|
|
236
|
+
name: "weather_card",
|
|
237
|
+
render: ({ data }) => (
|
|
238
|
+
<Text>{data.city}: {data.temperature}°F</Text>
|
|
239
|
+
),
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
// Mount inside AssistantRuntimeProvider to register
|
|
243
|
+
<WeatherCardUI />
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### useInlineRender
|
|
247
|
+
|
|
248
|
+
Wrap a render function component so that it always uses the latest version without re-creating a stable reference. Useful when passing a render prop inline and the function closes over changing state.
|
|
249
|
+
|
|
250
|
+
```tsx
|
|
251
|
+
import { useInlineRender } from "@assistant-ui/react-ink";
|
|
252
|
+
|
|
253
|
+
const render = useInlineRender(({ args, result }) => (
|
|
254
|
+
<Text>{args.city}: {result?.temperature}°F</Text>
|
|
255
|
+
));
|
|
256
|
+
|
|
257
|
+
useAssistantToolUI({ toolName: "get_weather", render });
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
## Runtime Providers
|
|
261
|
+
|
|
262
|
+
### AssistantRuntimeProvider
|
|
263
|
+
|
|
264
|
+
Connects an `AssistantRuntime` to the React tree. All primitives and hooks must be used inside this provider.
|
|
265
|
+
|
|
266
|
+
```tsx
|
|
267
|
+
import { AssistantRuntimeProvider, useLocalRuntime } from "@assistant-ui/react-ink";
|
|
268
|
+
|
|
269
|
+
const runtime = useLocalRuntime(chatModel);
|
|
270
|
+
|
|
271
|
+
<AssistantRuntimeProvider runtime={runtime}>
|
|
272
|
+
{/* app content */}
|
|
273
|
+
</AssistantRuntimeProvider>
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
| Prop | Type | Description |
|
|
277
|
+
|------|------|-------------|
|
|
278
|
+
| `runtime` | `AssistantRuntime` | The runtime instance to provide |
|
|
279
|
+
|
|
280
|
+
## Context Providers
|
|
281
|
+
|
|
282
|
+
These low-level providers are used to set up scoped contexts for rendering primitives outside of the standard `ThreadPrimitive.Messages` / `MessagePrimitive.Parts` hierarchy.
|
|
283
|
+
|
|
284
|
+
### MessageByIndexProvider
|
|
285
|
+
|
|
286
|
+
Sets up the message context for a given message index in the thread. Used internally by `ThreadPrimitive.Messages`.
|
|
287
|
+
|
|
288
|
+
```tsx
|
|
289
|
+
import { MessageByIndexProvider } from "@assistant-ui/react-ink";
|
|
290
|
+
|
|
291
|
+
<MessageByIndexProvider index={0}>
|
|
292
|
+
<MessagePrimitive.Root>...</MessagePrimitive.Root>
|
|
293
|
+
</MessageByIndexProvider>
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
| Prop | Type | Description |
|
|
297
|
+
|------|------|-------------|
|
|
298
|
+
| `index` | `number` | Zero-based index of the message in the thread |
|
|
299
|
+
|
|
300
|
+
### PartByIndexProvider
|
|
301
|
+
|
|
302
|
+
Sets up the part context for a given part index in the current message. Used internally by `MessagePrimitive.Parts`.
|
|
303
|
+
|
|
304
|
+
```tsx
|
|
305
|
+
import { PartByIndexProvider } from "@assistant-ui/react-ink";
|
|
306
|
+
|
|
307
|
+
<PartByIndexProvider index={0}>
|
|
308
|
+
{/* part content */}
|
|
309
|
+
</PartByIndexProvider>
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
| Prop | Type | Description |
|
|
313
|
+
|------|------|-------------|
|
|
314
|
+
| `index` | `number` | Zero-based index of the part in the message |
|
|
315
|
+
|
|
316
|
+
### TextMessagePartProvider
|
|
317
|
+
|
|
318
|
+
Provides a synthetic text part context with a fixed text value. Useful for rendering text content outside of a real message part (e.g., in previews or testing).
|
|
319
|
+
|
|
320
|
+
```tsx
|
|
321
|
+
import { TextMessagePartProvider } from "@assistant-ui/react-ink";
|
|
322
|
+
|
|
323
|
+
<TextMessagePartProvider text="Hello world" isRunning={false}>
|
|
324
|
+
{/* content rendered with a text part context */}
|
|
325
|
+
</TextMessagePartProvider>
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
| Prop | Type | Description |
|
|
329
|
+
|------|------|-------------|
|
|
330
|
+
| `text` | `string` | The text content for the synthetic part |
|
|
331
|
+
| `isRunning` | `boolean` | Whether the part should appear as running (default: `false`) |
|
|
332
|
+
|
|
333
|
+
### ChainOfThoughtByIndicesProvider
|
|
334
|
+
|
|
335
|
+
Sets up a chain-of-thought context spanning a range of message parts by start and end index. Used to group consecutive reasoning parts.
|
|
336
|
+
|
|
337
|
+
```tsx
|
|
338
|
+
import { ChainOfThoughtByIndicesProvider } from "@assistant-ui/react-ink";
|
|
339
|
+
|
|
340
|
+
<ChainOfThoughtByIndicesProvider startIndex={1} endIndex={3}>
|
|
341
|
+
<ChainOfThoughtPrimitive.Root>...</ChainOfThoughtPrimitive.Root>
|
|
342
|
+
</ChainOfThoughtByIndicesProvider>
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
| Prop | Type | Description |
|
|
346
|
+
|------|------|-------------|
|
|
347
|
+
| `startIndex` | `number` | Index of the first part in the chain-of-thought range |
|
|
348
|
+
| `endIndex` | `number` | Index of the last part in the chain-of-thought range |
|
|
349
|
+
|
|
350
|
+
### ChainOfThoughtPartByIndexProvider
|
|
351
|
+
|
|
352
|
+
Sets up the part context for a specific part within the current chain-of-thought by index.
|
|
353
|
+
|
|
354
|
+
```tsx
|
|
355
|
+
import { ChainOfThoughtPartByIndexProvider } from "@assistant-ui/react-ink";
|
|
356
|
+
|
|
357
|
+
<ChainOfThoughtPartByIndexProvider index={0}>
|
|
358
|
+
{/* chain-of-thought part content */}
|
|
359
|
+
</ChainOfThoughtPartByIndexProvider>
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
| Prop | Type | Description |
|
|
363
|
+
|------|------|-------------|
|
|
364
|
+
| `index` | `number` | Zero-based index of the part within the chain-of-thought |
|
|
365
|
+
|
|
366
|
+
### SuggestionByIndexProvider
|
|
367
|
+
|
|
368
|
+
Sets up the suggestion context for a given suggestion index. Used internally by `ThreadPrimitive.Suggestions`.
|
|
369
|
+
|
|
370
|
+
```tsx
|
|
371
|
+
import { SuggestionByIndexProvider } from "@assistant-ui/react-ink";
|
|
372
|
+
|
|
373
|
+
<SuggestionByIndexProvider index={0}>
|
|
374
|
+
<SuggestionPrimitive.Title />
|
|
375
|
+
</SuggestionByIndexProvider>
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
| Prop | Type | Description |
|
|
379
|
+
|------|------|-------------|
|
|
380
|
+
| `index` | `number` | Zero-based index of the suggestion |
|
|
381
|
+
|
|
382
|
+
### ThreadListItemByIndexProvider
|
|
383
|
+
|
|
384
|
+
Sets up the thread list item context for a given index, differentiating between regular and archived threads.
|
|
385
|
+
|
|
386
|
+
```tsx
|
|
387
|
+
import { ThreadListItemByIndexProvider } from "@assistant-ui/react-ink";
|
|
388
|
+
|
|
389
|
+
<ThreadListItemByIndexProvider index={0} archived={false}>
|
|
390
|
+
<ThreadListItemPrimitive.Root>...</ThreadListItemPrimitive.Root>
|
|
391
|
+
</ThreadListItemByIndexProvider>
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
| Prop | Type | Description |
|
|
395
|
+
|------|------|-------------|
|
|
396
|
+
| `index` | `number` | Zero-based index in the thread list |
|
|
397
|
+
| `archived` | `boolean` | Whether to index into the archived thread list |
|
|
398
|
+
|
|
399
|
+
### ThreadListItemRuntimeProvider
|
|
400
|
+
|
|
401
|
+
Sets up the thread list item context from a `ThreadListItemRuntime` instance directly.
|
|
402
|
+
|
|
403
|
+
```tsx
|
|
404
|
+
import { ThreadListItemRuntimeProvider } from "@assistant-ui/react-ink";
|
|
405
|
+
|
|
406
|
+
<ThreadListItemRuntimeProvider runtime={threadListItemRuntime}>
|
|
407
|
+
<ThreadListItemPrimitive.Root>...</ThreadListItemPrimitive.Root>
|
|
408
|
+
</ThreadListItemRuntimeProvider>
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
| Prop | Type | Description |
|
|
412
|
+
|------|------|-------------|
|
|
413
|
+
| `runtime` | `ThreadListItemRuntime` | The thread list item runtime instance |
|
|
414
|
+
|
|
415
|
+
### MessageAttachmentByIndexProvider
|
|
416
|
+
|
|
417
|
+
Sets up the attachment context for a specific message attachment by index.
|
|
418
|
+
|
|
419
|
+
```tsx
|
|
420
|
+
import { MessageAttachmentByIndexProvider } from "@assistant-ui/react-ink";
|
|
421
|
+
|
|
422
|
+
<MessageAttachmentByIndexProvider index={0}>
|
|
423
|
+
<AttachmentPrimitive.Name />
|
|
424
|
+
</MessageAttachmentByIndexProvider>
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
| Prop | Type | Description |
|
|
428
|
+
|------|------|-------------|
|
|
429
|
+
| `index` | `number` | Zero-based index of the attachment in the message |
|
|
430
|
+
|
|
431
|
+
### ComposerAttachmentByIndexProvider
|
|
432
|
+
|
|
433
|
+
Sets up the attachment context for a specific composer attachment by index.
|
|
434
|
+
|
|
435
|
+
```tsx
|
|
436
|
+
import { ComposerAttachmentByIndexProvider } from "@assistant-ui/react-ink";
|
|
437
|
+
|
|
438
|
+
<ComposerAttachmentByIndexProvider index={0}>
|
|
439
|
+
<AttachmentPrimitive.Name />
|
|
440
|
+
<AttachmentPrimitive.Remove>
|
|
441
|
+
<Text color="red">[x]</Text>
|
|
442
|
+
</AttachmentPrimitive.Remove>
|
|
443
|
+
</ComposerAttachmentByIndexProvider>
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
| Prop | Type | Description |
|
|
447
|
+
|------|------|-------------|
|
|
448
|
+
| `index` | `number` | Zero-based index of the attachment in the composer |
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Getting Started
|
|
3
|
+
description: Build AI chat interfaces for the terminal with @assistant-ui/react-ink.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Quick Start
|
|
7
|
+
|
|
8
|
+
The fastest way to get started with assistant-ui for the terminal.
|
|
9
|
+
|
|
10
|
+
<Steps>
|
|
11
|
+
<Step>
|
|
12
|
+
|
|
13
|
+
### Create a new project
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
npx assistant-ui@latest create --ink my-chat-app
|
|
17
|
+
cd my-chat-app
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
</Step>
|
|
21
|
+
<Step>
|
|
22
|
+
|
|
23
|
+
### Install dependencies
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
pnpm install
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
</Step>
|
|
30
|
+
<Step>
|
|
31
|
+
|
|
32
|
+
### Start the app
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
pnpm dev
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
</Step>
|
|
39
|
+
</Steps>
|
|
40
|
+
|
|
41
|
+
## Manual Setup
|
|
42
|
+
|
|
43
|
+
If you prefer to add assistant-ui to an existing Node.js project, follow these steps.
|
|
44
|
+
|
|
45
|
+
<Steps>
|
|
46
|
+
<Step>
|
|
47
|
+
|
|
48
|
+
### Install dependencies
|
|
49
|
+
|
|
50
|
+
```sh
|
|
51
|
+
npm install @assistant-ui/react-ink @assistant-ui/react-ink-markdown ink react
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
</Step>
|
|
55
|
+
<Step>
|
|
56
|
+
|
|
57
|
+
### Create a chat model adapter
|
|
58
|
+
|
|
59
|
+
Define how your app communicates with your AI backend. This example uses a simple streaming adapter:
|
|
60
|
+
|
|
61
|
+
```ts title="adapters/my-chat-adapter.ts"
|
|
62
|
+
import type { ChatModelAdapter } from "@assistant-ui/react-ink";
|
|
63
|
+
|
|
64
|
+
export const myChatAdapter: ChatModelAdapter = {
|
|
65
|
+
async *run({ messages, abortSignal }) {
|
|
66
|
+
const response = await fetch("http://localhost:3000/api/chat", {
|
|
67
|
+
method: "POST",
|
|
68
|
+
headers: { "Content-Type": "application/json" },
|
|
69
|
+
body: JSON.stringify({ messages }),
|
|
70
|
+
signal: abortSignal,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const reader = response.body?.getReader();
|
|
74
|
+
if (!reader) throw new Error("No response body");
|
|
75
|
+
|
|
76
|
+
const decoder = new TextDecoder();
|
|
77
|
+
let fullText = "";
|
|
78
|
+
|
|
79
|
+
while (true) {
|
|
80
|
+
const { done, value } = await reader.read();
|
|
81
|
+
if (done) break;
|
|
82
|
+
|
|
83
|
+
const chunk = decoder.decode(value, { stream: true });
|
|
84
|
+
fullText += chunk;
|
|
85
|
+
yield { content: [{ type: "text", text: fullText }] };
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
<Callout type="info">
|
|
92
|
+
This is the same `ChatModelAdapter` interface used in `@assistant-ui/react` and `@assistant-ui/react-native`. If you already have an adapter, you can reuse it as-is.
|
|
93
|
+
</Callout>
|
|
94
|
+
|
|
95
|
+
</Step>
|
|
96
|
+
<Step>
|
|
97
|
+
|
|
98
|
+
### Set up the runtime
|
|
99
|
+
|
|
100
|
+
```tsx title="app.tsx"
|
|
101
|
+
import { Box, Text } from "ink";
|
|
102
|
+
import {
|
|
103
|
+
AssistantRuntimeProvider,
|
|
104
|
+
useLocalRuntime,
|
|
105
|
+
} from "@assistant-ui/react-ink";
|
|
106
|
+
import { myChatAdapter } from "./adapters/my-chat-adapter.js";
|
|
107
|
+
|
|
108
|
+
export function App() {
|
|
109
|
+
const runtime = useLocalRuntime(myChatAdapter);
|
|
110
|
+
|
|
111
|
+
return (
|
|
112
|
+
<AssistantRuntimeProvider runtime={runtime}>
|
|
113
|
+
<Box flexDirection="column" padding={1}>
|
|
114
|
+
<Text bold color="cyan">My Terminal Chat</Text>
|
|
115
|
+
{/* your chat UI */}
|
|
116
|
+
</Box>
|
|
117
|
+
</AssistantRuntimeProvider>
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
</Step>
|
|
123
|
+
<Step>
|
|
124
|
+
|
|
125
|
+
### Build your chat UI
|
|
126
|
+
|
|
127
|
+
Use primitives to compose your terminal chat interface:
|
|
128
|
+
|
|
129
|
+
```tsx title="components/thread.tsx"
|
|
130
|
+
import { Box, Text } from "ink";
|
|
131
|
+
import {
|
|
132
|
+
ThreadPrimitive,
|
|
133
|
+
ComposerPrimitive,
|
|
134
|
+
useAuiState,
|
|
135
|
+
} from "@assistant-ui/react-ink";
|
|
136
|
+
import { MarkdownText } from "@assistant-ui/react-ink-markdown";
|
|
137
|
+
|
|
138
|
+
const Message = () => {
|
|
139
|
+
const message = useAuiState((s) => s.message);
|
|
140
|
+
const isUser = message.role === "user";
|
|
141
|
+
const text = message.content
|
|
142
|
+
.filter((p) => p.type === "text")
|
|
143
|
+
.map((p) => ("text" in p ? p.text : ""))
|
|
144
|
+
.join("");
|
|
145
|
+
|
|
146
|
+
if (isUser) {
|
|
147
|
+
return (
|
|
148
|
+
<Box marginBottom={1}>
|
|
149
|
+
<Text bold color="green">You: </Text>
|
|
150
|
+
<Text wrap="wrap">{text}</Text>
|
|
151
|
+
</Box>
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return (
|
|
156
|
+
<Box flexDirection="column" marginBottom={1}>
|
|
157
|
+
<Text bold color="blue">AI:</Text>
|
|
158
|
+
<MarkdownText text={text} />
|
|
159
|
+
</Box>
|
|
160
|
+
);
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
const StatusIndicator = () => {
|
|
164
|
+
const isRunning = useAuiState((s) => s.thread.isRunning);
|
|
165
|
+
if (!isRunning) return null;
|
|
166
|
+
return (
|
|
167
|
+
<Box marginBottom={1}>
|
|
168
|
+
<Text color="yellow">Thinking...</Text>
|
|
169
|
+
</Box>
|
|
170
|
+
);
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
export const Thread = () => {
|
|
174
|
+
return (
|
|
175
|
+
<ThreadPrimitive.Root>
|
|
176
|
+
<ThreadPrimitive.Empty>
|
|
177
|
+
<Box marginBottom={1}>
|
|
178
|
+
<Text dimColor>No messages yet. Start typing below!</Text>
|
|
179
|
+
</Box>
|
|
180
|
+
</ThreadPrimitive.Empty>
|
|
181
|
+
|
|
182
|
+
<ThreadPrimitive.Messages>
|
|
183
|
+
{() => <Message />}
|
|
184
|
+
</ThreadPrimitive.Messages>
|
|
185
|
+
|
|
186
|
+
<StatusIndicator />
|
|
187
|
+
|
|
188
|
+
<Box borderStyle="round" borderColor="gray" paddingX={1}>
|
|
189
|
+
<Text color="gray">{"> "}</Text>
|
|
190
|
+
<ComposerPrimitive.Input
|
|
191
|
+
submitOnEnter
|
|
192
|
+
placeholder="Type a message..."
|
|
193
|
+
autoFocus
|
|
194
|
+
/>
|
|
195
|
+
</Box>
|
|
196
|
+
</ThreadPrimitive.Root>
|
|
197
|
+
);
|
|
198
|
+
};
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
</Step>
|
|
202
|
+
<Step>
|
|
203
|
+
|
|
204
|
+
### Render with Ink
|
|
205
|
+
|
|
206
|
+
```tsx title="index.tsx"
|
|
207
|
+
import { render } from "ink";
|
|
208
|
+
import { App } from "./app.js";
|
|
209
|
+
|
|
210
|
+
render(<App />);
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
</Step>
|
|
214
|
+
</Steps>
|
|
215
|
+
|
|
216
|
+
## What's Next?
|
|
217
|
+
|
|
218
|
+
<Cards>
|
|
219
|
+
<Card
|
|
220
|
+
title="Migration from Web"
|
|
221
|
+
description="Already using assistant-ui? Migrate your web app to the terminal."
|
|
222
|
+
href="/docs/ink/migration"
|
|
223
|
+
/>
|
|
224
|
+
<Card
|
|
225
|
+
title="Custom Backend"
|
|
226
|
+
description="Connect to your own backend API or manage threads server-side."
|
|
227
|
+
href="/docs/ink/custom-backend"
|
|
228
|
+
/>
|
|
229
|
+
<Card
|
|
230
|
+
title="Primitives"
|
|
231
|
+
description="Composable terminal UI components for building chat interfaces."
|
|
232
|
+
href="/docs/ink/primitives"
|
|
233
|
+
/>
|
|
234
|
+
<Card
|
|
235
|
+
title="Example App"
|
|
236
|
+
description="Full terminal chat example with markdown rendering and streaming."
|
|
237
|
+
href="https://github.com/assistant-ui/assistant-ui/tree/main/examples/with-react-ink"
|
|
238
|
+
/>
|
|
239
|
+
</Cards>
|