ai 5.0.0-canary.22 → 5.0.0-canary.23

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/dist/index.mjs CHANGED
@@ -974,303 +974,282 @@ function getToolInvocations(message) {
974
974
  }
975
975
 
976
976
  // src/ui/process-ui-message-stream.ts
977
- function processUIMessageStream({
978
- stream,
979
- onUpdate,
980
- onToolCall,
981
- onFinish,
977
+ function createStreamingUIMessageState({
982
978
  lastMessage,
983
- newMessageId,
984
- messageMetadataSchema
985
- }) {
979
+ newMessageId = "no-id"
980
+ } = {}) {
986
981
  var _a17;
987
982
  const isContinuation = (lastMessage == null ? void 0 : lastMessage.role) === "assistant";
988
- let step = isContinuation ? 1 + ((_a17 = extractMaxToolInvocationStep(getToolInvocations(lastMessage))) != null ? _a17 : 0) : 0;
983
+ const step = isContinuation ? 1 + ((_a17 = extractMaxToolInvocationStep(getToolInvocations(lastMessage))) != null ? _a17 : 0) : 0;
989
984
  const message = isContinuation ? structuredClone(lastMessage) : {
990
985
  id: newMessageId,
991
986
  metadata: {},
992
987
  role: "assistant",
993
988
  parts: []
994
989
  };
995
- let currentTextPart = void 0;
996
- let currentReasoningPart = void 0;
997
- function updateToolInvocationPart(toolCallId, invocation) {
998
- const part = message.parts.find(
999
- (part2) => part2.type === "tool-invocation" && part2.toolInvocation.toolCallId === toolCallId
1000
- );
1001
- if (part != null) {
1002
- part.toolInvocation = invocation;
1003
- } else {
1004
- message.parts.push({
1005
- type: "tool-invocation",
1006
- toolInvocation: invocation
1007
- });
1008
- }
1009
- }
1010
- const partialToolCalls = {};
1011
- async function updateMessageMetadata(metadata) {
1012
- if (metadata != null) {
1013
- const mergedMetadata = message.metadata != null ? mergeObjects(message.metadata, metadata) : metadata;
1014
- if (messageMetadataSchema != null) {
1015
- await validateTypes({
1016
- value: mergedMetadata,
1017
- schema: messageMetadataSchema
1018
- });
1019
- }
1020
- message.metadata = mergedMetadata;
1021
- }
1022
- }
990
+ return {
991
+ message,
992
+ activeTextPart: void 0,
993
+ activeReasoningPart: void 0,
994
+ partialToolCalls: {},
995
+ step
996
+ };
997
+ }
998
+ function processUIMessageStream({
999
+ stream,
1000
+ onToolCall,
1001
+ messageMetadataSchema,
1002
+ runUpdateMessageJob
1003
+ }) {
1023
1004
  return stream.pipeThrough(
1024
1005
  new TransformStream({
1025
1006
  async transform(chunk, controller) {
1026
- const { type, value } = chunk;
1027
- switch (type) {
1028
- case "text": {
1029
- if (currentTextPart == null) {
1030
- currentTextPart = {
1031
- type: "text",
1032
- text: value
1033
- };
1034
- message.parts.push(currentTextPart);
1007
+ await runUpdateMessageJob(async ({ state, write }) => {
1008
+ function updateToolInvocationPart(toolCallId, invocation) {
1009
+ const part = state.message.parts.find(
1010
+ (part2) => part2.type === "tool-invocation" && part2.toolInvocation.toolCallId === toolCallId
1011
+ );
1012
+ if (part != null) {
1013
+ part.toolInvocation = invocation;
1035
1014
  } else {
1036
- currentTextPart.text += value;
1015
+ state.message.parts.push({
1016
+ type: "tool-invocation",
1017
+ toolInvocation: invocation
1018
+ });
1037
1019
  }
1038
- onUpdate == null ? void 0 : onUpdate({ message });
1039
- break;
1040
1020
  }
1041
- case "reasoning": {
1042
- if (currentReasoningPart == null) {
1043
- currentReasoningPart = {
1044
- type: "reasoning",
1045
- text: value.text,
1046
- providerMetadata: value.providerMetadata
1047
- };
1048
- message.parts.push(currentReasoningPart);
1049
- } else {
1050
- currentReasoningPart.text += value.text;
1051
- currentReasoningPart.providerMetadata = value.providerMetadata;
1021
+ async function updateMessageMetadata(metadata) {
1022
+ if (metadata != null) {
1023
+ const mergedMetadata = state.message.metadata != null ? mergeObjects(state.message.metadata, metadata) : metadata;
1024
+ if (messageMetadataSchema != null) {
1025
+ await validateTypes({
1026
+ value: mergedMetadata,
1027
+ schema: messageMetadataSchema
1028
+ });
1029
+ }
1030
+ state.message.metadata = mergedMetadata;
1052
1031
  }
1053
- onUpdate == null ? void 0 : onUpdate({ message });
1054
- break;
1055
1032
  }
1056
- case "reasoning-part-finish": {
1057
- if (currentReasoningPart != null) {
1058
- currentReasoningPart = void 0;
1033
+ const { type, value } = chunk;
1034
+ switch (type) {
1035
+ case "text": {
1036
+ if (state.activeTextPart == null) {
1037
+ state.activeTextPart = {
1038
+ type: "text",
1039
+ text: value
1040
+ };
1041
+ state.message.parts.push(state.activeTextPart);
1042
+ } else {
1043
+ state.activeTextPart.text += value;
1044
+ }
1045
+ write();
1046
+ break;
1059
1047
  }
1060
- break;
1061
- }
1062
- case "file": {
1063
- message.parts.push({
1064
- type: "file",
1065
- mediaType: value.mediaType,
1066
- url: value.url
1067
- });
1068
- onUpdate == null ? void 0 : onUpdate({ message });
1069
- break;
1070
- }
1071
- case "source": {
1072
- message.parts.push({
1073
- type: "source",
1074
- source: value
1075
- });
1076
- onUpdate == null ? void 0 : onUpdate({ message });
1077
- break;
1078
- }
1079
- case "tool-call-streaming-start": {
1080
- const toolInvocations = getToolInvocations(message);
1081
- partialToolCalls[value.toolCallId] = {
1082
- text: "",
1083
- step,
1084
- toolName: value.toolName,
1085
- index: toolInvocations.length
1086
- };
1087
- updateToolInvocationPart(value.toolCallId, {
1088
- state: "partial-call",
1089
- step,
1090
- toolCallId: value.toolCallId,
1091
- toolName: value.toolName,
1092
- args: void 0
1093
- });
1094
- onUpdate == null ? void 0 : onUpdate({ message });
1095
- break;
1096
- }
1097
- case "tool-call-delta": {
1098
- const partialToolCall = partialToolCalls[value.toolCallId];
1099
- partialToolCall.text += value.argsTextDelta;
1100
- const { value: partialArgs } = await parsePartialJson(
1101
- partialToolCall.text
1102
- );
1103
- updateToolInvocationPart(value.toolCallId, {
1104
- state: "partial-call",
1105
- step: partialToolCall.step,
1106
- toolCallId: value.toolCallId,
1107
- toolName: partialToolCall.toolName,
1108
- args: partialArgs
1109
- });
1110
- onUpdate == null ? void 0 : onUpdate({ message });
1111
- break;
1112
- }
1113
- case "tool-call": {
1114
- const call = { args: value.args, ...value };
1115
- updateToolInvocationPart(value.toolCallId, {
1116
- state: "call",
1117
- step,
1118
- ...call
1119
- });
1120
- onUpdate == null ? void 0 : onUpdate({ message });
1121
- if (onToolCall) {
1122
- const result = await onToolCall({
1123
- toolCall: call
1048
+ case "reasoning": {
1049
+ if (state.activeReasoningPart == null) {
1050
+ state.activeReasoningPart = {
1051
+ type: "reasoning",
1052
+ text: value.text,
1053
+ providerMetadata: value.providerMetadata
1054
+ };
1055
+ state.message.parts.push(state.activeReasoningPart);
1056
+ } else {
1057
+ state.activeReasoningPart.text += value.text;
1058
+ state.activeReasoningPart.providerMetadata = value.providerMetadata;
1059
+ }
1060
+ write();
1061
+ break;
1062
+ }
1063
+ case "reasoning-part-finish": {
1064
+ if (state.activeReasoningPart != null) {
1065
+ state.activeReasoningPart = void 0;
1066
+ }
1067
+ break;
1068
+ }
1069
+ case "file": {
1070
+ state.message.parts.push({
1071
+ type: "file",
1072
+ mediaType: value.mediaType,
1073
+ url: value.url
1074
+ });
1075
+ write();
1076
+ break;
1077
+ }
1078
+ case "source": {
1079
+ state.message.parts.push({
1080
+ type: "source",
1081
+ source: value
1082
+ });
1083
+ write();
1084
+ break;
1085
+ }
1086
+ case "tool-call-streaming-start": {
1087
+ const toolInvocations = getToolInvocations(state.message);
1088
+ state.partialToolCalls[value.toolCallId] = {
1089
+ text: "",
1090
+ step: state.step,
1091
+ toolName: value.toolName,
1092
+ index: toolInvocations.length
1093
+ };
1094
+ updateToolInvocationPart(value.toolCallId, {
1095
+ state: "partial-call",
1096
+ step: state.step,
1097
+ toolCallId: value.toolCallId,
1098
+ toolName: value.toolName,
1099
+ args: void 0
1100
+ });
1101
+ write();
1102
+ break;
1103
+ }
1104
+ case "tool-call-delta": {
1105
+ const partialToolCall = state.partialToolCalls[value.toolCallId];
1106
+ partialToolCall.text += value.argsTextDelta;
1107
+ const { value: partialArgs } = await parsePartialJson(
1108
+ partialToolCall.text
1109
+ );
1110
+ updateToolInvocationPart(value.toolCallId, {
1111
+ state: "partial-call",
1112
+ step: partialToolCall.step,
1113
+ toolCallId: value.toolCallId,
1114
+ toolName: partialToolCall.toolName,
1115
+ args: partialArgs
1124
1116
  });
1125
- if (result != null) {
1126
- updateToolInvocationPart(value.toolCallId, {
1127
- state: "result",
1128
- step,
1129
- ...call,
1130
- result
1117
+ write();
1118
+ break;
1119
+ }
1120
+ case "tool-call": {
1121
+ const call = { args: value.args, ...value };
1122
+ updateToolInvocationPart(value.toolCallId, {
1123
+ state: "call",
1124
+ step: state.step,
1125
+ ...call
1126
+ });
1127
+ write();
1128
+ if (onToolCall) {
1129
+ const result = await onToolCall({
1130
+ toolCall: call
1131
1131
  });
1132
- onUpdate == null ? void 0 : onUpdate({ message });
1132
+ if (result != null) {
1133
+ updateToolInvocationPart(value.toolCallId, {
1134
+ state: "result",
1135
+ step: state.step,
1136
+ ...call,
1137
+ result
1138
+ });
1139
+ write();
1140
+ }
1133
1141
  }
1142
+ break;
1134
1143
  }
1135
- break;
1136
- }
1137
- case "tool-result": {
1138
- const toolInvocations = getToolInvocations(message);
1139
- if (toolInvocations == null) {
1140
- throw new Error("tool_result must be preceded by a tool_call");
1141
- }
1142
- const toolInvocationIndex = toolInvocations.findIndex(
1143
- (invocation) => invocation.toolCallId === value.toolCallId
1144
- );
1145
- if (toolInvocationIndex === -1) {
1146
- throw new Error(
1147
- "tool_result must be preceded by a tool_call with the same toolCallId"
1144
+ case "tool-result": {
1145
+ const toolInvocations = getToolInvocations(state.message);
1146
+ if (toolInvocations == null) {
1147
+ throw new Error("tool_result must be preceded by a tool_call");
1148
+ }
1149
+ const toolInvocationIndex = toolInvocations.findIndex(
1150
+ (invocation) => invocation.toolCallId === value.toolCallId
1148
1151
  );
1152
+ if (toolInvocationIndex === -1) {
1153
+ throw new Error(
1154
+ "tool_result must be preceded by a tool_call with the same toolCallId"
1155
+ );
1156
+ }
1157
+ const result = { result: value.result, ...value };
1158
+ updateToolInvocationPart(value.toolCallId, {
1159
+ ...toolInvocations[toolInvocationIndex],
1160
+ state: "result",
1161
+ ...result
1162
+ });
1163
+ write();
1164
+ break;
1149
1165
  }
1150
- const result = { result: value.result, ...value };
1151
- updateToolInvocationPart(value.toolCallId, {
1152
- ...toolInvocations[toolInvocationIndex],
1153
- state: "result",
1154
- ...result
1155
- });
1156
- onUpdate == null ? void 0 : onUpdate({ message });
1157
- break;
1158
- }
1159
- case "start-step": {
1160
- message.parts.push({ type: "step-start" });
1161
- await updateMessageMetadata(value.metadata);
1162
- onUpdate == null ? void 0 : onUpdate({ message });
1163
- break;
1164
- }
1165
- case "finish-step": {
1166
- step += 1;
1167
- currentTextPart = void 0;
1168
- currentReasoningPart = void 0;
1169
- await updateMessageMetadata(value.metadata);
1170
- if (value.metadata != null) {
1171
- onUpdate == null ? void 0 : onUpdate({ message });
1166
+ case "start-step": {
1167
+ state.message.parts.push({ type: "step-start" });
1168
+ await updateMessageMetadata(value.metadata);
1169
+ write();
1170
+ break;
1172
1171
  }
1173
- break;
1174
- }
1175
- case "start": {
1176
- if (value.messageId != null) {
1177
- message.id = value.messageId;
1172
+ case "finish-step": {
1173
+ state.step += 1;
1174
+ state.activeTextPart = void 0;
1175
+ state.activeReasoningPart = void 0;
1176
+ await updateMessageMetadata(value.metadata);
1177
+ if (value.metadata != null) {
1178
+ write();
1179
+ }
1180
+ break;
1178
1181
  }
1179
- await updateMessageMetadata(value.metadata);
1180
- if (value.messageId != null || value.metadata != null) {
1181
- onUpdate == null ? void 0 : onUpdate({ message });
1182
+ case "start": {
1183
+ if (value.messageId != null) {
1184
+ state.message.id = value.messageId;
1185
+ }
1186
+ await updateMessageMetadata(value.metadata);
1187
+ if (value.messageId != null || value.metadata != null) {
1188
+ write();
1189
+ }
1190
+ break;
1182
1191
  }
1183
- break;
1184
- }
1185
- case "finish": {
1186
- await updateMessageMetadata(value.metadata);
1187
- if (value.metadata != null) {
1188
- onUpdate == null ? void 0 : onUpdate({ message });
1192
+ case "finish": {
1193
+ await updateMessageMetadata(value.metadata);
1194
+ if (value.metadata != null) {
1195
+ write();
1196
+ }
1197
+ break;
1189
1198
  }
1190
- break;
1191
- }
1192
- case "metadata": {
1193
- await updateMessageMetadata(value.metadata);
1194
- if (value.metadata != null) {
1195
- onUpdate == null ? void 0 : onUpdate({ message });
1199
+ case "metadata": {
1200
+ await updateMessageMetadata(value.metadata);
1201
+ if (value.metadata != null) {
1202
+ write();
1203
+ }
1204
+ break;
1205
+ }
1206
+ case "error": {
1207
+ throw new Error(value);
1208
+ }
1209
+ default: {
1210
+ const _exhaustiveCheck = type;
1211
+ throw new Error(`Unhandled stream part: ${_exhaustiveCheck}`);
1196
1212
  }
1197
- break;
1198
- }
1199
- case "error": {
1200
- throw new Error(value);
1201
- }
1202
- default: {
1203
- const _exhaustiveCheck = type;
1204
- throw new Error(`Unhandled stream part: ${_exhaustiveCheck}`);
1205
1213
  }
1206
- }
1207
- controller.enqueue(chunk);
1208
- },
1209
- flush() {
1210
- onFinish == null ? void 0 : onFinish({ message });
1214
+ controller.enqueue(chunk);
1215
+ });
1211
1216
  }
1212
1217
  })
1213
1218
  );
1214
1219
  }
1215
1220
 
1216
- // src/ui/process-chat-text-response.ts
1217
- import { generateId as generateIdFunction } from "@ai-sdk/provider-utils";
1218
-
1219
- // src/ui/process-text-stream.ts
1220
- async function processTextStream({
1221
- stream,
1222
- onTextPart
1223
- }) {
1224
- const reader = stream.pipeThrough(new TextDecoderStream()).getReader();
1225
- while (true) {
1226
- const { done, value } = await reader.read();
1227
- if (done) {
1228
- break;
1229
- }
1230
- await onTextPart(value);
1231
- }
1232
- }
1233
-
1234
- // src/ui/process-chat-text-response.ts
1235
- async function processChatTextResponse({
1236
- stream,
1237
- update,
1238
- onFinish,
1239
- generateId: generateId3 = generateIdFunction
1221
+ // src/ui/transform-text-to-ui-message-stream.ts
1222
+ function transformTextToUiMessageStream({
1223
+ stream
1240
1224
  }) {
1241
- const textPart = { type: "text", text: "" };
1242
- const resultMessage = {
1243
- id: generateId3(),
1244
- role: "assistant",
1245
- parts: [textPart]
1246
- };
1247
- await processTextStream({
1248
- stream,
1249
- onTextPart: (chunk) => {
1250
- textPart.text += chunk;
1251
- update({ message: { ...resultMessage } });
1252
- }
1253
- });
1254
- onFinish == null ? void 0 : onFinish({ message: resultMessage });
1225
+ return stream.pipeThrough(
1226
+ new TransformStream({
1227
+ start(controller) {
1228
+ controller.enqueue({ type: "start", value: {} });
1229
+ controller.enqueue({ type: "start-step", value: {} });
1230
+ },
1231
+ async transform(part, controller) {
1232
+ controller.enqueue({ type: "text", value: part });
1233
+ },
1234
+ async flush(controller) {
1235
+ controller.enqueue({ type: "finish-step", value: {} });
1236
+ controller.enqueue({ type: "finish", value: {} });
1237
+ }
1238
+ })
1239
+ );
1255
1240
  }
1256
1241
 
1257
1242
  // src/ui/call-chat-api.ts
1258
1243
  var getOriginalFetch = () => fetch;
1259
- async function callChatApi({
1244
+ async function fetchUIMessageStream({
1260
1245
  api,
1261
1246
  body,
1262
1247
  streamProtocol = "ui-message",
1263
1248
  credentials,
1264
1249
  headers,
1265
1250
  abortController,
1266
- onUpdate,
1267
- onFinish,
1268
- onToolCall,
1269
- generateId: generateId3,
1270
1251
  fetch: fetch2 = getOriginalFetch(),
1271
- lastMessage,
1272
- requestType = "generate",
1273
- messageMetadataSchema
1252
+ requestType = "generate"
1274
1253
  }) {
1275
1254
  var _a17, _b, _c;
1276
1255
  const response = requestType === "resume" ? await fetch2(`${api}?chatId=${body.id}`, {
@@ -1299,177 +1278,681 @@ async function callChatApi({
1299
1278
  if (!response.body) {
1300
1279
  throw new Error("The response body is empty.");
1301
1280
  }
1302
- switch (streamProtocol) {
1303
- case "text": {
1304
- await processChatTextResponse({
1305
- stream: response.body,
1306
- update: onUpdate,
1307
- onFinish,
1308
- generateId: generateId3
1281
+ return streamProtocol === "text" ? transformTextToUiMessageStream({
1282
+ stream: response.body.pipeThrough(new TextDecoderStream())
1283
+ }) : parseJsonEventStream({
1284
+ stream: response.body,
1285
+ schema: uiMessageStreamPartSchema
1286
+ }).pipeThrough(
1287
+ new TransformStream({
1288
+ async transform(part, controller) {
1289
+ if (!part.success) {
1290
+ throw part.error;
1291
+ }
1292
+ controller.enqueue(part.value);
1293
+ }
1294
+ })
1295
+ );
1296
+ }
1297
+ async function consumeUIMessageStream({
1298
+ stream,
1299
+ onUpdate,
1300
+ onFinish,
1301
+ onToolCall,
1302
+ generateId: generateId3,
1303
+ lastMessage,
1304
+ messageMetadataSchema
1305
+ }) {
1306
+ const state = createStreamingUIMessageState({
1307
+ lastMessage,
1308
+ newMessageId: generateId3()
1309
+ });
1310
+ const runUpdateMessageJob = async (job) => {
1311
+ await job({
1312
+ state,
1313
+ write: () => {
1314
+ onUpdate({ message: state.message });
1315
+ }
1316
+ });
1317
+ };
1318
+ await consumeStream({
1319
+ stream: processUIMessageStream({
1320
+ stream,
1321
+ onToolCall,
1322
+ messageMetadataSchema,
1323
+ runUpdateMessageJob
1324
+ }),
1325
+ onError: (error) => {
1326
+ throw error;
1327
+ }
1328
+ });
1329
+ onFinish == null ? void 0 : onFinish({ message: state.message });
1330
+ }
1331
+ async function callChatApi({
1332
+ api,
1333
+ body,
1334
+ streamProtocol = "ui-message",
1335
+ credentials,
1336
+ headers,
1337
+ abortController,
1338
+ onUpdate,
1339
+ onFinish,
1340
+ onToolCall,
1341
+ generateId: generateId3,
1342
+ fetch: fetch2 = getOriginalFetch(),
1343
+ lastMessage,
1344
+ requestType = "generate",
1345
+ messageMetadataSchema
1346
+ }) {
1347
+ const stream = await fetchUIMessageStream({
1348
+ api,
1349
+ body,
1350
+ streamProtocol,
1351
+ credentials,
1352
+ headers,
1353
+ abortController,
1354
+ fetch: fetch2,
1355
+ requestType
1356
+ });
1357
+ await consumeUIMessageStream({
1358
+ stream,
1359
+ onUpdate,
1360
+ onFinish,
1361
+ onToolCall,
1362
+ generateId: generateId3,
1363
+ lastMessage,
1364
+ messageMetadataSchema
1365
+ });
1366
+ }
1367
+
1368
+ // src/ui/call-completion-api.ts
1369
+ import { parseJsonEventStream as parseJsonEventStream2 } from "@ai-sdk/provider-utils";
1370
+
1371
+ // src/ui/process-text-stream.ts
1372
+ async function processTextStream({
1373
+ stream,
1374
+ onTextPart
1375
+ }) {
1376
+ const reader = stream.pipeThrough(new TextDecoderStream()).getReader();
1377
+ while (true) {
1378
+ const { done, value } = await reader.read();
1379
+ if (done) {
1380
+ break;
1381
+ }
1382
+ await onTextPart(value);
1383
+ }
1384
+ }
1385
+
1386
+ // src/ui/call-completion-api.ts
1387
+ var getOriginalFetch2 = () => fetch;
1388
+ async function callCompletionApi({
1389
+ api,
1390
+ prompt,
1391
+ credentials,
1392
+ headers,
1393
+ body,
1394
+ streamProtocol = "data",
1395
+ setCompletion,
1396
+ setLoading,
1397
+ setError,
1398
+ setAbortController,
1399
+ onFinish,
1400
+ onError,
1401
+ fetch: fetch2 = getOriginalFetch2()
1402
+ }) {
1403
+ var _a17;
1404
+ try {
1405
+ setLoading(true);
1406
+ setError(void 0);
1407
+ const abortController = new AbortController();
1408
+ setAbortController(abortController);
1409
+ setCompletion("");
1410
+ const response = await fetch2(api, {
1411
+ method: "POST",
1412
+ body: JSON.stringify({
1413
+ prompt,
1414
+ ...body
1415
+ }),
1416
+ credentials,
1417
+ headers: {
1418
+ "Content-Type": "application/json",
1419
+ ...headers
1420
+ },
1421
+ signal: abortController.signal
1422
+ }).catch((err) => {
1423
+ throw err;
1424
+ });
1425
+ if (!response.ok) {
1426
+ throw new Error(
1427
+ (_a17 = await response.text()) != null ? _a17 : "Failed to fetch the chat response."
1428
+ );
1429
+ }
1430
+ if (!response.body) {
1431
+ throw new Error("The response body is empty.");
1432
+ }
1433
+ let result = "";
1434
+ switch (streamProtocol) {
1435
+ case "text": {
1436
+ await processTextStream({
1437
+ stream: response.body,
1438
+ onTextPart: (chunk) => {
1439
+ result += chunk;
1440
+ setCompletion(result);
1441
+ }
1442
+ });
1443
+ break;
1444
+ }
1445
+ case "data": {
1446
+ await consumeStream({
1447
+ stream: parseJsonEventStream2({
1448
+ stream: response.body,
1449
+ schema: uiMessageStreamPartSchema
1450
+ }).pipeThrough(
1451
+ new TransformStream({
1452
+ async transform(part) {
1453
+ if (!part.success) {
1454
+ throw part.error;
1455
+ }
1456
+ const { type, value } = part.value;
1457
+ if (type === "text") {
1458
+ result += value;
1459
+ setCompletion(result);
1460
+ } else if (type === "error") {
1461
+ throw new Error(value);
1462
+ }
1463
+ }
1464
+ })
1465
+ ),
1466
+ onError: (error) => {
1467
+ throw error;
1468
+ }
1469
+ });
1470
+ break;
1471
+ }
1472
+ default: {
1473
+ const exhaustiveCheck = streamProtocol;
1474
+ throw new Error(`Unknown stream protocol: ${exhaustiveCheck}`);
1475
+ }
1476
+ }
1477
+ if (onFinish) {
1478
+ onFinish(prompt, result);
1479
+ }
1480
+ setAbortController(null);
1481
+ return result;
1482
+ } catch (err) {
1483
+ if (err.name === "AbortError") {
1484
+ setAbortController(null);
1485
+ return null;
1486
+ }
1487
+ if (err instanceof Error) {
1488
+ if (onError) {
1489
+ onError(err);
1490
+ }
1491
+ }
1492
+ setError(err);
1493
+ } finally {
1494
+ setLoading(false);
1495
+ }
1496
+ }
1497
+
1498
+ // src/ui/chat-store.ts
1499
+ import {
1500
+ generateId as generateIdFunc
1501
+ } from "@ai-sdk/provider-utils";
1502
+
1503
+ // src/util/serial-job-executor.ts
1504
+ var SerialJobExecutor = class {
1505
+ constructor() {
1506
+ this.queue = [];
1507
+ this.isProcessing = false;
1508
+ }
1509
+ async processQueue() {
1510
+ if (this.isProcessing) {
1511
+ return;
1512
+ }
1513
+ this.isProcessing = true;
1514
+ while (this.queue.length > 0) {
1515
+ await this.queue[0]();
1516
+ this.queue.shift();
1517
+ }
1518
+ this.isProcessing = false;
1519
+ }
1520
+ async run(job) {
1521
+ return new Promise((resolve, reject) => {
1522
+ this.queue.push(async () => {
1523
+ try {
1524
+ await job();
1525
+ resolve();
1526
+ } catch (error) {
1527
+ reject(error);
1528
+ }
1529
+ });
1530
+ void this.processQueue();
1531
+ });
1532
+ }
1533
+ };
1534
+
1535
+ // src/ui/should-resubmit-messages.ts
1536
+ function shouldResubmitMessages({
1537
+ originalMaxToolInvocationStep,
1538
+ originalMessageCount,
1539
+ maxSteps,
1540
+ messages
1541
+ }) {
1542
+ var _a17;
1543
+ const lastMessage = messages[messages.length - 1];
1544
+ return (
1545
+ // check if the feature is enabled:
1546
+ maxSteps > 1 && // ensure there is a last message:
1547
+ lastMessage != null && // ensure we actually have new steps (to prevent infinite loops in case of errors):
1548
+ (messages.length > originalMessageCount || extractMaxToolInvocationStep(getToolInvocations(lastMessage)) !== originalMaxToolInvocationStep) && // check that next step is possible:
1549
+ isAssistantMessageWithCompletedToolCalls(lastMessage) && // limit the number of automatic steps:
1550
+ ((_a17 = extractMaxToolInvocationStep(getToolInvocations(lastMessage))) != null ? _a17 : 0) < maxSteps
1551
+ );
1552
+ }
1553
+ function isAssistantMessageWithCompletedToolCalls(message) {
1554
+ if (message.role !== "assistant") {
1555
+ return false;
1556
+ }
1557
+ const lastStepStartIndex = message.parts.reduce((lastIndex, part, index) => {
1558
+ return part.type === "step-start" ? index : lastIndex;
1559
+ }, -1);
1560
+ const lastStepToolInvocations = message.parts.slice(lastStepStartIndex + 1).filter((part) => part.type === "tool-invocation");
1561
+ return lastStepToolInvocations.length > 0 && lastStepToolInvocations.every((part) => "result" in part.toolInvocation);
1562
+ }
1563
+
1564
+ // src/ui/update-tool-call-result.ts
1565
+ function updateToolCallResult({
1566
+ messages,
1567
+ toolCallId,
1568
+ toolResult: result
1569
+ }) {
1570
+ const lastMessage = messages[messages.length - 1];
1571
+ const invocationPart = lastMessage.parts.find(
1572
+ (part) => part.type === "tool-invocation" && part.toolInvocation.toolCallId === toolCallId
1573
+ );
1574
+ if (invocationPart == null) {
1575
+ return;
1576
+ }
1577
+ invocationPart.toolInvocation = {
1578
+ ...invocationPart.toolInvocation,
1579
+ state: "result",
1580
+ result
1581
+ };
1582
+ }
1583
+
1584
+ // src/ui/chat-store.ts
1585
+ var ChatStore = class {
1586
+ constructor({
1587
+ chats = {},
1588
+ generateId: generateId3,
1589
+ messageMetadataSchema,
1590
+ transport,
1591
+ maxSteps = 1
1592
+ }) {
1593
+ this.chats = new Map(
1594
+ Object.entries(chats).map(([id, state]) => [
1595
+ id,
1596
+ {
1597
+ messages: [...state.messages],
1598
+ status: "ready",
1599
+ activeResponse: void 0,
1600
+ error: void 0,
1601
+ jobExecutor: new SerialJobExecutor()
1602
+ }
1603
+ ])
1604
+ );
1605
+ this.maxSteps = maxSteps;
1606
+ this.transport = transport;
1607
+ this.subscribers = /* @__PURE__ */ new Set();
1608
+ this.generateId = generateId3 != null ? generateId3 : generateIdFunc;
1609
+ this.messageMetadataSchema = messageMetadataSchema;
1610
+ }
1611
+ hasChat(id) {
1612
+ return this.chats.has(id);
1613
+ }
1614
+ addChat(id, messages) {
1615
+ this.chats.set(id, {
1616
+ messages,
1617
+ status: "ready",
1618
+ jobExecutor: new SerialJobExecutor()
1619
+ });
1620
+ }
1621
+ getChats() {
1622
+ return Array.from(this.chats.entries());
1623
+ }
1624
+ get chatCount() {
1625
+ return this.chats.size;
1626
+ }
1627
+ getStatus(id) {
1628
+ return this.getChat(id).status;
1629
+ }
1630
+ setStatus({
1631
+ id,
1632
+ status,
1633
+ error
1634
+ }) {
1635
+ const chat = this.getChat(id);
1636
+ if (chat.status === status)
1637
+ return;
1638
+ chat.status = status;
1639
+ chat.error = error;
1640
+ this.emit({ type: "chat-status-changed", chatId: id, error });
1641
+ }
1642
+ getError(id) {
1643
+ return this.getChat(id).error;
1644
+ }
1645
+ getMessages(id) {
1646
+ return this.getChat(id).messages;
1647
+ }
1648
+ getLastMessage(id) {
1649
+ const chat = this.getChat(id);
1650
+ return chat.messages[chat.messages.length - 1];
1651
+ }
1652
+ subscribe(subscriber) {
1653
+ this.subscribers.add(subscriber);
1654
+ return () => this.subscribers.delete(subscriber);
1655
+ }
1656
+ setMessages({
1657
+ id,
1658
+ messages
1659
+ }) {
1660
+ this.getChat(id).messages = [...messages];
1661
+ this.emit({ type: "chat-messages-changed", chatId: id });
1662
+ }
1663
+ appendMessage({
1664
+ id,
1665
+ message
1666
+ }) {
1667
+ const chat = this.getChat(id);
1668
+ chat.messages = [...chat.messages, { ...message }];
1669
+ this.emit({ type: "chat-messages-changed", chatId: id });
1670
+ }
1671
+ removeAssistantResponse(id) {
1672
+ const chat = this.getChat(id);
1673
+ const lastMessage = chat.messages[chat.messages.length - 1];
1674
+ if (lastMessage == null) {
1675
+ throw new Error("Cannot remove assistant response from empty chat");
1676
+ }
1677
+ if (lastMessage.role !== "assistant") {
1678
+ throw new Error("Last message is not an assistant message");
1679
+ }
1680
+ this.setMessages({ id, messages: chat.messages.slice(0, -1) });
1681
+ }
1682
+ async submitMessage({
1683
+ chatId,
1684
+ message,
1685
+ headers,
1686
+ body,
1687
+ onError,
1688
+ onToolCall,
1689
+ onFinish
1690
+ }) {
1691
+ var _a17;
1692
+ const chat = this.getChat(chatId);
1693
+ const currentMessages = chat.messages;
1694
+ await this.triggerRequest({
1695
+ chatId,
1696
+ messages: currentMessages.concat({
1697
+ ...message,
1698
+ id: (_a17 = message.id) != null ? _a17 : this.generateId()
1699
+ }),
1700
+ headers,
1701
+ body,
1702
+ requestType: "generate",
1703
+ onError,
1704
+ onToolCall,
1705
+ onFinish
1706
+ });
1707
+ }
1708
+ async resubmitLastUserMessage({
1709
+ chatId,
1710
+ headers,
1711
+ body,
1712
+ onError,
1713
+ onToolCall,
1714
+ onFinish
1715
+ }) {
1716
+ const messages = this.getChat(chatId).messages;
1717
+ const messagesToSubmit = messages[messages.length - 1].role === "assistant" ? messages.slice(0, -1) : messages;
1718
+ if (messagesToSubmit.length === 0) {
1719
+ return;
1720
+ }
1721
+ return this.triggerRequest({
1722
+ chatId,
1723
+ requestType: "generate",
1724
+ messages: messagesToSubmit,
1725
+ headers,
1726
+ body,
1727
+ onError,
1728
+ onToolCall,
1729
+ onFinish
1730
+ });
1731
+ }
1732
+ async resumeStream({
1733
+ chatId,
1734
+ headers,
1735
+ body,
1736
+ onError,
1737
+ onToolCall,
1738
+ onFinish
1739
+ }) {
1740
+ const chat = this.getChat(chatId);
1741
+ const currentMessages = chat.messages;
1742
+ return this.triggerRequest({
1743
+ chatId,
1744
+ messages: currentMessages,
1745
+ requestType: "resume",
1746
+ headers,
1747
+ body,
1748
+ onError,
1749
+ onToolCall,
1750
+ onFinish
1751
+ });
1752
+ }
1753
+ async addToolResult({
1754
+ chatId,
1755
+ toolCallId,
1756
+ result
1757
+ }) {
1758
+ const chat = this.getChat(chatId);
1759
+ chat.jobExecutor.run(async () => {
1760
+ const currentMessages = chat.messages;
1761
+ updateToolCallResult({
1762
+ messages: currentMessages,
1763
+ toolCallId,
1764
+ toolResult: result
1309
1765
  });
1766
+ this.setMessages({ id: chatId, messages: currentMessages });
1767
+ if (chat.status === "submitted" || chat.status === "streaming") {
1768
+ return;
1769
+ }
1770
+ const lastMessage = currentMessages[currentMessages.length - 1];
1771
+ if (isAssistantMessageWithCompletedToolCalls(lastMessage)) {
1772
+ await this.triggerRequest({
1773
+ messages: currentMessages,
1774
+ requestType: "generate",
1775
+ chatId
1776
+ });
1777
+ }
1778
+ });
1779
+ }
1780
+ async stopStream({ chatId }) {
1781
+ var _a17;
1782
+ const chat = this.getChat(chatId);
1783
+ if (chat.status !== "streaming" && chat.status !== "submitted")
1310
1784
  return;
1785
+ if ((_a17 = chat.activeResponse) == null ? void 0 : _a17.abortController) {
1786
+ chat.activeResponse.abortController.abort();
1787
+ chat.activeResponse.abortController = void 0;
1311
1788
  }
1312
- case "ui-message": {
1789
+ }
1790
+ emit(event) {
1791
+ for (const subscriber of this.subscribers) {
1792
+ subscriber.onChatChanged(event);
1793
+ }
1794
+ }
1795
+ getChat(id) {
1796
+ if (!this.hasChat(id)) {
1797
+ throw new Error(`chat '${id}' not found`);
1798
+ }
1799
+ return this.chats.get(id);
1800
+ }
1801
+ async triggerRequest({
1802
+ chatId,
1803
+ messages: chatMessages,
1804
+ requestType,
1805
+ headers,
1806
+ body,
1807
+ onError,
1808
+ onToolCall,
1809
+ onFinish
1810
+ }) {
1811
+ const self = this;
1812
+ const chat = this.getChat(chatId);
1813
+ this.setStatus({ id: chatId, status: "submitted", error: void 0 });
1814
+ const messageCount = chatMessages.length;
1815
+ const maxStep = extractMaxToolInvocationStep(
1816
+ getToolInvocations(chatMessages[chatMessages.length - 1])
1817
+ );
1818
+ try {
1819
+ const activeResponse = {
1820
+ state: createStreamingUIMessageState({
1821
+ lastMessage: chatMessages[chatMessages.length - 1],
1822
+ newMessageId: self.generateId()
1823
+ }),
1824
+ abortController: new AbortController()
1825
+ };
1826
+ chat.activeResponse = activeResponse;
1827
+ const stream = await self.transport.submitMessages({
1828
+ chatId,
1829
+ messages: chatMessages,
1830
+ body,
1831
+ headers,
1832
+ abortController: activeResponse.abortController,
1833
+ requestType
1834
+ });
1835
+ const runUpdateMessageJob = (job) => (
1836
+ // serialize the job execution to avoid race conditions:
1837
+ chat.jobExecutor.run(
1838
+ () => job({
1839
+ state: activeResponse.state,
1840
+ write: () => {
1841
+ self.setStatus({ id: chatId, status: "streaming" });
1842
+ const replaceLastMessage = activeResponse.state.message.id === chatMessages[chatMessages.length - 1].id;
1843
+ const newMessages = [
1844
+ ...replaceLastMessage ? chatMessages.slice(0, chatMessages.length - 1) : chatMessages,
1845
+ activeResponse.state.message
1846
+ ];
1847
+ self.setMessages({
1848
+ id: chatId,
1849
+ messages: newMessages
1850
+ });
1851
+ }
1852
+ })
1853
+ )
1854
+ );
1313
1855
  await consumeStream({
1314
1856
  stream: processUIMessageStream({
1315
- stream: parseJsonEventStream({
1316
- stream: response.body,
1317
- schema: uiMessageStreamPartSchema
1318
- }).pipeThrough(
1319
- new TransformStream({
1320
- async transform(part, controller) {
1321
- if (!part.success) {
1322
- throw part.error;
1323
- }
1324
- controller.enqueue(part.value);
1325
- }
1326
- })
1327
- ),
1328
- onUpdate({ message }) {
1329
- const copiedMessage = {
1330
- // deep copy the message to ensure that deep changes (msg attachments) are updated
1331
- // with SolidJS. SolidJS uses referential integration of sub-objects to detect changes.
1332
- ...structuredClone(message),
1333
- // add a revision id to ensure that the message is updated with SWR. SWR uses a
1334
- // hashing approach by default to detect changes, but it only works for shallow
1335
- // changes. This is why we need to add a revision id to ensure that the message
1336
- // is updated with SWR (without it, the changes get stuck in SWR and are not
1337
- // forwarded to rendering):
1338
- revisionId: generateId3()
1339
- };
1340
- onUpdate({ message: copiedMessage });
1341
- },
1342
- lastMessage,
1857
+ stream,
1343
1858
  onToolCall,
1344
- onFinish,
1345
- newMessageId: generateId3(),
1346
- messageMetadataSchema
1859
+ messageMetadataSchema: self.messageMetadataSchema,
1860
+ runUpdateMessageJob
1347
1861
  }),
1348
1862
  onError: (error) => {
1349
1863
  throw error;
1350
1864
  }
1351
1865
  });
1352
- return;
1353
- }
1354
- default: {
1355
- const exhaustiveCheck = streamProtocol;
1356
- throw new Error(`Unknown stream protocol: ${exhaustiveCheck}`);
1866
+ onFinish == null ? void 0 : onFinish({ message: activeResponse.state.message });
1867
+ this.setStatus({ id: chatId, status: "ready" });
1868
+ } catch (err) {
1869
+ if (err.name === "AbortError") {
1870
+ this.setStatus({ id: chatId, status: "ready" });
1871
+ return null;
1872
+ }
1873
+ if (onError && err instanceof Error) {
1874
+ onError(err);
1875
+ }
1876
+ this.setStatus({ id: chatId, status: "error", error: err });
1877
+ } finally {
1878
+ chat.activeResponse = void 0;
1879
+ }
1880
+ const currentMessages = self.getMessages(chatId);
1881
+ if (shouldResubmitMessages({
1882
+ originalMaxToolInvocationStep: maxStep,
1883
+ originalMessageCount: messageCount,
1884
+ maxSteps: self.maxSteps,
1885
+ messages: currentMessages
1886
+ })) {
1887
+ await self.triggerRequest({
1888
+ chatId,
1889
+ requestType,
1890
+ onError,
1891
+ onToolCall,
1892
+ onFinish,
1893
+ headers,
1894
+ body,
1895
+ messages: currentMessages
1896
+ });
1357
1897
  }
1358
1898
  }
1359
- }
1899
+ };
1360
1900
 
1361
- // src/ui/call-completion-api.ts
1362
- import { parseJsonEventStream as parseJsonEventStream2 } from "@ai-sdk/provider-utils";
1363
- var getOriginalFetch2 = () => fetch;
1364
- async function callCompletionApi({
1365
- api,
1366
- prompt,
1367
- credentials,
1368
- headers,
1369
- body,
1370
- streamProtocol = "data",
1371
- setCompletion,
1372
- setLoading,
1373
- setError,
1374
- setAbortController,
1375
- onFinish,
1376
- onError,
1377
- fetch: fetch2 = getOriginalFetch2()
1378
- }) {
1379
- var _a17;
1380
- try {
1381
- setLoading(true);
1382
- setError(void 0);
1383
- const abortController = new AbortController();
1384
- setAbortController(abortController);
1385
- setCompletion("");
1386
- const response = await fetch2(api, {
1387
- method: "POST",
1388
- body: JSON.stringify({
1389
- prompt,
1390
- ...body
1391
- }),
1392
- credentials,
1901
+ // src/ui/chat-transport.ts
1902
+ var DefaultChatTransport = class {
1903
+ constructor({
1904
+ api,
1905
+ credentials,
1906
+ headers,
1907
+ body,
1908
+ streamProtocol,
1909
+ fetch: fetch2,
1910
+ prepareRequestBody
1911
+ }) {
1912
+ this.api = api;
1913
+ this.credentials = credentials;
1914
+ this.headers = headers;
1915
+ this.body = body;
1916
+ this.streamProtocol = streamProtocol;
1917
+ this.fetch = fetch2;
1918
+ this.prepareRequestBody = prepareRequestBody;
1919
+ }
1920
+ submitMessages({
1921
+ chatId,
1922
+ messages,
1923
+ abortController,
1924
+ body,
1925
+ headers,
1926
+ requestType
1927
+ }) {
1928
+ var _a17, _b;
1929
+ return fetchUIMessageStream({
1930
+ api: this.api,
1393
1931
  headers: {
1394
- "Content-Type": "application/json",
1932
+ ...this.headers,
1395
1933
  ...headers
1396
1934
  },
1397
- signal: abortController.signal
1398
- }).catch((err) => {
1399
- throw err;
1935
+ body: (_b = (_a17 = this.prepareRequestBody) == null ? void 0 : _a17.call(this, {
1936
+ id: chatId,
1937
+ // TODO change to chatId
1938
+ messages,
1939
+ ...this.body,
1940
+ ...body
1941
+ })) != null ? _b : {
1942
+ id: chatId,
1943
+ // TODO change to chatId
1944
+ messages,
1945
+ ...this.body,
1946
+ ...body
1947
+ },
1948
+ streamProtocol: this.streamProtocol,
1949
+ credentials: this.credentials,
1950
+ abortController: () => abortController,
1951
+ fetch: this.fetch,
1952
+ requestType
1400
1953
  });
1401
- if (!response.ok) {
1402
- throw new Error(
1403
- (_a17 = await response.text()) != null ? _a17 : "Failed to fetch the chat response."
1404
- );
1405
- }
1406
- if (!response.body) {
1407
- throw new Error("The response body is empty.");
1408
- }
1409
- let result = "";
1410
- switch (streamProtocol) {
1411
- case "text": {
1412
- await processTextStream({
1413
- stream: response.body,
1414
- onTextPart: (chunk) => {
1415
- result += chunk;
1416
- setCompletion(result);
1417
- }
1418
- });
1419
- break;
1420
- }
1421
- case "data": {
1422
- await consumeStream({
1423
- stream: parseJsonEventStream2({
1424
- stream: response.body,
1425
- schema: uiMessageStreamPartSchema
1426
- }).pipeThrough(
1427
- new TransformStream({
1428
- async transform(part) {
1429
- if (!part.success) {
1430
- throw part.error;
1431
- }
1432
- const { type, value } = part.value;
1433
- if (type === "text") {
1434
- result += value;
1435
- setCompletion(result);
1436
- } else if (type === "error") {
1437
- throw new Error(value);
1438
- }
1439
- }
1440
- })
1441
- ),
1442
- onError: (error) => {
1443
- throw error;
1444
- }
1445
- });
1446
- break;
1447
- }
1448
- default: {
1449
- const exhaustiveCheck = streamProtocol;
1450
- throw new Error(`Unknown stream protocol: ${exhaustiveCheck}`);
1451
- }
1452
- }
1453
- if (onFinish) {
1454
- onFinish(prompt, result);
1455
- }
1456
- setAbortController(null);
1457
- return result;
1458
- } catch (err) {
1459
- if (err.name === "AbortError") {
1460
- setAbortController(null);
1461
- return null;
1462
- }
1463
- if (err instanceof Error) {
1464
- if (onError) {
1465
- onError(err);
1466
- }
1467
- }
1468
- setError(err);
1469
- } finally {
1470
- setLoading(false);
1471
1954
  }
1472
- }
1955
+ };
1473
1956
 
1474
1957
  // src/ui/convert-file-list-to-file-ui-parts.ts
1475
1958
  async function convertFileListToFileUIParts(files) {
@@ -1657,53 +2140,38 @@ function convertToModelMessages(messages, options) {
1657
2140
  }
1658
2141
  var convertToCoreMessages = convertToModelMessages;
1659
2142
 
1660
- // src/ui/should-resubmit-messages.ts
1661
- function shouldResubmitMessages({
1662
- originalMaxToolInvocationStep,
1663
- originalMessageCount,
1664
- maxSteps,
1665
- messages
1666
- }) {
1667
- var _a17;
1668
- const lastMessage = messages[messages.length - 1];
1669
- return (
1670
- // check if the feature is enabled:
1671
- maxSteps > 1 && // ensure there is a last message:
1672
- lastMessage != null && // ensure we actually have new steps (to prevent infinite loops in case of errors):
1673
- (messages.length > originalMessageCount || extractMaxToolInvocationStep(getToolInvocations(lastMessage)) !== originalMaxToolInvocationStep) && // check that next step is possible:
1674
- isAssistantMessageWithCompletedToolCalls(lastMessage) && // limit the number of automatic steps:
1675
- ((_a17 = extractMaxToolInvocationStep(getToolInvocations(lastMessage))) != null ? _a17 : 0) < maxSteps
1676
- );
1677
- }
1678
- function isAssistantMessageWithCompletedToolCalls(message) {
1679
- if (message.role !== "assistant") {
1680
- return false;
1681
- }
1682
- const lastStepStartIndex = message.parts.reduce((lastIndex, part, index) => {
1683
- return part.type === "step-start" ? index : lastIndex;
1684
- }, -1);
1685
- const lastStepToolInvocations = message.parts.slice(lastStepStartIndex + 1).filter((part) => part.type === "tool-invocation");
1686
- return lastStepToolInvocations.length > 0 && lastStepToolInvocations.every((part) => "result" in part.toolInvocation);
1687
- }
1688
-
1689
- // src/ui/update-tool-call-result.ts
1690
- function updateToolCallResult({
1691
- messages,
1692
- toolCallId,
1693
- toolResult: result
2143
+ // src/ui/default-chat-store.ts
2144
+ import {
2145
+ generateId as generateIdFunc2
2146
+ } from "@ai-sdk/provider-utils";
2147
+ function defaultChatStore({
2148
+ api,
2149
+ fetch: fetch2,
2150
+ streamProtocol = "ui-message",
2151
+ credentials,
2152
+ headers,
2153
+ body,
2154
+ prepareRequestBody,
2155
+ generateId: generateId3 = generateIdFunc2,
2156
+ messageMetadataSchema,
2157
+ maxSteps = 1,
2158
+ chats
1694
2159
  }) {
1695
- const lastMessage = messages[messages.length - 1];
1696
- const invocationPart = lastMessage.parts.find(
1697
- (part) => part.type === "tool-invocation" && part.toolInvocation.toolCallId === toolCallId
1698
- );
1699
- if (invocationPart == null) {
1700
- return;
1701
- }
1702
- invocationPart.toolInvocation = {
1703
- ...invocationPart.toolInvocation,
1704
- state: "result",
1705
- result
1706
- };
2160
+ return new ChatStore({
2161
+ transport: new DefaultChatTransport({
2162
+ api,
2163
+ fetch: fetch2,
2164
+ streamProtocol,
2165
+ credentials,
2166
+ headers,
2167
+ body,
2168
+ prepareRequestBody
2169
+ }),
2170
+ generateId: generateId3,
2171
+ messageMetadataSchema,
2172
+ maxSteps,
2173
+ chats
2174
+ });
1707
2175
  }
1708
2176
 
1709
2177
  // src/ui-message-stream/create-ui-message-stream.ts
@@ -6849,22 +7317,38 @@ var DefaultStreamTextResult = class {
6849
7317
  }
6850
7318
  })
6851
7319
  );
6852
- return onFinish == null ? baseStream : processUIMessageStream({
6853
- stream: baseStream,
7320
+ if (onFinish == null) {
7321
+ return baseStream;
7322
+ }
7323
+ const state = createStreamingUIMessageState({
6854
7324
  lastMessage,
6855
- newMessageId: messageId != null ? messageId : this.generateId(),
6856
- onFinish: ({ message }) => {
6857
- const isContinuation2 = message.id === (lastMessage == null ? void 0 : lastMessage.id);
6858
- onFinish({
6859
- isContinuation: isContinuation2,
6860
- responseMessage: message,
6861
- messages: [
6862
- ...isContinuation2 ? originalMessages.slice(0, -1) : originalMessages,
6863
- message
6864
- ]
6865
- });
6866
- }
7325
+ newMessageId: messageId != null ? messageId : this.generateId()
6867
7326
  });
7327
+ const runUpdateMessageJob = async (job) => {
7328
+ await job({ state, write: () => {
7329
+ } });
7330
+ };
7331
+ return processUIMessageStream({
7332
+ stream: baseStream,
7333
+ runUpdateMessageJob
7334
+ }).pipeThrough(
7335
+ new TransformStream({
7336
+ transform(chunk, controller) {
7337
+ controller.enqueue(chunk);
7338
+ },
7339
+ flush() {
7340
+ const isContinuation2 = state.message.id === (lastMessage == null ? void 0 : lastMessage.id);
7341
+ onFinish({
7342
+ isContinuation: isContinuation2,
7343
+ responseMessage: state.message,
7344
+ messages: [
7345
+ ...isContinuation2 ? originalMessages.slice(0, -1) : originalMessages,
7346
+ state.message
7347
+ ]
7348
+ });
7349
+ }
7350
+ })
7351
+ );
6868
7352
  }
6869
7353
  pipeUIMessageStreamToResponse(response, {
6870
7354
  newMessageId,
@@ -7944,6 +8428,8 @@ var DefaultTranscriptionResult = class {
7944
8428
  export {
7945
8429
  AISDKError16 as AISDKError,
7946
8430
  APICallError,
8431
+ ChatStore,
8432
+ DefaultChatTransport,
7947
8433
  DownloadError,
7948
8434
  EmptyResponseBodyError,
7949
8435
  InvalidArgumentError,
@@ -7991,6 +8477,7 @@ export {
7991
8477
  createUIMessageStream,
7992
8478
  createUIMessageStreamResponse,
7993
8479
  customProvider,
8480
+ defaultChatStore,
7994
8481
  defaultSettingsMiddleware,
7995
8482
  embed,
7996
8483
  embedMany,
@@ -8014,7 +8501,6 @@ export {
8014
8501
  parsePartialJson,
8015
8502
  pipeTextStreamToResponse,
8016
8503
  pipeUIMessageStreamToResponse,
8017
- processTextStream,
8018
8504
  shouldResubmitMessages,
8019
8505
  simulateReadableStream,
8020
8506
  simulateStreamingMiddleware,