@anuma/sdk 7.3.0 → 7.3.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.
@@ -26093,6 +26093,67 @@ var import_watermelondb19 = __toESM(require_watermelondb());
26093
26093
  // src/lib/db/entities/operations.ts
26094
26094
  var import_watermelondb18 = __toESM(require_watermelondb());
26095
26095
 
26096
+ // src/lib/db/memoryVault/types.ts
26097
+ var MEMORY_KINDS = [
26098
+ "display_name",
26099
+ "birth_date",
26100
+ "bio",
26101
+ "occupation",
26102
+ "interest",
26103
+ "gender",
26104
+ "height_cm",
26105
+ "looking_for",
26106
+ "politics",
26107
+ "religion",
26108
+ "ethnicity",
26109
+ "smoking",
26110
+ "drinking",
26111
+ "exercise",
26112
+ "sexuality",
26113
+ "prompt"
26114
+ ];
26115
+ var MEMORY_LEVELS = ["private", "matching", "profile"];
26116
+ var MemoryLevelError = class extends Error {
26117
+ constructor(message) {
26118
+ super(message);
26119
+ this.name = "MemoryLevelError";
26120
+ }
26121
+ };
26122
+ var MemorySourceIneligibleError = class extends Error {
26123
+ constructor() {
26124
+ super("Memory source is no longer eligible");
26125
+ this.name = "MemorySourceIneligibleError";
26126
+ }
26127
+ };
26128
+ var PUBLISHED_SCOPES = /* @__PURE__ */ new Set(["shared", "public"]);
26129
+ function levelFromScope(scope) {
26130
+ return typeof scope === "string" && PUBLISHED_SCOPES.has(scope) ? "matching" : "private";
26131
+ }
26132
+ function scopeForLevel(level) {
26133
+ return level === "private" ? "private" : "shared";
26134
+ }
26135
+ function resolveMemoryLevel(level, scope) {
26136
+ return typeof level === "string" && MEMORY_LEVELS.includes(level) ? level : levelFromScope(scope);
26137
+ }
26138
+ function levelForScopeChange(current, nextScope) {
26139
+ const implied = levelFromScope(nextScope);
26140
+ return implied === "matching" && resolveMemoryLevel(current.level, current.scope) === "profile" ? "profile" : implied;
26141
+ }
26142
+ function parseMedia(value) {
26143
+ if (typeof value !== "string" || value === "") return null;
26144
+ try {
26145
+ const parsed = JSON.parse(value);
26146
+ if (!Array.isArray(parsed)) return null;
26147
+ const refs = parsed.filter((r) => typeof r === "object" && r !== null).map((r) => ({
26148
+ feedItemId: Number(r.feedItemId ?? r.feed_item_id),
26149
+ objectKey: r.objectKey ?? r.object_key ?? null
26150
+ })).filter((r) => Number.isFinite(r.feedItemId));
26151
+ return refs.length > 0 ? refs : null;
26152
+ } catch {
26153
+ return null;
26154
+ }
26155
+ }
26156
+
26096
26157
  // src/lib/db/entities/types.ts
