@anuma/sdk 6.21.1 → 6.23.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.
Files changed (32) hide show
  1. package/dist/expo/{chunk-CIMZZ7GQ.mjs → chunk-6BULYLRY.mjs} +92 -8
  2. package/dist/expo/index.cjs +761 -162
  3. package/dist/expo/index.d.mts +151 -9
  4. package/dist/expo/index.d.ts +151 -9
  5. package/dist/expo/index.mjs +516 -14
  6. package/dist/{react/recall-7Q3V337H.mjs → expo/recall-CUTJWQDQ.mjs} +1 -1
  7. package/dist/memory/context.cjs +183 -0
  8. package/dist/memory/context.d.mts +936 -0
  9. package/dist/memory/context.d.ts +936 -0
  10. package/dist/memory/context.mjs +157 -0
  11. package/dist/react/{chunk-AVYB5IXC.mjs → chunk-GPLMMMZN.mjs} +1 -1
  12. package/dist/react/{chunk-JRVAUZHM.mjs → chunk-K4N52PSK.mjs} +93 -9
  13. package/dist/react/{consolidate-URHGJT7I.mjs → consolidate-XKS6IZFC.mjs} +2 -2
  14. package/dist/react/index.cjs +876 -270
  15. package/dist/react/index.d.mts +209 -9
  16. package/dist/react/index.d.ts +209 -9
  17. package/dist/react/index.mjs +569 -65
  18. package/dist/{expo/recall-FQQGE6A2.mjs → react/recall-LFHIWONV.mjs} +2 -2
  19. package/dist/server/{chunk-4DSDATYG.mjs → chunk-FEDRFVHD.mjs} +182 -98
  20. package/dist/server/index.cjs +815 -216
  21. package/dist/server/index.d.mts +150 -5
  22. package/dist/server/index.d.ts +150 -5
  23. package/dist/server/index.mjs +509 -7
  24. package/dist/server/{recall-HA4UX4BB.mjs → recall-Z2WJGXOL.mjs} +1 -1
  25. package/dist/telemetry/index.d.mts +7 -1
  26. package/dist/telemetry/index.d.ts +7 -1
  27. package/dist/tools/index.cjs +347 -1
  28. package/dist/tools/index.d.mts +167 -1
  29. package/dist/tools/index.d.ts +167 -1
  30. package/dist/tools/index.mjs +343 -1
  31. package/package.json +8 -1
  32. package/dist/react/{chunk-WUG6GTHO.mjs → chunk-MHZB6KIX.mjs} +8 -8
@@ -11,6 +11,7 @@ import {
11
11
  ENTITY_FANOUT,
12
12
  ENTITY_KINDS,
13
13
  EncryptionKeyMissingError,
14
+ ExtractionJob,
14
15
  LRUCache,
15
16
  MAX_HOPS,
16
17
  NODE_BUDGET,
@@ -65,6 +66,7 @@ import {
65
66
  deleteAllVaultMemoriesForUserOp,
66
67
  deleteApiV1WalletsBindingByAddress,
67
68
  deleteConversationOp,
69
+ deleteMessageOp,
68
70
  deleteVaultMemoryOp,
69
71
  eagerEmbedContent,
70
72
  embedAllMessages,
@@ -179,14 +181,14 @@ import {
179
181
  updateVaultMemoryOp,
180
182
  useEncryption,
181
183
  vaultMemoryToStored
182
- } from "./chunk-JRVAUZHM.mjs";
184
+ } from "./chunk-K4N52PSK.mjs";
183
185
  import {
184
186
  PiiRedactor,
185
187
  createStreamingDeAnonymizer,
186
188
  isPiiRedactor,
187
189
  notifyConsolidationFallback,
188
190
  resolvePiiRedactor
189
- } from "./chunk-AVYB5IXC.mjs";
191
+ } from "./chunk-GPLMMMZN.mjs";
190
192
  import {
191
193
  INTERNAL_FLOW_MARKER,
192
194
  callPortalJsonCompletion,
@@ -202,7 +204,7 @@ import {
202
204
  taskTypeHeader,
203
205
  validateEndpointOverride,
204
206
  withInternalFlowMarker
205
- } from "./chunk-WUG6GTHO.mjs";
207
+ } from "./chunk-MHZB6KIX.mjs";
206
208
  import {
207
209
  BASE_URL,
208
210
  MCP_R2_DOMAIN,
@@ -6959,7 +6961,8 @@ function classifyDecay(m, now, policy) {
6959
6961
  if (m.eventTimeEnd < now - resolved.pastEventGraceMs) return "archive";
6960
6962
  if (m.eventTimeEnd >= now) return "keep";
6961
6963
  }
6962
- if (now - m.updatedAt > ttlForType(m.factType, resolved)) return "archive";
6964
+ const observedAt = Number.isFinite(m.lastObservedAt) ? m.lastObservedAt : m.updatedAt;
6965
+ if (now - Math.max(m.updatedAt, observedAt) > ttlForType(m.factType, resolved)) return "archive";
6963
6966
  return "keep";
6964
6967
  }
6965
6968
 
@@ -7525,6 +7528,7 @@ async function retain(content, ctx, options = {}) {
7525
7528
  const updated = await updateVaultMemoryOp(ctx.vaultCtx, targetId, {
7526
7529
  content: existing.content,
7527
7530
  proofCountIncrement: 1,
7531
+ observationSourceIds: options.sourceChunkIds,
7528
7532
  sourceChunkIds: mergedSourceIds,
7529
7533
  // resurrect encodes the decay gate: ACTIVE target → { preserveUpdatedAt:
7530
7534
  // true } (main's normal re-observation path — bump proof_count without
@@ -7731,7 +7735,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
7731
7735
  content: m.content,
7732
7736
  similarity: m.similarity
7733
7737
  }));
7734
- const { consolidateMemory: doConsolidate } = await import("./consolidate-URHGJT7I.mjs");
7738
+ const { consolidateMemory: doConsolidate } = await import("./consolidate-XKS6IZFC.mjs");
7735
7739
  const decision = await doConsolidate(trimmed, candidates, consolidateOptions);
7736
7740
  if (decision.action === "create") return decision.fallbackReason ? null : { create: true };
