@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.
Files changed (137) hide show
  1. package/.docs/organized/code-examples/waterfall.md +5 -3
  2. package/.docs/organized/code-examples/with-a2a.md +676 -0
  3. package/.docs/organized/code-examples/with-ag-ui.md +7 -8
  4. package/.docs/organized/code-examples/with-ai-sdk-v6.md +28 -16
  5. package/.docs/organized/code-examples/with-artifacts.md +5 -5
  6. package/.docs/organized/code-examples/with-assistant-transport.md +3 -3
  7. package/.docs/organized/code-examples/with-chain-of-thought.md +34 -26
  8. package/.docs/organized/code-examples/with-cloud-standalone.md +10 -8
  9. package/.docs/organized/code-examples/with-cloud.md +5 -5
  10. package/.docs/organized/code-examples/with-custom-thread-list.md +7 -7
  11. package/.docs/organized/code-examples/with-elevenlabs-scribe.md +8 -8
  12. package/.docs/organized/code-examples/with-expo.md +571 -539
  13. package/.docs/organized/code-examples/with-external-store.md +3 -4
  14. package/.docs/organized/code-examples/with-ffmpeg.md +5 -5
  15. package/.docs/organized/code-examples/with-google-adk.md +353 -0
  16. package/.docs/organized/code-examples/with-heat-graph.md +304 -0
  17. package/.docs/organized/code-examples/with-langgraph.md +25 -23
  18. package/.docs/organized/code-examples/with-parent-id-grouping.md +4 -4
  19. package/.docs/organized/code-examples/with-react-hook-form.md +6 -9
  20. package/.docs/organized/code-examples/with-react-ink.md +265 -0
  21. package/.docs/organized/code-examples/with-react-router.md +10 -11
  22. package/.docs/organized/code-examples/with-store.md +29 -18
  23. package/.docs/organized/code-examples/with-tanstack.md +7 -7
  24. package/.docs/organized/code-examples/with-tap-runtime.md +6 -4
  25. package/.docs/raw/blog/2025-01-31-changelog/index.mdx +1 -1
  26. package/.docs/raw/blog/2026-03-launch-week/index.mdx +227 -0
  27. package/.docs/raw/docs/(docs)/architecture.mdx +1 -1
  28. package/.docs/raw/docs/(docs)/cli.mdx +14 -9
  29. package/.docs/raw/docs/(docs)/copilots/make-assistant-tool-ui.mdx +8 -3
  30. package/.docs/raw/docs/(docs)/copilots/make-assistant-tool.mdx +5 -1
  31. package/.docs/raw/docs/(docs)/copilots/{make-assistant-readable.mdx → make-assistant-visible.mdx} +14 -5
  32. package/.docs/raw/docs/(docs)/copilots/model-context.mdx +11 -11
  33. package/.docs/raw/docs/(docs)/copilots/motivation.mdx +2 -2
  34. package/.docs/raw/docs/(docs)/devtools.mdx +3 -2
  35. package/.docs/raw/docs/(docs)/guides/attachments.mdx +9 -11
  36. package/.docs/raw/docs/(docs)/guides/branching.mdx +11 -6
  37. package/.docs/raw/docs/(docs)/guides/chain-of-thought.mdx +18 -16
  38. package/.docs/raw/docs/(docs)/guides/context-api.mdx +81 -43
  39. package/.docs/raw/docs/(docs)/guides/dictation.mdx +5 -5
  40. package/.docs/raw/docs/(docs)/guides/editing.mdx +16 -7
  41. package/.docs/raw/docs/(docs)/guides/latex.mdx +3 -0
  42. package/.docs/raw/docs/(docs)/guides/message-timing.mdx +2 -1
  43. package/.docs/raw/docs/(docs)/guides/multi-agent.mdx +173 -0
  44. package/.docs/raw/docs/(docs)/guides/quoting.mdx +55 -206
  45. package/.docs/raw/docs/(docs)/guides/speech.mdx +1 -4
  46. package/.docs/raw/docs/(docs)/guides/suggestions.mdx +9 -15
  47. package/.docs/raw/docs/(docs)/guides/tool-ui.mdx +17 -7
  48. package/.docs/raw/docs/(docs)/guides/tools.mdx +24 -9
  49. package/.docs/raw/docs/(docs)/index.mdx +3 -3
  50. package/.docs/raw/docs/(docs)/installation.mdx +69 -46
  51. package/.docs/raw/docs/(reference)/api-reference/context-providers/text-message-part-provider.mdx +20 -6
  52. package/.docs/raw/docs/(reference)/api-reference/integrations/react-data-stream.mdx +24 -4
  53. package/.docs/raw/docs/(reference)/api-reference/integrations/react-hook-form.mdx +1 -1
  54. package/.docs/raw/docs/(reference)/api-reference/integrations/vercel-ai-sdk.mdx +20 -19
  55. package/.docs/raw/docs/(reference)/api-reference/overview.mdx +28 -53
  56. package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar.mdx +4 -4
  57. package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-modal.mdx +7 -1
  58. package/.docs/raw/docs/(reference)/api-reference/primitives/attachment.mdx +20 -14
  59. package/.docs/raw/docs/(reference)/api-reference/primitives/branch-picker.mdx +1 -1
  60. package/.docs/raw/docs/(reference)/api-reference/primitives/composer.mdx +99 -45
  61. package/.docs/raw/docs/(reference)/api-reference/primitives/message-part.mdx +52 -40
  62. package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +343 -23
  63. package/.docs/raw/docs/(reference)/api-reference/primitives/suggestion.mdx +4 -6
  64. package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list-item.mdx +4 -2
  65. package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list.mdx +3 -5
  66. package/.docs/raw/docs/(reference)/api-reference/primitives/thread.mdx +169 -22
  67. package/.docs/raw/docs/(reference)/api-reference/runtimes/assistant-runtime.mdx +14 -4
  68. package/.docs/raw/docs/(reference)/api-reference/runtimes/attachment-runtime.mdx +15 -26
  69. package/.docs/raw/docs/(reference)/api-reference/runtimes/composer-runtime.mdx +39 -21
  70. package/.docs/raw/docs/(reference)/api-reference/runtimes/message-part-runtime.mdx +33 -9
  71. package/.docs/raw/docs/(reference)/api-reference/runtimes/message-runtime.mdx +48 -21
  72. package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-item-runtime.mdx +36 -7
  73. package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-runtime.mdx +30 -10
  74. package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-runtime.mdx +12 -10
  75. package/.docs/raw/docs/(reference)/migrations/deprecation-policy.mdx +1 -1
  76. package/.docs/raw/docs/(reference)/migrations/react-langgraph-v0-7.mdx +9 -4
  77. package/.docs/raw/docs/(reference)/migrations/v0-11.mdx +7 -5
  78. package/.docs/raw/docs/(reference)/migrations/v0-12.mdx +9 -7
  79. package/.docs/raw/docs/(reference)/migrations/v0-14.mdx +159 -0
  80. package/.docs/raw/docs/(reference)/react-compatibility.mdx +5 -134
  81. package/.docs/raw/docs/cloud/ai-sdk-assistant-ui.mdx +89 -7
  82. package/.docs/raw/docs/cloud/ai-sdk.mdx +19 -5
  83. package/.docs/raw/docs/cloud/langgraph.mdx +13 -3
  84. package/.docs/raw/docs/ink/adapters.mdx +41 -0
  85. package/.docs/raw/docs/ink/custom-backend.mdx +203 -0
  86. package/.docs/raw/docs/ink/hooks.mdx +448 -0
  87. package/.docs/raw/docs/ink/index.mdx +239 -0
  88. package/.docs/raw/docs/ink/migration.mdx +140 -0
  89. package/.docs/raw/docs/ink/primitives.mdx +699 -0
  90. package/.docs/raw/docs/react-native/adapters.mdx +63 -87
  91. package/.docs/raw/docs/react-native/custom-backend.mdx +11 -14
  92. package/.docs/raw/docs/react-native/hooks.mdx +214 -232
  93. package/.docs/raw/docs/react-native/index.mdx +118 -159
  94. package/.docs/raw/docs/react-native/migration.mdx +144 -0
  95. package/.docs/raw/docs/react-native/primitives.mdx +431 -302
  96. package/.docs/raw/docs/runtimes/a2a/index.mdx +294 -0
  97. package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +9 -9
  98. package/.docs/raw/docs/runtimes/ai-sdk/v5-legacy.mdx +14 -3
  99. package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +53 -0
  100. package/.docs/raw/docs/runtimes/assistant-transport.mdx +59 -25
  101. package/.docs/raw/docs/runtimes/custom/custom-thread-list.mdx +13 -6
  102. package/.docs/raw/docs/runtimes/custom/external-store.mdx +138 -38
  103. package/.docs/raw/docs/runtimes/custom/local.mdx +184 -42
  104. package/.docs/raw/docs/runtimes/data-stream.mdx +92 -19
  105. package/.docs/raw/docs/runtimes/google-adk/index.mdx +624 -0
  106. package/.docs/raw/docs/runtimes/helicone.mdx +6 -6
  107. package/.docs/raw/docs/runtimes/langgraph/index.mdx +38 -27
  108. package/.docs/raw/docs/runtimes/langgraph/tutorial/introduction.mdx +1 -1
  109. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-1.mdx +15 -20
  110. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +7 -11
  111. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-3.mdx +8 -11
  112. package/.docs/raw/docs/runtimes/langserve.mdx +6 -7
  113. package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +18 -3
  114. package/.docs/raw/docs/ui/context-display.mdx +147 -0
  115. package/.docs/raw/docs/ui/file.mdx +5 -4
  116. package/.docs/raw/docs/ui/image.mdx +5 -4
  117. package/.docs/raw/docs/ui/markdown.mdx +3 -1
  118. package/.docs/raw/docs/ui/model-selector.mdx +8 -8
  119. package/.docs/raw/docs/ui/part-grouping.mdx +7 -10
  120. package/.docs/raw/docs/ui/quote.mdx +210 -0
  121. package/.docs/raw/docs/ui/reasoning.mdx +12 -11
  122. package/.docs/raw/docs/ui/sources.mdx +88 -17
  123. package/.docs/raw/docs/ui/streamdown.mdx +16 -7
  124. package/.docs/raw/docs/ui/thread-list.mdx +11 -13
  125. package/.docs/raw/docs/ui/thread.mdx +28 -33
  126. package/.docs/raw/docs/ui/tool-fallback.mdx +5 -6
  127. package/.docs/raw/docs/ui/tool-group.mdx +9 -8
  128. package/.docs/raw/docs/utilities/heat-graph.mdx +236 -0
  129. package/.docs/raw/docs/utilities/tw-shimmer.mdx +211 -0
  130. package/package.json +4 -4
  131. package/.docs/raw/docs/(reference)/legacy/styled/assistant-modal.mdx +0 -77
  132. package/.docs/raw/docs/(reference)/legacy/styled/decomposition.mdx +0 -635
  133. package/.docs/raw/docs/(reference)/legacy/styled/markdown.mdx +0 -77
  134. package/.docs/raw/docs/(reference)/legacy/styled/scrollbar.mdx +0 -72
  135. package/.docs/raw/docs/(reference)/legacy/styled/thread-width.mdx +0 -22
  136. package/.docs/raw/docs/(reference)/legacy/styled/thread.mdx +0 -77
  137. /package/.docs/raw/docs/cloud/{overview.mdx → index.mdx} +0 -0
