@assistant-ui/mcp-docs-server 0.1.29 → 0.1.30
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 +15 -7
- package/.docs/organized/code-examples/with-a2a.md +8 -20
- package/.docs/organized/code-examples/with-ag-ui.md +9 -6
- package/.docs/organized/code-examples/with-ai-sdk-v6.md +8 -8
- package/.docs/organized/code-examples/with-artifacts.md +10 -8
- package/.docs/organized/code-examples/with-assistant-transport.md +9 -10
- package/.docs/organized/code-examples/with-chain-of-thought.md +7 -7
- package/.docs/organized/code-examples/with-cloud-standalone.md +13 -10
- package/.docs/organized/code-examples/with-cloud.md +8 -9
- package/.docs/organized/code-examples/with-custom-thread-list.md +8 -8
- package/.docs/organized/code-examples/with-elevenlabs-conversational.md +15 -10
- package/.docs/organized/code-examples/with-elevenlabs-scribe.md +11 -11
- package/.docs/organized/code-examples/with-expo.md +20 -16
- package/.docs/organized/code-examples/with-external-store.md +7 -7
- package/.docs/organized/code-examples/with-ffmpeg.md +15 -10
- package/.docs/organized/code-examples/with-generative-ui.md +7 -7
- package/.docs/organized/code-examples/with-google-adk.md +6 -6
- package/.docs/organized/code-examples/with-heat-graph.md +5 -5
- package/.docs/organized/code-examples/with-interactables.md +8 -23
- package/.docs/organized/code-examples/with-langchain.md +437 -0
- package/.docs/organized/code-examples/with-langgraph.md +15 -15
- package/.docs/organized/code-examples/with-livekit.md +15 -10
- package/.docs/organized/code-examples/with-opencode.md +8 -10
- package/.docs/organized/code-examples/with-parent-id-grouping.md +8 -8
- package/.docs/organized/code-examples/with-react-hook-form.md +219 -147
- package/.docs/organized/code-examples/with-react-ink.md +2 -2
- package/.docs/organized/code-examples/with-react-router.md +10 -10
- package/.docs/organized/code-examples/with-store.md +8 -5
- package/.docs/organized/code-examples/with-tanstack.md +8 -8
- package/.docs/organized/code-examples/with-tap-runtime.md +9 -5
- package/.docs/raw/docs/(docs)/guides/mentions.mdx +248 -109
- package/.docs/raw/docs/(docs)/guides/slash-commands.mdx +112 -92
- package/.docs/raw/docs/(docs)/rtl.mdx +79 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/composer.mdx +149 -40
- package/.docs/raw/docs/(reference)/api-reference/primitives/message-part.mdx +2 -0
- package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-runtime.mdx +4 -0
- package/.docs/raw/docs/cloud/ai-sdk-assistant-ui.mdx +1 -1
- package/.docs/raw/docs/primitives/composer.mdx +94 -62
- package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +57 -0
- package/.docs/raw/docs/runtimes/custom/custom-thread-list.mdx +47 -1
- package/.docs/raw/docs/runtimes/custom/external-store.mdx +1 -1
- package/.docs/raw/docs/runtimes/langchain/comparison.mdx +60 -0
- package/.docs/raw/docs/runtimes/langchain/index.mdx +210 -0
- package/.docs/raw/docs/runtimes/langgraph/index.mdx +155 -63
- package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +12 -4
- package/.docs/raw/docs/ui/composer-trigger-popover.mdx +199 -0
- package/.docs/raw/docs/ui/directive-text.mdx +113 -0
- package/.docs/raw/docs/ui/reasoning.mdx +13 -9
- package/dist/utils/logger.js +1 -1
- package/dist/utils/logger.js.map +1 -1
- package/package.json +3 -3
- package/src/utils/logger.ts +1 -1
- package/.docs/raw/docs/ui/mention.mdx +0 -168
|
@@ -416,76 +416,124 @@ import { AuiIf } from "@assistant-ui/react";
|
|
|
416
416
|
</AuiIf>
|
|
417
417
|
```
|
|
418
418
|
|
|
419
|
-
##
|
|
419
|
+
## Trigger Popover Primitives (Unstable)
|
|
420
420
|
|
|
421
421
|
<Callout type="warn">
|
|
422
422
|
These primitives are under the `Unstable_` prefix and may change without notice.
|
|
423
423
|
</Callout>
|
|
424
424
|
|
|
425
|
-
|
|
425
|
+
Unified primitives for any character-triggered popover (`@` mentions, `/` slash commands, `:` emoji, etc.). Multiple triggers coexist under a single `TriggerPopoverRoot`. See the [Mentions guide](/docs/guides/mentions) and [Slash Commands guide](/docs/guides/slash-commands) for full documentation and the [ComposerTriggerPopover component](/docs/ui/composer-trigger-popover) for a pre-built implementation.
|
|
426
426
|
|
|
427
427
|
### Anatomy
|
|
428
428
|
|
|
429
429
|
```tsx
|
|
430
430
|
import { ComposerPrimitive } from "@assistant-ui/react";
|
|
431
|
+
import { unstable_defaultDirectiveFormatter } from "@assistant-ui/core";
|
|
431
432
|
|
|
432
433
|
const Composer = () => (
|
|
433
|
-
<ComposerPrimitive.
|
|
434
|
+
<ComposerPrimitive.Unstable_TriggerPopoverRoot>
|
|
434
435
|
<ComposerPrimitive.Root>
|
|
435
436
|
<ComposerPrimitive.Input />
|
|
436
|
-
|
|
437
|
-
|
|
437
|
+
|
|
438
|
+
<ComposerPrimitive.Unstable_TriggerPopover
|
|
439
|
+
char="@"
|
|
440
|
+
adapter={mention.adapter}
|
|
441
|
+
>
|
|
442
|
+
<ComposerPrimitive.Unstable_TriggerPopover.Directive
|
|
443
|
+
{...mention.directive}
|
|
444
|
+
/>
|
|
445
|
+
<ComposerPrimitive.Unstable_TriggerPopoverCategories>
|
|
438
446
|
{(categories) =>
|
|
439
447
|
categories.map((cat) => (
|
|
440
|
-
<ComposerPrimitive.
|
|
448
|
+
<ComposerPrimitive.Unstable_TriggerPopoverCategoryItem
|
|
441
449
|
key={cat.id}
|
|
442
450
|
categoryId={cat.id}
|
|
443
451
|
>
|
|
444
452
|
{cat.label}
|
|
445
|
-
</ComposerPrimitive.
|
|
453
|
+
</ComposerPrimitive.Unstable_TriggerPopoverCategoryItem>
|
|
446
454
|
))
|
|
447
455
|
}
|
|
448
|
-
</ComposerPrimitive.
|
|
449
|
-
<ComposerPrimitive.
|
|
456
|
+
</ComposerPrimitive.Unstable_TriggerPopoverCategories>
|
|
457
|
+
<ComposerPrimitive.Unstable_TriggerPopoverItems>
|
|
450
458
|
{(items) =>
|
|
451
459
|
items.map((item) => (
|
|
452
|
-
<ComposerPrimitive.
|
|
460
|
+
<ComposerPrimitive.Unstable_TriggerPopoverItem
|
|
453
461
|
key={item.id}
|
|
454
462
|
item={item}
|
|
455
463
|
>
|
|
456
464
|
{item.label}
|
|
457
|
-
</ComposerPrimitive.
|
|
465
|
+
</ComposerPrimitive.Unstable_TriggerPopoverItem>
|
|
458
466
|
))
|
|
459
467
|
}
|
|
460
|
-
</ComposerPrimitive.
|
|
461
|
-
<ComposerPrimitive.
|
|
468
|
+
</ComposerPrimitive.Unstable_TriggerPopoverItems>
|
|
469
|
+
<ComposerPrimitive.Unstable_TriggerPopoverBack>
|
|
462
470
|
Back
|
|
463
|
-
</ComposerPrimitive.
|
|
464
|
-
</ComposerPrimitive.
|
|
471
|
+
</ComposerPrimitive.Unstable_TriggerPopoverBack>
|
|
472
|
+
</ComposerPrimitive.Unstable_TriggerPopover>
|
|
465
473
|
</ComposerPrimitive.Root>
|
|
466
|
-
</ComposerPrimitive.
|
|
474
|
+
</ComposerPrimitive.Unstable_TriggerPopoverRoot>
|
|
467
475
|
);
|
|
468
476
|
```
|
|
469
477
|
|
|
470
|
-
###
|
|
478
|
+
### Unstable_TriggerPopoverRoot
|
|
479
|
+
|
|
480
|
+
Root provider that groups one or more `TriggerPopover` declarations. Owns the shared `ComposerInputPluginRegistry` that routes cursor and keyboard events to each registered trigger.
|
|
481
|
+
|
|
482
|
+
No props.
|
|
483
|
+
|
|
484
|
+
### Unstable_TriggerPopover
|
|
485
|
+
|
|
486
|
+
Declares a trigger and renders its popover container. Only renders its DOM (and children) while this trigger is active in the composer input. Each declaration has an isolated scope — sub-primitives placed inside read state from this declaration only.
|
|
487
|
+
|
|
488
|
+
| Prop | Type | Default | Description |
|
|
489
|
+
| --- | --- | --- | --- |
|
|
490
|
+
| `char` | `string` | — | Character(s) that activate the trigger (e.g. `"@"`, `"/"`) — unique within the root |
|
|
491
|
+
| `adapter` | `Unstable_TriggerAdapter` | — | Provides categories, items, and search |
|
|
492
|
+
|
|
493
|
+
Selection behavior is declared by rendering **exactly one** behavior sub-primitive inside the `TriggerPopover`:
|
|
494
|
+
|
|
495
|
+
- [`Unstable_TriggerPopover.Directive`](#unstable_triggerpopoverdirective) — inserts `:type[label]{name=id}` into the composer on selection (mention behavior).
|
|
496
|
+
- [`Unstable_TriggerPopover.Action`](#unstable_triggerpopoveraction) — fires `onExecute` on selection; leaves a directive chip as an audit trail by default.
|
|
497
|
+
|
|
498
|
+
Renders a `<div>` with `role="listbox"` when open.
|
|
499
|
+
|
|
500
|
+
### Unstable_TriggerPopover.Directive
|
|
501
|
+
|
|
502
|
+
Behavior sub-primitive. Placed inside a `<Unstable_TriggerPopover>`. Renders nothing — registers an `"directive"` behavior with its parent. Exactly one behavior sub-primitive is allowed per `TriggerPopover`.
|
|
503
|
+
|
|
504
|
+
| Prop | Type | Default | Description |
|
|
505
|
+
| --- | --- | --- | --- |
|
|
506
|
+
| `formatter` | `Unstable_DirectiveFormatter` | `unstable_defaultDirectiveFormatter` | Serializes the selected item into composer text (and parses it back). |
|
|
507
|
+
| `onInserted` | `(item) => void` | — | Fires after the directive text has been inserted. |
|
|
508
|
+
|
|
509
|
+
### Unstable_TriggerPopover.Action
|
|
471
510
|
|
|
472
|
-
|
|
511
|
+
Behavior sub-primitive. Placed inside a `<Unstable_TriggerPopover>`. Renders nothing — registers an `"action"` behavior with its parent. Exactly one behavior sub-primitive is allowed per `TriggerPopover`.
|
|
473
512
|
|
|
474
513
|
| Prop | Type | Default | Description |
|
|
475
514
|
| --- | --- | --- | --- |
|
|
476
|
-
| `
|
|
477
|
-
| `
|
|
478
|
-
| `
|
|
515
|
+
| `formatter` | `Unstable_DirectiveFormatter` | `unstable_defaultDirectiveFormatter` | Serializes the audit-trail chip (unused when `removeOnExecute` is true). |
|
|
516
|
+
| `onExecute` | `(item) => void` | — | Called the moment an item is selected — typically routes to a handler map. Required. |
|
|
517
|
+
| `removeOnExecute` | `boolean` | `false` | When `true`, strips the trigger text from the composer instead of leaving a chip. |
|
|
479
518
|
|
|
480
|
-
###
|
|
519
|
+
### Unstable_TriggerBehavior
|
|
481
520
|
|
|
482
|
-
|
|
521
|
+
Union type returned by the two behavior sub-primitives and consumed internally by the popover resources. Exported for advanced use cases (e.g. custom sub-primitives).
|
|
483
522
|
|
|
484
|
-
|
|
523
|
+
```ts
|
|
524
|
+
import type { Unstable_TriggerBehavior } from "@assistant-ui/react";
|
|
525
|
+
|
|
526
|
+
// Equivalent shape:
|
|
527
|
+
// Unstable_TriggerBehavior =
|
|
528
|
+
// | { kind: "directive"; formatter: Unstable_DirectiveFormatter; onInserted?: (item) => void }
|
|
529
|
+
// | { kind: "action"; formatter: Unstable_DirectiveFormatter; onExecute: (item) => void; removeOnExecute?: boolean }
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
### Unstable_TriggerPopoverCategories
|
|
485
533
|
|
|
486
534
|
Renders the top-level category list. Accepts a render function `(categories) => ReactNode`. Hidden when a category is selected or when in search mode.
|
|
487
535
|
|
|
488
|
-
###
|
|
536
|
+
### Unstable_TriggerPopoverCategoryItem
|
|
489
537
|
|
|
490
538
|
A button that drills into a category. Renders `role="option"` with automatic `data-highlighted` and `aria-selected` when keyboard-navigated.
|
|
491
539
|
|
|
@@ -493,25 +541,26 @@ A button that drills into a category. Renders `role="option"` with automatic `da
|
|
|
493
541
|
| --- | --- | --- |
|
|
494
542
|
| `categoryId` | `string` | The category to select on click |
|
|
495
543
|
|
|
496
|
-
###
|
|
544
|
+
### Unstable_TriggerPopoverItems
|
|
497
545
|
|
|
498
546
|
Renders the item list for the active category or search results. Accepts a render function `(items) => ReactNode`. Hidden when no category is selected and not in search mode.
|
|
499
547
|
|
|
500
|
-
###
|
|
548
|
+
### Unstable_TriggerPopoverItem
|
|
501
549
|
|
|
502
|
-
A button that
|
|
550
|
+
A button that selects an item. Renders `role="option"` with automatic `data-highlighted` and `aria-selected` when keyboard-navigated.
|
|
503
551
|
|
|
504
552
|
| Prop | Type | Description |
|
|
505
553
|
| --- | --- | --- |
|
|
506
|
-
| `item` | `
|
|
554
|
+
| `item` | `Unstable_TriggerItem` | The item to select on click |
|
|
555
|
+
| `index` | `number` | Optional index override for highlight matching |
|
|
507
556
|
|
|
508
|
-
###
|
|
557
|
+
### Unstable_TriggerPopoverBack
|
|
509
558
|
|
|
510
559
|
A button that navigates back from items to the category list. Only renders when a category is active.
|
|
511
560
|
|
|
512
|
-
###
|
|
561
|
+
### unstable_useTriggerPopoverScopeContext
|
|
513
562
|
|
|
514
|
-
Hook to access the
|
|
563
|
+
Hook to access the popover state and actions for the nearest enclosing `Unstable_TriggerPopover`.
|
|
515
564
|
|
|
516
565
|
```tsx
|
|
517
566
|
const {
|
|
@@ -527,19 +576,79 @@ const {
|
|
|
527
576
|
goBack,
|
|
528
577
|
close,
|
|
529
578
|
handleKeyDown,
|
|
530
|
-
|
|
531
|
-
} = unstable_useMentionContext();
|
|
579
|
+
} = unstable_useTriggerPopoverScopeContext();
|
|
532
580
|
```
|
|
533
581
|
|
|
534
|
-
###
|
|
582
|
+
### unstable_useTriggerPopoverTriggers
|
|
583
|
+
|
|
584
|
+
Hook to iterate every trigger registered under the current `Unstable_TriggerPopoverRoot`. Intended for input-level integrations (e.g. Lexical `DirectivePlugin`). Returns `ReadonlyMap<string, Unstable_RegisteredTrigger>`.
|
|
585
|
+
|
|
586
|
+
### unstable_useMentionAdapter
|
|
535
587
|
|
|
536
|
-
|
|
588
|
+
Returns a spreadable `{ adapter, directive }` bundle for `@` mentions. Reads tools registered via `useAssistantTool`, accepts explicit `items`, and supports multi-category drill-down.
|
|
537
589
|
|
|
538
590
|
```tsx
|
|
539
|
-
import {
|
|
591
|
+
import {
|
|
592
|
+
unstable_useMentionAdapter,
|
|
593
|
+
type Unstable_Mention,
|
|
594
|
+
} from "@assistant-ui/react";
|
|
595
|
+
|
|
596
|
+
function MyComposer() {
|
|
597
|
+
// Default: tools from model context as a single "Tools" category
|
|
598
|
+
const mention = unstable_useMentionAdapter();
|
|
599
|
+
|
|
600
|
+
return (
|
|
601
|
+
<ComposerTriggerPopover char="@" {...mention} />
|
|
602
|
+
);
|
|
603
|
+
}
|
|
604
|
+
```
|
|
540
605
|
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
606
|
+
```tsx
|
|
607
|
+
// Multi-category + tools appended as their own category
|
|
608
|
+
const mention = unstable_useMentionAdapter({
|
|
609
|
+
categories: [
|
|
610
|
+
{ id: "users", label: "Users", items: [/* ... */] },
|
|
611
|
+
{ id: "files", label: "Files", items: [/* ... */] },
|
|
612
|
+
],
|
|
613
|
+
includeModelContextTools: true,
|
|
544
614
|
});
|
|
545
615
|
```
|
|
616
|
+
|
|
617
|
+
Options:
|
|
618
|
+
|
|
619
|
+
| Option | Type | Description |
|
|
620
|
+
| --- | --- | --- |
|
|
621
|
+
| `items` | `Unstable_Mention[]` | Flat list; ignored when `categories` is set. |
|
|
622
|
+
| `categories` | `{ id, label, items: Unstable_Mention[] }[]` | Drill-down groups. |
|
|
623
|
+
| `includeModelContextTools` | `boolean \| { category?, formatLabel?, icon? }` | Tools integration. Defaults to `true` iff neither `items` nor `categories`. |
|
|
624
|
+
| `formatter` | `Unstable_DirectiveFormatter` | Override directive serialization. |
|
|
625
|
+
| `onInserted` | `(item) => void` | Fires after the directive is inserted. |
|
|
626
|
+
| `iconMap` | `Record<string, Unstable_IconComponent>` | `metadata.icon` / category id → React component. |
|
|
627
|
+
| `fallbackIcon` | `Unstable_IconComponent` | Fallback when no `iconMap` entry matches. |
|
|
628
|
+
|
|
629
|
+
Returns `{ adapter, directive, iconMap?, fallbackIcon? }`.
|
|
630
|
+
|
|
631
|
+
### unstable_useSlashCommandAdapter
|
|
632
|
+
|
|
633
|
+
Returns a spreadable `{ adapter, action }` bundle for slash commands. Commands are declared as data + inline `execute` callbacks; `execute` lives in the hook closure and is never attached to the returned `Unstable_TriggerItem`, keeping items JSON-serializable.
|
|
634
|
+
|
|
635
|
+
```tsx
|
|
636
|
+
import {
|
|
637
|
+
unstable_useSlashCommandAdapter,
|
|
638
|
+
type Unstable_SlashCommand,
|
|
639
|
+
} from "@assistant-ui/react";
|
|
640
|
+
|
|
641
|
+
const SLASH_COMMANDS: readonly Unstable_SlashCommand[] = [
|
|
642
|
+
{ id: "summarize", execute: () => runSummarize(), icon: "FileText" },
|
|
643
|
+
{ id: "translate", execute: () => runTranslate(), icon: "Languages" },
|
|
644
|
+
];
|
|
645
|
+
|
|
646
|
+
function MyComposer() {
|
|
647
|
+
const slash = unstable_useSlashCommandAdapter({ commands: SLASH_COMMANDS });
|
|
648
|
+
return (
|
|
649
|
+
<ComposerTriggerPopover char="/" {...slash} />
|
|
650
|
+
);
|
|
651
|
+
}
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
Pass `removeOnExecute: true` on the hook options to strip the trigger text from the composer after executing. The hook also accepts `iconMap` / `fallbackIcon` options that flow into the returned bundle — `{...slash}` spreads them into `ComposerTriggerPopover`.
|
|
@@ -187,6 +187,8 @@ function MyComponent() {
|
|
|
187
187
|
|
|
188
188
|
Each data component receives the full data part as props: `{ type: "data", name: string, data: T, status: MessagePartStatus }`.
|
|
189
189
|
|
|
190
|
+
For a catch-all renderer (e.g. LangSmith's [`LoadExternalComponent`](/docs/runtimes/langgraph#dynamic-loading-with-fallback) loaded at runtime), pass `Fallback` via the inline `data` config on `MessagePrimitive.Parts`, or use the LangGraph adapter's [`uiComponents.fallback`](/docs/runtimes/langgraph#dynamic-loading-with-fallback) option.
|
|
191
|
+
|
|
190
192
|
### Messages (Sub-Agent)
|
|
191
193
|
|
|
192
194
|
Renders nested messages from a tool call part's `messages` field. This is used in multi-agent setups where a sub-agent's conversation is embedded inside a tool call.
|
|
@@ -18,6 +18,10 @@ const aui = useAui();
|
|
|
18
18
|
await aui.threads().switchToNewThread();
|
|
19
19
|
await aui.threads().switchToThread(threadId);
|
|
20
20
|
|
|
21
|
+
// Re-fetch the thread list from the remote adapter
|
|
22
|
+
// (e.g. after async auth completes)
|
|
23
|
+
await aui.threads().reload();
|
|
24
|
+
|
|
21
25
|
// Access the main thread runtime
|
|
22
26
|
const mainThread = aui.threads().main;
|
|
23
27
|
|
|
@@ -166,7 +166,7 @@ export default function ChatPage() {
|
|
|
166
166
|
name: "history",
|
|
167
167
|
type: "ThreadHistoryAdapter",
|
|
168
168
|
description:
|
|
169
|
-
"Adapter for loading and saving thread history. Used to restore previous messages when switching threads.",
|
|
169
|
+
"Adapter for loading and saving thread history. Used to restore previous messages when switching threads. The adapter must implement `withFormat` when used with AI SDK — see [Persisting Chat History](/docs/runtimes/ai-sdk/v6#persisting-chat-history).",
|
|
170
170
|
},
|
|
171
171
|
],
|
|
172
172
|
},
|
|
@@ -104,26 +104,31 @@ The primitive's behavior (keyboard handling, disabled state, form submission) is
|
|
|
104
104
|
|
|
105
105
|
### Unstable Trigger Popovers
|
|
106
106
|
|
|
107
|
-
Composer includes an unstable **trigger popover** system for character-triggered popovers (e.g. `@` for mentions, `/` for slash commands). Multiple triggers
|
|
108
|
-
|
|
109
|
-
**Mentions** (`@` trigger) — insert directive text into the message:
|
|
107
|
+
Composer includes an unstable **trigger popover** system for character-triggered popovers (e.g. `@` for mentions, `/` for slash commands). Multiple triggers coexist under a single `TriggerPopoverRoot`.
|
|
110
108
|
|
|
111
109
|
```tsx
|
|
112
|
-
<ComposerPrimitive.
|
|
110
|
+
<ComposerPrimitive.Unstable_TriggerPopoverRoot>
|
|
113
111
|
<ComposerPrimitive.Root>
|
|
114
|
-
<ComposerPrimitive.Input placeholder="Type @ to mention..." />
|
|
115
|
-
<ComposerPrimitive.Unstable_MentionPopover />
|
|
116
|
-
</ComposerPrimitive.Root>
|
|
117
|
-
</ComposerPrimitive.Unstable_MentionRoot>
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
**Slash commands** (`/` trigger) — execute an action and clear the command text:
|
|
112
|
+
<ComposerPrimitive.Input placeholder="Type @ to mention, / for commands..." />
|
|
121
113
|
|
|
122
|
-
|
|
123
|
-
<ComposerPrimitive.
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
114
|
+
{/* @ mention — inserts directive text into the message */}
|
|
115
|
+
<ComposerPrimitive.Unstable_TriggerPopover
|
|
116
|
+
char="@"
|
|
117
|
+
adapter={mentionAdapter}
|
|
118
|
+
>
|
|
119
|
+
<ComposerPrimitive.Unstable_TriggerPopover.Directive formatter={formatter} />
|
|
120
|
+
{/* popover UI */}
|
|
121
|
+
</ComposerPrimitive.Unstable_TriggerPopover>
|
|
122
|
+
|
|
123
|
+
{/* / slash command — runs a handler on selection; leaves an audit-trail chip by default */}
|
|
124
|
+
<ComposerPrimitive.Unstable_TriggerPopover
|
|
125
|
+
char="/"
|
|
126
|
+
adapter={slashAdapter}
|
|
127
|
+
>
|
|
128
|
+
<ComposerPrimitive.Unstable_TriggerPopover.Action
|
|
129
|
+
formatter={formatter}
|
|
130
|
+
onExecute={(item) => commandHandlers[item.id]?.()}
|
|
131
|
+
/>
|
|
127
132
|
<ComposerPrimitive.Unstable_TriggerPopoverItems>
|
|
128
133
|
{(items) => items.map(item => (
|
|
129
134
|
<ComposerPrimitive.Unstable_TriggerPopoverItem key={item.id} item={item}>
|
|
@@ -131,9 +136,9 @@ Composer includes an unstable **trigger popover** system for character-triggered
|
|
|
131
136
|
</ComposerPrimitive.Unstable_TriggerPopoverItem>
|
|
132
137
|
))}
|
|
133
138
|
</ComposerPrimitive.Unstable_TriggerPopoverItems>
|
|
134
|
-
</ComposerPrimitive.
|
|
139
|
+
</ComposerPrimitive.Unstable_TriggerPopover>
|
|
135
140
|
</ComposerPrimitive.Root>
|
|
136
|
-
</ComposerPrimitive.
|
|
141
|
+
</ComposerPrimitive.Unstable_TriggerPopoverRoot>
|
|
137
142
|
```
|
|
138
143
|
|
|
139
144
|
See the [Mentions guide](/docs/guides/mentions) and [Slash Commands guide](/docs/guides/slash-commands) for full documentation.
|
|
@@ -313,103 +318,130 @@ Clears the active quote from the composer. Renders a `<button>` element unless `
|
|
|
313
318
|
</ComposerPrimitive.QuoteDismiss>
|
|
314
319
|
```
|
|
315
320
|
|
|
316
|
-
###
|
|
321
|
+
### Unstable_TriggerPopoverRoot
|
|
317
322
|
|
|
318
|
-
|
|
323
|
+
Root provider that groups one or more `TriggerPopover` declarations and owns the shared input plugin registry.
|
|
319
324
|
|
|
320
325
|
```tsx
|
|
321
|
-
<ComposerPrimitive.
|
|
326
|
+
<ComposerPrimitive.Unstable_TriggerPopoverRoot>
|
|
322
327
|
<ComposerPrimitive.Root>
|
|
323
|
-
<LexicalComposerInput placeholder="Type @ to mention
|
|
324
|
-
<ComposerPrimitive.
|
|
328
|
+
<LexicalComposerInput placeholder="Type @ to mention, / for commands..." />
|
|
329
|
+
<ComposerPrimitive.Unstable_TriggerPopover char="@" adapter={mentionAdapter}>
|
|
330
|
+
<ComposerPrimitive.Unstable_TriggerPopover.Directive formatter={formatter} />
|
|
331
|
+
...
|
|
332
|
+
</ComposerPrimitive.Unstable_TriggerPopover>
|
|
325
333
|
</ComposerPrimitive.Root>
|
|
326
|
-
</ComposerPrimitive.
|
|
334
|
+
</ComposerPrimitive.Unstable_TriggerPopoverRoot>
|
|
327
335
|
```
|
|
328
336
|
|
|
329
|
-
|
|
337
|
+
### Unstable_TriggerPopover
|
|
330
338
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
Container for the mention picker popover. It only renders while a trigger match is active.
|
|
339
|
+
Declares a trigger (by `char`, `adapter`) and renders the popover container. Selection behavior is declared by rendering exactly one behavior sub-primitive inside — either `<Unstable_TriggerPopover.Directive>` (insert a directive on selection) or `<Unstable_TriggerPopover.Action>` (run `onExecute` on selection). Only renders its DOM (and children) while the trigger is active in the composer input.
|
|
334
340
|
|
|
335
341
|
```tsx
|
|
336
|
-
<ComposerPrimitive.
|
|
337
|
-
|
|
342
|
+
<ComposerPrimitive.Unstable_TriggerPopover
|
|
343
|
+
char="@"
|
|
344
|
+
adapter={mentionAdapter}
|
|
345
|
+
className="rounded-lg border bg-popover p-1 shadow-md"
|
|
346
|
+
>
|
|
347
|
+
<ComposerPrimitive.Unstable_TriggerPopover.Directive formatter={formatter} />
|
|
348
|
+
<ComposerPrimitive.Unstable_TriggerPopoverCategories>
|
|
338
349
|
{(categories) => categories.map((category) => (
|
|
339
|
-
<ComposerPrimitive.
|
|
350
|
+
<ComposerPrimitive.Unstable_TriggerPopoverCategoryItem
|
|
340
351
|
key={category.id}
|
|
341
352
|
categoryId={category.id}
|
|
342
353
|
>
|
|
343
354
|
{category.label}
|
|
344
|
-
</ComposerPrimitive.
|
|
355
|
+
</ComposerPrimitive.Unstable_TriggerPopoverCategoryItem>
|
|
345
356
|
))}
|
|
346
|
-
</ComposerPrimitive.
|
|
347
|
-
</ComposerPrimitive.
|
|
357
|
+
</ComposerPrimitive.Unstable_TriggerPopoverCategories>
|
|
358
|
+
</ComposerPrimitive.Unstable_TriggerPopover>
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
Behavior is supplied by exactly one of two sub-primitives:
|
|
362
|
+
|
|
363
|
+
- `<Unstable_TriggerPopover.Directive formatter={...} onInserted={...} />` — writes `:type[label]{name=id}` into the composer text (mention behavior)
|
|
364
|
+
- `<Unstable_TriggerPopover.Action onExecute={...} removeOnExecute={...} />` — runs a callback on selection; leaves a directive chip behind by default (slash-command behavior)
|
|
365
|
+
|
|
366
|
+
### Unstable_TriggerPopover.Directive
|
|
367
|
+
|
|
368
|
+
Behavior sub-primitive. Registers the directive-insert behavior with its parent `TriggerPopover`. Renders nothing.
|
|
369
|
+
|
|
370
|
+
```tsx
|
|
371
|
+
<ComposerPrimitive.Unstable_TriggerPopover.Directive
|
|
372
|
+
formatter={unstable_defaultDirectiveFormatter}
|
|
373
|
+
onInserted={(item) => track("mention", item.id)}
|
|
374
|
+
/>
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
### Unstable_TriggerPopover.Action
|
|
378
|
+
|
|
379
|
+
Behavior sub-primitive. Registers the action behavior with its parent `TriggerPopover`. Renders nothing. By default leaves a directive chip behind after executing (audit trail); pass `removeOnExecute` to strip the trigger text entirely.
|
|
380
|
+
|
|
381
|
+
```tsx
|
|
382
|
+
<ComposerPrimitive.Unstable_TriggerPopover.Action
|
|
383
|
+
onExecute={(item) => commandHandlers[item.id]?.()}
|
|
384
|
+
removeOnExecute={false}
|
|
385
|
+
/>
|
|
348
386
|
```
|
|
349
387
|
|
|
350
|
-
###
|
|
388
|
+
### Unstable_TriggerPopoverCategories
|
|
351
389
|
|
|
352
|
-
Render-function primitive for the top-level
|
|
390
|
+
Render-function primitive for the top-level category list. Only renders while no category is active and search mode is off.
|
|
353
391
|
|
|
354
392
|
```tsx
|
|
355
|
-
<ComposerPrimitive.
|
|
393
|
+
<ComposerPrimitive.Unstable_TriggerPopoverCategories>
|
|
356
394
|
{(categories) => categories.map((category) => (
|
|
357
|
-
<ComposerPrimitive.
|
|
395
|
+
<ComposerPrimitive.Unstable_TriggerPopoverCategoryItem
|
|
358
396
|
key={category.id}
|
|
359
397
|
categoryId={category.id}
|
|
360
398
|
>
|
|
361
399
|
{category.label}
|
|
362
|
-
</ComposerPrimitive.
|
|
400
|
+
</ComposerPrimitive.Unstable_TriggerPopoverCategoryItem>
|
|
363
401
|
))}
|
|
364
|
-
</ComposerPrimitive.
|
|
402
|
+
</ComposerPrimitive.Unstable_TriggerPopoverCategories>
|
|
365
403
|
```
|
|
366
404
|
|
|
367
|
-
|
|
405
|
+
### Unstable_TriggerPopoverCategoryItem
|
|
368
406
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
Button that selects a mention category and drills into its items.
|
|
407
|
+
Button that selects a category and drills into its items.
|
|
372
408
|
|
|
373
409
|
```tsx
|
|
374
|
-
<ComposerPrimitive.
|
|
410
|
+
<ComposerPrimitive.Unstable_TriggerPopoverCategoryItem categoryId="tools">
|
|
375
411
|
Tools
|
|
376
|
-
</ComposerPrimitive.
|
|
412
|
+
</ComposerPrimitive.Unstable_TriggerPopoverCategoryItem>
|
|
377
413
|
```
|
|
378
414
|
|
|
379
|
-
###
|
|
415
|
+
### Unstable_TriggerPopoverItems
|
|
380
416
|
|
|
381
|
-
Render-function primitive for the items inside the currently selected category.
|
|
417
|
+
Render-function primitive for the items inside the currently selected category (or global search results).
|
|
382
418
|
|
|
383
419
|
```tsx
|
|
384
|
-
<ComposerPrimitive.
|
|
420
|
+
<ComposerPrimitive.Unstable_TriggerPopoverItems>
|
|
385
421
|
{(items) => items.map((item) => (
|
|
386
|
-
<ComposerPrimitive.
|
|
422
|
+
<ComposerPrimitive.Unstable_TriggerPopoverItem key={item.id} item={item} />
|
|
387
423
|
))}
|
|
388
|
-
</ComposerPrimitive.
|
|
424
|
+
</ComposerPrimitive.Unstable_TriggerPopoverItems>
|
|
389
425
|
```
|
|
390
426
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
### Unstable_MentionItem
|
|
427
|
+
### Unstable_TriggerPopoverItem
|
|
394
428
|
|
|
395
|
-
Selectable
|
|
429
|
+
Selectable item inside the popover.
|
|
396
430
|
|
|
397
431
|
```tsx
|
|
398
|
-
<ComposerPrimitive.
|
|
432
|
+
<ComposerPrimitive.Unstable_TriggerPopoverItem item={item}>
|
|
399
433
|
{item.label}
|
|
400
|
-
</ComposerPrimitive.
|
|
434
|
+
</ComposerPrimitive.Unstable_TriggerPopoverItem>
|
|
401
435
|
```
|
|
402
436
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
### Unstable_MentionBack
|
|
437
|
+
### Unstable_TriggerPopoverBack
|
|
406
438
|
|
|
407
439
|
Back button used when drilling from categories into a specific item list.
|
|
408
440
|
|
|
409
441
|
```tsx
|
|
410
|
-
<ComposerPrimitive.
|
|
442
|
+
<ComposerPrimitive.Unstable_TriggerPopoverBack className="rounded-md px-2 py-1 text-sm hover:bg-accent">
|
|
411
443
|
Back
|
|
412
|
-
</ComposerPrimitive.
|
|
444
|
+
</ComposerPrimitive.Unstable_TriggerPopoverBack>
|
|
413
445
|
```
|
|
414
446
|
|
|
415
447
|
## Patterns
|
|
@@ -154,6 +154,63 @@ export function TokenCounter() {
|
|
|
154
154
|
</Step>
|
|
155
155
|
</Steps>
|
|
156
156
|
|
|
157
|
+
## Persisting Chat History
|
|
158
|
+
|
|
159
|
+
By default, messages live only in memory and reset on reload. To persist and restore history per thread, provide a `ThreadHistoryAdapter` via `adapters.history`.
|
|
160
|
+
|
|
161
|
+
<Callout type="warn">
|
|
162
|
+
The adapter **must** implement `withFormat`. `useChatRuntime` persists history through `withFormat(fmt)` so messages round-trip as AI SDK `UIMessage` objects. An adapter without `withFormat` throws at runtime — `load` / `append` on the top level are unused in the AI SDK path.
|
|
163
|
+
</Callout>
|
|
164
|
+
|
|
165
|
+
<Callout type="info">
|
|
166
|
+
For server-side cloud persistence with zero adapter code, see the [AssistantCloud integration](/docs/cloud/ai-sdk-assistant-ui).
|
|
167
|
+
</Callout>
|
|
168
|
+
|
|
169
|
+
### Example
|
|
170
|
+
|
|
171
|
+
```tsx
|
|
172
|
+
"use client";
|
|
173
|
+
|
|
174
|
+
import { useChatRuntime } from "@assistant-ui/react-ai-sdk";
|
|
175
|
+
import type { ThreadHistoryAdapter } from "@assistant-ui/react";
|
|
176
|
+
|
|
177
|
+
const historyAdapter: ThreadHistoryAdapter = {
|
|
178
|
+
// Required by the type — unused by useChatRuntime.
|
|
179
|
+
async load() {
|
|
180
|
+
return { headId: null, messages: [] };
|
|
181
|
+
},
|
|
182
|
+
async append() {},
|
|
183
|
+
|
|
184
|
+
// `fmt` encodes UIMessage ↔ storage rows (ai-sdk/v6 format).
|
|
185
|
+
withFormat: (fmt) => ({
|
|
186
|
+
async load() {
|
|
187
|
+
const rows = await fetch("/api/history").then((r) => r.json());
|
|
188
|
+
return { messages: rows.map(fmt.decode) };
|
|
189
|
+
},
|
|
190
|
+
async append(item) {
|
|
191
|
+
await fetch("/api/history", {
|
|
192
|
+
method: "POST",
|
|
193
|
+
body: JSON.stringify({
|
|
194
|
+
id: fmt.getId(item.message),
|
|
195
|
+
parent_id: item.parentId,
|
|
196
|
+
format: fmt.format,
|
|
197
|
+
content: fmt.encode(item),
|
|
198
|
+
}),
|
|
199
|
+
});
|
|
200
|
+
},
|
|
201
|
+
}),
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
function Chat() {
|
|
205
|
+
const runtime = useChatRuntime({
|
|
206
|
+
adapters: { history: historyAdapter },
|
|
207
|
+
});
|
|
208
|
+
// ...
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Each persisted row follows `{ id, parent_id, format, content }`; `fmt.encode` produces the `content` payload and `fmt.decode` reverses it, so your backend never needs to know about `UIMessage` internals.
|
|
213
|
+
|
|
157
214
|
## Key Changes from v5
|
|
158
215
|
|
|
159
216
|
| Feature | v5 | v6 |
|
|
@@ -216,12 +216,58 @@ When the hook mounts it calls `list()` on your adapter, hydrates existing thread
|
|
|
216
216
|
|
|
217
217
|
## Thread Lifecycle Cheatsheet
|
|
218
218
|
|
|
219
|
-
- `list()` hydrates threads on mount
|
|
219
|
+
- `list()` hydrates threads on mount. It runs once; call `runtime.threads.reload()` to re-fetch.
|
|
220
220
|
- Creating a new conversation calls `initialize()` once the user sends the first message.
|
|
221
221
|
- `archive`, `unarchive`, and `delete` are called optimistically; throw to revert the UI.
|
|
222
222
|
- `generateTitle()` powers the automatic title button and expects an `AssistantStream`.
|
|
223
223
|
- Provide a `runtimeHook` that always returns a fresh runtime instance per active thread.
|
|
224
224
|
|
|
225
|
+
## Reloading After Async Authentication
|
|
226
|
+
|
|
227
|
+
If your adapter depends on an authenticated user (e.g. an OIDC provider, `better-auth`, `next-auth`) and the auth state resolves asynchronously after `useRemoteThreadListRuntime` has mounted, the initial `list()` call may run before the user is available. Call `aui.threads().reload()` when auth completes to re-fetch with the authenticated request.
|
|
228
|
+
|
|
229
|
+
```tsx title="app/ThreadListProvider.tsx"
|
|
230
|
+
"use client";
|
|
231
|
+
|
|
232
|
+
import { useEffect } from "react";
|
|
233
|
+
import { useAuth } from "react-oidc-context";
|
|
234
|
+
import {
|
|
235
|
+
AssistantRuntimeProvider,
|
|
236
|
+
useAui,
|
|
237
|
+
useLocalRuntime,
|
|
238
|
+
useRemoteThreadListRuntime,
|
|
239
|
+
} from "@assistant-ui/react";
|
|
240
|
+
|
|
241
|
+
function ReloadOnAuth() {
|
|
242
|
+
const aui = useAui();
|
|
243
|
+
const { isLoading, user } = useAuth();
|
|
244
|
+
|
|
245
|
+
useEffect(() => {
|
|
246
|
+
if (!isLoading && user) {
|
|
247
|
+
aui.threads().reload();
|
|
248
|
+
}
|
|
249
|
+
}, [isLoading, user?.id]);
|
|
250
|
+
|
|
251
|
+
return null;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
export function ThreadListProvider({ children }) {
|
|
255
|
+
const runtime = useRemoteThreadListRuntime({
|
|
256
|
+
runtimeHook: () => useLocalRuntime(myModelAdapter),
|
|
257
|
+
adapter: useThreadListAdapter(),
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
return (
|
|
261
|
+
<AssistantRuntimeProvider runtime={runtime}>
|
|
262
|
+
<ReloadOnAuth />
|
|
263
|
+
{children}
|
|
264
|
+
</AssistantRuntimeProvider>
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
`reload()` replaces the cached load promise and discards any in-flight response from a superseded call, so it is safe to invoke multiple times (for example, on logout followed by a new login). `useAui` must be called inside `AssistantRuntimeProvider`, so the effect lives in a child component.
|
|
270
|
+
|
|
225
271
|
## Avoiding Race Conditions in History Adapters
|
|
226
272
|
|
|
227
273
|
<Callout type="warn">
|