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

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 (112) hide show
  1. package/.docs/organized/code-examples/waterfall.md +15 -17
  2. package/.docs/organized/code-examples/with-a2a.md +19 -19
  3. package/.docs/organized/code-examples/with-ag-ui.md +25 -20
  4. package/.docs/organized/code-examples/with-ai-sdk-v6.md +6 -4
  5. package/.docs/organized/code-examples/with-artifacts.md +34 -28
  6. package/.docs/organized/code-examples/with-assistant-transport.md +59 -47
  7. package/.docs/organized/code-examples/with-browser-extension.md +17 -5
  8. package/.docs/organized/code-examples/with-chain-of-thought.md +376 -78
  9. package/.docs/organized/code-examples/with-cloud-standalone.md +20 -19
  10. package/.docs/organized/code-examples/with-cloud.md +6 -4
  11. package/.docs/organized/code-examples/with-custom-thread-list.md +9 -7
  12. package/.docs/organized/code-examples/with-elevenlabs-conversational.md +18 -16
  13. package/.docs/organized/code-examples/with-elevenlabs-scribe.md +9 -8
  14. package/.docs/organized/code-examples/with-expo.md +23 -17
  15. package/.docs/organized/code-examples/with-external-store.md +4 -2
  16. package/.docs/organized/code-examples/with-ffmpeg.md +317 -280
  17. package/.docs/organized/code-examples/with-generative-ui.md +1018 -214
  18. package/.docs/organized/code-examples/with-google-adk.md +4 -2
  19. package/.docs/organized/code-examples/with-heat-graph.md +8 -6
  20. package/.docs/organized/code-examples/with-image-generation.md +19 -17
  21. package/.docs/organized/code-examples/with-interactables.md +312 -234
  22. package/.docs/organized/code-examples/with-langchain.md +9 -7
  23. package/.docs/organized/code-examples/with-langgraph.md +82 -78
  24. package/.docs/organized/code-examples/with-livekit.md +19 -17
  25. package/.docs/organized/code-examples/with-mcp.md +13 -7
  26. package/.docs/organized/code-examples/with-opencode.md +61 -61
  27. package/.docs/organized/code-examples/with-react-hook-form.md +14 -12
  28. package/.docs/organized/code-examples/with-react-ink.md +2 -2
  29. package/.docs/organized/code-examples/with-react-router.md +11 -9
  30. package/.docs/organized/code-examples/with-resumable-stream.md +10 -9
  31. package/.docs/organized/code-examples/with-store.md +14 -12
  32. package/.docs/organized/code-examples/with-tanstack.md +8 -9
  33. package/.docs/organized/code-examples/with-tap-runtime.md +21 -19
  34. package/.docs/raw/docs/(docs)/architecture.mdx +43 -2
  35. package/.docs/raw/docs/(docs)/cli.mdx +1 -2
  36. package/.docs/raw/docs/(docs)/copilots/model-context.mdx +34 -26
  37. package/.docs/raw/docs/(docs)/copilots/motivation.mdx +32 -26
  38. package/.docs/raw/docs/(docs)/installation.mdx +1 -1
  39. package/.docs/raw/docs/(reference)/api-reference/adapters/persistence.mdx +5 -1
  40. package/.docs/raw/docs/(reference)/api-reference/external-store/message-conversion.mdx +14 -14
  41. package/.docs/raw/docs/(reference)/api-reference/external-store/runtime.mdx +11 -1
  42. package/.docs/raw/docs/(reference)/api-reference/generative-ui/index.mdx +18 -0
  43. package/.docs/raw/docs/(reference)/api-reference/generative-ui/rendering.mdx +33 -0
  44. package/.docs/raw/docs/(reference)/api-reference/generative-ui/spec.mdx +45 -0
  45. package/.docs/raw/docs/(reference)/api-reference/hooks/composer-triggers.mdx +41 -41
  46. package/.docs/raw/docs/(reference)/api-reference/hooks/model-context.mdx +19 -1
  47. package/.docs/raw/docs/(reference)/api-reference/hooks/primitives.mdx +122 -122
  48. package/.docs/raw/docs/(reference)/api-reference/integrations/react-ai-sdk.mdx +32 -2
  49. package/.docs/raw/docs/(reference)/api-reference/model-context/context.mdx +6 -0
  50. package/.docs/raw/docs/(reference)/api-reference/overview.mdx +4 -6
  51. package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +30 -0
  52. package/.docs/raw/docs/(reference)/api-reference/tools/component-tools.mdx +20 -3
  53. package/.docs/raw/docs/(reference)/api-reference/tools/index.mdx +8 -8
  54. package/.docs/raw/docs/(reference)/api-reference/tools/rendering.mdx +52 -4
  55. package/.docs/raw/docs/(reference)/api-reference/tools/toolkits.mdx +6 -7
  56. package/.docs/raw/docs/(reference)/api-reference/utilities/miscellaneous.mdx +58 -46
  57. package/.docs/raw/docs/cloud/ai-sdk.mdx +0 -2
  58. package/.docs/raw/docs/guides/chain-of-thought.mdx +7 -9
  59. package/.docs/raw/docs/guides/context-api.mdx +2 -1
  60. package/.docs/raw/docs/guides/index.mdx +3 -12
  61. package/.docs/raw/docs/guides/mentions.mdx +4 -4
  62. package/.docs/raw/docs/guides/slash-commands.mdx +1 -1
  63. package/.docs/raw/docs/guides/suggestions.mdx +1 -1
  64. package/.docs/raw/docs/ink/hooks.mdx +98 -85
  65. package/.docs/raw/docs/ink/migration.mdx +1 -1
  66. package/.docs/raw/docs/ink/primitives.mdx +2 -2
  67. package/.docs/raw/docs/integrations/frameworks/ai-sdk.mdx +1 -1
  68. package/.docs/raw/docs/integrations/index.mdx +2 -2
  69. package/.docs/raw/docs/integrations/persistence/custom-adapter.mdx +17 -2
  70. package/.docs/raw/docs/migrations/toolkit-tools.mdx +226 -0
  71. package/.docs/raw/docs/primitives/chain-of-thought.mdx +10 -16
  72. package/.docs/raw/docs/primitives/message.mdx +9 -10
  73. package/.docs/raw/docs/react-native/hooks.mdx +57 -82
  74. package/.docs/raw/docs/react-native/migration.mdx +1 -1
  75. package/.docs/raw/docs/react-native/primitives.mdx +2 -2
  76. package/.docs/raw/docs/runtimes/a2a/client-and-hooks.mdx +3 -0
  77. package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +122 -1
  78. package/.docs/raw/docs/runtimes/concepts/threads.mdx +7 -1
  79. package/.docs/raw/docs/runtimes/custom/local-runtime.mdx +18 -7
  80. package/.docs/raw/docs/runtimes/google-adk/hooks.mdx +108 -38
  81. package/.docs/raw/docs/runtimes/langgraph/generative-ui.mdx +2 -2
  82. package/.docs/raw/docs/runtimes/langgraph/streaming.mdx +1 -1
  83. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +64 -50
  84. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-3.mdx +98 -86
  85. package/.docs/raw/docs/tools/backend.mdx +136 -0
  86. package/.docs/raw/docs/tools/defining-tools.mdx +413 -0
  87. package/.docs/raw/docs/tools/dynamic-tools.mdx +110 -0
  88. package/.docs/raw/docs/tools/generative-ui.mdx +214 -0
  89. package/.docs/raw/docs/tools/index.mdx +76 -0
  90. package/.docs/raw/docs/{guides → tools}/interactables.mdx +1 -1
  91. package/.docs/raw/docs/{integrations/tools → tools}/mcp.mdx +77 -50
  92. package/.docs/raw/docs/{guides → tools}/multi-agent.mdx +17 -19
  93. package/.docs/raw/docs/tools/tool-ui.mdx +967 -0
  94. package/.docs/raw/docs/{integrations/tools/react-mcp.mdx → tools/user-managed-mcp.mdx} +3 -3
  95. package/.docs/raw/docs/ui/directive-text.mdx +3 -3
  96. package/.docs/raw/docs/ui/mcp-config.mdx +4 -4
  97. package/.docs/raw/docs/ui/part-grouping.mdx +84 -50
  98. package/.docs/raw/docs/ui/reasoning.mdx +4 -5
  99. package/.docs/raw/docs/ui/tool-group.mdx +5 -6
  100. package/.docs/raw/docs/utilities/heat-graph.mdx +1 -1
  101. package/dist/index.d.ts.map +1 -1
  102. package/dist/prepare-docs/code-examples.d.ts.map +1 -1
  103. package/dist/prepare-docs/copy-raw.d.ts.map +1 -1
  104. package/dist/utils/paths.d.ts.map +1 -1
  105. package/package.json +3 -3
  106. package/.docs/organized/code-examples/with-parent-id-grouping.md +0 -596
  107. package/.docs/raw/docs/(docs)/copilots/make-assistant-tool-ui.mdx +0 -151
  108. package/.docs/raw/docs/(docs)/copilots/make-assistant-tool.mdx +0 -230
  109. package/.docs/raw/docs/guides/generative-ui.mdx +0 -142
  110. package/.docs/raw/docs/guides/tool-ui.mdx +0 -858
  111. package/.docs/raw/docs/guides/tools.mdx +0 -736
  112. /package/.docs/raw/docs/{guides → tools}/mcp-apps.mdx +0 -0
