@anuma/sdk 6.2.0 → 6.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.
@@ -53,6 +53,7 @@ import {
53
53
  embedMessage,
54
54
  encryptField,
55
55
  encryptJsonField,
56
+ encryptVaultMemoryContent,
56
57
  extractAssistantText,
57
58
  extractUserMessageFromMessages,
58
59
  finalizeThoughtProcess,
@@ -90,6 +91,7 @@ import {
90
91
  makeSyntheticStoredMessage,
91
92
  onClearAllEncryptionState,
92
93
  onKeyAvailable,
94
+ parseMedia,
93
95
  postApiV1CreditsPurchase,
94
96
  preEmbedVaultMemories,
95
97
  prepareVaultCandidates,
@@ -121,7 +123,7 @@ import {
121
123
  upsertMessageOp,
122
124
  useEncryption,
123
125
  vaultMemoryToStored
124
- } from "./chunk-NH5VY3G7.mjs";
126
+ } from "./chunk-PBCULYOW.mjs";
125
127
  import {
126
128
  PII_PATTERNS,
127
129
  PiiRedactor,
@@ -5637,6 +5639,9 @@ __decorateClass([
5637
5639
  __decorateClass([
5638
5640
  field3("topics_updated_at")
5639
5641
  ], VaultMemory.prototype, "topicsUpdatedAt", 2);
5642
+ __decorateClass([
5643
+ field3("media")
5644
+ ], VaultMemory.prototype, "media", 2);
5640
5645
  __decorateClass([
5641
5646
  field3("topics_extracted_at")
5642
5647
  ], VaultMemory.prototype, "topicsExtractedAt", 2);
@@ -5684,6 +5689,133 @@ __decorateClass([
5684
5689
  field3("is_deleted")
5685
5690
  ], VaultMemory.prototype, "isDeleted", 2);
5686
5691
 
5692
+ // src/lib/memory/decay.ts
5693
+ var DAY_MS = 24 * 60 * 60 * 1e3;
5694
+ var SHORT_TTL_MS = 30 * DAY_MS;
5695
+ var MEDIUM_TTL_MS = 180 * DAY_MS;
5696
+ var SOURCE_PHOTO = "photo";
5697
+ var NEVER_TTL_MS = Number.POSITIVE_INFINITY;
5698
+ var HARD_DELETE_WINDOW_MS = 30 * DAY_MS;
5699
+ var PAST_EVENT_GRACE_MS = 7 * DAY_MS;
5700
+ var DEFAULT_DECAY_POLICY = {
5701
+ ttlByType: {
5702
+ identity: NEVER_TTL_MS,
5703
+ preference: NEVER_TTL_MS,
5704
+ relationship: NEVER_TTL_MS,
5705
+ constraint: NEVER_TTL_MS,
5706
+ plan: SHORT_TTL_MS,
5707
+ ongoing_context: SHORT_TTL_MS,
5708
+ other: MEDIUM_TTL_MS
5709
+ },
5710
+ fallbackTtlMs: MEDIUM_TTL_MS,
5711
+ hardDeleteWindowMs: HARD_DELETE_WINDOW_MS,
5712
+ pastEventGraceMs: PAST_EVENT_GRACE_MS
5713
+ };
5714
+ function resolvePolicy(policy) {
5715
+ if (!policy) return DEFAULT_DECAY_POLICY;
5716
+ return {
5717
+ ttlByType: { ...DEFAULT_DECAY_POLICY.ttlByType, ...policy.ttlByType },
5718
+ fallbackTtlMs: policy.fallbackTtlMs ?? DEFAULT_DECAY_POLICY.fallbackTtlMs,
5719
+ hardDeleteWindowMs: policy.hardDeleteWindowMs ?? DEFAULT_DECAY_POLICY.hardDeleteWindowMs,
5720
+ pastEventGraceMs: policy.pastEventGraceMs ?? DEFAULT_DECAY_POLICY.pastEventGraceMs
5721
+ };
5722
+ }
5723
+ function ttlForType(factType, policy) {
5724
+ const resolved = resolvePolicy(policy);
5725
+ if (factType === null) return resolved.fallbackTtlMs;
5726
+ return resolved.ttlByType[factType] ?? resolved.fallbackTtlMs;
5727
+ }
5728
+ function isTimeSensitiveType(factType) {
5729
+ return factType === "plan" || factType === "ongoing_context";
5730
+ }
5731
+ function hasFiniteTimestamps(m, now) {
5732
+ return Number.isFinite(now) && Number.isFinite(m.updatedAt) && (m.archivedAt === null || Number.isFinite(m.archivedAt));
5733
+ }
5734
+ function classifyDecay(m, now, policy) {
5735
+ const resolved = resolvePolicy(policy);
5736
+ if (!hasFiniteTimestamps(m, now)) {
5737
+ getLogger().warn("[memory/decay] non-finite timestamp on a memory row; keeping it", {
5738
+ now,
5739
+ updatedAt: m.updatedAt,
5740
+ archivedAt: m.archivedAt,
5741
+ factType: m.factType
5742
+ });
5743
+ return "keep";
5744
+ }
5745
+ if (m.archivedAt !== null) {
5746
+ return now - m.archivedAt > resolved.hardDeleteWindowMs ? "delete" : "keep";
5747
+ }
5748
+ if (m.source === "manual" || m.source === SOURCE_PHOTO) return "keep";
5749
+ if (isTimeSensitiveType(m.factType) && m.eventTimeEnd !== null) {
5750
+ if (m.eventTimeEnd < now - resolved.pastEventGraceMs) return "archive";
5751
+ if (m.eventTimeEnd >= now) return "keep";
5752
+ }
5753
+ if (now - m.updatedAt > ttlForType(m.factType, resolved)) return "archive";
5754
+ return "keep";
5755
+ }
5756
+
5757
+ // src/lib/db/memoryVault/photoIngest.ts
5758
+ var PHOTO_MEMORY_ID_PREFIX = "photo:";
5759
+ async function ingestPublishedPhotoMemoriesOp(ctx, rows) {
5760
+ const byId = /* @__PURE__ */ new Map();
5761
+ for (const r of rows) {
5762
+ if (typeof r.memoryId !== "string" || !r.memoryId.startsWith(PHOTO_MEMORY_ID_PREFIX)) continue;
5763
+ if (!byId.has(r.memoryId)) byId.set(r.memoryId, r);
5764
+ }
5765
+ const photoRows = [...byId.values()];
5766
+ if (photoRows.length === 0) return { inserted: 0, skipped: 0 };
5767
+ const known = await ctx.vaultMemoryCollection.query().fetchIds().then((ids) => new Set(ids));
5768
+ const candidates = photoRows.filter((r) => !known.has(r.memoryId));
5769
+ if (candidates.length === 0) return { inserted: 0, skipped: photoRows.length };
5770
+ const fresh = candidates;
5771
+ const contents = await Promise.all(
5772
+ fresh.map(async (r) => {
5773
+ if (ctx.walletAddress && ctx.signMessage) {
5774
+ return encryptVaultMemoryContent(
5775
+ r.text,
5776
+ ctx.walletAddress,
5777
+ ctx.signMessage,
5778
+ ctx.embeddedWalletSigner
5779
+ );
5780
+ }
5781
+ return r.text;
5782
+ })
5783
+ );
5784
+ const now = Date.now();
5785
+ let inserted = 0;
5786
+ await ctx.database.write(async () => {
5787
+ const present = new Set(await ctx.vaultMemoryCollection.query().fetchIds());
5788
+ const writable = fresh.map((row, i) => ({ row, content: contents[i] })).filter(({ row }) => !present.has(row.memoryId));
5789
+ inserted = writable.length;
5790
+ if (writable.length === 0) return;
5791
+ const prepared = writable.map(
5792
+ ({ row, content }) => ctx.vaultMemoryCollection.prepareCreate((record) => {
5793
+ record._raw.id = row.memoryId;
5794
+ record._setRaw("content", content);
5795
+ record._setRaw("scope", "private");
5796
+ record._setRaw("folder_id", null);
5797
+ record._setRaw("user_id", ctx.userId ?? null);
5798
+ record._setRaw("is_deleted", false);
5799
+ record._setRaw("proof_count", 1);
5800
+ record._setRaw("source", SOURCE_PHOTO);
5801
+ record._setRaw(
5802
+ "media",
5803
+ row.media && row.media.length > 0 ? JSON.stringify(row.media) : null
5804
+ );
5805
+ record._setRaw("visibility", "public");
5806
+ record._setRaw("published_at", now);
5807
+ if (row.eventTime) {
5808
+ record._setRaw("event_time_start", row.eventTime.start ?? null);
5809
+ record._setRaw("event_time_end", row.eventTime.end ?? null);
5810
+ record._setRaw("event_time_kind", row.eventTime.kind ?? null);
5811
+ }
5812
+ })
5813
+ );
5814
+ await ctx.database.batch(...prepared);
5815
+ });
5816
+ return { inserted, skipped: photoRows.length - inserted };
5817
+ }
5818
+
5687
5819
  // src/lib/db/queue/manager.ts
5688
5820
  import { v7 as uuidv72 } from "uuid";
5689
5821
  var MAX_OPERATIONS_PER_WALLET = 1e3;
@@ -6929,6 +7061,9 @@ async function extractFacts(messages, options) {
6929
7061
  ...options.apiKey !== void 0 && { apiKey: options.apiKey },
6930
7062
  ...options.getToken !== void 0 && { getToken: options.getToken },
6931
7063
  ...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
7064
+ ...options.endpointOverride !== void 0 && {
7065
+ endpointOverride: options.endpointOverride
7066
+ },
6932
7067
  model: options.model ?? DEFAULT_EXTRACTION_MODEL,
6933
7068
  systemPrompt: SYSTEM_PROMPT2,
6934
7069
  userMessage: `Today's date is ${today}. Resolve any relative dates ("yesterday", "next week") against it.
@@ -7439,70 +7574,6 @@ function createChunkVectorCache(maxSize = DEFAULT_CHUNK_CACHE_SIZE) {
7439
7574
  return new LRUCache(maxSize);
7440
7575
  }
7441
7576
 
7442
- // src/lib/memory/decay.ts
7443
- var DAY_MS = 24 * 60 * 60 * 1e3;
7444
- var SHORT_TTL_MS = 30 * DAY_MS;
7445
- var MEDIUM_TTL_MS = 180 * DAY_MS;
7446
- var NEVER_TTL_MS = Number.POSITIVE_INFINITY;
7447
- var HARD_DELETE_WINDOW_MS = 30 * DAY_MS;
7448
- var PAST_EVENT_GRACE_MS = 7 * DAY_MS;
7449
- var DEFAULT_DECAY_POLICY = {
7450
- ttlByType: {
7451
- identity: NEVER_TTL_MS,
7452
- preference: NEVER_TTL_MS,
7453
- relationship: NEVER_TTL_MS,
7454
- constraint: NEVER_TTL_MS,
7455
- plan: SHORT_TTL_MS,
7456
- ongoing_context: SHORT_TTL_MS,
7457
- other: MEDIUM_TTL_MS
7458
- },
7459
- fallbackTtlMs: MEDIUM_TTL_MS,
7460
- hardDeleteWindowMs: HARD_DELETE_WINDOW_MS,
7461
- pastEventGraceMs: PAST_EVENT_GRACE_MS
7462
- };
7463
- function resolvePolicy(policy) {
7464
- if (!policy) return DEFAULT_DECAY_POLICY;
7465
- return {
7466
- ttlByType: { ...DEFAULT_DECAY_POLICY.ttlByType, ...policy.ttlByType },
7467
- fallbackTtlMs: policy.fallbackTtlMs ?? DEFAULT_DECAY_POLICY.fallbackTtlMs,
7468
- hardDeleteWindowMs: policy.hardDeleteWindowMs ?? DEFAULT_DECAY_POLICY.hardDeleteWindowMs,
7469
- pastEventGraceMs: policy.pastEventGraceMs ?? DEFAULT_DECAY_POLICY.pastEventGraceMs
7470
- };
7471
- }
7472
- function ttlForType(factType, policy) {
7473
- const resolved = resolvePolicy(policy);
7474
- if (factType === null) return resolved.fallbackTtlMs;
7475
- return resolved.ttlByType[factType] ?? resolved.fallbackTtlMs;
7476
- }
7477
- function isTimeSensitiveType(factType) {
7478
- return factType === "plan" || factType === "ongoing_context";
7479
- }
7480
- function hasFiniteTimestamps(m, now) {
7481
- return Number.isFinite(now) && Number.isFinite(m.updatedAt) && (m.archivedAt === null || Number.isFinite(m.archivedAt));
7482
- }
7483
- function classifyDecay(m, now, policy) {
7484
- const resolved = resolvePolicy(policy);
7485
- if (!hasFiniteTimestamps(m, now)) {
7486
- getLogger().warn("[memory/decay] non-finite timestamp on a memory row; keeping it", {
7487
- now,
7488
- updatedAt: m.updatedAt,
7489
- archivedAt: m.archivedAt,
7490
- factType: m.factType
7491
- });
7492
- return "keep";
7493
- }
7494
- if (m.archivedAt !== null) {
7495
- return now - m.archivedAt > resolved.hardDeleteWindowMs ? "delete" : "keep";
7496
- }
7497
- if (m.source === "manual") return "keep";
7498
- if (isTimeSensitiveType(m.factType) && m.eventTimeEnd !== null) {
7499
- if (m.eventTimeEnd < now - resolved.pastEventGraceMs) return "archive";
7500
- if (m.eventTimeEnd >= now) return "keep";
7501
- }
7502
- if (now - m.updatedAt > ttlForType(m.factType, resolved)) return "archive";
7503
- return "keep";
7504
- }
7505
-
7506
7577
  // src/lib/memory/decayClassifier.ts
7507
7578
  var DEFAULT_MODEL2 = "inclusionai/ling-2.6-flash";
7508
7579
  var DEFAULT_ATTEMPTS2 = 2;
@@ -7600,7 +7671,7 @@ function toDecayInput(c) {
7600
7671
  };
7601
7672
  }
7602
7673
  function isBorderline(input) {
7603
- if (input.source === "manual") return false;
7674
+ if (input.source === "manual" || input.source === SOURCE_PHOTO) return false;
7604
7675
  if (input.trustTier === "quarantined") return false;
7605
7676
  if (input.archivedAt !== null) return false;
7606
7677
  if (input.factType === null || input.factType === "other") return true;
@@ -12258,7 +12329,7 @@ __decorateClass([
12258
12329
  ], VaultFolder.prototype, "context", 2);
12259
12330
 
12260
12331
  // src/lib/db/schema.ts
12261
- var SDK_SCHEMA_VERSION = 44;
12332
+ var SDK_SCHEMA_VERSION = 45;
12262
12333
  var sdkSchema = appSchema2({
12263
12334
  version: SDK_SCHEMA_VERSION,
12264
12335
  tables: [
@@ -12406,6 +12477,18 @@ var sdkSchema = appSchema2({
12406
12477
  // paths key on `updated_at` — so without this a topic-only change would
12407
12478
  // neither upload nor merge. Null = `topics` never written.
12408
12479
  { name: "topics_updated_at", type: "number", isOptional: true },
12480
+ // The photo(s) a SERVER-EXTRACTED memory was read out of, as a JSON
12481
+ // array of `{feed_item_id, object_key}` — exactly what
12482
+ // GET /api/memories/published returns in `media[]`. Enough to render the
12483
+ // source image without a second round-trip per memory.
12484
+ //
12485
+ // A JSON column rather than a join table: nothing on the client ever
12486
+ // queries BY photo (the only direction is memory -> render its image),
12487
+ // so a table would add a sync lane and a local-id space to serve a
12488
+ // question nobody asks. `topics` and `source_chunk_ids` set the
12489
+ // precedent for a list that is only ever read back whole. Null on
12490
+ // anything not extracted from a photo.
12491
+ { name: "media", type: "string", isOptional: true },
12409
12492
  // Unix ms of the last LLM topic-extraction pass over this memory's
12410
12493
  // content. Null = never extracted standalone (legacy rows with entity
12411
12494
  // links are grandfathered — see getMemoriesNeedingTopicExtractionOp).
@@ -13240,6 +13323,20 @@ var sdkMigrations = schemaMigrations2({
13240
13323
  columns: [{ name: "origin", type: "string", isOptional: true }]
13241
13324
  })
13242
13325
  ]
13326
+ },
13327
+ // v44 -> v45: `media` on memory_vault — the photo(s) a server-extracted
13328
+ // memory was read out of, as JSON `[{feed_item_id, object_key}]`, mirroring
13329
+ // the `media[]` that GET /api/memories/published already returns. Existing
13330
+ // rows keep NULL, which is the correct value for every memory that did not
13331
+ // come from a photo (i.e. all of them until photo ingest runs).
13332
+ {
13333
+ toVersion: 45,
13334
+ steps: [
13335
+ addColumns2({
13336
+ table: "memory_vault",
13337
+ columns: [{ name: "media", type: "string", isOptional: true }]
13338
+ })
13339
+ ]
13243
13340
  }
13244
13341
  ]
13245
13342
  });
@@ -14706,12 +14803,14 @@ export {
14706
14803
  getVaultMemoryOp,
14707
14804
  hardDeleteDecayedOp,
14708
14805
  hasEncryptionKey,
14806
+ ingestPublishedPhotoMemoriesOp,
14709
14807
  injectionSignatureCatalog,
14710
14808
  isPiiRedactor,
14711
14809
  isRerankerAvailable,
14712
14810
  moveMemoriesToFolderOp,
14713
14811
  noopLogger,
14714
14812
  onKeyAvailable,
14813
+ parseMedia,
14715
14814
  preEmbedVaultMemories,
14716
14815
  quantizeEmbedding,
14717
14816
  queueManager,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  recall
3
- } from "./chunk-NH5VY3G7.mjs";
3
+ } from "./chunk-PBCULYOW.mjs";
4
4
  import "./chunk-ILAWDQDE.mjs";
5
5
  import "./chunk-GYKJOWEO.mjs";
6
6
  export {
@@ -2560,6 +2560,22 @@ async function decryptVaultMemoryFields(memory, address, signMessage, embeddedWa
2560
2560
  };
2561
2561
  }
2562
2562
 
2563
+ // src/lib/db/memoryVault/types.ts
2564
+ function parseMedia(value) {
2565
+ if (typeof value !== "string" || value === "") return null;
2566
+ try {
2567
+ const parsed = JSON.parse(value);
2568
+ if (!Array.isArray(parsed)) return null;
2569
+ const refs = parsed.filter((r) => typeof r === "object" && r !== null).map((r) => ({
2570
+ feedItemId: Number(r.feedItemId ?? r.feed_item_id),
2571
+ objectKey: r.objectKey ?? r.object_key ?? null
2572
+ })).filter((r) => Number.isFinite(r.feedItemId));
2573
+ return refs.length > 0 ? refs : null;
2574
+ } catch {
2575
+ return null;
2576
+ }
2577
+ }
2578
+
2563
2579
  // src/lib/db/memoryVault/operations.ts
2564
2580
  function visibilityOrPrivate(value) {
2565
2581
  return value === "public" ? value : "private";
@@ -2623,6 +2639,7 @@ function vaultMemoryToStoredRaw(memory) {
2623
2639
  sourceChunkIds,
2624
2640
  proofCount: memory.proofCount ?? null,
2625
2641
  source: memory.source ?? null,
2642
+ media: parseMedia(memory.media),
2626
2643
  eventTimeStart: memory.eventTimeStart ?? null,
2627
2644
  eventTimeEnd: memory.eventTimeEnd ?? null,
2628
2645
  eventTimeKind: memory.eventTimeKind ?? null,
@@ -2905,6 +2922,7 @@ function vaultMemoryRawToStoredRaw(raw) {
2905
2922
  eventTimeKind: raw.event_time_kind ?? null,
2906
2923
  // SQLite stores booleans as 0/1, LokiJS as true/false — coerce both.
2907
2924
  topicsUserManaged: raw.topics_user_managed === true || raw.topics_user_managed === 1,
2925
+ media: parseMedia(raw.media),
2908
2926
  topics: parseTopics(raw.topics),
2909
2927
  topicsUpdatedAt: raw.topics_updated_at ?? null,
2910
2928
  topicsExtractedAt: raw.topics_extracted_at ?? null,
@@ -6783,7 +6801,7 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
6783
6801
  subQueries = decomp.subQueries;
6784
6802
  }
6785
6803
  }
6786
- const { recall: recall2 } = await import("./recall-B7POS7NA.mjs");
6804
+ const { recall: recall2 } = await import("./recall-PCM7H5TA.mjs");
6787
6805
  let recallDegraded = [];
6788
6806
  const result = await recall2(
6789
6807
  query,
@@ -7838,6 +7856,8 @@ export {
7838
7856
  backfillMemoryEntityUserIdsOp,
7839
7857
  getMemoriesByEntityNamesOp,
7840
7858
  getEntitiesByMemoryIdsOp,
7859
+ encryptVaultMemoryContent,
7860
+ parseMedia,
7841
7861
  vaultMemoryToStored,
7842
7862
  createVaultMemoryOp,
7843
7863
  createSupersedingMemoryOp,