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/CHANGELOG.md +11 -0
- package/dist/index.d.mts +688 -293
- package/dist/index.d.ts +688 -293
- package/dist/index.js +997 -513
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +949 -463
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
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
|
978
|
-
stream,
|
979
|
-
onUpdate,
|
980
|
-
onToolCall,
|
981
|
-
onFinish,
|
977
|
+
function createStreamingUIMessageState({
|
982
978
|
lastMessage,
|
983
|
-
newMessageId
|
984
|
-
|
985
|
-
}) {
|
979
|
+
newMessageId = "no-id"
|
980
|
+
} = {}) {
|
986
981
|
var _a17;
|
987
982
|
const isContinuation = (lastMessage == null ? void 0 : lastMessage.role) === "assistant";
|
988
|
-
|
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
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
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
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
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
|
-
|
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
|
-
|
1042
|
-
if (
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
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
|
-
|
1057
|
-
|
1058
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
1126
|
-
|
1127
|
-
|
1128
|
-
|
1129
|
-
|
1130
|
-
|
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
|
-
|
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
|
-
|
1136
|
-
|
1137
|
-
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
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
|
-
|
1151
|
-
|
1152
|
-
|
1153
|
-
|
1154
|
-
|
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
|
-
|
1174
|
-
|
1175
|
-
|
1176
|
-
|
1177
|
-
|
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
|
-
|
1180
|
-
|
1181
|
-
|
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
|
-
|
1184
|
-
|
1185
|
-
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1192
|
+
case "finish": {
|
1193
|
+
await updateMessageMetadata(value.metadata);
|
1194
|
+
if (value.metadata != null) {
|
1195
|
+
write();
|
1196
|
+
}
|
1197
|
+
break;
|
1189
1198
|
}
|
1190
|
-
|
1191
|
-
|
1192
|
-
|
1193
|
-
|
1194
|
-
|
1195
|
-
|
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
|
-
|
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/
|
1217
|
-
|
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
|
-
|
1242
|
-
|
1243
|
-
|
1244
|
-
|
1245
|
-
|
1246
|
-
|
1247
|
-
|
1248
|
-
|
1249
|
-
|
1250
|
-
|
1251
|
-
|
1252
|
-
|
1253
|
-
|
1254
|
-
|
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
|
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
|
-
|
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
|
-
|
1303
|
-
|
1304
|
-
|
1305
|
-
|
1306
|
-
|
1307
|
-
|
1308
|
-
|
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
|
-
|
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
|
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
|
-
|
1345
|
-
|
1346
|
-
messageMetadataSchema
|
1859
|
+
messageMetadataSchema: self.messageMetadataSchema,
|
1860
|
+
runUpdateMessageJob
|
1347
1861
|
}),
|
1348
1862
|
onError: (error) => {
|
1349
1863
|
throw error;
|
1350
1864
|
}
|
1351
1865
|
});
|
1352
|
-
|
1353
|
-
|
1354
|
-
|
1355
|
-
|
1356
|
-
|
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/
|
1362
|
-
|
1363
|
-
|
1364
|
-
|
1365
|
-
|
1366
|
-
|
1367
|
-
|
1368
|
-
|
1369
|
-
|
1370
|
-
|
1371
|
-
|
1372
|
-
|
1373
|
-
|
1374
|
-
|
1375
|
-
|
1376
|
-
|
1377
|
-
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1383
|
-
|
1384
|
-
|
1385
|
-
|
1386
|
-
|
1387
|
-
|
1388
|
-
|
1389
|
-
|
1390
|
-
|
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
|
-
|
1932
|
+
...this.headers,
|
1395
1933
|
...headers
|
1396
1934
|
},
|
1397
|
-
|
1398
|
-
|
1399
|
-
|
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/
|
1661
|
-
|
1662
|
-
|
1663
|
-
|
1664
|
-
|
1665
|
-
|
1666
|
-
|
1667
|
-
|
1668
|
-
|
1669
|
-
|
1670
|
-
|
1671
|
-
|
1672
|
-
|
1673
|
-
|
1674
|
-
|
1675
|
-
|
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
|
-
|
1696
|
-
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
1703
|
-
|
1704
|
-
|
1705
|
-
|
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
|
-
|
6853
|
-
|
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,
|