@dudousxd/nestjs-agent-react 0.17.0 → 0.18.0
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/README.md +43 -6
- package/dist/index.cjs +556 -213
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +134 -1
- package/dist/index.d.ts +134 -1
- package/dist/index.js +512 -175
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -42,6 +42,7 @@ __export(src_exports, {
|
|
|
42
42
|
MessageList: () => MessageList,
|
|
43
43
|
QuotaBlockedError: () => QuotaBlockedError,
|
|
44
44
|
SPEECH_LANGUAGES: () => SPEECH_LANGUAGES,
|
|
45
|
+
acceptsFile: () => acceptsFile,
|
|
45
46
|
applyCompletion: () => applyCompletion,
|
|
46
47
|
approvalCountdown: () => approvalCountdown,
|
|
47
48
|
backgroundRunsFromThread: () => backgroundRunsFromThread,
|
|
@@ -52,7 +53,10 @@ __export(src_exports, {
|
|
|
52
53
|
describeTimestamp: () => describeTimestamp,
|
|
53
54
|
describeToolCall: () => describeToolCall,
|
|
54
55
|
describeUsage: () => describeUsage,
|
|
56
|
+
dragHasFiles: () => dragHasFiles,
|
|
55
57
|
extractMessageText: () => extractMessageText,
|
|
58
|
+
fileKind: () => fileKind,
|
|
59
|
+
filesFromClipboard: () => filesFromClipboard,
|
|
56
60
|
fillTemplate: () => fillTemplate,
|
|
57
61
|
filterAutocompleteItems: () => filterAutocompleteItems,
|
|
58
62
|
findActiveTrigger: () => findActiveTrigger,
|
|
@@ -62,6 +66,7 @@ __export(src_exports, {
|
|
|
62
66
|
inferResultView: () => inferResultView,
|
|
63
67
|
isActionCall: () => isActionCall,
|
|
64
68
|
loadStoredSpeechLang: () => loadStoredSpeechLang,
|
|
69
|
+
messageFiles: () => messageFiles,
|
|
65
70
|
notifyThreads: () => notifyThreads,
|
|
66
71
|
onThreadsEvent: () => onThreadsEvent,
|
|
67
72
|
persistSpeechLang: () => persistSpeechLang,
|
|
@@ -77,6 +82,7 @@ __export(src_exports, {
|
|
|
77
82
|
useAgentChat: () => useAgentChat,
|
|
78
83
|
useAgents: () => useAgents,
|
|
79
84
|
useApprovalCountdown: () => useApprovalCountdown,
|
|
85
|
+
useAttachments: () => useAttachments,
|
|
80
86
|
useChatTranscript: () => useChatTranscript,
|
|
81
87
|
useComposerAutocomplete: () => useComposerAutocomplete,
|
|
82
88
|
useElapsed: () => useElapsed,
|
|
@@ -217,6 +223,9 @@ var AgentClient = class {
|
|
|
217
223
|
* what a caller then rides on `sendMessage({ text }, { body: { attachments: [...] } })`.
|
|
218
224
|
*/
|
|
219
225
|
async uploadAttachment(file, options = {}) {
|
|
226
|
+
if (options.onProgress !== void 0 && this.options.fetch === void 0 && typeof XMLHttpRequest !== "undefined") {
|
|
227
|
+
return this.uploadWithProgress(file, options);
|
|
228
|
+
}
|
|
220
229
|
const formData = new FormData();
|
|
221
230
|
formData.append("file", file);
|
|
222
231
|
const response = await this.fetchImpl()(`${this.baseUrl()}/agent/attachments`, {
|
|
@@ -231,7 +240,47 @@ var AgentClient = class {
|
|
|
231
240
|
signal: options.signal
|
|
232
241
|
} : {}
|
|
233
242
|
});
|
|
234
|
-
|
|
243
|
+
const attachment = await this.handleResponse(response, "POST", "/agent/attachments");
|
|
244
|
+
options.onProgress?.(1);
|
|
245
|
+
return attachment;
|
|
246
|
+
}
|
|
247
|
+
async uploadWithProgress(file, { signal, onProgress }) {
|
|
248
|
+
const headers = {
|
|
249
|
+
accept: "application/json",
|
|
250
|
+
...await this.resolveHeaders()
|
|
251
|
+
};
|
|
252
|
+
const url = `${this.baseUrl()}/agent/attachments`;
|
|
253
|
+
return new Promise((resolve, reject) => {
|
|
254
|
+
const xhr = new XMLHttpRequest();
|
|
255
|
+
xhr.open("POST", url);
|
|
256
|
+
for (const [name, value] of Object.entries(headers)) xhr.setRequestHeader(name, value);
|
|
257
|
+
xhr.withCredentials = this.options.credentials === "include";
|
|
258
|
+
xhr.upload.onprogress = (event) => {
|
|
259
|
+
if (event.lengthComputable && event.total > 0) onProgress?.(event.loaded / event.total);
|
|
260
|
+
};
|
|
261
|
+
xhr.onload = () => {
|
|
262
|
+
if (xhr.status < 200 || xhr.status >= 300) {
|
|
263
|
+
reject(new AgentHttpError(xhr.status, "POST", "/agent/attachments", xhr.statusText));
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
onProgress?.(1);
|
|
267
|
+
resolve(JSON.parse(xhr.responseText));
|
|
268
|
+
};
|
|
269
|
+
xhr.onerror = () => reject(new TypeError("Network error while uploading the attachment"));
|
|
270
|
+
xhr.onabort = () => reject(new DOMException("The upload was aborted", "AbortError"));
|
|
271
|
+
if (signal !== void 0) {
|
|
272
|
+
if (signal.aborted) {
|
|
273
|
+
reject(new DOMException("The upload was aborted", "AbortError"));
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
signal.addEventListener("abort", () => xhr.abort(), {
|
|
277
|
+
once: true
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
const formData = new FormData();
|
|
281
|
+
formData.append("file", file);
|
|
282
|
+
xhr.send(formData);
|
|
283
|
+
});
|
|
235
284
|
}
|
|
236
285
|
promoteThread(id) {
|
|
237
286
|
return this.request("POST", `/agent/threads/${encodeURIComponent(id)}/promote`);
|
|
@@ -1079,6 +1128,68 @@ function delay(ms, signal) {
|
|
|
1079
1128
|
}
|
|
1080
1129
|
__name(delay, "delay");
|
|
1081
1130
|
|
|
1131
|
+
// src/attachments/files.ts
|
|
1132
|
+
function fileKind(mediaType) {
|
|
1133
|
+
const type = mediaType.toLowerCase();
|
|
1134
|
+
if (type.startsWith("image/")) return "image";
|
|
1135
|
+
if (type === "application/pdf") return "pdf";
|
|
1136
|
+
if (type.startsWith("text/") || type === "application/json") return "text";
|
|
1137
|
+
if (type.startsWith("audio/")) return "audio";
|
|
1138
|
+
if (type.startsWith("video/")) return "video";
|
|
1139
|
+
return "other";
|
|
1140
|
+
}
|
|
1141
|
+
__name(fileKind, "fileKind");
|
|
1142
|
+
function messageFiles(message) {
|
|
1143
|
+
const files = [];
|
|
1144
|
+
for (const part of message.parts) {
|
|
1145
|
+
if (part.type !== "file") continue;
|
|
1146
|
+
const file = part;
|
|
1147
|
+
const filename = file.filename ?? null;
|
|
1148
|
+
const dot = filename?.lastIndexOf(".") ?? -1;
|
|
1149
|
+
const mediaId = file.providerMetadata?.agent?.mediaId;
|
|
1150
|
+
files.push({
|
|
1151
|
+
url: file.url,
|
|
1152
|
+
mediaType: file.mediaType,
|
|
1153
|
+
filename,
|
|
1154
|
+
kind: fileKind(file.mediaType),
|
|
1155
|
+
extension: filename !== null && dot > 0 ? filename.slice(dot + 1).toLowerCase() : null,
|
|
1156
|
+
mediaId: typeof mediaId === "string" ? mediaId : null
|
|
1157
|
+
});
|
|
1158
|
+
}
|
|
1159
|
+
return files;
|
|
1160
|
+
}
|
|
1161
|
+
__name(messageFiles, "messageFiles");
|
|
1162
|
+
function acceptsFile(accept, file) {
|
|
1163
|
+
const rules = (typeof accept === "string" ? accept.split(",") : accept ?? []).map((rule) => rule.trim().toLowerCase()).filter((rule) => rule.length > 0);
|
|
1164
|
+
if (rules.length === 0) return true;
|
|
1165
|
+
const type = file.type.toLowerCase();
|
|
1166
|
+
const name = file.name.toLowerCase();
|
|
1167
|
+
return rules.some((rule) => {
|
|
1168
|
+
if (rule.startsWith(".")) return name.endsWith(rule);
|
|
1169
|
+
if (rule.endsWith("/*")) return type.startsWith(rule.slice(0, -1));
|
|
1170
|
+
return type === rule;
|
|
1171
|
+
});
|
|
1172
|
+
}
|
|
1173
|
+
__name(acceptsFile, "acceptsFile");
|
|
1174
|
+
function filesFromClipboard(data) {
|
|
1175
|
+
if (!data) return [];
|
|
1176
|
+
const files = [];
|
|
1177
|
+
for (const item of Array.from(data.items ?? [])) {
|
|
1178
|
+
if (item.kind !== "file") continue;
|
|
1179
|
+
const file = item.getAsFile();
|
|
1180
|
+
if (file !== null) files.push(file);
|
|
1181
|
+
}
|
|
1182
|
+
return files.length > 0 ? files : Array.from(data.files ?? []);
|
|
1183
|
+
}
|
|
1184
|
+
__name(filesFromClipboard, "filesFromClipboard");
|
|
1185
|
+
function dragHasFiles(data) {
|
|
1186
|
+
return Array.from(data?.types ?? []).includes("Files");
|
|
1187
|
+
}
|
|
1188
|
+
__name(dragHasFiles, "dragHasFiles");
|
|
1189
|
+
|
|
1190
|
+
// src/attachments/use-attachments.ts
|
|
1191
|
+
var import_react2 = require("react");
|
|
1192
|
+
|
|
1082
1193
|
// src/backend.ts
|
|
1083
1194
|
var AgentBackendUnsupportedError = class extends Error {
|
|
1084
1195
|
static {
|
|
@@ -1099,19 +1210,239 @@ function requireBackendMethod(backend, name) {
|
|
|
1099
1210
|
}
|
|
1100
1211
|
__name(requireBackendMethod, "requireBackendMethod");
|
|
1101
1212
|
|
|
1213
|
+
// src/attachments/use-attachments.ts
|
|
1214
|
+
var DEFAULT_REJECTION = {
|
|
1215
|
+
type: /* @__PURE__ */ __name((file) => `${file.name} is not a supported file type`, "type"),
|
|
1216
|
+
size: /* @__PURE__ */ __name((file) => `${file.name} is too large`, "size"),
|
|
1217
|
+
count: /* @__PURE__ */ __name(() => "Too many files", "count")
|
|
1218
|
+
};
|
|
1219
|
+
var sequence = 0;
|
|
1220
|
+
function useAttachments(options) {
|
|
1221
|
+
const latest = (0, import_react2.useRef)(options);
|
|
1222
|
+
latest.current = options;
|
|
1223
|
+
const [items, setItems] = (0, import_react2.useState)([]);
|
|
1224
|
+
const itemsRef = (0, import_react2.useRef)(items);
|
|
1225
|
+
itemsRef.current = items;
|
|
1226
|
+
const controllers = (0, import_react2.useRef)(/* @__PURE__ */ new Map());
|
|
1227
|
+
const [dragDepth, setDragDepth] = (0, import_react2.useState)(0);
|
|
1228
|
+
const patch = (0, import_react2.useCallback)((id, change) => {
|
|
1229
|
+
setItems((current) => current.map((item) => item.id === id ? {
|
|
1230
|
+
...item,
|
|
1231
|
+
...change
|
|
1232
|
+
} : item));
|
|
1233
|
+
}, []);
|
|
1234
|
+
const start = (0, import_react2.useCallback)((item) => {
|
|
1235
|
+
const { upload, backend } = latest.current;
|
|
1236
|
+
const run = upload ?? (backend?.uploadAttachment !== void 0 ? backend.uploadAttachment.bind(backend) : void 0);
|
|
1237
|
+
if (run === void 0) {
|
|
1238
|
+
patch(item.id, {
|
|
1239
|
+
status: "error",
|
|
1240
|
+
error: new AgentBackendUnsupportedError("uploadAttachment").message
|
|
1241
|
+
});
|
|
1242
|
+
return;
|
|
1243
|
+
}
|
|
1244
|
+
const controller = new AbortController();
|
|
1245
|
+
controllers.current.set(item.id, controller);
|
|
1246
|
+
run(item.file, {
|
|
1247
|
+
signal: controller.signal,
|
|
1248
|
+
onProgress: /* @__PURE__ */ __name((fraction) => patch(item.id, {
|
|
1249
|
+
progress: Math.max(0, Math.min(1, fraction))
|
|
1250
|
+
}), "onProgress")
|
|
1251
|
+
}).then((attachment) => {
|
|
1252
|
+
if (controller.signal.aborted) return;
|
|
1253
|
+
controllers.current.delete(item.id);
|
|
1254
|
+
patch(item.id, {
|
|
1255
|
+
status: "ready",
|
|
1256
|
+
progress: 1,
|
|
1257
|
+
attachment
|
|
1258
|
+
});
|
|
1259
|
+
}, (error) => {
|
|
1260
|
+
if (controller.signal.aborted) return;
|
|
1261
|
+
controllers.current.delete(item.id);
|
|
1262
|
+
patch(item.id, {
|
|
1263
|
+
status: "error",
|
|
1264
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1265
|
+
});
|
|
1266
|
+
});
|
|
1267
|
+
}, [
|
|
1268
|
+
patch
|
|
1269
|
+
]);
|
|
1270
|
+
const add = (0, import_react2.useCallback)((files) => {
|
|
1271
|
+
if (files == null) return;
|
|
1272
|
+
const { accept: accept2, maxBytes, maxFiles, describeRejection } = latest.current;
|
|
1273
|
+
const describe = /* @__PURE__ */ __name((reason, file) => describeRejection?.(reason, file) ?? DEFAULT_REJECTION[reason](file), "describe");
|
|
1274
|
+
let room = maxFiles === void 0 ? Number.POSITIVE_INFINITY : maxFiles - itemsRef.current.filter((item) => item.status !== "rejected").length;
|
|
1275
|
+
const staged = [];
|
|
1276
|
+
for (const file of Array.from(files)) {
|
|
1277
|
+
sequence += 1;
|
|
1278
|
+
const base = {
|
|
1279
|
+
id: `att-${sequence}`,
|
|
1280
|
+
file,
|
|
1281
|
+
name: file.name,
|
|
1282
|
+
size: file.size,
|
|
1283
|
+
type: file.type,
|
|
1284
|
+
progress: 0
|
|
1285
|
+
};
|
|
1286
|
+
const reason = !acceptsFile(accept2, file) ? "type" : maxBytes !== void 0 && file.size > maxBytes ? "size" : room <= 0 ? "count" : void 0;
|
|
1287
|
+
if (reason !== void 0) {
|
|
1288
|
+
staged.push({
|
|
1289
|
+
...base,
|
|
1290
|
+
status: "rejected",
|
|
1291
|
+
error: describe(reason, file)
|
|
1292
|
+
});
|
|
1293
|
+
continue;
|
|
1294
|
+
}
|
|
1295
|
+
room -= 1;
|
|
1296
|
+
const previewUrl = file.type.startsWith("image/") && typeof URL.createObjectURL === "function" ? URL.createObjectURL(file) : void 0;
|
|
1297
|
+
staged.push({
|
|
1298
|
+
...base,
|
|
1299
|
+
status: "uploading",
|
|
1300
|
+
...previewUrl ? {
|
|
1301
|
+
previewUrl
|
|
1302
|
+
} : {}
|
|
1303
|
+
});
|
|
1304
|
+
}
|
|
1305
|
+
if (staged.length === 0) return;
|
|
1306
|
+
setItems((current) => [
|
|
1307
|
+
...current,
|
|
1308
|
+
...staged
|
|
1309
|
+
]);
|
|
1310
|
+
for (const item of staged) {
|
|
1311
|
+
if (item.status === "uploading") start(item);
|
|
1312
|
+
}
|
|
1313
|
+
}, [
|
|
1314
|
+
start
|
|
1315
|
+
]);
|
|
1316
|
+
const release = (0, import_react2.useCallback)((item) => {
|
|
1317
|
+
if (item === void 0) return;
|
|
1318
|
+
controllers.current.get(item.id)?.abort();
|
|
1319
|
+
controllers.current.delete(item.id);
|
|
1320
|
+
if (item.previewUrl !== void 0 && typeof URL.revokeObjectURL === "function") {
|
|
1321
|
+
URL.revokeObjectURL(item.previewUrl);
|
|
1322
|
+
}
|
|
1323
|
+
}, []);
|
|
1324
|
+
const remove = (0, import_react2.useCallback)((id) => {
|
|
1325
|
+
release(itemsRef.current.find((item) => item.id === id));
|
|
1326
|
+
setItems((current) => current.filter((item) => item.id !== id));
|
|
1327
|
+
}, [
|
|
1328
|
+
release
|
|
1329
|
+
]);
|
|
1330
|
+
const clear = (0, import_react2.useCallback)(() => {
|
|
1331
|
+
for (const item of itemsRef.current) release(item);
|
|
1332
|
+
setItems([]);
|
|
1333
|
+
}, [
|
|
1334
|
+
release
|
|
1335
|
+
]);
|
|
1336
|
+
const retry = (0, import_react2.useCallback)((id) => {
|
|
1337
|
+
const item = itemsRef.current.find((candidate) => candidate.id === id);
|
|
1338
|
+
if (item === void 0 || item.status !== "error") return;
|
|
1339
|
+
const { error: _previous, ...rest } = item;
|
|
1340
|
+
const again = {
|
|
1341
|
+
...rest,
|
|
1342
|
+
status: "uploading",
|
|
1343
|
+
progress: 0
|
|
1344
|
+
};
|
|
1345
|
+
setItems((current) => current.map((candidate) => candidate.id === id ? again : candidate));
|
|
1346
|
+
start(again);
|
|
1347
|
+
}, [
|
|
1348
|
+
start
|
|
1349
|
+
]);
|
|
1350
|
+
(0, import_react2.useEffect)(() => () => {
|
|
1351
|
+
for (const item of itemsRef.current) release(item);
|
|
1352
|
+
}, [
|
|
1353
|
+
release
|
|
1354
|
+
]);
|
|
1355
|
+
const onPaste = (0, import_react2.useCallback)((event) => {
|
|
1356
|
+
const files = filesFromClipboard(event.clipboardData);
|
|
1357
|
+
if (files.length === 0) return;
|
|
1358
|
+
event.preventDefault();
|
|
1359
|
+
add(files);
|
|
1360
|
+
}, [
|
|
1361
|
+
add
|
|
1362
|
+
]);
|
|
1363
|
+
const dropZoneProps = (0, import_react2.useMemo)(() => ({
|
|
1364
|
+
onDragEnter: /* @__PURE__ */ __name((event) => {
|
|
1365
|
+
if (!dragHasFiles(event.dataTransfer)) return;
|
|
1366
|
+
event.preventDefault();
|
|
1367
|
+
setDragDepth((depth) => depth + 1);
|
|
1368
|
+
}, "onDragEnter"),
|
|
1369
|
+
onDragOver: /* @__PURE__ */ __name((event) => {
|
|
1370
|
+
if (dragHasFiles(event.dataTransfer)) event.preventDefault();
|
|
1371
|
+
}, "onDragOver"),
|
|
1372
|
+
onDragLeave: /* @__PURE__ */ __name((event) => {
|
|
1373
|
+
if (!dragHasFiles(event.dataTransfer)) return;
|
|
1374
|
+
setDragDepth((depth) => Math.max(0, depth - 1));
|
|
1375
|
+
}, "onDragLeave"),
|
|
1376
|
+
onDrop: /* @__PURE__ */ __name((event) => {
|
|
1377
|
+
if (!dragHasFiles(event.dataTransfer)) return;
|
|
1378
|
+
event.preventDefault();
|
|
1379
|
+
setDragDepth(0);
|
|
1380
|
+
add(event.dataTransfer?.files);
|
|
1381
|
+
}, "onDrop")
|
|
1382
|
+
}), [
|
|
1383
|
+
add
|
|
1384
|
+
]);
|
|
1385
|
+
const accept = options.accept;
|
|
1386
|
+
const inputProps = (0, import_react2.useMemo)(() => ({
|
|
1387
|
+
type: "file",
|
|
1388
|
+
accept: typeof accept === "string" ? accept : accept?.join(","),
|
|
1389
|
+
multiple: options.maxFiles === void 0 || options.maxFiles > 1,
|
|
1390
|
+
onChange: /* @__PURE__ */ __name((event) => {
|
|
1391
|
+
const input = event.currentTarget;
|
|
1392
|
+
add(input.files);
|
|
1393
|
+
input.value = "";
|
|
1394
|
+
}, "onChange")
|
|
1395
|
+
}), [
|
|
1396
|
+
accept,
|
|
1397
|
+
options.maxFiles,
|
|
1398
|
+
add
|
|
1399
|
+
]);
|
|
1400
|
+
return (0, import_react2.useMemo)(() => {
|
|
1401
|
+
const ready = items.filter((item) => item.status === "ready" && item.attachment !== void 0);
|
|
1402
|
+
const attachments = ready.map((item) => item.attachment);
|
|
1403
|
+
return {
|
|
1404
|
+
items,
|
|
1405
|
+
add,
|
|
1406
|
+
remove,
|
|
1407
|
+
retry,
|
|
1408
|
+
clear,
|
|
1409
|
+
isUploading: items.some((item) => item.status === "uploading"),
|
|
1410
|
+
attachments,
|
|
1411
|
+
refs: attachments.map((attachment) => ({
|
|
1412
|
+
mediaId: attachment.mediaId
|
|
1413
|
+
})),
|
|
1414
|
+
inputProps,
|
|
1415
|
+
dropZoneProps,
|
|
1416
|
+
isDragging: dragDepth > 0,
|
|
1417
|
+
onPaste
|
|
1418
|
+
};
|
|
1419
|
+
}, [
|
|
1420
|
+
items,
|
|
1421
|
+
add,
|
|
1422
|
+
remove,
|
|
1423
|
+
retry,
|
|
1424
|
+
clear,
|
|
1425
|
+
inputProps,
|
|
1426
|
+
dropZoneProps,
|
|
1427
|
+
dragDepth,
|
|
1428
|
+
onPaste
|
|
1429
|
+
]);
|
|
1430
|
+
}
|
|
1431
|
+
__name(useAttachments, "useAttachments");
|
|
1432
|
+
|
|
1102
1433
|
// src/catalog/use-agents.ts
|
|
1103
|
-
var
|
|
1434
|
+
var import_react4 = require("react");
|
|
1104
1435
|
|
|
1105
1436
|
// src/catalog/use-resource.ts
|
|
1106
|
-
var
|
|
1437
|
+
var import_react3 = require("react");
|
|
1107
1438
|
function useResource(load2, key, enabled) {
|
|
1108
|
-
const [data, setData] = (0,
|
|
1109
|
-
const [isLoading, setIsLoading] = (0,
|
|
1110
|
-
const [error, setError] = (0,
|
|
1111
|
-
const loadRef = (0,
|
|
1439
|
+
const [data, setData] = (0, import_react3.useState)(void 0);
|
|
1440
|
+
const [isLoading, setIsLoading] = (0, import_react3.useState)(enabled);
|
|
1441
|
+
const [error, setError] = (0, import_react3.useState)(null);
|
|
1442
|
+
const loadRef = (0, import_react3.useRef)(load2);
|
|
1112
1443
|
loadRef.current = load2;
|
|
1113
|
-
const generation = (0,
|
|
1114
|
-
const refresh = (0,
|
|
1444
|
+
const generation = (0, import_react3.useRef)(0);
|
|
1445
|
+
const refresh = (0, import_react3.useCallback)(async () => {
|
|
1115
1446
|
const mine = ++generation.current;
|
|
1116
1447
|
setIsLoading(true);
|
|
1117
1448
|
try {
|
|
@@ -1126,7 +1457,7 @@ function useResource(load2, key, enabled) {
|
|
|
1126
1457
|
if (mine === generation.current) setIsLoading(false);
|
|
1127
1458
|
}
|
|
1128
1459
|
}, []);
|
|
1129
|
-
(0,
|
|
1460
|
+
(0, import_react3.useEffect)(() => {
|
|
1130
1461
|
if (!enabled) return;
|
|
1131
1462
|
void refresh();
|
|
1132
1463
|
}, [
|
|
@@ -1147,7 +1478,7 @@ __name(useResource, "useResource");
|
|
|
1147
1478
|
function useAgents(options) {
|
|
1148
1479
|
const { backend, enabled = true } = options;
|
|
1149
1480
|
const { data, isLoading, error, refresh } = useResource(() => requireBackendMethod(backend, "listAgents")(), "", enabled);
|
|
1150
|
-
return (0,
|
|
1481
|
+
return (0, import_react4.useMemo)(() => {
|
|
1151
1482
|
const agents = data ?? [];
|
|
1152
1483
|
return {
|
|
1153
1484
|
agents,
|
|
@@ -1166,11 +1497,11 @@ function useAgents(options) {
|
|
|
1166
1497
|
__name(useAgents, "useAgents");
|
|
1167
1498
|
|
|
1168
1499
|
// src/catalog/use-models.ts
|
|
1169
|
-
var
|
|
1500
|
+
var import_react5 = require("react");
|
|
1170
1501
|
function useModels(options) {
|
|
1171
1502
|
const { backend, agent, enabled = true } = options;
|
|
1172
1503
|
const { data, isLoading, error, refresh } = useResource(() => requireBackendMethod(backend, "listModels")(agent), `${agent ?? ""}`, enabled);
|
|
1173
|
-
return (0,
|
|
1504
|
+
return (0, import_react5.useMemo)(() => {
|
|
1174
1505
|
const providers = data?.providers ?? [];
|
|
1175
1506
|
const models = providers.flatMap((provider) => provider.models.map((model) => ({
|
|
1176
1507
|
...model,
|
|
@@ -1200,7 +1531,7 @@ function useModels(options) {
|
|
|
1200
1531
|
__name(useModels, "useModels");
|
|
1201
1532
|
|
|
1202
1533
|
// src/quota/use-quota.ts
|
|
1203
|
-
var
|
|
1534
|
+
var import_react6 = require("react");
|
|
1204
1535
|
|
|
1205
1536
|
// src/threads/threads-events.ts
|
|
1206
1537
|
var listeners = /* @__PURE__ */ new WeakMap();
|
|
@@ -1227,7 +1558,7 @@ __name(onThreadsEvent, "onThreadsEvent");
|
|
|
1227
1558
|
function useQuota(options) {
|
|
1228
1559
|
const { backend, enabled = true, pollMs } = options;
|
|
1229
1560
|
const { data, isLoading, error, refresh } = useResource(() => requireBackendMethod(backend, "getQuota")(), "", enabled);
|
|
1230
|
-
(0,
|
|
1561
|
+
(0, import_react6.useEffect)(() => {
|
|
1231
1562
|
if (!enabled) return;
|
|
1232
1563
|
return onThreadsEvent(backend, (event) => {
|
|
1233
1564
|
if (event.type === "changed") void refresh();
|
|
@@ -1237,7 +1568,7 @@ function useQuota(options) {
|
|
|
1237
1568
|
enabled,
|
|
1238
1569
|
refresh
|
|
1239
1570
|
]);
|
|
1240
|
-
(0,
|
|
1571
|
+
(0, import_react6.useEffect)(() => {
|
|
1241
1572
|
if (!enabled || pollMs === void 0 || pollMs <= 0) return;
|
|
1242
1573
|
const timer = setInterval(() => void refresh(), pollMs);
|
|
1243
1574
|
return () => clearInterval(timer);
|
|
@@ -1246,7 +1577,7 @@ function useQuota(options) {
|
|
|
1246
1577
|
pollMs,
|
|
1247
1578
|
refresh
|
|
1248
1579
|
]);
|
|
1249
|
-
return (0,
|
|
1580
|
+
return (0, import_react6.useMemo)(() => {
|
|
1250
1581
|
const windows = data?.windows ?? [];
|
|
1251
1582
|
return {
|
|
1252
1583
|
report: data,
|
|
@@ -1268,27 +1599,27 @@ function useQuota(options) {
|
|
|
1268
1599
|
__name(useQuota, "useQuota");
|
|
1269
1600
|
|
|
1270
1601
|
// src/feedback/use-message-feedback.ts
|
|
1271
|
-
var
|
|
1602
|
+
var import_react7 = require("react");
|
|
1272
1603
|
function useMessageFeedback(options) {
|
|
1273
|
-
const latest = (0,
|
|
1604
|
+
const latest = (0, import_react7.useRef)(options);
|
|
1274
1605
|
latest.current = options;
|
|
1275
|
-
const [local, setLocal] = (0,
|
|
1276
|
-
const [pending, setPending] = (0,
|
|
1277
|
-
const [error, setError] = (0,
|
|
1278
|
-
const localRef = (0,
|
|
1606
|
+
const [local, setLocal] = (0, import_react7.useState)(/* @__PURE__ */ new Map());
|
|
1607
|
+
const [pending, setPending] = (0, import_react7.useState)(/* @__PURE__ */ new Set());
|
|
1608
|
+
const [error, setError] = (0, import_react7.useState)(null);
|
|
1609
|
+
const localRef = (0, import_react7.useRef)(local);
|
|
1279
1610
|
localRef.current = local;
|
|
1280
|
-
const resolved = (0,
|
|
1281
|
-
const feedbackOf = (0,
|
|
1611
|
+
const resolved = (0, import_react7.useRef)(/* @__PURE__ */ new Map());
|
|
1612
|
+
const feedbackOf = (0, import_react7.useCallback)((message) => {
|
|
1282
1613
|
const mine = local.get(message.id);
|
|
1283
1614
|
if (mine !== void 0) return mine.feedback;
|
|
1284
1615
|
return metadataOf(message).feedback ?? null;
|
|
1285
1616
|
}, [
|
|
1286
1617
|
local
|
|
1287
1618
|
]);
|
|
1288
|
-
const isPending = (0,
|
|
1619
|
+
const isPending = (0, import_react7.useCallback)((message) => pending.has(message.id), [
|
|
1289
1620
|
pending
|
|
1290
1621
|
]);
|
|
1291
|
-
const storedIdFor = (0,
|
|
1622
|
+
const storedIdFor = (0, import_react7.useCallback)(async (message) => {
|
|
1292
1623
|
const runId = metadataOf(message).runId;
|
|
1293
1624
|
if (runId === void 0) return message.id;
|
|
1294
1625
|
const known = resolved.current.get(message.id);
|
|
@@ -1308,7 +1639,7 @@ function useMessageFeedback(options) {
|
|
|
1308
1639
|
resolved.current.set(message.id, row.id);
|
|
1309
1640
|
return row.id;
|
|
1310
1641
|
}, []);
|
|
1311
|
-
const rate = (0,
|
|
1642
|
+
const rate = (0, import_react7.useCallback)(async (message, value, comment) => {
|
|
1312
1643
|
const setFeedback = requireBackendMethod(latest.current.backend, "setMessageFeedback");
|
|
1313
1644
|
const had = localRef.current.get(message.id);
|
|
1314
1645
|
const optimistic = value === null ? null : {
|
|
@@ -1354,7 +1685,7 @@ function useMessageFeedback(options) {
|
|
|
1354
1685
|
}, [
|
|
1355
1686
|
storedIdFor
|
|
1356
1687
|
]);
|
|
1357
|
-
const toggle = (0,
|
|
1688
|
+
const toggle = (0, import_react7.useCallback)((message, value) => {
|
|
1358
1689
|
const mine = localRef.current.get(message.id);
|
|
1359
1690
|
const current = mine !== void 0 ? mine.feedback : metadataOf(message).feedback ?? null;
|
|
1360
1691
|
return rate(message, current?.value === value ? null : value);
|
|
@@ -1377,16 +1708,16 @@ function metadataOf(message) {
|
|
|
1377
1708
|
__name(metadataOf, "metadataOf");
|
|
1378
1709
|
|
|
1379
1710
|
// src/threads/use-threads.ts
|
|
1380
|
-
var
|
|
1711
|
+
var import_react8 = require("react");
|
|
1381
1712
|
function useThreads(options) {
|
|
1382
1713
|
const { backend, enabled = true } = options;
|
|
1383
|
-
const [threads, setThreads] = (0,
|
|
1384
|
-
const [isLoading, setIsLoading] = (0,
|
|
1385
|
-
const [error, setError] = (0,
|
|
1386
|
-
const threadsRef = (0,
|
|
1714
|
+
const [threads, setThreads] = (0, import_react8.useState)([]);
|
|
1715
|
+
const [isLoading, setIsLoading] = (0, import_react8.useState)(enabled);
|
|
1716
|
+
const [error, setError] = (0, import_react8.useState)(null);
|
|
1717
|
+
const threadsRef = (0, import_react8.useRef)(threads);
|
|
1387
1718
|
threadsRef.current = threads;
|
|
1388
|
-
const generation = (0,
|
|
1389
|
-
const refresh = (0,
|
|
1719
|
+
const generation = (0, import_react8.useRef)(0);
|
|
1720
|
+
const refresh = (0, import_react8.useCallback)(async () => {
|
|
1390
1721
|
const mine = ++generation.current;
|
|
1391
1722
|
setIsLoading(true);
|
|
1392
1723
|
try {
|
|
@@ -1403,7 +1734,7 @@ function useThreads(options) {
|
|
|
1403
1734
|
}, [
|
|
1404
1735
|
backend
|
|
1405
1736
|
]);
|
|
1406
|
-
(0,
|
|
1737
|
+
(0, import_react8.useEffect)(() => {
|
|
1407
1738
|
if (!enabled) return;
|
|
1408
1739
|
void refresh();
|
|
1409
1740
|
return onThreadsEvent(backend, (event) => {
|
|
@@ -1423,7 +1754,7 @@ function useThreads(options) {
|
|
|
1423
1754
|
enabled,
|
|
1424
1755
|
refresh
|
|
1425
1756
|
]);
|
|
1426
|
-
const rename = (0,
|
|
1757
|
+
const rename = (0, import_react8.useCallback)(async (id, title) => {
|
|
1427
1758
|
const before = threadsRef.current;
|
|
1428
1759
|
setThreads((current) => current.map((thread) => thread.id === id ? {
|
|
1429
1760
|
...thread,
|
|
@@ -1445,7 +1776,7 @@ function useThreads(options) {
|
|
|
1445
1776
|
}, [
|
|
1446
1777
|
backend
|
|
1447
1778
|
]);
|
|
1448
|
-
const remove = (0,
|
|
1779
|
+
const remove = (0, import_react8.useCallback)(async (id) => {
|
|
1449
1780
|
const before = threadsRef.current;
|
|
1450
1781
|
setThreads((current) => current.filter((thread) => thread.id !== id));
|
|
1451
1782
|
try {
|
|
@@ -1520,10 +1851,10 @@ function backgroundRunsFromThread(messages) {
|
|
|
1520
1851
|
__name(backgroundRunsFromThread, "backgroundRunsFromThread");
|
|
1521
1852
|
|
|
1522
1853
|
// src/components/chat-input.tsx
|
|
1523
|
-
var
|
|
1854
|
+
var import_react10 = __toESM(require("react"), 1);
|
|
1524
1855
|
|
|
1525
1856
|
// src/components/use-speech-recognition.ts
|
|
1526
|
-
var
|
|
1857
|
+
var import_react9 = require("react");
|
|
1527
1858
|
function getRecognitionCtor() {
|
|
1528
1859
|
if (typeof window === "undefined") return null;
|
|
1529
1860
|
const scope = window;
|
|
@@ -1531,15 +1862,15 @@ function getRecognitionCtor() {
|
|
|
1531
1862
|
}
|
|
1532
1863
|
__name(getRecognitionCtor, "getRecognitionCtor");
|
|
1533
1864
|
function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTranscript }) {
|
|
1534
|
-
const recognitionRef = (0,
|
|
1535
|
-
const [isListening, setIsListening] = (0,
|
|
1536
|
-
const ctor = (0,
|
|
1865
|
+
const recognitionRef = (0, import_react9.useRef)(null);
|
|
1866
|
+
const [isListening, setIsListening] = (0, import_react9.useState)(false);
|
|
1867
|
+
const ctor = (0, import_react9.useMemo)(() => getRecognitionCtor(), []);
|
|
1537
1868
|
const isSupported = ctor !== null;
|
|
1538
|
-
const finalRef = (0,
|
|
1539
|
-
const interimRef = (0,
|
|
1869
|
+
const finalRef = (0, import_react9.useRef)(onFinalTranscript);
|
|
1870
|
+
const interimRef = (0, import_react9.useRef)(onInterimTranscript);
|
|
1540
1871
|
finalRef.current = onFinalTranscript;
|
|
1541
1872
|
interimRef.current = onInterimTranscript;
|
|
1542
|
-
(0,
|
|
1873
|
+
(0, import_react9.useEffect)(() => {
|
|
1543
1874
|
if (!ctor) return;
|
|
1544
1875
|
const recognition = new ctor();
|
|
1545
1876
|
recognition.lang = lang;
|
|
@@ -1578,7 +1909,7 @@ function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTran
|
|
|
1578
1909
|
ctor,
|
|
1579
1910
|
lang
|
|
1580
1911
|
]);
|
|
1581
|
-
const start = (0,
|
|
1912
|
+
const start = (0, import_react9.useCallback)(() => {
|
|
1582
1913
|
const recognition = recognitionRef.current;
|
|
1583
1914
|
if (!recognition) return;
|
|
1584
1915
|
try {
|
|
@@ -1588,7 +1919,7 @@ function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTran
|
|
|
1588
1919
|
console.warn("SpeechRecognition start failed", error);
|
|
1589
1920
|
}
|
|
1590
1921
|
}, []);
|
|
1591
|
-
const stop = (0,
|
|
1922
|
+
const stop = (0, import_react9.useCallback)(() => {
|
|
1592
1923
|
const recognition = recognitionRef.current;
|
|
1593
1924
|
if (!recognition) return;
|
|
1594
1925
|
try {
|
|
@@ -1607,8 +1938,8 @@ __name(useSpeechRecognition, "useSpeechRecognition");
|
|
|
1607
1938
|
|
|
1608
1939
|
// src/components/chat-input.tsx
|
|
1609
1940
|
function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = true, speechLang = "en-US", sendLabel = "Send", onStop, isStreaming = false, stopLabel = "Stop generating", className, textareaClassName, sendButtonClassName, micButtonClassName, stopButtonClassName, renderMic }) {
|
|
1610
|
-
const [value, setValue] = (0,
|
|
1611
|
-
const [interim, setInterim] = (0,
|
|
1941
|
+
const [value, setValue] = (0, import_react10.useState)("");
|
|
1942
|
+
const [interim, setInterim] = (0, import_react10.useState)("");
|
|
1612
1943
|
const speech = useSpeechRecognition({
|
|
1613
1944
|
lang: speechLang,
|
|
1614
1945
|
onFinalTranscript: /* @__PURE__ */ __name((text) => {
|
|
@@ -1619,7 +1950,7 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
|
|
|
1619
1950
|
}, "onFinalTranscript"),
|
|
1620
1951
|
onInterimTranscript: /* @__PURE__ */ __name((text) => setInterim(text), "onInterimTranscript")
|
|
1621
1952
|
});
|
|
1622
|
-
(0,
|
|
1953
|
+
(0, import_react10.useEffect)(() => {
|
|
1623
1954
|
if (!speech.isListening) setInterim("");
|
|
1624
1955
|
}, [
|
|
1625
1956
|
speech.isListening
|
|
@@ -1647,9 +1978,9 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
|
|
|
1647
1978
|
const displayValue = speech.isListening && interim ? `${value}${value && !value.endsWith(" ") ? " " : ""}${interim}` : value;
|
|
1648
1979
|
const showMic = enableSpeech && speech.isSupported;
|
|
1649
1980
|
const showStop = isStreaming && onStop !== void 0;
|
|
1650
|
-
return /* @__PURE__ */
|
|
1981
|
+
return /* @__PURE__ */ import_react10.default.createElement("div", {
|
|
1651
1982
|
className
|
|
1652
|
-
}, /* @__PURE__ */
|
|
1983
|
+
}, /* @__PURE__ */ import_react10.default.createElement("textarea", {
|
|
1653
1984
|
className: textareaClassName,
|
|
1654
1985
|
rows,
|
|
1655
1986
|
value: displayValue,
|
|
@@ -1660,17 +1991,17 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
|
|
|
1660
1991
|
}, "onChange"),
|
|
1661
1992
|
onKeyDown: handleKeyDown,
|
|
1662
1993
|
placeholder: placeholder ?? "Ask something (Enter to send, Shift+Enter for newline)"
|
|
1663
|
-
}), /* @__PURE__ */
|
|
1994
|
+
}), /* @__PURE__ */ import_react10.default.createElement("button", {
|
|
1664
1995
|
type: "button",
|
|
1665
1996
|
className: sendButtonClassName,
|
|
1666
1997
|
onClick: submit,
|
|
1667
1998
|
disabled: disabled || !value.trim()
|
|
1668
|
-
}, sendLabel), showStop ? /* @__PURE__ */
|
|
1999
|
+
}, sendLabel), showStop ? /* @__PURE__ */ import_react10.default.createElement("button", {
|
|
1669
2000
|
type: "button",
|
|
1670
2001
|
className: stopButtonClassName,
|
|
1671
2002
|
onClick: /* @__PURE__ */ __name(() => void onStop(), "onClick"),
|
|
1672
2003
|
"aria-label": "Stop generating"
|
|
1673
|
-
}, stopLabel) : null, showMic ? /* @__PURE__ */
|
|
2004
|
+
}, stopLabel) : null, showMic ? /* @__PURE__ */ import_react10.default.createElement("button", {
|
|
1674
2005
|
type: "button",
|
|
1675
2006
|
className: micButtonClassName,
|
|
1676
2007
|
onClick: toggleMic,
|
|
@@ -1683,10 +2014,10 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
|
|
|
1683
2014
|
__name(ChatInput, "ChatInput");
|
|
1684
2015
|
|
|
1685
2016
|
// src/components/message-item.tsx
|
|
1686
|
-
var
|
|
2017
|
+
var import_react13 = __toESM(require("react"), 1);
|
|
1687
2018
|
|
|
1688
2019
|
// src/transcript/use-chat-transcript.ts
|
|
1689
|
-
var
|
|
2020
|
+
var import_react12 = require("react");
|
|
1690
2021
|
|
|
1691
2022
|
// src/transcript/model.ts
|
|
1692
2023
|
var import_nestjs_agent_core2 = require("@dudousxd/nestjs-agent-core");
|
|
@@ -2663,11 +2994,11 @@ function formatCostUsd(cost) {
|
|
|
2663
2994
|
__name(formatCostUsd, "formatCostUsd");
|
|
2664
2995
|
|
|
2665
2996
|
// src/transcript/use-stick-to-bottom.ts
|
|
2666
|
-
var
|
|
2997
|
+
var import_react11 = require("react");
|
|
2667
2998
|
function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
2668
|
-
const containerRef = (0,
|
|
2669
|
-
const [isAtBottom, setIsAtBottom] = (0,
|
|
2670
|
-
const measure = (0,
|
|
2999
|
+
const containerRef = (0, import_react11.useRef)(null);
|
|
3000
|
+
const [isAtBottom, setIsAtBottom] = (0, import_react11.useState)(true);
|
|
3001
|
+
const measure = (0, import_react11.useCallback)(() => {
|
|
2671
3002
|
const element = containerRef.current;
|
|
2672
3003
|
if (!element) {
|
|
2673
3004
|
return;
|
|
@@ -2677,7 +3008,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
|
2677
3008
|
}, [
|
|
2678
3009
|
threshold
|
|
2679
3010
|
]);
|
|
2680
|
-
const scrollToBottom = (0,
|
|
3011
|
+
const scrollToBottom = (0, import_react11.useCallback)(() => {
|
|
2681
3012
|
const element = containerRef.current;
|
|
2682
3013
|
if (!element) {
|
|
2683
3014
|
return;
|
|
@@ -2685,7 +3016,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
|
2685
3016
|
element.scrollTop = element.scrollHeight;
|
|
2686
3017
|
setIsAtBottom(true);
|
|
2687
3018
|
}, []);
|
|
2688
|
-
const setContainer = (0,
|
|
3019
|
+
const setContainer = (0, import_react11.useCallback)((element) => {
|
|
2689
3020
|
containerRef.current = element;
|
|
2690
3021
|
if (element) {
|
|
2691
3022
|
measure();
|
|
@@ -2693,7 +3024,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
|
2693
3024
|
}, [
|
|
2694
3025
|
measure
|
|
2695
3026
|
]);
|
|
2696
|
-
(0,
|
|
3027
|
+
(0, import_react11.useEffect)(() => {
|
|
2697
3028
|
if (isAtBottom) {
|
|
2698
3029
|
scrollToBottom();
|
|
2699
3030
|
}
|
|
@@ -2702,7 +3033,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
|
2702
3033
|
isAtBottom,
|
|
2703
3034
|
scrollToBottom
|
|
2704
3035
|
]);
|
|
2705
|
-
const getContainerProps = (0,
|
|
3036
|
+
const getContainerProps = (0, import_react11.useCallback)(() => ({
|
|
2706
3037
|
ref: setContainer,
|
|
2707
3038
|
onScroll: measure
|
|
2708
3039
|
}), [
|
|
@@ -2724,14 +3055,14 @@ var DEFAULT_LOAD_EARLIER_STEP = 50;
|
|
|
2724
3055
|
var DEFAULT_COPY_RESET_MS = 1500;
|
|
2725
3056
|
function useChatTranscript(options) {
|
|
2726
3057
|
const { messages, status, initialVisibleCount = DEFAULT_VISIBLE_COUNT, loadEarlierStep = DEFAULT_LOAD_EARLIER_STEP, followUps, stickToBottomThreshold } = options;
|
|
2727
|
-
const latest = (0,
|
|
3058
|
+
const latest = (0, import_react12.useRef)(options);
|
|
2728
3059
|
latest.current = options;
|
|
2729
|
-
const [visibleCount, setVisibleCount] = (0,
|
|
2730
|
-
const [stopRequested, setStopRequested] = (0,
|
|
3060
|
+
const [visibleCount, setVisibleCount] = (0, import_react12.useState)(initialVisibleCount);
|
|
3061
|
+
const [stopRequested, setStopRequested] = (0, import_react12.useState)(false);
|
|
2731
3062
|
const isStreaming = status === "streaming" || status === "reconnecting";
|
|
2732
3063
|
const isBusy = status === "submitted" || isStreaming;
|
|
2733
3064
|
const isEmpty = messages.length === 0;
|
|
2734
|
-
(0,
|
|
3065
|
+
(0, import_react12.useEffect)(() => {
|
|
2735
3066
|
if (!isBusy) {
|
|
2736
3067
|
setStopRequested(false);
|
|
2737
3068
|
}
|
|
@@ -2748,7 +3079,7 @@ function useChatTranscript(options) {
|
|
|
2748
3079
|
streamingMessageId,
|
|
2749
3080
|
options
|
|
2750
3081
|
});
|
|
2751
|
-
const stop = (0,
|
|
3082
|
+
const stop = (0, import_react12.useCallback)(() => {
|
|
2752
3083
|
const current = latest.current;
|
|
2753
3084
|
if (current.status !== "submitted" && current.status !== "streaming" && current.status !== "reconnecting") {
|
|
2754
3085
|
return;
|
|
@@ -2756,8 +3087,8 @@ function useChatTranscript(options) {
|
|
|
2756
3087
|
setStopRequested(true);
|
|
2757
3088
|
void current.onStop?.();
|
|
2758
3089
|
}, []);
|
|
2759
|
-
const loadEarlier = (0,
|
|
2760
|
-
const showAll = (0,
|
|
3090
|
+
const loadEarlier = (0, import_react12.useCallback)(() => setVisibleCount((count) => count + (latest.current.loadEarlierStep ?? DEFAULT_LOAD_EARLIER_STEP)), []);
|
|
3091
|
+
const showAll = (0, import_react12.useCallback)(() => setVisibleCount(latest.current.messages.length), []);
|
|
2761
3092
|
const scroll = useStickToBottom({
|
|
2762
3093
|
contentKey: contentSignature(messages),
|
|
2763
3094
|
...stickToBottomThreshold !== void 0 ? {
|
|
@@ -2793,7 +3124,7 @@ function useChatTranscript(options) {
|
|
|
2793
3124
|
__name(useChatTranscript, "useChatTranscript");
|
|
2794
3125
|
function useTranscriptItem(options) {
|
|
2795
3126
|
const { message, isStreaming = false } = options;
|
|
2796
|
-
const messagesRef = (0,
|
|
3127
|
+
const messagesRef = (0, import_react12.useRef)([
|
|
2797
3128
|
message
|
|
2798
3129
|
]);
|
|
2799
3130
|
if (messagesRef.current[0] !== message) {
|
|
@@ -2811,13 +3142,13 @@ function useTranscriptItem(options) {
|
|
|
2811
3142
|
}
|
|
2812
3143
|
__name(useTranscriptItem, "useTranscriptItem");
|
|
2813
3144
|
function useTranscriptItems({ messages, visibleStart, streamingMessageId, options }) {
|
|
2814
|
-
const [drafts, setDrafts] = (0,
|
|
2815
|
-
const [copied, setCopied] = (0,
|
|
2816
|
-
const [openReasoning, setOpenReasoning] = (0,
|
|
2817
|
-
const [picks, setPicks] = (0,
|
|
2818
|
-
const [settling, setSettling] = (0,
|
|
2819
|
-
const [settleErrors, setSettleErrors] = (0,
|
|
2820
|
-
const latest = (0,
|
|
3145
|
+
const [drafts, setDrafts] = (0, import_react12.useState)(() => /* @__PURE__ */ new Map());
|
|
3146
|
+
const [copied, setCopied] = (0, import_react12.useState)(() => /* @__PURE__ */ new Set());
|
|
3147
|
+
const [openReasoning, setOpenReasoning] = (0, import_react12.useState)(() => /* @__PURE__ */ new Map());
|
|
3148
|
+
const [picks, setPicks] = (0, import_react12.useState)(() => /* @__PURE__ */ new Map());
|
|
3149
|
+
const [settling, setSettling] = (0, import_react12.useState)(() => /* @__PURE__ */ new Map());
|
|
3150
|
+
const [settleErrors, setSettleErrors] = (0, import_react12.useState)(() => /* @__PURE__ */ new Map());
|
|
3151
|
+
const latest = (0, import_react12.useRef)({
|
|
2821
3152
|
options,
|
|
2822
3153
|
drafts,
|
|
2823
3154
|
picks,
|
|
@@ -2829,23 +3160,23 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2829
3160
|
picks,
|
|
2830
3161
|
messages
|
|
2831
3162
|
};
|
|
2832
|
-
const copyTimers = (0,
|
|
2833
|
-
(0,
|
|
3163
|
+
const copyTimers = (0, import_react12.useRef)(/* @__PURE__ */ new Map());
|
|
3164
|
+
(0, import_react12.useEffect)(() => () => {
|
|
2834
3165
|
for (const timer of copyTimers.current.values()) {
|
|
2835
3166
|
clearTimeout(timer);
|
|
2836
3167
|
}
|
|
2837
3168
|
copyTimers.current.clear();
|
|
2838
3169
|
}, []);
|
|
2839
|
-
const callbackCache = (0,
|
|
2840
|
-
const reasoningToggleCache = (0,
|
|
2841
|
-
const toggleReasoning = (0,
|
|
3170
|
+
const callbackCache = (0, import_react12.useRef)(/* @__PURE__ */ new Map());
|
|
3171
|
+
const reasoningToggleCache = (0, import_react12.useRef)(/* @__PURE__ */ new Map());
|
|
3172
|
+
const toggleReasoning = (0, import_react12.useCallback)((key, open) => {
|
|
2842
3173
|
setOpenReasoning((current) => {
|
|
2843
3174
|
const next = new Map(current);
|
|
2844
3175
|
next.set(key, open ?? !(current.get(key) ?? false));
|
|
2845
3176
|
return next;
|
|
2846
3177
|
});
|
|
2847
3178
|
}, []);
|
|
2848
|
-
const stableToggle = (0,
|
|
3179
|
+
const stableToggle = (0, import_react12.useCallback)((key) => {
|
|
2849
3180
|
let cached = reasoningToggleCache.current.get(key);
|
|
2850
3181
|
if (!cached) {
|
|
2851
3182
|
cached = /* @__PURE__ */ __name((open) => toggleReasoning(key, open), "cached");
|
|
@@ -2855,10 +3186,10 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2855
3186
|
}, [
|
|
2856
3187
|
toggleReasoning
|
|
2857
3188
|
]);
|
|
2858
|
-
const pick = (0,
|
|
3189
|
+
const pick = (0, import_react12.useCallback)((toolCallId, questionId, values) => {
|
|
2859
3190
|
setPicks((current) => new Map(current).set(pickKey(toolCallId, questionId), values));
|
|
2860
3191
|
}, []);
|
|
2861
|
-
const settle = (0,
|
|
3192
|
+
const settle = (0, import_react12.useCallback)((toolCallId, action, send) => {
|
|
2862
3193
|
setSettleErrors((current) => {
|
|
2863
3194
|
if (!current.has(toolCallId)) {
|
|
2864
3195
|
return current;
|
|
@@ -2882,7 +3213,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2882
3213
|
failed(error);
|
|
2883
3214
|
}
|
|
2884
3215
|
}, []);
|
|
2885
|
-
const answer = (0,
|
|
3216
|
+
const answer = (0, import_react12.useCallback)((toolCallId) => {
|
|
2886
3217
|
const current = latest.current;
|
|
2887
3218
|
const onAnswer = current.options.onAnswer;
|
|
2888
3219
|
if (!onAnswer) {
|
|
@@ -2892,7 +3223,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2892
3223
|
}, [
|
|
2893
3224
|
settle
|
|
2894
3225
|
]);
|
|
2895
|
-
const skip = (0,
|
|
3226
|
+
const skip = (0, import_react12.useCallback)((toolCallId) => {
|
|
2896
3227
|
const onSkip = latest.current.options.onSkip;
|
|
2897
3228
|
if (onSkip) {
|
|
2898
3229
|
settle(toolCallId, "skip", () => onSkip(toolCallId));
|
|
@@ -2900,7 +3231,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2900
3231
|
}, [
|
|
2901
3232
|
settle
|
|
2902
3233
|
]);
|
|
2903
|
-
const approve = (0,
|
|
3234
|
+
const approve = (0, import_react12.useCallback)((toolCallId, options2) => {
|
|
2904
3235
|
const onApprove = latest.current.options.onApprove;
|
|
2905
3236
|
if (onApprove) {
|
|
2906
3237
|
settle(toolCallId, "approve", () => options2 === void 0 ? onApprove(toolCallId) : onApprove(toolCallId, options2));
|
|
@@ -2908,7 +3239,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2908
3239
|
}, [
|
|
2909
3240
|
settle
|
|
2910
3241
|
]);
|
|
2911
|
-
const reject = (0,
|
|
3242
|
+
const reject = (0, import_react12.useCallback)((toolCallId) => {
|
|
2912
3243
|
const onReject = latest.current.options.onReject;
|
|
2913
3244
|
if (onReject) {
|
|
2914
3245
|
settle(toolCallId, "reject", () => onReject(toolCallId));
|
|
@@ -2916,7 +3247,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2916
3247
|
}, [
|
|
2917
3248
|
settle
|
|
2918
3249
|
]);
|
|
2919
|
-
const callbacksFor = (0,
|
|
3250
|
+
const callbacksFor = (0, import_react12.useCallback)((id) => {
|
|
2920
3251
|
const cached = callbackCache.current.get(id);
|
|
2921
3252
|
if (cached) {
|
|
2922
3253
|
return cached;
|
|
@@ -3158,7 +3489,7 @@ function MessageItem({ message, isStreaming = false, editable, onEditSubmit, reg
|
|
|
3158
3489
|
getCreatedAt: /* @__PURE__ */ __name(() => createdAt, "getCreatedAt")
|
|
3159
3490
|
} : {}
|
|
3160
3491
|
});
|
|
3161
|
-
return /* @__PURE__ */
|
|
3492
|
+
return /* @__PURE__ */ import_react13.default.createElement(MessageItemView, {
|
|
3162
3493
|
item,
|
|
3163
3494
|
...slots
|
|
3164
3495
|
});
|
|
@@ -3166,51 +3497,51 @@ function MessageItem({ message, isStreaming = false, editable, onEditSubmit, reg
|
|
|
3166
3497
|
__name(MessageItem, "MessageItem");
|
|
3167
3498
|
function MessageItemView({ item, ...slots }) {
|
|
3168
3499
|
const { classNames } = slots;
|
|
3169
|
-
const actionRow = /* @__PURE__ */
|
|
3500
|
+
const actionRow = /* @__PURE__ */ import_react13.default.createElement("div", {
|
|
3170
3501
|
className: classNames?.actions,
|
|
3171
3502
|
"data-actions-for": item.role
|
|
3172
|
-
}, item.copy.available ? /* @__PURE__ */
|
|
3503
|
+
}, item.copy.available ? /* @__PURE__ */ import_react13.default.createElement("button", {
|
|
3173
3504
|
type: "button",
|
|
3174
3505
|
onClick: item.copy.copy,
|
|
3175
3506
|
className: classNames?.actionButton,
|
|
3176
3507
|
title: item.copy.copied ? "Copied!" : "Copy message text"
|
|
3177
|
-
}, item.copy.copied ? "Copied" : "Copy") : null, item.fork.available ? /* @__PURE__ */
|
|
3508
|
+
}, item.copy.copied ? "Copied" : "Copy") : null, item.fork.available ? /* @__PURE__ */ import_react13.default.createElement("button", {
|
|
3178
3509
|
type: "button",
|
|
3179
3510
|
onClick: item.fork.run,
|
|
3180
3511
|
className: classNames?.actionButton,
|
|
3181
3512
|
title: "Fork thread from this message"
|
|
3182
|
-
}, "Fork") : null, item.regenerate.available ? /* @__PURE__ */
|
|
3513
|
+
}, "Fork") : null, item.regenerate.available ? /* @__PURE__ */ import_react13.default.createElement("button", {
|
|
3183
3514
|
type: "button",
|
|
3184
3515
|
onClick: item.regenerate.run,
|
|
3185
3516
|
className: classNames?.actionButton,
|
|
3186
3517
|
title: "Regenerate response"
|
|
3187
|
-
}, "Regenerate") : null, slots.meta, !item.isUser && item.usage ? /* @__PURE__ */
|
|
3518
|
+
}, "Regenerate") : null, slots.meta, !item.isUser && item.usage ? /* @__PURE__ */ import_react13.default.createElement("span", {
|
|
3188
3519
|
className: classNames?.usage,
|
|
3189
3520
|
title: `Input ${item.usage.inputTokens.toLocaleString()} \xB7 Output ${item.usage.outputTokens.toLocaleString()} tokens`
|
|
3190
|
-
}, item.usage.costLabel, " \xB7 ", item.usage.tokensLabel) : null, item.timestamp ? /* @__PURE__ */
|
|
3521
|
+
}, item.usage.costLabel, " \xB7 ", item.usage.tokensLabel) : null, item.timestamp ? /* @__PURE__ */ import_react13.default.createElement("span", {
|
|
3191
3522
|
className: classNames?.timestamp,
|
|
3192
3523
|
title: item.timestamp.absolute
|
|
3193
3524
|
}, item.timestamp.relative) : null);
|
|
3194
3525
|
if (item.edit.available) {
|
|
3195
|
-
return /* @__PURE__ */
|
|
3526
|
+
return /* @__PURE__ */ import_react13.default.createElement(EditableUserBubble, {
|
|
3196
3527
|
item,
|
|
3197
3528
|
slots,
|
|
3198
3529
|
actions: actionRow
|
|
3199
3530
|
});
|
|
3200
3531
|
}
|
|
3201
3532
|
const className = joinClasses(classNames?.root, classNames?.byRole?.[item.role]);
|
|
3202
|
-
return /* @__PURE__ */
|
|
3533
|
+
return /* @__PURE__ */ import_react13.default.createElement("div", {
|
|
3203
3534
|
className,
|
|
3204
3535
|
"data-role": item.role,
|
|
3205
3536
|
"data-streaming": item.isStreaming ? "true" : void 0
|
|
3206
|
-
}, /* @__PURE__ */
|
|
3537
|
+
}, /* @__PURE__ */ import_react13.default.createElement("div", null, renderBlocks(item, slots)), actionRow);
|
|
3207
3538
|
}
|
|
3208
3539
|
__name(MessageItemView, "MessageItemView");
|
|
3209
3540
|
function renderBlocks(item, slots) {
|
|
3210
3541
|
const nodes = [];
|
|
3211
3542
|
for (const block of item.blocks) {
|
|
3212
3543
|
if (block.kind === "text") {
|
|
3213
|
-
nodes.push(/* @__PURE__ */
|
|
3544
|
+
nodes.push(/* @__PURE__ */ import_react13.default.createElement("div", {
|
|
3214
3545
|
key: block.key,
|
|
3215
3546
|
className: slots.classNames?.text
|
|
3216
3547
|
}, slots.renderText ? slots.renderText(block.text, {
|
|
@@ -3231,7 +3562,7 @@ function renderBlocks(item, slots) {
|
|
|
3231
3562
|
continue;
|
|
3232
3563
|
}
|
|
3233
3564
|
if (block.kind === "ui" && slots.renderUi) {
|
|
3234
|
-
nodes.push(/* @__PURE__ */
|
|
3565
|
+
nodes.push(/* @__PURE__ */ import_react13.default.createElement("div", {
|
|
3235
3566
|
key: block.key,
|
|
3236
3567
|
"data-slot": "ui",
|
|
3237
3568
|
"data-component": block.component
|
|
@@ -3242,18 +3573,18 @@ function renderBlocks(item, slots) {
|
|
|
3242
3573
|
}
|
|
3243
3574
|
__name(renderBlocks, "renderBlocks");
|
|
3244
3575
|
function renderFilesBlock(block, slots) {
|
|
3245
|
-
return /* @__PURE__ */
|
|
3576
|
+
return /* @__PURE__ */ import_react13.default.createElement("div", {
|
|
3246
3577
|
key: block.key,
|
|
3247
3578
|
className: slots.classNames?.files,
|
|
3248
3579
|
"data-files": "true"
|
|
3249
|
-
}, slots.renderFiles ? slots.renderFiles(block.files) : block.files.map((file) => /* @__PURE__ */
|
|
3580
|
+
}, slots.renderFiles ? slots.renderFiles(block.files) : block.files.map((file) => /* @__PURE__ */ import_react13.default.createElement("a", {
|
|
3250
3581
|
key: file.url,
|
|
3251
3582
|
href: file.url,
|
|
3252
3583
|
target: "_blank",
|
|
3253
3584
|
rel: "noreferrer",
|
|
3254
3585
|
className: slots.classNames?.file,
|
|
3255
3586
|
title: file.filename ?? file.mediaType
|
|
3256
|
-
}, file.isImage ? /* @__PURE__ */
|
|
3587
|
+
}, file.isImage ? /* @__PURE__ */ import_react13.default.createElement("img", {
|
|
3257
3588
|
src: file.url,
|
|
3258
3589
|
alt: file.filename ?? "image",
|
|
3259
3590
|
className: slots.classNames?.fileImage
|
|
@@ -3261,17 +3592,17 @@ function renderFilesBlock(block, slots) {
|
|
|
3261
3592
|
}
|
|
3262
3593
|
__name(renderFilesBlock, "renderFilesBlock");
|
|
3263
3594
|
function renderReasoningBlock(block, slots) {
|
|
3264
|
-
return /* @__PURE__ */
|
|
3595
|
+
return /* @__PURE__ */ import_react13.default.createElement("div", {
|
|
3265
3596
|
key: block.key,
|
|
3266
3597
|
className: slots.classNames?.reasoning,
|
|
3267
3598
|
"data-reasoning": "true",
|
|
3268
3599
|
"data-streaming": block.isStreaming ? "true" : void 0
|
|
3269
|
-
}, /* @__PURE__ */
|
|
3600
|
+
}, /* @__PURE__ */ import_react13.default.createElement("button", {
|
|
3270
3601
|
type: "button",
|
|
3271
3602
|
className: slots.classNames?.reasoningToggle,
|
|
3272
3603
|
onClick: /* @__PURE__ */ __name(() => block.toggle(), "onClick"),
|
|
3273
3604
|
"aria-expanded": block.isOpen
|
|
3274
|
-
}, slots.reasoningLabel ?? "Reasoning"), block.isOpen ? /* @__PURE__ */
|
|
3605
|
+
}, slots.reasoningLabel ?? "Reasoning"), block.isOpen ? /* @__PURE__ */ import_react13.default.createElement("div", {
|
|
3275
3606
|
className: slots.classNames?.reasoningText
|
|
3276
3607
|
}, slots.renderReasoning ? slots.renderReasoning(block.text, {
|
|
3277
3608
|
isStreaming: block.isStreaming,
|
|
@@ -3282,7 +3613,7 @@ __name(renderReasoningBlock, "renderReasoningBlock");
|
|
|
3282
3613
|
function renderToolBlock(item, block, slots) {
|
|
3283
3614
|
if (slots.renderToolGroup) {
|
|
3284
3615
|
return [
|
|
3285
|
-
/* @__PURE__ */
|
|
3616
|
+
/* @__PURE__ */ import_react13.default.createElement(import_react13.default.Fragment, {
|
|
3286
3617
|
key: block.key
|
|
3287
3618
|
}, slots.renderToolGroup(block.parts, block.key))
|
|
3288
3619
|
];
|
|
@@ -3293,7 +3624,7 @@ function renderToolBlock(item, block, slots) {
|
|
|
3293
3624
|
const renderToolPart = slots.renderToolPart;
|
|
3294
3625
|
return block.parts.map((part) => {
|
|
3295
3626
|
const partKey = `${item.id}-${part.toolCallId}`;
|
|
3296
|
-
return /* @__PURE__ */
|
|
3627
|
+
return /* @__PURE__ */ import_react13.default.createElement(import_react13.default.Fragment, {
|
|
3297
3628
|
key: partKey
|
|
3298
3629
|
}, renderToolPart(part, partKey));
|
|
3299
3630
|
});
|
|
@@ -3303,14 +3634,14 @@ function EditableUserBubble({ item, slots, actions }) {
|
|
|
3303
3634
|
const { classNames } = slots;
|
|
3304
3635
|
const { edit } = item;
|
|
3305
3636
|
if (!edit.isEditing) {
|
|
3306
|
-
return /* @__PURE__ */
|
|
3637
|
+
return /* @__PURE__ */ import_react13.default.createElement("div", {
|
|
3307
3638
|
className: joinClasses(classNames?.root, classNames?.byRole?.user),
|
|
3308
3639
|
"data-role": "user"
|
|
3309
|
-
}, /* @__PURE__ */
|
|
3640
|
+
}, /* @__PURE__ */ import_react13.default.createElement("div", {
|
|
3310
3641
|
className: classNames?.text
|
|
3311
3642
|
}, slots.renderText ? slots.renderText(item.text, {
|
|
3312
3643
|
isStreaming: false
|
|
3313
|
-
}) : item.text), /* @__PURE__ */
|
|
3644
|
+
}) : item.text), /* @__PURE__ */ import_react13.default.createElement("button", {
|
|
3314
3645
|
type: "button",
|
|
3315
3646
|
onClick: edit.start,
|
|
3316
3647
|
className: classNames?.actionButton,
|
|
@@ -3318,18 +3649,18 @@ function EditableUserBubble({ item, slots, actions }) {
|
|
|
3318
3649
|
}, "Edit"), actions);
|
|
3319
3650
|
}
|
|
3320
3651
|
const textareaProps = edit.getTextareaProps();
|
|
3321
|
-
return /* @__PURE__ */
|
|
3652
|
+
return /* @__PURE__ */ import_react13.default.createElement("div", {
|
|
3322
3653
|
"data-editing": "true"
|
|
3323
|
-
}, /* @__PURE__ */
|
|
3654
|
+
}, /* @__PURE__ */ import_react13.default.createElement("textarea", {
|
|
3324
3655
|
...textareaProps,
|
|
3325
3656
|
rows: Math.min(8, edit.draft.split("\n").length + 1),
|
|
3326
3657
|
className: classNames?.editTextarea
|
|
3327
|
-
}), /* @__PURE__ */
|
|
3658
|
+
}), /* @__PURE__ */ import_react13.default.createElement("div", {
|
|
3328
3659
|
className: classNames?.editActions
|
|
3329
|
-
}, /* @__PURE__ */
|
|
3660
|
+
}, /* @__PURE__ */ import_react13.default.createElement("button", {
|
|
3330
3661
|
type: "button",
|
|
3331
3662
|
onClick: edit.cancel
|
|
3332
|
-
}, "Cancel"), /* @__PURE__ */
|
|
3663
|
+
}, "Cancel"), /* @__PURE__ */ import_react13.default.createElement("button", {
|
|
3333
3664
|
type: "button",
|
|
3334
3665
|
onClick: edit.save,
|
|
3335
3666
|
disabled: !edit.canSave
|
|
@@ -3573,35 +3904,35 @@ function toItem(entry) {
|
|
|
3573
3904
|
__name(toItem, "toItem");
|
|
3574
3905
|
|
|
3575
3906
|
// src/composer/use-composer-autocomplete.ts
|
|
3576
|
-
var
|
|
3907
|
+
var import_react14 = require("react");
|
|
3577
3908
|
function useComposerAutocomplete(options) {
|
|
3578
3909
|
const { value, sources, acceptOnTab = true } = options;
|
|
3579
|
-
const latest = (0,
|
|
3910
|
+
const latest = (0, import_react14.useRef)(options);
|
|
3580
3911
|
latest.current = options;
|
|
3581
|
-
const inputRef = (0,
|
|
3582
|
-
const [caret, setCaret] = (0,
|
|
3583
|
-
const [items, setItems] = (0,
|
|
3584
|
-
const [isLoading, setLoading] = (0,
|
|
3585
|
-
const [error, setError] = (0,
|
|
3586
|
-
const [activeIndex, setActiveIndex] = (0,
|
|
3587
|
-
const [dismissedIndex, setDismissedIndex] = (0,
|
|
3912
|
+
const inputRef = (0, import_react14.useRef)(null);
|
|
3913
|
+
const [caret, setCaret] = (0, import_react14.useState)(value.length);
|
|
3914
|
+
const [items, setItems] = (0, import_react14.useState)([]);
|
|
3915
|
+
const [isLoading, setLoading] = (0, import_react14.useState)(false);
|
|
3916
|
+
const [error, setError] = (0, import_react14.useState)(null);
|
|
3917
|
+
const [activeIndex, setActiveIndex] = (0, import_react14.useState)(0);
|
|
3918
|
+
const [dismissedIndex, setDismissedIndex] = (0, import_react14.useState)(null);
|
|
3588
3919
|
const safeCaret = Math.min(caret, value.length);
|
|
3589
|
-
const match = (0,
|
|
3920
|
+
const match = (0, import_react14.useMemo)(() => findActiveTrigger(value, safeCaret, sources), [
|
|
3590
3921
|
value,
|
|
3591
3922
|
safeCaret,
|
|
3592
3923
|
sources
|
|
3593
3924
|
]);
|
|
3594
3925
|
const isActive = match !== null && dismissedIndex !== match.index;
|
|
3595
|
-
const matchRef = (0,
|
|
3926
|
+
const matchRef = (0, import_react14.useRef)(match);
|
|
3596
3927
|
matchRef.current = match;
|
|
3597
|
-
const caretRef = (0,
|
|
3928
|
+
const caretRef = (0, import_react14.useRef)(safeCaret);
|
|
3598
3929
|
caretRef.current = safeCaret;
|
|
3599
|
-
const itemsRef = (0,
|
|
3930
|
+
const itemsRef = (0, import_react14.useRef)(items);
|
|
3600
3931
|
itemsRef.current = items;
|
|
3601
|
-
const activeIndexRef = (0,
|
|
3932
|
+
const activeIndexRef = (0, import_react14.useRef)(activeIndex);
|
|
3602
3933
|
activeIndexRef.current = activeIndex;
|
|
3603
3934
|
const requestKey = isActive && match ? `${match.source.id}\0${match.query}` : null;
|
|
3604
|
-
(0,
|
|
3935
|
+
(0, import_react14.useEffect)(() => {
|
|
3605
3936
|
const current = matchRef.current;
|
|
3606
3937
|
if (requestKey === null || current === null) {
|
|
3607
3938
|
setItems([]);
|
|
@@ -3649,25 +3980,25 @@ function useComposerAutocomplete(options) {
|
|
|
3649
3980
|
]);
|
|
3650
3981
|
const isOpen = isActive;
|
|
3651
3982
|
const activeItem = isOpen ? items[activeIndex] ?? null : null;
|
|
3652
|
-
const reactId = (0,
|
|
3983
|
+
const reactId = (0, import_react14.useId)();
|
|
3653
3984
|
const listboxId = options.id ?? `agent-autocomplete-${reactId}`;
|
|
3654
|
-
const optionId = (0,
|
|
3985
|
+
const optionId = (0, import_react14.useCallback)((index) => `${listboxId}-option-${index}`, [
|
|
3655
3986
|
listboxId
|
|
3656
3987
|
]);
|
|
3657
|
-
const highlight = (0,
|
|
3988
|
+
const highlight = (0, import_react14.useCallback)((index) => {
|
|
3658
3989
|
const total = itemsRef.current.length;
|
|
3659
3990
|
if (total === 0) return;
|
|
3660
3991
|
setActiveIndex((index % total + total) % total);
|
|
3661
3992
|
}, []);
|
|
3662
|
-
const moveHighlight = (0,
|
|
3993
|
+
const moveHighlight = (0, import_react14.useCallback)((delta) => highlight(activeIndexRef.current + delta), [
|
|
3663
3994
|
highlight
|
|
3664
3995
|
]);
|
|
3665
|
-
const dismiss = (0,
|
|
3996
|
+
const dismiss = (0, import_react14.useCallback)(() => {
|
|
3666
3997
|
const current = matchRef.current;
|
|
3667
3998
|
if (current) setDismissedIndex(current.index);
|
|
3668
3999
|
}, []);
|
|
3669
|
-
const pendingCaret = (0,
|
|
3670
|
-
const accept = (0,
|
|
4000
|
+
const pendingCaret = (0, import_react14.useRef)(null);
|
|
4001
|
+
const accept = (0, import_react14.useCallback)((item) => {
|
|
3671
4002
|
const current = matchRef.current;
|
|
3672
4003
|
if (!current) return;
|
|
3673
4004
|
const chosen = item ?? itemsRef.current[activeIndexRef.current];
|
|
@@ -3678,16 +4009,16 @@ function useComposerAutocomplete(options) {
|
|
|
3678
4009
|
setDismissedIndex(null);
|
|
3679
4010
|
pendingCaret.current = edit.caret;
|
|
3680
4011
|
}, []);
|
|
3681
|
-
(0,
|
|
4012
|
+
(0, import_react14.useLayoutEffect)(() => {
|
|
3682
4013
|
const position = pendingCaret.current;
|
|
3683
4014
|
if (position === null) return;
|
|
3684
4015
|
pendingCaret.current = null;
|
|
3685
4016
|
inputRef.current?.setSelectionRange(position, position);
|
|
3686
4017
|
});
|
|
3687
|
-
const readCaret = (0,
|
|
4018
|
+
const readCaret = (0, import_react14.useCallback)((element) => {
|
|
3688
4019
|
setCaret(element.selectionStart ?? element.value.length);
|
|
3689
4020
|
}, []);
|
|
3690
|
-
const onKeyDown = (0,
|
|
4021
|
+
const onKeyDown = (0, import_react14.useCallback)((event) => {
|
|
3691
4022
|
if (!isOpen) return;
|
|
3692
4023
|
const hasItems = itemsRef.current.length > 0;
|
|
3693
4024
|
switch (event.key) {
|
|
@@ -3725,23 +4056,23 @@ function useComposerAutocomplete(options) {
|
|
|
3725
4056
|
dismiss,
|
|
3726
4057
|
moveHighlight
|
|
3727
4058
|
]);
|
|
3728
|
-
const onChange = (0,
|
|
4059
|
+
const onChange = (0, import_react14.useCallback)((event) => {
|
|
3729
4060
|
readCaret(event.target);
|
|
3730
4061
|
const next = findActiveTrigger(event.target.value, event.target.selectionStart ?? event.target.value.length, latest.current.sources);
|
|
3731
4062
|
setDismissedIndex((current) => current !== null && next?.index === current ? current : null);
|
|
3732
4063
|
}, [
|
|
3733
4064
|
readCaret
|
|
3734
4065
|
]);
|
|
3735
|
-
const onSelect = (0,
|
|
4066
|
+
const onSelect = (0, import_react14.useCallback)((event) => readCaret(event.currentTarget), [
|
|
3736
4067
|
readCaret
|
|
3737
4068
|
]);
|
|
3738
|
-
const onClick = (0,
|
|
4069
|
+
const onClick = (0, import_react14.useCallback)((event) => readCaret(event.currentTarget), [
|
|
3739
4070
|
readCaret
|
|
3740
4071
|
]);
|
|
3741
|
-
const setInput = (0,
|
|
4072
|
+
const setInput = (0, import_react14.useCallback)((element) => {
|
|
3742
4073
|
inputRef.current = element;
|
|
3743
4074
|
}, []);
|
|
3744
|
-
const getInputProps = (0,
|
|
4075
|
+
const getInputProps = (0, import_react14.useCallback)(() => ({
|
|
3745
4076
|
ref: setInput,
|
|
3746
4077
|
onChange,
|
|
3747
4078
|
onKeyDown,
|
|
@@ -3769,7 +4100,7 @@ function useComposerAutocomplete(options) {
|
|
|
3769
4100
|
activeIndex,
|
|
3770
4101
|
optionId
|
|
3771
4102
|
]);
|
|
3772
|
-
const getListboxProps = (0,
|
|
4103
|
+
const getListboxProps = (0, import_react14.useCallback)(() => ({
|
|
3773
4104
|
id: listboxId,
|
|
3774
4105
|
role: "listbox",
|
|
3775
4106
|
"aria-label": match?.source.label ?? match?.source.id ?? "Suggestions"
|
|
@@ -3777,7 +4108,7 @@ function useComposerAutocomplete(options) {
|
|
|
3777
4108
|
listboxId,
|
|
3778
4109
|
match
|
|
3779
4110
|
]);
|
|
3780
|
-
const getOptionProps = (0,
|
|
4111
|
+
const getOptionProps = (0, import_react14.useCallback)((index) => ({
|
|
3781
4112
|
id: optionId(index),
|
|
3782
4113
|
role: "option",
|
|
3783
4114
|
"aria-selected": index === activeIndex
|
|
@@ -3811,7 +4142,7 @@ function isPromise(value) {
|
|
|
3811
4142
|
__name(isPromise, "isPromise");
|
|
3812
4143
|
|
|
3813
4144
|
// src/presentation/use-tool-catalog.ts
|
|
3814
|
-
var
|
|
4145
|
+
var import_react15 = require("react");
|
|
3815
4146
|
var shared = /* @__PURE__ */ new WeakMap();
|
|
3816
4147
|
function load(client, agent) {
|
|
3817
4148
|
let byAgent = shared.get(client);
|
|
@@ -3835,11 +4166,11 @@ function load(client, agent) {
|
|
|
3835
4166
|
__name(load, "load");
|
|
3836
4167
|
function useToolCatalog(options) {
|
|
3837
4168
|
const { client, agent, enabled = true } = options;
|
|
3838
|
-
const [entries, setEntries] = (0,
|
|
3839
|
-
const [isLoading, setLoading] = (0,
|
|
3840
|
-
const [error, setError] = (0,
|
|
3841
|
-
const [generation, setGeneration] = (0,
|
|
3842
|
-
(0,
|
|
4169
|
+
const [entries, setEntries] = (0, import_react15.useState)([]);
|
|
4170
|
+
const [isLoading, setLoading] = (0, import_react15.useState)(enabled);
|
|
4171
|
+
const [error, setError] = (0, import_react15.useState)(null);
|
|
4172
|
+
const [generation, setGeneration] = (0, import_react15.useState)(0);
|
|
4173
|
+
(0, import_react15.useEffect)(() => {
|
|
3843
4174
|
if (!enabled) {
|
|
3844
4175
|
setLoading(false);
|
|
3845
4176
|
return;
|
|
@@ -3865,14 +4196,14 @@ function useToolCatalog(options) {
|
|
|
3865
4196
|
enabled,
|
|
3866
4197
|
generation
|
|
3867
4198
|
]);
|
|
3868
|
-
const refresh = (0,
|
|
4199
|
+
const refresh = (0, import_react15.useCallback)(() => {
|
|
3869
4200
|
shared.get(client)?.delete(agent ?? "");
|
|
3870
4201
|
setGeneration((current) => current + 1);
|
|
3871
4202
|
}, [
|
|
3872
4203
|
client,
|
|
3873
4204
|
agent
|
|
3874
4205
|
]);
|
|
3875
|
-
const catalog = (0,
|
|
4206
|
+
const catalog = (0, import_react15.useMemo)(() => toolCatalogFrom(entries), [
|
|
3876
4207
|
entries
|
|
3877
4208
|
]);
|
|
3878
4209
|
return {
|
|
@@ -3886,7 +4217,7 @@ function useToolCatalog(options) {
|
|
|
3886
4217
|
__name(useToolCatalog, "useToolCatalog");
|
|
3887
4218
|
|
|
3888
4219
|
// src/approvals/countdown.ts
|
|
3889
|
-
var
|
|
4220
|
+
var import_react16 = require("react");
|
|
3890
4221
|
function approvalCountdown(expiresAt, now = Date.now()) {
|
|
3891
4222
|
const deadline = expiresAt == null ? Number.NaN : Date.parse(expiresAt);
|
|
3892
4223
|
if (!Number.isFinite(deadline)) {
|
|
@@ -3904,10 +4235,10 @@ function approvalCountdown(expiresAt, now = Date.now()) {
|
|
|
3904
4235
|
__name(approvalCountdown, "approvalCountdown");
|
|
3905
4236
|
function useApprovalCountdown(expiresAt, options = {}) {
|
|
3906
4237
|
const { intervalMs = 1e3 } = options;
|
|
3907
|
-
const nowRef = (0,
|
|
4238
|
+
const nowRef = (0, import_react16.useRef)(options.now ?? Date.now);
|
|
3908
4239
|
nowRef.current = options.now ?? Date.now;
|
|
3909
|
-
const [state, setState] = (0,
|
|
3910
|
-
(0,
|
|
4240
|
+
const [state, setState] = (0, import_react16.useState)(() => approvalCountdown(expiresAt, nowRef.current()));
|
|
4241
|
+
(0, import_react16.useEffect)(() => {
|
|
3911
4242
|
const read = /* @__PURE__ */ __name(() => approvalCountdown(expiresAt, nowRef.current()), "read");
|
|
3912
4243
|
const first = read();
|
|
3913
4244
|
setState(first);
|
|
@@ -3970,7 +4301,13 @@ function storedMessageToUiMessage(message) {
|
|
|
3970
4301
|
type: "file",
|
|
3971
4302
|
mediaType: attachment.contentType,
|
|
3972
4303
|
filename: attachment.name,
|
|
3973
|
-
url: attachment.url
|
|
4304
|
+
url: attachment.url,
|
|
4305
|
+
// The stored id rides along, so a replayed file can be referenced again (`messageFiles`).
|
|
4306
|
+
providerMetadata: {
|
|
4307
|
+
agent: {
|
|
4308
|
+
mediaId: attachment.mediaId
|
|
4309
|
+
}
|
|
4310
|
+
}
|
|
3974
4311
|
});
|
|
3975
4312
|
}
|
|
3976
4313
|
const toolCallIds = new Set((message.toolCalls ?? []).map((call) => call.id));
|
|
@@ -4148,21 +4485,21 @@ function sumUsage(rows) {
|
|
|
4148
4485
|
__name(sumUsage, "sumUsage");
|
|
4149
4486
|
|
|
4150
4487
|
// src/use-agent-chat.ts
|
|
4151
|
-
var
|
|
4152
|
-
var
|
|
4488
|
+
var import_react17 = require("@ai-sdk/react");
|
|
4489
|
+
var import_react18 = require("react");
|
|
4153
4490
|
function useAgentChat(options) {
|
|
4154
|
-
const latest = (0,
|
|
4491
|
+
const latest = (0, import_react18.useRef)(options);
|
|
4155
4492
|
latest.current = options;
|
|
4156
|
-
const [runId, setRunId] = (0,
|
|
4157
|
-
const runIdRef = (0,
|
|
4493
|
+
const [runId, setRunId] = (0, import_react18.useState)(options.resumeRunId);
|
|
4494
|
+
const runIdRef = (0, import_react18.useRef)(runId);
|
|
4158
4495
|
runIdRef.current = runId;
|
|
4159
|
-
const settlingRunIdRef = (0,
|
|
4160
|
-
const autoResumeRunIdRef = (0,
|
|
4161
|
-
const [autoResume, setAutoResume] = (0,
|
|
4162
|
-
const [activeRunId, setActiveRunId] = (0,
|
|
4163
|
-
const regenerateNext = (0,
|
|
4164
|
-
const createdThreadId = (0,
|
|
4165
|
-
const client = (0,
|
|
4496
|
+
const settlingRunIdRef = (0, import_react18.useRef)(void 0);
|
|
4497
|
+
const autoResumeRunIdRef = (0, import_react18.useRef)(void 0);
|
|
4498
|
+
const [autoResume, setAutoResume] = (0, import_react18.useState)(false);
|
|
4499
|
+
const [activeRunId, setActiveRunId] = (0, import_react18.useState)(null);
|
|
4500
|
+
const regenerateNext = (0, import_react18.useRef)(false);
|
|
4501
|
+
const createdThreadId = (0, import_react18.useRef)(void 0);
|
|
4502
|
+
const client = (0, import_react18.useMemo)(() => {
|
|
4166
4503
|
if (options.backend) return options.backend;
|
|
4167
4504
|
if (options.client) return options.client;
|
|
4168
4505
|
return new AgentClient({
|
|
@@ -4178,11 +4515,11 @@ function useAgentChat(options) {
|
|
|
4178
4515
|
getHeaders: /* @__PURE__ */ __name(async () => mergeHeaders(latest.current), "getHeaders")
|
|
4179
4516
|
});
|
|
4180
4517
|
}, []);
|
|
4181
|
-
const [connection, setConnection] = (0,
|
|
4518
|
+
const [connection, setConnection] = (0, import_react18.useState)({
|
|
4182
4519
|
status: "live"
|
|
4183
4520
|
});
|
|
4184
|
-
const resyncAfterSettle = (0,
|
|
4185
|
-
(0,
|
|
4521
|
+
const resyncAfterSettle = (0, import_react18.useRef)(false);
|
|
4522
|
+
(0, import_react18.useEffect)(() => {
|
|
4186
4523
|
if (!options.resume || options.threadId === void 0) return;
|
|
4187
4524
|
let cancelled = false;
|
|
4188
4525
|
const threadId = options.threadId;
|
|
@@ -4202,7 +4539,7 @@ function useAgentChat(options) {
|
|
|
4202
4539
|
options.resume,
|
|
4203
4540
|
options.threadId
|
|
4204
4541
|
]);
|
|
4205
|
-
const transport = (0,
|
|
4542
|
+
const transport = (0, import_react18.useMemo)(() => {
|
|
4206
4543
|
function onMeta(meta) {
|
|
4207
4544
|
settlingRunIdRef.current = meta.runId;
|
|
4208
4545
|
setRunId(meta.runId);
|
|
@@ -4257,8 +4594,8 @@ function useAgentChat(options) {
|
|
|
4257
4594
|
}, "onAttemptStart")
|
|
4258
4595
|
});
|
|
4259
4596
|
}, []);
|
|
4260
|
-
const backgroundRef = (0,
|
|
4261
|
-
const chat = (0,
|
|
4597
|
+
const backgroundRef = (0, import_react18.useRef)(() => Promise.resolve());
|
|
4598
|
+
const chat = (0, import_react17.useChat)({
|
|
4262
4599
|
transport,
|
|
4263
4600
|
resume: options.resumeRunId !== void 0 || autoResume,
|
|
4264
4601
|
...options.threadId !== void 0 ? {
|
|
@@ -4306,7 +4643,7 @@ function useAgentChat(options) {
|
|
|
4306
4643
|
}
|
|
4307
4644
|
}, "onFinish")
|
|
4308
4645
|
});
|
|
4309
|
-
const chatRef = (0,
|
|
4646
|
+
const chatRef = (0, import_react18.useRef)(chat);
|
|
4310
4647
|
chatRef.current = chat;
|
|
4311
4648
|
async function resyncFromThread() {
|
|
4312
4649
|
const threadId = latest.current.threadId ?? createdThreadId.current;
|
|
@@ -4318,11 +4655,11 @@ function useAgentChat(options) {
|
|
|
4318
4655
|
}
|
|
4319
4656
|
}
|
|
4320
4657
|
__name(resyncFromThread, "resyncFromThread");
|
|
4321
|
-
const turnInFlight = (0,
|
|
4322
|
-
const isTurnInFlight = (0,
|
|
4658
|
+
const turnInFlight = (0, import_react18.useRef)(false);
|
|
4659
|
+
const isTurnInFlight = (0, import_react18.useCallback)(() => turnInFlight.current || transport.isAttemptLive, [
|
|
4323
4660
|
transport
|
|
4324
4661
|
]);
|
|
4325
|
-
const sendMessage = (0,
|
|
4662
|
+
const sendMessage = (0, import_react18.useCallback)(async (...args) => {
|
|
4326
4663
|
const blocked = latest.current.blocked;
|
|
4327
4664
|
if (blocked != null) throw new QuotaBlockedError(blocked);
|
|
4328
4665
|
if (isTurnInFlight()) return;
|
|
@@ -4335,15 +4672,15 @@ function useAgentChat(options) {
|
|
|
4335
4672
|
}, [
|
|
4336
4673
|
isTurnInFlight
|
|
4337
4674
|
]);
|
|
4338
|
-
const addToolResult = (0,
|
|
4675
|
+
const addToolResult = (0, import_react18.useCallback)(({ tool, toolCallId, output }) => chatRef.current.addToolResult({
|
|
4339
4676
|
tool,
|
|
4340
4677
|
toolCallId,
|
|
4341
4678
|
output
|
|
4342
4679
|
}), []);
|
|
4343
|
-
const [threads, setThreads] = (0,
|
|
4344
|
-
const [quota, setQuota] = (0,
|
|
4345
|
-
const [backgroundRuns, setBackgroundRuns] = (0,
|
|
4346
|
-
const refreshBackground = (0,
|
|
4680
|
+
const [threads, setThreads] = (0, import_react18.useState)([]);
|
|
4681
|
+
const [quota, setQuota] = (0, import_react18.useState)(null);
|
|
4682
|
+
const [backgroundRuns, setBackgroundRuns] = (0, import_react18.useState)([]);
|
|
4683
|
+
const refreshBackground = (0, import_react18.useCallback)(async () => {
|
|
4347
4684
|
const threadId = latest.current.threadId ?? createdThreadId.current;
|
|
4348
4685
|
if (threadId === void 0) {
|
|
4349
4686
|
return;
|
|
@@ -4368,7 +4705,7 @@ function useAgentChat(options) {
|
|
|
4368
4705
|
]);
|
|
4369
4706
|
backgroundRef.current = refreshBackground;
|
|
4370
4707
|
const isWorking = backgroundRuns.some((run) => run.status === "running");
|
|
4371
|
-
(0,
|
|
4708
|
+
(0, import_react18.useEffect)(() => {
|
|
4372
4709
|
if (options.background !== true || options.threadId === void 0) {
|
|
4373
4710
|
return;
|
|
4374
4711
|
}
|
|
@@ -4378,7 +4715,7 @@ function useAgentChat(options) {
|
|
|
4378
4715
|
options.threadId,
|
|
4379
4716
|
refreshBackground
|
|
4380
4717
|
]);
|
|
4381
|
-
(0,
|
|
4718
|
+
(0, import_react18.useEffect)(() => {
|
|
4382
4719
|
const every = latest.current.backgroundPollMs ?? 5e3;
|
|
4383
4720
|
if (latest.current.background !== true || !isWorking || every <= 0) {
|
|
4384
4721
|
return;
|
|
@@ -4389,26 +4726,26 @@ function useAgentChat(options) {
|
|
|
4389
4726
|
isWorking,
|
|
4390
4727
|
refreshBackground
|
|
4391
4728
|
]);
|
|
4392
|
-
const loadThreads = (0,
|
|
4729
|
+
const loadThreads = (0, import_react18.useCallback)(async () => {
|
|
4393
4730
|
const list = await client.listThreads();
|
|
4394
4731
|
setThreads(list);
|
|
4395
4732
|
return list;
|
|
4396
4733
|
}, [
|
|
4397
4734
|
client
|
|
4398
4735
|
]);
|
|
4399
|
-
const loadThread = (0,
|
|
4736
|
+
const loadThread = (0, import_react18.useCallback)((id) => client.getThread(id), [
|
|
4400
4737
|
client
|
|
4401
4738
|
]);
|
|
4402
|
-
const deleteThread = (0,
|
|
4739
|
+
const deleteThread = (0, import_react18.useCallback)(async (id) => {
|
|
4403
4740
|
await client.deleteThread(id);
|
|
4404
4741
|
setThreads((current) => current.filter((thread) => thread.id !== id));
|
|
4405
4742
|
}, [
|
|
4406
4743
|
client
|
|
4407
4744
|
]);
|
|
4408
|
-
const forkThread = (0,
|
|
4745
|
+
const forkThread = (0, import_react18.useCallback)((threadId, messageId) => requireBackendMethod(client, "forkFromMessage")(threadId, messageId), [
|
|
4409
4746
|
client
|
|
4410
4747
|
]);
|
|
4411
|
-
const renameThread = (0,
|
|
4748
|
+
const renameThread = (0, import_react18.useCallback)(async (id, title) => {
|
|
4412
4749
|
await client.updateThread(id, {
|
|
4413
4750
|
title
|
|
4414
4751
|
});
|
|
@@ -4419,24 +4756,24 @@ function useAgentChat(options) {
|
|
|
4419
4756
|
}, [
|
|
4420
4757
|
client
|
|
4421
4758
|
]);
|
|
4422
|
-
const promoteThread = (0,
|
|
4759
|
+
const promoteThread = (0, import_react18.useCallback)(async (id) => {
|
|
4423
4760
|
await requireBackendMethod(client, "promoteThread")(id);
|
|
4424
4761
|
await loadThreads();
|
|
4425
4762
|
}, [
|
|
4426
4763
|
client,
|
|
4427
4764
|
loadThreads
|
|
4428
4765
|
]);
|
|
4429
|
-
const truncateFromMessage = (0,
|
|
4766
|
+
const truncateFromMessage = (0, import_react18.useCallback)((threadId, messageId) => requireBackendMethod(client, "truncateFromMessage")(threadId, messageId).then(() => void 0), [
|
|
4430
4767
|
client
|
|
4431
4768
|
]);
|
|
4432
|
-
const loadQuota = (0,
|
|
4769
|
+
const loadQuota = (0, import_react18.useCallback)(async () => {
|
|
4433
4770
|
const today = await requireBackendMethod(client, "getQuotaToday")();
|
|
4434
4771
|
setQuota(today);
|
|
4435
4772
|
return today;
|
|
4436
4773
|
}, [
|
|
4437
4774
|
client
|
|
4438
4775
|
]);
|
|
4439
|
-
const cancel = (0,
|
|
4776
|
+
const cancel = (0, import_react18.useCallback)(async () => {
|
|
4440
4777
|
chatRef.current.stop();
|
|
4441
4778
|
const activeRunId2 = runIdRef.current;
|
|
4442
4779
|
if (activeRunId2) {
|
|
@@ -4448,7 +4785,7 @@ function useAgentChat(options) {
|
|
|
4448
4785
|
}, [
|
|
4449
4786
|
client
|
|
4450
4787
|
]);
|
|
4451
|
-
const approve = (0,
|
|
4788
|
+
const approve = (0, import_react18.useCallback)(async ({ toolCallId, remember, via }) => {
|
|
4452
4789
|
await requireBackendMethod(client, "approveToolCall")({
|
|
4453
4790
|
toolCallId,
|
|
4454
4791
|
...remember === true ? {
|
|
@@ -4461,7 +4798,7 @@ function useAgentChat(options) {
|
|
|
4461
4798
|
}, [
|
|
4462
4799
|
client
|
|
4463
4800
|
]);
|
|
4464
|
-
const reject = (0,
|
|
4801
|
+
const reject = (0, import_react18.useCallback)(async ({ toolCallId, reason, via }) => {
|
|
4465
4802
|
await requireBackendMethod(client, "rejectToolCall")({
|
|
4466
4803
|
toolCallId,
|
|
4467
4804
|
...reason !== void 0 ? {
|
|
@@ -4474,7 +4811,7 @@ function useAgentChat(options) {
|
|
|
4474
4811
|
}, [
|
|
4475
4812
|
client
|
|
4476
4813
|
]);
|
|
4477
|
-
const answer = (0,
|
|
4814
|
+
const answer = (0, import_react18.useCallback)(async ({ toolCallId, answers }) => {
|
|
4478
4815
|
await requireBackendMethod(client, "answerToolCall")({
|
|
4479
4816
|
toolCallId,
|
|
4480
4817
|
...answers !== void 0 ? {
|
|
@@ -4484,14 +4821,14 @@ function useAgentChat(options) {
|
|
|
4484
4821
|
}, [
|
|
4485
4822
|
client
|
|
4486
4823
|
]);
|
|
4487
|
-
const skip = (0,
|
|
4824
|
+
const skip = (0, import_react18.useCallback)(async ({ toolCallId }) => {
|
|
4488
4825
|
await requireBackendMethod(client, "skipToolCall")({
|
|
4489
4826
|
toolCallId
|
|
4490
4827
|
});
|
|
4491
4828
|
}, [
|
|
4492
4829
|
client
|
|
4493
4830
|
]);
|
|
4494
|
-
const regenerate = (0,
|
|
4831
|
+
const regenerate = (0, import_react18.useCallback)(() => {
|
|
4495
4832
|
const blocked = latest.current.blocked;
|
|
4496
4833
|
if (blocked != null) throw new QuotaBlockedError(blocked);
|
|
4497
4834
|
if (isTurnInFlight()) return;
|
|
@@ -4508,7 +4845,7 @@ function useAgentChat(options) {
|
|
|
4508
4845
|
isWorking,
|
|
4509
4846
|
refresh: refreshBackground
|
|
4510
4847
|
};
|
|
4511
|
-
const setThreadModel = (0,
|
|
4848
|
+
const setThreadModel = (0, import_react18.useCallback)(async (model) => {
|
|
4512
4849
|
const threadId = latest.current.threadId ?? createdThreadId.current;
|
|
4513
4850
|
if (threadId === void 0) {
|
|
4514
4851
|
throw new Error("setThreadModel: this chat has no thread yet");
|
|
@@ -4522,7 +4859,7 @@ function useAgentChat(options) {
|
|
|
4522
4859
|
}, [
|
|
4523
4860
|
client
|
|
4524
4861
|
]);
|
|
4525
|
-
const getThreadId = (0,
|
|
4862
|
+
const getThreadId = (0, import_react18.useCallback)(() => latest.current.threadId ?? createdThreadId.current, []);
|
|
4526
4863
|
const status = connection.status === "reconnecting" ? "reconnecting" : chat.status;
|
|
4527
4864
|
return {
|
|
4528
4865
|
...chat,
|
|
@@ -4596,6 +4933,7 @@ __name(mergeHeaders, "mergeHeaders");
|
|
|
4596
4933
|
MessageList,
|
|
4597
4934
|
QuotaBlockedError,
|
|
4598
4935
|
SPEECH_LANGUAGES,
|
|
4936
|
+
acceptsFile,
|
|
4599
4937
|
applyCompletion,
|
|
4600
4938
|
approvalCountdown,
|
|
4601
4939
|
backgroundRunsFromThread,
|
|
@@ -4606,7 +4944,10 @@ __name(mergeHeaders, "mergeHeaders");
|
|
|
4606
4944
|
describeTimestamp,
|
|
4607
4945
|
describeToolCall,
|
|
4608
4946
|
describeUsage,
|
|
4947
|
+
dragHasFiles,
|
|
4609
4948
|
extractMessageText,
|
|
4949
|
+
fileKind,
|
|
4950
|
+
filesFromClipboard,
|
|
4610
4951
|
fillTemplate,
|
|
4611
4952
|
filterAutocompleteItems,
|
|
4612
4953
|
findActiveTrigger,
|
|
@@ -4616,6 +4957,7 @@ __name(mergeHeaders, "mergeHeaders");
|
|
|
4616
4957
|
inferResultView,
|
|
4617
4958
|
isActionCall,
|
|
4618
4959
|
loadStoredSpeechLang,
|
|
4960
|
+
messageFiles,
|
|
4619
4961
|
notifyThreads,
|
|
4620
4962
|
onThreadsEvent,
|
|
4621
4963
|
persistSpeechLang,
|
|
@@ -4631,6 +4973,7 @@ __name(mergeHeaders, "mergeHeaders");
|
|
|
4631
4973
|
useAgentChat,
|
|
4632
4974
|
useAgents,
|
|
4633
4975
|
useApprovalCountdown,
|
|
4976
|
+
useAttachments,
|
|
4634
4977
|
useChatTranscript,
|
|
4635
4978
|
useComposerAutocomplete,
|
|
4636
4979
|
useElapsed,
|