@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.js
CHANGED
|
@@ -125,6 +125,9 @@ var AgentClient = class {
|
|
|
125
125
|
* what a caller then rides on `sendMessage({ text }, { body: { attachments: [...] } })`.
|
|
126
126
|
*/
|
|
127
127
|
async uploadAttachment(file, options = {}) {
|
|
128
|
+
if (options.onProgress !== void 0 && this.options.fetch === void 0 && typeof XMLHttpRequest !== "undefined") {
|
|
129
|
+
return this.uploadWithProgress(file, options);
|
|
130
|
+
}
|
|
128
131
|
const formData = new FormData();
|
|
129
132
|
formData.append("file", file);
|
|
130
133
|
const response = await this.fetchImpl()(`${this.baseUrl()}/agent/attachments`, {
|
|
@@ -139,7 +142,47 @@ var AgentClient = class {
|
|
|
139
142
|
signal: options.signal
|
|
140
143
|
} : {}
|
|
141
144
|
});
|
|
142
|
-
|
|
145
|
+
const attachment = await this.handleResponse(response, "POST", "/agent/attachments");
|
|
146
|
+
options.onProgress?.(1);
|
|
147
|
+
return attachment;
|
|
148
|
+
}
|
|
149
|
+
async uploadWithProgress(file, { signal, onProgress }) {
|
|
150
|
+
const headers = {
|
|
151
|
+
accept: "application/json",
|
|
152
|
+
...await this.resolveHeaders()
|
|
153
|
+
};
|
|
154
|
+
const url = `${this.baseUrl()}/agent/attachments`;
|
|
155
|
+
return new Promise((resolve, reject) => {
|
|
156
|
+
const xhr = new XMLHttpRequest();
|
|
157
|
+
xhr.open("POST", url);
|
|
158
|
+
for (const [name, value] of Object.entries(headers)) xhr.setRequestHeader(name, value);
|
|
159
|
+
xhr.withCredentials = this.options.credentials === "include";
|
|
160
|
+
xhr.upload.onprogress = (event) => {
|
|
161
|
+
if (event.lengthComputable && event.total > 0) onProgress?.(event.loaded / event.total);
|
|
162
|
+
};
|
|
163
|
+
xhr.onload = () => {
|
|
164
|
+
if (xhr.status < 200 || xhr.status >= 300) {
|
|
165
|
+
reject(new AgentHttpError(xhr.status, "POST", "/agent/attachments", xhr.statusText));
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
onProgress?.(1);
|
|
169
|
+
resolve(JSON.parse(xhr.responseText));
|
|
170
|
+
};
|
|
171
|
+
xhr.onerror = () => reject(new TypeError("Network error while uploading the attachment"));
|
|
172
|
+
xhr.onabort = () => reject(new DOMException("The upload was aborted", "AbortError"));
|
|
173
|
+
if (signal !== void 0) {
|
|
174
|
+
if (signal.aborted) {
|
|
175
|
+
reject(new DOMException("The upload was aborted", "AbortError"));
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
signal.addEventListener("abort", () => xhr.abort(), {
|
|
179
|
+
once: true
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
const formData = new FormData();
|
|
183
|
+
formData.append("file", file);
|
|
184
|
+
xhr.send(formData);
|
|
185
|
+
});
|
|
143
186
|
}
|
|
144
187
|
promoteThread(id) {
|
|
145
188
|
return this.request("POST", `/agent/threads/${encodeURIComponent(id)}/promote`);
|
|
@@ -987,6 +1030,68 @@ function delay(ms, signal) {
|
|
|
987
1030
|
}
|
|
988
1031
|
__name(delay, "delay");
|
|
989
1032
|
|
|
1033
|
+
// src/attachments/files.ts
|
|
1034
|
+
function fileKind(mediaType) {
|
|
1035
|
+
const type = mediaType.toLowerCase();
|
|
1036
|
+
if (type.startsWith("image/")) return "image";
|
|
1037
|
+
if (type === "application/pdf") return "pdf";
|
|
1038
|
+
if (type.startsWith("text/") || type === "application/json") return "text";
|
|
1039
|
+
if (type.startsWith("audio/")) return "audio";
|
|
1040
|
+
if (type.startsWith("video/")) return "video";
|
|
1041
|
+
return "other";
|
|
1042
|
+
}
|
|
1043
|
+
__name(fileKind, "fileKind");
|
|
1044
|
+
function messageFiles(message) {
|
|
1045
|
+
const files = [];
|
|
1046
|
+
for (const part of message.parts) {
|
|
1047
|
+
if (part.type !== "file") continue;
|
|
1048
|
+
const file = part;
|
|
1049
|
+
const filename = file.filename ?? null;
|
|
1050
|
+
const dot = filename?.lastIndexOf(".") ?? -1;
|
|
1051
|
+
const mediaId = file.providerMetadata?.agent?.mediaId;
|
|
1052
|
+
files.push({
|
|
1053
|
+
url: file.url,
|
|
1054
|
+
mediaType: file.mediaType,
|
|
1055
|
+
filename,
|
|
1056
|
+
kind: fileKind(file.mediaType),
|
|
1057
|
+
extension: filename !== null && dot > 0 ? filename.slice(dot + 1).toLowerCase() : null,
|
|
1058
|
+
mediaId: typeof mediaId === "string" ? mediaId : null
|
|
1059
|
+
});
|
|
1060
|
+
}
|
|
1061
|
+
return files;
|
|
1062
|
+
}
|
|
1063
|
+
__name(messageFiles, "messageFiles");
|
|
1064
|
+
function acceptsFile(accept, file) {
|
|
1065
|
+
const rules = (typeof accept === "string" ? accept.split(",") : accept ?? []).map((rule) => rule.trim().toLowerCase()).filter((rule) => rule.length > 0);
|
|
1066
|
+
if (rules.length === 0) return true;
|
|
1067
|
+
const type = file.type.toLowerCase();
|
|
1068
|
+
const name = file.name.toLowerCase();
|
|
1069
|
+
return rules.some((rule) => {
|
|
1070
|
+
if (rule.startsWith(".")) return name.endsWith(rule);
|
|
1071
|
+
if (rule.endsWith("/*")) return type.startsWith(rule.slice(0, -1));
|
|
1072
|
+
return type === rule;
|
|
1073
|
+
});
|
|
1074
|
+
}
|
|
1075
|
+
__name(acceptsFile, "acceptsFile");
|
|
1076
|
+
function filesFromClipboard(data) {
|
|
1077
|
+
if (!data) return [];
|
|
1078
|
+
const files = [];
|
|
1079
|
+
for (const item of Array.from(data.items ?? [])) {
|
|
1080
|
+
if (item.kind !== "file") continue;
|
|
1081
|
+
const file = item.getAsFile();
|
|
1082
|
+
if (file !== null) files.push(file);
|
|
1083
|
+
}
|
|
1084
|
+
return files.length > 0 ? files : Array.from(data.files ?? []);
|
|
1085
|
+
}
|
|
1086
|
+
__name(filesFromClipboard, "filesFromClipboard");
|
|
1087
|
+
function dragHasFiles(data) {
|
|
1088
|
+
return Array.from(data?.types ?? []).includes("Files");
|
|
1089
|
+
}
|
|
1090
|
+
__name(dragHasFiles, "dragHasFiles");
|
|
1091
|
+
|
|
1092
|
+
// src/attachments/use-attachments.ts
|
|
1093
|
+
import { useCallback, useEffect as useEffect2, useMemo, useRef as useRef2, useState as useState2 } from "react";
|
|
1094
|
+
|
|
990
1095
|
// src/backend.ts
|
|
991
1096
|
var AgentBackendUnsupportedError = class extends Error {
|
|
992
1097
|
static {
|
|
@@ -1007,19 +1112,239 @@ function requireBackendMethod(backend, name) {
|
|
|
1007
1112
|
}
|
|
1008
1113
|
__name(requireBackendMethod, "requireBackendMethod");
|
|
1009
1114
|
|
|
1115
|
+
// src/attachments/use-attachments.ts
|
|
1116
|
+
var DEFAULT_REJECTION = {
|
|
1117
|
+
type: /* @__PURE__ */ __name((file) => `${file.name} is not a supported file type`, "type"),
|
|
1118
|
+
size: /* @__PURE__ */ __name((file) => `${file.name} is too large`, "size"),
|
|
1119
|
+
count: /* @__PURE__ */ __name(() => "Too many files", "count")
|
|
1120
|
+
};
|
|
1121
|
+
var sequence = 0;
|
|
1122
|
+
function useAttachments(options) {
|
|
1123
|
+
const latest = useRef2(options);
|
|
1124
|
+
latest.current = options;
|
|
1125
|
+
const [items, setItems] = useState2([]);
|
|
1126
|
+
const itemsRef = useRef2(items);
|
|
1127
|
+
itemsRef.current = items;
|
|
1128
|
+
const controllers = useRef2(/* @__PURE__ */ new Map());
|
|
1129
|
+
const [dragDepth, setDragDepth] = useState2(0);
|
|
1130
|
+
const patch = useCallback((id, change) => {
|
|
1131
|
+
setItems((current) => current.map((item) => item.id === id ? {
|
|
1132
|
+
...item,
|
|
1133
|
+
...change
|
|
1134
|
+
} : item));
|
|
1135
|
+
}, []);
|
|
1136
|
+
const start = useCallback((item) => {
|
|
1137
|
+
const { upload, backend } = latest.current;
|
|
1138
|
+
const run = upload ?? (backend?.uploadAttachment !== void 0 ? backend.uploadAttachment.bind(backend) : void 0);
|
|
1139
|
+
if (run === void 0) {
|
|
1140
|
+
patch(item.id, {
|
|
1141
|
+
status: "error",
|
|
1142
|
+
error: new AgentBackendUnsupportedError("uploadAttachment").message
|
|
1143
|
+
});
|
|
1144
|
+
return;
|
|
1145
|
+
}
|
|
1146
|
+
const controller = new AbortController();
|
|
1147
|
+
controllers.current.set(item.id, controller);
|
|
1148
|
+
run(item.file, {
|
|
1149
|
+
signal: controller.signal,
|
|
1150
|
+
onProgress: /* @__PURE__ */ __name((fraction) => patch(item.id, {
|
|
1151
|
+
progress: Math.max(0, Math.min(1, fraction))
|
|
1152
|
+
}), "onProgress")
|
|
1153
|
+
}).then((attachment) => {
|
|
1154
|
+
if (controller.signal.aborted) return;
|
|
1155
|
+
controllers.current.delete(item.id);
|
|
1156
|
+
patch(item.id, {
|
|
1157
|
+
status: "ready",
|
|
1158
|
+
progress: 1,
|
|
1159
|
+
attachment
|
|
1160
|
+
});
|
|
1161
|
+
}, (error) => {
|
|
1162
|
+
if (controller.signal.aborted) return;
|
|
1163
|
+
controllers.current.delete(item.id);
|
|
1164
|
+
patch(item.id, {
|
|
1165
|
+
status: "error",
|
|
1166
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1167
|
+
});
|
|
1168
|
+
});
|
|
1169
|
+
}, [
|
|
1170
|
+
patch
|
|
1171
|
+
]);
|
|
1172
|
+
const add = useCallback((files) => {
|
|
1173
|
+
if (files == null) return;
|
|
1174
|
+
const { accept: accept2, maxBytes, maxFiles, describeRejection } = latest.current;
|
|
1175
|
+
const describe = /* @__PURE__ */ __name((reason, file) => describeRejection?.(reason, file) ?? DEFAULT_REJECTION[reason](file), "describe");
|
|
1176
|
+
let room = maxFiles === void 0 ? Number.POSITIVE_INFINITY : maxFiles - itemsRef.current.filter((item) => item.status !== "rejected").length;
|
|
1177
|
+
const staged = [];
|
|
1178
|
+
for (const file of Array.from(files)) {
|
|
1179
|
+
sequence += 1;
|
|
1180
|
+
const base = {
|
|
1181
|
+
id: `att-${sequence}`,
|
|
1182
|
+
file,
|
|
1183
|
+
name: file.name,
|
|
1184
|
+
size: file.size,
|
|
1185
|
+
type: file.type,
|
|
1186
|
+
progress: 0
|
|
1187
|
+
};
|
|
1188
|
+
const reason = !acceptsFile(accept2, file) ? "type" : maxBytes !== void 0 && file.size > maxBytes ? "size" : room <= 0 ? "count" : void 0;
|
|
1189
|
+
if (reason !== void 0) {
|
|
1190
|
+
staged.push({
|
|
1191
|
+
...base,
|
|
1192
|
+
status: "rejected",
|
|
1193
|
+
error: describe(reason, file)
|
|
1194
|
+
});
|
|
1195
|
+
continue;
|
|
1196
|
+
}
|
|
1197
|
+
room -= 1;
|
|
1198
|
+
const previewUrl = file.type.startsWith("image/") && typeof URL.createObjectURL === "function" ? URL.createObjectURL(file) : void 0;
|
|
1199
|
+
staged.push({
|
|
1200
|
+
...base,
|
|
1201
|
+
status: "uploading",
|
|
1202
|
+
...previewUrl ? {
|
|
1203
|
+
previewUrl
|
|
1204
|
+
} : {}
|
|
1205
|
+
});
|
|
1206
|
+
}
|
|
1207
|
+
if (staged.length === 0) return;
|
|
1208
|
+
setItems((current) => [
|
|
1209
|
+
...current,
|
|
1210
|
+
...staged
|
|
1211
|
+
]);
|
|
1212
|
+
for (const item of staged) {
|
|
1213
|
+
if (item.status === "uploading") start(item);
|
|
1214
|
+
}
|
|
1215
|
+
}, [
|
|
1216
|
+
start
|
|
1217
|
+
]);
|
|
1218
|
+
const release = useCallback((item) => {
|
|
1219
|
+
if (item === void 0) return;
|
|
1220
|
+
controllers.current.get(item.id)?.abort();
|
|
1221
|
+
controllers.current.delete(item.id);
|
|
1222
|
+
if (item.previewUrl !== void 0 && typeof URL.revokeObjectURL === "function") {
|
|
1223
|
+
URL.revokeObjectURL(item.previewUrl);
|
|
1224
|
+
}
|
|
1225
|
+
}, []);
|
|
1226
|
+
const remove = useCallback((id) => {
|
|
1227
|
+
release(itemsRef.current.find((item) => item.id === id));
|
|
1228
|
+
setItems((current) => current.filter((item) => item.id !== id));
|
|
1229
|
+
}, [
|
|
1230
|
+
release
|
|
1231
|
+
]);
|
|
1232
|
+
const clear = useCallback(() => {
|
|
1233
|
+
for (const item of itemsRef.current) release(item);
|
|
1234
|
+
setItems([]);
|
|
1235
|
+
}, [
|
|
1236
|
+
release
|
|
1237
|
+
]);
|
|
1238
|
+
const retry = useCallback((id) => {
|
|
1239
|
+
const item = itemsRef.current.find((candidate) => candidate.id === id);
|
|
1240
|
+
if (item === void 0 || item.status !== "error") return;
|
|
1241
|
+
const { error: _previous, ...rest } = item;
|
|
1242
|
+
const again = {
|
|
1243
|
+
...rest,
|
|
1244
|
+
status: "uploading",
|
|
1245
|
+
progress: 0
|
|
1246
|
+
};
|
|
1247
|
+
setItems((current) => current.map((candidate) => candidate.id === id ? again : candidate));
|
|
1248
|
+
start(again);
|
|
1249
|
+
}, [
|
|
1250
|
+
start
|
|
1251
|
+
]);
|
|
1252
|
+
useEffect2(() => () => {
|
|
1253
|
+
for (const item of itemsRef.current) release(item);
|
|
1254
|
+
}, [
|
|
1255
|
+
release
|
|
1256
|
+
]);
|
|
1257
|
+
const onPaste = useCallback((event) => {
|
|
1258
|
+
const files = filesFromClipboard(event.clipboardData);
|
|
1259
|
+
if (files.length === 0) return;
|
|
1260
|
+
event.preventDefault();
|
|
1261
|
+
add(files);
|
|
1262
|
+
}, [
|
|
1263
|
+
add
|
|
1264
|
+
]);
|
|
1265
|
+
const dropZoneProps = useMemo(() => ({
|
|
1266
|
+
onDragEnter: /* @__PURE__ */ __name((event) => {
|
|
1267
|
+
if (!dragHasFiles(event.dataTransfer)) return;
|
|
1268
|
+
event.preventDefault();
|
|
1269
|
+
setDragDepth((depth) => depth + 1);
|
|
1270
|
+
}, "onDragEnter"),
|
|
1271
|
+
onDragOver: /* @__PURE__ */ __name((event) => {
|
|
1272
|
+
if (dragHasFiles(event.dataTransfer)) event.preventDefault();
|
|
1273
|
+
}, "onDragOver"),
|
|
1274
|
+
onDragLeave: /* @__PURE__ */ __name((event) => {
|
|
1275
|
+
if (!dragHasFiles(event.dataTransfer)) return;
|
|
1276
|
+
setDragDepth((depth) => Math.max(0, depth - 1));
|
|
1277
|
+
}, "onDragLeave"),
|
|
1278
|
+
onDrop: /* @__PURE__ */ __name((event) => {
|
|
1279
|
+
if (!dragHasFiles(event.dataTransfer)) return;
|
|
1280
|
+
event.preventDefault();
|
|
1281
|
+
setDragDepth(0);
|
|
1282
|
+
add(event.dataTransfer?.files);
|
|
1283
|
+
}, "onDrop")
|
|
1284
|
+
}), [
|
|
1285
|
+
add
|
|
1286
|
+
]);
|
|
1287
|
+
const accept = options.accept;
|
|
1288
|
+
const inputProps = useMemo(() => ({
|
|
1289
|
+
type: "file",
|
|
1290
|
+
accept: typeof accept === "string" ? accept : accept?.join(","),
|
|
1291
|
+
multiple: options.maxFiles === void 0 || options.maxFiles > 1,
|
|
1292
|
+
onChange: /* @__PURE__ */ __name((event) => {
|
|
1293
|
+
const input = event.currentTarget;
|
|
1294
|
+
add(input.files);
|
|
1295
|
+
input.value = "";
|
|
1296
|
+
}, "onChange")
|
|
1297
|
+
}), [
|
|
1298
|
+
accept,
|
|
1299
|
+
options.maxFiles,
|
|
1300
|
+
add
|
|
1301
|
+
]);
|
|
1302
|
+
return useMemo(() => {
|
|
1303
|
+
const ready = items.filter((item) => item.status === "ready" && item.attachment !== void 0);
|
|
1304
|
+
const attachments = ready.map((item) => item.attachment);
|
|
1305
|
+
return {
|
|
1306
|
+
items,
|
|
1307
|
+
add,
|
|
1308
|
+
remove,
|
|
1309
|
+
retry,
|
|
1310
|
+
clear,
|
|
1311
|
+
isUploading: items.some((item) => item.status === "uploading"),
|
|
1312
|
+
attachments,
|
|
1313
|
+
refs: attachments.map((attachment) => ({
|
|
1314
|
+
mediaId: attachment.mediaId
|
|
1315
|
+
})),
|
|
1316
|
+
inputProps,
|
|
1317
|
+
dropZoneProps,
|
|
1318
|
+
isDragging: dragDepth > 0,
|
|
1319
|
+
onPaste
|
|
1320
|
+
};
|
|
1321
|
+
}, [
|
|
1322
|
+
items,
|
|
1323
|
+
add,
|
|
1324
|
+
remove,
|
|
1325
|
+
retry,
|
|
1326
|
+
clear,
|
|
1327
|
+
inputProps,
|
|
1328
|
+
dropZoneProps,
|
|
1329
|
+
dragDepth,
|
|
1330
|
+
onPaste
|
|
1331
|
+
]);
|
|
1332
|
+
}
|
|
1333
|
+
__name(useAttachments, "useAttachments");
|
|
1334
|
+
|
|
1010
1335
|
// src/catalog/use-agents.ts
|
|
1011
|
-
import { useMemo } from "react";
|
|
1336
|
+
import { useMemo as useMemo2 } from "react";
|
|
1012
1337
|
|
|
1013
1338
|
// src/catalog/use-resource.ts
|
|
1014
|
-
import { useCallback, useEffect as
|
|
1339
|
+
import { useCallback as useCallback2, useEffect as useEffect3, useRef as useRef3, useState as useState3 } from "react";
|
|
1015
1340
|
function useResource(load2, key, enabled) {
|
|
1016
|
-
const [data, setData] =
|
|
1017
|
-
const [isLoading, setIsLoading] =
|
|
1018
|
-
const [error, setError] =
|
|
1019
|
-
const loadRef =
|
|
1341
|
+
const [data, setData] = useState3(void 0);
|
|
1342
|
+
const [isLoading, setIsLoading] = useState3(enabled);
|
|
1343
|
+
const [error, setError] = useState3(null);
|
|
1344
|
+
const loadRef = useRef3(load2);
|
|
1020
1345
|
loadRef.current = load2;
|
|
1021
|
-
const generation =
|
|
1022
|
-
const refresh =
|
|
1346
|
+
const generation = useRef3(0);
|
|
1347
|
+
const refresh = useCallback2(async () => {
|
|
1023
1348
|
const mine = ++generation.current;
|
|
1024
1349
|
setIsLoading(true);
|
|
1025
1350
|
try {
|
|
@@ -1034,7 +1359,7 @@ function useResource(load2, key, enabled) {
|
|
|
1034
1359
|
if (mine === generation.current) setIsLoading(false);
|
|
1035
1360
|
}
|
|
1036
1361
|
}, []);
|
|
1037
|
-
|
|
1362
|
+
useEffect3(() => {
|
|
1038
1363
|
if (!enabled) return;
|
|
1039
1364
|
void refresh();
|
|
1040
1365
|
}, [
|
|
@@ -1055,7 +1380,7 @@ __name(useResource, "useResource");
|
|
|
1055
1380
|
function useAgents(options) {
|
|
1056
1381
|
const { backend, enabled = true } = options;
|
|
1057
1382
|
const { data, isLoading, error, refresh } = useResource(() => requireBackendMethod(backend, "listAgents")(), "", enabled);
|
|
1058
|
-
return
|
|
1383
|
+
return useMemo2(() => {
|
|
1059
1384
|
const agents = data ?? [];
|
|
1060
1385
|
return {
|
|
1061
1386
|
agents,
|
|
@@ -1074,11 +1399,11 @@ function useAgents(options) {
|
|
|
1074
1399
|
__name(useAgents, "useAgents");
|
|
1075
1400
|
|
|
1076
1401
|
// src/catalog/use-models.ts
|
|
1077
|
-
import { useMemo as
|
|
1402
|
+
import { useMemo as useMemo3 } from "react";
|
|
1078
1403
|
function useModels(options) {
|
|
1079
1404
|
const { backend, agent, enabled = true } = options;
|
|
1080
1405
|
const { data, isLoading, error, refresh } = useResource(() => requireBackendMethod(backend, "listModels")(agent), `${agent ?? ""}`, enabled);
|
|
1081
|
-
return
|
|
1406
|
+
return useMemo3(() => {
|
|
1082
1407
|
const providers = data?.providers ?? [];
|
|
1083
1408
|
const models = providers.flatMap((provider) => provider.models.map((model) => ({
|
|
1084
1409
|
...model,
|
|
@@ -1108,7 +1433,7 @@ function useModels(options) {
|
|
|
1108
1433
|
__name(useModels, "useModels");
|
|
1109
1434
|
|
|
1110
1435
|
// src/quota/use-quota.ts
|
|
1111
|
-
import { useEffect as
|
|
1436
|
+
import { useEffect as useEffect4, useMemo as useMemo4 } from "react";
|
|
1112
1437
|
|
|
1113
1438
|
// src/threads/threads-events.ts
|
|
1114
1439
|
var listeners = /* @__PURE__ */ new WeakMap();
|
|
@@ -1135,7 +1460,7 @@ __name(onThreadsEvent, "onThreadsEvent");
|
|
|
1135
1460
|
function useQuota(options) {
|
|
1136
1461
|
const { backend, enabled = true, pollMs } = options;
|
|
1137
1462
|
const { data, isLoading, error, refresh } = useResource(() => requireBackendMethod(backend, "getQuota")(), "", enabled);
|
|
1138
|
-
|
|
1463
|
+
useEffect4(() => {
|
|
1139
1464
|
if (!enabled) return;
|
|
1140
1465
|
return onThreadsEvent(backend, (event) => {
|
|
1141
1466
|
if (event.type === "changed") void refresh();
|
|
@@ -1145,7 +1470,7 @@ function useQuota(options) {
|
|
|
1145
1470
|
enabled,
|
|
1146
1471
|
refresh
|
|
1147
1472
|
]);
|
|
1148
|
-
|
|
1473
|
+
useEffect4(() => {
|
|
1149
1474
|
if (!enabled || pollMs === void 0 || pollMs <= 0) return;
|
|
1150
1475
|
const timer = setInterval(() => void refresh(), pollMs);
|
|
1151
1476
|
return () => clearInterval(timer);
|
|
@@ -1154,7 +1479,7 @@ function useQuota(options) {
|
|
|
1154
1479
|
pollMs,
|
|
1155
1480
|
refresh
|
|
1156
1481
|
]);
|
|
1157
|
-
return
|
|
1482
|
+
return useMemo4(() => {
|
|
1158
1483
|
const windows = data?.windows ?? [];
|
|
1159
1484
|
return {
|
|
1160
1485
|
report: data,
|
|
@@ -1176,27 +1501,27 @@ function useQuota(options) {
|
|
|
1176
1501
|
__name(useQuota, "useQuota");
|
|
1177
1502
|
|
|
1178
1503
|
// src/feedback/use-message-feedback.ts
|
|
1179
|
-
import { useCallback as
|
|
1504
|
+
import { useCallback as useCallback3, useRef as useRef4, useState as useState4 } from "react";
|
|
1180
1505
|
function useMessageFeedback(options) {
|
|
1181
|
-
const latest =
|
|
1506
|
+
const latest = useRef4(options);
|
|
1182
1507
|
latest.current = options;
|
|
1183
|
-
const [local, setLocal] =
|
|
1184
|
-
const [pending, setPending] =
|
|
1185
|
-
const [error, setError] =
|
|
1186
|
-
const localRef =
|
|
1508
|
+
const [local, setLocal] = useState4(/* @__PURE__ */ new Map());
|
|
1509
|
+
const [pending, setPending] = useState4(/* @__PURE__ */ new Set());
|
|
1510
|
+
const [error, setError] = useState4(null);
|
|
1511
|
+
const localRef = useRef4(local);
|
|
1187
1512
|
localRef.current = local;
|
|
1188
|
-
const resolved =
|
|
1189
|
-
const feedbackOf =
|
|
1513
|
+
const resolved = useRef4(/* @__PURE__ */ new Map());
|
|
1514
|
+
const feedbackOf = useCallback3((message) => {
|
|
1190
1515
|
const mine = local.get(message.id);
|
|
1191
1516
|
if (mine !== void 0) return mine.feedback;
|
|
1192
1517
|
return metadataOf(message).feedback ?? null;
|
|
1193
1518
|
}, [
|
|
1194
1519
|
local
|
|
1195
1520
|
]);
|
|
1196
|
-
const isPending =
|
|
1521
|
+
const isPending = useCallback3((message) => pending.has(message.id), [
|
|
1197
1522
|
pending
|
|
1198
1523
|
]);
|
|
1199
|
-
const storedIdFor =
|
|
1524
|
+
const storedIdFor = useCallback3(async (message) => {
|
|
1200
1525
|
const runId = metadataOf(message).runId;
|
|
1201
1526
|
if (runId === void 0) return message.id;
|
|
1202
1527
|
const known = resolved.current.get(message.id);
|
|
@@ -1216,7 +1541,7 @@ function useMessageFeedback(options) {
|
|
|
1216
1541
|
resolved.current.set(message.id, row.id);
|
|
1217
1542
|
return row.id;
|
|
1218
1543
|
}, []);
|
|
1219
|
-
const rate =
|
|
1544
|
+
const rate = useCallback3(async (message, value, comment) => {
|
|
1220
1545
|
const setFeedback = requireBackendMethod(latest.current.backend, "setMessageFeedback");
|
|
1221
1546
|
const had = localRef.current.get(message.id);
|
|
1222
1547
|
const optimistic = value === null ? null : {
|
|
@@ -1262,7 +1587,7 @@ function useMessageFeedback(options) {
|
|
|
1262
1587
|
}, [
|
|
1263
1588
|
storedIdFor
|
|
1264
1589
|
]);
|
|
1265
|
-
const toggle =
|
|
1590
|
+
const toggle = useCallback3((message, value) => {
|
|
1266
1591
|
const mine = localRef.current.get(message.id);
|
|
1267
1592
|
const current = mine !== void 0 ? mine.feedback : metadataOf(message).feedback ?? null;
|
|
1268
1593
|
return rate(message, current?.value === value ? null : value);
|
|
@@ -1285,16 +1610,16 @@ function metadataOf(message) {
|
|
|
1285
1610
|
__name(metadataOf, "metadataOf");
|
|
1286
1611
|
|
|
1287
1612
|
// src/threads/use-threads.ts
|
|
1288
|
-
import { useCallback as
|
|
1613
|
+
import { useCallback as useCallback4, useEffect as useEffect5, useRef as useRef5, useState as useState5 } from "react";
|
|
1289
1614
|
function useThreads(options) {
|
|
1290
1615
|
const { backend, enabled = true } = options;
|
|
1291
|
-
const [threads, setThreads] =
|
|
1292
|
-
const [isLoading, setIsLoading] =
|
|
1293
|
-
const [error, setError] =
|
|
1294
|
-
const threadsRef =
|
|
1616
|
+
const [threads, setThreads] = useState5([]);
|
|
1617
|
+
const [isLoading, setIsLoading] = useState5(enabled);
|
|
1618
|
+
const [error, setError] = useState5(null);
|
|
1619
|
+
const threadsRef = useRef5(threads);
|
|
1295
1620
|
threadsRef.current = threads;
|
|
1296
|
-
const generation =
|
|
1297
|
-
const refresh =
|
|
1621
|
+
const generation = useRef5(0);
|
|
1622
|
+
const refresh = useCallback4(async () => {
|
|
1298
1623
|
const mine = ++generation.current;
|
|
1299
1624
|
setIsLoading(true);
|
|
1300
1625
|
try {
|
|
@@ -1311,7 +1636,7 @@ function useThreads(options) {
|
|
|
1311
1636
|
}, [
|
|
1312
1637
|
backend
|
|
1313
1638
|
]);
|
|
1314
|
-
|
|
1639
|
+
useEffect5(() => {
|
|
1315
1640
|
if (!enabled) return;
|
|
1316
1641
|
void refresh();
|
|
1317
1642
|
return onThreadsEvent(backend, (event) => {
|
|
@@ -1331,7 +1656,7 @@ function useThreads(options) {
|
|
|
1331
1656
|
enabled,
|
|
1332
1657
|
refresh
|
|
1333
1658
|
]);
|
|
1334
|
-
const rename =
|
|
1659
|
+
const rename = useCallback4(async (id, title) => {
|
|
1335
1660
|
const before = threadsRef.current;
|
|
1336
1661
|
setThreads((current) => current.map((thread) => thread.id === id ? {
|
|
1337
1662
|
...thread,
|
|
@@ -1353,7 +1678,7 @@ function useThreads(options) {
|
|
|
1353
1678
|
}, [
|
|
1354
1679
|
backend
|
|
1355
1680
|
]);
|
|
1356
|
-
const remove =
|
|
1681
|
+
const remove = useCallback4(async (id) => {
|
|
1357
1682
|
const before = threadsRef.current;
|
|
1358
1683
|
setThreads((current) => current.filter((thread) => thread.id !== id));
|
|
1359
1684
|
try {
|
|
@@ -1427,11 +1752,29 @@ function backgroundRunsFromThread(messages) {
|
|
|
1427
1752
|
}
|
|
1428
1753
|
__name(backgroundRunsFromThread, "backgroundRunsFromThread");
|
|
1429
1754
|
|
|
1755
|
+
// src/components/ambient-ui.ts
|
|
1756
|
+
import { createContext, useContext } from "react";
|
|
1757
|
+
function sharedContext(key) {
|
|
1758
|
+
const symbol = Symbol.for(key);
|
|
1759
|
+
const holder = globalThis;
|
|
1760
|
+
const existing = holder[symbol];
|
|
1761
|
+
if (existing !== void 0) return existing;
|
|
1762
|
+
const created = createContext(null);
|
|
1763
|
+
holder[symbol] = created;
|
|
1764
|
+
return created;
|
|
1765
|
+
}
|
|
1766
|
+
__name(sharedContext, "sharedContext");
|
|
1767
|
+
var AmbientRenderUiContext = sharedContext("@dudousxd/nestjs-agent-react:ambient-render-ui");
|
|
1768
|
+
function useAmbientRenderUi() {
|
|
1769
|
+
return useContext(AmbientRenderUiContext);
|
|
1770
|
+
}
|
|
1771
|
+
__name(useAmbientRenderUi, "useAmbientRenderUi");
|
|
1772
|
+
|
|
1430
1773
|
// src/components/chat-input.tsx
|
|
1431
|
-
import React2, { useEffect as
|
|
1774
|
+
import React2, { useEffect as useEffect7, useState as useState7 } from "react";
|
|
1432
1775
|
|
|
1433
1776
|
// src/components/use-speech-recognition.ts
|
|
1434
|
-
import { useCallback as
|
|
1777
|
+
import { useCallback as useCallback5, useEffect as useEffect6, useMemo as useMemo5, useRef as useRef6, useState as useState6 } from "react";
|
|
1435
1778
|
function getRecognitionCtor() {
|
|
1436
1779
|
if (typeof window === "undefined") return null;
|
|
1437
1780
|
const scope = window;
|
|
@@ -1439,15 +1782,15 @@ function getRecognitionCtor() {
|
|
|
1439
1782
|
}
|
|
1440
1783
|
__name(getRecognitionCtor, "getRecognitionCtor");
|
|
1441
1784
|
function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTranscript }) {
|
|
1442
|
-
const recognitionRef =
|
|
1443
|
-
const [isListening, setIsListening] =
|
|
1444
|
-
const ctor =
|
|
1785
|
+
const recognitionRef = useRef6(null);
|
|
1786
|
+
const [isListening, setIsListening] = useState6(false);
|
|
1787
|
+
const ctor = useMemo5(() => getRecognitionCtor(), []);
|
|
1445
1788
|
const isSupported = ctor !== null;
|
|
1446
|
-
const finalRef =
|
|
1447
|
-
const interimRef =
|
|
1789
|
+
const finalRef = useRef6(onFinalTranscript);
|
|
1790
|
+
const interimRef = useRef6(onInterimTranscript);
|
|
1448
1791
|
finalRef.current = onFinalTranscript;
|
|
1449
1792
|
interimRef.current = onInterimTranscript;
|
|
1450
|
-
|
|
1793
|
+
useEffect6(() => {
|
|
1451
1794
|
if (!ctor) return;
|
|
1452
1795
|
const recognition = new ctor();
|
|
1453
1796
|
recognition.lang = lang;
|
|
@@ -1486,7 +1829,7 @@ function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTran
|
|
|
1486
1829
|
ctor,
|
|
1487
1830
|
lang
|
|
1488
1831
|
]);
|
|
1489
|
-
const start =
|
|
1832
|
+
const start = useCallback5(() => {
|
|
1490
1833
|
const recognition = recognitionRef.current;
|
|
1491
1834
|
if (!recognition) return;
|
|
1492
1835
|
try {
|
|
@@ -1496,7 +1839,7 @@ function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTran
|
|
|
1496
1839
|
console.warn("SpeechRecognition start failed", error);
|
|
1497
1840
|
}
|
|
1498
1841
|
}, []);
|
|
1499
|
-
const stop =
|
|
1842
|
+
const stop = useCallback5(() => {
|
|
1500
1843
|
const recognition = recognitionRef.current;
|
|
1501
1844
|
if (!recognition) return;
|
|
1502
1845
|
try {
|
|
@@ -1515,8 +1858,8 @@ __name(useSpeechRecognition, "useSpeechRecognition");
|
|
|
1515
1858
|
|
|
1516
1859
|
// src/components/chat-input.tsx
|
|
1517
1860
|
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 }) {
|
|
1518
|
-
const [value, setValue] =
|
|
1519
|
-
const [interim, setInterim] =
|
|
1861
|
+
const [value, setValue] = useState7("");
|
|
1862
|
+
const [interim, setInterim] = useState7("");
|
|
1520
1863
|
const speech = useSpeechRecognition({
|
|
1521
1864
|
lang: speechLang,
|
|
1522
1865
|
onFinalTranscript: /* @__PURE__ */ __name((text) => {
|
|
@@ -1527,7 +1870,7 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
|
|
|
1527
1870
|
}, "onFinalTranscript"),
|
|
1528
1871
|
onInterimTranscript: /* @__PURE__ */ __name((text) => setInterim(text), "onInterimTranscript")
|
|
1529
1872
|
});
|
|
1530
|
-
|
|
1873
|
+
useEffect7(() => {
|
|
1531
1874
|
if (!speech.isListening) setInterim("");
|
|
1532
1875
|
}, [
|
|
1533
1876
|
speech.isListening
|
|
@@ -1594,7 +1937,7 @@ __name(ChatInput, "ChatInput");
|
|
|
1594
1937
|
import React3 from "react";
|
|
1595
1938
|
|
|
1596
1939
|
// src/transcript/use-chat-transcript.ts
|
|
1597
|
-
import { useCallback as
|
|
1940
|
+
import { useCallback as useCallback7, useEffect as useEffect9, useRef as useRef8, useState as useState9 } from "react";
|
|
1598
1941
|
|
|
1599
1942
|
// src/transcript/model.ts
|
|
1600
1943
|
import { readElicitationInput, validateElicitationAnswer as validateElicitationAnswer2 } from "@dudousxd/nestjs-agent-core";
|
|
@@ -2571,11 +2914,11 @@ function formatCostUsd(cost) {
|
|
|
2571
2914
|
__name(formatCostUsd, "formatCostUsd");
|
|
2572
2915
|
|
|
2573
2916
|
// src/transcript/use-stick-to-bottom.ts
|
|
2574
|
-
import { useCallback as
|
|
2917
|
+
import { useCallback as useCallback6, useEffect as useEffect8, useRef as useRef7, useState as useState8 } from "react";
|
|
2575
2918
|
function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
2576
|
-
const containerRef =
|
|
2577
|
-
const [isAtBottom, setIsAtBottom] =
|
|
2578
|
-
const measure =
|
|
2919
|
+
const containerRef = useRef7(null);
|
|
2920
|
+
const [isAtBottom, setIsAtBottom] = useState8(true);
|
|
2921
|
+
const measure = useCallback6(() => {
|
|
2579
2922
|
const element = containerRef.current;
|
|
2580
2923
|
if (!element) {
|
|
2581
2924
|
return;
|
|
@@ -2585,7 +2928,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
|
2585
2928
|
}, [
|
|
2586
2929
|
threshold
|
|
2587
2930
|
]);
|
|
2588
|
-
const scrollToBottom =
|
|
2931
|
+
const scrollToBottom = useCallback6(() => {
|
|
2589
2932
|
const element = containerRef.current;
|
|
2590
2933
|
if (!element) {
|
|
2591
2934
|
return;
|
|
@@ -2593,7 +2936,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
|
2593
2936
|
element.scrollTop = element.scrollHeight;
|
|
2594
2937
|
setIsAtBottom(true);
|
|
2595
2938
|
}, []);
|
|
2596
|
-
const setContainer =
|
|
2939
|
+
const setContainer = useCallback6((element) => {
|
|
2597
2940
|
containerRef.current = element;
|
|
2598
2941
|
if (element) {
|
|
2599
2942
|
measure();
|
|
@@ -2601,7 +2944,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
|
2601
2944
|
}, [
|
|
2602
2945
|
measure
|
|
2603
2946
|
]);
|
|
2604
|
-
|
|
2947
|
+
useEffect8(() => {
|
|
2605
2948
|
if (isAtBottom) {
|
|
2606
2949
|
scrollToBottom();
|
|
2607
2950
|
}
|
|
@@ -2610,7 +2953,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
|
2610
2953
|
isAtBottom,
|
|
2611
2954
|
scrollToBottom
|
|
2612
2955
|
]);
|
|
2613
|
-
const getContainerProps =
|
|
2956
|
+
const getContainerProps = useCallback6(() => ({
|
|
2614
2957
|
ref: setContainer,
|
|
2615
2958
|
onScroll: measure
|
|
2616
2959
|
}), [
|
|
@@ -2632,14 +2975,14 @@ var DEFAULT_LOAD_EARLIER_STEP = 50;
|
|
|
2632
2975
|
var DEFAULT_COPY_RESET_MS = 1500;
|
|
2633
2976
|
function useChatTranscript(options) {
|
|
2634
2977
|
const { messages, status, initialVisibleCount = DEFAULT_VISIBLE_COUNT, loadEarlierStep = DEFAULT_LOAD_EARLIER_STEP, followUps, stickToBottomThreshold } = options;
|
|
2635
|
-
const latest =
|
|
2978
|
+
const latest = useRef8(options);
|
|
2636
2979
|
latest.current = options;
|
|
2637
|
-
const [visibleCount, setVisibleCount] =
|
|
2638
|
-
const [stopRequested, setStopRequested] =
|
|
2980
|
+
const [visibleCount, setVisibleCount] = useState9(initialVisibleCount);
|
|
2981
|
+
const [stopRequested, setStopRequested] = useState9(false);
|
|
2639
2982
|
const isStreaming = status === "streaming" || status === "reconnecting";
|
|
2640
2983
|
const isBusy = status === "submitted" || isStreaming;
|
|
2641
2984
|
const isEmpty = messages.length === 0;
|
|
2642
|
-
|
|
2985
|
+
useEffect9(() => {
|
|
2643
2986
|
if (!isBusy) {
|
|
2644
2987
|
setStopRequested(false);
|
|
2645
2988
|
}
|
|
@@ -2656,7 +2999,7 @@ function useChatTranscript(options) {
|
|
|
2656
2999
|
streamingMessageId,
|
|
2657
3000
|
options
|
|
2658
3001
|
});
|
|
2659
|
-
const stop =
|
|
3002
|
+
const stop = useCallback7(() => {
|
|
2660
3003
|
const current = latest.current;
|
|
2661
3004
|
if (current.status !== "submitted" && current.status !== "streaming" && current.status !== "reconnecting") {
|
|
2662
3005
|
return;
|
|
@@ -2664,8 +3007,8 @@ function useChatTranscript(options) {
|
|
|
2664
3007
|
setStopRequested(true);
|
|
2665
3008
|
void current.onStop?.();
|
|
2666
3009
|
}, []);
|
|
2667
|
-
const loadEarlier =
|
|
2668
|
-
const showAll =
|
|
3010
|
+
const loadEarlier = useCallback7(() => setVisibleCount((count) => count + (latest.current.loadEarlierStep ?? DEFAULT_LOAD_EARLIER_STEP)), []);
|
|
3011
|
+
const showAll = useCallback7(() => setVisibleCount(latest.current.messages.length), []);
|
|
2669
3012
|
const scroll = useStickToBottom({
|
|
2670
3013
|
contentKey: contentSignature(messages),
|
|
2671
3014
|
...stickToBottomThreshold !== void 0 ? {
|
|
@@ -2701,7 +3044,7 @@ function useChatTranscript(options) {
|
|
|
2701
3044
|
__name(useChatTranscript, "useChatTranscript");
|
|
2702
3045
|
function useTranscriptItem(options) {
|
|
2703
3046
|
const { message, isStreaming = false } = options;
|
|
2704
|
-
const messagesRef =
|
|
3047
|
+
const messagesRef = useRef8([
|
|
2705
3048
|
message
|
|
2706
3049
|
]);
|
|
2707
3050
|
if (messagesRef.current[0] !== message) {
|
|
@@ -2719,13 +3062,13 @@ function useTranscriptItem(options) {
|
|
|
2719
3062
|
}
|
|
2720
3063
|
__name(useTranscriptItem, "useTranscriptItem");
|
|
2721
3064
|
function useTranscriptItems({ messages, visibleStart, streamingMessageId, options }) {
|
|
2722
|
-
const [drafts, setDrafts] =
|
|
2723
|
-
const [copied, setCopied] =
|
|
2724
|
-
const [openReasoning, setOpenReasoning] =
|
|
2725
|
-
const [picks, setPicks] =
|
|
2726
|
-
const [settling, setSettling] =
|
|
2727
|
-
const [settleErrors, setSettleErrors] =
|
|
2728
|
-
const latest =
|
|
3065
|
+
const [drafts, setDrafts] = useState9(() => /* @__PURE__ */ new Map());
|
|
3066
|
+
const [copied, setCopied] = useState9(() => /* @__PURE__ */ new Set());
|
|
3067
|
+
const [openReasoning, setOpenReasoning] = useState9(() => /* @__PURE__ */ new Map());
|
|
3068
|
+
const [picks, setPicks] = useState9(() => /* @__PURE__ */ new Map());
|
|
3069
|
+
const [settling, setSettling] = useState9(() => /* @__PURE__ */ new Map());
|
|
3070
|
+
const [settleErrors, setSettleErrors] = useState9(() => /* @__PURE__ */ new Map());
|
|
3071
|
+
const latest = useRef8({
|
|
2729
3072
|
options,
|
|
2730
3073
|
drafts,
|
|
2731
3074
|
picks,
|
|
@@ -2737,23 +3080,23 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2737
3080
|
picks,
|
|
2738
3081
|
messages
|
|
2739
3082
|
};
|
|
2740
|
-
const copyTimers =
|
|
2741
|
-
|
|
3083
|
+
const copyTimers = useRef8(/* @__PURE__ */ new Map());
|
|
3084
|
+
useEffect9(() => () => {
|
|
2742
3085
|
for (const timer of copyTimers.current.values()) {
|
|
2743
3086
|
clearTimeout(timer);
|
|
2744
3087
|
}
|
|
2745
3088
|
copyTimers.current.clear();
|
|
2746
3089
|
}, []);
|
|
2747
|
-
const callbackCache =
|
|
2748
|
-
const reasoningToggleCache =
|
|
2749
|
-
const toggleReasoning =
|
|
3090
|
+
const callbackCache = useRef8(/* @__PURE__ */ new Map());
|
|
3091
|
+
const reasoningToggleCache = useRef8(/* @__PURE__ */ new Map());
|
|
3092
|
+
const toggleReasoning = useCallback7((key, open) => {
|
|
2750
3093
|
setOpenReasoning((current) => {
|
|
2751
3094
|
const next = new Map(current);
|
|
2752
3095
|
next.set(key, open ?? !(current.get(key) ?? false));
|
|
2753
3096
|
return next;
|
|
2754
3097
|
});
|
|
2755
3098
|
}, []);
|
|
2756
|
-
const stableToggle =
|
|
3099
|
+
const stableToggle = useCallback7((key) => {
|
|
2757
3100
|
let cached = reasoningToggleCache.current.get(key);
|
|
2758
3101
|
if (!cached) {
|
|
2759
3102
|
cached = /* @__PURE__ */ __name((open) => toggleReasoning(key, open), "cached");
|
|
@@ -2763,10 +3106,10 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2763
3106
|
}, [
|
|
2764
3107
|
toggleReasoning
|
|
2765
3108
|
]);
|
|
2766
|
-
const pick =
|
|
3109
|
+
const pick = useCallback7((toolCallId, questionId, values) => {
|
|
2767
3110
|
setPicks((current) => new Map(current).set(pickKey(toolCallId, questionId), values));
|
|
2768
3111
|
}, []);
|
|
2769
|
-
const settle =
|
|
3112
|
+
const settle = useCallback7((toolCallId, action, send) => {
|
|
2770
3113
|
setSettleErrors((current) => {
|
|
2771
3114
|
if (!current.has(toolCallId)) {
|
|
2772
3115
|
return current;
|
|
@@ -2790,7 +3133,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2790
3133
|
failed(error);
|
|
2791
3134
|
}
|
|
2792
3135
|
}, []);
|
|
2793
|
-
const answer =
|
|
3136
|
+
const answer = useCallback7((toolCallId) => {
|
|
2794
3137
|
const current = latest.current;
|
|
2795
3138
|
const onAnswer = current.options.onAnswer;
|
|
2796
3139
|
if (!onAnswer) {
|
|
@@ -2800,7 +3143,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2800
3143
|
}, [
|
|
2801
3144
|
settle
|
|
2802
3145
|
]);
|
|
2803
|
-
const skip =
|
|
3146
|
+
const skip = useCallback7((toolCallId) => {
|
|
2804
3147
|
const onSkip = latest.current.options.onSkip;
|
|
2805
3148
|
if (onSkip) {
|
|
2806
3149
|
settle(toolCallId, "skip", () => onSkip(toolCallId));
|
|
@@ -2808,7 +3151,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2808
3151
|
}, [
|
|
2809
3152
|
settle
|
|
2810
3153
|
]);
|
|
2811
|
-
const approve =
|
|
3154
|
+
const approve = useCallback7((toolCallId, options2) => {
|
|
2812
3155
|
const onApprove = latest.current.options.onApprove;
|
|
2813
3156
|
if (onApprove) {
|
|
2814
3157
|
settle(toolCallId, "approve", () => options2 === void 0 ? onApprove(toolCallId) : onApprove(toolCallId, options2));
|
|
@@ -2816,7 +3159,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2816
3159
|
}, [
|
|
2817
3160
|
settle
|
|
2818
3161
|
]);
|
|
2819
|
-
const reject =
|
|
3162
|
+
const reject = useCallback7((toolCallId) => {
|
|
2820
3163
|
const onReject = latest.current.options.onReject;
|
|
2821
3164
|
if (onReject) {
|
|
2822
3165
|
settle(toolCallId, "reject", () => onReject(toolCallId));
|
|
@@ -2824,7 +3167,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2824
3167
|
}, [
|
|
2825
3168
|
settle
|
|
2826
3169
|
]);
|
|
2827
|
-
const callbacksFor =
|
|
3170
|
+
const callbacksFor = useCallback7((id) => {
|
|
2828
3171
|
const cached = callbackCache.current.get(id);
|
|
2829
3172
|
if (cached) {
|
|
2830
3173
|
return cached;
|
|
@@ -3072,7 +3415,12 @@ function MessageItem({ message, isStreaming = false, editable, onEditSubmit, reg
|
|
|
3072
3415
|
});
|
|
3073
3416
|
}
|
|
3074
3417
|
__name(MessageItem, "MessageItem");
|
|
3075
|
-
function MessageItemView({ item, ...
|
|
3418
|
+
function MessageItemView({ item, ...given }) {
|
|
3419
|
+
const ambientRenderUi = useAmbientRenderUi();
|
|
3420
|
+
const slots = given.renderUi === void 0 && ambientRenderUi !== null ? {
|
|
3421
|
+
...given,
|
|
3422
|
+
renderUi: ambientRenderUi
|
|
3423
|
+
} : given;
|
|
3076
3424
|
const { classNames } = slots;
|
|
3077
3425
|
const actionRow = /* @__PURE__ */ React3.createElement("div", {
|
|
3078
3426
|
className: classNames?.actions,
|
|
@@ -3481,35 +3829,35 @@ function toItem(entry) {
|
|
|
3481
3829
|
__name(toItem, "toItem");
|
|
3482
3830
|
|
|
3483
3831
|
// src/composer/use-composer-autocomplete.ts
|
|
3484
|
-
import { useCallback as
|
|
3832
|
+
import { useCallback as useCallback8, useEffect as useEffect10, useId, useLayoutEffect, useMemo as useMemo6, useRef as useRef9, useState as useState10 } from "react";
|
|
3485
3833
|
function useComposerAutocomplete(options) {
|
|
3486
3834
|
const { value, sources, acceptOnTab = true } = options;
|
|
3487
|
-
const latest =
|
|
3835
|
+
const latest = useRef9(options);
|
|
3488
3836
|
latest.current = options;
|
|
3489
|
-
const inputRef =
|
|
3490
|
-
const [caret, setCaret] =
|
|
3491
|
-
const [items, setItems] =
|
|
3492
|
-
const [isLoading, setLoading] =
|
|
3493
|
-
const [error, setError] =
|
|
3494
|
-
const [activeIndex, setActiveIndex] =
|
|
3495
|
-
const [dismissedIndex, setDismissedIndex] =
|
|
3837
|
+
const inputRef = useRef9(null);
|
|
3838
|
+
const [caret, setCaret] = useState10(value.length);
|
|
3839
|
+
const [items, setItems] = useState10([]);
|
|
3840
|
+
const [isLoading, setLoading] = useState10(false);
|
|
3841
|
+
const [error, setError] = useState10(null);
|
|
3842
|
+
const [activeIndex, setActiveIndex] = useState10(0);
|
|
3843
|
+
const [dismissedIndex, setDismissedIndex] = useState10(null);
|
|
3496
3844
|
const safeCaret = Math.min(caret, value.length);
|
|
3497
|
-
const match =
|
|
3845
|
+
const match = useMemo6(() => findActiveTrigger(value, safeCaret, sources), [
|
|
3498
3846
|
value,
|
|
3499
3847
|
safeCaret,
|
|
3500
3848
|
sources
|
|
3501
3849
|
]);
|
|
3502
3850
|
const isActive = match !== null && dismissedIndex !== match.index;
|
|
3503
|
-
const matchRef =
|
|
3851
|
+
const matchRef = useRef9(match);
|
|
3504
3852
|
matchRef.current = match;
|
|
3505
|
-
const caretRef =
|
|
3853
|
+
const caretRef = useRef9(safeCaret);
|
|
3506
3854
|
caretRef.current = safeCaret;
|
|
3507
|
-
const itemsRef =
|
|
3855
|
+
const itemsRef = useRef9(items);
|
|
3508
3856
|
itemsRef.current = items;
|
|
3509
|
-
const activeIndexRef =
|
|
3857
|
+
const activeIndexRef = useRef9(activeIndex);
|
|
3510
3858
|
activeIndexRef.current = activeIndex;
|
|
3511
3859
|
const requestKey = isActive && match ? `${match.source.id}\0${match.query}` : null;
|
|
3512
|
-
|
|
3860
|
+
useEffect10(() => {
|
|
3513
3861
|
const current = matchRef.current;
|
|
3514
3862
|
if (requestKey === null || current === null) {
|
|
3515
3863
|
setItems([]);
|
|
@@ -3559,23 +3907,23 @@ function useComposerAutocomplete(options) {
|
|
|
3559
3907
|
const activeItem = isOpen ? items[activeIndex] ?? null : null;
|
|
3560
3908
|
const reactId = useId();
|
|
3561
3909
|
const listboxId = options.id ?? `agent-autocomplete-${reactId}`;
|
|
3562
|
-
const optionId =
|
|
3910
|
+
const optionId = useCallback8((index) => `${listboxId}-option-${index}`, [
|
|
3563
3911
|
listboxId
|
|
3564
3912
|
]);
|
|
3565
|
-
const highlight =
|
|
3913
|
+
const highlight = useCallback8((index) => {
|
|
3566
3914
|
const total = itemsRef.current.length;
|
|
3567
3915
|
if (total === 0) return;
|
|
3568
3916
|
setActiveIndex((index % total + total) % total);
|
|
3569
3917
|
}, []);
|
|
3570
|
-
const moveHighlight =
|
|
3918
|
+
const moveHighlight = useCallback8((delta) => highlight(activeIndexRef.current + delta), [
|
|
3571
3919
|
highlight
|
|
3572
3920
|
]);
|
|
3573
|
-
const dismiss =
|
|
3921
|
+
const dismiss = useCallback8(() => {
|
|
3574
3922
|
const current = matchRef.current;
|
|
3575
3923
|
if (current) setDismissedIndex(current.index);
|
|
3576
3924
|
}, []);
|
|
3577
|
-
const pendingCaret =
|
|
3578
|
-
const accept =
|
|
3925
|
+
const pendingCaret = useRef9(null);
|
|
3926
|
+
const accept = useCallback8((item) => {
|
|
3579
3927
|
const current = matchRef.current;
|
|
3580
3928
|
if (!current) return;
|
|
3581
3929
|
const chosen = item ?? itemsRef.current[activeIndexRef.current];
|
|
@@ -3592,10 +3940,10 @@ function useComposerAutocomplete(options) {
|
|
|
3592
3940
|
pendingCaret.current = null;
|
|
3593
3941
|
inputRef.current?.setSelectionRange(position, position);
|
|
3594
3942
|
});
|
|
3595
|
-
const readCaret =
|
|
3943
|
+
const readCaret = useCallback8((element) => {
|
|
3596
3944
|
setCaret(element.selectionStart ?? element.value.length);
|
|
3597
3945
|
}, []);
|
|
3598
|
-
const onKeyDown =
|
|
3946
|
+
const onKeyDown = useCallback8((event) => {
|
|
3599
3947
|
if (!isOpen) return;
|
|
3600
3948
|
const hasItems = itemsRef.current.length > 0;
|
|
3601
3949
|
switch (event.key) {
|
|
@@ -3633,23 +3981,23 @@ function useComposerAutocomplete(options) {
|
|
|
3633
3981
|
dismiss,
|
|
3634
3982
|
moveHighlight
|
|
3635
3983
|
]);
|
|
3636
|
-
const onChange =
|
|
3984
|
+
const onChange = useCallback8((event) => {
|
|
3637
3985
|
readCaret(event.target);
|
|
3638
3986
|
const next = findActiveTrigger(event.target.value, event.target.selectionStart ?? event.target.value.length, latest.current.sources);
|
|
3639
3987
|
setDismissedIndex((current) => current !== null && next?.index === current ? current : null);
|
|
3640
3988
|
}, [
|
|
3641
3989
|
readCaret
|
|
3642
3990
|
]);
|
|
3643
|
-
const onSelect =
|
|
3991
|
+
const onSelect = useCallback8((event) => readCaret(event.currentTarget), [
|
|
3644
3992
|
readCaret
|
|
3645
3993
|
]);
|
|
3646
|
-
const onClick =
|
|
3994
|
+
const onClick = useCallback8((event) => readCaret(event.currentTarget), [
|
|
3647
3995
|
readCaret
|
|
3648
3996
|
]);
|
|
3649
|
-
const setInput =
|
|
3997
|
+
const setInput = useCallback8((element) => {
|
|
3650
3998
|
inputRef.current = element;
|
|
3651
3999
|
}, []);
|
|
3652
|
-
const getInputProps =
|
|
4000
|
+
const getInputProps = useCallback8(() => ({
|
|
3653
4001
|
ref: setInput,
|
|
3654
4002
|
onChange,
|
|
3655
4003
|
onKeyDown,
|
|
@@ -3677,7 +4025,7 @@ function useComposerAutocomplete(options) {
|
|
|
3677
4025
|
activeIndex,
|
|
3678
4026
|
optionId
|
|
3679
4027
|
]);
|
|
3680
|
-
const getListboxProps =
|
|
4028
|
+
const getListboxProps = useCallback8(() => ({
|
|
3681
4029
|
id: listboxId,
|
|
3682
4030
|
role: "listbox",
|
|
3683
4031
|
"aria-label": match?.source.label ?? match?.source.id ?? "Suggestions"
|
|
@@ -3685,7 +4033,7 @@ function useComposerAutocomplete(options) {
|
|
|
3685
4033
|
listboxId,
|
|
3686
4034
|
match
|
|
3687
4035
|
]);
|
|
3688
|
-
const getOptionProps =
|
|
4036
|
+
const getOptionProps = useCallback8((index) => ({
|
|
3689
4037
|
id: optionId(index),
|
|
3690
4038
|
role: "option",
|
|
3691
4039
|
"aria-selected": index === activeIndex
|
|
@@ -3719,7 +4067,7 @@ function isPromise(value) {
|
|
|
3719
4067
|
__name(isPromise, "isPromise");
|
|
3720
4068
|
|
|
3721
4069
|
// src/presentation/use-tool-catalog.ts
|
|
3722
|
-
import { useCallback as
|
|
4070
|
+
import { useCallback as useCallback9, useEffect as useEffect11, useMemo as useMemo7, useState as useState11 } from "react";
|
|
3723
4071
|
var shared = /* @__PURE__ */ new WeakMap();
|
|
3724
4072
|
function load(client, agent) {
|
|
3725
4073
|
let byAgent = shared.get(client);
|
|
@@ -3743,11 +4091,11 @@ function load(client, agent) {
|
|
|
3743
4091
|
__name(load, "load");
|
|
3744
4092
|
function useToolCatalog(options) {
|
|
3745
4093
|
const { client, agent, enabled = true } = options;
|
|
3746
|
-
const [entries, setEntries] =
|
|
3747
|
-
const [isLoading, setLoading] =
|
|
3748
|
-
const [error, setError] =
|
|
3749
|
-
const [generation, setGeneration] =
|
|
3750
|
-
|
|
4094
|
+
const [entries, setEntries] = useState11([]);
|
|
4095
|
+
const [isLoading, setLoading] = useState11(enabled);
|
|
4096
|
+
const [error, setError] = useState11(null);
|
|
4097
|
+
const [generation, setGeneration] = useState11(0);
|
|
4098
|
+
useEffect11(() => {
|
|
3751
4099
|
if (!enabled) {
|
|
3752
4100
|
setLoading(false);
|
|
3753
4101
|
return;
|
|
@@ -3773,14 +4121,14 @@ function useToolCatalog(options) {
|
|
|
3773
4121
|
enabled,
|
|
3774
4122
|
generation
|
|
3775
4123
|
]);
|
|
3776
|
-
const refresh =
|
|
4124
|
+
const refresh = useCallback9(() => {
|
|
3777
4125
|
shared.get(client)?.delete(agent ?? "");
|
|
3778
4126
|
setGeneration((current) => current + 1);
|
|
3779
4127
|
}, [
|
|
3780
4128
|
client,
|
|
3781
4129
|
agent
|
|
3782
4130
|
]);
|
|
3783
|
-
const catalog =
|
|
4131
|
+
const catalog = useMemo7(() => toolCatalogFrom(entries), [
|
|
3784
4132
|
entries
|
|
3785
4133
|
]);
|
|
3786
4134
|
return {
|
|
@@ -3794,7 +4142,7 @@ function useToolCatalog(options) {
|
|
|
3794
4142
|
__name(useToolCatalog, "useToolCatalog");
|
|
3795
4143
|
|
|
3796
4144
|
// src/approvals/countdown.ts
|
|
3797
|
-
import { useEffect as
|
|
4145
|
+
import { useEffect as useEffect12, useRef as useRef10, useState as useState12 } from "react";
|
|
3798
4146
|
function approvalCountdown(expiresAt, now = Date.now()) {
|
|
3799
4147
|
const deadline = expiresAt == null ? Number.NaN : Date.parse(expiresAt);
|
|
3800
4148
|
if (!Number.isFinite(deadline)) {
|
|
@@ -3812,10 +4160,10 @@ function approvalCountdown(expiresAt, now = Date.now()) {
|
|
|
3812
4160
|
__name(approvalCountdown, "approvalCountdown");
|
|
3813
4161
|
function useApprovalCountdown(expiresAt, options = {}) {
|
|
3814
4162
|
const { intervalMs = 1e3 } = options;
|
|
3815
|
-
const nowRef =
|
|
4163
|
+
const nowRef = useRef10(options.now ?? Date.now);
|
|
3816
4164
|
nowRef.current = options.now ?? Date.now;
|
|
3817
|
-
const [state, setState] =
|
|
3818
|
-
|
|
4165
|
+
const [state, setState] = useState12(() => approvalCountdown(expiresAt, nowRef.current()));
|
|
4166
|
+
useEffect12(() => {
|
|
3819
4167
|
const read = /* @__PURE__ */ __name(() => approvalCountdown(expiresAt, nowRef.current()), "read");
|
|
3820
4168
|
const first = read();
|
|
3821
4169
|
setState(first);
|
|
@@ -3878,7 +4226,13 @@ function storedMessageToUiMessage(message) {
|
|
|
3878
4226
|
type: "file",
|
|
3879
4227
|
mediaType: attachment.contentType,
|
|
3880
4228
|
filename: attachment.name,
|
|
3881
|
-
url: attachment.url
|
|
4229
|
+
url: attachment.url,
|
|
4230
|
+
// The stored id rides along, so a replayed file can be referenced again (`messageFiles`).
|
|
4231
|
+
providerMetadata: {
|
|
4232
|
+
agent: {
|
|
4233
|
+
mediaId: attachment.mediaId
|
|
4234
|
+
}
|
|
4235
|
+
}
|
|
3882
4236
|
});
|
|
3883
4237
|
}
|
|
3884
4238
|
const toolCallIds = new Set((message.toolCalls ?? []).map((call) => call.id));
|
|
@@ -4057,20 +4411,20 @@ __name(sumUsage, "sumUsage");
|
|
|
4057
4411
|
|
|
4058
4412
|
// src/use-agent-chat.ts
|
|
4059
4413
|
import { useChat } from "@ai-sdk/react";
|
|
4060
|
-
import { useCallback as
|
|
4414
|
+
import { useCallback as useCallback10, useEffect as useEffect13, useMemo as useMemo8, useRef as useRef11, useState as useState13 } from "react";
|
|
4061
4415
|
function useAgentChat(options) {
|
|
4062
|
-
const latest =
|
|
4416
|
+
const latest = useRef11(options);
|
|
4063
4417
|
latest.current = options;
|
|
4064
|
-
const [runId, setRunId] =
|
|
4065
|
-
const runIdRef =
|
|
4418
|
+
const [runId, setRunId] = useState13(options.resumeRunId);
|
|
4419
|
+
const runIdRef = useRef11(runId);
|
|
4066
4420
|
runIdRef.current = runId;
|
|
4067
|
-
const settlingRunIdRef =
|
|
4068
|
-
const autoResumeRunIdRef =
|
|
4069
|
-
const [autoResume, setAutoResume] =
|
|
4070
|
-
const [activeRunId, setActiveRunId] =
|
|
4071
|
-
const regenerateNext =
|
|
4072
|
-
const createdThreadId =
|
|
4073
|
-
const client =
|
|
4421
|
+
const settlingRunIdRef = useRef11(void 0);
|
|
4422
|
+
const autoResumeRunIdRef = useRef11(void 0);
|
|
4423
|
+
const [autoResume, setAutoResume] = useState13(false);
|
|
4424
|
+
const [activeRunId, setActiveRunId] = useState13(null);
|
|
4425
|
+
const regenerateNext = useRef11(false);
|
|
4426
|
+
const createdThreadId = useRef11(void 0);
|
|
4427
|
+
const client = useMemo8(() => {
|
|
4074
4428
|
if (options.backend) return options.backend;
|
|
4075
4429
|
if (options.client) return options.client;
|
|
4076
4430
|
return new AgentClient({
|
|
@@ -4086,11 +4440,11 @@ function useAgentChat(options) {
|
|
|
4086
4440
|
getHeaders: /* @__PURE__ */ __name(async () => mergeHeaders(latest.current), "getHeaders")
|
|
4087
4441
|
});
|
|
4088
4442
|
}, []);
|
|
4089
|
-
const [connection, setConnection] =
|
|
4443
|
+
const [connection, setConnection] = useState13({
|
|
4090
4444
|
status: "live"
|
|
4091
4445
|
});
|
|
4092
|
-
const resyncAfterSettle =
|
|
4093
|
-
|
|
4446
|
+
const resyncAfterSettle = useRef11(false);
|
|
4447
|
+
useEffect13(() => {
|
|
4094
4448
|
if (!options.resume || options.threadId === void 0) return;
|
|
4095
4449
|
let cancelled = false;
|
|
4096
4450
|
const threadId = options.threadId;
|
|
@@ -4110,7 +4464,7 @@ function useAgentChat(options) {
|
|
|
4110
4464
|
options.resume,
|
|
4111
4465
|
options.threadId
|
|
4112
4466
|
]);
|
|
4113
|
-
const transport =
|
|
4467
|
+
const transport = useMemo8(() => {
|
|
4114
4468
|
function onMeta(meta) {
|
|
4115
4469
|
settlingRunIdRef.current = meta.runId;
|
|
4116
4470
|
setRunId(meta.runId);
|
|
@@ -4165,7 +4519,7 @@ function useAgentChat(options) {
|
|
|
4165
4519
|
}, "onAttemptStart")
|
|
4166
4520
|
});
|
|
4167
4521
|
}, []);
|
|
4168
|
-
const backgroundRef =
|
|
4522
|
+
const backgroundRef = useRef11(() => Promise.resolve());
|
|
4169
4523
|
const chat = useChat({
|
|
4170
4524
|
transport,
|
|
4171
4525
|
resume: options.resumeRunId !== void 0 || autoResume,
|
|
@@ -4214,7 +4568,7 @@ function useAgentChat(options) {
|
|
|
4214
4568
|
}
|
|
4215
4569
|
}, "onFinish")
|
|
4216
4570
|
});
|
|
4217
|
-
const chatRef =
|
|
4571
|
+
const chatRef = useRef11(chat);
|
|
4218
4572
|
chatRef.current = chat;
|
|
4219
4573
|
async function resyncFromThread() {
|
|
4220
4574
|
const threadId = latest.current.threadId ?? createdThreadId.current;
|
|
@@ -4226,11 +4580,11 @@ function useAgentChat(options) {
|
|
|
4226
4580
|
}
|
|
4227
4581
|
}
|
|
4228
4582
|
__name(resyncFromThread, "resyncFromThread");
|
|
4229
|
-
const turnInFlight =
|
|
4230
|
-
const isTurnInFlight =
|
|
4583
|
+
const turnInFlight = useRef11(false);
|
|
4584
|
+
const isTurnInFlight = useCallback10(() => turnInFlight.current || transport.isAttemptLive, [
|
|
4231
4585
|
transport
|
|
4232
4586
|
]);
|
|
4233
|
-
const sendMessage =
|
|
4587
|
+
const sendMessage = useCallback10(async (...args) => {
|
|
4234
4588
|
const blocked = latest.current.blocked;
|
|
4235
4589
|
if (blocked != null) throw new QuotaBlockedError(blocked);
|
|
4236
4590
|
if (isTurnInFlight()) return;
|
|
@@ -4243,15 +4597,15 @@ function useAgentChat(options) {
|
|
|
4243
4597
|
}, [
|
|
4244
4598
|
isTurnInFlight
|
|
4245
4599
|
]);
|
|
4246
|
-
const addToolResult =
|
|
4600
|
+
const addToolResult = useCallback10(({ tool, toolCallId, output }) => chatRef.current.addToolResult({
|
|
4247
4601
|
tool,
|
|
4248
4602
|
toolCallId,
|
|
4249
4603
|
output
|
|
4250
4604
|
}), []);
|
|
4251
|
-
const [threads, setThreads] =
|
|
4252
|
-
const [quota, setQuota] =
|
|
4253
|
-
const [backgroundRuns, setBackgroundRuns] =
|
|
4254
|
-
const refreshBackground =
|
|
4605
|
+
const [threads, setThreads] = useState13([]);
|
|
4606
|
+
const [quota, setQuota] = useState13(null);
|
|
4607
|
+
const [backgroundRuns, setBackgroundRuns] = useState13([]);
|
|
4608
|
+
const refreshBackground = useCallback10(async () => {
|
|
4255
4609
|
const threadId = latest.current.threadId ?? createdThreadId.current;
|
|
4256
4610
|
if (threadId === void 0) {
|
|
4257
4611
|
return;
|
|
@@ -4276,7 +4630,7 @@ function useAgentChat(options) {
|
|
|
4276
4630
|
]);
|
|
4277
4631
|
backgroundRef.current = refreshBackground;
|
|
4278
4632
|
const isWorking = backgroundRuns.some((run) => run.status === "running");
|
|
4279
|
-
|
|
4633
|
+
useEffect13(() => {
|
|
4280
4634
|
if (options.background !== true || options.threadId === void 0) {
|
|
4281
4635
|
return;
|
|
4282
4636
|
}
|
|
@@ -4286,7 +4640,7 @@ function useAgentChat(options) {
|
|
|
4286
4640
|
options.threadId,
|
|
4287
4641
|
refreshBackground
|
|
4288
4642
|
]);
|
|
4289
|
-
|
|
4643
|
+
useEffect13(() => {
|
|
4290
4644
|
const every = latest.current.backgroundPollMs ?? 5e3;
|
|
4291
4645
|
if (latest.current.background !== true || !isWorking || every <= 0) {
|
|
4292
4646
|
return;
|
|
@@ -4297,26 +4651,26 @@ function useAgentChat(options) {
|
|
|
4297
4651
|
isWorking,
|
|
4298
4652
|
refreshBackground
|
|
4299
4653
|
]);
|
|
4300
|
-
const loadThreads =
|
|
4654
|
+
const loadThreads = useCallback10(async () => {
|
|
4301
4655
|
const list = await client.listThreads();
|
|
4302
4656
|
setThreads(list);
|
|
4303
4657
|
return list;
|
|
4304
4658
|
}, [
|
|
4305
4659
|
client
|
|
4306
4660
|
]);
|
|
4307
|
-
const loadThread =
|
|
4661
|
+
const loadThread = useCallback10((id) => client.getThread(id), [
|
|
4308
4662
|
client
|
|
4309
4663
|
]);
|
|
4310
|
-
const deleteThread =
|
|
4664
|
+
const deleteThread = useCallback10(async (id) => {
|
|
4311
4665
|
await client.deleteThread(id);
|
|
4312
4666
|
setThreads((current) => current.filter((thread) => thread.id !== id));
|
|
4313
4667
|
}, [
|
|
4314
4668
|
client
|
|
4315
4669
|
]);
|
|
4316
|
-
const forkThread =
|
|
4670
|
+
const forkThread = useCallback10((threadId, messageId) => requireBackendMethod(client, "forkFromMessage")(threadId, messageId), [
|
|
4317
4671
|
client
|
|
4318
4672
|
]);
|
|
4319
|
-
const renameThread =
|
|
4673
|
+
const renameThread = useCallback10(async (id, title) => {
|
|
4320
4674
|
await client.updateThread(id, {
|
|
4321
4675
|
title
|
|
4322
4676
|
});
|
|
@@ -4327,24 +4681,24 @@ function useAgentChat(options) {
|
|
|
4327
4681
|
}, [
|
|
4328
4682
|
client
|
|
4329
4683
|
]);
|
|
4330
|
-
const promoteThread =
|
|
4684
|
+
const promoteThread = useCallback10(async (id) => {
|
|
4331
4685
|
await requireBackendMethod(client, "promoteThread")(id);
|
|
4332
4686
|
await loadThreads();
|
|
4333
4687
|
}, [
|
|
4334
4688
|
client,
|
|
4335
4689
|
loadThreads
|
|
4336
4690
|
]);
|
|
4337
|
-
const truncateFromMessage =
|
|
4691
|
+
const truncateFromMessage = useCallback10((threadId, messageId) => requireBackendMethod(client, "truncateFromMessage")(threadId, messageId).then(() => void 0), [
|
|
4338
4692
|
client
|
|
4339
4693
|
]);
|
|
4340
|
-
const loadQuota =
|
|
4694
|
+
const loadQuota = useCallback10(async () => {
|
|
4341
4695
|
const today = await requireBackendMethod(client, "getQuotaToday")();
|
|
4342
4696
|
setQuota(today);
|
|
4343
4697
|
return today;
|
|
4344
4698
|
}, [
|
|
4345
4699
|
client
|
|
4346
4700
|
]);
|
|
4347
|
-
const cancel =
|
|
4701
|
+
const cancel = useCallback10(async () => {
|
|
4348
4702
|
chatRef.current.stop();
|
|
4349
4703
|
const activeRunId2 = runIdRef.current;
|
|
4350
4704
|
if (activeRunId2) {
|
|
@@ -4356,7 +4710,7 @@ function useAgentChat(options) {
|
|
|
4356
4710
|
}, [
|
|
4357
4711
|
client
|
|
4358
4712
|
]);
|
|
4359
|
-
const approve =
|
|
4713
|
+
const approve = useCallback10(async ({ toolCallId, remember, via }) => {
|
|
4360
4714
|
await requireBackendMethod(client, "approveToolCall")({
|
|
4361
4715
|
toolCallId,
|
|
4362
4716
|
...remember === true ? {
|
|
@@ -4369,7 +4723,7 @@ function useAgentChat(options) {
|
|
|
4369
4723
|
}, [
|
|
4370
4724
|
client
|
|
4371
4725
|
]);
|
|
4372
|
-
const reject =
|
|
4726
|
+
const reject = useCallback10(async ({ toolCallId, reason, via }) => {
|
|
4373
4727
|
await requireBackendMethod(client, "rejectToolCall")({
|
|
4374
4728
|
toolCallId,
|
|
4375
4729
|
...reason !== void 0 ? {
|
|
@@ -4382,7 +4736,7 @@ function useAgentChat(options) {
|
|
|
4382
4736
|
}, [
|
|
4383
4737
|
client
|
|
4384
4738
|
]);
|
|
4385
|
-
const answer =
|
|
4739
|
+
const answer = useCallback10(async ({ toolCallId, answers }) => {
|
|
4386
4740
|
await requireBackendMethod(client, "answerToolCall")({
|
|
4387
4741
|
toolCallId,
|
|
4388
4742
|
...answers !== void 0 ? {
|
|
@@ -4392,14 +4746,14 @@ function useAgentChat(options) {
|
|
|
4392
4746
|
}, [
|
|
4393
4747
|
client
|
|
4394
4748
|
]);
|
|
4395
|
-
const skip =
|
|
4749
|
+
const skip = useCallback10(async ({ toolCallId }) => {
|
|
4396
4750
|
await requireBackendMethod(client, "skipToolCall")({
|
|
4397
4751
|
toolCallId
|
|
4398
4752
|
});
|
|
4399
4753
|
}, [
|
|
4400
4754
|
client
|
|
4401
4755
|
]);
|
|
4402
|
-
const regenerate =
|
|
4756
|
+
const regenerate = useCallback10(() => {
|
|
4403
4757
|
const blocked = latest.current.blocked;
|
|
4404
4758
|
if (blocked != null) throw new QuotaBlockedError(blocked);
|
|
4405
4759
|
if (isTurnInFlight()) return;
|
|
@@ -4416,7 +4770,7 @@ function useAgentChat(options) {
|
|
|
4416
4770
|
isWorking,
|
|
4417
4771
|
refresh: refreshBackground
|
|
4418
4772
|
};
|
|
4419
|
-
const setThreadModel =
|
|
4773
|
+
const setThreadModel = useCallback10(async (model) => {
|
|
4420
4774
|
const threadId = latest.current.threadId ?? createdThreadId.current;
|
|
4421
4775
|
if (threadId === void 0) {
|
|
4422
4776
|
throw new Error("setThreadModel: this chat has no thread yet");
|
|
@@ -4430,7 +4784,7 @@ function useAgentChat(options) {
|
|
|
4430
4784
|
}, [
|
|
4431
4785
|
client
|
|
4432
4786
|
]);
|
|
4433
|
-
const getThreadId =
|
|
4787
|
+
const getThreadId = useCallback10(() => latest.current.threadId ?? createdThreadId.current, []);
|
|
4434
4788
|
const status = connection.status === "reconnecting" ? "reconnecting" : chat.status;
|
|
4435
4789
|
return {
|
|
4436
4790
|
...chat,
|
|
@@ -4496,6 +4850,7 @@ export {
|
|
|
4496
4850
|
AgentChatTransport,
|
|
4497
4851
|
AgentClient,
|
|
4498
4852
|
AgentHttpError,
|
|
4853
|
+
AmbientRenderUiContext,
|
|
4499
4854
|
ChatInput,
|
|
4500
4855
|
DEFAULT_SPEECH_LANG,
|
|
4501
4856
|
MessageItem,
|
|
@@ -4503,6 +4858,7 @@ export {
|
|
|
4503
4858
|
MessageList,
|
|
4504
4859
|
QuotaBlockedError,
|
|
4505
4860
|
SPEECH_LANGUAGES,
|
|
4861
|
+
acceptsFile,
|
|
4506
4862
|
applyCompletion,
|
|
4507
4863
|
approvalCountdown,
|
|
4508
4864
|
backgroundRunsFromThread,
|
|
@@ -4513,7 +4869,10 @@ export {
|
|
|
4513
4869
|
describeTimestamp,
|
|
4514
4870
|
describeToolCall,
|
|
4515
4871
|
describeUsage,
|
|
4872
|
+
dragHasFiles,
|
|
4516
4873
|
extractMessageText,
|
|
4874
|
+
fileKind,
|
|
4875
|
+
filesFromClipboard,
|
|
4517
4876
|
fillTemplate,
|
|
4518
4877
|
filterAutocompleteItems,
|
|
4519
4878
|
findActiveTrigger,
|
|
@@ -4523,6 +4882,7 @@ export {
|
|
|
4523
4882
|
inferResultView,
|
|
4524
4883
|
isActionCall,
|
|
4525
4884
|
loadStoredSpeechLang,
|
|
4885
|
+
messageFiles,
|
|
4526
4886
|
notifyThreads,
|
|
4527
4887
|
onThreadsEvent,
|
|
4528
4888
|
persistSpeechLang,
|
|
@@ -4537,7 +4897,9 @@ export {
|
|
|
4537
4897
|
toolCatalogFrom,
|
|
4538
4898
|
useAgentChat,
|
|
4539
4899
|
useAgents,
|
|
4900
|
+
useAmbientRenderUi,
|
|
4540
4901
|
useApprovalCountdown,
|
|
4902
|
+
useAttachments,
|
|
4541
4903
|
useChatTranscript,
|
|
4542
4904
|
useComposerAutocomplete,
|
|
4543
4905
|
useElapsed,
|