26097
26158
  var ENTITY_KINDS = [
26098
26159
  "person",
@@ -26142,7 +26203,7 @@ function parseTopics(value) {
26142
26203
  // src/lib/db/entities/operations.ts
26143
26204
  async function assertCanWrite(ctx) {
26144
26205
  if (ctx.canWrite && !await ctx.canWrite()) {
26145
- throw new Error("Memory source is no longer eligible");
26206
+ throw new MemorySourceIneligibleError();
26146
26207
  }
26147
26208
  }
26148
26209
  function entityToStored(e) {
@@ -26534,61 +26595,6 @@ function serializeSourceChunkIds(ids) {
26534
26595
  return JSON.stringify(ids.slice(start));
26535
26596
  }
26536
26597
 
26537
- // src/lib/db/memoryVault/types.ts
26538
- var MEMORY_KINDS = [
26539
- "display_name",
26540
- "birth_date",
26541
- "bio",
26542
- "occupation",
26543
- "interest",
26544
- "gender",
26545
- "height_cm",
26546
- "looking_for",
26547
- "politics",
26548
- "religion",
26549
- "ethnicity",
26550
- "smoking",
26551
- "drinking",
26552
- "exercise",
26553
- "sexuality",
26554
- "prompt"
26555
- ];
26556
- var MEMORY_LEVELS = ["private", "matching", "profile"];
26557
- var MemoryLevelError = class extends Error {
26558
- constructor(message) {
26559
- super(message);
26560
- this.name = "MemoryLevelError";
26561
- }
26562
- };
26563
- var PUBLISHED_SCOPES = /* @__PURE__ */ new Set(["shared", "public"]);
26564
- function levelFromScope(scope) {
26565
- return typeof scope === "string" && PUBLISHED_SCOPES.has(scope) ? "matching" : "private";
26566
- }
26567
- function scopeForLevel(level) {
26568
- return level === "private" ? "private" : "shared";
26569
- }
26570
- function resolveMemoryLevel(level, scope) {
26571
- return typeof level === "string" && MEMORY_LEVELS.includes(level) ? level : levelFromScope(scope);
26572
- }
26573
- function levelForScopeChange(current, nextScope) {
26574
- const implied = levelFromScope(nextScope);
26575
- return implied === "matching" && resolveMemoryLevel(current.level, current.scope) === "profile" ? "profile" : implied;
26576
- }
26577
- function parseMedia(value) {
26578
- if (typeof value !== "string" || value === "") return null;
26579
- try {
26580
- const parsed = JSON.parse(value);
26581
- if (!Array.isArray(parsed)) return null;
26582
- const refs = parsed.filter((r) => typeof r === "object" && r !== null).map((r) => ({
26583
- feedItemId: Number(r.feedItemId ?? r.feed_item_id),
26584
- objectKey: r.objectKey ?? r.object_key ?? null
26585
- })).filter((r) => Number.isFinite(r.feedItemId));
26586
- return refs.length > 0 ? refs : null;
26587
- } catch {
26588
- return null;
26589
- }
26590
- }
26591
-
26592
26598
  // src/lib/db/memoryVault/operations.ts
26593
26599
  function visibilityOrPrivate(value) {
26594
26600
  return value === "public" ? value : "private";
@@ -26608,7 +26614,7 @@ function isKinded(record) {
26608
26614
  }
26609
26615
  async function assertCanWrite2(ctx) {
26610
26616
  if (ctx.canWrite && !await ctx.canWrite()) {
26611
- throw new Error("Memory source is no longer eligible");
26617
+ throw new MemorySourceIneligibleError();
26612
26618
  }
26613
26619
  }
26614
26620
  function assertValidKindLevel(kind, level) {
@@ -27285,7 +27291,7 @@ async function updateVaultMemoryOp(ctx, id, opts) {
27285
27291
  ctx.embeddedWalletSigner
27286
27292
  );
27287
27293
  } catch (err) {
27288
- if (err instanceof MemoryLevelError) throw err;
27294
+ if (err instanceof MemoryLevelError || err instanceof MemorySourceIneligibleError) throw err;
27289
27295
  return null;
27290
27296
  }
27291
27297
  }
@@ -30961,6 +30967,13 @@ var DEFAULT_AUTO_MERGE_THRESHOLD = 0.8;
30961
30967
  var DEFAULT_SCOPE = "private";
30962
30968
  var DEFAULT_CONSOLIDATE_THRESHOLD = 0.55;
30963
30969
  var DEFAULT_CONSOLIDATE_TOP_K = 20;
30970
+ var RetainError = class extends Error {
30971
+ constructor(reason, message) {
30972
+ super(message);
30973
+ this.reason = reason;
30974
+ this.name = "RetainError";
30975
+ }
30976
+ };
30964
30977
  async function retain(content, ctx, options = {}) {
30965
30978
  const embeddingOptions = {
30966
30979
  ...ctx.embeddingOptions,
@@ -31016,7 +31029,8 @@ async function retainWithPersistence(content, ctx, options = {}) {
31016
31029
  });
31017
31030
  prepared = withoutKindedRows(prepared);
31018
31031
  if (prepared.embeddingFailure || prepared.embeddingsUnavailable) {
31019
- throw new Error(
31032
+ throw new RetainError(
31033
+ "embeddings-unavailable",
31020
31034
  "retain: embeddings unavailable \u2014 refusing to auto-merge against an inert cosine lane, which would create a duplicate instead of merging into the existing memory. Retry when embeddings recover, or pass enableAutoMerge: false to force a create."
31021
31035
  );
31022
31036
  }
@@ -31386,7 +31400,10 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
31386
31400
  async function assertMergeTargetGoneOrThrow(ctx, targetId) {
31387
31401
  const stillExists = await (ctx.persistence.getFresh ? ctx.persistence.getFresh(targetId) : ctx.persistence.get(targetId));
31388
31402
  if (stillExists && (stillExists.kind === null || stillExists.kind === void 0)) {
31389
- throw new Error(`retain: merge into memory ${targetId} failed to persist`);
31403
+ throw new RetainError(
31404
+ "merge-not-persisted",
31405
+ `retain: merge into memory ${targetId} failed to persist`
31406
+ );
31390
31407
  }
31391
31408
  }
31392
31409
 
@@ -31544,6 +31561,12 @@ function restoreCandidates(candidates, redactor, ownNames) {
31544
31561
  (c) => c.candidate.content.length <= MAX_CONTENT_LENGTH && !c.unresolved && !isLowSignalContent(c.candidate.content, ownNames)
31545
31562
  ).map((c) => c.candidate);
31546
31563
  }
31564
+ function writeFailureReasonOf(err) {
31565
+ if (err instanceof MemorySourceIneligibleError) return "source-ineligible";
31566
+ if (err instanceof RetainError) return err.reason;
31567
+ if (err?.name === "AbortError") return "aborted";
31568
+ return "unknown";
31569
+ }
31547
31570
  async function extractAndRetain(messages, retainCtx, options) {
31548
31571
  const { memoryStore, signal } = options;
31549
31572
  if (memoryStore === null) throw new Error("Memory store is not ready");
@@ -31633,6 +31656,7 @@ async function extractAndRetain(messages, retainCtx, options) {
31633
31656
  const results = [];
31634
31657
  const quarantinedInfo = [];
31635
31658
  let failedWrites = 0;
31659
+ let writeFailureReason;
31636
31660
  let auditRows;
31637
31661
  const tRetain = Date.now();
31638
31662
  for (const { candidate, isQuarantined, reason, signature } of toRetain) {
@@ -31728,6 +31752,7 @@ async function extractAndRetain(messages, retainCtx, options) {
31728
31752
  }
31729
31753
  } catch (err) {
31730
31754
  failedWrites++;
31755
+ writeFailureReason ?? (writeFailureReason = writeFailureReasonOf(err));
31731
31756
  log.warn("[memory/extract] retain failed for one candidate", err);
31732
31757
  options.onCandidateFailed?.(candidate, err);
31733
31758
  }
@@ -31740,6 +31765,7 @@ async function extractAndRetain(messages, retainCtx, options) {
31740
31765
  candidates: succeededCandidates,
31741
31766
  results,
31742
31767
  failedCount: failedWrites,
31768
+ ...writeFailureReason !== void 0 && { writeFailureReason },
31743
31769
  outcome,
31744
31770
  quarantined: quarantinedInfo,
31745
31771
  funnel: {
@@ -32008,7 +32034,17 @@ function createAutoExtractor(options) {
32008
32034
  const t0 = Date.now();
32009
32035
  void (async () => {
32010
32036
  try {
32011
- const { candidates, results, failedCount, outcome, failure, funnel, timings, model } = await extractAndRetain(window2, retainCtx, {
32037
+ const {
32038
+ candidates,
32039
+ results,
32040
+ failedCount,
32041
+ writeFailureReason,
32042
+ outcome,
32043
+ failure,
32044
+ funnel,
32045
+ timings,
32046
+ model
32047
+ } = await extractAndRetain(window2, retainCtx, {
32012
32048
  extract,
32013
32049
  memoryStore: options.memoryStore,
32014
32050
  signal: options.signal,
@@ -32044,6 +32080,7 @@ function createAutoExtractor(options) {
32044
32080
  candidates,
32045
32081
  results,
32046
32082
  failedCount,
32083
+ ...writeFailureReason !== void 0 && { writeFailureReason },
32047
32084
  durationMs: Date.now() - t0,
32048
32085
  conversationId,
32049
32086
  outcome,
@@ -34156,10 +34193,10 @@ function createLocalMemoryStore(options) {
34156
34193
  const assertWrite = async (writeOptions) => {
34157
34194
  writeOptions?.signal?.throwIfAborted();
34158
34195
  if (writeOptions?.canWrite && !await writeOptions.canWrite()) {
34159
- throw new Error("Memory source is no longer eligible");
34196
+ throw new MemorySourceIneligibleError();
34160
34197
  }
34161
34198
  if (options.canWrite && !await options.canWrite()) {
34162
- throw new Error("Memory source is no longer eligible");
34199
+ throw new MemorySourceIneligibleError();
34163
34200
  }
34164
34201
  writeOptions?.signal?.throwIfAborted();
34165
34202
  };
@@ -35404,6 +35441,26 @@ function createDurableAutoExtractor(options) {
35404
35441
  );
35405
35442
  continue;
35406
35443
  }
35444
+ const foreign = new Set(
35445
+ ids.filter((_id, index) => loaded[index]?.conversationId !== conversationId)
35446
+ );
35447
+ if (foreign.size) {
35448
+ await database.write(
35449
+ () => job.update(
35450
+ (r) => r._setRaw(
35451
+ "message_ids",
35452
+ JSON.stringify(idsOf(job).filter((id) => !foreign.has(id)))
35453
+ )
35454
+ )
35455
+ );
35456
+ attempts.delete(job.id);
35457
+ scheduleAfterSuccess = true;
35458
+ reportError(
35459
+ new Error(`Dropped ${foreign.size} source id(s) from another conversation`),
35460
+ conversationId
35461
+ );
35462
+ continue;
35463
+ }
35407
35464
  const locked = loaded.filter((message) => message && isEncrypted(message.content));
35408
35465
  if (locked.length) {
35409
35466
  throw new LockedSourcesError(
@@ -35413,7 +35470,7 @@ function createDurableAutoExtractor(options) {
35413
35470
  );
35414
35471
  }
35415
35472
  const messages = loaded.flatMap(
35416
- (m) => m && m.conversationId === conversationId && (m.role === "user" || m.role === "assistant") ? [{ id: m.uniqueId, role: m.role, content: m.content }] : []
35473
+ (m) => m && (m.role === "user" || m.role === "assistant") ? [{ id: m.uniqueId, role: m.role, content: m.content }] : []
35417
35474
  );
35418
35475
  const jobScope = currentScope() === "private" ? "private" : String(job._getRaw("scope"));
35419
35476
  const jobFolderId = job._getRaw("folder_id") ?? null;
@@ -35506,9 +35563,31 @@ function createDurableAutoExtractor(options) {
35506
35563
  (candidate) => candidate._getRaw("scope") === scope && (candidate._getRaw("folder_id") ?? null) === folderId
35507
35564
  );
35508
35565
  const positions = new Map(ids.map((id, index) => [id, index]));
35566
+ const watermarks = existing.flatMap((prior) => {
35567
+ const watermark = prior._getRaw("watermark");
35568
+ return typeof watermark === "string" && watermark ? [watermark] : [];
35569
+ });
35570
+ if (watermarks.length) {
35571
+ const misplaced = new Set(
35572
+ await storage.messagesCollection.query(
35573
+ import_watermelondb25.Q.where("id", import_watermelondb25.Q.oneOf(watermarks)),
35574
+ import_watermelondb25.Q.where("conversation_id", import_watermelondb25.Q.notEq(conversationId))
35575
+ ).fetchIds()
35576
+ );
35577
+ for (const prior of existing)
35578
+ if (misplaced.has(String(prior._getRaw("watermark"))))
35579
+ await prior.update((r) => {
35580
+ r._setRaw("watermark", null);
35581
+ r._setRaw("watermark_seq", null);
35582
+ });
35583
+ }
35509
35584
  const rows = await storage.messagesCollection.query(import_watermelondb25.Q.where("id", import_watermelondb25.Q.oneOf(ids))).fetch();
35585
+ const foreignRows = new Set(
35586
+ rows.filter((row) => row._getRaw("conversation_id") !== conversationId).map((row) => row.id)
35587
+ );
35510
35588
  const sequences = /* @__PURE__ */ new Map();
35511
35589
  for (const row of rows) {
35590
+ if (foreignRows.has(row.id)) continue;
35512
35591
  const sequence = Number(row._getRaw("message_id"));
35513
35592
  if (Number.isFinite(sequence) && sequence > 0) sequences.set(row.id, sequence);
35514
35593
  }
@@ -35551,7 +35630,7 @@ function createDurableAutoExtractor(options) {
35551
35630
  const ownWatermark = job?._getRaw("watermark");
35552
35631
  const atOwnWatermark = !!job && boundary >= 0 && failedSessionsOf(job, String(ownWatermark)) < MAX_FAILED_SESSIONS && (ids[boundary] === ownWatermark || sequences.get(ids[boundary]) !== void 0 && sequences.get(ids[boundary]) === seqOf(job));
35553
35632
  const overlapStart = atOwnWatermark ? Math.max(0, boundary - 1) : start;
35554
- const fresh = ids.slice(overlapStart).filter((id) => !foreignSources.has(id));
35633
+ const fresh = ids.slice(overlapStart).filter((id) => !foreignSources.has(id) && !foreignRows.has(id));
35555
35634
  if (!fresh.length) return;
35556
35635
  if (job) {
35557
35636
  await job.update(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anuma/sdk",
3
- "version": "7.3.0",
3
+ "version": "7.3.1",
4
4
  "description": "",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",