@anuma/sdk 6.1.1 → 6.3.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.
@@ -63,6 +63,7 @@ import {
63
63
  encryptDataWithKey,
64
64
  encryptField,
65
65
  encryptJsonField,
66
+ encryptVaultMemoryContent,
66
67
  exportPublicKey,
67
68
  generateConversationId,
68
69
  generateEmbedding,
@@ -93,6 +94,7 @@ import {
93
94
  makeSyntheticStoredMessage,
94
95
  onClearAllEncryptionState,
95
96
  onKeyAvailable,
97
+ parseMedia,
96
98
  preEmbedVaultMemories,
97
99
  prepareVaultCandidates,
98
100
  rankPreparedVaultCandidates,
@@ -137,7 +139,7 @@ import {
137
139
  updateVaultMemoryOp,
138
140
  upsertMessageOp,
139
141
  vaultMemoryToStored
140
- } from "./chunk-FYT5MBVO.mjs";
142
+ } from "./chunk-S5WEN7TE.mjs";
141
143
  import {
142
144
  createStreamingDeAnonymizer,
143
145
  notifyConsolidationFallback,
@@ -912,6 +914,9 @@ __decorateClass([
912
914
  __decorateClass([
913
915
  (0, import_decorators2.json)("tool_call_events", (raw) => raw)
914
916
  ], Message.prototype, "toolCallEvents", 2);
917
+ __decorateClass([
918
+ (0, import_decorators2.text)("origin")
919
+ ], Message.prototype, "origin", 2);
915
920
  var Conversation = class extends import_watermelondb2.Model {
916
921
  };
917
922
  Conversation.table = "conversations";
@@ -1136,6 +1141,9 @@ __decorateClass([
1136
1141
  __decorateClass([
1137
1142
  (0, import_decorators6.field)("topics_updated_at")
1138
1143
  ], VaultMemory.prototype, "topicsUpdatedAt", 2);
1144
+ __decorateClass([
1145
+ (0, import_decorators6.field)("media")
1146
+ ], VaultMemory.prototype, "media", 2);
1139
1147
  __decorateClass([
1140
1148
  (0, import_decorators6.field)("topics_extracted_at")
1141
1149
  ], VaultMemory.prototype, "topicsExtractedAt", 2);
@@ -1319,7 +1327,7 @@ __decorateClass([
1319
1327
  ], VaultFolder.prototype, "context", 2);
1320
1328
 
1321
1329
  // src/lib/db/schema.ts
1322
- var SDK_SCHEMA_VERSION = 43;
1330
+ var SDK_SCHEMA_VERSION = 45;
1323
1331
  var sdkSchema = (0, import_watermelondb12.appSchema)({
1324
1332
  version: SDK_SCHEMA_VERSION,
1325
1333
  tables: [
@@ -1357,8 +1365,10 @@ var sdkSchema = (0, import_watermelondb12.appSchema)({
1357
1365
  // Parent message for branching
1358
1366
  { name: "feedback", type: "string", isOptional: true },
1359
1367
  // 'like' | 'dislike' | null
1360
- { name: "tool_call_events", type: "string", isOptional: true }
1368
+ { name: "tool_call_events", type: "string", isOptional: true },
1361
1369
  // JSON stringified LlmapiToolCallEvent[]
1370
+ { name: "origin", type: "string", isOptional: true }
1371
+ // MessageOrigin — provenance, NOT encrypted (see v44)
1362
1372
  ]
1363
1373
  }),
1364
1374
  (0, import_watermelondb12.tableSchema)({
@@ -1465,6 +1475,18 @@ var sdkSchema = (0, import_watermelondb12.appSchema)({
1465
1475
  // paths key on `updated_at` — so without this a topic-only change would
1466
1476
  // neither upload nor merge. Null = `topics` never written.
1467
1477
  { name: "topics_updated_at", type: "number", isOptional: true },
1478
+ // The photo(s) a SERVER-EXTRACTED memory was read out of, as a JSON
1479
+ // array of `{feed_item_id, object_key}` — exactly what
1480
+ // GET /api/memories/published returns in `media[]`. Enough to render the
1481
+ // source image without a second round-trip per memory.
1482
+ //
1483
+ // A JSON column rather than a join table: nothing on the client ever
1484
+ // queries BY photo (the only direction is memory -> render its image),
1485
+ // so a table would add a sync lane and a local-id space to serve a
1486
+ // question nobody asks. `topics` and `source_chunk_ids` set the
1487
+ // precedent for a list that is only ever read back whole. Null on
1488
+ // anything not extracted from a photo.
1489
+ { name: "media", type: "string", isOptional: true },
1468
1490
  // Unix ms of the last LLM topic-extraction pass over this memory's
1469
1491
  // content. Null = never extracted standalone (legacy rows with entity
1470
1492
  // links are grandfathered — see getMemoriesNeedingTopicExtractionOp).
@@ -2286,6 +2308,33 @@ var sdkMigrations = (0, import_migrations.schemaMigrations)({
2286
2308
  "CREATE INDEX IF NOT EXISTS conversations_is_deleted_created_at ON conversations (is_deleted, created_at);"
2287
2309
  )
2288
2310
  ]
2311
+ },
2312
+ // v43 -> v44: Added origin column to history — the provenance tag the embedding
2313
+ // sweep reads to skip never-rendered tool-result rows. No backfill: NULL means
2314
+ // "legacy, provenance unknown" and keeps the pre-v44 behaviour of embedding the
2315
+ // row, so the only rows that stop being embedded are ones a v44+ producer tagged.
2316
+ {
2317
+ toVersion: 44,
2318
+ steps: [
2319
+ (0, import_migrations.addColumns)({
2320
+ table: "history",
2321
+ columns: [{ name: "origin", type: "string", isOptional: true }]
2322
+ })
2323
+ ]
2324
+ },
2325
+ // v44 -> v45: `media` on memory_vault — the photo(s) a server-extracted
2326
+ // memory was read out of, as JSON `[{feed_item_id, object_key}]`, mirroring
2327
+ // the `media[]` that GET /api/memories/published already returns. Existing
2328
+ // rows keep NULL, which is the correct value for every memory that did not
2329
+ // come from a photo (i.e. all of them until photo ingest runs).
2330
+ {
2331
+ toVersion: 45,
2332
+ steps: [
2333
+ (0, import_migrations.addColumns)({
2334
+ table: "memory_vault",
2335
+ columns: [{ name: "media", type: "string", isOptional: true }]
2336
+ })
2337
+ ]
2289
2338
  }
2290
2339
  ]
2291
2340
  });
@@ -3564,6 +3613,133 @@ async function cleanupConversationSummary(database, conversationId) {
3564
3613
  }
3565
3614
  }
3566
3615
 
3616
+ // src/lib/memory/decay.ts
3617
+ var DAY_MS = 24 * 60 * 60 * 1e3;
3618
+ var SHORT_TTL_MS = 30 * DAY_MS;
3619
+ var MEDIUM_TTL_MS = 180 * DAY_MS;
3620
+ var SOURCE_PHOTO = "photo";
3621
+ var NEVER_TTL_MS = Number.POSITIVE_INFINITY;
3622
+ var HARD_DELETE_WINDOW_MS = 30 * DAY_MS;
3623
+ var PAST_EVENT_GRACE_MS = 7 * DAY_MS;
3624
+ var DEFAULT_DECAY_POLICY = {
3625
+ ttlByType: {
3626
+ identity: NEVER_TTL_MS,
3627
+ preference: NEVER_TTL_MS,
3628
+ relationship: NEVER_TTL_MS,
3629
+ constraint: NEVER_TTL_MS,
3630
+ plan: SHORT_TTL_MS,
3631
+ ongoing_context: SHORT_TTL_MS,
3632
+ other: MEDIUM_TTL_MS
3633
+ },
3634
+ fallbackTtlMs: MEDIUM_TTL_MS,
3635
+ hardDeleteWindowMs: HARD_DELETE_WINDOW_MS,
3636
+ pastEventGraceMs: PAST_EVENT_GRACE_MS
3637
+ };
3638
+ function resolvePolicy(policy) {
3639
+ if (!policy) return DEFAULT_DECAY_POLICY;
3640
+ return {
3641
+ ttlByType: { ...DEFAULT_DECAY_POLICY.ttlByType, ...policy.ttlByType },
3642
+ fallbackTtlMs: policy.fallbackTtlMs ?? DEFAULT_DECAY_POLICY.fallbackTtlMs,
3643
+ hardDeleteWindowMs: policy.hardDeleteWindowMs ?? DEFAULT_DECAY_POLICY.hardDeleteWindowMs,
3644
+ pastEventGraceMs: policy.pastEventGraceMs ?? DEFAULT_DECAY_POLICY.pastEventGraceMs
3645
+ };
3646
+ }
3647
+ function ttlForType(factType, policy) {
3648
+ const resolved = resolvePolicy(policy);
3649
+ if (factType === null) return resolved.fallbackTtlMs;
3650
+ return resolved.ttlByType[factType] ?? resolved.fallbackTtlMs;
3651
+ }
3652
+ function isTimeSensitiveType(factType) {
3653
+ return factType === "plan" || factType === "ongoing_context";
3654
+ }
3655
+ function hasFiniteTimestamps(m, now) {
3656
+ return Number.isFinite(now) && Number.isFinite(m.updatedAt) && (m.archivedAt === null || Number.isFinite(m.archivedAt));
3657
+ }
3658
+ function classifyDecay(m, now, policy) {
3659
+ const resolved = resolvePolicy(policy);
3660
+ if (!hasFiniteTimestamps(m, now)) {
3661
+ getLogger().warn("[memory/decay] non-finite timestamp on a memory row; keeping it", {
3662
+ now,
3663
+ updatedAt: m.updatedAt,
3664
+ archivedAt: m.archivedAt,
3665
+ factType: m.factType
3666
+ });
3667
+ return "keep";
3668
+ }
3669
+ if (m.archivedAt !== null) {
3670
+ return now - m.archivedAt > resolved.hardDeleteWindowMs ? "delete" : "keep";
3671
+ }
3672
+ if (m.source === "manual" || m.source === SOURCE_PHOTO) return "keep";
3673
+ if (isTimeSensitiveType(m.factType) && m.eventTimeEnd !== null) {
3674
+ if (m.eventTimeEnd < now - resolved.pastEventGraceMs) return "archive";
3675
+ if (m.eventTimeEnd >= now) return "keep";
3676
+ }
3677
+ if (now - m.updatedAt > ttlForType(m.factType, resolved)) return "archive";
3678
+ return "keep";
3679
+ }
3680
+
3681
+ // src/lib/db/memoryVault/photoIngest.ts
3682
+ var PHOTO_MEMORY_ID_PREFIX = "photo:";
3683
+ async function ingestPublishedPhotoMemoriesOp(ctx, rows) {
3684
+ const byId = /* @__PURE__ */ new Map();
3685
+ for (const r of rows) {
3686
+ if (typeof r.memoryId !== "string" || !r.memoryId.startsWith(PHOTO_MEMORY_ID_PREFIX)) continue;
3687
+ if (!byId.has(r.memoryId)) byId.set(r.memoryId, r);
3688
+ }
3689
+ const photoRows = [...byId.values()];
3690
+ if (photoRows.length === 0) return { inserted: 0, skipped: 0 };
3691
+ const known = await ctx.vaultMemoryCollection.query().fetchIds().then((ids) => new Set(ids));
3692
+ const candidates = photoRows.filter((r) => !known.has(r.memoryId));
3693
+ if (candidates.length === 0) return { inserted: 0, skipped: photoRows.length };
3694
+ const fresh = candidates;
3695
+ const contents = await Promise.all(
3696
+ fresh.map(async (r) => {
3697
+ if (ctx.walletAddress && ctx.signMessage) {
3698
+ return encryptVaultMemoryContent(
3699
+ r.text,
3700
+ ctx.walletAddress,
3701
+ ctx.signMessage,
3702
+ ctx.embeddedWalletSigner
3703
+ );
3704
+ }
3705
+ return r.text;
3706
+ })
3707
+ );
3708
+ const now = Date.now();
3709
+ let inserted = 0;
3710
+ await ctx.database.write(async () => {
3711
+ const present = new Set(await ctx.vaultMemoryCollection.query().fetchIds());
3712
+ const writable = fresh.map((row, i) => ({ row, content: contents[i] })).filter(({ row }) => !present.has(row.memoryId));
3713
+ inserted = writable.length;
3714
+ if (writable.length === 0) return;
3715
+ const prepared = writable.map(
3716
+ ({ row, content }) => ctx.vaultMemoryCollection.prepareCreate((record) => {
3717
+ record._raw.id = row.memoryId;
3718
+ record._setRaw("content", content);
3719
+ record._setRaw("scope", "private");
3720
+ record._setRaw("folder_id", null);
3721
+ record._setRaw("user_id", ctx.userId ?? null);
3722
+ record._setRaw("is_deleted", false);
3723
+ record._setRaw("proof_count", 1);
3724
+ record._setRaw("source", SOURCE_PHOTO);
3725
+ record._setRaw(
3726
+ "media",
3727
+ row.media && row.media.length > 0 ? JSON.stringify(row.media) : null
3728
+ );
3729
+ record._setRaw("visibility", "public");
3730
+ record._setRaw("published_at", now);
3731
+ if (row.eventTime) {
3732
+ record._setRaw("event_time_start", row.eventTime.start ?? null);
3733
+ record._setRaw("event_time_end", row.eventTime.end ?? null);
3734
+ record._setRaw("event_time_kind", row.eventTime.kind ?? null);
3735
+ }
3736
+ })
3737
+ );
3738
+ await ctx.database.batch(...prepared);
3739
+ });
3740
+ return { inserted, skipped: photoRows.length - inserted };
3741
+ }
3742
+
3567
3743
  // src/lib/db/project/operations.ts
3568
3744
  var import_watermelondb15 = __toESM(require_watermelondb());
3569
3745
 
@@ -6234,70 +6410,6 @@ function createChunkVectorCache(maxSize = DEFAULT_CHUNK_CACHE_SIZE) {
6234
6410
  return new LRUCache(maxSize);
6235
6411
  }
6236
6412
 
6237
- // src/lib/memory/decay.ts
6238
- var DAY_MS = 24 * 60 * 60 * 1e3;
6239
- var SHORT_TTL_MS = 30 * DAY_MS;
6240
- var MEDIUM_TTL_MS = 180 * DAY_MS;
6241
- var NEVER_TTL_MS = Number.POSITIVE_INFINITY;
6242
- var HARD_DELETE_WINDOW_MS = 30 * DAY_MS;
6243
- var PAST_EVENT_GRACE_MS = 7 * DAY_MS;
6244
- var DEFAULT_DECAY_POLICY = {
6245
- ttlByType: {
6246
- identity: NEVER_TTL_MS,
6247
- preference: NEVER_TTL_MS,
6248
- relationship: NEVER_TTL_MS,
6249
- constraint: NEVER_TTL_MS,
6250
- plan: SHORT_TTL_MS,
6251
- ongoing_context: SHORT_TTL_MS,
6252
- other: MEDIUM_TTL_MS
6253
- },
6254
- fallbackTtlMs: MEDIUM_TTL_MS,
6255
- hardDeleteWindowMs: HARD_DELETE_WINDOW_MS,
6256
- pastEventGraceMs: PAST_EVENT_GRACE_MS
6257
- };
6258
- function resolvePolicy(policy) {
6259
- if (!policy) return DEFAULT_DECAY_POLICY;
6260
- return {
6261
- ttlByType: { ...DEFAULT_DECAY_POLICY.ttlByType, ...policy.ttlByType },
6262
- fallbackTtlMs: policy.fallbackTtlMs ?? DEFAULT_DECAY_POLICY.fallbackTtlMs,
6263
- hardDeleteWindowMs: policy.hardDeleteWindowMs ?? DEFAULT_DECAY_POLICY.hardDeleteWindowMs,
6264
- pastEventGraceMs: policy.pastEventGraceMs ?? DEFAULT_DECAY_POLICY.pastEventGraceMs
6265
- };
6266
- }
6267
- function ttlForType(factType, policy) {
6268
- const resolved = resolvePolicy(policy);
6269
- if (factType === null) return resolved.fallbackTtlMs;
6270
- return resolved.ttlByType[factType] ?? resolved.fallbackTtlMs;
6271
- }
6272
- function isTimeSensitiveType(factType) {
6273
- return factType === "plan" || factType === "ongoing_context";
6274
- }
6275
- function hasFiniteTimestamps(m, now) {
6276
- return Number.isFinite(now) && Number.isFinite(m.updatedAt) && (m.archivedAt === null || Number.isFinite(m.archivedAt));
6277
- }
6278
- function classifyDecay(m, now, policy) {
6279
- const resolved = resolvePolicy(policy);
6280
- if (!hasFiniteTimestamps(m, now)) {
6281
- getLogger().warn("[memory/decay] non-finite timestamp on a memory row; keeping it", {
6282
- now,
6283
- updatedAt: m.updatedAt,
6284
- archivedAt: m.archivedAt,
6285
- factType: m.factType
6286
- });
6287
- return "keep";
6288
- }
6289
- if (m.archivedAt !== null) {
6290
- return now - m.archivedAt > resolved.hardDeleteWindowMs ? "delete" : "keep";
6291
- }
6292
- if (m.source === "manual") return "keep";
6293
- if (isTimeSensitiveType(m.factType) && m.eventTimeEnd !== null) {
6294
- if (m.eventTimeEnd < now - resolved.pastEventGraceMs) return "archive";
6295
- if (m.eventTimeEnd >= now) return "keep";
6296
- }
6297
- if (now - m.updatedAt > ttlForType(m.factType, resolved)) return "archive";
6298
- return "keep";
6299
- }
6300
-
6301
6413
  // src/lib/memory/decayClassifier.ts
6302
6414
  var DEFAULT_MODEL2 = "inclusionai/ling-2.6-flash";
6303
6415
  var DEFAULT_ATTEMPTS2 = 2;
@@ -6395,7 +6507,7 @@ function toDecayInput(c) {
6395
6507
  };
6396
6508
  }
6397
6509
  function isBorderline(input) {
6398
- if (input.source === "manual") return false;
6510
+ if (input.source === "manual" || input.source === SOURCE_PHOTO) return false;
6399
6511
  if (input.trustTier === "quarantined") return false;
6400
6512
  if (input.archivedAt !== null) return false;
6401
6513
  if (input.factType === null || input.factType === "other") return true;
@@ -13635,6 +13747,7 @@ export {
13635
13747
  hardDeleteMediaOp,
13636
13748
  hasEncryptionKey,
13637
13749
  hasKeyPair,
13750
+ ingestPublishedPhotoMemoriesOp,
13638
13751
  injectionSignatureCatalog,
13639
13752
  isRerankerAvailable,
13640
13753
  isSupportedFile,
@@ -13645,6 +13758,7 @@ export {
13645
13758
  mediaToStored,
13646
13759
  migrateFromModelPreferencesOp,
13647
13760
  onKeyAvailable,
13761
+ parseMedia,
13648
13762
  preEmbedVaultMemories,
13649
13763
  preprocessFiles,
13650
13764
  progressiveSummarize,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  recall
3
- } from "./chunk-FYT5MBVO.mjs";
3
+ } from "./chunk-S5WEN7TE.mjs";
4
4
  import "./chunk-OBDRKQQI.mjs";
5
5
  import "./chunk-3RPGXXPZ.mjs";
6
6
  export {
@@ -2528,7 +2528,7 @@ IMPORTANT: For write operations (POST, PUT, PATCH, DELETE), always confirm with
2528
2528
  }
2529
2529
  try {
2530
2530
  const data = JSON.parse(text);
2531
- const json = JSON.stringify(data, null, 2);
2531
+ const json = JSON.stringify(data);
2532
2532
  return truncate(json, MAX_RESPONSE_SIZE);
2533
2533
  } catch {
2534
2534
  return truncate(text, MAX_RESPONSE_SIZE);
@@ -2379,7 +2379,7 @@ IMPORTANT: For write operations (POST, PUT, PATCH, DELETE), always confirm with
2379
2379
  }
2380
2380
  try {
2381
2381
  const data = JSON.parse(text);
2382
- const json = JSON.stringify(data, null, 2);
2382
+ const json = JSON.stringify(data);
2383
2383
  return truncate(json, MAX_RESPONSE_SIZE);
2384
2384
  } catch {
2385
2385
  return truncate(text, MAX_RESPONSE_SIZE);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anuma/sdk",
3
- "version": "6.1.1",
3
+ "version": "6.3.0",
4
4
  "description": "",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",