"use client" import * as React from "react" import { useChat } from "@ai-sdk/react" import { createChat, getMessageText } from "@/lib/ai" import { PartSource } from "@/registry/bases/radix/blocks/preview-03/components/part-source" import { PartText } from "@/registry/bases/radix/blocks/preview-03/components/part-text" import { PromptInput } from "@/registry/bases/radix/blocks/preview-03/components/prompt-input" import { Example } from "@/registry/bases/radix/components/example" import { Button } from "@/registry/bases/radix/ui/button" import { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, } from "@/registry/bases/radix/ui/card" import { Marker, MarkerContent, MarkerIcon, } from "@/registry/bases/radix/ui/marker" import { Message, MessageContent } from "@/registry/bases/radix/ui/message" import { MessageScroller, MessageScrollerButton, MessageScrollerContent, MessageScrollerItem, MessageScrollerProvider, MessageScrollerViewport, } from "@/registry/bases/radix/ui/message-scroller" import { Spinner } from "@/registry/bases/radix/ui/spinner" import { IconPlaceholder } from "@/app/(app)/create/components/icon-placeholder" const chat = createChat() .user("What should I read before migrating message rendering?") .sleep(1000) .assistant(({ writer }) => { writer.sourceUrl({ sourceId: "source-ai-sdk-ui-message", title: "AI SDK UIMessage", url: "https://ai-sdk.dev/docs/reference/ai-sdk-core/ui-message", }) writer.sourceUrl({ sourceId: "source-ai-sdk-transport", title: "AI SDK transport", url: "https://ai-sdk.dev/docs/ai-sdk-ui/transport", }) writer.sourceDocument({ sourceId: "source-migration-notes", title: "Internal migration notes", filename: "message-rendering-plan.md", mediaType: "text/markdown", }) writer.text( "Start with the **UIMessage** shape, then read the transport docs so your renderer understands streamed parts. The migration notes should stay close to the component work because they capture the local composition decisions." ) }) const initialMessages = chat.get(0) const transport = chat.transport() export function SourcesChat() { const { status, messages, sendMessage, setMessages } = useChat({ messages: initialMessages, transport, }) const nextMessage = chat.next(messages) const isBusy = status === "submitted" || status === "streaming" const onSubmit = (input: string) => { if (!input.trim()) { return } if (nextMessage && input === getMessageText(nextMessage)) { void sendMessage(nextMessage) return } void sendMessage({ text: input }) } return ( Reading list Source URL and source document parts. {messages.map((message) => ( {message.parts.map((part, index) => ( {part.type === "text" ? ( ) : part.type === "source-url" || part.type === "source-document" ? ( ) : null} ))} ))} {status === "submitted" ? ( Thinking... ) : null} ) }