@anuma/sdk 6.31.4 → 6.33.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.
@@ -1595,6 +1595,7 @@ __export(index_exports, {
1595
1595
  createGitHubTools: () => createGitHubTools,
1596
1596
  createLlmDecayClassifier: () => createLlmDecayClassifier,
1597
1597
  createLlmNeighborRefiner: () => createLlmNeighborRefiner,
1598
+ createLocalMemoryStore: () => createLocalMemoryStore,
1598
1599
  createMediaBatchOp: () => createMediaBatchOp,
1599
1600
  createMediaOp: () => createMediaOp,
1600
1601
  createMemoryEngineTool: () => createMemoryEngineTool,
@@ -1653,6 +1654,7 @@ __export(index_exports, {
1653
1654
  extractEntitiesForMemories: () => extractEntitiesForMemories,
1654
1655
  extractFacts: () => extractFacts,
1655
1656
  extractFileIds: () => extractFileIds,
1657
+ extractMCPImageUrls: () => extractMCPImageUrls,
1656
1658
  fileExists: () => fileExists,
1657
1659
  findById: () => findById,
1658
1660
  findMatchingTools: () => findMatchingTools,
@@ -10603,6 +10605,7 @@ async function resumeStream(options) {
10603
10605
  // src/react/useChat.ts
10604
10606
  var import_react = require("react");
10605
10607
  init_clientConfig();
10608
+ init_logger();
10606
10609
  init_redactor();
10607
10610
  function useChat(options) {
10608
10611
  const {
@@ -10616,6 +10619,8 @@ function useChat(options) {
10616
10619
  onServerToolCall,
10617
10620
  onToolCallArgumentsDelta,
10618
10621
  onStepFinish,
10622
+ resumable,
10623
+ onStreamMeta,
10619
10624
  apiType: defaultApiType = "auto",
10620
10625
  smoothing,
10621
10626
  preProcessors,
@@ -10625,25 +10630,37 @@ function useChat(options) {
10625
10630
  const [isLoading, setIsLoading] = (0, import_react.useState)(false);
10626
10631
  const abortControllerRef = (0, import_react.useRef)(null);
10627
10632
  const requestIdRef = (0, import_react.useRef)(0);
10633
+ const pendingInferenceRef = (0, import_react.useRef)(
10634
+ null
10635
+ );
10636
+ const cancelInference = (0, import_react.useCallback)(
10637
+ (inferenceId, requestToken) => {
10638
+ void (async () => {
10639
+ const token = requestToken ?? (getToken ? await getToken() : null);
10640
+ const response = await fetch(`${baseUrl}${streamCancelPath(inferenceId)}`, {
10641
+ method: "POST",
10642
+ headers: token ? { Authorization: `Bearer ${token}` } : void 0
10643
+ });
10644
+ if (!response.ok) throw new Error(`Stream cancellation failed: ${response.status}`);
10645
+ })().catch((error) => getLogger().warn("[useChat] stream cancel POST failed:", error));
10646
+ },
10647
+ [getToken, baseUrl]
10648
+ );
10628
10649
  const piiRedactorRef = (0, import_react.useRef)(null);
10629
10650
  if (piiRedaction === true && !piiRedactorRef.current) {
10630
10651
  piiRedactorRef.current = new PiiRedactor();
10631
10652
  }
10632
10653
  const resolvedPiiRedaction = piiRedaction === true ? piiRedactorRef.current : piiRedaction;
10633
10654
  const stop = (0, import_react.useCallback)(() => {
10655
+ const pending = pendingInferenceRef.current;
10656
+ pendingInferenceRef.current = null;
10657
+ pending?.cancel();
10634
10658
  if (abortControllerRef.current) {
10635
10659
  abortControllerRef.current.abort();
10636
10660
  abortControllerRef.current = null;
10637
10661
  }
10638
10662
  }, []);
10639
- (0, import_react.useEffect)(() => {
10640
- return () => {
10641
- if (abortControllerRef.current) {
10642
- abortControllerRef.current.abort();
10643
- abortControllerRef.current = null;
10644
- }
10645
- };
10646
- }, []);
10663
+ (0, import_react.useEffect)(() => stop, [stop]);
10647
10664
  const sendMessage = (0, import_react.useCallback)(
10648
10665
  async ({
10649
10666
  messages,
@@ -10669,13 +10686,12 @@ function useChat(options) {
10669
10686
  endpointOverride,
10670
10687
  piiRedaction: requestPiiRedaction
10671
10688
  }) => {
10672
- if (abortControllerRef.current) {
10673
- abortControllerRef.current.abort();
10674
- }
10689
+ stop();
10675
10690
  const abortController = new AbortController();
10676
10691
  abortControllerRef.current = abortController;
10677
10692
  const requestId = ++requestIdRef.current;
10678
10693
  setIsLoading(true);
10694
+ let succeeded = false;
10679
10695
  try {
10680
10696
  const tokenGetterValidation = validateTokenGetter(getToken);
10681
10697
  if (!tokenGetterValidation.valid) {
@@ -10738,6 +10754,22 @@ function useChat(options) {
10738
10754
  headers,
10739
10755
  apiType: requestApiType ?? defaultApiType,
10740
10756
  endpointOverride,
10757
+ resumable,
10758
+ onStreamMeta: resumable || onStreamMeta ? (meta) => {
10759
+ if (requestId !== requestIdRef.current || abortController.signal.aborted) {
10760
+ if (resumable) cancelInference(meta.inferenceId, token);
10761
+ return;
10762
+ }
10763
+ const previous = pendingInferenceRef.current;
10764
+ if (previous && previous.round === meta.round && previous.id !== meta.inferenceId)
10765
+ previous.cancel();
10766
+ pendingInferenceRef.current = {
10767
+ id: meta.inferenceId,
10768
+ round: meta.round,
10769
+ cancel: resumable ? () => cancelInference(meta.inferenceId, token) : () => void 0
10770
+ };
10771
+ onStreamMeta?.(meta);
10772
+ } : void 0,
10741
10773
  temperature,
10742
10774
  maxOutputTokens,
10743
10775
  tools,
@@ -10767,6 +10799,7 @@ function useChat(options) {
10767
10799
  piiRedaction: requestPiiRedaction ?? resolvedPiiRedaction,
10768
10800
  onPiiRedacted
10769
10801
  });
10802
+ succeeded = result.error === null;
10770
10803
  return result;
10771
10804
  } catch (err) {
10772
10805
  return createErrorResult(
@@ -10777,12 +10810,16 @@ function useChat(options) {
10777
10810
  if (requestIdRef.current === requestId) {
10778
10811
  setIsLoading(false);
10779
10812
  abortControllerRef.current = null;
10813
+ if (!succeeded) pendingInferenceRef.current?.cancel();
10814
+ pendingInferenceRef.current = null;
10780
10815
  }
10781
10816
  }
10782
10817
  },
10783
10818
  [
10784
10819
  getToken,
10785
10820
  baseUrl,
10821
+ stop,
10822
+ cancelInference,
10786
10823
  globalOnData,
10787
10824
  globalOnThinking,
10788
10825
  onFinish,
@@ -10791,6 +10828,8 @@ function useChat(options) {
10791
10828
  onServerToolCall,
10792
10829
  onToolCallArgumentsDelta,
10793
10830
  onStepFinish,
10831
+ resumable,
10832
+ onStreamMeta,
10794
10833
  defaultApiType,
10795
10834
  smoothing,
10796
10835
  preProcessors,
@@ -17164,7 +17203,10 @@ async function eagerEmbedContent(content, embeddingOptions, cache, vaultCtx, mem
17164
17203
  if (memoryId) cacheRowVector(cache, memoryId, Float32Array.from(embedding), updatedAt, content);
17165
17204
  if (vaultCtx && memoryId) {
17166
17205
  const currentModel = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
17167
- updateVaultMemoryEmbeddingOp(vaultCtx, memoryId, JSON.stringify(embedding), currentModel).catch(
17206
+ updateVaultMemoryEmbeddingOp(vaultCtx, memoryId, JSON.stringify(embedding), currentModel, {
17207
+ content,
17208
+ ...updatedAt !== void 0 && { updatedAt: updatedAt.getTime() }
17209
+ }).catch(
17168
17210
  // Silently swallow – SDK must not use console.*; embedding will be retried on next search
17169
17211
  () => {
17170
17212
  }
@@ -20703,6 +20745,353 @@ function parseAnswer(body, base, parseSchema) {
20703
20745
  };
20704
20746
  }
20705
20747
 
20748
+ // src/lib/memory/store/local.ts
20749
+ var import_watermelondb13 = require("@nozbe/watermelondb");
20750
+ init_logger();
20751
+
20752
+ // src/lib/memory/topicExtract.ts
20753
+ init_logger();
20754
+ init_redactor();
20755
+ init_portalLlm();
20756
+ var TOPIC_EXTRACTION_BATCH_SIZE = 10;
20757
+ var MAX_CHARS_PER_MEMORY = 300;
20758
+ var MAX_VOCABULARY_NAMES = 100;
20759
+ var MAX_COMPLETION_TOKENS = 8192;
20760
+ var SYSTEM_PROMPT6 = `You assign topics to saved memories for a personal memory system.
20761
+
20762
+ 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.
20763
+
20764
+ 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:
20765
+ - 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.
20766
+ - KEEP the specific thing instead, when the memory names one: "Blue Bottle on Valencia" over "cafe", "Chicago Marathon" over "event", "Hollowpoint Labs" over "work".
20767
+ - Prefer 0 entities over a weak one. A memory whose only candidate is a generic noun has NO entities.
20768
+ ${ENTITY_KIND_GUIDELINES}
20769
+
20770
+ Each memory below is written as "<id>: <text>". Output strict JSON: {"memories": [{"id": string, "entities": [{"name": string, "kind": string}]}]}
20771
+ - exactly one element per input memory; copy its id EXACTLY as written (the token before the first ": "), with no brackets, quotes, or extra characters
20772
+ - "entities" may be empty when a memory mentions no named entities \u2014 most short memories have 0-3
20773
+ No prose.`;
20774
+ async function extractEntitiesForMemories(memories, options) {
20775
+ const out = /* @__PURE__ */ new Map();
20776
+ if (memories.length === 0) return out;
20777
+ const redactor = resolvePiiRedactor(options.piiRedaction);
20778
+ const vocabulary = [];
20779
+ for (const name of (options.existingEntityNames ?? []).filter((n) => n.trim().length > 0).slice(0, MAX_VOCABULARY_NAMES)) {
20780
+ vocabulary.push(redactor ? (await redactor.redactTextAsync(name)).text : name);
20781
+ }
20782
+ const vocabularyNote = vocabulary.length > 0 ? `The user's existing topics: ${vocabulary.join(", ")}.
20783
+ When a memory refers to one of these, reuse the EXACT existing name (same spelling, casing, spacing and punctuation) instead of a variant \u2014 if "Foo.ai" is listed, never emit "Foo ai" or "Foo AI", and if "Jane Roe" is listed, emit that rather than a bare "Jane".
20784
+
20785
+ ` : "";
20786
+ for (let i = 0; i < memories.length; i += TOPIC_EXTRACTION_BATCH_SIZE) {
20787
+ const batch = memories.slice(i, i + TOPIC_EXTRACTION_BATCH_SIZE);
20788
+ const rows = [];
20789
+ for (const m of batch) {
20790
+ const content = m.content.slice(0, MAX_CHARS_PER_MEMORY).replace(/\s+/g, " ").trim();
20791
+ rows.push(`${m.id}: ${redactor ? (await redactor.redactTextAsync(content)).text : content}`);
20792
+ }
20793
+ const listing = rows.join("\n");
20794
+ const parsed = await callPortalJsonCompletion({
20795
+ ...options.apiKey !== void 0 && { apiKey: options.apiKey },
20796
+ ...options.getToken !== void 0 && { getToken: options.getToken },
20797
+ ...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
20798
+ taskType: "memory_topic",
20799
+ ...options.endpointOverride !== void 0 && {
20800
+ endpointOverride: options.endpointOverride
20801
+ },
20802
+ model: options.model ?? DEFAULT_EXTRACTION_MODEL,
20803
+ systemPrompt: SYSTEM_PROMPT6,
20804
+ userMessage: `${vocabularyNote}Memories:
20805
+ ${listing}
20806
+
20807
+ List each memory's named entities.`,
20808
+ tag: "memory/topics",
20809
+ extra: { max_completion_tokens: MAX_COMPLETION_TOKENS },
20810
+ ...options.fetchFn && { fetchFn: options.fetchFn },
20811
+ ...options.maxAttempts !== void 0 && { maxAttempts: options.maxAttempts },
20812
+ ...options.timeoutMs !== void 0 && { timeoutMs: options.timeoutMs },
20813
+ ...options.totalTimeoutMs !== void 0 && { totalTimeoutMs: options.totalTimeoutMs },
20814
+ ...options.backoffMs && { backoffMs: options.backoffMs }
20815
+ });
20816
+ if (parsed === null) {
20817
+ getLogger().warn(
20818
+ `[memory/topics] batch of ${batch.length} failed after retries \u2014 will retry next sweep`
20819
+ );
20820
+ continue;
20821
+ }
20822
+ const validIds = new Set(batch.map((m) => m.id));
20823
+ const byId = parseTopicResponse(parsed, validIds);
20824
+ if (byId === null) {
20825
+ getLogger().warn(
20826
+ `[memory/topics] batch of ${batch.length} returned an unrecognized shape \u2014 will retry next sweep`
20827
+ );
20828
+ continue;
20829
+ }
20830
+ for (const m of batch) {
20831
+ const entities = byId.get(m.id);
20832
+ if (entities === void 0) {
20833
+ continue;
20834
+ }
20835
+ out.set(m.id, redactor ? restoreEntities(entities, redactor) : entities);
20836
+ }
20837
+ }
20838
+ return out;
20839
+ }
20840
+ function restoreEntities(entities, redactor) {
20841
+ return entities.map((e) => ({ kind: e.kind, restored: redactor.restoreForStorage(e.name) })).filter((e) => !e.restored.unresolved).map(
20842
+ (e) => e.kind !== void 0 ? { name: e.restored.text, kind: e.kind } : { name: e.restored.text }
20843
+ );
20844
+ }
20845
+ function parseTopicResponse(parsed, validIds) {
20846
+ if (typeof parsed !== "object" || parsed === null) return null;
20847
+ const list = parsed.memories;
20848
+ if (!Array.isArray(list)) return null;
20849
+ const out = /* @__PURE__ */ new Map();
20850
+ for (const raw of list) {
20851
+ if (typeof raw !== "object" || raw === null) continue;
20852
+ const obj = raw;
20853
+ if (typeof obj.id !== "string") continue;
20854
+ const id = obj.id.trim().replace(/:$/, "").replace(/^\[([\s\S]*)\]$/, "$1").trim();
20855
+ if (!validIds.has(id) || out.has(id)) continue;
20856
+ const entities = Array.isArray(obj.entities) ? parseEntities(obj.entities) : [];
20857
+ out.set(id, entities);
20858
+ }
20859
+ return out;
20860
+ }
20861
+ var DEGRADED_TOPIC_SKIP = {
20862
+ excluded: false,
20863
+ "link-declined": false,
20864
+ "stamp-declined": false,
20865
+ "llm-unanswered": true,
20866
+ unreadable: true,
20867
+ "not-found": true,
20868
+ "link-failed": true
20869
+ };
20870
+ function isDegradedTopicSkip(reason) {
20871
+ return DEGRADED_TOPIC_SKIP[reason] === true;
20872
+ }
20873
+ async function extractAndLinkEntitiesForMemoriesOp(ctx, memoryIds, options) {
20874
+ const entityCtx = ctx.entityCtx;
20875
+ if (!entityCtx) {
20876
+ throw new Error("extractAndLinkEntitiesForMemoriesOp requires ctx.entityCtx");
20877
+ }
20878
+ const log = getLogger();
20879
+ const extractedAt = options.now ?? Date.now();
20880
+ const skippedIds = [];
20881
+ const skippedReasons = /* @__PURE__ */ new Map();
20882
+ const skip = (id, reason) => {
20883
+ if (skippedReasons.has(id)) return;
20884
+ skippedIds.push(id);
20885
+ skippedReasons.set(id, reason);
20886
+ };
20887
+ const inputs = [];
20888
+ for (const id of new Set(memoryIds)) {
20889
+ let record;
20890
+ try {
20891
+ record = await ctx.vaultMemoryCollection.find(id);
20892
+ } catch (err) {
20893
+ log.warn("[memory/topics] vault lookup failed for extraction", err);
20894
+ skip(id, "not-found");
20895
+ continue;
20896
+ }
20897
+ if (record.isDeleted || ctx.userId !== void 0 && record.userId !== ctx.userId || record.topicsUserManaged) {
20898
+ skip(id, "excluded");
20899
+ continue;
20900
+ }
20901
+ try {
20902
+ const stored = await vaultMemoryToStored(
20903
+ record,
20904
+ ctx.walletAddress,
20905
+ ctx.signMessage,
20906
+ ctx.embeddedWalletSigner
20907
+ );
20908
+ inputs.push({ id, content: stored.content });
20909
+ } catch (err) {
20910
+ log.warn("[memory/topics] failed to load memory for extraction", err);
20911
+ skip(id, "unreadable");
20912
+ }
20913
+ }
20914
+ const entitiesByMemory = await extractEntitiesForMemories(inputs, options);
20915
+ const toStamp = [];
20916
+ for (const input of inputs) {
20917
+ const entities = entitiesByMemory.get(input.id);
20918
+ if (entities === void 0) {
20919
+ skip(input.id, "llm-unanswered");
20920
+ continue;
20921
+ }
20922
+ try {
20923
+ const linked = await replaceMemoryEntitiesGuardedOp(entityCtx, input.id, entities);
20924
+ if (linked === null) {
20925
+ skip(input.id, "link-declined");
20926
+ entitiesByMemory.delete(input.id);
20927
+ continue;
20928
+ }
20929
+ } catch (err) {
20930
+ log.warn("[memory/topics] replaceMemoryEntitiesGuardedOp failed", err);
20931
+ skip(input.id, "link-failed");
20932
+ entitiesByMemory.delete(input.id);
20933
+ continue;
20934
+ }
20935
+ toStamp.push(input.id);
20936
+ }
20937
+ const stampedIds = await stampTopicsExtractedAtOp(ctx, toStamp, extractedAt);
20938
+ const stampedSet = new Set(stampedIds);
20939
+ for (const id of toStamp) {
20940
+ if (!stampedSet.has(id)) {
20941
+ skip(id, "stamp-declined");
20942
+ entitiesByMemory.delete(id);
20943
+ }
20944
+ }
20945
+ return { entitiesByMemory, stampedIds, skippedIds, skippedReasons };
20946
+ }
20947
+
20948
+ // src/lib/memory/store/local.ts
20949
+ function createLocalMemoryStore(options) {
20950
+ const { database, userId } = options;
20951
+ const entityCtx = {
20952
+ database,
20953
+ entityCollection: database.get("entity"),
20954
+ memoryEntityCollection: database.get("memory_entity"),
20955
+ ...userId !== void 0 && { userId },
20956
+ ...options.allowUnscopedRows !== void 0 && {
20957
+ allowUnscopedRows: options.allowUnscopedRows
20958
+ }
20959
+ };
20960
+ const vaultCtx = {
20961
+ database,
20962
+ vaultMemoryCollection: database.get("memory_vault"),
20963
+ walletAddress: options.walletAddress,
20964
+ signMessage: options.signMessage,
20965
+ embeddedWalletSigner: options.embeddedWalletSigner,
20966
+ ...userId !== void 0 && { userId },
20967
+ ...options.singleTenant !== void 0 && { singleTenant: options.singleTenant },
20968
+ // Deletes cascade to memory_entity, so the graph lane never serves a
20969
+ // deleted memory's id.
20970
+ entityCtx
20971
+ };
20972
+ const vaultCache = options.vaultCache ?? createVaultEmbeddingCache();
20973
+ const ownedBy = userId !== void 0 ? [import_watermelondb13.Q.where("user_id", userId)] : [];
20974
+ const watchedColumns = [
20975
+ "content",
20976
+ "scope",
20977
+ "updated_at",
20978
+ "fact_type",
20979
+ "event_time_start",
20980
+ "event_time_end",
20981
+ "event_time_kind",
20982
+ "archived_at",
20983
+ "trust_tier",
20984
+ "superseded_by",
20985
+ "visibility",
20986
+ "published_at",
20987
+ "geohash",
20988
+ "topics",
20989
+ "topics_user_managed",
20990
+ "media",
20991
+ "source"
20992
+ ];
20993
+ const embedInBackground = (memory) => {
20994
+ eagerEmbedContent(
20995
+ memory.content,
20996
+ options.embeddingOptions,
20997
+ vaultCache,
20998
+ vaultCtx,
20999
+ memory.uniqueId,
21000
+ memory.updatedAt
21001
+ ).catch((err) => {
21002
+ getLogger().warn("[memory/store] Failed to embed memory:", err);
21003
+ });
21004
+ };
21005
+ return {
21006
+ list: (listOptions) => getAllVaultMemoriesOp(vaultCtx, listOptions),
21007
+ get: (id) => getVaultMemoryOp(vaultCtx, id),
21008
+ listArchived: async () => {
21009
+ const ids = await vaultCtx.vaultMemoryCollection.query(import_watermelondb13.Q.where("is_deleted", false), import_watermelondb13.Q.where("archived_at", import_watermelondb13.Q.notEq(null)), ...ownedBy).fetchIds();
21010
+ if (ids.length === 0) return [];
21011
+ const rows = await getAllVaultMemoriesOp(vaultCtx, { memoryIds: ids, includeArchived: true });
21012
+ return rows.sort((a, b) => (b.archivedAt ?? 0) - (a.archivedAt ?? 0));
21013
+ },
21014
+ memoriesByTopics: (names) => getMemoriesByEntityNamesOp(entityCtx, names),
21015
+ topicsByMemories: (memoryIds) => getEntitiesByMemoryIdsOp(entityCtx, memoryIds),
21016
+ create: async (input) => {
21017
+ const created = await createVaultMemoryOp(vaultCtx, input);
21018
+ if (input.embedding === void 0) embedInBackground(created);
21019
+ return created;
21020
+ },
21021
+ createMany: async (inputs) => {
21022
+ const created = await createVaultMemoriesBatchOp(vaultCtx, inputs);
21023
+ created.forEach((memory, i) => {
21024
+ if (inputs[i].embedding === void 0) embedInBackground(memory);
21025
+ });
21026
+ return created;
21027
+ },
21028
+ update: async (id, patch) => {
21029
+ const reembed = patch.embedding === void 0;
21030
+ const updated = await updateVaultMemoryOp(
21031
+ vaultCtx,
21032
+ id,
21033
+ reembed ? { ...patch, embedding: null } : patch
21034
+ );
21035
+ if (!updated) return null;
21036
+ vaultCache.delete(id);
21037
+ if (reembed) embedInBackground(updated);
21038
+ return updated;
21039
+ },
21040
+ delete: async (id) => {
21041
+ const deleted = await deleteVaultMemoryOp(vaultCtx, id);
21042
+ if (deleted) vaultCache.delete(id);
21043
+ return deleted;
21044
+ },
21045
+ supersede: (id, supersededById) => supersedeVaultMemoryOp(vaultCtx, id, supersededById),
21046
+ archive: (id) => archiveVaultMemoryOp(vaultCtx, id),
21047
+ restore: (id) => restoreVaultMemoryOp(vaultCtx, id),
21048
+ setTopics: (memoryId, topics) => setMemoryEntitiesOp(vaultCtx, memoryId, topics),
21049
+ addTopics: (memoryId, topics) => database.write(async (writer) => {
21050
+ const owned = await vaultCtx.vaultMemoryCollection.query(import_watermelondb13.Q.where("id", memoryId), import_watermelondb13.Q.where("is_deleted", false), ...ownedBy).fetchCount();
21051
+ return owned > 0 ? writer.callWriter(() => linkMemoryEntitiesOp(entityCtx, memoryId, topics)) : [];
21052
+ }),
21053
+ setVisibility: (id, visibility, visibilityOptions) => setMemoryVisibilityOp(vaultCtx, id, { visibility, ...visibilityOptions }),
21054
+ recall: (query, recallOptions) => recall(
21055
+ query,
21056
+ { vaultCtx, entityCtx, embeddingOptions: options.embeddingOptions, vaultCache },
21057
+ { ...recallOptions, types: ["fact"] }
21058
+ ),
21059
+ retain: (content, retainOptions) => retain(
21060
+ content,
21061
+ { vaultCtx, embeddingOptions: options.embeddingOptions, vaultCache },
21062
+ retainOptions
21063
+ ),
21064
+ subscribe: (onChange, subscribeOptions) => {
21065
+ const afterFirst = () => {
21066
+ let first = true;
21067
+ return () => {
21068
+ if (first) first = false;
21069
+ else onChange();
21070
+ };
21071
+ };
21072
+ const memories = subscribeOptions?.includeDeleted ? vaultCtx.vaultMemoryCollection.query(...ownedBy).observe() : vaultCtx.vaultMemoryCollection.query(import_watermelondb13.Q.where("is_deleted", false), ...ownedBy).observeWithColumns(
21073
+ subscribeOptions?.embeddings ? [...watchedColumns, "embedding", "embedding_model"] : watchedColumns
21074
+ );
21075
+ const subscriptions = [memories.subscribe(afterFirst())];
21076
+ if (subscribeOptions?.topics) {
21077
+ const linksOwnedBy = userId === void 0 ? [] : options.allowUnscopedRows ? [import_watermelondb13.Q.or(import_watermelondb13.Q.where("user_id", userId), import_watermelondb13.Q.where("user_id", null))] : [import_watermelondb13.Q.where("user_id", userId)];
21078
+ subscriptions.push(
21079
+ entityCtx.memoryEntityCollection.query(...linksOwnedBy).observe().subscribe(afterFirst())
21080
+ );
21081
+ }
21082
+ return () => subscriptions.forEach((s) => s.unsubscribe());
21083
+ },
21084
+ maintenance: {
21085
+ createDecaySweeper: (sweeperOptions) => createDecaySweeper({ ...sweeperOptions, vaultCtx }),
21086
+ getTopicBacklog: (backlogOptions) => getMemoriesNeedingTopicExtractionOp(vaultCtx, backlogOptions),
21087
+ extractTopics: (memoryIds, extractOptions) => extractAndLinkEntitiesForMemoriesOp(vaultCtx, memoryIds, extractOptions),
21088
+ stampTopicsExtracted: (memoryIds, extractedAt, version) => stampTopicsExtractedAtOp(vaultCtx, memoryIds, extractedAt, version),
21089
+ relinkTopics: (memoryIds) => relinkMemoryTopicsOp(vaultCtx, memoryIds),
21090
+ backfillTopics: (memoryIds) => backfillMemoryTopicsOp(vaultCtx, memoryIds)
21091
+ }
21092
+ };
21093
+ }
21094
+
20706
21095
  // src/lib/memory/synthesizeProfile.ts
20707
21096
  init_internalFlowMarker();
20708
21097
  init_logger();
@@ -21232,202 +21621,6 @@ function normalizeInterests(values) {
21232
21621
  return out.length > 0 ? out : void 0;
21233
21622
  }
21234
21623
 
21235
- // src/lib/memory/topicExtract.ts
21236
- init_logger();
21237
- init_redactor();
21238
- init_portalLlm();
21239
- var TOPIC_EXTRACTION_BATCH_SIZE = 10;
21240
- var MAX_CHARS_PER_MEMORY = 300;
21241
- var MAX_VOCABULARY_NAMES = 100;
21242
- var MAX_COMPLETION_TOKENS = 8192;
21243
- var SYSTEM_PROMPT6 = `You assign topics to saved memories for a personal memory system.
21244
-
21245
- 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.
21246
-
21247
- 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:
21248
- - 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.
21249
- - KEEP the specific thing instead, when the memory names one: "Blue Bottle on Valencia" over "cafe", "Chicago Marathon" over "event", "Hollowpoint Labs" over "work".
21250
- - Prefer 0 entities over a weak one. A memory whose only candidate is a generic noun has NO entities.
21251
- ${ENTITY_KIND_GUIDELINES}
21252
-
21253
- Each memory below is written as "<id>: <text>". Output strict JSON: {"memories": [{"id": string, "entities": [{"name": string, "kind": string}]}]}
21254
- - exactly one element per input memory; copy its id EXACTLY as written (the token before the first ": "), with no brackets, quotes, or extra characters
21255
- - "entities" may be empty when a memory mentions no named entities \u2014 most short memories have 0-3
21256
- No prose.`;
21257
- async function extractEntitiesForMemories(memories, options) {
21258
- const out = /* @__PURE__ */ new Map();
21259
- if (memories.length === 0) return out;
21260
- const redactor = resolvePiiRedactor(options.piiRedaction);
21261
- const vocabulary = [];
21262
- for (const name of (options.existingEntityNames ?? []).filter((n) => n.trim().length > 0).slice(0, MAX_VOCABULARY_NAMES)) {
21263
- vocabulary.push(redactor ? (await redactor.redactTextAsync(name)).text : name);
21264
- }
21265
- const vocabularyNote = vocabulary.length > 0 ? `The user's existing topics: ${vocabulary.join(", ")}.
21266
- When a memory refers to one of these, reuse the EXACT existing name (same spelling, casing, spacing and punctuation) instead of a variant \u2014 if "Foo.ai" is listed, never emit "Foo ai" or "Foo AI", and if "Jane Roe" is listed, emit that rather than a bare "Jane".
21267
-
21268
- ` : "";
21269
- for (let i = 0; i < memories.length; i += TOPIC_EXTRACTION_BATCH_SIZE) {
21270
- const batch = memories.slice(i, i + TOPIC_EXTRACTION_BATCH_SIZE);
21271
- const rows = [];
21272
- for (const m of batch) {
21273
- const content = m.content.slice(0, MAX_CHARS_PER_MEMORY).replace(/\s+/g, " ").trim();
21274
- rows.push(`${m.id}: ${redactor ? (await redactor.redactTextAsync(content)).text : content}`);
21275
- }
21276
- const listing = rows.join("\n");
21277
- const parsed = await callPortalJsonCompletion({
21278
- ...options.apiKey !== void 0 && { apiKey: options.apiKey },
21279
- ...options.getToken !== void 0 && { getToken: options.getToken },
21280
- ...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
21281
- taskType: "memory_topic",
21282
- ...options.endpointOverride !== void 0 && {
21283
- endpointOverride: options.endpointOverride
21284
- },
21285
- model: options.model ?? DEFAULT_EXTRACTION_MODEL,
21286
- systemPrompt: SYSTEM_PROMPT6,
21287
- userMessage: `${vocabularyNote}Memories:
21288
- ${listing}
21289
-
21290
- List each memory's named entities.`,
21291
- tag: "memory/topics",
21292
- extra: { max_completion_tokens: MAX_COMPLETION_TOKENS },
21293
- ...options.fetchFn && { fetchFn: options.fetchFn },
21294
- ...options.maxAttempts !== void 0 && { maxAttempts: options.maxAttempts },
21295
- ...options.timeoutMs !== void 0 && { timeoutMs: options.timeoutMs },
21296
- ...options.totalTimeoutMs !== void 0 && { totalTimeoutMs: options.totalTimeoutMs },
21297
- ...options.backoffMs && { backoffMs: options.backoffMs }
21298
- });
21299
- if (parsed === null) {
21300
- getLogger().warn(
21301
- `[memory/topics] batch of ${batch.length} failed after retries \u2014 will retry next sweep`
21302
- );
21303
- continue;
21304
- }
21305
- const validIds = new Set(batch.map((m) => m.id));
21306
- const byId = parseTopicResponse(parsed, validIds);
21307
- if (byId === null) {
21308
- getLogger().warn(
21309
- `[memory/topics] batch of ${batch.length} returned an unrecognized shape \u2014 will retry next sweep`
21310
- );
21311
- continue;
21312
- }
21313
- for (const m of batch) {
21314
- const entities = byId.get(m.id);
21315
- if (entities === void 0) {
21316
- continue;
21317
- }
21318
- out.set(m.id, redactor ? restoreEntities(entities, redactor) : entities);
21319
- }
21320
- }
21321
- return out;
21322
- }
21323
- function restoreEntities(entities, redactor) {
21324
- return entities.map((e) => ({ kind: e.kind, restored: redactor.restoreForStorage(e.name) })).filter((e) => !e.restored.unresolved).map(
21325
- (e) => e.kind !== void 0 ? { name: e.restored.text, kind: e.kind } : { name: e.restored.text }
21326
- );
21327
- }
21328
- function parseTopicResponse(parsed, validIds) {
21329
- if (typeof parsed !== "object" || parsed === null) return null;
21330
- const list = parsed.memories;
21331
- if (!Array.isArray(list)) return null;
21332
- const out = /* @__PURE__ */ new Map();
21333
- for (const raw of list) {
21334
- if (typeof raw !== "object" || raw === null) continue;
21335
- const obj = raw;
21336
- if (typeof obj.id !== "string") continue;
21337
- const id = obj.id.trim().replace(/:$/, "").replace(/^\[([\s\S]*)\]$/, "$1").trim();
21338
- if (!validIds.has(id) || out.has(id)) continue;
21339
- const entities = Array.isArray(obj.entities) ? parseEntities(obj.entities) : [];
21340
- out.set(id, entities);
21341
- }
21342
- return out;
21343
- }
21344
- var DEGRADED_TOPIC_SKIP = {
21345
- excluded: false,
21346
- "link-declined": false,
21347
- "stamp-declined": false,
21348
- "llm-unanswered": true,
21349
- unreadable: true,
21350
- "not-found": true,
21351
- "link-failed": true
21352
- };
21353
- function isDegradedTopicSkip(reason) {
21354
- return DEGRADED_TOPIC_SKIP[reason] === true;
21355
- }
21356
- async function extractAndLinkEntitiesForMemoriesOp(ctx, memoryIds, options) {
21357
- const entityCtx = ctx.entityCtx;
21358
- if (!entityCtx) {
21359
- throw new Error("extractAndLinkEntitiesForMemoriesOp requires ctx.entityCtx");
21360
- }
21361
- const log = getLogger();
21362
- const extractedAt = options.now ?? Date.now();
21363
- const skippedIds = [];
21364
- const skippedReasons = /* @__PURE__ */ new Map();
21365
- const skip = (id, reason) => {
21366
- if (skippedReasons.has(id)) return;
21367
- skippedIds.push(id);
21368
- skippedReasons.set(id, reason);
21369
- };
21370
- const inputs = [];
21371
- for (const id of new Set(memoryIds)) {
21372
- let record;
21373
- try {
21374
- record = await ctx.vaultMemoryCollection.find(id);
21375
- } catch (err) {
21376
- log.warn("[memory/topics] vault lookup failed for extraction", err);
21377
- skip(id, "not-found");
21378
- continue;
21379
- }
21380
- if (record.isDeleted || ctx.userId !== void 0 && record.userId !== ctx.userId || record.topicsUserManaged) {
21381
- skip(id, "excluded");
21382
- continue;
21383
- }
21384
- try {
21385
- const stored = await vaultMemoryToStored(
21386
- record,
21387
- ctx.walletAddress,
21388
- ctx.signMessage,
21389
- ctx.embeddedWalletSigner
21390
- );
21391
- inputs.push({ id, content: stored.content });
21392
- } catch (err) {
21393
- log.warn("[memory/topics] failed to load memory for extraction", err);
21394
- skip(id, "unreadable");
21395
- }
21396
- }
21397
- const entitiesByMemory = await extractEntitiesForMemories(inputs, options);
21398
- const toStamp = [];
21399
- for (const input of inputs) {
21400
- const entities = entitiesByMemory.get(input.id);
21401
- if (entities === void 0) {
21402
- skip(input.id, "llm-unanswered");
21403
- continue;
21404
- }
21405
- try {
21406
- const linked = await replaceMemoryEntitiesGuardedOp(entityCtx, input.id, entities);
21407
- if (linked === null) {
21408
- skip(input.id, "link-declined");
21409
- entitiesByMemory.delete(input.id);
21410
- continue;
21411
- }
21412
- } catch (err) {
21413
- log.warn("[memory/topics] replaceMemoryEntitiesGuardedOp failed", err);
21414
- skip(input.id, "link-failed");
21415
- entitiesByMemory.delete(input.id);
21416
- continue;
21417
- }
21418
- toStamp.push(input.id);
21419
- }
21420
- const stampedIds = await stampTopicsExtractedAtOp(ctx, toStamp, extractedAt);
21421
- const stampedSet = new Set(stampedIds);
21422
- for (const id of toStamp) {
21423
- if (!stampedSet.has(id)) {
21424
- skip(id, "stamp-declined");
21425
- entitiesByMemory.delete(id);
21426
- }
21427
- }
21428
- return { entitiesByMemory, stampedIds, skippedIds, skippedReasons };
21429
- }
21430
-
21431
21624
  // src/lib/memory/verifySupport.ts
21432
21625
  init_logger();
21433
21626
  init_redactor();
@@ -21821,7 +22014,7 @@ async function assembleMemoryContext(options) {
21821
22014
  }
21822
22015
 
21823
22016
  // src/lib/memory/durableExtraction.ts
21824
- var import_watermelondb13 = require("@nozbe/watermelondb");
22017
+ var import_watermelondb14 = require("@nozbe/watermelondb");
21825
22018
  var MAX_JOBS_PER_PASS = 3;
21826
22019
  var MAX_ATTEMPTS = 3;
21827
22020
  var MAX_FAILED_SESSIONS = 3;
@@ -21968,7 +22161,7 @@ function createDurableAutoExtractor(options) {
21968
22161
  ...options.retainCtx,
21969
22162
  vaultCtx: {
21970
22163
  ...vault,
21971
- canWrite: async () => !disposed && !cancelled && await storage.conversationsCollection.query(import_watermelondb13.Q.where("conversation_id", conversationId), import_watermelondb13.Q.where("is_deleted", false)).fetchCount() > 0 && await storage.messagesCollection.query(import_watermelondb13.Q.where("conversation_id", conversationId), import_watermelondb13.Q.where("id", import_watermelondb13.Q.oneOf(ids))).fetchCount() === ids.length && (!vault.canWrite || await vault.canWrite()) && !disposed && !cancelled
22164
+ canWrite: async () => !disposed && !cancelled && await storage.conversationsCollection.query(import_watermelondb14.Q.where("conversation_id", conversationId), import_watermelondb14.Q.where("is_deleted", false)).fetchCount() > 0 && await storage.messagesCollection.query(import_watermelondb14.Q.where("conversation_id", conversationId), import_watermelondb14.Q.where("id", import_watermelondb14.Q.oneOf(ids))).fetchCount() === ids.length && (!vault.canWrite || await vault.canWrite()) && !disposed && !cancelled
21972
22165
  }
21973
22166
  },
21974
22167
  // The model follows the job's scope, not the mode alive at drain time.
@@ -22110,7 +22303,7 @@ function createDurableAutoExtractor(options) {
22110
22303
  let scheduleAfterSuccess = false;
22111
22304
  try {
22112
22305
  await writes;
22113
- const pending = await jobs.query(import_watermelondb13.Q.where("owner_key", owner), import_watermelondb13.Q.where("message_ids", import_watermelondb13.Q.notEq("[]"))).fetch();
22306
+ const pending = await jobs.query(import_watermelondb14.Q.where("owner_key", owner), import_watermelondb14.Q.where("message_ids", import_watermelondb14.Q.notEq("[]"))).fetch();
22114
22307
  storeFailures = 0;
22115
22308
  let processed = 0;
22116
22309
  for (const job of pending) {
@@ -22126,7 +22319,7 @@ function createDurableAutoExtractor(options) {
22126
22319
  let ids = [];
22127
22320
  let loaded = [];
22128
22321
  try {
22129
- const conversations = await storage.conversationsCollection.query(import_watermelondb13.Q.where("conversation_id", conversationId), import_watermelondb13.Q.where("is_deleted", false)).fetchCount();
22322
+ const conversations = await storage.conversationsCollection.query(import_watermelondb14.Q.where("conversation_id", conversationId), import_watermelondb14.Q.where("is_deleted", false)).fetchCount();
22130
22323
  if (!conversations) {
22131
22324
  await database.write(() => job.destroyPermanently());
22132
22325
  continue;
@@ -22243,12 +22436,12 @@ function createDurableAutoExtractor(options) {
22243
22436
  const scope = currentScope();
22244
22437
  writes = writes.then(
22245
22438
  () => database.write(async () => {
22246
- const existing = await jobs.query(import_watermelondb13.Q.where("owner_key", owner), import_watermelondb13.Q.where("conversation_id", conversationId)).fetch();
22439
+ const existing = await jobs.query(import_watermelondb14.Q.where("owner_key", owner), import_watermelondb14.Q.where("conversation_id", conversationId)).fetch();
22247
22440
  const job = existing.find(
22248
22441
  (candidate) => candidate._getRaw("scope") === scope && (candidate._getRaw("folder_id") ?? null) === folderId
22249
22442
  );
22250
22443
  const positions = new Map(ids.map((id, index) => [id, index]));
22251
- const rows = await storage.messagesCollection.query(import_watermelondb13.Q.where("id", import_watermelondb13.Q.oneOf(ids))).fetch();
22444
+ const rows = await storage.messagesCollection.query(import_watermelondb14.Q.where("id", import_watermelondb14.Q.oneOf(ids))).fetch();
22252
22445
  const sequences = /* @__PURE__ */ new Map();
22253
22446
  for (const row of rows) {
22254
22447
  const sequence = Number(row._getRaw("message_id"));
@@ -24690,6 +24883,8 @@ function useChatStorage(options) {
24690
24883
  onError,
24691
24884
  onServerToolCall,
24692
24885
  onToolCallArgumentsDelta,
24886
+ resumable,
24887
+ onStreamMeta,
24693
24888
  apiType,
24694
24889
  walletAddress,
24695
24890
  signMessage,
@@ -25254,6 +25449,8 @@ function useChatStorage(options) {
25254
25449
  onError,
25255
25450
  onServerToolCall,
25256
25451
  onToolCallArgumentsDelta,
25452
+ resumable,
25453
+ onStreamMeta,
25257
25454
  apiType,
25258
25455
  preProcessors,
25259
25456
  smoothing,
@@ -25676,6 +25873,7 @@ function useChatStorage(options) {
25676
25873
  return {
25677
25874
  data: result2.data,
25678
25875
  error: null,
25876
+ autoExecutedToolResults: "autoExecutedToolResults" in result2 ? result2.autoExecutedToolResults : void 0,
25679
25877
  skipped: true
25680
25878
  };
25681
25879
  }
@@ -26437,13 +26635,13 @@ function useChatStorage(options) {
26437
26635
  }
26438
26636
 
26439
26637
  // src/lib/db/schema.ts
26440
- var import_watermelondb22 = require("@nozbe/watermelondb");
26638
+ var import_watermelondb23 = require("@nozbe/watermelondb");
26441
26639
  var import_migrations2 = require("@nozbe/watermelondb/Schema/migrations");
26442
26640
 
26443
26641
  // src/lib/db/appFiles/models.ts
26444
- var import_watermelondb14 = require("@nozbe/watermelondb");
26642
+ var import_watermelondb15 = require("@nozbe/watermelondb");
26445
26643
  var import_decorators4 = require("@nozbe/watermelondb/decorators");
26446
- var AppFile = class extends import_watermelondb14.Model {
26644
+ var AppFile = class extends import_watermelondb15.Model {
26447
26645
  };
26448
26646
  AppFile.table = "app_files";
26449
26647
  AppFile.associations = {};
@@ -26465,9 +26663,9 @@ __decorateClass([
26465
26663
  ], AppFile.prototype, "updatedAt", 2);
26466
26664
 
26467
26665
  // src/lib/db/conversationMemory/models.ts
26468
- var import_watermelondb15 = require("@nozbe/watermelondb");
26666
+ var import_watermelondb16 = require("@nozbe/watermelondb");
26469
26667
  var import_decorators5 = require("@nozbe/watermelondb/decorators");
26470
- var ConversationMemory = class extends import_watermelondb15.Model {
26668
+ var ConversationMemory = class extends import_watermelondb16.Model {
26471
26669
  };
26472
26670
  ConversationMemory.table = "conversation_memory";
26473
26671
  ConversationMemory.associations = {};
@@ -26486,9 +26684,9 @@ __decorateClass([
26486
26684
  ], ConversationMemory.prototype, "createdAt", 2);
26487
26685
 
26488
26686
  // src/lib/db/entities/models.ts
26489
- var import_watermelondb16 = require("@nozbe/watermelondb");
26687
+ var import_watermelondb17 = require("@nozbe/watermelondb");
26490
26688
  var import_decorators6 = require("@nozbe/watermelondb/decorators");
26491
- var Entity = class extends import_watermelondb16.Model {
26689
+ var Entity = class extends import_watermelondb17.Model {
26492
26690
  };
26493
26691
  Entity.table = "entity";
26494
26692
  __decorateClass([
@@ -26504,7 +26702,7 @@ __decorateClass([
26504
26702
  __decorateClass([
26505
26703
  (0, import_decorators6.date)("updated_at")
26506
26704
  ], Entity.prototype, "updatedAt", 2);
26507
- var MemoryEntity = class extends import_watermelondb16.Model {
26705
+ var MemoryEntity = class extends import_watermelondb17.Model {
26508
26706
  };
26509
26707
  MemoryEntity.table = "memory_entity";
26510
26708
  __decorateClass([
@@ -26522,9 +26720,9 @@ __decorateClass([
26522
26720
  ], MemoryEntity.prototype, "createdAt", 2);
26523
26721
 
26524
26722
  // src/lib/db/project/models.ts
26525
- var import_watermelondb17 = require("@nozbe/watermelondb");
26723
+ var import_watermelondb18 = require("@nozbe/watermelondb");
26526
26724
  var import_decorators7 = require("@nozbe/watermelondb/decorators");
26527
- var Project = class extends import_watermelondb17.Model {
26725
+ var Project = class extends import_watermelondb18.Model {
26528
26726
  };
26529
26727
  Project.table = "projects";
26530
26728
  Project.associations = {
@@ -26547,10 +26745,10 @@ __decorateClass([
26547
26745
  ], Project.prototype, "isDeleted", 2);
26548
26746
 
26549
26747
  // src/lib/db/savedTools/models.ts
26550
- var import_watermelondb18 = require("@nozbe/watermelondb");
26748
+ var import_watermelondb19 = require("@nozbe/watermelondb");
26551
26749
  var import_decorators8 = require("@nozbe/watermelondb/decorators");
26552
26750
  var sanitizeParameters = (raw) => raw ?? {};
26553
- var SavedTool = class extends import_watermelondb18.Model {
26751
+ var SavedTool = class extends import_watermelondb19.Model {
26554
26752
  };
26555
26753
  SavedTool.table = "saved_tools";
26556
26754
  SavedTool.associations = {};
@@ -26584,9 +26782,9 @@ __decorateClass([
26584
26782
  ], SavedTool.prototype, "isDeleted", 2);
26585
26783
 
26586
26784
  // src/lib/db/settings/models.ts
26587
- var import_watermelondb19 = require("@nozbe/watermelondb");
26785
+ var import_watermelondb20 = require("@nozbe/watermelondb");
26588
26786
  var import_decorators9 = require("@nozbe/watermelondb/decorators");
26589
- var ModelPreference = class extends import_watermelondb19.Model {
26787
+ var ModelPreference = class extends import_watermelondb20.Model {
26590
26788
  };
26591
26789
  ModelPreference.table = "modelPreferences";
26592
26790
  __decorateClass([
@@ -26597,9 +26795,9 @@ __decorateClass([
26597
26795
  ], ModelPreference.prototype, "models", 2);
26598
26796
 
26599
26797
  // src/lib/db/userPreferences/models.ts
26600
- var import_watermelondb20 = require("@nozbe/watermelondb");
26798
+ var import_watermelondb21 = require("@nozbe/watermelondb");
26601
26799
  var import_decorators10 = require("@nozbe/watermelondb/decorators");
26602
- var UserPreference = class extends import_watermelondb20.Model {
26800
+ var UserPreference = class extends import_watermelondb21.Model {
26603
26801
  };
26604
26802
  UserPreference.table = "userPreferences";
26605
26803
  __decorateClass([
@@ -26628,9 +26826,9 @@ __decorateClass([
26628
26826
  ], UserPreference.prototype, "updatedAt", 2);
26629
26827
 
26630
26828
  // src/lib/db/vaultFolders/models.ts
26631
- var import_watermelondb21 = require("@nozbe/watermelondb");
26829
+ var import_watermelondb22 = require("@nozbe/watermelondb");
26632
26830
  var import_decorators11 = require("@nozbe/watermelondb/decorators");
26633
- var VaultFolder = class extends import_watermelondb21.Model {
26831
+ var VaultFolder = class extends import_watermelondb22.Model {
26634
26832
  };
26635
26833
  VaultFolder.table = "vault_folders";
26636
26834
  __decorateClass([
@@ -26658,10 +26856,10 @@ __decorateClass([
26658
26856
 
26659
26857
  // src/lib/db/schema.ts
26660
26858
  var SDK_SCHEMA_VERSION = 47;
26661
- var sdkSchema = (0, import_watermelondb22.appSchema)({
26859
+ var sdkSchema = (0, import_watermelondb23.appSchema)({
26662
26860
  version: SDK_SCHEMA_VERSION,
26663
26861
  tables: [
26664
- (0, import_watermelondb22.tableSchema)({
26862
+ (0, import_watermelondb23.tableSchema)({
26665
26863
  name: "memory_extraction_jobs",
26666
26864
  columns: [
26667
26865
  { name: "owner_key", type: "string", isIndexed: true },
@@ -26681,7 +26879,7 @@ var sdkSchema = (0, import_watermelondb22.appSchema)({
26681
26879
  ]
26682
26880
  }),
26683
26881
  // Chat storage tables
26684
- (0, import_watermelondb22.tableSchema)({
26882
+ (0, import_watermelondb23.tableSchema)({
26685
26883
  name: "history",
26686
26884
  columns: [
26687
26885
  { name: "message_id", type: "number" },
@@ -26720,7 +26918,7 @@ var sdkSchema = (0, import_watermelondb22.appSchema)({
26720
26918
  // MessageOrigin — provenance, NOT encrypted (see v44)
26721
26919
  ]
26722
26920
  }),
26723
- (0, import_watermelondb22.tableSchema)({
26921
+ (0, import_watermelondb23.tableSchema)({
26724
26922
  name: "conversations",
26725
26923
  columns: [
26726
26924
  { name: "conversation_id", type: "string", isIndexed: true },
@@ -26742,7 +26940,7 @@ var sdkSchema = (0, import_watermelondb22.appSchema)({
26742
26940
  ]
26743
26941
  }),
26744
26942
  // Project storage table
26745
- (0, import_watermelondb22.tableSchema)({
26943
+ (0, import_watermelondb23.tableSchema)({
26746
26944
  name: "projects",
26747
26945
  columns: [
26748
26946
  { name: "project_id", type: "string", isIndexed: true },
@@ -26753,7 +26951,7 @@ var sdkSchema = (0, import_watermelondb22.appSchema)({
26753
26951
  ]
26754
26952
  }),
26755
26953
  // Settings storage tables (deprecated - use userPreferences)
26756
- (0, import_watermelondb22.tableSchema)({
26954
+ (0, import_watermelondb23.tableSchema)({
26757
26955
  name: "modelPreferences",
26758
26956
  columns: [
26759
26957
  { name: "wallet_address", type: "string", isIndexed: true },
@@ -26761,7 +26959,7 @@ var sdkSchema = (0, import_watermelondb22.appSchema)({
26761
26959
  ]
26762
26960
  }),
26763
26961
  // Unified user preferences storage
26764
- (0, import_watermelondb22.tableSchema)({
26962
+ (0, import_watermelondb23.tableSchema)({
26765
26963
  name: "userPreferences",
26766
26964
  columns: [
26767
26965
  // Identity
@@ -26780,7 +26978,7 @@ var sdkSchema = (0, import_watermelondb22.appSchema)({
26780
26978
  ]
26781
26979
  }),
26782
26980
  // Memory vault storage
26783
- (0, import_watermelondb22.tableSchema)({
26981
+ (0, import_watermelondb23.tableSchema)({
26784
26982
  name: "memory_vault",
26785
26983
  columns: [
26786
26984
  { name: "content", type: "string" },
@@ -26908,7 +27106,7 @@ var sdkSchema = (0, import_watermelondb22.appSchema)({
26908
27106
  ]
26909
27107
  }),
26910
27108
  // Entity table — canonical names extracted from auto-extraction (W5).
26911
- (0, import_watermelondb22.tableSchema)({
27109
+ (0, import_watermelondb23.tableSchema)({
26912
27110
  name: "entity",
26913
27111
  columns: [
26914
27112
  { name: "canonical_name", type: "string", isIndexed: true },
@@ -26918,7 +27116,7 @@ var sdkSchema = (0, import_watermelondb22.appSchema)({
26918
27116
  ]
26919
27117
  }),
26920
27118
  // Many-to-many join: which memories reference which entities.
26921
- (0, import_watermelondb22.tableSchema)({
27119
+ (0, import_watermelondb23.tableSchema)({
26922
27120
  name: "memory_entity",
26923
27121
  columns: [
26924
27122
  { name: "memory_id", type: "string", isIndexed: true },
@@ -26928,7 +27126,7 @@ var sdkSchema = (0, import_watermelondb22.appSchema)({
26928
27126
  ]
26929
27127
  }),
26930
27128
  // Vault folder organization
26931
- (0, import_watermelondb22.tableSchema)({
27129
+ (0, import_watermelondb23.tableSchema)({
26932
27130
  name: "vault_folders",
26933
27131
  columns: [
26934
27132
  { name: "name", type: "string" },
@@ -26941,7 +27139,7 @@ var sdkSchema = (0, import_watermelondb22.appSchema)({
26941
27139
  ]
26942
27140
  }),
26943
27141
  // Conversation summary cache for progressive history summarization
26944
- (0, import_watermelondb22.tableSchema)({
27142
+ (0, import_watermelondb23.tableSchema)({
26945
27143
  name: "conversation_summaries",
26946
27144
  columns: [
26947
27145
  { name: "conversation_id", type: "string", isIndexed: true },
@@ -26954,7 +27152,7 @@ var sdkSchema = (0, import_watermelondb22.appSchema)({
26954
27152
  ]
26955
27153
  }),
26956
27154
  // Media library storage (images, videos, audio, documents)
26957
- (0, import_watermelondb22.tableSchema)({
27155
+ (0, import_watermelondb23.tableSchema)({
26958
27156
  name: "media",
26959
27157
  columns: [
26960
27158
  // Identity
@@ -26990,7 +27188,7 @@ var sdkSchema = (0, import_watermelondb22.appSchema)({
26990
27188
  ]
26991
27189
  }),
26992
27190
  // ── App files ─────────────────────────────────────────────────────────
26993
- (0, import_watermelondb22.tableSchema)({
27191
+ (0, import_watermelondb23.tableSchema)({
26994
27192
  name: "app_files",
26995
27193
  columns: [
26996
27194
  { name: "conversation_id", type: "string", isIndexed: true },
@@ -27001,7 +27199,7 @@ var sdkSchema = (0, import_watermelondb22.appSchema)({
27001
27199
  ]
27002
27200
  }),
27003
27201
  // ── Saved tools ──────────────────────────────────────────────────────
27004
- (0, import_watermelondb22.tableSchema)({
27202
+ (0, import_watermelondb23.tableSchema)({
27005
27203
  name: "saved_tools",
27006
27204
  columns: [
27007
27205
  { name: "name", type: "string" },
@@ -27017,7 +27215,7 @@ var sdkSchema = (0, import_watermelondb22.appSchema)({
27017
27215
  ]
27018
27216
  }),
27019
27217
  // ── Conversation memories (panel persistence) ────────────────────────
27020
- (0, import_watermelondb22.tableSchema)({
27218
+ (0, import_watermelondb23.tableSchema)({
27021
27219
  name: "conversation_memory",
27022
27220
  columns: [
27023
27221
  { name: "conversation_id", type: "string", isIndexed: true },
@@ -27739,7 +27937,7 @@ var sdkModelClasses = [
27739
27937
  ];
27740
27938
 
27741
27939
  // src/lib/db/manager.ts
27742
- var import_watermelondb23 = require("@nozbe/watermelondb");
27940
+ var import_watermelondb24 = require("@nozbe/watermelondb");
27743
27941
  var DESTRUCTIVE_MIGRATION_VERSION = 8;
27744
27942
  var webPlatformStorage = {
27745
27943
  getItem: (key) => localStorage.getItem(key),
@@ -27820,7 +28018,7 @@ var DatabaseManager = class {
27820
28018
  walletAddress
27821
28019
  });
27822
28020
  const adapter = this.createAdapter(dbName, sdkSchema, sdkMigrations);
27823
- const database = new import_watermelondb23.Database({
28021
+ const database = new import_watermelondb24.Database({
27824
28022
  adapter,
27825
28023
  modelClasses: sdkModelClasses
27826
28024
  });
@@ -27905,7 +28103,7 @@ function useDatabaseManager(walletAddress, manager) {
27905
28103
  }
27906
28104
 
27907
28105
  // src/lib/db/project/operations.ts
27908
- var import_watermelondb24 = require("@nozbe/watermelondb");
28106
+ var import_watermelondb25 = require("@nozbe/watermelondb");
27909
28107
 
27910
28108
  // src/lib/db/project/types.ts
27911
28109
  function generateProjectId() {
@@ -27936,15 +28134,15 @@ async function createProjectOp(ctx, opts, defaultName = "New Project") {
27936
28134
  return projectToStored(created);
27937
28135
  }
27938
28136
  async function getProjectOp(ctx, id) {
27939
- const results = await ctx.projectsCollection.query(import_watermelondb24.Q.where("project_id", id), import_watermelondb24.Q.where("is_deleted", false)).fetch();
28137
+ const results = await ctx.projectsCollection.query(import_watermelondb25.Q.where("project_id", id), import_watermelondb25.Q.where("is_deleted", false)).fetch();
27940
28138
  return results.length > 0 ? projectToStored(results[0]) : null;
27941
28139
  }
27942
28140
  async function getProjectsOp(ctx) {
27943
- const results = await ctx.projectsCollection.query(import_watermelondb24.Q.where("is_deleted", false), import_watermelondb24.Q.sortBy("created_at", import_watermelondb24.Q.desc)).fetch();
28141
+ const results = await ctx.projectsCollection.query(import_watermelondb25.Q.where("is_deleted", false), import_watermelondb25.Q.sortBy("created_at", import_watermelondb25.Q.desc)).fetch();
27944
28142
  return results.map(projectToStored);
27945
28143
  }
27946
28144
  async function updateProjectNameOp(ctx, id, name) {
27947
- const results = await ctx.projectsCollection.query(import_watermelondb24.Q.where("project_id", id), import_watermelondb24.Q.where("is_deleted", false)).fetch();
28145
+ const results = await ctx.projectsCollection.query(import_watermelondb25.Q.where("project_id", id), import_watermelondb25.Q.where("is_deleted", false)).fetch();
27948
28146
  if (results.length > 0) {
27949
28147
  await ctx.database.write(async () => {
27950
28148
  await results[0].update((proj) => {
@@ -27956,7 +28154,7 @@ async function updateProjectNameOp(ctx, id, name) {
27956
28154
  return false;
27957
28155
  }
27958
28156
  async function updateProjectOp(ctx, id, opts) {
27959
- const results = await ctx.projectsCollection.query(import_watermelondb24.Q.where("project_id", id), import_watermelondb24.Q.where("is_deleted", false)).fetch();
28157
+ const results = await ctx.projectsCollection.query(import_watermelondb25.Q.where("project_id", id), import_watermelondb25.Q.where("is_deleted", false)).fetch();
27960
28158
  if (results.length > 0) {
27961
28159
  await ctx.database.write(async () => {
27962
28160
  await results[0].update((proj) => {
@@ -27968,7 +28166,7 @@ async function updateProjectOp(ctx, id, opts) {
27968
28166
  return false;
27969
28167
  }
27970
28168
  async function deleteProjectOp(ctx, id) {
27971
- const results = await ctx.projectsCollection.query(import_watermelondb24.Q.where("project_id", id), import_watermelondb24.Q.where("is_deleted", false)).fetch();
28169
+ const results = await ctx.projectsCollection.query(import_watermelondb25.Q.where("project_id", id), import_watermelondb25.Q.where("is_deleted", false)).fetch();
27972
28170
  if (results.length > 0) {
27973
28171
  await ctx.database.write(async () => {
27974
28172
  await results[0].update((proj) => {
@@ -27981,18 +28179,18 @@ async function deleteProjectOp(ctx, id) {
27981
28179
  }
27982
28180
  async function getProjectConversationsOp(ctx, projectId) {
27983
28181
  const results = await ctx.conversationsCollection.query(
27984
- import_watermelondb24.Q.where("project_id", projectId),
27985
- import_watermelondb24.Q.where("is_deleted", false),
27986
- import_watermelondb24.Q.sortBy("created_at", import_watermelondb24.Q.desc)
28182
+ import_watermelondb25.Q.where("project_id", projectId),
28183
+ import_watermelondb25.Q.where("is_deleted", false),
28184
+ import_watermelondb25.Q.sortBy("created_at", import_watermelondb25.Q.desc)
27987
28185
  ).fetch();
27988
28186
  return results.map(conversationToStoredRaw);
27989
28187
  }
27990
28188
  async function getProjectConversationCountOp(ctx, projectId) {
27991
- return await ctx.conversationsCollection.query(import_watermelondb24.Q.where("project_id", projectId), import_watermelondb24.Q.where("is_deleted", false)).fetchCount();
28189
+ return await ctx.conversationsCollection.query(import_watermelondb25.Q.where("project_id", projectId), import_watermelondb25.Q.where("is_deleted", false)).fetchCount();
27992
28190
  }
27993
28191
 
27994
28192
  // src/react/useFiles.ts
27995
- var import_watermelondb25 = require("@nozbe/watermelondb");
28193
+ var import_watermelondb26 = require("@nozbe/watermelondb");
27996
28194
  var import_react7 = require("react");
27997
28195
  init_logger();
27998
28196
  function useFiles(options) {
@@ -28011,7 +28209,7 @@ function useFiles(options) {
28011
28209
  setIsLoading(true);
28012
28210
  try {
28013
28211
  const coll = database.get("media");
28014
- await coll.query(import_watermelondb25.Q.take(1)).fetch();
28212
+ await coll.query(import_watermelondb26.Q.take(1)).fetch();
28015
28213
  setMediaCollection(coll);
28016
28214
  setIsReady(true);
28017
28215
  } catch (error) {
@@ -28419,7 +28617,7 @@ function useFiles(options) {
28419
28617
  }
28420
28618
 
28421
28619
  // src/react/useProjects.ts
28422
- var import_watermelondb26 = require("@nozbe/watermelondb");
28620
+ var import_watermelondb27 = require("@nozbe/watermelondb");
28423
28621
  var import_react8 = require("react");
28424
28622
  init_logger();
28425
28623
  function useProjects(options) {
@@ -28442,7 +28640,7 @@ function useProjects(options) {
28442
28640
  conversations: convColl?.table
28443
28641
  });
28444
28642
  getLogger().debug("[useProjects] Running test query on projects table...");
28445
- const testResult = await projColl.query(import_watermelondb26.Q.take(1)).fetch();
28643
+ const testResult = await projColl.query(import_watermelondb27.Q.take(1)).fetch();
28446
28644
  getLogger().debug(
28447
28645
  "[useProjects] Test query succeeded, found",
28448
28646
  testResult.length,
@@ -28529,7 +28727,7 @@ function useProjects(options) {
28529
28727
  if (!projectsCollection) {
28530
28728
  return;
28531
28729
  }
28532
- const subscription = projectsCollection.query(import_watermelondb26.Q.where("is_deleted", false)).observe().subscribe((records) => {
28730
+ const subscription = projectsCollection.query(import_watermelondb27.Q.where("is_deleted", false)).observe().subscribe((records) => {
28533
28731
  setProjects(records.map(projectToStored));
28534
28732
  });
28535
28733
  return () => subscription.unsubscribe();
@@ -28652,7 +28850,7 @@ function useProjects(options) {
28652
28850
  }
28653
28851
 
28654
28852
  // src/lib/db/settings/operations.ts
28655
- var import_watermelondb27 = require("@nozbe/watermelondb");
28853
+ var import_watermelondb28 = require("@nozbe/watermelondb");
28656
28854
  function modelPreferenceToStored(preference) {
28657
28855
  return {
28658
28856
  uniqueId: preference.id,
@@ -28661,12 +28859,12 @@ function modelPreferenceToStored(preference) {
28661
28859
  };
28662
28860
  }
28663
28861
  async function getModelPreferenceOp(ctx, walletAddress) {
28664
- const results = await ctx.modelPreferencesCollection.query(import_watermelondb27.Q.where("wallet_address", walletAddress)).fetch();
28862
+ const results = await ctx.modelPreferencesCollection.query(import_watermelondb28.Q.where("wallet_address", walletAddress)).fetch();
28665
28863
  return results.length > 0 ? modelPreferenceToStored(results[0]) : null;
28666
28864
  }
28667
28865
  async function setModelPreferenceOp(ctx, walletAddress, models) {
28668
28866
  const result = await ctx.database.write(async () => {
28669
- const results = await ctx.modelPreferencesCollection.query(import_watermelondb27.Q.where("wallet_address", walletAddress)).fetch();
28867
+ const results = await ctx.modelPreferencesCollection.query(import_watermelondb28.Q.where("wallet_address", walletAddress)).fetch();
28670
28868
  if (results.length > 0) {
28671
28869
  const preference = results[0];
28672
28870
  await preference.update((pref) => {
@@ -28684,7 +28882,7 @@ async function setModelPreferenceOp(ctx, walletAddress, models) {
28684
28882
  return modelPreferenceToStored(result);
28685
28883
  }
28686
28884
  async function deleteModelPreferenceOp(ctx, walletAddress) {
28687
- const results = await ctx.modelPreferencesCollection.query(import_watermelondb27.Q.where("wallet_address", walletAddress)).fetch();
28885
+ const results = await ctx.modelPreferencesCollection.query(import_watermelondb28.Q.where("wallet_address", walletAddress)).fetch();
28688
28886
  if (results.length === 0) return false;
28689
28887
  await ctx.database.write(async () => {
28690
28888
  await results[0].destroyPermanently();
@@ -28693,11 +28891,11 @@ async function deleteModelPreferenceOp(ctx, walletAddress) {
28693
28891
  }
28694
28892
 
28695
28893
  // src/lib/db/settings/schema.ts
28696
- var import_watermelondb28 = require("@nozbe/watermelondb");
28697
- var settingsStorageSchema = (0, import_watermelondb28.appSchema)({
28894
+ var import_watermelondb29 = require("@nozbe/watermelondb");
28895
+ var settingsStorageSchema = (0, import_watermelondb29.appSchema)({
28698
28896
  version: 1,
28699
28897
  tables: [
28700
- (0, import_watermelondb28.tableSchema)({
28898
+ (0, import_watermelondb29.tableSchema)({
28701
28899
  name: "modelPreferences",
28702
28900
  columns: [
28703
28901
  { name: "wallet_address", type: "string", isIndexed: true },
@@ -28708,7 +28906,7 @@ var settingsStorageSchema = (0, import_watermelondb28.appSchema)({
28708
28906
  });
28709
28907
 
28710
28908
  // src/lib/db/vaultFolders/operations.ts
28711
- var import_watermelondb29 = require("@nozbe/watermelondb");
28909
+ var import_watermelondb30 = require("@nozbe/watermelondb");
28712
28910
  function folderToStored(folder) {
28713
28911
  return {
28714
28912
  uniqueId: folder.id,
@@ -28733,7 +28931,7 @@ async function createVaultFolderOp(ctx, opts) {
28733
28931
  return folderToStored(created);
28734
28932
  }
28735
28933
  async function getAllVaultFoldersOp(ctx) {
28736
- const results = await ctx.vaultFolderCollection.query(import_watermelondb29.Q.where("is_deleted", false), import_watermelondb29.Q.sortBy("created_at", import_watermelondb29.Q.desc)).fetch();
28934
+ const results = await ctx.vaultFolderCollection.query(import_watermelondb30.Q.where("is_deleted", false), import_watermelondb30.Q.sortBy("created_at", import_watermelondb30.Q.desc)).fetch();
28737
28935
  return results.map(folderToStored);
28738
28936
  }
28739
28937
  async function updateVaultFolderOp(ctx, id, opts) {
@@ -28742,7 +28940,7 @@ async function updateVaultFolderOp(ctx, id, opts) {
28742
28940
  if (record.isDeleted) return null;
28743
28941
  const scopeChanged = opts.scope !== void 0 && opts.scope !== record.scope;
28744
28942
  const updated = await ctx.database.write(async () => {
28745
- const memories = scopeChanged ? await ctx.vaultMemoryCollection.query(import_watermelondb29.Q.where("folder_id", id), import_watermelondb29.Q.where("is_deleted", false)).fetch() : [];
28943
+ const memories = scopeChanged ? await ctx.vaultMemoryCollection.query(import_watermelondb30.Q.where("folder_id", id), import_watermelondb30.Q.where("is_deleted", false)).fetch() : [];
28746
28944
  const updates = [];
28747
28945
  updates.push(
28748
28946
  record.prepareUpdate((r) => {
@@ -28770,7 +28968,7 @@ async function deleteVaultFolderOp(ctx, id) {
28770
28968
  const record = await ctx.vaultFolderCollection.find(id);
28771
28969
  if (record.isDeleted) return false;
28772
28970
  await ctx.database.write(async () => {
28773
- const memories = await ctx.vaultMemoryCollection.query(import_watermelondb29.Q.where("folder_id", id), import_watermelondb29.Q.where("is_deleted", false)).fetch();
28971
+ const memories = await ctx.vaultMemoryCollection.query(import_watermelondb30.Q.where("folder_id", id), import_watermelondb30.Q.where("is_deleted", false)).fetch();
28774
28972
  const preparedMemories = memories.map(
28775
28973
  (memory) => memory.prepareUpdate((r) => {
28776
28974
  r._setRaw("folder_id", null);
@@ -28839,7 +29037,7 @@ async function updateVaultFolderContextOp(ctx, id, context) {
28839
29037
  }
28840
29038
  }
28841
29039
  async function getVaultFolderMemoryCountOp(ctx, folderId) {
28842
- return await ctx.vaultMemoryCollection.query(import_watermelondb29.Q.where("folder_id", folderId), import_watermelondb29.Q.where("is_deleted", false)).fetchCount();
29040
+ return await ctx.vaultMemoryCollection.query(import_watermelondb30.Q.where("folder_id", folderId), import_watermelondb30.Q.where("is_deleted", false)).fetchCount();
28843
29041
  }
28844
29042
 
28845
29043
  // src/lib/db/vaultFolders/defaults.ts
@@ -28885,7 +29083,7 @@ async function _ensureDefaultFoldersImpl(ctx) {
28885
29083
  var import_react9 = require("react");
28886
29084
 
28887
29085
  // src/lib/db/userPreferences/operations.ts
28888
- var import_watermelondb30 = require("@nozbe/watermelondb");
29086
+ var import_watermelondb31 = require("@nozbe/watermelondb");
28889
29087
  function userPreferenceToStored(preference) {
28890
29088
  return {
28891
29089
  uniqueId: preference.id,
@@ -28900,7 +29098,7 @@ function userPreferenceToStored(preference) {
28900
29098
  };
28901
29099
  }
28902
29100
  async function getUserPreferenceOp(ctx, walletAddress) {
28903
- const results = await ctx.userPreferencesCollection.query(import_watermelondb30.Q.where("wallet_address", walletAddress)).fetch();
29101
+ const results = await ctx.userPreferencesCollection.query(import_watermelondb31.Q.where("wallet_address", walletAddress)).fetch();
28904
29102
  return results.length > 0 ? userPreferenceToStored(results[0]) : null;
28905
29103
  }
28906
29104
  async function createUserPreferenceOp(ctx, opts) {
@@ -28920,7 +29118,7 @@ async function createUserPreferenceOp(ctx, opts) {
28920
29118
  return userPreferenceToStored(created);
28921
29119
  }
28922
29120
  async function updateUserPreferenceOp(ctx, walletAddress, opts) {
28923
- const results = await ctx.userPreferencesCollection.query(import_watermelondb30.Q.where("wallet_address", walletAddress)).fetch();
29121
+ const results = await ctx.userPreferencesCollection.query(import_watermelondb31.Q.where("wallet_address", walletAddress)).fetch();
28924
29122
  if (results.length === 0) return null;
28925
29123
  const preference = results[0];
28926
29124
  await ctx.database.write(async () => {
@@ -28948,7 +29146,7 @@ async function updateUserPreferenceOp(ctx, walletAddress, opts) {
28948
29146
  async function setUserPreferenceOp(ctx, walletAddress, opts) {
28949
29147
  const now = Date.now();
28950
29148
  const result = await ctx.database.write(async () => {
28951
- const results = await ctx.userPreferencesCollection.query(import_watermelondb30.Q.where("wallet_address", walletAddress)).fetch();
29149
+ const results = await ctx.userPreferencesCollection.query(import_watermelondb31.Q.where("wallet_address", walletAddress)).fetch();
28952
29150
  if (results.length > 0) {
28953
29151
  const preference = results[0];
28954
29152
  await preference.update((pref) => {
@@ -28996,7 +29194,7 @@ async function updateModelsOp(ctx, walletAddress, models) {
28996
29194
  return updateUserPreferenceOp(ctx, walletAddress, { models });
28997
29195
  }
28998
29196
  async function deleteUserPreferenceOp(ctx, walletAddress) {
28999
- const results = await ctx.userPreferencesCollection.query(import_watermelondb30.Q.where("wallet_address", walletAddress)).fetch();
29197
+ const results = await ctx.userPreferencesCollection.query(import_watermelondb31.Q.where("wallet_address", walletAddress)).fetch();
29000
29198
  if (results.length === 0) return false;
29001
29199
  await ctx.database.write(async () => {
29002
29200
  await results[0].destroyPermanently();
@@ -29011,9 +29209,9 @@ async function migrateFromModelPreferencesOp(ctx, walletAddress) {
29011
29209
  if (existing) {
29012
29210
  return existing;
29013
29211
  }
29014
- const modelResults = await ctx.modelPreferencesCollection.query(import_watermelondb30.Q.where("wallet_address", walletAddress)).fetch();
29212
+ const modelResults = await ctx.modelPreferencesCollection.query(import_watermelondb31.Q.where("wallet_address", walletAddress)).fetch();
29015
29213
  const personalityKey = `${walletAddress}_personality_settings`;
29016
- const personalityResults = await ctx.modelPreferencesCollection.query(import_watermelondb30.Q.where("wallet_address", personalityKey)).fetch();
29214
+ const personalityResults = await ctx.modelPreferencesCollection.query(import_watermelondb31.Q.where("wallet_address", personalityKey)).fetch();
29017
29215
  if (modelResults.length === 0 && personalityResults.length === 0) {
29018
29216
  return null;
29019
29217
  }
@@ -29055,11 +29253,11 @@ async function migrateFromModelPreferencesOp(ctx, walletAddress) {
29055
29253
  }
29056
29254
 
29057
29255
  // src/lib/db/userPreferences/schema.ts
29058
- var import_watermelondb31 = require("@nozbe/watermelondb");
29059
- var userPreferencesStorageSchema = (0, import_watermelondb31.appSchema)({
29256
+ var import_watermelondb32 = require("@nozbe/watermelondb");
29257
+ var userPreferencesStorageSchema = (0, import_watermelondb32.appSchema)({
29060
29258
  version: 1,
29061
29259
  tables: [
29062
- (0, import_watermelondb31.tableSchema)({
29260
+ (0, import_watermelondb32.tableSchema)({
29063
29261
  name: "userPreferences",
29064
29262
  columns: [
29065
29263
  // Identity
@@ -29119,7 +29317,7 @@ var SLIDER_CONFIG = [
29119
29317
  ];
29120
29318
 
29121
29319
  // src/react/userSettingsStore.ts
29122
- var import_watermelondb32 = require("@nozbe/watermelondb");
29320
+ var import_watermelondb33 = require("@nozbe/watermelondb");
29123
29321
  var EMPTY_SNAPSHOT = Object.freeze({
29124
29322
  modelPreference: null,
29125
29323
  userPreference: null,
@@ -29181,7 +29379,7 @@ async function startLoad(entry, walletAddress) {
29181
29379
  }
29182
29380
  function startObserve(entry, walletAddress) {
29183
29381
  let isInitialEmission = true;
29184
- entry.observeSub = entry.storageCtx.userPreferencesCollection.query(import_watermelondb32.Q.where("wallet_address", walletAddress)).observeWithColumns([
29382
+ entry.observeSub = entry.storageCtx.userPreferencesCollection.query(import_watermelondb33.Q.where("wallet_address", walletAddress)).observeWithColumns([
29185
29383
  "nickname",
29186
29384
  "occupation",
29187
29385
  "description",
@@ -29445,7 +29643,7 @@ function useSettings(options) {
29445
29643
  }
29446
29644
 
29447
29645
  // src/lib/db/appFiles/operations.ts
29448
- var import_watermelondb33 = require("@nozbe/watermelondb");
29646
+ var import_watermelondb34 = require("@nozbe/watermelondb");
29449
29647
 
29450
29648
  // src/utils/paths.ts
29451
29649
  function normalizePath(p) {
@@ -29471,7 +29669,7 @@ async function putAppFileOp(ctx, conversationId, path, content) {
29471
29669
  const normalized = normalizePath(path);
29472
29670
  const now = Date.now();
29473
29671
  const result = await ctx.database.write(async () => {
29474
- const existing = await ctx.appFilesCollection.query(import_watermelondb33.Q.where("conversation_id", conversationId), import_watermelondb33.Q.where("path", normalized)).fetch();
29672
+ const existing = await ctx.appFilesCollection.query(import_watermelondb34.Q.where("conversation_id", conversationId), import_watermelondb34.Q.where("path", normalized)).fetch();
29475
29673
  if (existing.length > 0) {
29476
29674
  await existing[0].update((f) => {
29477
29675
  f._setRaw("content", content);
@@ -29491,11 +29689,11 @@ async function putAppFileOp(ctx, conversationId, path, content) {
29491
29689
  }
29492
29690
  async function getAppFileOp(ctx, conversationId, path) {
29493
29691
  const normalized = normalizePath(path);
29494
- const results = await ctx.appFilesCollection.query(import_watermelondb33.Q.where("conversation_id", conversationId), import_watermelondb33.Q.where("path", normalized)).fetch();
29692
+ const results = await ctx.appFilesCollection.query(import_watermelondb34.Q.where("conversation_id", conversationId), import_watermelondb34.Q.where("path", normalized)).fetch();
29495
29693
  return results.length > 0 ? appFileToStored(results[0]) : null;
29496
29694
  }
29497
29695
  async function getAppFilesOp(ctx, conversationId) {
29498
- const results = await ctx.appFilesCollection.query(import_watermelondb33.Q.where("conversation_id", conversationId)).fetch();
29696
+ const results = await ctx.appFilesCollection.query(import_watermelondb34.Q.where("conversation_id", conversationId)).fetch();
29499
29697
  return results.map(appFileToStored);
29500
29698
  }
29501
29699
  async function getAppFileMapOp(ctx, conversationId) {
@@ -29506,7 +29704,7 @@ async function getAppFileMapOp(ctx, conversationId) {
29506
29704
  }
29507
29705
  async function deleteAppFileOp(ctx, conversationId, path) {
29508
29706
  const normalized = normalizePath(path);
29509
- const results = await ctx.appFilesCollection.query(import_watermelondb33.Q.where("conversation_id", conversationId), import_watermelondb33.Q.where("path", normalized)).fetch();
29707
+ const results = await ctx.appFilesCollection.query(import_watermelondb34.Q.where("conversation_id", conversationId), import_watermelondb34.Q.where("path", normalized)).fetch();
29510
29708
  if (results.length === 0) return false;
29511
29709
  await ctx.database.write(async () => {
29512
29710
  await results[0].destroyPermanently();
@@ -29514,7 +29712,7 @@ async function deleteAppFileOp(ctx, conversationId, path) {
29514
29712
  return true;
29515
29713
  }
29516
29714
  async function deleteAllAppFilesOp(ctx, conversationId) {
29517
- const results = await ctx.appFilesCollection.query(import_watermelondb33.Q.where("conversation_id", conversationId)).fetch();
29715
+ const results = await ctx.appFilesCollection.query(import_watermelondb34.Q.where("conversation_id", conversationId)).fetch();
29518
29716
  if (results.length === 0) return;
29519
29717
  await ctx.database.write(async () => {
29520
29718
  const batch = results.map((file) => file.prepareDestroyPermanently());
@@ -29523,7 +29721,7 @@ async function deleteAllAppFilesOp(ctx, conversationId) {
29523
29721
  }
29524
29722
 
29525
29723
  // src/lib/db/conversationMemory/operations.ts
29526
- var import_watermelondb34 = require("@nozbe/watermelondb");
29724
+ var import_watermelondb35 = require("@nozbe/watermelondb");
29527
29725
  var MAX_PER_CONVERSATION = 200;
29528
29726
  function conversationMemoryToStored(row) {
29529
29727
  return {
@@ -29538,7 +29736,7 @@ async function addConversationMemoriesOp(ctx, conversationId, items) {
29538
29736
  if (!conversationId || items.length === 0) return;
29539
29737
  const now = Date.now();
29540
29738
  await ctx.database.write(async () => {
29541
- const existing = await ctx.conversationMemoryCollection.query(import_watermelondb34.Q.where("conversation_id", conversationId), import_watermelondb34.Q.sortBy("created_at", import_watermelondb34.Q.asc)).fetch();
29739
+ const existing = await ctx.conversationMemoryCollection.query(import_watermelondb35.Q.where("conversation_id", conversationId), import_watermelondb35.Q.sortBy("created_at", import_watermelondb35.Q.asc)).fetch();
29542
29740
  const seen = new Set(existing.map((r) => r.memoryId));
29543
29741
  const batchSeen = /* @__PURE__ */ new Set();
29544
29742
  const deduped = [];
@@ -29573,20 +29771,20 @@ async function addConversationMemoriesOp(ctx, conversationId, items) {
29573
29771
  }
29574
29772
  async function getConversationMemoriesOp(ctx, conversationId) {
29575
29773
  if (!conversationId) return [];
29576
- const rows = await ctx.conversationMemoryCollection.query(import_watermelondb34.Q.where("conversation_id", conversationId), import_watermelondb34.Q.sortBy("created_at", import_watermelondb34.Q.asc)).fetch();
29774
+ const rows = await ctx.conversationMemoryCollection.query(import_watermelondb35.Q.where("conversation_id", conversationId), import_watermelondb35.Q.sortBy("created_at", import_watermelondb35.Q.asc)).fetch();
29577
29775
  return rows.map(conversationMemoryToStored);
29578
29776
  }
29579
29777
  async function clearConversationMemoriesOp(ctx, conversationId) {
29580
29778
  if (!conversationId) return;
29581
29779
  await ctx.database.write(async () => {
29582
- const rows = await ctx.conversationMemoryCollection.query(import_watermelondb34.Q.where("conversation_id", conversationId)).fetch();
29780
+ const rows = await ctx.conversationMemoryCollection.query(import_watermelondb35.Q.where("conversation_id", conversationId)).fetch();
29583
29781
  if (rows.length === 0) return;
29584
29782
  await ctx.database.batch(...rows.map((r) => r.prepareDestroyPermanently()));
29585
29783
  });
29586
29784
  }
29587
29785
 
29588
29786
  // src/lib/db/savedTools/operations.ts
29589
- var import_watermelondb35 = require("@nozbe/watermelondb");
29787
+ var import_watermelondb36 = require("@nozbe/watermelondb");
29590
29788
  function savedToolToStored(tool) {
29591
29789
  return {
29592
29790
  uniqueId: tool.id,
@@ -29619,7 +29817,7 @@ async function createSavedToolOp(ctx, opts) {
29619
29817
  return savedToolToStored(created);
29620
29818
  }
29621
29819
  async function getAllSavedToolsOp(ctx) {
29622
- const results = await ctx.savedToolsCollection.query(import_watermelondb35.Q.where("is_deleted", false), import_watermelondb35.Q.sortBy("created_at", import_watermelondb35.Q.desc)).fetch();
29820
+ const results = await ctx.savedToolsCollection.query(import_watermelondb36.Q.where("is_deleted", false), import_watermelondb36.Q.sortBy("created_at", import_watermelondb36.Q.desc)).fetch();
29623
29821
  return results.map(savedToolToStored);
29624
29822
  }
29625
29823
  async function getSavedToolByIdOp(ctx, uniqueId) {
@@ -32280,8 +32478,8 @@ function createDropboxFileIndex(backupFolder) {
32280
32478
  };
32281
32479
  }
32282
32480
  async function readLocalUpdatedAt(database, conversationId) {
32283
- const { Q: Q19 } = await import("@nozbe/watermelondb");
32284
- const records = await database.get("conversations").query(Q19.where("conversation_id", conversationId)).fetch();
32481
+ const { Q: Q20 } = await import("@nozbe/watermelondb");
32482
+ const records = await database.get("conversations").query(Q20.where("conversation_id", conversationId)).fetch();
32285
32483
  const match = records.map(conversationToStoredRaw).find((c) => c.conversationId === conversationId);
32286
32484
  return match ? match.updatedAt : null;
32287
32485
  }
@@ -32337,9 +32535,9 @@ async function pushConversationToDropbox(database, conversationId, userAddress,
32337
32535
  }
32338
32536
  async function performDropboxExport(database, userAddress, token, deps, onProgress, backupFolder = DEFAULT_BACKUP_FOLDER) {
32339
32537
  await deps.requestEncryptionKey(userAddress);
32340
- const { Q: Q19 } = await import("@nozbe/watermelondb");
32538
+ const { Q: Q20 } = await import("@nozbe/watermelondb");
32341
32539
  const conversationsCollection = database.get("conversations");
32342
- const records = await conversationsCollection.query(Q19.where("is_deleted", false)).fetch();
32540
+ const records = await conversationsCollection.query(Q20.where("is_deleted", false)).fetch();
32343
32541
  const conversations = records.map(conversationToStoredRaw);
32344
32542
  const total = conversations.length;
32345
32543
  if (total === 0) {
@@ -33016,8 +33214,8 @@ function createDriveFileIndex(folderId) {
33016
33214
  };
33017
33215
  }
33018
33216
  async function readLocalUpdatedAt2(database, conversationId) {
33019
- const { Q: Q19 } = await import("@nozbe/watermelondb");
33020
- const records = await database.get("conversations").query(Q19.where("conversation_id", conversationId)).fetch();
33217
+ const { Q: Q20 } = await import("@nozbe/watermelondb");
33218
+ const records = await database.get("conversations").query(Q20.where("conversation_id", conversationId)).fetch();
33021
33219
  const match = records.map(conversationToStoredRaw).find((c) => c.conversationId === conversationId);
33022
33220
  return match ? match.updatedAt : null;
33023
33221
  }
@@ -33097,9 +33295,9 @@ async function performGoogleDriveExport(database, userAddress, token, deps, onPr
33097
33295
  }
33098
33296
  const { folderId, token: activeToken } = folderResult;
33099
33297
  const fileIndex = createDriveFileIndex(folderId);
33100
- const { Q: Q19 } = await import("@nozbe/watermelondb");
33298
+ const { Q: Q20 } = await import("@nozbe/watermelondb");
33101
33299
  const conversationsCollection = database.get("conversations");
33102
- const records = await conversationsCollection.query(Q19.where("is_deleted", false)).fetch();
33300
+ const records = await conversationsCollection.query(Q20.where("is_deleted", false)).fetch();
33103
33301
  const conversations = records.map(conversationToStoredRaw);
33104
33302
  const total = conversations.length;
33105
33303
  if (total === 0) {
@@ -33679,9 +33877,9 @@ async function pushConversationToICloud(database, conversationId, userAddress, d
33679
33877
  const filename = `${conversationId}.json`;
33680
33878
  const existingFile = await findICloudFile(filename);
33681
33879
  if (existingFile) {
33682
- const { Q: Q19 } = await import("@nozbe/watermelondb");
33880
+ const { Q: Q20 } = await import("@nozbe/watermelondb");
33683
33881
  const conversationsCollection = database.get("conversations");
33684
- const records = await conversationsCollection.query(Q19.where("conversation_id", conversationId)).fetch();
33882
+ const records = await conversationsCollection.query(Q20.where("conversation_id", conversationId)).fetch();
33685
33883
  if (records.length > 0) {
33686
33884
  const conversation = conversationToStoredRaw(records[0]);
33687
33885
  const localUpdated = conversation.updatedAt.getTime();
@@ -33711,9 +33909,9 @@ async function pushConversationToICloud(database, conversationId, userAddress, d
33711
33909
  }
33712
33910
  async function performICloudExport(database, userAddress, deps, onProgress) {
33713
33911
  await deps.requestEncryptionKey(userAddress);
33714
- const { Q: Q19 } = await import("@nozbe/watermelondb");
33912
+ const { Q: Q20 } = await import("@nozbe/watermelondb");
33715
33913
  const conversationsCollection = database.get("conversations");
33716
- const records = await conversationsCollection.query(Q19.where("is_deleted", false)).fetch();
33914
+ const records = await conversationsCollection.query(Q20.where("is_deleted", false)).fetch();
33717
33915
  const conversations = records.map(conversationToStoredRaw);
33718
33916
  const total = conversations.length;
33719
33917
  if (total === 0) {
@@ -37688,6 +37886,7 @@ function renderAnumaJsx(jsx3) {
37688
37886
  createGitHubTools,
37689
37887
  createLlmDecayClassifier,
37690
37888
  createLlmNeighborRefiner,
37889
+ createLocalMemoryStore,
37691
37890
  createMediaBatchOp,
37692
37891
  createMediaOp,
37693
37892
  createMemoryEngineTool,
@@ -37746,6 +37945,7 @@ function renderAnumaJsx(jsx3) {
37746
37945
  extractEntitiesForMemories,
37747
37946
  extractFacts,
37748
37947
  extractFileIds,
37948
+ extractMCPImageUrls,
37749
37949
  fileExists,
37750
37950
  findById,
37751
37951
  findMatchingTools,