@anuma/sdk 10.4.3 → 10.5.1

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.
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  INTERNAL_FLOW_MARKER,
3
+ PII_PATTERNS,
3
4
  PiiRedactor,
4
5
  callPortalJsonCompletion,
5
6
  consoleLogger,
@@ -19,7 +20,7 @@ import {
19
20
  taskTypeHeader,
20
21
  validateEndpointOverride,
21
22
  withInternalFlowMarker
22
- } from "./chunk-6ANL34M3.mjs";
23
+ } from "./chunk-6QCUNXU6.mjs";
23
24
  import {
24
25
  BASE_URL,
25
26
  MCP_R2_DOMAIN,
@@ -11625,7 +11626,7 @@ var ChatStoreError = class extends Error {
11625
11626
  };
11626
11627
 
11627
11628
  // src/lib/chatStore/remote.ts
11628
- var kinds = /* @__PURE__ */ new Set(["conversation", "message", "summary", "project", "memory_links"]);
11629
+ var kinds = /* @__PURE__ */ new Set(["conversation", "message", "summary", "project", "memory_links", "setting"]);
11629
11630
  var cipherPattern = /^enc:v\d+:(?:[0-9a-f]{2}){28,}$/i;
11630
11631
  var maxPayload = 2 * 1024 * 1024;
11631
11632
  var storedDims2 = 1536;
@@ -11681,9 +11682,12 @@ function validRecord(value) {
11681
11682
  (key3) => ![...metadata, "data"].includes(key3)
11682
11683
  ))
11683
11684
  return false;
11684
- const root = value.kind === "conversation" || value.kind === "project";
11685
+ const root = rootKind(value.kind);
11685
11686
  return root ? value.conversationId === "" : id(value.conversationId);
11686
11687
  }
