@dudousxd/nestjs-agent-react 0.17.0 → 0.19.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 +70 -29
- package/dist/generative-ui-BhXFni8j.d.ts +167 -0
- package/dist/generative-ui-C53b3FoA.d.cts +167 -0
- package/dist/genui-json-render.cjs +521 -4
- package/dist/genui-json-render.cjs.map +1 -1
- package/dist/genui-json-render.d.cts +15 -2
- package/dist/genui-json-render.d.ts +15 -2
- package/dist/genui-json-render.js +518 -2
- package/dist/genui-json-render.js.map +1 -1
- package/dist/genui.cjs +120 -23
- package/dist/genui.cjs.map +1 -1
- package/dist/genui.d.cts +5 -52
- package/dist/genui.d.ts +5 -52
- package/dist/genui.js +106 -11
- package/dist/genui.js.map +1 -1
- package/dist/index.cjs +584 -214
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +157 -7
- package/dist/index.d.ts +157 -7
- package/dist/index.js +538 -176
- package/dist/index.js.map +1 -1
- package/package.json +3 -4
- package/dist/types-DFD-soWU.d.cts +0 -86
- package/dist/types-DFD-soWU.d.ts +0 -86
package/dist/index.cjs
CHANGED
|
@@ -35,6 +35,7 @@ __export(src_exports, {
|
|
|
35
35
|
AgentChatTransport: () => AgentChatTransport,
|
|
36
36
|
AgentClient: () => AgentClient,
|
|
37
37
|
AgentHttpError: () => AgentHttpError,
|
|
38
|
+
AmbientRenderUiContext: () => AmbientRenderUiContext,
|
|
38
39
|
ChatInput: () => ChatInput,
|
|
39
40
|
DEFAULT_SPEECH_LANG: () => DEFAULT_SPEECH_LANG,
|
|
40
41
|
MessageItem: () => MessageItem,
|
|
@@ -42,6 +43,7 @@ __export(src_exports, {
|
|
|
42
43
|
MessageList: () => MessageList,
|
|
43
44
|
QuotaBlockedError: () => QuotaBlockedError,
|
|
44
45
|
SPEECH_LANGUAGES: () => SPEECH_LANGUAGES,
|
|
46
|
+
acceptsFile: () => acceptsFile,
|
|
45
47
|
applyCompletion: () => applyCompletion,
|
|
46
48
|
approvalCountdown: () => approvalCountdown,
|
|
47
49
|
backgroundRunsFromThread: () => backgroundRunsFromThread,
|
|
@@ -52,7 +54,10 @@ __export(src_exports, {
|
|
|
52
54
|
describeTimestamp: () => describeTimestamp,
|
|
53
55
|
describeToolCall: () => describeToolCall,
|
|
54
56
|
describeUsage: () => describeUsage,
|
|
57
|
+
dragHasFiles: () => dragHasFiles,
|
|
55
58
|
extractMessageText: () => extractMessageText,
|
|
59
|
+
fileKind: () => fileKind,
|
|
60
|
+
filesFromClipboard: () => filesFromClipboard,
|
|
56
61
|
fillTemplate: () => fillTemplate,
|
|
57
62
|
filterAutocompleteItems: () => filterAutocompleteItems,
|
|
58
63
|
findActiveTrigger: () => findActiveTrigger,
|
|
@@ -62,6 +67,7 @@ __export(src_exports, {
|
|
|
62
67
|
inferResultView: () => inferResultView,
|
|
63
68
|
isActionCall: () => isActionCall,
|
|
64
69
|
loadStoredSpeechLang: () => loadStoredSpeechLang,
|
|
70
|
+
messageFiles: () => messageFiles,
|
|
65
71
|
notifyThreads: () => notifyThreads,
|
|
66
72
|
onThreadsEvent: () => onThreadsEvent,
|
|
67
73
|
persistSpeechLang: () => persistSpeechLang,
|
|
@@ -76,7 +82,9 @@ __export(src_exports, {
|
|
|
76
82
|
toolCatalogFrom: () => toolCatalogFrom,
|
|
77
83
|
useAgentChat: () => useAgentChat,
|
|
78
84
|
useAgents: () => useAgents,
|
|
85
|
+
useAmbientRenderUi: () => useAmbientRenderUi,
|
|
79
86
|
useApprovalCountdown: () => useApprovalCountdown,
|
|
87
|
+
useAttachments: () => useAttachments,
|
|
80
88
|
useChatTranscript: () => useChatTranscript,
|
|
81
89
|
useComposerAutocomplete: () => useComposerAutocomplete,
|
|
82
90
|
useElapsed: () => useElapsed,
|
|
@@ -217,6 +225,9 @@ var AgentClient = class {
|
|
|
217
225
|
* what a caller then rides on `sendMessage({ text }, { body: { attachments: [...] } })`.
|
|
218
226
|
*/
|
|
219
227
|
async uploadAttachment(file, options = {}) {
|
|
228
|
+
if (options.onProgress !== void 0 && this.options.fetch === void 0 && typeof XMLHttpRequest !== "undefined") {
|
|
229
|
+
return this.uploadWithProgress(file, options);
|
|
230
|
+
}
|
|
220
231
|
const formData = new FormData();
|
|
221
232
|
formData.append("file", file);
|
|
222
233
|
const response = await this.fetchImpl()(`${this.baseUrl()}/agent/attachments`, {
|
|
@@ -231,7 +242,47 @@ var AgentClient = class {
|
|
|
231
242
|
signal: options.signal
|
|
232
243
|
} : {}
|
|
233
244
|
});
|
|
234
|
-
|
|
245
|
+
const attachment = await this.handleResponse(response, "POST", "/agent/attachments");
|
|
246
|
+
options.onProgress?.(1);
|
|
247
|
+
return attachment;
|
|
248
|
+
}
|
|
249
|
+
async uploadWithProgress(file, { signal, onProgress }) {
|
|
250
|
+
const headers = {
|
|
251
|
+
accept: "application/json",
|
|
252
|
+
...await this.resolveHeaders()
|
|
253
|
+
};
|
|
254
|
+
const url = `${this.baseUrl()}/agent/attachments`;
|
|
255
|
+
return new Promise((resolve, reject) => {
|
|
256
|
+
const xhr = new XMLHttpRequest();
|
|
257
|
+
xhr.open("POST", url);
|
|
258
|
+
for (const [name, value] of Object.entries(headers)) xhr.setRequestHeader(name, value);
|
|
259
|
+
xhr.withCredentials = this.options.credentials === "include";
|
|
260
|
+
xhr.upload.onprogress = (event) => {
|
|
261
|
+
if (event.lengthComputable && event.total > 0) onProgress?.(event.loaded / event.total);
|
|
262
|
+
};
|
|
263
|
+
xhr.onload = () => {
|
|
264
|
+
if (xhr.status < 200 || xhr.status >= 300) {
|
|
265
|
+
reject(new AgentHttpError(xhr.status, "POST", "/agent/attachments", xhr.statusText));
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
onProgress?.(1);
|
|
269
|
+
resolve(JSON.parse(xhr.responseText));
|
|
270
|
+
};
|
|
271
|
+
xhr.onerror = () => reject(new TypeError("Network error while uploading the attachment"));
|
|
272
|
+
xhr.onabort = () => reject(new DOMException("The upload was aborted", "AbortError"));
|
|
273
|
+
if (signal !== void 0) {
|
|
274
|
+
if (signal.aborted) {
|
|
275
|
+
reject(new DOMException("The upload was aborted", "AbortError"));
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
signal.addEventListener("abort", () => xhr.abort(), {
|
|
279
|
+
once: true
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
const formData = new FormData();
|
|
283
|
+
formData.append("file", file);
|
|
284
|
+
xhr.send(formData);
|
|
285
|
+
});
|
|
235
286
|
}
|
|
236
287
|
promoteThread(id) {
|
|
237
288
|
return this.request("POST", `/agent/threads/${encodeURIComponent(id)}/promote`);
|
|
@@ -1079,6 +1130,68 @@ function delay(ms, signal) {
|
|
|
1079
1130
|
}
|
|
1080
1131
|
__name(delay, "delay");
|
|
1081
1132
|
|
|
1133
|
+
// src/attachments/files.ts
|
|
1134
|
+
function fileKind(mediaType) {
|
|
1135
|
+
const type = mediaType.toLowerCase();
|
|
1136
|
+
if (type.startsWith("image/")) return "image";
|
|
1137
|
+
if (type === "application/pdf") return "pdf";
|
|
1138
|
+
if (type.startsWith("text/") || type === "application/json") return "text";
|
|
1139
|
+
if (type.startsWith("audio/")) return "audio";
|
|
1140
|
+
if (type.startsWith("video/")) return "video";
|
|
1141
|
+
return "other";
|
|
1142
|
+
}
|
|
1143
|
+
__name(fileKind, "fileKind");
|
|
1144
|
+
function messageFiles(message) {
|
|
1145
|
+
const files = [];
|
|
1146
|
+
for (const part of message.parts) {
|
|
1147
|
+
if (part.type !== "file") continue;
|
|
1148
|
+
const file = part;
|
|
1149
|
+
const filename = file.filename ?? null;
|
|
1150
|
+
const dot = filename?.lastIndexOf(".") ?? -1;
|
|
1151
|
+
const mediaId = file.providerMetadata?.agent?.mediaId;
|
|
1152
|
+
files.push({
|
|
1153
|
+
url: file.url,
|
|
1154
|
+
mediaType: file.mediaType,
|
|
1155
|
+
filename,
|
|
1156
|
+
kind: fileKind(file.mediaType),
|
|
1157
|
+
extension: filename !== null && dot > 0 ? filename.slice(dot + 1).toLowerCase() : null,
|
|
1158
|
+
mediaId: typeof mediaId === "string" ? mediaId : null
|
|
1159
|
+
});
|
|
1160
|
+
}
|
|
1161
|
+
return files;
|
|
1162
|
+
}
|
|
1163
|
+
__name(messageFiles, "messageFiles");
|
|
1164
|
+
function acceptsFile(accept, file) {
|
|
1165
|
+
const rules = (typeof accept === "string" ? accept.split(",") : accept ?? []).map((rule) => rule.trim().toLowerCase()).filter((rule) => rule.length > 0);
|
|
1166
|
+
if (rules.length === 0) return true;
|
|
1167
|
+
const type = file.type.toLowerCase();
|
|
1168
|
+
const name = file.name.toLowerCase();
|
|
1169
|
+
return rules.some((rule) => {
|
|
1170
|
+
if (rule.startsWith(".")) return name.endsWith(rule);
|
|
1171
|
+
if (rule.endsWith("/*")) return type.startsWith(rule.slice(0, -1));
|
|
1172
|
+
return type === rule;
|
|
1173
|
+
});
|
|
1174
|
+
}
|
|
1175
|
+
__name(acceptsFile, "acceptsFile");
|
|
1176
|
+
function filesFromClipboard(data) {
|
|
1177
|
+
if (!data) return [];
|
|
1178
|
+
const files = [];
|
|
1179
|
+
for (const item of Array.from(data.items ?? [])) {
|
|
1180
|
+
if (item.kind !== "file") continue;
|
|
1181
|
+
const file = item.getAsFile();
|
|
1182
|
+
if (file !== null) files.push(file);
|
|
1183
|
+
}
|
|
1184
|
+
return files.length > 0 ? files : Array.from(data.files ?? []);
|
|
1185
|
+
}
|
|
1186
|
+
__name(filesFromClipboard, "filesFromClipboard");
|
|
1187
|
+
function dragHasFiles(data) {
|
|
1188
|
+
return Array.from(data?.types ?? []).includes("Files");
|
|
1189
|
+
}
|
|
1190
|
+
__name(dragHasFiles, "dragHasFiles");
|
|
1191
|
+
|
|
1192
|
+
// src/attachments/use-attachments.ts
|
|
1193
|
+
var import_react2 = require("react");
|
|
1194
|
+
|
|
1082
1195
|
// src/backend.ts
|
|
1083
1196
|
var AgentBackendUnsupportedError = class extends Error {
|
|
1084
1197
|
static {
|
|
@@ -1099,19 +1212,239 @@ function requireBackendMethod(backend, name) {
|
|
|
1099
1212
|
}
|
|
1100
1213
|
__name(requireBackendMethod, "requireBackendMethod");
|
|
1101
1214
|
|
|
1215
|
+
// src/attachments/use-attachments.ts
|
|
1216
|
+
var DEFAULT_REJECTION = {
|
|
1217
|
+
type: /* @__PURE__ */ __name((file) => `${file.name} is not a supported file type`, "type"),
|
|
1218
|
+
size: /* @__PURE__ */ __name((file) => `${file.name} is too large`, "size"),
|
|
1219
|
+
count: /* @__PURE__ */ __name(() => "Too many files", "count")
|
|
1220
|
+
};
|
|
1221
|
+
var sequence = 0;
|
|
1222
|
+
function useAttachments(options) {
|
|
1223
|
+
const latest = (0, import_react2.useRef)(options);
|
|
1224
|
+
latest.current = options;
|
|
1225
|
+
const [items, setItems] = (0, import_react2.useState)([]);
|
|
1226
|
+
const itemsRef = (0, import_react2.useRef)(items);
|
|
1227
|
+
itemsRef.current = items;
|
|
1228
|
+
const controllers = (0, import_react2.useRef)(/* @__PURE__ */ new Map());
|
|
1229
|
+
const [dragDepth, setDragDepth] = (0, import_react2.useState)(0);
|
|
1230
|
+
const patch = (0, import_react2.useCallback)((id, change) => {
|
|
1231
|
+
setItems((current) => current.map((item) => item.id === id ? {
|
|
1232
|
+
...item,
|
|
1233
|
+
...change
|
|
1234
|
+
} : item));
|
|
1235
|
+
}, []);
|
|
1236
|
+
const start = (0, import_react2.useCallback)((item) => {
|
|
1237
|
+
const { upload, backend } = latest.current;
|
|
1238
|
+
const run = upload ?? (backend?.uploadAttachment !== void 0 ? backend.uploadAttachment.bind(backend) : void 0);
|
|
1239
|
+
if (run === void 0) {
|
|
1240
|
+
patch(item.id, {
|
|
1241
|
+
status: "error",
|
|
1242
|
+
error: new AgentBackendUnsupportedError("uploadAttachment").message
|
|
1243
|
+
});
|
|
1244
|
+
return;
|
|
1245
|
+
}
|
|
1246
|
+
const controller = new AbortController();
|
|
1247
|
+
controllers.current.set(item.id, controller);
|
|
1248
|
+
run(item.file, {
|
|
1249
|
+
signal: controller.signal,
|
|
1250
|
+
onProgress: /* @__PURE__ */ __name((fraction) => patch(item.id, {
|
|
1251
|
+
progress: Math.max(0, Math.min(1, fraction))
|
|
1252
|
+
}), "onProgress")
|
|
1253
|
+
}).then((attachment) => {
|
|
1254
|
+
if (controller.signal.aborted) return;
|
|
1255
|
+
controllers.current.delete(item.id);
|
|
1256
|
+
patch(item.id, {
|
|
1257
|
+
status: "ready",
|
|
1258
|
+
progress: 1,
|
|
1259
|
+
attachment
|
|
1260
|
+
});
|
|
1261
|
+
}, (error) => {
|
|
1262
|
+
if (controller.signal.aborted) return;
|
|
1263
|
+
controllers.current.delete(item.id);
|
|
1264
|
+
patch(item.id, {
|
|
1265
|
+
status: "error",
|
|
1266
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1267
|
+
});
|
|
1268
|
+
});
|
|
1269
|
+
}, [
|
|
1270
|
+
patch
|
|
1271
|
+
]);
|
|
1272
|
+
const add = (0, import_react2.useCallback)((files) => {
|
|
1273
|
+
if (files == null) return;
|
|
1274
|
+
const { accept: accept2, maxBytes, maxFiles, describeRejection } = latest.current;
|
|
1275
|
+
const describe = /* @__PURE__ */ __name((reason, file) => describeRejection?.(reason, file) ?? DEFAULT_REJECTION[reason](file), "describe");
|
|
1276
|
+
let room = maxFiles === void 0 ? Number.POSITIVE_INFINITY : maxFiles - itemsRef.current.filter((item) => item.status !== "rejected").length;
|
|
1277
|
+
const staged = [];
|
|
1278
|
+
for (const file of Array.from(files)) {
|
|
1279
|
+
sequence += 1;
|
|
1280
|
+
const base = {
|
|
1281
|
+
id: `att-${sequence}`,
|
|
1282
|
+
file,
|
|
1283
|
+
name: file.name,
|
|
1284
|
+
size: file.size,
|
|
1285
|
+
type: file.type,
|
|
1286
|
+
progress: 0
|
|
1287
|
+
};
|
|
1288
|
+
const reason = !acceptsFile(accept2, file) ? "type" : maxBytes !== void 0 && file.size > maxBytes ? "size" : room <= 0 ? "count" : void 0;
|
|
1289
|
+
if (reason !== void 0) {
|
|
1290
|
+
staged.push({
|
|
1291
|
+
...base,
|
|
1292
|
+
status: "rejected",
|
|
1293
|
+
error: describe(reason, file)
|
|
1294
|
+
});
|
|
1295
|
+
continue;
|
|
1296
|
+
}
|
|
1297
|
+
room -= 1;
|
|
1298
|
+
const previewUrl = file.type.startsWith("image/") && typeof URL.createObjectURL === "function" ? URL.createObjectURL(file) : void 0;
|
|
1299
|
+
staged.push({
|
|
1300
|
+
...base,
|
|
1301
|
+
status: "uploading",
|
|
1302
|
+
...previewUrl ? {
|
|
1303
|
+
previewUrl
|
|
1304
|
+
} : {}
|
|
1305
|
+
});
|
|
1306
|
+
}
|
|
1307
|
+
if (staged.length === 0) return;
|
|
1308
|
+
setItems((current) => [
|
|
1309
|
+
...current,
|
|
1310
|
+
...staged
|
|
1311
|
+
]);
|
|
1312
|
+
for (const item of staged) {
|
|
1313
|
+
if (item.status === "uploading") start(item);
|
|
1314
|
+
}
|
|
1315
|
+
}, [
|
|
1316
|
+
start
|
|
1317
|
+
]);
|
|
1318
|
+
const release = (0, import_react2.useCallback)((item) => {
|
|
1319
|
+
if (item === void 0) return;
|
|
1320
|
+
controllers.current.get(item.id)?.abort();
|
|
1321
|
+
controllers.current.delete(item.id);
|
|
1322
|
+
if (item.previewUrl !== void 0 && typeof URL.revokeObjectURL === "function") {
|
|
1323
|
+
URL.revokeObjectURL(item.previewUrl);
|
|
1324
|
+
}
|
|
1325
|
+
}, []);
|
|
1326
|
+
const remove = (0, import_react2.useCallback)((id) => {
|
|
1327
|
+
release(itemsRef.current.find((item) => item.id === id));
|
|
1328
|
+
setItems((current) => current.filter((item) => item.id !== id));
|
|
1329
|
+
}, [
|
|
1330
|
+
release
|
|
1331
|
+
]);
|
|
1332
|
+
const clear = (0, import_react2.useCallback)(() => {
|
|
1333
|
+
for (const item of itemsRef.current) release(item);
|
|
1334
|
+
setItems([]);
|
|
1335
|
+
}, [
|
|
1336
|
+
release
|
|
1337
|
+
]);
|
|
1338
|
+
const retry = (0, import_react2.useCallback)((id) => {
|
|
1339
|
+
const item = itemsRef.current.find((candidate) => candidate.id === id);
|
|
1340
|
+
if (item === void 0 || item.status !== "error") return;
|
|
1341
|
+
const { error: _previous, ...rest } = item;
|
|
1342
|
+
const again = {
|
|
1343
|
+
...rest,
|
|
1344
|
+
status: "uploading",
|
|
1345
|
+
progress: 0
|
|
1346
|
+
};
|
|
1347
|
+
setItems((current) => current.map((candidate) => candidate.id === id ? again : candidate));
|
|
1348
|
+
start(again);
|
|
1349
|
+
}, [
|
|
1350
|
+
start
|
|
1351
|
+
]);
|
|
1352
|
+
(0, import_react2.useEffect)(() => () => {
|
|
1353
|
+
for (const item of itemsRef.current) release(item);
|
|
1354
|
+
}, [
|
|
1355
|
+
release
|
|
1356
|
+
]);
|
|
1357
|
+
const onPaste = (0, import_react2.useCallback)((event) => {
|
|
1358
|
+
const files = filesFromClipboard(event.clipboardData);
|
|
1359
|
+
if (files.length === 0) return;
|
|
1360
|
+
event.preventDefault();
|
|
1361
|
+
add(files);
|
|
1362
|
+
}, [
|
|
1363
|
+
add
|
|
1364
|
+
]);
|
|
1365
|
+
const dropZoneProps = (0, import_react2.useMemo)(() => ({
|
|
1366
|
+
onDragEnter: /* @__PURE__ */ __name((event) => {
|
|
1367
|
+
if (!dragHasFiles(event.dataTransfer)) return;
|
|
1368
|
+
event.preventDefault();
|
|
1369
|
+
setDragDepth((depth) => depth + 1);
|
|
1370
|
+
}, "onDragEnter"),
|
|
1371
|
+
onDragOver: /* @__PURE__ */ __name((event) => {
|
|
1372
|
+
if (dragHasFiles(event.dataTransfer)) event.preventDefault();
|
|
1373
|
+
}, "onDragOver"),
|
|
1374
|
+
onDragLeave: /* @__PURE__ */ __name((event) => {
|
|
1375
|
+
if (!dragHasFiles(event.dataTransfer)) return;
|
|
1376
|
+
setDragDepth((depth) => Math.max(0, depth - 1));
|
|
1377
|
+
}, "onDragLeave"),
|
|
1378
|
+
onDrop: /* @__PURE__ */ __name((event) => {
|
|
1379
|
+
if (!dragHasFiles(event.dataTransfer)) return;
|
|
1380
|
+
event.preventDefault();
|
|
1381
|
+
setDragDepth(0);
|
|
1382
|
+
add(event.dataTransfer?.files);
|
|
1383
|
+
}, "onDrop")
|
|
1384
|
+
}), [
|
|
1385
|
+
add
|
|
1386
|
+
]);
|
|
1387
|
+
const accept = options.accept;
|
|
1388
|
+
const inputProps = (0, import_react2.useMemo)(() => ({
|
|
1389
|
+
type: "file",
|
|
1390
|
+
accept: typeof accept === "string" ? accept : accept?.join(","),
|
|
1391
|
+
multiple: options.maxFiles === void 0 || options.maxFiles > 1,
|
|
1392
|
+
onChange: /* @__PURE__ */ __name((event) => {
|
|
1393
|
+
const input = event.currentTarget;
|
|
1394
|
+
add(input.files);
|
|
1395
|
+
input.value = "";
|
|
1396
|
+
}, "onChange")
|
|
1397
|
+
}), [
|
|
1398
|
+
accept,
|
|
1399
|
+
options.maxFiles,
|
|
1400
|
+
add
|
|
1401
|
+
]);
|
|
1402
|
+
return (0, import_react2.useMemo)(() => {
|
|
1403
|
+
const ready = items.filter((item) => item.status === "ready" && item.attachment !== void 0);
|
|
1404
|
+
const attachments = ready.map((item) => item.attachment);
|
|
1405
|
+
return {
|
|
1406
|
+
items,
|
|
1407
|
+
add,
|
|
1408
|
+
remove,
|
|
1409
|
+
retry,
|
|
1410
|
+
clear,
|
|
1411
|
+
isUploading: items.some((item) => item.status === "uploading"),
|
|
1412
|
+
attachments,
|
|
1413
|
+
refs: attachments.map((attachment) => ({
|
|
1414
|
+
mediaId: attachment.mediaId
|
|
1415
|
+
})),
|
|
1416
|
+
inputProps,
|
|
1417
|
+
dropZoneProps,
|
|
1418
|
+
isDragging: dragDepth > 0,
|
|
1419
|
+
onPaste
|
|
1420
|
+
};
|
|
1421
|
+
}, [
|
|
1422
|
+
items,
|
|
1423
|
+
add,
|
|
1424
|
+
remove,
|
|
1425
|
+
retry,
|
|
1426
|
+
clear,
|
|
1427
|
+
inputProps,
|
|
1428
|
+
dropZoneProps,
|
|
1429
|
+
dragDepth,
|
|
1430
|
+
onPaste
|
|
1431
|
+
]);
|
|
1432
|
+
}
|
|
1433
|
+
__name(useAttachments, "useAttachments");
|
|
1434
|
+
|
|
1102
1435
|
// src/catalog/use-agents.ts
|
|
1103
|
-
var
|
|
1436
|
+
var import_react4 = require("react");
|
|
1104
1437
|
|
|
1105
1438
|
// src/catalog/use-resource.ts
|
|
1106
|
-
var
|
|
1439
|
+
var import_react3 = require("react");
|
|
1107
1440
|
function useResource(load2, key, enabled) {
|
|
1108
|
-
const [data, setData] = (0,
|
|
1109
|
-
const [isLoading, setIsLoading] = (0,
|
|
1110
|
-
const [error, setError] = (0,
|
|
1111
|
-
const loadRef = (0,
|
|
1441
|
+
const [data, setData] = (0, import_react3.useState)(void 0);
|
|
1442
|
+
const [isLoading, setIsLoading] = (0, import_react3.useState)(enabled);
|
|
1443
|
+
const [error, setError] = (0, import_react3.useState)(null);
|
|
1444
|
+
const loadRef = (0, import_react3.useRef)(load2);
|
|
1112
1445
|
loadRef.current = load2;
|
|
1113
|
-
const generation = (0,
|
|
1114
|
-
const refresh = (0,
|
|
1446
|
+
const generation = (0, import_react3.useRef)(0);
|
|
1447
|
+
const refresh = (0, import_react3.useCallback)(async () => {
|
|
1115
1448
|
const mine = ++generation.current;
|
|
1116
1449
|
setIsLoading(true);
|
|
1117
1450
|
try {
|
|
@@ -1126,7 +1459,7 @@ function useResource(load2, key, enabled) {
|
|
|
1126
1459
|
if (mine === generation.current) setIsLoading(false);
|
|
1127
1460
|
}
|
|
1128
1461
|
}, []);
|
|
1129
|
-
(0,
|
|
1462
|
+
(0, import_react3.useEffect)(() => {
|
|
1130
1463
|
if (!enabled) return;
|
|
1131
1464
|
void refresh();
|
|
1132
1465
|
}, [
|
|
@@ -1147,7 +1480,7 @@ __name(useResource, "useResource");
|
|
|
1147
1480
|
function useAgents(options) {
|
|
1148
1481
|
const { backend, enabled = true } = options;
|
|
1149
1482
|
const { data, isLoading, error, refresh } = useResource(() => requireBackendMethod(backend, "listAgents")(), "", enabled);
|
|
1150
|
-
return (0,
|
|
1483
|
+
return (0, import_react4.useMemo)(() => {
|
|
1151
1484
|
const agents = data ?? [];
|
|
1152
1485
|
return {
|
|
1153
1486
|
agents,
|
|
@@ -1166,11 +1499,11 @@ function useAgents(options) {
|
|
|
1166
1499
|
__name(useAgents, "useAgents");
|
|
1167
1500
|
|
|
1168
1501
|
// src/catalog/use-models.ts
|
|
1169
|
-
var
|
|
1502
|
+
var import_react5 = require("react");
|
|
1170
1503
|
function useModels(options) {
|
|
1171
1504
|
const { backend, agent, enabled = true } = options;
|
|
1172
1505
|
const { data, isLoading, error, refresh } = useResource(() => requireBackendMethod(backend, "listModels")(agent), `${agent ?? ""}`, enabled);
|
|
1173
|
-
return (0,
|
|
1506
|
+
return (0, import_react5.useMemo)(() => {
|
|
1174
1507
|
const providers = data?.providers ?? [];
|
|
1175
1508
|
const models = providers.flatMap((provider) => provider.models.map((model) => ({
|
|
1176
1509
|
...model,
|
|
@@ -1200,7 +1533,7 @@ function useModels(options) {
|
|
|
1200
1533
|
__name(useModels, "useModels");
|
|
1201
1534
|
|
|
1202
1535
|
// src/quota/use-quota.ts
|
|
1203
|
-
var
|
|
1536
|
+
var import_react6 = require("react");
|
|
1204
1537
|
|
|
1205
1538
|
// src/threads/threads-events.ts
|
|
1206
1539
|
var listeners = /* @__PURE__ */ new WeakMap();
|
|
@@ -1227,7 +1560,7 @@ __name(onThreadsEvent, "onThreadsEvent");
|
|
|
1227
1560
|
function useQuota(options) {
|
|
1228
1561
|
const { backend, enabled = true, pollMs } = options;
|
|
1229
1562
|
const { data, isLoading, error, refresh } = useResource(() => requireBackendMethod(backend, "getQuota")(), "", enabled);
|
|
1230
|
-
(0,
|
|
1563
|
+
(0, import_react6.useEffect)(() => {
|
|
1231
1564
|
if (!enabled) return;
|
|
1232
1565
|
return onThreadsEvent(backend, (event) => {
|
|
1233
1566
|
if (event.type === "changed") void refresh();
|
|
@@ -1237,7 +1570,7 @@ function useQuota(options) {
|
|
|
1237
1570
|
enabled,
|
|
1238
1571
|
refresh
|
|
1239
1572
|
]);
|
|
1240
|
-
(0,
|
|
1573
|
+
(0, import_react6.useEffect)(() => {
|
|
1241
1574
|
if (!enabled || pollMs === void 0 || pollMs <= 0) return;
|
|
1242
1575
|
const timer = setInterval(() => void refresh(), pollMs);
|
|
1243
1576
|
return () => clearInterval(timer);
|
|
@@ -1246,7 +1579,7 @@ function useQuota(options) {
|
|
|
1246
1579
|
pollMs,
|
|
1247
1580
|
refresh
|
|
1248
1581
|
]);
|
|
1249
|
-
return (0,
|
|
1582
|
+
return (0, import_react6.useMemo)(() => {
|
|
1250
1583
|
const windows = data?.windows ?? [];
|
|
1251
1584
|
return {
|
|
1252
1585
|
report: data,
|
|
@@ -1268,27 +1601,27 @@ function useQuota(options) {
|
|
|
1268
1601
|
__name(useQuota, "useQuota");
|
|
1269
1602
|
|
|
1270
1603
|
// src/feedback/use-message-feedback.ts
|
|
1271
|
-
var
|
|
1604
|
+
var import_react7 = require("react");
|
|
1272
1605
|
function useMessageFeedback(options) {
|
|
1273
|
-
const latest = (0,
|
|
1606
|
+
const latest = (0, import_react7.useRef)(options);
|
|
1274
1607
|
latest.current = options;
|
|
1275
|
-
const [local, setLocal] = (0,
|
|
1276
|
-
const [pending, setPending] = (0,
|
|
1277
|
-
const [error, setError] = (0,
|
|
1278
|
-
const localRef = (0,
|
|
1608
|
+
const [local, setLocal] = (0, import_react7.useState)(/* @__PURE__ */ new Map());
|
|
1609
|
+
const [pending, setPending] = (0, import_react7.useState)(/* @__PURE__ */ new Set());
|
|
1610
|
+
const [error, setError] = (0, import_react7.useState)(null);
|
|
1611
|
+
const localRef = (0, import_react7.useRef)(local);
|
|
1279
1612
|
localRef.current = local;
|
|
1280
|
-
const resolved = (0,
|
|
1281
|
-
const feedbackOf = (0,
|
|
1613
|
+
const resolved = (0, import_react7.useRef)(/* @__PURE__ */ new Map());
|
|
1614
|
+
const feedbackOf = (0, import_react7.useCallback)((message) => {
|
|
1282
1615
|
const mine = local.get(message.id);
|
|
1283
1616
|
if (mine !== void 0) return mine.feedback;
|
|
1284
1617
|
return metadataOf(message).feedback ?? null;
|
|
1285
1618
|
}, [
|
|
1286
1619
|
local
|
|
1287
1620
|
]);
|
|
1288
|
-
const isPending = (0,
|
|
1621
|
+
const isPending = (0, import_react7.useCallback)((message) => pending.has(message.id), [
|
|
1289
1622
|
pending
|
|
1290
1623
|
]);
|
|
1291
|
-
const storedIdFor = (0,
|
|
1624
|
+
const storedIdFor = (0, import_react7.useCallback)(async (message) => {
|
|
1292
1625
|
const runId = metadataOf(message).runId;
|
|
1293
1626
|
if (runId === void 0) return message.id;
|
|
1294
1627
|
const known = resolved.current.get(message.id);
|
|
@@ -1308,7 +1641,7 @@ function useMessageFeedback(options) {
|
|
|
1308
1641
|
resolved.current.set(message.id, row.id);
|
|
1309
1642
|
return row.id;
|
|
1310
1643
|
}, []);
|
|
1311
|
-
const rate = (0,
|
|
1644
|
+
const rate = (0, import_react7.useCallback)(async (message, value, comment) => {
|
|
1312
1645
|
const setFeedback = requireBackendMethod(latest.current.backend, "setMessageFeedback");
|
|
1313
1646
|
const had = localRef.current.get(message.id);
|
|
1314
1647
|
const optimistic = value === null ? null : {
|
|
@@ -1354,7 +1687,7 @@ function useMessageFeedback(options) {
|
|
|
1354
1687
|
}, [
|
|
1355
1688
|
storedIdFor
|
|
1356
1689
|
]);
|
|
1357
|
-
const toggle = (0,
|
|
1690
|
+
const toggle = (0, import_react7.useCallback)((message, value) => {
|
|
1358
1691
|
const mine = localRef.current.get(message.id);
|
|
1359
1692
|
const current = mine !== void 0 ? mine.feedback : metadataOf(message).feedback ?? null;
|
|
1360
1693
|
return rate(message, current?.value === value ? null : value);
|
|
@@ -1377,16 +1710,16 @@ function metadataOf(message) {
|
|
|
1377
1710
|
__name(metadataOf, "metadataOf");
|
|
1378
1711
|
|
|
1379
1712
|
// src/threads/use-threads.ts
|
|
1380
|
-
var
|
|
1713
|
+
var import_react8 = require("react");
|
|
1381
1714
|
function useThreads(options) {
|
|
1382
1715
|
const { backend, enabled = true } = options;
|
|
1383
|
-
const [threads, setThreads] = (0,
|
|
1384
|
-
const [isLoading, setIsLoading] = (0,
|
|
1385
|
-
const [error, setError] = (0,
|
|
1386
|
-
const threadsRef = (0,
|
|
1716
|
+
const [threads, setThreads] = (0, import_react8.useState)([]);
|
|
1717
|
+
const [isLoading, setIsLoading] = (0, import_react8.useState)(enabled);
|
|
1718
|
+
const [error, setError] = (0, import_react8.useState)(null);
|
|
1719
|
+
const threadsRef = (0, import_react8.useRef)(threads);
|
|
1387
1720
|
threadsRef.current = threads;
|
|
1388
|
-
const generation = (0,
|
|
1389
|
-
const refresh = (0,
|
|
1721
|
+
const generation = (0, import_react8.useRef)(0);
|
|
1722
|
+
const refresh = (0, import_react8.useCallback)(async () => {
|
|
1390
1723
|
const mine = ++generation.current;
|
|
1391
1724
|
setIsLoading(true);
|
|
1392
1725
|
try {
|
|
@@ -1403,7 +1736,7 @@ function useThreads(options) {
|
|
|
1403
1736
|
}, [
|
|
1404
1737
|
backend
|
|
1405
1738
|
]);
|
|
1406
|
-
(0,
|
|
1739
|
+
(0, import_react8.useEffect)(() => {
|
|
1407
1740
|
if (!enabled) return;
|
|
1408
1741
|
void refresh();
|
|
1409
1742
|
return onThreadsEvent(backend, (event) => {
|
|
@@ -1423,7 +1756,7 @@ function useThreads(options) {
|
|
|
1423
1756
|
enabled,
|
|
1424
1757
|
refresh
|
|
1425
1758
|
]);
|
|
1426
|
-
const rename = (0,
|
|
1759
|
+
const rename = (0, import_react8.useCallback)(async (id, title) => {
|
|
1427
1760
|
const before = threadsRef.current;
|
|
1428
1761
|
setThreads((current) => current.map((thread) => thread.id === id ? {
|
|
1429
1762
|
...thread,
|
|
@@ -1445,7 +1778,7 @@ function useThreads(options) {
|
|
|
1445
1778
|
}, [
|
|
1446
1779
|
backend
|
|
1447
1780
|
]);
|
|
1448
|
-
const remove = (0,
|
|
1781
|
+
const remove = (0, import_react8.useCallback)(async (id) => {
|
|
1449
1782
|
const before = threadsRef.current;
|
|
1450
1783
|
setThreads((current) => current.filter((thread) => thread.id !== id));
|
|
1451
1784
|
try {
|
|
@@ -1519,11 +1852,29 @@ function backgroundRunsFromThread(messages) {
|
|
|
1519
1852
|
}
|
|
1520
1853
|
__name(backgroundRunsFromThread, "backgroundRunsFromThread");
|
|
1521
1854
|
|
|
1855
|
+
// src/components/ambient-ui.ts
|
|
1856
|
+
var import_react9 = require("react");
|
|
1857
|
+
function sharedContext(key) {
|
|
1858
|
+
const symbol = Symbol.for(key);
|
|
1859
|
+
const holder = globalThis;
|
|
1860
|
+
const existing = holder[symbol];
|
|
1861
|
+
if (existing !== void 0) return existing;
|
|
1862
|
+
const created = (0, import_react9.createContext)(null);
|
|
1863
|
+
holder[symbol] = created;
|
|
1864
|
+
return created;
|
|
1865
|
+
}
|
|
1866
|
+
__name(sharedContext, "sharedContext");
|
|
1867
|
+
var AmbientRenderUiContext = sharedContext("@dudousxd/nestjs-agent-react:ambient-render-ui");
|
|
1868
|
+
function useAmbientRenderUi() {
|
|
1869
|
+
return (0, import_react9.useContext)(AmbientRenderUiContext);
|
|
1870
|
+
}
|
|
1871
|
+
__name(useAmbientRenderUi, "useAmbientRenderUi");
|
|
1872
|
+
|
|
1522
1873
|
// src/components/chat-input.tsx
|
|
1523
|
-
var
|
|
1874
|
+
var import_react11 = __toESM(require("react"), 1);
|
|
1524
1875
|
|
|
1525
1876
|
// src/components/use-speech-recognition.ts
|
|
1526
|
-
var
|
|
1877
|
+
var import_react10 = require("react");
|
|
1527
1878
|
function getRecognitionCtor() {
|
|
1528
1879
|
if (typeof window === "undefined") return null;
|
|
1529
1880
|
const scope = window;
|
|
@@ -1531,15 +1882,15 @@ function getRecognitionCtor() {
|
|
|
1531
1882
|
}
|
|
1532
1883
|
__name(getRecognitionCtor, "getRecognitionCtor");
|
|
1533
1884
|
function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTranscript }) {
|
|
1534
|
-
const recognitionRef = (0,
|
|
1535
|
-
const [isListening, setIsListening] = (0,
|
|
1536
|
-
const ctor = (0,
|
|
1885
|
+
const recognitionRef = (0, import_react10.useRef)(null);
|
|
1886
|
+
const [isListening, setIsListening] = (0, import_react10.useState)(false);
|
|
1887
|
+
const ctor = (0, import_react10.useMemo)(() => getRecognitionCtor(), []);
|
|
1537
1888
|
const isSupported = ctor !== null;
|
|
1538
|
-
const finalRef = (0,
|
|
1539
|
-
const interimRef = (0,
|
|
1889
|
+
const finalRef = (0, import_react10.useRef)(onFinalTranscript);
|
|
1890
|
+
const interimRef = (0, import_react10.useRef)(onInterimTranscript);
|
|
1540
1891
|
finalRef.current = onFinalTranscript;
|
|
1541
1892
|
interimRef.current = onInterimTranscript;
|
|
1542
|
-
(0,
|
|
1893
|
+
(0, import_react10.useEffect)(() => {
|
|
1543
1894
|
if (!ctor) return;
|
|
1544
1895
|
const recognition = new ctor();
|
|
1545
1896
|
recognition.lang = lang;
|
|
@@ -1578,7 +1929,7 @@ function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTran
|
|
|
1578
1929
|
ctor,
|
|
1579
1930
|
lang
|
|
1580
1931
|
]);
|
|
1581
|
-
const start = (0,
|
|
1932
|
+
const start = (0, import_react10.useCallback)(() => {
|
|
1582
1933
|
const recognition = recognitionRef.current;
|
|
1583
1934
|
if (!recognition) return;
|
|
1584
1935
|
try {
|
|
@@ -1588,7 +1939,7 @@ function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTran
|
|
|
1588
1939
|
console.warn("SpeechRecognition start failed", error);
|
|
1589
1940
|
}
|
|
1590
1941
|
}, []);
|
|
1591
|
-
const stop = (0,
|
|
1942
|
+
const stop = (0, import_react10.useCallback)(() => {
|
|
1592
1943
|
const recognition = recognitionRef.current;
|
|
1593
1944
|
if (!recognition) return;
|
|
1594
1945
|
try {
|
|
@@ -1607,8 +1958,8 @@ __name(useSpeechRecognition, "useSpeechRecognition");
|
|
|
1607
1958
|
|
|
1608
1959
|
// src/components/chat-input.tsx
|
|
1609
1960
|
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,
|
|
1961
|
+
const [value, setValue] = (0, import_react11.useState)("");
|
|
1962
|
+
const [interim, setInterim] = (0, import_react11.useState)("");
|
|
1612
1963
|
const speech = useSpeechRecognition({
|
|
1613
1964
|
lang: speechLang,
|
|
1614
1965
|
onFinalTranscript: /* @__PURE__ */ __name((text) => {
|
|
@@ -1619,7 +1970,7 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
|
|
|
1619
1970
|
}, "onFinalTranscript"),
|
|
1620
1971
|
onInterimTranscript: /* @__PURE__ */ __name((text) => setInterim(text), "onInterimTranscript")
|
|
1621
1972
|
});
|
|
1622
|
-
(0,
|
|
1973
|
+
(0, import_react11.useEffect)(() => {
|
|
1623
1974
|
if (!speech.isListening) setInterim("");
|
|
1624
1975
|
}, [
|
|
1625
1976
|
speech.isListening
|
|
@@ -1647,9 +1998,9 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
|
|
|
1647
1998
|
const displayValue = speech.isListening && interim ? `${value}${value && !value.endsWith(" ") ? " " : ""}${interim}` : value;
|
|
1648
1999
|
const showMic = enableSpeech && speech.isSupported;
|
|
1649
2000
|
const showStop = isStreaming && onStop !== void 0;
|
|
1650
|
-
return /* @__PURE__ */
|
|
2001
|
+
return /* @__PURE__ */ import_react11.default.createElement("div", {
|
|
1651
2002
|
className
|
|
1652
|
-
}, /* @__PURE__ */
|
|
2003
|
+
}, /* @__PURE__ */ import_react11.default.createElement("textarea", {
|
|
1653
2004
|
className: textareaClassName,
|
|
1654
2005
|
rows,
|
|
1655
2006
|
value: displayValue,
|
|
@@ -1660,17 +2011,17 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
|
|
|
1660
2011
|
}, "onChange"),
|
|
1661
2012
|
onKeyDown: handleKeyDown,
|
|
1662
2013
|
placeholder: placeholder ?? "Ask something (Enter to send, Shift+Enter for newline)"
|
|
1663
|
-
}), /* @__PURE__ */
|
|
2014
|
+
}), /* @__PURE__ */ import_react11.default.createElement("button", {
|
|
1664
2015
|
type: "button",
|
|
1665
2016
|
className: sendButtonClassName,
|
|
1666
2017
|
onClick: submit,
|
|
1667
2018
|
disabled: disabled || !value.trim()
|
|
1668
|
-
}, sendLabel), showStop ? /* @__PURE__ */
|
|
2019
|
+
}, sendLabel), showStop ? /* @__PURE__ */ import_react11.default.createElement("button", {
|
|
1669
2020
|
type: "button",
|
|
1670
2021
|
className: stopButtonClassName,
|
|
1671
2022
|
onClick: /* @__PURE__ */ __name(() => void onStop(), "onClick"),
|
|
1672
2023
|
"aria-label": "Stop generating"
|
|
1673
|
-
}, stopLabel) : null, showMic ? /* @__PURE__ */
|
|
2024
|
+
}, stopLabel) : null, showMic ? /* @__PURE__ */ import_react11.default.createElement("button", {
|
|
1674
2025
|
type: "button",
|
|
1675
2026
|
className: micButtonClassName,
|
|
1676
2027
|
onClick: toggleMic,
|
|
@@ -1683,10 +2034,10 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
|
|
|
1683
2034
|
__name(ChatInput, "ChatInput");
|
|
1684
2035
|
|
|
1685
2036
|
// src/components/message-item.tsx
|
|
1686
|
-
var
|
|
2037
|
+
var import_react14 = __toESM(require("react"), 1);
|
|
1687
2038
|
|
|
1688
2039
|
// src/transcript/use-chat-transcript.ts
|
|
1689
|
-
var
|
|
2040
|
+
var import_react13 = require("react");
|
|
1690
2041
|
|
|
1691
2042
|
// src/transcript/model.ts
|
|
1692
2043
|
var import_nestjs_agent_core2 = require("@dudousxd/nestjs-agent-core");
|
|
@@ -2663,11 +3014,11 @@ function formatCostUsd(cost) {
|
|
|
2663
3014
|
__name(formatCostUsd, "formatCostUsd");
|
|
2664
3015
|
|
|
2665
3016
|
// src/transcript/use-stick-to-bottom.ts
|
|
2666
|
-
var
|
|
3017
|
+
var import_react12 = require("react");
|
|
2667
3018
|
function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
2668
|
-
const containerRef = (0,
|
|
2669
|
-
const [isAtBottom, setIsAtBottom] = (0,
|
|
2670
|
-
const measure = (0,
|
|
3019
|
+
const containerRef = (0, import_react12.useRef)(null);
|
|
3020
|
+
const [isAtBottom, setIsAtBottom] = (0, import_react12.useState)(true);
|
|
3021
|
+
const measure = (0, import_react12.useCallback)(() => {
|
|
2671
3022
|
const element = containerRef.current;
|
|
2672
3023
|
if (!element) {
|
|
2673
3024
|
return;
|
|
@@ -2677,7 +3028,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
|
2677
3028
|
}, [
|
|
2678
3029
|
threshold
|
|
2679
3030
|
]);
|
|
2680
|
-
const scrollToBottom = (0,
|
|
3031
|
+
const scrollToBottom = (0, import_react12.useCallback)(() => {
|
|
2681
3032
|
const element = containerRef.current;
|
|
2682
3033
|
if (!element) {
|
|
2683
3034
|
return;
|
|
@@ -2685,7 +3036,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
|
2685
3036
|
element.scrollTop = element.scrollHeight;
|
|
2686
3037
|
setIsAtBottom(true);
|
|
2687
3038
|
}, []);
|
|
2688
|
-
const setContainer = (0,
|
|
3039
|
+
const setContainer = (0, import_react12.useCallback)((element) => {
|
|
2689
3040
|
containerRef.current = element;
|
|
2690
3041
|
if (element) {
|
|
2691
3042
|
measure();
|
|
@@ -2693,7 +3044,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
|
2693
3044
|
}, [
|
|
2694
3045
|
measure
|
|
2695
3046
|
]);
|
|
2696
|
-
(0,
|
|
3047
|
+
(0, import_react12.useEffect)(() => {
|
|
2697
3048
|
if (isAtBottom) {
|
|
2698
3049
|
scrollToBottom();
|
|
2699
3050
|
}
|
|
@@ -2702,7 +3053,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
|
2702
3053
|
isAtBottom,
|
|
2703
3054
|
scrollToBottom
|
|
2704
3055
|
]);
|
|
2705
|
-
const getContainerProps = (0,
|
|
3056
|
+
const getContainerProps = (0, import_react12.useCallback)(() => ({
|
|
2706
3057
|
ref: setContainer,
|
|
2707
3058
|
onScroll: measure
|
|
2708
3059
|
}), [
|
|
@@ -2724,14 +3075,14 @@ var DEFAULT_LOAD_EARLIER_STEP = 50;
|
|
|
2724
3075
|
var DEFAULT_COPY_RESET_MS = 1500;
|
|
2725
3076
|
function useChatTranscript(options) {
|
|
2726
3077
|
const { messages, status, initialVisibleCount = DEFAULT_VISIBLE_COUNT, loadEarlierStep = DEFAULT_LOAD_EARLIER_STEP, followUps, stickToBottomThreshold } = options;
|
|
2727
|
-
const latest = (0,
|
|
3078
|
+
const latest = (0, import_react13.useRef)(options);
|
|
2728
3079
|
latest.current = options;
|
|
2729
|
-
const [visibleCount, setVisibleCount] = (0,
|
|
2730
|
-
const [stopRequested, setStopRequested] = (0,
|
|
3080
|
+
const [visibleCount, setVisibleCount] = (0, import_react13.useState)(initialVisibleCount);
|
|
3081
|
+
const [stopRequested, setStopRequested] = (0, import_react13.useState)(false);
|
|
2731
3082
|
const isStreaming = status === "streaming" || status === "reconnecting";
|
|
2732
3083
|
const isBusy = status === "submitted" || isStreaming;
|
|
2733
3084
|
const isEmpty = messages.length === 0;
|
|
2734
|
-
(0,
|
|
3085
|
+
(0, import_react13.useEffect)(() => {
|
|
2735
3086
|
if (!isBusy) {
|
|
2736
3087
|
setStopRequested(false);
|
|
2737
3088
|
}
|
|
@@ -2748,7 +3099,7 @@ function useChatTranscript(options) {
|
|
|
2748
3099
|
streamingMessageId,
|
|
2749
3100
|
options
|
|
2750
3101
|
});
|
|
2751
|
-
const stop = (0,
|
|
3102
|
+
const stop = (0, import_react13.useCallback)(() => {
|
|
2752
3103
|
const current = latest.current;
|
|
2753
3104
|
if (current.status !== "submitted" && current.status !== "streaming" && current.status !== "reconnecting") {
|
|
2754
3105
|
return;
|
|
@@ -2756,8 +3107,8 @@ function useChatTranscript(options) {
|
|
|
2756
3107
|
setStopRequested(true);
|
|
2757
3108
|
void current.onStop?.();
|
|
2758
3109
|
}, []);
|
|
2759
|
-
const loadEarlier = (0,
|
|
2760
|
-
const showAll = (0,
|
|
3110
|
+
const loadEarlier = (0, import_react13.useCallback)(() => setVisibleCount((count) => count + (latest.current.loadEarlierStep ?? DEFAULT_LOAD_EARLIER_STEP)), []);
|
|
3111
|
+
const showAll = (0, import_react13.useCallback)(() => setVisibleCount(latest.current.messages.length), []);
|
|
2761
3112
|
const scroll = useStickToBottom({
|
|
2762
3113
|
contentKey: contentSignature(messages),
|
|
2763
3114
|
...stickToBottomThreshold !== void 0 ? {
|
|
@@ -2793,7 +3144,7 @@ function useChatTranscript(options) {
|
|
|
2793
3144
|
__name(useChatTranscript, "useChatTranscript");
|
|
2794
3145
|
function useTranscriptItem(options) {
|
|
2795
3146
|
const { message, isStreaming = false } = options;
|
|
2796
|
-
const messagesRef = (0,
|
|
3147
|
+
const messagesRef = (0, import_react13.useRef)([
|
|
2797
3148
|
message
|
|
2798
3149
|
]);
|
|
2799
3150
|
if (messagesRef.current[0] !== message) {
|
|
@@ -2811,13 +3162,13 @@ function useTranscriptItem(options) {
|
|
|
2811
3162
|
}
|
|
2812
3163
|
__name(useTranscriptItem, "useTranscriptItem");
|
|
2813
3164
|
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,
|
|
3165
|
+
const [drafts, setDrafts] = (0, import_react13.useState)(() => /* @__PURE__ */ new Map());
|
|
3166
|
+
const [copied, setCopied] = (0, import_react13.useState)(() => /* @__PURE__ */ new Set());
|
|
3167
|
+
const [openReasoning, setOpenReasoning] = (0, import_react13.useState)(() => /* @__PURE__ */ new Map());
|
|
3168
|
+
const [picks, setPicks] = (0, import_react13.useState)(() => /* @__PURE__ */ new Map());
|
|
3169
|
+
const [settling, setSettling] = (0, import_react13.useState)(() => /* @__PURE__ */ new Map());
|
|
3170
|
+
const [settleErrors, setSettleErrors] = (0, import_react13.useState)(() => /* @__PURE__ */ new Map());
|
|
3171
|
+
const latest = (0, import_react13.useRef)({
|
|
2821
3172
|
options,
|
|
2822
3173
|
drafts,
|
|
2823
3174
|
picks,
|
|
@@ -2829,23 +3180,23 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2829
3180
|
picks,
|
|
2830
3181
|
messages
|
|
2831
3182
|
};
|
|
2832
|
-
const copyTimers = (0,
|
|
2833
|
-
(0,
|
|
3183
|
+
const copyTimers = (0, import_react13.useRef)(/* @__PURE__ */ new Map());
|
|
3184
|
+
(0, import_react13.useEffect)(() => () => {
|
|
2834
3185
|
for (const timer of copyTimers.current.values()) {
|
|
2835
3186
|
clearTimeout(timer);
|
|
2836
3187
|
}
|
|
2837
3188
|
copyTimers.current.clear();
|
|
2838
3189
|
}, []);
|
|
2839
|
-
const callbackCache = (0,
|
|
2840
|
-
const reasoningToggleCache = (0,
|
|
2841
|
-
const toggleReasoning = (0,
|
|
3190
|
+
const callbackCache = (0, import_react13.useRef)(/* @__PURE__ */ new Map());
|
|
3191
|
+
const reasoningToggleCache = (0, import_react13.useRef)(/* @__PURE__ */ new Map());
|
|
3192
|
+
const toggleReasoning = (0, import_react13.useCallback)((key, open) => {
|
|
2842
3193
|
setOpenReasoning((current) => {
|
|
2843
3194
|
const next = new Map(current);
|
|
2844
3195
|
next.set(key, open ?? !(current.get(key) ?? false));
|
|
2845
3196
|
return next;
|
|
2846
3197
|
});
|
|
2847
3198
|
}, []);
|
|
2848
|
-
const stableToggle = (0,
|
|
3199
|
+
const stableToggle = (0, import_react13.useCallback)((key) => {
|
|
2849
3200
|
let cached = reasoningToggleCache.current.get(key);
|
|
2850
3201
|
if (!cached) {
|
|
2851
3202
|
cached = /* @__PURE__ */ __name((open) => toggleReasoning(key, open), "cached");
|
|
@@ -2855,10 +3206,10 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2855
3206
|
}, [
|
|
2856
3207
|
toggleReasoning
|
|
2857
3208
|
]);
|
|
2858
|
-
const pick = (0,
|
|
3209
|
+
const pick = (0, import_react13.useCallback)((toolCallId, questionId, values) => {
|
|
2859
3210
|
setPicks((current) => new Map(current).set(pickKey(toolCallId, questionId), values));
|
|
2860
3211
|
}, []);
|
|
2861
|
-
const settle = (0,
|
|
3212
|
+
const settle = (0, import_react13.useCallback)((toolCallId, action, send) => {
|
|
2862
3213
|
setSettleErrors((current) => {
|
|
2863
3214
|
if (!current.has(toolCallId)) {
|
|
2864
3215
|
return current;
|
|
@@ -2882,7 +3233,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2882
3233
|
failed(error);
|
|
2883
3234
|
}
|
|
2884
3235
|
}, []);
|
|
2885
|
-
const answer = (0,
|
|
3236
|
+
const answer = (0, import_react13.useCallback)((toolCallId) => {
|
|
2886
3237
|
const current = latest.current;
|
|
2887
3238
|
const onAnswer = current.options.onAnswer;
|
|
2888
3239
|
if (!onAnswer) {
|
|
@@ -2892,7 +3243,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2892
3243
|
}, [
|
|
2893
3244
|
settle
|
|
2894
3245
|
]);
|
|
2895
|
-
const skip = (0,
|
|
3246
|
+
const skip = (0, import_react13.useCallback)((toolCallId) => {
|
|
2896
3247
|
const onSkip = latest.current.options.onSkip;
|
|
2897
3248
|
if (onSkip) {
|
|
2898
3249
|
settle(toolCallId, "skip", () => onSkip(toolCallId));
|
|
@@ -2900,7 +3251,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2900
3251
|
}, [
|
|
2901
3252
|
settle
|
|
2902
3253
|
]);
|
|
2903
|
-
const approve = (0,
|
|
3254
|
+
const approve = (0, import_react13.useCallback)((toolCallId, options2) => {
|
|
2904
3255
|
const onApprove = latest.current.options.onApprove;
|
|
2905
3256
|
if (onApprove) {
|
|
2906
3257
|
settle(toolCallId, "approve", () => options2 === void 0 ? onApprove(toolCallId) : onApprove(toolCallId, options2));
|
|
@@ -2908,7 +3259,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2908
3259
|
}, [
|
|
2909
3260
|
settle
|
|
2910
3261
|
]);
|
|
2911
|
-
const reject = (0,
|
|
3262
|
+
const reject = (0, import_react13.useCallback)((toolCallId) => {
|
|
2912
3263
|
const onReject = latest.current.options.onReject;
|
|
2913
3264
|
if (onReject) {
|
|
2914
3265
|
settle(toolCallId, "reject", () => onReject(toolCallId));
|
|
@@ -2916,7 +3267,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2916
3267
|
}, [
|
|
2917
3268
|
settle
|
|
2918
3269
|
]);
|
|
2919
|
-
const callbacksFor = (0,
|
|
3270
|
+
const callbacksFor = (0, import_react13.useCallback)((id) => {
|
|
2920
3271
|
const cached = callbackCache.current.get(id);
|
|
2921
3272
|
if (cached) {
|
|
2922
3273
|
return cached;
|
|
@@ -3158,59 +3509,64 @@ function MessageItem({ message, isStreaming = false, editable, onEditSubmit, reg
|
|
|
3158
3509
|
getCreatedAt: /* @__PURE__ */ __name(() => createdAt, "getCreatedAt")
|
|
3159
3510
|
} : {}
|
|
3160
3511
|
});
|
|
3161
|
-
return /* @__PURE__ */
|
|
3512
|
+
return /* @__PURE__ */ import_react14.default.createElement(MessageItemView, {
|
|
3162
3513
|
item,
|
|
3163
3514
|
...slots
|
|
3164
3515
|
});
|
|
3165
3516
|
}
|
|
3166
3517
|
__name(MessageItem, "MessageItem");
|
|
3167
|
-
function MessageItemView({ item, ...
|
|
3518
|
+
function MessageItemView({ item, ...given }) {
|
|
3519
|
+
const ambientRenderUi = useAmbientRenderUi();
|
|
3520
|
+
const slots = given.renderUi === void 0 && ambientRenderUi !== null ? {
|
|
3521
|
+
...given,
|
|
3522
|
+
renderUi: ambientRenderUi
|
|
3523
|
+
} : given;
|
|
3168
3524
|
const { classNames } = slots;
|
|
3169
|
-
const actionRow = /* @__PURE__ */
|
|
3525
|
+
const actionRow = /* @__PURE__ */ import_react14.default.createElement("div", {
|
|
3170
3526
|
className: classNames?.actions,
|
|
3171
3527
|
"data-actions-for": item.role
|
|
3172
|
-
}, item.copy.available ? /* @__PURE__ */
|
|
3528
|
+
}, item.copy.available ? /* @__PURE__ */ import_react14.default.createElement("button", {
|
|
3173
3529
|
type: "button",
|
|
3174
3530
|
onClick: item.copy.copy,
|
|
3175
3531
|
className: classNames?.actionButton,
|
|
3176
3532
|
title: item.copy.copied ? "Copied!" : "Copy message text"
|
|
3177
|
-
}, item.copy.copied ? "Copied" : "Copy") : null, item.fork.available ? /* @__PURE__ */
|
|
3533
|
+
}, item.copy.copied ? "Copied" : "Copy") : null, item.fork.available ? /* @__PURE__ */ import_react14.default.createElement("button", {
|
|
3178
3534
|
type: "button",
|
|
3179
3535
|
onClick: item.fork.run,
|
|
3180
3536
|
className: classNames?.actionButton,
|
|
3181
3537
|
title: "Fork thread from this message"
|
|
3182
|
-
}, "Fork") : null, item.regenerate.available ? /* @__PURE__ */
|
|
3538
|
+
}, "Fork") : null, item.regenerate.available ? /* @__PURE__ */ import_react14.default.createElement("button", {
|
|
3183
3539
|
type: "button",
|
|
3184
3540
|
onClick: item.regenerate.run,
|
|
3185
3541
|
className: classNames?.actionButton,
|
|
3186
3542
|
title: "Regenerate response"
|
|
3187
|
-
}, "Regenerate") : null, slots.meta, !item.isUser && item.usage ? /* @__PURE__ */
|
|
3543
|
+
}, "Regenerate") : null, slots.meta, !item.isUser && item.usage ? /* @__PURE__ */ import_react14.default.createElement("span", {
|
|
3188
3544
|
className: classNames?.usage,
|
|
3189
3545
|
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__ */
|
|
3546
|
+
}, item.usage.costLabel, " \xB7 ", item.usage.tokensLabel) : null, item.timestamp ? /* @__PURE__ */ import_react14.default.createElement("span", {
|
|
3191
3547
|
className: classNames?.timestamp,
|
|
3192
3548
|
title: item.timestamp.absolute
|
|
3193
3549
|
}, item.timestamp.relative) : null);
|
|
3194
3550
|
if (item.edit.available) {
|
|
3195
|
-
return /* @__PURE__ */
|
|
3551
|
+
return /* @__PURE__ */ import_react14.default.createElement(EditableUserBubble, {
|
|
3196
3552
|
item,
|
|
3197
3553
|
slots,
|
|
3198
3554
|
actions: actionRow
|
|
3199
3555
|
});
|
|
3200
3556
|
}
|
|
3201
3557
|
const className = joinClasses(classNames?.root, classNames?.byRole?.[item.role]);
|
|
3202
|
-
return /* @__PURE__ */
|
|
3558
|
+
return /* @__PURE__ */ import_react14.default.createElement("div", {
|
|
3203
3559
|
className,
|
|
3204
3560
|
"data-role": item.role,
|
|
3205
3561
|
"data-streaming": item.isStreaming ? "true" : void 0
|
|
3206
|
-
}, /* @__PURE__ */
|
|
3562
|
+
}, /* @__PURE__ */ import_react14.default.createElement("div", null, renderBlocks(item, slots)), actionRow);
|
|
3207
3563
|
}
|
|
3208
3564
|
__name(MessageItemView, "MessageItemView");
|
|
3209
3565
|
function renderBlocks(item, slots) {
|
|
3210
3566
|
const nodes = [];
|
|
3211
3567
|
for (const block of item.blocks) {
|
|
3212
3568
|
if (block.kind === "text") {
|
|
3213
|
-
nodes.push(/* @__PURE__ */
|
|
3569
|
+
nodes.push(/* @__PURE__ */ import_react14.default.createElement("div", {
|
|
3214
3570
|
key: block.key,
|
|
3215
3571
|
className: slots.classNames?.text
|
|
3216
3572
|
}, slots.renderText ? slots.renderText(block.text, {
|
|
@@ -3231,7 +3587,7 @@ function renderBlocks(item, slots) {
|
|
|
3231
3587
|
continue;
|
|
3232
3588
|
}
|
|
3233
3589
|
if (block.kind === "ui" && slots.renderUi) {
|
|
3234
|
-
nodes.push(/* @__PURE__ */
|
|
3590
|
+
nodes.push(/* @__PURE__ */ import_react14.default.createElement("div", {
|
|
3235
3591
|
key: block.key,
|
|
3236
3592
|
"data-slot": "ui",
|
|
3237
3593
|
"data-component": block.component
|
|
@@ -3242,18 +3598,18 @@ function renderBlocks(item, slots) {
|
|
|
3242
3598
|
}
|
|
3243
3599
|
__name(renderBlocks, "renderBlocks");
|
|
3244
3600
|
function renderFilesBlock(block, slots) {
|
|
3245
|
-
return /* @__PURE__ */
|
|
3601
|
+
return /* @__PURE__ */ import_react14.default.createElement("div", {
|
|
3246
3602
|
key: block.key,
|
|
3247
3603
|
className: slots.classNames?.files,
|
|
3248
3604
|
"data-files": "true"
|
|
3249
|
-
}, slots.renderFiles ? slots.renderFiles(block.files) : block.files.map((file) => /* @__PURE__ */
|
|
3605
|
+
}, slots.renderFiles ? slots.renderFiles(block.files) : block.files.map((file) => /* @__PURE__ */ import_react14.default.createElement("a", {
|
|
3250
3606
|
key: file.url,
|
|
3251
3607
|
href: file.url,
|
|
3252
3608
|
target: "_blank",
|
|
3253
3609
|
rel: "noreferrer",
|
|
3254
3610
|
className: slots.classNames?.file,
|
|
3255
3611
|
title: file.filename ?? file.mediaType
|
|
3256
|
-
}, file.isImage ? /* @__PURE__ */
|
|
3612
|
+
}, file.isImage ? /* @__PURE__ */ import_react14.default.createElement("img", {
|
|
3257
3613
|
src: file.url,
|
|
3258
3614
|
alt: file.filename ?? "image",
|
|
3259
3615
|
className: slots.classNames?.fileImage
|
|
@@ -3261,17 +3617,17 @@ function renderFilesBlock(block, slots) {
|
|
|
3261
3617
|
}
|
|
3262
3618
|
__name(renderFilesBlock, "renderFilesBlock");
|
|
3263
3619
|
function renderReasoningBlock(block, slots) {
|
|
3264
|
-
return /* @__PURE__ */
|
|
3620
|
+
return /* @__PURE__ */ import_react14.default.createElement("div", {
|
|
3265
3621
|
key: block.key,
|
|
3266
3622
|
className: slots.classNames?.reasoning,
|
|
3267
3623
|
"data-reasoning": "true",
|
|
3268
3624
|
"data-streaming": block.isStreaming ? "true" : void 0
|
|
3269
|
-
}, /* @__PURE__ */
|
|
3625
|
+
}, /* @__PURE__ */ import_react14.default.createElement("button", {
|
|
3270
3626
|
type: "button",
|
|
3271
3627
|
className: slots.classNames?.reasoningToggle,
|
|
3272
3628
|
onClick: /* @__PURE__ */ __name(() => block.toggle(), "onClick"),
|
|
3273
3629
|
"aria-expanded": block.isOpen
|
|
3274
|
-
}, slots.reasoningLabel ?? "Reasoning"), block.isOpen ? /* @__PURE__ */
|
|
3630
|
+
}, slots.reasoningLabel ?? "Reasoning"), block.isOpen ? /* @__PURE__ */ import_react14.default.createElement("div", {
|
|
3275
3631
|
className: slots.classNames?.reasoningText
|
|
3276
3632
|
}, slots.renderReasoning ? slots.renderReasoning(block.text, {
|
|
3277
3633
|
isStreaming: block.isStreaming,
|
|
@@ -3282,7 +3638,7 @@ __name(renderReasoningBlock, "renderReasoningBlock");
|
|
|
3282
3638
|
function renderToolBlock(item, block, slots) {
|
|
3283
3639
|
if (slots.renderToolGroup) {
|
|
3284
3640
|
return [
|
|
3285
|
-
/* @__PURE__ */
|
|
3641
|
+
/* @__PURE__ */ import_react14.default.createElement(import_react14.default.Fragment, {
|
|
3286
3642
|
key: block.key
|
|
3287
3643
|
}, slots.renderToolGroup(block.parts, block.key))
|
|
3288
3644
|
];
|
|
@@ -3293,7 +3649,7 @@ function renderToolBlock(item, block, slots) {
|
|
|
3293
3649
|
const renderToolPart = slots.renderToolPart;
|
|
3294
3650
|
return block.parts.map((part) => {
|
|
3295
3651
|
const partKey = `${item.id}-${part.toolCallId}`;
|
|
3296
|
-
return /* @__PURE__ */
|
|
3652
|
+
return /* @__PURE__ */ import_react14.default.createElement(import_react14.default.Fragment, {
|
|
3297
3653
|
key: partKey
|
|
3298
3654
|
}, renderToolPart(part, partKey));
|
|
3299
3655
|
});
|
|
@@ -3303,14 +3659,14 @@ function EditableUserBubble({ item, slots, actions }) {
|
|
|
3303
3659
|
const { classNames } = slots;
|
|
3304
3660
|
const { edit } = item;
|
|
3305
3661
|
if (!edit.isEditing) {
|
|
3306
|
-
return /* @__PURE__ */
|
|
3662
|
+
return /* @__PURE__ */ import_react14.default.createElement("div", {
|
|
3307
3663
|
className: joinClasses(classNames?.root, classNames?.byRole?.user),
|
|
3308
3664
|
"data-role": "user"
|
|
3309
|
-
}, /* @__PURE__ */
|
|
3665
|
+
}, /* @__PURE__ */ import_react14.default.createElement("div", {
|
|
3310
3666
|
className: classNames?.text
|
|
3311
3667
|
}, slots.renderText ? slots.renderText(item.text, {
|
|
3312
3668
|
isStreaming: false
|
|
3313
|
-
}) : item.text), /* @__PURE__ */
|
|
3669
|
+
}) : item.text), /* @__PURE__ */ import_react14.default.createElement("button", {
|
|
3314
3670
|
type: "button",
|
|
3315
3671
|
onClick: edit.start,
|
|
3316
3672
|
className: classNames?.actionButton,
|
|
@@ -3318,18 +3674,18 @@ function EditableUserBubble({ item, slots, actions }) {
|
|
|
3318
3674
|
}, "Edit"), actions);
|
|
3319
3675
|
}
|
|
3320
3676
|
const textareaProps = edit.getTextareaProps();
|
|
3321
|
-
return /* @__PURE__ */
|
|
3677
|
+
return /* @__PURE__ */ import_react14.default.createElement("div", {
|
|
3322
3678
|
"data-editing": "true"
|
|
3323
|
-
}, /* @__PURE__ */
|
|
3679
|
+
}, /* @__PURE__ */ import_react14.default.createElement("textarea", {
|
|
3324
3680
|
...textareaProps,
|
|
3325
3681
|
rows: Math.min(8, edit.draft.split("\n").length + 1),
|
|
3326
3682
|
className: classNames?.editTextarea
|
|
3327
|
-
}), /* @__PURE__ */
|
|
3683
|
+
}), /* @__PURE__ */ import_react14.default.createElement("div", {
|
|
3328
3684
|
className: classNames?.editActions
|
|
3329
|
-
}, /* @__PURE__ */
|
|
3685
|
+
}, /* @__PURE__ */ import_react14.default.createElement("button", {
|
|
3330
3686
|
type: "button",
|
|
3331
3687
|
onClick: edit.cancel
|
|
3332
|
-
}, "Cancel"), /* @__PURE__ */
|
|
3688
|
+
}, "Cancel"), /* @__PURE__ */ import_react14.default.createElement("button", {
|
|
3333
3689
|
type: "button",
|
|
3334
3690
|
onClick: edit.save,
|
|
3335
3691
|
disabled: !edit.canSave
|
|
@@ -3573,35 +3929,35 @@ function toItem(entry) {
|
|
|
3573
3929
|
__name(toItem, "toItem");
|
|
3574
3930
|
|
|
3575
3931
|
// src/composer/use-composer-autocomplete.ts
|
|
3576
|
-
var
|
|
3932
|
+
var import_react15 = require("react");
|
|
3577
3933
|
function useComposerAutocomplete(options) {
|
|
3578
3934
|
const { value, sources, acceptOnTab = true } = options;
|
|
3579
|
-
const latest = (0,
|
|
3935
|
+
const latest = (0, import_react15.useRef)(options);
|
|
3580
3936
|
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,
|
|
3937
|
+
const inputRef = (0, import_react15.useRef)(null);
|
|
3938
|
+
const [caret, setCaret] = (0, import_react15.useState)(value.length);
|
|
3939
|
+
const [items, setItems] = (0, import_react15.useState)([]);
|
|
3940
|
+
const [isLoading, setLoading] = (0, import_react15.useState)(false);
|
|
3941
|
+
const [error, setError] = (0, import_react15.useState)(null);
|
|
3942
|
+
const [activeIndex, setActiveIndex] = (0, import_react15.useState)(0);
|
|
3943
|
+
const [dismissedIndex, setDismissedIndex] = (0, import_react15.useState)(null);
|
|
3588
3944
|
const safeCaret = Math.min(caret, value.length);
|
|
3589
|
-
const match = (0,
|
|
3945
|
+
const match = (0, import_react15.useMemo)(() => findActiveTrigger(value, safeCaret, sources), [
|
|
3590
3946
|
value,
|
|
3591
3947
|
safeCaret,
|
|
3592
3948
|
sources
|
|
3593
3949
|
]);
|
|
3594
3950
|
const isActive = match !== null && dismissedIndex !== match.index;
|
|
3595
|
-
const matchRef = (0,
|
|
3951
|
+
const matchRef = (0, import_react15.useRef)(match);
|
|
3596
3952
|
matchRef.current = match;
|
|
3597
|
-
const caretRef = (0,
|
|
3953
|
+
const caretRef = (0, import_react15.useRef)(safeCaret);
|
|
3598
3954
|
caretRef.current = safeCaret;
|
|
3599
|
-
const itemsRef = (0,
|
|
3955
|
+
const itemsRef = (0, import_react15.useRef)(items);
|
|
3600
3956
|
itemsRef.current = items;
|
|
3601
|
-
const activeIndexRef = (0,
|
|
3957
|
+
const activeIndexRef = (0, import_react15.useRef)(activeIndex);
|
|
3602
3958
|
activeIndexRef.current = activeIndex;
|
|
3603
3959
|
const requestKey = isActive && match ? `${match.source.id}\0${match.query}` : null;
|
|
3604
|
-
(0,
|
|
3960
|
+
(0, import_react15.useEffect)(() => {
|
|
3605
3961
|
const current = matchRef.current;
|
|
3606
3962
|
if (requestKey === null || current === null) {
|
|
3607
3963
|
setItems([]);
|
|
@@ -3649,25 +4005,25 @@ function useComposerAutocomplete(options) {
|
|
|
3649
4005
|
]);
|
|
3650
4006
|
const isOpen = isActive;
|
|
3651
4007
|
const activeItem = isOpen ? items[activeIndex] ?? null : null;
|
|
3652
|
-
const reactId = (0,
|
|
4008
|
+
const reactId = (0, import_react15.useId)();
|
|
3653
4009
|
const listboxId = options.id ?? `agent-autocomplete-${reactId}`;
|
|
3654
|
-
const optionId = (0,
|
|
4010
|
+
const optionId = (0, import_react15.useCallback)((index) => `${listboxId}-option-${index}`, [
|
|
3655
4011
|
listboxId
|
|
3656
4012
|
]);
|
|
3657
|
-
const highlight = (0,
|
|
4013
|
+
const highlight = (0, import_react15.useCallback)((index) => {
|
|
3658
4014
|
const total = itemsRef.current.length;
|
|
3659
4015
|
if (total === 0) return;
|
|
3660
4016
|
setActiveIndex((index % total + total) % total);
|
|
3661
4017
|
}, []);
|
|
3662
|
-
const moveHighlight = (0,
|
|
4018
|
+
const moveHighlight = (0, import_react15.useCallback)((delta) => highlight(activeIndexRef.current + delta), [
|
|
3663
4019
|
highlight
|
|
3664
4020
|
]);
|
|
3665
|
-
const dismiss = (0,
|
|
4021
|
+
const dismiss = (0, import_react15.useCallback)(() => {
|
|
3666
4022
|
const current = matchRef.current;
|
|
3667
4023
|
if (current) setDismissedIndex(current.index);
|
|
3668
4024
|
}, []);
|
|
3669
|
-
const pendingCaret = (0,
|
|
3670
|
-
const accept = (0,
|
|
4025
|
+
const pendingCaret = (0, import_react15.useRef)(null);
|
|
4026
|
+
const accept = (0, import_react15.useCallback)((item) => {
|
|
3671
4027
|
const current = matchRef.current;
|
|
3672
4028
|
if (!current) return;
|
|
3673
4029
|
const chosen = item ?? itemsRef.current[activeIndexRef.current];
|
|
@@ -3678,16 +4034,16 @@ function useComposerAutocomplete(options) {
|
|
|
3678
4034
|
setDismissedIndex(null);
|
|
3679
4035
|
pendingCaret.current = edit.caret;
|
|
3680
4036
|
}, []);
|
|
3681
|
-
(0,
|
|
4037
|
+
(0, import_react15.useLayoutEffect)(() => {
|
|
3682
4038
|
const position = pendingCaret.current;
|
|
3683
4039
|
if (position === null) return;
|
|
3684
4040
|
pendingCaret.current = null;
|
|
3685
4041
|
inputRef.current?.setSelectionRange(position, position);
|
|
3686
4042
|
});
|
|
3687
|
-
const readCaret = (0,
|
|
4043
|
+
const readCaret = (0, import_react15.useCallback)((element) => {
|
|
3688
4044
|
setCaret(element.selectionStart ?? element.value.length);
|
|
3689
4045
|
}, []);
|
|
3690
|
-
const onKeyDown = (0,
|
|
4046
|
+
const onKeyDown = (0, import_react15.useCallback)((event) => {
|
|
3691
4047
|
if (!isOpen) return;
|
|
3692
4048
|
const hasItems = itemsRef.current.length > 0;
|
|
3693
4049
|
switch (event.key) {
|
|
@@ -3725,23 +4081,23 @@ function useComposerAutocomplete(options) {
|
|
|
3725
4081
|
dismiss,
|
|
3726
4082
|
moveHighlight
|
|
3727
4083
|
]);
|
|
3728
|
-
const onChange = (0,
|
|
4084
|
+
const onChange = (0, import_react15.useCallback)((event) => {
|
|
3729
4085
|
readCaret(event.target);
|
|
3730
4086
|
const next = findActiveTrigger(event.target.value, event.target.selectionStart ?? event.target.value.length, latest.current.sources);
|
|
3731
4087
|
setDismissedIndex((current) => current !== null && next?.index === current ? current : null);
|
|
3732
4088
|
}, [
|
|
3733
4089
|
readCaret
|
|
3734
4090
|
]);
|
|
3735
|
-
const onSelect = (0,
|
|
4091
|
+
const onSelect = (0, import_react15.useCallback)((event) => readCaret(event.currentTarget), [
|
|
3736
4092
|
readCaret
|
|
3737
4093
|
]);
|
|
3738
|
-
const onClick = (0,
|
|
4094
|
+
const onClick = (0, import_react15.useCallback)((event) => readCaret(event.currentTarget), [
|
|
3739
4095
|
readCaret
|
|
3740
4096
|
]);
|
|
3741
|
-
const setInput = (0,
|
|
4097
|
+
const setInput = (0, import_react15.useCallback)((element) => {
|
|
3742
4098
|
inputRef.current = element;
|
|
3743
4099
|
}, []);
|
|
3744
|
-
const getInputProps = (0,
|
|
4100
|
+
const getInputProps = (0, import_react15.useCallback)(() => ({
|
|
3745
4101
|
ref: setInput,
|
|
3746
4102
|
onChange,
|
|
3747
4103
|
onKeyDown,
|
|
@@ -3769,7 +4125,7 @@ function useComposerAutocomplete(options) {
|
|
|
3769
4125
|
activeIndex,
|
|
3770
4126
|
optionId
|
|
3771
4127
|
]);
|
|
3772
|
-
const getListboxProps = (0,
|
|
4128
|
+
const getListboxProps = (0, import_react15.useCallback)(() => ({
|
|
3773
4129
|
id: listboxId,
|
|
3774
4130
|
role: "listbox",
|
|
3775
4131
|
"aria-label": match?.source.label ?? match?.source.id ?? "Suggestions"
|
|
@@ -3777,7 +4133,7 @@ function useComposerAutocomplete(options) {
|
|
|
3777
4133
|
listboxId,
|
|
3778
4134
|
match
|
|
3779
4135
|
]);
|
|
3780
|
-
const getOptionProps = (0,
|
|
4136
|
+
const getOptionProps = (0, import_react15.useCallback)((index) => ({
|
|
3781
4137
|
id: optionId(index),
|
|
3782
4138
|
role: "option",
|
|
3783
4139
|
"aria-selected": index === activeIndex
|
|
@@ -3811,7 +4167,7 @@ function isPromise(value) {
|
|
|
3811
4167
|
__name(isPromise, "isPromise");
|
|
3812
4168
|
|
|
3813
4169
|
// src/presentation/use-tool-catalog.ts
|
|
3814
|
-
var
|
|
4170
|
+
var import_react16 = require("react");
|
|
3815
4171
|
var shared = /* @__PURE__ */ new WeakMap();
|
|
3816
4172
|
function load(client, agent) {
|
|
3817
4173
|
let byAgent = shared.get(client);
|
|
@@ -3835,11 +4191,11 @@ function load(client, agent) {
|
|
|
3835
4191
|
__name(load, "load");
|
|
3836
4192
|
function useToolCatalog(options) {
|
|
3837
4193
|
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,
|
|
4194
|
+
const [entries, setEntries] = (0, import_react16.useState)([]);
|
|
4195
|
+
const [isLoading, setLoading] = (0, import_react16.useState)(enabled);
|
|
4196
|
+
const [error, setError] = (0, import_react16.useState)(null);
|
|
4197
|
+
const [generation, setGeneration] = (0, import_react16.useState)(0);
|
|
4198
|
+
(0, import_react16.useEffect)(() => {
|
|
3843
4199
|
if (!enabled) {
|
|
3844
4200
|
setLoading(false);
|
|
3845
4201
|
return;
|
|
@@ -3865,14 +4221,14 @@ function useToolCatalog(options) {
|
|
|
3865
4221
|
enabled,
|
|
3866
4222
|
generation
|
|
3867
4223
|
]);
|
|
3868
|
-
const refresh = (0,
|
|
4224
|
+
const refresh = (0, import_react16.useCallback)(() => {
|
|
3869
4225
|
shared.get(client)?.delete(agent ?? "");
|
|
3870
4226
|
setGeneration((current) => current + 1);
|
|
3871
4227
|
}, [
|
|
3872
4228
|
client,
|
|
3873
4229
|
agent
|
|
3874
4230
|
]);
|
|
3875
|
-
const catalog = (0,
|
|
4231
|
+
const catalog = (0, import_react16.useMemo)(() => toolCatalogFrom(entries), [
|
|
3876
4232
|
entries
|
|
3877
4233
|
]);
|
|
3878
4234
|
return {
|
|
@@ -3886,7 +4242,7 @@ function useToolCatalog(options) {
|
|
|
3886
4242
|
__name(useToolCatalog, "useToolCatalog");
|
|
3887
4243
|
|
|
3888
4244
|
// src/approvals/countdown.ts
|
|
3889
|
-
var
|
|
4245
|
+
var import_react17 = require("react");
|
|
3890
4246
|
function approvalCountdown(expiresAt, now = Date.now()) {
|
|
3891
4247
|
const deadline = expiresAt == null ? Number.NaN : Date.parse(expiresAt);
|
|
3892
4248
|
if (!Number.isFinite(deadline)) {
|
|
@@ -3904,10 +4260,10 @@ function approvalCountdown(expiresAt, now = Date.now()) {
|
|
|
3904
4260
|
__name(approvalCountdown, "approvalCountdown");
|
|
3905
4261
|
function useApprovalCountdown(expiresAt, options = {}) {
|
|
3906
4262
|
const { intervalMs = 1e3 } = options;
|
|
3907
|
-
const nowRef = (0,
|
|
4263
|
+
const nowRef = (0, import_react17.useRef)(options.now ?? Date.now);
|
|
3908
4264
|
nowRef.current = options.now ?? Date.now;
|
|
3909
|
-
const [state, setState] = (0,
|
|
3910
|
-
(0,
|
|
4265
|
+
const [state, setState] = (0, import_react17.useState)(() => approvalCountdown(expiresAt, nowRef.current()));
|
|
4266
|
+
(0, import_react17.useEffect)(() => {
|
|
3911
4267
|
const read = /* @__PURE__ */ __name(() => approvalCountdown(expiresAt, nowRef.current()), "read");
|
|
3912
4268
|
const first = read();
|
|
3913
4269
|
setState(first);
|
|
@@ -3970,7 +4326,13 @@ function storedMessageToUiMessage(message) {
|
|
|
3970
4326
|
type: "file",
|
|
3971
4327
|
mediaType: attachment.contentType,
|
|
3972
4328
|
filename: attachment.name,
|
|
3973
|
-
url: attachment.url
|
|
4329
|
+
url: attachment.url,
|
|
4330
|
+
// The stored id rides along, so a replayed file can be referenced again (`messageFiles`).
|
|
4331
|
+
providerMetadata: {
|
|
4332
|
+
agent: {
|
|
4333
|
+
mediaId: attachment.mediaId
|
|
4334
|
+
}
|
|
4335
|
+
}
|
|
3974
4336
|
});
|
|
3975
4337
|
}
|
|
3976
4338
|
const toolCallIds = new Set((message.toolCalls ?? []).map((call) => call.id));
|
|
@@ -4148,21 +4510,21 @@ function sumUsage(rows) {
|
|
|
4148
4510
|
__name(sumUsage, "sumUsage");
|
|
4149
4511
|
|
|
4150
4512
|
// src/use-agent-chat.ts
|
|
4151
|
-
var
|
|
4152
|
-
var
|
|
4513
|
+
var import_react18 = require("@ai-sdk/react");
|
|
4514
|
+
var import_react19 = require("react");
|
|
4153
4515
|
function useAgentChat(options) {
|
|
4154
|
-
const latest = (0,
|
|
4516
|
+
const latest = (0, import_react19.useRef)(options);
|
|
4155
4517
|
latest.current = options;
|
|
4156
|
-
const [runId, setRunId] = (0,
|
|
4157
|
-
const runIdRef = (0,
|
|
4518
|
+
const [runId, setRunId] = (0, import_react19.useState)(options.resumeRunId);
|
|
4519
|
+
const runIdRef = (0, import_react19.useRef)(runId);
|
|
4158
4520
|
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,
|
|
4521
|
+
const settlingRunIdRef = (0, import_react19.useRef)(void 0);
|
|
4522
|
+
const autoResumeRunIdRef = (0, import_react19.useRef)(void 0);
|
|
4523
|
+
const [autoResume, setAutoResume] = (0, import_react19.useState)(false);
|
|
4524
|
+
const [activeRunId, setActiveRunId] = (0, import_react19.useState)(null);
|
|
4525
|
+
const regenerateNext = (0, import_react19.useRef)(false);
|
|
4526
|
+
const createdThreadId = (0, import_react19.useRef)(void 0);
|
|
4527
|
+
const client = (0, import_react19.useMemo)(() => {
|
|
4166
4528
|
if (options.backend) return options.backend;
|
|
4167
4529
|
if (options.client) return options.client;
|
|
4168
4530
|
return new AgentClient({
|
|
@@ -4178,11 +4540,11 @@ function useAgentChat(options) {
|
|
|
4178
4540
|
getHeaders: /* @__PURE__ */ __name(async () => mergeHeaders(latest.current), "getHeaders")
|
|
4179
4541
|
});
|
|
4180
4542
|
}, []);
|
|
4181
|
-
const [connection, setConnection] = (0,
|
|
4543
|
+
const [connection, setConnection] = (0, import_react19.useState)({
|
|
4182
4544
|
status: "live"
|
|
4183
4545
|
});
|
|
4184
|
-
const resyncAfterSettle = (0,
|
|
4185
|
-
(0,
|
|
4546
|
+
const resyncAfterSettle = (0, import_react19.useRef)(false);
|
|
4547
|
+
(0, import_react19.useEffect)(() => {
|
|
4186
4548
|
if (!options.resume || options.threadId === void 0) return;
|
|
4187
4549
|
let cancelled = false;
|
|
4188
4550
|
const threadId = options.threadId;
|
|
@@ -4202,7 +4564,7 @@ function useAgentChat(options) {
|
|
|
4202
4564
|
options.resume,
|
|
4203
4565
|
options.threadId
|
|
4204
4566
|
]);
|
|
4205
|
-
const transport = (0,
|
|
4567
|
+
const transport = (0, import_react19.useMemo)(() => {
|
|
4206
4568
|
function onMeta(meta) {
|
|
4207
4569
|
settlingRunIdRef.current = meta.runId;
|
|
4208
4570
|
setRunId(meta.runId);
|
|
@@ -4257,8 +4619,8 @@ function useAgentChat(options) {
|
|
|
4257
4619
|
}, "onAttemptStart")
|
|
4258
4620
|
});
|
|
4259
4621
|
}, []);
|
|
4260
|
-
const backgroundRef = (0,
|
|
4261
|
-
const chat = (0,
|
|
4622
|
+
const backgroundRef = (0, import_react19.useRef)(() => Promise.resolve());
|
|
4623
|
+
const chat = (0, import_react18.useChat)({
|
|
4262
4624
|
transport,
|
|
4263
4625
|
resume: options.resumeRunId !== void 0 || autoResume,
|
|
4264
4626
|
...options.threadId !== void 0 ? {
|
|
@@ -4306,7 +4668,7 @@ function useAgentChat(options) {
|
|
|
4306
4668
|
}
|
|
4307
4669
|
}, "onFinish")
|
|
4308
4670
|
});
|
|
4309
|
-
const chatRef = (0,
|
|
4671
|
+
const chatRef = (0, import_react19.useRef)(chat);
|
|
4310
4672
|
chatRef.current = chat;
|
|
4311
4673
|
async function resyncFromThread() {
|
|
4312
4674
|
const threadId = latest.current.threadId ?? createdThreadId.current;
|
|
@@ -4318,11 +4680,11 @@ function useAgentChat(options) {
|
|
|
4318
4680
|
}
|
|
4319
4681
|
}
|
|
4320
4682
|
__name(resyncFromThread, "resyncFromThread");
|
|
4321
|
-
const turnInFlight = (0,
|
|
4322
|
-
const isTurnInFlight = (0,
|
|
4683
|
+
const turnInFlight = (0, import_react19.useRef)(false);
|
|
4684
|
+
const isTurnInFlight = (0, import_react19.useCallback)(() => turnInFlight.current || transport.isAttemptLive, [
|
|
4323
4685
|
transport
|
|
4324
4686
|
]);
|
|
4325
|
-
const sendMessage = (0,
|
|
4687
|
+
const sendMessage = (0, import_react19.useCallback)(async (...args) => {
|
|
4326
4688
|
const blocked = latest.current.blocked;
|
|
4327
4689
|
if (blocked != null) throw new QuotaBlockedError(blocked);
|
|
4328
4690
|
if (isTurnInFlight()) return;
|
|
@@ -4335,15 +4697,15 @@ function useAgentChat(options) {
|
|
|
4335
4697
|
}, [
|
|
4336
4698
|
isTurnInFlight
|
|
4337
4699
|
]);
|
|
4338
|
-
const addToolResult = (0,
|
|
4700
|
+
const addToolResult = (0, import_react19.useCallback)(({ tool, toolCallId, output }) => chatRef.current.addToolResult({
|
|
4339
4701
|
tool,
|
|
4340
4702
|
toolCallId,
|
|
4341
4703
|
output
|
|
4342
4704
|
}), []);
|
|
4343
|
-
const [threads, setThreads] = (0,
|
|
4344
|
-
const [quota, setQuota] = (0,
|
|
4345
|
-
const [backgroundRuns, setBackgroundRuns] = (0,
|
|
4346
|
-
const refreshBackground = (0,
|
|
4705
|
+
const [threads, setThreads] = (0, import_react19.useState)([]);
|
|
4706
|
+
const [quota, setQuota] = (0, import_react19.useState)(null);
|
|
4707
|
+
const [backgroundRuns, setBackgroundRuns] = (0, import_react19.useState)([]);
|
|
4708
|
+
const refreshBackground = (0, import_react19.useCallback)(async () => {
|
|
4347
4709
|
const threadId = latest.current.threadId ?? createdThreadId.current;
|
|
4348
4710
|
if (threadId === void 0) {
|
|
4349
4711
|
return;
|
|
@@ -4368,7 +4730,7 @@ function useAgentChat(options) {
|
|
|
4368
4730
|
]);
|
|
4369
4731
|
backgroundRef.current = refreshBackground;
|
|
4370
4732
|
const isWorking = backgroundRuns.some((run) => run.status === "running");
|
|
4371
|
-
(0,
|
|
4733
|
+
(0, import_react19.useEffect)(() => {
|
|
4372
4734
|
if (options.background !== true || options.threadId === void 0) {
|
|
4373
4735
|
return;
|
|
4374
4736
|
}
|
|
@@ -4378,7 +4740,7 @@ function useAgentChat(options) {
|
|
|
4378
4740
|
options.threadId,
|
|
4379
4741
|
refreshBackground
|
|
4380
4742
|
]);
|
|
4381
|
-
(0,
|
|
4743
|
+
(0, import_react19.useEffect)(() => {
|
|
4382
4744
|
const every = latest.current.backgroundPollMs ?? 5e3;
|
|
4383
4745
|
if (latest.current.background !== true || !isWorking || every <= 0) {
|
|
4384
4746
|
return;
|
|
@@ -4389,26 +4751,26 @@ function useAgentChat(options) {
|
|
|
4389
4751
|
isWorking,
|
|
4390
4752
|
refreshBackground
|
|
4391
4753
|
]);
|
|
4392
|
-
const loadThreads = (0,
|
|
4754
|
+
const loadThreads = (0, import_react19.useCallback)(async () => {
|
|
4393
4755
|
const list = await client.listThreads();
|
|
4394
4756
|
setThreads(list);
|
|
4395
4757
|
return list;
|
|
4396
4758
|
}, [
|
|
4397
4759
|
client
|
|
4398
4760
|
]);
|
|
4399
|
-
const loadThread = (0,
|
|
4761
|
+
const loadThread = (0, import_react19.useCallback)((id) => client.getThread(id), [
|
|
4400
4762
|
client
|
|
4401
4763
|
]);
|
|
4402
|
-
const deleteThread = (0,
|
|
4764
|
+
const deleteThread = (0, import_react19.useCallback)(async (id) => {
|
|
4403
4765
|
await client.deleteThread(id);
|
|
4404
4766
|
setThreads((current) => current.filter((thread) => thread.id !== id));
|
|
4405
4767
|
}, [
|
|
4406
4768
|
client
|
|
4407
4769
|
]);
|
|
4408
|
-
const forkThread = (0,
|
|
4770
|
+
const forkThread = (0, import_react19.useCallback)((threadId, messageId) => requireBackendMethod(client, "forkFromMessage")(threadId, messageId), [
|
|
4409
4771
|
client
|
|
4410
4772
|
]);
|
|
4411
|
-
const renameThread = (0,
|
|
4773
|
+
const renameThread = (0, import_react19.useCallback)(async (id, title) => {
|
|
4412
4774
|
await client.updateThread(id, {
|
|
4413
4775
|
title
|
|
4414
4776
|
});
|
|
@@ -4419,24 +4781,24 @@ function useAgentChat(options) {
|
|
|
4419
4781
|
}, [
|
|
4420
4782
|
client
|
|
4421
4783
|
]);
|
|
4422
|
-
const promoteThread = (0,
|
|
4784
|
+
const promoteThread = (0, import_react19.useCallback)(async (id) => {
|
|
4423
4785
|
await requireBackendMethod(client, "promoteThread")(id);
|
|
4424
4786
|
await loadThreads();
|
|
4425
4787
|
}, [
|
|
4426
4788
|
client,
|
|
4427
4789
|
loadThreads
|
|
4428
4790
|
]);
|
|
4429
|
-
const truncateFromMessage = (0,
|
|
4791
|
+
const truncateFromMessage = (0, import_react19.useCallback)((threadId, messageId) => requireBackendMethod(client, "truncateFromMessage")(threadId, messageId).then(() => void 0), [
|
|
4430
4792
|
client
|
|
4431
4793
|
]);
|
|
4432
|
-
const loadQuota = (0,
|
|
4794
|
+
const loadQuota = (0, import_react19.useCallback)(async () => {
|
|
4433
4795
|
const today = await requireBackendMethod(client, "getQuotaToday")();
|
|
4434
4796
|
setQuota(today);
|
|
4435
4797
|
return today;
|
|
4436
4798
|
}, [
|
|
4437
4799
|
client
|
|
4438
4800
|
]);
|
|
4439
|
-
const cancel = (0,
|
|
4801
|
+
const cancel = (0, import_react19.useCallback)(async () => {
|
|
4440
4802
|
chatRef.current.stop();
|
|
4441
4803
|
const activeRunId2 = runIdRef.current;
|
|
4442
4804
|
if (activeRunId2) {
|
|
@@ -4448,7 +4810,7 @@ function useAgentChat(options) {
|
|
|
4448
4810
|
}, [
|
|
4449
4811
|
client
|
|
4450
4812
|
]);
|
|
4451
|
-
const approve = (0,
|
|
4813
|
+
const approve = (0, import_react19.useCallback)(async ({ toolCallId, remember, via }) => {
|
|
4452
4814
|
await requireBackendMethod(client, "approveToolCall")({
|
|
4453
4815
|
toolCallId,
|
|
4454
4816
|
...remember === true ? {
|
|
@@ -4461,7 +4823,7 @@ function useAgentChat(options) {
|
|
|
4461
4823
|
}, [
|
|
4462
4824
|
client
|
|
4463
4825
|
]);
|
|
4464
|
-
const reject = (0,
|
|
4826
|
+
const reject = (0, import_react19.useCallback)(async ({ toolCallId, reason, via }) => {
|
|
4465
4827
|
await requireBackendMethod(client, "rejectToolCall")({
|
|
4466
4828
|
toolCallId,
|
|
4467
4829
|
...reason !== void 0 ? {
|
|
@@ -4474,7 +4836,7 @@ function useAgentChat(options) {
|
|
|
4474
4836
|
}, [
|
|
4475
4837
|
client
|
|
4476
4838
|
]);
|
|
4477
|
-
const answer = (0,
|
|
4839
|
+
const answer = (0, import_react19.useCallback)(async ({ toolCallId, answers }) => {
|
|
4478
4840
|
await requireBackendMethod(client, "answerToolCall")({
|
|
4479
4841
|
toolCallId,
|
|
4480
4842
|
...answers !== void 0 ? {
|
|
@@ -4484,14 +4846,14 @@ function useAgentChat(options) {
|
|
|
4484
4846
|
}, [
|
|
4485
4847
|
client
|
|
4486
4848
|
]);
|
|
4487
|
-
const skip = (0,
|
|
4849
|
+
const skip = (0, import_react19.useCallback)(async ({ toolCallId }) => {
|
|
4488
4850
|
await requireBackendMethod(client, "skipToolCall")({
|
|
4489
4851
|
toolCallId
|
|
4490
4852
|
});
|
|
4491
4853
|
}, [
|
|
4492
4854
|
client
|
|
4493
4855
|
]);
|
|
4494
|
-
const regenerate = (0,
|
|
4856
|
+
const regenerate = (0, import_react19.useCallback)(() => {
|
|
4495
4857
|
const blocked = latest.current.blocked;
|
|
4496
4858
|
if (blocked != null) throw new QuotaBlockedError(blocked);
|
|
4497
4859
|
if (isTurnInFlight()) return;
|
|
@@ -4508,7 +4870,7 @@ function useAgentChat(options) {
|
|
|
4508
4870
|
isWorking,
|
|
4509
4871
|
refresh: refreshBackground
|
|
4510
4872
|
};
|
|
4511
|
-
const setThreadModel = (0,
|
|
4873
|
+
const setThreadModel = (0, import_react19.useCallback)(async (model) => {
|
|
4512
4874
|
const threadId = latest.current.threadId ?? createdThreadId.current;
|
|
4513
4875
|
if (threadId === void 0) {
|
|
4514
4876
|
throw new Error("setThreadModel: this chat has no thread yet");
|
|
@@ -4522,7 +4884,7 @@ function useAgentChat(options) {
|
|
|
4522
4884
|
}, [
|
|
4523
4885
|
client
|
|
4524
4886
|
]);
|
|
4525
|
-
const getThreadId = (0,
|
|
4887
|
+
const getThreadId = (0, import_react19.useCallback)(() => latest.current.threadId ?? createdThreadId.current, []);
|
|
4526
4888
|
const status = connection.status === "reconnecting" ? "reconnecting" : chat.status;
|
|
4527
4889
|
return {
|
|
4528
4890
|
...chat,
|
|
@@ -4589,6 +4951,7 @@ __name(mergeHeaders, "mergeHeaders");
|
|
|
4589
4951
|
AgentChatTransport,
|
|
4590
4952
|
AgentClient,
|
|
4591
4953
|
AgentHttpError,
|
|
4954
|
+
AmbientRenderUiContext,
|
|
4592
4955
|
ChatInput,
|
|
4593
4956
|
DEFAULT_SPEECH_LANG,
|
|
4594
4957
|
MessageItem,
|
|
@@ -4596,6 +4959,7 @@ __name(mergeHeaders, "mergeHeaders");
|
|
|
4596
4959
|
MessageList,
|
|
4597
4960
|
QuotaBlockedError,
|
|
4598
4961
|
SPEECH_LANGUAGES,
|
|
4962
|
+
acceptsFile,
|
|
4599
4963
|
applyCompletion,
|
|
4600
4964
|
approvalCountdown,
|
|
4601
4965
|
backgroundRunsFromThread,
|
|
@@ -4606,7 +4970,10 @@ __name(mergeHeaders, "mergeHeaders");
|
|
|
4606
4970
|
describeTimestamp,
|
|
4607
4971
|
describeToolCall,
|
|
4608
4972
|
describeUsage,
|
|
4973
|
+
dragHasFiles,
|
|
4609
4974
|
extractMessageText,
|
|
4975
|
+
fileKind,
|
|
4976
|
+
filesFromClipboard,
|
|
4610
4977
|
fillTemplate,
|
|
4611
4978
|
filterAutocompleteItems,
|
|
4612
4979
|
findActiveTrigger,
|
|
@@ -4616,6 +4983,7 @@ __name(mergeHeaders, "mergeHeaders");
|
|
|
4616
4983
|
inferResultView,
|
|
4617
4984
|
isActionCall,
|
|
4618
4985
|
loadStoredSpeechLang,
|
|
4986
|
+
messageFiles,
|
|
4619
4987
|
notifyThreads,
|
|
4620
4988
|
onThreadsEvent,
|
|
4621
4989
|
persistSpeechLang,
|
|
@@ -4630,7 +4998,9 @@ __name(mergeHeaders, "mergeHeaders");
|
|
|
4630
4998
|
toolCatalogFrom,
|
|
4631
4999
|
useAgentChat,
|
|
4632
5000
|
useAgents,
|
|
5001
|
+
useAmbientRenderUi,
|
|
4633
5002
|
useApprovalCountdown,
|
|
5003
|
+
useAttachments,
|
|
4634
5004
|
useChatTranscript,
|
|
4635
5005
|
useComposerAutocomplete,
|
|
4636
5006
|
useElapsed,
|