Skip to content

Commit

Permalink
feat (ui/solid): add support for prepareRequestBody (#4711)
Browse files Browse the repository at this point in the history
Co-authored-by: Jai <[email protected]>
  • Loading branch information
lgrammel and Jaikant authored Feb 5, 2025
1 parent b51bcc3 commit 244dd77
Show file tree
Hide file tree
Showing 8 changed files with 317 additions and 119 deletions.
5 changes: 5 additions & 0 deletions .changeset/tidy-badgers-return.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@ai-sdk/solid': patch
---

feat (ui/solid): add support for prepareRequestBody
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ tags: ['next', 'chat']

<Note type="warning">
`experimental_prepareRequestBody` is an experimental feature and only
available in React.
available in React and Solid.
</Note>

By default, `useChat` sends all messages as well as information from the request to the server.
Expand Down
4 changes: 2 additions & 2 deletions content/docs/07-reference/02-ai-sdk-ui/01-use-chat.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,10 @@ Allows you to easily create a conversational user interface for your chatbot app
},
{
name: 'experimental_prepareRequestBody',
type: '(options: { messages: Message[]; requestData?: JSONValue; requestBody?: object, id: string }) => unknown',
type: '(options: { messages: UIMessage[]; requestData?: JSONValue; requestBody?: object, id: string }) => unknown',
isOptional: true,
description:
'Experimental (React only). When a function is provided, it will be used to prepare the request body for the chat API. This can be useful for customizing the request body based on the messages and data in the chat.',
'Experimental (React & Solid only). When a function is provided, it will be used to prepare the request body for the chat API. This can be useful for customizing the request body based on the messages and data in the chat.',
},
{
name: 'experimental_throttle',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { openai } from '@ai-sdk/openai';
import { streamText, Message } from 'ai';
import { APIEvent } from '@solidjs/start/server';

export const POST = async (event: APIEvent) => {
// Extract the `messages` from the body of the request
const { message } = await event.request.json();

// Implement your own logic here to add message history
const previousMessages: Message[] = [];
const messages = [...previousMessages, message];

// Call the language model
const result = streamText({
model: openai('gpt-4o-mini'),
messages,
async onFinish({ text, toolCalls, toolResults, usage, finishReason }) {
// Implement your own logic here, e.g. for storing messages
},
});

// Respond with the stream
return result.toDataStreamResponse();
};
78 changes: 78 additions & 0 deletions examples/solidstart-openai/src/routes/use-chat-request/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/* eslint-disable @next/next/no-img-element */
import { For } from 'solid-js';
import { useChat } from '@ai-sdk/solid';
import { createIdGenerator } from 'ai';

export default function Chat() {
const {
input,
messages,
handleInputChange,
handleSubmit,
isLoading,
error,
stop,
reload,
} = useChat({
api: '/api/use-chat-request',
sendExtraMessageFields: true,
generateId: createIdGenerator({ prefix: 'msgc', size: 16 }),

experimental_prepareRequestBody({ messages }) {
return {
message: messages[messages.length - 1],
};
},
});

return (
<div class="flex flex-col w-full max-w-md py-24 mx-auto stretch">
<div class="flex flex-col gap-2 p-2">
<For each={messages()}>
{message => (
<div class="whitespace-pre-wrap">
{message.role === 'user' ? 'User: ' : 'AI: '}
{message.content}
</div>
)}
</For>
</div>

{isLoading() && (
<div class="mt-4 text-gray-500">
<div>Loading...</div>
<button
type="button"
class="px-4 py-2 mt-4 text-blue-500 border border-blue-500 rounded-md"
onClick={stop}
>
Stop
</button>
</div>
)}

{error() && (
<div class="mt-4">
<div class="text-red-500">An error occurred.</div>
<button
type="button"
class="px-4 py-2 mt-4 text-blue-500 border border-blue-500 rounded-md"
onClick={() => reload()}
>
Retry
</button>
</div>
)}

<form onSubmit={handleSubmit} class="fixed bottom-0 w-full max-w-md p-2">
<input
class="w-full p-2 mb-8 border border-gray-300 rounded shadow-xl"
value={input()}
placeholder="Say something..."
onInput={handleInputChange}
disabled={isLoading()}
/>
</form>
</div>
);
}
2 changes: 1 addition & 1 deletion packages/react/src/use-chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ export function useChat({
*/
experimental_prepareRequestBody?: (options: {
id: string;
messages: Message[];
messages: UIMessage[];
requestData?: JSONValue;
requestBody?: object;
}) => unknown;
Expand Down
Loading

0 comments on commit 244dd77

Please sign in to comment.