ai 6.0.31 → 6.0.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.
- package/CHANGELOG.md +6 -0
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/internal/index.js +1 -1
- package/dist/internal/index.mjs +1 -1
- package/docs/00-introduction/index.mdx +76 -0
- package/docs/02-foundations/01-overview.mdx +43 -0
- package/docs/02-foundations/02-providers-and-models.mdx +163 -0
- package/docs/02-foundations/03-prompts.mdx +620 -0
- package/docs/02-foundations/04-tools.mdx +160 -0
- package/docs/02-foundations/05-streaming.mdx +62 -0
- package/docs/02-foundations/index.mdx +43 -0
- package/docs/02-getting-started/00-choosing-a-provider.mdx +110 -0
- package/docs/02-getting-started/01-navigating-the-library.mdx +85 -0
- package/docs/02-getting-started/02-nextjs-app-router.mdx +556 -0
- package/docs/02-getting-started/03-nextjs-pages-router.mdx +542 -0
- package/docs/02-getting-started/04-svelte.mdx +627 -0
- package/docs/02-getting-started/05-nuxt.mdx +566 -0
- package/docs/02-getting-started/06-nodejs.mdx +512 -0
- package/docs/02-getting-started/07-expo.mdx +766 -0
- package/docs/02-getting-started/08-tanstack-start.mdx +583 -0
- package/docs/02-getting-started/index.mdx +44 -0
- package/docs/03-agents/01-overview.mdx +96 -0
- package/docs/03-agents/02-building-agents.mdx +367 -0
- package/docs/03-agents/03-workflows.mdx +370 -0
- package/docs/03-agents/04-loop-control.mdx +350 -0
- package/docs/03-agents/05-configuring-call-options.mdx +286 -0
- package/docs/03-agents/index.mdx +40 -0
- package/docs/03-ai-sdk-core/01-overview.mdx +33 -0
- package/docs/03-ai-sdk-core/05-generating-text.mdx +600 -0
- package/docs/03-ai-sdk-core/10-generating-structured-data.mdx +662 -0
- package/docs/03-ai-sdk-core/15-tools-and-tool-calling.mdx +1102 -0
- package/docs/03-ai-sdk-core/16-mcp-tools.mdx +375 -0
- package/docs/03-ai-sdk-core/20-prompt-engineering.mdx +144 -0
- package/docs/03-ai-sdk-core/25-settings.mdx +198 -0
- package/docs/03-ai-sdk-core/30-embeddings.mdx +247 -0
- package/docs/03-ai-sdk-core/31-reranking.mdx +218 -0
- package/docs/03-ai-sdk-core/35-image-generation.mdx +341 -0
- package/docs/03-ai-sdk-core/36-transcription.mdx +173 -0
- package/docs/03-ai-sdk-core/37-speech.mdx +167 -0
- package/docs/03-ai-sdk-core/40-middleware.mdx +480 -0
- package/docs/03-ai-sdk-core/45-provider-management.mdx +349 -0
- package/docs/03-ai-sdk-core/50-error-handling.mdx +149 -0
- package/docs/03-ai-sdk-core/55-testing.mdx +218 -0
- package/docs/03-ai-sdk-core/60-telemetry.mdx +313 -0
- package/docs/03-ai-sdk-core/65-devtools.mdx +107 -0
- package/docs/03-ai-sdk-core/index.mdx +88 -0
- package/docs/04-ai-sdk-ui/01-overview.mdx +44 -0
- package/docs/04-ai-sdk-ui/02-chatbot.mdx +1313 -0
- package/docs/04-ai-sdk-ui/03-chatbot-message-persistence.mdx +535 -0
- package/docs/04-ai-sdk-ui/03-chatbot-resume-streams.mdx +263 -0
- package/docs/04-ai-sdk-ui/03-chatbot-tool-usage.mdx +682 -0
- package/docs/04-ai-sdk-ui/04-generative-user-interfaces.mdx +389 -0
- package/docs/04-ai-sdk-ui/05-completion.mdx +186 -0
- package/docs/04-ai-sdk-ui/08-object-generation.mdx +344 -0
- package/docs/04-ai-sdk-ui/20-streaming-data.mdx +397 -0
- package/docs/04-ai-sdk-ui/21-error-handling.mdx +190 -0
- package/docs/04-ai-sdk-ui/21-transport.mdx +174 -0
- package/docs/04-ai-sdk-ui/24-reading-ui-message-streams.mdx +104 -0
- package/docs/04-ai-sdk-ui/25-message-metadata.mdx +152 -0
- package/docs/04-ai-sdk-ui/50-stream-protocol.mdx +477 -0
- package/docs/04-ai-sdk-ui/index.mdx +64 -0
- package/docs/05-ai-sdk-rsc/01-overview.mdx +45 -0
- package/docs/05-ai-sdk-rsc/02-streaming-react-components.mdx +209 -0
- package/docs/05-ai-sdk-rsc/03-generative-ui-state.mdx +279 -0
- package/docs/05-ai-sdk-rsc/03-saving-and-restoring-states.mdx +105 -0
- package/docs/05-ai-sdk-rsc/04-multistep-interfaces.mdx +282 -0
- package/docs/05-ai-sdk-rsc/05-streaming-values.mdx +158 -0
- package/docs/05-ai-sdk-rsc/06-loading-state.mdx +273 -0
- package/docs/05-ai-sdk-rsc/08-error-handling.mdx +96 -0
- package/docs/05-ai-sdk-rsc/09-authentication.mdx +42 -0
- package/docs/05-ai-sdk-rsc/10-migrating-to-ui.mdx +722 -0
- package/docs/05-ai-sdk-rsc/index.mdx +58 -0
- package/docs/06-advanced/01-prompt-engineering.mdx +96 -0
- package/docs/06-advanced/02-stopping-streams.mdx +184 -0
- package/docs/06-advanced/03-backpressure.mdx +173 -0
- package/docs/06-advanced/04-caching.mdx +169 -0
- package/docs/06-advanced/05-multiple-streamables.mdx +68 -0
- package/docs/06-advanced/06-rate-limiting.mdx +60 -0
- package/docs/06-advanced/07-rendering-ui-with-language-models.mdx +213 -0
- package/docs/06-advanced/08-model-as-router.mdx +120 -0
- package/docs/06-advanced/09-multistep-interfaces.mdx +115 -0
- package/docs/06-advanced/09-sequential-generations.mdx +55 -0
- package/docs/06-advanced/10-vercel-deployment-guide.mdx +117 -0
- package/docs/06-advanced/index.mdx +11 -0
- package/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx +2142 -0
- package/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx +3215 -0
- package/docs/07-reference/01-ai-sdk-core/03-generate-object.mdx +780 -0
- package/docs/07-reference/01-ai-sdk-core/04-stream-object.mdx +1140 -0
- package/docs/07-reference/01-ai-sdk-core/05-embed.mdx +190 -0
- package/docs/07-reference/01-ai-sdk-core/06-embed-many.mdx +171 -0
- package/docs/07-reference/01-ai-sdk-core/06-rerank.mdx +309 -0
- package/docs/07-reference/01-ai-sdk-core/10-generate-image.mdx +227 -0
- package/docs/07-reference/01-ai-sdk-core/11-transcribe.mdx +138 -0
- package/docs/07-reference/01-ai-sdk-core/12-generate-speech.mdx +214 -0
- package/docs/07-reference/01-ai-sdk-core/15-agent.mdx +203 -0
- package/docs/07-reference/01-ai-sdk-core/16-tool-loop-agent.mdx +449 -0
- package/docs/07-reference/01-ai-sdk-core/17-create-agent-ui-stream.mdx +148 -0
- package/docs/07-reference/01-ai-sdk-core/18-create-agent-ui-stream-response.mdx +168 -0
- package/docs/07-reference/01-ai-sdk-core/18-pipe-agent-ui-stream-to-response.mdx +144 -0
- package/docs/07-reference/01-ai-sdk-core/20-tool.mdx +196 -0
- package/docs/07-reference/01-ai-sdk-core/22-dynamic-tool.mdx +175 -0
- package/docs/07-reference/01-ai-sdk-core/23-create-mcp-client.mdx +410 -0
- package/docs/07-reference/01-ai-sdk-core/24-mcp-stdio-transport.mdx +68 -0
- package/docs/07-reference/01-ai-sdk-core/25-json-schema.mdx +94 -0
- package/docs/07-reference/01-ai-sdk-core/26-zod-schema.mdx +109 -0
- package/docs/07-reference/01-ai-sdk-core/27-valibot-schema.mdx +55 -0
- package/docs/07-reference/01-ai-sdk-core/28-output.mdx +342 -0
- package/docs/07-reference/01-ai-sdk-core/30-model-message.mdx +415 -0
- package/docs/07-reference/01-ai-sdk-core/31-ui-message.mdx +246 -0
- package/docs/07-reference/01-ai-sdk-core/32-validate-ui-messages.mdx +101 -0
- package/docs/07-reference/01-ai-sdk-core/33-safe-validate-ui-messages.mdx +113 -0
- package/docs/07-reference/01-ai-sdk-core/40-provider-registry.mdx +182 -0
- package/docs/07-reference/01-ai-sdk-core/42-custom-provider.mdx +121 -0
- package/docs/07-reference/01-ai-sdk-core/50-cosine-similarity.mdx +52 -0
- package/docs/07-reference/01-ai-sdk-core/60-wrap-language-model.mdx +59 -0
- package/docs/07-reference/01-ai-sdk-core/61-wrap-image-model.mdx +64 -0
- package/docs/07-reference/01-ai-sdk-core/65-language-model-v2-middleware.mdx +46 -0
- package/docs/07-reference/01-ai-sdk-core/66-extract-reasoning-middleware.mdx +68 -0
- package/docs/07-reference/01-ai-sdk-core/67-simulate-streaming-middleware.mdx +71 -0
- package/docs/07-reference/01-ai-sdk-core/68-default-settings-middleware.mdx +80 -0
- package/docs/07-reference/01-ai-sdk-core/69-add-tool-input-examples-middleware.mdx +155 -0
- package/docs/07-reference/01-ai-sdk-core/70-extract-json-middleware.mdx +147 -0
- package/docs/07-reference/01-ai-sdk-core/70-step-count-is.mdx +84 -0
- package/docs/07-reference/01-ai-sdk-core/71-has-tool-call.mdx +120 -0
- package/docs/07-reference/01-ai-sdk-core/75-simulate-readable-stream.mdx +94 -0
- package/docs/07-reference/01-ai-sdk-core/80-smooth-stream.mdx +145 -0
- package/docs/07-reference/01-ai-sdk-core/90-generate-id.mdx +43 -0
- package/docs/07-reference/01-ai-sdk-core/91-create-id-generator.mdx +89 -0
- package/docs/07-reference/01-ai-sdk-core/index.mdx +159 -0
- package/docs/07-reference/02-ai-sdk-ui/01-use-chat.mdx +446 -0
- package/docs/07-reference/02-ai-sdk-ui/02-use-completion.mdx +179 -0
- package/docs/07-reference/02-ai-sdk-ui/03-use-object.mdx +178 -0
- package/docs/07-reference/02-ai-sdk-ui/31-convert-to-model-messages.mdx +230 -0
- package/docs/07-reference/02-ai-sdk-ui/32-prune-messages.mdx +108 -0
- package/docs/07-reference/02-ai-sdk-ui/40-create-ui-message-stream.mdx +151 -0
- package/docs/07-reference/02-ai-sdk-ui/41-create-ui-message-stream-response.mdx +113 -0
- package/docs/07-reference/02-ai-sdk-ui/42-pipe-ui-message-stream-to-response.mdx +73 -0
- package/docs/07-reference/02-ai-sdk-ui/43-read-ui-message-stream.mdx +57 -0
- package/docs/07-reference/02-ai-sdk-ui/46-infer-ui-tools.mdx +99 -0
- package/docs/07-reference/02-ai-sdk-ui/47-infer-ui-tool.mdx +75 -0
- package/docs/07-reference/02-ai-sdk-ui/50-direct-chat-transport.mdx +333 -0
- package/docs/07-reference/02-ai-sdk-ui/index.mdx +89 -0
- package/docs/07-reference/03-ai-sdk-rsc/01-stream-ui.mdx +767 -0
- package/docs/07-reference/03-ai-sdk-rsc/02-create-ai.mdx +90 -0
- package/docs/07-reference/03-ai-sdk-rsc/03-create-streamable-ui.mdx +91 -0
- package/docs/07-reference/03-ai-sdk-rsc/04-create-streamable-value.mdx +48 -0
- package/docs/07-reference/03-ai-sdk-rsc/05-read-streamable-value.mdx +78 -0
- package/docs/07-reference/03-ai-sdk-rsc/06-get-ai-state.mdx +50 -0
- package/docs/07-reference/03-ai-sdk-rsc/07-get-mutable-ai-state.mdx +70 -0
- package/docs/07-reference/03-ai-sdk-rsc/08-use-ai-state.mdx +26 -0
- package/docs/07-reference/03-ai-sdk-rsc/09-use-actions.mdx +42 -0
- package/docs/07-reference/03-ai-sdk-rsc/10-use-ui-state.mdx +35 -0
- package/docs/07-reference/03-ai-sdk-rsc/11-use-streamable-value.mdx +46 -0
- package/docs/07-reference/03-ai-sdk-rsc/20-render.mdx +262 -0
- package/docs/07-reference/03-ai-sdk-rsc/index.mdx +67 -0
- package/docs/07-reference/04-stream-helpers/01-ai-stream.mdx +89 -0
- package/docs/07-reference/04-stream-helpers/02-streaming-text-response.mdx +79 -0
- package/docs/07-reference/04-stream-helpers/05-stream-to-response.mdx +108 -0
- package/docs/07-reference/04-stream-helpers/07-openai-stream.mdx +77 -0
- package/docs/07-reference/04-stream-helpers/08-anthropic-stream.mdx +79 -0
- package/docs/07-reference/04-stream-helpers/09-aws-bedrock-stream.mdx +91 -0
- package/docs/07-reference/04-stream-helpers/10-aws-bedrock-anthropic-stream.mdx +96 -0
- package/docs/07-reference/04-stream-helpers/10-aws-bedrock-messages-stream.mdx +96 -0
- package/docs/07-reference/04-stream-helpers/11-aws-bedrock-cohere-stream.mdx +93 -0
- package/docs/07-reference/04-stream-helpers/12-aws-bedrock-llama-2-stream.mdx +93 -0
- package/docs/07-reference/04-stream-helpers/13-cohere-stream.mdx +78 -0
- package/docs/07-reference/04-stream-helpers/14-google-generative-ai-stream.mdx +85 -0
- package/docs/07-reference/04-stream-helpers/15-hugging-face-stream.mdx +84 -0
- package/docs/07-reference/04-stream-helpers/16-langchain-adapter.mdx +98 -0
- package/docs/07-reference/04-stream-helpers/16-llamaindex-adapter.mdx +70 -0
- package/docs/07-reference/04-stream-helpers/17-mistral-stream.mdx +81 -0
- package/docs/07-reference/04-stream-helpers/18-replicate-stream.mdx +83 -0
- package/docs/07-reference/04-stream-helpers/19-inkeep-stream.mdx +80 -0
- package/docs/07-reference/04-stream-helpers/index.mdx +103 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-api-call-error.mdx +30 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-download-error.mdx +27 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-empty-response-body-error.mdx +24 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-invalid-argument-error.mdx +26 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-invalid-data-content-error.mdx +25 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-invalid-data-content.mdx +26 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-invalid-message-role-error.mdx +25 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-invalid-prompt-error.mdx +47 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-invalid-response-data-error.mdx +25 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-invalid-tool-approval-error.mdx +25 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-invalid-tool-input-error.mdx +27 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-json-parse-error.mdx +25 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-load-api-key-error.mdx +24 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-load-setting-error.mdx +24 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-message-conversion-error.mdx +25 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-no-content-generated-error.mdx +24 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-no-image-generated-error.mdx +36 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-no-object-generated-error.mdx +43 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-no-speech-generated-error.mdx +25 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-no-such-model-error.mdx +26 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-no-such-provider-error.mdx +28 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-no-such-tool-error.mdx +26 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-no-transcript-generated-error.mdx +25 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-retry-error.mdx +27 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-too-many-embedding-values-for-call-error.mdx +27 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-tool-call-not-found-for-approval-error.mdx +26 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-tool-call-repair-error.mdx +28 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-type-validation-error.mdx +25 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-unsupported-functionality-error.mdx +25 -0
- package/docs/07-reference/05-ai-sdk-errors/index.mdx +38 -0
- package/docs/07-reference/index.mdx +34 -0
- package/docs/08-migration-guides/00-versioning.mdx +46 -0
- package/docs/08-migration-guides/24-migration-guide-6-0.mdx +823 -0
- package/docs/08-migration-guides/25-migration-guide-5-0-data.mdx +882 -0
- package/docs/08-migration-guides/26-migration-guide-5-0.mdx +3427 -0
- package/docs/08-migration-guides/27-migration-guide-4-2.mdx +99 -0
- package/docs/08-migration-guides/28-migration-guide-4-1.mdx +14 -0
- package/docs/08-migration-guides/29-migration-guide-4-0.mdx +1157 -0
- package/docs/08-migration-guides/36-migration-guide-3-4.mdx +14 -0
- package/docs/08-migration-guides/37-migration-guide-3-3.mdx +64 -0
- package/docs/08-migration-guides/38-migration-guide-3-2.mdx +46 -0
- package/docs/08-migration-guides/39-migration-guide-3-1.mdx +168 -0
- package/docs/08-migration-guides/index.mdx +22 -0
- package/docs/09-troubleshooting/01-azure-stream-slow.mdx +33 -0
- package/docs/09-troubleshooting/02-client-side-function-calls-not-invoked.mdx +22 -0
- package/docs/09-troubleshooting/03-server-actions-in-client-components.mdx +40 -0
- package/docs/09-troubleshooting/04-strange-stream-output.mdx +36 -0
- package/docs/09-troubleshooting/05-streamable-ui-errors.mdx +16 -0
- package/docs/09-troubleshooting/05-tool-invocation-missing-result.mdx +106 -0
- package/docs/09-troubleshooting/06-streaming-not-working-when-deployed.mdx +31 -0
- package/docs/09-troubleshooting/06-streaming-not-working-when-proxied.mdx +31 -0
- package/docs/09-troubleshooting/06-timeout-on-vercel.mdx +60 -0
- package/docs/09-troubleshooting/07-unclosed-streams.mdx +34 -0
- package/docs/09-troubleshooting/08-use-chat-failed-to-parse-stream.mdx +26 -0
- package/docs/09-troubleshooting/09-client-stream-error.mdx +25 -0
- package/docs/09-troubleshooting/10-use-chat-tools-no-response.mdx +32 -0
- package/docs/09-troubleshooting/11-use-chat-custom-request-options.mdx +149 -0
- package/docs/09-troubleshooting/12-typescript-performance-zod.mdx +46 -0
- package/docs/09-troubleshooting/12-use-chat-an-error-occurred.mdx +59 -0
- package/docs/09-troubleshooting/13-repeated-assistant-messages.mdx +73 -0
- package/docs/09-troubleshooting/14-stream-abort-handling.mdx +73 -0
- package/docs/09-troubleshooting/14-tool-calling-with-structured-outputs.mdx +48 -0
- package/docs/09-troubleshooting/15-abort-breaks-resumable-streams.mdx +55 -0
- package/docs/09-troubleshooting/15-stream-text-not-working.mdx +33 -0
- package/docs/09-troubleshooting/16-streaming-status-delay.mdx +63 -0
- package/docs/09-troubleshooting/17-use-chat-stale-body-data.mdx +141 -0
- package/docs/09-troubleshooting/18-ontoolcall-type-narrowing.mdx +66 -0
- package/docs/09-troubleshooting/19-unsupported-model-version.mdx +50 -0
- package/docs/09-troubleshooting/20-no-object-generated-content-filter.mdx +72 -0
- package/docs/09-troubleshooting/30-model-is-not-assignable-to-type.mdx +21 -0
- package/docs/09-troubleshooting/40-typescript-cannot-find-namespace-jsx.mdx +24 -0
- package/docs/09-troubleshooting/50-react-maximum-update-depth-exceeded.mdx +39 -0
- package/docs/09-troubleshooting/60-jest-cannot-find-module-ai-rsc.mdx +22 -0
- package/docs/09-troubleshooting/index.mdx +11 -0
- package/package.json +8 -4
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Handling Loading State
|
|
3
|
+
description: Overview of handling loading state with AI SDK RSC
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Handling Loading State
|
|
7
|
+
|
|
8
|
+
<Note type="warning">
|
|
9
|
+
AI SDK RSC is currently experimental. We recommend using [AI SDK
|
|
10
|
+
UI](/docs/ai-sdk-ui/overview) for production. For guidance on migrating from
|
|
11
|
+
RSC to UI, see our [migration guide](/docs/ai-sdk-rsc/migrating-to-ui).
|
|
12
|
+
</Note>
|
|
13
|
+
|
|
14
|
+
Given that responses from language models can often take a while to complete, it's crucial to be able to show loading state to users. This provides visual feedback that the system is working on their request and helps maintain a positive user experience.
|
|
15
|
+
|
|
16
|
+
There are three approaches you can take to handle loading state with the AI SDK RSC:
|
|
17
|
+
|
|
18
|
+
- Managing loading state similar to how you would in a traditional Next.js application. This involves setting a loading state variable in the client and updating it when the response is received.
|
|
19
|
+
- Streaming loading state from the server to the client. This approach allows you to track loading state on a more granular level and provide more detailed feedback to the user.
|
|
20
|
+
- Streaming loading component from the server to the client. This approach allows you to stream a React Server Component to the client while awaiting the model's response.
|
|
21
|
+
|
|
22
|
+
## Handling Loading State on the Client
|
|
23
|
+
|
|
24
|
+
### Client
|
|
25
|
+
|
|
26
|
+
Let's create a simple Next.js page that will call the `generateResponse` function when the form is submitted. The function will take in the user's prompt (`input`) and then generate a response (`response`). To handle the loading state, use the `loading` state variable. When the form is submitted, set `loading` to `true`, and when the response is received, set it back to `false`. While the response is being streamed, the input field will be disabled.
|
|
27
|
+
|
|
28
|
+
```tsx filename='app/page.tsx'
|
|
29
|
+
'use client';
|
|
30
|
+
|
|
31
|
+
import { useState } from 'react';
|
|
32
|
+
import { generateResponse } from './actions';
|
|
33
|
+
import { readStreamableValue } from '@ai-sdk/rsc';
|
|
34
|
+
|
|
35
|
+
// Force the page to be dynamic and allow streaming responses up to 30 seconds
|
|
36
|
+
export const maxDuration = 30;
|
|
37
|
+
|
|
38
|
+
export default function Home() {
|
|
39
|
+
const [input, setInput] = useState<string>('');
|
|
40
|
+
const [generation, setGeneration] = useState<string>('');
|
|
41
|
+
const [loading, setLoading] = useState<boolean>(false);
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<div>
|
|
45
|
+
<div>{generation}</div>
|
|
46
|
+
<form
|
|
47
|
+
onSubmit={async e => {
|
|
48
|
+
e.preventDefault();
|
|
49
|
+
setLoading(true);
|
|
50
|
+
const response = await generateResponse(input);
|
|
51
|
+
|
|
52
|
+
let textContent = '';
|
|
53
|
+
|
|
54
|
+
for await (const delta of readStreamableValue(response)) {
|
|
55
|
+
textContent = `${textContent}${delta}`;
|
|
56
|
+
setGeneration(textContent);
|
|
57
|
+
}
|
|
58
|
+
setInput('');
|
|
59
|
+
setLoading(false);
|
|
60
|
+
}}
|
|
61
|
+
>
|
|
62
|
+
<input
|
|
63
|
+
type="text"
|
|
64
|
+
value={input}
|
|
65
|
+
disabled={loading}
|
|
66
|
+
className="disabled:opacity-50"
|
|
67
|
+
onChange={event => {
|
|
68
|
+
setInput(event.target.value);
|
|
69
|
+
}}
|
|
70
|
+
/>
|
|
71
|
+
<button>Send Message</button>
|
|
72
|
+
</form>
|
|
73
|
+
</div>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Server
|
|
79
|
+
|
|
80
|
+
Now let's implement the `generateResponse` function. Use the `streamText` function to generate a response to the input.
|
|
81
|
+
|
|
82
|
+
```typescript filename='app/actions.ts'
|
|
83
|
+
'use server';
|
|
84
|
+
|
|
85
|
+
import { streamText } from 'ai';
|
|
86
|
+
__PROVIDER_IMPORT__;
|
|
87
|
+
import { createStreamableValue } from '@ai-sdk/rsc';
|
|
88
|
+
|
|
89
|
+
export async function generateResponse(prompt: string) {
|
|
90
|
+
const stream = createStreamableValue();
|
|
91
|
+
|
|
92
|
+
(async () => {
|
|
93
|
+
const { textStream } = streamText({
|
|
94
|
+
model: __MODEL__,
|
|
95
|
+
prompt,
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
for await (const text of textStream) {
|
|
99
|
+
stream.update(text);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
stream.done();
|
|
103
|
+
})();
|
|
104
|
+
|
|
105
|
+
return stream.value;
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Streaming Loading State from the Server
|
|
110
|
+
|
|
111
|
+
If you are looking to track loading state on a more granular level, you can create a new streamable value to store a custom variable and then read this on the frontend. Let's update the example to create a new streamable value for tracking loading state:
|
|
112
|
+
|
|
113
|
+
### Server
|
|
114
|
+
|
|
115
|
+
```typescript filename='app/actions.ts' highlight='9,22,25'
|
|
116
|
+
'use server';
|
|
117
|
+
|
|
118
|
+
import { streamText } from 'ai';
|
|
119
|
+
__PROVIDER_IMPORT__;
|
|
120
|
+
import { createStreamableValue } from '@ai-sdk/rsc';
|
|
121
|
+
|
|
122
|
+
export async function generateResponse(prompt: string) {
|
|
123
|
+
const stream = createStreamableValue();
|
|
124
|
+
const loadingState = createStreamableValue({ loading: true });
|
|
125
|
+
|
|
126
|
+
(async () => {
|
|
127
|
+
const { textStream } = streamText({
|
|
128
|
+
model: __MODEL__,
|
|
129
|
+
prompt,
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
for await (const text of textStream) {
|
|
133
|
+
stream.update(text);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
stream.done();
|
|
137
|
+
loadingState.done({ loading: false });
|
|
138
|
+
})();
|
|
139
|
+
|
|
140
|
+
return { response: stream.value, loadingState: loadingState.value };
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Client
|
|
145
|
+
|
|
146
|
+
```tsx filename='app/page.tsx' highlight="22,30-34"
|
|
147
|
+
'use client';
|
|
148
|
+
|
|
149
|
+
import { useState } from 'react';
|
|
150
|
+
import { generateResponse } from './actions';
|
|
151
|
+
import { readStreamableValue } from '@ai-sdk/rsc';
|
|
152
|
+
|
|
153
|
+
// Force the page to be dynamic and allow streaming responses up to 30 seconds
|
|
154
|
+
export const maxDuration = 30;
|
|
155
|
+
|
|
156
|
+
export default function Home() {
|
|
157
|
+
const [input, setInput] = useState<string>('');
|
|
158
|
+
const [generation, setGeneration] = useState<string>('');
|
|
159
|
+
const [loading, setLoading] = useState<boolean>(false);
|
|
160
|
+
|
|
161
|
+
return (
|
|
162
|
+
<div>
|
|
163
|
+
<div>{generation}</div>
|
|
164
|
+
<form
|
|
165
|
+
onSubmit={async e => {
|
|
166
|
+
e.preventDefault();
|
|
167
|
+
setLoading(true);
|
|
168
|
+
const { response, loadingState } = await generateResponse(input);
|
|
169
|
+
|
|
170
|
+
let textContent = '';
|
|
171
|
+
|
|
172
|
+
for await (const responseDelta of readStreamableValue(response)) {
|
|
173
|
+
textContent = `${textContent}${responseDelta}`;
|
|
174
|
+
setGeneration(textContent);
|
|
175
|
+
}
|
|
176
|
+
for await (const loadingDelta of readStreamableValue(loadingState)) {
|
|
177
|
+
if (loadingDelta) {
|
|
178
|
+
setLoading(loadingDelta.loading);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
setInput('');
|
|
182
|
+
setLoading(false);
|
|
183
|
+
}}
|
|
184
|
+
>
|
|
185
|
+
<input
|
|
186
|
+
type="text"
|
|
187
|
+
value={input}
|
|
188
|
+
disabled={loading}
|
|
189
|
+
className="disabled:opacity-50"
|
|
190
|
+
onChange={event => {
|
|
191
|
+
setInput(event.target.value);
|
|
192
|
+
}}
|
|
193
|
+
/>
|
|
194
|
+
<button>Send Message</button>
|
|
195
|
+
</form>
|
|
196
|
+
</div>
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
This allows you to provide more detailed feedback about the generation process to your users.
|
|
202
|
+
|
|
203
|
+
## Streaming Loading Components with `streamUI`
|
|
204
|
+
|
|
205
|
+
If you are using the [ `streamUI` ](/docs/reference/ai-sdk-rsc/stream-ui) function, you can stream the loading state to the client in the form of a React component. `streamUI` supports the usage of [ JavaScript generator functions ](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*), which allow you to yield some value (in this case a React component) while some other blocking work completes.
|
|
206
|
+
|
|
207
|
+
## Server
|
|
208
|
+
|
|
209
|
+
```ts
|
|
210
|
+
'use server';
|
|
211
|
+
|
|
212
|
+
import { openai } from '@ai-sdk/openai';
|
|
213
|
+
import { streamUI } from '@ai-sdk/rsc';
|
|
214
|
+
|
|
215
|
+
export async function generateResponse(prompt: string) {
|
|
216
|
+
const result = await streamUI({
|
|
217
|
+
model: openai('gpt-4o'),
|
|
218
|
+
prompt,
|
|
219
|
+
text: async function* ({ content }) {
|
|
220
|
+
yield <div>loading...</div>;
|
|
221
|
+
return <div>{content}</div>;
|
|
222
|
+
},
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
return result.value;
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
<Note>
|
|
230
|
+
Remember to update the file from `.ts` to `.tsx` because you are defining a
|
|
231
|
+
React component in the `streamUI` function.
|
|
232
|
+
</Note>
|
|
233
|
+
|
|
234
|
+
## Client
|
|
235
|
+
|
|
236
|
+
```tsx
|
|
237
|
+
'use client';
|
|
238
|
+
|
|
239
|
+
import { useState } from 'react';
|
|
240
|
+
import { generateResponse } from './actions';
|
|
241
|
+
import { readStreamableValue } from '@ai-sdk/rsc';
|
|
242
|
+
|
|
243
|
+
// Force the page to be dynamic and allow streaming responses up to 30 seconds
|
|
244
|
+
export const maxDuration = 30;
|
|
245
|
+
|
|
246
|
+
export default function Home() {
|
|
247
|
+
const [input, setInput] = useState<string>('');
|
|
248
|
+
const [generation, setGeneration] = useState<React.ReactNode>();
|
|
249
|
+
|
|
250
|
+
return (
|
|
251
|
+
<div>
|
|
252
|
+
<div>{generation}</div>
|
|
253
|
+
<form
|
|
254
|
+
onSubmit={async e => {
|
|
255
|
+
e.preventDefault();
|
|
256
|
+
const result = await generateResponse(input);
|
|
257
|
+
setGeneration(result);
|
|
258
|
+
setInput('');
|
|
259
|
+
}}
|
|
260
|
+
>
|
|
261
|
+
<input
|
|
262
|
+
type="text"
|
|
263
|
+
value={input}
|
|
264
|
+
onChange={event => {
|
|
265
|
+
setInput(event.target.value);
|
|
266
|
+
}}
|
|
267
|
+
/>
|
|
268
|
+
<button>Send Message</button>
|
|
269
|
+
</form>
|
|
270
|
+
</div>
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
```
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Error Handling
|
|
3
|
+
description: Learn how to handle errors with the AI SDK.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Error Handling
|
|
7
|
+
|
|
8
|
+
<Note type="warning">
|
|
9
|
+
AI SDK RSC is currently experimental. We recommend using [AI SDK
|
|
10
|
+
UI](/docs/ai-sdk-ui/overview) for production. For guidance on migrating from
|
|
11
|
+
RSC to UI, see our [migration guide](/docs/ai-sdk-rsc/migrating-to-ui).
|
|
12
|
+
</Note>
|
|
13
|
+
|
|
14
|
+
Two categories of errors can occur when working with the RSC API: errors while streaming user interfaces and errors while streaming other values.
|
|
15
|
+
|
|
16
|
+
## Handling UI Errors
|
|
17
|
+
|
|
18
|
+
To handle errors while generating UI, the [`streamableUI`](/docs/reference/ai-sdk-rsc/create-streamable-ui) object exposes an `error()` method.
|
|
19
|
+
|
|
20
|
+
```tsx filename='app/actions.tsx'
|
|
21
|
+
'use server';
|
|
22
|
+
|
|
23
|
+
import { createStreamableUI } from '@ai-sdk/rsc';
|
|
24
|
+
|
|
25
|
+
export async function getStreamedUI() {
|
|
26
|
+
const ui = createStreamableUI();
|
|
27
|
+
|
|
28
|
+
(async () => {
|
|
29
|
+
ui.update(<div>loading</div>);
|
|
30
|
+
const data = await fetchData();
|
|
31
|
+
ui.done(<div>{data}</div>);
|
|
32
|
+
})().catch(e => {
|
|
33
|
+
ui.error(<div>Error: {e.message}</div>);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
return ui.value;
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
With this method, you can catch any error with the stream, and return relevant UI. On the client, you can also use a [React Error Boundary](https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary) to wrap the streamed component and catch any additional errors.
|
|
41
|
+
|
|
42
|
+
```tsx filename='app/page.tsx'
|
|
43
|
+
import { getStreamedUI } from '@/actions';
|
|
44
|
+
import { useState } from 'react';
|
|
45
|
+
import { ErrorBoundary } from './ErrorBoundary';
|
|
46
|
+
|
|
47
|
+
export default function Page() {
|
|
48
|
+
const [streamedUI, setStreamedUI] = useState(null);
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<div>
|
|
52
|
+
<button
|
|
53
|
+
onClick={async () => {
|
|
54
|
+
const newUI = await getStreamedUI();
|
|
55
|
+
setStreamedUI(newUI);
|
|
56
|
+
}}
|
|
57
|
+
>
|
|
58
|
+
What does the new UI look like?
|
|
59
|
+
</button>
|
|
60
|
+
<ErrorBoundary>{streamedUI}</ErrorBoundary>
|
|
61
|
+
</div>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Handling Other Errors
|
|
67
|
+
|
|
68
|
+
To handle other errors while streaming, you can return an error object that the receiver can use to determine why the failure occurred.
|
|
69
|
+
|
|
70
|
+
```tsx filename='app/actions.tsx'
|
|
71
|
+
'use server';
|
|
72
|
+
|
|
73
|
+
import { createStreamableValue } from '@ai-sdk/rsc';
|
|
74
|
+
import { fetchData, emptyData } from '../utils/data';
|
|
75
|
+
|
|
76
|
+
export const getStreamedData = async () => {
|
|
77
|
+
const streamableData = createStreamableValue<string>(emptyData);
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
(() => {
|
|
81
|
+
const data1 = await fetchData();
|
|
82
|
+
streamableData.update(data1);
|
|
83
|
+
|
|
84
|
+
const data2 = await fetchData();
|
|
85
|
+
streamableData.update(data2);
|
|
86
|
+
|
|
87
|
+
const data3 = await fetchData();
|
|
88
|
+
streamableData.done(data3);
|
|
89
|
+
})();
|
|
90
|
+
|
|
91
|
+
return { data: streamableData.value };
|
|
92
|
+
} catch (e) {
|
|
93
|
+
return { error: e.message };
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
```
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Handling Authentication
|
|
3
|
+
description: Learn how to authenticate with the AI SDK.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Authentication
|
|
7
|
+
|
|
8
|
+
<Note type="warning">
|
|
9
|
+
AI SDK RSC is currently experimental. We recommend using [AI SDK
|
|
10
|
+
UI](/docs/ai-sdk-ui/overview) for production. For guidance on migrating from
|
|
11
|
+
RSC to UI, see our [migration guide](/docs/ai-sdk-rsc/migrating-to-ui).
|
|
12
|
+
</Note>
|
|
13
|
+
|
|
14
|
+
The RSC API makes extensive use of [`Server Actions`](https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations) to power streaming values and UI from the server.
|
|
15
|
+
|
|
16
|
+
Server Actions are exposed as public, unprotected endpoints. As a result, you should treat Server Actions as you would public-facing API endpoints and ensure that the user is authorized to perform the action before returning any data.
|
|
17
|
+
|
|
18
|
+
```tsx filename="app/actions.tsx"
|
|
19
|
+
'use server';
|
|
20
|
+
|
|
21
|
+
import { cookies } from 'next/headers';
|
|
22
|
+
import { createStremableUI } from '@ai-sdk/rsc';
|
|
23
|
+
import { validateToken } from '../utils/auth';
|
|
24
|
+
|
|
25
|
+
export const getWeather = async () => {
|
|
26
|
+
const token = cookies().get('token');
|
|
27
|
+
|
|
28
|
+
if (!token || !validateToken(token)) {
|
|
29
|
+
return {
|
|
30
|
+
error: 'This action requires authentication',
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const streamableDisplay = createStreamableUI(null);
|
|
34
|
+
|
|
35
|
+
streamableDisplay.update(<Skeleton />);
|
|
36
|
+
streamableDisplay.done(<Weather />);
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
display: streamableDisplay.value,
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
```
|