@@ -81,46 +81,44 @@ type PurchaseStockResult = {
81
81
  };
82
82
  ```
83
83
 
84
- Then we use `makeAssistantToolUI` to define the tool UI:
84
+ Then we define a tool UI renderer:
85
85
 
86
86
  ```tsx title="@/components/tools/purchase-stock/PurchaseStockTool.tsx"
87
87
  "use client";
88
88
 
89
89
  import { TransactionConfirmationPending } from "./transaction-confirmation-pending";
90
90
  import { TransactionConfirmationFinal } from "./transaction-confirmation-final";
91
- import { makeAssistantToolUI } from "@assistant-ui/react";
92
-
93
- export const PurchaseStockTool = makeAssistantToolUI<PurchaseStockArgs, string>(
94
- {
95
- toolName: "purchase_stock",
96
- render: function PurchaseStockUI({ args, result, status, addResult }) {
97
- const handleReject = async () => {
98
- addResult(JSON.stringify({ approve: false }));
99
- };
100
-
101
- const handleConfirm = async () => {
102
- addResult(JSON.stringify({ approve: true }));
103
- };
104
-
105
- return (
106
- <div className="mb-4 flex flex-col items-center gap-2">
107
- <div>
108
- <pre className="whitespace-pre-wrap break-all text-center">
109
- purchase_stock({JSON.stringify(args)})
110
- </pre>
111
- </div>
112
- {!result && status.type !== "running" && (
113
- <TransactionConfirmationPending
114
- {...args}
115
- onConfirm={handleConfirm}
116
- onReject={handleReject}
117
- />
118
- )}
119
- </div>
120
- );
121
- },
122
- },
123
- );
91
+ import type { ToolCallMessagePartComponent } from "@assistant-ui/react";
92
+
93
+ export const PurchaseStockToolUI: ToolCallMessagePartComponent<
94
+ PurchaseStockArgs,
95
+ string
96
+ > = function PurchaseStockUI({ args, result, status, addResult }) {
97
+ const handleReject = async () => {
98
+ addResult(JSON.stringify({ approve: false }));
99
+ };
100
+
101
+ const handleConfirm = async () => {
102
+ addResult(JSON.stringify({ approve: true }));
103
+ };
104
+
105
+ return (
106
+ <div className="mb-4 flex flex-col items-center gap-2">
107
+ <div>
108
+ <pre className="whitespace-pre-wrap break-all text-center">
109
+ purchase_stock({JSON.stringify(args)})
110
+ </pre>
111
+ </div>
112
+ {!result && status.type !== "running" && (
113
+ <TransactionConfirmationPending
114
+ {...args}
115
+ onConfirm={handleConfirm}
116
+ onReject={handleReject}
117
+ />
118
+ )}
119
+ </div>
120
+ );
121
+ };
124
122
  ```
125
123
 
126
124
  Finally, we add a `TransactionConfirmationPending` component to ask for approval.
@@ -208,16 +206,32 @@ export function TransactionConfirmationPending(props: TransactionConfirmation) {
208
206
 
209
207
  ### Bind approval UI
210
208
 
211
- ```tsx title="@/app/page.tsx" {1,8}
212
- import { PurchaseStockTool } from "@/components/tools/purchase-stock/PurchaseStockTool";
209
+ ```tsx title="@/app/page.tsx" {1-5,12}
210
+ "use client";
211
+
212
+ import { Thread } from "@/components/assistant-ui/thread";
213
+ import { PriceSnapshotToolUI } from "@/components/tools/price-snapshot/PriceSnapshotTool";
214
+ import { PurchaseStockToolUI } from "@/components/tools/purchase-stock/PurchaseStockTool";
215
+ import { AuiProvider, Tools, type Toolkit, useAui } from "@assistant-ui/react";
216
+
217
+ const toolkit = {
218
+ price_snapshot: {
219
+ type: "backend",
220
+ render: PriceSnapshotToolUI,
221
+ },
222
+ purchase_stock: {
223
+ type: "backend",
224
+ render: PurchaseStockToolUI,
225
+ },
226
+ } satisfies Toolkit;
213
227
 
214
228
  export default function Home() {
229
+ const aui = useAui({ tools: Tools({ toolkit }) });
230
+
215
231
  return (
216
- <div className="flex h-full flex-col">
217
- <PriceSnapshotTool />
218
- <PurchaseStockTool />
232
+ <AuiProvider value={aui}>
219
233
  <Thread />
220
- </div>
234
+ </AuiProvider>
221
235
  );
222
236
  }
223
237
  ```
