@anuma/sdk 7.0.7 → 7.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -26140,6 +26140,11 @@ function parseTopics(value) {
26140
26140
  }
26141
26141
 
26142
26142
  // src/lib/db/entities/operations.ts
26143
+ async function assertCanWrite(ctx) {
26144
+ if (ctx.canWrite && !await ctx.canWrite()) {
26145
+ throw new Error("Memory source is no longer eligible");
26146
+ }
26147
+ }
26143
26148
  function entityToStored(e) {
26144
26149
  return {
26145
26150
  uniqueId: e.id,
@@ -26280,6 +26285,7 @@ async function linkMemoryEntitiesOp(ctx, memoryId, entityInputs, options) {
26280
26285
  let skipped = false;
26281
26286
  let entities = [];
26282
26287
  await ctx.database.write(async () => {
26288
+ await assertCanWrite(ctx);
26283
26289
  const {
26284
26290
  entities: byName,
26285
26291
  operations: entityOps,
@@ -26355,6 +26361,7 @@ async function replaceMemoryEntities(ctx, memoryId, entityInputs, options) {
26355
26361
  let skipped = false;
26356
26362
  let entities = [];
26357
26363
  await ctx.database.write(async () => {
26364
+ await assertCanWrite(ctx);
26358
26365
  const vaultRow = await findVaultRowInWrite(ctx, memoryId);
26359
26366
  if (options.guarded && autoLinkBlocked(vaultRow)) {
26360
26367
  skipped = true;
@@ -26415,6 +26422,7 @@ async function unlinkMemoryEntitiesOp(ctx, memoryIds) {
26415
26422
  const links = await ctx.memoryEntityCollection.query(import_watermelondb18.Q.where("memory_id", import_watermelondb18.Q.oneOf(Array.from(memoryIds)))).fetch();
26416
26423
  if (links.length === 0) return;
26417
26424
  await ctx.database.write(async () => {
26425
+ await assertCanWrite(ctx);
26418
26426
  await ctx.database.batch(...links.map((l) => l.prepareDestroyPermanently()));
26419
26427
  });
26420
26428
  }
@@ -26423,6 +26431,7 @@ async function unlinkAllMemoryEntitiesForUserOp(ctx, userId) {
26423
26431
  const links = await ctx.memoryEntityCollection.query(import_watermelondb18.Q.where("user_id", userId)).fetch();
26424
26432
  if (links.length === 0) return;
26425
26433
  await ctx.database.write(async () => {
26434
+ await assertCanWrite(ctx);
26426
26435
  await ctx.database.batch(...links.map((l) => l.prepareDestroyPermanently()));
26427
26436
  });
26428
26437
  }
@@ -26597,6 +26606,11 @@ function visibilityConditions(requested) {
26597
26606
  function isKinded(record) {
26598
26607
  return record.kind !== null && record.kind !== void 0;
26599
26608
  }
26609
+ async function assertCanWrite2(ctx) {
26610
+ if (ctx.canWrite && !await ctx.canWrite()) {
26611
+ throw new Error("Memory source is no longer eligible");
26612
+ }
26613
+ }
26600
26614
  function assertValidKindLevel(kind, level) {
26601
26615
  const hasKind = kind !== null && kind !== void 0;
26602
26616
  if (hasKind && !MEMORY_KINDS.includes(kind)) {
@@ -26777,8 +26791,7 @@ async function createVaultMemoryOp(ctx, opts) {
26777
26791
  ctx.embeddedWalletSigner
26778
26792
  ) : opts.content;
26779
26793
  const created = await ctx.database.write(async () => {
26780
- if (ctx.canWrite && !await ctx.canWrite())
26781
- throw new Error("Memory source is no longer eligible");
26794
+ await assertCanWrite2(ctx);
26782
26795
  return ctx.vaultMemoryCollection.create(
26783
26796
  (record) => populateNewVaultMemory(record, ctx, opts, encryptedContent, encryptedKindValue)
26784
26797
  );
@@ -26797,8 +26810,7 @@ async function createSupersedingMemoryOp(ctx, opts, targetId) {
26797
26810
  ) : opts.content;
26798
26811
  let createdRecord = null;
26799
26812
  await ctx.database.write(async () => {
26800
- if (ctx.canWrite && !await ctx.canWrite())
26801
- throw new Error("Memory source is no longer eligible");
26813
+ await assertCanWrite2(ctx);
26802
26814
  let target;
26803
26815
  try {
26804
26816
  target = await ctx.vaultMemoryCollection.find(targetId);
@@ -26890,8 +26902,7 @@ async function createVaultMemoriesBatchOp(ctx, optionsArray) {
26890
26902
  })
26891
26903
  );
26892
26904
  const created = await ctx.database.write(async () => {
26893
- if (ctx.canWrite && !await ctx.canWrite())
26894
- throw new Error("Memory source is no longer eligible");
26905
+ await assertCanWrite2(ctx);
26895
26906
  const prepared = optionsArray.map(
26896
26907
  (opts, i) => ctx.vaultMemoryCollection.prepareCreate(
26897
26908
  (record) => populateNewVaultMemory(record, ctx, opts, encryptedContents[i], encryptedKindValues[i])
@@ -27182,8 +27193,7 @@ async function updateVaultMemoryOp(ctx, id, opts) {
27182
27193
  const record = probe;
27183
27194
  const originalUpdatedAt = record.updatedAt.getTime();
27184
27195
  await ctx.database.write(async () => {
27185
- if (ctx.canWrite && !await ctx.canWrite())
27186
- throw new Error("Memory source is no longer eligible");
27196
+ await assertCanWrite2(ctx);
27187
27197
  if (record.isDeleted || record.supersededBy || !isOwnedByCtxUser(ctx, record) || opts.freeFormOnly && isKinded(record)) {
27188
27198
  stale = true;
27189
27199
  return;
@@ -27294,6 +27304,7 @@ async function setMemoryEntitiesOp(ctx, memoryId, entities) {
27294
27304
  let stale = false;
27295
27305
  const originalUpdatedAt = record.updatedAt.getTime();
27296
27306
  await ctx.database.write(async (writer) => {
27307
+ await assertCanWrite2(ctx);
27297
27308
  if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) {
27298
27309
  stale = true;
27299
27310
  return;
@@ -27335,6 +27346,7 @@ async function clearMemoryTopicsOverrideOp(ctx, memoryId, options) {
27335
27346
  const originalUpdatedAt = record.updatedAt.getTime();
27336
27347
  let cleared = false;
27337
27348
  await ctx.database.write(async () => {
27349
+ await assertCanWrite2(ctx);
27338
27350
  if (options?.unlessTopicsRecorded && parseTopics(record.topics) !== null) return;
27339
27351
  cleared = true;
27340
27352
  await record.update((r) => {
@@ -27358,6 +27370,7 @@ async function setMemoryVisibilityOp(ctx, id, opts) {
27358
27370
  if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return null;
27359
27371
  let stale = false;
27360
27372
  await ctx.database.write(async () => {
27373
+ await assertCanWrite2(ctx);
27361
27374
  if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) {
27362
27375
  stale = true;
27363
27376
  return;
@@ -27386,6 +27399,7 @@ async function deleteVaultMemoryOp(ctx, id) {
27386
27399
  if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return false;
27387
27400
  let stale = false;
27388
27401
  await ctx.database.write(async () => {
27402
+ await assertCanWrite2(ctx);
27389
27403
  if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) {
27390
27404
  stale = true;
27391
27405
  return;
@@ -27423,8 +27437,7 @@ async function supersedeVaultMemoryOp(ctx, id, supersededById) {
27423
27437
  }
27424
27438
  let stale = false;
27425
27439
  await ctx.database.write(async () => {
27426
- if (ctx.canWrite && !await ctx.canWrite())
27427
- throw new Error("Memory source is no longer eligible");
27440
+ await assertCanWrite2(ctx);
27428
27441
  if (record.isDeleted || record.supersededBy || !isOwnedByCtxUser(ctx, record)) {
27429
27442
  stale = true;
27430
27443
  return;
@@ -27586,6 +27599,7 @@ async function stampTopicsExtractedAtOp(ctx, memoryIds, extractedAt, version = T
27586
27599
  for (let i = 0; i < uniqueIds.length; i += CHUNK) {
27587
27600
  const chunkIds = uniqueIds.slice(i, i + CHUNK);
27588
27601
  await ctx.database.write(async () => {
27602
+ await assertCanWrite2(ctx);
27589
27603
  const records = [];
27590
27604
  for (const id of chunkIds) {
27591
27605
  try {
@@ -27619,6 +27633,7 @@ async function relinkMemoryTopicsOp(ctx, memoryIds) {
27619
27633
  for (const id of Array.from(new Set(memoryIds))) {
27620
27634
  try {
27621
27635
  await ctx.database.write(async (writer) => {
27636
+ await assertCanWrite2(ctx);
27622
27637
  let record;
27623
27638
  try {
27624
27639
  record = await ctx.vaultMemoryCollection.find(id);
@@ -27649,6 +27664,7 @@ async function backfillMemoryTopicsOp(ctx, memoryIds) {
27649
27664
  for (let i = 0; i < uniqueIds.length; i += CHUNK) {
27650
27665
  const chunkIds = uniqueIds.slice(i, i + CHUNK);
27651
27666
  await ctx.database.write(async () => {
27667
+ await assertCanWrite2(ctx);
27652
27668
  const writes = [];
27653
27669
  for (const id of chunkIds) {
27654
27670
  let record;
@@ -27681,6 +27697,7 @@ async function deleteAllVaultMemoriesForUserOp(ctx, userId) {
27681
27697
  const records = await ctx.vaultMemoryCollection.query(import_watermelondb19.Q.where("user_id", userId), import_watermelondb19.Q.where("is_deleted", false)).fetch();
27682
27698
  if (records.length === 0) return 0;
27683
27699
  await ctx.database.write(async () => {
27700
+ await assertCanWrite2(ctx);
27684
27701
  const prepared = records.map(
27685
27702
  (record) => record.prepareUpdate((r) => {
27686
27703
  r._setRaw("is_deleted", true);
@@ -27735,6 +27752,7 @@ async function archiveVaultMemoryOp(ctx, id, opts) {
27735
27752
  let stale = false;
27736
27753
  const archivedAtValue = opts?.now ?? Date.now();
27737
27754
  await ctx.database.write(async () => {
27755
+ await assertCanWrite2(ctx);
27738
27756
  if (record.isDeleted || !isOwnedByCtxUser(ctx, record) || record.archivedAt !== null) {
27739
27757
  stale = true;
27740
27758
  return;
@@ -27758,6 +27776,7 @@ async function restoreVaultMemoryOp(ctx, id) {
27758
27776
  if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return false;
27759
27777
  let stale = false;
27760
27778
  await ctx.database.write(async () => {
27779
+ await assertCanWrite2(ctx);
27761
27780
  if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) {
27762
27781
  stale = true;
27763
27782
  return;
@@ -27778,6 +27797,7 @@ async function hardDeleteDecayedOp(ctx, id, opts) {
27778
27797
  const now = opts.now ?? Date.now();
27779
27798
  let stale = false;
27780
27799
  await ctx.database.write(async () => {
27800
+ await assertCanWrite2(ctx);
27781
27801
  const archivedAt = record.archivedAt;
27782
27802
  if (record.isDeleted || !isOwnedByCtxUser(ctx, record) || archivedAt === null || now - archivedAt <= opts.hardDeleteWindowMs) {
27783
27803
  stale = true;
@@ -27817,6 +27837,7 @@ async function updateVaultMemoryEmbeddingOp(ctx, id, embedding, embeddingModel,
27817
27837
  }
27818
27838
  let written = false;
27819
27839
  await ctx.database.write(async () => {
27840
+ await assertCanWrite2(ctx);
27820
27841
  if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return;
27821
27842
  const originalUpdatedAt = record.updatedAt.getTime();
27822
27843
  if (originalUpdatedAt !== readUpdatedAt || record._getRaw("content") !== readStoredContent)
@@ -31488,6 +31509,13 @@ function restoreCandidates(candidates, redactor, ownNames) {
31488
31509
  ).map((c) => c.candidate);
31489
31510
  }
31490
31511
  async function extractAndRetain(messages, retainCtx, options) {
31512
+ const { memoryStore, signal } = options;
31513
+ if (memoryStore === null) throw new Error("Memory store is not ready");
31514
+ if (memoryStore && options.folderId !== void 0 && options.folderId !== null)
31515
+ throw new Error("Remote memory extraction does not support folders");
31516
+ if (memoryStore && options.extract.piiRedaction && !memoryStore.masksEmbeddingInput)
31517
+ throw new Error("PII-redacted extraction requires a memory store that masks embedding inputs");
31518
+ signal?.throwIfAborted();
31491
31519
  const minConfidence = options.minConfidence ?? DEFAULT_MIN_CONFIDENCE;
31492
31520
  const resolvedConsolidatePii = options.consolidateOptions?.piiRedaction ?? options.extract.piiRedaction;
31493
31521
  const consolidateOptions = options.consolidateOptions !== void 0 ? {
@@ -31521,6 +31549,7 @@ async function extractAndRetain(messages, retainCtx, options) {
31521
31549
  }
31522
31550
  });
31523
31551
  const extractMs = Date.now() - tExtract;
31552
+ signal?.throwIfAborted();
31524
31553
  const filtered = candidates.filter((c) => c.confidence >= minConfidence);
31525
31554
  const log = getLogger();
31526
31555
  const screened = screenCandidatesForInjection(filtered);
@@ -31568,16 +31597,33 @@ async function extractAndRetain(messages, retainCtx, options) {
31568
31597
  const results = [];
31569
31598
  const quarantinedInfo = [];
31570
31599
  let failedWrites = 0;
31600
+ let auditRows;
31571
31601
  const tRetain = Date.now();
31572
31602
  for (const { candidate, isQuarantined, reason, signature } of toRetain) {
31573
31603
  try {
31604
+ signal?.throwIfAborted();
31574
31605
  if (isQuarantined) {
31575
- const existingId = await findQuarantinedDuplicateOp(
31576
- retainCtx.vaultCtx,
31577
- candidate.content,
31578
- candidate.sourceMessageIds,
31579
- { scope: options.scope ?? "private", folderId: options.folderId ?? null }
31580
- ).catch(() => null);
31606
+ let existingId;
31607
+ if (memoryStore) {
31608
+ auditRows ?? (auditRows = memoryStore.list({
31609
+ scopes: [options.scope ?? "private"],
31610
+ includeArchived: true,
31611
+ includeQuarantined: true,
31612
+ includeSuperseded: true
31613
+ }));
31614
+ const sourceKey = [...new Set(candidate.sourceMessageIds)].sort().join("\0");
31615
+ const normalize = (value) => value.normalize("NFKC").trim().replace(/\s+/g, " ").toLowerCase();
31616
+ existingId = (await auditRows).find(
31617
+ (row) => row.trustTier === "quarantined" && row.scope === (options.scope ?? "private") && [...new Set(row.sourceChunkIds ?? [])].sort().join("\0") === sourceKey && normalize(row.content) === normalize(candidate.content)
31618
+ )?.uniqueId ?? null;
31619
+ } else {
31620
+ existingId = await findQuarantinedDuplicateOp(
31621
+ retainCtx.vaultCtx,
31622
+ candidate.content,
31623
+ candidate.sourceMessageIds,
31624
+ { scope: options.scope ?? "private", folderId: options.folderId ?? null }
31625
+ ).catch(() => null);
31626
+ }
31581
31627
  if (existingId) {
31582
31628
  quarantinedInfo.push({
31583
31629
  candidate,
@@ -31588,18 +31634,26 @@ async function extractAndRetain(messages, retainCtx, options) {
31588
31634
  continue;
31589
31635
  }
31590
31636
  }
31591
- const result = await retain(candidate.content, retainCtx, {
31637
+ const retainOptions = {
31592
31638
  source: "auto-extracted",
31593
31639
  sourceChunkIds: candidate.sourceMessageIds,
31594
31640
  respectTombstones: true,
31595
31641
  ...options.scope !== void 0 && { scope: options.scope },
31596
- ...options.folderId !== void 0 && { folderId: options.folderId },
31597
31642
  ...consolidateOptions !== void 0 && { consolidateOptions },
31598
31643
  ...candidate.eventTime !== null && { eventTime: candidate.eventTime },
31599
31644
  factType: candidate.type,
31600
31645
  ...isQuarantined && { trustTier: "quarantined", enableAutoMerge: false }
31646
+ };
31647
+ const result = memoryStore ? await memoryStore.retain(candidate.content, {
31648
+ ...retainOptions,
31649
+ canWrite: retainCtx.vaultCtx.canWrite,
31650
+ signal
31651
+ }) : await retain(candidate.content, retainCtx, {
31652
+ ...retainOptions,
31653
+ ...options.folderId !== void 0 && { folderId: options.folderId }
31601
31654
  });
31602
31655
  if (isQuarantined) {
31656
+ auditRows = void 0;
31603
31657
  const info = {
31604
31658
  candidate,
31605
31659
  memoryId: result.memoryId,
@@ -31618,9 +31672,16 @@ async function extractAndRetain(messages, retainCtx, options) {
31618
31672
  }
31619
31673
  succeededCandidates.push(candidate);
31620
31674
  results.push(result);
31621
- if (result.action !== "suppressed" && options.entityCtx && candidate.entities.length > 0) {
31675
+ if (result.action !== "suppressed" && candidate.entities.length > 0) {
31622
31676
  try {
31623
- if (!await isMemoryTopicsUserManaged(options.entityCtx, result.memoryId)) {
31677
+ signal?.throwIfAborted();
31678
+ if (memoryStore) {
31679
+ await memoryStore.addTopics(result.memoryId, candidate.entities, {
31680
+ unlessUserManaged: true,
31681
+ canWrite: retainCtx.vaultCtx.canWrite,
31682
+ signal
31683
+ });
31684
+ } else if (options.entityCtx && !await isMemoryTopicsUserManaged(options.entityCtx, result.memoryId)) {
31624
31685
  await linkMemoryEntitiesOp(options.entityCtx, result.memoryId, candidate.entities, {
31625
31686
  unlessTopicsUserManaged: true
31626
31687
  });
@@ -31868,7 +31929,7 @@ function createAutoExtractor(options) {
31868
31929
  };
31869
31930
  const consolidateOptions = options.consolidate ? { ...options.consolidate, ...subPassAuth(options.consolidate.baseUrl) } : void 0;
31870
31931
  const injectionClassifierOptions = options.injectionClassifier ? { ...options.injectionClassifier, ...subPassAuth(options.injectionClassifier.baseUrl) } : void 0;
31871
- if (options.retainCtx.vaultCtx.entityCtx && !options.entityCtx) {
31932
+ if (!options.memoryStore && options.retainCtx.vaultCtx.entityCtx && !options.entityCtx) {
31872
31933
  getLogger().warn(
31873
31934
  "[memory/extract] retainCtx.vaultCtx.entityCtx is set but extractor was created without `entityCtx` \u2014 W5 graph lane will receive no writes"
31874
31935
  );
@@ -31913,6 +31974,8 @@ function createAutoExtractor(options) {
31913
31974
  try {
31914
31975
  const { candidates, results, failedCount, outcome, failure, funnel, timings, model } = await extractAndRetain(window2, retainCtx, {
31915
31976
  extract,
31977
+ memoryStore: options.memoryStore,
31978
+ signal: options.signal,
31916
31979
  ...options.minConfidence !== void 0 && { minConfidence: options.minConfidence },
31917
31980
  ...options.entityCtx !== void 0 && { entityCtx: options.entityCtx },
31918
31981
  ...options.scope !== void 0 && { scope: options.scope },
@@ -34025,6 +34088,7 @@ function createLocalMemoryStore(options) {
34025
34088
  database,
34026
34089
  entityCollection: database.get("entity"),
34027
34090
  memoryEntityCollection: database.get("memory_entity"),
34091
+ canWrite: options.canWrite,
34028
34092
  ...userId !== void 0 && { userId },
34029
34093
  ...options.allowUnscopedRows !== void 0 && {
34030
34094
  allowUnscopedRows: options.allowUnscopedRows
@@ -34036,10 +34100,21 @@ function createLocalMemoryStore(options) {
34036
34100
  walletAddress: options.walletAddress,
34037
34101
  signMessage: options.signMessage,
34038
34102
  embeddedWalletSigner: options.embeddedWalletSigner,
34103
+ canWrite: options.canWrite,
34039
34104
  ...userId !== void 0 && { userId },
34040
34105
  ...options.singleTenant !== void 0 && { singleTenant: options.singleTenant },
34041
34106
  entityCtx
34042
34107
  };
34108
+ const assertWrite = async (writeOptions) => {
34109
+ writeOptions?.signal?.throwIfAborted();
34110
+ if (writeOptions?.canWrite && !await writeOptions.canWrite()) {
34111
+ throw new Error("Memory source is no longer eligible");
34112
+ }
34113
+ if (options.canWrite && !await options.canWrite()) {
34114
+ throw new Error("Memory source is no longer eligible");
34115
+ }
34116
+ writeOptions?.signal?.throwIfAborted();
34117
+ };
34043
34118
  const vaultCache = options.vaultCache ?? createVaultEmbeddingCache();
34044
34119
  const ownedBy = userId !== void 0 ? [import_watermelondb24.Q.where("user_id", userId)] : [];
34045
34120
  const linksOwnedBy = userId === void 0 ? [] : options.allowUnscopedRows ? [import_watermelondb24.Q.or(import_watermelondb24.Q.where("user_id", userId), import_watermelondb24.Q.where("user_id", null))] : [import_watermelondb24.Q.where("user_id", userId)];
@@ -34151,9 +34226,25 @@ function createLocalMemoryStore(options) {
34151
34226
  archive: (id) => archiveVaultMemoryOp(vaultCtx, id),
34152
34227
  restore: (id) => restoreVaultMemoryOp(vaultCtx, id),
34153
34228
  setTopics: (memoryId, topics) => setMemoryEntitiesOp(vaultCtx, memoryId, topics),
34154
- addTopics: (memoryId, topics) => database.write(async (writer) => {
34229
+ addTopics: (memoryId, topics, writeOptions) => database.write(async (writer) => {
34230
+ await assertWrite(writeOptions);
34155
34231
  const owned = await vaultCtx.vaultMemoryCollection.query(import_watermelondb24.Q.where("id", memoryId), import_watermelondb24.Q.where("is_deleted", false), ...ownedBy).fetchCount();
34156
- return owned > 0 ? writer.callWriter(() => linkMemoryEntitiesOp(entityCtx, memoryId, topics)) : [];
34232
+ return owned > 0 ? writer.callWriter(
34233
+ () => linkMemoryEntitiesOp(
34234
+ {
34235
+ ...entityCtx,
34236
+ canWrite: async () => {
34237
+ await assertWrite(writeOptions);
34238
+ return true;
34239
+ }
34240
+ },
34241
+ memoryId,
34242
+ topics,
34243
+ {
34244
+ unlessTopicsUserManaged: writeOptions?.unlessUserManaged
34245
+ }
34246
+ )
34247
+ ) : [];
34157
34248
  }),
34158
34249
  setVisibility: (id, visibility, visibilityOptions) => setMemoryVisibilityOp(vaultCtx, id, { visibility, ...visibilityOptions }),
34159
34250
  recall: (query, recallOptions) => recall(
@@ -34163,7 +34254,17 @@ function createLocalMemoryStore(options) {
34163
34254
  ),
34164
34255
  retain: (content, retainOptions) => retain(
34165
34256
  content,
34166
- { vaultCtx, embeddingOptions: options.embeddingOptions, vaultCache },
34257
+ {
34258
+ vaultCtx: {
34259
+ ...vaultCtx,
34260
+ canWrite: async () => {
34261
+ await assertWrite(retainOptions);
34262
+ return true;
34263
+ }
34264
+ },
34265
+ embeddingOptions: options.embeddingOptions,
34266
+ vaultCache
34267
+ },
34167
34268
  retainOptions
34168
34269
  ),
34169
34270
  factSource: {
@@ -35013,6 +35114,7 @@ function createDurableAutoExtractor(options) {
35013
35114
  };
35014
35115
  const folderId = options.folderId ?? null;
35015
35116
  let disposed = false;
35117
+ let activeBatch = null;
35016
35118
  let running = false;
35017
35119
  let wakeRequested = false;
35018
35120
  let timer;
@@ -35049,14 +35151,18 @@ function createDurableAutoExtractor(options) {
35049
35151
  }, delay);
35050
35152
  }
35051
35153
  async function extractBatch(messages, conversationId, ids, jobScope, jobFolderId) {
35154
+ if (disposed) throw new Error("Extraction session was disposed");
35052
35155
  let watchdog;
35053
35156
  let cancelled = false;
35157
+ const controller = new AbortController();
35158
+ activeBatch = controller;
35054
35159
  const model = options.modelForScope?.(jobScope) ?? options.extract.model;
35055
35160
  try {
35056
35161
  return await Promise.race([
35057
35162
  new Promise((resolve, reject) => {
35058
35163
  const worker = createAutoExtractor({
35059
35164
  ...options,
35165
+ signal: controller.signal,
35060
35166
  retainCtx: {
35061
35167
  ...options.retainCtx,
35062
35168
  vaultCtx: {
@@ -35085,6 +35191,8 @@ function createDurableAutoExtractor(options) {
35085
35191
  ]);
35086
35192
  } finally {
35087
35193
  cancelled = true;
35194
+ controller.abort();
35195
+ if (activeBatch === controller) activeBatch = null;
35088
35196
  if (watchdog !== void 0) clearTimeout(watchdog);
35089
35197
  }
35090
35198
  }
@@ -35096,6 +35204,7 @@ function createDurableAutoExtractor(options) {
35096
35204
  for (const message of loaded)
35097
35205
  if (message && message.messageId > 0) sequences.set(message.uniqueId, message.messageId);
35098
35206
  await database.write(async () => {
35207
+ if (disposed) return;
35099
35208
  const current = idsOf(job);
35100
35209
  const acknowledged = ids.filter((id) => current.includes(id));
35101
35210
  if (!acknowledged.length) return;
@@ -35268,6 +35377,7 @@ function createDurableAutoExtractor(options) {
35268
35377
  jobScope,
35269
35378
  jobFolderId
35270
35379
  );
35380
+ if (disposed) throw new Error("Extraction session was disposed");
35271
35381
  options.onTurnComplete?.(result);
35272
35382
  return result;
35273
35383
  };
@@ -35304,6 +35414,7 @@ function createDurableAutoExtractor(options) {
35304
35414
  );
35305
35415
  scheduleAfterSuccess = true;
35306
35416
  } catch (error) {
35417
+ if (disposed) break;
35307
35418
  attempts.set(job.id, attempted + 1);
35308
35419
  retry = true;
35309
35420
  reportError(error, conversationId);
@@ -35326,6 +35437,14 @@ function createDurableAutoExtractor(options) {
35326
35437
  schedule(retry ? options.retryDelayMs ?? 3e4 : 0);
35327
35438
  }
35328
35439
  }
35440
+ function dispose() {
35441
+ disposed = true;
35442
+ activeBatch?.abort(options.signal?.reason);
35443
+ if (timer !== void 0) clearTimeout(timer);
35444
+ options.signal?.removeEventListener("abort", dispose);
35445
+ }
35446
+ if (options.signal?.aborted) dispose();
35447
+ else options.signal?.addEventListener("abort", dispose, { once: true });
35329
35448
  schedule(0);
35330
35449
  return {
35331
35450
  processTurn(messages, conversationId) {
@@ -35405,10 +35524,7 @@ function createDurableAutoExtractor(options) {
35405
35524
  return true;
35406
35525
  },
35407
35526
  isProcessing: () => running,
35408
- dispose() {
35409
- disposed = true;
35410
- if (timer !== void 0) clearTimeout(timer);
35411
- }
35527
+ dispose
35412
35528
  };
35413
35529
  }
35414
35530
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anuma/sdk",
3
- "version": "7.0.7",
3
+ "version": "7.1.1",
4
4
  "description": "",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",