11688
+ function rootKind(kind) {
11689
+ return kind === "conversation" || kind === "project" || kind === "setting";
11690
+ }
11687
11691
  function embeddings(write) {
11688
11692
  if (write.embeddings === void 0) return true;
11689
11693
  return Array.isArray(write.embeddings) && !write.record.isDeleted && (write.record.kind === "message" || write.record.kind === "summary") && write.embeddings.length <= maxChunksPerRecord && (write.embeddingModel === void 0 || typeof write.embeddingModel === "string" && write.embeddingModel.length <= 256) && Array.from({ length: write.embeddings.length }, (_, i) => i).every(
@@ -11891,7 +11895,7 @@ async function createRemoteChatStore(options) {
11891
11895
  async list(query) {
11892
11896
  const limit = query.limit ?? 20;
11893
11897
  const parent = query.conversationId ?? "";
11894
- if (!kinds.has(query.kind) || !integer(limit, 1) || query.includeDeleted !== void 0 && typeof query.includeDeleted !== "boolean" || limit > 200 || (query.cursor?.length ?? 0) > 2048 || (query.kind === "conversation" || query.kind === "project" ? parent !== "" : !id(parent)))
11898
+ if (!kinds.has(query.kind) || !integer(limit, 1) || query.includeDeleted !== void 0 && typeof query.includeDeleted !== "boolean" || limit > 200 || (query.cursor?.length ?? 0) > 2048 || (rootKind(query.kind) ? parent !== "" : !id(parent)))
11895
11899
  invalid();
11896
11900
  const params = new URLSearchParams({
11897
11901
  account_id: String(accountId),
@@ -12034,10 +12038,12 @@ async function createRemoteChatStore(options) {
12034
12038
  },
12035
12039
  async changes(cursor, options2) {
12036
12040
  const limit = options2?.limit ?? 100;
12037
- if (!integer(limit, 1) || limit > 200 || cursor !== void 0 && (!text5(cursor) || cursor.length > 2048))
12041
+ const kindsFilter = options2?.kinds;
12042
+ if (!integer(limit, 1) || limit > 200 || cursor !== void 0 && (!text5(cursor) || cursor.length > 2048) || kindsFilter !== void 0 && (!Array.isArray(kindsFilter) || kindsFilter.length === 0 || new Set(kindsFilter).size !== kindsFilter.length || kindsFilter.some((k) => !kinds.has(k))))
12038
12043
  invalid();
12039
12044
  const params = new URLSearchParams({ account_id: String(accountId), limit: String(limit) });
12040
12045
  if (cursor) params.set("cursor", cursor);
12046
+ if (kindsFilter) params.set("kinds", kindsFilter.join(","));
12041
12047
  const value = await request(`/changes?${params}`, {}, options2?.signal);
12042
12048
  if (!object(value) || !Array.isArray(value.items) || value.items.length > limit || value.next_cursor !== void 0 && !text5(value.next_cursor) || value.changes_cursor !== void 0 && !text5(value.changes_cursor))
12043
12049
  invalid();
@@ -12448,6 +12454,62 @@ async function migrateChatsToRemote(options) {
12448
12454
  return passes(false);
12449
12455
  }
12450
12456
 
12457
+ // src/lib/chatStore/settings.ts
12458
+ var maxSaveAttempts = 3;
12459
+ function toSetting(snapshot) {
12460
+ if (snapshot.record.isDeleted) return null;
12461
+ return {
12462
+ section: snapshot.record.id,
12463
+ data: snapshot.record.data,
12464
+ version: snapshot.version,
12465
+ createdAt: snapshot.record.createdAt,
12466
+ updatedAt: snapshot.record.updatedAt
12467
+ };
12468
+ }
12469
+ async function loadSettings(store, signal) {
12470
+ const out = /* @__PURE__ */ new Map();
12471
+ let cursor;
12472
+ do {
12473
+ const page = await store.list({ kind: "setting", limit: 100, cursor, signal });
12474
+ for (const item of page.items) {
12475
+ const setting = toSetting(item);
12476
+ if (setting) out.set(setting.section, setting);
12477
+ }
12478
+ cursor = page.nextCursor;
12479
+ } while (cursor);
12480
+ return out;
12481
+ }
12482
+ async function saveSetting(store, section, data, signal) {
12483
+ for (let attempt = 1; ; attempt++) {
12484
+ const current = await store.get("setting", section, signal);
12485
+ const now = Date.now();
12486
+ try {
12487
+ const [saved] = await store.putMany(
12488
+ [
12489
+ {
12490
+ record: {
12491
+ kind: "setting",
12492
+ id: section,
12493
+ conversationId: "",
12494
+ sortKey: 0,
12495
+ createdAt: current?.record.createdAt ?? now,
12496
+ updatedAt: Math.max(now, (current?.record.updatedAt ?? 0) + 1),
12497
+ isDeleted: false,
12498
+ data
12499
+ },
12500
+ expectedVersion: current?.version ?? 0
12501
+ }
12502
+ ],
12503
+ signal
12504
+ );
12505
+ return toSetting(saved);
12506
+ } catch (error) {
12507
+ if (!(error instanceof ChatStoreError) || error.code !== "version_conflict" || attempt >= maxSaveAttempts)
12508
+ throw error;
12509
+ }
12510
+ }
12511
+ }
12512
+
12451
12513
  // src/lib/chatStore/vaultAttachments.ts
12452
12514
  var frameVersion = 1;
12453
12515
  var ivBytes = 12;
@@ -19791,6 +19853,125 @@ var WEAK_MODIFIERS = /* @__PURE__ */ new Set([
19791
19853
  "and",
19792
19854
  "or"
19793
19855
  ]);
19856
+ var MAX_ENTITY_NAME_LENGTH = 120;
19857
+ var MAX_ENTITY_NAME_TOKENS = 11;
19858
+ var PREFIXED_HEX = /^0x[0-9a-f]{16,}$/i;
19859
+ var BARE_HEX = /^[0-9a-f]{32,}$/i;
19860
+ var BASE58_STRING = /^[1-9A-HJ-NP-Za-km-z]{32,88}$/;
19861
+ var UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
19862
+ var TRUNCATED_ID = /^[0-9a-z]{3,}(?:…|\.{2,3})[0-9a-z]{3,}$/i;
19863
+ var KEY_SEGMENT_MIN_LENGTH = 16;
19864
+ var LONG_DIGIT_RUN = /^\d{6,}$/;
19865
+ var CURRENCY_MARKED = /[$€£¥₹₿]\d|\d[$€£¥₹₿]/;
19866
+ var NUMERIC_TOKEN = /^[~≈+\-−]?(?:us\$|[$€£¥₹₿])?\d(?:[\d,.]*\d)?(?:k|mm|m|bn|b|t|x|%|[$€£¥₹₿])?$/i;
19867
+ var PLAIN_YEAR = /^(?:1\d{3}|20\d{2})$/;
19868
+ var SUFFIXED_NAME = /^\d*[1-9][kmb]$/i;
19869
+ var BARE_INTEGER = /^\d+$/;
19870
+ var TICKER = /^\$?[A-Z]{2,6}$/;
19871
+ var DETACHED_CURRENCY_SYMBOL = /(^|\s)([$€£¥₹₿])\s+(?=\d)|(\d)\s+([$€£¥₹₿])(?=\s|$)/gu;
19872
+ var LEADING_PUNCTUATION = /^[^\p{L}\p{N}$€£¥₹₿~≈+\-−]+/u;
19873
+ var TRAILING_KEPT_CHARACTER = /[\p{L}\p{N}$€£¥₹₿%]/u;
19874
+ var LEADING_CURRENCY_CODES = /* @__PURE__ */ new Set(["usd", "eur", "gbp", "jpy", "cad", "aud", "chf", "cny"]);
19875
+ var QUANTITY_UNIT_WORDS = /* @__PURE__ */ new Set([
19876
+ "usd",
19877
+ "usdc",
19878
+ "usdt",
19879
+ "eur",
19880
+ "gbp",
19881
+ "sol",
19882
+ "eth",
19883
+ "btc",
19884
+ "dollar",
19885
+ "dollars",
19886
+ "euro",
19887
+ "euros",
19888
+ "buck",
19889
+ "bucks",
19890
+ "k",
19891
+ "thousand",
19892
+ "million",
19893
+ "billion",
19894
+ "trillion",
19895
+ "share",
19896
+ "shares",
19897
+ "token",
19898
+ "tokens",
19899
+ "coin",
19900
+ "coins",
19901
+ "unit",
19902
+ "units",
19903
+ "position",
19904
+ "balance",
19905
+ "stake",
19906
+ "holdings"
19907
+ ]);
19908
+ var AMOUNT_WORDS = /* @__PURE__ */ new Set([...QUANTITY_UNIT_WORDS, "percent", "of"]);
19909
+ var NAME_PII_CATEGORIES = /* @__PURE__ */ new Set(["EMAIL", "PHONE", "SSN", "CREDIT_CARD"]);
19910
+ var NAME_PII_PATTERNS = PII_PATTERNS.filter(
19911
+ (pattern) => NAME_PII_CATEGORIES.has(pattern.category) && pattern.context === void 0
19912
+ );
19913
+ var KEPT_PLACEHOLDER_CATEGORIES = /* @__PURE__ */ new Set(["PERSON", "LOCATION", "ORG"]);
19914
+ var PLACEHOLDER_TOKEN = /\b([A-Za-z]+(?:_[A-Za-z]+)*)_\d+\b/g;
19915
+ function trimPunctuation(token) {
19916
+ const chars = Array.from(token.replace(LEADING_PUNCTUATION, ""));
19917
+ let end = chars.length;
19918
+ while (end > 0 && !TRAILING_KEPT_CHARACTER.test(chars[end - 1])) end--;
19919
+ return chars.slice(0, end).join("");
19920
+ }
19921
+ function hasLetterAndDigit(text16) {
19922
+ return /\p{L}/u.test(text16) && /\p{N}/u.test(text16);
19923
+ }
19924
+ function isIdentifierToken(token) {
19925
+ if (PREFIXED_HEX.test(token) || BARE_HEX.test(token) || BASE58_STRING.test(token)) return true;
19926
+ if (UUID.test(token) || LONG_DIGIT_RUN.test(token)) return true;
19927
+ if (TRUNCATED_ID.test(token) && hasLetterAndDigit(token)) return true;
19928
+ return token.split(/[-_.]/).some((segment) => segment.length >= KEY_SEGMENT_MIN_LENGTH && hasLetterAndDigit(segment));
19929
+ }
19930
+ function containsStructuredPii(name) {
19931
+ return NAME_PII_PATTERNS.some(
19932
+ (pattern) => (name.match(pattern.regex) ?? []).some((match) => pattern.validate?.(match) ?? true)
19933
+ );
19934
+ }
19935
+ function isAmountUnitToken(token) {
19936
+ return NUMERIC_TOKEN.test(token) || TICKER.test(token) || AMOUNT_WORDS.has(token.toLowerCase());
19937
+ }
19938
+ function isAmountWordOrNumber(token) {
19939
+ return NUMERIC_TOKEN.test(token) || AMOUNT_WORDS.has(token.toLowerCase());
19940
+ }
19941
+ function isAmount(tokens) {
19942
+ const start = LEADING_CURRENCY_CODES.has(tokens[0]?.toLowerCase() ?? "") ? 1 : 0;
19943
+ const first = tokens[start];
19944
+ if (first === void 0 || !NUMERIC_TOKEN.test(first)) return false;
19945
+ const units = tokens.slice(start + 1);
19946
+ if (start === 0 && units.length === 0)
19947
+ return !PLAIN_YEAR.test(first) && !SUFFIXED_NAME.test(first);
19948
+ if (!units.every(isAmountUnitToken)) return false;
19949
+ return start === 1 || !BARE_INTEGER.test(first) || units.some(isAmountWordOrNumber);
19950
+ }
19951
+ function hasQuantityPhrase(tokens) {
19952
+ return tokens.some(
19953
+ (token, i) => NUMERIC_TOKEN.test(token) && QUANTITY_UNIT_WORDS.has(tokens[i + 1]?.toLowerCase() ?? "")
19954
+ );
19955
+ }
19956
+ function isIdentifierOrAmountEntityName(name) {
19957
+ const trimmed = name.trim();
19958
+ if (trimmed.length > MAX_ENTITY_NAME_LENGTH) return true;
19959
+ if (containsStructuredPii(trimmed)) return true;
19960
+ const tokens = trimmed.replace(DETACHED_CURRENCY_SYMBOL, "$1$2$3$4").split(/\s+/).map(trimPunctuation).filter((token) => token.length > 0);
19961
+ if (tokens.length === 0) return false;
19962
+ if (tokens.length > MAX_ENTITY_NAME_TOKENS) return true;
19963
+ if (tokens.some(isIdentifierToken)) return true;
19964
+ if (tokens.some((token) => CURRENCY_MARKED.test(token))) return true;
19965
+ return isAmount(tokens) || hasQuantityPhrase(tokens);
19966
+ }
19967
+ function restoreEntityName(name, redactor) {
19968
+ for (const [token, category] of name.matchAll(PLACEHOLDER_TOKEN)) {
19969
+ if (KEPT_PLACEHOLDER_CATEGORIES.has(category.toUpperCase())) continue;
19970
+ if (redactor.restoreForStorage(token).text !== token) return null;
19971
+ }
19972
+ const restored = redactor.restoreForStorage(name);
19973
+ return restored.unresolved || isIdentifierOrAmountEntityName(restored.text) ? null : restored.text;
19974
+ }
19794
19975
 
19795
19976
  // src/lib/memory/injectionClassifier.ts
19796
19977
  var DEFAULT_MODEL = "inclusionai/ling-2.6-flash";
@@ -22293,7 +22474,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
22293
22474
  content: m.content,
22294
22475
  similarity: m.similarity
22295
22476
  }));
22296
- const { consolidateMemory: doConsolidate } = await import("./consolidate-JL4P6FXW.mjs");
22477
+ const { consolidateMemory: doConsolidate } = await import("./consolidate-RASCVKD2.mjs");
22297
22478
  const decision = await doConsolidate(trimmed, candidates, consolidateOptions);
22298
22479
  if (decision.action === "create") return decision.fallbackReason ? null : { create: true };
22299
22480
  if (decision.action === "supersede" && decision.content) {
@@ -22586,8 +22767,8 @@ function restoreCandidates(candidates, redactor, ownNames) {
22586
22767
  ...c,
22587
22768
  content: content.text,
22588
22769
  entities: c.entities.flatMap((e) => {
22589
- const restored = redactor.restoreForStorage(e.name);
22590
- return restored.unresolved ? [] : [{ ...e, name: restored.text }];
22770
+ const name = restoreEntityName(e.name, redactor);
22771
+ return name === null ? [] : [{ ...e, name }];
22591
22772
  })
22592
22773
  },
22593
22774
  unresolved: content.unresolved
@@ -22855,18 +23036,21 @@ function validateCandidates(parsed, validIds, userIds, fallbackSourceId, ownName
22855
23036
  }
22856
23037
  return out;
22857
23038
  }
23039
+ function isAcceptedEntityName(name) {
23040
+ return name.length > 0 && !isGenericEntityName(name) && !isIdentifierOrAmountEntityName(name);
23041
+ }
22858
23042
  function parseEntities(raw) {
22859
23043
  const out = [];
22860
23044
  for (const e of raw) {
22861
23045
  if (typeof e === "string") {
22862
23046
  const name2 = e.trim();
22863
- if (name2.length > 0 && !isGenericEntityName(name2)) out.push({ name: name2 });
23047
+ if (isAcceptedEntityName(name2)) out.push({ name: name2 });
22864
23048
  continue;
22865
23049
  }
22866
23050
  if (typeof e !== "object" || e === null) continue;
22867
23051
  const obj = e;
22868
23052
  const name = typeof obj.name === "string" ? obj.name.trim() : "";
22869
- if (name.length === 0 || isGenericEntityName(name)) continue;
23053
+ if (!isAcceptedEntityName(name)) continue;
22870
23054
  const kind = typeof obj.kind === "string" && ENTITY_KINDS.includes(obj.kind) ? obj.kind : void 0;
22871
23055
  const weight = typeof obj.salience === "string" && Object.keys(TOPIC_SALIENCE_WEIGHTS).includes(obj.salience) ? TOPIC_SALIENCE_WEIGHTS[obj.salience] : void 0;
22872
23056
  out.push({
@@ -25035,6 +25219,7 @@ Each memory is a short statement about the user. For each memory, list the NAMED
25035
25219
  Include only NAMED entities, skip generic/common nouns. A topic must identify a specific thing the user could recognize by name; if it would be equally true of thousands of unrelated memories, leave it out:
25036
25220
  - SKIP bare generic nouns even when the memory capitalizes them or a calendar entry is titled that way \u2014 "Home", "Work", "Meeting", "Lunch", "Birthday", "Appointment", "Trip", "Today", "Friday", "March" are NOT topics.
25037
25221
  - KEEP the specific thing instead, when the memory names one: "Blue Bottle on Valencia" over "cafe", "Chicago Marathon" over "event", "Hollowpoint Labs" over "work".
25222
+ - SKIP identifiers and numbers \u2014 addresses, hashes, keys, account or order numbers, balances, prices, amounts and position sizes are NOT topics. Use the general subject instead: "Solana" or "trading" rather than "3.5 SOL" or an address.
25038
25223
  - Prefer 0 entities over a weak one. A memory whose only candidate is a generic noun has NO entities.
25039
25224
  ${ENTITY_KIND_GUIDELINES}
25040
25225
 
@@ -25140,8 +25325,8 @@ List each memory's named entities.`,
25140
25325
  }
25141
25326
  function restoreEntities(entities, redactor) {
25142
25327
  return entities.flatMap((e) => {
25143
- const restored = redactor.restoreForStorage(e.name);
25144
- return restored.unresolved ? [] : [{ ...e, name: restored.text }];
25328
+ const name = restoreEntityName(e.name, redactor);
25329
+ return name === null ? [] : [{ ...e, name }];
25145
25330
  });
25146
25331
  }
25147
25332
  function parseTopicResponse(parsed, validIds) {
@@ -37500,6 +37685,7 @@ function useCredits(options = {}) {
37500
37685
  const baseUrlRef = useRef5(baseUrl);
37501
37686
  const onErrorRef = useRef5(onError);
37502
37687
  const abortControllerRef = useRef5(null);
37688
+ const hasFetchedRef = useRef5(false);
37503
37689
  useEffect6(() => {
37504
37690
  getTokenRef.current = getToken;
37505
37691
  baseUrlRef.current = baseUrl;
@@ -37507,6 +37693,7 @@ function useCredits(options = {}) {
37507
37693
  });
37508
37694
  useEffect6(() => {
37509
37695
  return () => {
37696
+ hasFetchedRef.current = false;
37510
37697
  if (abortControllerRef.current) {
37511
37698
  abortControllerRef.current.abort();
37512
37699
  abortControllerRef.current = null;
@@ -37554,14 +37741,14 @@ function useCredits(options = {}) {
37554
37741
  headers,
37555
37742
  signal
37556
37743
  });
37744
+ if (signal.aborted) return;
37557
37745
  if (response.error) {
37558
37746
  const errorMsg = response.error.error ?? "Failed to fetch credit balance";
37559
- throw new Error(errorMsg);
37747
+ throw Object.assign(new Error(errorMsg), { cause: response.error });
37560
37748
  }
37561
- if (signal.aborted) return;
37562
37749
  setBalance(response.data ?? null);
37563
37750
  } catch (err) {
37564
- if (err instanceof Error && err.name === "AbortError") return;
37751
+ if (signal.aborted || err instanceof Error && err.name === "AbortError") return;
37565
37752
  handleError(err);
37566
37753
  } finally {
37567
37754
  stopLoading();
@@ -37623,7 +37810,6 @@ function useCredits(options = {}) {
37623
37810
  },
37624
37811
  [getHeaders, handleError, startLoading, stopLoading]
37625
37812
  );
37626
- const hasFetchedRef = useRef5(false);
37627
37813
  useEffect6(() => {
37628
37814
  if (autoFetch && !hasFetchedRef.current) {
37629
37815
  hasFetchedRef.current = true;
@@ -39553,6 +39739,8 @@ function useSubscription(options = {}) {
39553
39739
  const baseUrlRef = useRef8(baseUrl);
39554
39740
  const onErrorRef = useRef8(onError);
39555
39741
  const abortControllerRef = useRef8(null);
39742
+ const hasFetchedRef = useRef8(false);
39743
+ const loadingCountRef = useRef8(0);
39556
39744
  useEffect12(() => {
39557
39745
  getTokenRef.current = getToken;
39558
39746
  baseUrlRef.current = baseUrl;
@@ -39560,12 +39748,21 @@ function useSubscription(options = {}) {
39560
39748
  });
39561
39749
  useEffect12(() => {
39562
39750
  return () => {
39751
+ hasFetchedRef.current = false;
39563
39752
  if (abortControllerRef.current) {
39564
39753
  abortControllerRef.current.abort();
39565
39754
  abortControllerRef.current = null;
39566
39755
  }
39567
39756
  };
39568
39757
  }, []);
39758
+ const startLoading = useCallback18(() => {
39759
+ loadingCountRef.current++;
39760
+ setIsLoading(true);
39761
+ }, []);
39762
+ const stopLoading = useCallback18(() => {
39763
+ loadingCountRef.current = Math.max(0, loadingCountRef.current - 1);
39764
+ setIsLoading(loadingCountRef.current > 0);
39765
+ }, []);
39569
39766
  const getHeaders = useCallback18(async () => {
39570
39767
  const headers = {};
39571
39768
  if (getTokenRef.current) {
@@ -39589,7 +39786,7 @@ function useSubscription(options = {}) {
39589
39786
  const abortController = new AbortController();
39590
39787
  abortControllerRef.current = abortController;
39591
39788
  const signal = abortController.signal;
39592
- setIsLoading(true);
39789
+ startLoading();
39593
39790
  setError(null);
39594
39791
  try {
39595
39792
  const headers = await getHeaders();
@@ -39599,33 +39796,31 @@ function useSubscription(options = {}) {
39599
39796
  headers,
39600
39797
  signal
39601
39798
  });
39799
+ if (signal.aborted) return;
39602
39800
  if (response.error) {
39603
39801
  const errorMsg = response.error.error ?? "Failed to fetch subscription status";
39604
- throw new Error(errorMsg);
39802
+ throw Object.assign(new Error(errorMsg), { cause: response.error });
39605
39803
  }
39606
- if (signal.aborted) return;
39607
39804
  setStatus(response.data ?? null);
39608
39805
  } catch (err) {
39609
- if (err instanceof Error && err.name === "AbortError") {
39806
+ if (signal.aborted || err instanceof Error && err.name === "AbortError") {
39610
39807
  return;
39611
39808
  }
39612
39809
  handleError(err);
39613
39810
  } finally {
39614
- if (!signal.aborted) {
39615
- setIsLoading(false);
39616
- }
39811
+ stopLoading();
39617
39812
  if (abortControllerRef.current === abortController) {
39618
39813
  abortControllerRef.current = null;
39619
39814
  }
39620
39815
  }
39621
- }, [getHeaders, handleError]);
39816
+ }, [getHeaders, handleError, startLoading, stopLoading]);
39622
39817
  const refetch = useCallback18(async () => {
39623
39818
  setStatus(null);
39624
39819
  await fetchStatus();
39625
39820
  }, [fetchStatus]);
39626
39821
  const createCheckoutSession = useCallback18(
39627
39822
  async (opts) => {
39628
- setIsLoading(true);
39823
+ startLoading();
39629
39824
  setError(null);
39630
39825
  try {
39631
39826
  const headers = await getHeaders();
@@ -39648,14 +39843,14 @@ function useSubscription(options = {}) {
39648
39843
  handleError(err);
39649
39844
  return null;
39650
39845
  } finally {
39651
- setIsLoading(false);
39846
+ stopLoading();
39652
39847
  }
39653
39848
  },
39654
- [getHeaders, handleError]
39849
+ [getHeaders, handleError, startLoading, stopLoading]
39655
39850
  );
39656
39851
  const openCustomerPortal = useCallback18(
39657
39852
  async (opts) => {
39658
- setIsLoading(true);
39853
+ startLoading();
39659
39854
  setError(null);
39660
39855
  try {
39661
39856
  const headers = await getHeaders();
@@ -39675,13 +39870,13 @@ function useSubscription(options = {}) {
39675
39870
  handleError(err);
39676
39871
  return null;
39677
39872
  } finally {
39678
- setIsLoading(false);
39873
+ stopLoading();
39679
39874
  }
39680
39875
  },
39681
- [getHeaders, handleError]
39876
+ [getHeaders, handleError, startLoading, stopLoading]
39682
39877
  );
39683
39878
  const cancelSubscription = useCallback18(async () => {
39684
- setIsLoading(true);
39879
+ startLoading();
39685
39880
  setError(null);
39686
39881
  try {
39687
39882
  const headers = await getHeaders();
@@ -39699,11 +39894,11 @@ function useSubscription(options = {}) {
39699
39894
  handleError(err);
39700
39895
  return null;
39701
39896
  } finally {
39702
- setIsLoading(false);
39897
+ stopLoading();
39703
39898
  }
39704
- }, [getHeaders, handleError, fetchStatus]);
39899
+ }, [getHeaders, handleError, startLoading, stopLoading, fetchStatus]);
39705
39900
  const renewSubscription = useCallback18(async () => {
39706
- setIsLoading(true);
39901
+ startLoading();
39707
39902
  setError(null);
39708
39903
  try {
39709
39904
  const headers = await getHeaders();
@@ -39721,10 +39916,9 @@ function useSubscription(options = {}) {
39721
39916
  handleError(err);
39722
39917
  return null;
39723
39918
  } finally {
39724
- setIsLoading(false);
39919
+ stopLoading();
39725
39920
  }
39726
- }, [getHeaders, handleError, fetchStatus]);
39727
- const hasFetchedRef = useRef8(false);
39921
+ }, [getHeaders, handleError, startLoading, stopLoading, fetchStatus]);
39728
39922
  useEffect12(() => {
39729
39923
  if (autoFetch && !hasFetchedRef.current) {
39730
39924
  hasFetchedRef.current = true;
@@ -40288,6 +40482,8 @@ function useWalletBinding(options = {}) {
40288
40482
  const baseUrlRef = useRef12(baseUrl);
40289
40483
  const onErrorRef = useRef12(onError);
40290
40484
  const abortControllerRef = useRef12(null);
40485
+ const hasFetchedRef = useRef12(false);
40486
+ const loadingCountRef = useRef12(0);
40291
40487
  useEffect14(() => {
40292
40488
  getTokenRef.current = getToken;
40293
40489
  baseUrlRef.current = baseUrl;
@@ -40295,12 +40491,21 @@ function useWalletBinding(options = {}) {
40295
40491
  });
40296
40492
  useEffect14(() => {
40297
40493
  return () => {
40494
+ hasFetchedRef.current = false;
40298
40495
  if (abortControllerRef.current) {
40299
40496
  abortControllerRef.current.abort();
40300
40497
  abortControllerRef.current = null;
40301
40498
  }
40302
40499
  };
40303
40500
  }, []);
40501
+ const startLoading = useCallback22(() => {
40502
+ loadingCountRef.current++;
40503
+ setIsLoading(true);
40504
+ }, []);
40505
+ const stopLoading = useCallback22(() => {
40506
+ loadingCountRef.current = Math.max(0, loadingCountRef.current - 1);
40507
+ setIsLoading(loadingCountRef.current > 0);
40508
+ }, []);
40304
40509
  const getHeaders = useCallback22(async () => {
40305
40510
  const headers = {};
40306
40511
  if (getTokenRef.current) {
@@ -40324,7 +40529,7 @@ function useWalletBinding(options = {}) {
40324
40529
  const abortController = new AbortController();
40325
40530
  abortControllerRef.current = abortController;
40326
40531
  const signal = abortController.signal;
40327
- setIsLoading(true);
40532
+ startLoading();
40328
40533
  setError(null);
40329
40534
  try {
40330
40535
  const headers = await getHeaders();
@@ -40334,34 +40539,32 @@ function useWalletBinding(options = {}) {
40334
40539
  headers,
40335
40540
  signal
40336
40541
  });
40542
+ if (signal.aborted) return;
40337
40543
  if (response.error) {
40338
40544
  const errorMsg = response.error.error ?? "Failed to fetch bound wallets";
40339
- throw new Error(errorMsg);
40545
+ throw Object.assign(new Error(errorMsg), { cause: response.error });
40340
40546
  }
40341
- if (signal.aborted) return;
40342
40547
  setWallets(response.data?.wallets ?? []);
40343
40548
  setTotals(response.data?.totals ?? null);
40344
40549
  } catch (err) {
40345
- if (err instanceof Error && err.name === "AbortError") {
40550
+ if (signal.aborted || err instanceof Error && err.name === "AbortError") {
40346
40551
  return;
40347
40552
  }
40348
40553
  handleError(err);
40349
40554
  } finally {
40350
- if (!signal.aborted) {
40351
- setIsLoading(false);
40352
- }
40555
+ stopLoading();
40353
40556
  if (abortControllerRef.current === abortController) {
40354
40557
  abortControllerRef.current = null;
40355
40558
  }
40356
40559
  }
40357
- }, [getHeaders, handleError]);
40560
+ }, [getHeaders, handleError, startLoading, stopLoading]);
40358
40561
  const refetch = useCallback22(async () => {
40359
40562
  setWallets([]);
40360
40563
  setTotals(null);
40361
40564
  await fetchBinding();
40362
40565
  }, [fetchBinding]);
40363
40566
  const getNonce = useCallback22(async () => {
40364
- setIsLoading(true);
40567
+ startLoading();
40365
40568
  setError(null);
40366
40569
  try {
40367
40570
  const headers = await getHeaders();
@@ -40378,12 +40581,12 @@ function useWalletBinding(options = {}) {
40378
40581
  handleError(err);
40379
40582
  return null;
40380
40583
  } finally {
40381
- setIsLoading(false);
40584
+ stopLoading();
40382
40585
  }
40383
- }, [getHeaders, handleError]);
40586
+ }, [getHeaders, handleError, startLoading, stopLoading]);
40384
40587
  const bindWallet = useCallback22(
40385
40588
  async (request) => {
40386
- setIsLoading(true);
40589
+ startLoading();
40387
40590
  setError(null);
40388
40591
  try {
40389
40592
  const headers = await getHeaders();
@@ -40402,14 +40605,14 @@ function useWalletBinding(options = {}) {
40402
40605
  handleError(err);
40403
40606
  return null;
40404
40607
  } finally {
40405
- setIsLoading(false);
40608
+ stopLoading();
40406
40609
  }
40407
40610
  },
40408
- [getHeaders, handleError, fetchBinding]
40611
+ [getHeaders, handleError, startLoading, stopLoading, fetchBinding]
40409
40612
  );
40410
40613
  const unbindWallet = useCallback22(
40411
40614
  async (address) => {
40412
- setIsLoading(true);
40615
+ startLoading();
40413
40616
  setError(null);
40414
40617
  try {
40415
40618
  const headers = await getHeaders();
@@ -40428,12 +40631,11 @@ function useWalletBinding(options = {}) {
40428
40631
  handleError(err);
40429
40632
  return false;
40430
40633
  } finally {
40431
- setIsLoading(false);
40634
+ stopLoading();
40432
40635
  }
40433
40636
  },
40434
- [getHeaders, handleError, fetchBinding]
40637
+ [getHeaders, handleError, startLoading, stopLoading, fetchBinding]
40435
40638
  );
40436
- const hasFetchedRef = useRef12(false);
40437
40639
  useEffect14(() => {
40438
40640
  if (autoFetch && !hasFetchedRef.current) {
40439
40641
  hasFetchedRef.current = true;
@@ -40773,6 +40975,7 @@ export {
40773
40975
  isSupportedFile,
40774
40976
  isSupportedMediaType,
40775
40977
  linkMemoryEntitiesOp,
40978
+ loadSettings,
40776
40979
  localChatBackend,
40777
40980
  maskScopedEmbeddingCache,
40778
40981
  maxVaultAttachmentBytes,
@@ -40820,6 +41023,7 @@ export {
40820
41023
  resumeStream,
40821
41024
  retain,
40822
41025
  revokeNotionAccess,
41026
+ saveSetting,
40823
41027
  savedToolToStored,
40824
41028
  scoreProfileSalience,
40825
41029
  screenCandidatesForInjection,
@@ -1084,6 +1084,7 @@ function notifyConsolidationFallback(reason, onFallback, detail) {
1084
1084
  export {
1085
1085
  getLogger,
1086
1086
  taskTypeHeader,
1087
+ PII_PATTERNS,
1087
1088
  resolvePiiRedactor,
1088
1089
  createStreamingDeAnonymizer,
1089
1090
  validateEndpointOverride,
@@ -4,7 +4,7 @@ import {
4
4
  notifyConsolidationFallback,
5
5
  requiresResponsesTransport,
6
6
  resolvePiiRedactor
7
- } from "./chunk-BIMEZT3O.mjs";
7
+ } from "./chunk-JEY3L7WD.mjs";
8
8
  import "./chunk-3RPGXXPZ.mjs";
9
9
 
10
10
  // src/lib/memory/consolidate.ts