@agents24/react 0.2.15 → 0.2.17
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/dist/index.js +136 -42
- package/dist/index.js.map +1 -1
- package/dist/thread-message-queue.d.ts +7 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -802,10 +802,13 @@ function reconcileRefreshedThreads(current, incoming, activeThreadId, concurrent
|
|
|
802
802
|
return concurrentEvents.reduce(applyThreadSummaryEvent, base);
|
|
803
803
|
}
|
|
804
804
|
function preferNewestThreadSummary(current, incoming) {
|
|
805
|
-
|
|
806
|
-
const
|
|
807
|
-
const
|
|
808
|
-
|
|
805
|
+
const currentTime = Date.parse(current?.updated_at || "");
|
|
806
|
+
const incomingTime = Date.parse(incoming.updated_at || "");
|
|
807
|
+
const newest = current && Number.isFinite(currentTime) && Number.isFinite(incomingTime) && currentTime > incomingTime ? current : incoming;
|
|
808
|
+
if (current?.last_run_id && current.last_run_id === incoming.last_run_id && !current.active_run && ["completed", "failed", "cancelled"].includes(current.last_run_status || "") && (!incoming.active_run || incoming.active_run.run_id === current.last_run_id)) {
|
|
809
|
+
return { ...newest, active_run: null, last_run_status: current.last_run_status };
|
|
810
|
+
}
|
|
811
|
+
return newest;
|
|
809
812
|
}
|
|
810
813
|
function adoptStreamingThread(state, threadId) {
|
|
811
814
|
const normalizedThreadId = threadId.trim();
|
|
@@ -846,7 +849,23 @@ function reconcileThreadTimeline(current, canonical, activeRunId, streamingMessa
|
|
|
846
849
|
const live = current.find((item) => item.id === message.id);
|
|
847
850
|
return activeRunId && live?.role === "assistant" && live.runId === activeRunId && (live.id === streamingMessageId || !live.isFinal || live.responseCompletion) ? message.responseCompletion && !live.responseCompletion ? { ...message, id: live.id, durableId: message.durableId || live.durableId } : { ...message, ...live, feedback: message.feedback, durableId: message.durableId || live.durableId } : message;
|
|
848
851
|
});
|
|
849
|
-
|
|
852
|
+
const retainedIds = new Set(retained.map((message) => message.id));
|
|
853
|
+
const userByRun = new Map(reconciled.filter((message) => message.role === "user").map((message) => [message.runId, message.id]));
|
|
854
|
+
const after = /* @__PURE__ */ new Map();
|
|
855
|
+
let anchor = null;
|
|
856
|
+
let anchorRun;
|
|
857
|
+
for (const message of current) {
|
|
858
|
+
if (canonicalIds.has(message.id)) {
|
|
859
|
+
anchor = message.id;
|
|
860
|
+
anchorRun = message.runId;
|
|
861
|
+
} else if (retainedIds.has(message.id)) {
|
|
862
|
+
const position = message.role === "assistant" && message.runId && message.runId !== anchorRun ? userByRun.get(message.runId) ?? anchor : anchor;
|
|
863
|
+
const group = after.get(position) || [];
|
|
864
|
+
group.push(message);
|
|
865
|
+
after.set(position, group);
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
return [...after.get(null) || [], ...reconciled.flatMap((message) => [message, ...after.get(message.id) || []])];
|
|
850
869
|
}
|
|
851
870
|
function prependThreadTimeline(current, older) {
|
|
852
871
|
const mounted = preserveMountedMessageIds(older, current);
|
|
@@ -1008,11 +1027,13 @@ function applyRuntimeEvent(state, event) {
|
|
|
1008
1027
|
...segment ? { durableId: segment.message_id } : {}
|
|
1009
1028
|
};
|
|
1010
1029
|
});
|
|
1030
|
+
const terminalThread = terminal ? { active_run: null, last_run_status: eventName.slice(4) } : {};
|
|
1011
1031
|
const threads = activeThreadId ? state.threads.some((thread) => thread.id === activeThreadId) ? state.threads.map((thread) => thread.id === activeThreadId ? {
|
|
1012
1032
|
...thread,
|
|
1013
1033
|
messages,
|
|
1014
1034
|
isHydrated: true,
|
|
1015
|
-
last_run_id: runId ?? thread.last_run_id,
|
|
1035
|
+
last_run_id: terminal && thread.active_run && thread.active_run.run_id !== runId ? thread.last_run_id : runId ?? thread.last_run_id,
|
|
1036
|
+
...!thread.active_run || thread.active_run.run_id === runId ? terminalThread : {},
|
|
1016
1037
|
contextWindow,
|
|
1017
1038
|
contextCompression
|
|
1018
1039
|
} : thread) : [{
|
|
@@ -1023,6 +1044,7 @@ function applyRuntimeEvent(state, event) {
|
|
|
1023
1044
|
messages,
|
|
1024
1045
|
isHydrated: true,
|
|
1025
1046
|
last_run_id: runId,
|
|
1047
|
+
...terminalThread,
|
|
1026
1048
|
contextWindow,
|
|
1027
1049
|
contextCompression
|
|
1028
1050
|
}, ...state.threads] : state.threads;
|
|
@@ -1098,12 +1120,14 @@ function useThreadMessageQueue({ threadId, transport, onPromoted, onUnknownPromo
|
|
|
1098
1120
|
const [pendingMessages, setPendingMessages] = React3.useState([]);
|
|
1099
1121
|
const [messageQueue, setMessageQueue] = React3.useState(null);
|
|
1100
1122
|
const pendingRef = React3.useRef(/* @__PURE__ */ new Map());
|
|
1123
|
+
const admissionRef = React3.useRef(null);
|
|
1124
|
+
const initialAdmissionRef = React3.useRef(null);
|
|
1101
1125
|
const versionRef = React3.useRef(0);
|
|
1102
1126
|
const cursorRef = React3.useRef(0);
|
|
1103
1127
|
const promotedRef = React3.useRef(/* @__PURE__ */ new Set());
|
|
1104
1128
|
const threadRef = React3.useRef(threadId);
|
|
1105
1129
|
const selectionGenerationRef = React3.useRef(0);
|
|
1106
|
-
if (threadRef.current !== threadId) selectionGenerationRef.current += 1;
|
|
1130
|
+
if (threadRef.current !== threadId && initialAdmissionRef.current?.threadId !== threadId) selectionGenerationRef.current += 1;
|
|
1107
1131
|
const transportRef = React3.useRef(transport);
|
|
1108
1132
|
const onPromotedRef = React3.useRef(onPromoted);
|
|
1109
1133
|
threadRef.current = threadId;
|
|
@@ -1113,10 +1137,16 @@ function useThreadMessageQueue({ threadId, transport, onPromoted, onUnknownPromo
|
|
|
1113
1137
|
ownSelectionRef.current = ownSelection;
|
|
1114
1138
|
const callbacksRef = React3.useRef({ onOptimistic, onDiscard, onUnknownPromotion });
|
|
1115
1139
|
callbacksRef.current = { onOptimistic, onDiscard, onUnknownPromotion };
|
|
1116
|
-
const ownOperation = React3.useCallback(() => ownSelectionRef.current?.() ?? captureChatOperation(() => ({
|
|
1140
|
+
const ownOperation = React3.useCallback((options) => ownSelectionRef.current?.(options) ?? captureChatOperation(() => ({
|
|
1117
1141
|
generation: selectionGenerationRef.current,
|
|
1118
1142
|
threadId: threadRef.current
|
|
1119
|
-
})), []);
|
|
1143
|
+
}), options), []);
|
|
1144
|
+
const confirmThreadAdmission = React3.useCallback((admittedThreadId) => {
|
|
1145
|
+
const initial = initialAdmissionRef.current;
|
|
1146
|
+
if (!initial || !initial.isCurrent()) return;
|
|
1147
|
+
initial.threadId = admittedThreadId;
|
|
1148
|
+
initial.resolve(admittedThreadId);
|
|
1149
|
+
}, []);
|
|
1120
1150
|
const assertCurrent = (isCurrent) => {
|
|
1121
1151
|
if (!isCurrent()) throw Object.assign(new Error("Thread selection changed."), { name: "AbortError" });
|
|
1122
1152
|
};
|
|
@@ -1195,12 +1225,24 @@ function useThreadMessageQueue({ threadId, transport, onPromoted, onUnknownPromo
|
|
|
1195
1225
|
updated_at: now
|
|
1196
1226
|
};
|
|
1197
1227
|
pendingRef.current.set(message.id, { ...message, optimisticQueued: queued });
|
|
1228
|
+
if (!queued && !threadRef.current && !initialAdmissionRef.current) {
|
|
1229
|
+
let resolve;
|
|
1230
|
+
const done = new Promise((callback) => {
|
|
1231
|
+
resolve = callback;
|
|
1232
|
+
});
|
|
1233
|
+
initialAdmissionRef.current = { id: message.id, done, resolve, isCurrent: ownOperation({ adoptThread: true }) };
|
|
1234
|
+
}
|
|
1198
1235
|
versionRef.current += 1;
|
|
1199
1236
|
if (queued) setPendingMessages((current) => [...current, message]);
|
|
1200
1237
|
else callbacksRef.current.onOptimistic?.(message, Boolean(input.uploading));
|
|
1201
1238
|
return message;
|
|
1202
|
-
}, []);
|
|
1203
|
-
const discardSubmission = React3.useCallback((message) => {
|
|
1239
|
+
}, [ownOperation]);
|
|
1240
|
+
const discardSubmission = React3.useCallback((message, failure) => {
|
|
1241
|
+
if (initialAdmissionRef.current?.id === message.id) {
|
|
1242
|
+
initialAdmissionRef.current.failure = failure;
|
|
1243
|
+
initialAdmissionRef.current.resolve(null);
|
|
1244
|
+
initialAdmissionRef.current = null;
|
|
1245
|
+
}
|
|
1204
1246
|
if (!pendingRef.current.has(message.id)) return;
|
|
1205
1247
|
pendingRef.current.delete(message.id);
|
|
1206
1248
|
callbacksRef.current.onDiscard?.(message);
|
|
@@ -1208,19 +1250,31 @@ function useThreadMessageQueue({ threadId, transport, onPromoted, onUnknownPromo
|
|
|
1208
1250
|
setPendingMessages((current) => current.filter((item) => item.client_submission_id !== message.client_submission_id));
|
|
1209
1251
|
}, []);
|
|
1210
1252
|
const submit = React3.useCallback(async (input) => {
|
|
1211
|
-
const
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
const
|
|
1253
|
+
const initial = !threadRef.current ? initialAdmissionRef.current : null;
|
|
1254
|
+
let selectedThreadId = threadRef.current;
|
|
1255
|
+
if (!selectedThreadId && !initial) throw new Error("No active Agent thread is available.");
|
|
1256
|
+
const isCurrent = ownOperation({ adoptThread: Boolean(initial) });
|
|
1257
|
+
const { queued: requestedQueued, prepare, attachments, uploading, ...submission } = input;
|
|
1258
|
+
const priorAdmission = admissionRef.current?.threadId === (selectedThreadId || "") ? admissionRef.current.done : void 0;
|
|
1259
|
+
const queued = Boolean(requestedQueued || priorAdmission || initial);
|
|
1215
1260
|
const optimistic = beginSubmission({
|
|
1216
1261
|
...submission,
|
|
1217
1262
|
attachments,
|
|
1218
1263
|
uploading,
|
|
1219
1264
|
clientSubmissionId: submission.clientSubmissionId || submission.idempotencyKey
|
|
1220
1265
|
}, queued);
|
|
1266
|
+
let releaseAdmission;
|
|
1267
|
+
const admission = { threadId: selectedThreadId || "", done: new Promise((resolve) => {
|
|
1268
|
+
releaseAdmission = resolve;
|
|
1269
|
+
}) };
|
|
1270
|
+
admissionRef.current = admission;
|
|
1221
1271
|
try {
|
|
1222
1272
|
const prepared = prepare ? await prepare() : {};
|
|
1273
|
+
if (initial) selectedThreadId = await initial.done;
|
|
1274
|
+
if (priorAdmission) await priorAdmission;
|
|
1223
1275
|
assertCurrent(isCurrent);
|
|
1276
|
+
if (!selectedThreadId) throw Object.assign(new Error("Initial message admission did not complete."), { name: "AbortError" });
|
|
1277
|
+
admission.threadId = selectedThreadId;
|
|
1224
1278
|
pendingRef.current.set(optimistic.id, { ...optimistic, optimisticQueued: queued, attachment_ids: prepared.attachmentIds || optimistic.attachment_ids, attachments: prepared.attachments || attachments });
|
|
1225
1279
|
const request = { ...submission, ...prepared, clientSubmissionId: optimistic.client_submission_id, threadId: selectedThreadId };
|
|
1226
1280
|
const result = await retrySubmissionAdmission(() => transportRef.current.submit(request));
|
|
@@ -1253,6 +1307,11 @@ function useThreadMessageQueue({ threadId, transport, onPromoted, onUnknownPromo
|
|
|
1253
1307
|
} catch (error) {
|
|
1254
1308
|
if (isCurrent()) discardSubmission(optimistic);
|
|
1255
1309
|
throw error;
|
|
1310
|
+
} finally {
|
|
1311
|
+
void Promise.resolve(priorAdmission).then(() => {
|
|
1312
|
+
releaseAdmission();
|
|
1313
|
+
if (admissionRef.current === admission) admissionRef.current = null;
|
|
1314
|
+
});
|
|
1256
1315
|
}
|
|
1257
1316
|
}, [beginSubmission, discardSubmission, refresh, ownOperation]);
|
|
1258
1317
|
const edit = React3.useCallback(async (message, input) => {
|
|
@@ -1288,16 +1347,63 @@ function useThreadMessageQueue({ threadId, transport, onPromoted, onUnknownPromo
|
|
|
1288
1347
|
await refresh(selectedThreadId);
|
|
1289
1348
|
return result;
|
|
1290
1349
|
}, [refresh, ownOperation]);
|
|
1291
|
-
React3.
|
|
1350
|
+
const reset = React3.useCallback(() => {
|
|
1351
|
+
initialAdmissionRef.current?.resolve(null);
|
|
1352
|
+
initialAdmissionRef.current = null;
|
|
1353
|
+
admissionRef.current = null;
|
|
1354
|
+
selectionGenerationRef.current += 1;
|
|
1292
1355
|
versionRef.current += 1;
|
|
1293
1356
|
cursorRef.current = 0;
|
|
1294
1357
|
promotedRef.current.clear();
|
|
1295
1358
|
pendingRef.current.clear();
|
|
1296
1359
|
setPendingMessages([]);
|
|
1297
1360
|
setMessageQueue(null);
|
|
1361
|
+
}, []);
|
|
1362
|
+
React3.useEffect(() => {
|
|
1363
|
+
const initial = initialAdmissionRef.current;
|
|
1364
|
+
const adopting = Boolean(initial?.threadId && initial.threadId === threadId && initial.isCurrent());
|
|
1365
|
+
if (adopting) {
|
|
1366
|
+
for (const [id, message] of pendingRef.current) pendingRef.current.set(id, { ...message, thread_id: threadId });
|
|
1367
|
+
initialAdmissionRef.current = null;
|
|
1368
|
+
} else {
|
|
1369
|
+
initial?.resolve(null);
|
|
1370
|
+
initialAdmissionRef.current = null;
|
|
1371
|
+
pendingRef.current.clear();
|
|
1372
|
+
setPendingMessages([]);
|
|
1373
|
+
}
|
|
1374
|
+
versionRef.current += 1;
|
|
1375
|
+
cursorRef.current = 0;
|
|
1376
|
+
promotedRef.current.clear();
|
|
1377
|
+
setMessageQueue(null);
|
|
1298
1378
|
if (threadId) void refresh(threadId).catch(() => void 0);
|
|
1379
|
+
return () => {
|
|
1380
|
+
initialAdmissionRef.current?.resolve(null);
|
|
1381
|
+
};
|
|
1299
1382
|
}, [threadId, refresh]);
|
|
1300
|
-
return {
|
|
1383
|
+
return {
|
|
1384
|
+
pendingMessages,
|
|
1385
|
+
messageQueue,
|
|
1386
|
+
refresh,
|
|
1387
|
+
hydrate,
|
|
1388
|
+
acceptNotice,
|
|
1389
|
+
beginSubmission,
|
|
1390
|
+
discardSubmission,
|
|
1391
|
+
reset,
|
|
1392
|
+
confirmThreadAdmission,
|
|
1393
|
+
hasPendingAdmission: () => Boolean(initialAdmissionRef.current?.isCurrent()),
|
|
1394
|
+
waitForInitialAdmission: () => {
|
|
1395
|
+
const initial = initialAdmissionRef.current;
|
|
1396
|
+
return initial ? initial.done.then((threadId2) => {
|
|
1397
|
+
if (!threadId2) throw initial.failure || Object.assign(new Error("Initial message admission detached."), { name: "AbortError" });
|
|
1398
|
+
return threadId2;
|
|
1399
|
+
}) : Promise.resolve(threadRef.current);
|
|
1400
|
+
},
|
|
1401
|
+
submit,
|
|
1402
|
+
edit,
|
|
1403
|
+
remove,
|
|
1404
|
+
retractForEdit,
|
|
1405
|
+
resume
|
|
1406
|
+
};
|
|
1301
1407
|
}
|
|
1302
1408
|
function optimisticSubmissionTurn(message) {
|
|
1303
1409
|
const user = {
|
|
@@ -1573,8 +1679,6 @@ function useAgentChat(options = {}) {
|
|
|
1573
1679
|
const promotedAttachRef = React7.useRef(null);
|
|
1574
1680
|
const olderRequestRef = React7.useRef(null);
|
|
1575
1681
|
const submissionGenerationRef = React7.useRef(0);
|
|
1576
|
-
const firstSubmissionRef = React7.useRef(null);
|
|
1577
|
-
const firstSubmissionAdmittedRef = React7.useRef(null);
|
|
1578
1682
|
const stateRef = React7.useRef(state);
|
|
1579
1683
|
stateRef.current = state;
|
|
1580
1684
|
const ownOperation = React7.useCallback((options2) => captureChatOperation(() => ({
|
|
@@ -1669,12 +1773,11 @@ function useAgentChat(options = {}) {
|
|
|
1669
1773
|
promotedAttachRef.current = null;
|
|
1670
1774
|
promotedRunHintRef.current = null;
|
|
1671
1775
|
olderRequestRef.current = null;
|
|
1672
|
-
|
|
1673
|
-
firstSubmissionAdmittedRef.current = null;
|
|
1776
|
+
queue.reset();
|
|
1674
1777
|
setIsSubmitting(false);
|
|
1675
1778
|
setIsLoadingOlder(false);
|
|
1676
1779
|
setIsLoadingHistory(false);
|
|
1677
|
-
}, []);
|
|
1780
|
+
}, [queue.reset]);
|
|
1678
1781
|
const detach = React7.useCallback(() => {
|
|
1679
1782
|
eventBuffer.flush();
|
|
1680
1783
|
streamControllerRef.current?.abort();
|
|
@@ -1794,12 +1897,12 @@ function useAgentChat(options = {}) {
|
|
|
1794
1897
|
const consumeEvent = React7.useCallback((event) => {
|
|
1795
1898
|
const eventThreadId = typeof event.payload?.thread_id === "string" ? event.payload.thread_id.trim() : "";
|
|
1796
1899
|
if (eventThreadId && !stateRef.current.activeThreadId) {
|
|
1900
|
+
queue.confirmThreadAdmission(eventThreadId);
|
|
1797
1901
|
update((current) => adoptStreamingThread(current, eventThreadId));
|
|
1798
1902
|
setIsSubmitting(false);
|
|
1799
|
-
firstSubmissionAdmittedRef.current?.();
|
|
1800
1903
|
}
|
|
1801
1904
|
eventBuffer.push(event);
|
|
1802
|
-
}, [eventBuffer, update]);
|
|
1905
|
+
}, [eventBuffer, update, queue.confirmThreadAdmission]);
|
|
1803
1906
|
const attachRun = React7.useCallback(async (runId, cursor) => {
|
|
1804
1907
|
eventBuffer.flush();
|
|
1805
1908
|
streamControllerRef.current?.abort();
|
|
@@ -1829,12 +1932,9 @@ function useAgentChat(options = {}) {
|
|
|
1829
1932
|
attachRunRef.current = attachRun;
|
|
1830
1933
|
const submit = React7.useCallback(async (input) => {
|
|
1831
1934
|
if (!input.text.trim() && !input.attachmentIds?.length && !input.uploads?.length) return;
|
|
1832
|
-
if (firstSubmissionRef.current && !stateRef.current.activeThreadId) {
|
|
1833
|
-
await firstSubmissionRef.current;
|
|
1834
|
-
}
|
|
1835
1935
|
const existingThreadId = stateRef.current.activeThreadId;
|
|
1836
|
-
if (existingThreadId) {
|
|
1837
|
-
const isCurrent = ownOperation();
|
|
1936
|
+
if (existingThreadId || queue.hasPendingAdmission()) {
|
|
1937
|
+
const isCurrent = ownOperation({ adoptThread: !existingThreadId });
|
|
1838
1938
|
const submissionGeneration = ++submissionGenerationRef.current;
|
|
1839
1939
|
clearOperationError();
|
|
1840
1940
|
setIsSubmitting(true);
|
|
@@ -1863,7 +1963,7 @@ function useAgentChat(options = {}) {
|
|
|
1863
1963
|
prepare: async () => {
|
|
1864
1964
|
const uploaded = input.uploads?.length ? await client.attachments.uploadBatch({
|
|
1865
1965
|
uploads: input.uploads,
|
|
1866
|
-
threadId: existingThreadId,
|
|
1966
|
+
threadId: existingThreadId || void 0,
|
|
1867
1967
|
requestedAgentId: input.requestedAgentId,
|
|
1868
1968
|
idempotencyKey: runtime.createId()
|
|
1869
1969
|
}) : [];
|
|
@@ -1888,9 +1988,7 @@ function useAgentChat(options = {}) {
|
|
|
1888
1988
|
return;
|
|
1889
1989
|
}
|
|
1890
1990
|
invalidateThreadOpen();
|
|
1891
|
-
const
|
|
1892
|
-
firstSubmissionAdmittedRef.current = resolve;
|
|
1893
|
-
});
|
|
1991
|
+
const submissionOwner = ownOperation({ adoptThread: true });
|
|
1894
1992
|
const stream = (async () => {
|
|
1895
1993
|
detach();
|
|
1896
1994
|
const controller = runtime.createAbortController();
|
|
@@ -1971,7 +2069,7 @@ function useAgentChat(options = {}) {
|
|
|
1971
2069
|
} catch (error) {
|
|
1972
2070
|
if (!isCurrent()) return;
|
|
1973
2071
|
const admitted = Boolean(stateRef.current.messages.find((message) => message.id === userId)?.runId);
|
|
1974
|
-
if (!admitted) queue.discardSubmission(ticket);
|
|
2072
|
+
if (!admitted) queue.discardSubmission(ticket, error);
|
|
1975
2073
|
if (!isAbortLike(error)) {
|
|
1976
2074
|
update((current) => ({
|
|
1977
2075
|
...current,
|
|
@@ -1982,19 +2080,15 @@ function useAgentChat(options = {}) {
|
|
|
1982
2080
|
throw error;
|
|
1983
2081
|
}
|
|
1984
2082
|
} finally {
|
|
2083
|
+
if (!stateRef.current.messages.some((message) => (message.id === ticket.id || message.clientSubmissionId === ticket.client_submission_id) && message.runId)) queue.discardSubmission(ticket);
|
|
1985
2084
|
if (isCurrent() && submissionGeneration === submissionGenerationRef.current) setIsSubmitting(false);
|
|
1986
2085
|
if (streamControllerRef.current === controller) streamControllerRef.current = null;
|
|
1987
2086
|
}
|
|
1988
2087
|
})();
|
|
1989
|
-
const accepted = Promise.race([stream, admission]);
|
|
1990
|
-
firstSubmissionRef.current = accepted;
|
|
1991
2088
|
try {
|
|
1992
|
-
await
|
|
1993
|
-
}
|
|
1994
|
-
if (
|
|
1995
|
-
firstSubmissionRef.current = null;
|
|
1996
|
-
firstSubmissionAdmittedRef.current = null;
|
|
1997
|
-
}
|
|
2089
|
+
await Promise.race([stream, queue.waitForInitialAdmission()]);
|
|
2090
|
+
} catch (error) {
|
|
2091
|
+
if (submissionOwner() || !isAbortLike(error)) throw error;
|
|
1998
2092
|
}
|
|
1999
2093
|
}, [clearOperationError, client, consumeEvent, detach, eventBuffer, failOperation, invalidateThreadOpen, queue.submit, refreshMessages, refreshThreads, runtime, update, ownOperation]);
|
|
2000
2094
|
const { steer, editPendingMessage, steerPendingMessage, removePendingMessage, resumeQueue } = useAgentChatQueueActions({
|