@assistant-ui/mcp-docs-server 0.1.31 → 0.1.32

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 (247) hide show
  1. package/.docs/organized/code-examples/waterfall.md +8 -8
  2. package/.docs/organized/code-examples/with-a2a.md +10 -10
  3. package/.docs/organized/code-examples/with-ag-ui.md +11 -11
  4. package/.docs/organized/code-examples/with-ai-sdk-v6.md +13 -13
  5. package/.docs/organized/code-examples/with-artifacts.md +13 -13
  6. package/.docs/organized/code-examples/with-assistant-transport.md +10 -10
  7. package/.docs/organized/code-examples/with-browser-extension.md +345 -0
  8. package/.docs/organized/code-examples/with-chain-of-thought.md +54 -17
  9. package/.docs/organized/code-examples/with-cloud-standalone.md +13 -13
  10. package/.docs/organized/code-examples/with-cloud.md +13 -13
  11. package/.docs/organized/code-examples/with-custom-thread-list.md +13 -13
  12. package/.docs/organized/code-examples/with-elevenlabs-conversational.md +17 -16
  13. package/.docs/organized/code-examples/with-elevenlabs-scribe.md +17 -16
  14. package/.docs/organized/code-examples/with-expo.md +24 -24
  15. package/.docs/organized/code-examples/with-external-store.md +10 -10
  16. package/.docs/organized/code-examples/with-ffmpeg.md +13 -13
  17. package/.docs/organized/code-examples/with-generative-ui.md +210 -13
  18. package/.docs/organized/code-examples/with-google-adk.md +10 -10
  19. package/.docs/organized/code-examples/with-heat-graph.md +8 -8
  20. package/.docs/organized/code-examples/with-image-generation.md +454 -0
  21. package/.docs/organized/code-examples/with-interactables.md +13 -13
  22. package/.docs/organized/code-examples/with-langchain.md +12 -12
  23. package/.docs/organized/code-examples/with-langgraph.md +15 -12
  24. package/.docs/organized/code-examples/with-livekit.md +18 -17
  25. package/.docs/organized/code-examples/with-mcp.md +748 -0
  26. package/.docs/organized/code-examples/with-opencode.md +11 -11
  27. package/.docs/organized/code-examples/with-parent-id-grouping.md +11 -11
  28. package/.docs/organized/code-examples/with-react-hook-form.md +14 -14
  29. package/.docs/organized/code-examples/with-react-ink.md +4 -4
  30. package/.docs/organized/code-examples/with-react-router.md +15 -15
  31. package/.docs/organized/code-examples/with-resumable-stream.md +660 -0
  32. package/.docs/organized/code-examples/with-store.md +8 -8
  33. package/.docs/organized/code-examples/with-tanstack.md +14 -14
  34. package/.docs/organized/code-examples/with-tap-runtime.md +11 -10
  35. package/.docs/raw/docs/(docs)/cli.mdx +1 -0
  36. package/.docs/raw/docs/(docs)/index.mdx +2 -2
  37. package/.docs/raw/docs/(docs)/installation.mdx +1 -1
  38. package/.docs/raw/docs/(reference)/api-reference/adapters/attachments.mdx +26 -24
  39. package/.docs/raw/docs/(reference)/api-reference/adapters/feedback.mdx +20 -0
  40. package/.docs/raw/docs/(reference)/api-reference/adapters/index.mdx +20 -12
  41. package/.docs/raw/docs/(reference)/api-reference/adapters/model.mdx +44 -0
  42. package/.docs/raw/docs/(reference)/api-reference/adapters/persistence.mdx +37 -16
  43. package/.docs/raw/docs/(reference)/api-reference/adapters/runtime.mdx +12 -23
  44. package/.docs/raw/docs/(reference)/api-reference/adapters/suggestions.mdx +20 -0
  45. package/.docs/raw/docs/(reference)/api-reference/context-providers/assistant-runtime-provider.mdx +37 -8
  46. package/.docs/raw/docs/(reference)/api-reference/context-providers/index.mdx +11 -9
  47. package/.docs/raw/docs/(reference)/api-reference/context-providers/scoped-providers.mdx +64 -0
  48. package/.docs/raw/docs/(reference)/api-reference/external-store/index.mdx +22 -0
  49. package/.docs/raw/docs/(reference)/api-reference/external-store/message-conversion.mdx +52 -0
  50. package/.docs/raw/docs/(reference)/api-reference/external-store/runtime.mdx +36 -0
  51. package/.docs/raw/docs/(reference)/api-reference/hooks/composer-triggers.mdx +98 -0
  52. package/.docs/raw/docs/(reference)/api-reference/hooks/index.mdx +18 -13
  53. package/.docs/raw/docs/(reference)/api-reference/hooks/model-context.mdx +18 -57
  54. package/.docs/raw/docs/(reference)/api-reference/hooks/primitives.mdx +640 -0
  55. package/.docs/raw/docs/(reference)/api-reference/hooks/runtimes.mdx +15 -28
  56. package/.docs/raw/docs/(reference)/api-reference/hooks/state.mdx +64 -18
  57. package/.docs/raw/docs/(reference)/api-reference/hooks/utilities.mdx +434 -0
  58. package/.docs/raw/docs/(reference)/api-reference/integrations/cloud-ai-sdk.mdx +24 -0
  59. package/.docs/raw/docs/(reference)/api-reference/integrations/index.mdx +11 -12
  60. package/.docs/raw/docs/(reference)/api-reference/integrations/react-ai-sdk.mdx +79 -0
  61. package/.docs/raw/docs/(reference)/api-reference/model-context/context.mdx +52 -0
  62. package/.docs/raw/docs/(reference)/api-reference/model-context/index.mdx +22 -0
  63. package/.docs/raw/docs/(reference)/api-reference/model-context/registry.mdx +20 -0
  64. package/.docs/raw/docs/(reference)/api-reference/overview.mdx +110 -131
  65. package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar-more.mdx +78 -221
  66. package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar.mdx +127 -242
  67. package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-if.mdx +39 -20
  68. package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-modal.mdx +66 -87
  69. package/.docs/raw/docs/(reference)/api-reference/primitives/attachment.mdx +50 -58
  70. package/.docs/raw/docs/(reference)/api-reference/primitives/branch-picker.mdx +80 -48
  71. package/.docs/raw/docs/(reference)/api-reference/primitives/chain-of-thought.mdx +67 -0
  72. package/.docs/raw/docs/(reference)/api-reference/primitives/composer.mdx +323 -461
  73. package/.docs/raw/docs/(reference)/api-reference/primitives/error.mdx +36 -43
  74. package/.docs/raw/docs/(reference)/api-reference/primitives/index.mdx +29 -24
  75. package/.docs/raw/docs/(reference)/api-reference/primitives/message-part.mdx +63 -245
  76. package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +175 -591
  77. package/.docs/raw/docs/(reference)/api-reference/primitives/queue-item.mdx +65 -0
  78. package/.docs/raw/docs/(reference)/api-reference/primitives/selection-toolbar.mdx +35 -22
  79. package/.docs/raw/docs/(reference)/api-reference/primitives/suggestion.mdx +57 -140
  80. package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list-item-more.mdx +70 -161
  81. package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list-item.mdx +84 -108
  82. package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list.mdx +77 -96
  83. package/.docs/raw/docs/(reference)/api-reference/primitives/thread.mdx +173 -349
  84. package/.docs/raw/docs/(reference)/api-reference/runtimes/assistant-runtime.mdx +9 -21
  85. package/.docs/raw/docs/(reference)/api-reference/runtimes/attachment-runtime.mdx +10 -21
  86. package/.docs/raw/docs/(reference)/api-reference/runtimes/composer-runtime.mdx +15 -70
  87. package/.docs/raw/docs/(reference)/api-reference/runtimes/index.mdx +18 -13
  88. package/.docs/raw/docs/(reference)/api-reference/runtimes/message-part-runtime.mdx +25 -28
  89. package/.docs/raw/docs/(reference)/api-reference/runtimes/message-runtime.mdx +11 -63
  90. package/.docs/raw/docs/(reference)/api-reference/runtimes/queue-state.mdx +20 -0
  91. package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-item-runtime.mdx +11 -48
  92. package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-runtime.mdx +10 -47
  93. package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-runtime.mdx +18 -30
  94. package/.docs/raw/docs/(reference)/api-reference/tools/component-tools.mdx +68 -0
  95. package/.docs/raw/docs/(reference)/api-reference/tools/index.mdx +39 -0
  96. package/.docs/raw/docs/(reference)/api-reference/tools/rendering.mdx +79 -0
  97. package/.docs/raw/docs/(reference)/api-reference/tools/status.mdx +42 -0
  98. package/.docs/raw/docs/(reference)/api-reference/tools/toolkits.mdx +92 -0
  99. package/.docs/raw/docs/(reference)/api-reference/transport/assistant-transport.mdx +48 -0
  100. package/.docs/raw/docs/(reference)/api-reference/transport/frame.mdx +62 -0
  101. package/.docs/raw/docs/(reference)/api-reference/transport/index.mdx +22 -0
  102. package/.docs/raw/docs/(reference)/api-reference/utilities/index.mdx +19 -0
  103. package/.docs/raw/docs/(reference)/api-reference/utilities/miscellaneous.mdx +131 -0
  104. package/.docs/raw/docs/(reference)/api-reference/voice/index.mdx +22 -0
  105. package/.docs/raw/docs/(reference)/api-reference/voice/session.mdx +54 -0
  106. package/.docs/raw/docs/(reference)/api-reference/voice/speech-dictation.mdx +36 -0
  107. package/.docs/raw/docs/cloud/ai-sdk.mdx +1 -1
  108. package/.docs/raw/docs/cloud/index.mdx +2 -2
  109. package/.docs/raw/docs/guides/attachments.mdx +4 -4
  110. package/.docs/raw/docs/guides/branching.mdx +1 -1
  111. package/.docs/raw/docs/guides/chain-of-thought.mdx +5 -5
  112. package/.docs/raw/docs/guides/context-api.mdx +4 -4
  113. package/.docs/raw/docs/guides/dictation.mdx +2 -2
  114. package/.docs/raw/docs/guides/editing.mdx +1 -1
  115. package/.docs/raw/docs/guides/generative-ui.mdx +142 -0
  116. package/.docs/raw/docs/guides/image-generation.mdx +74 -0
  117. package/.docs/raw/docs/guides/index.mdx +2 -2
  118. package/.docs/raw/docs/guides/interactables.mdx +2 -2
  119. package/.docs/raw/docs/guides/latex.mdx +2 -2
  120. package/.docs/raw/docs/guides/mcp-apps.mdx +231 -0
  121. package/.docs/raw/docs/guides/mentions.mdx +2 -2
  122. package/.docs/raw/docs/guides/message-timing.mdx +38 -5
  123. package/.docs/raw/docs/guides/multi-agent.mdx +2 -2
  124. package/.docs/raw/docs/guides/quoting.mdx +1 -1
  125. package/.docs/raw/docs/guides/resumable-stream-deployment.mdx +212 -0
  126. package/.docs/raw/docs/guides/resumable-stream-stores.mdx +152 -0
  127. package/.docs/raw/docs/guides/resumable-streams.mdx +210 -0
  128. package/.docs/raw/docs/guides/slash-commands.mdx +1 -1
  129. package/.docs/raw/docs/guides/speech.mdx +2 -2
  130. package/.docs/raw/docs/guides/suggestions.mdx +88 -4
  131. package/.docs/raw/docs/guides/tool-ui.mdx +2 -2
  132. package/.docs/raw/docs/guides/tools.mdx +66 -5
  133. package/.docs/raw/docs/guides/voice.mdx +2 -2
  134. package/.docs/raw/docs/ink/adapters.mdx +37 -1
  135. package/.docs/raw/docs/ink/custom-backend.mdx +59 -8
  136. package/.docs/raw/docs/ink/index.mdx +10 -11
  137. package/.docs/raw/docs/ink/primitives.mdx +349 -8
  138. package/.docs/raw/docs/integrations/auth/better-auth.mdx +1 -1
  139. package/.docs/raw/docs/integrations/auth/clerk.mdx +1 -1
  140. package/.docs/raw/docs/integrations/auth/next-auth.mdx +1 -1
  141. package/.docs/raw/docs/integrations/frameworks/ai-sdk.mdx +2 -2
  142. package/.docs/raw/docs/integrations/frameworks/cloudflare-agents/overview.mdx +282 -0
  143. package/.docs/raw/docs/integrations/frameworks/mastra/overview.mdx +2 -2
  144. package/.docs/raw/docs/integrations/frameworks/mastra/separate-server.mdx +1 -1
  145. package/.docs/raw/docs/integrations/gateways/index.mdx +9 -4
  146. package/.docs/raw/docs/integrations/index.mdx +15 -3
  147. package/.docs/raw/docs/integrations/observability/langfuse.mdx +8 -1
  148. package/.docs/raw/docs/integrations/observability/langsmith.mdx +8 -4
  149. package/.docs/raw/docs/integrations/tools/react-mcp.mdx +337 -0
  150. package/.docs/raw/docs/primitives/composer.mdx +53 -0
  151. package/.docs/raw/docs/primitives/index.mdx +2 -2
  152. package/.docs/raw/docs/primitives/suggestion.mdx +9 -0
  153. package/.docs/raw/docs/react-native/hooks.mdx +2 -2
  154. package/.docs/raw/docs/react-native/index.mdx +4 -4
  155. package/.docs/raw/docs/runtimes/a2a/client-and-hooks.mdx +4 -4
  156. package/.docs/raw/docs/runtimes/a2a/overview.mdx +2 -2
  157. package/.docs/raw/docs/runtimes/ag-ui/overview.mdx +2 -2
  158. package/.docs/raw/docs/runtimes/ag-ui/runtime-options.mdx +32 -1
  159. package/.docs/raw/docs/runtimes/ai-sdk/overview.mdx +2 -2
  160. package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +7 -2
  161. package/.docs/raw/docs/runtimes/ai-sdk/v5-legacy.mdx +1 -1
  162. package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +7 -0
  163. package/.docs/raw/docs/runtimes/custom/data-stream.mdx +27 -2
  164. package/.docs/raw/docs/runtimes/custom/external-store.mdx +9 -1
  165. package/.docs/raw/docs/runtimes/custom/overview.mdx +2 -2
  166. package/.docs/raw/docs/runtimes/google-adk/overview.mdx +2 -2
  167. package/.docs/raw/docs/runtimes/langchain.mdx +2 -2
  168. package/.docs/raw/docs/runtimes/langgraph/overview.mdx +2 -2
  169. package/.docs/raw/docs/runtimes/opencode/overview.mdx +2 -2
  170. package/.docs/raw/docs/runtimes/opencode/quickstart.mdx +1 -1
  171. package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +12 -5
  172. package/.docs/raw/docs/ui/composer-trigger-popover.mdx +11 -1
  173. package/.docs/raw/docs/ui/mcp-config.mdx +102 -0
  174. package/.docs/raw/docs/ui/model-selector.mdx +8 -8
  175. package/.docs/raw/docs/ui/sources.mdx +17 -0
  176. package/.docs/raw/docs/ui/streamdown.mdx +34 -2
  177. package/.docs/raw/docs/ui/thread-list.mdx +2 -2
  178. package/.docs/raw/docs/ui/thread.mdx +2 -2
  179. package/README.md +14 -72
  180. package/dist/constants.d.ts +12 -9
  181. package/dist/constants.d.ts.map +1 -1
  182. package/dist/constants.js +13 -9
  183. package/dist/constants.js.map +1 -1
  184. package/dist/index.d.ts +7 -3
  185. package/dist/index.d.ts.map +1 -1
  186. package/dist/index.js +25 -24
  187. package/dist/index.js.map +1 -1
  188. package/dist/prepare-docs/code-examples.d.ts +4 -1
  189. package/dist/prepare-docs/code-examples.d.ts.map +1 -1
  190. package/dist/prepare-docs/code-examples.js +109 -121
  191. package/dist/prepare-docs/code-examples.js.map +1 -1
  192. package/dist/prepare-docs/copy-raw.d.ts +4 -1
  193. package/dist/prepare-docs/copy-raw.d.ts.map +1 -1
  194. package/dist/prepare-docs/copy-raw.js +45 -42
  195. package/dist/prepare-docs/copy-raw.js.map +1 -1
  196. package/dist/prepare-docs/prepare.d.ts +1 -2
  197. package/dist/prepare-docs/prepare.js +17 -17
  198. package/dist/prepare-docs/prepare.js.map +1 -1
  199. package/dist/stdio.d.ts +1 -3
  200. package/dist/stdio.js +6 -3
  201. package/dist/stdio.js.map +1 -1
  202. package/dist/tools/docs.d.ts +20 -15
  203. package/dist/tools/docs.d.ts.map +1 -1
  204. package/dist/tools/docs.js +140 -161
  205. package/dist/tools/docs.js.map +1 -1
  206. package/dist/tools/examples.d.ts +20 -15
  207. package/dist/tools/examples.d.ts.map +1 -1
  208. package/dist/tools/examples.js +74 -86
  209. package/dist/tools/examples.js.map +1 -1
  210. package/dist/tools/tests/test-setup.d.ts +5 -2
  211. package/dist/tools/tests/test-setup.d.ts.map +1 -1
  212. package/dist/tools/tests/test-setup.js +21 -28
  213. package/dist/tools/tests/test-setup.js.map +1 -1
  214. package/dist/utils/logger.d.ts +8 -5
  215. package/dist/utils/logger.d.ts.map +1 -1
  216. package/dist/utils/logger.js +17 -17
  217. package/dist/utils/logger.js.map +1 -1
  218. package/dist/utils/mcp-format.d.ts +8 -5
  219. package/dist/utils/mcp-format.d.ts.map +1 -1
  220. package/dist/utils/mcp-format.js +9 -9
  221. package/dist/utils/mcp-format.js.map +1 -1
  222. package/dist/utils/mdx.d.ts +8 -6
  223. package/dist/utils/mdx.d.ts.map +1 -1
  224. package/dist/utils/mdx.js +22 -22
  225. package/dist/utils/mdx.js.map +1 -1
  226. package/dist/utils/paths.d.ts +9 -6
  227. package/dist/utils/paths.d.ts.map +1 -1
  228. package/dist/utils/paths.js +66 -76
  229. package/dist/utils/paths.js.map +1 -1
  230. package/dist/utils/security.d.ts +4 -1
  231. package/dist/utils/security.d.ts.map +1 -1
  232. package/dist/utils/security.js +19 -40
  233. package/dist/utils/security.js.map +1 -1
  234. package/package.json +5 -5
  235. package/.docs/raw/docs/(reference)/api-reference/adapters/feedback-speech.mdx +0 -41
  236. package/.docs/raw/docs/(reference)/api-reference/context-providers/text-message-part-provider.mdx +0 -40
  237. package/.docs/raw/docs/(reference)/api-reference/integrations/react-data-stream.mdx +0 -260
  238. package/.docs/raw/docs/(reference)/api-reference/integrations/react-hook-form.mdx +0 -103
  239. package/.docs/raw/docs/(reference)/api-reference/integrations/vercel-ai-sdk.mdx +0 -254
  240. package/dist/prepare-docs/prepare.d.ts.map +0 -1
  241. package/dist/stdio.d.ts.map +0 -1
  242. /package/.docs/raw/docs/{(reference)/migrations → migrations}/deprecation-policy.mdx +0 -0
  243. /package/.docs/raw/docs/{(reference) → migrations}/react-compatibility.mdx +0 -0
  244. /package/.docs/raw/docs/{(reference)/migrations → migrations}/react-langgraph-v0-7.mdx +0 -0
  245. /package/.docs/raw/docs/{(reference)/migrations → migrations}/v0-11.mdx +0 -0
  246. /package/.docs/raw/docs/{(reference)/migrations → migrations}/v0-12.mdx +0 -0
  247. /package/.docs/raw/docs/{(reference)/migrations → migrations}/v0-14.mdx +0 -0
