@assistant-ui/mcp-docs-server 0.1.36 → 0.1.39
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 +8 -9
- package/.docs/organized/code-examples/with-a2a.md +16 -11
- package/.docs/organized/code-examples/with-ag-ui.md +16 -11
- package/.docs/organized/code-examples/{with-ai-sdk-v6.md → with-ai-sdk-v7.md} +32 -21
- package/.docs/organized/code-examples/with-artifacts.md +17 -10
- package/.docs/organized/code-examples/with-assistant-transport.md +15 -8
- package/.docs/organized/code-examples/with-browser-extension.md +15 -8
- package/.docs/organized/code-examples/with-chain-of-thought.md +17 -10
- package/.docs/organized/code-examples/with-cloud-standalone.md +10 -9
- package/.docs/organized/code-examples/with-cloud.md +18 -13
- package/.docs/organized/code-examples/with-custom-thread-list.md +17 -10
- package/.docs/organized/code-examples/with-elevenlabs-conversational.md +20 -13
- package/.docs/organized/code-examples/with-elevenlabs-scribe.md +20 -13
- package/.docs/organized/code-examples/with-eve.md +16 -9
- package/.docs/organized/code-examples/with-expo.md +26 -23
- package/.docs/organized/code-examples/with-external-store.md +16 -11
- package/.docs/organized/code-examples/with-ffmpeg.md +18 -13
- package/.docs/organized/code-examples/with-generative-ui.md +20 -15
- package/.docs/organized/code-examples/with-google-adk.md +16 -9
- package/.docs/organized/code-examples/with-heat-graph.md +8 -9
- package/.docs/organized/code-examples/with-image-generation.md +17 -10
- package/.docs/organized/code-examples/with-interactables.md +19 -15
- package/.docs/organized/code-examples/with-langchain.md +17 -10
- package/.docs/organized/code-examples/with-langgraph.md +17 -10
- package/.docs/organized/code-examples/with-livekit.md +21 -14
- package/.docs/organized/code-examples/with-mcp.md +40 -18
- package/.docs/organized/code-examples/with-opencode.md +22 -17
- package/.docs/organized/code-examples/with-pi.md +47 -12
- package/.docs/organized/code-examples/with-react-hook-form.md +19 -14
- package/.docs/organized/code-examples/with-react-ink-web.md +6 -6
- package/.docs/organized/code-examples/with-react-ink.md +2 -2
- package/.docs/organized/code-examples/with-react-router.md +20 -15
- package/.docs/organized/code-examples/with-resumable-stream.md +19 -12
- package/.docs/organized/code-examples/with-store.md +8 -9
- package/.docs/organized/code-examples/with-tanstack.md +17 -11
- package/.docs/organized/code-examples/with-tap-runtime.md +16 -11
- package/.docs/organized/code-examples/with-virtualized-thread.md +17 -12
- package/.docs/raw/docs/(docs)/base-ui.mdx +39 -0
- package/.docs/raw/docs/(docs)/cli.mdx +18 -2
- package/.docs/raw/docs/(docs)/installation.mdx +15 -1
- package/.docs/raw/docs/(docs)/rtl.mdx +2 -4
- package/.docs/raw/docs/(reference)/api-reference/generative-ui/actions.mdx +56 -0
- package/.docs/raw/docs/(reference)/api-reference/generative-ui/components.mdx +86 -0
- package/.docs/raw/docs/(reference)/api-reference/generative-ui/index.mdx +19 -1
- package/.docs/raw/docs/(reference)/api-reference/generative-ui/json-generative-ui.mdx +42 -0
- package/.docs/raw/docs/(reference)/api-reference/generative-ui/rendering.mdx +53 -2
- package/.docs/raw/docs/(reference)/api-reference/generative-ui/slack.mdx +81 -0
- package/.docs/raw/docs/(reference)/api-reference/generative-ui/teams.mdx +86 -0
- package/.docs/raw/docs/(reference)/api-reference/generative-ui/tokens.mdx +62 -0
- package/.docs/raw/docs/(reference)/api-reference/integrations/index.mdx +4 -1
- package/.docs/raw/docs/(reference)/api-reference/integrations/react-ai-sdk.mdx +4 -2
- package/.docs/raw/docs/(reference)/api-reference/integrations/react-data-stream.mdx +37 -0
- package/.docs/raw/docs/(reference)/api-reference/overview.mdx +1 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-if.mdx +29 -29
- package/.docs/raw/docs/(reference)/api-reference/primitives/composition.mdx +1 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/index.mdx +3 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/selection-toolbar.mdx +2 -0
- package/.docs/raw/docs/(reference)/api-reference/tools/status.mdx +0 -2
- package/.docs/raw/docs/(reference)/api-reference/tools/toolkits.mdx +12 -9
- package/.docs/raw/docs/(reference)/api-reference/utilities/miscellaneous.mdx +4 -0
- package/.docs/raw/docs/cloud/ai-sdk-assistant-ui.mdx +7 -1
- package/.docs/raw/docs/cloud/langgraph.mdx +4 -2
- package/.docs/raw/docs/guides/chatgpt-subscription.mdx +108 -0
- package/.docs/raw/docs/guides/dictation.mdx +185 -257
- package/.docs/raw/docs/guides/index.mdx +10 -0
- package/.docs/raw/docs/guides/mentions.mdx +31 -3
- package/.docs/raw/docs/guides/resumable-streams.mdx +12 -1
- package/.docs/raw/docs/guides/speech.mdx +47 -29
- package/.docs/raw/docs/guides/suggestions.mdx +70 -1
- package/.docs/raw/docs/guides/voice.mdx +197 -267
- package/.docs/raw/docs/ink/primitives.mdx +35 -1
- package/.docs/raw/docs/integrations/frameworks/ai-sdk.mdx +13 -7
- package/.docs/raw/docs/integrations/frameworks/cloudflare-agents/overview.mdx +3 -3
- package/.docs/raw/docs/integrations/frameworks/mastra/full-stack.mdx +1 -1
- package/.docs/raw/docs/integrations/frameworks/mastra/overview.mdx +3 -3
- package/.docs/raw/docs/integrations/frameworks/mastra/separate-server.mdx +1 -1
- package/.docs/raw/docs/integrations/gateways/index.mdx +2 -2
- package/.docs/raw/docs/integrations/index.mdx +1 -1
- package/.docs/raw/docs/integrations/observability/helicone.mdx +1 -1
- package/.docs/raw/docs/integrations/observability/langfuse.mdx +1 -1
- package/.docs/raw/docs/integrations/observability/langsmith.mdx +3 -3
- package/.docs/raw/docs/migrations/index.mdx +50 -0
- package/.docs/raw/docs/migrations/react-langgraph-v0-7.mdx +2 -2
- package/.docs/raw/docs/migrations/toolkit-tools.mdx +4 -2
- package/.docs/raw/docs/primitives/chain-of-thought.mdx +6 -1
- package/.docs/raw/docs/primitives/composer.mdx +16 -0
- package/.docs/raw/docs/primitives/selection-toolbar.mdx +25 -0
- package/.docs/raw/docs/primitives/thread-list.mdx +30 -6
- package/.docs/raw/docs/react-native/primitives.mdx +23 -0
- package/.docs/raw/docs/runtimes/a2a/quickstart.mdx +1 -1
- package/.docs/raw/docs/runtimes/ag-ui/agent-state.mdx +124 -0
- package/.docs/raw/docs/runtimes/ag-ui/quickstart.mdx +1 -1
- package/.docs/raw/docs/runtimes/ag-ui/runtime-options.mdx +13 -2
- package/.docs/raw/docs/runtimes/ai-sdk/overview.mdx +13 -4
- package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +11 -11
- package/.docs/raw/docs/runtimes/ai-sdk/v5-legacy.mdx +5 -5
- package/.docs/raw/docs/runtimes/ai-sdk/{v6.mdx → v6-legacy.mdx} +8 -6
- package/.docs/raw/docs/runtimes/ai-sdk/v7.mdx +717 -0
- package/.docs/raw/docs/runtimes/concepts/adapters.mdx +1 -1
- package/.docs/raw/docs/runtimes/concepts/architecture.mdx +1 -1
- package/.docs/raw/docs/runtimes/custom/data-stream.mdx +10 -19
- package/.docs/raw/docs/runtimes/custom/external-store.mdx +1 -1
- package/.docs/raw/docs/runtimes/custom/local-runtime.mdx +2 -0
- package/.docs/raw/docs/runtimes/eve/overview.mdx +1 -1
- package/.docs/raw/docs/runtimes/google-adk/quickstart.mdx +1 -1
- package/.docs/raw/docs/runtimes/langchain.mdx +2 -2
- package/.docs/raw/docs/runtimes/langgraph/agent-state.mdx +181 -0
- package/.docs/raw/docs/runtimes/opencode/hooks.mdx +1 -1
- package/.docs/raw/docs/tools/backend.mdx +6 -3
- package/.docs/raw/docs/tools/defining-tools.mdx +12 -1
- package/.docs/raw/docs/tools/generative-ui.mdx +95 -0
- package/.docs/raw/docs/tools/mcp-apps.mdx +37 -10
- package/.docs/raw/docs/tools/mcp.mdx +105 -3
- package/.docs/raw/docs/tools/tool-ui.mdx +6 -4
- package/.docs/raw/docs/tools/user-managed-mcp.mdx +41 -4
- package/.docs/raw/docs/ui/accordion.mdx +16 -10
- package/.docs/raw/docs/ui/assistant-modal.mdx +8 -4
- package/.docs/raw/docs/ui/attachment.mdx +5 -1
- package/.docs/raw/docs/ui/badge.mdx +23 -12
- package/.docs/raw/docs/ui/follow-up-suggestions.mdx +80 -0
- package/.docs/raw/docs/ui/model-selector.mdx +69 -6
- package/.docs/raw/docs/ui/select.mdx +22 -14
- package/.docs/raw/docs/ui/sources.mdx +1 -1
- package/.docs/raw/docs/ui/tabs.mdx +25 -14
- package/.docs/raw/docs/utilities/heat-graph.mdx +2 -2
- package/README.md +1 -1
- package/dist/constants.d.ts +2 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +2 -1
- package/dist/constants.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -1
- package/dist/prepare-docs/code-examples.d.ts.map +1 -1
- package/dist/prepare-docs/copy-raw.d.ts.map +1 -1
- package/dist/prepare-docs/copy-raw.js +0 -4
- package/dist/prepare-docs/copy-raw.js.map +1 -1
- package/dist/prompts/xulux-playground.d.ts +12 -0
- package/dist/prompts/xulux-playground.d.ts.map +1 -0
- package/dist/prompts/xulux-playground.js +33 -0
- package/dist/prompts/xulux-playground.js.map +1 -0
- package/dist/tools/docs.d.ts +2 -4
- package/dist/tools/docs.d.ts.map +1 -1
- package/dist/tools/docs.js +38 -10
- package/dist/tools/docs.js.map +1 -1
- package/dist/tools/examples.d.ts +5 -5
- package/dist/tools/examples.d.ts.map +1 -1
- package/dist/tools/examples.js +10 -7
- package/dist/tools/examples.js.map +1 -1
- package/dist/tools/resources.d.ts +6 -0
- package/dist/tools/resources.d.ts.map +1 -0
- package/dist/tools/resources.js +74 -0
- package/dist/tools/resources.js.map +1 -0
- package/dist/tools/search.d.ts +30 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +39 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/tests/test-setup.d.ts.map +1 -1
- package/dist/tools/tests/test-setup.js +7 -1
- package/dist/tools/tests/test-setup.js.map +1 -1
- package/dist/tools/xulux-templates.d.ts +72 -0
- package/dist/tools/xulux-templates.d.ts.map +1 -0
- package/dist/tools/xulux-templates.js +82 -0
- package/dist/tools/xulux-templates.js.map +1 -0
- package/dist/utils/cache.d.ts +5 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/cache.js +18 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/mcp-format.d.ts +1 -0
- package/dist/utils/mcp-format.d.ts.map +1 -1
- package/dist/utils/mcp-format.js +7 -4
- package/dist/utils/mcp-format.js.map +1 -1
- package/dist/utils/mdx.d.ts +2 -1
- package/dist/utils/mdx.d.ts.map +1 -1
- package/dist/utils/mdx.js +19 -2
- package/dist/utils/mdx.js.map +1 -1
- package/dist/utils/paths.d.ts +2 -1
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +20 -1
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/search.d.ts +10 -0
- package/dist/utils/search.d.ts.map +1 -0
- package/dist/utils/search.js +97 -0
- package/dist/utils/search.js.map +1 -0
- package/dist/utils/security.d.ts.map +1 -1
- package/dist/xulux/catalog-client.d.ts +14 -0
- package/dist/xulux/catalog-client.d.ts.map +1 -0
- package/dist/xulux/catalog-client.js +67 -0
- package/dist/xulux/catalog-client.js.map +1 -0
- package/dist/xulux/fallback-catalog.d.ts +7 -0
- package/dist/xulux/fallback-catalog.d.ts.map +1 -0
- package/dist/xulux/fallback-catalog.js +47 -0
- package/dist/xulux/fallback-catalog.js.map +1 -0
- package/dist/xulux/fetch-sandbox.d.ts +5 -0
- package/dist/xulux/fetch-sandbox.d.ts.map +1 -0
- package/dist/xulux/fetch-sandbox.js +40 -0
- package/dist/xulux/fetch-sandbox.js.map +1 -0
- package/dist/xulux/template-service.d.ts +84 -0
- package/dist/xulux/template-service.d.ts.map +1 -0
- package/dist/xulux/template-service.js +223 -0
- package/dist/xulux/template-service.js.map +1 -0
- package/dist/xulux/types.d.ts +55 -0
- package/dist/xulux/types.d.ts.map +1 -0
- package/dist/xulux/types.js +6 -0
- package/dist/xulux/types.js.map +1 -0
- package/package.json +5 -5
- package/src/constants.ts +2 -0
- package/src/index.ts +67 -0
- package/src/prepare-docs/copy-raw.ts +0 -5
- package/src/prompts/xulux-playground.ts +36 -0
- package/src/tools/docs.ts +52 -4
- package/src/tools/examples.ts +18 -11
- package/src/tools/resources.ts +114 -0
- package/src/tools/search.ts +46 -0
- package/src/tools/tests/completions.test.ts +46 -0
- package/src/tools/tests/directory-size-cap.test.ts +50 -0
- package/src/tools/tests/docs.test.ts +20 -0
- package/src/tools/tests/examples.test.ts +5 -5
- package/src/tools/tests/listings-cache.test.ts +19 -0
- package/src/tools/tests/mcp-protocol.test.ts +92 -1
- package/src/tools/tests/resources.test.ts +102 -0
- package/src/tools/tests/search.test.ts +37 -0
- package/src/tools/tests/test-setup.ts +10 -0
- package/src/tools/tests/xulux-templates.test.ts +262 -0
- package/src/tools/xulux-templates.ts +141 -0
- package/src/utils/cache.ts +20 -0
- package/src/utils/mcp-format.ts +8 -6
- package/src/utils/mdx.ts +21 -1
- package/src/utils/paths.ts +25 -0
- package/src/utils/search.ts +131 -0
- package/src/utils/tests/cache.test.ts +51 -0
- package/src/utils/tests/mcp-format.test.ts +22 -0
- package/src/utils/tests/security.test.ts +1 -1
- package/src/xulux/catalog-client.ts +105 -0
- package/src/xulux/fallback-catalog.ts +63 -0
- package/src/xulux/fetch-sandbox.ts +56 -0
- package/src/xulux/template-service.ts +406 -0
- package/src/xulux/types.ts +60 -0
- package/.docs/raw/blog/2024-07-29-hello/index.mdx +0 -64
- package/.docs/raw/blog/2024-09-11/index.mdx +0 -10
- package/.docs/raw/blog/2024-12-15/index.mdx +0 -10
- package/.docs/raw/blog/2025-01-31-changelog/index.mdx +0 -127
- package/.docs/raw/blog/2026-03-launch-week/index.mdx +0 -258
- package/.docs/raw/docs/(reference)/api-reference/hooks/utilities.mdx +0 -464
|
@@ -8,11 +8,13 @@ import { SpeechSample } from "@/components/docs/samples/speech";
|
|
|
8
8
|
|
|
9
9
|
assistant-ui supports text-to-speech via the `SpeechSynthesisAdapter` interface. When a speech adapter is configured, users can trigger playback for any assistant message.
|
|
10
10
|
|
|
11
|
+
Speech is the read-aloud mode: one message at a time, text to audio. For a live duplex conversation, see [Realtime Voice](/docs/guides/voice). For push-to-talk input into the composer, see [Dictation](/docs/guides/dictation).
|
|
12
|
+
|
|
11
13
|
<SpeechSample />
|
|
12
14
|
|
|
13
15
|
## SpeechSynthesisAdapter
|
|
14
16
|
|
|
15
|
-
The
|
|
17
|
+
The adapter has a single method. The type lives in `@assistant-ui/core` and is re-exported from `@assistant-ui/react`:
|
|
16
18
|
|
|
17
19
|
```tsx
|
|
18
20
|
import type { SpeechSynthesisAdapter } from "@assistant-ui/react";
|
|
@@ -22,26 +24,30 @@ type SpeechSynthesisAdapter = {
|
|
|
22
24
|
};
|
|
23
25
|
```
|
|
24
26
|
|
|
25
|
-
`speak`
|
|
27
|
+
`speak` receives the plain text of an assistant message and returns an `Utterance`:
|
|
26
28
|
|
|
27
29
|
```tsx
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
30
|
+
namespace SpeechSynthesisAdapter {
|
|
31
|
+
type Status =
|
|
32
|
+
| { type: "starting" | "running" }
|
|
33
|
+
| {
|
|
34
|
+
type: "ended";
|
|
35
|
+
reason: "finished" | "cancelled" | "error";
|
|
36
|
+
error?: unknown;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
type Utterance = {
|
|
40
|
+
status: Status;
|
|
41
|
+
cancel: () => void;
|
|
42
|
+
subscribe: (callback: () => void) => Unsubscribe;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
37
45
|
```
|
|
38
46
|
|
|
39
|
-
Currently the following built-in adapter is available:
|
|
40
|
-
|
|
41
|
-
- `WebSpeechSynthesisAdapter`: uses the browser's `Web Speech API` (`SpeechSynthesis`)
|
|
42
|
-
|
|
43
47
|
## WebSpeechSynthesisAdapter
|
|
44
48
|
|
|
49
|
+
The built-in adapter uses the browser's Web Speech API (`SpeechSynthesis` / `SpeechSynthesisUtterance`):
|
|
50
|
+
|
|
45
51
|
```tsx
|
|
46
52
|
import { WebSpeechSynthesisAdapter } from "@assistant-ui/react";
|
|
47
53
|
|
|
@@ -52,7 +58,9 @@ const runtime = useChatRuntime({
|
|
|
52
58
|
});
|
|
53
59
|
```
|
|
54
60
|
|
|
55
|
-
|
|
61
|
+
When a speech adapter is provided, `capabilities.speech` is set to `true` automatically.
|
|
62
|
+
|
|
63
|
+
## UI: ActionBarPrimitive.Speak
|
|
56
64
|
|
|
57
65
|
The default action bar does not include a speech button. Add `ActionBarPrimitive.Speak` and `ActionBarPrimitive.StopSpeaking` to your assistant message action bar:
|
|
58
66
|
|
|
@@ -79,21 +87,17 @@ const AssistantActionBar = () => {
|
|
|
79
87
|
};
|
|
80
88
|
```
|
|
81
89
|
|
|
82
|
-
`ActionBarPrimitive.Speak` is
|
|
90
|
+
`ActionBarPrimitive.Speak` is disabled when no speech adapter is configured. While playback is active, `message.speech` holds the current speech state so the UI can switch to `StopSpeaking`.
|
|
83
91
|
|
|
84
|
-
## Custom
|
|
92
|
+
## Custom adapters
|
|
85
93
|
|
|
86
|
-
Implement `SpeechSynthesisAdapter` to call any external TTS API
|
|
94
|
+
Implement `SpeechSynthesisAdapter` to call any external TTS provider. Fetch audio from your API, play it with `HTMLAudioElement`, and drive utterance status through `subscribe`:
|
|
87
95
|
|
|
88
96
|
```tsx title="lib/custom-tts-adapter.ts"
|
|
89
97
|
import type { SpeechSynthesisAdapter } from "@assistant-ui/react";
|
|
90
98
|
|
|
91
99
|
export class CustomTTSAdapter implements SpeechSynthesisAdapter {
|
|
92
|
-
private apiUrl: string
|
|
93
|
-
|
|
94
|
-
constructor(options: { apiUrl: string }) {
|
|
95
|
-
this.apiUrl = options.apiUrl;
|
|
96
|
-
}
|
|
100
|
+
constructor(private apiUrl: string) {}
|
|
97
101
|
|
|
98
102
|
speak(text: string): SpeechSynthesisAdapter.Utterance {
|
|
99
103
|
const subscribers = new Set<() => void>();
|
|
@@ -104,7 +108,10 @@ export class CustomTTSAdapter implements SpeechSynthesisAdapter {
|
|
|
104
108
|
for (const cb of subscribers) cb();
|
|
105
109
|
};
|
|
106
110
|
|
|
107
|
-
const finish = (
|
|
111
|
+
const finish = (
|
|
112
|
+
reason: "finished" | "cancelled" | "error",
|
|
113
|
+
error?: unknown,
|
|
114
|
+
) => {
|
|
108
115
|
if (status.type === "ended") return;
|
|
109
116
|
status = { type: "ended", reason, error };
|
|
110
117
|
notify();
|
|
@@ -117,17 +124,20 @@ export class CustomTTSAdapter implements SpeechSynthesisAdapter {
|
|
|
117
124
|
})
|
|
118
125
|
.then((res) => res.blob())
|
|
119
126
|
.then((blob) => {
|
|
127
|
+
if (status.type === "ended") return;
|
|
120
128
|
audio = new Audio(URL.createObjectURL(blob));
|
|
121
129
|
status = { type: "running" };
|
|
122
130
|
notify();
|
|
123
131
|
audio.onended = () => finish("finished");
|
|
124
132
|
audio.onerror = (e) => finish("error", e);
|
|
125
|
-
audio.play();
|
|
133
|
+
audio.play().catch((err) => finish("error", err));
|
|
126
134
|
})
|
|
127
135
|
.catch((err) => finish("error", err));
|
|
128
136
|
|
|
129
137
|
return {
|
|
130
|
-
get status() {
|
|
138
|
+
get status() {
|
|
139
|
+
return status;
|
|
140
|
+
},
|
|
131
141
|
cancel: () => {
|
|
132
142
|
audio?.pause();
|
|
133
143
|
finish("cancelled");
|
|
@@ -141,14 +151,22 @@ export class CustomTTSAdapter implements SpeechSynthesisAdapter {
|
|
|
141
151
|
}
|
|
142
152
|
```
|
|
143
153
|
|
|
144
|
-
Wire it
|
|
154
|
+
Wire it on the same `adapters.speech` slot as the built-in adapter:
|
|
145
155
|
|
|
146
156
|
```tsx
|
|
147
157
|
import { CustomTTSAdapter } from "@/lib/custom-tts-adapter";
|
|
148
158
|
|
|
149
159
|
const runtime = useChatRuntime({
|
|
150
160
|
adapters: {
|
|
151
|
-
speech: new CustomTTSAdapter(
|
|
161
|
+
speech: new CustomTTSAdapter("/api/tts"),
|
|
152
162
|
},
|
|
153
163
|
});
|
|
154
164
|
```
|
|
165
|
+
|
|
166
|
+
Use this shape for any provider TTS (OpenAI, ElevenLabs, cloud speech APIs, and so on). Keep the server route responsible for API keys; the adapter only needs a URL that returns audio bytes.
|
|
167
|
+
|
|
168
|
+
## Related guides
|
|
169
|
+
|
|
170
|
+
- [Realtime Voice](/docs/guides/voice): duplex voice sessions with `RealtimeVoiceAdapter`, `createVoiceSession`, and the voice UI component.
|
|
171
|
+
- [Dictation](/docs/guides/dictation): speech-to-text into the composer with `DictationAdapter` and `ComposerPrimitive.Dictate`.
|
|
172
|
+
- [Speech and Dictation API reference](/docs/api-reference/voice/speech-dictation): generated type docs.
|
|
@@ -163,6 +163,30 @@ const runtime = useLocalRuntime(myChatModel, {
|
|
|
163
163
|
});
|
|
164
164
|
```
|
|
165
165
|
|
|
166
|
+
For LLM-powered follow ups, use `createSuggestionAdapter`. It builds a deterministic transcript prompt from recent messages and calls your `complete` function. Forward the optional `signal` so in-flight generation can be cancelled when a new run starts.
|
|
167
|
+
|
|
168
|
+
```tsx
|
|
169
|
+
import { createSuggestionAdapter, useLocalRuntime } from "@assistant-ui/react";
|
|
170
|
+
|
|
171
|
+
const suggestionAdapter = createSuggestionAdapter({
|
|
172
|
+
async complete({ prompt, signal }) {
|
|
173
|
+
const response = await fetch("/api/suggestions", {
|
|
174
|
+
method: "POST",
|
|
175
|
+
headers: { "Content-Type": "application/json" },
|
|
176
|
+
body: JSON.stringify({ prompt }),
|
|
177
|
+
signal,
|
|
178
|
+
});
|
|
179
|
+
const data: string[] = await response.json();
|
|
180
|
+
return data;
|
|
181
|
+
},
|
|
182
|
+
count: 3,
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
const runtime = useLocalRuntime(myChatModel, {
|
|
186
|
+
adapters: { suggestion: suggestionAdapter },
|
|
187
|
+
});
|
|
188
|
+
```
|
|
189
|
+
|
|
166
190
|
### External store runtime
|
|
167
191
|
|
|
168
192
|
`useExternalStoreRuntime` exposes a `suggestions` field, so you can drive follow ups straight from your application state.
|
|
@@ -190,7 +214,52 @@ const [suggestions, setSuggestions] = useState<ThreadSuggestion[]>([]);
|
|
|
190
214
|
const runtime = useChatRuntime({ suggestions });
|
|
191
215
|
```
|
|
192
216
|
|
|
193
|
-
|
|
217
|
+
They also accept the same `suggestion` adapter as the local runtime under `adapters`, so one adapter works across both runtimes. When set, the adapter owns `thread.suggestions` after each run settles, and any static `suggestions` option is ignored. Pair it with `createSuggestionAdapter` for built-in prompt construction:
|
|
218
|
+
|
|
219
|
+
```tsx
|
|
220
|
+
import { createSuggestionAdapter } from "@assistant-ui/react";
|
|
221
|
+
import { useChatRuntime } from "@assistant-ui/react-ai-sdk";
|
|
222
|
+
|
|
223
|
+
const runtime = useChatRuntime({
|
|
224
|
+
adapters: {
|
|
225
|
+
suggestion: createSuggestionAdapter({
|
|
226
|
+
async complete({ prompt, signal }) {
|
|
227
|
+
const response = await fetch("/api/suggestions", {
|
|
228
|
+
method: "POST",
|
|
229
|
+
headers: { "Content-Type": "application/json" },
|
|
230
|
+
body: JSON.stringify({ prompt }),
|
|
231
|
+
signal,
|
|
232
|
+
});
|
|
233
|
+
return response.json();
|
|
234
|
+
},
|
|
235
|
+
}),
|
|
236
|
+
},
|
|
237
|
+
});
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
Example route that returns suggestion strings with the AI SDK:
|
|
241
|
+
|
|
242
|
+
```ts
|
|
243
|
+
// app/api/suggestions/route.ts
|
|
244
|
+
import { generateObject } from "ai";
|
|
245
|
+
import { z } from "zod";
|
|
246
|
+
|
|
247
|
+
export async function POST(req: Request) {
|
|
248
|
+
const { prompt } = await req.json();
|
|
249
|
+
|
|
250
|
+
const { object } = await generateObject({
|
|
251
|
+
model: yourModel,
|
|
252
|
+
schema: z.object({
|
|
253
|
+
suggestions: z.array(z.string()).min(1).max(5),
|
|
254
|
+
}),
|
|
255
|
+
prompt,
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
return Response.json(object.suggestions);
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
The local runtime clears its suggestions when a new run starts. External store runtimes keep whatever state you push, so you control the lifetime. With `adapters.suggestion` on the AI SDK runtime, suggestions clear on run start and regenerate after settle, matching the local runtime.
|
|
194
263
|
|
|
195
264
|
### Rendering runtime suggestions
|
|
196
265
|
|