1
- import { FetchFunction } from '@ai-sdk/provider-utils' ;
1
+ import { FetchFunction , Resolvable , resolve } from '@ai-sdk/provider-utils' ;
2
2
import { UIMessageChunk } from '../ui-message-stream/ui-message-chunks' ;
3
3
import { ChatTransport } from './chat-transport' ;
4
4
import { UIMessage } from './ui-messages' ;
@@ -52,20 +52,29 @@ export type PrepareReconnectToStreamRequest = (options: {
52
52
api ?: string ;
53
53
} > ;
54
54
55
+ /**
56
+ * Options for the `HttpChatTransport` class.
57
+ *
58
+ * @param UI_MESSAGE - The type of message to be used in the chat.
59
+ */
55
60
export type HttpChatTransportInitOptions < UI_MESSAGE extends UIMessage > = {
61
+ /**
62
+ * The API URL to be used for the chat transport.
63
+ * Defaults to '/api/chat'.
64
+ */
56
65
api ?: string ;
57
66
58
67
/**
59
68
* The credentials mode to be used for the fetch request.
60
69
* Possible values are: 'omit', 'same-origin', 'include'.
61
70
* Defaults to 'same-origin'.
62
71
*/
63
- credentials ?: RequestCredentials ;
72
+ credentials ?: Resolvable < RequestCredentials > ;
64
73
65
74
/**
66
75
* HTTP headers to be sent with the API request.
67
76
*/
68
- headers ?: Record < string , string > | Headers ;
77
+ headers ?: Resolvable < Record < string , string > | Headers > ;
69
78
70
79
/**
71
80
* Extra body object to be sent with the API request.
@@ -79,7 +88,7 @@ export type HttpChatTransportInitOptions<UI_MESSAGE extends UIMessage> = {
79
88
* })
80
89
* ```
81
90
*/
82
- body ?: object ;
91
+ body ?: Resolvable < object > ;
83
92
84
93
/**
85
94
Custom fetch implementation. You can use it as a middleware to intercept requests,
@@ -98,16 +107,25 @@ export type HttpChatTransportInitOptions<UI_MESSAGE extends UIMessage> = {
98
107
*/
99
108
prepareSendMessagesRequest ?: PrepareSendMessagesRequest < UI_MESSAGE > ;
100
109
110
+ /**
111
+ * When a function is provided, it will be used
112
+ * to prepare the request body for the chat API. This can be useful for
113
+ * customizing the request body based on the messages and data in the chat.
114
+ *
115
+ * @param id The id of the chat.
116
+ * @param messages The current messages in the chat.
117
+ * @param requestBody The request body object passed in the chat request.
118
+ */
101
119
prepareReconnectToStreamRequest ?: PrepareReconnectToStreamRequest ;
102
120
} ;
103
121
104
122
export abstract class HttpChatTransport < UI_MESSAGE extends UIMessage >
105
123
implements ChatTransport < UI_MESSAGE >
106
124
{
107
125
protected api : string ;
108
- protected credentials ?: RequestCredentials ;
109
- protected headers ?: Record < string , string > | Headers ;
110
- protected body ?: object ;
126
+ protected credentials : HttpChatTransportInitOptions < UI_MESSAGE > [ 'credentials' ] ;
127
+ protected headers : HttpChatTransportInitOptions < UI_MESSAGE > [ 'headers' ] ;
128
+ protected body : HttpChatTransportInitOptions < UI_MESSAGE > [ 'body' ] ;
111
129
protected fetch ?: FetchFunction ;
112
130
protected prepareSendMessagesRequest ?: PrepareSendMessagesRequest < UI_MESSAGE > ;
113
131
protected prepareReconnectToStreamRequest ?: PrepareReconnectToStreamRequest ;
@@ -134,13 +152,17 @@ export abstract class HttpChatTransport<UI_MESSAGE extends UIMessage>
134
152
abortSignal,
135
153
...options
136
154
} : Parameters < ChatTransport < UI_MESSAGE > [ 'sendMessages' ] > [ 0 ] ) {
155
+ const resolvedBody = await resolve ( this . body ) ;
156
+ const resolvedHeaders = await resolve ( this . headers ) ;
157
+ const resolvedCredentials = await resolve ( this . credentials ) ;
158
+
137
159
const preparedRequest = await this . prepareSendMessagesRequest ?.( {
138
160
api : this . api ,
139
161
id : options . chatId ,
140
162
messages : options . messages ,
141
- body : { ...this . body , ...options . body } ,
142
- headers : { ...this . headers , ...options . headers } ,
143
- credentials : this . credentials ,
163
+ body : { ...resolvedBody , ...options . body } ,
164
+ headers : { ...resolvedHeaders , ...options . headers } ,
165
+ credentials : resolvedCredentials ,
144
166
requestMetadata : options . metadata ,
145
167
trigger : options . trigger ,
146
168
messageId : options . messageId ,
@@ -150,19 +172,19 @@ export abstract class HttpChatTransport<UI_MESSAGE extends UIMessage>
150
172
const headers =
151
173
preparedRequest ?. headers !== undefined
152
174
? preparedRequest . headers
153
- : { ...this . headers , ...options . headers } ;
175
+ : { ...resolvedHeaders , ...options . headers } ;
154
176
const body =
155
177
preparedRequest ?. body !== undefined
156
178
? preparedRequest . body
157
179
: {
158
- ...this . body ,
180
+ ...resolvedBody ,
159
181
...options . body ,
160
182
id : options . chatId ,
161
183
messages : options . messages ,
162
184
trigger : options . trigger ,
163
185
messageId : options . messageId ,
164
186
} ;
165
- const credentials = preparedRequest ?. credentials ?? this . credentials ;
187
+ const credentials = preparedRequest ?. credentials ?? resolvedCredentials ;
166
188
167
189
// avoid caching globalThis.fetch in case it is patched by other libraries
168
190
const fetch = this . fetch ?? globalThis . fetch ;
@@ -194,21 +216,25 @@ export abstract class HttpChatTransport<UI_MESSAGE extends UIMessage>
194
216
async reconnectToStream (
195
217
options : Parameters < ChatTransport < UI_MESSAGE > [ 'reconnectToStream' ] > [ 0 ] ,
196
218
) : Promise < ReadableStream < UIMessageChunk > | null > {
219
+ const resolvedBody = await resolve ( this . body ) ;
220
+ const resolvedHeaders = await resolve ( this . headers ) ;
221
+ const resolvedCredentials = await resolve ( this . credentials ) ;
222
+
197
223
const preparedRequest = await this . prepareReconnectToStreamRequest ?.( {
198
224
api : this . api ,
199
225
id : options . chatId ,
200
- body : { ...this . body , ...options . body } ,
201
- headers : { ...this . headers , ...options . headers } ,
202
- credentials : this . credentials ,
226
+ body : { ...resolvedBody , ...options . body } ,
227
+ headers : { ...resolvedHeaders , ...options . headers } ,
228
+ credentials : resolvedCredentials ,
203
229
requestMetadata : options . metadata ,
204
230
} ) ;
205
231
206
232
const api = preparedRequest ?. api ?? `${ this . api } /${ options . chatId } /stream` ;
207
233
const headers =
208
234
preparedRequest ?. headers !== undefined
209
235
? preparedRequest . headers
210
- : { ...this . headers , ...options . headers } ;
211
- const credentials = preparedRequest ?. credentials ?? this . credentials ;
236
+ : { ...resolvedHeaders , ...options . headers } ;
237
+ const credentials = preparedRequest ?. credentials ?? resolvedCredentials ;
212
238
213
239
// avoid caching globalThis.fetch in case it is patched by other libraries
214
240
const fetch = this . fetch ?? globalThis . fetch ;
0 commit comments