7737
7741
  if (decision.action === "supersede" && decision.content) {
@@ -7768,6 +7772,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
7768
7772
  const updated = await updateVaultMemoryOp(ctx.vaultCtx, decision.targetId, {
7769
7773
  content: existing.content,
7770
7774
  proofCountIncrement: 1,
7775
+ observationSourceIds: options.sourceChunkIds,
7771
7776
  sourceChunkIds: mergedSourceIds,
7772
7777
  // ACTIVE target → { preserveUpdatedAt: true } (main's normal re-observation
7773
7778
  // path); ARCHIVED (non-superseded, non-deleted) → { restore: true } and no
@@ -7817,6 +7822,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
7817
7822
  const updated = await updateVaultMemoryOp(ctx.vaultCtx, decision.targetId, {
7818
7823
  content: decision.content,
7819
7824
  proofCountIncrement: 1,
7825
+ observationSourceIds: options.sourceChunkIds,
7820
7826
  sourceChunkIds: mergedSourceIds,
7821
7827
  embedding: JSON.stringify(newEmbedding),
7822
7828
  embeddingModel: consolidatedModel,
@@ -8453,7 +8459,7 @@ function createAutoExtractor(options) {
8453
8459
  onQuarantined: (info) => options.onMemoryQuarantined?.({ ...info, conversationId })
8454
8460
  }
8455
8461
  });
8456
- if (outcome !== "empty-after-retry") {
8462
+ if (outcome !== "empty-after-retry" && failedCount === 0) {
8457
8463
  const advancedTo = window2[window2.length - 1].id;
8458
8464
  stateFor(conversationId).watermark = advancedTo;
8459
8465
  persistCursor(conversationId, messages, advancedTo, contiguous);
@@ -8608,6 +8614,7 @@ function toDecayInput(c) {
8608
8614
  eventTimeEnd: c.eventTimeEnd,
8609
8615
  eventTimeKind: c.eventTimeKind,
8610
8616
  updatedAt: c.updatedAt,
8617
+ lastObservedAt: c.lastObservedAt,
8611
8618
  archivedAt: c.archivedAt,
8612
8619
  source: c.source,
8613
8620
  trustTier: c.trustTier
@@ -8689,7 +8696,8 @@ function createDecaySweeper(options) {
8689
8696
  for (const c of toArchive) {
8690
8697
  const ok = await archiveVaultMemoryOp(vaultCtx, c.uniqueId, {
8691
8698
  now,
8692
- expectedUpdatedAt: c.updatedAt
8699
+ expectedUpdatedAt: c.updatedAt,
8700
+ expectedLastObservedAt: c.lastObservedAt ?? null
8693
8701
  });
8694
8702
  if (ok) archived++;
8695
8703
  }
@@ -8934,6 +8942,7 @@ function createRecallTool(ctx, toolOptions, callbacks) {
8934
8942
  budget: defaultBudget,
8935
8943
  ...toolOptions?.minScore !== void 0 && { minScore: toolOptions.minScore },
8936
8944
  ...toolOptions?.scopes && { scopes: toolOptions.scopes },
8945
+ ...toolOptions?.memoryIds !== void 0 && { memoryIds: toolOptions.memoryIds },
8937
8946
  ...toolOptions?.folderId !== void 0 && { folderId: toolOptions.folderId },
8938
8947
  ...toolOptions?.excludeConversationId && {
8939
8948
  excludeConversationId: toolOptions.excludeConversationId
@@ -10123,6 +10132,462 @@ function createMessageSourceResolver(ctx) {
10123
10132
  };
10124
10133
  }
10125
10134
 
10135
+ // src/lib/memory/context.ts
10136
+ function shouldRecallMemory(query) {
10137
+ const normalized = query.trim().toLowerCase().replace(/[.!?。!?¡¿]+$/u, "").replace(/^[¡¿]+/u, "");
10138
+ return normalized.length > 0 && !/^(hi|hi there|hello|hey|yes|no|yep|nope|sure|k|ok|okay|thanks|thank you|thank you very much|thanks a lot|cool|great|got it|sounds good|hola|buenos días|buenas|sí|si|gracias|muchas gracias|vale|bonjour|salut|oui|non|merci|merci beaucoup|d'accord|hallo|guten tag|ja|nein|danke|danke schön|alles klar|olá|obrigado|obrigada|ciao|grazie|sì|你好|谢谢|好的|こんにちは|ありがとう|안녕하세요|감사합니다)$/u.test(
10139
+ normalized
10140
+ );
10141
+ }
10142
+ async function assembleMemoryContext(options) {
10143
+ const { query, recall: recall2, loadFacts, loadSessionRefs } = options;
10144
+ const memoryIds = options.memoryIds ?? options.recallOptions?.memoryIds;
10145
+ const ranked = shouldRecallMemory(query);
10146
+ const degraded = [];
10147
+ const guard = async (lane, run, fallback) => {
10148
+ try {
10149
+ return await run();
10150
+ } catch (error) {
10151
+ degraded.push(lane);
10152
+ try {
10153
+ options.onDegraded?.(lane, error);
10154
+ } catch {
10155
+ }
10156
+ return fallback;
10157
+ }
10158
+ };
10159
+ const scoped = memoryIds !== void 0 || options.recallOptions?.scopes !== void 0 || options.recallOptions?.folderId !== void 0;
10160
+ const allowed = memoryIds !== void 0 ? new Set(memoryIds) : void 0;
10161
+ const filters = {
10162
+ ...options.recallOptions?.scopes && { scopes: options.recallOptions.scopes },
10163
+ ...options.recallOptions?.folderId !== void 0 && {
10164
+ folderId: options.recallOptions.folderId
10165
+ }
10166
+ };
10167
+ const active = (m) => !m.isDeleted && !m.archivedAt && !m.supersededBy && m.trustTier !== "quarantined" && (!allowed || allowed.has(m.uniqueId));
10168
+ const asItem = (m, lane, score = 1) => ({
10169
+ id: m.uniqueId,
10170
+ content: m.content,
10171
+ score,
10172
+ lane,
10173
+ sourceIds: m.sourceChunkIds ?? []
10174
+ });
10175
+ const empty = {
10176
+ memories: [],
10177
+ usedBudget: options.recallOptions?.budget ?? "low",
10178
+ reranked: false,
10179
+ candidateCount: 0
10180
+ };
10181
+ const [facts, episodes, profile, session] = await Promise.all([
10182
+ ranked ? guard(
10183
+ "fact",
10184
+ () => recall2(query, { ...options.recallOptions, types: ["fact"], limit: 20, memoryIds }),
10185
+ empty
10186
+ ) : empty,
10187
+ ranked && !scoped && options.includeEpisodes !== false ? guard(
10188
+ "episode",
10189
+ () => recall2(query, {
10190
+ ...options.recallOptions,
10191
+ types: ["chunk"],
10192
+ limit: 4,
10193
+ minScore: 0.5,
10194
+ onDiagnostics: void 0
10195
+ }),
10196
+ empty
10197
+ ) : empty,
10198
+ loadFacts ? guard(
10199
+ "profile",
10200
+ async () => {
10201
+ const stable = await loadFacts({
10202
+ ...filters,
10203
+ memoryIds,
10204
+ factTypes: ["identity", "preference", "constraint", "relationship"],
10205
+ limit: 8
10206
+ });
10207
+ const dynamic = await loadFacts({
10208
+ ...filters,
10209
+ memoryIds,
10210
+ factTypes: ["ongoing_context", "plan"],
10211
+ limit: 4
10212
+ });
10213
+ return [...stable, ...dynamic].filter(active).map((m) => asItem(m, "profile"));
10214
+ },
10215
+ []
10216
+ ) : [],
10217
+ loadFacts && loadSessionRefs ? guard(
10218
+ "session",
10219
+ async () => {
10220
+ const refs = (await loadSessionRefs()).filter((r) => !allowed || allowed.has(r.memoryId)).sort((a, b) => b.score - a.score).slice(0, 10);
10221
+ if (!refs.length) return [];
10222
+ const rows = await loadFacts({ ...filters, memoryIds: refs.map((r) => r.memoryId) });
10223
+ const byId = new Map(rows.filter(active).map((m) => [m.uniqueId, m]));
10224
+ return refs.flatMap((ref) => {
10225
+ const m = byId.get(ref.memoryId);
10226
+ return m ? [asItem(m, "session", ref.score)] : [];
10227
+ });
10228
+ },
10229
+ []
10230
+ ) : []
10231
+ ]);
10232
+ const toItems = (result, lane) => result.memories.filter((m) => !allowed || allowed.has(m.id)).map((m) => ({
10233
+ id: m.id,
10234
+ content: m.content,
10235
+ score: m.score,
10236
+ lane,
10237
+ ...lane === "fact" && { recalled: true },
10238
+ sourceIds: m.sourceChunkIds ?? (m.messageId ? [m.messageId] : [])
10239
+ }));
10240
+ const recalledFacts = toItems(facts, "fact");
10241
+ const recalledScores = /* @__PURE__ */ new Map();
10242
+ const recalledContentScores = /* @__PURE__ */ new Map();
10243
+ for (const item of recalledFacts) {
10244
+ recalledScores.set(item.id, Math.max(recalledScores.get(item.id) ?? -Infinity, item.score));
10245
+ const content = item.content.trim();
10246
+ recalledContentScores.set(
10247
+ content,
10248
+ Math.max(recalledContentScores.get(content) ?? -Infinity, item.score)
10249
+ );
10250
+ }
10251
+ const rankedProfile = profile.map((item) => {
10252
+ const score = Math.max(
10253
+ recalledScores.get(item.id) ?? -Infinity,
10254
+ recalledContentScores.get(item.content.trim()) ?? -Infinity
10255
+ );
10256
+ return score === -Infinity ? item : { ...item, score, recalled: true };
10257
+ });
10258
+ const lanes = [
10259
+ [rankedProfile, 2e3],
10260
+ [recalledFacts, 6e3],
10261
+ [toItems(episodes, "episode"), 3e3],
10262
+ [session, 1e3]
10263
+ ];
10264
+ const items = [];
10265
+ const seenIds = /* @__PURE__ */ new Set();
10266
+ const seenContent = /* @__PURE__ */ new Set();
10267
+ let remaining = Math.max(0, options.maxChars ?? 12e3);
10268
+ let truncated = false;
10269
+ for (const [candidates, laneBudget] of lanes) {
10270
+ let laneRemaining = Math.min(laneBudget, remaining);
10271
+ for (const item of candidates) {
10272
+ const content = item.content?.trim();
10273
+ const key = `${item.lane === "episode" ? "episode" : "fact"}:${item.id}`;
10274
+ if (!content || seenIds.has(key) || seenContent.has(content)) continue;
10275
+ if (content.length > laneRemaining) {
10276
+ truncated = true;
10277
+ continue;
10278
+ }
10279
+ items.push({ ...item, content });
10280
+ seenIds.add(key);
10281
+ seenContent.add(content);
10282
+ remaining -= content.length;
10283
+ laneRemaining -= content.length;
10284
+ }
10285
+ }
10286
+ return { items, ranked, rankedCount: recalledFacts.length, degraded, truncated };
10287
+ }
10288
+
10289
+ // src/lib/memory/durableExtraction.ts
10290
+ import { Q as Q5 } from "@nozbe/watermelondb";
10291
+ var MAX_JOBS_PER_PASS = 3;
10292
+ var MAX_ATTEMPTS = 3;
10293
+ function idsOf(job) {
10294
+ return JSON.parse(String(job._getRaw("message_ids")));
10295
+ }
10296
+ function seqOf(job) {
10297
+ const raw = job._getRaw("watermark_seq");
10298
+ return typeof raw === "number" && raw > 0 ? raw : void 0;
10299
+ }
10300
+ function createDurableAutoExtractor(options) {
10301
+ const vault = options.retainCtx.vaultCtx;
10302
+ const database = vault.database;
10303
+ const owner = vault.userId ?? vault.walletAddress;
10304
+ if (!owner) throw new Error("Durable extraction requires a user or wallet owner");
10305
+ const jobs = database.get(ExtractionJob.table);
10306
+ const storage = {
10307
+ database,
10308
+ messagesCollection: database.get("history"),
10309
+ conversationsCollection: database.get("conversations"),
10310
+ walletAddress: vault.walletAddress,
10311
+ signMessage: vault.signMessage,
10312
+ embeddedWalletSigner: vault.embeddedWalletSigner
10313
+ };
10314
+ const folderId = options.folderId ?? null;
10315
+ let disposed = false;
10316
+ let running = false;
10317
+ let wakeRequested = false;
10318
+ let timer;
10319
+ let writes = Promise.resolve();
10320
+ let storeFailures = 0;
10321
+ const attempts = /* @__PURE__ */ new Map();
10322
+ const reportError = (error, conversationId) => {
10323
+ try {
10324
+ options.onError?.(error instanceof Error ? error : new Error(String(error)), conversationId);
10325
+ } catch {
10326
+ }
10327
+ };
10328
+ const currentScope = () => {
10329
+ try {
10330
+ const value = typeof options.scope === "function" ? options.scope() : options.scope;
10331
+ return value ?? "private";
10332
+ } catch (error) {
10333
+ reportError(error);
10334
+ return "private";
10335
+ }
10336
+ };
10337
+ function schedule(delay) {
10338
+ if (disposed) return;
10339
+ if (running || timer !== void 0) {
10340
+ if (running) wakeRequested = true;
10341
+ return;
10342
+ }
10343
+ timer = setTimeout(() => {
10344
+ timer = void 0;
10345
+ void drain();
10346
+ }, delay);
10347
+ }
10348
+ async function extractBatch(messages, conversationId, ids, jobScope, jobFolderId) {
10349
+ let watchdog;
10350
+ try {
10351
+ return await Promise.race([
10352
+ new Promise((resolve, reject) => {
10353
+ const worker = createAutoExtractor({
10354
+ ...options,
10355
+ retainCtx: {
10356
+ ...options.retainCtx,
10357
+ vaultCtx: {
10358
+ ...vault,
10359
+ canWrite: async () => !disposed && await storage.conversationsCollection.query(Q5.where("conversation_id", conversationId), Q5.where("is_deleted", false)).fetchCount() > 0 && await storage.messagesCollection.query(Q5.where("conversation_id", conversationId), Q5.where("id", Q5.oneOf(ids))).fetchCount() === ids.length && (!vault.canWrite || await vault.canWrite()) && !disposed
10360
+ }
10361
+ },
10362
+ // Never publish a private queued observation after a mode flip.
10363
+ scope: jobScope,
10364
+ folderId: jobFolderId,
10365
+ cursorStore: void 0,
10366
+ windowSize: 20,
10367
+ maxWindowSize: 20,
10368
+ onTurnComplete: resolve,
10369
+ onError: reject
10370
+ });
10371
+ worker.processTurn(messages, conversationId);
10372
+ worker.dispose();
10373
+ }),
10374
+ new Promise((_resolve, reject) => {
10375
+ watchdog = setTimeout(
10376
+ () => reject(new Error("Extraction did not settle in time; retained for retry")),
10377
+ options.batchTimeoutMs ?? 18e4
10378
+ );
10379
+ })
10380
+ ]);
10381
+ } finally {
10382
+ if (watchdog !== void 0) clearTimeout(watchdog);
10383
+ }
10384
+ }
10385
+ async function drain() {
10386
+ if (disposed || running) return;
10387
+ running = true;
10388
+ wakeRequested = false;
10389
+ let retry = false;
10390
+ let scheduleAfterSuccess = false;
10391
+ try {
10392
+ await writes;
10393
+ const pending = await jobs.query(Q5.where("owner_key", owner), Q5.where("message_ids", Q5.notEq("[]"))).fetch();
10394
+ storeFailures = 0;
10395
+ let processed = 0;
10396
+ for (const job of pending) {
10397
+ if (disposed) break;
10398
+ const attempted = attempts.get(job.id) ?? 0;
10399
+ if (attempted >= MAX_ATTEMPTS) continue;
10400
+ if (processed >= MAX_JOBS_PER_PASS) {
10401
+ scheduleAfterSuccess = true;
10402
+ break;
10403
+ }
10404
+ processed++;
10405
+ const conversationId = String(job._getRaw("conversation_id"));
10406
+ try {
10407
+ const conversations = await storage.conversationsCollection.query(Q5.where("conversation_id", conversationId), Q5.where("is_deleted", false)).fetchCount();
10408
+ if (!conversations) {
10409
+ await database.write(() => job.destroyPermanently());
10410
+ continue;
10411
+ }
10412
+ const ids = idsOf(job).slice(0, 20);
10413
+ const loaded = await Promise.all(ids.map((id) => getMessageOp(storage, id)));
10414
+ const missing = ids.filter((_id, index) => loaded[index] === null);
10415
+ if (missing.length) {
10416
+ if (attempted < MAX_ATTEMPTS - 1)
10417
+ throw new Error("Source messages not yet available; retained for retry");
10418
+ const dropped = new Set(missing);
10419
+ await database.write(
10420
+ () => job.update(
10421
+ (r) => r._setRaw(
10422
+ "message_ids",
10423
+ JSON.stringify(idsOf(job).filter((id) => !dropped.has(id)))
10424
+ )
10425
+ )
10426
+ );
10427
+ attempts.delete(job.id);
10428
+ scheduleAfterSuccess = true;
10429
+ reportError(
10430
+ new Error(
10431
+ `Dropped ${missing.length} unresolvable source id(s) to unblock extraction`
10432
+ ),
10433
+ conversationId
10434
+ );
10435
+ continue;
10436
+ }
10437
+ if (loaded.some(
10438
+ (message) => message && (message.decryptionStatus || isEncrypted(message.content))
10439
+ )) {
10440
+ throw new Error("Source messages are locked; retained for retry");
10441
+ }
10442
+ const messages = loaded.flatMap(
10443
+ (m) => m && m.conversationId === conversationId && (m.role === "user" || m.role === "assistant") ? [{ id: m.uniqueId, role: m.role, content: m.content }] : []
10444
+ );
10445
+ let success = messages.length === 0;
10446
+ if (messages.length) {
10447
+ const result = await extractBatch(
10448
+ messages,
10449
+ conversationId,
10450
+ ids,
10451
+ currentScope() === "private" ? "private" : String(job._getRaw("scope")),
10452
+ job._getRaw("folder_id") ?? null
10453
+ );
10454
+ success = result.failedCount === 0 && result.outcome !== "empty-after-retry";
10455
+ options.onTurnComplete?.(result);
10456
+ }
10457
+ if (!success) throw new Error("Extraction batch incomplete; retained for retry");
10458
+ attempts.delete(job.id);
10459
+ const sequences = /* @__PURE__ */ new Map();
10460
+ for (const message of loaded)
10461
+ if (message && message.messageId > 0)
10462
+ sequences.set(message.uniqueId, message.messageId);
10463
+ await database.write(async () => {
10464
+ const current = idsOf(job);
10465
+ const acknowledged = ids.filter((id) => current.includes(id));
10466
+ if (!acknowledged.length) return;
10467
+ const done = new Set(acknowledged);
10468
+ const remaining = current.filter((id) => !done.has(id));
10469
+ if (remaining.length) {
10470
+ await job.update(
10471
+ (r) => r._setRaw("message_ids", JSON.stringify([...acknowledged.slice(-2), ...remaining]))
10472
+ );
10473
+ } else await job.update((r) => r._setRaw("message_ids", "[]"));
10474
+ const newest = acknowledged[acknowledged.length - 1];
10475
+ await job.update((r) => {
10476
+ r._setRaw("watermark", newest);
10477
+ const sequence = sequences.get(newest);
10478
+ if (sequence !== void 0) {
10479
+ const prior = seqOf(job);
10480
+ r._setRaw(
10481
+ "watermark_seq",
10482
+ prior === void 0 ? sequence : Math.max(prior, sequence)
10483
+ );
10484
+ }
10485
+ });
10486
+ });
10487
+ scheduleAfterSuccess = true;
10488
+ } catch (error) {
10489
+ attempts.set(job.id, attempted + 1);
10490
+ retry = true;
10491
+ reportError(error, conversationId);
10492
+ }
10493
+ }
10494
+ } catch (error) {
10495
+ retry = ++storeFailures < 3;
10496
+ reportError(error);
10497
+ } finally {
10498
+ running = false;
10499
+ const woken = wakeRequested;
10500
+ wakeRequested = false;
10501
+ if (retry || scheduleAfterSuccess || woken)
10502
+ schedule(retry ? options.retryDelayMs ?? 3e4 : 0);
10503
+ }
10504
+ }
10505
+ schedule(0);
10506
+ return {
10507
+ processTurn(messages, conversationId) {
10508
+ if (disposed || !conversationId || !messages.length) return false;
10509
+ const ids = messages.map((m) => m.id);
10510
+ const scope = currentScope();
10511
+ writes = writes.then(
10512
+ () => database.write(async () => {
10513
+ const existing = await jobs.query(Q5.where("owner_key", owner), Q5.where("conversation_id", conversationId)).fetch();
10514
+ const job = existing.find(
10515
+ (candidate) => candidate._getRaw("scope") === scope && (candidate._getRaw("folder_id") ?? null) === folderId
10516
+ );
10517
+ const positions = new Map(ids.map((id, index) => [id, index]));
10518
+ const rows = await storage.messagesCollection.query(Q5.where("id", Q5.oneOf(ids))).fetch();
10519
+ const sequences = /* @__PURE__ */ new Map();
10520
+ for (const row of rows) {
10521
+ const sequence = Number(row._getRaw("message_id"));
10522
+ if (Number.isFinite(sequence) && sequence > 0) sequences.set(row.id, sequence);
10523
+ }
10524
+ let boundary = -1;
10525
+ let observedSeq = 0;
10526
+ const foreignSources = /* @__PURE__ */ new Set();
10527
+ for (const prior of existing) {
10528
+ const sources = [...idsOf(prior), String(prior._getRaw("watermark") ?? "")];
10529
+ for (const id of sources) {
10530
+ boundary = Math.max(boundary, positions.get(id) ?? -1);
10531
+ if (prior !== job) foreignSources.add(id);
10532
+ }
10533
+ observedSeq = Math.max(observedSeq, seqOf(prior) ?? 0);
10534
+ for (const id of idsOf(prior))
10535
+ observedSeq = Math.max(observedSeq, sequences.get(id) ?? 0);
10536
+ }
10537
+ if (observedSeq > 0)
10538
+ ids.forEach((id, index) => {
10539
+ const sequence = sequences.get(id);
10540
+ if (sequence !== void 0 && sequence <= observedSeq)
10541
+ boundary = Math.max(boundary, index);
10542
+ });
10543
+ if (!existing.length && options.cursorStore) {
10544
+ try {
10545
+ const cursor = options.cursorStore.get(conversationId);
10546
+ if (cursor) boundary = Math.max(boundary, positions.get(cursor) ?? -1);
10547
+ } catch (error) {
10548
+ reportError(error, conversationId);
10549
+ }
10550
+ }
10551
+ if (boundary < 0 && existing.some((prior) => idsOf(prior).length > 0 || seqOf(prior) !== void 0)) {
10552
+ reportError(
10553
+ new Error("Extraction boundary unresolved; skipped rather than re-observing"),
10554
+ conversationId
10555
+ );
10556
+ return;
10557
+ }
10558
+ const start = boundary >= 0 ? boundary + 1 : Math.max(0, ids.length - Math.max(1, options.windowSize ?? 6));
10559
+ if (start >= ids.length) return;
10560
+ const ownWatermark = job?._getRaw("watermark");
10561
+ const atOwnWatermark = !!job && boundary >= 0 && (ids[boundary] === ownWatermark || sequences.get(ids[boundary]) !== void 0 && sequences.get(ids[boundary]) === seqOf(job));
10562
+ const overlapStart = atOwnWatermark ? Math.max(0, boundary - 1) : start;
10563
+ const fresh = ids.slice(overlapStart).filter((id) => !foreignSources.has(id));
10564
+ if (!fresh.length) return;
10565
+ if (job) {
10566
+ await job.update(
10567
+ (r) => r._setRaw("message_ids", JSON.stringify([.../* @__PURE__ */ new Set([...idsOf(job), ...fresh])]))
10568
+ );
10569
+ attempts.delete(job.id);
10570
+ } else {
10571
+ await jobs.create((r) => {
10572
+ r._setRaw("owner_key", owner);
10573
+ r._setRaw("conversation_id", conversationId);
10574
+ r._setRaw("scope", scope);
10575
+ r._setRaw("folder_id", folderId);
10576
+ r._setRaw("message_ids", JSON.stringify([...new Set(fresh)]));
10577
+ });
10578
+ }
10579
+ })
10580
+ ).then(() => schedule(options.debounceMs ?? 2e4)).catch((error) => reportError(error, conversationId));
10581
+ return true;
10582
+ },
10583
+ isProcessing: () => running,
10584
+ dispose() {
10585
+ disposed = true;
10586
+ if (timer !== void 0) clearTimeout(timer);
10587
+ }
10588
+ };
10589
+ }
10590
+
10126
10591
  // src/lib/memoryEngine/quantization.ts
10127
10592
  var INT8_MAX = 127;
10128
10593
  function quantizeEmbedding(v) {
@@ -14697,10 +15162,25 @@ __decorateClass([
14697
15162
  ], VaultFolder.prototype, "context", 2);
14698
15163
 
14699
15164
  // src/lib/db/schema.ts
14700
- var SDK_SCHEMA_VERSION = 45;
15165
+ var SDK_SCHEMA_VERSION = 46;
14701
15166
  var sdkSchema = appSchema2({
14702
15167
  version: SDK_SCHEMA_VERSION,
14703
15168
  tables: [
15169
+ tableSchema2({
15170
+ name: "memory_extraction_jobs",
15171
+ columns: [
15172
+ { name: "owner_key", type: "string", isIndexed: true },
15173
+ { name: "conversation_id", type: "string", isIndexed: true },
15174
+ { name: "scope", type: "string" },
15175
+ { name: "message_ids", type: "string" },
15176
+ { name: "watermark", type: "string", isOptional: true },
15177
+ // Deletion-proof anchor: history.message_id of the newest acknowledged
15178
+ // source. `watermark` alone is an id, and deleting that message erased
15179
+ // the anchor — see the column note in extractionJobs/models.ts.
15180
+ { name: "watermark_seq", type: "number", isOptional: true },
15181
+ { name: "folder_id", type: "string", isOptional: true }
15182
+ ]
15183
+ }),
14704
15184
  // Chat storage tables
14705
15185
  tableSchema2({
14706
15186
  name: "history",
@@ -15705,10 +16185,28 @@ var sdkMigrations = schemaMigrations2({
15705
16185
  columns: [{ name: "media", type: "string", isOptional: true }]
15706
16186
  })
15707
16187
  ]
16188
+ },
16189
+ {
16190
+ toVersion: 46,
16191
+ steps: [
16192
+ createTable({
16193
+ name: "memory_extraction_jobs",
16194
+ columns: [
16195
+ { name: "owner_key", type: "string", isIndexed: true },
16196
+ { name: "conversation_id", type: "string", isIndexed: true },
16197
+ { name: "scope", type: "string" },
16198
+ { name: "message_ids", type: "string" },
16199
+ { name: "watermark", type: "string", isOptional: true },
16200
+ { name: "watermark_seq", type: "number", isOptional: true },
16201
+ { name: "folder_id", type: "string", isOptional: true }
16202
+ ]
16203
+ })
16204
+ ]
15708
16205
  }
15709
16206
  ]
15710
16207
  });
15711
16208
  var sdkModelClasses = [
16209
+ ExtractionJob,
15712
16210
  Message,
15713
16211
  Conversation,
15714
16212
  ConversationSummary,
@@ -15892,7 +16390,7 @@ function useDatabaseManager(walletAddress, manager) {
15892
16390
  }
15893
16391
 
15894
16392
  // src/lib/db/project/operations.ts
15895
- import { Q as Q5 } from "@nozbe/watermelondb";
16393
+ import { Q as Q6 } from "@nozbe/watermelondb";
15896
16394
 
15897
16395
  // src/lib/db/project/types.ts
15898
16396
  function generateProjectId() {
@@ -15923,15 +16421,15 @@ async function createProjectOp(ctx, opts, defaultName = "New Project") {
15923
16421
  return projectToStored(created);
15924
16422
  }
15925
16423
  async function getProjectOp(ctx, id) {
15926
- const results = await ctx.projectsCollection.query(Q5.where("project_id", id), Q5.where("is_deleted", false)).fetch();
16424
+ const results = await ctx.projectsCollection.query(Q6.where("project_id", id), Q6.where("is_deleted", false)).fetch();
15927
16425
  return results.length > 0 ? projectToStored(results[0]) : null;
15928
16426
  }
15929
16427
  async function getProjectsOp(ctx) {
15930
- const results = await ctx.projectsCollection.query(Q5.where("is_deleted", false), Q5.sortBy("created_at", Q5.desc)).fetch();
16428
+ const results = await ctx.projectsCollection.query(Q6.where("is_deleted", false), Q6.sortBy("created_at", Q6.desc)).fetch();
15931
16429
  return results.map(projectToStored);
15932
16430
  }
15933
16431
  async function updateProjectNameOp(ctx, id, name) {
15934
- const results = await ctx.projectsCollection.query(Q5.where("project_id", id), Q5.where("is_deleted", false)).fetch();
16432
+ const results = await ctx.projectsCollection.query(Q6.where("project_id", id), Q6.where("is_deleted", false)).fetch();
15935
16433
  if (results.length > 0) {
15936
16434
  await ctx.database.write(async () => {
15937
16435
  await results[0].update((proj) => {
@@ -15943,7 +16441,7 @@ async function updateProjectNameOp(ctx, id, name) {
15943
16441
  return false;
15944
16442
  }
15945
16443
  async function updateProjectOp(ctx, id, opts) {
15946
- const results = await ctx.projectsCollection.query(Q5.where("project_id", id), Q5.where("is_deleted", false)).fetch();
16444
+ const results = await ctx.projectsCollection.query(Q6.where("project_id", id), Q6.where("is_deleted", false)).fetch();
15947
16445
  if (results.length > 0) {
15948
16446
  await ctx.database.write(async () => {
15949
16447
  await results[0].update((proj) => {
@@ -15955,7 +16453,7 @@ async function updateProjectOp(ctx, id, opts) {
15955
16453
  return false;
15956
16454
  }
15957
16455
  async function deleteProjectOp(ctx, id) {
15958
- const results = await ctx.projectsCollection.query(Q5.where("project_id", id), Q5.where("is_deleted", false)).fetch();
16456
+ const results = await ctx.projectsCollection.query(Q6.where("project_id", id), Q6.where("is_deleted", false)).fetch();
15959
16457
  if (results.length > 0) {
15960
16458
  await ctx.database.write(async () => {
15961
16459
  await results[0].update((proj) => {
@@ -15968,18 +16466,18 @@ async function deleteProjectOp(ctx, id) {
15968
16466
  }
15969
16467
  async function getProjectConversationsOp(ctx, projectId) {
15970
16468
  const results = await ctx.conversationsCollection.query(
15971
- Q5.where("project_id", projectId),
15972
- Q5.where("is_deleted", false),
15973
- Q5.sortBy("created_at", Q5.desc)
16469
+ Q6.where("project_id", projectId),
16470
+ Q6.where("is_deleted", false),
16471
+ Q6.sortBy("created_at", Q6.desc)
15974
16472
  ).fetch();
15975
16473
  return results.map(conversationToStoredRaw);
15976
16474
  }
15977
16475
  async function getProjectConversationCountOp(ctx, projectId) {
15978
- return await ctx.conversationsCollection.query(Q5.where("project_id", projectId), Q5.where("is_deleted", false)).fetchCount();
16476
+ return await ctx.conversationsCollection.query(Q6.where("project_id", projectId), Q6.where("is_deleted", false)).fetchCount();
15979
16477
  }
15980
16478
 
15981
16479
  // src/react/useFiles.ts
15982
- import { Q as Q6 } from "@nozbe/watermelondb";
16480
+ import { Q as Q7 } from "@nozbe/watermelondb";
15983
16481
  import { useCallback as useCallback5, useEffect as useEffect4, useMemo as useMemo5, useState as useState5 } from "react";
15984
16482
  function useFiles(options) {
15985
16483
  const { database, walletAddress } = options;
@@ -15997,7 +16495,7 @@ function useFiles(options) {
15997
16495
  setIsLoading(true);
15998
16496
  try {
15999
16497
  const coll = database.get("media");
16000
- await coll.query(Q6.take(1)).fetch();
16498
+ await coll.query(Q7.take(1)).fetch();
16001
16499
  setMediaCollection(coll);
16002
16500
  setIsReady(true);
16003
16501
  } catch (error) {
@@ -16405,7 +16903,7 @@ function useFiles(options) {
16405
16903
  }
16406
16904
 
16407
16905
  // src/react/useProjects.ts
16408
- import { Q as Q7 } from "@nozbe/watermelondb";
16906
+ import { Q as Q8 } from "@nozbe/watermelondb";
16409
16907
  import { useCallback as useCallback6, useEffect as useEffect5, useMemo as useMemo6, useState as useState6 } from "react";
16410
16908
  function useProjects(options) {
16411
16909
  const { database, initialProjectId } = options;
@@ -16427,7 +16925,7 @@ function useProjects(options) {
16427
16925
  conversations: convColl?.table
16428
16926
  });
16429
16927
  getLogger().debug("[useProjects] Running test query on projects table...");
16430
- const testResult = await projColl.query(Q7.take(1)).fetch();
16928
+ const testResult = await projColl.query(Q8.take(1)).fetch();
16431
16929
  getLogger().debug(
16432
16930
  "[useProjects] Test query succeeded, found",
16433
16931
  testResult.length,
@@ -16514,7 +17012,7 @@ function useProjects(options) {
16514
17012
  if (!projectsCollection) {
16515
17013
  return;
16516
17014
  }
16517
- const subscription = projectsCollection.query(Q7.where("is_deleted", false)).observe().subscribe((records) => {
17015
+ const subscription = projectsCollection.query(Q8.where("is_deleted", false)).observe().subscribe((records) => {
16518
17016
  setProjects(records.map(projectToStored));
16519
17017
  });
16520
17018
  return () => subscription.unsubscribe();
@@ -16637,7 +17135,7 @@ function useProjects(options) {
16637
17135
  }
16638
17136
 
16639
17137
  // src/lib/db/settings/operations.ts
16640
- import { Q as Q8 } from "@nozbe/watermelondb";
17138
+ import { Q as Q9 } from "@nozbe/watermelondb";
16641
17139
  function modelPreferenceToStored(preference) {
16642
17140
  return {
16643
17141
  uniqueId: preference.id,
@@ -16646,12 +17144,12 @@ function modelPreferenceToStored(preference) {
16646
17144
  };
16647
17145
  }
16648
17146
  async function getModelPreferenceOp(ctx, walletAddress) {
16649
- const results = await ctx.modelPreferencesCollection.query(Q8.where("wallet_address", walletAddress)).fetch();
17147
+ const results = await ctx.modelPreferencesCollection.query(Q9.where("wallet_address", walletAddress)).fetch();
16650
17148
  return results.length > 0 ? modelPreferenceToStored(results[0]) : null;
16651
17149
  }
16652
17150
  async function setModelPreferenceOp(ctx, walletAddress, models) {
16653
17151
  const result = await ctx.database.write(async () => {
16654
- const results = await ctx.modelPreferencesCollection.query(Q8.where("wallet_address", walletAddress)).fetch();
17152
+ const results = await ctx.modelPreferencesCollection.query(Q9.where("wallet_address", walletAddress)).fetch();
16655
17153
  if (results.length > 0) {
16656
17154
  const preference = results[0];
16657
17155
  await preference.update((pref) => {
@@ -16669,7 +17167,7 @@ async function setModelPreferenceOp(ctx, walletAddress, models) {
16669
17167
  return modelPreferenceToStored(result);
16670
17168
  }
16671
17169
  async function deleteModelPreferenceOp(ctx, walletAddress) {
16672
- const results = await ctx.modelPreferencesCollection.query(Q8.where("wallet_address", walletAddress)).fetch();
17170
+ const results = await ctx.modelPreferencesCollection.query(Q9.where("wallet_address", walletAddress)).fetch();
16673
17171
  if (results.length === 0) return false;
16674
17172
  await ctx.database.write(async () => {
16675
17173
  await results[0].destroyPermanently();
@@ -16693,7 +17191,7 @@ var settingsStorageSchema = appSchema3({
16693
17191
  });
16694
17192
 
16695
17193
  // src/lib/db/vaultFolders/operations.ts
16696
- import { Q as Q9 } from "@nozbe/watermelondb";
17194
+ import { Q as Q10 } from "@nozbe/watermelondb";
16697
17195
  function folderToStored(folder) {
16698
17196
  return {
16699
17197
  uniqueId: folder.id,
@@ -16718,7 +17216,7 @@ async function createVaultFolderOp(ctx, opts) {
16718
17216
  return folderToStored(created);
16719
17217
  }
16720
17218
  async function getAllVaultFoldersOp(ctx) {
16721
- const results = await ctx.vaultFolderCollection.query(Q9.where("is_deleted", false), Q9.sortBy("created_at", Q9.desc)).fetch();
17219
+ const results = await ctx.vaultFolderCollection.query(Q10.where("is_deleted", false), Q10.sortBy("created_at", Q10.desc)).fetch();
16722
17220
  return results.map(folderToStored);
16723
17221
  }
16724
17222
  async function updateVaultFolderOp(ctx, id, opts) {
@@ -16727,7 +17225,7 @@ async function updateVaultFolderOp(ctx, id, opts) {
16727
17225
  if (record.isDeleted) return null;
16728
17226
  const scopeChanged = opts.scope !== void 0 && opts.scope !== record.scope;
16729
17227
  const updated = await ctx.database.write(async () => {
16730
- const memories = scopeChanged ? await ctx.vaultMemoryCollection.query(Q9.where("folder_id", id), Q9.where("is_deleted", false)).fetch() : [];
17228
+ const memories = scopeChanged ? await ctx.vaultMemoryCollection.query(Q10.where("folder_id", id), Q10.where("is_deleted", false)).fetch() : [];
16731
17229
  const updates = [];
16732
17230
  updates.push(
16733
17231
  record.prepareUpdate((r) => {
@@ -16755,7 +17253,7 @@ async function deleteVaultFolderOp(ctx, id) {
16755
17253
  const record = await ctx.vaultFolderCollection.find(id);
16756
17254
  if (record.isDeleted) return false;
16757
17255
  await ctx.database.write(async () => {
16758
- const memories = await ctx.vaultMemoryCollection.query(Q9.where("folder_id", id), Q9.where("is_deleted", false)).fetch();
17256
+ const memories = await ctx.vaultMemoryCollection.query(Q10.where("folder_id", id), Q10.where("is_deleted", false)).fetch();
16759
17257
  const preparedMemories = memories.map(
16760
17258
  (memory) => memory.prepareUpdate((r) => {
16761
17259
  r._setRaw("folder_id", null);
@@ -16824,7 +17322,7 @@ async function updateVaultFolderContextOp(ctx, id, context) {
16824
17322
  }
16825
17323
  }
16826
17324
  async function getVaultFolderMemoryCountOp(ctx, folderId) {
16827
- return await ctx.vaultMemoryCollection.query(Q9.where("folder_id", folderId), Q9.where("is_deleted", false)).fetchCount();
17325
+ return await ctx.vaultMemoryCollection.query(Q10.where("folder_id", folderId), Q10.where("is_deleted", false)).fetchCount();
16828
17326
  }
16829
17327
 
16830
17328
  // src/lib/db/vaultFolders/defaults.ts
@@ -16870,7 +17368,7 @@ async function _ensureDefaultFoldersImpl(ctx) {
16870
17368
  import { useCallback as useCallback7, useMemo as useMemo7, useSyncExternalStore } from "react";
16871
17369
 
16872
17370
  // src/lib/db/userPreferences/operations.ts
16873
- import { Q as Q10 } from "@nozbe/watermelondb";
17371
+ import { Q as Q11 } from "@nozbe/watermelondb";
16874
17372
  function userPreferenceToStored(preference) {
16875
17373
  return {
16876
17374
  uniqueId: preference.id,
@@ -16885,7 +17383,7 @@ function userPreferenceToStored(preference) {
16885
17383
  };
16886
17384
  }
16887
17385
  async function getUserPreferenceOp(ctx, walletAddress) {
16888
- const results = await ctx.userPreferencesCollection.query(Q10.where("wallet_address", walletAddress)).fetch();
17386
+ const results = await ctx.userPreferencesCollection.query(Q11.where("wallet_address", walletAddress)).fetch();
16889
17387
  return results.length > 0 ? userPreferenceToStored(results[0]) : null;
16890
17388
  }
16891
17389
  async function createUserPreferenceOp(ctx, opts) {
@@ -16905,7 +17403,7 @@ async function createUserPreferenceOp(ctx, opts) {
16905
17403
  return userPreferenceToStored(created);
16906
17404
  }
16907
17405
  async function updateUserPreferenceOp(ctx, walletAddress, opts) {
16908
- const results = await ctx.userPreferencesCollection.query(Q10.where("wallet_address", walletAddress)).fetch();
17406
+ const results = await ctx.userPreferencesCollection.query(Q11.where("wallet_address", walletAddress)).fetch();
16909
17407
  if (results.length === 0) return null;
16910
17408
  const preference = results[0];
16911
17409
  await ctx.database.write(async () => {
@@ -16933,7 +17431,7 @@ async function updateUserPreferenceOp(ctx, walletAddress, opts) {
16933
17431
  async function setUserPreferenceOp(ctx, walletAddress, opts) {
16934
17432
  const now = Date.now();
16935
17433
  const result = await ctx.database.write(async () => {
16936
- const results = await ctx.userPreferencesCollection.query(Q10.where("wallet_address", walletAddress)).fetch();
17434
+ const results = await ctx.userPreferencesCollection.query(Q11.where("wallet_address", walletAddress)).fetch();
16937
17435
  if (results.length > 0) {
16938
17436
  const preference = results[0];
16939
17437
  await preference.update((pref) => {
@@ -16981,7 +17479,7 @@ async function updateModelsOp(ctx, walletAddress, models) {
16981
17479
  return updateUserPreferenceOp(ctx, walletAddress, { models });
16982
17480
  }
16983
17481
  async function deleteUserPreferenceOp(ctx, walletAddress) {
16984
- const results = await ctx.userPreferencesCollection.query(Q10.where("wallet_address", walletAddress)).fetch();
17482
+ const results = await ctx.userPreferencesCollection.query(Q11.where("wallet_address", walletAddress)).fetch();
16985
17483
  if (results.length === 0) return false;
16986
17484
  await ctx.database.write(async () => {
16987
17485
  await results[0].destroyPermanently();
@@ -16996,9 +17494,9 @@ async function migrateFromModelPreferencesOp(ctx, walletAddress) {
16996
17494
  if (existing) {
16997
17495
  return existing;
16998
17496
  }
16999
- const modelResults = await ctx.modelPreferencesCollection.query(Q10.where("wallet_address", walletAddress)).fetch();
17497
+ const modelResults = await ctx.modelPreferencesCollection.query(Q11.where("wallet_address", walletAddress)).fetch();
17000
17498
  const personalityKey = `${walletAddress}_personality_settings`;
17001
- const personalityResults = await ctx.modelPreferencesCollection.query(Q10.where("wallet_address", personalityKey)).fetch();
17499
+ const personalityResults = await ctx.modelPreferencesCollection.query(Q11.where("wallet_address", personalityKey)).fetch();
17002
17500
  if (modelResults.length === 0 && personalityResults.length === 0) {
17003
17501
  return null;
17004
17502
  }
@@ -17104,7 +17602,7 @@ var SLIDER_CONFIG = [
17104
17602
  ];
17105
17603
 
17106
17604
  // src/react/userSettingsStore.ts
17107
- import { Q as Q11 } from "@nozbe/watermelondb";
17605
+ import { Q as Q12 } from "@nozbe/watermelondb";
17108
17606
  var EMPTY_SNAPSHOT = Object.freeze({
17109
17607
  modelPreference: null,
17110
17608
  userPreference: null,
@@ -17166,7 +17664,7 @@ async function startLoad(entry, walletAddress) {
17166
17664
  }
17167
17665
  function startObserve(entry, walletAddress) {
17168
17666
  let isInitialEmission = true;
17169
- entry.observeSub = entry.storageCtx.userPreferencesCollection.query(Q11.where("wallet_address", walletAddress)).observeWithColumns([
17667
+ entry.observeSub = entry.storageCtx.userPreferencesCollection.query(Q12.where("wallet_address", walletAddress)).observeWithColumns([
17170
17668
  "nickname",
17171
17669
  "occupation",
17172
17670
  "description",
@@ -17430,7 +17928,7 @@ function useSettings(options) {
17430
17928
  }
17431
17929
 
17432
17930
  // src/lib/db/appFiles/operations.ts
17433
- import { Q as Q12 } from "@nozbe/watermelondb";
17931
+ import { Q as Q13 } from "@nozbe/watermelondb";
17434
17932
 
17435
17933
  // src/utils/paths.ts
17436
17934
  function normalizePath(p) {
@@ -17456,7 +17954,7 @@ async function putAppFileOp(ctx, conversationId, path, content) {
17456
17954
  const normalized = normalizePath(path);
17457
17955
  const now = Date.now();
17458
17956
  const result = await ctx.database.write(async () => {
17459
- const existing = await ctx.appFilesCollection.query(Q12.where("conversation_id", conversationId), Q12.where("path", normalized)).fetch();
17957
+ const existing = await ctx.appFilesCollection.query(Q13.where("conversation_id", conversationId), Q13.where("path", normalized)).fetch();
17460
17958
  if (existing.length > 0) {
17461
17959
  await existing[0].update((f) => {
17462
17960
  f._setRaw("content", content);
@@ -17476,11 +17974,11 @@ async function putAppFileOp(ctx, conversationId, path, content) {
17476
17974
  }
17477
17975
  async function getAppFileOp(ctx, conversationId, path) {
17478
17976
  const normalized = normalizePath(path);
17479
- const results = await ctx.appFilesCollection.query(Q12.where("conversation_id", conversationId), Q12.where("path", normalized)).fetch();
17977
+ const results = await ctx.appFilesCollection.query(Q13.where("conversation_id", conversationId), Q13.where("path", normalized)).fetch();
17480
17978
  return results.length > 0 ? appFileToStored(results[0]) : null;
17481
17979
  }
17482
17980
  async function getAppFilesOp(ctx, conversationId) {
17483
- const results = await ctx.appFilesCollection.query(Q12.where("conversation_id", conversationId)).fetch();
17981
+ const results = await ctx.appFilesCollection.query(Q13.where("conversation_id", conversationId)).fetch();
17484
17982
  return results.map(appFileToStored);
17485
17983
  }
17486
17984
  async function getAppFileMapOp(ctx, conversationId) {
@@ -17491,7 +17989,7 @@ async function getAppFileMapOp(ctx, conversationId) {
17491
17989
  }
17492
17990
  async function deleteAppFileOp(ctx, conversationId, path) {
17493
17991
  const normalized = normalizePath(path);
17494
- const results = await ctx.appFilesCollection.query(Q12.where("conversation_id", conversationId), Q12.where("path", normalized)).fetch();
17992
+ const results = await ctx.appFilesCollection.query(Q13.where("conversation_id", conversationId), Q13.where("path", normalized)).fetch();
17495
17993
  if (results.length === 0) return false;
17496
17994
  await ctx.database.write(async () => {
17497
17995
  await results[0].destroyPermanently();
@@ -17499,7 +17997,7 @@ async function deleteAppFileOp(ctx, conversationId, path) {
17499
17997
  return true;
17500
17998
  }
17501
17999
  async function deleteAllAppFilesOp(ctx, conversationId) {
17502
- const results = await ctx.appFilesCollection.query(Q12.where("conversation_id", conversationId)).fetch();
18000
+ const results = await ctx.appFilesCollection.query(Q13.where("conversation_id", conversationId)).fetch();
17503
18001
  if (results.length === 0) return;
17504
18002
  await ctx.database.write(async () => {
17505
18003
  const batch = results.map((file) => file.prepareDestroyPermanently());
@@ -17508,7 +18006,7 @@ async function deleteAllAppFilesOp(ctx, conversationId) {
17508
18006
  }
17509
18007
 
17510
18008
  // src/lib/db/conversationMemory/operations.ts
17511
- import { Q as Q13 } from "@nozbe/watermelondb";
18009
+ import { Q as Q14 } from "@nozbe/watermelondb";
17512
18010
  var MAX_PER_CONVERSATION = 200;
17513
18011
  function conversationMemoryToStored(row) {
17514
18012
  return {
@@ -17523,7 +18021,7 @@ async function addConversationMemoriesOp(ctx, conversationId, items) {
17523
18021
  if (!conversationId || items.length === 0) return;
17524
18022
  const now = Date.now();
17525
18023
  await ctx.database.write(async () => {
17526
- const existing = await ctx.conversationMemoryCollection.query(Q13.where("conversation_id", conversationId), Q13.sortBy("created_at", Q13.asc)).fetch();
18024
+ const existing = await ctx.conversationMemoryCollection.query(Q14.where("conversation_id", conversationId), Q14.sortBy("created_at", Q14.asc)).fetch();
17527
18025
  const seen = new Set(existing.map((r) => r.memoryId));
17528
18026
  const batchSeen = /* @__PURE__ */ new Set();
17529
18027
  const deduped = [];
@@ -17558,20 +18056,20 @@ async function addConversationMemoriesOp(ctx, conversationId, items) {
17558
18056
  }
17559
18057
  async function getConversationMemoriesOp(ctx, conversationId) {
17560
18058
  if (!conversationId) return [];
17561
- const rows = await ctx.conversationMemoryCollection.query(Q13.where("conversation_id", conversationId), Q13.sortBy("created_at", Q13.asc)).fetch();
18059
+ const rows = await ctx.conversationMemoryCollection.query(Q14.where("conversation_id", conversationId), Q14.sortBy("created_at", Q14.asc)).fetch();
17562
18060
  return rows.map(conversationMemoryToStored);
17563
18061
  }
17564
18062
  async function clearConversationMemoriesOp(ctx, conversationId) {
17565
18063
  if (!conversationId) return;
17566
18064
  await ctx.database.write(async () => {
17567
- const rows = await ctx.conversationMemoryCollection.query(Q13.where("conversation_id", conversationId)).fetch();
18065
+ const rows = await ctx.conversationMemoryCollection.query(Q14.where("conversation_id", conversationId)).fetch();
17568
18066
  if (rows.length === 0) return;
17569
18067
  await ctx.database.batch(...rows.map((r) => r.prepareDestroyPermanently()));
17570
18068
  });
17571
18069
  }
17572
18070
 
17573
18071
  // src/lib/db/savedTools/operations.ts
17574
- import { Q as Q14 } from "@nozbe/watermelondb";
18072
+ import { Q as Q15 } from "@nozbe/watermelondb";
17575
18073
  function savedToolToStored(tool) {
17576
18074
  return {
17577
18075
  uniqueId: tool.id,
@@ -17604,7 +18102,7 @@ async function createSavedToolOp(ctx, opts) {
17604
18102
  return savedToolToStored(created);
17605
18103
  }
17606
18104
  async function getAllSavedToolsOp(ctx) {
17607
- const results = await ctx.savedToolsCollection.query(Q14.where("is_deleted", false), Q14.sortBy("created_at", Q14.desc)).fetch();
18105
+ const results = await ctx.savedToolsCollection.query(Q15.where("is_deleted", false), Q15.sortBy("created_at", Q15.desc)).fetch();
17608
18106
  return results.map(savedToolToStored);
17609
18107
  }
17610
18108
  async function getSavedToolByIdOp(ctx, uniqueId) {
@@ -20127,9 +20625,9 @@ async function pushConversationToDropbox(database, conversationId, userAddress,
20127
20625
  const filename = `${conversationId}.json`;
20128
20626
  const existingFile = await findDropboxFile(token, filename, backupFolder);
20129
20627
  if (existingFile) {
20130
- const { Q: Q15 } = await import("@nozbe/watermelondb");
20628
+ const { Q: Q16 } = await import("@nozbe/watermelondb");
20131
20629
  const conversationsCollection = database.get("conversations");
20132
- const records = await conversationsCollection.query(Q15.where("conversation_id", conversationId)).fetch();
20630
+ const records = await conversationsCollection.query(Q16.where("conversation_id", conversationId)).fetch();
20133
20631
  if (records.length > 0) {
20134
20632
  const conversation = conversationToStoredRaw(records[0]);
20135
20633
  const localUpdated = conversation.updatedAt.getTime();
@@ -20167,9 +20665,9 @@ async function pushConversationToDropbox(database, conversationId, userAddress,
20167
20665
  }
20168
20666
  async function performDropboxExport(database, userAddress, token, deps, onProgress, backupFolder = DEFAULT_BACKUP_FOLDER) {
20169
20667
  await deps.requestEncryptionKey(userAddress);
20170
- const { Q: Q15 } = await import("@nozbe/watermelondb");
20668
+ const { Q: Q16 } = await import("@nozbe/watermelondb");
20171
20669
  const conversationsCollection = database.get("conversations");
20172
- const records = await conversationsCollection.query(Q15.where("is_deleted", false)).fetch();
20670
+ const records = await conversationsCollection.query(Q16.where("is_deleted", false)).fetch();
20173
20671
  const conversations = records.map(conversationToStoredRaw);
20174
20672
  const total = conversations.length;
20175
20673
  if (total === 0) {
@@ -20811,9 +21309,9 @@ async function pushConversationToDrive(database, conversationId, userAddress, to
20811
21309
  const filename = `${conversationId}.json`;
20812
21310
  const existingFile = await findDriveFile(activeToken, folderId, filename);
20813
21311
  if (existingFile) {
20814
- const { Q: Q15 } = await import("@nozbe/watermelondb");
21312
+ const { Q: Q16 } = await import("@nozbe/watermelondb");
20815
21313
  const conversationsCollection = database.get("conversations");
20816
- const records = await conversationsCollection.query(Q15.where("conversation_id", conversationId)).fetch();
21314
+ const records = await conversationsCollection.query(Q16.where("conversation_id", conversationId)).fetch();
20817
21315
  if (records.length > 0) {
20818
21316
  const conversation = conversationToStoredRaw(records[0]);
20819
21317
  const localUpdated = conversation.updatedAt.getTime();
@@ -20866,9 +21364,9 @@ async function performGoogleDriveExport(database, userAddress, token, deps, onPr
20866
21364
  return { success: false, uploaded: 0, skipped: 0, total: 0 };
20867
21365
  }
20868
21366
  const { token: activeToken } = folderResult;
20869
- const { Q: Q15 } = await import("@nozbe/watermelondb");
21367
+ const { Q: Q16 } = await import("@nozbe/watermelondb");
20870
21368
  const conversationsCollection = database.get("conversations");
20871
- const records = await conversationsCollection.query(Q15.where("is_deleted", false)).fetch();
21369
+ const records = await conversationsCollection.query(Q16.where("is_deleted", false)).fetch();
20872
21370
  const conversations = records.map(conversationToStoredRaw);
20873
21371
  const total = conversations.length;
20874
21372
  if (total === 0) {
@@ -21453,9 +21951,9 @@ async function pushConversationToICloud(database, conversationId, userAddress, d
21453
21951
  const filename = `${conversationId}.json`;
21454
21952
  const existingFile = await findICloudFile(filename);
21455
21953
  if (existingFile) {
21456
- const { Q: Q15 } = await import("@nozbe/watermelondb");
21954
+ const { Q: Q16 } = await import("@nozbe/watermelondb");
21457
21955
  const conversationsCollection = database.get("conversations");
21458
- const records = await conversationsCollection.query(Q15.where("conversation_id", conversationId)).fetch();
21956
+ const records = await conversationsCollection.query(Q16.where("conversation_id", conversationId)).fetch();
21459
21957
  if (records.length > 0) {
21460
21958
  const conversation = conversationToStoredRaw(records[0]);
21461
21959
  const localUpdated = conversation.updatedAt.getTime();
@@ -21485,9 +21983,9 @@ async function pushConversationToICloud(database, conversationId, userAddress, d
21485
21983
  }
21486
21984
  async function performICloudExport(database, userAddress, deps, onProgress) {
21487
21985
  await deps.requestEncryptionKey(userAddress);
21488
- const { Q: Q15 } = await import("@nozbe/watermelondb");
21986
+ const { Q: Q16 } = await import("@nozbe/watermelondb");
21489
21987
  const conversationsCollection = database.get("conversations");
21490
- const records = await conversationsCollection.query(Q15.where("is_deleted", false)).fetch();
21988
+ const records = await conversationsCollection.query(Q16.where("is_deleted", false)).fetch();
21491
21989
  const conversations = records.map(conversationToStoredRaw);
21492
21990
  const total = conversations.length;
21493
21991
  if (total === 0) {
@@ -25338,6 +25836,7 @@ export {
25338
25836
  HARD_DELETE_WINDOW_MS,
25339
25837
  ICloudAuthProvider,
25340
25838
  INFERENCE_ID_HEADER,
25839
+ INTERNAL_FLOW_MARKER,
25341
25840
  LoggerProvider,
25342
25841
  MAX_HOPS,
25343
25842
  MEDIUM_TTL_MS,
@@ -25386,6 +25885,7 @@ export {
25386
25885
  addConversationMemoriesOp,
25387
25886
  appFileToStored,
25388
25887
  archiveVaultMemoryOp,
25888
+ assembleMemoryContext,
25389
25889
  backfillMemoryEntityUserIdsOp,
25390
25890
  backfillMemoryTopicsOp,
25391
25891
  capHopsForDensity,
@@ -25428,6 +25928,7 @@ export {
25428
25928
  createChunkVectorCache,
25429
25929
  createCryptoPricePreProcessor,
25430
25930
  createDecaySweeper,
25931
+ createDurableAutoExtractor,
25431
25932
  createGitHubTools,
25432
25933
  createLlmDecayClassifier,
25433
25934
  createLlmNeighborRefiner,
@@ -25464,6 +25965,7 @@ export {
25464
25965
  deleteMediaByConversationOp,
25465
25966
  deleteMediaByMessageOp,
25466
25967
  deleteMediaOp,
25968
+ deleteMessageOp,
25467
25969
  deleteProjectOp,
25468
25970
  deleteSavedToolOp,
25469
25971
  deleteVaultFolderOp,
@@ -25668,6 +26170,7 @@ export {
25668
26170
  setMemoryVisibilityOp,
25669
26171
  settingsStorageSchema,
25670
26172
  shouldChunkMessage,
26173
+ shouldRecallMemory,
25671
26174
  shouldRefreshTools,
25672
26175
  stampTopicsExtractedAtOp,
25673
26176
  startGithubAuth,
@@ -25733,5 +26236,6 @@ export {
25733
26236
  verifyMemoriesForPublish,
25734
26237
  walk,
25735
26238
  webPlatformStorage,
26239
+ withInternalFlowMarker,
25736
26240
  writeEncryptedFile
25737
26241
  };