@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
@@ -12352,7 +12352,7 @@ var require_Query = __commonJS({
12352
12352
  var _subscribeToCount = _interopRequireDefault(require_subscribeToCount());
12353
12353
  var _subscribeToQuery = _interopRequireDefault(require_subscribeToQuery());
12354
12354
  var _subscribeToQueryWithColumns = _interopRequireDefault(require_subscribeToQueryWithColumns());
12355
- var Q10 = _interopRequireWildcard(require_QueryDescription());
12355
+ var Q11 = _interopRequireWildcard(require_QueryDescription());
12356
12356
  var _helpers = require_helpers2();
12357
12357
  var _class;
12358
12358
  var _descriptor;
@@ -12384,8 +12384,8 @@ var require_Query = __commonJS({
12384
12384
  (0, _initializerDefineProperty2.default)(this, "_cachedCountSubscribable", _descriptor2, this);
12385
12385
  (0, _initializerDefineProperty2.default)(this, "_cachedCountThrottledSubscribable", _descriptor3, this);
12386
12386
  this.collection = collection;
12387
- this._rawDescription = Q10.buildQueryDescription(clauses);
12388
- this.description = Q10.queryWithoutDeleted(this._rawDescription);
12387
+ this._rawDescription = Q11.buildQueryDescription(clauses);
12388
+ this.description = Q11.queryWithoutDeleted(this._rawDescription);
12389
12389
  }
12390
12390
  var _proto = Query2.prototype;
12391
12391
  _proto.extend = function(...args) {
@@ -12404,12 +12404,12 @@ var require_Query = __commonJS({
12404
12404
  sql
12405
12405
  } = this._rawDescription;
12406
12406
  (0, _invariant.default)(!sql, "Cannot extend an unsafe SQL query");
12407
- return new Query2(collection, [Q10.experimentalJoinTables(joinTables)].concat((0, _toConsumableArray2.default)(nestedJoinTables.map(function({
12407
+ return new Query2(collection, [Q11.experimentalJoinTables(joinTables)].concat((0, _toConsumableArray2.default)(nestedJoinTables.map(function({
12408
12408
  from,
12409
12409
  to
12410
12410
  }) {
12411
- return Q10.experimentalNestedJoin(from, to);
12412
- })), (0, _toConsumableArray2.default)(where), (0, _toConsumableArray2.default)(sortBy), (0, _toConsumableArray2.default)(take ? [Q10.take(take)] : []), (0, _toConsumableArray2.default)(skip ? [Q10.skip(skip)] : []), (0, _toConsumableArray2.default)(lokiTransform ? [Q10.unsafeLokiTransform(lokiTransform)] : []), (0, _toConsumableArray2.default)(clauses)));
12411
+ return Q11.experimentalNestedJoin(from, to);
12412
+ })), (0, _toConsumableArray2.default)(where), (0, _toConsumableArray2.default)(sortBy), (0, _toConsumableArray2.default)(take ? [Q11.take(take)] : []), (0, _toConsumableArray2.default)(skip ? [Q11.skip(skip)] : []), (0, _toConsumableArray2.default)(lokiTransform ? [Q11.unsafeLokiTransform(lokiTransform)] : []), (0, _toConsumableArray2.default)(clauses)));
12413
12413
  };
12414
12414
  _proto.pipe = function(transform) {
12415
12415
  return transform(this);
@@ -13851,7 +13851,7 @@ var require_helpers5 = __commonJS({
13851
13851
  exports2.createTimestampsFor = void 0;
13852
13852
  exports2.fetchDescendants = fetchDescendants;
13853
13853
  var _fp = require_fp();
13854
- var Q10 = _interopRequireWildcard(require_QueryDescription());
13854
+ var Q11 = _interopRequireWildcard(require_QueryDescription());
13855
13855
  function _getRequireWildcardCache(e) {
13856
13856
  if ("function" != typeof WeakMap) return null;
13857
13857
  var r = /* @__PURE__ */ new WeakMap(), t = /* @__PURE__ */ new WeakMap();
@@ -13889,7 +13889,7 @@ var require_helpers5 = __commonJS({
13889
13889
  });
13890
13890
  var childrenQueries = hasManyAssociations.map(function([key, value]) {
13891
13891
  var childCollection = model.collections.get(key);
13892
- return childCollection.query(Q10.where(value.foreignKey, model.id));
13892
+ return childCollection.query(Q11.where(value.foreignKey, model.id));
13893
13893
  });
13894
13894
  return childrenQueries;
13895
13895
  }
@@ -13965,8 +13965,8 @@ var require_Model = __commonJS({
13965
13965
  function associations(...associationList) {
13966
13966
  return (0, _fromPairs.default)(associationList);
13967
13967
  }
13968
- var Model12 = exports2.default = /* @__PURE__ */ (function() {
13969
- function Model13(collection, raw) {
13968
+ var Model13 = exports2.default = /* @__PURE__ */ (function() {
13969
+ function Model14(collection, raw) {
13970
13970
  this._isEditing = false;
13971
13971
  this._preparedState = null;
13972
13972
  this.__changes = null;
@@ -13974,7 +13974,7 @@ var require_Model = __commonJS({
13974
13974
  this.collection = collection;
13975
13975
  this._raw = raw;
13976
13976
  }
13977
- var _proto = Model13.prototype;
13977
+ var _proto = Model14.prototype;
13978
13978
  _proto._getChanges = function() {
13979
13979
  if (!this.__changes) {
13980
13980
  this.__changes = new _rx.BehaviorSubject(this);
@@ -14119,7 +14119,7 @@ var require_Model = __commonJS({
14119
14119
  _proto.callReader = function(action) {
14120
14120
  return this.db._workQueue.subAction(action);
14121
14121
  };
14122
- Model13._prepareCreate = function(collection, recordBuilder) {
14122
+ Model14._prepareCreate = function(collection, recordBuilder) {
14123
14123
  var record = new this(
14124
14124
  collection,
14125
14125
  // sanitizedRaw sets id
@@ -14132,13 +14132,13 @@ var require_Model = __commonJS({
14132
14132
  record.__logVerbose("prepareCreate");
14133
14133
  return record;
14134
14134
  };
14135
- Model13._prepareCreateFromDirtyRaw = function(collection, dirtyRaw) {
14135
+ Model14._prepareCreateFromDirtyRaw = function(collection, dirtyRaw) {
14136
14136
  var record = new this(collection, (0, _RawRecord.sanitizedRaw)(dirtyRaw, collection.schema));
14137
14137
  record._preparedState = "create";
14138
14138
  record.__logVerbose("prepareCreateFromDirtyRaw");
14139
14139
  return record;
14140
14140
  };
14141
- Model13._disposableFromDirtyRaw = function(collection, dirtyRaw) {
14141
+ Model14._disposableFromDirtyRaw = function(collection, dirtyRaw) {
14142
14142
  var record = new this(collection, (0, _RawRecord.sanitizedRaw)(dirtyRaw, collection.schema));
14143
14143
  record._raw._status = "disposable";
14144
14144
  record.__logVerbose("disposableFromDirtyRaw");
@@ -14196,7 +14196,7 @@ var require_Model = __commonJS({
14196
14196
  _logger.default.debug("".concat(debugName, ": ").concat(this.__debugName));
14197
14197
  }
14198
14198
  };
14199
- return (0, _createClass2.default)(Model13, [{
14199
+ return (0, _createClass2.default)(Model14, [{
14200
14200
  key: "id",
14201
14201
  get: function get() {
14202
14202
  return this._raw.id;
@@ -14258,8 +14258,8 @@ var require_Model = __commonJS({
14258
14258
  }
14259
14259
  }]);
14260
14260
  })();
14261
- Model12.associations = {};
14262
- Model12._wmelonTag = "model";
14261
+ Model13.associations = {};
14262
+ Model13._wmelonTag = "model";
14263
14263
  }
14264
14264
  });
14265
14265
 
@@ -14270,8 +14270,8 @@ var require_watermelondb = __commonJS({
14270
14270
  var _interopRequireDefault = require_interopRequireDefault();
14271
14271
  exports2.__esModule = true;
14272
14272
  exports2.tableSchema = exports2.tableName = exports2.localStorageKey = exports2.columnName = exports2.associations = exports2.appSchema = exports2.Relation = exports2.Query = exports2.Q = exports2.Model = exports2.Database = exports2.Collection = void 0;
14273
- var Q10 = _interopRequireWildcard(require_QueryDescription());
14274
- exports2.Q = Q10;
14273
+ var Q11 = _interopRequireWildcard(require_QueryDescription());
14274
+ exports2.Q = Q11;
14275
14275
  var _Collection = _interopRequireDefault(require_Collection());
14276
14276
  exports2.Collection = _Collection.default;
14277
14277
  var _Database = _interopRequireDefault(require_Database());
@@ -14475,7 +14475,7 @@ var require_children = __commonJS({
14475
14475
  var _makeDecorator = _interopRequireDefault(require_makeDecorator());
14476
14476
  var _logError = _interopRequireDefault(require_logError());
14477
14477
  var _invariant = _interopRequireDefault(require_invariant());
14478
- var Q10 = _interopRequireWildcard(require_QueryDescription());
14478
+ var Q11 = _interopRequireWildcard(require_QueryDescription());
14479
14479
  function _getRequireWildcardCache(e) {
14480
14480
  if ("function" != typeof WeakMap) return null;
14481
14481
  var r = /* @__PURE__ */ new WeakMap(), t = /* @__PURE__ */ new WeakMap();
@@ -14509,7 +14509,7 @@ var require_children = __commonJS({
14509
14509
  var childCollection = model.collections.get(childTable);
14510
14510
  var association = model.constructor.associations[childTable];
14511
14511
  (0, _invariant.default)(association && "has_many" === association.type, "@children decorator used for a table that's not has_many");
14512
- var query = childCollection.query(Q10.where(association.foreignKey, model.id));
14512
+ var query = childCollection.query(Q11.where(association.foreignKey, model.id));
14513
14513
  that._childrenQueryCache[childTable] = query;
14514
14514
  return query;
14515
14515
  },
@@ -14923,6 +14923,18 @@ var require_decorators = __commonJS({
14923
14923
  }
14924
14924
  });
14925
14925
 
14926
+ // src/lib/db/extractionJobs/models.ts
14927
+ var import_watermelondb5, ExtractionJob;
14928
+ var init_models = __esm({
14929
+ "src/lib/db/extractionJobs/models.ts"() {
14930
+ "use strict";
14931
+ import_watermelondb5 = __toESM(require_watermelondb());
14932
+ ExtractionJob = class extends import_watermelondb5.Model {
14933
+ };
14934
+ ExtractionJob.table = "memory_extraction_jobs";
14935
+ }
14936
+ });
14937
+
14926
14938
  // node_modules/.pnpm/@nozbe+watermelondb@0.28.0/node_modules/@nozbe/watermelondb/Schema/migrations/stepsForMigration.js
14927
14939
  var require_stepsForMigration = __commonJS({
14928
14940
  "node_modules/.pnpm/@nozbe+watermelondb@0.28.0/node_modules/@nozbe/watermelondb/Schema/migrations/stepsForMigration.js"(exports2) {
@@ -16460,7 +16472,7 @@ async function createConversationOp(ctx, opts, defaultTitle = "New Conversation"
16460
16472
  );
16461
16473
  }
16462
16474
  async function getConversationOp(ctx, id) {
16463
- const results = await ctx.conversationsCollection.query(import_watermelondb14.Q.where("conversation_id", id), import_watermelondb14.Q.where("is_deleted", false)).fetch();
16475
+ const results = await ctx.conversationsCollection.query(import_watermelondb15.Q.where("conversation_id", id), import_watermelondb15.Q.where("is_deleted", false)).fetch();
16464
16476
  return results.length > 0 ? await conversationToStored(
16465
16477
  results[0],
16466
16478
  ctx.walletAddress,
@@ -16469,7 +16481,7 @@ async function getConversationOp(ctx, id) {
16469
16481
  ) : null;
16470
16482
  }
16471
16483
  async function getConversationsOp(ctx) {
16472
- const results = await ctx.conversationsCollection.query(import_watermelondb14.Q.where("is_deleted", false), import_watermelondb14.Q.sortBy("created_at", import_watermelondb14.Q.desc)).unsafeFetchRaw();
16484
+ const results = await ctx.conversationsCollection.query(import_watermelondb15.Q.where("is_deleted", false), import_watermelondb15.Q.sortBy("created_at", import_watermelondb15.Q.desc)).unsafeFetchRaw();
16473
16485
  return Promise.all(
16474
16486
  results.map(
16475
16487
  (raw) => conversationRawToStored(raw, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
@@ -16490,33 +16502,33 @@ function conversationRawToLazyStored(raw) {
16490
16502
  };
16491
16503
  }
16492
16504
  async function getConversationsLazyOp(ctx) {
16493
- const results = await ctx.conversationsCollection.query(import_watermelondb14.Q.where("is_deleted", false), import_watermelondb14.Q.sortBy("created_at", import_watermelondb14.Q.desc)).unsafeFetchRaw();
16505
+ const results = await ctx.conversationsCollection.query(import_watermelondb15.Q.where("is_deleted", false), import_watermelondb15.Q.sortBy("created_at", import_watermelondb15.Q.desc)).unsafeFetchRaw();
16494
16506
  return results.map(conversationRawToLazyStored);
16495
16507
  }
16496
16508
  async function getConversationsPageOp(ctx, options) {
16497
16509
  const limit = Math.floor(options?.limit ?? 200);
16498
16510
  if (!Number.isFinite(limit) || limit < 1) return [];
16499
16511
  const exclude = new Set(options?.boundaryExcludeUniqueIds ?? []);
16500
- const clauses = [import_watermelondb14.Q.where("is_deleted", false)];
16512
+ const clauses = [import_watermelondb15.Q.where("is_deleted", false)];
16501
16513
  if (options?.before !== void 0) {
16502
16514
  clauses.push(
16503
- exclude.size > 0 ? import_watermelondb14.Q.where("created_at", import_watermelondb14.Q.lte(options.before)) : import_watermelondb14.Q.where("created_at", import_watermelondb14.Q.lt(options.before))
16515
+ exclude.size > 0 ? import_watermelondb15.Q.where("created_at", import_watermelondb15.Q.lte(options.before)) : import_watermelondb15.Q.where("created_at", import_watermelondb15.Q.lt(options.before))
16504
16516
  );
16505
16517
  }
16506
- const fetched = await ctx.conversationsCollection.query(...clauses, import_watermelondb14.Q.sortBy("created_at", import_watermelondb14.Q.desc), import_watermelondb14.Q.take(limit + exclude.size)).unsafeFetchRaw();
16518
+ const fetched = await ctx.conversationsCollection.query(...clauses, import_watermelondb15.Q.sortBy("created_at", import_watermelondb15.Q.desc), import_watermelondb15.Q.take(limit + exclude.size)).unsafeFetchRaw();
16507
16519
  const results = exclude.size > 0 ? fetched.filter((raw) => !exclude.has(raw.id)) : fetched;
16508
16520
  return results.slice(0, limit).map(conversationRawToLazyStored);
16509
16521
  }
16510
16522
  async function getConversationsByProjectLazyOp(ctx, projectId) {
16511
16523
  const results = await ctx.conversationsCollection.query(
16512
- import_watermelondb14.Q.where("project_id", projectId === null ? "" : projectId),
16513
- import_watermelondb14.Q.where("is_deleted", false),
16514
- import_watermelondb14.Q.sortBy("created_at", import_watermelondb14.Q.desc)
16524
+ import_watermelondb15.Q.where("project_id", projectId === null ? "" : projectId),
16525
+ import_watermelondb15.Q.where("is_deleted", false),
16526
+ import_watermelondb15.Q.sortBy("created_at", import_watermelondb15.Q.desc)
16515
16527
  ).unsafeFetchRaw();
16516
16528
  return results.map(conversationRawToLazyStored);
16517
16529
  }
16518
16530
  async function updateConversationTitleOp(ctx, id, title) {
16519
- const results = await ctx.conversationsCollection.query(import_watermelondb14.Q.where("conversation_id", id), import_watermelondb14.Q.where("is_deleted", false)).fetch();
16531
+ const results = await ctx.conversationsCollection.query(import_watermelondb15.Q.where("conversation_id", id), import_watermelondb15.Q.where("is_deleted", false)).fetch();
16520
16532
  if (results.length > 0) {
16521
16533
  const encryptedOpts = ctx.walletAddress && ctx.signMessage ? await encryptConversationFields(
16522
16534
  { title },
@@ -16535,19 +16547,21 @@ async function updateConversationTitleOp(ctx, id, title) {
16535
16547
  return false;
16536
16548
  }
16537
16549
  async function deleteConversationOp(ctx, id) {
16538
- const results = await ctx.conversationsCollection.query(import_watermelondb14.Q.where("conversation_id", id), import_watermelondb14.Q.where("is_deleted", false)).fetch();
16550
+ const results = await ctx.conversationsCollection.query(import_watermelondb15.Q.where("conversation_id", id), import_watermelondb15.Q.where("is_deleted", false)).fetch();
16539
16551
  if (results.length > 0) {
16540
16552
  await ctx.database.write(async () => {
16541
16553
  await results[0].update((conv) => {
16542
16554
  conv._setRaw("is_deleted", true);
16543
16555
  });
16556
+ const jobs = ctx.database.schema?.tables[ExtractionJob.table] ? await ctx.database.get(ExtractionJob.table).query(import_watermelondb15.Q.where("conversation_id", id)).fetch() : [];
16557
+ for (const job of jobs) await job.destroyPermanently();
16544
16558
  });
16545
16559
  return true;
16546
16560
  }
16547
16561
  return false;
16548
16562
  }
16549
16563
  async function updateConversationProjectOp(ctx, id, projectId) {
16550
- const results = await ctx.conversationsCollection.query(import_watermelondb14.Q.where("conversation_id", id), import_watermelondb14.Q.where("is_deleted", false)).fetch();
16564
+ const results = await ctx.conversationsCollection.query(import_watermelondb15.Q.where("conversation_id", id), import_watermelondb15.Q.where("is_deleted", false)).fetch();
16551
16565
  if (results.length > 0) {
16552
16566
  await ctx.database.write(async () => {
16553
16567
  await results[0].update((conv) => {
@@ -16560,9 +16574,9 @@ async function updateConversationProjectOp(ctx, id, projectId) {
16560
16574
  }
16561
16575
  async function getConversationsByProjectOp(ctx, projectId) {
16562
16576
  const results = await ctx.conversationsCollection.query(
16563
- import_watermelondb14.Q.where("project_id", projectId === null ? "" : projectId),
16564
- import_watermelondb14.Q.where("is_deleted", false),
16565
- import_watermelondb14.Q.sortBy("created_at", import_watermelondb14.Q.desc)
16577
+ import_watermelondb15.Q.where("project_id", projectId === null ? "" : projectId),
16578
+ import_watermelondb15.Q.where("is_deleted", false),
16579
+ import_watermelondb15.Q.sortBy("created_at", import_watermelondb15.Q.desc)
16566
16580
  ).unsafeFetchRaw();
16567
16581
  return Promise.all(
16568
16582
  results.map(
@@ -16571,7 +16585,7 @@ async function getConversationsByProjectOp(ctx, projectId) {
16571
16585
  );
16572
16586
  }
16573
16587
  async function getMessagesOp(ctx, convId) {
16574
- const results = await ctx.messagesCollection.query(import_watermelondb14.Q.where("conversation_id", convId), import_watermelondb14.Q.sortBy("message_id", import_watermelondb14.Q.asc)).unsafeFetchRaw();
16588
+ const results = await ctx.messagesCollection.query(import_watermelondb15.Q.where("conversation_id", convId), import_watermelondb15.Q.sortBy("message_id", import_watermelondb15.Q.asc)).unsafeFetchRaw();
16575
16589
  return Promise.all(
16576
16590
  results.map(
16577
16591
  (raw) => messageRawToStored(raw, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
@@ -16579,8 +16593,16 @@ async function getMessagesOp(ctx, convId) {
16579
16593
  );
16580
16594
  }
16581
16595
  async function clearMessagesOp(ctx, convId) {
16582
- const messages = await ctx.messagesCollection.query(import_watermelondb14.Q.where("conversation_id", convId)).fetch();
16583
16596
  await ctx.database.write(async () => {
16597
+ const messages = await ctx.messagesCollection.query(import_watermelondb15.Q.where("conversation_id", convId)).fetch();
16598
+ const jobs = ctx.database.schema?.tables[ExtractionJob.table] ? await ctx.database.get(ExtractionJob.table).query(import_watermelondb15.Q.where("conversation_id", convId)).fetch() : [];
16599
+ for (const job of jobs) {
16600
+ await job.update((row) => {
16601
+ row._setRaw("message_ids", "[]");
16602
+ row._setRaw("watermark", null);
16603
+ row._setRaw("watermark_seq", null);
16604
+ });
16605
+ }
16584
16606
  for (const message of messages) {
16585
16607
  await message.update((msg) => {
16586
16608
  msg._setRaw("file_ids", null);
@@ -16590,6 +16612,30 @@ async function clearMessagesOp(ctx, convId) {
16590
16612
  }
16591
16613
  });
16592
16614
  }
16615
+ async function deleteMessageOp(ctx, uniqueId) {
16616
+ let message;
16617
+ try {
16618
+ message = await ctx.messagesCollection.find(uniqueId);
16619
+ } catch {
16620
+ return null;
16621
+ }
16622
+ await ctx.database.write(async () => {
16623
+ const jobs = ctx.database.schema?.tables[ExtractionJob.table] ? await ctx.database.get(ExtractionJob.table).query(import_watermelondb15.Q.where("conversation_id", message.conversationId)).fetch() : [];
16624
+ for (const job of jobs) {
16625
+ const ids = JSON.parse(String(job._getRaw("message_ids")));
16626
+ await job.update((row) => {
16627
+ row._setRaw("message_ids", JSON.stringify(ids.filter((id) => id !== uniqueId)));
16628
+ if (row._getRaw("watermark") === uniqueId) row._setRaw("watermark", null);
16629
+ });
16630
+ }
16631
+ await message.update((msg) => {
16632
+ msg._setRaw("file_ids", null);
16633
+ msg._setRaw("files", null);
16634
+ });
16635
+ await message.destroyPermanently();
16636
+ });
16637
+ return uniqueId;
16638
+ }
16593
16639
  async function encryptMessageOptsIfNeeded(ctx, opts) {
16594
16640
  return ctx.walletAddress && ctx.signMessage ? await encryptMessageFields(opts, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner) : opts;
16595
16641
  }
@@ -16647,9 +16693,9 @@ async function createMessageOp(ctx, opts) {
16647
16693
  }
16648
16694
  }
16649
16695
  const newest = await ctx.messagesCollection.query(
16650
- import_watermelondb14.Q.where("conversation_id", opts.conversationId),
16651
- import_watermelondb14.Q.sortBy("message_id", import_watermelondb14.Q.desc),
16652
- import_watermelondb14.Q.take(1)
16696
+ import_watermelondb15.Q.where("conversation_id", opts.conversationId),
16697
+ import_watermelondb15.Q.sortBy("message_id", import_watermelondb15.Q.desc),
16698
+ import_watermelondb15.Q.take(1)
16653
16699
  ).fetch();
16654
16700
  const messageId = (newest[0]?.messageId ?? 0) + 1;
16655
16701
  const encryptedOpts = await encryptMessageOptsIfNeeded(ctx, opts);
@@ -16663,7 +16709,7 @@ async function createMessageOp(ctx, opts) {
16663
16709
  return messageToStored(created, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
16664
16710
  }
16665
16711
  async function upsertMessageOp(ctx, opts) {
16666
- const results = await ctx.messagesCollection.query(import_watermelondb14.Q.where("id", opts.uniqueId)).fetch();
16712
+ const results = await ctx.messagesCollection.query(import_watermelondb15.Q.where("id", opts.uniqueId)).fetch();
16667
16713
  const existing = results.length > 0 ? results[0] : null;
16668
16714
  if (!existing) {
16669
16715
  return createMessageOp(ctx, opts);
@@ -16844,12 +16890,12 @@ async function readRawJsonField(raw, column, walletAddress) {
16844
16890
  }
16845
16891
  async function searchMessagesOp(ctx, queryVector, options) {
16846
16892
  const { limit = 10, minSimilarity = 0.5, conversationId } = options || {};
16847
- const activeConversations = await ctx.conversationsCollection.query(import_watermelondb14.Q.where("is_deleted", false)).fetch();
16893
+ const activeConversations = await ctx.conversationsCollection.query(import_watermelondb15.Q.where("is_deleted", false)).fetch();
16848
16894
  const activeConversationIds = new Set(
16849
16895
  // Use _getRaw for reliable raw column access
16850
16896
  activeConversations.map((c) => String(c._getRaw("conversation_id")))
16851
16897
  );
16852
- const queryConditions = conversationId ? [import_watermelondb14.Q.where("conversation_id", conversationId)] : [];
16898
+ const queryConditions = conversationId ? [import_watermelondb15.Q.where("conversation_id", conversationId)] : [];
16853
16899
  const messages = await ctx.messagesCollection.query(...queryConditions).unsafeFetchRaw();
16854
16900
  const candidates = [];
16855
16901
  for (const message of messages) {
@@ -16883,12 +16929,12 @@ async function searchChunksOp(ctx, queryVector, options) {
16883
16929
  embeddingModel,
16884
16930
  chunkCache
16885
16931
  } = options || {};
16886
- const activeConversations = await ctx.conversationsCollection.query(import_watermelondb14.Q.where("is_deleted", false)).fetch();
16932
+ const activeConversations = await ctx.conversationsCollection.query(import_watermelondb15.Q.where("is_deleted", false)).fetch();
16887
16933
  const activeConversationIds = new Set(
16888
16934
  // Use _getRaw for reliable raw column access
16889
16935
  activeConversations.map((c) => String(c._getRaw("conversation_id")))
16890
16936
  );
16891
- const queryConditions = conversationId ? [import_watermelondb14.Q.where("conversation_id", conversationId)] : [];
16937
+ const queryConditions = conversationId ? [import_watermelondb15.Q.where("conversation_id", conversationId)] : [];
16892
16938
  const messages = await ctx.messagesCollection.query(...queryConditions).unsafeFetchRaw();
16893
16939
  const candidates = [];
16894
16940
  let staleSkipped = 0;
@@ -17014,13 +17060,13 @@ async function searchChunksOp(ctx, queryVector, options) {
17014
17060
  }
17015
17061
  async function getAllFilesOp(ctx, options) {
17016
17062
  const { conversationId, limit } = options || {};
17017
- const activeConversations = await ctx.conversationsCollection.query(import_watermelondb14.Q.where("is_deleted", false)).fetch();
17063
+ const activeConversations = await ctx.conversationsCollection.query(import_watermelondb15.Q.where("is_deleted", false)).fetch();
17018
17064
  const activeConversationIds = new Set(
17019
17065
  // Use _getRaw for reliable raw column access
17020
17066
  activeConversations.map((c) => String(c._getRaw("conversation_id")))
17021
17067
  );
17022
- const queryConditions = conversationId ? [import_watermelondb14.Q.where("conversation_id", conversationId)] : [];
17023
- const messages = await ctx.messagesCollection.query(...queryConditions, import_watermelondb14.Q.sortBy("created_at", import_watermelondb14.Q.desc)).fetch();
17068
+ const queryConditions = conversationId ? [import_watermelondb15.Q.where("conversation_id", conversationId)] : [];
17069
+ const messages = await ctx.messagesCollection.query(...queryConditions, import_watermelondb15.Q.sortBy("created_at", import_watermelondb15.Q.desc)).fetch();
17024
17070
  const filesWithContext = [];
17025
17071
  for (const message of messages) {
17026
17072
  const msgConvId = String(message._getRaw("conversation_id"));
@@ -17081,16 +17127,17 @@ function makeSyntheticStoredConversation(opts, defaultTitle) {
17081
17127
  isDeleted: false
17082
17128
  };
17083
17129
  }
17084
- var import_watermelondb14, import_uuid2;
17130
+ var import_watermelondb15, import_uuid2;
17085
17131
  var init_operations = __esm({
17086
17132
  "src/lib/db/chat/operations.ts"() {
17087
17133
  "use strict";
17088
- import_watermelondb14 = __toESM(require_watermelondb());
17134
+ import_watermelondb15 = __toESM(require_watermelondb());
17089
17135
  import_uuid2 = require("uuid");
17090
17136
  init_logger();
17091
17137
  init_vector();
17092
17138
  init_vectorEncoding();
17093
17139
  init_encryption_utils();
17140
+ init_models();
17094
17141
  init_conversationEncryption();
17095
17142
  init_encryption();
17096
17143
  init_types2();
@@ -17226,7 +17273,7 @@ async function upsertEntitiesInWrite(ctx, entities) {
17226
17273
  const unique = Array.from(kindByName.keys());
17227
17274
  const out = /* @__PURE__ */ new Map();
17228
17275
  if (unique.length === 0) return { entities: out, operations: [], kindBackfills: [] };
17229
- const existing = await ctx.entityCollection.query(import_watermelondb16.Q.where("canonical_name", import_watermelondb16.Q.oneOf(unique))).fetch();
17276
+ const existing = await ctx.entityCollection.query(import_watermelondb17.Q.where("canonical_name", import_watermelondb17.Q.oneOf(unique))).fetch();
17230
17277
  const existingNames = new Set(existing.map((e) => e.canonicalName));
17231
17278
  const kindBackfills = existing.filter((e) => {
17232
17279
  const incoming = kindByName.get(e.canonicalName);
@@ -17256,7 +17303,7 @@ function prepareKindBackfills(backfills) {
17256
17303
  }
17257
17304
  async function findVaultRowInWrite(ctx, memoryId) {
17258
17305
  try {
17259
- const rows = await ctx.database.get("memory_vault").query(import_watermelondb16.Q.where("id", memoryId)).fetch();
17306
+ const rows = await ctx.database.get("memory_vault").query(import_watermelondb17.Q.where("id", memoryId)).fetch();
17260
17307
  return rows[0] ?? null;
17261
17308
  } catch {
17262
17309
  return null;
@@ -17331,7 +17378,7 @@ async function linkMemoryEntitiesOp(ctx, memoryId, entityInputs, options) {
17331
17378
  return;
17332
17379
  }
17333
17380
  if (entities.length === 0) return;
17334
- const existingLinks = await ctx.memoryEntityCollection.query(import_watermelondb16.Q.where("memory_id", memoryId)).fetch();
17381
+ const existingLinks = await ctx.memoryEntityCollection.query(import_watermelondb17.Q.where("memory_id", memoryId)).fetch();
17335
17382
  const existingEntityIds = new Set(existingLinks.map((l) => String(l.entityId)));
17336
17383
  const toCreate = entities.filter((e) => !existingEntityIds.has(e.uniqueId));
17337
17384
  const keptIds = entities.map((e) => e.uniqueId);
@@ -17366,7 +17413,7 @@ async function linkMemoryEntitiesOp(ctx, memoryId, entityInputs, options) {
17366
17413
  }
17367
17414
  async function resolveEntitiesByIds(ctx, entityIds) {
17368
17415
  if (entityIds.length === 0) return [];
17369
- const rows = await ctx.entityCollection.query(import_watermelondb16.Q.where("id", import_watermelondb16.Q.oneOf(Array.from(entityIds)))).fetch();
17416
+ const rows = await ctx.entityCollection.query(import_watermelondb17.Q.where("id", import_watermelondb17.Q.oneOf(Array.from(entityIds)))).fetch();
17370
17417
  return rows.map(entityToStored);
17371
17418
  }
17372
17419
  function autoLinkBlocked(row) {
@@ -17401,7 +17448,7 @@ async function replaceMemoryEntities(ctx, memoryId, entityInputs, options) {
17401
17448
  kindBackfills
17402
17449
  } = await upsertEntitiesInWrite(ctx, normalized);
17403
17450
  entities = Array.from(byName.values());
17404
- const existingLinks = await ctx.memoryEntityCollection.query(import_watermelondb16.Q.where("memory_id", memoryId)).fetch();
17451
+ const existingLinks = await ctx.memoryEntityCollection.query(import_watermelondb17.Q.where("memory_id", memoryId)).fetch();
17405
17452
  const keep = new Set(entities.map((e) => e.uniqueId));
17406
17453
  const existingEntityIds = new Set(existingLinks.map((l) => String(l.entityId)));
17407
17454
  const toCreate = entities.filter((e) => !existingEntityIds.has(e.uniqueId));
@@ -17436,17 +17483,17 @@ async function replaceMemoryEntities(ctx, memoryId, entityInputs, options) {
17436
17483
  async function findOrphanedEntities(ctx, memoryId, toDestroy) {
17437
17484
  const candidateIds = [...new Set(toDestroy.map((l) => String(l.entityId)))];
17438
17485
  if (candidateIds.length === 0) return [];
17439
- const links = await ctx.memoryEntityCollection.query(import_watermelondb16.Q.where("entity_id", import_watermelondb16.Q.oneOf(candidateIds))).fetch();
17486
+ const links = await ctx.memoryEntityCollection.query(import_watermelondb17.Q.where("entity_id", import_watermelondb17.Q.oneOf(candidateIds))).fetch();
17440
17487
  const stillLinked = new Set(
17441
17488
  links.filter((l) => String(l.memoryId) !== memoryId).map((l) => String(l.entityId))
17442
17489
  );
17443
17490
  const orphanIds = candidateIds.filter((id) => !stillLinked.has(id));
17444
17491
  if (orphanIds.length === 0) return [];
17445
- return await ctx.entityCollection.query(import_watermelondb16.Q.where("id", import_watermelondb16.Q.oneOf(orphanIds))).fetch();
17492
+ return await ctx.entityCollection.query(import_watermelondb17.Q.where("id", import_watermelondb17.Q.oneOf(orphanIds))).fetch();
17446
17493
  }
17447
17494
  async function unlinkMemoryEntitiesOp(ctx, memoryIds) {
17448
17495
  if (memoryIds.length === 0) return;
17449
- const links = await ctx.memoryEntityCollection.query(import_watermelondb16.Q.where("memory_id", import_watermelondb16.Q.oneOf(Array.from(memoryIds)))).fetch();
17496
+ const links = await ctx.memoryEntityCollection.query(import_watermelondb17.Q.where("memory_id", import_watermelondb17.Q.oneOf(Array.from(memoryIds)))).fetch();
17450
17497
  if (links.length === 0) return;
17451
17498
  await ctx.database.write(async () => {
17452
17499
  await ctx.database.batch(...links.map((l) => l.prepareDestroyPermanently()));
@@ -17454,7 +17501,7 @@ async function unlinkMemoryEntitiesOp(ctx, memoryIds) {
17454
17501
  }
17455
17502
  async function unlinkAllMemoryEntitiesForUserOp(ctx, userId) {
17456
17503
  if (!userId) return;
17457
- const links = await ctx.memoryEntityCollection.query(import_watermelondb16.Q.where("user_id", userId)).fetch();
17504
+ const links = await ctx.memoryEntityCollection.query(import_watermelondb17.Q.where("user_id", userId)).fetch();
17458
17505
  if (links.length === 0) return;
17459
17506
  await ctx.database.write(async () => {
17460
17507
  await ctx.database.batch(...links.map((l) => l.prepareDestroyPermanently()));
@@ -17463,15 +17510,15 @@ async function unlinkAllMemoryEntitiesForUserOp(ctx, userId) {
17463
17510
  async function getMemoriesByEntityNamesOp(ctx, entityNames) {
17464
17511
  const unique = Array.from(new Set(entityNames.map(normalizeEntityName).filter((n) => n.length > 0)));
17465
17512
  if (unique.length === 0) return /* @__PURE__ */ new Map();
17466
- const entityRows = await ctx.entityCollection.query(import_watermelondb16.Q.where("canonical_name", import_watermelondb16.Q.oneOf(unique))).fetch();
17513
+ const entityRows = await ctx.entityCollection.query(import_watermelondb17.Q.where("canonical_name", import_watermelondb17.Q.oneOf(unique))).fetch();
17467
17514
  if (entityRows.length === 0) return /* @__PURE__ */ new Map();
17468
17515
  const entityIdToName = new Map(entityRows.map((e) => [e.id, e.canonicalName]));
17469
- const linkConditions = [import_watermelondb16.Q.where("entity_id", import_watermelondb16.Q.oneOf(entityRows.map((e) => e.id)))];
17516
+ const linkConditions = [import_watermelondb17.Q.where("entity_id", import_watermelondb17.Q.oneOf(entityRows.map((e) => e.id)))];
17470
17517
  if (ctx.userId !== void 0) {
17471
17518
  if (ctx.allowUnscopedRows) {
17472
- linkConditions.push(import_watermelondb16.Q.or(import_watermelondb16.Q.where("user_id", ctx.userId), import_watermelondb16.Q.where("user_id", null)));
17519
+ linkConditions.push(import_watermelondb17.Q.or(import_watermelondb17.Q.where("user_id", ctx.userId), import_watermelondb17.Q.where("user_id", null)));
17473
17520
  } else {
17474
- linkConditions.push(import_watermelondb16.Q.where("user_id", ctx.userId));
17521
+ linkConditions.push(import_watermelondb17.Q.where("user_id", ctx.userId));
17475
17522
  }
17476
17523
  }
17477
17524
  const links = await ctx.memoryEntityCollection.query(...linkConditions).fetch();
@@ -17492,18 +17539,18 @@ async function getMemoriesByEntityNamesOp(ctx, entityNames) {
17492
17539
  async function getEntitiesByMemoryIdsOp(ctx, memoryIds) {
17493
17540
  const unique = Array.from(new Set(memoryIds.filter((id) => id.length > 0)));
17494
17541
  if (unique.length === 0) return /* @__PURE__ */ new Map();
17495
- const linkConditions = [import_watermelondb16.Q.where("memory_id", import_watermelondb16.Q.oneOf(unique))];
17542
+ const linkConditions = [import_watermelondb17.Q.where("memory_id", import_watermelondb17.Q.oneOf(unique))];
17496
17543
  if (ctx.userId !== void 0) {
17497
17544
  if (ctx.allowUnscopedRows) {
17498
- linkConditions.push(import_watermelondb16.Q.or(import_watermelondb16.Q.where("user_id", ctx.userId), import_watermelondb16.Q.where("user_id", null)));
17545
+ linkConditions.push(import_watermelondb17.Q.or(import_watermelondb17.Q.where("user_id", ctx.userId), import_watermelondb17.Q.where("user_id", null)));
17499
17546
  } else {
17500
- linkConditions.push(import_watermelondb16.Q.where("user_id", ctx.userId));
17547
+ linkConditions.push(import_watermelondb17.Q.where("user_id", ctx.userId));
17501
17548
  }
17502
17549
  }
17503
17550
  const links = await ctx.memoryEntityCollection.query(...linkConditions).fetch();
17504
17551
  if (links.length === 0) return /* @__PURE__ */ new Map();
17505
17552
  const entityIds = Array.from(new Set(links.map((l) => String(l.entityId))));
17506
- const entityRows = await ctx.entityCollection.query(import_watermelondb16.Q.where("id", import_watermelondb16.Q.oneOf(entityIds))).fetch();
17553
+ const entityRows = await ctx.entityCollection.query(import_watermelondb17.Q.where("id", import_watermelondb17.Q.oneOf(entityIds))).fetch();
17507
17554
  const entityIdToName = new Map(entityRows.map((e) => [e.id, e.canonicalName]));
17508
17555
  const out = /* @__PURE__ */ new Map();
17509
17556
  for (const link of links) {
@@ -17519,11 +17566,11 @@ async function getEntitiesByMemoryIdsOp(ctx, memoryIds) {
17519
17566
  }
17520
17567
  return out;
17521
17568
  }
17522
- var import_watermelondb16;
17569
+ var import_watermelondb17;
17523
17570
  var init_operations2 = __esm({
17524
17571
  "src/lib/db/entities/operations.ts"() {
17525
17572
  "use strict";
17526
- import_watermelondb16 = __toESM(require_watermelondb());
17573
+ import_watermelondb17 = __toESM(require_watermelondb());
17527
17574
  init_types3();
17528
17575
  }
17529
17576
  });
@@ -17590,23 +17637,24 @@ function visibilityOrPrivate(value) {
17590
17637
  function visibilityConditions(requested) {
17591
17638
  if (!requested?.length) return [];
17592
17639
  if (!requested.includes("private")) {
17593
- return [import_watermelondb17.Q.where("visibility", import_watermelondb17.Q.oneOf([...requested]))];
17640
+ return [import_watermelondb18.Q.where("visibility", import_watermelondb18.Q.oneOf([...requested]))];
17594
17641
  }
17595
17642
  const excluded = NON_PRIVATE_VISIBILITIES.filter((v) => !requested.includes(v));
17596
17643
  if (excluded.length === 0) return [];
17597
- return [import_watermelondb17.Q.or(import_watermelondb17.Q.where("visibility", null), import_watermelondb17.Q.where("visibility", import_watermelondb17.Q.notIn(excluded)))];
17644
+ return [import_watermelondb18.Q.or(import_watermelondb18.Q.where("visibility", null), import_watermelondb18.Q.where("visibility", import_watermelondb18.Q.notIn(excluded)))];
17598
17645
  }
17599
17646
  function isOwnedByCtxUser(ctx, record) {
17600
17647
  return ctx.userId === void 0 || record.userId === ctx.userId;
17601
17648
  }
17602
17649
  function baseVaultConditions(ctx, options) {
17603
17650
  return [
17604
- ...options?.includeDeleted ? [] : [import_watermelondb17.Q.where("is_deleted", false)],
17605
- ...options?.includeArchived ? [] : [import_watermelondb17.Q.where("archived_at", import_watermelondb17.Q.eq(null))],
17606
- ...options?.includeQuarantined ? [] : [import_watermelondb17.Q.where("trust_tier", import_watermelondb17.Q.notEq("quarantined"))],
17607
- ...options?.includeSuperseded ? [] : [import_watermelondb17.Q.where("superseded_by", null)],
17608
- ...ctx.userId !== void 0 ? [import_watermelondb17.Q.where("user_id", ctx.userId)] : [],
17609
- ...options?.since ? [import_watermelondb17.Q.where("updated_at", import_watermelondb17.Q.gt(options.since.getTime()))] : []
17651
+ ...options?.memoryIds !== void 0 ? [import_watermelondb18.Q.where("id", import_watermelondb18.Q.oneOf(options.memoryIds))] : [],
17652
+ ...options?.includeDeleted ? [] : [import_watermelondb18.Q.where("is_deleted", false)],
17653
+ ...options?.includeArchived ? [] : [import_watermelondb18.Q.where("archived_at", import_watermelondb18.Q.eq(null))],
17654
+ ...options?.includeQuarantined ? [] : [import_watermelondb18.Q.where("trust_tier", import_watermelondb18.Q.notEq("quarantined"))],
17655
+ ...options?.includeSuperseded ? [] : [import_watermelondb18.Q.where("superseded_by", null)],
17656
+ ...ctx.userId !== void 0 ? [import_watermelondb18.Q.where("user_id", ctx.userId)] : [],
17657
+ ...options?.since ? [import_watermelondb18.Q.where("updated_at", import_watermelondb18.Q.gt(options.since.getTime()))] : []
17610
17658
  ];
17611
17659
  }
17612
17660
  function normalizeTrustTier(value) {
@@ -17684,6 +17732,8 @@ async function createVaultMemoryOp(ctx, opts) {
17684
17732
  ctx.embeddedWalletSigner
17685
17733
  ) : opts.content;
17686
17734
  const created = await ctx.database.write(async () => {
17735
+ if (ctx.canWrite && !await ctx.canWrite())
17736
+ throw new Error("Memory source is no longer eligible");
17687
17737
  return ctx.vaultMemoryCollection.create((record) => {
17688
17738
  record._setRaw("content", encryptedContent);
17689
17739
  record._setRaw("scope", scope);
@@ -17733,6 +17783,8 @@ async function createSupersedingMemoryOp(ctx, opts, targetId) {
17733
17783
  ) : opts.content;
17734
17784
  let createdRecord = null;
17735
17785
  await ctx.database.write(async () => {
17786
+ if (ctx.canWrite && !await ctx.canWrite())
17787
+ throw new Error("Memory source is no longer eligible");
17736
17788
  let target;
17737
17789
  try {
17738
17790
  target = await ctx.vaultMemoryCollection.find(targetId);
@@ -17778,11 +17830,11 @@ async function createSupersedingMemoryOp(ctx, opts, targetId) {
17778
17830
  async function getMemoriesByEventTimeOp(ctx, windowStart, windowEnd) {
17779
17831
  const records = await ctx.vaultMemoryCollection.query(
17780
17832
  ...baseVaultConditions(ctx),
17781
- import_watermelondb17.Q.where("event_time_start", import_watermelondb17.Q.notEq(null)),
17782
- import_watermelondb17.Q.where("event_time_start", import_watermelondb17.Q.lte(windowEnd)),
17783
- import_watermelondb17.Q.or(
17784
- import_watermelondb17.Q.where("event_time_start", import_watermelondb17.Q.gte(windowStart)),
17785
- import_watermelondb17.Q.where("event_time_kind", import_watermelondb17.Q.oneOf(["range", "ongoing"]))
17833
+ import_watermelondb18.Q.where("event_time_start", import_watermelondb18.Q.notEq(null)),
17834
+ import_watermelondb18.Q.where("event_time_start", import_watermelondb18.Q.lte(windowEnd)),
17835
+ import_watermelondb18.Q.or(
17836
+ import_watermelondb18.Q.where("event_time_start", import_watermelondb18.Q.gte(windowStart)),
17837
+ import_watermelondb18.Q.where("event_time_kind", import_watermelondb18.Q.oneOf(["range", "ongoing"]))
17786
17838
  )
17787
17839
  ).fetch();
17788
17840
  const out = [];
@@ -17837,6 +17889,8 @@ async function createVaultMemoriesBatchOp(ctx, optionsArray) {
17837
17889
  })
17838
17890
  );
17839
17891
  const created = await ctx.database.write(async () => {
17892
+ if (ctx.canWrite && !await ctx.canWrite())
17893
+ throw new Error("Memory source is no longer eligible");
17840
17894
  const prepared = optionsArray.map(
17841
17895
  (opts, i) => ctx.vaultMemoryCollection.prepareCreate((record) => {
17842
17896
  record._setRaw("content", encryptedContents[i]);
@@ -17957,12 +18011,12 @@ async function vaultMemoryRawToStored(raw, walletAddress, signMessage, embeddedW
17957
18011
  async function getAllVaultMemoriesOp(ctx, options) {
17958
18012
  const conditions = [
17959
18013
  ...baseVaultConditions(ctx, options),
17960
- ...options?.scopes?.length ? [import_watermelondb17.Q.where("scope", import_watermelondb17.Q.oneOf(options.scopes))] : [],
18014
+ ...options?.scopes?.length ? [import_watermelondb18.Q.where("scope", import_watermelondb18.Q.oneOf(options.scopes))] : [],
17961
18015
  ...visibilityConditions(options?.visibility),
17962
- ...options?.folderId !== void 0 ? [import_watermelondb17.Q.where("folder_id", options.folderId)] : [],
17963
- ...options?.factTypes?.length ? [import_watermelondb17.Q.where("fact_type", import_watermelondb17.Q.oneOf(options.factTypes))] : [],
17964
- import_watermelondb17.Q.sortBy(options?.since ? "updated_at" : "created_at", import_watermelondb17.Q.desc),
17965
- ...options?.limit !== null && options?.limit !== void 0 && options.limit > 0 ? [import_watermelondb17.Q.take(options.limit)] : []
18016
+ ...options?.folderId !== void 0 ? [import_watermelondb18.Q.where("folder_id", options.folderId)] : [],
18017
+ ...options?.factTypes?.length ? [import_watermelondb18.Q.where("fact_type", import_watermelondb18.Q.oneOf(options.factTypes))] : [],
18018
+ import_watermelondb18.Q.sortBy(options?.since ? "updated_at" : "created_at", import_watermelondb18.Q.desc),
18019
+ ...options?.limit !== null && options?.limit !== void 0 && options.limit > 0 ? [import_watermelondb18.Q.take(options.limit)] : []
17966
18020
  ];
17967
18021
  const results = await ctx.vaultMemoryCollection.query(...conditions).unsafeFetchRaw();
17968
18022
  return mapInBatches(
@@ -18000,6 +18054,11 @@ async function getVaultCandidateKeysOp(ctx, options) {
18000
18054
  });
18001
18055
  const clauses = [base.sql];
18002
18056
  const args = [...base.args];
18057
+ if (options?.memoryIds !== void 0) {
18058
+ if (options.memoryIds.length === 0) return [];
18059
+ clauses.push(`"id" in (${options.memoryIds.map(() => "?").join(",")})`);
18060
+ args.push(...options.memoryIds);
18061
+ }
18003
18062
  if (options?.scopes?.length) {
18004
18063
  clauses.push(`"scope" in (${options.scopes.map(() => "?").join(",")})`);
18005
18064
  args.push(...options.scopes);
@@ -18013,7 +18072,7 @@ async function getVaultCandidateKeysOp(ctx, options) {
18013
18072
  args.push(...options.factTypes);
18014
18073
  }
18015
18074
  const sql = `select "id", "scope", "folder_id", "embedding_model", "updated_at" from "memory_vault" where ${clauses.join(" and ")}`;
18016
- const rows = await ctx.vaultMemoryCollection.query(import_watermelondb17.Q.unsafeSqlQuery(sql, args)).unsafeFetchRaw();
18075
+ const rows = await ctx.vaultMemoryCollection.query(import_watermelondb18.Q.unsafeSqlQuery(sql, args)).unsafeFetchRaw();
18017
18076
  return rows.map(mapRaw);
18018
18077
  } catch (err) {
18019
18078
  getLogger().debug(
@@ -18021,11 +18080,12 @@ async function getVaultCandidateKeysOp(ctx, options) {
18021
18080
  );
18022
18081
  const conditions = [
18023
18082
  ...baseVaultConditions(ctx, {
18083
+ memoryIds: options?.memoryIds,
18024
18084
  ...options?.includeArchived !== void 0 && { includeArchived: options.includeArchived }
18025
18085
  }),
18026
- ...options?.scopes?.length ? [import_watermelondb17.Q.where("scope", import_watermelondb17.Q.oneOf(options.scopes))] : [],
18027
- ...options?.folderId !== void 0 ? [import_watermelondb17.Q.where("folder_id", options.folderId)] : [],
18028
- ...options?.factTypes?.length ? [import_watermelondb17.Q.where("fact_type", import_watermelondb17.Q.oneOf(options.factTypes))] : []
18086
+ ...options?.scopes?.length ? [import_watermelondb18.Q.where("scope", import_watermelondb18.Q.oneOf(options.scopes))] : [],
18087
+ ...options?.folderId !== void 0 ? [import_watermelondb18.Q.where("folder_id", options.folderId)] : [],
18088
+ ...options?.factTypes?.length ? [import_watermelondb18.Q.where("fact_type", import_watermelondb18.Q.oneOf(options.factTypes))] : []
18029
18089
  ];
18030
18090
  const rows = await ctx.vaultMemoryCollection.query(...conditions).unsafeFetchRaw();
18031
18091
  return rows.map(mapRaw);
@@ -18043,7 +18103,7 @@ async function getVaultEmbeddingsByIdsOp(ctx, ids, options) {
18043
18103
  ...options?.includeArchived !== void 0 && { includeArchived: options.includeArchived }
18044
18104
  });
18045
18105
  const sql = `select "id", "embedding", "embedding_model" from "memory_vault" where ${base.sql} and "id" in (${ids.map(() => "?").join(",")})`;
18046
- const rows = await ctx.vaultMemoryCollection.query(import_watermelondb17.Q.unsafeSqlQuery(sql, [...base.args, ...ids])).unsafeFetchRaw();
18106
+ const rows = await ctx.vaultMemoryCollection.query(import_watermelondb18.Q.unsafeSqlQuery(sql, [...base.args, ...ids])).unsafeFetchRaw();
18047
18107
  return rows.map(mapRaw);
18048
18108
  } catch (err) {
18049
18109
  getLogger().debug(
@@ -18055,7 +18115,7 @@ async function getVaultEmbeddingsByIdsOp(ctx, ids, options) {
18055
18115
  includeArchived: options.includeArchived
18056
18116
  }
18057
18117
  }),
18058
- import_watermelondb17.Q.where("id", import_watermelondb17.Q.oneOf(ids))
18118
+ import_watermelondb18.Q.where("id", import_watermelondb18.Q.oneOf(ids))
18059
18119
  ).unsafeFetchRaw();
18060
18120
  return rows.map(mapRaw);
18061
18121
  }
@@ -18066,7 +18126,7 @@ async function getVaultMemoriesByIdsOp(ctx, ids, options) {
18066
18126
  ...baseVaultConditions(ctx, {
18067
18127
  ...options?.includeArchived !== void 0 && { includeArchived: options.includeArchived }
18068
18128
  }),
18069
- import_watermelondb17.Q.where("id", import_watermelondb17.Q.oneOf(ids))
18129
+ import_watermelondb18.Q.where("id", import_watermelondb18.Q.oneOf(ids))
18070
18130
  ];
18071
18131
  const results = await ctx.vaultMemoryCollection.query(...conditions).unsafeFetchRaw();
18072
18132
  return mapInBatches(
@@ -18091,7 +18151,7 @@ async function countActiveVaultMemoriesOp(ctx) {
18091
18151
  }
18092
18152
  async function getActiveVaultMemoryIdsOp(ctx, ids) {
18093
18153
  if (ids.length === 0) return /* @__PURE__ */ new Set();
18094
- const rows = await ctx.vaultMemoryCollection.query(...baseVaultConditions(ctx), import_watermelondb17.Q.where("id", import_watermelondb17.Q.oneOf(ids))).unsafeFetchRaw();
18154
+ const rows = await ctx.vaultMemoryCollection.query(...baseVaultConditions(ctx), import_watermelondb18.Q.where("id", import_watermelondb18.Q.oneOf(ids))).unsafeFetchRaw();
18095
18155
  return new Set(rows.map((r) => r.id));
18096
18156
  }
18097
18157
  async function updateVaultMemoryOp(ctx, id, opts) {
@@ -18108,10 +18168,23 @@ async function updateVaultMemoryOp(ctx, id, opts) {
18108
18168
  const record = probe;
18109
18169
  const originalUpdatedAt = record.updatedAt.getTime();
18110
18170
  await ctx.database.write(async () => {
18171
+ if (ctx.canWrite && !await ctx.canWrite())
18172
+ throw new Error("Memory source is no longer eligible");
18111
18173
  if (record.isDeleted || record.supersededBy || !isOwnedByCtxUser(ctx, record)) {
18112
18174
  stale = true;
18113
18175
  return;
18114
18176
  }
18177
+ let observedSources = [];
18178
+ let replayedObservation = false;
18179
+ if (opts.observationSourceIds?.length) {
18180
+ try {
18181
+ const parsed = JSON.parse(record.sourceChunkIds ?? "[]");
18182
+ if (Array.isArray(parsed))
18183
+ observedSources = parsed.filter((id2) => typeof id2 === "string");
18184
+ } catch {
18185
+ }
18186
+ replayedObservation = opts.observationSourceIds.every((id2) => observedSources.includes(id2));
18187
+ }
18115
18188
  await record.update((r) => {
18116
18189
  r._setRaw("content", encryptedContent);
18117
18190
  if (opts.scope !== void 0) {
@@ -18125,9 +18198,15 @@ async function updateVaultMemoryOp(ctx, id, opts) {
18125
18198
  r._setRaw("embedding_model", opts.embeddingModel ?? null);
18126
18199
  }
18127
18200
  if (opts.sourceChunkIds !== void 0) {
18128
- r._setRaw("source_chunk_ids", JSON.stringify(opts.sourceChunkIds));
18201
+ r._setRaw(
18202
+ "source_chunk_ids",
18203
+ JSON.stringify(
18204
+ opts.observationSourceIds?.length ? [.../* @__PURE__ */ new Set([...observedSources, ...opts.sourceChunkIds])] : opts.sourceChunkIds
18205
+ )
18206
+ );
18129
18207
  }
18130
- if (opts.proofCountIncrement !== void 0) {
18208
+ if (replayedObservation) {
18209
+ } else if (opts.proofCountIncrement !== void 0) {
18131
18210
  const current = r.proofCount ?? 1;
18132
18211
  r._setRaw("proof_count", current + opts.proofCountIncrement);
18133
18212
  } else if (opts.proofCount !== void 0) {
@@ -18144,7 +18223,7 @@ async function updateVaultMemoryOp(ctx, id, opts) {
18144
18223
  if (opts.topicsUserManaged !== void 0) {
18145
18224
  r._setRaw("topics_user_managed", opts.topicsUserManaged);
18146
18225
  }
18147
- if (opts.lastObservedAt !== void 0) {
18226
+ if (opts.lastObservedAt !== void 0 && !replayedObservation) {
18148
18227
  r._setRaw("last_observed_at", opts.lastObservedAt);
18149
18228
  }
18150
18229
  if (opts.factType !== void 0) {
@@ -18270,6 +18349,8 @@ async function supersedeVaultMemoryOp(ctx, id, supersededById) {
18270
18349
  }
18271
18350
  let stale = false;
18272
18351
  await ctx.database.write(async () => {
18352
+ if (ctx.canWrite && !await ctx.canWrite())
18353
+ throw new Error("Memory source is no longer eligible");
18273
18354
  if (record.isDeleted || record.supersededBy || !isOwnedByCtxUser(ctx, record)) {
18274
18355
  stale = true;
18275
18356
  return;
@@ -18290,9 +18371,9 @@ async function supersedeVaultMemoryOp(ctx, id, supersededById) {
18290
18371
  }
18291
18372
  async function getUnfiledVaultMemoriesOp(ctx) {
18292
18373
  const conditions = [
18293
- import_watermelondb17.Q.where("folder_id", null),
18374
+ import_watermelondb18.Q.where("folder_id", null),
18294
18375
  ...baseVaultConditions(ctx),
18295
- import_watermelondb17.Q.sortBy("created_at", import_watermelondb17.Q.desc)
18376
+ import_watermelondb18.Q.sortBy("created_at", import_watermelondb18.Q.desc)
18296
18377
  ];
18297
18378
  const results = await ctx.vaultMemoryCollection.query(...conditions).fetch();
18298
18379
  return mapInBatches(
@@ -18305,7 +18386,7 @@ async function linkedEntityNamesByMemory(entityCtx, memoryIds) {
18305
18386
  const entityIdByMemory = /* @__PURE__ */ new Map();
18306
18387
  const allEntityIds = /* @__PURE__ */ new Set();
18307
18388
  for (let i = 0; i < memoryIds.length; i += CHUNK) {
18308
- const links = await entityCtx.memoryEntityCollection.query(import_watermelondb17.Q.where("memory_id", import_watermelondb17.Q.oneOf(memoryIds.slice(i, i + CHUNK)))).unsafeFetchRaw();
18389
+ const links = await entityCtx.memoryEntityCollection.query(import_watermelondb18.Q.where("memory_id", import_watermelondb18.Q.oneOf(memoryIds.slice(i, i + CHUNK)))).unsafeFetchRaw();
18309
18390
  for (const link of links) {
18310
18391
  const memoryId = String(link.memory_id);
18311
18392
  const entityId = String(link.entity_id);
@@ -18321,7 +18402,7 @@ async function linkedEntityNamesByMemory(entityCtx, memoryIds) {
18321
18402
  const entityIds = Array.from(allEntityIds);
18322
18403
  const nameById = /* @__PURE__ */ new Map();
18323
18404
  for (let i = 0; i < entityIds.length; i += CHUNK) {
18324
- const entities = await entityCtx.entityCollection.query(import_watermelondb17.Q.where("id", import_watermelondb17.Q.oneOf(entityIds.slice(i, i + CHUNK)))).unsafeFetchRaw();
18405
+ const entities = await entityCtx.entityCollection.query(import_watermelondb18.Q.where("id", import_watermelondb18.Q.oneOf(entityIds.slice(i, i + CHUNK)))).unsafeFetchRaw();
18325
18406
  for (const e of entities) {
18326
18407
  if (typeof e.canonical_name === "string") nameById.set(String(e.id), e.canonical_name);
18327
18408
  }
@@ -18350,7 +18431,7 @@ async function getMemoriesNeedingTopicExtractionOp(ctx, options) {
18350
18431
  if (!entityCtx) {
18351
18432
  throw new Error("getMemoriesNeedingTopicExtractionOp requires ctx.entityCtx");
18352
18433
  }
18353
- const conditions = [...baseVaultConditions(ctx), import_watermelondb17.Q.sortBy("created_at", import_watermelondb17.Q.desc)];
18434
+ const conditions = [...baseVaultConditions(ctx), import_watermelondb18.Q.sortBy("created_at", import_watermelondb18.Q.desc)];
18354
18435
  const rows = await ctx.vaultMemoryCollection.query(...conditions).unsafeFetchRaw();
18355
18436
  const linkedNames = await linkedEntityNamesByMemory(
18356
18437
  entityCtx,
@@ -18501,10 +18582,10 @@ async function backfillMemoryTopicsOp(ctx, memoryIds) {
18501
18582
  }
18502
18583
  if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) continue;
18503
18584
  if (parseTopics(record.topics) !== null) continue;
18504
- const links = await entityCtx.memoryEntityCollection.query(import_watermelondb17.Q.where("memory_id", id)).unsafeFetchRaw();
18585
+ const links = await entityCtx.memoryEntityCollection.query(import_watermelondb18.Q.where("memory_id", id)).unsafeFetchRaw();
18505
18586
  const entityIds = links.map((l) => String(l.entity_id));
18506
18587
  if (entityIds.length === 0) continue;
18507
- const entities = await entityCtx.entityCollection.query(import_watermelondb17.Q.where("id", import_watermelondb17.Q.oneOf(entityIds))).fetch();
18588
+ const entities = await entityCtx.entityCollection.query(import_watermelondb18.Q.where("id", import_watermelondb18.Q.oneOf(entityIds))).fetch();
18508
18589
  if (entities.length === 0) continue;
18509
18590
  const source = record.topicsUserManaged ? "user" : "auto";
18510
18591
  const write = await resolveMemoryTopicsWrite(entityCtx, id, entities, [], source);
@@ -18520,7 +18601,7 @@ async function backfillMemoryTopicsOp(ctx, memoryIds) {
18520
18601
  }
18521
18602
  async function deleteAllVaultMemoriesForUserOp(ctx, userId) {
18522
18603
  if (ctx.userId !== void 0 && ctx.userId !== userId) return 0;
18523
- const records = await ctx.vaultMemoryCollection.query(import_watermelondb17.Q.where("user_id", userId), import_watermelondb17.Q.where("is_deleted", false)).fetch();
18604
+ const records = await ctx.vaultMemoryCollection.query(import_watermelondb18.Q.where("user_id", userId), import_watermelondb18.Q.where("is_deleted", false)).fetch();
18524
18605
  if (records.length === 0) return 0;
18525
18606
  await ctx.database.write(async () => {
18526
18607
  const prepared = records.map(
@@ -18561,6 +18642,7 @@ async function getDecayCandidatesRawOp(ctx) {
18561
18642
  eventTimeEnd: raw.event_time_end ?? null,
18562
18643
  eventTimeKind: raw.event_time_kind ?? null,
18563
18644
  updatedAt: raw.updated_at,
18645
+ lastObservedAt: raw.last_observed_at ?? null,
18564
18646
  archivedAt: raw.archived_at ?? null,
18565
18647
  source: raw.source ?? null,
18566
18648
  trustTier: raw.trust_tier ?? null
@@ -18577,7 +18659,7 @@ async function archiveVaultMemoryOp(ctx, id, opts) {
18577
18659
  stale = true;
18578
18660
  return;
18579
18661
  }
18580
- if (opts?.expectedUpdatedAt !== void 0 && record.updatedAt.getTime() !== opts.expectedUpdatedAt) {
18662
+ if (opts?.expectedUpdatedAt !== void 0 && record.updatedAt.getTime() !== opts.expectedUpdatedAt || opts?.expectedLastObservedAt !== void 0 && (record.lastObservedAt ?? null) !== opts.expectedLastObservedAt) {
18581
18663
  stale = true;
18582
18664
  return;
18583
18665
  }
@@ -18652,11 +18734,11 @@ async function updateVaultMemoryEmbeddingOp(ctx, id, embedding, embeddingModel)
18652
18734
  return false;
18653
18735
  }
18654
18736
  }
18655
- var import_watermelondb17, NON_PRIVATE_VISIBILITIES, KNOWN_TRUST_TIERS, TOPICS_EXTRACTION_VERSION;
18737
+ var import_watermelondb18, NON_PRIVATE_VISIBILITIES, KNOWN_TRUST_TIERS, TOPICS_EXTRACTION_VERSION;
18656
18738
  var init_operations3 = __esm({
18657
18739
  "src/lib/db/memoryVault/operations.ts"() {
18658
18740
  "use strict";
18659
- import_watermelondb17 = __toESM(require_watermelondb());
18741
+ import_watermelondb18 = __toESM(require_watermelondb());
18660
18742
  init_logger();
18661
18743
  init_operations2();
18662
18744
  init_types3();
@@ -21644,7 +21726,9 @@ function dedupeBy(items, ...keys) {
21644
21726
  return out;
21645
21727
  }
21646
21728
  async function recall(query, ctx, options = {}) {
21647
- const types = options.types ?? ["fact"];
21729
+ const requestedTypes = options.types ?? ["fact"];
21730
+ const chunksScopeRestricted = options.memoryIds !== void 0 && requestedTypes.includes("chunk");
21731
+ const types = options.memoryIds !== void 0 ? requestedTypes.filter((kind) => kind === "fact") : requestedTypes;
21648
21732
  const limit = options.limit ?? DEFAULT_LIMIT;
21649
21733
  const usedBudget = options.budget ?? DEFAULT_BUDGET;
21650
21734
  const flags = flagsForBudget(usedBudget);
@@ -21696,7 +21780,10 @@ async function recall(query, ctx, options = {}) {
21696
21780
  if (embeddingsUnavailable) degraded.push("embeddings-unavailable");
21697
21781
  if (graphLaneFailed) degraded.push("graph-lane-failed");
21698
21782
  if (temporalLaneFailed) degraded.push("temporal-lane-failed");
21699
- const laneRan = types.includes("fact") && !!ctx.vaultCtx && !!ctx.vaultCache || types.includes("chunk") && !!ctx.storageCtx;
21783
+ if (chunksScopeRestricted) degraded.push("chunks-scope-restricted");
21784
+ const laneRan = types.includes("fact") && !!ctx.vaultCtx && !!ctx.vaultCache || types.includes("chunk") && !!ctx.storageCtx || // The chunk lane was wired and deliberately dropped for the scope, which
21785
+ // is not the "requested kinds have no store" wiring bug `no-lanes` means.
21786
+ chunksScopeRestricted && !!ctx.storageCtx;
21700
21787
  const scores = admitted.map((m) => m.score);
21701
21788
  const minScoreApplied = factResults.length > 0 ? factFloor : chunkResults.length > 0 ? chunkFloor : factFloor >= 0 ? factFloor : chunkFloor;
21702
21789
  const diagnostics = {
@@ -21841,6 +21928,7 @@ async function recall(query, ctx, options = {}) {
21841
21928
  ...options.scopes && { scopes: options.scopes },
21842
21929
  ...options.folderId !== void 0 && { folderId: options.folderId },
21843
21930
  ...options.factTypes?.length && { factTypes: options.factTypes },
21931
+ ...options.memoryIds !== void 0 && { memoryIds: options.memoryIds },
21844
21932
  ...options.factTypeWeights && { factTypeWeights: options.factTypeWeights },
21845
21933
  ...entityRanking.length > 0 && { entityRanking },
21846
21934
  ...temporalRanking.length > 0 && { temporalRanking }
@@ -22844,6 +22932,7 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
22844
22932
  const scopes = searchOptions?.scopes;
22845
22933
  const folderId = searchOptions?.folderId;
22846
22934
  const queryOpts = {};
22935
+ if (searchOptions?.memoryIds !== void 0) queryOpts.memoryIds = searchOptions.memoryIds;
22847
22936
  if (scopes?.length) queryOpts.scopes = scopes;
22848
22937
  if (folderId !== void 0) queryOpts.folderId = folderId;
22849
22938
  if (searchOptions?.factTypes?.length) queryOpts.factTypes = searchOptions.factTypes;
@@ -24380,6 +24469,7 @@ __export(index_exports, {
24380
24469
  activatedToolSetNames: () => activatedToolSetNames,
24381
24470
  analyzeStyle: () => analyzeStyle,
24382
24471
  archiveVaultMemoryOp: () => archiveVaultMemoryOp,
24472
+ assembleMemoryContext: () => assembleMemoryContext,
24383
24473
  backfillMemoryTopicsOp: () => backfillMemoryTopicsOp,
24384
24474
  buildConnectorGuidance: () => buildConnectorGuidance,
24385
24475
  buildDeniedToolsRider: () => buildDeniedToolsRider,
@@ -24414,6 +24504,7 @@ __export(index_exports, {
24414
24504
  createConversationOp: () => createConversationOp,
24415
24505
  createCryptoPricePreProcessor: () => createCryptoPricePreProcessor,
24416
24506
  createDecaySweeper: () => createDecaySweeper,
24507
+ createDurableAutoExtractor: () => createDurableAutoExtractor,
24417
24508
  createLlmDecayClassifier: () => createLlmDecayClassifier,
24418
24509
  createLlmNeighborRefiner: () => createLlmNeighborRefiner,
24419
24510
  createMediaBatchOp: () => createMediaBatchOp,
@@ -24447,6 +24538,7 @@ __export(index_exports, {
24447
24538
  deleteMediaByConversationOp: () => deleteMediaByConversationOp,
24448
24539
  deleteMediaByMessageOp: () => deleteMediaByMessageOp,
24449
24540
  deleteMediaOp: () => deleteMediaOp,
24541
+ deleteMessageOp: () => deleteMessageOp,
24450
24542
  deleteModelPreferenceOp: () => deleteModelPreferenceOp,
24451
24543
  deleteProjectOp: () => deleteProjectOp,
24452
24544
  deleteUserPreferenceOp: () => deleteUserPreferenceOp,
@@ -24571,6 +24663,7 @@ __export(index_exports, {
24571
24663
  setUserPreferenceOp: () => setUserPreferenceOp,
24572
24664
  shouldAnalyzeStyle: () => shouldAnalyzeStyle,
24573
24665
  shouldChunkMessage: () => shouldChunkMessage,
24666
+ shouldRecallMemory: () => shouldRecallMemory,
24574
24667
  shouldRefreshTools: () => shouldRefreshTools,
24575
24668
  splitMessagesAtThreshold: () => splitMessagesAtThreshold,
24576
24669
  stampTopicsExtractedAtOp: () => stampTopicsExtractedAtOp,
@@ -24605,10 +24698,10 @@ __export(index_exports, {
24605
24698
  module.exports = __toCommonJS(index_exports);
24606
24699
 
24607
24700
  // src/lib/db/manager.ts
24608
- var import_watermelondb13 = __toESM(require_watermelondb());
24701
+ var import_watermelondb14 = __toESM(require_watermelondb());
24609
24702
 
24610
24703
  // src/lib/db/schema.ts
24611
- var import_watermelondb12 = __toESM(require_watermelondb());
24704
+ var import_watermelondb13 = __toESM(require_watermelondb());
24612
24705
  var import_migrations = __toESM(require_migrations());
24613
24706
 
24614
24707
  // src/lib/db/appFiles/models.ts
@@ -24827,10 +24920,13 @@ __decorateClass([
24827
24920
  (0, import_decorators4.date)("created_at")
24828
24921
  ], MemoryEntity.prototype, "createdAt", 2);
24829
24922
 
24923
+ // src/lib/db/schema.ts
24924
+ init_models();
24925
+
24830
24926
  // src/lib/db/media/models.ts
24831
- var import_watermelondb5 = __toESM(require_watermelondb());
24927
+ var import_watermelondb6 = __toESM(require_watermelondb());
24832
24928
  var import_decorators5 = __toESM(require_decorators());
24833
- var Media = class extends import_watermelondb5.Model {
24929
+ var Media = class extends import_watermelondb6.Model {
24834
24930
  };
24835
24931
  Media.table = "media";
24836
24932
  Media.associations = {
@@ -24891,9 +24987,9 @@ __decorateClass([
24891
24987
  ], Media.prototype, "isDeleted", 2);
24892
24988
 
24893
24989
  // src/lib/db/memoryVault/models.ts
24894
- var import_watermelondb6 = __toESM(require_watermelondb());
24990
+ var import_watermelondb7 = __toESM(require_watermelondb());
24895
24991
  var import_decorators6 = __toESM(require_decorators());
24896
- var VaultMemory = class extends import_watermelondb6.Model {
24992
+ var VaultMemory = class extends import_watermelondb7.Model {
24897
24993
  };
24898
24994
  VaultMemory.table = "memory_vault";
24899
24995
  __decorateClass([
@@ -24992,9 +25088,9 @@ __decorateClass([
24992
25088
  ], VaultMemory.prototype, "isDeleted", 2);
24993
25089
 
24994
25090
  // src/lib/db/project/models.ts
24995
- var import_watermelondb7 = __toESM(require_watermelondb());
25091
+ var import_watermelondb8 = __toESM(require_watermelondb());
24996
25092
  var import_decorators7 = __toESM(require_decorators());
24997
- var Project = class extends import_watermelondb7.Model {
25093
+ var Project = class extends import_watermelondb8.Model {
24998
25094
  };
24999
25095
  Project.table = "projects";
25000
25096
  Project.associations = {
@@ -25017,10 +25113,10 @@ __decorateClass([
25017
25113
  ], Project.prototype, "isDeleted", 2);
25018
25114
 
25019
25115
  // src/lib/db/savedTools/models.ts
25020
- var import_watermelondb8 = __toESM(require_watermelondb());
25116
+ var import_watermelondb9 = __toESM(require_watermelondb());
25021
25117
  var import_decorators8 = __toESM(require_decorators());
25022
25118
  var sanitizeParameters = (raw) => raw ?? {};
25023
- var SavedTool = class extends import_watermelondb8.Model {
25119
+ var SavedTool = class extends import_watermelondb9.Model {
25024
25120
  };
25025
25121
  SavedTool.table = "saved_tools";
25026
25122
  SavedTool.associations = {};
@@ -25054,9 +25150,9 @@ __decorateClass([
25054
25150
  ], SavedTool.prototype, "isDeleted", 2);
25055
25151
 
25056
25152
  // src/lib/db/settings/models.ts
25057
- var import_watermelondb9 = __toESM(require_watermelondb());
25153
+ var import_watermelondb10 = __toESM(require_watermelondb());
25058
25154
  var import_decorators9 = __toESM(require_decorators());
25059
- var ModelPreference = class extends import_watermelondb9.Model {
25155
+ var ModelPreference = class extends import_watermelondb10.Model {
25060
25156
  };
25061
25157
  ModelPreference.table = "modelPreferences";
25062
25158
  __decorateClass([
@@ -25067,9 +25163,9 @@ __decorateClass([
25067
25163
  ], ModelPreference.prototype, "models", 2);
25068
25164
 
25069
25165
  // src/lib/db/userPreferences/models.ts
25070
- var import_watermelondb10 = __toESM(require_watermelondb());
25166
+ var import_watermelondb11 = __toESM(require_watermelondb());
25071
25167
  var import_decorators10 = __toESM(require_decorators());
25072
- var UserPreference = class extends import_watermelondb10.Model {
25168
+ var UserPreference = class extends import_watermelondb11.Model {
25073
25169
  };
25074
25170
  UserPreference.table = "userPreferences";
25075
25171
  __decorateClass([
@@ -25098,9 +25194,9 @@ __decorateClass([
25098
25194
  ], UserPreference.prototype, "updatedAt", 2);
25099
25195
 
25100
25196
  // src/lib/db/vaultFolders/models.ts
25101
- var import_watermelondb11 = __toESM(require_watermelondb());
25197
+ var import_watermelondb12 = __toESM(require_watermelondb());
25102
25198
  var import_decorators11 = __toESM(require_decorators());
25103
- var VaultFolder = class extends import_watermelondb11.Model {
25199
+ var VaultFolder = class extends import_watermelondb12.Model {
25104
25200
  };
25105
25201
  VaultFolder.table = "vault_folders";
25106
25202
  __decorateClass([
@@ -25127,12 +25223,27 @@ __decorateClass([
25127
25223
  ], VaultFolder.prototype, "context", 2);
25128
25224
 
25129
25225
  // src/lib/db/schema.ts
25130
- var SDK_SCHEMA_VERSION = 45;
25131
- var sdkSchema = (0, import_watermelondb12.appSchema)({
25226
+ var SDK_SCHEMA_VERSION = 46;
25227
+ var sdkSchema = (0, import_watermelondb13.appSchema)({
25132
25228
  version: SDK_SCHEMA_VERSION,
25133
25229
  tables: [
25230
+ (0, import_watermelondb13.tableSchema)({
25231
+ name: "memory_extraction_jobs",
25232
+ columns: [
25233
+ { name: "owner_key", type: "string", isIndexed: true },
25234
+ { name: "conversation_id", type: "string", isIndexed: true },
25235
+ { name: "scope", type: "string" },
25236
+ { name: "message_ids", type: "string" },
25237
+ { name: "watermark", type: "string", isOptional: true },
25238
+ // Deletion-proof anchor: history.message_id of the newest acknowledged
25239
+ // source. `watermark` alone is an id, and deleting that message erased
25240
+ // the anchor — see the column note in extractionJobs/models.ts.
25241
+ { name: "watermark_seq", type: "number", isOptional: true },
25242
+ { name: "folder_id", type: "string", isOptional: true }
25243
+ ]
25244
+ }),
25134
25245
  // Chat storage tables
25135
- (0, import_watermelondb12.tableSchema)({
25246
+ (0, import_watermelondb13.tableSchema)({
25136
25247
  name: "history",
25137
25248
  columns: [
25138
25249
  { name: "message_id", type: "number" },
@@ -25171,7 +25282,7 @@ var sdkSchema = (0, import_watermelondb12.appSchema)({
25171
25282
  // MessageOrigin — provenance, NOT encrypted (see v44)
25172
25283
  ]
25173
25284
  }),
25174
- (0, import_watermelondb12.tableSchema)({
25285
+ (0, import_watermelondb13.tableSchema)({
25175
25286
  name: "conversations",
25176
25287
  columns: [
25177
25288
  { name: "conversation_id", type: "string", isIndexed: true },
@@ -25193,7 +25304,7 @@ var sdkSchema = (0, import_watermelondb12.appSchema)({
25193
25304
  ]
25194
25305
  }),
25195
25306
  // Project storage table
25196
- (0, import_watermelondb12.tableSchema)({
25307
+ (0, import_watermelondb13.tableSchema)({
25197
25308
  name: "projects",
25198
25309
  columns: [
25199
25310
  { name: "project_id", type: "string", isIndexed: true },
@@ -25204,7 +25315,7 @@ var sdkSchema = (0, import_watermelondb12.appSchema)({
25204
25315
  ]
25205
25316
  }),
25206
25317
  // Settings storage tables (deprecated - use userPreferences)
25207
- (0, import_watermelondb12.tableSchema)({
25318
+ (0, import_watermelondb13.tableSchema)({
25208
25319
  name: "modelPreferences",
25209
25320
  columns: [
25210
25321
  { name: "wallet_address", type: "string", isIndexed: true },
@@ -25212,7 +25323,7 @@ var sdkSchema = (0, import_watermelondb12.appSchema)({
25212
25323
  ]
25213
25324
  }),
25214
25325
  // Unified user preferences storage
25215
- (0, import_watermelondb12.tableSchema)({
25326
+ (0, import_watermelondb13.tableSchema)({
25216
25327
  name: "userPreferences",
25217
25328
  columns: [
25218
25329
  // Identity
@@ -25231,7 +25342,7 @@ var sdkSchema = (0, import_watermelondb12.appSchema)({
25231
25342
  ]
25232
25343
  }),
25233
25344
  // Memory vault storage
25234
- (0, import_watermelondb12.tableSchema)({
25345
+ (0, import_watermelondb13.tableSchema)({
25235
25346
  name: "memory_vault",
25236
25347
  columns: [
25237
25348
  { name: "content", type: "string" },
@@ -25359,7 +25470,7 @@ var sdkSchema = (0, import_watermelondb12.appSchema)({
25359
25470
  ]
25360
25471
  }),
25361
25472
  // Entity table — canonical names extracted from auto-extraction (W5).
25362
- (0, import_watermelondb12.tableSchema)({
25473
+ (0, import_watermelondb13.tableSchema)({
25363
25474
  name: "entity",
25364
25475
  columns: [
25365
25476
  { name: "canonical_name", type: "string", isIndexed: true },
@@ -25369,7 +25480,7 @@ var sdkSchema = (0, import_watermelondb12.appSchema)({
25369
25480
  ]
25370
25481
  }),
25371
25482
  // Many-to-many join: which memories reference which entities.
25372
- (0, import_watermelondb12.tableSchema)({
25483
+ (0, import_watermelondb13.tableSchema)({
25373
25484
  name: "memory_entity",
25374
25485
  columns: [
25375
25486
  { name: "memory_id", type: "string", isIndexed: true },
@@ -25379,7 +25490,7 @@ var sdkSchema = (0, import_watermelondb12.appSchema)({
25379
25490
  ]
25380
25491
  }),
25381
25492
  // Vault folder organization
25382
- (0, import_watermelondb12.tableSchema)({
25493
+ (0, import_watermelondb13.tableSchema)({
25383
25494
  name: "vault_folders",
25384
25495
  columns: [
25385
25496
  { name: "name", type: "string" },
@@ -25392,7 +25503,7 @@ var sdkSchema = (0, import_watermelondb12.appSchema)({
25392
25503
  ]
25393
25504
  }),
25394
25505
  // Conversation summary cache for progressive history summarization
25395
- (0, import_watermelondb12.tableSchema)({
25506
+ (0, import_watermelondb13.tableSchema)({
25396
25507
  name: "conversation_summaries",
25397
25508
  columns: [
25398
25509
  { name: "conversation_id", type: "string", isIndexed: true },
@@ -25405,7 +25516,7 @@ var sdkSchema = (0, import_watermelondb12.appSchema)({
25405
25516
  ]
25406
25517
  }),
25407
25518
  // Media library storage (images, videos, audio, documents)
25408
- (0, import_watermelondb12.tableSchema)({
25519
+ (0, import_watermelondb13.tableSchema)({
25409
25520
  name: "media",
25410
25521
  columns: [
25411
25522
  // Identity
@@ -25441,7 +25552,7 @@ var sdkSchema = (0, import_watermelondb12.appSchema)({
25441
25552
  ]
25442
25553
  }),
25443
25554
  // ── App files ─────────────────────────────────────────────────────────
25444
- (0, import_watermelondb12.tableSchema)({
25555
+ (0, import_watermelondb13.tableSchema)({
25445
25556
  name: "app_files",
25446
25557
  columns: [
25447
25558
  { name: "conversation_id", type: "string", isIndexed: true },
@@ -25452,7 +25563,7 @@ var sdkSchema = (0, import_watermelondb12.appSchema)({
25452
25563
  ]
25453
25564
  }),
25454
25565
  // ── Saved tools ──────────────────────────────────────────────────────
25455
- (0, import_watermelondb12.tableSchema)({
25566
+ (0, import_watermelondb13.tableSchema)({
25456
25567
  name: "saved_tools",
25457
25568
  columns: [
25458
25569
  { name: "name", type: "string" },
@@ -25468,7 +25579,7 @@ var sdkSchema = (0, import_watermelondb12.appSchema)({
25468
25579
  ]
25469
25580
  }),
25470
25581
  // ── Conversation memories (panel persistence) ────────────────────────
25471
- (0, import_watermelondb12.tableSchema)({
25582
+ (0, import_watermelondb13.tableSchema)({
25472
25583
  name: "conversation_memory",
25473
25584
  columns: [
25474
25585
  { name: "conversation_id", type: "string", isIndexed: true },
@@ -26135,10 +26246,28 @@ var sdkMigrations = (0, import_migrations.schemaMigrations)({
26135
26246
  columns: [{ name: "media", type: "string", isOptional: true }]
26136
26247
  })
26137
26248
  ]
26249
+ },
26250
+ {
26251
+ toVersion: 46,
26252
+ steps: [
26253
+ (0, import_migrations.createTable)({
26254
+ name: "memory_extraction_jobs",
26255
+ columns: [
26256
+ { name: "owner_key", type: "string", isIndexed: true },
26257
+ { name: "conversation_id", type: "string", isIndexed: true },
26258
+ { name: "scope", type: "string" },
26259
+ { name: "message_ids", type: "string" },
26260
+ { name: "watermark", type: "string", isOptional: true },
26261
+ { name: "watermark_seq", type: "number", isOptional: true },
26262
+ { name: "folder_id", type: "string", isOptional: true }
26263
+ ]
26264
+ })
26265
+ ]
26138
26266
  }
26139
26267
  ]
26140
26268
  });
26141
26269
  var sdkModelClasses = [
26270
+ ExtractionJob,
26142
26271
  Message,
26143
26272
  Conversation,
26144
26273
  ConversationSummary,
@@ -26236,7 +26365,7 @@ var DatabaseManager = class {
26236
26365
  walletAddress
26237
26366
  });
26238
26367
  const adapter = this.createAdapter(dbName, sdkSchema, sdkMigrations);
26239
- const database = new import_watermelondb13.Database({
26368
+ const database = new import_watermelondb14.Database({
26240
26369
  adapter,
26241
26370
  modelClasses: sdkModelClasses
26242
26371
  });
@@ -26969,7 +27098,7 @@ async function decryptConversationTitle(encryptedTitle, address) {
26969
27098
  init_operations();
26970
27099
 
26971
27100
  // src/lib/db/chat/summaryOperations.ts
26972
- var import_watermelondb15 = __toESM(require_watermelondb());
27101
+ var import_watermelondb16 = __toESM(require_watermelondb());
26973
27102
  function createSummaryContext(database) {
26974
27103
  return {
26975
27104
  database,
@@ -26988,14 +27117,14 @@ function modelToStored(record) {
26988
27117
  };
26989
27118
  }
26990
27119
  async function getConversationSummaryOp(ctx, conversationId) {
26991
- const results = await ctx.summariesCollection.query(import_watermelondb15.Q.where("conversation_id", conversationId)).fetch();
27120
+ const results = await ctx.summariesCollection.query(import_watermelondb16.Q.where("conversation_id", conversationId)).fetch();
26992
27121
  if (results.length === 0) return null;
26993
27122
  return modelToStored(results[0]);
26994
27123
  }
26995
27124
  async function upsertConversationSummaryOp(ctx, conversationId, summary, summarizedUpTo, tokenCount) {
26996
27125
  let record;
26997
27126
  await ctx.database.write(async () => {
26998
- const existing = await ctx.summariesCollection.query(import_watermelondb15.Q.where("conversation_id", conversationId)).fetch();
27127
+ const existing = await ctx.summariesCollection.query(import_watermelondb16.Q.where("conversation_id", conversationId)).fetch();
26999
27128
  if (existing.length > 0) {
27000
27129
  record = await existing[0].update((rec) => {
27001
27130
  rec.summary = summary;
@@ -27015,7 +27144,7 @@ async function upsertConversationSummaryOp(ctx, conversationId, summary, summari
27015
27144
  }
27016
27145
  async function deleteConversationSummaryOp(ctx, conversationId) {
27017
27146
  await ctx.database.write(async () => {
27018
- const existing = await ctx.summariesCollection.query(import_watermelondb15.Q.where("conversation_id", conversationId)).fetch();
27147
+ const existing = await ctx.summariesCollection.query(import_watermelondb16.Q.where("conversation_id", conversationId)).fetch();
27019
27148
  for (const record of existing) {
27020
27149
  await record.destroyPermanently();
27021
27150
  }
@@ -27505,7 +27634,8 @@ function classifyDecay(m, now, policy) {
27505
27634
  if (m.eventTimeEnd < now - resolved.pastEventGraceMs) return "archive";
27506
27635
  if (m.eventTimeEnd >= now) return "keep";
27507
27636
  }
27508
- if (now - m.updatedAt > ttlForType(m.factType, resolved)) return "archive";
27637
+ const observedAt = Number.isFinite(m.lastObservedAt) ? m.lastObservedAt : m.updatedAt;
27638
+ if (now - Math.max(m.updatedAt, observedAt) > ttlForType(m.factType, resolved)) return "archive";
27509
27639
  return "keep";
27510
27640
  }
27511
27641
 
@@ -27576,7 +27706,7 @@ async function ingestPublishedPhotoMemoriesOp(ctx, rows) {
27576
27706
  init_types4();
27577
27707
 
27578
27708
  // src/lib/db/project/operations.ts
27579
- var import_watermelondb18 = __toESM(require_watermelondb());
27709
+ var import_watermelondb19 = __toESM(require_watermelondb());
27580
27710
  init_operations();
27581
27711
 
27582
27712
  // src/lib/db/project/types.ts
@@ -27608,15 +27738,15 @@ async function createProjectOp(ctx, opts, defaultName = "New Project") {
27608
27738
  return projectToStored(created);
27609
27739
  }
27610
27740
  async function getProjectOp(ctx, id) {
27611
- const results = await ctx.projectsCollection.query(import_watermelondb18.Q.where("project_id", id), import_watermelondb18.Q.where("is_deleted", false)).fetch();
27741
+ const results = await ctx.projectsCollection.query(import_watermelondb19.Q.where("project_id", id), import_watermelondb19.Q.where("is_deleted", false)).fetch();
27612
27742
  return results.length > 0 ? projectToStored(results[0]) : null;
27613
27743
  }
27614
27744
  async function getProjectsOp(ctx) {
27615
- const results = await ctx.projectsCollection.query(import_watermelondb18.Q.where("is_deleted", false), import_watermelondb18.Q.sortBy("created_at", import_watermelondb18.Q.desc)).fetch();
27745
+ const results = await ctx.projectsCollection.query(import_watermelondb19.Q.where("is_deleted", false), import_watermelondb19.Q.sortBy("created_at", import_watermelondb19.Q.desc)).fetch();
27616
27746
  return results.map(projectToStored);
27617
27747
  }
27618
27748
  async function updateProjectNameOp(ctx, id, name) {
27619
- const results = await ctx.projectsCollection.query(import_watermelondb18.Q.where("project_id", id), import_watermelondb18.Q.where("is_deleted", false)).fetch();
27749
+ const results = await ctx.projectsCollection.query(import_watermelondb19.Q.where("project_id", id), import_watermelondb19.Q.where("is_deleted", false)).fetch();
27620
27750
  if (results.length > 0) {
27621
27751
  await ctx.database.write(async () => {
27622
27752
  await results[0].update((proj) => {
@@ -27628,7 +27758,7 @@ async function updateProjectNameOp(ctx, id, name) {
27628
27758
  return false;
27629
27759
  }
27630
27760
  async function updateProjectOp(ctx, id, opts) {
27631
- const results = await ctx.projectsCollection.query(import_watermelondb18.Q.where("project_id", id), import_watermelondb18.Q.where("is_deleted", false)).fetch();
27761
+ const results = await ctx.projectsCollection.query(import_watermelondb19.Q.where("project_id", id), import_watermelondb19.Q.where("is_deleted", false)).fetch();
27632
27762
  if (results.length > 0) {
27633
27763
  await ctx.database.write(async () => {
27634
27764
  await results[0].update((proj) => {
@@ -27640,7 +27770,7 @@ async function updateProjectOp(ctx, id, opts) {
27640
27770
  return false;
27641
27771
  }
27642
27772
  async function deleteProjectOp(ctx, id) {
27643
- const results = await ctx.projectsCollection.query(import_watermelondb18.Q.where("project_id", id), import_watermelondb18.Q.where("is_deleted", false)).fetch();
27773
+ const results = await ctx.projectsCollection.query(import_watermelondb19.Q.where("project_id", id), import_watermelondb19.Q.where("is_deleted", false)).fetch();
27644
27774
  if (results.length > 0) {
27645
27775
  await ctx.database.write(async () => {
27646
27776
  await results[0].update((proj) => {
@@ -27653,14 +27783,14 @@ async function deleteProjectOp(ctx, id) {
27653
27783
  }
27654
27784
  async function getProjectConversationsOp(ctx, projectId) {
27655
27785
  const results = await ctx.conversationsCollection.query(
27656
- import_watermelondb18.Q.where("project_id", projectId),
27657
- import_watermelondb18.Q.where("is_deleted", false),
27658
- import_watermelondb18.Q.sortBy("created_at", import_watermelondb18.Q.desc)
27786
+ import_watermelondb19.Q.where("project_id", projectId),
27787
+ import_watermelondb19.Q.where("is_deleted", false),
27788
+ import_watermelondb19.Q.sortBy("created_at", import_watermelondb19.Q.desc)
27659
27789
  ).fetch();
27660
27790
  return results.map(conversationToStoredRaw);
27661
27791
  }
27662
27792
  async function getProjectConversationCountOp(ctx, projectId) {
27663
- return await ctx.conversationsCollection.query(import_watermelondb18.Q.where("project_id", projectId), import_watermelondb18.Q.where("is_deleted", false)).fetchCount();
27793
+ return await ctx.conversationsCollection.query(import_watermelondb19.Q.where("project_id", projectId), import_watermelondb19.Q.where("is_deleted", false)).fetchCount();
27664
27794
  }
27665
27795
 
27666
27796
  // src/lib/db/media/types.ts
@@ -27687,7 +27817,7 @@ function isSupportedMediaType(mimeType) {
27687
27817
  }
27688
27818
 
27689
27819
  // src/lib/db/media/operations.ts
27690
- var import_watermelondb19 = __toESM(require_watermelondb());
27820
+ var import_watermelondb20 = __toESM(require_watermelondb());
27691
27821
  init_logger();
27692
27822
 
27693
27823
  // src/lib/storage/mcpImages.ts
@@ -27921,7 +28051,7 @@ async function createMediaBatchOp(ctx, optionsArray) {
27921
28051
  })
27922
28052
  );
27923
28053
  });
27924
- const results = await mediaCollection.query(import_watermelondb19.Q.where("media_id", import_watermelondb19.Q.oneOf(mediaIds))).fetch();
28054
+ const results = await mediaCollection.query(import_watermelondb20.Q.where("media_id", import_watermelondb20.Q.oneOf(mediaIds))).fetch();
27925
28055
  return Promise.all(
27926
28056
  results.map(
27927
28057
  (m) => mediaToStored(m, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
@@ -27930,21 +28060,21 @@ async function createMediaBatchOp(ctx, optionsArray) {
27930
28060
  }
27931
28061
  async function getMediaByIdOp(ctx, mediaId) {
27932
28062
  const mediaCollection = ctx.database.get("media");
27933
- const results = await mediaCollection.query(import_watermelondb19.Q.where("media_id", mediaId), import_watermelondb19.Q.where("is_deleted", false)).fetch();
28063
+ const results = await mediaCollection.query(import_watermelondb20.Q.where("media_id", mediaId), import_watermelondb20.Q.where("is_deleted", false)).fetch();
27934
28064
  return results.length > 0 ? await mediaToStored(results[0], ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner) : null;
27935
28065
  }
27936
28066
  async function getMediaBySourceUrlOp(ctx, sourceUrl, walletAddress) {
27937
28067
  const mediaCollection = ctx.database.get("media");
27938
28068
  const results = await mediaCollection.query(
27939
- import_watermelondb19.Q.where("source_url", sourceUrl),
27940
- import_watermelondb19.Q.where("wallet_address", walletAddress),
27941
- import_watermelondb19.Q.where("is_deleted", false)
28069
+ import_watermelondb20.Q.where("source_url", sourceUrl),
28070
+ import_watermelondb20.Q.where("wallet_address", walletAddress),
28071
+ import_watermelondb20.Q.where("is_deleted", false)
27942
28072
  ).fetch();
27943
28073
  return results.length > 0 ? await mediaToStored(results[0], ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner) : null;
27944
28074
  }
27945
28075
  async function updateMediaOp(ctx, mediaId, options) {
27946
28076
  const mediaCollection = ctx.database.get("media");
27947
- const results = await mediaCollection.query(import_watermelondb19.Q.where("media_id", mediaId)).fetch();
28077
+ const results = await mediaCollection.query(import_watermelondb20.Q.where("media_id", mediaId)).fetch();
27948
28078
  if (results.length === 0) {
27949
28079
  return null;
27950
28080
  }
@@ -27964,7 +28094,7 @@ async function updateMediaOp(ctx, mediaId, options) {
27964
28094
  m._setRaw("updated_at", now);
27965
28095
  });
27966
28096
  });
27967
- const updated = await mediaCollection.query(import_watermelondb19.Q.where("media_id", mediaId)).fetch();
28097
+ const updated = await mediaCollection.query(import_watermelondb20.Q.where("media_id", mediaId)).fetch();
27968
28098
  return updated.length > 0 ? await mediaToStored(updated[0], ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner) : null;
27969
28099
  }
27970
28100
  async function updateMediaMessageIdBatchOp(ctx, mediaIds, messageId) {
@@ -27972,7 +28102,7 @@ async function updateMediaMessageIdBatchOp(ctx, mediaIds, messageId) {
27972
28102
  return 0;
27973
28103
  }
27974
28104
  const mediaCollection = ctx.database.get("media");
27975
- const results = await mediaCollection.query(import_watermelondb19.Q.where("media_id", import_watermelondb19.Q.oneOf(mediaIds))).fetch();
28105
+ const results = await mediaCollection.query(import_watermelondb20.Q.where("media_id", import_watermelondb20.Q.oneOf(mediaIds))).fetch();
27976
28106
  if (results.length === 0) {
27977
28107
  return 0;
27978
28108
  }
@@ -27994,13 +28124,13 @@ var IMAGE_VIDEO_MIMES = VIDEO_EXTENSIONS.map((ext) => `image/${ext}`);
27994
28124
  async function relinkMisclassifiedVideosOp(ctx, walletAddress) {
27995
28125
  const mediaCollection = ctx.database.get("media");
27996
28126
  const candidates = await mediaCollection.query(
27997
- import_watermelondb19.Q.where("wallet_address", walletAddress),
27998
- import_watermelondb19.Q.where("is_deleted", false),
27999
- import_watermelondb19.Q.where("media_type", "image"),
28000
- import_watermelondb19.Q.or(
28001
- import_watermelondb19.Q.where("mime_type", import_watermelondb19.Q.like("video/%")),
28002
- ...IMAGE_VIDEO_MIMES.map((m) => import_watermelondb19.Q.where("mime_type", m)),
28003
- import_watermelondb19.Q.where("mime_type", "application/octet-stream")
28127
+ import_watermelondb20.Q.where("wallet_address", walletAddress),
28128
+ import_watermelondb20.Q.where("is_deleted", false),
28129
+ import_watermelondb20.Q.where("media_type", "image"),
28130
+ import_watermelondb20.Q.or(
28131
+ import_watermelondb20.Q.where("mime_type", import_watermelondb20.Q.like("video/%")),
28132
+ ...IMAGE_VIDEO_MIMES.map((m) => import_watermelondb20.Q.where("mime_type", m)),
28133
+ import_watermelondb20.Q.where("mime_type", "application/octet-stream")
28004
28134
  )
28005
28135
  ).fetch();
28006
28136
  if (candidates.length === 0) {
@@ -28049,7 +28179,7 @@ async function relinkMisclassifiedVideosOp(ctx, walletAddress) {
28049
28179
  }
28050
28180
  async function deleteMediaOp(ctx, mediaId) {
28051
28181
  const mediaCollection = ctx.database.get("media");
28052
- const results = await mediaCollection.query(import_watermelondb19.Q.where("media_id", mediaId)).fetch();
28182
+ const results = await mediaCollection.query(import_watermelondb20.Q.where("media_id", mediaId)).fetch();
28053
28183
  if (results.length === 0) {
28054
28184
  return false;
28055
28185
  }
@@ -28067,7 +28197,7 @@ async function deleteMediaOp(ctx, mediaId) {
28067
28197
  }
28068
28198
  async function hardDeleteMediaOp(ctx, mediaId) {
28069
28199
  const mediaCollection = ctx.database.get("media");
28070
- const results = await mediaCollection.query(import_watermelondb19.Q.where("media_id", mediaId)).fetch();
28200
+ const results = await mediaCollection.query(import_watermelondb20.Q.where("media_id", mediaId)).fetch();
28071
28201
  if (results.length === 0) {
28072
28202
  return false;
28073
28203
  }
@@ -28079,28 +28209,28 @@ async function hardDeleteMediaOp(ctx, mediaId) {
28079
28209
  }
28080
28210
  async function getMediaOp(ctx, filters) {
28081
28211
  const mediaCollection = ctx.database.get("media");
28082
- const conditions = [import_watermelondb19.Q.where("wallet_address", filters.walletAddress)];
28212
+ const conditions = [import_watermelondb20.Q.where("wallet_address", filters.walletAddress)];
28083
28213
  if (!filters.includeDeleted) {
28084
- conditions.push(import_watermelondb19.Q.where("is_deleted", false));
28214
+ conditions.push(import_watermelondb20.Q.where("is_deleted", false));
28085
28215
  }
28086
28216
  if (filters.mediaType) {
28087
- conditions.push(import_watermelondb19.Q.where("media_type", filters.mediaType));
28217
+ conditions.push(import_watermelondb20.Q.where("media_type", filters.mediaType));
28088
28218
  }
28089
28219
  if (filters.role) {
28090
- conditions.push(import_watermelondb19.Q.where("role", filters.role));
28220
+ conditions.push(import_watermelondb20.Q.where("role", filters.role));
28091
28221
  }
28092
28222
  if (filters.conversationId) {
28093
- conditions.push(import_watermelondb19.Q.where("conversation_id", filters.conversationId));
28223
+ conditions.push(import_watermelondb20.Q.where("conversation_id", filters.conversationId));
28094
28224
  }
28095
28225
  if (filters.model) {
28096
- conditions.push(import_watermelondb19.Q.where("model", filters.model));
28226
+ conditions.push(import_watermelondb20.Q.where("model", filters.model));
28097
28227
  }
28098
- conditions.push(import_watermelondb19.Q.sortBy("created_at", import_watermelondb19.Q.desc));
28228
+ conditions.push(import_watermelondb20.Q.sortBy("created_at", import_watermelondb20.Q.desc));
28099
28229
  if (filters.limit) {
28100
- conditions.push(import_watermelondb19.Q.take(filters.limit));
28230
+ conditions.push(import_watermelondb20.Q.take(filters.limit));
28101
28231
  }
28102
28232
  if (filters.offset) {
28103
- conditions.push(import_watermelondb19.Q.skip(filters.offset));
28233
+ conditions.push(import_watermelondb20.Q.skip(filters.offset));
28104
28234
  }
28105
28235
  const results = await mediaCollection.query(...conditions).fetch();
28106
28236
  return Promise.all(
@@ -28130,9 +28260,9 @@ async function getMediaByConversationOp(ctx, walletAddress, conversationId, limi
28130
28260
  async function getMediaByMessageOp(ctx, messageId) {
28131
28261
  const mediaCollection = ctx.database.get("media");
28132
28262
  const results = await mediaCollection.query(
28133
- import_watermelondb19.Q.where("message_id", messageId),
28134
- import_watermelondb19.Q.where("is_deleted", false),
28135
- import_watermelondb19.Q.sortBy("created_at", import_watermelondb19.Q.asc)
28263
+ import_watermelondb20.Q.where("message_id", messageId),
28264
+ import_watermelondb20.Q.where("is_deleted", false),
28265
+ import_watermelondb20.Q.sortBy("created_at", import_watermelondb20.Q.asc)
28136
28266
  ).fetch();
28137
28267
  return Promise.all(
28138
28268
  results.map(
@@ -28145,9 +28275,9 @@ async function getMediaByIdsOp(ctx, mediaIds, includeDeleted = false) {
28145
28275
  return [];
28146
28276
  }
28147
28277
  const mediaCollection = ctx.database.get("media");
28148
- const conditions = [import_watermelondb19.Q.where("media_id", import_watermelondb19.Q.oneOf(mediaIds))];
28278
+ const conditions = [import_watermelondb20.Q.where("media_id", import_watermelondb20.Q.oneOf(mediaIds))];
28149
28279
  if (!includeDeleted) {
28150
- conditions.push(import_watermelondb19.Q.where("is_deleted", false));
28280
+ conditions.push(import_watermelondb20.Q.where("is_deleted", false));
28151
28281
  }
28152
28282
  const results = await mediaCollection.query(...conditions).fetch();
28153
28283
  const mediaMap = new Map(results.map((m) => [m.mediaId, m]));
@@ -28184,10 +28314,10 @@ async function searchMediaOp(ctx, walletAddress, query, limit) {
28184
28314
  const queryLower = query.toLowerCase();
28185
28315
  const MAX_SEARCH_RECORDS = 500;
28186
28316
  const allResults = await mediaCollection.query(
28187
- import_watermelondb19.Q.where("wallet_address", walletAddress),
28188
- import_watermelondb19.Q.where("is_deleted", false),
28189
- import_watermelondb19.Q.sortBy("created_at", import_watermelondb19.Q.desc),
28190
- import_watermelondb19.Q.take(MAX_SEARCH_RECORDS)
28317
+ import_watermelondb20.Q.where("wallet_address", walletAddress),
28318
+ import_watermelondb20.Q.where("is_deleted", false),
28319
+ import_watermelondb20.Q.sortBy("created_at", import_watermelondb20.Q.desc),
28320
+ import_watermelondb20.Q.take(MAX_SEARCH_RECORDS)
28191
28321
  ).fetch();
28192
28322
  const decrypted = await Promise.all(
28193
28323
  allResults.map(
@@ -28200,11 +28330,11 @@ async function searchMediaOp(ctx, walletAddress, query, limit) {
28200
28330
  async function getMediaCountOp(ctx, walletAddress, mediaType) {
28201
28331
  const mediaCollection = ctx.database.get("media");
28202
28332
  const conditions = [
28203
- import_watermelondb19.Q.where("wallet_address", walletAddress),
28204
- import_watermelondb19.Q.where("is_deleted", false)
28333
+ import_watermelondb20.Q.where("wallet_address", walletAddress),
28334
+ import_watermelondb20.Q.where("is_deleted", false)
28205
28335
  ];
28206
28336
  if (mediaType) {
28207
- conditions.push(import_watermelondb19.Q.where("media_type", mediaType));
28337
+ conditions.push(import_watermelondb20.Q.where("media_type", mediaType));
28208
28338
  }
28209
28339
  return await mediaCollection.query(...conditions).fetchCount();
28210
28340
  }
@@ -28219,7 +28349,7 @@ async function getMediaCountsByTypeOp(ctx, walletAddress) {
28219
28349
  }
28220
28350
  async function deleteMediaByConversationOp(ctx, conversationId) {
28221
28351
  const mediaCollection = ctx.database.get("media");
28222
- const results = await mediaCollection.query(import_watermelondb19.Q.where("conversation_id", conversationId), import_watermelondb19.Q.where("is_deleted", false)).fetch();
28352
+ const results = await mediaCollection.query(import_watermelondb20.Q.where("conversation_id", conversationId), import_watermelondb20.Q.where("is_deleted", false)).fetch();
28223
28353
  if (results.length === 0) {
28224
28354
  return 0;
28225
28355
  }
@@ -28240,7 +28370,7 @@ async function deleteMediaByConversationOp(ctx, conversationId) {
28240
28370
  }
28241
28371
  async function deleteMediaByMessageOp(ctx, messageId) {
28242
28372
  const mediaCollection = ctx.database.get("media");
28243
- const results = await mediaCollection.query(import_watermelondb19.Q.where("message_id", messageId), import_watermelondb19.Q.where("is_deleted", false)).fetch();
28373
+ const results = await mediaCollection.query(import_watermelondb20.Q.where("message_id", messageId), import_watermelondb20.Q.where("is_deleted", false)).fetch();
28244
28374
  if (results.length === 0) {
28245
28375
  return 0;
28246
28376
  }
@@ -28261,7 +28391,7 @@ async function deleteMediaByMessageOp(ctx, messageId) {
28261
28391
  }
28262
28392
 
28263
28393
  // src/lib/db/userPreferences/operations.ts
28264
- var import_watermelondb20 = __toESM(require_watermelondb());
28394
+ var import_watermelondb21 = __toESM(require_watermelondb());
28265
28395
  function userPreferenceToStored(preference) {
28266
28396
  return {
28267
28397
  uniqueId: preference.id,
@@ -28276,7 +28406,7 @@ function userPreferenceToStored(preference) {
28276
28406
  };
28277
28407
  }
28278
28408
  async function getUserPreferenceOp(ctx, walletAddress) {
28279
- const results = await ctx.userPreferencesCollection.query(import_watermelondb20.Q.where("wallet_address", walletAddress)).fetch();
28409
+ const results = await ctx.userPreferencesCollection.query(import_watermelondb21.Q.where("wallet_address", walletAddress)).fetch();
28280
28410
  return results.length > 0 ? userPreferenceToStored(results[0]) : null;
28281
28411
  }
28282
28412
  async function createUserPreferenceOp(ctx, opts) {
@@ -28296,7 +28426,7 @@ async function createUserPreferenceOp(ctx, opts) {
28296
28426
  return userPreferenceToStored(created);
28297
28427
  }
28298
28428
  async function updateUserPreferenceOp(ctx, walletAddress, opts) {
28299
- const results = await ctx.userPreferencesCollection.query(import_watermelondb20.Q.where("wallet_address", walletAddress)).fetch();
28429
+ const results = await ctx.userPreferencesCollection.query(import_watermelondb21.Q.where("wallet_address", walletAddress)).fetch();
28300
28430
  if (results.length === 0) return null;
28301
28431
  const preference = results[0];
28302
28432
  await ctx.database.write(async () => {
@@ -28324,7 +28454,7 @@ async function updateUserPreferenceOp(ctx, walletAddress, opts) {
28324
28454
  async function setUserPreferenceOp(ctx, walletAddress, opts) {
28325
28455
  const now = Date.now();
28326
28456
  const result = await ctx.database.write(async () => {
28327
- const results = await ctx.userPreferencesCollection.query(import_watermelondb20.Q.where("wallet_address", walletAddress)).fetch();
28457
+ const results = await ctx.userPreferencesCollection.query(import_watermelondb21.Q.where("wallet_address", walletAddress)).fetch();
28328
28458
  if (results.length > 0) {
28329
28459
  const preference = results[0];
28330
28460
  await preference.update((pref) => {
@@ -28372,7 +28502,7 @@ async function updateModelsOp(ctx, walletAddress, models) {
28372
28502
  return updateUserPreferenceOp(ctx, walletAddress, { models });
28373
28503
  }
28374
28504
  async function deleteUserPreferenceOp(ctx, walletAddress) {
28375
- const results = await ctx.userPreferencesCollection.query(import_watermelondb20.Q.where("wallet_address", walletAddress)).fetch();
28505
+ const results = await ctx.userPreferencesCollection.query(import_watermelondb21.Q.where("wallet_address", walletAddress)).fetch();
28376
28506
  if (results.length === 0) return false;
28377
28507
  await ctx.database.write(async () => {
28378
28508
  await results[0].destroyPermanently();
@@ -28387,9 +28517,9 @@ async function migrateFromModelPreferencesOp(ctx, walletAddress) {
28387
28517
  if (existing) {
28388
28518
  return existing;
28389
28519
  }
28390
- const modelResults = await ctx.modelPreferencesCollection.query(import_watermelondb20.Q.where("wallet_address", walletAddress)).fetch();
28520
+ const modelResults = await ctx.modelPreferencesCollection.query(import_watermelondb21.Q.where("wallet_address", walletAddress)).fetch();
28391
28521
  const personalityKey = `${walletAddress}_personality_settings`;
28392
- const personalityResults = await ctx.modelPreferencesCollection.query(import_watermelondb20.Q.where("wallet_address", personalityKey)).fetch();
28522
+ const personalityResults = await ctx.modelPreferencesCollection.query(import_watermelondb21.Q.where("wallet_address", personalityKey)).fetch();
28393
28523
  if (modelResults.length === 0 && personalityResults.length === 0) {
28394
28524
  return null;
28395
28525
  }
@@ -28469,7 +28599,7 @@ var SLIDER_CONFIG = [
28469
28599
  ];
28470
28600
 
28471
28601
  // src/lib/db/settings/operations.ts
28472
- var import_watermelondb21 = __toESM(require_watermelondb());
28602
+ var import_watermelondb22 = __toESM(require_watermelondb());
28473
28603
  function modelPreferenceToStored(preference) {
28474
28604
  return {
28475
28605
  uniqueId: preference.id,
@@ -28478,12 +28608,12 @@ function modelPreferenceToStored(preference) {
28478
28608
  };
28479
28609
  }
28480
28610
  async function getModelPreferenceOp(ctx, walletAddress) {
28481
- const results = await ctx.modelPreferencesCollection.query(import_watermelondb21.Q.where("wallet_address", walletAddress)).fetch();
28611
+ const results = await ctx.modelPreferencesCollection.query(import_watermelondb22.Q.where("wallet_address", walletAddress)).fetch();
28482
28612
  return results.length > 0 ? modelPreferenceToStored(results[0]) : null;
28483
28613
  }
28484
28614
  async function setModelPreferenceOp(ctx, walletAddress, models) {
28485
28615
  const result = await ctx.database.write(async () => {
28486
- const results = await ctx.modelPreferencesCollection.query(import_watermelondb21.Q.where("wallet_address", walletAddress)).fetch();
28616
+ const results = await ctx.modelPreferencesCollection.query(import_watermelondb22.Q.where("wallet_address", walletAddress)).fetch();
28487
28617
  if (results.length > 0) {
28488
28618
  const preference = results[0];
28489
28619
  await preference.update((pref) => {
@@ -28501,7 +28631,7 @@ async function setModelPreferenceOp(ctx, walletAddress, models) {
28501
28631
  return modelPreferenceToStored(result);
28502
28632
  }
28503
28633
  async function deleteModelPreferenceOp(ctx, walletAddress) {
28504
- const results = await ctx.modelPreferencesCollection.query(import_watermelondb21.Q.where("wallet_address", walletAddress)).fetch();
28634
+ const results = await ctx.modelPreferencesCollection.query(import_watermelondb22.Q.where("wallet_address", walletAddress)).fetch();
28505
28635
  if (results.length === 0) return false;
28506
28636
  await ctx.database.write(async () => {
28507
28637
  await results[0].destroyPermanently();
@@ -28888,7 +29018,7 @@ function createMemoryVaultTool(vaultCtx, options, embeddingOptions, cache) {
28888
29018
  }
28889
29019
 
28890
29020
  // src/lib/memory/autoExtract.ts
28891
- var import_watermelondb22 = __toESM(require_watermelondb());
29021
+ var import_watermelondb23 = __toESM(require_watermelondb());
28892
29022
  init_operations2();
28893
29023
  init_types3();
28894
29024
  init_logger();
@@ -29404,6 +29534,7 @@ async function retain(content, ctx, options = {}) {
29404
29534
  const updated = await updateVaultMemoryOp(ctx.vaultCtx, targetId, {
29405
29535
  content: existing.content,
29406
29536
  proofCountIncrement: 1,
29537
+ observationSourceIds: options.sourceChunkIds,
29407
29538
  sourceChunkIds: mergedSourceIds,
29408
29539
  // resurrect encodes the decay gate: ACTIVE target → { preserveUpdatedAt:
29409
29540
  // true } (main's normal re-observation path — bump proof_count without
@@ -29647,6 +29778,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
29647
29778
  const updated = await updateVaultMemoryOp(ctx.vaultCtx, decision.targetId, {
29648
29779
  content: existing.content,
29649
29780
  proofCountIncrement: 1,
29781
+ observationSourceIds: options.sourceChunkIds,
29650
29782
  sourceChunkIds: mergedSourceIds,
29651
29783
  // ACTIVE target → { preserveUpdatedAt: true } (main's normal re-observation
29652
29784
  // path); ARCHIVED (non-superseded, non-deleted) → { restore: true } and no
@@ -29696,6 +29828,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
29696
29828
  const updated = await updateVaultMemoryOp(ctx.vaultCtx, decision.targetId, {
29697
29829
  content: decision.content,
29698
29830
  proofCountIncrement: 1,
29831
+ observationSourceIds: options.sourceChunkIds,
29699
29832
  sourceChunkIds: mergedSourceIds,
29700
29833
  embedding: JSON.stringify(newEmbedding),
29701
29834
  embeddingModel: consolidatedModel,
@@ -29747,7 +29880,7 @@ async function assertMergeTargetGoneOrThrow(ctx, targetId) {
29747
29880
  // src/lib/memory/autoExtract.ts
29748
29881
  async function isMemoryTopicsUserManaged(ctx, memoryId) {
29749
29882
  try {
29750
- const rows = await ctx.database.get(VaultMemory.table).query(import_watermelondb22.Q.where("id", memoryId)).fetch();
29883
+ const rows = await ctx.database.get(VaultMemory.table).query(import_watermelondb23.Q.where("id", memoryId)).fetch();
29751
29884
  return rows[0]?.topicsUserManaged === true;
29752
29885
  } catch {
29753
29886
  return true;
@@ -30334,7 +30467,7 @@ function createAutoExtractor(options) {
30334
30467
  onQuarantined: (info) => options.onMemoryQuarantined?.({ ...info, conversationId })
30335
30468
  }
30336
30469
  });
30337
- if (outcome !== "empty-after-retry") {
30470
+ if (outcome !== "empty-after-retry" && failedCount === 0) {
30338
30471
  const advancedTo = window2[window2.length - 1].id;
30339
30472
  stateFor(conversationId).watermark = advancedTo;
30340
30473
  persistCursor(conversationId, messages, advancedTo, contiguous);
@@ -30495,6 +30628,7 @@ function toDecayInput(c) {
30495
30628
  eventTimeEnd: c.eventTimeEnd,
30496
30629
  eventTimeKind: c.eventTimeKind,
30497
30630
  updatedAt: c.updatedAt,
30631
+ lastObservedAt: c.lastObservedAt,
30498
30632
  archivedAt: c.archivedAt,
30499
30633
  source: c.source,
30500
30634
  trustTier: c.trustTier
@@ -30576,7 +30710,8 @@ function createDecaySweeper(options) {
30576
30710
  for (const c of toArchive) {
30577
30711
  const ok = await archiveVaultMemoryOp(vaultCtx, c.uniqueId, {
30578
30712
  now,
30579
- expectedUpdatedAt: c.updatedAt
30713
+ expectedUpdatedAt: c.updatedAt,
30714
+ expectedLastObservedAt: c.lastObservedAt ?? null
30580
30715
  });
30581
30716
  if (ok) archived++;
30582
30717
  }
@@ -30832,6 +30967,7 @@ function createRecallTool(ctx, toolOptions, callbacks) {
30832
30967
  budget: defaultBudget,
30833
30968
  ...toolOptions?.minScore !== void 0 && { minScore: toolOptions.minScore },
30834
30969
  ...toolOptions?.scopes && { scopes: toolOptions.scopes },
30970
+ ...toolOptions?.memoryIds !== void 0 && { memoryIds: toolOptions.memoryIds },
30835
30971
  ...toolOptions?.folderId !== void 0 && { folderId: toolOptions.folderId },
30836
30972
  ...toolOptions?.excludeConversationId && {
30837
30973
  excludeConversationId: toolOptions.excludeConversationId
@@ -32047,6 +32183,465 @@ function createMessageSourceResolver(ctx) {
32047
32183
  };
32048
32184
  }
32049
32185
 
32186
+ // src/lib/memory/context.ts
32187
+ function shouldRecallMemory(query) {
32188
+ const normalized = query.trim().toLowerCase().replace(/[.!?。!?¡¿]+$/u, "").replace(/^[¡¿]+/u, "");
32189
+ 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(
32190
+ normalized
32191
+ );
32192
+ }
32193
+ async function assembleMemoryContext(options) {
32194
+ const { query, recall: recall2, loadFacts, loadSessionRefs } = options;
32195
+ const memoryIds = options.memoryIds ?? options.recallOptions?.memoryIds;
32196
+ const ranked = shouldRecallMemory(query);
32197
+ const degraded = [];
32198
+ const guard = async (lane, run, fallback) => {
32199
+ try {
32200
+ return await run();
32201
+ } catch (error) {
32202
+ degraded.push(lane);
32203
+ try {
32204
+ options.onDegraded?.(lane, error);
32205
+ } catch {
32206
+ }
32207
+ return fallback;
32208
+ }
32209
+ };
32210
+ const scoped = memoryIds !== void 0 || options.recallOptions?.scopes !== void 0 || options.recallOptions?.folderId !== void 0;
32211
+ const allowed = memoryIds !== void 0 ? new Set(memoryIds) : void 0;
32212
+ const filters = {
32213
+ ...options.recallOptions?.scopes && { scopes: options.recallOptions.scopes },
32214
+ ...options.recallOptions?.folderId !== void 0 && {
32215
+ folderId: options.recallOptions.folderId
32216
+ }
32217
+ };
32218
+ const active = (m) => !m.isDeleted && !m.archivedAt && !m.supersededBy && m.trustTier !== "quarantined" && (!allowed || allowed.has(m.uniqueId));
32219
+ const asItem = (m, lane, score = 1) => ({
32220
+ id: m.uniqueId,
32221
+ content: m.content,
32222
+ score,
32223
+ lane,
32224
+ sourceIds: m.sourceChunkIds ?? []
32225
+ });
32226
+ const empty = {
32227
+ memories: [],
32228
+ usedBudget: options.recallOptions?.budget ?? "low",
32229
+ reranked: false,
32230
+ candidateCount: 0
32231
+ };
32232
+ const [facts, episodes, profile, session] = await Promise.all([
32233
+ ranked ? guard(
32234
+ "fact",
32235
+ () => recall2(query, { ...options.recallOptions, types: ["fact"], limit: 20, memoryIds }),
32236
+ empty
32237
+ ) : empty,
32238
+ ranked && !scoped && options.includeEpisodes !== false ? guard(
32239
+ "episode",
32240
+ () => recall2(query, {
32241
+ ...options.recallOptions,
32242
+ types: ["chunk"],
32243
+ limit: 4,
32244
+ minScore: 0.5,
32245
+ onDiagnostics: void 0
32246
+ }),
32247
+ empty
32248
+ ) : empty,
32249
+ loadFacts ? guard(
32250
+ "profile",
32251
+ async () => {
32252
+ const stable = await loadFacts({
32253
+ ...filters,
32254
+ memoryIds,
32255
+ factTypes: ["identity", "preference", "constraint", "relationship"],
32256
+ limit: 8
32257
+ });
32258
+ const dynamic = await loadFacts({
32259
+ ...filters,
32260
+ memoryIds,
32261
+ factTypes: ["ongoing_context", "plan"],
32262
+ limit: 4
32263
+ });
32264
+ return [...stable, ...dynamic].filter(active).map((m) => asItem(m, "profile"));
32265
+ },
32266
+ []
32267
+ ) : [],
32268
+ loadFacts && loadSessionRefs ? guard(
32269
+ "session",
32270
+ async () => {
32271
+ const refs = (await loadSessionRefs()).filter((r) => !allowed || allowed.has(r.memoryId)).sort((a, b) => b.score - a.score).slice(0, 10);
32272
+ if (!refs.length) return [];
32273
+ const rows = await loadFacts({ ...filters, memoryIds: refs.map((r) => r.memoryId) });
32274
+ const byId = new Map(rows.filter(active).map((m) => [m.uniqueId, m]));
32275
+ return refs.flatMap((ref) => {
32276
+ const m = byId.get(ref.memoryId);
32277
+ return m ? [asItem(m, "session", ref.score)] : [];
32278
+ });
32279
+ },
32280
+ []
32281
+ ) : []
32282
+ ]);
32283
+ const toItems = (result, lane) => result.memories.filter((m) => !allowed || allowed.has(m.id)).map((m) => ({
32284
+ id: m.id,
32285
+ content: m.content,
32286
+ score: m.score,
32287
+ lane,
32288
+ ...lane === "fact" && { recalled: true },
32289
+ sourceIds: m.sourceChunkIds ?? (m.messageId ? [m.messageId] : [])
32290
+ }));
32291
+ const recalledFacts = toItems(facts, "fact");
32292
+ const recalledScores = /* @__PURE__ */ new Map();
32293
+ const recalledContentScores = /* @__PURE__ */ new Map();
32294
+ for (const item of recalledFacts) {
32295
+ recalledScores.set(item.id, Math.max(recalledScores.get(item.id) ?? -Infinity, item.score));
32296
+ const content = item.content.trim();
32297
+ recalledContentScores.set(
32298
+ content,
32299
+ Math.max(recalledContentScores.get(content) ?? -Infinity, item.score)
32300
+ );
32301
+ }
32302
+ const rankedProfile = profile.map((item) => {
32303
+ const score = Math.max(
32304
+ recalledScores.get(item.id) ?? -Infinity,
32305
+ recalledContentScores.get(item.content.trim()) ?? -Infinity
32306
+ );
32307
+ return score === -Infinity ? item : { ...item, score, recalled: true };
32308
+ });
32309
+ const lanes = [
32310
+ [rankedProfile, 2e3],
32311
+ [recalledFacts, 6e3],
32312
+ [toItems(episodes, "episode"), 3e3],
32313
+ [session, 1e3]
32314
+ ];
32315
+ const items = [];
32316
+ const seenIds = /* @__PURE__ */ new Set();
32317
+ const seenContent = /* @__PURE__ */ new Set();
32318
+ let remaining = Math.max(0, options.maxChars ?? 12e3);
32319
+ let truncated = false;
32320
+ for (const [candidates, laneBudget] of lanes) {
32321
+ let laneRemaining = Math.min(laneBudget, remaining);
32322
+ for (const item of candidates) {
32323
+ const content = item.content?.trim();
32324
+ const key = `${item.lane === "episode" ? "episode" : "fact"}:${item.id}`;
32325
+ if (!content || seenIds.has(key) || seenContent.has(content)) continue;
32326
+ if (content.length > laneRemaining) {
32327
+ truncated = true;
32328
+ continue;
32329
+ }
32330
+ items.push({ ...item, content });
32331
+ seenIds.add(key);
32332
+ seenContent.add(content);
32333
+ remaining -= content.length;
32334
+ laneRemaining -= content.length;
32335
+ }
32336
+ }
32337
+ return { items, ranked, rankedCount: recalledFacts.length, degraded, truncated };
32338
+ }
32339
+
32340
+ // src/lib/memory/durableExtraction.ts
32341
+ var import_watermelondb24 = __toESM(require_watermelondb());
32342
+ init_encryption();
32343
+ init_operations();
32344
+ init_models();
32345
+ var MAX_JOBS_PER_PASS = 3;
32346
+ var MAX_ATTEMPTS = 3;
32347
+ function idsOf(job) {
32348
+ return JSON.parse(String(job._getRaw("message_ids")));
32349
+ }
32350
+ function seqOf(job) {
32351
+ const raw = job._getRaw("watermark_seq");
32352
+ return typeof raw === "number" && raw > 0 ? raw : void 0;
32353
+ }
32354
+ function createDurableAutoExtractor(options) {
32355
+ const vault = options.retainCtx.vaultCtx;
32356
+ const database = vault.database;
32357
+ const owner = vault.userId ?? vault.walletAddress;
32358
+ if (!owner) throw new Error("Durable extraction requires a user or wallet owner");
32359
+ const jobs = database.get(ExtractionJob.table);
32360
+ const storage = {
32361
+ database,
32362
+ messagesCollection: database.get("history"),
32363
+ conversationsCollection: database.get("conversations"),
32364
+ walletAddress: vault.walletAddress,
32365
+ signMessage: vault.signMessage,
32366
+ embeddedWalletSigner: vault.embeddedWalletSigner
32367
+ };
32368
+ const folderId = options.folderId ?? null;
32369
+ let disposed = false;
32370
+ let running = false;
32371
+ let wakeRequested = false;
32372
+ let timer;
32373
+ let writes = Promise.resolve();
32374
+ let storeFailures = 0;
32375
+ const attempts = /* @__PURE__ */ new Map();
32376
+ const reportError = (error, conversationId) => {
32377
+ try {
32378
+ options.onError?.(error instanceof Error ? error : new Error(String(error)), conversationId);
32379
+ } catch {
32380
+ }
32381
+ };
32382
+ const currentScope = () => {
32383
+ try {
32384
+ const value = typeof options.scope === "function" ? options.scope() : options.scope;
32385
+ return value ?? "private";
32386
+ } catch (error) {
32387
+ reportError(error);
32388
+ return "private";
32389
+ }
32390
+ };
32391
+ function schedule(delay) {
32392
+ if (disposed) return;
32393
+ if (running || timer !== void 0) {
32394
+ if (running) wakeRequested = true;
32395
+ return;
32396
+ }
32397
+ timer = setTimeout(() => {
32398
+ timer = void 0;
32399
+ void drain();
32400
+ }, delay);
32401
+ }
32402
+ async function extractBatch(messages, conversationId, ids, jobScope, jobFolderId) {
32403
+ let watchdog;
32404
+ try {
32405
+ return await Promise.race([
32406
+ new Promise((resolve, reject) => {
32407
+ const worker = createAutoExtractor({
32408
+ ...options,
32409
+ retainCtx: {
32410
+ ...options.retainCtx,
32411
+ vaultCtx: {
32412
+ ...vault,
32413
+ canWrite: async () => !disposed && await storage.conversationsCollection.query(import_watermelondb24.Q.where("conversation_id", conversationId), import_watermelondb24.Q.where("is_deleted", false)).fetchCount() > 0 && await storage.messagesCollection.query(import_watermelondb24.Q.where("conversation_id", conversationId), import_watermelondb24.Q.where("id", import_watermelondb24.Q.oneOf(ids))).fetchCount() === ids.length && (!vault.canWrite || await vault.canWrite()) && !disposed
32414
+ }
32415
+ },
32416
+ // Never publish a private queued observation after a mode flip.
32417
+ scope: jobScope,
32418
+ folderId: jobFolderId,
32419
+ cursorStore: void 0,
32420
+ windowSize: 20,
32421
+ maxWindowSize: 20,
32422
+ onTurnComplete: resolve,
32423
+ onError: reject
32424
+ });
32425
+ worker.processTurn(messages, conversationId);
32426
+ worker.dispose();
32427
+ }),
32428
+ new Promise((_resolve, reject) => {
32429
+ watchdog = setTimeout(
32430
+ () => reject(new Error("Extraction did not settle in time; retained for retry")),
32431
+ options.batchTimeoutMs ?? 18e4
32432
+ );
32433
+ })
32434
+ ]);
32435
+ } finally {
32436
+ if (watchdog !== void 0) clearTimeout(watchdog);
32437
+ }
32438
+ }
32439
+ async function drain() {
32440
+ if (disposed || running) return;
32441
+ running = true;
32442
+ wakeRequested = false;
32443
+ let retry = false;
32444
+ let scheduleAfterSuccess = false;
32445
+ try {
32446
+ await writes;
32447
+ const pending = await jobs.query(import_watermelondb24.Q.where("owner_key", owner), import_watermelondb24.Q.where("message_ids", import_watermelondb24.Q.notEq("[]"))).fetch();
32448
+ storeFailures = 0;
32449
+ let processed = 0;
32450
+ for (const job of pending) {
32451
+ if (disposed) break;
32452
+ const attempted = attempts.get(job.id) ?? 0;
32453
+ if (attempted >= MAX_ATTEMPTS) continue;
32454
+ if (processed >= MAX_JOBS_PER_PASS) {
32455
+ scheduleAfterSuccess = true;
32456
+ break;
32457
+ }
32458
+ processed++;
32459
+ const conversationId = String(job._getRaw("conversation_id"));
32460
+ try {
32461
+ const conversations = await storage.conversationsCollection.query(import_watermelondb24.Q.where("conversation_id", conversationId), import_watermelondb24.Q.where("is_deleted", false)).fetchCount();
32462
+ if (!conversations) {
32463
+ await database.write(() => job.destroyPermanently());
32464
+ continue;
32465
+ }
32466
+ const ids = idsOf(job).slice(0, 20);
32467
+ const loaded = await Promise.all(ids.map((id) => getMessageOp(storage, id)));
32468
+ const missing = ids.filter((_id, index) => loaded[index] === null);
32469
+ if (missing.length) {
32470
+ if (attempted < MAX_ATTEMPTS - 1)
32471
+ throw new Error("Source messages not yet available; retained for retry");
32472
+ const dropped = new Set(missing);
32473
+ await database.write(
32474
+ () => job.update(
32475
+ (r) => r._setRaw(
32476
+ "message_ids",
32477
+ JSON.stringify(idsOf(job).filter((id) => !dropped.has(id)))
32478
+ )
32479
+ )
32480
+ );
32481
+ attempts.delete(job.id);
32482
+ scheduleAfterSuccess = true;
32483
+ reportError(
32484
+ new Error(
32485
+ `Dropped ${missing.length} unresolvable source id(s) to unblock extraction`
32486
+ ),
32487
+ conversationId
32488
+ );
32489
+ continue;
32490
+ }
32491
+ if (loaded.some(
32492
+ (message) => message && (message.decryptionStatus || isEncrypted(message.content))
32493
+ )) {
32494
+ throw new Error("Source messages are locked; retained for retry");
32495
+ }
32496
+ const messages = loaded.flatMap(
32497
+ (m) => m && m.conversationId === conversationId && (m.role === "user" || m.role === "assistant") ? [{ id: m.uniqueId, role: m.role, content: m.content }] : []
32498
+ );
32499
+ let success = messages.length === 0;
32500
+ if (messages.length) {
32501
+ const result = await extractBatch(
32502
+ messages,
32503
+ conversationId,
32504
+ ids,
32505
+ currentScope() === "private" ? "private" : String(job._getRaw("scope")),
32506
+ job._getRaw("folder_id") ?? null
32507
+ );
32508
+ success = result.failedCount === 0 && result.outcome !== "empty-after-retry";
32509
+ options.onTurnComplete?.(result);
32510
+ }
32511
+ if (!success) throw new Error("Extraction batch incomplete; retained for retry");
32512
+ attempts.delete(job.id);
32513
+ const sequences = /* @__PURE__ */ new Map();
32514
+ for (const message of loaded)
32515
+ if (message && message.messageId > 0)
32516
+ sequences.set(message.uniqueId, message.messageId);
32517
+ await database.write(async () => {
32518
+ const current = idsOf(job);
32519
+ const acknowledged = ids.filter((id) => current.includes(id));
32520
+ if (!acknowledged.length) return;
32521
+ const done = new Set(acknowledged);
32522
+ const remaining = current.filter((id) => !done.has(id));
32523
+ if (remaining.length) {
32524
+ await job.update(
32525
+ (r) => r._setRaw("message_ids", JSON.stringify([...acknowledged.slice(-2), ...remaining]))
32526
+ );
32527
+ } else await job.update((r) => r._setRaw("message_ids", "[]"));
32528
+ const newest = acknowledged[acknowledged.length - 1];
32529
+ await job.update((r) => {
32530
+ r._setRaw("watermark", newest);
32531
+ const sequence = sequences.get(newest);
32532
+ if (sequence !== void 0) {
32533
+ const prior = seqOf(job);
32534
+ r._setRaw(
32535
+ "watermark_seq",
32536
+ prior === void 0 ? sequence : Math.max(prior, sequence)
32537
+ );
32538
+ }
32539
+ });
32540
+ });
32541
+ scheduleAfterSuccess = true;
32542
+ } catch (error) {
32543
+ attempts.set(job.id, attempted + 1);
32544
+ retry = true;
32545
+ reportError(error, conversationId);
32546
+ }
32547
+ }
32548
+ } catch (error) {
32549
+ retry = ++storeFailures < 3;
32550
+ reportError(error);
32551
+ } finally {
32552
+ running = false;
32553
+ const woken = wakeRequested;
32554
+ wakeRequested = false;
32555
+ if (retry || scheduleAfterSuccess || woken)
32556
+ schedule(retry ? options.retryDelayMs ?? 3e4 : 0);
32557
+ }
32558
+ }
32559
+ schedule(0);
32560
+ return {
32561
+ processTurn(messages, conversationId) {
32562
+ if (disposed || !conversationId || !messages.length) return false;
32563
+ const ids = messages.map((m) => m.id);
32564
+ const scope = currentScope();
32565
+ writes = writes.then(
32566
+ () => database.write(async () => {
32567
+ const existing = await jobs.query(import_watermelondb24.Q.where("owner_key", owner), import_watermelondb24.Q.where("conversation_id", conversationId)).fetch();
32568
+ const job = existing.find(
32569
+ (candidate) => candidate._getRaw("scope") === scope && (candidate._getRaw("folder_id") ?? null) === folderId
32570
+ );
32571
+ const positions = new Map(ids.map((id, index) => [id, index]));
32572
+ const rows = await storage.messagesCollection.query(import_watermelondb24.Q.where("id", import_watermelondb24.Q.oneOf(ids))).fetch();
32573
+ const sequences = /* @__PURE__ */ new Map();
32574
+ for (const row of rows) {
32575
+ const sequence = Number(row._getRaw("message_id"));
32576
+ if (Number.isFinite(sequence) && sequence > 0) sequences.set(row.id, sequence);
32577
+ }
32578
+ let boundary = -1;
32579
+ let observedSeq = 0;
32580
+ const foreignSources = /* @__PURE__ */ new Set();
32581
+ for (const prior of existing) {
32582
+ const sources = [...idsOf(prior), String(prior._getRaw("watermark") ?? "")];
32583
+ for (const id of sources) {
32584
+ boundary = Math.max(boundary, positions.get(id) ?? -1);
32585
+ if (prior !== job) foreignSources.add(id);
32586
+ }
32587
+ observedSeq = Math.max(observedSeq, seqOf(prior) ?? 0);
32588
+ for (const id of idsOf(prior))
32589
+ observedSeq = Math.max(observedSeq, sequences.get(id) ?? 0);
32590
+ }
32591
+ if (observedSeq > 0)
32592
+ ids.forEach((id, index) => {
32593
+ const sequence = sequences.get(id);
32594
+ if (sequence !== void 0 && sequence <= observedSeq)
32595
+ boundary = Math.max(boundary, index);
32596
+ });
32597
+ if (!existing.length && options.cursorStore) {
32598
+ try {
32599
+ const cursor = options.cursorStore.get(conversationId);
32600
+ if (cursor) boundary = Math.max(boundary, positions.get(cursor) ?? -1);
32601
+ } catch (error) {
32602
+ reportError(error, conversationId);
32603
+ }
32604
+ }
32605
+ if (boundary < 0 && existing.some((prior) => idsOf(prior).length > 0 || seqOf(prior) !== void 0)) {
32606
+ reportError(
32607
+ new Error("Extraction boundary unresolved; skipped rather than re-observing"),
32608
+ conversationId
32609
+ );
32610
+ return;
32611
+ }
32612
+ const start = boundary >= 0 ? boundary + 1 : Math.max(0, ids.length - Math.max(1, options.windowSize ?? 6));
32613
+ if (start >= ids.length) return;
32614
+ const ownWatermark = job?._getRaw("watermark");
32615
+ const atOwnWatermark = !!job && boundary >= 0 && (ids[boundary] === ownWatermark || sequences.get(ids[boundary]) !== void 0 && sequences.get(ids[boundary]) === seqOf(job));
32616
+ const overlapStart = atOwnWatermark ? Math.max(0, boundary - 1) : start;
32617
+ const fresh = ids.slice(overlapStart).filter((id) => !foreignSources.has(id));
32618
+ if (!fresh.length) return;
32619
+ if (job) {
32620
+ await job.update(
32621
+ (r) => r._setRaw("message_ids", JSON.stringify([.../* @__PURE__ */ new Set([...idsOf(job), ...fresh])]))
32622
+ );
32623
+ attempts.delete(job.id);
32624
+ } else {
32625
+ await jobs.create((r) => {
32626
+ r._setRaw("owner_key", owner);
32627
+ r._setRaw("conversation_id", conversationId);
32628
+ r._setRaw("scope", scope);
32629
+ r._setRaw("folder_id", folderId);
32630
+ r._setRaw("message_ids", JSON.stringify([...new Set(fresh)]));
32631
+ });
32632
+ }
32633
+ })
32634
+ ).then(() => schedule(options.debounceMs ?? 2e4)).catch((error) => reportError(error, conversationId));
32635
+ return true;
32636
+ },
32637
+ isProcessing: () => running,
32638
+ dispose() {
32639
+ disposed = true;
32640
+ if (timer !== void 0) clearTimeout(timer);
32641
+ }
32642
+ };
32643
+ }
32644
+
32050
32645
  // src/tools/appBuilderPrompt.ts
32051
32646
  var APP_BUILDER_PROMPT = `App Builder tools (create_file, patch_file, and the rest described below) are available this turn, but they are OPTIONAL \u2014 having them does not mean you should build anything.
32052
32647
 
@@ -37752,6 +38347,7 @@ function buildSystemPrompt(ctx, options) {
37752
38347
  activatedToolSetNames,
37753
38348
  analyzeStyle,
37754
38349
  archiveVaultMemoryOp,
38350
+ assembleMemoryContext,
37755
38351
  backfillMemoryTopicsOp,
37756
38352
  buildConnectorGuidance,
37757
38353
  buildDeniedToolsRider,
@@ -37786,6 +38382,7 @@ function buildSystemPrompt(ctx, options) {
37786
38382
  createConversationOp,
37787
38383
  createCryptoPricePreProcessor,
37788
38384
  createDecaySweeper,
38385
+ createDurableAutoExtractor,
37789
38386
  createLlmDecayClassifier,
37790
38387
  createLlmNeighborRefiner,
37791
38388
  createMediaBatchOp,
@@ -37819,6 +38416,7 @@ function buildSystemPrompt(ctx, options) {
37819
38416
  deleteMediaByConversationOp,
37820
38417
  deleteMediaByMessageOp,
37821
38418
  deleteMediaOp,
38419
+ deleteMessageOp,
37822
38420
  deleteModelPreferenceOp,
37823
38421
  deleteProjectOp,
37824
38422
  deleteUserPreferenceOp,
@@ -37943,6 +38541,7 @@ function buildSystemPrompt(ctx, options) {
37943
38541
  setUserPreferenceOp,
37944
38542
  shouldAnalyzeStyle,
37945
38543
  shouldChunkMessage,
38544
+ shouldRecallMemory,
37946
38545
  shouldRefreshTools,
37947
38546
  splitMessagesAtThreshold,
37948
38547
  stampTopicsExtractedAtOp,