@dudousxd/nestjs-agent-react 0.15.0 → 0.16.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 +29 -0
- package/dist/index.cjs +325 -194
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +75 -3
- package/dist/index.d.ts +75 -3
- package/dist/index.js +285 -156
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -147,6 +147,15 @@ var AgentClient = class {
|
|
|
147
147
|
truncateFromMessage(threadId, messageId) {
|
|
148
148
|
return this.request("DELETE", `/agent/threads/${encodeURIComponent(threadId)}/from/${encodeURIComponent(messageId)}`);
|
|
149
149
|
}
|
|
150
|
+
/** `GET /agent/models?agent=` — the models this caller may pick, grouped by provider. */
|
|
151
|
+
listModels(agent) {
|
|
152
|
+
const query = agent === void 0 ? "" : `?agent=${encodeURIComponent(agent)}`;
|
|
153
|
+
return this.request("GET", `/agent/models${query}`);
|
|
154
|
+
}
|
|
155
|
+
/** `GET /agent/agents` — the registered agents, the default one flagged. */
|
|
156
|
+
listAgents() {
|
|
157
|
+
return this.request("GET", "/agent/agents");
|
|
158
|
+
}
|
|
150
159
|
getQuotaToday() {
|
|
151
160
|
return this.request("GET", "/agent/quota/today");
|
|
152
161
|
}
|
|
@@ -994,28 +1003,128 @@ function requireBackendMethod(backend, name) {
|
|
|
994
1003
|
}
|
|
995
1004
|
__name(requireBackendMethod, "requireBackendMethod");
|
|
996
1005
|
|
|
1006
|
+
// src/catalog/use-agents.ts
|
|
1007
|
+
import { useMemo } from "react";
|
|
1008
|
+
|
|
1009
|
+
// src/catalog/use-resource.ts
|
|
1010
|
+
import { useCallback, useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
|
|
1011
|
+
function useResource(load2, key, enabled) {
|
|
1012
|
+
const [data, setData] = useState2(void 0);
|
|
1013
|
+
const [isLoading, setIsLoading] = useState2(enabled);
|
|
1014
|
+
const [error, setError] = useState2(null);
|
|
1015
|
+
const loadRef = useRef2(load2);
|
|
1016
|
+
loadRef.current = load2;
|
|
1017
|
+
const generation = useRef2(0);
|
|
1018
|
+
const refresh = useCallback(async () => {
|
|
1019
|
+
const mine = ++generation.current;
|
|
1020
|
+
setIsLoading(true);
|
|
1021
|
+
try {
|
|
1022
|
+
const value = await loadRef.current();
|
|
1023
|
+
if (mine !== generation.current) return;
|
|
1024
|
+
setData(value);
|
|
1025
|
+
setError(null);
|
|
1026
|
+
} catch (caught) {
|
|
1027
|
+
if (mine !== generation.current) return;
|
|
1028
|
+
setError(caught instanceof Error ? caught : new Error(String(caught)));
|
|
1029
|
+
} finally {
|
|
1030
|
+
if (mine === generation.current) setIsLoading(false);
|
|
1031
|
+
}
|
|
1032
|
+
}, []);
|
|
1033
|
+
useEffect2(() => {
|
|
1034
|
+
if (!enabled) return;
|
|
1035
|
+
void refresh();
|
|
1036
|
+
}, [
|
|
1037
|
+
enabled,
|
|
1038
|
+
key,
|
|
1039
|
+
refresh
|
|
1040
|
+
]);
|
|
1041
|
+
return {
|
|
1042
|
+
data,
|
|
1043
|
+
isLoading,
|
|
1044
|
+
error,
|
|
1045
|
+
refresh
|
|
1046
|
+
};
|
|
1047
|
+
}
|
|
1048
|
+
__name(useResource, "useResource");
|
|
1049
|
+
|
|
1050
|
+
// src/catalog/use-agents.ts
|
|
1051
|
+
function useAgents(options) {
|
|
1052
|
+
const { backend, enabled = true } = options;
|
|
1053
|
+
const { data, isLoading, error, refresh } = useResource(() => requireBackendMethod(backend, "listAgents")(), "", enabled);
|
|
1054
|
+
return useMemo(() => {
|
|
1055
|
+
const agents = data ?? [];
|
|
1056
|
+
return {
|
|
1057
|
+
agents,
|
|
1058
|
+
defaultAgent: agents.find((agent) => agent.isDefault === true)?.name ?? null,
|
|
1059
|
+
isLoading,
|
|
1060
|
+
error,
|
|
1061
|
+
refresh
|
|
1062
|
+
};
|
|
1063
|
+
}, [
|
|
1064
|
+
data,
|
|
1065
|
+
isLoading,
|
|
1066
|
+
error,
|
|
1067
|
+
refresh
|
|
1068
|
+
]);
|
|
1069
|
+
}
|
|
1070
|
+
__name(useAgents, "useAgents");
|
|
1071
|
+
|
|
1072
|
+
// src/catalog/use-models.ts
|
|
1073
|
+
import { useMemo as useMemo2 } from "react";
|
|
1074
|
+
function useModels(options) {
|
|
1075
|
+
const { backend, agent, enabled = true } = options;
|
|
1076
|
+
const { data, isLoading, error, refresh } = useResource(() => requireBackendMethod(backend, "listModels")(agent), `${agent ?? ""}`, enabled);
|
|
1077
|
+
return useMemo2(() => {
|
|
1078
|
+
const providers = data?.providers ?? [];
|
|
1079
|
+
const models = providers.flatMap((provider) => provider.models.map((model) => ({
|
|
1080
|
+
...model,
|
|
1081
|
+
providerId: provider.id,
|
|
1082
|
+
providerLabel: provider.label
|
|
1083
|
+
})));
|
|
1084
|
+
const byId = new Map(models.map((model) => [
|
|
1085
|
+
model.id,
|
|
1086
|
+
model
|
|
1087
|
+
]));
|
|
1088
|
+
return {
|
|
1089
|
+
providers,
|
|
1090
|
+
models,
|
|
1091
|
+
defaultModel: data?.default ?? null,
|
|
1092
|
+
find: /* @__PURE__ */ __name((id) => id == null ? void 0 : byId.get(id), "find"),
|
|
1093
|
+
isLoading,
|
|
1094
|
+
error,
|
|
1095
|
+
refresh
|
|
1096
|
+
};
|
|
1097
|
+
}, [
|
|
1098
|
+
data,
|
|
1099
|
+
isLoading,
|
|
1100
|
+
error,
|
|
1101
|
+
refresh
|
|
1102
|
+
]);
|
|
1103
|
+
}
|
|
1104
|
+
__name(useModels, "useModels");
|
|
1105
|
+
|
|
997
1106
|
// src/feedback/use-message-feedback.ts
|
|
998
|
-
import { useCallback, useRef as
|
|
1107
|
+
import { useCallback as useCallback2, useRef as useRef3, useState as useState3 } from "react";
|
|
999
1108
|
function useMessageFeedback(options) {
|
|
1000
|
-
const latest =
|
|
1109
|
+
const latest = useRef3(options);
|
|
1001
1110
|
latest.current = options;
|
|
1002
|
-
const [local, setLocal] =
|
|
1003
|
-
const [pending, setPending] =
|
|
1004
|
-
const [error, setError] =
|
|
1005
|
-
const localRef =
|
|
1111
|
+
const [local, setLocal] = useState3(/* @__PURE__ */ new Map());
|
|
1112
|
+
const [pending, setPending] = useState3(/* @__PURE__ */ new Set());
|
|
1113
|
+
const [error, setError] = useState3(null);
|
|
1114
|
+
const localRef = useRef3(local);
|
|
1006
1115
|
localRef.current = local;
|
|
1007
|
-
const resolved =
|
|
1008
|
-
const feedbackOf =
|
|
1116
|
+
const resolved = useRef3(/* @__PURE__ */ new Map());
|
|
1117
|
+
const feedbackOf = useCallback2((message) => {
|
|
1009
1118
|
const mine = local.get(message.id);
|
|
1010
1119
|
if (mine !== void 0) return mine.feedback;
|
|
1011
1120
|
return metadataOf(message).feedback ?? null;
|
|
1012
1121
|
}, [
|
|
1013
1122
|
local
|
|
1014
1123
|
]);
|
|
1015
|
-
const isPending =
|
|
1124
|
+
const isPending = useCallback2((message) => pending.has(message.id), [
|
|
1016
1125
|
pending
|
|
1017
1126
|
]);
|
|
1018
|
-
const storedIdFor =
|
|
1127
|
+
const storedIdFor = useCallback2(async (message) => {
|
|
1019
1128
|
const runId = metadataOf(message).runId;
|
|
1020
1129
|
if (runId === void 0) return message.id;
|
|
1021
1130
|
const known = resolved.current.get(message.id);
|
|
@@ -1035,7 +1144,7 @@ function useMessageFeedback(options) {
|
|
|
1035
1144
|
resolved.current.set(message.id, row.id);
|
|
1036
1145
|
return row.id;
|
|
1037
1146
|
}, []);
|
|
1038
|
-
const rate =
|
|
1147
|
+
const rate = useCallback2(async (message, value, comment) => {
|
|
1039
1148
|
const setFeedback = requireBackendMethod(latest.current.backend, "setMessageFeedback");
|
|
1040
1149
|
const had = localRef.current.get(message.id);
|
|
1041
1150
|
const optimistic = value === null ? null : {
|
|
@@ -1081,7 +1190,7 @@ function useMessageFeedback(options) {
|
|
|
1081
1190
|
}, [
|
|
1082
1191
|
storedIdFor
|
|
1083
1192
|
]);
|
|
1084
|
-
const toggle =
|
|
1193
|
+
const toggle = useCallback2((message, value) => {
|
|
1085
1194
|
const mine = localRef.current.get(message.id);
|
|
1086
1195
|
const current = mine !== void 0 ? mine.feedback : metadataOf(message).feedback ?? null;
|
|
1087
1196
|
return rate(message, current?.value === value ? null : value);
|
|
@@ -1125,16 +1234,16 @@ function onThreadsEvent(backend, listener) {
|
|
|
1125
1234
|
__name(onThreadsEvent, "onThreadsEvent");
|
|
1126
1235
|
|
|
1127
1236
|
// src/threads/use-threads.ts
|
|
1128
|
-
import { useCallback as
|
|
1237
|
+
import { useCallback as useCallback3, useEffect as useEffect3, useRef as useRef4, useState as useState4 } from "react";
|
|
1129
1238
|
function useThreads(options) {
|
|
1130
1239
|
const { backend, enabled = true } = options;
|
|
1131
|
-
const [threads, setThreads] =
|
|
1132
|
-
const [isLoading, setIsLoading] =
|
|
1133
|
-
const [error, setError] =
|
|
1134
|
-
const threadsRef =
|
|
1240
|
+
const [threads, setThreads] = useState4([]);
|
|
1241
|
+
const [isLoading, setIsLoading] = useState4(enabled);
|
|
1242
|
+
const [error, setError] = useState4(null);
|
|
1243
|
+
const threadsRef = useRef4(threads);
|
|
1135
1244
|
threadsRef.current = threads;
|
|
1136
|
-
const generation =
|
|
1137
|
-
const refresh =
|
|
1245
|
+
const generation = useRef4(0);
|
|
1246
|
+
const refresh = useCallback3(async () => {
|
|
1138
1247
|
const mine = ++generation.current;
|
|
1139
1248
|
setIsLoading(true);
|
|
1140
1249
|
try {
|
|
@@ -1151,7 +1260,7 @@ function useThreads(options) {
|
|
|
1151
1260
|
}, [
|
|
1152
1261
|
backend
|
|
1153
1262
|
]);
|
|
1154
|
-
|
|
1263
|
+
useEffect3(() => {
|
|
1155
1264
|
if (!enabled) return;
|
|
1156
1265
|
void refresh();
|
|
1157
1266
|
return onThreadsEvent(backend, (event) => {
|
|
@@ -1171,7 +1280,7 @@ function useThreads(options) {
|
|
|
1171
1280
|
enabled,
|
|
1172
1281
|
refresh
|
|
1173
1282
|
]);
|
|
1174
|
-
const rename =
|
|
1283
|
+
const rename = useCallback3(async (id, title) => {
|
|
1175
1284
|
const before = threadsRef.current;
|
|
1176
1285
|
setThreads((current) => current.map((thread) => thread.id === id ? {
|
|
1177
1286
|
...thread,
|
|
@@ -1193,7 +1302,7 @@ function useThreads(options) {
|
|
|
1193
1302
|
}, [
|
|
1194
1303
|
backend
|
|
1195
1304
|
]);
|
|
1196
|
-
const remove =
|
|
1305
|
+
const remove = useCallback3(async (id) => {
|
|
1197
1306
|
const before = threadsRef.current;
|
|
1198
1307
|
setThreads((current) => current.filter((thread) => thread.id !== id));
|
|
1199
1308
|
try {
|
|
@@ -1268,10 +1377,10 @@ function backgroundRunsFromThread(messages) {
|
|
|
1268
1377
|
__name(backgroundRunsFromThread, "backgroundRunsFromThread");
|
|
1269
1378
|
|
|
1270
1379
|
// src/components/chat-input.tsx
|
|
1271
|
-
import React2, { useEffect as
|
|
1380
|
+
import React2, { useEffect as useEffect5, useState as useState6 } from "react";
|
|
1272
1381
|
|
|
1273
1382
|
// src/components/use-speech-recognition.ts
|
|
1274
|
-
import { useCallback as
|
|
1383
|
+
import { useCallback as useCallback4, useEffect as useEffect4, useMemo as useMemo3, useRef as useRef5, useState as useState5 } from "react";
|
|
1275
1384
|
function getRecognitionCtor() {
|
|
1276
1385
|
if (typeof window === "undefined") return null;
|
|
1277
1386
|
const scope = window;
|
|
@@ -1279,15 +1388,15 @@ function getRecognitionCtor() {
|
|
|
1279
1388
|
}
|
|
1280
1389
|
__name(getRecognitionCtor, "getRecognitionCtor");
|
|
1281
1390
|
function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTranscript }) {
|
|
1282
|
-
const recognitionRef =
|
|
1283
|
-
const [isListening, setIsListening] =
|
|
1284
|
-
const ctor =
|
|
1391
|
+
const recognitionRef = useRef5(null);
|
|
1392
|
+
const [isListening, setIsListening] = useState5(false);
|
|
1393
|
+
const ctor = useMemo3(() => getRecognitionCtor(), []);
|
|
1285
1394
|
const isSupported = ctor !== null;
|
|
1286
|
-
const finalRef =
|
|
1287
|
-
const interimRef =
|
|
1395
|
+
const finalRef = useRef5(onFinalTranscript);
|
|
1396
|
+
const interimRef = useRef5(onInterimTranscript);
|
|
1288
1397
|
finalRef.current = onFinalTranscript;
|
|
1289
1398
|
interimRef.current = onInterimTranscript;
|
|
1290
|
-
|
|
1399
|
+
useEffect4(() => {
|
|
1291
1400
|
if (!ctor) return;
|
|
1292
1401
|
const recognition = new ctor();
|
|
1293
1402
|
recognition.lang = lang;
|
|
@@ -1326,7 +1435,7 @@ function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTran
|
|
|
1326
1435
|
ctor,
|
|
1327
1436
|
lang
|
|
1328
1437
|
]);
|
|
1329
|
-
const start =
|
|
1438
|
+
const start = useCallback4(() => {
|
|
1330
1439
|
const recognition = recognitionRef.current;
|
|
1331
1440
|
if (!recognition) return;
|
|
1332
1441
|
try {
|
|
@@ -1336,7 +1445,7 @@ function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTran
|
|
|
1336
1445
|
console.warn("SpeechRecognition start failed", error);
|
|
1337
1446
|
}
|
|
1338
1447
|
}, []);
|
|
1339
|
-
const stop =
|
|
1448
|
+
const stop = useCallback4(() => {
|
|
1340
1449
|
const recognition = recognitionRef.current;
|
|
1341
1450
|
if (!recognition) return;
|
|
1342
1451
|
try {
|
|
@@ -1355,8 +1464,8 @@ __name(useSpeechRecognition, "useSpeechRecognition");
|
|
|
1355
1464
|
|
|
1356
1465
|
// src/components/chat-input.tsx
|
|
1357
1466
|
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 }) {
|
|
1358
|
-
const [value, setValue] =
|
|
1359
|
-
const [interim, setInterim] =
|
|
1467
|
+
const [value, setValue] = useState6("");
|
|
1468
|
+
const [interim, setInterim] = useState6("");
|
|
1360
1469
|
const speech = useSpeechRecognition({
|
|
1361
1470
|
lang: speechLang,
|
|
1362
1471
|
onFinalTranscript: /* @__PURE__ */ __name((text) => {
|
|
@@ -1367,7 +1476,7 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
|
|
|
1367
1476
|
}, "onFinalTranscript"),
|
|
1368
1477
|
onInterimTranscript: /* @__PURE__ */ __name((text) => setInterim(text), "onInterimTranscript")
|
|
1369
1478
|
});
|
|
1370
|
-
|
|
1479
|
+
useEffect5(() => {
|
|
1371
1480
|
if (!speech.isListening) setInterim("");
|
|
1372
1481
|
}, [
|
|
1373
1482
|
speech.isListening
|
|
@@ -1434,7 +1543,7 @@ __name(ChatInput, "ChatInput");
|
|
|
1434
1543
|
import React3 from "react";
|
|
1435
1544
|
|
|
1436
1545
|
// src/transcript/use-chat-transcript.ts
|
|
1437
|
-
import { useCallback as
|
|
1546
|
+
import { useCallback as useCallback6, useEffect as useEffect7, useRef as useRef7, useState as useState8 } from "react";
|
|
1438
1547
|
|
|
1439
1548
|
// src/transcript/model.ts
|
|
1440
1549
|
import { readElicitationInput, validateElicitationAnswer as validateElicitationAnswer2 } from "@dudousxd/nestjs-agent-core";
|
|
@@ -2411,11 +2520,11 @@ function formatCostUsd(cost) {
|
|
|
2411
2520
|
__name(formatCostUsd, "formatCostUsd");
|
|
2412
2521
|
|
|
2413
2522
|
// src/transcript/use-stick-to-bottom.ts
|
|
2414
|
-
import { useCallback as
|
|
2523
|
+
import { useCallback as useCallback5, useEffect as useEffect6, useRef as useRef6, useState as useState7 } from "react";
|
|
2415
2524
|
function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
2416
|
-
const containerRef =
|
|
2417
|
-
const [isAtBottom, setIsAtBottom] =
|
|
2418
|
-
const measure =
|
|
2525
|
+
const containerRef = useRef6(null);
|
|
2526
|
+
const [isAtBottom, setIsAtBottom] = useState7(true);
|
|
2527
|
+
const measure = useCallback5(() => {
|
|
2419
2528
|
const element = containerRef.current;
|
|
2420
2529
|
if (!element) {
|
|
2421
2530
|
return;
|
|
@@ -2425,7 +2534,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
|
2425
2534
|
}, [
|
|
2426
2535
|
threshold
|
|
2427
2536
|
]);
|
|
2428
|
-
const scrollToBottom =
|
|
2537
|
+
const scrollToBottom = useCallback5(() => {
|
|
2429
2538
|
const element = containerRef.current;
|
|
2430
2539
|
if (!element) {
|
|
2431
2540
|
return;
|
|
@@ -2433,7 +2542,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
|
2433
2542
|
element.scrollTop = element.scrollHeight;
|
|
2434
2543
|
setIsAtBottom(true);
|
|
2435
2544
|
}, []);
|
|
2436
|
-
const setContainer =
|
|
2545
|
+
const setContainer = useCallback5((element) => {
|
|
2437
2546
|
containerRef.current = element;
|
|
2438
2547
|
if (element) {
|
|
2439
2548
|
measure();
|
|
@@ -2441,7 +2550,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
|
2441
2550
|
}, [
|
|
2442
2551
|
measure
|
|
2443
2552
|
]);
|
|
2444
|
-
|
|
2553
|
+
useEffect6(() => {
|
|
2445
2554
|
if (isAtBottom) {
|
|
2446
2555
|
scrollToBottom();
|
|
2447
2556
|
}
|
|
@@ -2450,7 +2559,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
|
2450
2559
|
isAtBottom,
|
|
2451
2560
|
scrollToBottom
|
|
2452
2561
|
]);
|
|
2453
|
-
const getContainerProps =
|
|
2562
|
+
const getContainerProps = useCallback5(() => ({
|
|
2454
2563
|
ref: setContainer,
|
|
2455
2564
|
onScroll: measure
|
|
2456
2565
|
}), [
|
|
@@ -2472,14 +2581,14 @@ var DEFAULT_LOAD_EARLIER_STEP = 50;
|
|
|
2472
2581
|
var DEFAULT_COPY_RESET_MS = 1500;
|
|
2473
2582
|
function useChatTranscript(options) {
|
|
2474
2583
|
const { messages, status, initialVisibleCount = DEFAULT_VISIBLE_COUNT, loadEarlierStep = DEFAULT_LOAD_EARLIER_STEP, followUps, stickToBottomThreshold } = options;
|
|
2475
|
-
const latest =
|
|
2584
|
+
const latest = useRef7(options);
|
|
2476
2585
|
latest.current = options;
|
|
2477
|
-
const [visibleCount, setVisibleCount] =
|
|
2478
|
-
const [stopRequested, setStopRequested] =
|
|
2586
|
+
const [visibleCount, setVisibleCount] = useState8(initialVisibleCount);
|
|
2587
|
+
const [stopRequested, setStopRequested] = useState8(false);
|
|
2479
2588
|
const isStreaming = status === "streaming" || status === "reconnecting";
|
|
2480
2589
|
const isBusy = status === "submitted" || isStreaming;
|
|
2481
2590
|
const isEmpty = messages.length === 0;
|
|
2482
|
-
|
|
2591
|
+
useEffect7(() => {
|
|
2483
2592
|
if (!isBusy) {
|
|
2484
2593
|
setStopRequested(false);
|
|
2485
2594
|
}
|
|
@@ -2496,7 +2605,7 @@ function useChatTranscript(options) {
|
|
|
2496
2605
|
streamingMessageId,
|
|
2497
2606
|
options
|
|
2498
2607
|
});
|
|
2499
|
-
const stop =
|
|
2608
|
+
const stop = useCallback6(() => {
|
|
2500
2609
|
const current = latest.current;
|
|
2501
2610
|
if (current.status !== "submitted" && current.status !== "streaming" && current.status !== "reconnecting") {
|
|
2502
2611
|
return;
|
|
@@ -2504,8 +2613,8 @@ function useChatTranscript(options) {
|
|
|
2504
2613
|
setStopRequested(true);
|
|
2505
2614
|
void current.onStop?.();
|
|
2506
2615
|
}, []);
|
|
2507
|
-
const loadEarlier =
|
|
2508
|
-
const showAll =
|
|
2616
|
+
const loadEarlier = useCallback6(() => setVisibleCount((count) => count + (latest.current.loadEarlierStep ?? DEFAULT_LOAD_EARLIER_STEP)), []);
|
|
2617
|
+
const showAll = useCallback6(() => setVisibleCount(latest.current.messages.length), []);
|
|
2509
2618
|
const scroll = useStickToBottom({
|
|
2510
2619
|
contentKey: contentSignature(messages),
|
|
2511
2620
|
...stickToBottomThreshold !== void 0 ? {
|
|
@@ -2541,7 +2650,7 @@ function useChatTranscript(options) {
|
|
|
2541
2650
|
__name(useChatTranscript, "useChatTranscript");
|
|
2542
2651
|
function useTranscriptItem(options) {
|
|
2543
2652
|
const { message, isStreaming = false } = options;
|
|
2544
|
-
const messagesRef =
|
|
2653
|
+
const messagesRef = useRef7([
|
|
2545
2654
|
message
|
|
2546
2655
|
]);
|
|
2547
2656
|
if (messagesRef.current[0] !== message) {
|
|
@@ -2559,13 +2668,13 @@ function useTranscriptItem(options) {
|
|
|
2559
2668
|
}
|
|
2560
2669
|
__name(useTranscriptItem, "useTranscriptItem");
|
|
2561
2670
|
function useTranscriptItems({ messages, visibleStart, streamingMessageId, options }) {
|
|
2562
|
-
const [drafts, setDrafts] =
|
|
2563
|
-
const [copied, setCopied] =
|
|
2564
|
-
const [openReasoning, setOpenReasoning] =
|
|
2565
|
-
const [picks, setPicks] =
|
|
2566
|
-
const [settling, setSettling] =
|
|
2567
|
-
const [settleErrors, setSettleErrors] =
|
|
2568
|
-
const latest =
|
|
2671
|
+
const [drafts, setDrafts] = useState8(() => /* @__PURE__ */ new Map());
|
|
2672
|
+
const [copied, setCopied] = useState8(() => /* @__PURE__ */ new Set());
|
|
2673
|
+
const [openReasoning, setOpenReasoning] = useState8(() => /* @__PURE__ */ new Map());
|
|
2674
|
+
const [picks, setPicks] = useState8(() => /* @__PURE__ */ new Map());
|
|
2675
|
+
const [settling, setSettling] = useState8(() => /* @__PURE__ */ new Map());
|
|
2676
|
+
const [settleErrors, setSettleErrors] = useState8(() => /* @__PURE__ */ new Map());
|
|
2677
|
+
const latest = useRef7({
|
|
2569
2678
|
options,
|
|
2570
2679
|
drafts,
|
|
2571
2680
|
picks,
|
|
@@ -2577,23 +2686,23 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2577
2686
|
picks,
|
|
2578
2687
|
messages
|
|
2579
2688
|
};
|
|
2580
|
-
const copyTimers =
|
|
2581
|
-
|
|
2689
|
+
const copyTimers = useRef7(/* @__PURE__ */ new Map());
|
|
2690
|
+
useEffect7(() => () => {
|
|
2582
2691
|
for (const timer of copyTimers.current.values()) {
|
|
2583
2692
|
clearTimeout(timer);
|
|
2584
2693
|
}
|
|
2585
2694
|
copyTimers.current.clear();
|
|
2586
2695
|
}, []);
|
|
2587
|
-
const callbackCache =
|
|
2588
|
-
const reasoningToggleCache =
|
|
2589
|
-
const toggleReasoning =
|
|
2696
|
+
const callbackCache = useRef7(/* @__PURE__ */ new Map());
|
|
2697
|
+
const reasoningToggleCache = useRef7(/* @__PURE__ */ new Map());
|
|
2698
|
+
const toggleReasoning = useCallback6((key, open) => {
|
|
2590
2699
|
setOpenReasoning((current) => {
|
|
2591
2700
|
const next = new Map(current);
|
|
2592
2701
|
next.set(key, open ?? !(current.get(key) ?? false));
|
|
2593
2702
|
return next;
|
|
2594
2703
|
});
|
|
2595
2704
|
}, []);
|
|
2596
|
-
const stableToggle =
|
|
2705
|
+
const stableToggle = useCallback6((key) => {
|
|
2597
2706
|
let cached = reasoningToggleCache.current.get(key);
|
|
2598
2707
|
if (!cached) {
|
|
2599
2708
|
cached = /* @__PURE__ */ __name((open) => toggleReasoning(key, open), "cached");
|
|
@@ -2603,10 +2712,10 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2603
2712
|
}, [
|
|
2604
2713
|
toggleReasoning
|
|
2605
2714
|
]);
|
|
2606
|
-
const pick =
|
|
2715
|
+
const pick = useCallback6((toolCallId, questionId, values) => {
|
|
2607
2716
|
setPicks((current) => new Map(current).set(pickKey(toolCallId, questionId), values));
|
|
2608
2717
|
}, []);
|
|
2609
|
-
const settle =
|
|
2718
|
+
const settle = useCallback6((toolCallId, action, send) => {
|
|
2610
2719
|
setSettleErrors((current) => {
|
|
2611
2720
|
if (!current.has(toolCallId)) {
|
|
2612
2721
|
return current;
|
|
@@ -2630,7 +2739,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2630
2739
|
failed(error);
|
|
2631
2740
|
}
|
|
2632
2741
|
}, []);
|
|
2633
|
-
const answer =
|
|
2742
|
+
const answer = useCallback6((toolCallId) => {
|
|
2634
2743
|
const current = latest.current;
|
|
2635
2744
|
const onAnswer = current.options.onAnswer;
|
|
2636
2745
|
if (!onAnswer) {
|
|
@@ -2640,7 +2749,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2640
2749
|
}, [
|
|
2641
2750
|
settle
|
|
2642
2751
|
]);
|
|
2643
|
-
const skip =
|
|
2752
|
+
const skip = useCallback6((toolCallId) => {
|
|
2644
2753
|
const onSkip = latest.current.options.onSkip;
|
|
2645
2754
|
if (onSkip) {
|
|
2646
2755
|
settle(toolCallId, "skip", () => onSkip(toolCallId));
|
|
@@ -2648,7 +2757,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2648
2757
|
}, [
|
|
2649
2758
|
settle
|
|
2650
2759
|
]);
|
|
2651
|
-
const approve =
|
|
2760
|
+
const approve = useCallback6((toolCallId, options2) => {
|
|
2652
2761
|
const onApprove = latest.current.options.onApprove;
|
|
2653
2762
|
if (onApprove) {
|
|
2654
2763
|
settle(toolCallId, "approve", () => options2 === void 0 ? onApprove(toolCallId) : onApprove(toolCallId, options2));
|
|
@@ -2656,7 +2765,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2656
2765
|
}, [
|
|
2657
2766
|
settle
|
|
2658
2767
|
]);
|
|
2659
|
-
const reject =
|
|
2768
|
+
const reject = useCallback6((toolCallId) => {
|
|
2660
2769
|
const onReject = latest.current.options.onReject;
|
|
2661
2770
|
if (onReject) {
|
|
2662
2771
|
settle(toolCallId, "reject", () => onReject(toolCallId));
|
|
@@ -2664,7 +2773,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2664
2773
|
}, [
|
|
2665
2774
|
settle
|
|
2666
2775
|
]);
|
|
2667
|
-
const callbacksFor =
|
|
2776
|
+
const callbacksFor = useCallback6((id) => {
|
|
2668
2777
|
const cached = callbackCache.current.get(id);
|
|
2669
2778
|
if (cached) {
|
|
2670
2779
|
return cached;
|
|
@@ -3321,35 +3430,35 @@ function toItem(entry) {
|
|
|
3321
3430
|
__name(toItem, "toItem");
|
|
3322
3431
|
|
|
3323
3432
|
// src/composer/use-composer-autocomplete.ts
|
|
3324
|
-
import { useCallback as
|
|
3433
|
+
import { useCallback as useCallback7, useEffect as useEffect8, useId, useLayoutEffect, useMemo as useMemo4, useRef as useRef8, useState as useState9 } from "react";
|
|
3325
3434
|
function useComposerAutocomplete(options) {
|
|
3326
3435
|
const { value, sources, acceptOnTab = true } = options;
|
|
3327
|
-
const latest =
|
|
3436
|
+
const latest = useRef8(options);
|
|
3328
3437
|
latest.current = options;
|
|
3329
|
-
const inputRef =
|
|
3330
|
-
const [caret, setCaret] =
|
|
3331
|
-
const [items, setItems] =
|
|
3332
|
-
const [isLoading, setLoading] =
|
|
3333
|
-
const [error, setError] =
|
|
3334
|
-
const [activeIndex, setActiveIndex] =
|
|
3335
|
-
const [dismissedIndex, setDismissedIndex] =
|
|
3438
|
+
const inputRef = useRef8(null);
|
|
3439
|
+
const [caret, setCaret] = useState9(value.length);
|
|
3440
|
+
const [items, setItems] = useState9([]);
|
|
3441
|
+
const [isLoading, setLoading] = useState9(false);
|
|
3442
|
+
const [error, setError] = useState9(null);
|
|
3443
|
+
const [activeIndex, setActiveIndex] = useState9(0);
|
|
3444
|
+
const [dismissedIndex, setDismissedIndex] = useState9(null);
|
|
3336
3445
|
const safeCaret = Math.min(caret, value.length);
|
|
3337
|
-
const match =
|
|
3446
|
+
const match = useMemo4(() => findActiveTrigger(value, safeCaret, sources), [
|
|
3338
3447
|
value,
|
|
3339
3448
|
safeCaret,
|
|
3340
3449
|
sources
|
|
3341
3450
|
]);
|
|
3342
3451
|
const isActive = match !== null && dismissedIndex !== match.index;
|
|
3343
|
-
const matchRef =
|
|
3452
|
+
const matchRef = useRef8(match);
|
|
3344
3453
|
matchRef.current = match;
|
|
3345
|
-
const caretRef =
|
|
3454
|
+
const caretRef = useRef8(safeCaret);
|
|
3346
3455
|
caretRef.current = safeCaret;
|
|
3347
|
-
const itemsRef =
|
|
3456
|
+
const itemsRef = useRef8(items);
|
|
3348
3457
|
itemsRef.current = items;
|
|
3349
|
-
const activeIndexRef =
|
|
3458
|
+
const activeIndexRef = useRef8(activeIndex);
|
|
3350
3459
|
activeIndexRef.current = activeIndex;
|
|
3351
3460
|
const requestKey = isActive && match ? `${match.source.id}\0${match.query}` : null;
|
|
3352
|
-
|
|
3461
|
+
useEffect8(() => {
|
|
3353
3462
|
const current = matchRef.current;
|
|
3354
3463
|
if (requestKey === null || current === null) {
|
|
3355
3464
|
setItems([]);
|
|
@@ -3399,23 +3508,23 @@ function useComposerAutocomplete(options) {
|
|
|
3399
3508
|
const activeItem = isOpen ? items[activeIndex] ?? null : null;
|
|
3400
3509
|
const reactId = useId();
|
|
3401
3510
|
const listboxId = options.id ?? `agent-autocomplete-${reactId}`;
|
|
3402
|
-
const optionId =
|
|
3511
|
+
const optionId = useCallback7((index) => `${listboxId}-option-${index}`, [
|
|
3403
3512
|
listboxId
|
|
3404
3513
|
]);
|
|
3405
|
-
const highlight =
|
|
3514
|
+
const highlight = useCallback7((index) => {
|
|
3406
3515
|
const total = itemsRef.current.length;
|
|
3407
3516
|
if (total === 0) return;
|
|
3408
3517
|
setActiveIndex((index % total + total) % total);
|
|
3409
3518
|
}, []);
|
|
3410
|
-
const moveHighlight =
|
|
3519
|
+
const moveHighlight = useCallback7((delta) => highlight(activeIndexRef.current + delta), [
|
|
3411
3520
|
highlight
|
|
3412
3521
|
]);
|
|
3413
|
-
const dismiss =
|
|
3522
|
+
const dismiss = useCallback7(() => {
|
|
3414
3523
|
const current = matchRef.current;
|
|
3415
3524
|
if (current) setDismissedIndex(current.index);
|
|
3416
3525
|
}, []);
|
|
3417
|
-
const pendingCaret =
|
|
3418
|
-
const accept =
|
|
3526
|
+
const pendingCaret = useRef8(null);
|
|
3527
|
+
const accept = useCallback7((item) => {
|
|
3419
3528
|
const current = matchRef.current;
|
|
3420
3529
|
if (!current) return;
|
|
3421
3530
|
const chosen = item ?? itemsRef.current[activeIndexRef.current];
|
|
@@ -3432,10 +3541,10 @@ function useComposerAutocomplete(options) {
|
|
|
3432
3541
|
pendingCaret.current = null;
|
|
3433
3542
|
inputRef.current?.setSelectionRange(position, position);
|
|
3434
3543
|
});
|
|
3435
|
-
const readCaret =
|
|
3544
|
+
const readCaret = useCallback7((element) => {
|
|
3436
3545
|
setCaret(element.selectionStart ?? element.value.length);
|
|
3437
3546
|
}, []);
|
|
3438
|
-
const onKeyDown =
|
|
3547
|
+
const onKeyDown = useCallback7((event) => {
|
|
3439
3548
|
if (!isOpen) return;
|
|
3440
3549
|
const hasItems = itemsRef.current.length > 0;
|
|
3441
3550
|
switch (event.key) {
|
|
@@ -3473,23 +3582,23 @@ function useComposerAutocomplete(options) {
|
|
|
3473
3582
|
dismiss,
|
|
3474
3583
|
moveHighlight
|
|
3475
3584
|
]);
|
|
3476
|
-
const onChange =
|
|
3585
|
+
const onChange = useCallback7((event) => {
|
|
3477
3586
|
readCaret(event.target);
|
|
3478
3587
|
const next = findActiveTrigger(event.target.value, event.target.selectionStart ?? event.target.value.length, latest.current.sources);
|
|
3479
3588
|
setDismissedIndex((current) => current !== null && next?.index === current ? current : null);
|
|
3480
3589
|
}, [
|
|
3481
3590
|
readCaret
|
|
3482
3591
|
]);
|
|
3483
|
-
const onSelect =
|
|
3592
|
+
const onSelect = useCallback7((event) => readCaret(event.currentTarget), [
|
|
3484
3593
|
readCaret
|
|
3485
3594
|
]);
|
|
3486
|
-
const onClick =
|
|
3595
|
+
const onClick = useCallback7((event) => readCaret(event.currentTarget), [
|
|
3487
3596
|
readCaret
|
|
3488
3597
|
]);
|
|
3489
|
-
const setInput =
|
|
3598
|
+
const setInput = useCallback7((element) => {
|
|
3490
3599
|
inputRef.current = element;
|
|
3491
3600
|
}, []);
|
|
3492
|
-
const getInputProps =
|
|
3601
|
+
const getInputProps = useCallback7(() => ({
|
|
3493
3602
|
ref: setInput,
|
|
3494
3603
|
onChange,
|
|
3495
3604
|
onKeyDown,
|
|
@@ -3517,7 +3626,7 @@ function useComposerAutocomplete(options) {
|
|
|
3517
3626
|
activeIndex,
|
|
3518
3627
|
optionId
|
|
3519
3628
|
]);
|
|
3520
|
-
const getListboxProps =
|
|
3629
|
+
const getListboxProps = useCallback7(() => ({
|
|
3521
3630
|
id: listboxId,
|
|
3522
3631
|
role: "listbox",
|
|
3523
3632
|
"aria-label": match?.source.label ?? match?.source.id ?? "Suggestions"
|
|
@@ -3525,7 +3634,7 @@ function useComposerAutocomplete(options) {
|
|
|
3525
3634
|
listboxId,
|
|
3526
3635
|
match
|
|
3527
3636
|
]);
|
|
3528
|
-
const getOptionProps =
|
|
3637
|
+
const getOptionProps = useCallback7((index) => ({
|
|
3529
3638
|
id: optionId(index),
|
|
3530
3639
|
role: "option",
|
|
3531
3640
|
"aria-selected": index === activeIndex
|
|
@@ -3559,7 +3668,7 @@ function isPromise(value) {
|
|
|
3559
3668
|
__name(isPromise, "isPromise");
|
|
3560
3669
|
|
|
3561
3670
|
// src/presentation/use-tool-catalog.ts
|
|
3562
|
-
import { useCallback as
|
|
3671
|
+
import { useCallback as useCallback8, useEffect as useEffect9, useMemo as useMemo5, useState as useState10 } from "react";
|
|
3563
3672
|
var shared = /* @__PURE__ */ new WeakMap();
|
|
3564
3673
|
function load(client, agent) {
|
|
3565
3674
|
let byAgent = shared.get(client);
|
|
@@ -3583,11 +3692,11 @@ function load(client, agent) {
|
|
|
3583
3692
|
__name(load, "load");
|
|
3584
3693
|
function useToolCatalog(options) {
|
|
3585
3694
|
const { client, agent, enabled = true } = options;
|
|
3586
|
-
const [entries, setEntries] =
|
|
3587
|
-
const [isLoading, setLoading] =
|
|
3588
|
-
const [error, setError] =
|
|
3589
|
-
const [generation, setGeneration] =
|
|
3590
|
-
|
|
3695
|
+
const [entries, setEntries] = useState10([]);
|
|
3696
|
+
const [isLoading, setLoading] = useState10(enabled);
|
|
3697
|
+
const [error, setError] = useState10(null);
|
|
3698
|
+
const [generation, setGeneration] = useState10(0);
|
|
3699
|
+
useEffect9(() => {
|
|
3591
3700
|
if (!enabled) {
|
|
3592
3701
|
setLoading(false);
|
|
3593
3702
|
return;
|
|
@@ -3613,14 +3722,14 @@ function useToolCatalog(options) {
|
|
|
3613
3722
|
enabled,
|
|
3614
3723
|
generation
|
|
3615
3724
|
]);
|
|
3616
|
-
const refresh =
|
|
3725
|
+
const refresh = useCallback8(() => {
|
|
3617
3726
|
shared.get(client)?.delete(agent ?? "");
|
|
3618
3727
|
setGeneration((current) => current + 1);
|
|
3619
3728
|
}, [
|
|
3620
3729
|
client,
|
|
3621
3730
|
agent
|
|
3622
3731
|
]);
|
|
3623
|
-
const catalog =
|
|
3732
|
+
const catalog = useMemo5(() => toolCatalogFrom(entries), [
|
|
3624
3733
|
entries
|
|
3625
3734
|
]);
|
|
3626
3735
|
return {
|
|
@@ -3634,7 +3743,7 @@ function useToolCatalog(options) {
|
|
|
3634
3743
|
__name(useToolCatalog, "useToolCatalog");
|
|
3635
3744
|
|
|
3636
3745
|
// src/approvals/countdown.ts
|
|
3637
|
-
import { useEffect as
|
|
3746
|
+
import { useEffect as useEffect10, useRef as useRef9, useState as useState11 } from "react";
|
|
3638
3747
|
function approvalCountdown(expiresAt, now = Date.now()) {
|
|
3639
3748
|
const deadline = expiresAt == null ? Number.NaN : Date.parse(expiresAt);
|
|
3640
3749
|
if (!Number.isFinite(deadline)) {
|
|
@@ -3652,10 +3761,10 @@ function approvalCountdown(expiresAt, now = Date.now()) {
|
|
|
3652
3761
|
__name(approvalCountdown, "approvalCountdown");
|
|
3653
3762
|
function useApprovalCountdown(expiresAt, options = {}) {
|
|
3654
3763
|
const { intervalMs = 1e3 } = options;
|
|
3655
|
-
const nowRef =
|
|
3764
|
+
const nowRef = useRef9(options.now ?? Date.now);
|
|
3656
3765
|
nowRef.current = options.now ?? Date.now;
|
|
3657
|
-
const [state, setState] =
|
|
3658
|
-
|
|
3766
|
+
const [state, setState] = useState11(() => approvalCountdown(expiresAt, nowRef.current()));
|
|
3767
|
+
useEffect10(() => {
|
|
3659
3768
|
const read = /* @__PURE__ */ __name(() => approvalCountdown(expiresAt, nowRef.current()), "read");
|
|
3660
3769
|
const first = read();
|
|
3661
3770
|
setState(first);
|
|
@@ -3897,20 +4006,20 @@ __name(sumUsage, "sumUsage");
|
|
|
3897
4006
|
|
|
3898
4007
|
// src/use-agent-chat.ts
|
|
3899
4008
|
import { useChat } from "@ai-sdk/react";
|
|
3900
|
-
import { useCallback as
|
|
4009
|
+
import { useCallback as useCallback9, useEffect as useEffect11, useMemo as useMemo6, useRef as useRef10, useState as useState12 } from "react";
|
|
3901
4010
|
function useAgentChat(options) {
|
|
3902
|
-
const latest =
|
|
4011
|
+
const latest = useRef10(options);
|
|
3903
4012
|
latest.current = options;
|
|
3904
|
-
const [runId, setRunId] =
|
|
3905
|
-
const runIdRef =
|
|
4013
|
+
const [runId, setRunId] = useState12(options.resumeRunId);
|
|
4014
|
+
const runIdRef = useRef10(runId);
|
|
3906
4015
|
runIdRef.current = runId;
|
|
3907
|
-
const settlingRunIdRef =
|
|
3908
|
-
const autoResumeRunIdRef =
|
|
3909
|
-
const [autoResume, setAutoResume] =
|
|
3910
|
-
const [activeRunId, setActiveRunId] =
|
|
3911
|
-
const regenerateNext =
|
|
3912
|
-
const createdThreadId =
|
|
3913
|
-
const client =
|
|
4016
|
+
const settlingRunIdRef = useRef10(void 0);
|
|
4017
|
+
const autoResumeRunIdRef = useRef10(void 0);
|
|
4018
|
+
const [autoResume, setAutoResume] = useState12(false);
|
|
4019
|
+
const [activeRunId, setActiveRunId] = useState12(null);
|
|
4020
|
+
const regenerateNext = useRef10(false);
|
|
4021
|
+
const createdThreadId = useRef10(void 0);
|
|
4022
|
+
const client = useMemo6(() => {
|
|
3914
4023
|
if (options.backend) return options.backend;
|
|
3915
4024
|
if (options.client) return options.client;
|
|
3916
4025
|
return new AgentClient({
|
|
@@ -3926,11 +4035,11 @@ function useAgentChat(options) {
|
|
|
3926
4035
|
getHeaders: /* @__PURE__ */ __name(async () => mergeHeaders(latest.current), "getHeaders")
|
|
3927
4036
|
});
|
|
3928
4037
|
}, []);
|
|
3929
|
-
const [connection, setConnection] =
|
|
4038
|
+
const [connection, setConnection] = useState12({
|
|
3930
4039
|
status: "live"
|
|
3931
4040
|
});
|
|
3932
|
-
const resyncAfterSettle =
|
|
3933
|
-
|
|
4041
|
+
const resyncAfterSettle = useRef10(false);
|
|
4042
|
+
useEffect11(() => {
|
|
3934
4043
|
if (!options.resume || options.threadId === void 0) return;
|
|
3935
4044
|
let cancelled = false;
|
|
3936
4045
|
const threadId = options.threadId;
|
|
@@ -3950,7 +4059,7 @@ function useAgentChat(options) {
|
|
|
3950
4059
|
options.resume,
|
|
3951
4060
|
options.threadId
|
|
3952
4061
|
]);
|
|
3953
|
-
const transport =
|
|
4062
|
+
const transport = useMemo6(() => {
|
|
3954
4063
|
function onMeta(meta) {
|
|
3955
4064
|
settlingRunIdRef.current = meta.runId;
|
|
3956
4065
|
setRunId(meta.runId);
|
|
@@ -3987,6 +4096,9 @@ function useAgentChat(options) {
|
|
|
3987
4096
|
...threadId !== void 0 ? {
|
|
3988
4097
|
threadId
|
|
3989
4098
|
} : {},
|
|
4099
|
+
...current.model !== void 0 ? {
|
|
4100
|
+
model: current.model
|
|
4101
|
+
} : {},
|
|
3990
4102
|
...pageContext ? {
|
|
3991
4103
|
pageContext
|
|
3992
4104
|
} : {},
|
|
@@ -4002,7 +4114,7 @@ function useAgentChat(options) {
|
|
|
4002
4114
|
}, "onAttemptStart")
|
|
4003
4115
|
});
|
|
4004
4116
|
}, []);
|
|
4005
|
-
const backgroundRef =
|
|
4117
|
+
const backgroundRef = useRef10(() => Promise.resolve());
|
|
4006
4118
|
const chat = useChat({
|
|
4007
4119
|
transport,
|
|
4008
4120
|
resume: options.resumeRunId !== void 0 || autoResume,
|
|
@@ -4051,7 +4163,7 @@ function useAgentChat(options) {
|
|
|
4051
4163
|
}
|
|
4052
4164
|
}, "onFinish")
|
|
4053
4165
|
});
|
|
4054
|
-
const chatRef =
|
|
4166
|
+
const chatRef = useRef10(chat);
|
|
4055
4167
|
chatRef.current = chat;
|
|
4056
4168
|
async function resyncFromThread() {
|
|
4057
4169
|
const threadId = latest.current.threadId ?? createdThreadId.current;
|
|
@@ -4063,11 +4175,11 @@ function useAgentChat(options) {
|
|
|
4063
4175
|
}
|
|
4064
4176
|
}
|
|
4065
4177
|
__name(resyncFromThread, "resyncFromThread");
|
|
4066
|
-
const turnInFlight =
|
|
4067
|
-
const isTurnInFlight =
|
|
4178
|
+
const turnInFlight = useRef10(false);
|
|
4179
|
+
const isTurnInFlight = useCallback9(() => turnInFlight.current || transport.isAttemptLive, [
|
|
4068
4180
|
transport
|
|
4069
4181
|
]);
|
|
4070
|
-
const sendMessage =
|
|
4182
|
+
const sendMessage = useCallback9(async (...args) => {
|
|
4071
4183
|
if (isTurnInFlight()) return;
|
|
4072
4184
|
turnInFlight.current = true;
|
|
4073
4185
|
try {
|
|
@@ -4078,15 +4190,15 @@ function useAgentChat(options) {
|
|
|
4078
4190
|
}, [
|
|
4079
4191
|
isTurnInFlight
|
|
4080
4192
|
]);
|
|
4081
|
-
const addToolResult =
|
|
4193
|
+
const addToolResult = useCallback9(({ tool, toolCallId, output }) => chatRef.current.addToolResult({
|
|
4082
4194
|
tool,
|
|
4083
4195
|
toolCallId,
|
|
4084
4196
|
output
|
|
4085
4197
|
}), []);
|
|
4086
|
-
const [threads, setThreads] =
|
|
4087
|
-
const [quota, setQuota] =
|
|
4088
|
-
const [backgroundRuns, setBackgroundRuns] =
|
|
4089
|
-
const refreshBackground =
|
|
4198
|
+
const [threads, setThreads] = useState12([]);
|
|
4199
|
+
const [quota, setQuota] = useState12(null);
|
|
4200
|
+
const [backgroundRuns, setBackgroundRuns] = useState12([]);
|
|
4201
|
+
const refreshBackground = useCallback9(async () => {
|
|
4090
4202
|
const threadId = latest.current.threadId ?? createdThreadId.current;
|
|
4091
4203
|
if (threadId === void 0) {
|
|
4092
4204
|
return;
|
|
@@ -4111,7 +4223,7 @@ function useAgentChat(options) {
|
|
|
4111
4223
|
]);
|
|
4112
4224
|
backgroundRef.current = refreshBackground;
|
|
4113
4225
|
const isWorking = backgroundRuns.some((run) => run.status === "running");
|
|
4114
|
-
|
|
4226
|
+
useEffect11(() => {
|
|
4115
4227
|
if (options.background !== true || options.threadId === void 0) {
|
|
4116
4228
|
return;
|
|
4117
4229
|
}
|
|
@@ -4121,7 +4233,7 @@ function useAgentChat(options) {
|
|
|
4121
4233
|
options.threadId,
|
|
4122
4234
|
refreshBackground
|
|
4123
4235
|
]);
|
|
4124
|
-
|
|
4236
|
+
useEffect11(() => {
|
|
4125
4237
|
const every = latest.current.backgroundPollMs ?? 5e3;
|
|
4126
4238
|
if (latest.current.background !== true || !isWorking || every <= 0) {
|
|
4127
4239
|
return;
|
|
@@ -4132,26 +4244,26 @@ function useAgentChat(options) {
|
|
|
4132
4244
|
isWorking,
|
|
4133
4245
|
refreshBackground
|
|
4134
4246
|
]);
|
|
4135
|
-
const loadThreads =
|
|
4247
|
+
const loadThreads = useCallback9(async () => {
|
|
4136
4248
|
const list = await client.listThreads();
|
|
4137
4249
|
setThreads(list);
|
|
4138
4250
|
return list;
|
|
4139
4251
|
}, [
|
|
4140
4252
|
client
|
|
4141
4253
|
]);
|
|
4142
|
-
const loadThread =
|
|
4254
|
+
const loadThread = useCallback9((id) => client.getThread(id), [
|
|
4143
4255
|
client
|
|
4144
4256
|
]);
|
|
4145
|
-
const deleteThread =
|
|
4257
|
+
const deleteThread = useCallback9(async (id) => {
|
|
4146
4258
|
await client.deleteThread(id);
|
|
4147
4259
|
setThreads((current) => current.filter((thread) => thread.id !== id));
|
|
4148
4260
|
}, [
|
|
4149
4261
|
client
|
|
4150
4262
|
]);
|
|
4151
|
-
const forkThread =
|
|
4263
|
+
const forkThread = useCallback9((threadId, messageId) => requireBackendMethod(client, "forkFromMessage")(threadId, messageId), [
|
|
4152
4264
|
client
|
|
4153
4265
|
]);
|
|
4154
|
-
const renameThread =
|
|
4266
|
+
const renameThread = useCallback9(async (id, title) => {
|
|
4155
4267
|
await client.updateThread(id, {
|
|
4156
4268
|
title
|
|
4157
4269
|
});
|
|
@@ -4162,24 +4274,24 @@ function useAgentChat(options) {
|
|
|
4162
4274
|
}, [
|
|
4163
4275
|
client
|
|
4164
4276
|
]);
|
|
4165
|
-
const promoteThread =
|
|
4277
|
+
const promoteThread = useCallback9(async (id) => {
|
|
4166
4278
|
await requireBackendMethod(client, "promoteThread")(id);
|
|
4167
4279
|
await loadThreads();
|
|
4168
4280
|
}, [
|
|
4169
4281
|
client,
|
|
4170
4282
|
loadThreads
|
|
4171
4283
|
]);
|
|
4172
|
-
const truncateFromMessage =
|
|
4284
|
+
const truncateFromMessage = useCallback9((threadId, messageId) => requireBackendMethod(client, "truncateFromMessage")(threadId, messageId).then(() => void 0), [
|
|
4173
4285
|
client
|
|
4174
4286
|
]);
|
|
4175
|
-
const loadQuota =
|
|
4287
|
+
const loadQuota = useCallback9(async () => {
|
|
4176
4288
|
const today = await requireBackendMethod(client, "getQuotaToday")();
|
|
4177
4289
|
setQuota(today);
|
|
4178
4290
|
return today;
|
|
4179
4291
|
}, [
|
|
4180
4292
|
client
|
|
4181
4293
|
]);
|
|
4182
|
-
const cancel =
|
|
4294
|
+
const cancel = useCallback9(async () => {
|
|
4183
4295
|
chatRef.current.stop();
|
|
4184
4296
|
const activeRunId2 = runIdRef.current;
|
|
4185
4297
|
if (activeRunId2) {
|
|
@@ -4191,7 +4303,7 @@ function useAgentChat(options) {
|
|
|
4191
4303
|
}, [
|
|
4192
4304
|
client
|
|
4193
4305
|
]);
|
|
4194
|
-
const approve =
|
|
4306
|
+
const approve = useCallback9(async ({ toolCallId, remember, via }) => {
|
|
4195
4307
|
await requireBackendMethod(client, "approveToolCall")({
|
|
4196
4308
|
toolCallId,
|
|
4197
4309
|
...remember === true ? {
|
|
@@ -4204,7 +4316,7 @@ function useAgentChat(options) {
|
|
|
4204
4316
|
}, [
|
|
4205
4317
|
client
|
|
4206
4318
|
]);
|
|
4207
|
-
const reject =
|
|
4319
|
+
const reject = useCallback9(async ({ toolCallId, reason, via }) => {
|
|
4208
4320
|
await requireBackendMethod(client, "rejectToolCall")({
|
|
4209
4321
|
toolCallId,
|
|
4210
4322
|
...reason !== void 0 ? {
|
|
@@ -4217,7 +4329,7 @@ function useAgentChat(options) {
|
|
|
4217
4329
|
}, [
|
|
4218
4330
|
client
|
|
4219
4331
|
]);
|
|
4220
|
-
const answer =
|
|
4332
|
+
const answer = useCallback9(async ({ toolCallId, answers }) => {
|
|
4221
4333
|
await requireBackendMethod(client, "answerToolCall")({
|
|
4222
4334
|
toolCallId,
|
|
4223
4335
|
...answers !== void 0 ? {
|
|
@@ -4227,14 +4339,14 @@ function useAgentChat(options) {
|
|
|
4227
4339
|
}, [
|
|
4228
4340
|
client
|
|
4229
4341
|
]);
|
|
4230
|
-
const skip =
|
|
4342
|
+
const skip = useCallback9(async ({ toolCallId }) => {
|
|
4231
4343
|
await requireBackendMethod(client, "skipToolCall")({
|
|
4232
4344
|
toolCallId
|
|
4233
4345
|
});
|
|
4234
4346
|
}, [
|
|
4235
4347
|
client
|
|
4236
4348
|
]);
|
|
4237
|
-
const regenerate =
|
|
4349
|
+
const regenerate = useCallback9(() => {
|
|
4238
4350
|
if (isTurnInFlight()) return;
|
|
4239
4351
|
regenerateNext.current = true;
|
|
4240
4352
|
turnInFlight.current = true;
|
|
@@ -4249,7 +4361,21 @@ function useAgentChat(options) {
|
|
|
4249
4361
|
isWorking,
|
|
4250
4362
|
refresh: refreshBackground
|
|
4251
4363
|
};
|
|
4252
|
-
const
|
|
4364
|
+
const setThreadModel = useCallback9(async (model) => {
|
|
4365
|
+
const threadId = latest.current.threadId ?? createdThreadId.current;
|
|
4366
|
+
if (threadId === void 0) {
|
|
4367
|
+
throw new Error("setThreadModel: this chat has no thread yet");
|
|
4368
|
+
}
|
|
4369
|
+
await client.updateThread(threadId, {
|
|
4370
|
+
model
|
|
4371
|
+
});
|
|
4372
|
+
notifyThreads(client, {
|
|
4373
|
+
type: "changed"
|
|
4374
|
+
});
|
|
4375
|
+
}, [
|
|
4376
|
+
client
|
|
4377
|
+
]);
|
|
4378
|
+
const getThreadId = useCallback9(() => latest.current.threadId ?? createdThreadId.current, []);
|
|
4253
4379
|
const status = connection.status === "reconnecting" ? "reconnecting" : chat.status;
|
|
4254
4380
|
return {
|
|
4255
4381
|
...chat,
|
|
@@ -4268,6 +4394,7 @@ function useAgentChat(options) {
|
|
|
4268
4394
|
* on the first send. A getter, because the created id is learned mid-stream.
|
|
4269
4395
|
*/
|
|
4270
4396
|
getThreadId,
|
|
4397
|
+
setThreadModel,
|
|
4271
4398
|
/** The backend this chat talks to — pass it to `useThreads`, `useMessageFeedback`, … */
|
|
4272
4399
|
backend: client,
|
|
4273
4400
|
/** Same object as {@link backend}; kept for callers that read it under its old name. */
|
|
@@ -4343,11 +4470,13 @@ export {
|
|
|
4343
4470
|
toolCallState,
|
|
4344
4471
|
toolCatalogFrom,
|
|
4345
4472
|
useAgentChat,
|
|
4473
|
+
useAgents,
|
|
4346
4474
|
useApprovalCountdown,
|
|
4347
4475
|
useChatTranscript,
|
|
4348
4476
|
useComposerAutocomplete,
|
|
4349
4477
|
useElapsed,
|
|
4350
4478
|
useMessageFeedback,
|
|
4479
|
+
useModels,
|
|
4351
4480
|
useSpeechRecognition,
|
|
4352
4481
|
useStickToBottom,
|
|
4353
4482
|
useThreads,
|