@@ -305,7 +319,7 @@ We will import the new `<TransactionConfirmationFinal />` component and use it i
305
319
 
306
320
  import { TransactionConfirmationPending } from "./transaction-confirmation-pending";
307
321
  import { TransactionConfirmationFinal } from "./transaction-confirmation-final";
308
- import { makeAssistantToolUI } from "@assistant-ui/react";
322
+ import type { ToolCallMessagePartComponent } from "@assistant-ui/react";
309
323
 
310
324
  type PurchaseStockArgs = {
311
325
  ticker: string;
@@ -320,51 +334,49 @@ type PurchaseStockResult = {
320
334
  error?: string;
321
335
  };
322
336
 
323
- export const PurchaseStockTool = makeAssistantToolUI<PurchaseStockArgs, string>(
324
- {
325
- toolName: "purchase_stock",
326
- render: function PurchaseStockUI({ args, result, status, addResult }) {
327
- let resultObj: PurchaseStockResult;
328
- try {
329
- resultObj = result ? JSON.parse(result) : {};
330
- } catch (e) {
331
- resultObj = { error: result! };
332
- }
333
-
334
- const handleReject = () => {
335
- addResult(JSON.stringify({ approve: false }));
336
- };
337
-
338
- const handleConfirm = async () => {
339
- addResult(JSON.stringify({ approve: true }));
340
- };
341
-
342
- return (
343
- <div className="mb-4 flex flex-col items-center gap-2">
344
- <div>
345
- <pre className="whitespace-pre-wrap break-all text-center">
346
- purchase_stock({JSON.stringify(args)})
347
- </pre>
348
- </div>
349
- {!result && status.type !== "running" && (
350
- <TransactionConfirmationPending
351
- {...args}
352
- onConfirm={handleConfirm}
353
- onReject={handleReject}
354
- />
355
- )}
356
- {resultObj.approve && <TransactionConfirmationFinal {...args} />}
357
- {resultObj.approve === false && (
358
- <pre className="font-bold text-red-600">User rejected purchase</pre>
359
- )}
360
- {resultObj.cancelled && (
361
- <pre className="font-bold text-red-600">Cancelled</pre>
362
- )}
363
- </div>
364
- );
365
- },
366
- },
367
- );
337
+ export const PurchaseStockToolUI: ToolCallMessagePartComponent<
338
+ PurchaseStockArgs,
339
+ string
340
+ > = function PurchaseStockUI({ args, result, status, addResult }) {
341
+ let resultObj: PurchaseStockResult;
342
+ try {
343
+ resultObj = result ? JSON.parse(result) : {};
344
+ } catch (e) {
345
+ resultObj = { error: result! };
346
+ }
347
+
348
+ const handleReject = () => {
349
+ addResult(JSON.stringify({ approve: false }));
350
+ };
351
+
352
+ const handleConfirm = async () => {
353
+ addResult(JSON.stringify({ approve: true }));
354
+ };
355
+
356
+ return (
357
+ <div className="mb-4 flex flex-col items-center gap-2">
358
+ <div>
359
+ <pre className="whitespace-pre-wrap break-all text-center">
360
+ purchase_stock({JSON.stringify(args)})
361
+ </pre>
362
+ </div>
363
+ {!result && status.type !== "running" && (
364
+ <TransactionConfirmationPending
365
+ {...args}
366
+ onConfirm={handleConfirm}
367
+ onReject={handleReject}
368
+ />
369
+ )}
370
+ {resultObj.approve && <TransactionConfirmationFinal {...args} />}
371
+ {resultObj.approve === false && (
372
+ <pre className="font-bold text-red-600">User rejected purchase</pre>
373
+ )}
374
+ {resultObj.cancelled && (
375
+ <pre className="font-bold text-red-600">Cancelled</pre>
376
+ )}
377
+ </div>
378
+ );
379
+ };
368
380
  ```
369
381
 
370
382
  ### Try it out!
@@ -0,0 +1,136 @@
1
+ ---
2
+ title: Backend Tools
3
+ description: Wire assistant-ui toolkits into your server with the AI SDK — generativeTools, frontendTools, mixing client and server tools, and multi-modal results.
4
+ platforms: ["react"]
5
+ ---
6
+
7
+ A tool is only callable if the **model** knows about it, and the model is configured on your server. This page covers wiring a toolkit into an AI SDK route handler: exposing your generative toolkit, receiving client-defined tools, mixing the two, and round-tripping multi-modal results.
8
+
9
+ For authoring tools, see [Defining Tools](/docs/tools/defining-tools). For MCP servers, see [MCP](/docs/tools/mcp).
10
+
11
+ ## The request body
12
+
13
+ `@assistant-ui/react-ai-sdk` posts `{ messages, system, tools }` to your route. `tools` is the map of **frontend** tools the client serialized for this request (the model needs their schemas to call them, even though they run in the browser):
14
+
15
+ ```ts
16
+ const {
17
+ messages,
18
+ system,
19
+ tools,
20
+ }: {
21
+ messages: UIMessage[];
22
+ system?: string;
23
+ tools?: Record<string, { description?: string; parameters: JSONSchema7 }>;
24
+ } = await req.json();
25
+ ```
26
+
27
+ ## Generative toolkits: `generativeTools`
28
+
29
+ When you author tools in a [`"use generative"` file](/docs/tools/defining-tools#quick-start-use-generative), the same import resolves to the **server build** inside a route handler — schema plus any backend `execute`, with renderers stripped. Pass it to `generativeTools` together with the uploaded `tools`:
30
+
31
+ ```ts title="app/api/chat/route.ts"
32
+ import { generativeTools } from "@assistant-ui/react-ai-sdk";
33
+ import { streamText, convertToModelMessages, type UIMessage } from "ai";
34
+ import { openai } from "@ai-sdk/openai";
35
+ import toolkit from "../../toolkit";
36
+
37
+ export async function POST(req: Request) {
38
+ const { messages, system, tools } = await req.json();
39
+
40
+ const result = streamText({
41
+ model: openai("gpt-5.4-nano"),
42
+ system,
43
+ messages: await convertToModelMessages(messages),
44
+ tools: generativeTools({ toolkit, frontendTools: tools }),
45
+ });
46
+
47
+ return result.toUIMessageStreamResponse();
48
+ }
49
+ ```
50
+
51
+ `generativeTools` registers every toolkit tool with the model using its schema, wires the backend `execute` where the server build carries one, and merges in the uploaded `frontendTools`. A server `execute` wins over an uploaded entry of the same name. Frontend and human tools (no server `execute`) are exposed schema-only and left for the client and the user to fulfill.
52
+
53
+ <Callout type="info">
54
+ If your toolkit spreads in MCP server tools (`defineMcpToolkit`), use
55
+ `new AISDKToolkit({ toolkit }).tools({ frontend })` instead of
56
+ `generativeTools` — it also opens the MCP connections. See [MCP](/docs/tools/mcp).
57
+ </Callout>
58
+
59
+ ## Client-defined tools: `frontendTools`
60
+
61
+ If you don't use the generative compiler — for example a plain [`satisfies Toolkit`](/docs/tools/defining-tools#render-only-tools-for-externally-executed-tools) with browser-executed tools — the AI SDK adapter still serializes those tools into the request `tools`. Convert them to the AI SDK shape with `frontendTools` and spread your own server tools alongside:
62
+
63
+ ```ts title="app/api/chat/route.ts"
64
+ import { frontendTools } from "@assistant-ui/react-ai-sdk";
65
+ import { streamText, convertToModelMessages, tool, zodSchema } from "ai";
66
+ import { openai } from "@ai-sdk/openai";
67
+ import { z } from "zod";
68
+
69
+ export async function POST(req: Request) {
70
+ const { messages, tools } = await req.json();
71
+
72
+ const result = streamText({
73
+ model: openai("gpt-5.4-nano"),
74
+ messages: await convertToModelMessages(messages),
75
+ tools: {
76
+ ...frontendTools(tools ?? {}),
77
+ query_database: tool({
78
+ description: "Query the application database.",
79
+ inputSchema: zodSchema(z.object({ query: z.string() })),
80
+ execute: async ({ query }) => db.query(query),
81
+ }),
82
+ },
83
+ });
84
+
85
+ return result.toUIMessageStreamResponse();
86
+ }
87
+ ```
88
+
89
+ `generativeTools` calls `frontendTools` for you under the hood; reach for `frontendTools` directly when you're not on the generative build.
90
+
91
+ <Callout type="tip">
92
+ `toToolsJSONSchema` emits the uploaded tools in alphabetical order, so two
93
+ renders that register the same set produce byte-identical request bodies —
94
+ which keeps provider prompt caches stable across renders.
95
+ </Callout>
96
+
97
+ ## Multi-modal results
98
+
99
+ When a tool declares [`toModelOutput`](/docs/tools/defining-tools#multi-modal-tool-results), frontend tool results round-trip through the AI SDK chat protocol back to your route on the next turn. For `toModelOutput` to fire on those round-tripped results, pass the tool registry to `convertToModelMessages` as well — the [same pattern the AI SDK documents](https://ai-sdk.dev/docs/reference/ai-sdk-ui/convert-to-model-messages#multi-modal-tool-responses) for any multi-modal tool response:
100
+
101
+ ```ts
102
+ const aiSDKTools = { ...frontendTools(tools ?? {}) };
103
+
104
+ const result = streamText({
105
+ model,
106
+ // Pass tools to BOTH calls so prior results are projected via toModelOutput.
107
+ messages: await convertToModelMessages(messages, { tools: aiSDKTools }),
108
+ tools: aiSDKTools,
109
+ });
110
+ ```
111
+
112
+ Skip the `{ tools }` argument and prior results are sent as a plain JSON blob — `toModelOutput` is silently ignored. Tools without `toModelOutput` are unaffected either way.
113
+
114
+ <Callout type="warn">
115
+ **Read/write compatibility for persisted threads.** When `toModelOutput` is
116
+ set, the runtime persists the AI SDK output as
117
+ `{ __aui_modelContent, value }`. Upgrade every reader before any writer starts
118
+ producing `toModelOutput`; older readers treat the whole envelope as the
119
+ `result` and break that tool's `render`. Don't return objects whose top-level
120
+ key is literally `__aui_modelContent` from any `execute`.
121
+ </Callout>
122
+
123
+ ## Multi-step tool calls
124
+
125
+ To let the model see a frontend tool's result and continue, configure the runtime to send back automatically when the last assistant message is complete with tool calls:
126
+
127
+ ```tsx
128
+ import { lastAssistantMessageIsCompleteWithToolCalls } from "ai";
129
+
130
+ const runtime = useChatRuntime({
131
+ api: "/api/chat",
132
+ sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithToolCalls,
133
+ });
134
+ ```
135
+
136
+ For the full AI SDK v6 backend setup — history persistence, reasoning, server-side approvals — see the [AI SDK v6 guide](/docs/runtimes/ai-sdk/v6).