@dudousxd/nestjs-agent-react 0.15.0 → 0.17.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 +46 -0
- package/dist/index.cjs +415 -215
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +118 -3
- package/dist/index.d.ts +118 -3
- package/dist/index.js +373 -177
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -40,6 +40,7 @@ __export(src_exports, {
|
|
|
40
40
|
MessageItem: () => MessageItem,
|
|
41
41
|
MessageItemView: () => MessageItemView,
|
|
42
42
|
MessageList: () => MessageList,
|
|
43
|
+
QuotaBlockedError: () => QuotaBlockedError,
|
|
43
44
|
SPEECH_LANGUAGES: () => SPEECH_LANGUAGES,
|
|
44
45
|
applyCompletion: () => applyCompletion,
|
|
45
46
|
approvalCountdown: () => approvalCountdown,
|
|
@@ -74,11 +75,14 @@ __export(src_exports, {
|
|
|
74
75
|
toolCallState: () => toolCallState,
|
|
75
76
|
toolCatalogFrom: () => toolCatalogFrom,
|
|
76
77
|
useAgentChat: () => useAgentChat,
|
|
78
|
+
useAgents: () => useAgents,
|
|
77
79
|
useApprovalCountdown: () => useApprovalCountdown,
|
|
78
80
|
useChatTranscript: () => useChatTranscript,
|
|
79
81
|
useComposerAutocomplete: () => useComposerAutocomplete,
|
|
80
82
|
useElapsed: () => useElapsed,
|
|
81
83
|
useMessageFeedback: () => useMessageFeedback,
|
|
84
|
+
useModels: () => useModels,
|
|
85
|
+
useQuota: () => useQuota,
|
|
82
86
|
useSpeechRecognition: () => useSpeechRecognition,
|
|
83
87
|
useStickToBottom: () => useStickToBottom,
|
|
84
88
|
useThreads: () => useThreads,
|
|
@@ -235,6 +239,19 @@ var AgentClient = class {
|
|
|
235
239
|
truncateFromMessage(threadId, messageId) {
|
|
236
240
|
return this.request("DELETE", `/agent/threads/${encodeURIComponent(threadId)}/from/${encodeURIComponent(messageId)}`);
|
|
237
241
|
}
|
|
242
|
+
/** `GET /agent/models?agent=` — the models this caller may pick, grouped by provider. */
|
|
243
|
+
listModels(agent) {
|
|
244
|
+
const query = agent === void 0 ? "" : `?agent=${encodeURIComponent(agent)}`;
|
|
245
|
+
return this.request("GET", `/agent/models${query}`);
|
|
246
|
+
}
|
|
247
|
+
/** `GET /agent/agents` — the registered agents, the default one flagged. */
|
|
248
|
+
listAgents() {
|
|
249
|
+
return this.request("GET", "/agent/agents");
|
|
250
|
+
}
|
|
251
|
+
/** `GET /agent/quota` — the caller's budget windows and the one blocking sends, if any. */
|
|
252
|
+
getQuota() {
|
|
253
|
+
return this.request("GET", "/agent/quota");
|
|
254
|
+
}
|
|
238
255
|
getQuotaToday() {
|
|
239
256
|
return this.request("GET", "/agent/quota/today");
|
|
240
257
|
}
|
|
@@ -1082,28 +1099,196 @@ function requireBackendMethod(backend, name) {
|
|
|
1082
1099
|
}
|
|
1083
1100
|
__name(requireBackendMethod, "requireBackendMethod");
|
|
1084
1101
|
|
|
1085
|
-
// src/
|
|
1102
|
+
// src/catalog/use-agents.ts
|
|
1103
|
+
var import_react3 = require("react");
|
|
1104
|
+
|
|
1105
|
+
// src/catalog/use-resource.ts
|
|
1086
1106
|
var import_react2 = require("react");
|
|
1107
|
+
function useResource(load2, key, enabled) {
|
|
1108
|
+
const [data, setData] = (0, import_react2.useState)(void 0);
|
|
1109
|
+
const [isLoading, setIsLoading] = (0, import_react2.useState)(enabled);
|
|
1110
|
+
const [error, setError] = (0, import_react2.useState)(null);
|
|
1111
|
+
const loadRef = (0, import_react2.useRef)(load2);
|
|
1112
|
+
loadRef.current = load2;
|
|
1113
|
+
const generation = (0, import_react2.useRef)(0);
|
|
1114
|
+
const refresh = (0, import_react2.useCallback)(async () => {
|
|
1115
|
+
const mine = ++generation.current;
|
|
1116
|
+
setIsLoading(true);
|
|
1117
|
+
try {
|
|
1118
|
+
const value = await loadRef.current();
|
|
1119
|
+
if (mine !== generation.current) return;
|
|
1120
|
+
setData(value);
|
|
1121
|
+
setError(null);
|
|
1122
|
+
} catch (caught) {
|
|
1123
|
+
if (mine !== generation.current) return;
|
|
1124
|
+
setError(caught instanceof Error ? caught : new Error(String(caught)));
|
|
1125
|
+
} finally {
|
|
1126
|
+
if (mine === generation.current) setIsLoading(false);
|
|
1127
|
+
}
|
|
1128
|
+
}, []);
|
|
1129
|
+
(0, import_react2.useEffect)(() => {
|
|
1130
|
+
if (!enabled) return;
|
|
1131
|
+
void refresh();
|
|
1132
|
+
}, [
|
|
1133
|
+
enabled,
|
|
1134
|
+
key,
|
|
1135
|
+
refresh
|
|
1136
|
+
]);
|
|
1137
|
+
return {
|
|
1138
|
+
data,
|
|
1139
|
+
isLoading,
|
|
1140
|
+
error,
|
|
1141
|
+
refresh
|
|
1142
|
+
};
|
|
1143
|
+
}
|
|
1144
|
+
__name(useResource, "useResource");
|
|
1145
|
+
|
|
1146
|
+
// src/catalog/use-agents.ts
|
|
1147
|
+
function useAgents(options) {
|
|
1148
|
+
const { backend, enabled = true } = options;
|
|
1149
|
+
const { data, isLoading, error, refresh } = useResource(() => requireBackendMethod(backend, "listAgents")(), "", enabled);
|
|
1150
|
+
return (0, import_react3.useMemo)(() => {
|
|
1151
|
+
const agents = data ?? [];
|
|
1152
|
+
return {
|
|
1153
|
+
agents,
|
|
1154
|
+
defaultAgent: agents.find((agent) => agent.isDefault === true)?.name ?? null,
|
|
1155
|
+
isLoading,
|
|
1156
|
+
error,
|
|
1157
|
+
refresh
|
|
1158
|
+
};
|
|
1159
|
+
}, [
|
|
1160
|
+
data,
|
|
1161
|
+
isLoading,
|
|
1162
|
+
error,
|
|
1163
|
+
refresh
|
|
1164
|
+
]);
|
|
1165
|
+
}
|
|
1166
|
+
__name(useAgents, "useAgents");
|
|
1167
|
+
|
|
1168
|
+
// src/catalog/use-models.ts
|
|
1169
|
+
var import_react4 = require("react");
|
|
1170
|
+
function useModels(options) {
|
|
1171
|
+
const { backend, agent, enabled = true } = options;
|
|
1172
|
+
const { data, isLoading, error, refresh } = useResource(() => requireBackendMethod(backend, "listModels")(agent), `${agent ?? ""}`, enabled);
|
|
1173
|
+
return (0, import_react4.useMemo)(() => {
|
|
1174
|
+
const providers = data?.providers ?? [];
|
|
1175
|
+
const models = providers.flatMap((provider) => provider.models.map((model) => ({
|
|
1176
|
+
...model,
|
|
1177
|
+
providerId: provider.id,
|
|
1178
|
+
providerLabel: provider.label
|
|
1179
|
+
})));
|
|
1180
|
+
const byId = new Map(models.map((model) => [
|
|
1181
|
+
model.id,
|
|
1182
|
+
model
|
|
1183
|
+
]));
|
|
1184
|
+
return {
|
|
1185
|
+
providers,
|
|
1186
|
+
models,
|
|
1187
|
+
defaultModel: data?.default ?? null,
|
|
1188
|
+
find: /* @__PURE__ */ __name((id) => id == null ? void 0 : byId.get(id), "find"),
|
|
1189
|
+
isLoading,
|
|
1190
|
+
error,
|
|
1191
|
+
refresh
|
|
1192
|
+
};
|
|
1193
|
+
}, [
|
|
1194
|
+
data,
|
|
1195
|
+
isLoading,
|
|
1196
|
+
error,
|
|
1197
|
+
refresh
|
|
1198
|
+
]);
|
|
1199
|
+
}
|
|
1200
|
+
__name(useModels, "useModels");
|
|
1201
|
+
|
|
1202
|
+
// src/quota/use-quota.ts
|
|
1203
|
+
var import_react5 = require("react");
|
|
1204
|
+
|
|
1205
|
+
// src/threads/threads-events.ts
|
|
1206
|
+
var listeners = /* @__PURE__ */ new WeakMap();
|
|
1207
|
+
function notifyThreads(backend, event) {
|
|
1208
|
+
for (const listener of listeners.get(backend) ?? []) {
|
|
1209
|
+
listener(event);
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
__name(notifyThreads, "notifyThreads");
|
|
1213
|
+
function onThreadsEvent(backend, listener) {
|
|
1214
|
+
let set = listeners.get(backend);
|
|
1215
|
+
if (set === void 0) {
|
|
1216
|
+
set = /* @__PURE__ */ new Set();
|
|
1217
|
+
listeners.set(backend, set);
|
|
1218
|
+
}
|
|
1219
|
+
set.add(listener);
|
|
1220
|
+
return () => {
|
|
1221
|
+
set.delete(listener);
|
|
1222
|
+
};
|
|
1223
|
+
}
|
|
1224
|
+
__name(onThreadsEvent, "onThreadsEvent");
|
|
1225
|
+
|
|
1226
|
+
// src/quota/use-quota.ts
|
|
1227
|
+
function useQuota(options) {
|
|
1228
|
+
const { backend, enabled = true, pollMs } = options;
|
|
1229
|
+
const { data, isLoading, error, refresh } = useResource(() => requireBackendMethod(backend, "getQuota")(), "", enabled);
|
|
1230
|
+
(0, import_react5.useEffect)(() => {
|
|
1231
|
+
if (!enabled) return;
|
|
1232
|
+
return onThreadsEvent(backend, (event) => {
|
|
1233
|
+
if (event.type === "changed") void refresh();
|
|
1234
|
+
});
|
|
1235
|
+
}, [
|
|
1236
|
+
backend,
|
|
1237
|
+
enabled,
|
|
1238
|
+
refresh
|
|
1239
|
+
]);
|
|
1240
|
+
(0, import_react5.useEffect)(() => {
|
|
1241
|
+
if (!enabled || pollMs === void 0 || pollMs <= 0) return;
|
|
1242
|
+
const timer = setInterval(() => void refresh(), pollMs);
|
|
1243
|
+
return () => clearInterval(timer);
|
|
1244
|
+
}, [
|
|
1245
|
+
enabled,
|
|
1246
|
+
pollMs,
|
|
1247
|
+
refresh
|
|
1248
|
+
]);
|
|
1249
|
+
return (0, import_react5.useMemo)(() => {
|
|
1250
|
+
const windows = data?.windows ?? [];
|
|
1251
|
+
return {
|
|
1252
|
+
report: data,
|
|
1253
|
+
windows,
|
|
1254
|
+
day: windows.find((window2) => window2.period === "day"),
|
|
1255
|
+
month: windows.find((window2) => window2.period === "month"),
|
|
1256
|
+
blocked: data?.blocked ?? null,
|
|
1257
|
+
isLoading,
|
|
1258
|
+
error,
|
|
1259
|
+
refresh
|
|
1260
|
+
};
|
|
1261
|
+
}, [
|
|
1262
|
+
data,
|
|
1263
|
+
isLoading,
|
|
1264
|
+
error,
|
|
1265
|
+
refresh
|
|
1266
|
+
]);
|
|
1267
|
+
}
|
|
1268
|
+
__name(useQuota, "useQuota");
|
|
1269
|
+
|
|
1270
|
+
// src/feedback/use-message-feedback.ts
|
|
1271
|
+
var import_react6 = require("react");
|
|
1087
1272
|
function useMessageFeedback(options) {
|
|
1088
|
-
const latest = (0,
|
|
1273
|
+
const latest = (0, import_react6.useRef)(options);
|
|
1089
1274
|
latest.current = options;
|
|
1090
|
-
const [local, setLocal] = (0,
|
|
1091
|
-
const [pending, setPending] = (0,
|
|
1092
|
-
const [error, setError] = (0,
|
|
1093
|
-
const localRef = (0,
|
|
1275
|
+
const [local, setLocal] = (0, import_react6.useState)(/* @__PURE__ */ new Map());
|
|
1276
|
+
const [pending, setPending] = (0, import_react6.useState)(/* @__PURE__ */ new Set());
|
|
1277
|
+
const [error, setError] = (0, import_react6.useState)(null);
|
|
1278
|
+
const localRef = (0, import_react6.useRef)(local);
|
|
1094
1279
|
localRef.current = local;
|
|
1095
|
-
const resolved = (0,
|
|
1096
|
-
const feedbackOf = (0,
|
|
1280
|
+
const resolved = (0, import_react6.useRef)(/* @__PURE__ */ new Map());
|
|
1281
|
+
const feedbackOf = (0, import_react6.useCallback)((message) => {
|
|
1097
1282
|
const mine = local.get(message.id);
|
|
1098
1283
|
if (mine !== void 0) return mine.feedback;
|
|
1099
1284
|
return metadataOf(message).feedback ?? null;
|
|
1100
1285
|
}, [
|
|
1101
1286
|
local
|
|
1102
1287
|
]);
|
|
1103
|
-
const isPending = (0,
|
|
1288
|
+
const isPending = (0, import_react6.useCallback)((message) => pending.has(message.id), [
|
|
1104
1289
|
pending
|
|
1105
1290
|
]);
|
|
1106
|
-
const storedIdFor = (0,
|
|
1291
|
+
const storedIdFor = (0, import_react6.useCallback)(async (message) => {
|
|
1107
1292
|
const runId = metadataOf(message).runId;
|
|
1108
1293
|
if (runId === void 0) return message.id;
|
|
1109
1294
|
const known = resolved.current.get(message.id);
|
|
@@ -1123,7 +1308,7 @@ function useMessageFeedback(options) {
|
|
|
1123
1308
|
resolved.current.set(message.id, row.id);
|
|
1124
1309
|
return row.id;
|
|
1125
1310
|
}, []);
|
|
1126
|
-
const rate = (0,
|
|
1311
|
+
const rate = (0, import_react6.useCallback)(async (message, value, comment) => {
|
|
1127
1312
|
const setFeedback = requireBackendMethod(latest.current.backend, "setMessageFeedback");
|
|
1128
1313
|
const had = localRef.current.get(message.id);
|
|
1129
1314
|
const optimistic = value === null ? null : {
|
|
@@ -1169,7 +1354,7 @@ function useMessageFeedback(options) {
|
|
|
1169
1354
|
}, [
|
|
1170
1355
|
storedIdFor
|
|
1171
1356
|
]);
|
|
1172
|
-
const toggle = (0,
|
|
1357
|
+
const toggle = (0, import_react6.useCallback)((message, value) => {
|
|
1173
1358
|
const mine = localRef.current.get(message.id);
|
|
1174
1359
|
const current = mine !== void 0 ? mine.feedback : metadataOf(message).feedback ?? null;
|
|
1175
1360
|
return rate(message, current?.value === value ? null : value);
|
|
@@ -1191,38 +1376,17 @@ function metadataOf(message) {
|
|
|
1191
1376
|
}
|
|
1192
1377
|
__name(metadataOf, "metadataOf");
|
|
1193
1378
|
|
|
1194
|
-
// src/threads/threads-events.ts
|
|
1195
|
-
var listeners = /* @__PURE__ */ new WeakMap();
|
|
1196
|
-
function notifyThreads(backend, event) {
|
|
1197
|
-
for (const listener of listeners.get(backend) ?? []) {
|
|
1198
|
-
listener(event);
|
|
1199
|
-
}
|
|
1200
|
-
}
|
|
1201
|
-
__name(notifyThreads, "notifyThreads");
|
|
1202
|
-
function onThreadsEvent(backend, listener) {
|
|
1203
|
-
let set = listeners.get(backend);
|
|
1204
|
-
if (set === void 0) {
|
|
1205
|
-
set = /* @__PURE__ */ new Set();
|
|
1206
|
-
listeners.set(backend, set);
|
|
1207
|
-
}
|
|
1208
|
-
set.add(listener);
|
|
1209
|
-
return () => {
|
|
1210
|
-
set.delete(listener);
|
|
1211
|
-
};
|
|
1212
|
-
}
|
|
1213
|
-
__name(onThreadsEvent, "onThreadsEvent");
|
|
1214
|
-
|
|
1215
1379
|
// src/threads/use-threads.ts
|
|
1216
|
-
var
|
|
1380
|
+
var import_react7 = require("react");
|
|
1217
1381
|
function useThreads(options) {
|
|
1218
1382
|
const { backend, enabled = true } = options;
|
|
1219
|
-
const [threads, setThreads] = (0,
|
|
1220
|
-
const [isLoading, setIsLoading] = (0,
|
|
1221
|
-
const [error, setError] = (0,
|
|
1222
|
-
const threadsRef = (0,
|
|
1383
|
+
const [threads, setThreads] = (0, import_react7.useState)([]);
|
|
1384
|
+
const [isLoading, setIsLoading] = (0, import_react7.useState)(enabled);
|
|
1385
|
+
const [error, setError] = (0, import_react7.useState)(null);
|
|
1386
|
+
const threadsRef = (0, import_react7.useRef)(threads);
|
|
1223
1387
|
threadsRef.current = threads;
|
|
1224
|
-
const generation = (0,
|
|
1225
|
-
const refresh = (0,
|
|
1388
|
+
const generation = (0, import_react7.useRef)(0);
|
|
1389
|
+
const refresh = (0, import_react7.useCallback)(async () => {
|
|
1226
1390
|
const mine = ++generation.current;
|
|
1227
1391
|
setIsLoading(true);
|
|
1228
1392
|
try {
|
|
@@ -1239,7 +1403,7 @@ function useThreads(options) {
|
|
|
1239
1403
|
}, [
|
|
1240
1404
|
backend
|
|
1241
1405
|
]);
|
|
1242
|
-
(0,
|
|
1406
|
+
(0, import_react7.useEffect)(() => {
|
|
1243
1407
|
if (!enabled) return;
|
|
1244
1408
|
void refresh();
|
|
1245
1409
|
return onThreadsEvent(backend, (event) => {
|
|
@@ -1259,7 +1423,7 @@ function useThreads(options) {
|
|
|
1259
1423
|
enabled,
|
|
1260
1424
|
refresh
|
|
1261
1425
|
]);
|
|
1262
|
-
const rename = (0,
|
|
1426
|
+
const rename = (0, import_react7.useCallback)(async (id, title) => {
|
|
1263
1427
|
const before = threadsRef.current;
|
|
1264
1428
|
setThreads((current) => current.map((thread) => thread.id === id ? {
|
|
1265
1429
|
...thread,
|
|
@@ -1281,7 +1445,7 @@ function useThreads(options) {
|
|
|
1281
1445
|
}, [
|
|
1282
1446
|
backend
|
|
1283
1447
|
]);
|
|
1284
|
-
const remove = (0,
|
|
1448
|
+
const remove = (0, import_react7.useCallback)(async (id) => {
|
|
1285
1449
|
const before = threadsRef.current;
|
|
1286
1450
|
setThreads((current) => current.filter((thread) => thread.id !== id));
|
|
1287
1451
|
try {
|
|
@@ -1356,10 +1520,10 @@ function backgroundRunsFromThread(messages) {
|
|
|
1356
1520
|
__name(backgroundRunsFromThread, "backgroundRunsFromThread");
|
|
1357
1521
|
|
|
1358
1522
|
// src/components/chat-input.tsx
|
|
1359
|
-
var
|
|
1523
|
+
var import_react9 = __toESM(require("react"), 1);
|
|
1360
1524
|
|
|
1361
1525
|
// src/components/use-speech-recognition.ts
|
|
1362
|
-
var
|
|
1526
|
+
var import_react8 = require("react");
|
|
1363
1527
|
function getRecognitionCtor() {
|
|
1364
1528
|
if (typeof window === "undefined") return null;
|
|
1365
1529
|
const scope = window;
|
|
@@ -1367,15 +1531,15 @@ function getRecognitionCtor() {
|
|
|
1367
1531
|
}
|
|
1368
1532
|
__name(getRecognitionCtor, "getRecognitionCtor");
|
|
1369
1533
|
function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTranscript }) {
|
|
1370
|
-
const recognitionRef = (0,
|
|
1371
|
-
const [isListening, setIsListening] = (0,
|
|
1372
|
-
const ctor = (0,
|
|
1534
|
+
const recognitionRef = (0, import_react8.useRef)(null);
|
|
1535
|
+
const [isListening, setIsListening] = (0, import_react8.useState)(false);
|
|
1536
|
+
const ctor = (0, import_react8.useMemo)(() => getRecognitionCtor(), []);
|
|
1373
1537
|
const isSupported = ctor !== null;
|
|
1374
|
-
const finalRef = (0,
|
|
1375
|
-
const interimRef = (0,
|
|
1538
|
+
const finalRef = (0, import_react8.useRef)(onFinalTranscript);
|
|
1539
|
+
const interimRef = (0, import_react8.useRef)(onInterimTranscript);
|
|
1376
1540
|
finalRef.current = onFinalTranscript;
|
|
1377
1541
|
interimRef.current = onInterimTranscript;
|
|
1378
|
-
(0,
|
|
1542
|
+
(0, import_react8.useEffect)(() => {
|
|
1379
1543
|
if (!ctor) return;
|
|
1380
1544
|
const recognition = new ctor();
|
|
1381
1545
|
recognition.lang = lang;
|
|
@@ -1414,7 +1578,7 @@ function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTran
|
|
|
1414
1578
|
ctor,
|
|
1415
1579
|
lang
|
|
1416
1580
|
]);
|
|
1417
|
-
const start = (0,
|
|
1581
|
+
const start = (0, import_react8.useCallback)(() => {
|
|
1418
1582
|
const recognition = recognitionRef.current;
|
|
1419
1583
|
if (!recognition) return;
|
|
1420
1584
|
try {
|
|
@@ -1424,7 +1588,7 @@ function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTran
|
|
|
1424
1588
|
console.warn("SpeechRecognition start failed", error);
|
|
1425
1589
|
}
|
|
1426
1590
|
}, []);
|
|
1427
|
-
const stop = (0,
|
|
1591
|
+
const stop = (0, import_react8.useCallback)(() => {
|
|
1428
1592
|
const recognition = recognitionRef.current;
|
|
1429
1593
|
if (!recognition) return;
|
|
1430
1594
|
try {
|
|
@@ -1443,8 +1607,8 @@ __name(useSpeechRecognition, "useSpeechRecognition");
|
|
|
1443
1607
|
|
|
1444
1608
|
// src/components/chat-input.tsx
|
|
1445
1609
|
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 }) {
|
|
1446
|
-
const [value, setValue] = (0,
|
|
1447
|
-
const [interim, setInterim] = (0,
|
|
1610
|
+
const [value, setValue] = (0, import_react9.useState)("");
|
|
1611
|
+
const [interim, setInterim] = (0, import_react9.useState)("");
|
|
1448
1612
|
const speech = useSpeechRecognition({
|
|
1449
1613
|
lang: speechLang,
|
|
1450
1614
|
onFinalTranscript: /* @__PURE__ */ __name((text) => {
|
|
@@ -1455,7 +1619,7 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
|
|
|
1455
1619
|
}, "onFinalTranscript"),
|
|
1456
1620
|
onInterimTranscript: /* @__PURE__ */ __name((text) => setInterim(text), "onInterimTranscript")
|
|
1457
1621
|
});
|
|
1458
|
-
(0,
|
|
1622
|
+
(0, import_react9.useEffect)(() => {
|
|
1459
1623
|
if (!speech.isListening) setInterim("");
|
|
1460
1624
|
}, [
|
|
1461
1625
|
speech.isListening
|
|
@@ -1483,9 +1647,9 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
|
|
|
1483
1647
|
const displayValue = speech.isListening && interim ? `${value}${value && !value.endsWith(" ") ? " " : ""}${interim}` : value;
|
|
1484
1648
|
const showMic = enableSpeech && speech.isSupported;
|
|
1485
1649
|
const showStop = isStreaming && onStop !== void 0;
|
|
1486
|
-
return /* @__PURE__ */
|
|
1650
|
+
return /* @__PURE__ */ import_react9.default.createElement("div", {
|
|
1487
1651
|
className
|
|
1488
|
-
}, /* @__PURE__ */
|
|
1652
|
+
}, /* @__PURE__ */ import_react9.default.createElement("textarea", {
|
|
1489
1653
|
className: textareaClassName,
|
|
1490
1654
|
rows,
|
|
1491
1655
|
value: displayValue,
|
|
@@ -1496,17 +1660,17 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
|
|
|
1496
1660
|
}, "onChange"),
|
|
1497
1661
|
onKeyDown: handleKeyDown,
|
|
1498
1662
|
placeholder: placeholder ?? "Ask something (Enter to send, Shift+Enter for newline)"
|
|
1499
|
-
}), /* @__PURE__ */
|
|
1663
|
+
}), /* @__PURE__ */ import_react9.default.createElement("button", {
|
|
1500
1664
|
type: "button",
|
|
1501
1665
|
className: sendButtonClassName,
|
|
1502
1666
|
onClick: submit,
|
|
1503
1667
|
disabled: disabled || !value.trim()
|
|
1504
|
-
}, sendLabel), showStop ? /* @__PURE__ */
|
|
1668
|
+
}, sendLabel), showStop ? /* @__PURE__ */ import_react9.default.createElement("button", {
|
|
1505
1669
|
type: "button",
|
|
1506
1670
|
className: stopButtonClassName,
|
|
1507
1671
|
onClick: /* @__PURE__ */ __name(() => void onStop(), "onClick"),
|
|
1508
1672
|
"aria-label": "Stop generating"
|
|
1509
|
-
}, stopLabel) : null, showMic ? /* @__PURE__ */
|
|
1673
|
+
}, stopLabel) : null, showMic ? /* @__PURE__ */ import_react9.default.createElement("button", {
|
|
1510
1674
|
type: "button",
|
|
1511
1675
|
className: micButtonClassName,
|
|
1512
1676
|
onClick: toggleMic,
|
|
@@ -1519,10 +1683,10 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
|
|
|
1519
1683
|
__name(ChatInput, "ChatInput");
|
|
1520
1684
|
|
|
1521
1685
|
// src/components/message-item.tsx
|
|
1522
|
-
var
|
|
1686
|
+
var import_react12 = __toESM(require("react"), 1);
|
|
1523
1687
|
|
|
1524
1688
|
// src/transcript/use-chat-transcript.ts
|
|
1525
|
-
var
|
|
1689
|
+
var import_react11 = require("react");
|
|
1526
1690
|
|
|
1527
1691
|
// src/transcript/model.ts
|
|
1528
1692
|
var import_nestjs_agent_core2 = require("@dudousxd/nestjs-agent-core");
|
|
@@ -2499,11 +2663,11 @@ function formatCostUsd(cost) {
|
|
|
2499
2663
|
__name(formatCostUsd, "formatCostUsd");
|
|
2500
2664
|
|
|
2501
2665
|
// src/transcript/use-stick-to-bottom.ts
|
|
2502
|
-
var
|
|
2666
|
+
var import_react10 = require("react");
|
|
2503
2667
|
function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
2504
|
-
const containerRef = (0,
|
|
2505
|
-
const [isAtBottom, setIsAtBottom] = (0,
|
|
2506
|
-
const measure = (0,
|
|
2668
|
+
const containerRef = (0, import_react10.useRef)(null);
|
|
2669
|
+
const [isAtBottom, setIsAtBottom] = (0, import_react10.useState)(true);
|
|
2670
|
+
const measure = (0, import_react10.useCallback)(() => {
|
|
2507
2671
|
const element = containerRef.current;
|
|
2508
2672
|
if (!element) {
|
|
2509
2673
|
return;
|
|
@@ -2513,7 +2677,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
|
2513
2677
|
}, [
|
|
2514
2678
|
threshold
|
|
2515
2679
|
]);
|
|
2516
|
-
const scrollToBottom = (0,
|
|
2680
|
+
const scrollToBottom = (0, import_react10.useCallback)(() => {
|
|
2517
2681
|
const element = containerRef.current;
|
|
2518
2682
|
if (!element) {
|
|
2519
2683
|
return;
|
|
@@ -2521,7 +2685,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
|
2521
2685
|
element.scrollTop = element.scrollHeight;
|
|
2522
2686
|
setIsAtBottom(true);
|
|
2523
2687
|
}, []);
|
|
2524
|
-
const setContainer = (0,
|
|
2688
|
+
const setContainer = (0, import_react10.useCallback)((element) => {
|
|
2525
2689
|
containerRef.current = element;
|
|
2526
2690
|
if (element) {
|
|
2527
2691
|
measure();
|
|
@@ -2529,7 +2693,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
|
2529
2693
|
}, [
|
|
2530
2694
|
measure
|
|
2531
2695
|
]);
|
|
2532
|
-
(0,
|
|
2696
|
+
(0, import_react10.useEffect)(() => {
|
|
2533
2697
|
if (isAtBottom) {
|
|
2534
2698
|
scrollToBottom();
|
|
2535
2699
|
}
|
|
@@ -2538,7 +2702,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
|
2538
2702
|
isAtBottom,
|
|
2539
2703
|
scrollToBottom
|
|
2540
2704
|
]);
|
|
2541
|
-
const getContainerProps = (0,
|
|
2705
|
+
const getContainerProps = (0, import_react10.useCallback)(() => ({
|
|
2542
2706
|
ref: setContainer,
|
|
2543
2707
|
onScroll: measure
|
|
2544
2708
|
}), [
|
|
@@ -2560,14 +2724,14 @@ var DEFAULT_LOAD_EARLIER_STEP = 50;
|
|
|
2560
2724
|
var DEFAULT_COPY_RESET_MS = 1500;
|
|
2561
2725
|
function useChatTranscript(options) {
|
|
2562
2726
|
const { messages, status, initialVisibleCount = DEFAULT_VISIBLE_COUNT, loadEarlierStep = DEFAULT_LOAD_EARLIER_STEP, followUps, stickToBottomThreshold } = options;
|
|
2563
|
-
const latest = (0,
|
|
2727
|
+
const latest = (0, import_react11.useRef)(options);
|
|
2564
2728
|
latest.current = options;
|
|
2565
|
-
const [visibleCount, setVisibleCount] = (0,
|
|
2566
|
-
const [stopRequested, setStopRequested] = (0,
|
|
2729
|
+
const [visibleCount, setVisibleCount] = (0, import_react11.useState)(initialVisibleCount);
|
|
2730
|
+
const [stopRequested, setStopRequested] = (0, import_react11.useState)(false);
|
|
2567
2731
|
const isStreaming = status === "streaming" || status === "reconnecting";
|
|
2568
2732
|
const isBusy = status === "submitted" || isStreaming;
|
|
2569
2733
|
const isEmpty = messages.length === 0;
|
|
2570
|
-
(0,
|
|
2734
|
+
(0, import_react11.useEffect)(() => {
|
|
2571
2735
|
if (!isBusy) {
|
|
2572
2736
|
setStopRequested(false);
|
|
2573
2737
|
}
|
|
@@ -2584,7 +2748,7 @@ function useChatTranscript(options) {
|
|
|
2584
2748
|
streamingMessageId,
|
|
2585
2749
|
options
|
|
2586
2750
|
});
|
|
2587
|
-
const stop = (0,
|
|
2751
|
+
const stop = (0, import_react11.useCallback)(() => {
|
|
2588
2752
|
const current = latest.current;
|
|
2589
2753
|
if (current.status !== "submitted" && current.status !== "streaming" && current.status !== "reconnecting") {
|
|
2590
2754
|
return;
|
|
@@ -2592,8 +2756,8 @@ function useChatTranscript(options) {
|
|
|
2592
2756
|
setStopRequested(true);
|
|
2593
2757
|
void current.onStop?.();
|
|
2594
2758
|
}, []);
|
|
2595
|
-
const loadEarlier = (0,
|
|
2596
|
-
const showAll = (0,
|
|
2759
|
+
const loadEarlier = (0, import_react11.useCallback)(() => setVisibleCount((count) => count + (latest.current.loadEarlierStep ?? DEFAULT_LOAD_EARLIER_STEP)), []);
|
|
2760
|
+
const showAll = (0, import_react11.useCallback)(() => setVisibleCount(latest.current.messages.length), []);
|
|
2597
2761
|
const scroll = useStickToBottom({
|
|
2598
2762
|
contentKey: contentSignature(messages),
|
|
2599
2763
|
...stickToBottomThreshold !== void 0 ? {
|
|
@@ -2629,7 +2793,7 @@ function useChatTranscript(options) {
|
|
|
2629
2793
|
__name(useChatTranscript, "useChatTranscript");
|
|
2630
2794
|
function useTranscriptItem(options) {
|
|
2631
2795
|
const { message, isStreaming = false } = options;
|
|
2632
|
-
const messagesRef = (0,
|
|
2796
|
+
const messagesRef = (0, import_react11.useRef)([
|
|
2633
2797
|
message
|
|
2634
2798
|
]);
|
|
2635
2799
|
if (messagesRef.current[0] !== message) {
|
|
@@ -2647,13 +2811,13 @@ function useTranscriptItem(options) {
|
|
|
2647
2811
|
}
|
|
2648
2812
|
__name(useTranscriptItem, "useTranscriptItem");
|
|
2649
2813
|
function useTranscriptItems({ messages, visibleStart, streamingMessageId, options }) {
|
|
2650
|
-
const [drafts, setDrafts] = (0,
|
|
2651
|
-
const [copied, setCopied] = (0,
|
|
2652
|
-
const [openReasoning, setOpenReasoning] = (0,
|
|
2653
|
-
const [picks, setPicks] = (0,
|
|
2654
|
-
const [settling, setSettling] = (0,
|
|
2655
|
-
const [settleErrors, setSettleErrors] = (0,
|
|
2656
|
-
const latest = (0,
|
|
2814
|
+
const [drafts, setDrafts] = (0, import_react11.useState)(() => /* @__PURE__ */ new Map());
|
|
2815
|
+
const [copied, setCopied] = (0, import_react11.useState)(() => /* @__PURE__ */ new Set());
|
|
2816
|
+
const [openReasoning, setOpenReasoning] = (0, import_react11.useState)(() => /* @__PURE__ */ new Map());
|
|
2817
|
+
const [picks, setPicks] = (0, import_react11.useState)(() => /* @__PURE__ */ new Map());
|
|
2818
|
+
const [settling, setSettling] = (0, import_react11.useState)(() => /* @__PURE__ */ new Map());
|
|
2819
|
+
const [settleErrors, setSettleErrors] = (0, import_react11.useState)(() => /* @__PURE__ */ new Map());
|
|
2820
|
+
const latest = (0, import_react11.useRef)({
|
|
2657
2821
|
options,
|
|
2658
2822
|
drafts,
|
|
2659
2823
|
picks,
|
|
@@ -2665,23 +2829,23 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2665
2829
|
picks,
|
|
2666
2830
|
messages
|
|
2667
2831
|
};
|
|
2668
|
-
const copyTimers = (0,
|
|
2669
|
-
(0,
|
|
2832
|
+
const copyTimers = (0, import_react11.useRef)(/* @__PURE__ */ new Map());
|
|
2833
|
+
(0, import_react11.useEffect)(() => () => {
|
|
2670
2834
|
for (const timer of copyTimers.current.values()) {
|
|
2671
2835
|
clearTimeout(timer);
|
|
2672
2836
|
}
|
|
2673
2837
|
copyTimers.current.clear();
|
|
2674
2838
|
}, []);
|
|
2675
|
-
const callbackCache = (0,
|
|
2676
|
-
const reasoningToggleCache = (0,
|
|
2677
|
-
const toggleReasoning = (0,
|
|
2839
|
+
const callbackCache = (0, import_react11.useRef)(/* @__PURE__ */ new Map());
|
|
2840
|
+
const reasoningToggleCache = (0, import_react11.useRef)(/* @__PURE__ */ new Map());
|
|
2841
|
+
const toggleReasoning = (0, import_react11.useCallback)((key, open) => {
|
|
2678
2842
|
setOpenReasoning((current) => {
|
|
2679
2843
|
const next = new Map(current);
|
|
2680
2844
|
next.set(key, open ?? !(current.get(key) ?? false));
|
|
2681
2845
|
return next;
|
|
2682
2846
|
});
|
|
2683
2847
|
}, []);
|
|
2684
|
-
const stableToggle = (0,
|
|
2848
|
+
const stableToggle = (0, import_react11.useCallback)((key) => {
|
|
2685
2849
|
let cached = reasoningToggleCache.current.get(key);
|
|
2686
2850
|
if (!cached) {
|
|
2687
2851
|
cached = /* @__PURE__ */ __name((open) => toggleReasoning(key, open), "cached");
|
|
@@ -2691,10 +2855,10 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2691
2855
|
}, [
|
|
2692
2856
|
toggleReasoning
|
|
2693
2857
|
]);
|
|
2694
|
-
const pick = (0,
|
|
2858
|
+
const pick = (0, import_react11.useCallback)((toolCallId, questionId, values) => {
|
|
2695
2859
|
setPicks((current) => new Map(current).set(pickKey(toolCallId, questionId), values));
|
|
2696
2860
|
}, []);
|
|
2697
|
-
const settle = (0,
|
|
2861
|
+
const settle = (0, import_react11.useCallback)((toolCallId, action, send) => {
|
|
2698
2862
|
setSettleErrors((current) => {
|
|
2699
2863
|
if (!current.has(toolCallId)) {
|
|
2700
2864
|
return current;
|
|
@@ -2718,7 +2882,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2718
2882
|
failed(error);
|
|
2719
2883
|
}
|
|
2720
2884
|
}, []);
|
|
2721
|
-
const answer = (0,
|
|
2885
|
+
const answer = (0, import_react11.useCallback)((toolCallId) => {
|
|
2722
2886
|
const current = latest.current;
|
|
2723
2887
|
const onAnswer = current.options.onAnswer;
|
|
2724
2888
|
if (!onAnswer) {
|
|
@@ -2728,7 +2892,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2728
2892
|
}, [
|
|
2729
2893
|
settle
|
|
2730
2894
|
]);
|
|
2731
|
-
const skip = (0,
|
|
2895
|
+
const skip = (0, import_react11.useCallback)((toolCallId) => {
|
|
2732
2896
|
const onSkip = latest.current.options.onSkip;
|
|
2733
2897
|
if (onSkip) {
|
|
2734
2898
|
settle(toolCallId, "skip", () => onSkip(toolCallId));
|
|
@@ -2736,7 +2900,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2736
2900
|
}, [
|
|
2737
2901
|
settle
|
|
2738
2902
|
]);
|
|
2739
|
-
const approve = (0,
|
|
2903
|
+
const approve = (0, import_react11.useCallback)((toolCallId, options2) => {
|
|
2740
2904
|
const onApprove = latest.current.options.onApprove;
|
|
2741
2905
|
if (onApprove) {
|
|
2742
2906
|
settle(toolCallId, "approve", () => options2 === void 0 ? onApprove(toolCallId) : onApprove(toolCallId, options2));
|
|
@@ -2744,7 +2908,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2744
2908
|
}, [
|
|
2745
2909
|
settle
|
|
2746
2910
|
]);
|
|
2747
|
-
const reject = (0,
|
|
2911
|
+
const reject = (0, import_react11.useCallback)((toolCallId) => {
|
|
2748
2912
|
const onReject = latest.current.options.onReject;
|
|
2749
2913
|
if (onReject) {
|
|
2750
2914
|
settle(toolCallId, "reject", () => onReject(toolCallId));
|
|
@@ -2752,7 +2916,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2752
2916
|
}, [
|
|
2753
2917
|
settle
|
|
2754
2918
|
]);
|
|
2755
|
-
const callbacksFor = (0,
|
|
2919
|
+
const callbacksFor = (0, import_react11.useCallback)((id) => {
|
|
2756
2920
|
const cached = callbackCache.current.get(id);
|
|
2757
2921
|
if (cached) {
|
|
2758
2922
|
return cached;
|
|
@@ -2994,7 +3158,7 @@ function MessageItem({ message, isStreaming = false, editable, onEditSubmit, reg
|
|
|
2994
3158
|
getCreatedAt: /* @__PURE__ */ __name(() => createdAt, "getCreatedAt")
|
|
2995
3159
|
} : {}
|
|
2996
3160
|
});
|
|
2997
|
-
return /* @__PURE__ */
|
|
3161
|
+
return /* @__PURE__ */ import_react12.default.createElement(MessageItemView, {
|
|
2998
3162
|
item,
|
|
2999
3163
|
...slots
|
|
3000
3164
|
});
|
|
@@ -3002,51 +3166,51 @@ function MessageItem({ message, isStreaming = false, editable, onEditSubmit, reg
|
|
|
3002
3166
|
__name(MessageItem, "MessageItem");
|
|
3003
3167
|
function MessageItemView({ item, ...slots }) {
|
|
3004
3168
|
const { classNames } = slots;
|
|
3005
|
-
const actionRow = /* @__PURE__ */
|
|
3169
|
+
const actionRow = /* @__PURE__ */ import_react12.default.createElement("div", {
|
|
3006
3170
|
className: classNames?.actions,
|
|
3007
3171
|
"data-actions-for": item.role
|
|
3008
|
-
}, item.copy.available ? /* @__PURE__ */
|
|
3172
|
+
}, item.copy.available ? /* @__PURE__ */ import_react12.default.createElement("button", {
|
|
3009
3173
|
type: "button",
|
|
3010
3174
|
onClick: item.copy.copy,
|
|
3011
3175
|
className: classNames?.actionButton,
|
|
3012
3176
|
title: item.copy.copied ? "Copied!" : "Copy message text"
|
|
3013
|
-
}, item.copy.copied ? "Copied" : "Copy") : null, item.fork.available ? /* @__PURE__ */
|
|
3177
|
+
}, item.copy.copied ? "Copied" : "Copy") : null, item.fork.available ? /* @__PURE__ */ import_react12.default.createElement("button", {
|
|
3014
3178
|
type: "button",
|
|
3015
3179
|
onClick: item.fork.run,
|
|
3016
3180
|
className: classNames?.actionButton,
|
|
3017
3181
|
title: "Fork thread from this message"
|
|
3018
|
-
}, "Fork") : null, item.regenerate.available ? /* @__PURE__ */
|
|
3182
|
+
}, "Fork") : null, item.regenerate.available ? /* @__PURE__ */ import_react12.default.createElement("button", {
|
|
3019
3183
|
type: "button",
|
|
3020
3184
|
onClick: item.regenerate.run,
|
|
3021
3185
|
className: classNames?.actionButton,
|
|
3022
3186
|
title: "Regenerate response"
|
|
3023
|
-
}, "Regenerate") : null, slots.meta, !item.isUser && item.usage ? /* @__PURE__ */
|
|
3187
|
+
}, "Regenerate") : null, slots.meta, !item.isUser && item.usage ? /* @__PURE__ */ import_react12.default.createElement("span", {
|
|
3024
3188
|
className: classNames?.usage,
|
|
3025
3189
|
title: `Input ${item.usage.inputTokens.toLocaleString()} \xB7 Output ${item.usage.outputTokens.toLocaleString()} tokens`
|
|
3026
|
-
}, item.usage.costLabel, " \xB7 ", item.usage.tokensLabel) : null, item.timestamp ? /* @__PURE__ */
|
|
3190
|
+
}, item.usage.costLabel, " \xB7 ", item.usage.tokensLabel) : null, item.timestamp ? /* @__PURE__ */ import_react12.default.createElement("span", {
|
|
3027
3191
|
className: classNames?.timestamp,
|
|
3028
3192
|
title: item.timestamp.absolute
|
|
3029
3193
|
}, item.timestamp.relative) : null);
|
|
3030
3194
|
if (item.edit.available) {
|
|
3031
|
-
return /* @__PURE__ */
|
|
3195
|
+
return /* @__PURE__ */ import_react12.default.createElement(EditableUserBubble, {
|
|
3032
3196
|
item,
|
|
3033
3197
|
slots,
|
|
3034
3198
|
actions: actionRow
|
|
3035
3199
|
});
|
|
3036
3200
|
}
|
|
3037
3201
|
const className = joinClasses(classNames?.root, classNames?.byRole?.[item.role]);
|
|
3038
|
-
return /* @__PURE__ */
|
|
3202
|
+
return /* @__PURE__ */ import_react12.default.createElement("div", {
|
|
3039
3203
|
className,
|
|
3040
3204
|
"data-role": item.role,
|
|
3041
3205
|
"data-streaming": item.isStreaming ? "true" : void 0
|
|
3042
|
-
}, /* @__PURE__ */
|
|
3206
|
+
}, /* @__PURE__ */ import_react12.default.createElement("div", null, renderBlocks(item, slots)), actionRow);
|
|
3043
3207
|
}
|
|
3044
3208
|
__name(MessageItemView, "MessageItemView");
|
|
3045
3209
|
function renderBlocks(item, slots) {
|
|
3046
3210
|
const nodes = [];
|
|
3047
3211
|
for (const block of item.blocks) {
|
|
3048
3212
|
if (block.kind === "text") {
|
|
3049
|
-
nodes.push(/* @__PURE__ */
|
|
3213
|
+
nodes.push(/* @__PURE__ */ import_react12.default.createElement("div", {
|
|
3050
3214
|
key: block.key,
|
|
3051
3215
|
className: slots.classNames?.text
|
|
3052
3216
|
}, slots.renderText ? slots.renderText(block.text, {
|
|
@@ -3067,7 +3231,7 @@ function renderBlocks(item, slots) {
|
|
|
3067
3231
|
continue;
|
|
3068
3232
|
}
|
|
3069
3233
|
if (block.kind === "ui" && slots.renderUi) {
|
|
3070
|
-
nodes.push(/* @__PURE__ */
|
|
3234
|
+
nodes.push(/* @__PURE__ */ import_react12.default.createElement("div", {
|
|
3071
3235
|
key: block.key,
|
|
3072
3236
|
"data-slot": "ui",
|
|
3073
3237
|
"data-component": block.component
|
|
@@ -3078,18 +3242,18 @@ function renderBlocks(item, slots) {
|
|
|
3078
3242
|
}
|
|
3079
3243
|
__name(renderBlocks, "renderBlocks");
|
|
3080
3244
|
function renderFilesBlock(block, slots) {
|
|
3081
|
-
return /* @__PURE__ */
|
|
3245
|
+
return /* @__PURE__ */ import_react12.default.createElement("div", {
|
|
3082
3246
|
key: block.key,
|
|
3083
3247
|
className: slots.classNames?.files,
|
|
3084
3248
|
"data-files": "true"
|
|
3085
|
-
}, slots.renderFiles ? slots.renderFiles(block.files) : block.files.map((file) => /* @__PURE__ */
|
|
3249
|
+
}, slots.renderFiles ? slots.renderFiles(block.files) : block.files.map((file) => /* @__PURE__ */ import_react12.default.createElement("a", {
|
|
3086
3250
|
key: file.url,
|
|
3087
3251
|
href: file.url,
|
|
3088
3252
|
target: "_blank",
|
|
3089
3253
|
rel: "noreferrer",
|
|
3090
3254
|
className: slots.classNames?.file,
|
|
3091
3255
|
title: file.filename ?? file.mediaType
|
|
3092
|
-
}, file.isImage ? /* @__PURE__ */
|
|
3256
|
+
}, file.isImage ? /* @__PURE__ */ import_react12.default.createElement("img", {
|
|
3093
3257
|
src: file.url,
|
|
3094
3258
|
alt: file.filename ?? "image",
|
|
3095
3259
|
className: slots.classNames?.fileImage
|
|
@@ -3097,17 +3261,17 @@ function renderFilesBlock(block, slots) {
|
|
|
3097
3261
|
}
|
|
3098
3262
|
__name(renderFilesBlock, "renderFilesBlock");
|
|
3099
3263
|
function renderReasoningBlock(block, slots) {
|
|
3100
|
-
return /* @__PURE__ */
|
|
3264
|
+
return /* @__PURE__ */ import_react12.default.createElement("div", {
|
|
3101
3265
|
key: block.key,
|
|
3102
3266
|
className: slots.classNames?.reasoning,
|
|
3103
3267
|
"data-reasoning": "true",
|
|
3104
3268
|
"data-streaming": block.isStreaming ? "true" : void 0
|
|
3105
|
-
}, /* @__PURE__ */
|
|
3269
|
+
}, /* @__PURE__ */ import_react12.default.createElement("button", {
|
|
3106
3270
|
type: "button",
|
|
3107
3271
|
className: slots.classNames?.reasoningToggle,
|
|
3108
3272
|
onClick: /* @__PURE__ */ __name(() => block.toggle(), "onClick"),
|
|
3109
3273
|
"aria-expanded": block.isOpen
|
|
3110
|
-
}, slots.reasoningLabel ?? "Reasoning"), block.isOpen ? /* @__PURE__ */
|
|
3274
|
+
}, slots.reasoningLabel ?? "Reasoning"), block.isOpen ? /* @__PURE__ */ import_react12.default.createElement("div", {
|
|
3111
3275
|
className: slots.classNames?.reasoningText
|
|
3112
3276
|
}, slots.renderReasoning ? slots.renderReasoning(block.text, {
|
|
3113
3277
|
isStreaming: block.isStreaming,
|
|
@@ -3118,7 +3282,7 @@ __name(renderReasoningBlock, "renderReasoningBlock");
|
|
|
3118
3282
|
function renderToolBlock(item, block, slots) {
|
|
3119
3283
|
if (slots.renderToolGroup) {
|
|
3120
3284
|
return [
|
|
3121
|
-
/* @__PURE__ */
|
|
3285
|
+
/* @__PURE__ */ import_react12.default.createElement(import_react12.default.Fragment, {
|
|
3122
3286
|
key: block.key
|
|
3123
3287
|
}, slots.renderToolGroup(block.parts, block.key))
|
|
3124
3288
|
];
|
|
@@ -3129,7 +3293,7 @@ function renderToolBlock(item, block, slots) {
|
|
|
3129
3293
|
const renderToolPart = slots.renderToolPart;
|
|
3130
3294
|
return block.parts.map((part) => {
|
|
3131
3295
|
const partKey = `${item.id}-${part.toolCallId}`;
|
|
3132
|
-
return /* @__PURE__ */
|
|
3296
|
+
return /* @__PURE__ */ import_react12.default.createElement(import_react12.default.Fragment, {
|
|
3133
3297
|
key: partKey
|
|
3134
3298
|
}, renderToolPart(part, partKey));
|
|
3135
3299
|
});
|
|
@@ -3139,14 +3303,14 @@ function EditableUserBubble({ item, slots, actions }) {
|
|
|
3139
3303
|
const { classNames } = slots;
|
|
3140
3304
|
const { edit } = item;
|
|
3141
3305
|
if (!edit.isEditing) {
|
|
3142
|
-
return /* @__PURE__ */
|
|
3306
|
+
return /* @__PURE__ */ import_react12.default.createElement("div", {
|
|
3143
3307
|
className: joinClasses(classNames?.root, classNames?.byRole?.user),
|
|
3144
3308
|
"data-role": "user"
|
|
3145
|
-
}, /* @__PURE__ */
|
|
3309
|
+
}, /* @__PURE__ */ import_react12.default.createElement("div", {
|
|
3146
3310
|
className: classNames?.text
|
|
3147
3311
|
}, slots.renderText ? slots.renderText(item.text, {
|
|
3148
3312
|
isStreaming: false
|
|
3149
|
-
}) : item.text), /* @__PURE__ */
|
|
3313
|
+
}) : item.text), /* @__PURE__ */ import_react12.default.createElement("button", {
|
|
3150
3314
|
type: "button",
|
|
3151
3315
|
onClick: edit.start,
|
|
3152
3316
|
className: classNames?.actionButton,
|
|
@@ -3154,18 +3318,18 @@ function EditableUserBubble({ item, slots, actions }) {
|
|
|
3154
3318
|
}, "Edit"), actions);
|
|
3155
3319
|
}
|
|
3156
3320
|
const textareaProps = edit.getTextareaProps();
|
|
3157
|
-
return /* @__PURE__ */
|
|
3321
|
+
return /* @__PURE__ */ import_react12.default.createElement("div", {
|
|
3158
3322
|
"data-editing": "true"
|
|
3159
|
-
}, /* @__PURE__ */
|
|
3323
|
+
}, /* @__PURE__ */ import_react12.default.createElement("textarea", {
|
|
3160
3324
|
...textareaProps,
|
|
3161
3325
|
rows: Math.min(8, edit.draft.split("\n").length + 1),
|
|
3162
3326
|
className: classNames?.editTextarea
|
|
3163
|
-
}), /* @__PURE__ */
|
|
3327
|
+
}), /* @__PURE__ */ import_react12.default.createElement("div", {
|
|
3164
3328
|
className: classNames?.editActions
|
|
3165
|
-
}, /* @__PURE__ */
|
|
3329
|
+
}, /* @__PURE__ */ import_react12.default.createElement("button", {
|
|
3166
3330
|
type: "button",
|
|
3167
3331
|
onClick: edit.cancel
|
|
3168
|
-
}, "Cancel"), /* @__PURE__ */
|
|
3332
|
+
}, "Cancel"), /* @__PURE__ */ import_react12.default.createElement("button", {
|
|
3169
3333
|
type: "button",
|
|
3170
3334
|
onClick: edit.save,
|
|
3171
3335
|
disabled: !edit.canSave
|
|
@@ -3409,35 +3573,35 @@ function toItem(entry) {
|
|
|
3409
3573
|
__name(toItem, "toItem");
|
|
3410
3574
|
|
|
3411
3575
|
// src/composer/use-composer-autocomplete.ts
|
|
3412
|
-
var
|
|
3576
|
+
var import_react13 = require("react");
|
|
3413
3577
|
function useComposerAutocomplete(options) {
|
|
3414
3578
|
const { value, sources, acceptOnTab = true } = options;
|
|
3415
|
-
const latest = (0,
|
|
3579
|
+
const latest = (0, import_react13.useRef)(options);
|
|
3416
3580
|
latest.current = options;
|
|
3417
|
-
const inputRef = (0,
|
|
3418
|
-
const [caret, setCaret] = (0,
|
|
3419
|
-
const [items, setItems] = (0,
|
|
3420
|
-
const [isLoading, setLoading] = (0,
|
|
3421
|
-
const [error, setError] = (0,
|
|
3422
|
-
const [activeIndex, setActiveIndex] = (0,
|
|
3423
|
-
const [dismissedIndex, setDismissedIndex] = (0,
|
|
3581
|
+
const inputRef = (0, import_react13.useRef)(null);
|
|
3582
|
+
const [caret, setCaret] = (0, import_react13.useState)(value.length);
|
|
3583
|
+
const [items, setItems] = (0, import_react13.useState)([]);
|
|
3584
|
+
const [isLoading, setLoading] = (0, import_react13.useState)(false);
|
|
3585
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
3586
|
+
const [activeIndex, setActiveIndex] = (0, import_react13.useState)(0);
|
|
3587
|
+
const [dismissedIndex, setDismissedIndex] = (0, import_react13.useState)(null);
|
|
3424
3588
|
const safeCaret = Math.min(caret, value.length);
|
|
3425
|
-
const match = (0,
|
|
3589
|
+
const match = (0, import_react13.useMemo)(() => findActiveTrigger(value, safeCaret, sources), [
|
|
3426
3590
|
value,
|
|
3427
3591
|
safeCaret,
|
|
3428
3592
|
sources
|
|
3429
3593
|
]);
|
|
3430
3594
|
const isActive = match !== null && dismissedIndex !== match.index;
|
|
3431
|
-
const matchRef = (0,
|
|
3595
|
+
const matchRef = (0, import_react13.useRef)(match);
|
|
3432
3596
|
matchRef.current = match;
|
|
3433
|
-
const caretRef = (0,
|
|
3597
|
+
const caretRef = (0, import_react13.useRef)(safeCaret);
|
|
3434
3598
|
caretRef.current = safeCaret;
|
|
3435
|
-
const itemsRef = (0,
|
|
3599
|
+
const itemsRef = (0, import_react13.useRef)(items);
|
|
3436
3600
|
itemsRef.current = items;
|
|
3437
|
-
const activeIndexRef = (0,
|
|
3601
|
+
const activeIndexRef = (0, import_react13.useRef)(activeIndex);
|
|
3438
3602
|
activeIndexRef.current = activeIndex;
|
|
3439
3603
|
const requestKey = isActive && match ? `${match.source.id}\0${match.query}` : null;
|
|
3440
|
-
(0,
|
|
3604
|
+
(0, import_react13.useEffect)(() => {
|
|
3441
3605
|
const current = matchRef.current;
|
|
3442
3606
|
if (requestKey === null || current === null) {
|
|
3443
3607
|
setItems([]);
|
|
@@ -3485,25 +3649,25 @@ function useComposerAutocomplete(options) {
|
|
|
3485
3649
|
]);
|
|
3486
3650
|
const isOpen = isActive;
|
|
3487
3651
|
const activeItem = isOpen ? items[activeIndex] ?? null : null;
|
|
3488
|
-
const reactId = (0,
|
|
3652
|
+
const reactId = (0, import_react13.useId)();
|
|
3489
3653
|
const listboxId = options.id ?? `agent-autocomplete-${reactId}`;
|
|
3490
|
-
const optionId = (0,
|
|
3654
|
+
const optionId = (0, import_react13.useCallback)((index) => `${listboxId}-option-${index}`, [
|
|
3491
3655
|
listboxId
|
|
3492
3656
|
]);
|
|
3493
|
-
const highlight = (0,
|
|
3657
|
+
const highlight = (0, import_react13.useCallback)((index) => {
|
|
3494
3658
|
const total = itemsRef.current.length;
|
|
3495
3659
|
if (total === 0) return;
|
|
3496
3660
|
setActiveIndex((index % total + total) % total);
|
|
3497
3661
|
}, []);
|
|
3498
|
-
const moveHighlight = (0,
|
|
3662
|
+
const moveHighlight = (0, import_react13.useCallback)((delta) => highlight(activeIndexRef.current + delta), [
|
|
3499
3663
|
highlight
|
|
3500
3664
|
]);
|
|
3501
|
-
const dismiss = (0,
|
|
3665
|
+
const dismiss = (0, import_react13.useCallback)(() => {
|
|
3502
3666
|
const current = matchRef.current;
|
|
3503
3667
|
if (current) setDismissedIndex(current.index);
|
|
3504
3668
|
}, []);
|
|
3505
|
-
const pendingCaret = (0,
|
|
3506
|
-
const accept = (0,
|
|
3669
|
+
const pendingCaret = (0, import_react13.useRef)(null);
|
|
3670
|
+
const accept = (0, import_react13.useCallback)((item) => {
|
|
3507
3671
|
const current = matchRef.current;
|
|
3508
3672
|
if (!current) return;
|
|
3509
3673
|
const chosen = item ?? itemsRef.current[activeIndexRef.current];
|
|
@@ -3514,16 +3678,16 @@ function useComposerAutocomplete(options) {
|
|
|
3514
3678
|
setDismissedIndex(null);
|
|
3515
3679
|
pendingCaret.current = edit.caret;
|
|
3516
3680
|
}, []);
|
|
3517
|
-
(0,
|
|
3681
|
+
(0, import_react13.useLayoutEffect)(() => {
|
|
3518
3682
|
const position = pendingCaret.current;
|
|
3519
3683
|
if (position === null) return;
|
|
3520
3684
|
pendingCaret.current = null;
|
|
3521
3685
|
inputRef.current?.setSelectionRange(position, position);
|
|
3522
3686
|
});
|
|
3523
|
-
const readCaret = (0,
|
|
3687
|
+
const readCaret = (0, import_react13.useCallback)((element) => {
|
|
3524
3688
|
setCaret(element.selectionStart ?? element.value.length);
|
|
3525
3689
|
}, []);
|
|
3526
|
-
const onKeyDown = (0,
|
|
3690
|
+
const onKeyDown = (0, import_react13.useCallback)((event) => {
|
|
3527
3691
|
if (!isOpen) return;
|
|
3528
3692
|
const hasItems = itemsRef.current.length > 0;
|
|
3529
3693
|
switch (event.key) {
|
|
@@ -3561,23 +3725,23 @@ function useComposerAutocomplete(options) {
|
|
|
3561
3725
|
dismiss,
|
|
3562
3726
|
moveHighlight
|
|
3563
3727
|
]);
|
|
3564
|
-
const onChange = (0,
|
|
3728
|
+
const onChange = (0, import_react13.useCallback)((event) => {
|
|
3565
3729
|
readCaret(event.target);
|
|
3566
3730
|
const next = findActiveTrigger(event.target.value, event.target.selectionStart ?? event.target.value.length, latest.current.sources);
|
|
3567
3731
|
setDismissedIndex((current) => current !== null && next?.index === current ? current : null);
|
|
3568
3732
|
}, [
|
|
3569
3733
|
readCaret
|
|
3570
3734
|
]);
|
|
3571
|
-
const onSelect = (0,
|
|
3735
|
+
const onSelect = (0, import_react13.useCallback)((event) => readCaret(event.currentTarget), [
|
|
3572
3736
|
readCaret
|
|
3573
3737
|
]);
|
|
3574
|
-
const onClick = (0,
|
|
3738
|
+
const onClick = (0, import_react13.useCallback)((event) => readCaret(event.currentTarget), [
|
|
3575
3739
|
readCaret
|
|
3576
3740
|
]);
|
|
3577
|
-
const setInput = (0,
|
|
3741
|
+
const setInput = (0, import_react13.useCallback)((element) => {
|
|
3578
3742
|
inputRef.current = element;
|
|
3579
3743
|
}, []);
|
|
3580
|
-
const getInputProps = (0,
|
|
3744
|
+
const getInputProps = (0, import_react13.useCallback)(() => ({
|
|
3581
3745
|
ref: setInput,
|
|
3582
3746
|
onChange,
|
|
3583
3747
|
onKeyDown,
|
|
@@ -3605,7 +3769,7 @@ function useComposerAutocomplete(options) {
|
|
|
3605
3769
|
activeIndex,
|
|
3606
3770
|
optionId
|
|
3607
3771
|
]);
|
|
3608
|
-
const getListboxProps = (0,
|
|
3772
|
+
const getListboxProps = (0, import_react13.useCallback)(() => ({
|
|
3609
3773
|
id: listboxId,
|
|
3610
3774
|
role: "listbox",
|
|
3611
3775
|
"aria-label": match?.source.label ?? match?.source.id ?? "Suggestions"
|
|
@@ -3613,7 +3777,7 @@ function useComposerAutocomplete(options) {
|
|
|
3613
3777
|
listboxId,
|
|
3614
3778
|
match
|
|
3615
3779
|
]);
|
|
3616
|
-
const getOptionProps = (0,
|
|
3780
|
+
const getOptionProps = (0, import_react13.useCallback)((index) => ({
|
|
3617
3781
|
id: optionId(index),
|
|
3618
3782
|
role: "option",
|
|
3619
3783
|
"aria-selected": index === activeIndex
|
|
@@ -3647,7 +3811,7 @@ function isPromise(value) {
|
|
|
3647
3811
|
__name(isPromise, "isPromise");
|
|
3648
3812
|
|
|
3649
3813
|
// src/presentation/use-tool-catalog.ts
|
|
3650
|
-
var
|
|
3814
|
+
var import_react14 = require("react");
|
|
3651
3815
|
var shared = /* @__PURE__ */ new WeakMap();
|
|
3652
3816
|
function load(client, agent) {
|
|
3653
3817
|
let byAgent = shared.get(client);
|
|
@@ -3671,11 +3835,11 @@ function load(client, agent) {
|
|
|
3671
3835
|
__name(load, "load");
|
|
3672
3836
|
function useToolCatalog(options) {
|
|
3673
3837
|
const { client, agent, enabled = true } = options;
|
|
3674
|
-
const [entries, setEntries] = (0,
|
|
3675
|
-
const [isLoading, setLoading] = (0,
|
|
3676
|
-
const [error, setError] = (0,
|
|
3677
|
-
const [generation, setGeneration] = (0,
|
|
3678
|
-
(0,
|
|
3838
|
+
const [entries, setEntries] = (0, import_react14.useState)([]);
|
|
3839
|
+
const [isLoading, setLoading] = (0, import_react14.useState)(enabled);
|
|
3840
|
+
const [error, setError] = (0, import_react14.useState)(null);
|
|
3841
|
+
const [generation, setGeneration] = (0, import_react14.useState)(0);
|
|
3842
|
+
(0, import_react14.useEffect)(() => {
|
|
3679
3843
|
if (!enabled) {
|
|
3680
3844
|
setLoading(false);
|
|
3681
3845
|
return;
|
|
@@ -3701,14 +3865,14 @@ function useToolCatalog(options) {
|
|
|
3701
3865
|
enabled,
|
|
3702
3866
|
generation
|
|
3703
3867
|
]);
|
|
3704
|
-
const refresh = (0,
|
|
3868
|
+
const refresh = (0, import_react14.useCallback)(() => {
|
|
3705
3869
|
shared.get(client)?.delete(agent ?? "");
|
|
3706
3870
|
setGeneration((current) => current + 1);
|
|
3707
3871
|
}, [
|
|
3708
3872
|
client,
|
|
3709
3873
|
agent
|
|
3710
3874
|
]);
|
|
3711
|
-
const catalog = (0,
|
|
3875
|
+
const catalog = (0, import_react14.useMemo)(() => toolCatalogFrom(entries), [
|
|
3712
3876
|
entries
|
|
3713
3877
|
]);
|
|
3714
3878
|
return {
|
|
@@ -3722,7 +3886,7 @@ function useToolCatalog(options) {
|
|
|
3722
3886
|
__name(useToolCatalog, "useToolCatalog");
|
|
3723
3887
|
|
|
3724
3888
|
// src/approvals/countdown.ts
|
|
3725
|
-
var
|
|
3889
|
+
var import_react15 = require("react");
|
|
3726
3890
|
function approvalCountdown(expiresAt, now = Date.now()) {
|
|
3727
3891
|
const deadline = expiresAt == null ? Number.NaN : Date.parse(expiresAt);
|
|
3728
3892
|
if (!Number.isFinite(deadline)) {
|
|
@@ -3740,10 +3904,10 @@ function approvalCountdown(expiresAt, now = Date.now()) {
|
|
|
3740
3904
|
__name(approvalCountdown, "approvalCountdown");
|
|
3741
3905
|
function useApprovalCountdown(expiresAt, options = {}) {
|
|
3742
3906
|
const { intervalMs = 1e3 } = options;
|
|
3743
|
-
const nowRef = (0,
|
|
3907
|
+
const nowRef = (0, import_react15.useRef)(options.now ?? Date.now);
|
|
3744
3908
|
nowRef.current = options.now ?? Date.now;
|
|
3745
|
-
const [state, setState] = (0,
|
|
3746
|
-
(0,
|
|
3909
|
+
const [state, setState] = (0, import_react15.useState)(() => approvalCountdown(expiresAt, nowRef.current()));
|
|
3910
|
+
(0, import_react15.useEffect)(() => {
|
|
3747
3911
|
const read = /* @__PURE__ */ __name(() => approvalCountdown(expiresAt, nowRef.current()), "read");
|
|
3748
3912
|
const first = read();
|
|
3749
3913
|
setState(first);
|
|
@@ -3984,21 +4148,21 @@ function sumUsage(rows) {
|
|
|
3984
4148
|
__name(sumUsage, "sumUsage");
|
|
3985
4149
|
|
|
3986
4150
|
// src/use-agent-chat.ts
|
|
3987
|
-
var
|
|
3988
|
-
var
|
|
4151
|
+
var import_react16 = require("@ai-sdk/react");
|
|
4152
|
+
var import_react17 = require("react");
|
|
3989
4153
|
function useAgentChat(options) {
|
|
3990
|
-
const latest = (0,
|
|
4154
|
+
const latest = (0, import_react17.useRef)(options);
|
|
3991
4155
|
latest.current = options;
|
|
3992
|
-
const [runId, setRunId] = (0,
|
|
3993
|
-
const runIdRef = (0,
|
|
4156
|
+
const [runId, setRunId] = (0, import_react17.useState)(options.resumeRunId);
|
|
4157
|
+
const runIdRef = (0, import_react17.useRef)(runId);
|
|
3994
4158
|
runIdRef.current = runId;
|
|
3995
|
-
const settlingRunIdRef = (0,
|
|
3996
|
-
const autoResumeRunIdRef = (0,
|
|
3997
|
-
const [autoResume, setAutoResume] = (0,
|
|
3998
|
-
const [activeRunId, setActiveRunId] = (0,
|
|
3999
|
-
const regenerateNext = (0,
|
|
4000
|
-
const createdThreadId = (0,
|
|
4001
|
-
const client = (0,
|
|
4159
|
+
const settlingRunIdRef = (0, import_react17.useRef)(void 0);
|
|
4160
|
+
const autoResumeRunIdRef = (0, import_react17.useRef)(void 0);
|
|
4161
|
+
const [autoResume, setAutoResume] = (0, import_react17.useState)(false);
|
|
4162
|
+
const [activeRunId, setActiveRunId] = (0, import_react17.useState)(null);
|
|
4163
|
+
const regenerateNext = (0, import_react17.useRef)(false);
|
|
4164
|
+
const createdThreadId = (0, import_react17.useRef)(void 0);
|
|
4165
|
+
const client = (0, import_react17.useMemo)(() => {
|
|
4002
4166
|
if (options.backend) return options.backend;
|
|
4003
4167
|
if (options.client) return options.client;
|
|
4004
4168
|
return new AgentClient({
|
|
@@ -4014,11 +4178,11 @@ function useAgentChat(options) {
|
|
|
4014
4178
|
getHeaders: /* @__PURE__ */ __name(async () => mergeHeaders(latest.current), "getHeaders")
|
|
4015
4179
|
});
|
|
4016
4180
|
}, []);
|
|
4017
|
-
const [connection, setConnection] = (0,
|
|
4181
|
+
const [connection, setConnection] = (0, import_react17.useState)({
|
|
4018
4182
|
status: "live"
|
|
4019
4183
|
});
|
|
4020
|
-
const resyncAfterSettle = (0,
|
|
4021
|
-
(0,
|
|
4184
|
+
const resyncAfterSettle = (0, import_react17.useRef)(false);
|
|
4185
|
+
(0, import_react17.useEffect)(() => {
|
|
4022
4186
|
if (!options.resume || options.threadId === void 0) return;
|
|
4023
4187
|
let cancelled = false;
|
|
4024
4188
|
const threadId = options.threadId;
|
|
@@ -4038,7 +4202,7 @@ function useAgentChat(options) {
|
|
|
4038
4202
|
options.resume,
|
|
4039
4203
|
options.threadId
|
|
4040
4204
|
]);
|
|
4041
|
-
const transport = (0,
|
|
4205
|
+
const transport = (0, import_react17.useMemo)(() => {
|
|
4042
4206
|
function onMeta(meta) {
|
|
4043
4207
|
settlingRunIdRef.current = meta.runId;
|
|
4044
4208
|
setRunId(meta.runId);
|
|
@@ -4075,6 +4239,9 @@ function useAgentChat(options) {
|
|
|
4075
4239
|
...threadId !== void 0 ? {
|
|
4076
4240
|
threadId
|
|
4077
4241
|
} : {},
|
|
4242
|
+
...current.model !== void 0 ? {
|
|
4243
|
+
model: current.model
|
|
4244
|
+
} : {},
|
|
4078
4245
|
...pageContext ? {
|
|
4079
4246
|
pageContext
|
|
4080
4247
|
} : {},
|
|
@@ -4090,8 +4257,8 @@ function useAgentChat(options) {
|
|
|
4090
4257
|
}, "onAttemptStart")
|
|
4091
4258
|
});
|
|
4092
4259
|
}, []);
|
|
4093
|
-
const backgroundRef = (0,
|
|
4094
|
-
const chat = (0,
|
|
4260
|
+
const backgroundRef = (0, import_react17.useRef)(() => Promise.resolve());
|
|
4261
|
+
const chat = (0, import_react16.useChat)({
|
|
4095
4262
|
transport,
|
|
4096
4263
|
resume: options.resumeRunId !== void 0 || autoResume,
|
|
4097
4264
|
...options.threadId !== void 0 ? {
|
|
@@ -4139,7 +4306,7 @@ function useAgentChat(options) {
|
|
|
4139
4306
|
}
|
|
4140
4307
|
}, "onFinish")
|
|
4141
4308
|
});
|
|
4142
|
-
const chatRef = (0,
|
|
4309
|
+
const chatRef = (0, import_react17.useRef)(chat);
|
|
4143
4310
|
chatRef.current = chat;
|
|
4144
4311
|
async function resyncFromThread() {
|
|
4145
4312
|
const threadId = latest.current.threadId ?? createdThreadId.current;
|
|
@@ -4151,11 +4318,13 @@ function useAgentChat(options) {
|
|
|
4151
4318
|
}
|
|
4152
4319
|
}
|
|
4153
4320
|
__name(resyncFromThread, "resyncFromThread");
|
|
4154
|
-
const turnInFlight = (0,
|
|
4155
|
-
const isTurnInFlight = (0,
|
|
4321
|
+
const turnInFlight = (0, import_react17.useRef)(false);
|
|
4322
|
+
const isTurnInFlight = (0, import_react17.useCallback)(() => turnInFlight.current || transport.isAttemptLive, [
|
|
4156
4323
|
transport
|
|
4157
4324
|
]);
|
|
4158
|
-
const sendMessage = (0,
|
|
4325
|
+
const sendMessage = (0, import_react17.useCallback)(async (...args) => {
|
|
4326
|
+
const blocked = latest.current.blocked;
|
|
4327
|
+
if (blocked != null) throw new QuotaBlockedError(blocked);
|
|
4159
4328
|
if (isTurnInFlight()) return;
|
|
4160
4329
|
turnInFlight.current = true;
|
|
4161
4330
|
try {
|
|
@@ -4166,15 +4335,15 @@ function useAgentChat(options) {
|
|
|
4166
4335
|
}, [
|
|
4167
4336
|
isTurnInFlight
|
|
4168
4337
|
]);
|
|
4169
|
-
const addToolResult = (0,
|
|
4338
|
+
const addToolResult = (0, import_react17.useCallback)(({ tool, toolCallId, output }) => chatRef.current.addToolResult({
|
|
4170
4339
|
tool,
|
|
4171
4340
|
toolCallId,
|
|
4172
4341
|
output
|
|
4173
4342
|
}), []);
|
|
4174
|
-
const [threads, setThreads] = (0,
|
|
4175
|
-
const [quota, setQuota] = (0,
|
|
4176
|
-
const [backgroundRuns, setBackgroundRuns] = (0,
|
|
4177
|
-
const refreshBackground = (0,
|
|
4343
|
+
const [threads, setThreads] = (0, import_react17.useState)([]);
|
|
4344
|
+
const [quota, setQuota] = (0, import_react17.useState)(null);
|
|
4345
|
+
const [backgroundRuns, setBackgroundRuns] = (0, import_react17.useState)([]);
|
|
4346
|
+
const refreshBackground = (0, import_react17.useCallback)(async () => {
|
|
4178
4347
|
const threadId = latest.current.threadId ?? createdThreadId.current;
|
|
4179
4348
|
if (threadId === void 0) {
|
|
4180
4349
|
return;
|
|
@@ -4199,7 +4368,7 @@ function useAgentChat(options) {
|
|
|
4199
4368
|
]);
|
|
4200
4369
|
backgroundRef.current = refreshBackground;
|
|
4201
4370
|
const isWorking = backgroundRuns.some((run) => run.status === "running");
|
|
4202
|
-
(0,
|
|
4371
|
+
(0, import_react17.useEffect)(() => {
|
|
4203
4372
|
if (options.background !== true || options.threadId === void 0) {
|
|
4204
4373
|
return;
|
|
4205
4374
|
}
|
|
@@ -4209,7 +4378,7 @@ function useAgentChat(options) {
|
|
|
4209
4378
|
options.threadId,
|
|
4210
4379
|
refreshBackground
|
|
4211
4380
|
]);
|
|
4212
|
-
(0,
|
|
4381
|
+
(0, import_react17.useEffect)(() => {
|
|
4213
4382
|
const every = latest.current.backgroundPollMs ?? 5e3;
|
|
4214
4383
|
if (latest.current.background !== true || !isWorking || every <= 0) {
|
|
4215
4384
|
return;
|
|
@@ -4220,26 +4389,26 @@ function useAgentChat(options) {
|
|
|
4220
4389
|
isWorking,
|
|
4221
4390
|
refreshBackground
|
|
4222
4391
|
]);
|
|
4223
|
-
const loadThreads = (0,
|
|
4392
|
+
const loadThreads = (0, import_react17.useCallback)(async () => {
|
|
4224
4393
|
const list = await client.listThreads();
|
|
4225
4394
|
setThreads(list);
|
|
4226
4395
|
return list;
|
|
4227
4396
|
}, [
|
|
4228
4397
|
client
|
|
4229
4398
|
]);
|
|
4230
|
-
const loadThread = (0,
|
|
4399
|
+
const loadThread = (0, import_react17.useCallback)((id) => client.getThread(id), [
|
|
4231
4400
|
client
|
|
4232
4401
|
]);
|
|
4233
|
-
const deleteThread = (0,
|
|
4402
|
+
const deleteThread = (0, import_react17.useCallback)(async (id) => {
|
|
4234
4403
|
await client.deleteThread(id);
|
|
4235
4404
|
setThreads((current) => current.filter((thread) => thread.id !== id));
|
|
4236
4405
|
}, [
|
|
4237
4406
|
client
|
|
4238
4407
|
]);
|
|
4239
|
-
const forkThread = (0,
|
|
4408
|
+
const forkThread = (0, import_react17.useCallback)((threadId, messageId) => requireBackendMethod(client, "forkFromMessage")(threadId, messageId), [
|
|
4240
4409
|
client
|
|
4241
4410
|
]);
|
|
4242
|
-
const renameThread = (0,
|
|
4411
|
+
const renameThread = (0, import_react17.useCallback)(async (id, title) => {
|
|
4243
4412
|
await client.updateThread(id, {
|
|
4244
4413
|
title
|
|
4245
4414
|
});
|
|
@@ -4250,24 +4419,24 @@ function useAgentChat(options) {
|
|
|
4250
4419
|
}, [
|
|
4251
4420
|
client
|
|
4252
4421
|
]);
|
|
4253
|
-
const promoteThread = (0,
|
|
4422
|
+
const promoteThread = (0, import_react17.useCallback)(async (id) => {
|
|
4254
4423
|
await requireBackendMethod(client, "promoteThread")(id);
|
|
4255
4424
|
await loadThreads();
|
|
4256
4425
|
}, [
|
|
4257
4426
|
client,
|
|
4258
4427
|
loadThreads
|
|
4259
4428
|
]);
|
|
4260
|
-
const truncateFromMessage = (0,
|
|
4429
|
+
const truncateFromMessage = (0, import_react17.useCallback)((threadId, messageId) => requireBackendMethod(client, "truncateFromMessage")(threadId, messageId).then(() => void 0), [
|
|
4261
4430
|
client
|
|
4262
4431
|
]);
|
|
4263
|
-
const loadQuota = (0,
|
|
4432
|
+
const loadQuota = (0, import_react17.useCallback)(async () => {
|
|
4264
4433
|
const today = await requireBackendMethod(client, "getQuotaToday")();
|
|
4265
4434
|
setQuota(today);
|
|
4266
4435
|
return today;
|
|
4267
4436
|
}, [
|
|
4268
4437
|
client
|
|
4269
4438
|
]);
|
|
4270
|
-
const cancel = (0,
|
|
4439
|
+
const cancel = (0, import_react17.useCallback)(async () => {
|
|
4271
4440
|
chatRef.current.stop();
|
|
4272
4441
|
const activeRunId2 = runIdRef.current;
|
|
4273
4442
|
if (activeRunId2) {
|
|
@@ -4279,7 +4448,7 @@ function useAgentChat(options) {
|
|
|
4279
4448
|
}, [
|
|
4280
4449
|
client
|
|
4281
4450
|
]);
|
|
4282
|
-
const approve = (0,
|
|
4451
|
+
const approve = (0, import_react17.useCallback)(async ({ toolCallId, remember, via }) => {
|
|
4283
4452
|
await requireBackendMethod(client, "approveToolCall")({
|
|
4284
4453
|
toolCallId,
|
|
4285
4454
|
...remember === true ? {
|
|
@@ -4292,7 +4461,7 @@ function useAgentChat(options) {
|
|
|
4292
4461
|
}, [
|
|
4293
4462
|
client
|
|
4294
4463
|
]);
|
|
4295
|
-
const reject = (0,
|
|
4464
|
+
const reject = (0, import_react17.useCallback)(async ({ toolCallId, reason, via }) => {
|
|
4296
4465
|
await requireBackendMethod(client, "rejectToolCall")({
|
|
4297
4466
|
toolCallId,
|
|
4298
4467
|
...reason !== void 0 ? {
|
|
@@ -4305,7 +4474,7 @@ function useAgentChat(options) {
|
|
|
4305
4474
|
}, [
|
|
4306
4475
|
client
|
|
4307
4476
|
]);
|
|
4308
|
-
const answer = (0,
|
|
4477
|
+
const answer = (0, import_react17.useCallback)(async ({ toolCallId, answers }) => {
|
|
4309
4478
|
await requireBackendMethod(client, "answerToolCall")({
|
|
4310
4479
|
toolCallId,
|
|
4311
4480
|
...answers !== void 0 ? {
|
|
@@ -4315,14 +4484,16 @@ function useAgentChat(options) {
|
|
|
4315
4484
|
}, [
|
|
4316
4485
|
client
|
|
4317
4486
|
]);
|
|
4318
|
-
const skip = (0,
|
|
4487
|
+
const skip = (0, import_react17.useCallback)(async ({ toolCallId }) => {
|
|
4319
4488
|
await requireBackendMethod(client, "skipToolCall")({
|
|
4320
4489
|
toolCallId
|
|
4321
4490
|
});
|
|
4322
4491
|
}, [
|
|
4323
4492
|
client
|
|
4324
4493
|
]);
|
|
4325
|
-
const regenerate = (0,
|
|
4494
|
+
const regenerate = (0, import_react17.useCallback)(() => {
|
|
4495
|
+
const blocked = latest.current.blocked;
|
|
4496
|
+
if (blocked != null) throw new QuotaBlockedError(blocked);
|
|
4326
4497
|
if (isTurnInFlight()) return;
|
|
4327
4498
|
regenerateNext.current = true;
|
|
4328
4499
|
turnInFlight.current = true;
|
|
@@ -4337,7 +4508,21 @@ function useAgentChat(options) {
|
|
|
4337
4508
|
isWorking,
|
|
4338
4509
|
refresh: refreshBackground
|
|
4339
4510
|
};
|
|
4340
|
-
const
|
|
4511
|
+
const setThreadModel = (0, import_react17.useCallback)(async (model) => {
|
|
4512
|
+
const threadId = latest.current.threadId ?? createdThreadId.current;
|
|
4513
|
+
if (threadId === void 0) {
|
|
4514
|
+
throw new Error("setThreadModel: this chat has no thread yet");
|
|
4515
|
+
}
|
|
4516
|
+
await client.updateThread(threadId, {
|
|
4517
|
+
model
|
|
4518
|
+
});
|
|
4519
|
+
notifyThreads(client, {
|
|
4520
|
+
type: "changed"
|
|
4521
|
+
});
|
|
4522
|
+
}, [
|
|
4523
|
+
client
|
|
4524
|
+
]);
|
|
4525
|
+
const getThreadId = (0, import_react17.useCallback)(() => latest.current.threadId ?? createdThreadId.current, []);
|
|
4341
4526
|
const status = connection.status === "reconnecting" ? "reconnecting" : chat.status;
|
|
4342
4527
|
return {
|
|
4343
4528
|
...chat,
|
|
@@ -4356,6 +4541,7 @@ function useAgentChat(options) {
|
|
|
4356
4541
|
* on the first send. A getter, because the created id is learned mid-stream.
|
|
4357
4542
|
*/
|
|
4358
4543
|
getThreadId,
|
|
4544
|
+
setThreadModel,
|
|
4359
4545
|
/** The backend this chat talks to — pass it to `useThreads`, `useMessageFeedback`, … */
|
|
4360
4546
|
backend: client,
|
|
4361
4547
|
/** Same object as {@link backend}; kept for callers that read it under its old name. */
|
|
@@ -4379,6 +4565,16 @@ function useAgentChat(options) {
|
|
|
4379
4565
|
};
|
|
4380
4566
|
}
|
|
4381
4567
|
__name(useAgentChat, "useAgentChat");
|
|
4568
|
+
var QuotaBlockedError = class extends Error {
|
|
4569
|
+
static {
|
|
4570
|
+
__name(this, "QuotaBlockedError");
|
|
4571
|
+
}
|
|
4572
|
+
block;
|
|
4573
|
+
constructor(block) {
|
|
4574
|
+
super(block.reason ?? `The ${block.period === "day" ? "daily" : "monthly"} quota is used up`), this.block = block;
|
|
4575
|
+
this.name = "QuotaBlockedError";
|
|
4576
|
+
}
|
|
4577
|
+
};
|
|
4382
4578
|
async function mergeHeaders(options) {
|
|
4383
4579
|
const dynamic = await options.getHeaders?.() ?? {};
|
|
4384
4580
|
return {
|
|
@@ -4398,6 +4594,7 @@ __name(mergeHeaders, "mergeHeaders");
|
|
|
4398
4594
|
MessageItem,
|
|
4399
4595
|
MessageItemView,
|
|
4400
4596
|
MessageList,
|
|
4597
|
+
QuotaBlockedError,
|
|
4401
4598
|
SPEECH_LANGUAGES,
|
|
4402
4599
|
applyCompletion,
|
|
4403
4600
|
approvalCountdown,
|
|
@@ -4432,11 +4629,14 @@ __name(mergeHeaders, "mergeHeaders");
|
|
|
4432
4629
|
toolCallState,
|
|
4433
4630
|
toolCatalogFrom,
|
|
4434
4631
|
useAgentChat,
|
|
4632
|
+
useAgents,
|
|
4435
4633
|
useApprovalCountdown,
|
|
4436
4634
|
useChatTranscript,
|
|
4437
4635
|
useComposerAutocomplete,
|
|
4438
4636
|
useElapsed,
|
|
4439
4637
|
useMessageFeedback,
|
|
4638
|
+
useModels,
|
|
4639
|
+
useQuota,
|
|
4440
4640
|
useSpeechRecognition,
|
|
4441
4641
|
useStickToBottom,
|
|
4442
4642
|
useThreads,
|