diff --git a/.changeset/sour-dancers-fetch.md b/.changeset/sour-dancers-fetch.md new file mode 100644 index 000000000..950832526 --- /dev/null +++ b/.changeset/sour-dancers-fetch.md @@ -0,0 +1,6 @@ +--- +"@assistant-ui/react-ai-sdk": patch +"@assistant-ui/react": patch +--- + +feat: lift thread composer state to ThreadRuntime.Composer diff --git a/apps/docs/components/docs/parameters/context.tsx b/apps/docs/components/docs/parameters/context.tsx index da1084984..9f8a64ce8 100644 --- a/apps/docs/components/docs/parameters/context.tsx +++ b/apps/docs/components/docs/parameters/context.tsx @@ -259,16 +259,16 @@ export const BaseComposerState: ParametersTableProps = { type: "BaseComposerState", parameters: [ { - name: "value", + name: "text", type: "string", required: true, - description: "The current value of the composer.", + description: "The current text of the composer.", }, { - name: "setValue", - type: "(value: string) => void", + name: "setText", + type: "(text: string) => void", required: true, - description: "A function to set the value of the composer.", + description: "A function to set the text of the composer.", }, ], }; diff --git a/apps/docs/content/docs/reference/context.mdx b/apps/docs/content/docs/reference/context.mdx index 81acab5c9..3e885cf3d 100644 --- a/apps/docs/content/docs/reference/context.mdx +++ b/apps/docs/content/docs/reference/context.mdx @@ -169,8 +169,8 @@ const { useComposer } = useThreadContext(); const value = useComposer((m) => m.value); const value = useComposer.getState().value; -const setValue = useComposer((m) => m.setValue); -const setValue = useComposer.getState().setValue; +const setText = useComposer((m) => m.setText); +const setText = useComposer.getState().setText; ``` @@ -254,8 +254,8 @@ const { useEditComposer } = useMessageContext(); const value = useEditComposer((m) => m.value); const value = useEditComposer.getState().value; -const setValue = useEditComposer((m) => m.setValue); -const setValue = useEditComposer.getState().setValue; +const setText = useEditComposer((m) => m.setText); +const setText = useEditComposer.getState().setText; ``` @@ -328,6 +328,6 @@ const { useComposer } = useComposerContext(); const value = useComposer((m) => m.value); const value = useComposer.getState().value; -const setValue = useComposer((m) => m.setValue); -const setValue = useComposer.getState().setValue; +const setText = useComposer((m) => m.setText); +const setText = useComposer.getState().setText; ``` diff --git a/packages/react-ai-sdk/src/ui/use-assistant/VercelUseAssistantThreadRuntime.tsx b/packages/react-ai-sdk/src/ui/use-assistant/VercelUseAssistantThreadRuntime.tsx index 62bf93b3c..f577437d1 100644 --- a/packages/react-ai-sdk/src/ui/use-assistant/VercelUseAssistantThreadRuntime.tsx +++ b/packages/react-ai-sdk/src/ui/use-assistant/VercelUseAssistantThreadRuntime.tsx @@ -30,6 +30,16 @@ export class VercelUseAssistantThreadRuntime implements ReactThreadRuntime { >; public messages: readonly ThreadMessage[] = []; + + public readonly composer = { + text: "", + setText: (value: string) => { + this.composer.text = value; + + for (const callback of this._subscriptions) callback(); + }, + }; + public readonly isDisabled = false; constructor(public vercel: ReturnType) { diff --git a/packages/react-ai-sdk/src/ui/use-chat/VercelUseChatThreadRuntime.tsx b/packages/react-ai-sdk/src/ui/use-chat/VercelUseChatThreadRuntime.tsx index dc53c2afd..651e5df08 100644 --- a/packages/react-ai-sdk/src/ui/use-chat/VercelUseChatThreadRuntime.tsx +++ b/packages/react-ai-sdk/src/ui/use-chat/VercelUseChatThreadRuntime.tsx @@ -45,6 +45,15 @@ export class VercelUseChatThreadRuntime implements ReactThreadRuntime { public messages: ThreadMessage[] = []; public readonly isDisabled = false; + public readonly composer = { + text: "", + setText: (value: string) => { + this.composer.text = value; + + for (const callback of this._subscriptions) callback(); + }, + }; + constructor(public vercel: ReturnType) { this.useVercel = create(() => ({ vercel, diff --git a/packages/react-ai-sdk/src/ui/utils/useVercelAIComposerSync.tsx b/packages/react-ai-sdk/src/ui/utils/useVercelAIComposerSync.tsx index 0ef102c26..b66a0d21e 100644 --- a/packages/react-ai-sdk/src/ui/utils/useVercelAIComposerSync.tsx +++ b/packages/react-ai-sdk/src/ui/utils/useVercelAIComposerSync.tsx @@ -9,8 +9,8 @@ export const useVercelAIComposerSync = (vercel: VercelHelpers) => { useEffect(() => { (useComposer as unknown as StoreApi).setState({ - value: vercel.input, - setValue: vercel.setInput, + text: vercel.input, + setText: vercel.setInput, }); }, [useComposer, vercel.input, vercel.setInput]); }; diff --git a/packages/react-playground/src/components/ui/assistant-ui/thread.tsx b/packages/react-playground/src/components/ui/assistant-ui/thread.tsx index 7ff31ad51..a65262a58 100644 --- a/packages/react-playground/src/components/ui/assistant-ui/thread.tsx +++ b/packages/react-playground/src/components/ui/assistant-ui/thread.tsx @@ -105,19 +105,19 @@ const Composer: FC = () => { useThreadContext(); const isRunning = useThread((t) => t.isRunning); - const hasValue = useComposer((c) => c.value.length > 0); + const hasText = useComposer((c) => c.text.length > 0); const performAdd = () => { const composer = useComposer.getState(); - const value = composer.value; - if (!value) return; + const text = composer.text; + if (!text) return; - composer.setValue(""); + composer.setText(""); useThreadActions.getState().append({ parentId: useThreadMessages.getState().at(-1)?.id ?? null, role, - content: [{ type: "text", text: value }], + content: [{ type: "text", text }], }); setRole("user"); @@ -167,7 +167,7 @@ const Composer: FC = () => {