@anuma/sdk 2.0.1 → 2.2.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.
@@ -72,6 +72,7 @@ import {
72
72
  getEncryptionKey,
73
73
  getImageModel,
74
74
  getMemoriesByEntityNamesOp,
75
+ getMemoriesNeedingTopicExtractionOp,
75
76
  getMessageCountOp,
76
77
  getMessageSkeletonsOp,
77
78
  getMessagesOp,
@@ -101,6 +102,7 @@ import {
101
102
  postAuthOauthByProviderRevoke,
102
103
  preEmbedVaultMemories,
103
104
  recall,
105
+ replaceMemoryEntitiesGuardedOp,
104
106
  requestEncryptionKey,
105
107
  requestKeyPair,
106
108
  resolveStoredUserContent,
@@ -109,6 +111,7 @@ import {
109
111
  searchVaultMemories,
110
112
  setMemoryEntitiesOp,
111
113
  shouldChunkMessage,
114
+ stampTopicsExtractedAtOp,
112
115
  stripToolCalls,
113
116
  updateConversationPinnedOp,
114
117
  updateConversationProjectOp,
@@ -120,8 +123,9 @@ import {
120
123
  updateMessageFileIdsOp,
121
124
  updateVaultMemoryEmbeddingOp,
122
125
  updateVaultMemoryOp,
123
- useEncryption
124
- } from "./chunk-63IW5BS5.mjs";
126
+ useEncryption,
127
+ vaultMemoryToStored
128
+ } from "./chunk-KRNJVLI6.mjs";
125
129
  import {
126
130
  PiiRedactor,
127
131
  createStreamingDeAnonymizer,
@@ -6659,6 +6663,9 @@ __decorateClass([
6659
6663
  __decorateClass([
6660
6664
  field3("topics_user_managed")
6661
6665
  ], VaultMemory.prototype, "topicsUserManaged", 2);
6666
+ __decorateClass([
6667
+ field3("topics_extracted_at")
6668
+ ], VaultMemory.prototype, "topicsExtractedAt", 2);
6662
6669
  __decorateClass([
6663
6670
  readonly2,
6664
6671
  date3("created_at")
@@ -6875,7 +6882,7 @@ async function isMemoryTopicsUserManaged(ctx, memoryId) {
6875
6882
  return true;
6876
6883
  }
6877
6884
  }
6878
- var DEFAULT_MODEL = "gpt-oss/gpt-oss-120b";
6885
+ var DEFAULT_EXTRACTION_MODEL = "gpt-oss/gpt-oss-120b";
6879
6886
  var DEFAULT_MIN_CONFIDENCE = 0.7;
6880
6887
  var MAX_CONTENT_LENGTH = 200;
6881
6888
  var MIN_CONTENT_LENGTH = 3;
@@ -6888,6 +6895,16 @@ var FACT_TYPES = [
6888
6895
  "constraint",
6889
6896
  "other"
6890
6897
  ];
6898
+ var ENTITY_KIND_GUIDELINES = `Choose the MOST SPECIFIC kind:
6899
+ - person: a named individual ("Sara", "Dr. Lee")
6900
+ - organization: a company, team, school, or group ("Google", "the Warriors", "Stanford")
6901
+ - place: a geographic location or venue ("San Francisco", "Blue Bottle on Valencia")
6902
+ - event: a dated or nameable occurrence ("Chicago Marathon", "the Japan trip", "their wedding")
6903
+ - product: a named app, tool, brand, device, book, film, or other media title ("Linear", "iPhone", "Dune", "Ableton")
6904
+ - thing: a concrete physical object that isn't a branded product ("road bike", "sourdough starter")
6905
+ - concept: a topic, skill, field, language, or idea ("machine learning", "Spanish", "async communication")
6906
+ - other: a named entity that genuinely fits none of the above \u2014 use sparingly
6907
+ Prefer organization / product / event / place over the generic "thing"; fall back to "thing" or "other" only when no specific kind fits.`;
6891
6908
  var SYSTEM_PROMPT = `You extract durable user facts from conversations for a personal memory system.
6892
6909
 
6893
6910
  A "durable fact" is something the user shared about themselves that should still be true in future conversations. Examples that ARE durable:
@@ -6916,16 +6933,7 @@ For each durable fact, output:
6916
6933
  - type: one of identity | preference | relationship | plan | ongoing_context | constraint | other
6917
6934
  - confidence: 0.0-1.0; how sure you are this is durable AND true. Only include facts >= 0.7.
6918
6935
  - sourceMessageIds: which message IDs from the conversation contained the evidence
6919
- - entities: named entities mentioned, each as an object { "name": string, "kind": one of "person" | "organization" | "place" | "event" | "product" | "thing" | "concept" | "other" }. Optional \u2014 include only NAMED entities, skip generic/common nouns. Choose the MOST SPECIFIC kind:
6920
- - person: a named individual ("Sara", "Dr. Lee")
6921
- - organization: a company, team, school, or group ("Google", "the Warriors", "Stanford")
6922
- - place: a geographic location or venue ("San Francisco", "Blue Bottle on Valencia")
6923
- - event: a dated or nameable occurrence ("Chicago Marathon", "the Japan trip", "their wedding")
6924
- - product: a named app, tool, brand, device, book, film, or other media title ("Linear", "iPhone", "Dune", "Ableton")
6925
- - thing: a concrete physical object that isn't a branded product ("road bike", "sourdough starter")
6926
- - concept: a topic, skill, field, language, or idea ("machine learning", "Spanish", "async communication")
6927
- - other: a named entity that genuinely fits none of the above \u2014 use sparingly
6928
- Prefer organization / product / event / place over the generic "thing"; fall back to "thing" or "other" only when no specific kind fits. Examples:
6936
+ - entities: named entities mentioned, each as an object { "name": string, "kind": one of "person" | "organization" | "place" | "event" | "product" | "thing" | "concept" | "other" }. Optional \u2014 include only NAMED entities, skip generic/common nouns. ${ENTITY_KIND_GUIDELINES} Examples:
6929
6937
  - "started a new job at Hollowpoint Labs and I'm learning Haskell for it" \u2192 entities: [{ "name": "Hollowpoint Labs", "kind": "organization" }, { "name": "Haskell", "kind": "concept" }]
6930
6938
  - "running the Berlin Half in May and I track workouts in Whoop" \u2192 entities: [{ "name": "Berlin Half", "kind": "event" }, { "name": "Whoop", "kind": "product" }]
6931
6939
  - eventTime: when the event in this fact occurs/occurred. Resolve relative phrases ("yesterday", "next week") against the current date given in the user message. Output one of:
@@ -6951,7 +6959,7 @@ async function extractFacts(messages, options) {
6951
6959
  ...options.apiKey !== void 0 && { apiKey: options.apiKey },
6952
6960
  ...options.getToken !== void 0 && { getToken: options.getToken },
6953
6961
  ...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
6954
- model: options.model ?? DEFAULT_MODEL,
6962
+ model: options.model ?? DEFAULT_EXTRACTION_MODEL,
6955
6963
  systemPrompt: SYSTEM_PROMPT,
6956
6964
  userMessage: `Today's date is ${today}. Resolve any relative dates ("yesterday", "next week") against it.
6957
6965
 
@@ -7045,7 +7053,9 @@ async function extractAndRetain(messages, retainCtx, options) {
7045
7053
  if (options.entityCtx && candidate.entities.length > 0) {
7046
7054
  try {
7047
7055
  if (!await isMemoryTopicsUserManaged(options.entityCtx, result.memoryId)) {
7048
- await linkMemoryEntitiesOp(options.entityCtx, result.memoryId, candidate.entities);
7056
+ await linkMemoryEntitiesOp(options.entityCtx, result.memoryId, candidate.entities, {
7057
+ unlessTopicsUserManaged: true
7058
+ });
7049
7059
  }
7050
7060
  } catch (err) {
7051
7061
  log.warn("[memory/extract] linkMemoryEntitiesOp failed", err);
@@ -7440,7 +7450,7 @@ function createRecallTool(ctx, toolOptions, callbacks) {
7440
7450
 
7441
7451
  // src/lib/memory/reflect.ts
7442
7452
  var DEFAULT_BASE_URL = BASE_URL;
7443
- var DEFAULT_MODEL2 = "anthropic/claude-sonnet-4-6";
7453
+ var DEFAULT_MODEL = "anthropic/claude-sonnet-4-6";
7444
7454
  var DEFAULT_MAX_TOKENS = 4096;
7445
7455
  var REQUEST_TIMEOUT_MS = 6e4;
7446
7456
  var DEFAULT_SYSTEM_PROMPT = `You are a personal assistant with access to the user's memory. Answer the user's question using the supplied memories as evidence.
@@ -7472,7 +7482,7 @@ async function reflect(query, ctx, options) {
7472
7482
  const evidence = recalled.memories.map((m, i) => `[${i + 1}] (id: ${m.id}, kind: ${m.kind})
7473
7483
  ${m.content}`).join("\n\n");
7474
7484
  const baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;
7475
- const model = options.llmModel ?? DEFAULT_MODEL2;
7485
+ const model = options.llmModel ?? DEFAULT_MODEL;
7476
7486
  const wantsStructured = !!options.responseSchema;
7477
7487
  const sendResponseFormat = wantsStructured && supportsResponseFormat(model, "json_schema");
7478
7488
  const basePrompt = options.systemPrompt ?? DEFAULT_SYSTEM_PROMPT;
@@ -7582,6 +7592,163 @@ function parseAnswer(body, base, parseSchema) {
7582
7592
  };
7583
7593
  }
7584
7594
 
7595
+ // src/lib/memory/topicExtract.ts
7596
+ var TOPIC_EXTRACTION_BATCH_SIZE = 10;
7597
+ var MAX_CHARS_PER_MEMORY = 300;
7598
+ var MAX_VOCABULARY_NAMES = 100;
7599
+ var SYSTEM_PROMPT2 = `You assign topics to saved memories for a personal memory system.
7600
+
7601
+ Each memory is a short statement about the user. For each memory, list the NAMED entities it mentions \u2014 these become the memory's topics, used to connect related memories in a knowledge graph.
7602
+
7603
+ Include only NAMED entities, skip generic/common nouns. ${ENTITY_KIND_GUIDELINES}
7604
+
7605
+ Output strict JSON: {"memories": [{"id": string, "entities": [{"name": string, "kind": string}]}]}
7606
+ - exactly one element per input memory, echoing its id verbatim
7607
+ - "entities" may be empty when a memory mentions no named entities \u2014 most short memories have 0-3
7608
+ No prose.`;
7609
+ async function extractEntitiesForMemories(memories, options) {
7610
+ const out = /* @__PURE__ */ new Map();
7611
+ if (memories.length === 0) return out;
7612
+ const redactor = resolvePiiRedactor(options.piiRedaction);
7613
+ const vocabulary = (options.existingEntityNames ?? []).filter((n) => n.trim().length > 0).slice(0, MAX_VOCABULARY_NAMES).map((n) => redactor ? redactor.redactText(n).text : n);
7614
+ const vocabularyNote = vocabulary.length > 0 ? `The user's existing topics: ${vocabulary.join(", ")}.
7615
+ When a memory refers to one of these, reuse the EXACT existing name (same spelling and casing) instead of a variant.
7616
+
7617
+ ` : "";
7618
+ for (let i = 0; i < memories.length; i += TOPIC_EXTRACTION_BATCH_SIZE) {
7619
+ const batch = memories.slice(i, i + TOPIC_EXTRACTION_BATCH_SIZE);
7620
+ const listing = batch.map((m) => {
7621
+ const content = m.content.slice(0, MAX_CHARS_PER_MEMORY);
7622
+ return `[${m.id}] ${redactor ? redactor.redactText(content).text : content}`;
7623
+ }).join("\n");
7624
+ const parsed = await callPortalJsonCompletion({
7625
+ ...options.apiKey !== void 0 && { apiKey: options.apiKey },
7626
+ ...options.getToken !== void 0 && { getToken: options.getToken },
7627
+ ...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
7628
+ model: options.model ?? DEFAULT_EXTRACTION_MODEL,
7629
+ systemPrompt: SYSTEM_PROMPT2,
7630
+ userMessage: `${vocabularyNote}Memories:
7631
+ ${listing}
7632
+
7633
+ List each memory's named entities.`,
7634
+ tag: "memory/topics",
7635
+ ...options.fetchFn && { fetchFn: options.fetchFn },
7636
+ ...options.maxAttempts !== void 0 && { maxAttempts: options.maxAttempts },
7637
+ ...options.timeoutMs !== void 0 && { timeoutMs: options.timeoutMs },
7638
+ ...options.totalTimeoutMs !== void 0 && { totalTimeoutMs: options.totalTimeoutMs },
7639
+ ...options.backoffMs && { backoffMs: options.backoffMs }
7640
+ });
7641
+ if (parsed === null) {
7642
+ getLogger().warn(
7643
+ `[memory/topics] batch of ${batch.length} failed after retries \u2014 will retry next sweep`
7644
+ );
7645
+ continue;
7646
+ }
7647
+ const validIds = new Set(batch.map((m) => m.id));
7648
+ const byId = parseTopicResponse(parsed, validIds);
7649
+ if (byId === null) {
7650
+ getLogger().warn(
7651
+ `[memory/topics] batch of ${batch.length} returned an unrecognized shape \u2014 will retry next sweep`
7652
+ );
7653
+ continue;
7654
+ }
7655
+ for (const m of batch) {
7656
+ const entities = byId.get(m.id);
7657
+ if (entities === void 0) {
7658
+ continue;
7659
+ }
7660
+ out.set(m.id, redactor ? restoreEntities(entities, redactor) : entities);
7661
+ }
7662
+ }
7663
+ return out;
7664
+ }
7665
+ function restoreEntities(entities, redactor) {
7666
+ return entities.map((e) => ({ kind: e.kind, restored: redactor.restoreForStorage(e.name) })).filter((e) => !e.restored.unresolved).map(
7667
+ (e) => e.kind !== void 0 ? { name: e.restored.text, kind: e.kind } : { name: e.restored.text }
7668
+ );
7669
+ }
7670
+ function parseTopicResponse(parsed, validIds) {
7671
+ if (typeof parsed !== "object" || parsed === null) return null;
7672
+ const list = parsed.memories;
7673
+ if (!Array.isArray(list)) return null;
7674
+ const out = /* @__PURE__ */ new Map();
7675
+ for (const raw of list) {
7676
+ if (typeof raw !== "object" || raw === null) continue;
7677
+ const obj = raw;
7678
+ if (typeof obj.id !== "string" || !validIds.has(obj.id) || out.has(obj.id)) continue;
7679
+ const entities = Array.isArray(obj.entities) ? parseEntities(obj.entities) : [];
7680
+ out.set(obj.id, entities);
7681
+ }
7682
+ return out;
7683
+ }
7684
+ async function extractAndLinkEntitiesForMemoriesOp(ctx, memoryIds, options) {
7685
+ const entityCtx = ctx.entityCtx;
7686
+ if (!entityCtx) {
7687
+ throw new Error("extractAndLinkEntitiesForMemoriesOp requires ctx.entityCtx");
7688
+ }
7689
+ const log = getLogger();
7690
+ const extractedAt = options.now ?? Date.now();
7691
+ const skippedIds = [];
7692
+ const inputs = [];
7693
+ for (const id of memoryIds) {
7694
+ let record;
7695
+ try {
7696
+ record = await ctx.vaultMemoryCollection.find(id);
7697
+ } catch {
7698
+ skippedIds.push(id);
7699
+ continue;
7700
+ }
7701
+ if (record.isDeleted || ctx.userId !== void 0 && record.userId !== ctx.userId || record.topicsUserManaged) {
7702
+ skippedIds.push(id);
7703
+ continue;
7704
+ }
7705
+ try {
7706
+ const stored = await vaultMemoryToStored(
7707
+ record,
7708
+ ctx.walletAddress,
7709
+ ctx.signMessage,
7710
+ ctx.embeddedWalletSigner
7711
+ );
7712
+ inputs.push({ id, content: stored.content });
7713
+ } catch (err) {
7714
+ log.warn("[memory/topics] failed to load memory for extraction", err);
7715
+ skippedIds.push(id);
7716
+ }
7717
+ }
7718
+ const entitiesByMemory = await extractEntitiesForMemories(inputs, options);
7719
+ const toStamp = [];
7720
+ for (const input of inputs) {
7721
+ const entities = entitiesByMemory.get(input.id);
7722
+ if (entities === void 0) {
7723
+ skippedIds.push(input.id);
7724
+ continue;
7725
+ }
7726
+ try {
7727
+ const linked = await replaceMemoryEntitiesGuardedOp(entityCtx, input.id, entities);
7728
+ if (linked === null) {
7729
+ skippedIds.push(input.id);
7730
+ entitiesByMemory.delete(input.id);
7731
+ continue;
7732
+ }
7733
+ } catch (err) {
7734
+ log.warn("[memory/topics] replaceMemoryEntitiesGuardedOp failed", err);
7735
+ skippedIds.push(input.id);
7736
+ entitiesByMemory.delete(input.id);
7737
+ continue;
7738
+ }
7739
+ toStamp.push(input.id);
7740
+ }
7741
+ const stampedIds = await stampTopicsExtractedAtOp(ctx, toStamp, extractedAt);
7742
+ const stampedSet = new Set(stampedIds);
7743
+ for (const id of toStamp) {
7744
+ if (!stampedSet.has(id)) {
7745
+ skippedIds.push(id);
7746
+ entitiesByMemory.delete(id);
7747
+ }
7748
+ }
7749
+ return { entitiesByMemory, stampedIds, skippedIds };
7750
+ }
7751
+
7585
7752
  // src/lib/memoryEngine/quantization.ts
7586
7753
  var INT8_MAX = 127;
7587
7754
  function quantizeEmbedding(v) {
@@ -11921,7 +12088,7 @@ __decorateClass([
11921
12088
  ], VaultFolder.prototype, "context", 2);
11922
12089
 
11923
12090
  // src/lib/db/schema.ts
11924
- var SDK_SCHEMA_VERSION = 35;
12091
+ var SDK_SCHEMA_VERSION = 36;
11925
12092
  var sdkSchema = appSchema2({
11926
12093
  version: SDK_SCHEMA_VERSION,
11927
12094
  tables: [
@@ -12042,7 +12209,11 @@ var sdkSchema = appSchema2({
12042
12209
  // When true, the user has manually set this memory's topics (entity
12043
12210
  // links). Auto-extraction then leaves its links alone — the user owns
12044
12211
  // them. Null/false = topics are auto-derived (default).
12045
- { name: "topics_user_managed", type: "boolean", isOptional: true }
12212
+ { name: "topics_user_managed", type: "boolean", isOptional: true },
12213
+ // Unix ms of the last LLM topic-extraction pass over this memory's
12214
+ // content. Null = never extracted standalone (legacy rows with entity
12215
+ // links are grandfathered — see getMemoriesNeedingTopicExtractionOp).
12216
+ { name: "topics_extracted_at", type: "number", isOptional: true }
12046
12217
  ]
12047
12218
  }),
12048
12219
  // Entity table — canonical names extracted from auto-extraction (W5).
@@ -12640,6 +12811,19 @@ var sdkMigrations = schemaMigrations2({
12640
12811
  ]
12641
12812
  })
12642
12813
  ]
12814
+ },
12815
+ // v35 -> v36: topics_extracted_at watermark on memory_vault. Existing rows
12816
+ // keep it NULL — rows that already have entity links are grandfathered as
12817
+ // extracted (no mass re-extraction on upgrade), rows without links are the
12818
+ // backfill target. See getMemoriesNeedingTopicExtractionOp.
12819
+ {
12820
+ toVersion: 36,
12821
+ steps: [
12822
+ addColumns2({
12823
+ table: "memory_vault",
12824
+ columns: [{ name: "topics_extracted_at", type: "number", isOptional: true }]
12825
+ })
12826
+ ]
12643
12827
  }
12644
12828
  ]
12645
12829
  });
@@ -14142,7 +14326,7 @@ function startObserve(entry, walletAddress) {
14142
14326
  isInitialEmission = false;
14143
14327
  }
14144
14328
  function subscribeUserSettings(database, walletAddress, listener) {
14145
- if (!walletAddress) return () => void 0;
14329
+ if (!database || !walletAddress) return () => void 0;
14146
14330
  const perDb = getOrCreatePerDb(database);
14147
14331
  let entry = perDb.get(walletAddress);
14148
14332
  if (!entry) {
@@ -14172,17 +14356,18 @@ function subscribeUserSettings(database, walletAddress, listener) {
14172
14356
  };
14173
14357
  }
14174
14358
  function getUserSettingsSnapshot(database, walletAddress) {
14175
- if (!walletAddress) return EMPTY_SNAPSHOT;
14359
+ if (!database || !walletAddress) return EMPTY_SNAPSHOT;
14176
14360
  return pool.get(database)?.get(walletAddress)?.snapshot ?? EMPTY_SNAPSHOT;
14177
14361
  }
14178
14362
  function patchUserSettingsSnapshot(database, walletAddress, patch) {
14179
- if (!walletAddress) return;
14363
+ if (!database || !walletAddress) return;
14180
14364
  const entry = pool.get(database)?.get(walletAddress);
14181
14365
  if (!entry) return;
14182
14366
  patchSnapshot(entry, patch);
14183
14367
  }
14184
14368
 
14185
14369
  // src/react/useSettings.ts
14370
+ var DB_NOT_READY = "Database not ready";
14186
14371
  function useSettings(options) {
14187
14372
  const { database, walletAddress } = options;
14188
14373
  const subscribe = useCallback7(
@@ -14195,24 +14380,25 @@ function useSettings(options) {
14195
14380
  );
14196
14381
  const snapshot = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
14197
14382
  const storageCtx = useMemo7(
14198
- () => ({
14383
+ () => database ? {
14199
14384
  database,
14200
14385
  userPreferencesCollection: database.get("userPreferences"),
14201
14386
  modelPreferencesCollection: database.get("modelPreferences")
14202
- }),
14387
+ } : null,
14203
14388
  [database]
14204
14389
  );
14205
14390
  const legacyStorageCtx = useMemo7(
14206
- () => ({
14391
+ () => database ? {
14207
14392
  database,
14208
14393
  modelPreferencesCollection: database.get("modelPreferences")
14209
- }),
14394
+ } : null,
14210
14395
  [database]
14211
14396
  );
14212
14397
  const getModelPreference = useCallback7(
14213
14398
  async (address) => {
14214
14399
  try {
14215
14400
  if (!address) throw new Error("Wallet address is required");
14401
+ if (!legacyStorageCtx) throw new Error(DB_NOT_READY);
14216
14402
  const result = await getModelPreferenceOp(legacyStorageCtx, address);
14217
14403
  return result;
14218
14404
  } catch (error) {
@@ -14225,6 +14411,7 @@ function useSettings(options) {
14225
14411
  async (address, models) => {
14226
14412
  try {
14227
14413
  if (!address) throw new Error("Wallet address is required");
14414
+ if (!legacyStorageCtx) throw new Error(DB_NOT_READY);
14228
14415
  const result = await setModelPreferenceOp(legacyStorageCtx, address, models);
14229
14416
  if (walletAddress && address === walletAddress) {
14230
14417
  patchUserSettingsSnapshot(database, walletAddress, { modelPreference: result });
@@ -14240,6 +14427,7 @@ function useSettings(options) {
14240
14427
  async (address) => {
14241
14428
  try {
14242
14429
  if (!address) throw new Error("Wallet address is required");
14430
+ if (!legacyStorageCtx) throw new Error(DB_NOT_READY);
14243
14431
  const deleted = await deleteModelPreferenceOp(legacyStorageCtx, address);
14244
14432
  if (deleted && walletAddress && address === walletAddress) {
14245
14433
  patchUserSettingsSnapshot(database, walletAddress, { modelPreference: null });
@@ -14255,6 +14443,7 @@ function useSettings(options) {
14255
14443
  async (address) => {
14256
14444
  try {
14257
14445
  if (!address) throw new Error("Wallet address is required");
14446
+ if (!storageCtx) throw new Error(DB_NOT_READY);
14258
14447
  const result = await getUserPreferenceOp(storageCtx, address);
14259
14448
  return result;
14260
14449
  } catch (error) {
@@ -14267,6 +14456,7 @@ function useSettings(options) {
14267
14456
  async (address, opts) => {
14268
14457
  try {
14269
14458
  if (!address) throw new Error("Wallet address is required");
14459
+ if (!storageCtx) throw new Error(DB_NOT_READY);
14270
14460
  const result = await setUserPreferenceOp(storageCtx, address, opts);
14271
14461
  if (walletAddress && address === walletAddress) {
14272
14462
  patchUserSettingsSnapshot(database, walletAddress, { userPreference: result });
@@ -14282,6 +14472,7 @@ function useSettings(options) {
14282
14472
  async (address, profile) => {
14283
14473
  try {
14284
14474
  if (!address) throw new Error("Wallet address is required");
14475
+ if (!storageCtx) throw new Error(DB_NOT_READY);
14285
14476
  const result = await updateProfileOp(storageCtx, address, profile);
14286
14477
  if (result && walletAddress && address === walletAddress) {
14287
14478
  patchUserSettingsSnapshot(database, walletAddress, { userPreference: result });
@@ -14297,6 +14488,7 @@ function useSettings(options) {
14297
14488
  async (address, personality) => {
14298
14489
  try {
14299
14490
  if (!address) throw new Error("Wallet address is required");
14491
+ if (!storageCtx) throw new Error(DB_NOT_READY);
14300
14492
  const result = await updatePersonalityOp(storageCtx, address, personality);
14301
14493
  if (result && walletAddress && address === walletAddress) {
14302
14494
  patchUserSettingsSnapshot(database, walletAddress, { userPreference: result });
@@ -14312,6 +14504,7 @@ function useSettings(options) {
14312
14504
  async (address, models) => {
14313
14505
  try {
14314
14506
  if (!address) throw new Error("Wallet address is required");
14507
+ if (!storageCtx) throw new Error(DB_NOT_READY);
14315
14508
  const result = await updateModelsOp(storageCtx, address, models);
14316
14509
  if (result && walletAddress && address === walletAddress) {
14317
14510
  patchUserSettingsSnapshot(database, walletAddress, { userPreference: result });
@@ -14327,6 +14520,7 @@ function useSettings(options) {
14327
14520
  async (address) => {
14328
14521
  try {
14329
14522
  if (!address) throw new Error("Wallet address is required");
14523
+ if (!storageCtx) throw new Error(DB_NOT_READY);
14330
14524
  const deleted = await deleteUserPreferenceOp(storageCtx, address);
14331
14525
  if (deleted && walletAddress && address === walletAddress) {
14332
14526
  patchUserSettingsSnapshot(database, walletAddress, { userPreference: null });
@@ -22283,6 +22477,7 @@ export {
22283
22477
  VaultMemory as StoredVaultMemoryModel,
22284
22478
  StreamExpiredError,
22285
22479
  THEME_ATTRS,
22480
+ TOPIC_EXTRACTION_BATCH_SIZE,
22286
22481
  TextProcessor,
22287
22482
  UIInteractionProvider,
22288
22483
  WalletPoller,
@@ -22374,7 +22569,9 @@ export {
22374
22569
  exportElementToPdf,
22375
22570
  exportMarkdownToPdf,
22376
22571
  exportPublicKey,
22572
+ extractAndLinkEntitiesForMemoriesOp,
22377
22573
  extractAndRetain,
22574
+ extractEntitiesForMemories,
22378
22575
  extractFacts,
22379
22576
  extractFileIds,
22380
22577
  fileExists,
@@ -22430,6 +22627,7 @@ export {
22430
22627
  getMediaOp,
22431
22628
  getMediaTypeFromMime,
22432
22629
  getMemoriesByEntityNamesOp,
22630
+ getMemoriesNeedingTopicExtractionOp,
22433
22631
  getNotionAccessToken,
22434
22632
  getNotionMCPUrl,
22435
22633
  getNumberAttr,
@@ -22510,6 +22708,7 @@ export {
22510
22708
  renderAnumaTree,
22511
22709
  renderElementToCanvas,
22512
22710
  replaceById,
22711
+ replaceMemoryEntitiesGuardedOp,
22513
22712
  requestEncryptionKey,
22514
22713
  requestKeyPair,
22515
22714
  resolveFilePlaceholders,
@@ -22535,6 +22734,7 @@ export {
22535
22734
  settingsStorageSchema,
22536
22735
  shouldChunkMessage,
22537
22736
  shouldRefreshTools,
22737
+ stampTopicsExtractedAtOp,
22538
22738
  startGithubAuth,
22539
22739
  startNotionAuth,
22540
22740
  storeCalendarPendingMessage,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  recall
3
- } from "./chunk-63IW5BS5.mjs";
3
+ } from "./chunk-KRNJVLI6.mjs";
4
4
  import "./chunk-DFVCS3QQ.mjs";
5
5
  import "./chunk-GYKJOWEO.mjs";
6
6
  export {