Skip to content

Commit 901df02

Browse files
authored
feat (ui): use UI_MESSAGE generic (#6735)
## Background `useChat` and related types are currently parameterized on message metadata and data types. This can be simplified to a parameterized ui message type, from which the other generic parameters can then be derived. ## Summary Use a generic `UIMessage` in `Chat` and related types. ## Future Work * parameterize tool invocations
1 parent 8dfcb11 commit 901df02

File tree

16 files changed

+159
-299
lines changed

16 files changed

+159
-299
lines changed

‎.changeset/sharp-apes-tickle.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
'@ai-sdk/svelte': major
3+
'@ai-sdk/react': major
4+
'@ai-sdk/vue': major
5+
'ai': major
6+
---
7+
8+
feat (ui): use UI_MESSAGE generic

‎examples/next-openai/app/use-chat-data-ui-parts/page.tsx

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,26 @@
22

33
import ChatInput from '@/component/chat-input';
44
import { useChat } from '@ai-sdk/react';
5-
import { DefaultChatTransport } from 'ai';
6-
import { z } from 'zod';
5+
import { DefaultChatTransport, UIMessage } from 'ai';
6+
7+
type MyMessage = UIMessage<
8+
never,
9+
{
10+
weather: {
11+
city: string;
12+
weather: string;
13+
status: 'loading' | 'success';
14+
};
15+
}
16+
>;
717

818
export default function Chat() {
9-
const { error, status, sendMessage, messages, reload, stop } = useChat({
10-
transport: new DefaultChatTransport({
11-
api: '/api/use-chat-data-ui-parts',
12-
}),
13-
dataPartSchemas: {
14-
weather: z.object({
15-
city: z.string(),
16-
weather: z.string(),
17-
status: z.enum(['loading', 'success']),
19+
const { error, status, sendMessage, messages, reload, stop } =
20+
useChat<MyMessage>({
21+
transport: new DefaultChatTransport({
22+
api: '/api/use-chat-data-ui-parts',
1823
}),
19-
},
20-
});
24+
});
2125

2226
return (
2327
<div className="flex flex-col w-full max-w-md py-24 mx-auto stretch">

‎examples/next-openai/app/use-chat-message-metadata/page.tsx

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
'use client';
22

3-
import { zodSchema } from '@ai-sdk/provider-utils';
4-
import { useChat } from '@ai-sdk/react';
5-
import { DefaultChatTransport } from 'ai';
6-
import { exampleMetadataSchema } from '../api/use-chat-message-metadata/example-metadata-schema';
73
import ChatInput from '@/component/chat-input';
4+
import { useChat } from '@ai-sdk/react';
5+
import { DefaultChatTransport, UIMessage } from 'ai';
6+
import { ExampleMetadata } from '../api/use-chat-message-metadata/example-metadata-schema';
7+
8+
type MyMessage = UIMessage<ExampleMetadata>;
89

910
export default function Chat() {
10-
const { error, status, sendMessage, messages, reload, stop } = useChat({
11-
transport: new DefaultChatTransport({
12-
api: '/api/use-chat-message-metadata',
13-
}),
14-
messageMetadataSchema: zodSchema(exampleMetadataSchema),
15-
});
11+
const { error, status, sendMessage, messages, reload, stop } =
12+
useChat<MyMessage>({
13+
transport: new DefaultChatTransport({
14+
api: '/api/use-chat-message-metadata',
15+
}),
16+
});
1617

1718
return (
1819
<div className="flex flex-col w-full max-w-md py-24 mx-auto stretch">

‎packages/ai/src/ui-message-stream/handle-ui-message-stream-finish.ts

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,7 @@ import {
33
processUIMessageStream,
44
StreamingUIMessageState,
55
} from '../ui/process-ui-message-stream';
6-
import {
7-
InferUIMessageData,
8-
InferUIMessageMetadata,
9-
UIMessage,
10-
} from '../ui/ui-messages';
6+
import { UIMessage } from '../ui/ui-messages';
117
import {
128
InferUIMessageStreamPart,
139
UIMessageStreamPart,
@@ -53,27 +49,16 @@ export function handleUIMessageStreamFinish<UI_MESSAGE extends UIMessage>({
5349

5450
const lastMessage = originalMessages?.[originalMessages.length - 1];
5551

56-
const state = createStreamingUIMessageState<
57-
InferUIMessageMetadata<UI_MESSAGE>,
58-
InferUIMessageData<UI_MESSAGE>
59-
>({
52+
const state = createStreamingUIMessageState<UI_MESSAGE>({
6053
lastMessage: lastMessage
61-
? (structuredClone(lastMessage) as UIMessage<
62-
InferUIMessageMetadata<UI_MESSAGE>,
63-
InferUIMessageData<UI_MESSAGE>
64-
>)
54+
? (structuredClone(lastMessage) as UI_MESSAGE)
6555
: undefined,
6656
messageId, // will be overridden by the stream
6757
});
6858

6959
const runUpdateMessageJob = async (
7060
job: (options: {
71-
state: StreamingUIMessageState<
72-
UIMessage<
73-
InferUIMessageMetadata<UI_MESSAGE>,
74-
InferUIMessageData<UI_MESSAGE>
75-
>
76-
>;
61+
state: StreamingUIMessageState<UI_MESSAGE>;
7762
write: () => void;
7863
}) => Promise<void>,
7964
) => {

‎packages/ai/src/ui/chat-transport.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
import { UIMessageStreamPart } from '../ui-message-stream';
22
import { ChatRequestOptions } from './chat';
3-
import { UIDataTypes, UIMessage } from './ui-messages';
3+
import { UIMessage } from './ui-messages';
44

5-
export interface ChatTransport<
6-
MESSAGE_METADATA,
7-
DATA_TYPES extends UIDataTypes,
8-
> {
5+
export interface ChatTransport<UI_MESSAGE extends UIMessage> {
96
// TODO better name
107
submitMessages: (
118
options: {
129
chatId: string;
13-
messages: UIMessage<MESSAGE_METADATA, DATA_TYPES>[];
10+
messages: UI_MESSAGE[];
1411
abortSignal: AbortSignal | undefined;
1512
requestType: 'generate' | 'resume'; // TODO have separate functions
1613
} & ChatRequestOptions,

0 commit comments

Comments
 (0)