@anuma/sdk 6.32.0 → 6.33.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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,
@@ -9588,7 +9589,13 @@ async function runToolLoop(options) {
9588
9589
  );
9589
9590
  const extra = results.flatMap((r) => Array.isArray(r) ? r : []);
9590
9591
  if (extra.length > 0) {
9591
- messages = [...messages, ...await redactBatch(extra)];
9592
+ let userIndex = messages.length - 1;
9593
+ while (userIndex > 0 && messages[userIndex].role !== "user") userIndex--;
9594
+ messages = [
9595
+ ...messages.slice(0, userIndex),
9596
+ ...await redactBatch(extra),
9597
+ ...messages.slice(userIndex)
9598
+ ];
9592
9599
  }
9593
9600
  }
9594
9601
  } catch (err) {
@@ -17202,7 +17209,10 @@ async function eagerEmbedContent(content, embeddingOptions, cache, vaultCtx, mem
17202
17209
  if (memoryId) cacheRowVector(cache, memoryId, Float32Array.from(embedding), updatedAt, content);
17203
17210
  if (vaultCtx && memoryId) {
17204
17211
  const currentModel = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
17205
- updateVaultMemoryEmbeddingOp(vaultCtx, memoryId, JSON.stringify(embedding), currentModel).catch(
17212
+ updateVaultMemoryEmbeddingOp(vaultCtx, memoryId, JSON.stringify(embedding), currentModel, {
17213
+ content,
17214
+ ...updatedAt !== void 0 && { updatedAt: updatedAt.getTime() }
17215
+ }).catch(
17206
17216
  // Silently swallow – SDK must not use console.*; embedding will be retried on next search
17207
17217
  () => {
17208
17218
  }
@@ -20741,6 +20751,353 @@ function parseAnswer(body, base, parseSchema) {
20741
20751
  };
20742
20752
  }
20743
20753
 
20754
+ // src/lib/memory/store/local.ts
20755
+ var import_watermelondb13 = require("@nozbe/watermelondb");
20756
+ init_logger();
20757
+
20758
+ // src/lib/memory/topicExtract.ts
20759
+ init_logger();
20760
+ init_redactor();
20761
+ init_portalLlm();
20762
+ var TOPIC_EXTRACTION_BATCH_SIZE = 10;
20763
+ var MAX_CHARS_PER_MEMORY = 300;
20764
+ var MAX_VOCABULARY_NAMES = 100;
20765
+ var MAX_COMPLETION_TOKENS = 8192;
20766
+ var SYSTEM_PROMPT6 = `You assign topics to saved memories for a personal memory system.
20767
+
20768
+ 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.
20769
+
20770
+ 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:
20771
+ - 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.
20772
+ - KEEP the specific thing instead, when the memory names one: "Blue Bottle on Valencia" over "cafe", "Chicago Marathon" over "event", "Hollowpoint Labs" over "work".
20773
+ - Prefer 0 entities over a weak one. A memory whose only candidate is a generic noun has NO entities.
20774
+ ${ENTITY_KIND_GUIDELINES}
20775
+
20776
+ Each memory below is written as "<id>: <text>". Output strict JSON: {"memories": [{"id": string, "entities": [{"name": string, "kind": string}]}]}
20777
+ - exactly one element per input memory; copy its id EXACTLY as written (the token before the first ": "), with no brackets, quotes, or extra characters
20778
+ - "entities" may be empty when a memory mentions no named entities \u2014 most short memories have 0-3
20779
+ No prose.`;
20780
+ async function extractEntitiesForMemories(memories, options) {
20781
+ const out = /* @__PURE__ */ new Map();
20782
+ if (memories.length === 0) return out;
20783
+ const redactor = resolvePiiRedactor(options.piiRedaction);
20784
+ const vocabulary = [];
20785
+ for (const name of (options.existingEntityNames ?? []).filter((n) => n.trim().length > 0).slice(0, MAX_VOCABULARY_NAMES)) {
20786
+ vocabulary.push(redactor ? (await redactor.redactTextAsync(name)).text : name);
20787
+ }
20788
+ const vocabularyNote = vocabulary.length > 0 ? `The user's existing topics: ${vocabulary.join(", ")}.
20789
+ 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".
20790
+
20791
+ ` : "";
20792
+ for (let i = 0; i < memories.length; i += TOPIC_EXTRACTION_BATCH_SIZE) {
20793
+ const batch = memories.slice(i, i + TOPIC_EXTRACTION_BATCH_SIZE);
20794
+ const rows = [];
20795
+ for (const m of batch) {
20796
+ const content = m.content.slice(0, MAX_CHARS_PER_MEMORY).replace(/\s+/g, " ").trim();
20797
+ rows.push(`${m.id}: ${redactor ? (await redactor.redactTextAsync(content)).text : content}`);
20798
+ }
20799
+ const listing = rows.join("\n");
20800
+ const parsed = await callPortalJsonCompletion({
20801
+ ...options.apiKey !== void 0 && { apiKey: options.apiKey },
20802
+ ...options.getToken !== void 0 && { getToken: options.getToken },
20803
+ ...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
20804
+ taskType: "memory_topic",
20805
+ ...options.endpointOverride !== void 0 && {
20806
+ endpointOverride: options.endpointOverride
20807
+ },
20808
+ model: options.model ?? DEFAULT_EXTRACTION_MODEL,
20809
+ systemPrompt: SYSTEM_PROMPT6,
20810
+ userMessage: `${vocabularyNote}Memories:
20811
+ ${listing}
20812
+
20813
+ List each memory's named entities.`,
20814
+ tag: "memory/topics",
20815
+ extra: { max_completion_tokens: MAX_COMPLETION_TOKENS },
20816
+ ...options.fetchFn && { fetchFn: options.fetchFn },
20817
+ ...options.maxAttempts !== void 0 && { maxAttempts: options.maxAttempts },
20818
+ ...options.timeoutMs !== void 0 && { timeoutMs: options.timeoutMs },
20819
+ ...options.totalTimeoutMs !== void 0 && { totalTimeoutMs: options.totalTimeoutMs },
20820
+ ...options.backoffMs && { backoffMs: options.backoffMs }
20821
+ });
20822
+ if (parsed === null) {
20823
+ getLogger().warn(
20824
+ `[memory/topics] batch of ${batch.length} failed after retries \u2014 will retry next sweep`
20825
+ );
20826
+ continue;
20827
+ }
20828
+ const validIds = new Set(batch.map((m) => m.id));
20829
+ const byId = parseTopicResponse(parsed, validIds);
20830
+ if (byId === null) {
20831
+ getLogger().warn(
20832
+ `[memory/topics] batch of ${batch.length} returned an unrecognized shape \u2014 will retry next sweep`
20833
+ );
20834
+ continue;
20835
+ }
20836
+ for (const m of batch) {
20837
+ const entities = byId.get(m.id);
20838
+ if (entities === void 0) {
20839
+ continue;
20840
+ }
20841
+ out.set(m.id, redactor ? restoreEntities(entities, redactor) : entities);
20842
+ }
20843
+ }
20844
+ return out;
20845
+ }
20846
+ function restoreEntities(entities, redactor) {
20847
+ return entities.map((e) => ({ kind: e.kind, restored: redactor.restoreForStorage(e.name) })).filter((e) => !e.restored.unresolved).map(
20848
+ (e) => e.kind !== void 0 ? { name: e.restored.text, kind: e.kind } : { name: e.restored.text }
20849
+ );
20850
+ }
20851
+ function parseTopicResponse(parsed, validIds) {
20852
+ if (typeof parsed !== "object" || parsed === null) return null;
20853
+ const list = parsed.memories;
20854
+ if (!Array.isArray(list)) return null;
20855
+ const out = /* @__PURE__ */ new Map();
20856
+ for (const raw of list) {
20857
+ if (typeof raw !== "object" || raw === null) continue;
20858
+ const obj = raw;
20859
+ if (typeof obj.id !== "string") continue;
20860
+ const id = obj.id.trim().replace(/:$/, "").replace(/^\[([\s\S]*)\]$/, "$1").trim();
20861
+ if (!validIds.has(id) || out.has(id)) continue;
20862
+ const entities = Array.isArray(obj.entities) ? parseEntities(obj.entities) : [];
20863
+ out.set(id, entities);
20864
+ }
20865
+ return out;
20866
+ }
20867
+ var DEGRADED_TOPIC_SKIP = {
20868
+ excluded: false,
20869
+ "link-declined": false,
20870
+ "stamp-declined": false,
20871
+ "llm-unanswered": true,
20872
+ unreadable: true,
20873
+ "not-found": true,
20874
+ "link-failed": true
20875
+ };
20876
+ function isDegradedTopicSkip(reason) {
20877
+ return DEGRADED_TOPIC_SKIP[reason] === true;
20878
+ }
20879
+ async function extractAndLinkEntitiesForMemoriesOp(ctx, memoryIds, options) {
20880
+ const entityCtx = ctx.entityCtx;
20881
+ if (!entityCtx) {
20882
+ throw new Error("extractAndLinkEntitiesForMemoriesOp requires ctx.entityCtx");
20883
+ }
20884
+ const log = getLogger();
20885
+ const extractedAt = options.now ?? Date.now();
20886
+ const skippedIds = [];
20887
+ const skippedReasons = /* @__PURE__ */ new Map();
20888
+ const skip = (id, reason) => {
20889
+ if (skippedReasons.has(id)) return;
20890
+ skippedIds.push(id);
20891
+ skippedReasons.set(id, reason);
20892
+ };
20893
+ const inputs = [];
20894
+ for (const id of new Set(memoryIds)) {
20895
+ let record;
20896
+ try {
20897
+ record = await ctx.vaultMemoryCollection.find(id);
20898
+ } catch (err) {
20899
+ log.warn("[memory/topics] vault lookup failed for extraction", err);
20900
+ skip(id, "not-found");
20901
+ continue;
20902
+ }
20903
+ if (record.isDeleted || ctx.userId !== void 0 && record.userId !== ctx.userId || record.topicsUserManaged) {
20904
+ skip(id, "excluded");
20905
+ continue;
20906
+ }
20907
+ try {
20908
+ const stored = await vaultMemoryToStored(
20909
+ record,
20910
+ ctx.walletAddress,
20911
+ ctx.signMessage,
20912
+ ctx.embeddedWalletSigner
20913
+ );
20914
+ inputs.push({ id, content: stored.content });
20915
+ } catch (err) {
20916
+ log.warn("[memory/topics] failed to load memory for extraction", err);
20917
+ skip(id, "unreadable");
20918
+ }
20919
+ }
20920
+ const entitiesByMemory = await extractEntitiesForMemories(inputs, options);
20921
+ const toStamp = [];
20922
+ for (const input of inputs) {
20923
+ const entities = entitiesByMemory.get(input.id);
20924
+ if (entities === void 0) {
20925
+ skip(input.id, "llm-unanswered");
20926
+ continue;
20927
+ }
20928
+ try {
20929
+ const linked = await replaceMemoryEntitiesGuardedOp(entityCtx, input.id, entities);
20930
+ if (linked === null) {
20931
+ skip(input.id, "link-declined");
20932
+ entitiesByMemory.delete(input.id);
20933
+ continue;
20934
+ }
20935
+ } catch (err) {
20936
+ log.warn("[memory/topics] replaceMemoryEntitiesGuardedOp failed", err);
20937
+ skip(input.id, "link-failed");
20938
+ entitiesByMemory.delete(input.id);
20939
+ continue;
20940
+ }
20941
+ toStamp.push(input.id);
20942
+ }
20943
+ const stampedIds = await stampTopicsExtractedAtOp(ctx, toStamp, extractedAt);
20944
+ const stampedSet = new Set(stampedIds);
20945
+ for (const id of toStamp) {
20946
+ if (!stampedSet.has(id)) {
20947
+ skip(id, "stamp-declined");
20948
+ entitiesByMemory.delete(id);
20949
+ }
20950
+ }
20951
+ return { entitiesByMemory, stampedIds, skippedIds, skippedReasons };
20952
+ }
20953
+
20954
+ // src/lib/memory/store/local.ts
20955
+ function createLocalMemoryStore(options) {
20956
+ const { database, userId } = options;
20957
+ const entityCtx = {
20958
+ database,
20959
+ entityCollection: database.get("entity"),
20960
+ memoryEntityCollection: database.get("memory_entity"),
20961
+ ...userId !== void 0 && { userId },
20962
+ ...options.allowUnscopedRows !== void 0 && {
20963
+ allowUnscopedRows: options.allowUnscopedRows
20964
+ }
20965
+ };
20966
+ const vaultCtx = {
20967
+ database,
20968
+ vaultMemoryCollection: database.get("memory_vault"),
20969
+ walletAddress: options.walletAddress,
20970
+ signMessage: options.signMessage,
20971
+ embeddedWalletSigner: options.embeddedWalletSigner,
20972
+ ...userId !== void 0 && { userId },
20973
+ ...options.singleTenant !== void 0 && { singleTenant: options.singleTenant },
20974
+ // Deletes cascade to memory_entity, so the graph lane never serves a
20975
+ // deleted memory's id.
20976
+ entityCtx
20977
+ };
20978
+ const vaultCache = options.vaultCache ?? createVaultEmbeddingCache();
20979
+ const ownedBy = userId !== void 0 ? [import_watermelondb13.Q.where("user_id", userId)] : [];
20980
+ const watchedColumns = [
20981
+ "content",
20982
+ "scope",
20983
+ "updated_at",
20984
+ "fact_type",
20985
+ "event_time_start",
20986
+ "event_time_end",
20987
+ "event_time_kind",
20988
+ "archived_at",
20989
+ "trust_tier",
20990
+ "superseded_by",
20991
+ "visibility",
20992
+ "published_at",
20993
+ "geohash",
20994
+ "topics",
20995
+ "topics_user_managed",
20996
+ "media",
20997
+ "source"
20998
+ ];
20999
+ const embedInBackground = (memory) => {
21000
+ eagerEmbedContent(
21001
+ memory.content,
21002
+ options.embeddingOptions,
21003
+ vaultCache,
21004
+ vaultCtx,
21005
+ memory.uniqueId,
21006
+ memory.updatedAt
21007
+ ).catch((err) => {
21008
+ getLogger().warn("[memory/store] Failed to embed memory:", err);
21009
+ });
21010
+ };
21011
+ return {
21012
+ list: (listOptions) => getAllVaultMemoriesOp(vaultCtx, listOptions),
21013
+ get: (id) => getVaultMemoryOp(vaultCtx, id),
21014
+ listArchived: async () => {
21015
+ 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();
21016
+ if (ids.length === 0) return [];
21017
+ const rows = await getAllVaultMemoriesOp(vaultCtx, { memoryIds: ids, includeArchived: true });
21018
+ return rows.sort((a, b) => (b.archivedAt ?? 0) - (a.archivedAt ?? 0));
21019
+ },
21020
+ memoriesByTopics: (names) => getMemoriesByEntityNamesOp(entityCtx, names),
21021
+ topicsByMemories: (memoryIds) => getEntitiesByMemoryIdsOp(entityCtx, memoryIds),
21022
+ create: async (input) => {
21023
+ const created = await createVaultMemoryOp(vaultCtx, input);
21024
+ if (input.embedding === void 0) embedInBackground(created);
21025
+ return created;
21026
+ },
21027
+ createMany: async (inputs) => {
21028
+ const created = await createVaultMemoriesBatchOp(vaultCtx, inputs);
21029
+ created.forEach((memory, i) => {
21030
+ if (inputs[i].embedding === void 0) embedInBackground(memory);
21031
+ });
21032
+ return created;
21033
+ },
21034
+ update: async (id, patch) => {
21035
+ const reembed = patch.embedding === void 0;
21036
+ const updated = await updateVaultMemoryOp(
21037
+ vaultCtx,
21038
+ id,
21039
+ reembed ? { ...patch, embedding: null } : patch
21040
+ );
21041
+ if (!updated) return null;
21042
+ vaultCache.delete(id);
21043
+ if (reembed) embedInBackground(updated);
21044
+ return updated;
21045
+ },
21046
+ delete: async (id) => {
21047
+ const deleted = await deleteVaultMemoryOp(vaultCtx, id);
21048
+ if (deleted) vaultCache.delete(id);
21049
+ return deleted;
21050
+ },
21051
+ supersede: (id, supersededById) => supersedeVaultMemoryOp(vaultCtx, id, supersededById),
21052
+ archive: (id) => archiveVaultMemoryOp(vaultCtx, id),
21053
+ restore: (id) => restoreVaultMemoryOp(vaultCtx, id),
21054
+ setTopics: (memoryId, topics) => setMemoryEntitiesOp(vaultCtx, memoryId, topics),
21055
+ addTopics: (memoryId, topics) => database.write(async (writer) => {
21056
+ const owned = await vaultCtx.vaultMemoryCollection.query(import_watermelondb13.Q.where("id", memoryId), import_watermelondb13.Q.where("is_deleted", false), ...ownedBy).fetchCount();
21057
+ return owned > 0 ? writer.callWriter(() => linkMemoryEntitiesOp(entityCtx, memoryId, topics)) : [];
21058
+ }),
21059
+ setVisibility: (id, visibility, visibilityOptions) => setMemoryVisibilityOp(vaultCtx, id, { visibility, ...visibilityOptions }),
21060
+ recall: (query, recallOptions) => recall(
21061
+ query,
21062
+ { vaultCtx, entityCtx, embeddingOptions: options.embeddingOptions, vaultCache },
21063
+ { ...recallOptions, types: ["fact"] }
21064
+ ),
21065
+ retain: (content, retainOptions) => retain(
21066
+ content,
21067
+ { vaultCtx, embeddingOptions: options.embeddingOptions, vaultCache },
21068
+ retainOptions
21069
+ ),
21070
+ subscribe: (onChange, subscribeOptions) => {
21071
+ const afterFirst = () => {
21072
+ let first = true;
21073
+ return () => {
21074
+ if (first) first = false;
21075
+ else onChange();
21076
+ };
21077
+ };
21078
+ const memories = subscribeOptions?.includeDeleted ? vaultCtx.vaultMemoryCollection.query(...ownedBy).observe() : vaultCtx.vaultMemoryCollection.query(import_watermelondb13.Q.where("is_deleted", false), ...ownedBy).observeWithColumns(
21079
+ subscribeOptions?.embeddings ? [...watchedColumns, "embedding", "embedding_model"] : watchedColumns
21080
+ );
21081
+ const subscriptions = [memories.subscribe(afterFirst())];
21082
+ if (subscribeOptions?.topics) {
21083
+ 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)];
21084
+ subscriptions.push(
21085
+ entityCtx.memoryEntityCollection.query(...linksOwnedBy).observe().subscribe(afterFirst())
21086
+ );
21087
+ }
21088
+ return () => subscriptions.forEach((s) => s.unsubscribe());
21089
+ },
21090
+ maintenance: {
21091
+ createDecaySweeper: (sweeperOptions) => createDecaySweeper({ ...sweeperOptions, vaultCtx }),
21092
+ getTopicBacklog: (backlogOptions) => getMemoriesNeedingTopicExtractionOp(vaultCtx, backlogOptions),
21093
+ extractTopics: (memoryIds, extractOptions) => extractAndLinkEntitiesForMemoriesOp(vaultCtx, memoryIds, extractOptions),
21094
+ stampTopicsExtracted: (memoryIds, extractedAt, version) => stampTopicsExtractedAtOp(vaultCtx, memoryIds, extractedAt, version),
21095
+ relinkTopics: (memoryIds) => relinkMemoryTopicsOp(vaultCtx, memoryIds),
21096
+ backfillTopics: (memoryIds) => backfillMemoryTopicsOp(vaultCtx, memoryIds)
21097
+ }
21098
+ };
21099
+ }
21100
+
20744
21101
  // src/lib/memory/synthesizeProfile.ts
20745
21102
  init_internalFlowMarker();
20746
21103
  init_logger();
@@ -21270,202 +21627,6 @@ function normalizeInterests(values) {
21270
21627
  return out.length > 0 ? out : void 0;
21271
21628
  }
21272
21629
 
21273
- // src/lib/memory/topicExtract.ts
21274
- init_logger();
21275
- init_redactor();
21276
- init_portalLlm();
21277
- var TOPIC_EXTRACTION_BATCH_SIZE = 10;
21278
- var MAX_CHARS_PER_MEMORY = 300;
21279
- var MAX_VOCABULARY_NAMES = 100;
21280
- var MAX_COMPLETION_TOKENS = 8192;
21281
- var SYSTEM_PROMPT6 = `You assign topics to saved memories for a personal memory system.
21282
-
21283
- 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.
21284
-
21285
- 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:
21286
- - 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.
21287
- - KEEP the specific thing instead, when the memory names one: "Blue Bottle on Valencia" over "cafe", "Chicago Marathon" over "event", "Hollowpoint Labs" over "work".
21288
- - Prefer 0 entities over a weak one. A memory whose only candidate is a generic noun has NO entities.
21289
- ${ENTITY_KIND_GUIDELINES}
21290
-
21291
- Each memory below is written as "<id>: <text>". Output strict JSON: {"memories": [{"id": string, "entities": [{"name": string, "kind": string}]}]}
21292
- - exactly one element per input memory; copy its id EXACTLY as written (the token before the first ": "), with no brackets, quotes, or extra characters
21293
- - "entities" may be empty when a memory mentions no named entities \u2014 most short memories have 0-3
21294
- No prose.`;
21295
- async function extractEntitiesForMemories(memories, options) {
21296
- const out = /* @__PURE__ */ new Map();
21297
- if (memories.length === 0) return out;
21298
- const redactor = resolvePiiRedactor(options.piiRedaction);
21299
- const vocabulary = [];
21300
- for (const name of (options.existingEntityNames ?? []).filter((n) => n.trim().length > 0).slice(0, MAX_VOCABULARY_NAMES)) {
21301
- vocabulary.push(redactor ? (await redactor.redactTextAsync(name)).text : name);
21302
- }
21303
- const vocabularyNote = vocabulary.length > 0 ? `The user's existing topics: ${vocabulary.join(", ")}.
21304
- 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".
21305
-
21306
- ` : "";
21307
- for (let i = 0; i < memories.length; i += TOPIC_EXTRACTION_BATCH_SIZE) {
21308
- const batch = memories.slice(i, i + TOPIC_EXTRACTION_BATCH_SIZE);
21309
- const rows = [];
21310
- for (const m of batch) {
21311
- const content = m.content.slice(0, MAX_CHARS_PER_MEMORY).replace(/\s+/g, " ").trim();
21312
- rows.push(`${m.id}: ${redactor ? (await redactor.redactTextAsync(content)).text : content}`);
21313
- }
21314
- const listing = rows.join("\n");
21315
- const parsed = await callPortalJsonCompletion({
21316
- ...options.apiKey !== void 0 && { apiKey: options.apiKey },
21317
- ...options.getToken !== void 0 && { getToken: options.getToken },
21318
- ...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
21319
- taskType: "memory_topic",
21320
- ...options.endpointOverride !== void 0 && {
21321
- endpointOverride: options.endpointOverride
21322
- },
21323
- model: options.model ?? DEFAULT_EXTRACTION_MODEL,
21324
- systemPrompt: SYSTEM_PROMPT6,
21325
- userMessage: `${vocabularyNote}Memories:
21326
- ${listing}
21327
-
21328
- List each memory's named entities.`,
21329
- tag: "memory/topics",
21330
- extra: { max_completion_tokens: MAX_COMPLETION_TOKENS },
21331
- ...options.fetchFn && { fetchFn: options.fetchFn },
21332
- ...options.maxAttempts !== void 0 && { maxAttempts: options.maxAttempts },
21333
- ...options.timeoutMs !== void 0 && { timeoutMs: options.timeoutMs },
21334
- ...options.totalTimeoutMs !== void 0 && { totalTimeoutMs: options.totalTimeoutMs },
21335
- ...options.backoffMs && { backoffMs: options.backoffMs }
21336
- });
21337
- if (parsed === null) {
21338
- getLogger().warn(
21339
- `[memory/topics] batch of ${batch.length} failed after retries \u2014 will retry next sweep`
21340
- );
21341
- continue;
21342
- }
21343
- const validIds = new Set(batch.map((m) => m.id));
21344
- const byId = parseTopicResponse(parsed, validIds);
21345
- if (byId === null) {
21346
- getLogger().warn(
21347
- `[memory/topics] batch of ${batch.length} returned an unrecognized shape \u2014 will retry next sweep`
21348
- );
21349
- continue;
21350
- }
21351
- for (const m of batch) {
21352
- const entities = byId.get(m.id);
21353
- if (entities === void 0) {
21354
- continue;
21355
- }
21356
- out.set(m.id, redactor ? restoreEntities(entities, redactor) : entities);
21357
- }
21358
- }
21359
- return out;
21360
- }
21361
- function restoreEntities(entities, redactor) {
21362
- return entities.map((e) => ({ kind: e.kind, restored: redactor.restoreForStorage(e.name) })).filter((e) => !e.restored.unresolved).map(
21363
- (e) => e.kind !== void 0 ? { name: e.restored.text, kind: e.kind } : { name: e.restored.text }
21364
- );
21365
- }
21366
- function parseTopicResponse(parsed, validIds) {
21367
- if (typeof parsed !== "object" || parsed === null) return null;
21368
- const list = parsed.memories;
21369
- if (!Array.isArray(list)) return null;
21370
- const out = /* @__PURE__ */ new Map();
21371
- for (const raw of list) {
21372
- if (typeof raw !== "object" || raw === null) continue;
21373
- const obj = raw;
21374
- if (typeof obj.id !== "string") continue;
21375
- const id = obj.id.trim().replace(/:$/, "").replace(/^\[([\s\S]*)\]$/, "$1").trim();
21376
- if (!validIds.has(id) || out.has(id)) continue;
21377
- const entities = Array.isArray(obj.entities) ? parseEntities(obj.entities) : [];
21378
- out.set(id, entities);
21379
- }
21380
- return out;
21381
- }
21382
- var DEGRADED_TOPIC_SKIP = {
21383
- excluded: false,
21384
- "link-declined": false,
21385
- "stamp-declined": false,
21386
- "llm-unanswered": true,
21387
- unreadable: true,
21388
- "not-found": true,
21389
- "link-failed": true
21390
- };
21391
- function isDegradedTopicSkip(reason) {
21392
- return DEGRADED_TOPIC_SKIP[reason] === true;
21393
- }
21394
- async function extractAndLinkEntitiesForMemoriesOp(ctx, memoryIds, options) {
21395
- const entityCtx = ctx.entityCtx;
21396
- if (!entityCtx) {
21397
- throw new Error("extractAndLinkEntitiesForMemoriesOp requires ctx.entityCtx");
21398
- }
21399
- const log = getLogger();
21400
- const extractedAt = options.now ?? Date.now();
21401
- const skippedIds = [];
21402
- const skippedReasons = /* @__PURE__ */ new Map();
21403
- const skip = (id, reason) => {
21404
- if (skippedReasons.has(id)) return;
21405
- skippedIds.push(id);
21406
- skippedReasons.set(id, reason);
21407
- };
21408
- const inputs = [];
21409
- for (const id of new Set(memoryIds)) {
21410
- let record;
21411
- try {
21412
- record = await ctx.vaultMemoryCollection.find(id);
21413
- } catch (err) {
21414
- log.warn("[memory/topics] vault lookup failed for extraction", err);
21415
- skip(id, "not-found");
21416
- continue;
21417
- }
21418
- if (record.isDeleted || ctx.userId !== void 0 && record.userId !== ctx.userId || record.topicsUserManaged) {
21419
- skip(id, "excluded");
21420
- continue;
21421
- }
21422
- try {
21423
- const stored = await vaultMemoryToStored(
21424
- record,
21425
- ctx.walletAddress,
21426
- ctx.signMessage,
21427
- ctx.embeddedWalletSigner
21428
- );
21429
- inputs.push({ id, content: stored.content });
21430
- } catch (err) {
21431
- log.warn("[memory/topics] failed to load memory for extraction", err);
21432
- skip(id, "unreadable");
21433
- }
21434
- }
21435
- const entitiesByMemory = await extractEntitiesForMemories(inputs, options);
21436
- const toStamp = [];
21437
- for (const input of inputs) {
21438
- const entities = entitiesByMemory.get(input.id);
21439
- if (entities === void 0) {
21440
- skip(input.id, "llm-unanswered");
21441
- continue;
21442
- }
21443
- try {
21444
- const linked = await replaceMemoryEntitiesGuardedOp(entityCtx, input.id, entities);
21445
- if (linked === null) {
21446
- skip(input.id, "link-declined");
21447
- entitiesByMemory.delete(input.id);
21448
- continue;
21449
- }
21450
- } catch (err) {
21451
- log.warn("[memory/topics] replaceMemoryEntitiesGuardedOp failed", err);
21452
- skip(input.id, "link-failed");
21453
- entitiesByMemory.delete(input.id);
21454
- continue;
21455
- }
21456
- toStamp.push(input.id);
21457
- }
21458
- const stampedIds = await stampTopicsExtractedAtOp(ctx, toStamp, extractedAt);
21459
- const stampedSet = new Set(stampedIds);
21460
- for (const id of toStamp) {
21461
- if (!stampedSet.has(id)) {
21462
- skip(id, "stamp-declined");
21463
- entitiesByMemory.delete(id);
21464
- }
21465
- }
21466
- return { entitiesByMemory, stampedIds, skippedIds, skippedReasons };
21467
- }
21468
-
21469
21630
  // src/lib/memory/verifySupport.ts
21470
21631
  init_logger();
21471
21632
  init_redactor();
@@ -21859,7 +22020,7 @@ async function assembleMemoryContext(options) {
21859
22020
  }
21860
22021
 
21861
22022
  // src/lib/memory/durableExtraction.ts
21862
- var import_watermelondb13 = require("@nozbe/watermelondb");
22023
+ var import_watermelondb14 = require("@nozbe/watermelondb");
21863
22024
  var MAX_JOBS_PER_PASS = 3;
21864
22025
  var MAX_ATTEMPTS = 3;
21865
22026
  var MAX_FAILED_SESSIONS = 3;
@@ -22006,7 +22167,7 @@ function createDurableAutoExtractor(options) {
22006
22167
  ...options.retainCtx,
22007
22168
  vaultCtx: {
22008
22169
  ...vault,
22009
- 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
22170
+ 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
22010
22171
  }
22011
22172
  },
22012
22173
  // The model follows the job's scope, not the mode alive at drain time.
@@ -22148,7 +22309,7 @@ function createDurableAutoExtractor(options) {
22148
22309
  let scheduleAfterSuccess = false;
22149
22310
  try {
22150
22311
  await writes;
22151
- const pending = await jobs.query(import_watermelondb13.Q.where("owner_key", owner), import_watermelondb13.Q.where("message_ids", import_watermelondb13.Q.notEq("[]"))).fetch();
22312
+ const pending = await jobs.query(import_watermelondb14.Q.where("owner_key", owner), import_watermelondb14.Q.where("message_ids", import_watermelondb14.Q.notEq("[]"))).fetch();
22152
22313
  storeFailures = 0;
22153
22314
  let processed = 0;
22154
22315
  for (const job of pending) {
@@ -22164,7 +22325,7 @@ function createDurableAutoExtractor(options) {
22164
22325
  let ids = [];
22165
22326
  let loaded = [];
22166
22327
  try {
22167
- const conversations = await storage.conversationsCollection.query(import_watermelondb13.Q.where("conversation_id", conversationId), import_watermelondb13.Q.where("is_deleted", false)).fetchCount();
22328
+ const conversations = await storage.conversationsCollection.query(import_watermelondb14.Q.where("conversation_id", conversationId), import_watermelondb14.Q.where("is_deleted", false)).fetchCount();
22168
22329
  if (!conversations) {
22169
22330
  await database.write(() => job.destroyPermanently());
22170
22331
  continue;
@@ -22281,12 +22442,12 @@ function createDurableAutoExtractor(options) {
22281
22442
  const scope = currentScope();
22282
22443
  writes = writes.then(
22283
22444
  () => database.write(async () => {
22284
- const existing = await jobs.query(import_watermelondb13.Q.where("owner_key", owner), import_watermelondb13.Q.where("conversation_id", conversationId)).fetch();
22445
+ const existing = await jobs.query(import_watermelondb14.Q.where("owner_key", owner), import_watermelondb14.Q.where("conversation_id", conversationId)).fetch();
22285
22446
  const job = existing.find(
22286
22447
  (candidate) => candidate._getRaw("scope") === scope && (candidate._getRaw("folder_id") ?? null) === folderId
22287
22448
  );
22288
22449
  const positions = new Map(ids.map((id, index) => [id, index]));
22289
- const rows = await storage.messagesCollection.query(import_watermelondb13.Q.where("id", import_watermelondb13.Q.oneOf(ids))).fetch();
22450
+ const rows = await storage.messagesCollection.query(import_watermelondb14.Q.where("id", import_watermelondb14.Q.oneOf(ids))).fetch();
22290
22451
  const sequences = /* @__PURE__ */ new Map();
22291
22452
  for (const row of rows) {
22292
22453
  const sequence = Number(row._getRaw("message_id"));
@@ -26480,13 +26641,13 @@ function useChatStorage(options) {
26480
26641
  }
26481
26642
 
26482
26643
  // src/lib/db/schema.ts
26483
- var import_watermelondb22 = require("@nozbe/watermelondb");
26644
+ var import_watermelondb23 = require("@nozbe/watermelondb");
26484
26645
  var import_migrations2 = require("@nozbe/watermelondb/Schema/migrations");
26485
26646
 
26486
26647
  // src/lib/db/appFiles/models.ts
26487
- var import_watermelondb14 = require("@nozbe/watermelondb");
26648
+ var import_watermelondb15 = require("@nozbe/watermelondb");
26488
26649
  var import_decorators4 = require("@nozbe/watermelondb/decorators");
26489
- var AppFile = class extends import_watermelondb14.Model {
26650
+ var AppFile = class extends import_watermelondb15.Model {
26490
26651
  };
26491
26652
  AppFile.table = "app_files";
26492
26653
  AppFile.associations = {};
@@ -26508,9 +26669,9 @@ __decorateClass([
26508
26669
  ], AppFile.prototype, "updatedAt", 2);
26509
26670
 
26510
26671
  // src/lib/db/conversationMemory/models.ts
26511
- var import_watermelondb15 = require("@nozbe/watermelondb");
26672
+ var import_watermelondb16 = require("@nozbe/watermelondb");
26512
26673
  var import_decorators5 = require("@nozbe/watermelondb/decorators");
26513
- var ConversationMemory = class extends import_watermelondb15.Model {
26674
+ var ConversationMemory = class extends import_watermelondb16.Model {
26514
26675
  };
26515
26676
  ConversationMemory.table = "conversation_memory";
26516
26677
  ConversationMemory.associations = {};
@@ -26529,9 +26690,9 @@ __decorateClass([
26529
26690
  ], ConversationMemory.prototype, "createdAt", 2);
26530
26691
 
26531
26692
  // src/lib/db/entities/models.ts
26532
- var import_watermelondb16 = require("@nozbe/watermelondb");
26693
+ var import_watermelondb17 = require("@nozbe/watermelondb");
26533
26694
  var import_decorators6 = require("@nozbe/watermelondb/decorators");
26534
- var Entity = class extends import_watermelondb16.Model {
26695
+ var Entity = class extends import_watermelondb17.Model {
26535
26696
  };
26536
26697
  Entity.table = "entity";
26537
26698
  __decorateClass([
@@ -26547,7 +26708,7 @@ __decorateClass([
26547
26708
  __decorateClass([
26548
26709
  (0, import_decorators6.date)("updated_at")
26549
26710
  ], Entity.prototype, "updatedAt", 2);
26550
- var MemoryEntity = class extends import_watermelondb16.Model {
26711
+ var MemoryEntity = class extends import_watermelondb17.Model {
26551
26712
  };
26552
26713
  MemoryEntity.table = "memory_entity";
26553
26714
  __decorateClass([
@@ -26565,9 +26726,9 @@ __decorateClass([
26565
26726
  ], MemoryEntity.prototype, "createdAt", 2);
26566
26727
 
26567
26728
  // src/lib/db/project/models.ts
26568
- var import_watermelondb17 = require("@nozbe/watermelondb");
26729
+ var import_watermelondb18 = require("@nozbe/watermelondb");
26569
26730
  var import_decorators7 = require("@nozbe/watermelondb/decorators");
26570
- var Project = class extends import_watermelondb17.Model {
26731
+ var Project = class extends import_watermelondb18.Model {
26571
26732
  };
26572
26733
  Project.table = "projects";
26573
26734
  Project.associations = {
@@ -26590,10 +26751,10 @@ __decorateClass([
26590
26751
  ], Project.prototype, "isDeleted", 2);
26591
26752
 
26592
26753
  // src/lib/db/savedTools/models.ts
26593
- var import_watermelondb18 = require("@nozbe/watermelondb");
26754
+ var import_watermelondb19 = require("@nozbe/watermelondb");
26594
26755
  var import_decorators8 = require("@nozbe/watermelondb/decorators");
26595
26756
  var sanitizeParameters = (raw) => raw ?? {};
26596
- var SavedTool = class extends import_watermelondb18.Model {
26757
+ var SavedTool = class extends import_watermelondb19.Model {
26597
26758
  };
26598
26759
  SavedTool.table = "saved_tools";
26599
26760
  SavedTool.associations = {};
@@ -26627,9 +26788,9 @@ __decorateClass([
26627
26788
  ], SavedTool.prototype, "isDeleted", 2);
26628
26789
 
26629
26790
  // src/lib/db/settings/models.ts
26630
- var import_watermelondb19 = require("@nozbe/watermelondb");
26791
+ var import_watermelondb20 = require("@nozbe/watermelondb");
26631
26792
  var import_decorators9 = require("@nozbe/watermelondb/decorators");
26632
- var ModelPreference = class extends import_watermelondb19.Model {
26793
+ var ModelPreference = class extends import_watermelondb20.Model {
26633
26794
  };
26634
26795
  ModelPreference.table = "modelPreferences";
26635
26796
  __decorateClass([
@@ -26640,9 +26801,9 @@ __decorateClass([
26640
26801
  ], ModelPreference.prototype, "models", 2);
26641
26802
 
26642
26803
  // src/lib/db/userPreferences/models.ts
26643
- var import_watermelondb20 = require("@nozbe/watermelondb");
26804
+ var import_watermelondb21 = require("@nozbe/watermelondb");
26644
26805
  var import_decorators10 = require("@nozbe/watermelondb/decorators");
26645
- var UserPreference = class extends import_watermelondb20.Model {
26806
+ var UserPreference = class extends import_watermelondb21.Model {
26646
26807
  };
26647
26808
  UserPreference.table = "userPreferences";
26648
26809
  __decorateClass([
@@ -26671,9 +26832,9 @@ __decorateClass([
26671
26832
  ], UserPreference.prototype, "updatedAt", 2);
26672
26833
 
26673
26834
  // src/lib/db/vaultFolders/models.ts
26674
- var import_watermelondb21 = require("@nozbe/watermelondb");
26835
+ var import_watermelondb22 = require("@nozbe/watermelondb");
26675
26836
  var import_decorators11 = require("@nozbe/watermelondb/decorators");
26676
- var VaultFolder = class extends import_watermelondb21.Model {
26837
+ var VaultFolder = class extends import_watermelondb22.Model {
26677
26838
  };
26678
26839
  VaultFolder.table = "vault_folders";
26679
26840
  __decorateClass([
@@ -26701,10 +26862,10 @@ __decorateClass([
26701
26862
 
26702
26863
  // src/lib/db/schema.ts
26703
26864
  var SDK_SCHEMA_VERSION = 47;
26704
- var sdkSchema = (0, import_watermelondb22.appSchema)({
26865
+ var sdkSchema = (0, import_watermelondb23.appSchema)({
26705
26866
  version: SDK_SCHEMA_VERSION,
26706
26867
  tables: [
26707
- (0, import_watermelondb22.tableSchema)({
26868
+ (0, import_watermelondb23.tableSchema)({
26708
26869
  name: "memory_extraction_jobs",
26709
26870
  columns: [
26710
26871
  { name: "owner_key", type: "string", isIndexed: true },
@@ -26724,7 +26885,7 @@ var sdkSchema = (0, import_watermelondb22.appSchema)({
26724
26885
  ]
26725
26886
  }),
26726
26887
  // Chat storage tables
26727
- (0, import_watermelondb22.tableSchema)({
26888
+ (0, import_watermelondb23.tableSchema)({
26728
26889
  name: "history",
26729
26890
  columns: [
26730
26891
  { name: "message_id", type: "number" },
@@ -26763,7 +26924,7 @@ var sdkSchema = (0, import_watermelondb22.appSchema)({
26763
26924
  // MessageOrigin — provenance, NOT encrypted (see v44)
26764
26925
  ]
26765
26926
  }),
26766
- (0, import_watermelondb22.tableSchema)({
26927
+ (0, import_watermelondb23.tableSchema)({
26767
26928
  name: "conversations",
26768
26929
  columns: [
26769
26930
  { name: "conversation_id", type: "string", isIndexed: true },
@@ -26785,7 +26946,7 @@ var sdkSchema = (0, import_watermelondb22.appSchema)({
26785
26946
  ]
26786
26947
  }),
26787
26948
  // Project storage table
26788
- (0, import_watermelondb22.tableSchema)({
26949
+ (0, import_watermelondb23.tableSchema)({
26789
26950
  name: "projects",
26790
26951
  columns: [
26791
26952
  { name: "project_id", type: "string", isIndexed: true },
@@ -26796,7 +26957,7 @@ var sdkSchema = (0, import_watermelondb22.appSchema)({
26796
26957
  ]
26797
26958
  }),
26798
26959
  // Settings storage tables (deprecated - use userPreferences)
26799
- (0, import_watermelondb22.tableSchema)({
26960
+ (0, import_watermelondb23.tableSchema)({
26800
26961
  name: "modelPreferences",
26801
26962
  columns: [
26802
26963
  { name: "wallet_address", type: "string", isIndexed: true },
@@ -26804,7 +26965,7 @@ var sdkSchema = (0, import_watermelondb22.appSchema)({
26804
26965
  ]
26805
26966
  }),
26806
26967
  // Unified user preferences storage
26807
- (0, import_watermelondb22.tableSchema)({
26968
+ (0, import_watermelondb23.tableSchema)({
26808
26969
  name: "userPreferences",
26809
26970
  columns: [
26810
26971
  // Identity
@@ -26823,7 +26984,7 @@ var sdkSchema = (0, import_watermelondb22.appSchema)({
26823
26984
  ]
26824
26985
  }),
26825
26986
  // Memory vault storage
26826
- (0, import_watermelondb22.tableSchema)({
26987
+ (0, import_watermelondb23.tableSchema)({
26827
26988
  name: "memory_vault",
26828
26989
  columns: [
26829
26990
  { name: "content", type: "string" },
@@ -26951,7 +27112,7 @@ var sdkSchema = (0, import_watermelondb22.appSchema)({
26951
27112
  ]
26952
27113
  }),
26953
27114
  // Entity table — canonical names extracted from auto-extraction (W5).
26954
- (0, import_watermelondb22.tableSchema)({
27115
+ (0, import_watermelondb23.tableSchema)({
26955
27116
  name: "entity",
26956
27117
  columns: [
26957
27118
  { name: "canonical_name", type: "string", isIndexed: true },
@@ -26961,7 +27122,7 @@ var sdkSchema = (0, import_watermelondb22.appSchema)({
26961
27122
  ]
26962
27123
  }),
26963
27124
  // Many-to-many join: which memories reference which entities.
26964
- (0, import_watermelondb22.tableSchema)({
27125
+ (0, import_watermelondb23.tableSchema)({
26965
27126
  name: "memory_entity",
26966
27127
  columns: [
26967
27128
  { name: "memory_id", type: "string", isIndexed: true },
@@ -26971,7 +27132,7 @@ var sdkSchema = (0, import_watermelondb22.appSchema)({
26971
27132
  ]
26972
27133
  }),
26973
27134
  // Vault folder organization
26974
- (0, import_watermelondb22.tableSchema)({
27135
+ (0, import_watermelondb23.tableSchema)({
26975
27136
  name: "vault_folders",
26976
27137
  columns: [
26977
27138
  { name: "name", type: "string" },
@@ -26984,7 +27145,7 @@ var sdkSchema = (0, import_watermelondb22.appSchema)({
26984
27145
  ]
26985
27146
  }),
26986
27147
  // Conversation summary cache for progressive history summarization
26987
- (0, import_watermelondb22.tableSchema)({
27148
+ (0, import_watermelondb23.tableSchema)({
26988
27149
  name: "conversation_summaries",
26989
27150
  columns: [
26990
27151
  { name: "conversation_id", type: "string", isIndexed: true },
@@ -26997,7 +27158,7 @@ var sdkSchema = (0, import_watermelondb22.appSchema)({
26997
27158
  ]
26998
27159
  }),
26999
27160
  // Media library storage (images, videos, audio, documents)
27000
- (0, import_watermelondb22.tableSchema)({
27161
+ (0, import_watermelondb23.tableSchema)({
27001
27162
  name: "media",
27002
27163
  columns: [
27003
27164
  // Identity
@@ -27033,7 +27194,7 @@ var sdkSchema = (0, import_watermelondb22.appSchema)({
27033
27194
  ]
27034
27195
  }),
27035
27196
  // ── App files ─────────────────────────────────────────────────────────
27036
- (0, import_watermelondb22.tableSchema)({
27197
+ (0, import_watermelondb23.tableSchema)({
27037
27198
  name: "app_files",
27038
27199
  columns: [
27039
27200
  { name: "conversation_id", type: "string", isIndexed: true },
@@ -27044,7 +27205,7 @@ var sdkSchema = (0, import_watermelondb22.appSchema)({
27044
27205
  ]
27045
27206
  }),
27046
27207
  // ── Saved tools ──────────────────────────────────────────────────────
27047
- (0, import_watermelondb22.tableSchema)({
27208
+ (0, import_watermelondb23.tableSchema)({
27048
27209
  name: "saved_tools",
27049
27210
  columns: [
27050
27211
  { name: "name", type: "string" },
@@ -27060,7 +27221,7 @@ var sdkSchema = (0, import_watermelondb22.appSchema)({
27060
27221
  ]
27061
27222
  }),
27062
27223
  // ── Conversation memories (panel persistence) ────────────────────────
27063
- (0, import_watermelondb22.tableSchema)({
27224
+ (0, import_watermelondb23.tableSchema)({
27064
27225
  name: "conversation_memory",
27065
27226
  columns: [
27066
27227
  { name: "conversation_id", type: "string", isIndexed: true },
@@ -27782,7 +27943,7 @@ var sdkModelClasses = [
27782
27943
  ];
27783
27944
 
27784
27945
  // src/lib/db/manager.ts
27785
- var import_watermelondb23 = require("@nozbe/watermelondb");
27946
+ var import_watermelondb24 = require("@nozbe/watermelondb");
27786
27947
  var DESTRUCTIVE_MIGRATION_VERSION = 8;
27787
27948
  var webPlatformStorage = {
27788
27949
  getItem: (key) => localStorage.getItem(key),
@@ -27863,7 +28024,7 @@ var DatabaseManager = class {
27863
28024
  walletAddress
27864
28025
  });
27865
28026
  const adapter = this.createAdapter(dbName, sdkSchema, sdkMigrations);
27866
- const database = new import_watermelondb23.Database({
28027
+ const database = new import_watermelondb24.Database({
27867
28028
  adapter,
27868
28029
  modelClasses: sdkModelClasses
27869
28030
  });
@@ -27948,7 +28109,7 @@ function useDatabaseManager(walletAddress, manager) {
27948
28109
  }
27949
28110
 
27950
28111
  // src/lib/db/project/operations.ts
27951
- var import_watermelondb24 = require("@nozbe/watermelondb");
28112
+ var import_watermelondb25 = require("@nozbe/watermelondb");
27952
28113
 
27953
28114
  // src/lib/db/project/types.ts
27954
28115
  function generateProjectId() {
@@ -27979,15 +28140,15 @@ async function createProjectOp(ctx, opts, defaultName = "New Project") {
27979
28140
  return projectToStored(created);
27980
28141
  }
27981
28142
  async function getProjectOp(ctx, id) {
27982
- const results = await ctx.projectsCollection.query(import_watermelondb24.Q.where("project_id", id), import_watermelondb24.Q.where("is_deleted", false)).fetch();
28143
+ const results = await ctx.projectsCollection.query(import_watermelondb25.Q.where("project_id", id), import_watermelondb25.Q.where("is_deleted", false)).fetch();
27983
28144
  return results.length > 0 ? projectToStored(results[0]) : null;
27984
28145
  }
27985
28146
  async function getProjectsOp(ctx) {
27986
- const results = await ctx.projectsCollection.query(import_watermelondb24.Q.where("is_deleted", false), import_watermelondb24.Q.sortBy("created_at", import_watermelondb24.Q.desc)).fetch();
28147
+ const results = await ctx.projectsCollection.query(import_watermelondb25.Q.where("is_deleted", false), import_watermelondb25.Q.sortBy("created_at", import_watermelondb25.Q.desc)).fetch();
27987
28148
  return results.map(projectToStored);
27988
28149
  }
27989
28150
  async function updateProjectNameOp(ctx, id, name) {
27990
- const results = await ctx.projectsCollection.query(import_watermelondb24.Q.where("project_id", id), import_watermelondb24.Q.where("is_deleted", false)).fetch();
28151
+ const results = await ctx.projectsCollection.query(import_watermelondb25.Q.where("project_id", id), import_watermelondb25.Q.where("is_deleted", false)).fetch();
27991
28152
  if (results.length > 0) {
27992
28153
  await ctx.database.write(async () => {
27993
28154
  await results[0].update((proj) => {
@@ -27999,7 +28160,7 @@ async function updateProjectNameOp(ctx, id, name) {
27999
28160
  return false;
28000
28161
  }
28001
28162
  async function updateProjectOp(ctx, id, opts) {
28002
- const results = await ctx.projectsCollection.query(import_watermelondb24.Q.where("project_id", id), import_watermelondb24.Q.where("is_deleted", false)).fetch();
28163
+ const results = await ctx.projectsCollection.query(import_watermelondb25.Q.where("project_id", id), import_watermelondb25.Q.where("is_deleted", false)).fetch();
28003
28164
  if (results.length > 0) {
28004
28165
  await ctx.database.write(async () => {
28005
28166
  await results[0].update((proj) => {
@@ -28011,7 +28172,7 @@ async function updateProjectOp(ctx, id, opts) {
28011
28172
  return false;
28012
28173
  }
28013
28174
  async function deleteProjectOp(ctx, id) {
28014
- const results = await ctx.projectsCollection.query(import_watermelondb24.Q.where("project_id", id), import_watermelondb24.Q.where("is_deleted", false)).fetch();
28175
+ const results = await ctx.projectsCollection.query(import_watermelondb25.Q.where("project_id", id), import_watermelondb25.Q.where("is_deleted", false)).fetch();
28015
28176
  if (results.length > 0) {
28016
28177
  await ctx.database.write(async () => {
28017
28178
  await results[0].update((proj) => {
@@ -28024,18 +28185,18 @@ async function deleteProjectOp(ctx, id) {
28024
28185
  }
28025
28186
  async function getProjectConversationsOp(ctx, projectId) {
28026
28187
  const results = await ctx.conversationsCollection.query(
28027
- import_watermelondb24.Q.where("project_id", projectId),
28028
- import_watermelondb24.Q.where("is_deleted", false),
28029
- import_watermelondb24.Q.sortBy("created_at", import_watermelondb24.Q.desc)
28188
+ import_watermelondb25.Q.where("project_id", projectId),
28189
+ import_watermelondb25.Q.where("is_deleted", false),
28190
+ import_watermelondb25.Q.sortBy("created_at", import_watermelondb25.Q.desc)
28030
28191
  ).fetch();
28031
28192
  return results.map(conversationToStoredRaw);
28032
28193
  }
28033
28194
  async function getProjectConversationCountOp(ctx, projectId) {
28034
- return await ctx.conversationsCollection.query(import_watermelondb24.Q.where("project_id", projectId), import_watermelondb24.Q.where("is_deleted", false)).fetchCount();
28195
+ return await ctx.conversationsCollection.query(import_watermelondb25.Q.where("project_id", projectId), import_watermelondb25.Q.where("is_deleted", false)).fetchCount();
28035
28196
  }
28036
28197
 
28037
28198
  // src/react/useFiles.ts
28038
- var import_watermelondb25 = require("@nozbe/watermelondb");
28199
+ var import_watermelondb26 = require("@nozbe/watermelondb");
28039
28200
  var import_react7 = require("react");
28040
28201
  init_logger();
28041
28202
  function useFiles(options) {
@@ -28054,7 +28215,7 @@ function useFiles(options) {
28054
28215
  setIsLoading(true);
28055
28216
  try {
28056
28217
  const coll = database.get("media");
28057
- await coll.query(import_watermelondb25.Q.take(1)).fetch();
28218
+ await coll.query(import_watermelondb26.Q.take(1)).fetch();
28058
28219
  setMediaCollection(coll);
28059
28220
  setIsReady(true);
28060
28221
  } catch (error) {
@@ -28462,7 +28623,7 @@ function useFiles(options) {
28462
28623
  }
28463
28624
 
28464
28625
  // src/react/useProjects.ts
28465
- var import_watermelondb26 = require("@nozbe/watermelondb");
28626
+ var import_watermelondb27 = require("@nozbe/watermelondb");
28466
28627
  var import_react8 = require("react");
28467
28628
  init_logger();
28468
28629
  function useProjects(options) {
@@ -28485,7 +28646,7 @@ function useProjects(options) {
28485
28646
  conversations: convColl?.table
28486
28647
  });
28487
28648
  getLogger().debug("[useProjects] Running test query on projects table...");
28488
- const testResult = await projColl.query(import_watermelondb26.Q.take(1)).fetch();
28649
+ const testResult = await projColl.query(import_watermelondb27.Q.take(1)).fetch();
28489
28650
  getLogger().debug(
28490
28651
  "[useProjects] Test query succeeded, found",
28491
28652
  testResult.length,
@@ -28572,7 +28733,7 @@ function useProjects(options) {
28572
28733
  if (!projectsCollection) {
28573
28734
  return;
28574
28735
  }
28575
- const subscription = projectsCollection.query(import_watermelondb26.Q.where("is_deleted", false)).observe().subscribe((records) => {
28736
+ const subscription = projectsCollection.query(import_watermelondb27.Q.where("is_deleted", false)).observe().subscribe((records) => {
28576
28737
  setProjects(records.map(projectToStored));
28577
28738
  });
28578
28739
  return () => subscription.unsubscribe();
@@ -28695,7 +28856,7 @@ function useProjects(options) {
28695
28856
  }
28696
28857
 
28697
28858
  // src/lib/db/settings/operations.ts
28698
- var import_watermelondb27 = require("@nozbe/watermelondb");
28859
+ var import_watermelondb28 = require("@nozbe/watermelondb");
28699
28860
  function modelPreferenceToStored(preference) {
28700
28861
  return {
28701
28862
  uniqueId: preference.id,
@@ -28704,12 +28865,12 @@ function modelPreferenceToStored(preference) {
28704
28865
  };
28705
28866
  }
28706
28867
  async function getModelPreferenceOp(ctx, walletAddress) {
28707
- const results = await ctx.modelPreferencesCollection.query(import_watermelondb27.Q.where("wallet_address", walletAddress)).fetch();
28868
+ const results = await ctx.modelPreferencesCollection.query(import_watermelondb28.Q.where("wallet_address", walletAddress)).fetch();
28708
28869
  return results.length > 0 ? modelPreferenceToStored(results[0]) : null;
28709
28870
  }
28710
28871
  async function setModelPreferenceOp(ctx, walletAddress, models) {
28711
28872
  const result = await ctx.database.write(async () => {
28712
- const results = await ctx.modelPreferencesCollection.query(import_watermelondb27.Q.where("wallet_address", walletAddress)).fetch();
28873
+ const results = await ctx.modelPreferencesCollection.query(import_watermelondb28.Q.where("wallet_address", walletAddress)).fetch();
28713
28874
  if (results.length > 0) {
28714
28875
  const preference = results[0];
28715
28876
  await preference.update((pref) => {
@@ -28727,7 +28888,7 @@ async function setModelPreferenceOp(ctx, walletAddress, models) {
28727
28888
  return modelPreferenceToStored(result);
28728
28889
  }
28729
28890
  async function deleteModelPreferenceOp(ctx, walletAddress) {
28730
- const results = await ctx.modelPreferencesCollection.query(import_watermelondb27.Q.where("wallet_address", walletAddress)).fetch();
28891
+ const results = await ctx.modelPreferencesCollection.query(import_watermelondb28.Q.where("wallet_address", walletAddress)).fetch();
28731
28892
  if (results.length === 0) return false;
28732
28893
  await ctx.database.write(async () => {
28733
28894
  await results[0].destroyPermanently();
@@ -28736,11 +28897,11 @@ async function deleteModelPreferenceOp(ctx, walletAddress) {
28736
28897
  }
28737
28898
 
28738
28899
  // src/lib/db/settings/schema.ts
28739
- var import_watermelondb28 = require("@nozbe/watermelondb");
28740
- var settingsStorageSchema = (0, import_watermelondb28.appSchema)({
28900
+ var import_watermelondb29 = require("@nozbe/watermelondb");
28901
+ var settingsStorageSchema = (0, import_watermelondb29.appSchema)({
28741
28902
  version: 1,
28742
28903
  tables: [
28743
- (0, import_watermelondb28.tableSchema)({
28904
+ (0, import_watermelondb29.tableSchema)({
28744
28905
  name: "modelPreferences",
28745
28906
  columns: [
28746
28907
  { name: "wallet_address", type: "string", isIndexed: true },
@@ -28751,7 +28912,7 @@ var settingsStorageSchema = (0, import_watermelondb28.appSchema)({
28751
28912
  });
28752
28913
 
28753
28914
  // src/lib/db/vaultFolders/operations.ts
28754
- var import_watermelondb29 = require("@nozbe/watermelondb");
28915
+ var import_watermelondb30 = require("@nozbe/watermelondb");
28755
28916
  function folderToStored(folder) {
28756
28917
  return {
28757
28918
  uniqueId: folder.id,
@@ -28776,7 +28937,7 @@ async function createVaultFolderOp(ctx, opts) {
28776
28937
  return folderToStored(created);
28777
28938
  }
28778
28939
  async function getAllVaultFoldersOp(ctx) {
28779
- const results = await ctx.vaultFolderCollection.query(import_watermelondb29.Q.where("is_deleted", false), import_watermelondb29.Q.sortBy("created_at", import_watermelondb29.Q.desc)).fetch();
28940
+ const results = await ctx.vaultFolderCollection.query(import_watermelondb30.Q.where("is_deleted", false), import_watermelondb30.Q.sortBy("created_at", import_watermelondb30.Q.desc)).fetch();
28780
28941
  return results.map(folderToStored);
28781
28942
  }
28782
28943
  async function updateVaultFolderOp(ctx, id, opts) {
@@ -28785,7 +28946,7 @@ async function updateVaultFolderOp(ctx, id, opts) {
28785
28946
  if (record.isDeleted) return null;
28786
28947
  const scopeChanged = opts.scope !== void 0 && opts.scope !== record.scope;
28787
28948
  const updated = await ctx.database.write(async () => {
28788
- const memories = scopeChanged ? await ctx.vaultMemoryCollection.query(import_watermelondb29.Q.where("folder_id", id), import_watermelondb29.Q.where("is_deleted", false)).fetch() : [];
28949
+ const memories = scopeChanged ? await ctx.vaultMemoryCollection.query(import_watermelondb30.Q.where("folder_id", id), import_watermelondb30.Q.where("is_deleted", false)).fetch() : [];
28789
28950
  const updates = [];
28790
28951
  updates.push(
28791
28952
  record.prepareUpdate((r) => {
@@ -28813,7 +28974,7 @@ async function deleteVaultFolderOp(ctx, id) {
28813
28974
  const record = await ctx.vaultFolderCollection.find(id);
28814
28975
  if (record.isDeleted) return false;
28815
28976
  await ctx.database.write(async () => {
28816
- const memories = await ctx.vaultMemoryCollection.query(import_watermelondb29.Q.where("folder_id", id), import_watermelondb29.Q.where("is_deleted", false)).fetch();
28977
+ const memories = await ctx.vaultMemoryCollection.query(import_watermelondb30.Q.where("folder_id", id), import_watermelondb30.Q.where("is_deleted", false)).fetch();
28817
28978
  const preparedMemories = memories.map(
28818
28979
  (memory) => memory.prepareUpdate((r) => {
28819
28980
  r._setRaw("folder_id", null);
@@ -28882,7 +29043,7 @@ async function updateVaultFolderContextOp(ctx, id, context) {
28882
29043
  }
28883
29044
  }
28884
29045
  async function getVaultFolderMemoryCountOp(ctx, folderId) {
28885
- return await ctx.vaultMemoryCollection.query(import_watermelondb29.Q.where("folder_id", folderId), import_watermelondb29.Q.where("is_deleted", false)).fetchCount();
29046
+ return await ctx.vaultMemoryCollection.query(import_watermelondb30.Q.where("folder_id", folderId), import_watermelondb30.Q.where("is_deleted", false)).fetchCount();
28886
29047
  }
28887
29048
 
28888
29049
  // src/lib/db/vaultFolders/defaults.ts
@@ -28928,7 +29089,7 @@ async function _ensureDefaultFoldersImpl(ctx) {
28928
29089
  var import_react9 = require("react");
28929
29090
 
28930
29091
  // src/lib/db/userPreferences/operations.ts
28931
- var import_watermelondb30 = require("@nozbe/watermelondb");
29092
+ var import_watermelondb31 = require("@nozbe/watermelondb");
28932
29093
  function userPreferenceToStored(preference) {
28933
29094
  return {
28934
29095
  uniqueId: preference.id,
@@ -28943,7 +29104,7 @@ function userPreferenceToStored(preference) {
28943
29104
  };
28944
29105
  }
28945
29106
  async function getUserPreferenceOp(ctx, walletAddress) {
28946
- const results = await ctx.userPreferencesCollection.query(import_watermelondb30.Q.where("wallet_address", walletAddress)).fetch();
29107
+ const results = await ctx.userPreferencesCollection.query(import_watermelondb31.Q.where("wallet_address", walletAddress)).fetch();
28947
29108
  return results.length > 0 ? userPreferenceToStored(results[0]) : null;
28948
29109
  }
28949
29110
  async function createUserPreferenceOp(ctx, opts) {
@@ -28963,7 +29124,7 @@ async function createUserPreferenceOp(ctx, opts) {
28963
29124
  return userPreferenceToStored(created);
28964
29125
  }
28965
29126
  async function updateUserPreferenceOp(ctx, walletAddress, opts) {
28966
- const results = await ctx.userPreferencesCollection.query(import_watermelondb30.Q.where("wallet_address", walletAddress)).fetch();
29127
+ const results = await ctx.userPreferencesCollection.query(import_watermelondb31.Q.where("wallet_address", walletAddress)).fetch();
28967
29128
  if (results.length === 0) return null;
28968
29129
  const preference = results[0];
28969
29130
  await ctx.database.write(async () => {
@@ -28991,7 +29152,7 @@ async function updateUserPreferenceOp(ctx, walletAddress, opts) {
28991
29152
  async function setUserPreferenceOp(ctx, walletAddress, opts) {
28992
29153
  const now = Date.now();
28993
29154
  const result = await ctx.database.write(async () => {
28994
- const results = await ctx.userPreferencesCollection.query(import_watermelondb30.Q.where("wallet_address", walletAddress)).fetch();
29155
+ const results = await ctx.userPreferencesCollection.query(import_watermelondb31.Q.where("wallet_address", walletAddress)).fetch();
28995
29156
  if (results.length > 0) {
28996
29157
  const preference = results[0];
28997
29158
  await preference.update((pref) => {
@@ -29039,7 +29200,7 @@ async function updateModelsOp(ctx, walletAddress, models) {
29039
29200
  return updateUserPreferenceOp(ctx, walletAddress, { models });
29040
29201
  }
29041
29202
  async function deleteUserPreferenceOp(ctx, walletAddress) {
29042
- const results = await ctx.userPreferencesCollection.query(import_watermelondb30.Q.where("wallet_address", walletAddress)).fetch();
29203
+ const results = await ctx.userPreferencesCollection.query(import_watermelondb31.Q.where("wallet_address", walletAddress)).fetch();
29043
29204
  if (results.length === 0) return false;
29044
29205
  await ctx.database.write(async () => {
29045
29206
  await results[0].destroyPermanently();
@@ -29054,9 +29215,9 @@ async function migrateFromModelPreferencesOp(ctx, walletAddress) {
29054
29215
  if (existing) {
29055
29216
  return existing;
29056
29217
  }
29057
- const modelResults = await ctx.modelPreferencesCollection.query(import_watermelondb30.Q.where("wallet_address", walletAddress)).fetch();
29218
+ const modelResults = await ctx.modelPreferencesCollection.query(import_watermelondb31.Q.where("wallet_address", walletAddress)).fetch();
29058
29219
  const personalityKey = `${walletAddress}_personality_settings`;
29059
- const personalityResults = await ctx.modelPreferencesCollection.query(import_watermelondb30.Q.where("wallet_address", personalityKey)).fetch();
29220
+ const personalityResults = await ctx.modelPreferencesCollection.query(import_watermelondb31.Q.where("wallet_address", personalityKey)).fetch();
29060
29221
  if (modelResults.length === 0 && personalityResults.length === 0) {
29061
29222
  return null;
29062
29223
  }
@@ -29098,11 +29259,11 @@ async function migrateFromModelPreferencesOp(ctx, walletAddress) {
29098
29259
  }
29099
29260
 
29100
29261
  // src/lib/db/userPreferences/schema.ts
29101
- var import_watermelondb31 = require("@nozbe/watermelondb");
29102
- var userPreferencesStorageSchema = (0, import_watermelondb31.appSchema)({
29262
+ var import_watermelondb32 = require("@nozbe/watermelondb");
29263
+ var userPreferencesStorageSchema = (0, import_watermelondb32.appSchema)({
29103
29264
  version: 1,
29104
29265
  tables: [
29105
- (0, import_watermelondb31.tableSchema)({
29266
+ (0, import_watermelondb32.tableSchema)({
29106
29267
  name: "userPreferences",
29107
29268
  columns: [
29108
29269
  // Identity
@@ -29162,7 +29323,7 @@ var SLIDER_CONFIG = [
29162
29323
  ];
29163
29324
 
29164
29325
  // src/react/userSettingsStore.ts
29165
- var import_watermelondb32 = require("@nozbe/watermelondb");
29326
+ var import_watermelondb33 = require("@nozbe/watermelondb");
29166
29327
  var EMPTY_SNAPSHOT = Object.freeze({
29167
29328
  modelPreference: null,
29168
29329
  userPreference: null,
@@ -29224,7 +29385,7 @@ async function startLoad(entry, walletAddress) {
29224
29385
  }
29225
29386
  function startObserve(entry, walletAddress) {
29226
29387
  let isInitialEmission = true;
29227
- entry.observeSub = entry.storageCtx.userPreferencesCollection.query(import_watermelondb32.Q.where("wallet_address", walletAddress)).observeWithColumns([
29388
+ entry.observeSub = entry.storageCtx.userPreferencesCollection.query(import_watermelondb33.Q.where("wallet_address", walletAddress)).observeWithColumns([
29228
29389
  "nickname",
29229
29390
  "occupation",
29230
29391
  "description",
@@ -29488,7 +29649,7 @@ function useSettings(options) {
29488
29649
  }
29489
29650
 
29490
29651
  // src/lib/db/appFiles/operations.ts
29491
- var import_watermelondb33 = require("@nozbe/watermelondb");
29652
+ var import_watermelondb34 = require("@nozbe/watermelondb");
29492
29653
 
29493
29654
  // src/utils/paths.ts
29494
29655
  function normalizePath(p) {
@@ -29514,7 +29675,7 @@ async function putAppFileOp(ctx, conversationId, path, content) {
29514
29675
  const normalized = normalizePath(path);
29515
29676
  const now = Date.now();
29516
29677
  const result = await ctx.database.write(async () => {
29517
- const existing = await ctx.appFilesCollection.query(import_watermelondb33.Q.where("conversation_id", conversationId), import_watermelondb33.Q.where("path", normalized)).fetch();
29678
+ const existing = await ctx.appFilesCollection.query(import_watermelondb34.Q.where("conversation_id", conversationId), import_watermelondb34.Q.where("path", normalized)).fetch();
29518
29679
  if (existing.length > 0) {
29519
29680
  await existing[0].update((f) => {
29520
29681
  f._setRaw("content", content);
@@ -29534,11 +29695,11 @@ async function putAppFileOp(ctx, conversationId, path, content) {
29534
29695
  }
29535
29696
  async function getAppFileOp(ctx, conversationId, path) {
29536
29697
  const normalized = normalizePath(path);
29537
- const results = await ctx.appFilesCollection.query(import_watermelondb33.Q.where("conversation_id", conversationId), import_watermelondb33.Q.where("path", normalized)).fetch();
29698
+ const results = await ctx.appFilesCollection.query(import_watermelondb34.Q.where("conversation_id", conversationId), import_watermelondb34.Q.where("path", normalized)).fetch();
29538
29699
  return results.length > 0 ? appFileToStored(results[0]) : null;
29539
29700
  }
29540
29701
  async function getAppFilesOp(ctx, conversationId) {
29541
- const results = await ctx.appFilesCollection.query(import_watermelondb33.Q.where("conversation_id", conversationId)).fetch();
29702
+ const results = await ctx.appFilesCollection.query(import_watermelondb34.Q.where("conversation_id", conversationId)).fetch();
29542
29703
  return results.map(appFileToStored);
29543
29704
  }
29544
29705
  async function getAppFileMapOp(ctx, conversationId) {
@@ -29549,7 +29710,7 @@ async function getAppFileMapOp(ctx, conversationId) {
29549
29710
  }
29550
29711
  async function deleteAppFileOp(ctx, conversationId, path) {
29551
29712
  const normalized = normalizePath(path);
29552
- const results = await ctx.appFilesCollection.query(import_watermelondb33.Q.where("conversation_id", conversationId), import_watermelondb33.Q.where("path", normalized)).fetch();
29713
+ const results = await ctx.appFilesCollection.query(import_watermelondb34.Q.where("conversation_id", conversationId), import_watermelondb34.Q.where("path", normalized)).fetch();
29553
29714
  if (results.length === 0) return false;
29554
29715
  await ctx.database.write(async () => {
29555
29716
  await results[0].destroyPermanently();
@@ -29557,7 +29718,7 @@ async function deleteAppFileOp(ctx, conversationId, path) {
29557
29718
  return true;
29558
29719
  }
29559
29720
  async function deleteAllAppFilesOp(ctx, conversationId) {
29560
- const results = await ctx.appFilesCollection.query(import_watermelondb33.Q.where("conversation_id", conversationId)).fetch();
29721
+ const results = await ctx.appFilesCollection.query(import_watermelondb34.Q.where("conversation_id", conversationId)).fetch();
29561
29722
  if (results.length === 0) return;
29562
29723
  await ctx.database.write(async () => {
29563
29724
  const batch = results.map((file) => file.prepareDestroyPermanently());
@@ -29566,7 +29727,7 @@ async function deleteAllAppFilesOp(ctx, conversationId) {
29566
29727
  }
29567
29728
 
29568
29729
  // src/lib/db/conversationMemory/operations.ts
29569
- var import_watermelondb34 = require("@nozbe/watermelondb");
29730
+ var import_watermelondb35 = require("@nozbe/watermelondb");
29570
29731
  var MAX_PER_CONVERSATION = 200;
29571
29732
  function conversationMemoryToStored(row) {
29572
29733
  return {
@@ -29581,7 +29742,7 @@ async function addConversationMemoriesOp(ctx, conversationId, items) {
29581
29742
  if (!conversationId || items.length === 0) return;
29582
29743
  const now = Date.now();
29583
29744
  await ctx.database.write(async () => {
29584
- const existing = await ctx.conversationMemoryCollection.query(import_watermelondb34.Q.where("conversation_id", conversationId), import_watermelondb34.Q.sortBy("created_at", import_watermelondb34.Q.asc)).fetch();
29745
+ const existing = await ctx.conversationMemoryCollection.query(import_watermelondb35.Q.where("conversation_id", conversationId), import_watermelondb35.Q.sortBy("created_at", import_watermelondb35.Q.asc)).fetch();
29585
29746
  const seen = new Set(existing.map((r) => r.memoryId));
29586
29747
  const batchSeen = /* @__PURE__ */ new Set();
29587
29748
  const deduped = [];
@@ -29616,20 +29777,20 @@ async function addConversationMemoriesOp(ctx, conversationId, items) {
29616
29777
  }
29617
29778
  async function getConversationMemoriesOp(ctx, conversationId) {
29618
29779
  if (!conversationId) return [];
29619
- const rows = await ctx.conversationMemoryCollection.query(import_watermelondb34.Q.where("conversation_id", conversationId), import_watermelondb34.Q.sortBy("created_at", import_watermelondb34.Q.asc)).fetch();
29780
+ const rows = await ctx.conversationMemoryCollection.query(import_watermelondb35.Q.where("conversation_id", conversationId), import_watermelondb35.Q.sortBy("created_at", import_watermelondb35.Q.asc)).fetch();
29620
29781
  return rows.map(conversationMemoryToStored);
29621
29782
  }
29622
29783
  async function clearConversationMemoriesOp(ctx, conversationId) {
29623
29784
  if (!conversationId) return;
29624
29785
  await ctx.database.write(async () => {
29625
- const rows = await ctx.conversationMemoryCollection.query(import_watermelondb34.Q.where("conversation_id", conversationId)).fetch();
29786
+ const rows = await ctx.conversationMemoryCollection.query(import_watermelondb35.Q.where("conversation_id", conversationId)).fetch();
29626
29787
  if (rows.length === 0) return;
29627
29788
  await ctx.database.batch(...rows.map((r) => r.prepareDestroyPermanently()));
29628
29789
  });
29629
29790
  }
29630
29791
 
29631
29792
  // src/lib/db/savedTools/operations.ts
29632
- var import_watermelondb35 = require("@nozbe/watermelondb");
29793
+ var import_watermelondb36 = require("@nozbe/watermelondb");
29633
29794
  function savedToolToStored(tool) {
29634
29795
  return {
29635
29796
  uniqueId: tool.id,
@@ -29662,7 +29823,7 @@ async function createSavedToolOp(ctx, opts) {
29662
29823
  return savedToolToStored(created);
29663
29824
  }
29664
29825
  async function getAllSavedToolsOp(ctx) {
29665
- const results = await ctx.savedToolsCollection.query(import_watermelondb35.Q.where("is_deleted", false), import_watermelondb35.Q.sortBy("created_at", import_watermelondb35.Q.desc)).fetch();
29826
+ const results = await ctx.savedToolsCollection.query(import_watermelondb36.Q.where("is_deleted", false), import_watermelondb36.Q.sortBy("created_at", import_watermelondb36.Q.desc)).fetch();
29666
29827
  return results.map(savedToolToStored);
29667
29828
  }
29668
29829
  async function getSavedToolByIdOp(ctx, uniqueId) {
@@ -32323,8 +32484,8 @@ function createDropboxFileIndex(backupFolder) {
32323
32484
  };
32324
32485
  }
32325
32486
  async function readLocalUpdatedAt(database, conversationId) {
32326
- const { Q: Q19 } = await import("@nozbe/watermelondb");
32327
- const records = await database.get("conversations").query(Q19.where("conversation_id", conversationId)).fetch();
32487
+ const { Q: Q20 } = await import("@nozbe/watermelondb");
32488
+ const records = await database.get("conversations").query(Q20.where("conversation_id", conversationId)).fetch();
32328
32489
  const match = records.map(conversationToStoredRaw).find((c) => c.conversationId === conversationId);
32329
32490
  return match ? match.updatedAt : null;
32330
32491
  }
@@ -32380,9 +32541,9 @@ async function pushConversationToDropbox(database, conversationId, userAddress,
32380
32541
  }
32381
32542
  async function performDropboxExport(database, userAddress, token, deps, onProgress, backupFolder = DEFAULT_BACKUP_FOLDER) {
32382
32543
  await deps.requestEncryptionKey(userAddress);
32383
- const { Q: Q19 } = await import("@nozbe/watermelondb");
32544
+ const { Q: Q20 } = await import("@nozbe/watermelondb");
32384
32545
  const conversationsCollection = database.get("conversations");
32385
- const records = await conversationsCollection.query(Q19.where("is_deleted", false)).fetch();
32546
+ const records = await conversationsCollection.query(Q20.where("is_deleted", false)).fetch();
32386
32547
  const conversations = records.map(conversationToStoredRaw);
32387
32548
  const total = conversations.length;
32388
32549
  if (total === 0) {
@@ -33059,8 +33220,8 @@ function createDriveFileIndex(folderId) {
33059
33220
  };
33060
33221
  }
33061
33222
  async function readLocalUpdatedAt2(database, conversationId) {
33062
- const { Q: Q19 } = await import("@nozbe/watermelondb");
33063
- const records = await database.get("conversations").query(Q19.where("conversation_id", conversationId)).fetch();
33223
+ const { Q: Q20 } = await import("@nozbe/watermelondb");
33224
+ const records = await database.get("conversations").query(Q20.where("conversation_id", conversationId)).fetch();
33064
33225
  const match = records.map(conversationToStoredRaw).find((c) => c.conversationId === conversationId);
33065
33226
  return match ? match.updatedAt : null;
33066
33227
  }
@@ -33140,9 +33301,9 @@ async function performGoogleDriveExport(database, userAddress, token, deps, onPr
33140
33301
  }
33141
33302
  const { folderId, token: activeToken } = folderResult;
33142
33303
  const fileIndex = createDriveFileIndex(folderId);
33143
- const { Q: Q19 } = await import("@nozbe/watermelondb");
33304
+ const { Q: Q20 } = await import("@nozbe/watermelondb");
33144
33305
  const conversationsCollection = database.get("conversations");
33145
- const records = await conversationsCollection.query(Q19.where("is_deleted", false)).fetch();
33306
+ const records = await conversationsCollection.query(Q20.where("is_deleted", false)).fetch();
33146
33307
  const conversations = records.map(conversationToStoredRaw);
33147
33308
  const total = conversations.length;
33148
33309
  if (total === 0) {
@@ -33722,9 +33883,9 @@ async function pushConversationToICloud(database, conversationId, userAddress, d
33722
33883
  const filename = `${conversationId}.json`;
33723
33884
  const existingFile = await findICloudFile(filename);
33724
33885
  if (existingFile) {
33725
- const { Q: Q19 } = await import("@nozbe/watermelondb");
33886
+ const { Q: Q20 } = await import("@nozbe/watermelondb");
33726
33887
  const conversationsCollection = database.get("conversations");
33727
- const records = await conversationsCollection.query(Q19.where("conversation_id", conversationId)).fetch();
33888
+ const records = await conversationsCollection.query(Q20.where("conversation_id", conversationId)).fetch();
33728
33889
  if (records.length > 0) {
33729
33890
  const conversation = conversationToStoredRaw(records[0]);
33730
33891
  const localUpdated = conversation.updatedAt.getTime();
@@ -33754,9 +33915,9 @@ async function pushConversationToICloud(database, conversationId, userAddress, d
33754
33915
  }
33755
33916
  async function performICloudExport(database, userAddress, deps, onProgress) {
33756
33917
  await deps.requestEncryptionKey(userAddress);
33757
- const { Q: Q19 } = await import("@nozbe/watermelondb");
33918
+ const { Q: Q20 } = await import("@nozbe/watermelondb");
33758
33919
  const conversationsCollection = database.get("conversations");
33759
- const records = await conversationsCollection.query(Q19.where("is_deleted", false)).fetch();
33920
+ const records = await conversationsCollection.query(Q20.where("is_deleted", false)).fetch();
33760
33921
  const conversations = records.map(conversationToStoredRaw);
33761
33922
  const total = conversations.length;
33762
33923
  if (total === 0) {
@@ -37731,6 +37892,7 @@ function renderAnumaJsx(jsx3) {
37731
37892
  createGitHubTools,
37732
37893
  createLlmDecayClassifier,
37733
37894
  createLlmNeighborRefiner,
37895
+ createLocalMemoryStore,
37734
37896
  createMediaBatchOp,
37735
37897
  createMediaOp,
37736
37898
  createMemoryEngineTool,