@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.cjs
CHANGED
|
@@ -74,11 +74,13 @@ __export(src_exports, {
|
|
|
74
74
|
toolCallState: () => toolCallState,
|
|
75
75
|
toolCatalogFrom: () => toolCatalogFrom,
|
|
76
76
|
useAgentChat: () => useAgentChat,
|
|
77
|
+
useAgents: () => useAgents,
|
|
77
78
|
useApprovalCountdown: () => useApprovalCountdown,
|
|
78
79
|
useChatTranscript: () => useChatTranscript,
|
|
79
80
|
useComposerAutocomplete: () => useComposerAutocomplete,
|
|
80
81
|
useElapsed: () => useElapsed,
|
|
81
82
|
useMessageFeedback: () => useMessageFeedback,
|
|
83
|
+
useModels: () => useModels,
|
|
82
84
|
useSpeechRecognition: () => useSpeechRecognition,
|
|
83
85
|
useStickToBottom: () => useStickToBottom,
|
|
84
86
|
useThreads: () => useThreads,
|
|
@@ -235,6 +237,15 @@ var AgentClient = class {
|
|
|
235
237
|
truncateFromMessage(threadId, messageId) {
|
|
236
238
|
return this.request("DELETE", `/agent/threads/${encodeURIComponent(threadId)}/from/${encodeURIComponent(messageId)}`);
|
|
237
239
|
}
|
|
240
|
+
/** `GET /agent/models?agent=` — the models this caller may pick, grouped by provider. */
|
|
241
|
+
listModels(agent) {
|
|
242
|
+
const query = agent === void 0 ? "" : `?agent=${encodeURIComponent(agent)}`;
|
|
243
|
+
return this.request("GET", `/agent/models${query}`);
|
|
244
|
+
}
|
|
245
|
+
/** `GET /agent/agents` — the registered agents, the default one flagged. */
|
|
246
|
+
listAgents() {
|
|
247
|
+
return this.request("GET", "/agent/agents");
|
|
248
|
+
}
|
|
238
249
|
getQuotaToday() {
|
|
239
250
|
return this.request("GET", "/agent/quota/today");
|
|
240
251
|
}
|
|
@@ -1082,28 +1093,128 @@ function requireBackendMethod(backend, name) {
|
|
|
1082
1093
|
}
|
|
1083
1094
|
__name(requireBackendMethod, "requireBackendMethod");
|
|
1084
1095
|
|
|
1085
|
-
// src/
|
|
1096
|
+
// src/catalog/use-agents.ts
|
|
1097
|
+
var import_react3 = require("react");
|
|
1098
|
+
|
|
1099
|
+
// src/catalog/use-resource.ts
|
|
1086
1100
|
var import_react2 = require("react");
|
|
1101
|
+
function useResource(load2, key, enabled) {
|
|
1102
|
+
const [data, setData] = (0, import_react2.useState)(void 0);
|
|
1103
|
+
const [isLoading, setIsLoading] = (0, import_react2.useState)(enabled);
|
|
1104
|
+
const [error, setError] = (0, import_react2.useState)(null);
|
|
1105
|
+
const loadRef = (0, import_react2.useRef)(load2);
|
|
1106
|
+
loadRef.current = load2;
|
|
1107
|
+
const generation = (0, import_react2.useRef)(0);
|
|
1108
|
+
const refresh = (0, import_react2.useCallback)(async () => {
|
|
1109
|
+
const mine = ++generation.current;
|
|
1110
|
+
setIsLoading(true);
|
|
1111
|
+
try {
|
|
1112
|
+
const value = await loadRef.current();
|
|
1113
|
+
if (mine !== generation.current) return;
|
|
1114
|
+
setData(value);
|
|
1115
|
+
setError(null);
|
|
1116
|
+
} catch (caught) {
|
|
1117
|
+
if (mine !== generation.current) return;
|
|
1118
|
+
setError(caught instanceof Error ? caught : new Error(String(caught)));
|
|
1119
|
+
} finally {
|
|
1120
|
+
if (mine === generation.current) setIsLoading(false);
|
|
1121
|
+
}
|
|
1122
|
+
}, []);
|
|
1123
|
+
(0, import_react2.useEffect)(() => {
|
|
1124
|
+
if (!enabled) return;
|
|
1125
|
+
void refresh();
|
|
1126
|
+
}, [
|
|
1127
|
+
enabled,
|
|
1128
|
+
key,
|
|
1129
|
+
refresh
|
|
1130
|
+
]);
|
|
1131
|
+
return {
|
|
1132
|
+
data,
|
|
1133
|
+
isLoading,
|
|
1134
|
+
error,
|
|
1135
|
+
refresh
|
|
1136
|
+
};
|
|
1137
|
+
}
|
|
1138
|
+
__name(useResource, "useResource");
|
|
1139
|
+
|
|
1140
|
+
// src/catalog/use-agents.ts
|
|
1141
|
+
function useAgents(options) {
|
|
1142
|
+
const { backend, enabled = true } = options;
|
|
1143
|
+
const { data, isLoading, error, refresh } = useResource(() => requireBackendMethod(backend, "listAgents")(), "", enabled);
|
|
1144
|
+
return (0, import_react3.useMemo)(() => {
|
|
1145
|
+
const agents = data ?? [];
|
|
1146
|
+
return {
|
|
1147
|
+
agents,
|
|
1148
|
+
defaultAgent: agents.find((agent) => agent.isDefault === true)?.name ?? null,
|
|
1149
|
+
isLoading,
|
|
1150
|
+
error,
|
|
1151
|
+
refresh
|
|
1152
|
+
};
|
|
1153
|
+
}, [
|
|
1154
|
+
data,
|
|
1155
|
+
isLoading,
|
|
1156
|
+
error,
|
|
1157
|
+
refresh
|
|
1158
|
+
]);
|
|
1159
|
+
}
|
|
1160
|
+
__name(useAgents, "useAgents");
|
|
1161
|
+
|
|
1162
|
+
// src/catalog/use-models.ts
|
|
1163
|
+
var import_react4 = require("react");
|
|
1164
|
+
function useModels(options) {
|
|
1165
|
+
const { backend, agent, enabled = true } = options;
|
|
1166
|
+
const { data, isLoading, error, refresh } = useResource(() => requireBackendMethod(backend, "listModels")(agent), `${agent ?? ""}`, enabled);
|
|
1167
|
+
return (0, import_react4.useMemo)(() => {
|
|
1168
|
+
const providers = data?.providers ?? [];
|
|
1169
|
+
const models = providers.flatMap((provider) => provider.models.map((model) => ({
|
|
1170
|
+
...model,
|
|
1171
|
+
providerId: provider.id,
|
|
1172
|
+
providerLabel: provider.label
|
|
1173
|
+
})));
|
|
1174
|
+
const byId = new Map(models.map((model) => [
|
|
1175
|
+
model.id,
|
|
1176
|
+
model
|
|
1177
|
+
]));
|
|
1178
|
+
return {
|
|
1179
|
+
providers,
|
|
1180
|
+
models,
|
|
1181
|
+
defaultModel: data?.default ?? null,
|
|
1182
|
+
find: /* @__PURE__ */ __name((id) => id == null ? void 0 : byId.get(id), "find"),
|
|
1183
|
+
isLoading,
|
|
1184
|
+
error,
|
|
1185
|
+
refresh
|
|
1186
|
+
};
|
|
1187
|
+
}, [
|
|
1188
|
+
data,
|
|
1189
|
+
isLoading,
|
|
1190
|
+
error,
|
|
1191
|
+
refresh
|
|
1192
|
+
]);
|
|
1193
|
+
}
|
|
1194
|
+
__name(useModels, "useModels");
|
|
1195
|
+
|
|
1196
|
+
// src/feedback/use-message-feedback.ts
|
|
1197
|
+
var import_react5 = require("react");
|
|
1087
1198
|
function useMessageFeedback(options) {
|
|
1088
|
-
const latest = (0,
|
|
1199
|
+
const latest = (0, import_react5.useRef)(options);
|
|
1089
1200
|
latest.current = options;
|
|
1090
|
-
const [local, setLocal] = (0,
|
|
1091
|
-
const [pending, setPending] = (0,
|
|
1092
|
-
const [error, setError] = (0,
|
|
1093
|
-
const localRef = (0,
|
|
1201
|
+
const [local, setLocal] = (0, import_react5.useState)(/* @__PURE__ */ new Map());
|
|
1202
|
+
const [pending, setPending] = (0, import_react5.useState)(/* @__PURE__ */ new Set());
|
|
1203
|
+
const [error, setError] = (0, import_react5.useState)(null);
|
|
1204
|
+
const localRef = (0, import_react5.useRef)(local);
|
|
1094
1205
|
localRef.current = local;
|
|
1095
|
-
const resolved = (0,
|
|
1096
|
-
const feedbackOf = (0,
|
|
1206
|
+
const resolved = (0, import_react5.useRef)(/* @__PURE__ */ new Map());
|
|
1207
|
+
const feedbackOf = (0, import_react5.useCallback)((message) => {
|
|
1097
1208
|
const mine = local.get(message.id);
|
|
1098
1209
|
if (mine !== void 0) return mine.feedback;
|
|
1099
1210
|
return metadataOf(message).feedback ?? null;
|
|
1100
1211
|
}, [
|
|
1101
1212
|
local
|
|
1102
1213
|
]);
|
|
1103
|
-
const isPending = (0,
|
|
1214
|
+
const isPending = (0, import_react5.useCallback)((message) => pending.has(message.id), [
|
|
1104
1215
|
pending
|
|
1105
1216
|
]);
|
|
1106
|
-
const storedIdFor = (0,
|
|
1217
|
+
const storedIdFor = (0, import_react5.useCallback)(async (message) => {
|
|
1107
1218
|
const runId = metadataOf(message).runId;
|
|
1108
1219
|
if (runId === void 0) return message.id;
|
|
1109
1220
|
const known = resolved.current.get(message.id);
|
|
@@ -1123,7 +1234,7 @@ function useMessageFeedback(options) {
|
|
|
1123
1234
|
resolved.current.set(message.id, row.id);
|
|
1124
1235
|
return row.id;
|
|
1125
1236
|
}, []);
|
|
1126
|
-
const rate = (0,
|
|
1237
|
+
const rate = (0, import_react5.useCallback)(async (message, value, comment) => {
|
|
1127
1238
|
const setFeedback = requireBackendMethod(latest.current.backend, "setMessageFeedback");
|
|
1128
1239
|
const had = localRef.current.get(message.id);
|
|
1129
1240
|
const optimistic = value === null ? null : {
|
|
@@ -1169,7 +1280,7 @@ function useMessageFeedback(options) {
|
|
|
1169
1280
|
}, [
|
|
1170
1281
|
storedIdFor
|
|
1171
1282
|
]);
|
|
1172
|
-
const toggle = (0,
|
|
1283
|
+
const toggle = (0, import_react5.useCallback)((message, value) => {
|
|
1173
1284
|
const mine = localRef.current.get(message.id);
|
|
1174
1285
|
const current = mine !== void 0 ? mine.feedback : metadataOf(message).feedback ?? null;
|
|
1175
1286
|
return rate(message, current?.value === value ? null : value);
|
|
@@ -1213,16 +1324,16 @@ function onThreadsEvent(backend, listener) {
|
|
|
1213
1324
|
__name(onThreadsEvent, "onThreadsEvent");
|
|
1214
1325
|
|
|
1215
1326
|
// src/threads/use-threads.ts
|
|
1216
|
-
var
|
|
1327
|
+
var import_react6 = require("react");
|
|
1217
1328
|
function useThreads(options) {
|
|
1218
1329
|
const { backend, enabled = true } = options;
|
|
1219
|
-
const [threads, setThreads] = (0,
|
|
1220
|
-
const [isLoading, setIsLoading] = (0,
|
|
1221
|
-
const [error, setError] = (0,
|
|
1222
|
-
const threadsRef = (0,
|
|
1330
|
+
const [threads, setThreads] = (0, import_react6.useState)([]);
|
|
1331
|
+
const [isLoading, setIsLoading] = (0, import_react6.useState)(enabled);
|
|
1332
|
+
const [error, setError] = (0, import_react6.useState)(null);
|
|
1333
|
+
const threadsRef = (0, import_react6.useRef)(threads);
|
|
1223
1334
|
threadsRef.current = threads;
|
|
1224
|
-
const generation = (0,
|
|
1225
|
-
const refresh = (0,
|
|
1335
|
+
const generation = (0, import_react6.useRef)(0);
|
|
1336
|
+
const refresh = (0, import_react6.useCallback)(async () => {
|
|
1226
1337
|
const mine = ++generation.current;
|
|
1227
1338
|
setIsLoading(true);
|
|
1228
1339
|
try {
|
|
@@ -1239,7 +1350,7 @@ function useThreads(options) {
|
|
|
1239
1350
|
}, [
|
|
1240
1351
|
backend
|
|
1241
1352
|
]);
|
|
1242
|
-
(0,
|
|
1353
|
+
(0, import_react6.useEffect)(() => {
|
|
1243
1354
|
if (!enabled) return;
|
|
1244
1355
|
void refresh();
|
|
1245
1356
|
return onThreadsEvent(backend, (event) => {
|
|
@@ -1259,7 +1370,7 @@ function useThreads(options) {
|
|
|
1259
1370
|
enabled,
|
|
1260
1371
|
refresh
|
|
1261
1372
|
]);
|
|
1262
|
-
const rename = (0,
|
|
1373
|
+
const rename = (0, import_react6.useCallback)(async (id, title) => {
|
|
1263
1374
|
const before = threadsRef.current;
|
|
1264
1375
|
setThreads((current) => current.map((thread) => thread.id === id ? {
|
|
1265
1376
|
...thread,
|
|
@@ -1281,7 +1392,7 @@ function useThreads(options) {
|
|
|
1281
1392
|
}, [
|
|
1282
1393
|
backend
|
|
1283
1394
|
]);
|
|
1284
|
-
const remove = (0,
|
|
1395
|
+
const remove = (0, import_react6.useCallback)(async (id) => {
|
|
1285
1396
|
const before = threadsRef.current;
|
|
1286
1397
|
setThreads((current) => current.filter((thread) => thread.id !== id));
|
|
1287
1398
|
try {
|
|
@@ -1356,10 +1467,10 @@ function backgroundRunsFromThread(messages) {
|
|
|
1356
1467
|
__name(backgroundRunsFromThread, "backgroundRunsFromThread");
|
|
1357
1468
|
|
|
1358
1469
|
// src/components/chat-input.tsx
|
|
1359
|
-
var
|
|
1470
|
+
var import_react8 = __toESM(require("react"), 1);
|
|
1360
1471
|
|
|
1361
1472
|
// src/components/use-speech-recognition.ts
|
|
1362
|
-
var
|
|
1473
|
+
var import_react7 = require("react");
|
|
1363
1474
|
function getRecognitionCtor() {
|
|
1364
1475
|
if (typeof window === "undefined") return null;
|
|
1365
1476
|
const scope = window;
|
|
@@ -1367,15 +1478,15 @@ function getRecognitionCtor() {
|
|
|
1367
1478
|
}
|
|
1368
1479
|
__name(getRecognitionCtor, "getRecognitionCtor");
|
|
1369
1480
|
function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTranscript }) {
|
|
1370
|
-
const recognitionRef = (0,
|
|
1371
|
-
const [isListening, setIsListening] = (0,
|
|
1372
|
-
const ctor = (0,
|
|
1481
|
+
const recognitionRef = (0, import_react7.useRef)(null);
|
|
1482
|
+
const [isListening, setIsListening] = (0, import_react7.useState)(false);
|
|
1483
|
+
const ctor = (0, import_react7.useMemo)(() => getRecognitionCtor(), []);
|
|
1373
1484
|
const isSupported = ctor !== null;
|
|
1374
|
-
const finalRef = (0,
|
|
1375
|
-
const interimRef = (0,
|
|
1485
|
+
const finalRef = (0, import_react7.useRef)(onFinalTranscript);
|
|
1486
|
+
const interimRef = (0, import_react7.useRef)(onInterimTranscript);
|
|
1376
1487
|
finalRef.current = onFinalTranscript;
|
|
1377
1488
|
interimRef.current = onInterimTranscript;
|
|
1378
|
-
(0,
|
|
1489
|
+
(0, import_react7.useEffect)(() => {
|
|
1379
1490
|
if (!ctor) return;
|
|
1380
1491
|
const recognition = new ctor();
|
|
1381
1492
|
recognition.lang = lang;
|
|
@@ -1414,7 +1525,7 @@ function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTran
|
|
|
1414
1525
|
ctor,
|
|
1415
1526
|
lang
|
|
1416
1527
|
]);
|
|
1417
|
-
const start = (0,
|
|
1528
|
+
const start = (0, import_react7.useCallback)(() => {
|
|
1418
1529
|
const recognition = recognitionRef.current;
|
|
1419
1530
|
if (!recognition) return;
|
|
1420
1531
|
try {
|
|
@@ -1424,7 +1535,7 @@ function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTran
|
|
|
1424
1535
|
console.warn("SpeechRecognition start failed", error);
|
|
1425
1536
|
}
|
|
1426
1537
|
}, []);
|
|
1427
|
-
const stop = (0,
|
|
1538
|
+
const stop = (0, import_react7.useCallback)(() => {
|
|
1428
1539
|
const recognition = recognitionRef.current;
|
|
1429
1540
|
if (!recognition) return;
|
|
1430
1541
|
try {
|
|
@@ -1443,8 +1554,8 @@ __name(useSpeechRecognition, "useSpeechRecognition");
|
|
|
1443
1554
|
|
|
1444
1555
|
// src/components/chat-input.tsx
|
|
1445
1556
|
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,
|
|
1557
|
+
const [value, setValue] = (0, import_react8.useState)("");
|
|
1558
|
+
const [interim, setInterim] = (0, import_react8.useState)("");
|
|
1448
1559
|
const speech = useSpeechRecognition({
|
|
1449
1560
|
lang: speechLang,
|
|
1450
1561
|
onFinalTranscript: /* @__PURE__ */ __name((text) => {
|
|
@@ -1455,7 +1566,7 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
|
|
|
1455
1566
|
}, "onFinalTranscript"),
|
|
1456
1567
|
onInterimTranscript: /* @__PURE__ */ __name((text) => setInterim(text), "onInterimTranscript")
|
|
1457
1568
|
});
|
|
1458
|
-
(0,
|
|
1569
|
+
(0, import_react8.useEffect)(() => {
|
|
1459
1570
|
if (!speech.isListening) setInterim("");
|
|
1460
1571
|
}, [
|
|
1461
1572
|
speech.isListening
|
|
@@ -1483,9 +1594,9 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
|
|
|
1483
1594
|
const displayValue = speech.isListening && interim ? `${value}${value && !value.endsWith(" ") ? " " : ""}${interim}` : value;
|
|
1484
1595
|
const showMic = enableSpeech && speech.isSupported;
|
|
1485
1596
|
const showStop = isStreaming && onStop !== void 0;
|
|
1486
|
-
return /* @__PURE__ */
|
|
1597
|
+
return /* @__PURE__ */ import_react8.default.createElement("div", {
|
|
1487
1598
|
className
|
|
1488
|
-
}, /* @__PURE__ */
|
|
1599
|
+
}, /* @__PURE__ */ import_react8.default.createElement("textarea", {
|
|
1489
1600
|
className: textareaClassName,
|
|
1490
1601
|
rows,
|
|
1491
1602
|
value: displayValue,
|
|
@@ -1496,17 +1607,17 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
|
|
|
1496
1607
|
}, "onChange"),
|
|
1497
1608
|
onKeyDown: handleKeyDown,
|
|
1498
1609
|
placeholder: placeholder ?? "Ask something (Enter to send, Shift+Enter for newline)"
|
|
1499
|
-
}), /* @__PURE__ */
|
|
1610
|
+
}), /* @__PURE__ */ import_react8.default.createElement("button", {
|
|
1500
1611
|
type: "button",
|
|
1501
1612
|
className: sendButtonClassName,
|
|
1502
1613
|
onClick: submit,
|
|
1503
1614
|
disabled: disabled || !value.trim()
|
|
1504
|
-
}, sendLabel), showStop ? /* @__PURE__ */
|
|
1615
|
+
}, sendLabel), showStop ? /* @__PURE__ */ import_react8.default.createElement("button", {
|
|
1505
1616
|
type: "button",
|
|
1506
1617
|
className: stopButtonClassName,
|
|
1507
1618
|
onClick: /* @__PURE__ */ __name(() => void onStop(), "onClick"),
|
|
1508
1619
|
"aria-label": "Stop generating"
|
|
1509
|
-
}, stopLabel) : null, showMic ? /* @__PURE__ */
|
|
1620
|
+
}, stopLabel) : null, showMic ? /* @__PURE__ */ import_react8.default.createElement("button", {
|
|
1510
1621
|
type: "button",
|
|
1511
1622
|
className: micButtonClassName,
|
|
1512
1623
|
onClick: toggleMic,
|
|
@@ -1519,10 +1630,10 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
|
|
|
1519
1630
|
__name(ChatInput, "ChatInput");
|
|
1520
1631
|
|
|
1521
1632
|
// src/components/message-item.tsx
|
|
1522
|
-
var
|
|
1633
|
+
var import_react11 = __toESM(require("react"), 1);
|
|
1523
1634
|
|
|
1524
1635
|
// src/transcript/use-chat-transcript.ts
|
|
1525
|
-
var
|
|
1636
|
+
var import_react10 = require("react");
|
|
1526
1637
|
|
|
1527
1638
|
// src/transcript/model.ts
|
|
1528
1639
|
var import_nestjs_agent_core2 = require("@dudousxd/nestjs-agent-core");
|
|
@@ -2499,11 +2610,11 @@ function formatCostUsd(cost) {
|
|
|
2499
2610
|
__name(formatCostUsd, "formatCostUsd");
|
|
2500
2611
|
|
|
2501
2612
|
// src/transcript/use-stick-to-bottom.ts
|
|
2502
|
-
var
|
|
2613
|
+
var import_react9 = require("react");
|
|
2503
2614
|
function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
2504
|
-
const containerRef = (0,
|
|
2505
|
-
const [isAtBottom, setIsAtBottom] = (0,
|
|
2506
|
-
const measure = (0,
|
|
2615
|
+
const containerRef = (0, import_react9.useRef)(null);
|
|
2616
|
+
const [isAtBottom, setIsAtBottom] = (0, import_react9.useState)(true);
|
|
2617
|
+
const measure = (0, import_react9.useCallback)(() => {
|
|
2507
2618
|
const element = containerRef.current;
|
|
2508
2619
|
if (!element) {
|
|
2509
2620
|
return;
|
|
@@ -2513,7 +2624,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
|
2513
2624
|
}, [
|
|
2514
2625
|
threshold
|
|
2515
2626
|
]);
|
|
2516
|
-
const scrollToBottom = (0,
|
|
2627
|
+
const scrollToBottom = (0, import_react9.useCallback)(() => {
|
|
2517
2628
|
const element = containerRef.current;
|
|
2518
2629
|
if (!element) {
|
|
2519
2630
|
return;
|
|
@@ -2521,7 +2632,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
|
2521
2632
|
element.scrollTop = element.scrollHeight;
|
|
2522
2633
|
setIsAtBottom(true);
|
|
2523
2634
|
}, []);
|
|
2524
|
-
const setContainer = (0,
|
|
2635
|
+
const setContainer = (0, import_react9.useCallback)((element) => {
|
|
2525
2636
|
containerRef.current = element;
|
|
2526
2637
|
if (element) {
|
|
2527
2638
|
measure();
|
|
@@ -2529,7 +2640,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
|
2529
2640
|
}, [
|
|
2530
2641
|
measure
|
|
2531
2642
|
]);
|
|
2532
|
-
(0,
|
|
2643
|
+
(0, import_react9.useEffect)(() => {
|
|
2533
2644
|
if (isAtBottom) {
|
|
2534
2645
|
scrollToBottom();
|
|
2535
2646
|
}
|
|
@@ -2538,7 +2649,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
|
2538
2649
|
isAtBottom,
|
|
2539
2650
|
scrollToBottom
|
|
2540
2651
|
]);
|
|
2541
|
-
const getContainerProps = (0,
|
|
2652
|
+
const getContainerProps = (0, import_react9.useCallback)(() => ({
|
|
2542
2653
|
ref: setContainer,
|
|
2543
2654
|
onScroll: measure
|
|
2544
2655
|
}), [
|
|
@@ -2560,14 +2671,14 @@ var DEFAULT_LOAD_EARLIER_STEP = 50;
|
|
|
2560
2671
|
var DEFAULT_COPY_RESET_MS = 1500;
|
|
2561
2672
|
function useChatTranscript(options) {
|
|
2562
2673
|
const { messages, status, initialVisibleCount = DEFAULT_VISIBLE_COUNT, loadEarlierStep = DEFAULT_LOAD_EARLIER_STEP, followUps, stickToBottomThreshold } = options;
|
|
2563
|
-
const latest = (0,
|
|
2674
|
+
const latest = (0, import_react10.useRef)(options);
|
|
2564
2675
|
latest.current = options;
|
|
2565
|
-
const [visibleCount, setVisibleCount] = (0,
|
|
2566
|
-
const [stopRequested, setStopRequested] = (0,
|
|
2676
|
+
const [visibleCount, setVisibleCount] = (0, import_react10.useState)(initialVisibleCount);
|
|
2677
|
+
const [stopRequested, setStopRequested] = (0, import_react10.useState)(false);
|
|
2567
2678
|
const isStreaming = status === "streaming" || status === "reconnecting";
|
|
2568
2679
|
const isBusy = status === "submitted" || isStreaming;
|
|
2569
2680
|
const isEmpty = messages.length === 0;
|
|
2570
|
-
(0,
|
|
2681
|
+
(0, import_react10.useEffect)(() => {
|
|
2571
2682
|
if (!isBusy) {
|
|
2572
2683
|
setStopRequested(false);
|
|
2573
2684
|
}
|
|
@@ -2584,7 +2695,7 @@ function useChatTranscript(options) {
|
|
|
2584
2695
|
streamingMessageId,
|
|
2585
2696
|
options
|
|
2586
2697
|
});
|
|
2587
|
-
const stop = (0,
|
|
2698
|
+
const stop = (0, import_react10.useCallback)(() => {
|
|
2588
2699
|
const current = latest.current;
|
|
2589
2700
|
if (current.status !== "submitted" && current.status !== "streaming" && current.status !== "reconnecting") {
|
|
2590
2701
|
return;
|
|
@@ -2592,8 +2703,8 @@ function useChatTranscript(options) {
|
|
|
2592
2703
|
setStopRequested(true);
|
|
2593
2704
|
void current.onStop?.();
|
|
2594
2705
|
}, []);
|
|
2595
|
-
const loadEarlier = (0,
|
|
2596
|
-
const showAll = (0,
|
|
2706
|
+
const loadEarlier = (0, import_react10.useCallback)(() => setVisibleCount((count) => count + (latest.current.loadEarlierStep ?? DEFAULT_LOAD_EARLIER_STEP)), []);
|
|
2707
|
+
const showAll = (0, import_react10.useCallback)(() => setVisibleCount(latest.current.messages.length), []);
|
|
2597
2708
|
const scroll = useStickToBottom({
|
|
2598
2709
|
contentKey: contentSignature(messages),
|
|
2599
2710
|
...stickToBottomThreshold !== void 0 ? {
|
|
@@ -2629,7 +2740,7 @@ function useChatTranscript(options) {
|
|
|
2629
2740
|
__name(useChatTranscript, "useChatTranscript");
|
|
2630
2741
|
function useTranscriptItem(options) {
|
|
2631
2742
|
const { message, isStreaming = false } = options;
|
|
2632
|
-
const messagesRef = (0,
|
|
2743
|
+
const messagesRef = (0, import_react10.useRef)([
|
|
2633
2744
|
message
|
|
2634
2745
|
]);
|
|
2635
2746
|
if (messagesRef.current[0] !== message) {
|
|
@@ -2647,13 +2758,13 @@ function useTranscriptItem(options) {
|
|
|
2647
2758
|
}
|
|
2648
2759
|
__name(useTranscriptItem, "useTranscriptItem");
|
|
2649
2760
|
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,
|
|
2761
|
+
const [drafts, setDrafts] = (0, import_react10.useState)(() => /* @__PURE__ */ new Map());
|
|
2762
|
+
const [copied, setCopied] = (0, import_react10.useState)(() => /* @__PURE__ */ new Set());
|
|
2763
|
+
const [openReasoning, setOpenReasoning] = (0, import_react10.useState)(() => /* @__PURE__ */ new Map());
|
|
2764
|
+
const [picks, setPicks] = (0, import_react10.useState)(() => /* @__PURE__ */ new Map());
|
|
2765
|
+
const [settling, setSettling] = (0, import_react10.useState)(() => /* @__PURE__ */ new Map());
|
|
2766
|
+
const [settleErrors, setSettleErrors] = (0, import_react10.useState)(() => /* @__PURE__ */ new Map());
|
|
2767
|
+
const latest = (0, import_react10.useRef)({
|
|
2657
2768
|
options,
|
|
2658
2769
|
drafts,
|
|
2659
2770
|
picks,
|
|
@@ -2665,23 +2776,23 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2665
2776
|
picks,
|
|
2666
2777
|
messages
|
|
2667
2778
|
};
|
|
2668
|
-
const copyTimers = (0,
|
|
2669
|
-
(0,
|
|
2779
|
+
const copyTimers = (0, import_react10.useRef)(/* @__PURE__ */ new Map());
|
|
2780
|
+
(0, import_react10.useEffect)(() => () => {
|
|
2670
2781
|
for (const timer of copyTimers.current.values()) {
|
|
2671
2782
|
clearTimeout(timer);
|
|
2672
2783
|
}
|
|
2673
2784
|
copyTimers.current.clear();
|
|
2674
2785
|
}, []);
|
|
2675
|
-
const callbackCache = (0,
|
|
2676
|
-
const reasoningToggleCache = (0,
|
|
2677
|
-
const toggleReasoning = (0,
|
|
2786
|
+
const callbackCache = (0, import_react10.useRef)(/* @__PURE__ */ new Map());
|
|
2787
|
+
const reasoningToggleCache = (0, import_react10.useRef)(/* @__PURE__ */ new Map());
|
|
2788
|
+
const toggleReasoning = (0, import_react10.useCallback)((key, open) => {
|
|
2678
2789
|
setOpenReasoning((current) => {
|
|
2679
2790
|
const next = new Map(current);
|
|
2680
2791
|
next.set(key, open ?? !(current.get(key) ?? false));
|
|
2681
2792
|
return next;
|
|
2682
2793
|
});
|
|
2683
2794
|
}, []);
|
|
2684
|
-
const stableToggle = (0,
|
|
2795
|
+
const stableToggle = (0, import_react10.useCallback)((key) => {
|
|
2685
2796
|
let cached = reasoningToggleCache.current.get(key);
|
|
2686
2797
|
if (!cached) {
|
|
2687
2798
|
cached = /* @__PURE__ */ __name((open) => toggleReasoning(key, open), "cached");
|
|
@@ -2691,10 +2802,10 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2691
2802
|
}, [
|
|
2692
2803
|
toggleReasoning
|
|
2693
2804
|
]);
|
|
2694
|
-
const pick = (0,
|
|
2805
|
+
const pick = (0, import_react10.useCallback)((toolCallId, questionId, values) => {
|
|
2695
2806
|
setPicks((current) => new Map(current).set(pickKey(toolCallId, questionId), values));
|
|
2696
2807
|
}, []);
|
|
2697
|
-
const settle = (0,
|
|
2808
|
+
const settle = (0, import_react10.useCallback)((toolCallId, action, send) => {
|
|
2698
2809
|
setSettleErrors((current) => {
|
|
2699
2810
|
if (!current.has(toolCallId)) {
|
|
2700
2811
|
return current;
|
|
@@ -2718,7 +2829,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2718
2829
|
failed(error);
|
|
2719
2830
|
}
|
|
2720
2831
|
}, []);
|
|
2721
|
-
const answer = (0,
|
|
2832
|
+
const answer = (0, import_react10.useCallback)((toolCallId) => {
|
|
2722
2833
|
const current = latest.current;
|
|
2723
2834
|
const onAnswer = current.options.onAnswer;
|
|
2724
2835
|
if (!onAnswer) {
|
|
@@ -2728,7 +2839,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2728
2839
|
}, [
|
|
2729
2840
|
settle
|
|
2730
2841
|
]);
|
|
2731
|
-
const skip = (0,
|
|
2842
|
+
const skip = (0, import_react10.useCallback)((toolCallId) => {
|
|
2732
2843
|
const onSkip = latest.current.options.onSkip;
|
|
2733
2844
|
if (onSkip) {
|
|
2734
2845
|
settle(toolCallId, "skip", () => onSkip(toolCallId));
|
|
@@ -2736,7 +2847,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2736
2847
|
}, [
|
|
2737
2848
|
settle
|
|
2738
2849
|
]);
|
|
2739
|
-
const approve = (0,
|
|
2850
|
+
const approve = (0, import_react10.useCallback)((toolCallId, options2) => {
|
|
2740
2851
|
const onApprove = latest.current.options.onApprove;
|
|
2741
2852
|
if (onApprove) {
|
|
2742
2853
|
settle(toolCallId, "approve", () => options2 === void 0 ? onApprove(toolCallId) : onApprove(toolCallId, options2));
|
|
@@ -2744,7 +2855,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2744
2855
|
}, [
|
|
2745
2856
|
settle
|
|
2746
2857
|
]);
|
|
2747
|
-
const reject = (0,
|
|
2858
|
+
const reject = (0, import_react10.useCallback)((toolCallId) => {
|
|
2748
2859
|
const onReject = latest.current.options.onReject;
|
|
2749
2860
|
if (onReject) {
|
|
2750
2861
|
settle(toolCallId, "reject", () => onReject(toolCallId));
|
|
@@ -2752,7 +2863,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
2752
2863
|
}, [
|
|
2753
2864
|
settle
|
|
2754
2865
|
]);
|
|
2755
|
-
const callbacksFor = (0,
|
|
2866
|
+
const callbacksFor = (0, import_react10.useCallback)((id) => {
|
|
2756
2867
|
const cached = callbackCache.current.get(id);
|
|
2757
2868
|
if (cached) {
|
|
2758
2869
|
return cached;
|
|
@@ -2994,7 +3105,7 @@ function MessageItem({ message, isStreaming = false, editable, onEditSubmit, reg
|
|
|
2994
3105
|
getCreatedAt: /* @__PURE__ */ __name(() => createdAt, "getCreatedAt")
|
|
2995
3106
|
} : {}
|
|
2996
3107
|
});
|
|
2997
|
-
return /* @__PURE__ */
|
|
3108
|
+
return /* @__PURE__ */ import_react11.default.createElement(MessageItemView, {
|
|
2998
3109
|
item,
|
|
2999
3110
|
...slots
|
|
3000
3111
|
});
|
|
@@ -3002,51 +3113,51 @@ function MessageItem({ message, isStreaming = false, editable, onEditSubmit, reg
|
|
|
3002
3113
|
__name(MessageItem, "MessageItem");
|
|
3003
3114
|
function MessageItemView({ item, ...slots }) {
|
|
3004
3115
|
const { classNames } = slots;
|
|
3005
|
-
const actionRow = /* @__PURE__ */
|
|
3116
|
+
const actionRow = /* @__PURE__ */ import_react11.default.createElement("div", {
|
|
3006
3117
|
className: classNames?.actions,
|
|
3007
3118
|
"data-actions-for": item.role
|
|
3008
|
-
}, item.copy.available ? /* @__PURE__ */
|
|
3119
|
+
}, item.copy.available ? /* @__PURE__ */ import_react11.default.createElement("button", {
|
|
3009
3120
|
type: "button",
|
|
3010
3121
|
onClick: item.copy.copy,
|
|
3011
3122
|
className: classNames?.actionButton,
|
|
3012
3123
|
title: item.copy.copied ? "Copied!" : "Copy message text"
|
|
3013
|
-
}, item.copy.copied ? "Copied" : "Copy") : null, item.fork.available ? /* @__PURE__ */
|
|
3124
|
+
}, item.copy.copied ? "Copied" : "Copy") : null, item.fork.available ? /* @__PURE__ */ import_react11.default.createElement("button", {
|
|
3014
3125
|
type: "button",
|
|
3015
3126
|
onClick: item.fork.run,
|
|
3016
3127
|
className: classNames?.actionButton,
|
|
3017
3128
|
title: "Fork thread from this message"
|
|
3018
|
-
}, "Fork") : null, item.regenerate.available ? /* @__PURE__ */
|
|
3129
|
+
}, "Fork") : null, item.regenerate.available ? /* @__PURE__ */ import_react11.default.createElement("button", {
|
|
3019
3130
|
type: "button",
|
|
3020
3131
|
onClick: item.regenerate.run,
|
|
3021
3132
|
className: classNames?.actionButton,
|
|
3022
3133
|
title: "Regenerate response"
|
|
3023
|
-
}, "Regenerate") : null, slots.meta, !item.isUser && item.usage ? /* @__PURE__ */
|
|
3134
|
+
}, "Regenerate") : null, slots.meta, !item.isUser && item.usage ? /* @__PURE__ */ import_react11.default.createElement("span", {
|
|
3024
3135
|
className: classNames?.usage,
|
|
3025
3136
|
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__ */
|
|
3137
|
+
}, item.usage.costLabel, " \xB7 ", item.usage.tokensLabel) : null, item.timestamp ? /* @__PURE__ */ import_react11.default.createElement("span", {
|
|
3027
3138
|
className: classNames?.timestamp,
|
|
3028
3139
|
title: item.timestamp.absolute
|
|
3029
3140
|
}, item.timestamp.relative) : null);
|
|
3030
3141
|
if (item.edit.available) {
|
|
3031
|
-
return /* @__PURE__ */
|
|
3142
|
+
return /* @__PURE__ */ import_react11.default.createElement(EditableUserBubble, {
|
|
3032
3143
|
item,
|
|
3033
3144
|
slots,
|
|
3034
3145
|
actions: actionRow
|
|
3035
3146
|
});
|
|
3036
3147
|
}
|
|
3037
3148
|
const className = joinClasses(classNames?.root, classNames?.byRole?.[item.role]);
|
|
3038
|
-
return /* @__PURE__ */
|
|
3149
|
+
return /* @__PURE__ */ import_react11.default.createElement("div", {
|
|
3039
3150
|
className,
|
|
3040
3151
|
"data-role": item.role,
|
|
3041
3152
|
"data-streaming": item.isStreaming ? "true" : void 0
|
|
3042
|
-
}, /* @__PURE__ */
|
|
3153
|
+
}, /* @__PURE__ */ import_react11.default.createElement("div", null, renderBlocks(item, slots)), actionRow);
|
|
3043
3154
|
}
|
|
3044
3155
|
__name(MessageItemView, "MessageItemView");
|
|
3045
3156
|
function renderBlocks(item, slots) {
|
|
3046
3157
|
const nodes = [];
|
|
3047
3158
|
for (const block of item.blocks) {
|
|
3048
3159
|
if (block.kind === "text") {
|
|
3049
|
-
nodes.push(/* @__PURE__ */
|
|
3160
|
+
nodes.push(/* @__PURE__ */ import_react11.default.createElement("div", {
|
|
3050
3161
|
key: block.key,
|
|
3051
3162
|
className: slots.classNames?.text
|
|
3052
3163
|
}, slots.renderText ? slots.renderText(block.text, {
|
|
@@ -3067,7 +3178,7 @@ function renderBlocks(item, slots) {
|
|
|
3067
3178
|
continue;
|
|
3068
3179
|
}
|
|
3069
3180
|
if (block.kind === "ui" && slots.renderUi) {
|
|
3070
|
-
nodes.push(/* @__PURE__ */
|
|
3181
|
+
nodes.push(/* @__PURE__ */ import_react11.default.createElement("div", {
|
|
3071
3182
|
key: block.key,
|
|
3072
3183
|
"data-slot": "ui",
|
|
3073
3184
|
"data-component": block.component
|
|
@@ -3078,18 +3189,18 @@ function renderBlocks(item, slots) {
|
|
|
3078
3189
|
}
|
|
3079
3190
|
__name(renderBlocks, "renderBlocks");
|
|
3080
3191
|
function renderFilesBlock(block, slots) {
|
|
3081
|
-
return /* @__PURE__ */
|
|
3192
|
+
return /* @__PURE__ */ import_react11.default.createElement("div", {
|
|
3082
3193
|
key: block.key,
|
|
3083
3194
|
className: slots.classNames?.files,
|
|
3084
3195
|
"data-files": "true"
|
|
3085
|
-
}, slots.renderFiles ? slots.renderFiles(block.files) : block.files.map((file) => /* @__PURE__ */
|
|
3196
|
+
}, slots.renderFiles ? slots.renderFiles(block.files) : block.files.map((file) => /* @__PURE__ */ import_react11.default.createElement("a", {
|
|
3086
3197
|
key: file.url,
|
|
3087
3198
|
href: file.url,
|
|
3088
3199
|
target: "_blank",
|
|
3089
3200
|
rel: "noreferrer",
|
|
3090
3201
|
className: slots.classNames?.file,
|
|
3091
3202
|
title: file.filename ?? file.mediaType
|
|
3092
|
-
}, file.isImage ? /* @__PURE__ */
|
|
3203
|
+
}, file.isImage ? /* @__PURE__ */ import_react11.default.createElement("img", {
|
|
3093
3204
|
src: file.url,
|
|
3094
3205
|
alt: file.filename ?? "image",
|
|
3095
3206
|
className: slots.classNames?.fileImage
|
|
@@ -3097,17 +3208,17 @@ function renderFilesBlock(block, slots) {
|
|
|
3097
3208
|
}
|
|
3098
3209
|
__name(renderFilesBlock, "renderFilesBlock");
|
|
3099
3210
|
function renderReasoningBlock(block, slots) {
|
|
3100
|
-
return /* @__PURE__ */
|
|
3211
|
+
return /* @__PURE__ */ import_react11.default.createElement("div", {
|
|
3101
3212
|
key: block.key,
|
|
3102
3213
|
className: slots.classNames?.reasoning,
|
|
3103
3214
|
"data-reasoning": "true",
|
|
3104
3215
|
"data-streaming": block.isStreaming ? "true" : void 0
|
|
3105
|
-
}, /* @__PURE__ */
|
|
3216
|
+
}, /* @__PURE__ */ import_react11.default.createElement("button", {
|
|
3106
3217
|
type: "button",
|
|
3107
3218
|
className: slots.classNames?.reasoningToggle,
|
|
3108
3219
|
onClick: /* @__PURE__ */ __name(() => block.toggle(), "onClick"),
|
|
3109
3220
|
"aria-expanded": block.isOpen
|
|
3110
|
-
}, slots.reasoningLabel ?? "Reasoning"), block.isOpen ? /* @__PURE__ */
|
|
3221
|
+
}, slots.reasoningLabel ?? "Reasoning"), block.isOpen ? /* @__PURE__ */ import_react11.default.createElement("div", {
|
|
3111
3222
|
className: slots.classNames?.reasoningText
|
|
3112
3223
|
}, slots.renderReasoning ? slots.renderReasoning(block.text, {
|
|
3113
3224
|
isStreaming: block.isStreaming,
|
|
@@ -3118,7 +3229,7 @@ __name(renderReasoningBlock, "renderReasoningBlock");
|
|
|
3118
3229
|
function renderToolBlock(item, block, slots) {
|
|
3119
3230
|
if (slots.renderToolGroup) {
|
|
3120
3231
|
return [
|
|
3121
|
-
/* @__PURE__ */
|
|
3232
|
+
/* @__PURE__ */ import_react11.default.createElement(import_react11.default.Fragment, {
|
|
3122
3233
|
key: block.key
|
|
3123
3234
|
}, slots.renderToolGroup(block.parts, block.key))
|
|
3124
3235
|
];
|
|
@@ -3129,7 +3240,7 @@ function renderToolBlock(item, block, slots) {
|
|
|
3129
3240
|
const renderToolPart = slots.renderToolPart;
|
|
3130
3241
|
return block.parts.map((part) => {
|
|
3131
3242
|
const partKey = `${item.id}-${part.toolCallId}`;
|
|
3132
|
-
return /* @__PURE__ */
|
|
3243
|
+
return /* @__PURE__ */ import_react11.default.createElement(import_react11.default.Fragment, {
|
|
3133
3244
|
key: partKey
|
|
3134
3245
|
}, renderToolPart(part, partKey));
|
|
3135
3246
|
});
|
|
@@ -3139,14 +3250,14 @@ function EditableUserBubble({ item, slots, actions }) {
|
|
|
3139
3250
|
const { classNames } = slots;
|
|
3140
3251
|
const { edit } = item;
|
|
3141
3252
|
if (!edit.isEditing) {
|
|
3142
|
-
return /* @__PURE__ */
|
|
3253
|
+
return /* @__PURE__ */ import_react11.default.createElement("div", {
|
|
3143
3254
|
className: joinClasses(classNames?.root, classNames?.byRole?.user),
|
|
3144
3255
|
"data-role": "user"
|
|
3145
|
-
}, /* @__PURE__ */
|
|
3256
|
+
}, /* @__PURE__ */ import_react11.default.createElement("div", {
|
|
3146
3257
|
className: classNames?.text
|
|
3147
3258
|
}, slots.renderText ? slots.renderText(item.text, {
|
|
3148
3259
|
isStreaming: false
|
|
3149
|
-
}) : item.text), /* @__PURE__ */
|
|
3260
|
+
}) : item.text), /* @__PURE__ */ import_react11.default.createElement("button", {
|
|
3150
3261
|
type: "button",
|
|
3151
3262
|
onClick: edit.start,
|
|
3152
3263
|
className: classNames?.actionButton,
|
|
@@ -3154,18 +3265,18 @@ function EditableUserBubble({ item, slots, actions }) {
|
|
|
3154
3265
|
}, "Edit"), actions);
|
|
3155
3266
|
}
|
|
3156
3267
|
const textareaProps = edit.getTextareaProps();
|
|
3157
|
-
return /* @__PURE__ */
|
|
3268
|
+
return /* @__PURE__ */ import_react11.default.createElement("div", {
|
|
3158
3269
|
"data-editing": "true"
|
|
3159
|
-
}, /* @__PURE__ */
|
|
3270
|
+
}, /* @__PURE__ */ import_react11.default.createElement("textarea", {
|
|
3160
3271
|
...textareaProps,
|
|
3161
3272
|
rows: Math.min(8, edit.draft.split("\n").length + 1),
|
|
3162
3273
|
className: classNames?.editTextarea
|
|
3163
|
-
}), /* @__PURE__ */
|
|
3274
|
+
}), /* @__PURE__ */ import_react11.default.createElement("div", {
|
|
3164
3275
|
className: classNames?.editActions
|
|
3165
|
-
}, /* @__PURE__ */
|
|
3276
|
+
}, /* @__PURE__ */ import_react11.default.createElement("button", {
|
|
3166
3277
|
type: "button",
|
|
3167
3278
|
onClick: edit.cancel
|
|
3168
|
-
}, "Cancel"), /* @__PURE__ */
|
|
3279
|
+
}, "Cancel"), /* @__PURE__ */ import_react11.default.createElement("button", {
|
|
3169
3280
|
type: "button",
|
|
3170
3281
|
onClick: edit.save,
|
|
3171
3282
|
disabled: !edit.canSave
|
|
@@ -3409,35 +3520,35 @@ function toItem(entry) {
|
|
|
3409
3520
|
__name(toItem, "toItem");
|
|
3410
3521
|
|
|
3411
3522
|
// src/composer/use-composer-autocomplete.ts
|
|
3412
|
-
var
|
|
3523
|
+
var import_react12 = require("react");
|
|
3413
3524
|
function useComposerAutocomplete(options) {
|
|
3414
3525
|
const { value, sources, acceptOnTab = true } = options;
|
|
3415
|
-
const latest = (0,
|
|
3526
|
+
const latest = (0, import_react12.useRef)(options);
|
|
3416
3527
|
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,
|
|
3528
|
+
const inputRef = (0, import_react12.useRef)(null);
|
|
3529
|
+
const [caret, setCaret] = (0, import_react12.useState)(value.length);
|
|
3530
|
+
const [items, setItems] = (0, import_react12.useState)([]);
|
|
3531
|
+
const [isLoading, setLoading] = (0, import_react12.useState)(false);
|
|
3532
|
+
const [error, setError] = (0, import_react12.useState)(null);
|
|
3533
|
+
const [activeIndex, setActiveIndex] = (0, import_react12.useState)(0);
|
|
3534
|
+
const [dismissedIndex, setDismissedIndex] = (0, import_react12.useState)(null);
|
|
3424
3535
|
const safeCaret = Math.min(caret, value.length);
|
|
3425
|
-
const match = (0,
|
|
3536
|
+
const match = (0, import_react12.useMemo)(() => findActiveTrigger(value, safeCaret, sources), [
|
|
3426
3537
|
value,
|
|
3427
3538
|
safeCaret,
|
|
3428
3539
|
sources
|
|
3429
3540
|
]);
|
|
3430
3541
|
const isActive = match !== null && dismissedIndex !== match.index;
|
|
3431
|
-
const matchRef = (0,
|
|
3542
|
+
const matchRef = (0, import_react12.useRef)(match);
|
|
3432
3543
|
matchRef.current = match;
|
|
3433
|
-
const caretRef = (0,
|
|
3544
|
+
const caretRef = (0, import_react12.useRef)(safeCaret);
|
|
3434
3545
|
caretRef.current = safeCaret;
|
|
3435
|
-
const itemsRef = (0,
|
|
3546
|
+
const itemsRef = (0, import_react12.useRef)(items);
|
|
3436
3547
|
itemsRef.current = items;
|
|
3437
|
-
const activeIndexRef = (0,
|
|
3548
|
+
const activeIndexRef = (0, import_react12.useRef)(activeIndex);
|
|
3438
3549
|
activeIndexRef.current = activeIndex;
|
|
3439
3550
|
const requestKey = isActive && match ? `${match.source.id}\0${match.query}` : null;
|
|
3440
|
-
(0,
|
|
3551
|
+
(0, import_react12.useEffect)(() => {
|
|
3441
3552
|
const current = matchRef.current;
|
|
3442
3553
|
if (requestKey === null || current === null) {
|
|
3443
3554
|
setItems([]);
|
|
@@ -3485,25 +3596,25 @@ function useComposerAutocomplete(options) {
|
|
|
3485
3596
|
]);
|
|
3486
3597
|
const isOpen = isActive;
|
|
3487
3598
|
const activeItem = isOpen ? items[activeIndex] ?? null : null;
|
|
3488
|
-
const reactId = (0,
|
|
3599
|
+
const reactId = (0, import_react12.useId)();
|
|
3489
3600
|
const listboxId = options.id ?? `agent-autocomplete-${reactId}`;
|
|
3490
|
-
const optionId = (0,
|
|
3601
|
+
const optionId = (0, import_react12.useCallback)((index) => `${listboxId}-option-${index}`, [
|
|
3491
3602
|
listboxId
|
|
3492
3603
|
]);
|
|
3493
|
-
const highlight = (0,
|
|
3604
|
+
const highlight = (0, import_react12.useCallback)((index) => {
|
|
3494
3605
|
const total = itemsRef.current.length;
|
|
3495
3606
|
if (total === 0) return;
|
|
3496
3607
|
setActiveIndex((index % total + total) % total);
|
|
3497
3608
|
}, []);
|
|
3498
|
-
const moveHighlight = (0,
|
|
3609
|
+
const moveHighlight = (0, import_react12.useCallback)((delta) => highlight(activeIndexRef.current + delta), [
|
|
3499
3610
|
highlight
|
|
3500
3611
|
]);
|
|
3501
|
-
const dismiss = (0,
|
|
3612
|
+
const dismiss = (0, import_react12.useCallback)(() => {
|
|
3502
3613
|
const current = matchRef.current;
|
|
3503
3614
|
if (current) setDismissedIndex(current.index);
|
|
3504
3615
|
}, []);
|
|
3505
|
-
const pendingCaret = (0,
|
|
3506
|
-
const accept = (0,
|
|
3616
|
+
const pendingCaret = (0, import_react12.useRef)(null);
|
|
3617
|
+
const accept = (0, import_react12.useCallback)((item) => {
|
|
3507
3618
|
const current = matchRef.current;
|
|
3508
3619
|
if (!current) return;
|
|
3509
3620
|
const chosen = item ?? itemsRef.current[activeIndexRef.current];
|
|
@@ -3514,16 +3625,16 @@ function useComposerAutocomplete(options) {
|
|
|
3514
3625
|
setDismissedIndex(null);
|
|
3515
3626
|
pendingCaret.current = edit.caret;
|
|
3516
3627
|
}, []);
|
|
3517
|
-
(0,
|
|
3628
|
+
(0, import_react12.useLayoutEffect)(() => {
|
|
3518
3629
|
const position = pendingCaret.current;
|
|
3519
3630
|
if (position === null) return;
|
|
3520
3631
|
pendingCaret.current = null;
|
|
3521
3632
|
inputRef.current?.setSelectionRange(position, position);
|
|
3522
3633
|
});
|
|
3523
|
-
const readCaret = (0,
|
|
3634
|
+
const readCaret = (0, import_react12.useCallback)((element) => {
|
|
3524
3635
|
setCaret(element.selectionStart ?? element.value.length);
|
|
3525
3636
|
}, []);
|
|
3526
|
-
const onKeyDown = (0,
|
|
3637
|
+
const onKeyDown = (0, import_react12.useCallback)((event) => {
|
|
3527
3638
|
if (!isOpen) return;
|
|
3528
3639
|
const hasItems = itemsRef.current.length > 0;
|
|
3529
3640
|
switch (event.key) {
|
|
@@ -3561,23 +3672,23 @@ function useComposerAutocomplete(options) {
|
|
|
3561
3672
|
dismiss,
|
|
3562
3673
|
moveHighlight
|
|
3563
3674
|
]);
|
|
3564
|
-
const onChange = (0,
|
|
3675
|
+
const onChange = (0, import_react12.useCallback)((event) => {
|
|
3565
3676
|
readCaret(event.target);
|
|
3566
3677
|
const next = findActiveTrigger(event.target.value, event.target.selectionStart ?? event.target.value.length, latest.current.sources);
|
|
3567
3678
|
setDismissedIndex((current) => current !== null && next?.index === current ? current : null);
|
|
3568
3679
|
}, [
|
|
3569
3680
|
readCaret
|
|
3570
3681
|
]);
|
|
3571
|
-
const onSelect = (0,
|
|
3682
|
+
const onSelect = (0, import_react12.useCallback)((event) => readCaret(event.currentTarget), [
|
|
3572
3683
|
readCaret
|
|
3573
3684
|
]);
|
|
3574
|
-
const onClick = (0,
|
|
3685
|
+
const onClick = (0, import_react12.useCallback)((event) => readCaret(event.currentTarget), [
|
|
3575
3686
|
readCaret
|
|
3576
3687
|
]);
|
|
3577
|
-
const setInput = (0,
|
|
3688
|
+
const setInput = (0, import_react12.useCallback)((element) => {
|
|
3578
3689
|
inputRef.current = element;
|
|
3579
3690
|
}, []);
|
|
3580
|
-
const getInputProps = (0,
|
|
3691
|
+
const getInputProps = (0, import_react12.useCallback)(() => ({
|
|
3581
3692
|
ref: setInput,
|
|
3582
3693
|
onChange,
|
|
3583
3694
|
onKeyDown,
|
|
@@ -3605,7 +3716,7 @@ function useComposerAutocomplete(options) {
|
|
|
3605
3716
|
activeIndex,
|
|
3606
3717
|
optionId
|
|
3607
3718
|
]);
|
|
3608
|
-
const getListboxProps = (0,
|
|
3719
|
+
const getListboxProps = (0, import_react12.useCallback)(() => ({
|
|
3609
3720
|
id: listboxId,
|
|
3610
3721
|
role: "listbox",
|
|
3611
3722
|
"aria-label": match?.source.label ?? match?.source.id ?? "Suggestions"
|
|
@@ -3613,7 +3724,7 @@ function useComposerAutocomplete(options) {
|
|
|
3613
3724
|
listboxId,
|
|
3614
3725
|
match
|
|
3615
3726
|
]);
|
|
3616
|
-
const getOptionProps = (0,
|
|
3727
|
+
const getOptionProps = (0, import_react12.useCallback)((index) => ({
|
|
3617
3728
|
id: optionId(index),
|
|
3618
3729
|
role: "option",
|
|
3619
3730
|
"aria-selected": index === activeIndex
|
|
@@ -3647,7 +3758,7 @@ function isPromise(value) {
|
|
|
3647
3758
|
__name(isPromise, "isPromise");
|
|
3648
3759
|
|
|
3649
3760
|
// src/presentation/use-tool-catalog.ts
|
|
3650
|
-
var
|
|
3761
|
+
var import_react13 = require("react");
|
|
3651
3762
|
var shared = /* @__PURE__ */ new WeakMap();
|
|
3652
3763
|
function load(client, agent) {
|
|
3653
3764
|
let byAgent = shared.get(client);
|
|
@@ -3671,11 +3782,11 @@ function load(client, agent) {
|
|
|
3671
3782
|
__name(load, "load");
|
|
3672
3783
|
function useToolCatalog(options) {
|
|
3673
3784
|
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,
|
|
3785
|
+
const [entries, setEntries] = (0, import_react13.useState)([]);
|
|
3786
|
+
const [isLoading, setLoading] = (0, import_react13.useState)(enabled);
|
|
3787
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
3788
|
+
const [generation, setGeneration] = (0, import_react13.useState)(0);
|
|
3789
|
+
(0, import_react13.useEffect)(() => {
|
|
3679
3790
|
if (!enabled) {
|
|
3680
3791
|
setLoading(false);
|
|
3681
3792
|
return;
|
|
@@ -3701,14 +3812,14 @@ function useToolCatalog(options) {
|
|
|
3701
3812
|
enabled,
|
|
3702
3813
|
generation
|
|
3703
3814
|
]);
|
|
3704
|
-
const refresh = (0,
|
|
3815
|
+
const refresh = (0, import_react13.useCallback)(() => {
|
|
3705
3816
|
shared.get(client)?.delete(agent ?? "");
|
|
3706
3817
|
setGeneration((current) => current + 1);
|
|
3707
3818
|
}, [
|
|
3708
3819
|
client,
|
|
3709
3820
|
agent
|
|
3710
3821
|
]);
|
|
3711
|
-
const catalog = (0,
|
|
3822
|
+
const catalog = (0, import_react13.useMemo)(() => toolCatalogFrom(entries), [
|
|
3712
3823
|
entries
|
|
3713
3824
|
]);
|
|
3714
3825
|
return {
|
|
@@ -3722,7 +3833,7 @@ function useToolCatalog(options) {
|
|
|
3722
3833
|
__name(useToolCatalog, "useToolCatalog");
|
|
3723
3834
|
|
|
3724
3835
|
// src/approvals/countdown.ts
|
|
3725
|
-
var
|
|
3836
|
+
var import_react14 = require("react");
|
|
3726
3837
|
function approvalCountdown(expiresAt, now = Date.now()) {
|
|
3727
3838
|
const deadline = expiresAt == null ? Number.NaN : Date.parse(expiresAt);
|
|
3728
3839
|
if (!Number.isFinite(deadline)) {
|
|
@@ -3740,10 +3851,10 @@ function approvalCountdown(expiresAt, now = Date.now()) {
|
|
|
3740
3851
|
__name(approvalCountdown, "approvalCountdown");
|
|
3741
3852
|
function useApprovalCountdown(expiresAt, options = {}) {
|
|
3742
3853
|
const { intervalMs = 1e3 } = options;
|
|
3743
|
-
const nowRef = (0,
|
|
3854
|
+
const nowRef = (0, import_react14.useRef)(options.now ?? Date.now);
|
|
3744
3855
|
nowRef.current = options.now ?? Date.now;
|
|
3745
|
-
const [state, setState] = (0,
|
|
3746
|
-
(0,
|
|
3856
|
+
const [state, setState] = (0, import_react14.useState)(() => approvalCountdown(expiresAt, nowRef.current()));
|
|
3857
|
+
(0, import_react14.useEffect)(() => {
|
|
3747
3858
|
const read = /* @__PURE__ */ __name(() => approvalCountdown(expiresAt, nowRef.current()), "read");
|
|
3748
3859
|
const first = read();
|
|
3749
3860
|
setState(first);
|
|
@@ -3984,21 +4095,21 @@ function sumUsage(rows) {
|
|
|
3984
4095
|
__name(sumUsage, "sumUsage");
|
|
3985
4096
|
|
|
3986
4097
|
// src/use-agent-chat.ts
|
|
3987
|
-
var
|
|
3988
|
-
var
|
|
4098
|
+
var import_react15 = require("@ai-sdk/react");
|
|
4099
|
+
var import_react16 = require("react");
|
|
3989
4100
|
function useAgentChat(options) {
|
|
3990
|
-
const latest = (0,
|
|
4101
|
+
const latest = (0, import_react16.useRef)(options);
|
|
3991
4102
|
latest.current = options;
|
|
3992
|
-
const [runId, setRunId] = (0,
|
|
3993
|
-
const runIdRef = (0,
|
|
4103
|
+
const [runId, setRunId] = (0, import_react16.useState)(options.resumeRunId);
|
|
4104
|
+
const runIdRef = (0, import_react16.useRef)(runId);
|
|
3994
4105
|
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,
|
|
4106
|
+
const settlingRunIdRef = (0, import_react16.useRef)(void 0);
|
|
4107
|
+
const autoResumeRunIdRef = (0, import_react16.useRef)(void 0);
|
|
4108
|
+
const [autoResume, setAutoResume] = (0, import_react16.useState)(false);
|
|
4109
|
+
const [activeRunId, setActiveRunId] = (0, import_react16.useState)(null);
|
|
4110
|
+
const regenerateNext = (0, import_react16.useRef)(false);
|
|
4111
|
+
const createdThreadId = (0, import_react16.useRef)(void 0);
|
|
4112
|
+
const client = (0, import_react16.useMemo)(() => {
|
|
4002
4113
|
if (options.backend) return options.backend;
|
|
4003
4114
|
if (options.client) return options.client;
|
|
4004
4115
|
return new AgentClient({
|
|
@@ -4014,11 +4125,11 @@ function useAgentChat(options) {
|
|
|
4014
4125
|
getHeaders: /* @__PURE__ */ __name(async () => mergeHeaders(latest.current), "getHeaders")
|
|
4015
4126
|
});
|
|
4016
4127
|
}, []);
|
|
4017
|
-
const [connection, setConnection] = (0,
|
|
4128
|
+
const [connection, setConnection] = (0, import_react16.useState)({
|
|
4018
4129
|
status: "live"
|
|
4019
4130
|
});
|
|
4020
|
-
const resyncAfterSettle = (0,
|
|
4021
|
-
(0,
|
|
4131
|
+
const resyncAfterSettle = (0, import_react16.useRef)(false);
|
|
4132
|
+
(0, import_react16.useEffect)(() => {
|
|
4022
4133
|
if (!options.resume || options.threadId === void 0) return;
|
|
4023
4134
|
let cancelled = false;
|
|
4024
4135
|
const threadId = options.threadId;
|
|
@@ -4038,7 +4149,7 @@ function useAgentChat(options) {
|
|
|
4038
4149
|
options.resume,
|
|
4039
4150
|
options.threadId
|
|
4040
4151
|
]);
|
|
4041
|
-
const transport = (0,
|
|
4152
|
+
const transport = (0, import_react16.useMemo)(() => {
|
|
4042
4153
|
function onMeta(meta) {
|
|
4043
4154
|
settlingRunIdRef.current = meta.runId;
|
|
4044
4155
|
setRunId(meta.runId);
|
|
@@ -4075,6 +4186,9 @@ function useAgentChat(options) {
|
|
|
4075
4186
|
...threadId !== void 0 ? {
|
|
4076
4187
|
threadId
|
|
4077
4188
|
} : {},
|
|
4189
|
+
...current.model !== void 0 ? {
|
|
4190
|
+
model: current.model
|
|
4191
|
+
} : {},
|
|
4078
4192
|
...pageContext ? {
|
|
4079
4193
|
pageContext
|
|
4080
4194
|
} : {},
|
|
@@ -4090,8 +4204,8 @@ function useAgentChat(options) {
|
|
|
4090
4204
|
}, "onAttemptStart")
|
|
4091
4205
|
});
|
|
4092
4206
|
}, []);
|
|
4093
|
-
const backgroundRef = (0,
|
|
4094
|
-
const chat = (0,
|
|
4207
|
+
const backgroundRef = (0, import_react16.useRef)(() => Promise.resolve());
|
|
4208
|
+
const chat = (0, import_react15.useChat)({
|
|
4095
4209
|
transport,
|
|
4096
4210
|
resume: options.resumeRunId !== void 0 || autoResume,
|
|
4097
4211
|
...options.threadId !== void 0 ? {
|
|
@@ -4139,7 +4253,7 @@ function useAgentChat(options) {
|
|
|
4139
4253
|
}
|
|
4140
4254
|
}, "onFinish")
|
|
4141
4255
|
});
|
|
4142
|
-
const chatRef = (0,
|
|
4256
|
+
const chatRef = (0, import_react16.useRef)(chat);
|
|
4143
4257
|
chatRef.current = chat;
|
|
4144
4258
|
async function resyncFromThread() {
|
|
4145
4259
|
const threadId = latest.current.threadId ?? createdThreadId.current;
|
|
@@ -4151,11 +4265,11 @@ function useAgentChat(options) {
|
|
|
4151
4265
|
}
|
|
4152
4266
|
}
|
|
4153
4267
|
__name(resyncFromThread, "resyncFromThread");
|
|
4154
|
-
const turnInFlight = (0,
|
|
4155
|
-
const isTurnInFlight = (0,
|
|
4268
|
+
const turnInFlight = (0, import_react16.useRef)(false);
|
|
4269
|
+
const isTurnInFlight = (0, import_react16.useCallback)(() => turnInFlight.current || transport.isAttemptLive, [
|
|
4156
4270
|
transport
|
|
4157
4271
|
]);
|
|
4158
|
-
const sendMessage = (0,
|
|
4272
|
+
const sendMessage = (0, import_react16.useCallback)(async (...args) => {
|
|
4159
4273
|
if (isTurnInFlight()) return;
|
|
4160
4274
|
turnInFlight.current = true;
|
|
4161
4275
|
try {
|
|
@@ -4166,15 +4280,15 @@ function useAgentChat(options) {
|
|
|
4166
4280
|
}, [
|
|
4167
4281
|
isTurnInFlight
|
|
4168
4282
|
]);
|
|
4169
|
-
const addToolResult = (0,
|
|
4283
|
+
const addToolResult = (0, import_react16.useCallback)(({ tool, toolCallId, output }) => chatRef.current.addToolResult({
|
|
4170
4284
|
tool,
|
|
4171
4285
|
toolCallId,
|
|
4172
4286
|
output
|
|
4173
4287
|
}), []);
|
|
4174
|
-
const [threads, setThreads] = (0,
|
|
4175
|
-
const [quota, setQuota] = (0,
|
|
4176
|
-
const [backgroundRuns, setBackgroundRuns] = (0,
|
|
4177
|
-
const refreshBackground = (0,
|
|
4288
|
+
const [threads, setThreads] = (0, import_react16.useState)([]);
|
|
4289
|
+
const [quota, setQuota] = (0, import_react16.useState)(null);
|
|
4290
|
+
const [backgroundRuns, setBackgroundRuns] = (0, import_react16.useState)([]);
|
|
4291
|
+
const refreshBackground = (0, import_react16.useCallback)(async () => {
|
|
4178
4292
|
const threadId = latest.current.threadId ?? createdThreadId.current;
|
|
4179
4293
|
if (threadId === void 0) {
|
|
4180
4294
|
return;
|
|
@@ -4199,7 +4313,7 @@ function useAgentChat(options) {
|
|
|
4199
4313
|
]);
|
|
4200
4314
|
backgroundRef.current = refreshBackground;
|
|
4201
4315
|
const isWorking = backgroundRuns.some((run) => run.status === "running");
|
|
4202
|
-
(0,
|
|
4316
|
+
(0, import_react16.useEffect)(() => {
|
|
4203
4317
|
if (options.background !== true || options.threadId === void 0) {
|
|
4204
4318
|
return;
|
|
4205
4319
|
}
|
|
@@ -4209,7 +4323,7 @@ function useAgentChat(options) {
|
|
|
4209
4323
|
options.threadId,
|
|
4210
4324
|
refreshBackground
|
|
4211
4325
|
]);
|
|
4212
|
-
(0,
|
|
4326
|
+
(0, import_react16.useEffect)(() => {
|
|
4213
4327
|
const every = latest.current.backgroundPollMs ?? 5e3;
|
|
4214
4328
|
if (latest.current.background !== true || !isWorking || every <= 0) {
|
|
4215
4329
|
return;
|
|
@@ -4220,26 +4334,26 @@ function useAgentChat(options) {
|
|
|
4220
4334
|
isWorking,
|
|
4221
4335
|
refreshBackground
|
|
4222
4336
|
]);
|
|
4223
|
-
const loadThreads = (0,
|
|
4337
|
+
const loadThreads = (0, import_react16.useCallback)(async () => {
|
|
4224
4338
|
const list = await client.listThreads();
|
|
4225
4339
|
setThreads(list);
|
|
4226
4340
|
return list;
|
|
4227
4341
|
}, [
|
|
4228
4342
|
client
|
|
4229
4343
|
]);
|
|
4230
|
-
const loadThread = (0,
|
|
4344
|
+
const loadThread = (0, import_react16.useCallback)((id) => client.getThread(id), [
|
|
4231
4345
|
client
|
|
4232
4346
|
]);
|
|
4233
|
-
const deleteThread = (0,
|
|
4347
|
+
const deleteThread = (0, import_react16.useCallback)(async (id) => {
|
|
4234
4348
|
await client.deleteThread(id);
|
|
4235
4349
|
setThreads((current) => current.filter((thread) => thread.id !== id));
|
|
4236
4350
|
}, [
|
|
4237
4351
|
client
|
|
4238
4352
|
]);
|
|
4239
|
-
const forkThread = (0,
|
|
4353
|
+
const forkThread = (0, import_react16.useCallback)((threadId, messageId) => requireBackendMethod(client, "forkFromMessage")(threadId, messageId), [
|
|
4240
4354
|
client
|
|
4241
4355
|
]);
|
|
4242
|
-
const renameThread = (0,
|
|
4356
|
+
const renameThread = (0, import_react16.useCallback)(async (id, title) => {
|
|
4243
4357
|
await client.updateThread(id, {
|
|
4244
4358
|
title
|
|
4245
4359
|
});
|
|
@@ -4250,24 +4364,24 @@ function useAgentChat(options) {
|
|
|
4250
4364
|
}, [
|
|
4251
4365
|
client
|
|
4252
4366
|
]);
|
|
4253
|
-
const promoteThread = (0,
|
|
4367
|
+
const promoteThread = (0, import_react16.useCallback)(async (id) => {
|
|
4254
4368
|
await requireBackendMethod(client, "promoteThread")(id);
|
|
4255
4369
|
await loadThreads();
|
|
4256
4370
|
}, [
|
|
4257
4371
|
client,
|
|
4258
4372
|
loadThreads
|
|
4259
4373
|
]);
|
|
4260
|
-
const truncateFromMessage = (0,
|
|
4374
|
+
const truncateFromMessage = (0, import_react16.useCallback)((threadId, messageId) => requireBackendMethod(client, "truncateFromMessage")(threadId, messageId).then(() => void 0), [
|
|
4261
4375
|
client
|
|
4262
4376
|
]);
|
|
4263
|
-
const loadQuota = (0,
|
|
4377
|
+
const loadQuota = (0, import_react16.useCallback)(async () => {
|
|
4264
4378
|
const today = await requireBackendMethod(client, "getQuotaToday")();
|
|
4265
4379
|
setQuota(today);
|
|
4266
4380
|
return today;
|
|
4267
4381
|
}, [
|
|
4268
4382
|
client
|
|
4269
4383
|
]);
|
|
4270
|
-
const cancel = (0,
|
|
4384
|
+
const cancel = (0, import_react16.useCallback)(async () => {
|
|
4271
4385
|
chatRef.current.stop();
|
|
4272
4386
|
const activeRunId2 = runIdRef.current;
|
|
4273
4387
|
if (activeRunId2) {
|
|
@@ -4279,7 +4393,7 @@ function useAgentChat(options) {
|
|
|
4279
4393
|
}, [
|
|
4280
4394
|
client
|
|
4281
4395
|
]);
|
|
4282
|
-
const approve = (0,
|
|
4396
|
+
const approve = (0, import_react16.useCallback)(async ({ toolCallId, remember, via }) => {
|
|
4283
4397
|
await requireBackendMethod(client, "approveToolCall")({
|
|
4284
4398
|
toolCallId,
|
|
4285
4399
|
...remember === true ? {
|
|
@@ -4292,7 +4406,7 @@ function useAgentChat(options) {
|
|
|
4292
4406
|
}, [
|
|
4293
4407
|
client
|
|
4294
4408
|
]);
|
|
4295
|
-
const reject = (0,
|
|
4409
|
+
const reject = (0, import_react16.useCallback)(async ({ toolCallId, reason, via }) => {
|
|
4296
4410
|
await requireBackendMethod(client, "rejectToolCall")({
|
|
4297
4411
|
toolCallId,
|
|
4298
4412
|
...reason !== void 0 ? {
|
|
@@ -4305,7 +4419,7 @@ function useAgentChat(options) {
|
|
|
4305
4419
|
}, [
|
|
4306
4420
|
client
|
|
4307
4421
|
]);
|
|
4308
|
-
const answer = (0,
|
|
4422
|
+
const answer = (0, import_react16.useCallback)(async ({ toolCallId, answers }) => {
|
|
4309
4423
|
await requireBackendMethod(client, "answerToolCall")({
|
|
4310
4424
|
toolCallId,
|
|
4311
4425
|
...answers !== void 0 ? {
|
|
@@ -4315,14 +4429,14 @@ function useAgentChat(options) {
|
|
|
4315
4429
|
}, [
|
|
4316
4430
|
client
|
|
4317
4431
|
]);
|
|
4318
|
-
const skip = (0,
|
|
4432
|
+
const skip = (0, import_react16.useCallback)(async ({ toolCallId }) => {
|
|
4319
4433
|
await requireBackendMethod(client, "skipToolCall")({
|
|
4320
4434
|
toolCallId
|
|
4321
4435
|
});
|
|
4322
4436
|
}, [
|
|
4323
4437
|
client
|
|
4324
4438
|
]);
|
|
4325
|
-
const regenerate = (0,
|
|
4439
|
+
const regenerate = (0, import_react16.useCallback)(() => {
|
|
4326
4440
|
if (isTurnInFlight()) return;
|
|
4327
4441
|
regenerateNext.current = true;
|
|
4328
4442
|
turnInFlight.current = true;
|
|
@@ -4337,7 +4451,21 @@ function useAgentChat(options) {
|
|
|
4337
4451
|
isWorking,
|
|
4338
4452
|
refresh: refreshBackground
|
|
4339
4453
|
};
|
|
4340
|
-
const
|
|
4454
|
+
const setThreadModel = (0, import_react16.useCallback)(async (model) => {
|
|
4455
|
+
const threadId = latest.current.threadId ?? createdThreadId.current;
|
|
4456
|
+
if (threadId === void 0) {
|
|
4457
|
+
throw new Error("setThreadModel: this chat has no thread yet");
|
|
4458
|
+
}
|
|
4459
|
+
await client.updateThread(threadId, {
|
|
4460
|
+
model
|
|
4461
|
+
});
|
|
4462
|
+
notifyThreads(client, {
|
|
4463
|
+
type: "changed"
|
|
4464
|
+
});
|
|
4465
|
+
}, [
|
|
4466
|
+
client
|
|
4467
|
+
]);
|
|
4468
|
+
const getThreadId = (0, import_react16.useCallback)(() => latest.current.threadId ?? createdThreadId.current, []);
|
|
4341
4469
|
const status = connection.status === "reconnecting" ? "reconnecting" : chat.status;
|
|
4342
4470
|
return {
|
|
4343
4471
|
...chat,
|
|
@@ -4356,6 +4484,7 @@ function useAgentChat(options) {
|
|
|
4356
4484
|
* on the first send. A getter, because the created id is learned mid-stream.
|
|
4357
4485
|
*/
|
|
4358
4486
|
getThreadId,
|
|
4487
|
+
setThreadModel,
|
|
4359
4488
|
/** The backend this chat talks to — pass it to `useThreads`, `useMessageFeedback`, … */
|
|
4360
4489
|
backend: client,
|
|
4361
4490
|
/** Same object as {@link backend}; kept for callers that read it under its old name. */
|
|
@@ -4432,11 +4561,13 @@ __name(mergeHeaders, "mergeHeaders");
|
|
|
4432
4561
|
toolCallState,
|
|
4433
4562
|
toolCatalogFrom,
|
|
4434
4563
|
useAgentChat,
|
|
4564
|
+
useAgents,
|
|
4435
4565
|
useApprovalCountdown,
|
|
4436
4566
|
useChatTranscript,
|
|
4437
4567
|
useComposerAutocomplete,
|
|
4438
4568
|
useElapsed,
|
|
4439
4569
|
useMessageFeedback,
|
|
4570
|
+
useModels,
|
|
4440
4571
|
useSpeechRecognition,
|
|
4441
4572
|
useStickToBottom,
|
|
4442
4573
|
useThreads,
|