@anuma/sdk 10.2.2 → 10.2.4
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/expo/{chunk-WRZTH4OS.mjs → chunk-ZIN4E7MR.mjs} +7 -0
- package/dist/expo/{consolidate-HKL5EGZT.mjs → consolidate-4WLZMXOS.mjs} +1 -1
- package/dist/expo/index.cjs +260 -113
- package/dist/expo/index.d.mts +3 -0
- package/dist/expo/index.d.ts +3 -0
- package/dist/expo/index.mjs +228 -89
- package/dist/index.cjs +7 -0
- package/dist/index.d.mts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.mjs +7 -0
- package/dist/react/{chunk-RSA3S6OA.mjs → chunk-7JYVPYGQ.mjs} +7 -0
- package/dist/react/{consolidate-WFTPBHDV.mjs → consolidate-3RQL75PJ.mjs} +1 -1
- package/dist/react/index.cjs +566 -419
- package/dist/react/index.d.mts +3 -0
- package/dist/react/index.d.ts +3 -0
- package/dist/react/index.mjs +418 -279
- package/dist/server/{chunk-QEROZ4VH.mjs → chunk-QK62YWBH.mjs} +7 -0
- package/dist/server/{consolidate-PYED62LW.mjs → consolidate-NW4UVA6T.mjs} +1 -1
- package/dist/server/index.cjs +67 -10
- package/dist/server/index.d.mts +3 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.mjs +62 -12
- package/package.json +1 -1
package/dist/expo/index.mjs
CHANGED
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
taskTypeHeader,
|
|
21
21
|
validateEndpointOverride,
|
|
22
22
|
withInternalFlowMarker
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-ZIN4E7MR.mjs";
|
|
24
24
|
import {
|
|
25
25
|
BASE_URL,
|
|
26
26
|
MCP_R2_DOMAIN,
|
|
@@ -1054,12 +1054,12 @@ async function persistKeyPair(address, startEpoch) {
|
|
|
1054
1054
|
const combined = new Uint8Array(iv.length + encryptedBytes.length);
|
|
1055
1055
|
combined.set(iv, 0);
|
|
1056
1056
|
combined.set(encryptedBytes, iv.length);
|
|
1057
|
-
const
|
|
1057
|
+
const storageKey2 = `${KEYPAIR_STORAGE_PREFIX}${address}`;
|
|
1058
1058
|
const encryptedHex = bytesToHex(combined);
|
|
1059
1059
|
if (sessionEpoch !== startEpoch) {
|
|
1060
1060
|
return;
|
|
1061
1061
|
}
|
|
1062
|
-
localStorage.setItem(
|
|
1062
|
+
localStorage.setItem(storageKey2, encryptedHex);
|
|
1063
1063
|
} catch (err) {
|
|
1064
1064
|
throw new Error(
|
|
1065
1065
|
`Failed to persist keypair: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -1070,8 +1070,8 @@ async function loadPersistedKeyPair(address) {
|
|
|
1070
1070
|
if (typeof window === "undefined") {
|
|
1071
1071
|
return null;
|
|
1072
1072
|
}
|
|
1073
|
-
const
|
|
1074
|
-
const encryptedHex = localStorage.getItem(
|
|
1073
|
+
const storageKey2 = `${KEYPAIR_STORAGE_PREFIX}${address}`;
|
|
1074
|
+
const encryptedHex = localStorage.getItem(storageKey2);
|
|
1075
1075
|
if (!encryptedHex) {
|
|
1076
1076
|
return null;
|
|
1077
1077
|
}
|
|
@@ -1122,7 +1122,7 @@ async function loadPersistedKeyPair(address) {
|
|
|
1122
1122
|
publicKey
|
|
1123
1123
|
};
|
|
1124
1124
|
} catch (error) {
|
|
1125
|
-
localStorage.removeItem(
|
|
1125
|
+
localStorage.removeItem(storageKey2);
|
|
1126
1126
|
getLogger().warn(
|
|
1127
1127
|
`Failed to load persisted keypair for ${address}: ${error instanceof Error ? error.message : String(error)}`
|
|
1128
1128
|
);
|
|
@@ -1133,8 +1133,8 @@ function clearPersistedKeyPair(address) {
|
|
|
1133
1133
|
if (typeof window === "undefined") {
|
|
1134
1134
|
return;
|
|
1135
1135
|
}
|
|
1136
|
-
const
|
|
1137
|
-
localStorage.removeItem(
|
|
1136
|
+
const storageKey2 = `${KEYPAIR_STORAGE_PREFIX}${address}`;
|
|
1137
|
+
localStorage.removeItem(storageKey2);
|
|
1138
1138
|
}
|
|
1139
1139
|
async function getKeyPair(address, signMessage, embeddedWalletSigner) {
|
|
1140
1140
|
const existingKeyPair = getStoredKeyPair(address);
|
|
@@ -7948,6 +7948,9 @@ var StreamSmoother = class {
|
|
|
7948
7948
|
this.rampDuration = config.rampDuration ?? 4e3;
|
|
7949
7949
|
}
|
|
7950
7950
|
}
|
|
7951
|
+
get hasPendingOutput() {
|
|
7952
|
+
return this.buffer.length > 0;
|
|
7953
|
+
}
|
|
7951
7954
|
/**
|
|
7952
7955
|
* Add text to the buffer. If smoothing is disabled, passes through immediately.
|
|
7953
7956
|
*/
|
|
@@ -8616,6 +8619,34 @@ async function runToolLoop(options) {
|
|
|
8616
8619
|
toolsChecksum: acc.toolsChecksum
|
|
8617
8620
|
};
|
|
8618
8621
|
};
|
|
8622
|
+
const drainSmoothers = async (acc, smoothers) => {
|
|
8623
|
+
let playbackAborted = false;
|
|
8624
|
+
const stopPlayback = () => {
|
|
8625
|
+
for (const smoother of smoothers) {
|
|
8626
|
+
if (isDetach()) smoother.flush();
|
|
8627
|
+
else smoother.destroy();
|
|
8628
|
+
}
|
|
8629
|
+
};
|
|
8630
|
+
const onAbort = () => {
|
|
8631
|
+
playbackAborted = !isDetach() && smoothers.some((smoother) => smoother.hasPendingOutput);
|
|
8632
|
+
stopPlayback();
|
|
8633
|
+
};
|
|
8634
|
+
combinedSignal?.addEventListener("abort", onAbort, { once: true });
|
|
8635
|
+
try {
|
|
8636
|
+
if (combinedSignal?.aborted) stopPlayback();
|
|
8637
|
+
await Promise.all(smoothers.map((smoother) => smoother.drain()));
|
|
8638
|
+
if (!playbackAborted) return;
|
|
8639
|
+
await fireAfterModelCall(buildModelCallEndPayload(acc, { error: "aborted" }));
|
|
8640
|
+
await fireRunError({ error: "Request aborted", stage: "model" });
|
|
8641
|
+
return {
|
|
8642
|
+
data: buildResponseFinal(acc),
|
|
8643
|
+
error: "Request aborted",
|
|
8644
|
+
toolsChecksum: acc.toolsChecksum
|
|
8645
|
+
};
|
|
8646
|
+
} finally {
|
|
8647
|
+
combinedSignal?.removeEventListener("abort", onAbort);
|
|
8648
|
+
}
|
|
8649
|
+
};
|
|
8619
8650
|
for (let attempt = 0; attempt < STREAM_RETRY_MAX_ATTEMPTS; attempt++) {
|
|
8620
8651
|
sseError = null;
|
|
8621
8652
|
if (combinedSignal?.aborted) {
|
|
@@ -8753,7 +8784,8 @@ async function runToolLoop(options) {
|
|
|
8753
8784
|
contentSmoother.flush();
|
|
8754
8785
|
thinkingSmoother.flush();
|
|
8755
8786
|
} else {
|
|
8756
|
-
await
|
|
8787
|
+
const interrupted = await drainSmoothers(accumulator, [contentSmoother, thinkingSmoother]);
|
|
8788
|
+
if (interrupted) return interrupted;
|
|
8757
8789
|
}
|
|
8758
8790
|
flushDeAnon();
|
|
8759
8791
|
await fireAfterModelCall(buildModelCallEndPayload(accumulator));
|
|
@@ -9272,7 +9304,11 @@ Executing tool: ${toolInfo}
|
|
|
9272
9304
|
contContentSmoother.flush();
|
|
9273
9305
|
contThinkingSmoother.flush();
|
|
9274
9306
|
} else {
|
|
9275
|
-
await
|
|
9307
|
+
const interrupted = await drainSmoothers(currentAccumulator, [
|
|
9308
|
+
contContentSmoother,
|
|
9309
|
+
contThinkingSmoother
|
|
9310
|
+
]);
|
|
9311
|
+
if (interrupted) return interrupted;
|
|
9276
9312
|
}
|
|
9277
9313
|
flushDeAnon();
|
|
9278
9314
|
await fireAfterModelCall(buildModelCallEndPayload(currentAccumulator));
|
|
@@ -9403,6 +9439,8 @@ async function resumeStream(options) {
|
|
|
9403
9439
|
let watchdog;
|
|
9404
9440
|
let idleFired = false;
|
|
9405
9441
|
let callerAborted = false;
|
|
9442
|
+
let playbackAborted = false;
|
|
9443
|
+
let draining = false;
|
|
9406
9444
|
let settled = false;
|
|
9407
9445
|
const idleEnabled = idleTimeoutMs > 0 && idleTimeoutMs !== Infinity && typeof setTimeout === "function";
|
|
9408
9446
|
const armWatchdog = () => {
|
|
@@ -9422,6 +9460,9 @@ async function resumeStream(options) {
|
|
|
9422
9460
|
const abortMessage = () => callerAborted ? "Resume aborted" : idleFired ? "Resume timed out" : "Resume aborted";
|
|
9423
9461
|
const onCallerAbort = () => {
|
|
9424
9462
|
callerAborted = true;
|
|
9463
|
+
playbackAborted = draining && (contentSmoother.hasPendingOutput || thinkingSmoother.hasPendingOutput);
|
|
9464
|
+
contentSmoother.destroy();
|
|
9465
|
+
thinkingSmoother.destroy();
|
|
9425
9466
|
disarmWatchdog();
|
|
9426
9467
|
idleController.abort();
|
|
9427
9468
|
};
|
|
@@ -9505,15 +9546,24 @@ async function resumeStream(options) {
|
|
|
9505
9546
|
statusCode
|
|
9506
9547
|
};
|
|
9507
9548
|
}
|
|
9508
|
-
|
|
9509
|
-
|
|
9510
|
-
|
|
9549
|
+
settled = true;
|
|
9550
|
+
disarmWatchdog();
|
|
9551
|
+
try {
|
|
9552
|
+
if (idleFired) return buildInterrupted(abortMessage());
|
|
9553
|
+
if (accumulator.toolCalls.size > 0) {
|
|
9554
|
+
return buildInterrupted("Stream ended with a pending tool request");
|
|
9555
|
+
}
|
|
9556
|
+
draining = true;
|
|
9557
|
+
await Promise.all([contentSmoother.drain(), thinkingSmoother.drain()]);
|
|
9558
|
+
if (playbackAborted) return buildInterrupted(abortMessage());
|
|
9559
|
+
const response = strategy.buildFinalResponse(accumulator);
|
|
9560
|
+
const deliveredOutput = emittedOutput || (accumulator.toolCallEvents?.length ?? 0) > 0;
|
|
9561
|
+
if (onFinish && deliveredOutput) onFinish(response);
|
|
9562
|
+
return { data: response, error: null, interrupted: false, empty: !deliveredOutput };
|
|
9563
|
+
} finally {
|
|
9564
|
+
draining = false;
|
|
9565
|
+
cleanup();
|
|
9511
9566
|
}
|
|
9512
|
-
await Promise.all([contentSmoother.drain(), thinkingSmoother.drain()]);
|
|
9513
|
-
const response = strategy.buildFinalResponse(accumulator);
|
|
9514
|
-
const deliveredOutput = emittedOutput || (accumulator.toolCallEvents?.length ?? 0) > 0;
|
|
9515
|
-
if (onFinish && deliveredOutput) onFinish(response);
|
|
9516
|
-
return { data: response, error: null, interrupted: false, empty: !deliveredOutput };
|
|
9517
9567
|
}
|
|
9518
9568
|
|
|
9519
9569
|
// src/lib/chat/stockPriceCentroids.ts
|
|
@@ -17868,11 +17918,11 @@ function loadVaultCorpus(ctx, options, preparation) {
|
|
|
17868
17918
|
}
|
|
17869
17919
|
return request;
|
|
17870
17920
|
}
|
|
17871
|
-
function rowRequestsFor(
|
|
17872
|
-
let byMask =
|
|
17921
|
+
function rowRequestsFor(registry3, ctx, maskInput) {
|
|
17922
|
+
let byMask = registry3.get(ctx);
|
|
17873
17923
|
if (!byMask) {
|
|
17874
17924
|
byMask = /* @__PURE__ */ new Map();
|
|
17875
|
-
|
|
17925
|
+
registry3.set(ctx, byMask);
|
|
17876
17926
|
}
|
|
17877
17927
|
let requests = byMask.get(maskInput);
|
|
17878
17928
|
if (!requests) {
|
|
@@ -18807,11 +18857,11 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
|
|
|
18807
18857
|
};
|
|
18808
18858
|
}
|
|
18809
18859
|
const limit = searchOptions?.limit ?? 5;
|
|
18810
|
-
const
|
|
18860
|
+
const scopes2 = searchOptions?.scopes;
|
|
18811
18861
|
const folderId = searchOptions?.folderId;
|
|
18812
18862
|
const queryOpts = {};
|
|
18813
18863
|
if (searchOptions?.memoryIds !== void 0) queryOpts.memoryIds = searchOptions.memoryIds;
|
|
18814
|
-
if (
|
|
18864
|
+
if (scopes2?.length) queryOpts.scopes = scopes2;
|
|
18815
18865
|
if (folderId !== void 0) queryOpts.folderId = folderId;
|
|
18816
18866
|
if (searchOptions?.factTypes?.length) queryOpts.factTypes = searchOptions.factTypes;
|
|
18817
18867
|
if (searchOptions?.includeArchived) queryOpts.includeArchived = true;
|
|
@@ -19589,7 +19639,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
19589
19639
|
content: m.content,
|
|
19590
19640
|
similarity: m.similarity
|
|
19591
19641
|
}));
|
|
19592
|
-
const { consolidateMemory: doConsolidate } = await import("./consolidate-
|
|
19642
|
+
const { consolidateMemory: doConsolidate } = await import("./consolidate-4WLZMXOS.mjs");
|
|
19593
19643
|
const decision = await doConsolidate(trimmed, candidates, consolidateOptions);
|
|
19594
19644
|
if (decision.action === "create") return decision.fallbackReason ? null : { create: true };
|
|
19595
19645
|
if (decision.action === "supersede" && decision.content) {
|
|
@@ -25068,17 +25118,17 @@ async function synthesizeProfile(ctx, options = {}) {
|
|
|
25068
25118
|
}
|
|
25069
25119
|
const recallCtx = store ? { embeddingOptions: ctx.embeddingOptions, factSource: store.factSource } : ctx;
|
|
25070
25120
|
const facets = options.facets ?? DEFAULT_PROFILE_FACETS;
|
|
25071
|
-
const
|
|
25121
|
+
const scopes2 = options.scopes ?? DEFAULT_SCOPES;
|
|
25072
25122
|
const config = {
|
|
25073
25123
|
facetKeys: facets.map((f) => f.key).sort(),
|
|
25074
25124
|
facetsSignature: facetsSignature(facets),
|
|
25075
|
-
scopes: [...
|
|
25125
|
+
scopes: [...scopes2].sort(),
|
|
25076
25126
|
redacted: options.redactor !== void 0,
|
|
25077
25127
|
reviewedMemoryIdsSignature: reviewedMemoryIdsSignature(options.reviewedMemoryIds)
|
|
25078
25128
|
};
|
|
25079
25129
|
const previous = options.previous && options.previous.version === PROFILE_DOC_VERSION && configMatches(options.previous.config, config) ? options.previous : void 0;
|
|
25080
|
-
const listOptions = { scopes, includeDeleted: true, includeSuperseded: true };
|
|
25081
|
-
const [memories, projections] = store ? await Promise.all([store.list(listOptions), store.listProjections(listOptions)]) : [await getVaultProfileMetadataOp(vaultCtx, { scopes }), []];
|
|
25130
|
+
const listOptions = { scopes: scopes2, includeDeleted: true, includeSuperseded: true };
|
|
25131
|
+
const [memories, projections] = store ? await Promise.all([store.list(listOptions), store.listProjections(listOptions)]) : [await getVaultProfileMetadataOp(vaultCtx, { scopes: scopes2 }), []];
|
|
25082
25132
|
const watermark = computeVaultWatermark(memories);
|
|
25083
25133
|
const observationTrends = summarizeObservationTrends(
|
|
25084
25134
|
memories.filter((m) => !m.isDeleted && m.supersededBy === null).map((m) => ({
|
|
@@ -25123,7 +25173,7 @@ async function synthesizeProfile(ctx, options = {}) {
|
|
|
25123
25173
|
for (const section of previous.sections) {
|
|
25124
25174
|
if (section.sourceMemoryIds.length > 0 && section.sourceMemoryIds.every((id2) => {
|
|
25125
25175
|
const memory = memoriesById.get(id2);
|
|
25126
|
-
return memory && !memory.isDeleted && !memory.supersededBy &&
|
|
25176
|
+
return memory && !memory.isDeleted && !memory.supersededBy && scopes2.includes(memory.scope) && (options.reviewedMemoryIds === void 0 || options.reviewedMemoryIds.includes(id2)) && changeTime(memory) <= previous.vaultWatermark;
|
|
25127
25177
|
})) {
|
|
25128
25178
|
fallbackPriors.set(section.key, section);
|
|
25129
25179
|
}
|
|
@@ -25296,7 +25346,7 @@ async function attributeFacts(ctx, candidates, facets) {
|
|
|
25296
25346
|
return keys;
|
|
25297
25347
|
}
|
|
25298
25348
|
async function synthesizeFacet(facet, ctx, options, prior, vaultPreparation) {
|
|
25299
|
-
const
|
|
25349
|
+
const scopes2 = options.scopes ?? DEFAULT_SCOPES;
|
|
25300
25350
|
const limit = options.limit ?? DEFAULT_FACET_RECALL_LIMIT;
|
|
25301
25351
|
const factTypeWeights = { ...DEFAULT_PROFILE_FACT_TYPE_WEIGHTS, ...options.factTypeWeights };
|
|
25302
25352
|
const proofCountAlpha = options.proofCountAlpha ?? DEFAULT_PROFILE_PROOF_ALPHA;
|
|
@@ -25313,7 +25363,7 @@ async function synthesizeFacet(facet, ctx, options, prior, vaultPreparation) {
|
|
|
25313
25363
|
}
|
|
25314
25364
|
const recalled = await recall(facet.query, ctx, {
|
|
25315
25365
|
vaultPreparation,
|
|
25316
|
-
scopes,
|
|
25366
|
+
scopes: scopes2,
|
|
25317
25367
|
limit: hasReviewGate ? RECALL_MAX_LIMIT : limit,
|
|
25318
25368
|
...hasReviewGate && { memoryIds: [...reviewed] },
|
|
25319
25369
|
types: ["fact"],
|
|
@@ -25340,7 +25390,7 @@ async function synthesizeFacet(facet, ctx, options, prior, vaultPreparation) {
|
|
|
25340
25390
|
llmModel: options.llmModel ?? DEFAULT_SYNTHESIS_MODEL,
|
|
25341
25391
|
baseUrl: options.baseUrl,
|
|
25342
25392
|
fetchFn: options.fetchFn,
|
|
25343
|
-
scopes,
|
|
25393
|
+
scopes: scopes2,
|
|
25344
25394
|
limit,
|
|
25345
25395
|
types: ["fact"],
|
|
25346
25396
|
maxTokens: DEFAULT_FACET_MAX_TOKENS,
|
|
@@ -29098,7 +29148,7 @@ function useChat(options) {
|
|
|
29098
29148
|
}
|
|
29099
29149
|
|
|
29100
29150
|
// src/expo/useChatStorage.ts
|
|
29101
|
-
import { useCallback as
|
|
29151
|
+
import { useCallback as useCallback5, useEffect as useEffect5, useMemo, useRef as useRef4, useState as useState4 } from "react";
|
|
29102
29152
|
import { v7 as uuidv78 } from "uuid";
|
|
29103
29153
|
|
|
29104
29154
|
// src/lib/chat/assembleMessages.ts
|
|
@@ -29884,6 +29934,106 @@ async function deleteMediaByConversationOp(ctx, conversationId) {
|
|
|
29884
29934
|
return results.length;
|
|
29885
29935
|
}
|
|
29886
29936
|
|
|
29937
|
+
// src/lib/pii/useConversationRedactors.ts
|
|
29938
|
+
import { useCallback as useCallback4, useEffect as useEffect4, useSyncExternalStore } from "react";
|
|
29939
|
+
var REDACTOR_LIMIT = 50;
|
|
29940
|
+
var registry2 = /* @__PURE__ */ new WeakMap();
|
|
29941
|
+
var compositeKeys = /* @__PURE__ */ new WeakMap();
|
|
29942
|
+
var scopes = /* @__PURE__ */ new Set();
|
|
29943
|
+
var retiredRedactor = new PiiRedactor();
|
|
29944
|
+
retiredRedactor.dispose();
|
|
29945
|
+
function retireScope(scope) {
|
|
29946
|
+
scopes.delete(scope);
|
|
29947
|
+
if (!scope.active) return;
|
|
29948
|
+
scope.active = false;
|
|
29949
|
+
for (const { redactor } of scope.redactors.values()) redactor.dispose();
|
|
29950
|
+
scope.redactors.clear();
|
|
29951
|
+
for (const redactor of scope.evicted) redactor.dispose();
|
|
29952
|
+
scope.evicted = [];
|
|
29953
|
+
for (const notify of scope.subscribers) notify();
|
|
29954
|
+
}
|
|
29955
|
+
function storageKey(storage, secondaryStorage) {
|
|
29956
|
+
if (!secondaryStorage) return storage;
|
|
29957
|
+
let inner = compositeKeys.get(storage);
|
|
29958
|
+
if (!inner) {
|
|
29959
|
+
inner = /* @__PURE__ */ new WeakMap();
|
|
29960
|
+
compositeKeys.set(storage, inner);
|
|
29961
|
+
}
|
|
29962
|
+
let key3 = inner.get(secondaryStorage);
|
|
29963
|
+
if (!key3) {
|
|
29964
|
+
key3 = {};
|
|
29965
|
+
inner.set(secondaryStorage, key3);
|
|
29966
|
+
}
|
|
29967
|
+
return key3;
|
|
29968
|
+
}
|
|
29969
|
+
function getScope(database, storage, account) {
|
|
29970
|
+
let stores = registry2.get(database);
|
|
29971
|
+
if (!stores) {
|
|
29972
|
+
stores = /* @__PURE__ */ new WeakMap();
|
|
29973
|
+
registry2.set(database, stores);
|
|
29974
|
+
}
|
|
29975
|
+
let accounts = stores.get(storage);
|
|
29976
|
+
if (!accounts) {
|
|
29977
|
+
accounts = /* @__PURE__ */ new Map();
|
|
29978
|
+
stores.set(storage, accounts);
|
|
29979
|
+
}
|
|
29980
|
+
let scope = accounts.get(account);
|
|
29981
|
+
if (!scope?.active) {
|
|
29982
|
+
scope = { active: true, users: 0, subscribers: /* @__PURE__ */ new Set(), redactors: /* @__PURE__ */ new Map(), evicted: [] };
|
|
29983
|
+
accounts.set(account, scope);
|
|
29984
|
+
}
|
|
29985
|
+
return scope;
|
|
29986
|
+
}
|
|
29987
|
+
onClearAllEncryptionState(() => {
|
|
29988
|
+
registry2 = /* @__PURE__ */ new WeakMap();
|
|
29989
|
+
for (const scope of [...scopes]) retireScope(scope);
|
|
29990
|
+
});
|
|
29991
|
+
function useConversationRedactors(database, account, storage, secondaryStorage) {
|
|
29992
|
+
const scope = getScope(database, storageKey(storage, secondaryStorage), account);
|
|
29993
|
+
const subscribe = useCallback4(
|
|
29994
|
+
(callback) => {
|
|
29995
|
+
scope.subscribers.add(callback);
|
|
29996
|
+
return () => {
|
|
29997
|
+
scope.subscribers.delete(callback);
|
|
29998
|
+
};
|
|
29999
|
+
},
|
|
30000
|
+
[scope]
|
|
30001
|
+
);
|
|
30002
|
+
const getSnapshot = useCallback4(() => scope.active ? scope : null, [scope]);
|
|
30003
|
+
useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
30004
|
+
useEffect4(() => {
|
|
30005
|
+
if (scope.active) scopes.add(scope);
|
|
30006
|
+
scope.users++;
|
|
30007
|
+
return () => {
|
|
30008
|
+
scope.users--;
|
|
30009
|
+
if (scope.users === 0) retireScope(scope);
|
|
30010
|
+
};
|
|
30011
|
+
}, [scope]);
|
|
30012
|
+
return useCallback4(
|
|
30013
|
+
(conversationId, nerDetector) => {
|
|
30014
|
+
if (!scope.active) return retiredRedactor;
|
|
30015
|
+
const cached = scope.redactors.get(conversationId);
|
|
30016
|
+
if (cached && cached.detector === nerDetector) {
|
|
30017
|
+
scope.redactors.delete(conversationId);
|
|
30018
|
+
scope.redactors.set(conversationId, cached);
|
|
30019
|
+
return cached.redactor;
|
|
30020
|
+
}
|
|
30021
|
+
if (cached) scope.evicted.push(cached.redactor);
|
|
30022
|
+
const redactor = new PiiRedactor({ nerDetector });
|
|
30023
|
+
scope.redactors.set(conversationId, { redactor, detector: nerDetector });
|
|
30024
|
+
if (scope.redactors.size > REDACTOR_LIMIT) {
|
|
30025
|
+
const oldest = scope.redactors.entries().next().value;
|
|
30026
|
+
if (oldest) {
|
|
30027
|
+
scope.evicted.push(oldest[1].redactor);
|
|
30028
|
+
scope.redactors.delete(oldest[0]);
|
|
30029
|
+
}
|
|
30030
|
+
}
|
|
30031
|
+
return redactor;
|
|
30032
|
+
},
|
|
30033
|
+
[scope]
|
|
30034
|
+
);
|
|
30035
|
+
}
|
|
30036
|
+
|
|
29887
30037
|
// src/lib/tools/selection/activeToolSets.ts
|
|
29888
30038
|
function mergeActiveToolSets(current, derived) {
|
|
29889
30039
|
if (derived.length === 0) return current;
|
|
@@ -29944,30 +30094,11 @@ function resetRecentToolSets() {
|
|
|
29944
30094
|
onClearAllEncryptionState(resetRecentToolSets);
|
|
29945
30095
|
|
|
29946
30096
|
// src/expo/useChatStorage.ts
|
|
29947
|
-
var CONVERSATION_REDACTOR_LIMIT = 50;
|
|
29948
|
-
var NO_CONVERSATION_KEY = "__no_conversation__";
|
|
29949
30097
|
var NO_STORE_FOLDERS = "Folders are not supported with a memoryStore";
|
|
29950
30098
|
var NO_STORE_MASK = "piiRedaction needs a memoryStore built with embeddingOptions.maskInput";
|
|
29951
30099
|
var MEMORY_STORE_NOT_READY = "Memory store is not ready";
|
|
29952
|
-
var conversationRedactors = /* @__PURE__ */ new Map();
|
|
29953
30100
|
var queuedBackends = /* @__PURE__ */ new WeakMap();
|
|
29954
30101
|
var clientToolFilterCache = /* @__PURE__ */ new Map();
|
|
29955
|
-
function getConversationRedactor(conversationId, nerDetector) {
|
|
29956
|
-
const key3 = conversationId ?? NO_CONVERSATION_KEY;
|
|
29957
|
-
const cached = conversationRedactors.get(key3);
|
|
29958
|
-
if (cached && cached.detector === nerDetector) {
|
|
29959
|
-
conversationRedactors.delete(key3);
|
|
29960
|
-
conversationRedactors.set(key3, cached);
|
|
29961
|
-
return cached.redactor;
|
|
29962
|
-
}
|
|
29963
|
-
const redactor = new PiiRedactor({ nerDetector });
|
|
29964
|
-
conversationRedactors.set(key3, { redactor, detector: nerDetector });
|
|
29965
|
-
if (conversationRedactors.size > CONVERSATION_REDACTOR_LIMIT) {
|
|
29966
|
-
const oldest = conversationRedactors.keys().next().value;
|
|
29967
|
-
if (oldest !== void 0) conversationRedactors.delete(oldest);
|
|
29968
|
-
}
|
|
29969
|
-
return redactor;
|
|
29970
|
-
}
|
|
29971
30102
|
function resolveCallPii(requestPiiRedaction, hookPiiRedaction, getConversationRedactorFor) {
|
|
29972
30103
|
const effective = requestPiiRedaction === void 0 ? hookPiiRedaction : requestPiiRedaction;
|
|
29973
30104
|
const redactor = effective === true ? getConversationRedactorFor() : isPiiRedactor(effective) ? effective : void 0;
|
|
@@ -30086,11 +30217,17 @@ function useChatStorage(options) {
|
|
|
30086
30217
|
foldToolResultsInHistoryRef.current = foldToolResultsInHistory;
|
|
30087
30218
|
const nerDetectorRef = useRef4(nerDetector);
|
|
30088
30219
|
nerDetectorRef.current = nerDetector;
|
|
30220
|
+
const getConversationRedactor = useConversationRedactors(
|
|
30221
|
+
database,
|
|
30222
|
+
walletAddress,
|
|
30223
|
+
memoryStore ?? chatBackend ?? database,
|
|
30224
|
+
memoryStore && chatBackend ? chatBackend : void 0
|
|
30225
|
+
);
|
|
30089
30226
|
const resolvedPiiRedaction = useMemo(
|
|
30090
30227
|
() => piiRedaction === true ? getConversationRedactor(currentConversationId, nerDetectorRef.current) : piiRedaction,
|
|
30091
|
-
[piiRedaction, currentConversationId]
|
|
30228
|
+
[piiRedaction, currentConversationId, getConversationRedactor]
|
|
30092
30229
|
);
|
|
30093
|
-
const maskForEmbedding =
|
|
30230
|
+
const maskForEmbedding = useCallback5(
|
|
30094
30231
|
(text16) => isPiiRedactor(resolvedPiiRedaction) ? resolvedPiiRedaction.maskText(text16) : text16,
|
|
30095
30232
|
[resolvedPiiRedaction]
|
|
30096
30233
|
);
|
|
@@ -30152,12 +30289,12 @@ function useChatStorage(options) {
|
|
|
30152
30289
|
isFlushing: false,
|
|
30153
30290
|
isPaused: false
|
|
30154
30291
|
});
|
|
30155
|
-
const refreshQueueStatus =
|
|
30292
|
+
const refreshQueueStatus = useCallback5(() => {
|
|
30156
30293
|
if (walletAddress) {
|
|
30157
30294
|
setQueueStatus(queueManager.getStatus(walletAddress));
|
|
30158
30295
|
}
|
|
30159
30296
|
}, [walletAddress]);
|
|
30160
|
-
const executeQueuedOperation =
|
|
30297
|
+
const executeQueuedOperation = useCallback5(
|
|
30161
30298
|
async (operation, encCtx) => {
|
|
30162
30299
|
const queued = queuedBackends.get(operation.payload) ?? backendFactory({
|
|
30163
30300
|
walletAddress: encCtx.walletAddress,
|
|
@@ -30202,7 +30339,7 @@ function useChatStorage(options) {
|
|
|
30202
30339
|
},
|
|
30203
30340
|
[backendFactory, database]
|
|
30204
30341
|
);
|
|
30205
|
-
const flushQueue =
|
|
30342
|
+
const flushQueue = useCallback5(async () => {
|
|
30206
30343
|
if (!walletAddress || !signMessage) {
|
|
30207
30344
|
return { succeeded: [], failed: [], total: 0 };
|
|
30208
30345
|
}
|
|
@@ -30221,18 +30358,18 @@ function useChatStorage(options) {
|
|
|
30221
30358
|
executeQueuedOperation,
|
|
30222
30359
|
refreshQueueStatus
|
|
30223
30360
|
]);
|
|
30224
|
-
const clearQueue =
|
|
30361
|
+
const clearQueue = useCallback5(() => {
|
|
30225
30362
|
if (walletAddress) {
|
|
30226
30363
|
queueManager.clear(walletAddress);
|
|
30227
30364
|
refreshQueueStatus();
|
|
30228
30365
|
}
|
|
30229
30366
|
}, [walletAddress, refreshQueueStatus]);
|
|
30230
|
-
|
|
30367
|
+
useEffect5(() => {
|
|
30231
30368
|
if (!walletAddress) return;
|
|
30232
30369
|
refreshQueueStatus();
|
|
30233
30370
|
return queueManager.onQueueChange(walletAddress, refreshQueueStatus);
|
|
30234
30371
|
}, [walletAddress, refreshQueueStatus]);
|
|
30235
|
-
|
|
30372
|
+
useEffect5(() => {
|
|
30236
30373
|
if (!getWalletAddress || walletAddress) return;
|
|
30237
30374
|
const poller = new WalletPoller();
|
|
30238
30375
|
return poller.startPolling(getWalletAddress, () => {
|
|
@@ -30240,7 +30377,7 @@ function useChatStorage(options) {
|
|
|
30240
30377
|
}, [getWalletAddress, walletAddress]);
|
|
30241
30378
|
const pendingOpsRef = useRef4([]);
|
|
30242
30379
|
const syntheticConvIdsRef = useRef4(/* @__PURE__ */ new Set());
|
|
30243
|
-
|
|
30380
|
+
useEffect5(() => {
|
|
30244
30381
|
if (!walletAddress || !enableQueue) return;
|
|
30245
30382
|
const pending = pendingOpsRef.current;
|
|
30246
30383
|
if (pending.length === 0) return;
|
|
@@ -30251,7 +30388,7 @@ function useChatStorage(options) {
|
|
|
30251
30388
|
pendingOpsRef.current = [];
|
|
30252
30389
|
refreshQueueStatus();
|
|
30253
30390
|
}, [walletAddress, enableQueue, refreshQueueStatus]);
|
|
30254
|
-
|
|
30391
|
+
useEffect5(() => {
|
|
30255
30392
|
if (!walletAddress || !enableQueue || !autoFlushOnKeyAvailable || !signMessage) return;
|
|
30256
30393
|
return onKeyAvailable(walletAddress, () => {
|
|
30257
30394
|
flushQueue().catch((err) => {
|
|
@@ -30259,7 +30396,7 @@ function useChatStorage(options) {
|
|
|
30259
30396
|
});
|
|
30260
30397
|
});
|
|
30261
30398
|
}, [walletAddress, enableQueue, autoFlushOnKeyAvailable, signMessage, flushQueue]);
|
|
30262
|
-
const writeOrQueue =
|
|
30399
|
+
const writeOrQueue = useCallback5(
|
|
30263
30400
|
async (opType, payload, directWrite, makeSynthetic, dependencies = []) => {
|
|
30264
30401
|
const currentStorageCtx = storageCtx.walletAddress ? storageCtx : storageCtxRef.current;
|
|
30265
30402
|
const currentBackend = storageCtx.walletAddress ? backend : backendRef.current;
|
|
@@ -30297,7 +30434,7 @@ function useChatStorage(options) {
|
|
|
30297
30434
|
},
|
|
30298
30435
|
[storageCtx, backend, enableQueue, signMessage, getWalletAddress]
|
|
30299
30436
|
);
|
|
30300
|
-
const embedMessageAsync =
|
|
30437
|
+
const embedMessageAsync = useCallback5(
|
|
30301
30438
|
async (message, mask = maskForEmbedding) => {
|
|
30302
30439
|
if (!autoEmbedMessages || !getToken) return;
|
|
30303
30440
|
if (message.content.length < minContentLength) return;
|
|
@@ -30334,7 +30471,7 @@ function useChatStorage(options) {
|
|
|
30334
30471
|
maskForEmbedding
|
|
30335
30472
|
]
|
|
30336
30473
|
);
|
|
30337
|
-
const createMemoryEngineTool2 =
|
|
30474
|
+
const createMemoryEngineTool2 = useCallback5(
|
|
30338
30475
|
(searchOptions) => {
|
|
30339
30476
|
if (!getToken) {
|
|
30340
30477
|
throw new Error("getToken is required for memory engine tool");
|
|
@@ -30352,13 +30489,13 @@ function useChatStorage(options) {
|
|
|
30352
30489
|
[database, walletAddress, embeddingModel]
|
|
30353
30490
|
);
|
|
30354
30491
|
const chunkVectorCacheRef = useRef4(createChunkVectorCache());
|
|
30355
|
-
|
|
30492
|
+
useEffect5(() => {
|
|
30356
30493
|
return onClearAllEncryptionState(() => {
|
|
30357
30494
|
vaultEmbeddingCache.clear();
|
|
30358
30495
|
chunkVectorCacheRef.current.clear();
|
|
30359
30496
|
});
|
|
30360
30497
|
}, [vaultEmbeddingCache]);
|
|
30361
|
-
const retainVaultMemory =
|
|
30498
|
+
const retainVaultMemory = useCallback5(
|
|
30362
30499
|
async (input) => {
|
|
30363
30500
|
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
30364
30501
|
if (memoryStore) {
|
|
@@ -30404,7 +30541,7 @@ function useChatStorage(options) {
|
|
|
30404
30541
|
storeMaskMissing
|
|
30405
30542
|
]
|
|
30406
30543
|
);
|
|
30407
|
-
const createMemoryVaultTool2 =
|
|
30544
|
+
const createMemoryVaultTool2 = useCallback5(
|
|
30408
30545
|
(options2) => {
|
|
30409
30546
|
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
30410
30547
|
if (storeMaskMissing) throw new Error(NO_STORE_MASK);
|
|
@@ -30415,7 +30552,7 @@ function useChatStorage(options) {
|
|
|
30415
30552
|
},
|
|
30416
30553
|
[vaultCtx, getToken, retainVaultMemory, memoryStore, storeMaskMissing]
|
|
30417
30554
|
);
|
|
30418
|
-
const createRecallTool2 =
|
|
30555
|
+
const createRecallTool2 = useCallback5(
|
|
30419
30556
|
(toolOptions, callbacks) => {
|
|
30420
30557
|
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
30421
30558
|
if (!getToken && !memoryStore) {
|
|
@@ -30461,7 +30598,7 @@ function useChatStorage(options) {
|
|
|
30461
30598
|
storeMaskMissing
|
|
30462
30599
|
]
|
|
30463
30600
|
);
|
|
30464
|
-
const recallFn =
|
|
30601
|
+
const recallFn = useCallback5(
|
|
30465
30602
|
async (query, options2) => {
|
|
30466
30603
|
if (memoryStore === null || !getToken && !memoryStore) {
|
|
30467
30604
|
return {
|
|
@@ -30510,7 +30647,7 @@ function useChatStorage(options) {
|
|
|
30510
30647
|
storeMaskMissing
|
|
30511
30648
|
]
|
|
30512
30649
|
);
|
|
30513
|
-
const getVaultMemories =
|
|
30650
|
+
const getVaultMemories = useCallback5(
|
|
30514
30651
|
(options2) => {
|
|
30515
30652
|
if (memoryStore === null) return Promise.resolve([]);
|
|
30516
30653
|
if (!memoryStore) return getAllVaultMemoriesOp(vaultCtx, options2);
|
|
@@ -30522,7 +30659,7 @@ function useChatStorage(options) {
|
|
|
30522
30659
|
},
|
|
30523
30660
|
[vaultCtx, memoryStore]
|
|
30524
30661
|
);
|
|
30525
|
-
const deleteVaultMemory =
|
|
30662
|
+
const deleteVaultMemory = useCallback5(
|
|
30526
30663
|
async (id2) => {
|
|
30527
30664
|
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
30528
30665
|
return memoryStore ? memoryStore.delete(id2) : deleteVaultMemoryOp(vaultCtx, id2);
|
|
@@ -30560,7 +30697,7 @@ function useChatStorage(options) {
|
|
|
30560
30697
|
const activeResumeRef = useRef4(null);
|
|
30561
30698
|
const retirementRef = useRef4(null);
|
|
30562
30699
|
const retirementStopRequestedRef = useRef4(false);
|
|
30563
|
-
const createConversation =
|
|
30700
|
+
const createConversation = useCallback5(
|
|
30564
30701
|
async (opts) => {
|
|
30565
30702
|
const conversationOpts = {
|
|
30566
30703
|
...opts,
|
|
@@ -30580,16 +30717,16 @@ function useChatStorage(options) {
|
|
|
30580
30717
|
},
|
|
30581
30718
|
[defaultConversationTitle, writeOrQueue]
|
|
30582
30719
|
);
|
|
30583
|
-
const getConversation =
|
|
30720
|
+
const getConversation = useCallback5(
|
|
30584
30721
|
async (id2) => {
|
|
30585
30722
|
return backend.getConversation(id2);
|
|
30586
30723
|
},
|
|
30587
30724
|
[backend]
|
|
30588
30725
|
);
|
|
30589
|
-
const getConversations =
|
|
30726
|
+
const getConversations = useCallback5(async () => {
|
|
30590
30727
|
return backend.getConversations();
|
|
30591
30728
|
}, [backend]);
|
|
30592
|
-
const updateConversationTitle =
|
|
30729
|
+
const updateConversationTitle = useCallback5(
|
|
30593
30730
|
async (id2, title) => {
|
|
30594
30731
|
const { result } = await writeOrQueue(
|
|
30595
30732
|
"updateConversationTitle",
|
|
@@ -30601,7 +30738,7 @@ function useChatStorage(options) {
|
|
|
30601
30738
|
},
|
|
30602
30739
|
[writeOrQueue]
|
|
30603
30740
|
);
|
|
30604
|
-
const updateConversationPinned =
|
|
30741
|
+
const updateConversationPinned = useCallback5(
|
|
30605
30742
|
async (id2, pinned) => {
|
|
30606
30743
|
const { result } = await writeOrQueue(
|
|
30607
30744
|
"updateConversationPinned",
|
|
@@ -30613,7 +30750,7 @@ function useChatStorage(options) {
|
|
|
30613
30750
|
},
|
|
30614
30751
|
[writeOrQueue]
|
|
30615
30752
|
);
|
|
30616
|
-
const deleteConversation =
|
|
30753
|
+
const deleteConversation = useCallback5(
|
|
30617
30754
|
async (id2) => {
|
|
30618
30755
|
const deleted = await backend.deleteConversation(id2);
|
|
30619
30756
|
if (deleted) {
|
|
@@ -30631,31 +30768,31 @@ function useChatStorage(options) {
|
|
|
30631
30768
|
},
|
|
30632
30769
|
[backend, database, walletAddress, signMessage, embeddedWalletSigner, currentConversationId]
|
|
30633
30770
|
);
|
|
30634
|
-
const getMessages =
|
|
30771
|
+
const getMessages = useCallback5(
|
|
30635
30772
|
async (convId) => {
|
|
30636
30773
|
return backend.getMessages(convId);
|
|
30637
30774
|
},
|
|
30638
30775
|
[backend]
|
|
30639
30776
|
);
|
|
30640
|
-
const getMessagesPage =
|
|
30777
|
+
const getMessagesPage = useCallback5(
|
|
30641
30778
|
async (convId, options2) => {
|
|
30642
30779
|
return backend.getMessagesPage(convId, options2);
|
|
30643
30780
|
},
|
|
30644
30781
|
[backend]
|
|
30645
30782
|
);
|
|
30646
|
-
const getMessageSkeletons =
|
|
30783
|
+
const getMessageSkeletons = useCallback5(
|
|
30647
30784
|
(convId) => {
|
|
30648
30785
|
return backend.getMessageSkeletons(convId);
|
|
30649
30786
|
},
|
|
30650
30787
|
[backend]
|
|
30651
30788
|
);
|
|
30652
|
-
const getMessageCount =
|
|
30789
|
+
const getMessageCount = useCallback5(
|
|
30653
30790
|
(convId) => {
|
|
30654
30791
|
return backend.getMessageCount(convId);
|
|
30655
30792
|
},
|
|
30656
30793
|
[backend]
|
|
30657
30794
|
);
|
|
30658
|
-
const extractSourcesFromAssistantMessage =
|
|
30795
|
+
const extractSourcesFromAssistantMessage = useCallback5(
|
|
30659
30796
|
(assistantMessage) => {
|
|
30660
30797
|
try {
|
|
30661
30798
|
const extractedSources = [];
|
|
@@ -30737,7 +30874,7 @@ function useChatStorage(options) {
|
|
|
30737
30874
|
},
|
|
30738
30875
|
[]
|
|
30739
30876
|
);
|
|
30740
|
-
const ensureConversation =
|
|
30877
|
+
const ensureConversation = useCallback5(async () => {
|
|
30741
30878
|
if (currentConversationId) {
|
|
30742
30879
|
if (syntheticConvIdsRef.current.has(currentConversationId)) {
|
|
30743
30880
|
return currentConversationId;
|
|
@@ -30763,7 +30900,7 @@ function useChatStorage(options) {
|
|
|
30763
30900
|
activeToolSetsRef.current = activeToolSets;
|
|
30764
30901
|
const getTokenRef = useRef4(getToken);
|
|
30765
30902
|
getTokenRef.current = getToken;
|
|
30766
|
-
const finalizeResumedRow =
|
|
30903
|
+
const finalizeResumedRow = useCallback5(
|
|
30767
30904
|
async (ctx, data, wasStopped, responseDuration, viaQueue = false) => {
|
|
30768
30905
|
const { content, thinking } = extractAssistantText(data);
|
|
30769
30906
|
let parentMessageId = ctx.userMessageUniqueId;
|
|
@@ -30837,7 +30974,7 @@ function useChatStorage(options) {
|
|
|
30837
30974
|
},
|
|
30838
30975
|
[backend, getMessages, writeOrQueue]
|
|
30839
30976
|
);
|
|
30840
|
-
const retirePendingTurn =
|
|
30977
|
+
const retirePendingTurn = useCallback5(async () => {
|
|
30841
30978
|
const visible = activeResumeRef.current;
|
|
30842
30979
|
if (visible && !visible.headless) {
|
|
30843
30980
|
baseStop();
|
|
@@ -30900,7 +31037,7 @@ function useChatStorage(options) {
|
|
|
30900
31037
|
}
|
|
30901
31038
|
}
|
|
30902
31039
|
}, [baseCancel, baseStop, finalizeResumedRow, walletAddress, signMessage, embeddedWalletSigner]);
|
|
30903
|
-
const sendMessage =
|
|
31040
|
+
const sendMessage = useCallback5(
|
|
30904
31041
|
async (args) => {
|
|
30905
31042
|
const {
|
|
30906
31043
|
messages,
|
|
@@ -31704,6 +31841,8 @@ function useChatStorage(options) {
|
|
|
31704
31841
|
getMessages,
|
|
31705
31842
|
backend,
|
|
31706
31843
|
baseSendMessage,
|
|
31844
|
+
getConversationRedactor,
|
|
31845
|
+
piiRedaction,
|
|
31707
31846
|
retirePendingTurn,
|
|
31708
31847
|
embedMessageAsync,
|
|
31709
31848
|
minContentLength,
|
|
@@ -31718,7 +31857,7 @@ function useChatStorage(options) {
|
|
|
31718
31857
|
onPiiRedacted
|
|
31719
31858
|
]
|
|
31720
31859
|
);
|
|
31721
|
-
const resumeStream2 =
|
|
31860
|
+
const resumeStream2 = useCallback5(
|
|
31722
31861
|
async (handleOverride, opts) => {
|
|
31723
31862
|
if (isResumingRef.current || retirementRef.current) {
|
|
31724
31863
|
return { data: null, error: "Resume already in progress", assistantMessage: null };
|
|
@@ -31848,7 +31987,7 @@ function useChatStorage(options) {
|
|
|
31848
31987
|
},
|
|
31849
31988
|
[baseResumeStream, currentConversationId, finalizeResumedRow, embedMessageAsync]
|
|
31850
31989
|
);
|
|
31851
|
-
const stop =
|
|
31990
|
+
const stop = useCallback5(() => {
|
|
31852
31991
|
if (retirementRef.current) {
|
|
31853
31992
|
retirementStopRequestedRef.current = true;
|
|
31854
31993
|
return;
|