@anuma/sdk 6.32.0 → 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.
@@ -15267,7 +15267,10 @@ async function eagerEmbedContent(content, embeddingOptions, cache, vaultCtx, mem
15267
15267
  if (memoryId) cacheRowVector(cache, memoryId, Float32Array.from(embedding), updatedAt, content);
15268
15268
  if (vaultCtx && memoryId) {
15269
15269
  const currentModel = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
15270
- updateVaultMemoryEmbeddingOp(vaultCtx, memoryId, JSON.stringify(embedding), currentModel).catch(
15270
+ updateVaultMemoryEmbeddingOp(vaultCtx, memoryId, JSON.stringify(embedding), currentModel, {
15271
+ content,
15272
+ ...updatedAt !== void 0 && { updatedAt: updatedAt.getTime() }
15273
+ }).catch(
15271
15274
  // Silently swallow – SDK must not use console.*; embedding will be retried on next search
15272
15275
  () => {
15273
15276
  }
@@ -18788,6 +18791,349 @@ function parseAnswer(body, base, parseSchema) {
18788
18791
  };
18789
18792
  }
18790
18793
 
18794
+ // src/lib/memory/store/local.ts
18795
+ import { Q as Q8 } from "@nozbe/watermelondb";
18796
+
18797
+ // src/lib/memory/topicExtract.ts
18798
+ var TOPIC_EXTRACTION_BATCH_SIZE = 10;
18799
+ var MAX_CHARS_PER_MEMORY = 300;
18800
+ var MAX_VOCABULARY_NAMES = 100;
18801
+ var MAX_COMPLETION_TOKENS = 8192;
18802
+ var SYSTEM_PROMPT5 = `You assign topics to saved memories for a personal memory system.
18803
+
18804
+ 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.
18805
+
18806
+ 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:
18807
+ - 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.
18808
+ - KEEP the specific thing instead, when the memory names one: "Blue Bottle on Valencia" over "cafe", "Chicago Marathon" over "event", "Hollowpoint Labs" over "work".
18809
+ - Prefer 0 entities over a weak one. A memory whose only candidate is a generic noun has NO entities.
18810
+ ${ENTITY_KIND_GUIDELINES}
18811
+
18812
+ Each memory below is written as "<id>: <text>". Output strict JSON: {"memories": [{"id": string, "entities": [{"name": string, "kind": string}]}]}
18813
+ - exactly one element per input memory; copy its id EXACTLY as written (the token before the first ": "), with no brackets, quotes, or extra characters
18814
+ - "entities" may be empty when a memory mentions no named entities \u2014 most short memories have 0-3
18815
+ No prose.`;
18816
+ async function extractEntitiesForMemories(memories, options) {
18817
+ const out = /* @__PURE__ */ new Map();
18818
+ if (memories.length === 0) return out;
18819
+ const redactor = resolvePiiRedactor(options.piiRedaction);
18820
+ const vocabulary = [];
18821
+ for (const name of (options.existingEntityNames ?? []).filter((n) => n.trim().length > 0).slice(0, MAX_VOCABULARY_NAMES)) {
18822
+ vocabulary.push(redactor ? (await redactor.redactTextAsync(name)).text : name);
18823
+ }
18824
+ const vocabularyNote = vocabulary.length > 0 ? `The user's existing topics: ${vocabulary.join(", ")}.
18825
+ 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".
18826
+
18827
+ ` : "";
18828
+ for (let i = 0; i < memories.length; i += TOPIC_EXTRACTION_BATCH_SIZE) {
18829
+ const batch = memories.slice(i, i + TOPIC_EXTRACTION_BATCH_SIZE);
18830
+ const rows = [];
18831
+ for (const m of batch) {
18832
+ const content = m.content.slice(0, MAX_CHARS_PER_MEMORY).replace(/\s+/g, " ").trim();
18833
+ rows.push(`${m.id}: ${redactor ? (await redactor.redactTextAsync(content)).text : content}`);
18834
+ }
18835
+ const listing = rows.join("\n");
18836
+ const parsed = await callPortalJsonCompletion({
18837
+ ...options.apiKey !== void 0 && { apiKey: options.apiKey },
18838
+ ...options.getToken !== void 0 && { getToken: options.getToken },
18839
+ ...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
18840
+ taskType: "memory_topic",
18841
+ ...options.endpointOverride !== void 0 && {
18842
+ endpointOverride: options.endpointOverride
18843
+ },
18844
+ model: options.model ?? DEFAULT_EXTRACTION_MODEL,
18845
+ systemPrompt: SYSTEM_PROMPT5,
18846
+ userMessage: `${vocabularyNote}Memories:
18847
+ ${listing}
18848
+
18849
+ List each memory's named entities.`,
18850
+ tag: "memory/topics",
18851
+ extra: { max_completion_tokens: MAX_COMPLETION_TOKENS },
18852
+ ...options.fetchFn && { fetchFn: options.fetchFn },
18853
+ ...options.maxAttempts !== void 0 && { maxAttempts: options.maxAttempts },
18854
+ ...options.timeoutMs !== void 0 && { timeoutMs: options.timeoutMs },
18855
+ ...options.totalTimeoutMs !== void 0 && { totalTimeoutMs: options.totalTimeoutMs },
18856
+ ...options.backoffMs && { backoffMs: options.backoffMs }
18857
+ });
18858
+ if (parsed === null) {
18859
+ getLogger().warn(
18860
+ `[memory/topics] batch of ${batch.length} failed after retries \u2014 will retry next sweep`
18861
+ );
18862
+ continue;
18863
+ }
18864
+ const validIds = new Set(batch.map((m) => m.id));
18865
+ const byId = parseTopicResponse(parsed, validIds);
18866
+ if (byId === null) {
18867
+ getLogger().warn(
18868
+ `[memory/topics] batch of ${batch.length} returned an unrecognized shape \u2014 will retry next sweep`
18869
+ );
18870
+ continue;
18871
+ }
18872
+ for (const m of batch) {
18873
+ const entities = byId.get(m.id);
18874
+ if (entities === void 0) {
18875
+ continue;
18876
+ }
18877
+ out.set(m.id, redactor ? restoreEntities(entities, redactor) : entities);
18878
+ }
18879
+ }
18880
+ return out;
18881
+ }
18882
+ function restoreEntities(entities, redactor) {
18883
+ return entities.map((e) => ({ kind: e.kind, restored: redactor.restoreForStorage(e.name) })).filter((e) => !e.restored.unresolved).map(
18884
+ (e) => e.kind !== void 0 ? { name: e.restored.text, kind: e.kind } : { name: e.restored.text }
18885
+ );
18886
+ }
18887
+ function parseTopicResponse(parsed, validIds) {
18888
+ if (typeof parsed !== "object" || parsed === null) return null;
18889
+ const list = parsed.memories;
18890
+ if (!Array.isArray(list)) return null;
18891
+ const out = /* @__PURE__ */ new Map();
18892
+ for (const raw of list) {
18893
+ if (typeof raw !== "object" || raw === null) continue;
18894
+ const obj = raw;
18895
+ if (typeof obj.id !== "string") continue;
18896
+ const id = obj.id.trim().replace(/:$/, "").replace(/^\[([\s\S]*)\]$/, "$1").trim();
18897
+ if (!validIds.has(id) || out.has(id)) continue;
18898
+ const entities = Array.isArray(obj.entities) ? parseEntities(obj.entities) : [];
18899
+ out.set(id, entities);
18900
+ }
18901
+ return out;
18902
+ }
18903
+ var DEGRADED_TOPIC_SKIP = {
18904
+ excluded: false,
18905
+ "link-declined": false,
18906
+ "stamp-declined": false,
18907
+ "llm-unanswered": true,
18908
+ unreadable: true,
18909
+ "not-found": true,
18910
+ "link-failed": true
18911
+ };
18912
+ function isDegradedTopicSkip(reason) {
18913
+ return DEGRADED_TOPIC_SKIP[reason] === true;
18914
+ }
18915
+ async function extractAndLinkEntitiesForMemoriesOp(ctx, memoryIds, options) {
18916
+ const entityCtx = ctx.entityCtx;
18917
+ if (!entityCtx) {
18918
+ throw new Error("extractAndLinkEntitiesForMemoriesOp requires ctx.entityCtx");
18919
+ }
18920
+ const log = getLogger();
18921
+ const extractedAt = options.now ?? Date.now();
18922
+ const skippedIds = [];
18923
+ const skippedReasons = /* @__PURE__ */ new Map();
18924
+ const skip = (id, reason) => {
18925
+ if (skippedReasons.has(id)) return;
18926
+ skippedIds.push(id);
18927
+ skippedReasons.set(id, reason);
18928
+ };
18929
+ const inputs = [];
18930
+ for (const id of new Set(memoryIds)) {
18931
+ let record;
18932
+ try {
18933
+ record = await ctx.vaultMemoryCollection.find(id);
18934
+ } catch (err) {
18935
+ log.warn("[memory/topics] vault lookup failed for extraction", err);
18936
+ skip(id, "not-found");
18937
+ continue;
18938
+ }
18939
+ if (record.isDeleted || ctx.userId !== void 0 && record.userId !== ctx.userId || record.topicsUserManaged) {
18940
+ skip(id, "excluded");
18941
+ continue;
18942
+ }
18943
+ try {
18944
+ const stored = await vaultMemoryToStored(
18945
+ record,
18946
+ ctx.walletAddress,
18947
+ ctx.signMessage,
18948
+ ctx.embeddedWalletSigner
18949
+ );
18950
+ inputs.push({ id, content: stored.content });
18951
+ } catch (err) {
18952
+ log.warn("[memory/topics] failed to load memory for extraction", err);
18953
+ skip(id, "unreadable");
18954
+ }
18955
+ }
18956
+ const entitiesByMemory = await extractEntitiesForMemories(inputs, options);
18957
+ const toStamp = [];
18958
+ for (const input of inputs) {
18959
+ const entities = entitiesByMemory.get(input.id);
18960
+ if (entities === void 0) {
18961
+ skip(input.id, "llm-unanswered");
18962
+ continue;
18963
+ }
18964
+ try {
18965
+ const linked = await replaceMemoryEntitiesGuardedOp(entityCtx, input.id, entities);
18966
+ if (linked === null) {
18967
+ skip(input.id, "link-declined");
18968
+ entitiesByMemory.delete(input.id);
18969
+ continue;
18970
+ }
18971
+ } catch (err) {
18972
+ log.warn("[memory/topics] replaceMemoryEntitiesGuardedOp failed", err);
18973
+ skip(input.id, "link-failed");
18974
+ entitiesByMemory.delete(input.id);
18975
+ continue;
18976
+ }
18977
+ toStamp.push(input.id);
18978
+ }
18979
+ const stampedIds = await stampTopicsExtractedAtOp(ctx, toStamp, extractedAt);
18980
+ const stampedSet = new Set(stampedIds);
18981
+ for (const id of toStamp) {
18982
+ if (!stampedSet.has(id)) {
18983
+ skip(id, "stamp-declined");
18984
+ entitiesByMemory.delete(id);
18985
+ }
18986
+ }
18987
+ return { entitiesByMemory, stampedIds, skippedIds, skippedReasons };
18988
+ }
18989
+
18990
+ // src/lib/memory/store/local.ts
18991
+ function createLocalMemoryStore(options) {
18992
+ const { database, userId } = options;
18993
+ const entityCtx = {
18994
+ database,
18995
+ entityCollection: database.get("entity"),
18996
+ memoryEntityCollection: database.get("memory_entity"),
18997
+ ...userId !== void 0 && { userId },
18998
+ ...options.allowUnscopedRows !== void 0 && {
18999
+ allowUnscopedRows: options.allowUnscopedRows
19000
+ }
19001
+ };
19002
+ const vaultCtx = {
19003
+ database,
19004
+ vaultMemoryCollection: database.get("memory_vault"),
19005
+ walletAddress: options.walletAddress,
19006
+ signMessage: options.signMessage,
19007
+ embeddedWalletSigner: options.embeddedWalletSigner,
19008
+ ...userId !== void 0 && { userId },
19009
+ ...options.singleTenant !== void 0 && { singleTenant: options.singleTenant },
19010
+ // Deletes cascade to memory_entity, so the graph lane never serves a
19011
+ // deleted memory's id.
19012
+ entityCtx
19013
+ };
19014
+ const vaultCache = options.vaultCache ?? createVaultEmbeddingCache();
19015
+ const ownedBy = userId !== void 0 ? [Q8.where("user_id", userId)] : [];
19016
+ const watchedColumns = [
19017
+ "content",
19018
+ "scope",
19019
+ "updated_at",
19020
+ "fact_type",
19021
+ "event_time_start",
19022
+ "event_time_end",
19023
+ "event_time_kind",
19024
+ "archived_at",
19025
+ "trust_tier",
19026
+ "superseded_by",
19027
+ "visibility",
19028
+ "published_at",
19029
+ "geohash",
19030
+ "topics",
19031
+ "topics_user_managed",
19032
+ "media",
19033
+ "source"
19034
+ ];
19035
+ const embedInBackground = (memory) => {
19036
+ eagerEmbedContent(
19037
+ memory.content,
19038
+ options.embeddingOptions,
19039
+ vaultCache,
19040
+ vaultCtx,
19041
+ memory.uniqueId,
19042
+ memory.updatedAt
19043
+ ).catch((err) => {
19044
+ getLogger().warn("[memory/store] Failed to embed memory:", err);
19045
+ });
19046
+ };
19047
+ return {
19048
+ list: (listOptions) => getAllVaultMemoriesOp(vaultCtx, listOptions),
19049
+ get: (id) => getVaultMemoryOp(vaultCtx, id),
19050
+ listArchived: async () => {
19051
+ const ids = await vaultCtx.vaultMemoryCollection.query(Q8.where("is_deleted", false), Q8.where("archived_at", Q8.notEq(null)), ...ownedBy).fetchIds();
19052
+ if (ids.length === 0) return [];
19053
+ const rows = await getAllVaultMemoriesOp(vaultCtx, { memoryIds: ids, includeArchived: true });
19054
+ return rows.sort((a, b) => (b.archivedAt ?? 0) - (a.archivedAt ?? 0));
19055
+ },
19056
+ memoriesByTopics: (names) => getMemoriesByEntityNamesOp(entityCtx, names),
19057
+ topicsByMemories: (memoryIds) => getEntitiesByMemoryIdsOp(entityCtx, memoryIds),
19058
+ create: async (input) => {
19059
+ const created = await createVaultMemoryOp(vaultCtx, input);
19060
+ if (input.embedding === void 0) embedInBackground(created);
19061
+ return created;
19062
+ },
19063
+ createMany: async (inputs) => {
19064
+ const created = await createVaultMemoriesBatchOp(vaultCtx, inputs);
19065
+ created.forEach((memory, i) => {
19066
+ if (inputs[i].embedding === void 0) embedInBackground(memory);
19067
+ });
19068
+ return created;
19069
+ },
19070
+ update: async (id, patch) => {
19071
+ const reembed = patch.embedding === void 0;
19072
+ const updated = await updateVaultMemoryOp(
19073
+ vaultCtx,
19074
+ id,
19075
+ reembed ? { ...patch, embedding: null } : patch
19076
+ );
19077
+ if (!updated) return null;
19078
+ vaultCache.delete(id);
19079
+ if (reembed) embedInBackground(updated);
19080
+ return updated;
19081
+ },
19082
+ delete: async (id) => {
19083
+ const deleted = await deleteVaultMemoryOp(vaultCtx, id);
19084
+ if (deleted) vaultCache.delete(id);
19085
+ return deleted;
19086
+ },
19087
+ supersede: (id, supersededById) => supersedeVaultMemoryOp(vaultCtx, id, supersededById),
19088
+ archive: (id) => archiveVaultMemoryOp(vaultCtx, id),
19089
+ restore: (id) => restoreVaultMemoryOp(vaultCtx, id),
19090
+ setTopics: (memoryId, topics) => setMemoryEntitiesOp(vaultCtx, memoryId, topics),
19091
+ addTopics: (memoryId, topics) => database.write(async (writer) => {
19092
+ const owned = await vaultCtx.vaultMemoryCollection.query(Q8.where("id", memoryId), Q8.where("is_deleted", false), ...ownedBy).fetchCount();
19093
+ return owned > 0 ? writer.callWriter(() => linkMemoryEntitiesOp(entityCtx, memoryId, topics)) : [];
19094
+ }),
19095
+ setVisibility: (id, visibility, visibilityOptions) => setMemoryVisibilityOp(vaultCtx, id, { visibility, ...visibilityOptions }),
19096
+ recall: (query, recallOptions) => recall(
19097
+ query,
19098
+ { vaultCtx, entityCtx, embeddingOptions: options.embeddingOptions, vaultCache },
19099
+ { ...recallOptions, types: ["fact"] }
19100
+ ),
19101
+ retain: (content, retainOptions) => retain(
19102
+ content,
19103
+ { vaultCtx, embeddingOptions: options.embeddingOptions, vaultCache },
19104
+ retainOptions
19105
+ ),
19106
+ subscribe: (onChange, subscribeOptions) => {
19107
+ const afterFirst = () => {
19108
+ let first = true;
19109
+ return () => {
19110
+ if (first) first = false;
19111
+ else onChange();
19112
+ };
19113
+ };
19114
+ const memories = subscribeOptions?.includeDeleted ? vaultCtx.vaultMemoryCollection.query(...ownedBy).observe() : vaultCtx.vaultMemoryCollection.query(Q8.where("is_deleted", false), ...ownedBy).observeWithColumns(
19115
+ subscribeOptions?.embeddings ? [...watchedColumns, "embedding", "embedding_model"] : watchedColumns
19116
+ );
19117
+ const subscriptions = [memories.subscribe(afterFirst())];
19118
+ if (subscribeOptions?.topics) {
19119
+ const linksOwnedBy = userId === void 0 ? [] : options.allowUnscopedRows ? [Q8.or(Q8.where("user_id", userId), Q8.where("user_id", null))] : [Q8.where("user_id", userId)];
19120
+ subscriptions.push(
19121
+ entityCtx.memoryEntityCollection.query(...linksOwnedBy).observe().subscribe(afterFirst())
19122
+ );
19123
+ }
19124
+ return () => subscriptions.forEach((s) => s.unsubscribe());
19125
+ },
19126
+ maintenance: {
19127
+ createDecaySweeper: (sweeperOptions) => createDecaySweeper({ ...sweeperOptions, vaultCtx }),
19128
+ getTopicBacklog: (backlogOptions) => getMemoriesNeedingTopicExtractionOp(vaultCtx, backlogOptions),
19129
+ extractTopics: (memoryIds, extractOptions) => extractAndLinkEntitiesForMemoriesOp(vaultCtx, memoryIds, extractOptions),
19130
+ stampTopicsExtracted: (memoryIds, extractedAt, version) => stampTopicsExtractedAtOp(vaultCtx, memoryIds, extractedAt, version),
19131
+ relinkTopics: (memoryIds) => relinkMemoryTopicsOp(vaultCtx, memoryIds),
19132
+ backfillTopics: (memoryIds) => backfillMemoryTopicsOp(vaultCtx, memoryIds)
19133
+ }
19134
+ };
19135
+ }
19136
+
18791
19137
  // src/lib/memory/synthesizeProfile.ts
18792
19138
  var DEFAULT_SYNTHESIS_MODEL = "inclusionai/ling-2.6-flash";
18793
19139
  var DEFAULT_FACET_RECALL_LIMIT = 20;
@@ -19315,199 +19661,6 @@ function normalizeInterests(values) {
19315
19661
  return out.length > 0 ? out : void 0;
19316
19662
  }
19317
19663
 
19318
- // src/lib/memory/topicExtract.ts
19319
- var TOPIC_EXTRACTION_BATCH_SIZE = 10;
19320
- var MAX_CHARS_PER_MEMORY = 300;
19321
- var MAX_VOCABULARY_NAMES = 100;
19322
- var MAX_COMPLETION_TOKENS = 8192;
19323
- var SYSTEM_PROMPT5 = `You assign topics to saved memories for a personal memory system.
19324
-
19325
- 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.
19326
-
19327
- 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:
19328
- - 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.
19329
- - KEEP the specific thing instead, when the memory names one: "Blue Bottle on Valencia" over "cafe", "Chicago Marathon" over "event", "Hollowpoint Labs" over "work".
19330
- - Prefer 0 entities over a weak one. A memory whose only candidate is a generic noun has NO entities.
19331
- ${ENTITY_KIND_GUIDELINES}
19332
-
19333
- Each memory below is written as "<id>: <text>". Output strict JSON: {"memories": [{"id": string, "entities": [{"name": string, "kind": string}]}]}
19334
- - exactly one element per input memory; copy its id EXACTLY as written (the token before the first ": "), with no brackets, quotes, or extra characters
19335
- - "entities" may be empty when a memory mentions no named entities \u2014 most short memories have 0-3
19336
- No prose.`;
19337
- async function extractEntitiesForMemories(memories, options) {
19338
- const out = /* @__PURE__ */ new Map();
19339
- if (memories.length === 0) return out;
19340
- const redactor = resolvePiiRedactor(options.piiRedaction);
19341
- const vocabulary = [];
19342
- for (const name of (options.existingEntityNames ?? []).filter((n) => n.trim().length > 0).slice(0, MAX_VOCABULARY_NAMES)) {
19343
- vocabulary.push(redactor ? (await redactor.redactTextAsync(name)).text : name);
19344
- }
19345
- const vocabularyNote = vocabulary.length > 0 ? `The user's existing topics: ${vocabulary.join(", ")}.
19346
- 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".
19347
-
19348
- ` : "";
19349
- for (let i = 0; i < memories.length; i += TOPIC_EXTRACTION_BATCH_SIZE) {
19350
- const batch = memories.slice(i, i + TOPIC_EXTRACTION_BATCH_SIZE);
19351
- const rows = [];
19352
- for (const m of batch) {
19353
- const content = m.content.slice(0, MAX_CHARS_PER_MEMORY).replace(/\s+/g, " ").trim();
19354
- rows.push(`${m.id}: ${redactor ? (await redactor.redactTextAsync(content)).text : content}`);
19355
- }
19356
- const listing = rows.join("\n");
19357
- const parsed = await callPortalJsonCompletion({
19358
- ...options.apiKey !== void 0 && { apiKey: options.apiKey },
19359
- ...options.getToken !== void 0 && { getToken: options.getToken },
19360
- ...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
19361
- taskType: "memory_topic",
19362
- ...options.endpointOverride !== void 0 && {
19363
- endpointOverride: options.endpointOverride
19364
- },
19365
- model: options.model ?? DEFAULT_EXTRACTION_MODEL,
19366
- systemPrompt: SYSTEM_PROMPT5,
19367
- userMessage: `${vocabularyNote}Memories:
19368
- ${listing}
19369
-
19370
- List each memory's named entities.`,
19371
- tag: "memory/topics",
19372
- extra: { max_completion_tokens: MAX_COMPLETION_TOKENS },
19373
- ...options.fetchFn && { fetchFn: options.fetchFn },
19374
- ...options.maxAttempts !== void 0 && { maxAttempts: options.maxAttempts },
19375
- ...options.timeoutMs !== void 0 && { timeoutMs: options.timeoutMs },
19376
- ...options.totalTimeoutMs !== void 0 && { totalTimeoutMs: options.totalTimeoutMs },
19377
- ...options.backoffMs && { backoffMs: options.backoffMs }
19378
- });
19379
- if (parsed === null) {
19380
- getLogger().warn(
19381
- `[memory/topics] batch of ${batch.length} failed after retries \u2014 will retry next sweep`
19382
- );
19383
- continue;
19384
- }
19385
- const validIds = new Set(batch.map((m) => m.id));
19386
- const byId = parseTopicResponse(parsed, validIds);
19387
- if (byId === null) {
19388
- getLogger().warn(
19389
- `[memory/topics] batch of ${batch.length} returned an unrecognized shape \u2014 will retry next sweep`
19390
- );
19391
- continue;
19392
- }
19393
- for (const m of batch) {
19394
- const entities = byId.get(m.id);
19395
- if (entities === void 0) {
19396
- continue;
19397
- }
19398
- out.set(m.id, redactor ? restoreEntities(entities, redactor) : entities);
19399
- }
19400
- }
19401
- return out;
19402
- }
19403
- function restoreEntities(entities, redactor) {
19404
- return entities.map((e) => ({ kind: e.kind, restored: redactor.restoreForStorage(e.name) })).filter((e) => !e.restored.unresolved).map(
19405
- (e) => e.kind !== void 0 ? { name: e.restored.text, kind: e.kind } : { name: e.restored.text }
19406
- );
19407
- }
19408
- function parseTopicResponse(parsed, validIds) {
19409
- if (typeof parsed !== "object" || parsed === null) return null;
19410
- const list = parsed.memories;
19411
- if (!Array.isArray(list)) return null;
19412
- const out = /* @__PURE__ */ new Map();
19413
- for (const raw of list) {
19414
- if (typeof raw !== "object" || raw === null) continue;
19415
- const obj = raw;
19416
- if (typeof obj.id !== "string") continue;
19417
- const id = obj.id.trim().replace(/:$/, "").replace(/^\[([\s\S]*)\]$/, "$1").trim();
19418
- if (!validIds.has(id) || out.has(id)) continue;
19419
- const entities = Array.isArray(obj.entities) ? parseEntities(obj.entities) : [];
19420
- out.set(id, entities);
19421
- }
19422
- return out;
19423
- }
19424
- var DEGRADED_TOPIC_SKIP = {
19425
- excluded: false,
19426
- "link-declined": false,
19427
- "stamp-declined": false,
19428
- "llm-unanswered": true,
19429
- unreadable: true,
19430
- "not-found": true,
19431
- "link-failed": true
19432
- };
19433
- function isDegradedTopicSkip(reason) {
19434
- return DEGRADED_TOPIC_SKIP[reason] === true;
19435
- }
19436
- async function extractAndLinkEntitiesForMemoriesOp(ctx, memoryIds, options) {
19437
- const entityCtx = ctx.entityCtx;
19438
- if (!entityCtx) {
19439
- throw new Error("extractAndLinkEntitiesForMemoriesOp requires ctx.entityCtx");
19440
- }
19441
- const log = getLogger();
19442
- const extractedAt = options.now ?? Date.now();
19443
- const skippedIds = [];
19444
- const skippedReasons = /* @__PURE__ */ new Map();
19445
- const skip = (id, reason) => {
19446
- if (skippedReasons.has(id)) return;
19447
- skippedIds.push(id);
19448
- skippedReasons.set(id, reason);
19449
- };
19450
- const inputs = [];
19451
- for (const id of new Set(memoryIds)) {
19452
- let record;
19453
- try {
19454
- record = await ctx.vaultMemoryCollection.find(id);
19455
- } catch (err) {
19456
- log.warn("[memory/topics] vault lookup failed for extraction", err);
19457
- skip(id, "not-found");
19458
- continue;
19459
- }
19460
- if (record.isDeleted || ctx.userId !== void 0 && record.userId !== ctx.userId || record.topicsUserManaged) {
19461
- skip(id, "excluded");
19462
- continue;
19463
- }
19464
- try {
19465
- const stored = await vaultMemoryToStored(
19466
- record,
19467
- ctx.walletAddress,
19468
- ctx.signMessage,
19469
- ctx.embeddedWalletSigner
19470
- );
19471
- inputs.push({ id, content: stored.content });
19472
- } catch (err) {
19473
- log.warn("[memory/topics] failed to load memory for extraction", err);
19474
- skip(id, "unreadable");
19475
- }
19476
- }
19477
- const entitiesByMemory = await extractEntitiesForMemories(inputs, options);
19478
- const toStamp = [];
19479
- for (const input of inputs) {
19480
- const entities = entitiesByMemory.get(input.id);
19481
- if (entities === void 0) {
19482
- skip(input.id, "llm-unanswered");
19483
- continue;
19484
- }
19485
- try {
19486
- const linked = await replaceMemoryEntitiesGuardedOp(entityCtx, input.id, entities);
19487
- if (linked === null) {
19488
- skip(input.id, "link-declined");
19489
- entitiesByMemory.delete(input.id);
19490
- continue;
19491
- }
19492
- } catch (err) {
19493
- log.warn("[memory/topics] replaceMemoryEntitiesGuardedOp failed", err);
19494
- skip(input.id, "link-failed");
19495
- entitiesByMemory.delete(input.id);
19496
- continue;
19497
- }
19498
- toStamp.push(input.id);
19499
- }
19500
- const stampedIds = await stampTopicsExtractedAtOp(ctx, toStamp, extractedAt);
19501
- const stampedSet = new Set(stampedIds);
19502
- for (const id of toStamp) {
19503
- if (!stampedSet.has(id)) {
19504
- skip(id, "stamp-declined");
19505
- entitiesByMemory.delete(id);
19506
- }
19507
- }
19508
- return { entitiesByMemory, stampedIds, skippedIds, skippedReasons };
19509
- }
19510
-
19511
19664
  // src/lib/memory/verifySupport.ts
19512
19665
  var DEFAULT_MODEL5 = "inclusionai/ling-2.6-flash";
19513
19666
  var DEFAULT_ATTEMPTS3 = 2;
@@ -19898,7 +20051,7 @@ async function assembleMemoryContext(options) {
19898
20051
  }
19899
20052
 
19900
20053
  // src/lib/memory/durableExtraction.ts
19901
- import { Q as Q8 } from "@nozbe/watermelondb";
20054
+ import { Q as Q9 } from "@nozbe/watermelondb";
19902
20055
  var MAX_JOBS_PER_PASS = 3;
19903
20056
  var MAX_ATTEMPTS = 3;
19904
20057
  var MAX_FAILED_SESSIONS = 3;
@@ -20045,7 +20198,7 @@ function createDurableAutoExtractor(options) {
20045
20198
  ...options.retainCtx,
20046
20199
  vaultCtx: {
20047
20200
  ...vault,
20048
- canWrite: async () => !disposed && !cancelled && await storage.conversationsCollection.query(Q8.where("conversation_id", conversationId), Q8.where("is_deleted", false)).fetchCount() > 0 && await storage.messagesCollection.query(Q8.where("conversation_id", conversationId), Q8.where("id", Q8.oneOf(ids))).fetchCount() === ids.length && (!vault.canWrite || await vault.canWrite()) && !disposed && !cancelled
20201
+ canWrite: async () => !disposed && !cancelled && await storage.conversationsCollection.query(Q9.where("conversation_id", conversationId), Q9.where("is_deleted", false)).fetchCount() > 0 && await storage.messagesCollection.query(Q9.where("conversation_id", conversationId), Q9.where("id", Q9.oneOf(ids))).fetchCount() === ids.length && (!vault.canWrite || await vault.canWrite()) && !disposed && !cancelled
20049
20202
  }
20050
20203
  },
20051
20204
  // The model follows the job's scope, not the mode alive at drain time.
@@ -20187,7 +20340,7 @@ function createDurableAutoExtractor(options) {
20187
20340
  let scheduleAfterSuccess = false;
20188
20341
  try {
20189
20342
  await writes;
20190
- const pending = await jobs.query(Q8.where("owner_key", owner), Q8.where("message_ids", Q8.notEq("[]"))).fetch();
20343
+ const pending = await jobs.query(Q9.where("owner_key", owner), Q9.where("message_ids", Q9.notEq("[]"))).fetch();
20191
20344
  storeFailures = 0;
20192
20345
  let processed = 0;
20193
20346
  for (const job of pending) {
@@ -20203,7 +20356,7 @@ function createDurableAutoExtractor(options) {
20203
20356
  let ids = [];
20204
20357
  let loaded = [];
20205
20358
  try {
20206
- const conversations = await storage.conversationsCollection.query(Q8.where("conversation_id", conversationId), Q8.where("is_deleted", false)).fetchCount();
20359
+ const conversations = await storage.conversationsCollection.query(Q9.where("conversation_id", conversationId), Q9.where("is_deleted", false)).fetchCount();
20207
20360
  if (!conversations) {
20208
20361
  await database.write(() => job.destroyPermanently());
20209
20362
  continue;
@@ -20320,12 +20473,12 @@ function createDurableAutoExtractor(options) {
20320
20473
  const scope = currentScope();
20321
20474
  writes = writes.then(
20322
20475
  () => database.write(async () => {
20323
- const existing = await jobs.query(Q8.where("owner_key", owner), Q8.where("conversation_id", conversationId)).fetch();
20476
+ const existing = await jobs.query(Q9.where("owner_key", owner), Q9.where("conversation_id", conversationId)).fetch();
20324
20477
  const job = existing.find(
20325
20478
  (candidate) => candidate._getRaw("scope") === scope && (candidate._getRaw("folder_id") ?? null) === folderId
20326
20479
  );
20327
20480
  const positions = new Map(ids.map((id, index) => [id, index]));
20328
- const rows = await storage.messagesCollection.query(Q8.where("id", Q8.oneOf(ids))).fetch();
20481
+ const rows = await storage.messagesCollection.query(Q9.where("id", Q9.oneOf(ids))).fetch();
20329
20482
  const sequences = /* @__PURE__ */ new Map();
20330
20483
  for (const row of rows) {
20331
20484
  const sequence = Number(row._getRaw("message_id"));
@@ -25980,7 +26133,7 @@ function useDatabaseManager(walletAddress, manager) {
25980
26133
  }
25981
26134
 
25982
26135
  // src/lib/db/project/operations.ts
25983
- import { Q as Q9 } from "@nozbe/watermelondb";
26136
+ import { Q as Q10 } from "@nozbe/watermelondb";
25984
26137
 
25985
26138
  // src/lib/db/project/types.ts
25986
26139
  function generateProjectId() {
@@ -26011,15 +26164,15 @@ async function createProjectOp(ctx, opts, defaultName = "New Project") {
26011
26164
  return projectToStored(created);
26012
26165
  }
26013
26166
  async function getProjectOp(ctx, id) {
26014
- const results = await ctx.projectsCollection.query(Q9.where("project_id", id), Q9.where("is_deleted", false)).fetch();
26167
+ const results = await ctx.projectsCollection.query(Q10.where("project_id", id), Q10.where("is_deleted", false)).fetch();
26015
26168
  return results.length > 0 ? projectToStored(results[0]) : null;
26016
26169
  }
26017
26170
  async function getProjectsOp(ctx) {
26018
- const results = await ctx.projectsCollection.query(Q9.where("is_deleted", false), Q9.sortBy("created_at", Q9.desc)).fetch();
26171
+ const results = await ctx.projectsCollection.query(Q10.where("is_deleted", false), Q10.sortBy("created_at", Q10.desc)).fetch();
26019
26172
  return results.map(projectToStored);
26020
26173
  }
26021
26174
  async function updateProjectNameOp(ctx, id, name) {
26022
- const results = await ctx.projectsCollection.query(Q9.where("project_id", id), Q9.where("is_deleted", false)).fetch();
26175
+ const results = await ctx.projectsCollection.query(Q10.where("project_id", id), Q10.where("is_deleted", false)).fetch();
26023
26176
  if (results.length > 0) {
26024
26177
  await ctx.database.write(async () => {
26025
26178
  await results[0].update((proj) => {
@@ -26031,7 +26184,7 @@ async function updateProjectNameOp(ctx, id, name) {
26031
26184
  return false;
26032
26185
  }
26033
26186
  async function updateProjectOp(ctx, id, opts) {
26034
- const results = await ctx.projectsCollection.query(Q9.where("project_id", id), Q9.where("is_deleted", false)).fetch();
26187
+ const results = await ctx.projectsCollection.query(Q10.where("project_id", id), Q10.where("is_deleted", false)).fetch();
26035
26188
  if (results.length > 0) {
26036
26189
  await ctx.database.write(async () => {
26037
26190
  await results[0].update((proj) => {
@@ -26043,7 +26196,7 @@ async function updateProjectOp(ctx, id, opts) {
26043
26196
  return false;
26044
26197
  }
26045
26198
  async function deleteProjectOp(ctx, id) {
26046
- const results = await ctx.projectsCollection.query(Q9.where("project_id", id), Q9.where("is_deleted", false)).fetch();
26199
+ const results = await ctx.projectsCollection.query(Q10.where("project_id", id), Q10.where("is_deleted", false)).fetch();
26047
26200
  if (results.length > 0) {
26048
26201
  await ctx.database.write(async () => {
26049
26202
  await results[0].update((proj) => {
@@ -26056,18 +26209,18 @@ async function deleteProjectOp(ctx, id) {
26056
26209
  }
26057
26210
  async function getProjectConversationsOp(ctx, projectId) {
26058
26211
  const results = await ctx.conversationsCollection.query(
26059
- Q9.where("project_id", projectId),
26060
- Q9.where("is_deleted", false),
26061
- Q9.sortBy("created_at", Q9.desc)
26212
+ Q10.where("project_id", projectId),
26213
+ Q10.where("is_deleted", false),
26214
+ Q10.sortBy("created_at", Q10.desc)
26062
26215
  ).fetch();
26063
26216
  return results.map(conversationToStoredRaw);
26064
26217
  }
26065
26218
  async function getProjectConversationCountOp(ctx, projectId) {
26066
- return await ctx.conversationsCollection.query(Q9.where("project_id", projectId), Q9.where("is_deleted", false)).fetchCount();
26219
+ return await ctx.conversationsCollection.query(Q10.where("project_id", projectId), Q10.where("is_deleted", false)).fetchCount();
26067
26220
  }
26068
26221
 
26069
26222
  // src/react/useFiles.ts
26070
- import { Q as Q10 } from "@nozbe/watermelondb";
26223
+ import { Q as Q11 } from "@nozbe/watermelondb";
26071
26224
  import { useCallback as useCallback5, useEffect as useEffect4, useMemo as useMemo5, useState as useState5 } from "react";
26072
26225
  function useFiles(options) {
26073
26226
  const { database, walletAddress } = options;
@@ -26085,7 +26238,7 @@ function useFiles(options) {
26085
26238
  setIsLoading(true);
26086
26239
  try {
26087
26240
  const coll = database.get("media");
26088
- await coll.query(Q10.take(1)).fetch();
26241
+ await coll.query(Q11.take(1)).fetch();
26089
26242
  setMediaCollection(coll);
26090
26243
  setIsReady(true);
26091
26244
  } catch (error) {
@@ -26493,7 +26646,7 @@ function useFiles(options) {
26493
26646
  }
26494
26647
 
26495
26648
  // src/react/useProjects.ts
26496
- import { Q as Q11 } from "@nozbe/watermelondb";
26649
+ import { Q as Q12 } from "@nozbe/watermelondb";
26497
26650
  import { useCallback as useCallback6, useEffect as useEffect5, useMemo as useMemo6, useState as useState6 } from "react";
26498
26651
  function useProjects(options) {
26499
26652
  const { database, initialProjectId } = options;
@@ -26515,7 +26668,7 @@ function useProjects(options) {
26515
26668
  conversations: convColl?.table
26516
26669
  });
26517
26670
  getLogger().debug("[useProjects] Running test query on projects table...");
26518
- const testResult = await projColl.query(Q11.take(1)).fetch();
26671
+ const testResult = await projColl.query(Q12.take(1)).fetch();
26519
26672
  getLogger().debug(
26520
26673
  "[useProjects] Test query succeeded, found",
26521
26674
  testResult.length,
@@ -26602,7 +26755,7 @@ function useProjects(options) {
26602
26755
  if (!projectsCollection) {
26603
26756
  return;
26604
26757
  }
26605
- const subscription = projectsCollection.query(Q11.where("is_deleted", false)).observe().subscribe((records) => {
26758
+ const subscription = projectsCollection.query(Q12.where("is_deleted", false)).observe().subscribe((records) => {
26606
26759
  setProjects(records.map(projectToStored));
26607
26760
  });
26608
26761
  return () => subscription.unsubscribe();
@@ -26725,7 +26878,7 @@ function useProjects(options) {
26725
26878
  }
26726
26879
 
26727
26880
  // src/lib/db/settings/operations.ts
26728
- import { Q as Q12 } from "@nozbe/watermelondb";
26881
+ import { Q as Q13 } from "@nozbe/watermelondb";
26729
26882
  function modelPreferenceToStored(preference) {
26730
26883
  return {
26731
26884
  uniqueId: preference.id,
@@ -26734,12 +26887,12 @@ function modelPreferenceToStored(preference) {
26734
26887
  };
26735
26888
  }
26736
26889
  async function getModelPreferenceOp(ctx, walletAddress) {
26737
- const results = await ctx.modelPreferencesCollection.query(Q12.where("wallet_address", walletAddress)).fetch();
26890
+ const results = await ctx.modelPreferencesCollection.query(Q13.where("wallet_address", walletAddress)).fetch();
26738
26891
  return results.length > 0 ? modelPreferenceToStored(results[0]) : null;
26739
26892
  }
26740
26893
  async function setModelPreferenceOp(ctx, walletAddress, models) {
26741
26894
  const result = await ctx.database.write(async () => {
26742
- const results = await ctx.modelPreferencesCollection.query(Q12.where("wallet_address", walletAddress)).fetch();
26895
+ const results = await ctx.modelPreferencesCollection.query(Q13.where("wallet_address", walletAddress)).fetch();
26743
26896
  if (results.length > 0) {
26744
26897
  const preference = results[0];
26745
26898
  await preference.update((pref) => {
@@ -26757,7 +26910,7 @@ async function setModelPreferenceOp(ctx, walletAddress, models) {
26757
26910
  return modelPreferenceToStored(result);
26758
26911
  }
26759
26912
  async function deleteModelPreferenceOp(ctx, walletAddress) {
26760
- const results = await ctx.modelPreferencesCollection.query(Q12.where("wallet_address", walletAddress)).fetch();
26913
+ const results = await ctx.modelPreferencesCollection.query(Q13.where("wallet_address", walletAddress)).fetch();
26761
26914
  if (results.length === 0) return false;
26762
26915
  await ctx.database.write(async () => {
26763
26916
  await results[0].destroyPermanently();
@@ -26781,7 +26934,7 @@ var settingsStorageSchema = appSchema3({
26781
26934
  });
26782
26935
 
26783
26936
  // src/lib/db/vaultFolders/operations.ts
26784
- import { Q as Q13 } from "@nozbe/watermelondb";
26937
+ import { Q as Q14 } from "@nozbe/watermelondb";
26785
26938
  function folderToStored(folder) {
26786
26939
  return {
26787
26940
  uniqueId: folder.id,
@@ -26806,7 +26959,7 @@ async function createVaultFolderOp(ctx, opts) {
26806
26959
  return folderToStored(created);
26807
26960
  }
26808
26961
  async function getAllVaultFoldersOp(ctx) {
26809
- const results = await ctx.vaultFolderCollection.query(Q13.where("is_deleted", false), Q13.sortBy("created_at", Q13.desc)).fetch();
26962
+ const results = await ctx.vaultFolderCollection.query(Q14.where("is_deleted", false), Q14.sortBy("created_at", Q14.desc)).fetch();
26810
26963
  return results.map(folderToStored);
26811
26964
  }
26812
26965
  async function updateVaultFolderOp(ctx, id, opts) {
@@ -26815,7 +26968,7 @@ async function updateVaultFolderOp(ctx, id, opts) {
26815
26968
  if (record.isDeleted) return null;
26816
26969
  const scopeChanged = opts.scope !== void 0 && opts.scope !== record.scope;
26817
26970
  const updated = await ctx.database.write(async () => {
26818
- const memories = scopeChanged ? await ctx.vaultMemoryCollection.query(Q13.where("folder_id", id), Q13.where("is_deleted", false)).fetch() : [];
26971
+ const memories = scopeChanged ? await ctx.vaultMemoryCollection.query(Q14.where("folder_id", id), Q14.where("is_deleted", false)).fetch() : [];
26819
26972
  const updates = [];
26820
26973
  updates.push(
26821
26974
  record.prepareUpdate((r) => {
@@ -26843,7 +26996,7 @@ async function deleteVaultFolderOp(ctx, id) {
26843
26996
  const record = await ctx.vaultFolderCollection.find(id);
26844
26997
  if (record.isDeleted) return false;
26845
26998
  await ctx.database.write(async () => {
26846
- const memories = await ctx.vaultMemoryCollection.query(Q13.where("folder_id", id), Q13.where("is_deleted", false)).fetch();
26999
+ const memories = await ctx.vaultMemoryCollection.query(Q14.where("folder_id", id), Q14.where("is_deleted", false)).fetch();
26847
27000
  const preparedMemories = memories.map(
26848
27001
  (memory) => memory.prepareUpdate((r) => {
26849
27002
  r._setRaw("folder_id", null);
@@ -26912,7 +27065,7 @@ async function updateVaultFolderContextOp(ctx, id, context) {
26912
27065
  }
26913
27066
  }
26914
27067
  async function getVaultFolderMemoryCountOp(ctx, folderId) {
26915
- return await ctx.vaultMemoryCollection.query(Q13.where("folder_id", folderId), Q13.where("is_deleted", false)).fetchCount();
27068
+ return await ctx.vaultMemoryCollection.query(Q14.where("folder_id", folderId), Q14.where("is_deleted", false)).fetchCount();
26916
27069
  }
26917
27070
 
26918
27071
  // src/lib/db/vaultFolders/defaults.ts
@@ -26958,7 +27111,7 @@ async function _ensureDefaultFoldersImpl(ctx) {
26958
27111
  import { useCallback as useCallback7, useMemo as useMemo7, useSyncExternalStore } from "react";
26959
27112
 
26960
27113
  // src/lib/db/userPreferences/operations.ts
26961
- import { Q as Q14 } from "@nozbe/watermelondb";
27114
+ import { Q as Q15 } from "@nozbe/watermelondb";
26962
27115
  function userPreferenceToStored(preference) {
26963
27116
  return {
26964
27117
  uniqueId: preference.id,
@@ -26973,7 +27126,7 @@ function userPreferenceToStored(preference) {
26973
27126
  };
26974
27127
  }
26975
27128
  async function getUserPreferenceOp(ctx, walletAddress) {
26976
- const results = await ctx.userPreferencesCollection.query(Q14.where("wallet_address", walletAddress)).fetch();
27129
+ const results = await ctx.userPreferencesCollection.query(Q15.where("wallet_address", walletAddress)).fetch();
26977
27130
  return results.length > 0 ? userPreferenceToStored(results[0]) : null;
26978
27131
  }
26979
27132
  async function createUserPreferenceOp(ctx, opts) {
@@ -26993,7 +27146,7 @@ async function createUserPreferenceOp(ctx, opts) {
26993
27146
  return userPreferenceToStored(created);
26994
27147
  }
26995
27148
  async function updateUserPreferenceOp(ctx, walletAddress, opts) {
26996
- const results = await ctx.userPreferencesCollection.query(Q14.where("wallet_address", walletAddress)).fetch();
27149
+ const results = await ctx.userPreferencesCollection.query(Q15.where("wallet_address", walletAddress)).fetch();
26997
27150
  if (results.length === 0) return null;
26998
27151
  const preference = results[0];
26999
27152
  await ctx.database.write(async () => {
@@ -27021,7 +27174,7 @@ async function updateUserPreferenceOp(ctx, walletAddress, opts) {
27021
27174
  async function setUserPreferenceOp(ctx, walletAddress, opts) {
27022
27175
  const now = Date.now();
27023
27176
  const result = await ctx.database.write(async () => {
27024
- const results = await ctx.userPreferencesCollection.query(Q14.where("wallet_address", walletAddress)).fetch();
27177
+ const results = await ctx.userPreferencesCollection.query(Q15.where("wallet_address", walletAddress)).fetch();
27025
27178
  if (results.length > 0) {
27026
27179
  const preference = results[0];
27027
27180
  await preference.update((pref) => {
@@ -27069,7 +27222,7 @@ async function updateModelsOp(ctx, walletAddress, models) {
27069
27222
  return updateUserPreferenceOp(ctx, walletAddress, { models });
27070
27223
  }
27071
27224
  async function deleteUserPreferenceOp(ctx, walletAddress) {
27072
- const results = await ctx.userPreferencesCollection.query(Q14.where("wallet_address", walletAddress)).fetch();
27225
+ const results = await ctx.userPreferencesCollection.query(Q15.where("wallet_address", walletAddress)).fetch();
27073
27226
  if (results.length === 0) return false;
27074
27227
  await ctx.database.write(async () => {
27075
27228
  await results[0].destroyPermanently();
@@ -27084,9 +27237,9 @@ async function migrateFromModelPreferencesOp(ctx, walletAddress) {
27084
27237
  if (existing) {
27085
27238
  return existing;
27086
27239
  }
27087
- const modelResults = await ctx.modelPreferencesCollection.query(Q14.where("wallet_address", walletAddress)).fetch();
27240
+ const modelResults = await ctx.modelPreferencesCollection.query(Q15.where("wallet_address", walletAddress)).fetch();
27088
27241
  const personalityKey = `${walletAddress}_personality_settings`;
27089
- const personalityResults = await ctx.modelPreferencesCollection.query(Q14.where("wallet_address", personalityKey)).fetch();
27242
+ const personalityResults = await ctx.modelPreferencesCollection.query(Q15.where("wallet_address", personalityKey)).fetch();
27090
27243
  if (modelResults.length === 0 && personalityResults.length === 0) {
27091
27244
  return null;
27092
27245
  }
@@ -27192,7 +27345,7 @@ var SLIDER_CONFIG = [
27192
27345
  ];
27193
27346
 
27194
27347
  // src/react/userSettingsStore.ts
27195
- import { Q as Q15 } from "@nozbe/watermelondb";
27348
+ import { Q as Q16 } from "@nozbe/watermelondb";
27196
27349
  var EMPTY_SNAPSHOT = Object.freeze({
27197
27350
  modelPreference: null,
27198
27351
  userPreference: null,
@@ -27254,7 +27407,7 @@ async function startLoad(entry, walletAddress) {
27254
27407
  }
27255
27408
  function startObserve(entry, walletAddress) {
27256
27409
  let isInitialEmission = true;
27257
- entry.observeSub = entry.storageCtx.userPreferencesCollection.query(Q15.where("wallet_address", walletAddress)).observeWithColumns([
27410
+ entry.observeSub = entry.storageCtx.userPreferencesCollection.query(Q16.where("wallet_address", walletAddress)).observeWithColumns([
27258
27411
  "nickname",
27259
27412
  "occupation",
27260
27413
  "description",
@@ -27518,7 +27671,7 @@ function useSettings(options) {
27518
27671
  }
27519
27672
 
27520
27673
  // src/lib/db/appFiles/operations.ts
27521
- import { Q as Q16 } from "@nozbe/watermelondb";
27674
+ import { Q as Q17 } from "@nozbe/watermelondb";
27522
27675
 
27523
27676
  // src/utils/paths.ts
27524
27677
  function normalizePath(p) {
@@ -27544,7 +27697,7 @@ async function putAppFileOp(ctx, conversationId, path, content) {
27544
27697
  const normalized = normalizePath(path);
27545
27698
  const now = Date.now();
27546
27699
  const result = await ctx.database.write(async () => {
27547
- const existing = await ctx.appFilesCollection.query(Q16.where("conversation_id", conversationId), Q16.where("path", normalized)).fetch();
27700
+ const existing = await ctx.appFilesCollection.query(Q17.where("conversation_id", conversationId), Q17.where("path", normalized)).fetch();
27548
27701
  if (existing.length > 0) {
27549
27702
  await existing[0].update((f) => {
27550
27703
  f._setRaw("content", content);
@@ -27564,11 +27717,11 @@ async function putAppFileOp(ctx, conversationId, path, content) {
27564
27717
  }
27565
27718
  async function getAppFileOp(ctx, conversationId, path) {
27566
27719
  const normalized = normalizePath(path);
27567
- const results = await ctx.appFilesCollection.query(Q16.where("conversation_id", conversationId), Q16.where("path", normalized)).fetch();
27720
+ const results = await ctx.appFilesCollection.query(Q17.where("conversation_id", conversationId), Q17.where("path", normalized)).fetch();
27568
27721
  return results.length > 0 ? appFileToStored(results[0]) : null;
27569
27722
  }
27570
27723
  async function getAppFilesOp(ctx, conversationId) {
27571
- const results = await ctx.appFilesCollection.query(Q16.where("conversation_id", conversationId)).fetch();
27724
+ const results = await ctx.appFilesCollection.query(Q17.where("conversation_id", conversationId)).fetch();
27572
27725
  return results.map(appFileToStored);
27573
27726
  }
27574
27727
  async function getAppFileMapOp(ctx, conversationId) {
@@ -27579,7 +27732,7 @@ async function getAppFileMapOp(ctx, conversationId) {
27579
27732
  }
27580
27733
  async function deleteAppFileOp(ctx, conversationId, path) {
27581
27734
  const normalized = normalizePath(path);
27582
- const results = await ctx.appFilesCollection.query(Q16.where("conversation_id", conversationId), Q16.where("path", normalized)).fetch();
27735
+ const results = await ctx.appFilesCollection.query(Q17.where("conversation_id", conversationId), Q17.where("path", normalized)).fetch();
27583
27736
  if (results.length === 0) return false;
27584
27737
  await ctx.database.write(async () => {
27585
27738
  await results[0].destroyPermanently();
@@ -27587,7 +27740,7 @@ async function deleteAppFileOp(ctx, conversationId, path) {
27587
27740
  return true;
27588
27741
  }
27589
27742
  async function deleteAllAppFilesOp(ctx, conversationId) {
27590
- const results = await ctx.appFilesCollection.query(Q16.where("conversation_id", conversationId)).fetch();
27743
+ const results = await ctx.appFilesCollection.query(Q17.where("conversation_id", conversationId)).fetch();
27591
27744
  if (results.length === 0) return;
27592
27745
  await ctx.database.write(async () => {
27593
27746
  const batch = results.map((file) => file.prepareDestroyPermanently());
@@ -27596,7 +27749,7 @@ async function deleteAllAppFilesOp(ctx, conversationId) {
27596
27749
  }
27597
27750
 
27598
27751
  // src/lib/db/conversationMemory/operations.ts
27599
- import { Q as Q17 } from "@nozbe/watermelondb";
27752
+ import { Q as Q18 } from "@nozbe/watermelondb";
27600
27753
  var MAX_PER_CONVERSATION = 200;
27601
27754
  function conversationMemoryToStored(row) {
27602
27755
  return {
@@ -27611,7 +27764,7 @@ async function addConversationMemoriesOp(ctx, conversationId, items) {
27611
27764
  if (!conversationId || items.length === 0) return;
27612
27765
  const now = Date.now();
27613
27766
  await ctx.database.write(async () => {
27614
- const existing = await ctx.conversationMemoryCollection.query(Q17.where("conversation_id", conversationId), Q17.sortBy("created_at", Q17.asc)).fetch();
27767
+ const existing = await ctx.conversationMemoryCollection.query(Q18.where("conversation_id", conversationId), Q18.sortBy("created_at", Q18.asc)).fetch();
27615
27768
  const seen = new Set(existing.map((r) => r.memoryId));
27616
27769
  const batchSeen = /* @__PURE__ */ new Set();
27617
27770
  const deduped = [];
@@ -27646,20 +27799,20 @@ async function addConversationMemoriesOp(ctx, conversationId, items) {
27646
27799
  }
27647
27800
  async function getConversationMemoriesOp(ctx, conversationId) {
27648
27801
  if (!conversationId) return [];
27649
- const rows = await ctx.conversationMemoryCollection.query(Q17.where("conversation_id", conversationId), Q17.sortBy("created_at", Q17.asc)).fetch();
27802
+ const rows = await ctx.conversationMemoryCollection.query(Q18.where("conversation_id", conversationId), Q18.sortBy("created_at", Q18.asc)).fetch();
27650
27803
  return rows.map(conversationMemoryToStored);
27651
27804
  }
27652
27805
  async function clearConversationMemoriesOp(ctx, conversationId) {
27653
27806
  if (!conversationId) return;
27654
27807
  await ctx.database.write(async () => {
27655
- const rows = await ctx.conversationMemoryCollection.query(Q17.where("conversation_id", conversationId)).fetch();
27808
+ const rows = await ctx.conversationMemoryCollection.query(Q18.where("conversation_id", conversationId)).fetch();
27656
27809
  if (rows.length === 0) return;
27657
27810
  await ctx.database.batch(...rows.map((r) => r.prepareDestroyPermanently()));
27658
27811
  });
27659
27812
  }
27660
27813
 
27661
27814
  // src/lib/db/savedTools/operations.ts
27662
- import { Q as Q18 } from "@nozbe/watermelondb";
27815
+ import { Q as Q19 } from "@nozbe/watermelondb";
27663
27816
  function savedToolToStored(tool) {
27664
27817
  return {
27665
27818
  uniqueId: tool.id,
@@ -27692,7 +27845,7 @@ async function createSavedToolOp(ctx, opts) {
27692
27845
  return savedToolToStored(created);
27693
27846
  }
27694
27847
  async function getAllSavedToolsOp(ctx) {
27695
- const results = await ctx.savedToolsCollection.query(Q18.where("is_deleted", false), Q18.sortBy("created_at", Q18.desc)).fetch();
27848
+ const results = await ctx.savedToolsCollection.query(Q19.where("is_deleted", false), Q19.sortBy("created_at", Q19.desc)).fetch();
27696
27849
  return results.map(savedToolToStored);
27697
27850
  }
27698
27851
  async function getSavedToolByIdOp(ctx, uniqueId) {
@@ -30348,8 +30501,8 @@ function createDropboxFileIndex(backupFolder) {
30348
30501
  };
30349
30502
  }
30350
30503
  async function readLocalUpdatedAt(database, conversationId) {
30351
- const { Q: Q19 } = await import("@nozbe/watermelondb");
30352
- const records = await database.get("conversations").query(Q19.where("conversation_id", conversationId)).fetch();
30504
+ const { Q: Q20 } = await import("@nozbe/watermelondb");
30505
+ const records = await database.get("conversations").query(Q20.where("conversation_id", conversationId)).fetch();
30353
30506
  const match = records.map(conversationToStoredRaw).find((c) => c.conversationId === conversationId);
30354
30507
  return match ? match.updatedAt : null;
30355
30508
  }
@@ -30405,9 +30558,9 @@ async function pushConversationToDropbox(database, conversationId, userAddress,
30405
30558
  }
30406
30559
  async function performDropboxExport(database, userAddress, token, deps, onProgress, backupFolder = DEFAULT_BACKUP_FOLDER) {
30407
30560
  await deps.requestEncryptionKey(userAddress);
30408
- const { Q: Q19 } = await import("@nozbe/watermelondb");
30561
+ const { Q: Q20 } = await import("@nozbe/watermelondb");
30409
30562
  const conversationsCollection = database.get("conversations");
30410
- const records = await conversationsCollection.query(Q19.where("is_deleted", false)).fetch();
30563
+ const records = await conversationsCollection.query(Q20.where("is_deleted", false)).fetch();
30411
30564
  const conversations = records.map(conversationToStoredRaw);
30412
30565
  const total = conversations.length;
30413
30566
  if (total === 0) {
@@ -31089,8 +31242,8 @@ function createDriveFileIndex(folderId) {
31089
31242
  };
31090
31243
  }
31091
31244
  async function readLocalUpdatedAt2(database, conversationId) {
31092
- const { Q: Q19 } = await import("@nozbe/watermelondb");
31093
- const records = await database.get("conversations").query(Q19.where("conversation_id", conversationId)).fetch();
31245
+ const { Q: Q20 } = await import("@nozbe/watermelondb");
31246
+ const records = await database.get("conversations").query(Q20.where("conversation_id", conversationId)).fetch();
31094
31247
  const match = records.map(conversationToStoredRaw).find((c) => c.conversationId === conversationId);
31095
31248
  return match ? match.updatedAt : null;
31096
31249
  }
@@ -31170,9 +31323,9 @@ async function performGoogleDriveExport(database, userAddress, token, deps, onPr
31170
31323
  }
31171
31324
  const { folderId, token: activeToken } = folderResult;
31172
31325
  const fileIndex = createDriveFileIndex(folderId);
31173
- const { Q: Q19 } = await import("@nozbe/watermelondb");
31326
+ const { Q: Q20 } = await import("@nozbe/watermelondb");
31174
31327
  const conversationsCollection = database.get("conversations");
31175
- const records = await conversationsCollection.query(Q19.where("is_deleted", false)).fetch();
31328
+ const records = await conversationsCollection.query(Q20.where("is_deleted", false)).fetch();
31176
31329
  const conversations = records.map(conversationToStoredRaw);
31177
31330
  const total = conversations.length;
31178
31331
  if (total === 0) {
@@ -31757,9 +31910,9 @@ async function pushConversationToICloud(database, conversationId, userAddress, d
31757
31910
  const filename = `${conversationId}.json`;
31758
31911
  const existingFile = await findICloudFile(filename);
31759
31912
  if (existingFile) {
31760
- const { Q: Q19 } = await import("@nozbe/watermelondb");
31913
+ const { Q: Q20 } = await import("@nozbe/watermelondb");
31761
31914
  const conversationsCollection = database.get("conversations");
31762
- const records = await conversationsCollection.query(Q19.where("conversation_id", conversationId)).fetch();
31915
+ const records = await conversationsCollection.query(Q20.where("conversation_id", conversationId)).fetch();
31763
31916
  if (records.length > 0) {
31764
31917
  const conversation = conversationToStoredRaw(records[0]);
31765
31918
  const localUpdated = conversation.updatedAt.getTime();
@@ -31789,9 +31942,9 @@ async function pushConversationToICloud(database, conversationId, userAddress, d
31789
31942
  }
31790
31943
  async function performICloudExport(database, userAddress, deps, onProgress) {
31791
31944
  await deps.requestEncryptionKey(userAddress);
31792
- const { Q: Q19 } = await import("@nozbe/watermelondb");
31945
+ const { Q: Q20 } = await import("@nozbe/watermelondb");
31793
31946
  const conversationsCollection = database.get("conversations");
31794
- const records = await conversationsCollection.query(Q19.where("is_deleted", false)).fetch();
31947
+ const records = await conversationsCollection.query(Q20.where("is_deleted", false)).fetch();
31795
31948
  const conversations = records.map(conversationToStoredRaw);
31796
31949
  const total = conversations.length;
31797
31950
  if (total === 0) {
@@ -35766,6 +35919,7 @@ export {
35766
35919
  createGitHubTools,
35767
35920
  createLlmDecayClassifier,
35768
35921
  createLlmNeighborRefiner,
35922
+ createLocalMemoryStore,
35769
35923
  createMediaBatchOp,
35770
35924
  createMediaOp,
35771
35925
  createMemoryEngineTool,