@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.
@@ -4884,6 +4884,27 @@ var init_encryption2 = __esm({
4884
4884
  }
4885
4885
  });
4886
4886
 
4887
+ // src/lib/db/memoryVault/types.ts
4888
+ function parseMedia(value) {
4889
+ if (typeof value !== "string" || value === "") return null;
4890
+ try {
4891
+ const parsed = JSON.parse(value);
4892
+ if (!Array.isArray(parsed)) return null;
4893
+ const refs = parsed.filter((r) => typeof r === "object" && r !== null).map((r) => ({
4894
+ feedItemId: Number(r.feedItemId ?? r.feed_item_id),
4895
+ objectKey: r.objectKey ?? r.object_key ?? null
4896
+ })).filter((r) => Number.isFinite(r.feedItemId));
4897
+ return refs.length > 0 ? refs : null;
4898
+ } catch {
4899
+ return null;
4900
+ }
4901
+ }
4902
+ var init_types4 = __esm({
4903
+ "src/lib/db/memoryVault/types.ts"() {
4904
+ "use strict";
4905
+ }
4906
+ });
4907
+
4887
4908
  // src/lib/db/memoryVault/operations.ts
4888
4909
  function visibilityOrPrivate(value) {
4889
4910
  return value === "public" ? value : "private";
@@ -4945,6 +4966,7 @@ function vaultMemoryToStoredRaw(memory) {
4945
4966
  sourceChunkIds,
4946
4967
  proofCount: memory.proofCount ?? null,
4947
4968
  source: memory.source ?? null,
4969
+ media: parseMedia(memory.media),
4948
4970
  eventTimeStart: memory.eventTimeStart ?? null,
4949
4971
  eventTimeEnd: memory.eventTimeEnd ?? null,
4950
4972
  eventTimeKind: memory.eventTimeKind ?? null,
@@ -5227,6 +5249,7 @@ function vaultMemoryRawToStoredRaw(raw) {
5227
5249
  eventTimeKind: raw.event_time_kind ?? null,
5228
5250
  // SQLite stores booleans as 0/1, LokiJS as true/false — coerce both.
5229
5251
  topicsUserManaged: raw.topics_user_managed === true || raw.topics_user_managed === 1,
5252
+ media: parseMedia(raw.media),
5230
5253
  topics: parseTopics(raw.topics),
5231
5254
  topicsUpdatedAt: raw.topics_updated_at ?? null,
5232
5255
  topicsExtractedAt: raw.topics_extracted_at ?? null,
@@ -6013,6 +6036,7 @@ var init_operations3 = __esm({
6013
6036
  init_operations2();
6014
6037
  init_types3();
6015
6038
  init_encryption2();
6039
+ init_types4();
6016
6040
  NON_PRIVATE_VISIBILITIES = ["public"];
6017
6041
  KNOWN_TRUST_TIERS = /* @__PURE__ */ new Set(["quarantined", "trusted"]);
6018
6042
  TOPICS_EXTRACTION_VERSION = 3;
@@ -6340,17 +6364,17 @@ function recencyMultiplier(updatedAt, opts = {}) {
6340
6364
  const now = opts.now ?? /* @__PURE__ */ new Date();
6341
6365
  const nowMs2 = now.getTime();
6342
6366
  if (!Number.isFinite(nowMs2)) return noDate;
6343
- const ageDays2 = Math.max(0, (nowMs2 - updatedMs) / DAY_MS);
6367
+ const ageDays2 = Math.max(0, (nowMs2 - updatedMs) / DAY_MS2);
6344
6368
  const perYearDecay = opts.perYearDecay ?? DEFAULT_PER_YEAR_DECAY;
6345
6369
  const floor = opts.floor ?? DEFAULT_FLOOR;
6346
6370
  const decay = perYearDecay * (ageDays2 / 365);
6347
6371
  return Math.max(floor, 1 - decay);
6348
6372
  }
6349
- var DAY_MS, DEFAULT_PER_YEAR_DECAY, DEFAULT_FLOOR, DEFAULT_NO_DATE_MULTIPLIER;
6373
+ var DAY_MS2, DEFAULT_PER_YEAR_DECAY, DEFAULT_FLOOR, DEFAULT_NO_DATE_MULTIPLIER;
6350
6374
  var init_recency = __esm({
6351
6375
  "src/lib/memory/recency.ts"() {
6352
6376
  "use strict";
6353
- DAY_MS = 1e3 * 60 * 60 * 24;
6377
+ DAY_MS2 = 1e3 * 60 * 60 * 24;
6354
6378
  DEFAULT_PER_YEAR_DECAY = 0.2;
6355
6379
  DEFAULT_FLOOR = 0.1;
6356
6380
  DEFAULT_NO_DATE_MULTIPLIER = 0.5;
@@ -7107,8 +7131,8 @@ function classifyObservationTrend(input, now = Date.now()) {
7107
7131
  const lastMsRaw = input.lastObservedAt;
7108
7132
  const lastMs = lastMsRaw !== null && lastMsRaw !== void 0 && Number.isFinite(lastMsRaw) ? Math.max(createdMs, lastMsRaw) : createdMs;
7109
7133
  const proofs = Math.max(1, input.proofCount ?? 1);
7110
- const ageDays2 = Math.max(0, (now - createdMs) / DAY_MS2);
7111
- const daysSinceLast = Math.max(0, (now - lastMs) / DAY_MS2);
7134
+ const ageDays2 = Math.max(0, (now - createdMs) / DAY_MS3);
7135
+ const daysSinceLast = Math.max(0, (now - lastMs) / DAY_MS3);
7112
7136
  if (daysSinceLast >= TREND_STALE_WINDOW_DAYS) return "stale";
7113
7137
  if (daysSinceLast >= TREND_RECENT_WINDOW_DAYS) return "weakening";
7114
7138
  if (ageDays2 <= TREND_RECENT_WINDOW_DAYS && proofs <= 2) return "new";
@@ -7129,11 +7153,11 @@ function summarizeObservationTrends(inputs, now = Date.now()) {
7129
7153
  }
7130
7154
  return counts;
7131
7155
  }
7132
- var DAY_MS2, TREND_RECENT_WINDOW_DAYS, TREND_STALE_WINDOW_DAYS;
7156
+ var DAY_MS3, TREND_RECENT_WINDOW_DAYS, TREND_STALE_WINDOW_DAYS;
7133
7157
  var init_observationTrend = __esm({
7134
7158
  "src/lib/memory/observationTrend.ts"() {
7135
7159
  "use strict";
7136
- DAY_MS2 = 1e3 * 60 * 60 * 24;
7160
+ DAY_MS3 = 1e3 * 60 * 60 * 24;
7137
7161
  TREND_RECENT_WINDOW_DAYS = 30;
7138
7162
  TREND_STALE_WINDOW_DAYS = 90;
7139
7163
  }
@@ -9581,6 +9605,7 @@ __export(index_exports, {
9581
9605
  hasICloudCredentials: () => hasICloudCredentials,
9582
9606
  hasKeyPair: () => hasKeyPair,
9583
9607
  hasNotionCredentials: () => hasNotionCredentials,
9608
+ ingestPublishedPhotoMemoriesOp: () => ingestPublishedPhotoMemoriesOp,
9584
9609
  injectionSignatureCatalog: () => injectionSignatureCatalog,
9585
9610
  insertAfterId: () => insertAfterId,
9586
9611
  insertChild: () => insertChild,
@@ -9607,6 +9632,7 @@ __export(index_exports, {
9607
9632
  noopLogger: () => noopLogger,
9608
9633
  onKeyAvailable: () => onKeyAvailable,
9609
9634
  parseJsx: () => parseJsx,
9635
+ parseMedia: () => parseMedia,
9610
9636
  preEmbedVaultMemories: () => preEmbedVaultMemories,
9611
9637
  preprocessFiles: () => preprocessFiles,
9612
9638
  previewToolSelection: () => previewToolSelection,
@@ -16406,6 +16432,9 @@ __decorateClass([
16406
16432
  __decorateClass([
16407
16433
  (0, import_decorators3.field)("topics_updated_at")
16408
16434
  ], VaultMemory.prototype, "topicsUpdatedAt", 2);
16435
+ __decorateClass([
16436
+ (0, import_decorators3.field)("media")
16437
+ ], VaultMemory.prototype, "media", 2);
16409
16438
  __decorateClass([
16410
16439
  (0, import_decorators3.field)("topics_extracted_at")
16411
16440
  ], VaultMemory.prototype, "topicsExtractedAt", 2);
@@ -16456,6 +16485,138 @@ __decorateClass([
16456
16485
  // src/lib/db/memoryVault/index.ts
16457
16486
  init_operations3();
16458
16487
 
16488
+ // src/lib/memory/decay.ts
16489
+ init_logger();
16490
+ var DAY_MS = 24 * 60 * 60 * 1e3;
16491
+ var SHORT_TTL_MS = 30 * DAY_MS;
16492
+ var MEDIUM_TTL_MS = 180 * DAY_MS;
16493
+ var SOURCE_PHOTO = "photo";
16494
+ var NEVER_TTL_MS = Number.POSITIVE_INFINITY;
16495
+ var HARD_DELETE_WINDOW_MS = 30 * DAY_MS;
16496
+ var PAST_EVENT_GRACE_MS = 7 * DAY_MS;
16497
+ var DEFAULT_DECAY_POLICY = {
16498
+ ttlByType: {
16499
+ identity: NEVER_TTL_MS,
16500
+ preference: NEVER_TTL_MS,
16501
+ relationship: NEVER_TTL_MS,
16502
+ constraint: NEVER_TTL_MS,
16503
+ plan: SHORT_TTL_MS,
16504
+ ongoing_context: SHORT_TTL_MS,
16505
+ other: MEDIUM_TTL_MS
16506
+ },
16507
+ fallbackTtlMs: MEDIUM_TTL_MS,
16508
+ hardDeleteWindowMs: HARD_DELETE_WINDOW_MS,
16509
+ pastEventGraceMs: PAST_EVENT_GRACE_MS
16510
+ };
16511
+ function resolvePolicy(policy) {
16512
+ if (!policy) return DEFAULT_DECAY_POLICY;
16513
+ return {
16514
+ ttlByType: { ...DEFAULT_DECAY_POLICY.ttlByType, ...policy.ttlByType },
16515
+ fallbackTtlMs: policy.fallbackTtlMs ?? DEFAULT_DECAY_POLICY.fallbackTtlMs,
16516
+ hardDeleteWindowMs: policy.hardDeleteWindowMs ?? DEFAULT_DECAY_POLICY.hardDeleteWindowMs,
16517
+ pastEventGraceMs: policy.pastEventGraceMs ?? DEFAULT_DECAY_POLICY.pastEventGraceMs
16518
+ };
16519
+ }
16520
+ function ttlForType(factType, policy) {
16521
+ const resolved = resolvePolicy(policy);
16522
+ if (factType === null) return resolved.fallbackTtlMs;
16523
+ return resolved.ttlByType[factType] ?? resolved.fallbackTtlMs;
16524
+ }
16525
+ function isTimeSensitiveType(factType) {
16526
+ return factType === "plan" || factType === "ongoing_context";
16527
+ }
16528
+ function hasFiniteTimestamps(m, now) {
16529
+ return Number.isFinite(now) && Number.isFinite(m.updatedAt) && (m.archivedAt === null || Number.isFinite(m.archivedAt));
16530
+ }
16531
+ function classifyDecay(m, now, policy) {
16532
+ const resolved = resolvePolicy(policy);
16533
+ if (!hasFiniteTimestamps(m, now)) {
16534
+ getLogger().warn("[memory/decay] non-finite timestamp on a memory row; keeping it", {
16535
+ now,
16536
+ updatedAt: m.updatedAt,
16537
+ archivedAt: m.archivedAt,
16538
+ factType: m.factType
16539
+ });
16540
+ return "keep";
16541
+ }
16542
+ if (m.archivedAt !== null) {
16543
+ return now - m.archivedAt > resolved.hardDeleteWindowMs ? "delete" : "keep";
16544
+ }
16545
+ if (m.source === "manual" || m.source === SOURCE_PHOTO) return "keep";
16546
+ if (isTimeSensitiveType(m.factType) && m.eventTimeEnd !== null) {
16547
+ if (m.eventTimeEnd < now - resolved.pastEventGraceMs) return "archive";
16548
+ if (m.eventTimeEnd >= now) return "keep";
16549
+ }
16550
+ if (now - m.updatedAt > ttlForType(m.factType, resolved)) return "archive";
16551
+ return "keep";
16552
+ }
16553
+
16554
+ // src/lib/db/memoryVault/photoIngest.ts
16555
+ init_encryption2();
16556
+ var PHOTO_MEMORY_ID_PREFIX = "photo:";
16557
+ async function ingestPublishedPhotoMemoriesOp(ctx, rows) {
16558
+ const byId = /* @__PURE__ */ new Map();
16559
+ for (const r of rows) {
16560
+ if (typeof r.memoryId !== "string" || !r.memoryId.startsWith(PHOTO_MEMORY_ID_PREFIX)) continue;
16561
+ if (!byId.has(r.memoryId)) byId.set(r.memoryId, r);
16562
+ }
16563
+ const photoRows = [...byId.values()];
16564
+ if (photoRows.length === 0) return { inserted: 0, skipped: 0 };
16565
+ const known = await ctx.vaultMemoryCollection.query().fetchIds().then((ids) => new Set(ids));
16566
+ const candidates = photoRows.filter((r) => !known.has(r.memoryId));
16567
+ if (candidates.length === 0) return { inserted: 0, skipped: photoRows.length };
16568
+ const fresh = candidates;
16569
+ const contents = await Promise.all(
16570
+ fresh.map(async (r) => {
16571
+ if (ctx.walletAddress && ctx.signMessage) {
16572
+ return encryptVaultMemoryContent(
16573
+ r.text,
16574
+ ctx.walletAddress,
16575
+ ctx.signMessage,
16576
+ ctx.embeddedWalletSigner
16577
+ );
16578
+ }
16579
+ return r.text;
16580
+ })
16581
+ );
16582
+ const now = Date.now();
16583
+ let inserted = 0;
16584
+ await ctx.database.write(async () => {
16585
+ const present = new Set(await ctx.vaultMemoryCollection.query().fetchIds());
16586
+ const writable = fresh.map((row, i) => ({ row, content: contents[i] })).filter(({ row }) => !present.has(row.memoryId));
16587
+ inserted = writable.length;
16588
+ if (writable.length === 0) return;
16589
+ const prepared = writable.map(
16590
+ ({ row, content }) => ctx.vaultMemoryCollection.prepareCreate((record) => {
16591
+ record._raw.id = row.memoryId;
16592
+ record._setRaw("content", content);
16593
+ record._setRaw("scope", "private");
16594
+ record._setRaw("folder_id", null);
16595
+ record._setRaw("user_id", ctx.userId ?? null);
16596
+ record._setRaw("is_deleted", false);
16597
+ record._setRaw("proof_count", 1);
16598
+ record._setRaw("source", SOURCE_PHOTO);
16599
+ record._setRaw(
16600
+ "media",
16601
+ row.media && row.media.length > 0 ? JSON.stringify(row.media) : null
16602
+ );
16603
+ record._setRaw("visibility", "public");
16604
+ record._setRaw("published_at", now);
16605
+ if (row.eventTime) {
16606
+ record._setRaw("event_time_start", row.eventTime.start ?? null);
16607
+ record._setRaw("event_time_end", row.eventTime.end ?? null);
16608
+ record._setRaw("event_time_kind", row.eventTime.kind ?? null);
16609
+ }
16610
+ })
16611
+ );
16612
+ await ctx.database.batch(...prepared);
16613
+ });
16614
+ return { inserted, skipped: photoRows.length - inserted };
16615
+ }
16616
+
16617
+ // src/lib/db/memoryVault/index.ts
16618
+ init_types4();
16619
+
16459
16620
  // src/react/useChatStorage.ts
16460
16621
  init_logger();
16461
16622
 
@@ -17382,6 +17543,9 @@ async function extractFacts(messages, options) {
17382
17543
  ...options.apiKey !== void 0 && { apiKey: options.apiKey },
17383
17544
  ...options.getToken !== void 0 && { getToken: options.getToken },
17384
17545
  ...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
17546
+ ...options.endpointOverride !== void 0 && {
17547
+ endpointOverride: options.endpointOverride
17548
+ },
17385
17549
  model: options.model ?? DEFAULT_EXTRACTION_MODEL,
17386
17550
  systemPrompt: SYSTEM_PROMPT4,
17387
17551
  userMessage: `Today's date is ${today}. Resolve any relative dates ("yesterday", "next week") against it.
@@ -17895,71 +18059,6 @@ function createChunkVectorCache(maxSize = DEFAULT_CHUNK_CACHE_SIZE) {
17895
18059
  return new LRUCache(maxSize);
17896
18060
  }
17897
18061
 
17898
- // src/lib/memory/decay.ts
17899
- init_logger();
17900
- var DAY_MS3 = 24 * 60 * 60 * 1e3;
17901
- var SHORT_TTL_MS = 30 * DAY_MS3;
17902
- var MEDIUM_TTL_MS = 180 * DAY_MS3;
17903
- var NEVER_TTL_MS = Number.POSITIVE_INFINITY;
17904
- var HARD_DELETE_WINDOW_MS = 30 * DAY_MS3;
17905
- var PAST_EVENT_GRACE_MS = 7 * DAY_MS3;
17906
- var DEFAULT_DECAY_POLICY = {
17907
- ttlByType: {
17908
- identity: NEVER_TTL_MS,
17909
- preference: NEVER_TTL_MS,
17910
- relationship: NEVER_TTL_MS,
17911
- constraint: NEVER_TTL_MS,
17912
- plan: SHORT_TTL_MS,
17913
- ongoing_context: SHORT_TTL_MS,
17914
- other: MEDIUM_TTL_MS
17915
- },
17916
- fallbackTtlMs: MEDIUM_TTL_MS,
17917
- hardDeleteWindowMs: HARD_DELETE_WINDOW_MS,
17918
- pastEventGraceMs: PAST_EVENT_GRACE_MS
17919
- };
17920
- function resolvePolicy(policy) {
17921
- if (!policy) return DEFAULT_DECAY_POLICY;
17922
- return {
17923
- ttlByType: { ...DEFAULT_DECAY_POLICY.ttlByType, ...policy.ttlByType },
17924
- fallbackTtlMs: policy.fallbackTtlMs ?? DEFAULT_DECAY_POLICY.fallbackTtlMs,
17925
- hardDeleteWindowMs: policy.hardDeleteWindowMs ?? DEFAULT_DECAY_POLICY.hardDeleteWindowMs,
17926
- pastEventGraceMs: policy.pastEventGraceMs ?? DEFAULT_DECAY_POLICY.pastEventGraceMs
17927
- };
17928
- }
17929
- function ttlForType(factType, policy) {
17930
- const resolved = resolvePolicy(policy);
17931
- if (factType === null) return resolved.fallbackTtlMs;
17932
- return resolved.ttlByType[factType] ?? resolved.fallbackTtlMs;
17933
- }
17934
- function isTimeSensitiveType(factType) {
17935
- return factType === "plan" || factType === "ongoing_context";
17936
- }
17937
- function hasFiniteTimestamps(m, now) {
17938
- return Number.isFinite(now) && Number.isFinite(m.updatedAt) && (m.archivedAt === null || Number.isFinite(m.archivedAt));
17939
- }
17940
- function classifyDecay(m, now, policy) {
17941
- const resolved = resolvePolicy(policy);
17942
- if (!hasFiniteTimestamps(m, now)) {
17943
- getLogger().warn("[memory/decay] non-finite timestamp on a memory row; keeping it", {
17944
- now,
17945
- updatedAt: m.updatedAt,
17946
- archivedAt: m.archivedAt,
17947
- factType: m.factType
17948
- });
17949
- return "keep";
17950
- }
17951
- if (m.archivedAt !== null) {
17952
- return now - m.archivedAt > resolved.hardDeleteWindowMs ? "delete" : "keep";
17953
- }
17954
- if (m.source === "manual") return "keep";
17955
- if (isTimeSensitiveType(m.factType) && m.eventTimeEnd !== null) {
17956
- if (m.eventTimeEnd < now - resolved.pastEventGraceMs) return "archive";
17957
- if (m.eventTimeEnd >= now) return "keep";
17958
- }
17959
- if (now - m.updatedAt > ttlForType(m.factType, resolved)) return "archive";
17960
- return "keep";
17961
- }
17962
-
17963
18062
  // src/lib/memory/decayClassifier.ts
17964
18063
  init_logger();
17965
18064
  init_redactor();
@@ -18062,7 +18161,7 @@ function toDecayInput(c) {
18062
18161
  };
18063
18162
  }
18064
18163
  function isBorderline(input) {
18065
- if (input.source === "manual") return false;
18164
+ if (input.source === "manual" || input.source === SOURCE_PHOTO) return false;
18066
18165
  if (input.trustTier === "quarantined") return false;
18067
18166
  if (input.archivedAt !== null) return false;
18068
18167
  if (input.factType === null || input.factType === "other") return true;
@@ -24056,7 +24155,7 @@ __decorateClass([
24056
24155
  ], VaultFolder.prototype, "context", 2);
24057
24156
 
24058
24157
  // src/lib/db/schema.ts
24059
- var SDK_SCHEMA_VERSION = 44;
24158
+ var SDK_SCHEMA_VERSION = 45;
24060
24159
  var sdkSchema = (0, import_watermelondb20.appSchema)({
24061
24160
  version: SDK_SCHEMA_VERSION,
24062
24161
  tables: [
@@ -24204,6 +24303,18 @@ var sdkSchema = (0, import_watermelondb20.appSchema)({
24204
24303
  // paths key on `updated_at` — so without this a topic-only change would
24205
24304
  // neither upload nor merge. Null = `topics` never written.
24206
24305
  { name: "topics_updated_at", type: "number", isOptional: true },
24306
+ // The photo(s) a SERVER-EXTRACTED memory was read out of, as a JSON
24307
+ // array of `{feed_item_id, object_key}` — exactly what
24308
+ // GET /api/memories/published returns in `media[]`. Enough to render the
24309
+ // source image without a second round-trip per memory.
24310
+ //
24311
+ // A JSON column rather than a join table: nothing on the client ever
24312
+ // queries BY photo (the only direction is memory -> render its image),
24313
+ // so a table would add a sync lane and a local-id space to serve a
24314
+ // question nobody asks. `topics` and `source_chunk_ids` set the
24315
+ // precedent for a list that is only ever read back whole. Null on
24316
+ // anything not extracted from a photo.
24317
+ { name: "media", type: "string", isOptional: true },
24207
24318
  // Unix ms of the last LLM topic-extraction pass over this memory's
24208
24319
  // content. Null = never extracted standalone (legacy rows with entity
24209
24320
  // links are grandfathered — see getMemoriesNeedingTopicExtractionOp).
@@ -25038,6 +25149,20 @@ var sdkMigrations = (0, import_migrations2.schemaMigrations)({
25038
25149
  columns: [{ name: "origin", type: "string", isOptional: true }]
25039
25150
  })
25040
25151
  ]
25152
+ },
25153
+ // v44 -> v45: `media` on memory_vault — the photo(s) a server-extracted
25154
+ // memory was read out of, as JSON `[{feed_item_id, object_key}]`, mirroring
25155
+ // the `media[]` that GET /api/memories/published already returns. Existing
25156
+ // rows keep NULL, which is the correct value for every memory that did not
25157
+ // come from a photo (i.e. all of them until photo ingest runs).
25158
+ {
25159
+ toVersion: 45,
25160
+ steps: [
25161
+ (0, import_migrations2.addColumns)({
25162
+ table: "memory_vault",
25163
+ columns: [{ name: "media", type: "string", isOptional: true }]
25164
+ })
25165
+ ]
25041
25166
  }
25042
25167
  ]
25043
25168
  });
@@ -34939,6 +35064,7 @@ function renderAnumaJsx(jsx3) {
34939
35064
  hasICloudCredentials,
34940
35065
  hasKeyPair,
34941
35066
  hasNotionCredentials,
35067
+ ingestPublishedPhotoMemoriesOp,
34942
35068
  injectionSignatureCatalog,
34943
35069
  insertAfterId,
34944
35070
  insertChild,
@@ -34965,6 +35091,7 @@ function renderAnumaJsx(jsx3) {
34965
35091
  noopLogger,
34966
35092
  onKeyAvailable,
34967
35093
  parseJsx,
35094
+ parseMedia,
34968
35095
  preEmbedVaultMemories,
34969
35096
  preprocessFiles,
34970
35097
  previewToolSelection,