@ai-sdk/react 0.0.35 → 0.0.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +8 -8
- package/.turbo/turbo-clean.log +1 -1
- package/CHANGELOG.md +17 -0
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
- package/src/use-chat.ui.test.tsx +356 -327
- package/src/use-object.ts +1 -1
package/src/use-chat.ui.test.tsx
CHANGED
|
@@ -265,8 +265,11 @@ describe('text stream', () => {
|
|
|
265
265
|
<div>
|
|
266
266
|
{messages.map((m, idx) => (
|
|
267
267
|
<div data-testid={`message-${idx}-text-stream`} key={m.id}>
|
|
268
|
-
{m.
|
|
269
|
-
{
|
|
268
|
+
<div data-testid={`message-${idx}-id`}>{m.id}</div>
|
|
269
|
+
<div data-testid={`message-${idx}-role`}>
|
|
270
|
+
{m.role === 'user' ? 'User: ' : 'AI: '}
|
|
271
|
+
</div>
|
|
272
|
+
<div data-testid={`message-${idx}-content`}>{m.content}</div>
|
|
270
273
|
</div>
|
|
271
274
|
))}
|
|
272
275
|
|
|
@@ -302,15 +305,39 @@ describe('text stream', () => {
|
|
|
302
305
|
async () => {
|
|
303
306
|
await userEvent.click(screen.getByTestId('do-append-text-stream'));
|
|
304
307
|
|
|
305
|
-
await screen.findByTestId('message-0-
|
|
306
|
-
expect(screen.getByTestId('message-0-
|
|
307
|
-
|
|
308
|
+
await screen.findByTestId('message-0-content');
|
|
309
|
+
expect(screen.getByTestId('message-0-content')).toHaveTextContent('hi');
|
|
310
|
+
|
|
311
|
+
await screen.findByTestId('message-1-content');
|
|
312
|
+
expect(screen.getByTestId('message-1-content')).toHaveTextContent(
|
|
313
|
+
'Hello, world.',
|
|
308
314
|
);
|
|
315
|
+
},
|
|
316
|
+
),
|
|
317
|
+
);
|
|
309
318
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
319
|
+
it(
|
|
320
|
+
'should have stable message ids',
|
|
321
|
+
withTestServer(
|
|
322
|
+
{ url: '/api/chat', type: 'controlled-stream' },
|
|
323
|
+
async ({ streamController }) => {
|
|
324
|
+
streamController.enqueue('He');
|
|
325
|
+
|
|
326
|
+
await userEvent.click(screen.getByTestId('do-append-text-stream'));
|
|
327
|
+
|
|
328
|
+
await screen.findByTestId('message-1-content');
|
|
329
|
+
expect(screen.getByTestId('message-1-content')).toHaveTextContent('He');
|
|
330
|
+
|
|
331
|
+
const id = screen.getByTestId('message-1-id').textContent;
|
|
332
|
+
|
|
333
|
+
streamController.enqueue('llo');
|
|
334
|
+
streamController.close();
|
|
335
|
+
|
|
336
|
+
await screen.findByTestId('message-1-content');
|
|
337
|
+
expect(screen.getByTestId('message-1-content')).toHaveTextContent(
|
|
338
|
+
'Hello',
|
|
313
339
|
);
|
|
340
|
+
expect(screen.getByTestId('message-1-id').textContent).toBe(id);
|
|
314
341
|
},
|
|
315
342
|
),
|
|
316
343
|
);
|
|
@@ -989,325 +1016,327 @@ describe('maxToolRoundtrips', () => {
|
|
|
989
1016
|
});
|
|
990
1017
|
});
|
|
991
1018
|
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1019
|
+
// Disabled: unstable with React 18.3.3 TODO re-enable
|
|
1020
|
+
//
|
|
1021
|
+
// describe('file attachments with data url', () => {
|
|
1022
|
+
// const TestComponent = () => {
|
|
1023
|
+
// const { messages, handleSubmit, handleInputChange, isLoading, input } =
|
|
1024
|
+
// useChat();
|
|
1025
|
+
|
|
1026
|
+
// const [attachments, setAttachments] = useState<FileList | undefined>(
|
|
1027
|
+
// undefined,
|
|
1028
|
+
// );
|
|
1029
|
+
// const fileInputRef = useRef<HTMLInputElement>(null);
|
|
1030
|
+
|
|
1031
|
+
// return (
|
|
1032
|
+
// <div>
|
|
1033
|
+
// {messages.map((m, idx) => (
|
|
1034
|
+
// <div data-testid={`message-${idx}`} key={m.id}>
|
|
1035
|
+
// {m.role === 'user' ? 'User: ' : 'AI: '}
|
|
1036
|
+
// {m.content}
|
|
1037
|
+
// {m.experimental_attachments?.map(attachment => {
|
|
1038
|
+
// if (attachment.contentType?.startsWith('image/')) {
|
|
1039
|
+
// return (
|
|
1040
|
+
// <img
|
|
1041
|
+
// key={attachment.name}
|
|
1042
|
+
// src={attachment.url}
|
|
1043
|
+
// alt={attachment.name}
|
|
1044
|
+
// data-testid={`attachment-${idx}`}
|
|
1045
|
+
// />
|
|
1046
|
+
// );
|
|
1047
|
+
// } else if (attachment.contentType?.startsWith('text/')) {
|
|
1048
|
+
// return (
|
|
1049
|
+
// <div key={attachment.name} data-testid={`attachment-${idx}`}>
|
|
1050
|
+
// {getTextFromDataUrl(attachment.url)}
|
|
1051
|
+
// </div>
|
|
1052
|
+
// );
|
|
1053
|
+
// }
|
|
1054
|
+
// })}
|
|
1055
|
+
// </div>
|
|
1056
|
+
// ))}
|
|
1057
|
+
|
|
1058
|
+
// <form
|
|
1059
|
+
// onSubmit={event => {
|
|
1060
|
+
// handleSubmit(event, {
|
|
1061
|
+
// experimental_attachments: attachments,
|
|
1062
|
+
// });
|
|
1063
|
+
// setAttachments(undefined);
|
|
1064
|
+
// if (fileInputRef.current) {
|
|
1065
|
+
// fileInputRef.current.value = '';
|
|
1066
|
+
// }
|
|
1067
|
+
// }}
|
|
1068
|
+
// data-testid="chat-form"
|
|
1069
|
+
// >
|
|
1070
|
+
// <input
|
|
1071
|
+
// type="file"
|
|
1072
|
+
// onChange={event => {
|
|
1073
|
+
// if (event.target.files) {
|
|
1074
|
+
// setAttachments(event.target.files);
|
|
1075
|
+
// }
|
|
1076
|
+
// }}
|
|
1077
|
+
// multiple
|
|
1078
|
+
// ref={fileInputRef}
|
|
1079
|
+
// data-testid="file-input"
|
|
1080
|
+
// />
|
|
1081
|
+
// <input
|
|
1082
|
+
// value={input}
|
|
1083
|
+
// onChange={handleInputChange}
|
|
1084
|
+
// disabled={isLoading}
|
|
1085
|
+
// data-testid="message-input"
|
|
1086
|
+
// />
|
|
1087
|
+
// <button type="submit" data-testid="submit-button">
|
|
1088
|
+
// Send
|
|
1089
|
+
// </button>
|
|
1090
|
+
// </form>
|
|
1091
|
+
// </div>
|
|
1092
|
+
// );
|
|
1093
|
+
// };
|
|
1094
|
+
|
|
1095
|
+
// beforeEach(() => {
|
|
1096
|
+
// render(<TestComponent />);
|
|
1097
|
+
// });
|
|
1098
|
+
|
|
1099
|
+
// afterEach(() => {
|
|
1100
|
+
// vi.restoreAllMocks();
|
|
1101
|
+
// cleanup();
|
|
1102
|
+
// });
|
|
1103
|
+
|
|
1104
|
+
// it(
|
|
1105
|
+
// 'should handle text file attachment and submission',
|
|
1106
|
+
// withTestServer(
|
|
1107
|
+
// {
|
|
1108
|
+
// url: '/api/chat',
|
|
1109
|
+
// type: 'stream-values',
|
|
1110
|
+
// content: ['0:"Response to message with text attachment"\n'],
|
|
1111
|
+
// },
|
|
1112
|
+
// async ({ call }) => {
|
|
1113
|
+
// const file = new File(['test file content'], 'test.txt', {
|
|
1114
|
+
// type: 'text/plain',
|
|
1115
|
+
// });
|
|
1116
|
+
|
|
1117
|
+
// const fileInput = screen.getByTestId('file-input');
|
|
1118
|
+
// await userEvent.upload(fileInput, file);
|
|
1119
|
+
|
|
1120
|
+
// const messageInput = screen.getByTestId('message-input');
|
|
1121
|
+
// await userEvent.type(messageInput, 'Message with text attachment');
|
|
1122
|
+
|
|
1123
|
+
// const submitButton = screen.getByTestId('submit-button');
|
|
1124
|
+
// await userEvent.click(submitButton);
|
|
1125
|
+
|
|
1126
|
+
// expect(await call(0).getRequestBodyJson()).toStrictEqual({
|
|
1127
|
+
// messages: [
|
|
1128
|
+
// {
|
|
1129
|
+
// role: 'user',
|
|
1130
|
+
// content: 'Message with text attachment',
|
|
1131
|
+
// experimental_attachments: [
|
|
1132
|
+
// {
|
|
1133
|
+
// name: 'test.txt',
|
|
1134
|
+
// contentType: 'text/plain',
|
|
1135
|
+
// url: 'data:text/plain;base64,dGVzdCBmaWxlIGNvbnRlbnQ=',
|
|
1136
|
+
// },
|
|
1137
|
+
// ],
|
|
1138
|
+
// },
|
|
1139
|
+
// ],
|
|
1140
|
+
// });
|
|
1141
|
+
|
|
1142
|
+
// await screen.findByTestId('message-0');
|
|
1143
|
+
// expect(screen.getByTestId('message-0')).toHaveTextContent(
|
|
1144
|
+
// 'User: Message with text attachment',
|
|
1145
|
+
// );
|
|
1146
|
+
|
|
1147
|
+
// await screen.findByTestId('attachment-0');
|
|
1148
|
+
// expect(screen.getByTestId('attachment-0')).toHaveTextContent(
|
|
1149
|
+
// 'test file content',
|
|
1150
|
+
// );
|
|
1151
|
+
|
|
1152
|
+
// await screen.findByTestId('message-1');
|
|
1153
|
+
// expect(screen.getByTestId('message-1')).toHaveTextContent(
|
|
1154
|
+
// 'AI: Response to message with text attachment',
|
|
1155
|
+
// );
|
|
1156
|
+
// },
|
|
1157
|
+
// ),
|
|
1158
|
+
// );
|
|
1159
|
+
|
|
1160
|
+
// it(
|
|
1161
|
+
// 'should handle image file attachment and submission',
|
|
1162
|
+
// withTestServer(
|
|
1163
|
+
// {
|
|
1164
|
+
// url: '/api/chat',
|
|
1165
|
+
// type: 'stream-values',
|
|
1166
|
+
// content: ['0:"Response to message with image attachment"\n'],
|
|
1167
|
+
// },
|
|
1168
|
+
// async ({ call }) => {
|
|
1169
|
+
// const file = new File(['test image content'], 'test.png', {
|
|
1170
|
+
// type: 'image/png',
|
|
1171
|
+
// });
|
|
1172
|
+
|
|
1173
|
+
// const fileInput = screen.getByTestId('file-input');
|
|
1174
|
+
// await userEvent.upload(fileInput, file);
|
|
1175
|
+
|
|
1176
|
+
// const messageInput = screen.getByTestId('message-input');
|
|
1177
|
+
// await userEvent.type(messageInput, 'Message with image attachment');
|
|
1178
|
+
|
|
1179
|
+
// const submitButton = screen.getByTestId('submit-button');
|
|
1180
|
+
// await userEvent.click(submitButton);
|
|
1181
|
+
|
|
1182
|
+
// expect(await call(0).getRequestBodyJson()).toStrictEqual({
|
|
1183
|
+
// messages: [
|
|
1184
|
+
// {
|
|
1185
|
+
// role: 'user',
|
|
1186
|
+
// content: 'Message with image attachment',
|
|
1187
|
+
// experimental_attachments: [
|
|
1188
|
+
// {
|
|
1189
|
+
// name: 'test.png',
|
|
1190
|
+
// contentType: 'image/png',
|
|
1191
|
+
// url: 'data:image/png;base64,dGVzdCBpbWFnZSBjb250ZW50',
|
|
1192
|
+
// },
|
|
1193
|
+
// ],
|
|
1194
|
+
// },
|
|
1195
|
+
// ],
|
|
1196
|
+
// });
|
|
1197
|
+
|
|
1198
|
+
// await screen.findByTestId('message-0');
|
|
1199
|
+
// expect(screen.getByTestId('message-0')).toHaveTextContent(
|
|
1200
|
+
// 'User: Message with image attachment',
|
|
1201
|
+
// );
|
|
1202
|
+
|
|
1203
|
+
// await screen.findByTestId('attachment-0');
|
|
1204
|
+
// expect(screen.getByTestId('attachment-0')).toHaveAttribute(
|
|
1205
|
+
// 'src',
|
|
1206
|
+
// expect.stringContaining('data:image/png;base64'),
|
|
1207
|
+
// );
|
|
1208
|
+
|
|
1209
|
+
// await screen.findByTestId('message-1');
|
|
1210
|
+
// expect(screen.getByTestId('message-1')).toHaveTextContent(
|
|
1211
|
+
// 'AI: Response to message with image attachment',
|
|
1212
|
+
// );
|
|
1213
|
+
// },
|
|
1214
|
+
// ),
|
|
1215
|
+
// );
|
|
1216
|
+
// });
|
|
1217
|
+
|
|
1218
|
+
// describe('file attachments with url', () => {
|
|
1219
|
+
// const TestComponent = () => {
|
|
1220
|
+
// const { messages, handleSubmit, handleInputChange, isLoading, input } =
|
|
1221
|
+
// useChat();
|
|
1222
|
+
|
|
1223
|
+
// return (
|
|
1224
|
+
// <div>
|
|
1225
|
+
// {messages.map((m, idx) => (
|
|
1226
|
+
// <div data-testid={`message-${idx}`} key={m.id}>
|
|
1227
|
+
// {m.role === 'user' ? 'User: ' : 'AI: '}
|
|
1228
|
+
// {m.content}
|
|
1229
|
+
// {m.experimental_attachments?.map(attachment => {
|
|
1230
|
+
// if (attachment.contentType?.startsWith('image/')) {
|
|
1231
|
+
// return (
|
|
1232
|
+
// <img
|
|
1233
|
+
// key={attachment.name}
|
|
1234
|
+
// src={attachment.url}
|
|
1235
|
+
// alt={attachment.name}
|
|
1236
|
+
// data-testid={`attachment-${idx}`}
|
|
1237
|
+
// />
|
|
1238
|
+
// );
|
|
1239
|
+
// } else if (attachment.contentType?.startsWith('text/')) {
|
|
1240
|
+
// return (
|
|
1241
|
+
// <div key={attachment.name} data-testid={`attachment-${idx}`}>
|
|
1242
|
+
// {Buffer.from(
|
|
1243
|
+
// attachment.url.split(',')[1],
|
|
1244
|
+
// 'base64',
|
|
1245
|
+
// ).toString('utf-8')}
|
|
1246
|
+
// </div>
|
|
1247
|
+
// );
|
|
1248
|
+
// }
|
|
1249
|
+
// })}
|
|
1250
|
+
// </div>
|
|
1251
|
+
// ))}
|
|
1252
|
+
|
|
1253
|
+
// <form
|
|
1254
|
+
// onSubmit={event => {
|
|
1255
|
+
// handleSubmit(event, {
|
|
1256
|
+
// experimental_attachments: [
|
|
1257
|
+
// {
|
|
1258
|
+
// name: 'test.png',
|
|
1259
|
+
// contentType: 'image/png',
|
|
1260
|
+
// url: 'https://example.com/image.png',
|
|
1261
|
+
// },
|
|
1262
|
+
// ],
|
|
1263
|
+
// });
|
|
1264
|
+
// }}
|
|
1265
|
+
// data-testid="chat-form"
|
|
1266
|
+
// >
|
|
1267
|
+
// <input
|
|
1268
|
+
// value={input}
|
|
1269
|
+
// onChange={handleInputChange}
|
|
1270
|
+
// disabled={isLoading}
|
|
1271
|
+
// data-testid="message-input"
|
|
1272
|
+
// />
|
|
1273
|
+
// <button type="submit" data-testid="submit-button">
|
|
1274
|
+
// Send
|
|
1275
|
+
// </button>
|
|
1276
|
+
// </form>
|
|
1277
|
+
// </div>
|
|
1278
|
+
// );
|
|
1279
|
+
// };
|
|
1280
|
+
|
|
1281
|
+
// beforeEach(() => {
|
|
1282
|
+
// render(<TestComponent />);
|
|
1283
|
+
// });
|
|
1284
|
+
|
|
1285
|
+
// afterEach(() => {
|
|
1286
|
+
// vi.restoreAllMocks();
|
|
1287
|
+
// cleanup();
|
|
1288
|
+
// });
|
|
1289
|
+
|
|
1290
|
+
// it(
|
|
1291
|
+
// 'should handle image file attachment and submission',
|
|
1292
|
+
// withTestServer(
|
|
1293
|
+
// {
|
|
1294
|
+
// url: '/api/chat',
|
|
1295
|
+
// type: 'stream-values',
|
|
1296
|
+
// content: ['0:"Response to message with image attachment"\n'],
|
|
1297
|
+
// },
|
|
1298
|
+
// async ({ call }) => {
|
|
1299
|
+
// const messageInput = screen.getByTestId('message-input');
|
|
1300
|
+
// await userEvent.type(messageInput, 'Message with image attachment');
|
|
1301
|
+
|
|
1302
|
+
// const submitButton = screen.getByTestId('submit-button');
|
|
1303
|
+
// await userEvent.click(submitButton);
|
|
1304
|
+
|
|
1305
|
+
// expect(await call(0).getRequestBodyJson()).toStrictEqual({
|
|
1306
|
+
// messages: [
|
|
1307
|
+
// {
|
|
1308
|
+
// role: 'user',
|
|
1309
|
+
// content: 'Message with image attachment',
|
|
1310
|
+
// experimental_attachments: [
|
|
1311
|
+
// {
|
|
1312
|
+
// name: 'test.png',
|
|
1313
|
+
// contentType: 'image/png',
|
|
1314
|
+
// url: 'https://example.com/image.png',
|
|
1315
|
+
// },
|
|
1316
|
+
// ],
|
|
1317
|
+
// },
|
|
1318
|
+
// ],
|
|
1319
|
+
// });
|
|
1320
|
+
|
|
1321
|
+
// await screen.findByTestId('message-0');
|
|
1322
|
+
// expect(screen.getByTestId('message-0')).toHaveTextContent(
|
|
1323
|
+
// 'User: Message with image attachment',
|
|
1324
|
+
// );
|
|
1325
|
+
|
|
1326
|
+
// await screen.findByTestId('attachment-0');
|
|
1327
|
+
// expect(screen.getByTestId('attachment-0')).toHaveAttribute(
|
|
1328
|
+
// 'src',
|
|
1329
|
+
// expect.stringContaining('https://example.com/image.png'),
|
|
1330
|
+
// );
|
|
1331
|
+
|
|
1332
|
+
// await screen.findByTestId('message-1');
|
|
1333
|
+
// expect(screen.getByTestId('message-1')).toHaveTextContent(
|
|
1334
|
+
// 'AI: Response to message with image attachment',
|
|
1335
|
+
// );
|
|
1336
|
+
// },
|
|
1337
|
+
// ),
|
|
1338
|
+
// );
|
|
1339
|
+
// });
|
|
1311
1340
|
|
|
1312
1341
|
describe('reload', () => {
|
|
1313
1342
|
const TestComponent = () => {
|