@@ -12,7 +12,7 @@ description: Quickest path to a working chat. Handles state while you handle the
12
12
 
13
13
  - **Built-in state management** for messages, threads, and conversation history
14
14
  - **Automatic features** like message editing, reloading, and branch switching
15
- - **Multi-thread support** through [Assistant Cloud](/docs/cloud/overview) or your own database using `useRemoteThreadListRuntime`
15
+ - **Multi-thread support** through [Assistant Cloud](/docs/cloud) or your own database using `useRemoteThreadListRuntime`
16
16
  - **Simple adapter pattern** to connect any backend API
17
17
 
18
18
  While LocalRuntime manages state in-memory by default, it offers multiple persistence options through adapters - use the history adapter for single-thread persistence, Assistant Cloud for managed multi-thread support, or implement your own storage with `useRemoteThreadListRuntime`.
@@ -419,11 +419,11 @@ For custom thread storage, use `useRemoteThreadListRuntime` with your own adapte
419
419
 
420
420
  ```tsx
421
421
  import {
422
- unstable_useRemoteThreadListRuntime as useRemoteThreadListRuntime,
422
+ useRemoteThreadListRuntime,
423
423
  useAui,
424
424
  RuntimeAdapterProvider,
425
425
  AssistantRuntimeProvider,
426
- type unstable_RemoteThreadListAdapter as RemoteThreadListAdapter,
426
+ type RemoteThreadListAdapter,
427
427
  type ThreadHistoryAdapter,
428
428
  } from "@assistant-ui/react";
429
429
  import { createAssistantStream } from "assistant-stream";
@@ -465,9 +465,9 @@ const myDatabaseAdapter: RemoteThreadListAdapter = {
465
465
  await db.threads.delete(remoteId);
466
466
  },
467
467
 
468
- async generateTitle(remoteId, messages) {
468
+ async generateTitle(remoteId, unstable_messages) {
469
469
  // Generate title from messages using your AI
470
- const newTitle = await generateTitle(messages);
470
+ const newTitle = await generateTitle(unstable_messages);
471
471
 
472
472
  // Persist the title in your DB
473
473
  await db.threads.update(remoteId, { title: newTitle });
@@ -632,7 +632,7 @@ Enable file and image uploads:
632
632
  ```tsx