@@ -1,84 +1,74 @@
1
- import { readdir, stat } from "node:fs/promises";
2
- import { join, extname } from "node:path";
3
- import { DOCS_PATH, MDX_EXTENSION, MD_EXTENSION } from "../constants.js";
1
+ import { DOCS_PATH, MDX_EXTENSION } from "../constants.js";
4
2
  import { logger } from "./logger.js";
3
+ import { extname, join } from "node:path";
4
+ import { readdir, stat } from "node:fs/promises";
5
+ //#region src/utils/paths.ts
5
6
  const SIMILARITY_THRESHOLDS = {
6
- EXACT_MATCH: 1,
7
- CONTAINS_MATCH: 0.8,
8
- PARTIAL_MATCH: 0.5,
9
- MIN_SUGGESTION: 0.3,
7
+ EXACT_MATCH: 1,
8
+ CONTAINS_MATCH: .8,
9
+ PARTIAL_MATCH: .5,
10
+ MIN_SUGGESTION: .3
10
11
  };
11
- export async function listDirContents(dirPath) {
12
- try {
13
- const items = await readdir(dirPath, { withFileTypes: true });
14
- const directories = items
15
- .filter((item) => item.isDirectory())
16
- .map((item) => item.name)
17
- .filter((name) => !name.startsWith("."))
18
- .sort();
19
- const files = items
20
- .filter((item) => item.isFile() &&
21
- (extname(item.name) === MDX_EXTENSION ||
22
- extname(item.name) === MD_EXTENSION))
23
- .map((item) => item.name)
24
- .sort();
25
- return { directories, files };
26
- }
27
- catch (error) {
28
- logger.error(`Failed to list directory contents: ${dirPath}`, error);
29
- return { directories: [], files: [] };
30
- }
12
+ async function listDirContents(dirPath) {
13
+ try {
14
+ const items = await readdir(dirPath, { withFileTypes: true });
15
+ return {
16
+ directories: items.filter((item) => item.isDirectory()).map((item) => item.name).filter((name) => !name.startsWith(".")).sort(),
17
+ files: items.filter((item) => item.isFile() && (extname(item.name) === ".mdx" || extname(item.name) === ".md")).map((item) => item.name).sort()
18
+ };
19
+ } catch (error) {
20
+ logger.error(`Failed to list directory contents: ${dirPath}`, error);
21
+ return {
22
+ directories: [],
23
+ files: []
24
+ };
25
+ }
31
26
  }
32
- export async function getAvailablePaths() {
33
- const paths = [];
34
- async function scanDirectory(dir, prefix = "") {
35
- const { directories, files } = await listDirContents(dir);
36
- for (const file of files) {
37
- const name = file.replace(MDX_EXTENSION, "").replace(MD_EXTENSION, "");
38
- paths.push(prefix ? `${prefix}/${name}` : name);
39
- }
40
- for (const subdir of directories) {
41
- const subdirPath = join(dir, subdir);
42
- const newPrefix = prefix ? `${prefix}/${subdir}` : subdir;
43
- paths.push(newPrefix);
44
- await scanDirectory(subdirPath, newPrefix);
45
- }
46
- }
47
- await scanDirectory(DOCS_PATH);
48
- return paths.sort();
27
+ async function getAvailablePaths() {
28
+ const paths = [];
29
+ async function scanDirectory(dir, prefix = "") {
30
+ const { directories, files } = await listDirContents(dir);
31
+ for (const file of files) {
32
+ const name = file.replace(MDX_EXTENSION, "").replace(".md", "");
33
+ paths.push(prefix ? `${prefix}/${name}` : name);
34
+ }
35
+ for (const subdir of directories) {
36
+ const subdirPath = join(dir, subdir);
37
+ const newPrefix = prefix ? `${prefix}/${subdir}` : subdir;
38
+ paths.push(newPrefix);
39
+ await scanDirectory(subdirPath, newPrefix);
40
+ }
41
+ }
42
+ await scanDirectory(DOCS_PATH);
43
+ return paths.sort();
49
44
  }
50
- export function findNearestPaths(requestedPath, availablePaths) {
51
- const normalizedRequest = requestedPath
52
- .toLowerCase()
53
- .replace(/[^a-z0-9]/g, "");
54
- const scored = availablePaths.map((path) => {
55
- const normalizedPath = path.toLowerCase().replace(/[^a-z0-9]/g, "");
56
- if (normalizedPath.includes(normalizedRequest)) {
57
- return { path, score: SIMILARITY_THRESHOLDS.EXACT_MATCH };
58
- }
59
- if (normalizedRequest.includes(normalizedPath)) {
60
- return { path, score: SIMILARITY_THRESHOLDS.CONTAINS_MATCH };
61
- }
62
- const overlap = [...normalizedRequest].filter((char) => normalizedPath.includes(char)).length;
63
- return {
64
- path,
65
- score: (overlap / normalizedRequest.length) *
66
- SIMILARITY_THRESHOLDS.PARTIAL_MATCH,
67
- };
68
- });
69
- return scored
70
- .filter((item) => item.score > SIMILARITY_THRESHOLDS.MIN_SUGGESTION)
71
- .sort((a, b) => b.score - a.score)
72
- .slice(0, 3)
73
- .map((item) => item.path);
45
+ function findNearestPaths(requestedPath, availablePaths) {
46
+ const normalizedRequest = requestedPath.toLowerCase().replace(/[^a-z0-9]/g, "");
47
+ return availablePaths.map((path) => {
48
+ const normalizedPath = path.toLowerCase().replace(/[^a-z0-9]/g, "");
49
+ if (normalizedPath.includes(normalizedRequest)) return {
50
+ path,
51
+ score: SIMILARITY_THRESHOLDS.EXACT_MATCH
52
+ };
53
+ if (normalizedRequest.includes(normalizedPath)) return {
54
+ path,
55
+ score: SIMILARITY_THRESHOLDS.CONTAINS_MATCH
56
+ };
57
+ return {
58
+ path,
59
+ score: [...normalizedRequest].filter((char) => normalizedPath.includes(char)).length / normalizedRequest.length * SIMILARITY_THRESHOLDS.PARTIAL_MATCH
60
+ };
61
+ }).filter((item) => item.score > SIMILARITY_THRESHOLDS.MIN_SUGGESTION).sort((a, b) => b.score - a.score).slice(0, 3).map((item) => item.path);
74
62
  }
75
- export async function pathExists(path) {
76
- try {
77
- await stat(path);
78
- return true;
79
- }
80
- catch {
81
- return false;
82
- }
63
+ async function pathExists(path) {
64
+ try {
65
+ await stat(path);
66
+ return true;
67
+ } catch {
68
+ return false;
69
+ }
83
70
  }
71
+ //#endregion
72
+ export { findNearestPaths, getAvailablePaths, listDirContents, pathExists };
73
+
84
74
  //# sourceMappingURL=paths.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"paths.js","names":[],"sources":["../../src/utils/paths.ts"],"sourcesContent":["import { readdir, stat } from \"node:fs/promises\";\nimport { join, extname } from \"node:path\";\nimport { DOCS_PATH, MDX_EXTENSION, MD_EXTENSION } from \"../constants.js\";\nimport { logger } from \"./logger.js\";\n\nconst SIMILARITY_THRESHOLDS = {\n EXACT_MATCH: 1,\n CONTAINS_MATCH: 0.8,\n PARTIAL_MATCH: 0.5,\n MIN_SUGGESTION: 0.3,\n} as const;\n\nexport async function listDirContents(dirPath: string): Promise<{\n directories: string[];\n files: string[];\n}> {\n try {\n const items = await readdir(dirPath, { withFileTypes: true });\n\n const directories = items\n .filter((item) => item.isDirectory())\n .map((item) => item.name)\n .filter((name) => !name.startsWith(\".\"))\n .sort();\n\n const files = items\n .filter(\n (item) =>\n item.isFile() &&\n (extname(item.name) === MDX_EXTENSION ||\n extname(item.name) === MD_EXTENSION),\n )\n .map((item) => item.name)\n .sort();\n\n return { directories, files };\n } catch (error) {\n logger.error(`Failed to list directory contents: ${dirPath}`, error);\n return { directories: [], files: [] };\n }\n}\n\nexport async function getAvailablePaths(): Promise<string[]> {\n const paths: string[] = [];\n\n async function scanDirectory(\n dir: string,\n prefix: string = \"\",\n ): Promise<void> {\n const { directories, files } = await listDirContents(dir);\n\n for (const file of files) {\n const name = file.replace(MDX_EXTENSION, \"\").replace(MD_EXTENSION, \"\");\n paths.push(prefix ? `${prefix}/${name}` : name);\n }\n\n for (const subdir of directories) {\n const subdirPath = join(dir, subdir);\n const newPrefix = prefix ? `${prefix}/${subdir}` : subdir;\n paths.push(newPrefix);\n await scanDirectory(subdirPath, newPrefix);\n }\n }\n\n await scanDirectory(DOCS_PATH);\n return paths.sort();\n}\n\nexport function findNearestPaths(\n requestedPath: string,\n availablePaths: string[],\n): string[] {\n const normalizedRequest = requestedPath\n .toLowerCase()\n .replace(/[^a-z0-9]/g, \"\");\n\n const scored = availablePaths.map((path) => {\n const normalizedPath = path.toLowerCase().replace(/[^a-z0-9]/g, \"\");\n\n if (normalizedPath.includes(normalizedRequest)) {\n return { path, score: SIMILARITY_THRESHOLDS.EXACT_MATCH };\n }\n\n if (normalizedRequest.includes(normalizedPath)) {\n return { path, score: SIMILARITY_THRESHOLDS.CONTAINS_MATCH };\n }\n\n const overlap = [...normalizedRequest].filter((char) =>\n normalizedPath.includes(char),\n ).length;\n\n return {\n path,\n score:\n (overlap / normalizedRequest.length) *\n SIMILARITY_THRESHOLDS.PARTIAL_MATCH,\n };\n });\n\n return scored\n .filter((item) => item.score > SIMILARITY_THRESHOLDS.MIN_SUGGESTION)\n .sort((a, b) => b.score - a.score)\n .slice(0, 3)\n .map((item) => item.path);\n}\n\nexport async function pathExists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n"],"mappings":";;;;;AAKA,MAAM,wBAAwB;CAC5B,aAAa;CACb,gBAAgB;CAChB,eAAe;CACf,gBAAgB;AAClB;AAEA,eAAsB,gBAAgB,SAGnC;CACD,IAAI;EACF,MAAM,QAAQ,MAAM,QAAQ,SAAS,EAAE,eAAe,KAAK,CAAC;EAkB5D,OAAO;GAAE,aAhBW,MACjB,QAAQ,SAAS,KAAK,YAAY,CAAC,EACnC,KAAK,SAAS,KAAK,IAAI,EACvB,QAAQ,SAAS,CAAC,KAAK,WAAW,GAAG,CAAC,EACtC,KAYgB;GAAG,OAVR,MACX,QACE,SACC,KAAK,OAAO,MACX,QAAQ,KAAK,IAAI,MAAA,UAChB,QAAQ,KAAK,IAAI,MAAA,MACvB,EACC,KAAK,SAAS,KAAK,IAAI,EACvB,KAEuB;EAAE;CAC9B,SAAS,OAAO;EACd,OAAO,MAAM,sCAAsC,WAAW,KAAK;EACnE,OAAO;GAAE,aAAa,CAAC;GAAG,OAAO,CAAC;EAAE;CACtC;AACF;AAEA,eAAsB,oBAAuC;CAC3D,MAAM,QAAkB,CAAC;CAEzB,eAAe,cACb,KACA,SAAiB,IACF;EACf,MAAM,EAAE,aAAa,UAAU,MAAM,gBAAgB,GAAG;EAExD,KAAK,MAAM,QAAQ,OAAO;GACxB,MAAM,OAAO,KAAK,QAAQ,eAAe,EAAE,EAAE,QAAA,OAAsB,EAAE;GACrE,MAAM,KAAK,SAAS,GAAG,OAAO,GAAG,SAAS,IAAI;EAChD;EAEA,KAAK,MAAM,UAAU,aAAa;GAChC,MAAM,aAAa,KAAK,KAAK,MAAM;GACnC,MAAM,YAAY,SAAS,GAAG,OAAO,GAAG,WAAW;GACnD,MAAM,KAAK,SAAS;GACpB,MAAM,cAAc,YAAY,SAAS;EAC3C;CACF;CAEA,MAAM,cAAc,SAAS;CAC7B,OAAO,MAAM,KAAK;AACpB;AAEA,SAAgB,iBACd,eACA,gBACU;CACV,MAAM,oBAAoB,cACvB,YAAY,EACZ,QAAQ,cAAc,EAAE;CAyB3B,OAvBe,eAAe,KAAK,SAAS;EAC1C,MAAM,iBAAiB,KAAK,YAAY,EAAE,QAAQ,cAAc,EAAE;EAElE,IAAI,eAAe,SAAS,iBAAiB,GAC3C,OAAO;GAAE;GAAM,OAAO,sBAAsB;EAAY;EAG1D,IAAI,kBAAkB,SAAS,cAAc,GAC3C,OAAO;GAAE;GAAM,OAAO,sBAAsB;EAAe;EAO7D,OAAO;GACL;GACA,OANc,CAAC,GAAG,iBAAiB,EAAE,QAAQ,SAC7C,eAAe,SAAS,IAAI,CAC9B,EAAE,SAKa,kBAAkB,SAC7B,sBAAsB;EAC1B;CACF,CAEY,EACT,QAAQ,SAAS,KAAK,QAAQ,sBAAsB,cAAc,EAClE,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK,EAChC,MAAM,GAAG,CAAC,EACV,KAAK,SAAS,KAAK,IAAI;AAC5B;AAEA,eAAsB,WAAW,MAAgC;CAC/D,IAAI;EACF,MAAM,KAAK,IAAI;EACf,OAAO;CACT,QAAQ;EACN,OAAO;CACT;AACF"}
@@ -1,2 +1,5 @@
1
- export declare function sanitizePath(userPath: string): string;
1
+ //#region src/utils/security.d.ts
2
+ declare function sanitizePath(userPath: string): string;
3
+ //#endregion
4
+ export { sanitizePath };
2
5
  //# sourceMappingURL=security.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../src/utils/security.ts"],"names":[],"mappings":"AAEA,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAiDrD"}
1
+ {"version":3,"file":"security.d.ts","names":[],"sources":["../../src/utils/security.ts"],"mappings":";iBAEgB,YAAA,CAAa,QAAgB"}
@@ -1,43 +1,22 @@
1
1
  import path from "node:path";
2
- export function sanitizePath(userPath) {
3
- if (!userPath || typeof userPath !== "string") {
4
- throw new Error("Invalid path: Path must be a non-empty string");
5
- }
6
- // Check for traversal patterns before normalization - defense in depth
7
- if (userPath.includes("../") || userPath.includes("..\\")) {
8
- throw new Error("Invalid path: Directory traversal attempt detected");
9
- }
10
- const normalized = path.normalize(userPath);
11
- if (path.isAbsolute(normalized)) {
12
- throw new Error("Invalid path: Absolute paths are not allowed");
13
- }
14
- const relativePath = path.relative("", normalized);
15
- if (relativePath.startsWith("..")) {
16
- throw new Error("Invalid path: Directory traversal attempt detected");
17
- }
18
- if (relativePath.includes("..")) {
19
- throw new Error("Invalid path: Path contains invalid traversal sequences");
20
- }
21
- if (relativePath.includes("\0")) {
22
- throw new Error("Invalid path: Path contains null bytes");
23
- }
24
- if (process.platform !== "win32") {
25
- if (normalized.includes("\\")) {
26
- throw new Error("Invalid path: Backslashes not allowed");
27
- }
28
- }
29
- else {
30
- if (normalized.includes(":") || normalized.startsWith("\\\\")) {
31
- throw new Error("Invalid path: Path contains invalid Windows characters");
32
- }
33
- }
34
- const segments = relativePath.split(path.sep);
35
- for (const segment of segments) {
36
- if (segment.startsWith(".") && segment !== ".") {
37
- throw new Error("Invalid path: Hidden files are not allowed");
38
- }
39
- }
40
- // Always return Unix-style paths for consistency across platforms
41
- return relativePath.replace(/\\/g, "/");
2
+ //#region src/utils/security.ts
3
+ function sanitizePath(userPath) {
4
+ if (!userPath || typeof userPath !== "string") throw new Error("Invalid path: Path must be a non-empty string");
5
+ if (userPath.includes("../") || userPath.includes("..\\")) throw new Error("Invalid path: Directory traversal attempt detected");
6
+ const normalized = path.normalize(userPath);
7
+ if (path.isAbsolute(normalized)) throw new Error("Invalid path: Absolute paths are not allowed");
8
+ const relativePath = path.relative("", normalized);
9
+ if (relativePath.startsWith("..")) throw new Error("Invalid path: Directory traversal attempt detected");
10
+ if (relativePath.includes("..")) throw new Error("Invalid path: Path contains invalid traversal sequences");
11
+ if (relativePath.includes("\0")) throw new Error("Invalid path: Path contains null bytes");
12
+ if (process.platform !== "win32") {
13
+ if (normalized.includes("\\")) throw new Error("Invalid path: Backslashes not allowed");
14
+ } else if (normalized.includes(":") || normalized.startsWith("\\\\")) throw new Error("Invalid path: Path contains invalid Windows characters");
15
+ const segments = relativePath.split(path.sep);
16
+ for (const segment of segments) if (segment.startsWith(".") && segment !== ".") throw new Error("Invalid path: Hidden files are not allowed");
17
+ return relativePath.replace(/\\/g, "/");
42
18
  }
19
+ //#endregion
20
+ export { sanitizePath };
21
+
43
22
  //# sourceMappingURL=security.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"security.js","sourceRoot":"","sources":["../../src/utils/security.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,UAAU,YAAY,CAAC,QAAgB;IAC3C,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;IAED,uEAAuE;IACvE,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACxE,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAE5C,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;IAEnD,IAAI,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACxE,CAAC;IAED,IAAI,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC7E,CAAC;IAED,IAAI,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAC5D,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;SAAM,CAAC;QACN,IAAI,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9D,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC9C,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,KAAK,GAAG,EAAE,CAAC;YAC/C,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IAED,kEAAkE;IAClE,OAAO,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAC1C,CAAC"}
1
+ {"version":3,"file":"security.js","names":[],"sources":["../../src/utils/security.ts"],"sourcesContent":["import path from \"node:path\";\n\nexport function sanitizePath(userPath: string): string {\n if (!userPath || typeof userPath !== \"string\") {\n throw new Error(\"Invalid path: Path must be a non-empty string\");\n }\n\n // Check for traversal patterns before normalization - defense in depth\n if (userPath.includes(\"../\") || userPath.includes(\"..\\\\\")) {\n throw new Error(\"Invalid path: Directory traversal attempt detected\");\n }\n\n const normalized = path.normalize(userPath);\n\n if (path.isAbsolute(normalized)) {\n throw new Error(\"Invalid path: Absolute paths are not allowed\");\n }\n\n const relativePath = path.relative(\"\", normalized);\n\n if (relativePath.startsWith(\"..\")) {\n throw new Error(\"Invalid path: Directory traversal attempt detected\");\n }\n\n if (relativePath.includes(\"..\")) {\n throw new Error(\"Invalid path: Path contains invalid traversal sequences\");\n }\n\n if (relativePath.includes(\"\\0\")) {\n throw new Error(\"Invalid path: Path contains null bytes\");\n }\n\n if (process.platform !== \"win32\") {\n if (normalized.includes(\"\\\\\")) {\n throw new Error(\"Invalid path: Backslashes not allowed\");\n }\n } else {\n if (normalized.includes(\":\") || normalized.startsWith(\"\\\\\\\\\")) {\n throw new Error(\"Invalid path: Path contains invalid Windows characters\");\n }\n }\n\n const segments = relativePath.split(path.sep);\n for (const segment of segments) {\n if (segment.startsWith(\".\") && segment !== \".\") {\n throw new Error(\"Invalid path: Hidden files are not allowed\");\n }\n }\n\n // Always return Unix-style paths for consistency across platforms\n return relativePath.replace(/\\\\/g, \"/\");\n}\n"],"mappings":";;AAEA,SAAgB,aAAa,UAA0B;CACrD,IAAI,CAAC,YAAY,OAAO,aAAa,UACnC,MAAM,IAAI,MAAM,+CAA+C;CAIjE,IAAI,SAAS,SAAS,KAAK,KAAK,SAAS,SAAS,MAAM,GACtD,MAAM,IAAI,MAAM,oDAAoD;CAGtE,MAAM,aAAa,KAAK,UAAU,QAAQ;CAE1C,IAAI,KAAK,WAAW,UAAU,GAC5B,MAAM,IAAI,MAAM,8CAA8C;CAGhE,MAAM,eAAe,KAAK,SAAS,IAAI,UAAU;CAEjD,IAAI,aAAa,WAAW,IAAI,GAC9B,MAAM,IAAI,MAAM,oDAAoD;CAGtE,IAAI,aAAa,SAAS,IAAI,GAC5B,MAAM,IAAI,MAAM,yDAAyD;CAG3E,IAAI,aAAa,SAAS,IAAI,GAC5B,MAAM,IAAI,MAAM,wCAAwC;CAG1D,IAAI,QAAQ,aAAa;MACnB,WAAW,SAAS,IAAI,GAC1B,MAAM,IAAI,MAAM,uCAAuC;CAAA,OAGzD,IAAI,WAAW,SAAS,GAAG,KAAK,WAAW,WAAW,MAAM,GAC1D,MAAM,IAAI,MAAM,wDAAwD;CAI5E,MAAM,WAAW,aAAa,MAAM,KAAK,GAAG;CAC5C,KAAK,MAAM,WAAW,UACpB,IAAI,QAAQ,WAAW,GAAG,KAAK,YAAY,KACzC,MAAM,IAAI,MAAM,4CAA4C;CAKhE,OAAO,aAAa,QAAQ,OAAO,GAAG;AACxC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@assistant-ui/mcp-docs-server",
3
- "version": "0.1.31",
3
+ "version": "0.1.32",
4
4
  "description": "MCP server for assistant-ui documentation and examples",
5
5
  "keywords": [
6
6
  "mcp",
@@ -37,10 +37,10 @@
37
37
  "zod": "^4.4.3"
38
38
  },
39
39
  "devDependencies": {
40
- "@types/node": "^25.6.0",
41
- "tsx": "^4.21.0",
42
- "vitest": "^4.1.5",
43
- "@assistant-ui/x-buildutils": "0.0.7"
40
+ "@types/node": "^25.9.1",
41
+ "tsx": "^4.22.3",
42
+ "vitest": "^4.1.7",
43
+ "@assistant-ui/x-buildutils": "0.0.9"
44
44
  },
45
45
  "publishConfig": {
46
46
  "access": "public",
@@ -1,41 +0,0 @@
1
- ---
2
- title: Feedback and Speech Adapters
3
- description: Capture message feedback and connect speech or dictation.
4
- ---
5
-
6
- ## Feedback
7
-
8
- `FeedbackAdapter` receives message feedback submitted through action primitives or runtime actions.
9
-
10
- ```tsx
11
- const runtime = useLocalRuntime(chatModelAdapter, {
12
- adapters: {
13
- feedback: {
14
- submit: async ({ message, type }) => {
15
- await fetch("/api/feedback", {
16
- method: "POST",
17
- body: JSON.stringify({ messageId: message.id, type }),
18
- });
19
- },
20
- },
21
- },
22
- });
23
- ```
24
-
25
- ## Speech
26
-
27
- `SpeechSynthesisAdapter` controls text-to-speech playback. `WebSpeechSynthesisAdapter` provides a browser implementation.
28
-
29
- ```tsx
30
- import { WebSpeechSynthesisAdapter } from "@assistant-ui/react";
31
-
32
- const runtime = useLocalRuntime(chatModelAdapter, {
33
- adapters: {
34
- speech: new WebSpeechSynthesisAdapter(),
35
- },
36
- });
37
- ```
38
-
39
- ## Dictation and Suggestions
40
-
41
- Runtime adapters can also provide dictation and suggestion behavior. Dictation powers composer voice input; suggestions power prompt suggestions rendered by thread and suggestion primitives.
@@ -1,40 +0,0 @@
1
- ---
2
- title: <TextMessagePartProvider />
3
- description: Context provider for reusing text components outside of message content.
4
- ---
5
-
6
- The `TextMessagePartProvider` provides data and APIs for `TextMessagePart` components.
7
-
8
- This is useful if you want to reuse the same `Text` component outside of a message text, e.g. with the `@assistant-ui/react-markdown` package.
9
-
10
- ```tsx
11
- import { TextMessagePartProvider } from "@assistant-ui/react";
12
-
13
- const MyApp = () => {
14
- return (
15
- <TextMessagePartProvider text={"Hello!"}>
16
- <MyMarkdownText />
17
- </TextMessagePartProvider>
18
- );
19
- };
20
- ```
21
-
22
- #### Properties
23
-
24
- <ParametersTable
25
- type="TextMessagePartProviderProps"
26
- parameters={[
27
- {
28
- name: "text",
29
- type: "string",
30
- required: true,
31
- description: "The text content to provide to child components.",
32
- },
33
- {
34
- name: "isRunning",
35
- type: "boolean",
36
- required: false,
37
- description: "Whether the text is still being streamed. Defaults to false.",
38
- },
39
- ]}
40
- />
@@ -1,260 +0,0 @@
1
- ---
2
- title: "@assistant-ui/react-data-stream"
3
- description: Hooks for connecting to data stream protocol endpoints and Assistant Cloud.
4
- ---
5
-
6
- Data Stream protocol integration for assistant-ui.
7
-
8
-
9
- ## API Reference
10
-
11
- ### `useDataStreamRuntime`
12
-
13
- Create a runtime that connects to a data stream protocol endpoint.
14
-
15
- ```tsx
16
- import { useDataStreamRuntime } from "@assistant-ui/react-data-stream";
17
-
18
- const MyRuntimeProvider = ({ children }: { children: React.ReactNode }) => {
19
- const runtime = useDataStreamRuntime({
20
- api: "/api/chat",
21
- });
22
-
23
- return (
24
- <AssistantRuntimeProvider runtime={runtime}>
25
- {children}
26
- </AssistantRuntimeProvider>
27
- );
28
- };
29
- ```
30
-
31
- <ParametersTable
32
- parameters={[
33
- {
34
- name: "api",
35
- type: "string",
36
- description: "The API endpoint URL for the data stream protocol.",
37
- },
38
- {
39
- name: "protocol",
40
- type: '"ui-message-stream" | "data-stream"',
41
- description: 'The streaming protocol to use. Defaults to "ui-message-stream". Use "data-stream" for legacy AI SDK compatibility.',
42
- },
43
- {
44
- name: "onData",
45
- type: "(data: { type: string; name: string; data: unknown; transient?: boolean }) => void",
46
- description: "Optional callback for data-* parts. Only applies when using the ui-message-stream protocol.",
47
- },
48
- {
49
- name: "onResponse",
50
- type: "(response: Response) => void | Promise<void>",
51
- description: "Optional callback called when a response is received.",
52
- },
53
- {
54
- name: "onFinish",
55
- type: "(message: ThreadMessage) => void",
56
- description: "Optional callback called when a message is finished.",
57
- },
58
- {
59
- name: "onError",
60
- type: "(error: Error) => void",
61
- description: "Optional callback called when an error occurs.",
62
- },
63
- {
64
- name: "onCancel",
65
- type: "() => void",
66
- description: "Optional callback called when a request is cancelled.",
67
- },
68
- {
69
- name: "credentials",
70
- type: "RequestCredentials",
71
- description: "Optional credentials mode for the fetch request.",
72
- },
73
- {
74
- name: "headers",
75
- type: "Record<string, string> | Headers | (() => Promise<Record<string, string> | Headers>)",
76
- description: "Optional headers to include in the request.",
77
- },
78
- {
79
- name: "body",
80
- type: "object | (() => Promise<object | undefined>)",
81
- description: "Optional additional body parameters to include in the request. Can be an object or an async function that returns one.",
82
- },
83
- {
84
- name: "sendExtraMessageFields",
85
- type: "boolean",
86
- description: "Whether to include extra message fields like IDs in the request.",
87
- },
88
- ]}
89
- />
90
-
91
- ### `useCloudRuntime`
92
-
93
- Create a runtime that connects to Assistant Cloud using the data stream protocol.
94
-
95
- ```tsx
96
- import { useCloudRuntime } from "@assistant-ui/react-data-stream";
97
-
98
- const MyRuntimeProvider = ({ children }: { children: React.ReactNode }) => {
99
- const runtime = useCloudRuntime({
100
- cloud: assistantCloud,
101
- assistantId: "my-assistant-id",
102
- });
103
-
104
- return (
105
- <AssistantRuntimeProvider runtime={runtime}>
106
- {children}
107
- </AssistantRuntimeProvider>
108
- );
109
- };
110
- ```
111
-
112
- <ParametersTable
113
- parameters={[
114
- {
115
- name: "cloud",
116
- type: "AssistantCloud",
117
- description: "The Assistant Cloud instance.",
118
- },
119
- {
120
- name: "assistantId",
121
- type: "string",
122
- description: "The ID of the assistant to connect to.",
123
- },
124
- {
125
- name: "protocol",
126
- type: '"ui-message-stream" | "data-stream"',
127
- description: 'The streaming protocol to use. Defaults to "ui-message-stream". Use "data-stream" for legacy AI SDK compatibility.',
128
- },
129
- {
130
- name: "onData",
131
- type: "(data: { type: string; name: string; data: unknown; transient?: boolean }) => void",
132
- description: "Optional callback for data-* parts. Only applies when using the ui-message-stream protocol.",
133
- },
134
- {
135
- name: "onResponse",
136
- type: "(response: Response) => void | Promise<void>",
137
- description: "Optional callback called when a response is received.",
138
- },
139
- {
140
- name: "onFinish",
141
- type: "(message: ThreadMessage) => void",
142
- description: "Optional callback called when a message is finished.",
143
- },
144
- {
145
- name: "onError",
146
- type: "(error: Error) => void",
147
- description: "Optional callback called when an error occurs.",
148
- },
149
- {
150
- name: "onCancel",
151
- type: "() => void",
152
- description: "Optional callback called when a request is cancelled.",
153
- },
154
- {
155
- name: "credentials",
156
- type: "RequestCredentials",
157
- description: "Optional credentials mode for the fetch request.",
158
- },
159
- {
160
- name: "headers",
161
- type: "Record<string, string> | Headers | (() => Promise<Record<string, string> | Headers>)",
162
- description: "Optional headers to include in the request.",
163
- },
164
- {
165
- name: "body",
166
- type: "object | (() => Promise<object | undefined>)",
167
- description: "Optional additional body parameters to include in the request. Can be an object or an async function that returns one.",
168
- },
169
- {
170
- name: "sendExtraMessageFields",
171
- type: "boolean",
172
- description: "Whether to include extra message fields like IDs in the request.",
173
- },
174
- ]}
175
- />
176
-
177
- ### `toLanguageModelMessages`
178
-
179
- Convert assistant-ui messages to AI SDK's `LanguageModelV2Message` format.
180
-
181
- <Callout type="info">
182
- For custom integrations, consider using `toGenericMessages` from `assistant-stream` instead.
183
- This function is specific to the AI SDK format.
184
- </Callout>
185
-
186
- ```tsx
187
- import { toLanguageModelMessages } from "@assistant-ui/react-data-stream";
188
-
189
- const languageModelMessages = toLanguageModelMessages(messages, {
190
- unstable_includeId: true,
191
- });
192
- ```
193
-
194
- <ParametersTable
195
- parameters={[
196
- {
197
- name: "messages",
198
- type: "readonly ThreadMessage[]",
199
- description: "The messages to convert.",
200
- },
201
- {
202
- name: "options",
203
- type: "{ unstable_includeId?: boolean }",
204
- description: "Optional conversion options.",
205
- children: [
206
- {
207
- type: "{ unstable_includeId?: boolean }",
208
- parameters: [
209
- {
210
- name: "unstable_includeId",
211
- type: "boolean",
212
- description: "Whether to include message IDs in the converted messages.",
213
- },
214
- ],
215
- },
216
- ],
217
- },
218
- ]}
219
- />
220
-
221
- ---
222
-
223
- ## Framework-Agnostic Utilities
224
-
225
- For custom integrations that don't use the AI SDK, use these utilities from `assistant-stream`:
226
-
227
- ### `toGenericMessages`
228
-
229
- Convert thread messages to a framework-agnostic format.
230
-
231
- ```tsx
232
- import { toGenericMessages } from "assistant-stream";
233
-
234
- const genericMessages = toGenericMessages(messages);
235
- ```
236
-
237
- Returns an array of `GenericMessage` which can be one of:
238
- - `{ role: "system"; content: string }`
239
- - `{ role: "user"; content: (GenericTextPart | GenericFilePart)[] }`
240
- - `{ role: "assistant"; content: (GenericTextPart | GenericToolCallPart)[] }`
241
- - `{ role: "tool"; content: GenericToolResultPart[] }`
242
-
243
- ### `toToolsJSONSchema`
244
-
245
- Convert tool definitions to JSON Schema format.
246
-
247
- ```tsx
248
- import { toToolsJSONSchema } from "assistant-stream";
249
-
250
- const toolSchemas = toToolsJSONSchema(tools);
251
- // Returns: Record<string, { description?: string; parameters: JSONSchema7 }>
252
- ```
253
-
254
- By default, filters out disabled tools and backend-only tools. Use the `filter` option to customize:
255
-
256
- ```tsx
257
- const allTools = toToolsJSONSchema(tools, {
258
- filter: () => true, // Include all tools
259
- });
260
- ```