diff --git a/.changeset/slow-feet-heal.md b/.changeset/slow-feet-heal.md new file mode 100644 index 000000000..0c8515485 --- /dev/null +++ b/.changeset/slow-feet-heal.md @@ -0,0 +1,5 @@ +--- +"@assistant-ui/react-ai-sdk": patch +--- + +refactor: align RSC adapter function names with useExternalStore diff --git a/apps/docs/content/docs/docs/runtimes/vercel-ai-sdk/rsc.mdx b/apps/docs/content/docs/docs/runtimes/vercel-ai-sdk/rsc.mdx index 3ee96aa08..c46857ad3 100644 --- a/apps/docs/content/docs/docs/runtimes/vercel-ai-sdk/rsc.mdx +++ b/apps/docs/content/docs/docs/runtimes/vercel-ai-sdk/rsc.mdx @@ -144,7 +144,7 @@ export function MyRuntimeProvider({ const { continueConversation } = useActions(); const [messages, setMessages] = useUIState(); - const append = async (m: AppendMessage) => { + const onNew = async (m: AppendMessage) => { if (m.content[0]?.type !== "text") throw new Error("Only text messages are supported"); @@ -159,7 +159,7 @@ export function MyRuntimeProvider({ setMessages((currentConversation) => [...currentConversation, message]); }; - const runtime = useVercelRSCRuntime({ messages, append }); + const runtime = useVercelRSCRuntime({ messages, onNew }); return ( diff --git a/apps/docs/content/docs/reference/integrations/vercel-ai-sdk.mdx b/apps/docs/content/docs/reference/integrations/vercel-ai-sdk.mdx index 1bbf7e584..1e1396d1d 100644 --- a/apps/docs/content/docs/reference/integrations/vercel-ai-sdk.mdx +++ b/apps/docs/content/docs/reference/integrations/vercel-ai-sdk.mdx @@ -76,7 +76,7 @@ import { useVercelRSCRuntime } from "@assistant-ui/react-ai-sdk"; const MyRuntimeProvider = ({ children }: { children: React.ReactNode }) => { const [messages, setMessages] = useUIState(); - const append = async (m: AppendMessage) => { + const onNew = async (m: AppendMessage) => { if (m.content[0]?.type !== "text") throw new Error("Only text messages are supported"); @@ -91,7 +91,7 @@ const MyRuntimeProvider = ({ children }: { children: React.ReactNode }) => { setMessages((currentConversation) => [...currentConversation, message]); }; - const runtime = useVercelRSCRuntime({ messages, append }); + const runtime = useVercelRSCRuntime({ messages, onNew }); return ( @@ -117,17 +117,17 @@ const MyRuntimeProvider = ({ children }: { children: React.ReactNode }) => { description: "The messages in the thread.", }, { - name: "append", + name: "onNew", type: "(message: AppendMessage) => Promise", description: "A function to append a message to the thread.", }, { - name: "edit", + name: "onEdit", type: "(message: AppendMessage) => Promise", description: "A function to edit a message.", }, { - name: "reload", + name: "onReload", type: "(parentId: string | null) => Promise", description: "A function to reload a message.", }, diff --git a/examples/search-agent-for-e-commerce/src/app/MyRuntimeProvider.tsx b/examples/search-agent-for-e-commerce/src/app/MyRuntimeProvider.tsx index 4ed015de9..dd71c8e96 100644 --- a/examples/search-agent-for-e-commerce/src/app/MyRuntimeProvider.tsx +++ b/examples/search-agent-for-e-commerce/src/app/MyRuntimeProvider.tsx @@ -18,7 +18,7 @@ export function MyRuntimeProvider({ const { continueConversation } = useActions(); const [messages, setMessages] = useUIState(); - const append = async (m: AppendMessage) => { + const onNew = async (m: AppendMessage) => { if (m.content[0]?.type !== "text") throw new Error("Only text messages are supported"); @@ -33,7 +33,7 @@ export function MyRuntimeProvider({ setMessages((currentConversation) => [...currentConversation, message]); }; - const runtime = useVercelRSCRuntime({ messages, append }); + const runtime = useVercelRSCRuntime({ messages, onNew }); return ( diff --git a/examples/search-agent-for-e-commerce/tsconfig.json b/examples/search-agent-for-e-commerce/tsconfig.json index 7b2858930..7975c1e58 100644 --- a/examples/search-agent-for-e-commerce/tsconfig.json +++ b/examples/search-agent-for-e-commerce/tsconfig.json @@ -18,7 +18,9 @@ } ], "paths": { - "@/*": ["./src/*"] + "@/*": ["./src/*"], + "@assistant-ui/*": ["../../packages/*/src"], + "@assistant-ui/react/*": ["../../packages/react/src/*"] } }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], diff --git a/examples/with-vercel-ai-rsc/app/page.tsx b/examples/with-vercel-ai-rsc/app/page.tsx index 9b148a026..f9edfa866 100644 --- a/examples/with-vercel-ai-rsc/app/page.tsx +++ b/examples/with-vercel-ai-rsc/app/page.tsx @@ -25,7 +25,7 @@ const MyRuntimeProvider = ({ children }: { children: React.ReactNode }) => { const { continueConversation } = useActions(); const [messages, setMessages] = useUIState(); - const append = async (m: AppendMessage) => { + const onNew = async (m: AppendMessage) => { if (m.content[0]?.type !== "text") throw new Error("Only text messages are supported"); @@ -40,7 +40,7 @@ const MyRuntimeProvider = ({ children }: { children: React.ReactNode }) => { setMessages((currentConversation) => [...currentConversation, message]); }; - const runtime = useVercelRSCRuntime({ messages, append }); + const runtime = useVercelRSCRuntime({ messages, onNew }); return ( diff --git a/packages/react-ai-sdk/src/rsc/VercelRSCAdapter.tsx b/packages/react-ai-sdk/src/rsc/VercelRSCAdapter.tsx index 297431b28..3482a1bad 100644 --- a/packages/react-ai-sdk/src/rsc/VercelRSCAdapter.tsx +++ b/packages/react-ai-sdk/src/rsc/VercelRSCAdapter.tsx @@ -8,10 +8,23 @@ type RSCMessageConverter = { type VercelRSCAdapterBase = { messages: T[]; - append: (message: AppendMessage) => Promise; + onNew?: (message: AppendMessage) => Promise; + onEdit?: ((message: AppendMessage) => Promise) | undefined; + onReload?: ((parentId: string | null) => Promise) | undefined; + convertMessage?: ((message: T) => VercelRSCMessage) | undefined; + + /** + * @deprecated Use `onNew` instead. This will be removed in 0.6.0. + */ + append?: (message: AppendMessage) => Promise; + /** + * @deprecated Use `onEdit` instead. This will be removed in 0.6.0. + */ edit?: ((message: AppendMessage) => Promise) | undefined; + /** + * @deprecated Use `onReload` instead. This will be removed in 0.6.0. + */ reload?: ((parentId: string | null) => Promise) | undefined; - convertMessage?: ((message: T) => VercelRSCMessage) | undefined; }; export type VercelRSCAdapter = VercelRSCAdapterBase & diff --git a/packages/react-ai-sdk/src/rsc/useVercelRSCRuntime.tsx b/packages/react-ai-sdk/src/rsc/useVercelRSCRuntime.tsx index 92189b4bd..20ac53db5 100644 --- a/packages/react-ai-sdk/src/rsc/useVercelRSCRuntime.tsx +++ b/packages/react-ai-sdk/src/rsc/useVercelRSCRuntime.tsx @@ -26,11 +26,14 @@ const vercelToThreadMessage = ( export const useVercelRSCRuntime = ( adapter: VercelRSCAdapter, ) => { + const onNew = adapter.onNew ?? adapter.append; + if (!onNew) + throw new Error("You must pass a onNew function to useVercelRSCRuntime"); const eAdapter: ExternalStoreAdapter = { messages: adapter.messages, - onNew: adapter.append, - onEdit: adapter.edit, - onReload: adapter.reload, + onNew, + onEdit: adapter.onEdit ?? adapter.edit, + onReload: adapter.onReload ?? adapter.reload, convertMessage: (m: T) => vercelToThreadMessage( adapter.convertMessage ?? ((m) => m as VercelRSCMessage),