633
633
  const attachmentAdapter: AttachmentAdapter = {
634
634
  accept: "image/*,application/pdf",
635
- async add(file) {
635
+ async add({ file }) {
636
636
  const formData = new FormData();
637
637
  formData.append("file", file);
638
638
 
@@ -646,7 +646,21 @@ const attachmentAdapter: AttachmentAdapter = {
646
646
  id,
647
647
  type: file.type.startsWith("image/") ? "image" : "document",
648
648
  name: file.name,
649
+ contentType: file.type,
650
+ file,
649
651
  url,
652
+ status: { type: "requires-action", reason: "composer-send" },
653
+ };
654
+ },
655
+ async send(attachment) {
656
+ return {
657
+ ...attachment,
658
+ status: { type: "complete" },
659
+ content: [
660
+ attachment.type === "image"
661
+ ? { type: "image", image: attachment.url }
662
+ : { type: "text", text: `[${attachment.name}](${attachment.url})` },
663
+ ],
650
664
  };
651
665
  },
652
666
  async remove(attachment) {
@@ -730,11 +744,32 @@ const speechAdapter: SpeechSynthesisAdapter = {
730
744
  const utterance = new SpeechSynthesisUtterance(text);
731
745
  utterance.rate = 1.0;
732
746
  utterance.pitch = 1.0;
733
- speechSynthesis.speak(utterance);
734
- },
735
747
 
736
- stop() {
737
- speechSynthesis.cancel();
748
+ const subscribers = new Set<() => void>();
749
+ const result: SpeechSynthesisAdapter.Utterance = {
750
+ status: { type: "running" },
751
+ cancel: () => {
752
+ speechSynthesis.cancel();
753
+ result.status = { type: "ended", reason: "cancelled" };
754
+ subscribers.forEach((cb) => cb());
755
+ },
756
+ subscribe: (callback) => {
757
+ subscribers.add(callback);
758
+ return () => subscribers.delete(callback);
759
+ },
760
+ };
761
+
762
+ utterance.addEventListener("end", () => {
763
+ result.status = { type: "ended", reason: "finished" };
764
+ subscribers.forEach((cb) => cb());
765
+ });
766
+ utterance.addEventListener("error", (e) => {
767
+ result.status = { type: "ended", reason: "error", error: e.error };
768
+ subscribers.forEach((cb) => cb());
769
+ });
770
+
771
+ speechSynthesis.speak(utterance);
772
+ return result;
738
773
  },
739
774
  };
740
775
 
@@ -754,7 +789,7 @@ const feedbackAdapter: FeedbackAdapter = {
754
789
  method: "POST",
755
790
  headers: { "Content-Type": "application/json" },
756
791
  body: JSON.stringify({
757
- messageId: feedback.messageId,
792
+ messageId: feedback.message.id,
758
793
  rating: feedback.type, // "positive" or "negative"
759
794
  }),
760
795
  });
@@ -779,9 +814,8 @@ const suggestionAdapter: SuggestionAdapter = {
779
814
  // Generate suggestions
780
815
  const suggestions = await generateSuggestions(lastMessage);
781
816
 
782
- yield suggestions.map((text) => ({
783
- id: crypto.randomUUID(),
784
- text,
817
+ yield suggestions.map((prompt) => ({
818
+ prompt,
785
819
  }));
786
820
  },
787
821
  };
@@ -795,18 +829,31 @@ const runtime = useLocalRuntime(MyModelAdapter, {
795
829
 
796
830
  ### Resuming a Run
797
831
 
798
- <Callout type="warning">
799
- The `unstable_resumeRun` method is experimental and may change in future
800
- releases.
801
- </Callout>
832
+ `resumeRun` reconnects to an in-progress or interrupted assistant run. This is essential for scenarios like:
833
+
834
+ - **Page refresh** while the backend is still generating a response
835
+ - **Network reconnection** after a temporary disconnect
836
+ - **Tab backgrounding** where the browser suspended the WebSocket connection
837
+ - **Thread switching** to a conversation that has an active backend stream
838
+
839
+ #### How it works
802
840
 
803
- Resume a conversation with a custom stream:
841
+ When you call `resumeRun`, the local runtime:
842
+
843
+ 1. Creates a new assistant message in the thread (or continues the existing one)
844
+ 2. Calls your provided `stream` function with `ChatModelRunOptions` (messages, abort signal, model context, etc.)
845
+ 3. Iterates over each `ChatModelRunResult` yielded by the stream, updating the assistant message with new content, status, and metadata
846
+ 4. Completes when the stream finishes or is cancelled
847
+
848
+ Unlike `startRun` (which uses the ChatModelAdapter), `resumeRun` **requires** a `stream` parameter — you provide the async generator that produces the response.
849
+
850
+ #### Basic example
804
851
 
805
852
  ```tsx
806
- import { useThreadRuntime, type ChatModelRunResult } from "@assistant-ui/react";
853
+ import { useAui } from "@assistant-ui/react";
854
+ import type { ChatModelRunResult } from "@assistant-ui/core";
807
855
 
808
- // Get the thread runtime
809
- const thread = useThreadRuntime();
856
+ const aui = useAui();
810
857
 
811
858
  // Create a custom stream
812
859
  async function* createCustomStream(): AsyncGenerator<ChatModelRunResult> {
@@ -825,36 +872,88 @@ async function* createCustomStream(): AsyncGenerator<ChatModelRunResult> {
825
872
  }
826
873
 
827
874
  // Resume a run with the custom stream
828
- thread.unstable_resumeRun({
875
+ aui.thread().resumeRun({
829
876
  parentId: "message-id", // ID of the message to respond to
830
- stream: createCustomStream(), // The stream to use for resuming
877
+ stream: createCustomStream,
831
878
  });
832
879
  ```
833
880
 
881
+ #### Reconnecting to a backend stream
882
+
883
+ A common pattern is checking whether the backend is still running, then reconnecting:
884
+
885
+ ```tsx
886
+ import { useAui } from "@assistant-ui/react";
887
+ import { useEffect, useRef } from "react";
888
+
889
+ function useStreamReconnect(threadId: string) {
890
+ const aui = useAui();
891
+ const hasCheckedRef = useRef(false);
892
+
893
+ useEffect(() => {
894
+ if (hasCheckedRef.current) return;
895
+ hasCheckedRef.current = true;
896
+
897
+ const checkAndResume = async () => {
898
+ // Check if the backend still has an active stream
899
+ const status = await fetch(`/api/status/${threadId}`).then((r) =>
900
+ r.json(),
901
+ );
902
+
903
+ if (status.isRunning) {
904
+ const parentId =
905
+ aui.thread().getState().messages.at(-1)?.id ?? null;
906
+ aui.thread().resumeRun({ parentId });
907
+ }
908
+ };
909
+
910
+ checkAndResume();
911
+ }, [aui, threadId]);
912
+ }
913
+ ```
914
+
915
+ #### ChatModelRunResult
916
+
917
+ Each value yielded by the stream is a `ChatModelRunResult`:
918
+
919
+ ```tsx
920
+ type ChatModelRunResult = {
921
+ /** The message content parts (text, tool calls, etc.) */
922
+ content: ThreadAssistantContentPart[];
923
+ /** Optional status override */
924
+ status?: MessageStatus;
925
+ /** Optional metadata (state, annotations, custom fields) */
926
+ metadata?: {
927
+ custom?: Record<string, unknown>;
928
+ steps?: unknown[];
929
+ // ...
930
+ };
931
+ };
932
+ ```
933
+
934
+ The stream should yield the **full cumulative content** on each iteration (not deltas). Each yield replaces the previous content of the assistant message.
935
+
834
936
  ### Custom Thread Management
835
937
 
836
- Access thread runtime for advanced control with `useThreadRuntime`:
938
+ Access thread actions for advanced control with `useAui`:
837
939
 
838
940
  ```tsx
839
- import { useThreadRuntime } from "@assistant-ui/react";
941
+ import { useAui } from "@assistant-ui/react";
840
942
 
841
943
  function MyComponent() {
842
- const thread = useThreadRuntime();
944
+ const aui = useAui();
843
945
 
844
946
  // Cancel current generation
845
947
  const handleCancel = () => {
846
- thread.cancelRun();
948
+ aui.thread().cancelRun();
847
949
  };
848
950
 
849
- // Switch to a different branch
850
- const handleSwitchBranch = (messageId: string, branchIndex: number) => {
851
- thread.switchToBranch(messageId, branchIndex);
852
- };
951
+ // Switch to a different branch (message scope)
952
+ // aui.message().switchToBranch({ position: "next" });
953
+ // aui.message().switchToBranch({ position: "previous" });
853
954
 
854
- // Reload a message
855
- const handleReload = (messageId: string) => {
856
- thread.reload(messageId);
857
- };
955
+ // Reload a message (message scope)
956
+ // aui.message().reload();
858
957
 
859
958
  return (
860
959
  // Your UI
@@ -889,11 +988,13 @@ const OpenAIAdapter: ChatModelAdapter = {
889
988
  signal: abortSignal,
890
989
  });
891
990
 
991
+ let fullText = "";
892
992
  for await (const chunk of stream) {
893
993
  const content = chunk.choices[0]?.delta?.content;
894
994
  if (content) {
995
+ fullText += content;
895
996
  yield {
896
- content: [{ type: "text", text: content }],
997
+ content: [{ type: "text", text: fullText }],
897
998
  };
898
999
  }
899
1000
  }
@@ -1118,6 +1219,12 @@ Parameters passed to the `run` function.
1118
1219
  description: "The conversation history to send to your API",
1119
1220
  required: true,
1120
1221
  },
1222
+ {
1223
+ name: "runConfig",
1224
+ type: "RunConfig",
1225
+ description: "Run configuration with optional custom metadata. `RunConfig` is `{ readonly custom?: Record<string, unknown> }`.",
1226
+ required: true,
1227
+ },
1121
1228
  {
1122
1229
  name: "abortSignal",
1123
1230
  type: "AbortSignal",
@@ -1130,11 +1237,31 @@ Parameters passed to the `run` function.
1130
1237
  description: "Additional context including configuration and tools",
1131
1238
  required: true,
1132
1239
  },
1240
+ {
1241
+ name: "unstable_assistantMessageId",
1242
+ type: "string | undefined",
1243
+ description: "The ID of the assistant message being generated. Useful for tracking or updating specific messages.",
1244
+ },
1133
1245
  {
1134
1246
  name: "unstable_threadId",
1135
1247
  type: "string | undefined",
1136
1248
  description: "The current thread/conversation identifier. Useful for passing to your backend API.",
1137
1249
  },
1250
+ {
1251
+ name: "unstable_parentId",
1252
+ type: "string | null | undefined",
1253
+ description: "The ID of the parent message this response is replying to. `null` if this is the first message in the thread.",
1254
+ },
1255
+ {
1256
+ name: "unstable_getMessage",
1257
+ type: "() => ThreadMessage",
1258
+ description: "Returns the current assistant message being generated. Useful for accessing message state during streaming.",
1259
+ },
1260
+ {
1261
+ name: "config",
1262
+ type: "ModelContext",
1263
+ description: "Deprecated. Renamed to `context`. Additional context including configuration and tools.",
1264
+ },
1138
1265
  ]}
1139
1266
  />
1140
1267
 
@@ -1147,7 +1274,7 @@ Configuration options for the `LocalRuntime`.
1147
1274
  parameters={[
1148
1275
  {
1149
1276
  name: "initialMessages",
1150
- type: "readonly ThreadMessage[]",
1277
+ type: "readonly ThreadMessageLike[]",
1151
1278
  description: "Pre-populate the thread with messages",
1152
1279
  },
1153
1280
  {
@@ -1155,7 +1282,7 @@ Configuration options for the `LocalRuntime`.
1155
1282
  type: "number",
1156
1283
  description:
1157
1284
  "Maximum number of sequential tool calls before requiring user input",
1158
- default: "5",
1285
+ default: "2",
1159
1286
  },
1160
1287
  {
1161
1288
  name: "cloud",
@@ -1182,6 +1309,11 @@ Configuration options for the `LocalRuntime`.
1182
1309
  type: "SpeechSynthesisAdapter",
1183
1310
  description: "Enable text-to-speech for messages",
1184
1311
  },
1312
+ {
1313
+ name: "dictation",
1314
+ type: "DictationAdapter",
1315
+ description: "Enable speech-to-text dictation",
1316
+ },
1185
1317
  {
1186
1318
  name: "feedback",
1187
1319
  type: "FeedbackAdapter",
@@ -1193,7 +1325,7 @@ Configuration options for the `LocalRuntime`.
1193
1325
  description: "Enable thread persistence and resumption",
1194
1326
  },
1195
1327
  {
1196
- name: "suggestions",
1328
+ name: "suggestion",
1197
1329
  type: "SuggestionAdapter",
1198
1330
  description: "Enable follow-up suggestions",
1199
1331
  },
@@ -1255,10 +1387,21 @@ Interface for implementing custom thread list storage.
1255
1387
  },
1256
1388
  {
1257
1389
  name: "generateTitle",
1258
- type: "(remoteId: string, messages: readonly ThreadMessage[]) => Promise<AssistantStream>",
1390
+ type: "(remoteId: string, unstable_messages: readonly ThreadMessage[]) => Promise<AssistantStream>",
1259
1391
  description: "Generates a title for the thread based on the conversation",
1260
1392
  required: true,
1261
1393
  },
1394
+ {
1395
+ name: "fetch",
1396
+ type: "(threadId: string) => Promise<RemoteThreadMetadata>",
1397
+ description: "Fetches metadata for a specific thread",
1398
+ required: true,
1399
+ },
1400
+ {
1401
+ name: "unstable_Provider",
1402
+ type: "(...args: any[]) => unknown",
1403
+ description: "Optional React provider component to wrap the runtime context",
1404
+ },
1262
1405
  ]}
1263
1406
  />
1264
1407
 
@@ -1269,7 +1412,6 @@ Interface for implementing custom thread list storage.
1269
1412
 
1270
1413
  ## Related Resources
1271
1414
 
1272
- - [Runtime Layer Concepts](/docs/concepts/runtime-layer)
1273
1415
  - [Pick a Runtime Guide](/docs/runtimes/pick-a-runtime)
1274
1416
  - [`ExternalStoreRuntime`](/docs/runtimes/custom/external-store)
1275
1417
  - [Examples Repository](https://github.com/assistant-ui/assistant-ui/tree/main/examples)
@@ -18,7 +18,7 @@ The data stream protocol is a standardized format for streaming AI responses tha
18
18
 
19
19
  ## Installation
20
20
 
21
- <InstallCommand npm={["@assistant-ui/react-data-stream"]} />
21
+ <InstallCommand npm={["@assistant-ui/react", "@assistant-ui/react-data-stream"]} />
22
22
 
23
23
  ## Basic Usage
24
24
 
@@ -160,35 +160,34 @@ const runtime = useDataStreamRuntime({
160
160
  Human-in-the-loop tools (using `human()` for tool interrupts) are not supported
161
161
  in the data stream runtime. If you need human approval workflows or interactive
162
162
  tool UIs, consider using [LocalRuntime](/docs/runtimes/custom/local) or
163
- [Assistant Cloud](/docs/cloud/overview) instead.
163
+ [Assistant Cloud](/docs/cloud) instead.
164
164
  </Callout>
165
165
 
166
166
  ### Frontend Tools
167
167
 
168
- Use the `frontendTools` helper to serialize client-side tools:
168
+ Use `toToolsJSONSchema` to serialize client-side tools:
169
169
 
170
170
  ```tsx
171
- import { frontendTools } from "@assistant-ui/react-data-stream";
172
- import { makeAssistantTool } from "@assistant-ui/react";
173
-
174
- const weatherTool = makeAssistantTool({
175
- toolName: "get_weather",
176
- description: "Get current weather",
177
- parameters: z.object({
178
- location: z.string(),
171
+ import { tool } from "@assistant-ui/react";
172
+ import { toToolsJSONSchema } from "assistant-stream";
173
+
174
+ const myTools = {
175
+ get_weather: tool({
176
+ description: "Get current weather",
177
+ parameters: z.object({
178
+ location: z.string(),
179
+ }),
180
+ execute: async ({ location }) => {
181
+ const weather = await fetchWeather(location);
182
+ return `Weather in ${location}: ${weather}`;
183
+ },
179
184
  }),
180
- execute: async ({ location }) => {
181
- const weather = await fetchWeather(location);
182
- return `Weather in ${location}: ${weather}`;
183
- },
184
- });
185
+ };
185
186
 
186
187
  const runtime = useDataStreamRuntime({
187
188
  api: "/api/chat",
188
189
  body: {
189
- tools: frontendTools({
190
- get_weather: weatherTool,
191
- }),
190
+ tools: toToolsJSONSchema(myTools),
192
191
  },
193
192
  });
194
193
  ```
@@ -344,6 +343,80 @@ const runtime = useDataStreamRuntime({
344
343
 
345
344
  Explore our [examples repository](https://github.com/assistant-ui/assistant-ui/tree/main/examples) for implementation references.
346
345
 
346
+ ## LocalRuntimeOptions
347
+
348
+ `useDataStreamRuntime` accepts all options from `LocalRuntimeOptions` in addition to its own options. These control the underlying local runtime behavior.
349
+
350
+ ### `maxSteps`
351
+
352
+ The maximum number of agentic steps (tool call rounds) allowed per run. Defaults to unlimited.
353
+
354
+ ```tsx
355
+ const runtime = useDataStreamRuntime({
356
+ api: "/api/chat",
357
+ maxSteps: 5,
358
+ });
359
+ ```
360
+
361
+ ### `initialMessages`
362
+
363
+ Pre-populate the thread with messages on first render. Useful for continuing an existing conversation.
364
+
365
+ ```tsx
366
+ const runtime = useDataStreamRuntime({
367
+ api: "/api/chat",
368
+ initialMessages: [
369
+ { role: "user", content: [{ type: "text", text: "Hello" }] },
370
+ { role: "assistant", content: [{ type: "text", text: "Hi! How can I help?" }] },
371
+ ],
372
+ });
373
+ ```
374
+
375
+ ### `adapters`
376
+
377
+ Extend the runtime with optional capability adapters. The `chatModel` adapter is handled internally by `useDataStreamRuntime` and cannot be overridden here.
378
+
379
+ ```tsx
380
+ const runtime = useDataStreamRuntime({
381
+ api: "/api/chat",
382
+ adapters: {
383
+ attachments: myAttachmentAdapter,
384
+ history: myHistoryAdapter,
385
+ speech: mySpeechAdapter,
386
+ dictation: myDictationAdapter,
387
+ feedback: myFeedbackAdapter,
388
+ suggestion: mySuggestionAdapter,
389
+ },
390
+ });
391
+ ```
392
+
393
+ See the [LocalRuntime adapters documentation](/docs/runtimes/custom/local#adapters) for details on implementing each adapter.
394
+
395
+ ### `cloud`
396
+
397
+ Connect to [Assistant Cloud](/docs/cloud) for managed multi-thread support, persistence, and thread management.
398
+
399
+ ```tsx
400
+ import { AssistantCloud } from "assistant-cloud";
401
+
402
+ const cloud = new AssistantCloud({ /* ... */ });
403
+
404
+ const runtime = useDataStreamRuntime({
405
+ api: "/api/chat",
406
+ cloud,
407
+ });
408
+ ```
409
+
410
+ ### `unstable_humanToolNames`
411
+
412
+ Names of tools that should pause execution and wait for human or external approval before proceeding.
413
+
414
+ <Callout type="warn">
415
+ Human-in-the-loop tool interrupts (`unstable_humanToolNames`) are not supported
416
+ in the data stream runtime. Use [LocalRuntime](/docs/runtimes/custom/local) if
417
+ you need this feature.
418
+ </Callout>
419
+
347
420
  ## API Reference
348
421
 
349
422
  For detailed API documentation, see the [`@assistant-ui/react-data-stream` API Reference](/docs/api-reference/integrations/react-data-stream).