@anuma/sdk 3.3.1 → 3.4.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.
@@ -4294,6 +4294,7 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
4294
4294
  createdAt: m.createdAt,
4295
4295
  updatedAt: m.updatedAt,
4296
4296
  proofCount: m.proofCount,
4297
+ lastObservedAt: m.lastObservedAt,
4297
4298
  eventTimeStart: m.eventTimeStart,
4298
4299
  sourceChunkIds: m.sourceChunkIds,
4299
4300
  eventTimeEnd: m.eventTimeEnd,
@@ -4310,13 +4311,27 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
4310
4311
  );
4311
4312
  }
4312
4313
  }
4313
- const timestampById = new Map(
4314
- memories.map((m) => [m.uniqueId, { createdAt: m.createdAt, updatedAt: m.updatedAt }])
4314
+ const metaById = new Map(
4315
+ memories.map((m) => [
4316
+ m.uniqueId,
4317
+ {
4318
+ createdAt: m.createdAt,
4319
+ updatedAt: m.updatedAt,
4320
+ proofCount: m.proofCount,
4321
+ lastObservedAt: m.lastObservedAt
4322
+ }
4323
+ ])
4315
4324
  );
4316
4325
  const stampTimestamps = (out) => {
4317
4326
  const results2 = out.results.map((r) => {
4318
- const ts = timestampById.get(r.uniqueId);
4319
- return ts ? { ...r, createdAt: ts.createdAt, updatedAt: ts.updatedAt } : r;
4327
+ const meta = metaById.get(r.uniqueId);
4328
+ return meta ? {
4329
+ ...r,
4330
+ createdAt: meta.createdAt,
4331
+ updatedAt: meta.updatedAt,
4332
+ proofCount: meta.proofCount,
4333
+ lastObservedAt: meta.lastObservedAt
4334
+ } : r;
4320
4335
  });
4321
4336
  return {
4322
4337
  results: results2,
@@ -4510,7 +4525,7 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
4510
4525
  legacy.map((r) => ({ id: r.uniqueId, content: r.content, score: r.similarity }))
4511
4526
  );
4512
4527
  }
4513
- const { recall: recall2 } = await import("./recall-C3LJ5R2E.mjs");
4528
+ const { recall: recall2 } = await import("./recall-7ZX6T2VD.mjs");
4514
4529
  const result = await recall2(
4515
4530
  query,
4516
4531
  { vaultCtx, embeddingOptions, vaultCache: cache },
@@ -4774,6 +4789,42 @@ Which should be expanded?`,
4774
4789
  };
4775
4790
  }
4776
4791
 
4792
+ // src/lib/memory/observationTrend.ts
4793
+ var DAY_MS2 = 1e3 * 60 * 60 * 24;
4794
+ var TREND_RECENT_WINDOW_DAYS = 30;
4795
+ var TREND_STALE_WINDOW_DAYS = 90;
4796
+ function toMs(value) {
4797
+ return value instanceof Date ? value.getTime() : value;
4798
+ }
4799
+ function classifyObservationTrend(input, now = Date.now()) {
4800
+ const createdMs = toMs(input.createdAt);
4801
+ if (!Number.isFinite(createdMs) || !Number.isFinite(now)) return "stable";
4802
+ const lastMsRaw = input.lastObservedAt;
4803
+ const lastMs = lastMsRaw !== null && lastMsRaw !== void 0 && Number.isFinite(lastMsRaw) ? Math.max(createdMs, lastMsRaw) : createdMs;
4804
+ const proofs = Math.max(1, input.proofCount ?? 1);
4805
+ const ageDays = Math.max(0, (now - createdMs) / DAY_MS2);
4806
+ const daysSinceLast = Math.max(0, (now - lastMs) / DAY_MS2);
4807
+ if (daysSinceLast >= TREND_STALE_WINDOW_DAYS) return "stale";
4808
+ if (daysSinceLast >= TREND_RECENT_WINDOW_DAYS) return "weakening";
4809
+ if (ageDays <= TREND_RECENT_WINDOW_DAYS && proofs <= 2) return "new";
4810
+ if (proofs >= 3) return "strengthening";
4811
+ if (proofs >= 2 && ageDays > TREND_RECENT_WINDOW_DAYS) return "strengthening";
4812
+ return "stable";
4813
+ }
4814
+ function summarizeObservationTrends(inputs, now = Date.now()) {
4815
+ const counts = {
4816
+ new: 0,
4817
+ strengthening: 0,
4818
+ stable: 0,
4819
+ weakening: 0,
4820
+ stale: 0
4821
+ };
4822
+ for (const input of inputs) {
4823
+ counts[classifyObservationTrend(input, now)]++;
4824
+ }
4825
+ return counts;
4826
+ }
4827
+
4777
4828
  // src/lib/memory/queryTemporal.ts
4778
4829
  var RELATIVE_DAY_ENTRIES = [
4779
4830
  [/\btoday\b/, "today", 0],
@@ -5168,7 +5219,7 @@ async function recall(query, ctx, options = {}) {
5168
5219
  const fuseStart = nowMs();
5169
5220
  if (types.length === 1 || factResults.length === 0 || chunkResults.length === 0) {
5170
5221
  const memories2 = [
5171
- ...factResults.map(toFactMemory),
5222
+ ...factResults.map((r) => toFactMemory(r, options.now)),
5172
5223
  ...chunkResults.map(toChunkMemory)
5173
5224
  ];
5174
5225
  memories2.sort((a, b) => b.score - a.score);
@@ -5189,7 +5240,7 @@ async function recall(query, ctx, options = {}) {
5189
5240
  const fused = rrfFuse([factRanking, chunkRanking], options.rrfK);
5190
5241
  const byId = /* @__PURE__ */ new Map();
5191
5242
  for (const r of factResults) {
5192
- const m = toFactMemory(r);
5243
+ const m = toFactMemory(r, options.now);
5193
5244
  m.score = fused.get(`fact:${r.uniqueId}`) ?? 0;
5194
5245
  if (!m.scoreBreakdown) m.scoreBreakdown = {};
5195
5246
  m.scoreBreakdown.fused = r.similarity;
@@ -5238,7 +5289,10 @@ async function recall(query, ctx, options = {}) {
5238
5289
  ...vaultSize !== void 0 && { vaultSize }
5239
5290
  };
5240
5291
  }
5241
- function toFactMemory(r) {
5292
+ function toFactMemory(r, now) {
5293
+ const createdAt = r.createdAt ?? /* @__PURE__ */ new Date(0);
5294
+ const proofCount = r.proofCount ?? void 0;
5295
+ const lastObservedAt = r.lastObservedAt ?? null;
5242
5296
  return {
5243
5297
  id: r.uniqueId,
5244
5298
  kind: "fact",
@@ -5254,6 +5308,18 @@ function toFactMemory(r) {
5254
5308
  // (and UI reading them) carry the fact's type. Undefined when untyped.
5255
5309
  ...r.factType !== void 0 && { factType: r.factType },
5256
5310
  ...r.sourceChunkIds !== void 0 && r.sourceChunkIds !== null && { sourceChunkIds: r.sourceChunkIds },
5311
+ ...proofCount !== void 0 && proofCount !== null && { proofCount },
5312
+ ...lastObservedAt !== null && { lastObservedAt },
5313
+ // C2 — algorithmic trend from evidence timestamps (no LLM). Honor
5314
+ // RecallOptions.now so back-dated eval harnesses get consistent labels.
5315
+ observationTrend: classifyObservationTrend(
5316
+ {
5317
+ createdAt,
5318
+ lastObservedAt,
5319
+ proofCount
5320
+ },
5321
+ now ?? Date.now()
5322
+ ),
5257
5323
  // r.similarity from searchVaultMemoriesWithSize is the fused score
5258
5324
  // (cosine + BM25 + RRF + recency + proof) when useFusion=true (the
5259
5325
  // default) and pure cosine when useFusion=false. The breakdown
@@ -5262,7 +5328,7 @@ function toFactMemory(r) {
5262
5328
  content: r.content,
5263
5329
  score: r.similarity,
5264
5330
  scoreBreakdown: { fused: r.similarity },
5265
- createdAt: r.createdAt ?? /* @__PURE__ */ new Date(0),
5331
+ createdAt,
5266
5332
  updatedAt: r.updatedAt ?? /* @__PURE__ */ new Date(0)
5267
5333
  };
5268
5334
  }
@@ -5430,6 +5496,10 @@ export {
5430
5496
  capHopsForDensity,
5431
5497
  traverseGraphLane,
5432
5498
  createLlmNeighborRefiner,
5499
+ TREND_RECENT_WINDOW_DAYS,
5500
+ TREND_STALE_WINDOW_DAYS,
5501
+ classifyObservationTrend,
5502
+ summarizeObservationTrends,
5433
5503
  recall,
5434
5504
  preEmbedVaultMemories,
5435
5505
  eagerEmbedContent,
@@ -5072,6 +5072,48 @@ var init_graphTraversal = __esm({
5072
5072
  }
5073
5073
  });
5074
5074
 
5075
+ // src/lib/memory/observationTrend.ts
5076
+ function toMs(value) {
5077
+ return value instanceof Date ? value.getTime() : value;
5078
+ }
5079
+ function classifyObservationTrend(input, now = Date.now()) {
5080
+ const createdMs = toMs(input.createdAt);
5081
+ if (!Number.isFinite(createdMs) || !Number.isFinite(now)) return "stable";
5082
+ const lastMsRaw = input.lastObservedAt;
5083
+ const lastMs = lastMsRaw !== null && lastMsRaw !== void 0 && Number.isFinite(lastMsRaw) ? Math.max(createdMs, lastMsRaw) : createdMs;
5084
+ const proofs = Math.max(1, input.proofCount ?? 1);
5085
+ const ageDays2 = Math.max(0, (now - createdMs) / DAY_MS2);
5086
+ const daysSinceLast = Math.max(0, (now - lastMs) / DAY_MS2);
5087
+ if (daysSinceLast >= TREND_STALE_WINDOW_DAYS) return "stale";
5088
+ if (daysSinceLast >= TREND_RECENT_WINDOW_DAYS) return "weakening";
5089
+ if (ageDays2 <= TREND_RECENT_WINDOW_DAYS && proofs <= 2) return "new";
5090
+ if (proofs >= 3) return "strengthening";
5091
+ if (proofs >= 2 && ageDays2 > TREND_RECENT_WINDOW_DAYS) return "strengthening";
5092
+ return "stable";
5093
+ }
5094
+ function summarizeObservationTrends(inputs, now = Date.now()) {
5095
+ const counts = {
5096
+ new: 0,
5097
+ strengthening: 0,
5098
+ stable: 0,
5099
+ weakening: 0,
5100
+ stale: 0
5101
+ };
5102
+ for (const input of inputs) {
5103
+ counts[classifyObservationTrend(input, now)]++;
5104
+ }
5105
+ return counts;
5106
+ }
5107
+ var DAY_MS2, TREND_RECENT_WINDOW_DAYS, TREND_STALE_WINDOW_DAYS;
5108
+ var init_observationTrend = __esm({
5109
+ "src/lib/memory/observationTrend.ts"() {
5110
+ "use strict";
5111
+ DAY_MS2 = 1e3 * 60 * 60 * 24;
5112
+ TREND_RECENT_WINDOW_DAYS = 30;
5113
+ TREND_STALE_WINDOW_DAYS = 90;
5114
+ }
5115
+ });
5116
+
5075
5117
  // src/lib/memory/queryTemporal.ts
5076
5118
  function startOfDay(ts) {
5077
5119
  const d = new Date(ts);
@@ -5471,7 +5513,7 @@ async function recall(query, ctx, options = {}) {
5471
5513
  const fuseStart = nowMs();
5472
5514
  if (types.length === 1 || factResults.length === 0 || chunkResults.length === 0) {
5473
5515
  const memories2 = [
5474
- ...factResults.map(toFactMemory),
5516
+ ...factResults.map((r) => toFactMemory(r, options.now)),
5475
5517
  ...chunkResults.map(toChunkMemory)
5476
5518
  ];
5477
5519
  memories2.sort((a, b) => b.score - a.score);
@@ -5492,7 +5534,7 @@ async function recall(query, ctx, options = {}) {
5492
5534
  const fused = rrfFuse([factRanking, chunkRanking], options.rrfK);
5493
5535
  const byId = /* @__PURE__ */ new Map();
5494
5536
  for (const r of factResults) {
5495
- const m = toFactMemory(r);
5537
+ const m = toFactMemory(r, options.now);
5496
5538
  m.score = fused.get(`fact:${r.uniqueId}`) ?? 0;
5497
5539
  if (!m.scoreBreakdown) m.scoreBreakdown = {};
5498
5540
  m.scoreBreakdown.fused = r.similarity;
@@ -5541,7 +5583,10 @@ async function recall(query, ctx, options = {}) {
5541
5583
  ...vaultSize !== void 0 && { vaultSize }
5542
5584
  };
5543
5585
  }
5544
- function toFactMemory(r) {
5586
+ function toFactMemory(r, now) {
5587
+ const createdAt = r.createdAt ?? /* @__PURE__ */ new Date(0);
5588
+ const proofCount = r.proofCount ?? void 0;
5589
+ const lastObservedAt = r.lastObservedAt ?? null;
5545
5590
  return {
5546
5591
  id: r.uniqueId,
5547
5592
  kind: "fact",
@@ -5557,6 +5602,18 @@ function toFactMemory(r) {
5557
5602
  // (and UI reading them) carry the fact's type. Undefined when untyped.
5558
5603
  ...r.factType !== void 0 && { factType: r.factType },
5559
5604
  ...r.sourceChunkIds !== void 0 && r.sourceChunkIds !== null && { sourceChunkIds: r.sourceChunkIds },
5605
+ ...proofCount !== void 0 && proofCount !== null && { proofCount },
5606
+ ...lastObservedAt !== null && { lastObservedAt },
5607
+ // C2 — algorithmic trend from evidence timestamps (no LLM). Honor
5608
+ // RecallOptions.now so back-dated eval harnesses get consistent labels.
5609
+ observationTrend: classifyObservationTrend(
5610
+ {
5611
+ createdAt,
5612
+ lastObservedAt,
5613
+ proofCount
5614
+ },
5615
+ now ?? Date.now()
5616
+ ),
5560
5617
  // r.similarity from searchVaultMemoriesWithSize is the fused score
5561
5618
  // (cosine + BM25 + RRF + recency + proof) when useFusion=true (the
5562
5619
  // default) and pure cosine when useFusion=false. The breakdown
@@ -5565,7 +5622,7 @@ function toFactMemory(r) {
5565
5622
  content: r.content,
5566
5623
  score: r.similarity,
5567
5624
  scoreBreakdown: { fused: r.similarity },
5568
- createdAt: r.createdAt ?? /* @__PURE__ */ new Date(0),
5625
+ createdAt,
5569
5626
  updatedAt: r.updatedAt ?? /* @__PURE__ */ new Date(0)
5570
5627
  };
5571
5628
  }
@@ -5648,6 +5705,7 @@ var init_recall = __esm({
5648
5705
  init_embeddings();
5649
5706
  init_searchTool();
5650
5707
  init_graphTraversal();
5708
+ init_observationTrend();
5651
5709
  init_queryEntities();
5652
5710
  init_queryTemporal();
5653
5711
  init_rrf();
@@ -6243,6 +6301,7 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
6243
6301
  createdAt: m.createdAt,
6244
6302
  updatedAt: m.updatedAt,
6245
6303
  proofCount: m.proofCount,
6304
+ lastObservedAt: m.lastObservedAt,
6246
6305
  eventTimeStart: m.eventTimeStart,
6247
6306
  sourceChunkIds: m.sourceChunkIds,
6248
6307
  eventTimeEnd: m.eventTimeEnd,
@@ -6259,13 +6318,27 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
6259
6318
  );
6260
6319
  }
6261
6320
  }
6262
- const timestampById = new Map(
6263
- memories.map((m) => [m.uniqueId, { createdAt: m.createdAt, updatedAt: m.updatedAt }])
6321
+ const metaById = new Map(
6322
+ memories.map((m) => [
6323
+ m.uniqueId,
6324
+ {
6325
+ createdAt: m.createdAt,
6326
+ updatedAt: m.updatedAt,
6327
+ proofCount: m.proofCount,
6328
+ lastObservedAt: m.lastObservedAt
6329
+ }
6330
+ ])
6264
6331
  );
6265
6332
  const stampTimestamps = (out) => {
6266
6333
  const results2 = out.results.map((r) => {
6267
- const ts = timestampById.get(r.uniqueId);
6268
- return ts ? { ...r, createdAt: ts.createdAt, updatedAt: ts.updatedAt } : r;
6334
+ const meta = metaById.get(r.uniqueId);
6335
+ return meta ? {
6336
+ ...r,
6337
+ createdAt: meta.createdAt,
6338
+ updatedAt: meta.updatedAt,
6339
+ proofCount: meta.proofCount,
6340
+ lastObservedAt: meta.lastObservedAt
6341
+ } : r;
6269
6342
  });
6270
6343
  return {
6271
6344
  results: results2,
@@ -6707,6 +6780,8 @@ __export(index_exports, {
6707
6780
  StreamExpiredError: () => StreamExpiredError,
6708
6781
  TOPICS_EXTRACTION_VERSION: () => TOPICS_EXTRACTION_VERSION,
6709
6782
  TOPIC_EXTRACTION_BATCH_SIZE: () => TOPIC_EXTRACTION_BATCH_SIZE,
6783
+ TREND_RECENT_WINDOW_DAYS: () => TREND_RECENT_WINDOW_DAYS,
6784
+ TREND_STALE_WINDOW_DAYS: () => TREND_STALE_WINDOW_DAYS,
6710
6785
  VAULT_SIZE_HOP_CAP: () => VAULT_SIZE_HOP_CAP,
6711
6786
  WalletPoller: () => WalletPoller,
6712
6787
  addConversationMemoriesOp: () => addConversationMemoriesOp,
@@ -6722,6 +6797,7 @@ __export(index_exports, {
6722
6797
  classifyCryptoPriceBatch: () => classifyCryptoPriceBatch,
6723
6798
  classifyDecay: () => classifyDecay,
6724
6799
  classifyInjectionCandidates: () => classifyInjectionCandidates,
6800
+ classifyObservationTrend: () => classifyObservationTrend,
6725
6801
  classifyStockPrice: () => classifyStockPrice,
6726
6802
  classifyStockPriceBatch: () => classifyStockPriceBatch,
6727
6803
  classifyWeather: () => classifyWeather,
@@ -6821,6 +6897,7 @@ __export(index_exports, {
6821
6897
  stampTopicsExtractedAtOp: () => stampTopicsExtractedAtOp,
6822
6898
  streamCancelPath: () => streamCancelPath,
6823
6899
  streamReplayPath: () => streamReplayPath,
6900
+ summarizeObservationTrends: () => summarizeObservationTrends,
6824
6901
  supersedeVaultMemoryOp: () => supersedeVaultMemoryOp,
6825
6902
  synthesizeProfile: () => synthesizeProfile,
6826
6903
  traverseGraphLane: () => traverseGraphLane,
@@ -14703,12 +14780,12 @@ function createChunkVectorCache(maxSize = DEFAULT_CHUNK_CACHE_SIZE) {
14703
14780
 
14704
14781
  // src/lib/memory/decay.ts
14705
14782
  init_logger();
14706
- var DAY_MS2 = 24 * 60 * 60 * 1e3;
14707
- var SHORT_TTL_MS = 30 * DAY_MS2;
14708
- var MEDIUM_TTL_MS = 180 * DAY_MS2;
14783
+ var DAY_MS3 = 24 * 60 * 60 * 1e3;
14784
+ var SHORT_TTL_MS = 30 * DAY_MS3;
14785
+ var MEDIUM_TTL_MS = 180 * DAY_MS3;
14709
14786
  var NEVER_TTL_MS = Number.POSITIVE_INFINITY;
14710
- var HARD_DELETE_WINDOW_MS = 30 * DAY_MS2;
14711
- var PAST_EVENT_GRACE_MS = 7 * DAY_MS2;
14787
+ var HARD_DELETE_WINDOW_MS = 30 * DAY_MS3;
14788
+ var PAST_EVENT_GRACE_MS = 7 * DAY_MS3;
14712
14789
  var DEFAULT_DECAY_POLICY = {
14713
14790
  ttlByType: {
14714
14791
  identity: NEVER_TTL_MS,
@@ -14968,6 +15045,7 @@ function createDecaySweeper(options) {
14968
15045
 
14969
15046
  // src/lib/memory/index.ts
14970
15047
  init_graphTraversal();
15048
+ init_observationTrend();
14971
15049
  init_recall();
14972
15050
 
14973
15051
  // src/lib/memory/recallTool.ts
@@ -15334,6 +15412,7 @@ init_logger();
15334
15412
  init_constants();
15335
15413
  init_embeddings();
15336
15414
  init_vector();
15415
+ init_observationTrend();
15337
15416
  var DEFAULT_SYNTHESIS_MODEL = "inclusionai/ling-2.6-flash";
15338
15417
  var DEFAULT_FACET_RECALL_LIMIT = 20;
15339
15418
  var DEFAULT_FACET_MAX_TOKENS = 512;
@@ -15419,6 +15498,13 @@ async function synthesizeProfile(ctx, options = {}) {
15419
15498
  includeSuperseded: true
15420
15499
  });
15421
15500
  const watermark = computeVaultWatermark(memories);
15501
+ const observationTrends = summarizeObservationTrends(
15502
+ memories.filter((m) => !m.isDeleted && m.supersededBy === null).map((m) => ({
15503
+ createdAt: m.createdAt,
15504
+ lastObservedAt: m.lastObservedAt,
15505
+ proofCount: m.proofCount
15506
+ }))
15507
+ );
15422
15508
  const presentIds = new Set(memories.map((m) => m.uniqueId));
15423
15509
  const hasStaleSections = previous?.sections.some((s) => s.stale);
15424
15510
  const citesMissingFact = previous?.sections.some(
@@ -15426,10 +15512,14 @@ async function synthesizeProfile(ctx, options = {}) {
15426
15512
  );
15427
15513
  if (previous && previous.vaultWatermark === watermark && !hasStaleSections && !citesMissingFact) {
15428
15514
  const sameOrder = previous.sections.length === facets.length && facets.every((f, i) => previous.sections[i]?.key === f.key);
15429
- if (sameOrder) return previous;
15515
+ if (sameOrder) {
15516
+ if (trendsEqual(previous.observationTrends, observationTrends)) return previous;
15517
+ return { ...previous, observationTrends };
15518
+ }
15430
15519
  return {
15431
15520
  ...previous,
15432
- sections: facets.map((f) => previous.sections.find((s) => s.key === f.key))
15521
+ sections: facets.map((f) => previous.sections.find((s) => s.key === f.key)),
15522
+ observationTrends
15433
15523
  };
15434
15524
  }
15435
15525
  const staleKeys = await computeStaleFacetKeys(ctx, memories, facets, previous, watermark);
@@ -15462,6 +15552,7 @@ async function synthesizeProfile(ctx, options = {}) {
15462
15552
  sections,
15463
15553
  vaultWatermark: watermark,
15464
15554
  config,
15555
+ observationTrends,
15465
15556
  generatedAt: Date.now()
15466
15557
  };
15467
15558
  }
@@ -15472,6 +15563,10 @@ function configMatches(a, b) {
15472
15563
  function facetsSignature(facets) {
15473
15564
  return facets.map((f) => JSON.stringify([f.key, f.label, f.query, f.guidance])).sort().join("\n");
15474
15565
  }
15566
+ function trendsEqual(a, b) {
15567
+ if (!a) return false;
15568
+ return a.new === b.new && a.strengthening === b.strengthening && a.stable === b.stable && a.weakening === b.weakening && a.stale === b.stale;
15569
+ }
15475
15570
  function changeTime(m) {
15476
15571
  return Math.max(m.updatedAt.getTime(), m.supersededAt ?? 0, m.lastObservedAt ?? 0);
15477
15572
  }
@@ -21226,6 +21321,8 @@ function createNotionTools(getAccessToken, requestNotionAccess) {
21226
21321
  StreamExpiredError,
21227
21322
  TOPICS_EXTRACTION_VERSION,
21228
21323
  TOPIC_EXTRACTION_BATCH_SIZE,
21324
+ TREND_RECENT_WINDOW_DAYS,
21325
+ TREND_STALE_WINDOW_DAYS,
21229
21326
  VAULT_SIZE_HOP_CAP,
21230
21327
  WalletPoller,
21231
21328
  addConversationMemoriesOp,
@@ -21241,6 +21338,7 @@ function createNotionTools(getAccessToken, requestNotionAccess) {
21241
21338
  classifyCryptoPriceBatch,
21242
21339
  classifyDecay,
21243
21340
  classifyInjectionCandidates,
21341
+ classifyObservationTrend,
21244
21342
  classifyStockPrice,
21245
21343
  classifyStockPriceBatch,
21246
21344
  classifyWeather,
@@ -21340,6 +21438,7 @@ function createNotionTools(getAccessToken, requestNotionAccess) {
21340
21438
  stampTopicsExtractedAtOp,
21341
21439
  streamCancelPath,
21342
21440
  streamReplayPath,
21441
+ summarizeObservationTrends,
21343
21442
  supersedeVaultMemoryOp,
21344
21443
  synthesizeProfile,
21345
21444
  traverseGraphLane,
@@ -4885,6 +4885,10 @@ interface VaultSearchResult {
4885
4885
  * real timestamps. Omitted when an item lacks the field upstream. */
4886
4886
  createdAt?: Date;
4887
4887
  updatedAt?: Date;
4888
+ /** Times this fact has been re-observed — for C2 trend labels. */
4889
+ proofCount?: number | null;
4890
+ /** C3 re-observation watermark (Unix ms) — for C2 trend labels. */
4891
+ lastObservedAt?: number | null;
4888
4892
  /** W6 temporal-lane anchors carried through to downstream `RankedMemory`
4889
4893
  * so the recall executor can surface dates to the answer model without
4890
4894
  * a second per-fact DB lookup + decrypt. Unix ms; null when the fact
@@ -4926,6 +4930,55 @@ declare function searchVaultMemories(query: string, vaultCtx: VaultMemoryOperati
4926
4930
  */
4927
4931
  declare function createMemoryVaultSearchTool(vaultCtx: VaultMemoryOperationsContext, embeddingOptions: EmbeddingOptions, cache: VaultEmbeddingCache, searchOptions?: MemoryVaultSearchOptions): ToolConfig;
4928
4932
 
4933
+ /**
4934
+ * C2 — Observation trend labels.
4935
+ *
4936
+ * Algorithmic (no LLM) classification of how a vault fact's evidence has
4937
+ * been evolving, derived from the C3 re-observation watermark
4938
+ * (`lastObservedAt`), `proofCount`, and `createdAt` over 30/90-day windows.
4939
+ *
4940
+ * We do not store a full observation-timestamp series — only first-seen,
4941
+ * last-seen, and count — so density is approximated from that triple.
4942
+ * Good enough for profile signals ("interests trending up") and vault
4943
+ * hygiene badges; not a substitute for an observations tier (C5).
4944
+ */
4945
+ /** Recent window — observations inside this count as "active". */
4946
+ declare const TREND_RECENT_WINDOW_DAYS = 30;
4947
+ /** Beyond this since last observation → stale. */
4948
+ declare const TREND_STALE_WINDOW_DAYS = 90;
4949
+ /**
4950
+ * How a fact's evidence has been evolving.
4951
+ *
4952
+ * - `new` — first seen inside the recent window, few proofs yet.
4953
+ * - `strengthening` — established fact re-observed recently (rising density).
4954
+ * - `stable` — known for a while, still observed inside the stale window.
4955
+ * - `weakening` — quiet for ≥30 and <90 days after having been observed.
4956
+ * - `stale` — no observation in ≥90 days.
4957
+ */
4958
+ type ObservationTrend = "new" | "strengthening" | "stable" | "weakening" | "stale";
4959
+ interface ObservationTrendInput {
4960
+ createdAt: Date | number;
4961
+ /**
4962
+ * C3 re-observation watermark (Unix ms). When null/undefined, the fact
4963
+ * has never been merged-into since the column landed — treat `createdAt`
4964
+ * as last-seen.
4965
+ */
4966
+ lastObservedAt?: number | null;
4967
+ /** Times this fact has been retained/merged. Defaults to 1. */
4968
+ proofCount?: number | null;
4969
+ }
4970
+ /**
4971
+ * Classify a vault fact's observation trend from its evidence timestamps.
4972
+ *
4973
+ * Pure + deterministic. Pass `now` for back-dated eval harnesses.
4974
+ */
4975
+ declare function classifyObservationTrend(input: ObservationTrendInput, now?: number): ObservationTrend;
4976
+ /**
4977
+ * Summarize trend counts over a set of facts — handy for profile synthesis
4978
+ * ("N interests strengthening") without another LLM pass.
4979
+ */
4980
+ declare function summarizeObservationTrends(inputs: readonly ObservationTrendInput[], now?: number): Record<ObservationTrend, number>;
4981
+
4929
4982
  /**
4930
4983
  * Unified memory layer types — the Recall / Retain API.
4931
4984
  *
@@ -4975,6 +5028,16 @@ interface RankedMemory {
4975
5028
  proofCount?: number;
4976
5029
  source?: string;
4977
5030
  folderId?: string | null;
5031
+ /**
5032
+ * C3 re-observation watermark (Unix ms). Null/undefined when the fact
5033
+ * has never been merge-reinforced since the column landed.
5034
+ */
5035
+ lastObservedAt?: number | null;
5036
+ /**
5037
+ * C2 observation-trend label derived from createdAt / lastObservedAt /
5038
+ * proofCount over 30/90-day windows. Fact-only; omitted for chunks.
5039
+ */
5040
+ observationTrend?: ObservationTrend;
4978
5041
  /**
4979
5042
  * Anchored event-time for the fact (the date the underlying event
4980
5043
  * occurred, not the write time). When present, the recall executor
@@ -7228,6 +7291,12 @@ interface ProfileDoc {
7228
7291
  vaultWatermark: number;
7229
7292
  /** The config that produced this doc — see {@link ProfileConfigFingerprint}. */
7230
7293
  config: ProfileConfigFingerprint;
7294
+ /**
7295
+ * C2 — counts of observation-trend labels over live vault facts at
7296
+ * synthesis time. Lets People Nearby surface "interests trending up"
7297
+ * without another LLM pass. Recomputed every synthesis (not delta-cached).
7298
+ */
7299
+ observationTrends: Record<ObservationTrend, number>;
7231
7300
  /** Unix ms this doc was produced. */
7232
7301
  generatedAt: number;
7233
7302
  }
@@ -8724,4 +8793,4 @@ declare function refreshNotionAccessToken(params: NotionRefreshTokenParams): Pro
8724
8793
  */
8725
8794
  declare function createNotionTools(getAccessToken: () => string | null, requestNotionAccess: () => Promise<string>): ToolConfig[];
8726
8795
 
8727
- export { type AutoExtractMessage, type AutoExtractor, type Budget, type CachedChunkVectors, type CachedServerTools, Conversation as ChatConversation, Message as ChatMessage, type ChatRole, type ChunkVectorCache, type ChunkingOptions, type ConsolidationFallbackReason, type ConversationMemoryInput, ConversationMemory as ConversationMemoryModel, type ConversationMemoryOperationsContext, type CreateAutoExtractorOptions, type CreateConversationOptions, type CreateDecaySweeperOptions, type CreateMessageOptions, type CreateVaultFolderOptions, type CreateVaultMemoryOptions, type CryptoPriceClassification, type CryptoPricePreProcessorOptions, DEFAULT_CACHE_EXPIRATION_MS, DEFAULT_CHUNK_CACHE_SIZE, DEFAULT_CHUNK_OVERLAP, DEFAULT_CHUNK_SIZE, DEFAULT_DECAY_POLICY, DEFAULT_MAX_CLASSIFIER_CALLS_PER_SWEEP, DEFAULT_MIN_CHUNK_SIZE, DEFAULT_PROFILE_FACETS, DEFAULT_VAULT_CACHE_SIZE, DatabaseManager, type DatabaseManagerLogger, type DatabaseManagerOptions, type DecayCandidateRaw, type DecayClassifier, type DecayInput, type DecayPolicy, type DecaySweepResult, type DecaySweeper, type DecayVerdict, ENTITY_FANOUT, type EmbeddedWalletSignerFn, type ExtractFactsOptions, type ExtractOutcome, type ExtractedCandidate, type ExtractedEntity, type ExtractionCursorStore, type FactType, type FileMetadata, type FlushResult, type GetConversationsPageOptions, type GetMessagesPageOptions, type GraphTraversalOptions, HARD_DELETE_WINDOW_MS, INFERENCE_ID_HEADER, type InjectionClassifierOptions, type InjectionReason, type LazyStoredConversation, type LlmDecayClassifierOptions, type LlmNeighborRefinerOptions, type Logger, LoggerProvider, type LoggerProviderProps, MAX_HOPS, MEDIUM_TTL_MS, type MemoriesNeedingTopicExtraction, type EmbeddingOptions as MemoryEngineEmbeddingOptions, type MemoryEngineResult, type MemoryEngineSearchOptions, type MemoryExtractedEvent, type MemoryKind, type MemoryQuarantinedEvent, type MemoryVaultSearchOptions, type MemoryVaultToolOptions, type MessageRedactionResult, type MessageSkeleton, NEVER_TTL_MS, NODE_BUDGET, NOTION_OAUTH_CONFIG, type NeighborRefiner, type NotionAuthUrlParams, type NotionClientRegistration, type NotionExchangeCodeParams, type NotionOAuthEndpoints, type NotionPKCEChallenge, type NotionRefreshTokenParams, type NotionTokenResponse, type NowSource, PAST_EVENT_GRACE_MS, PII_PATTERNS, PROFILE_DOC_VERSION, type PiiCategory, type PiiMatch, type PiiPattern, PiiRedactor, type PiiRedactorOptions, type PlatformStorage, type PortalLlmAuth, type ProfileConfigFingerprint, type ProfileDoc, type ProfileFacet, type ProfileFacetKey, type ProfileSection, type PromptPreProcessor, type PromptPreProcessorContext, type QuantizedEmbedding, type QuarantinedMemoryInfo, QueueManager, type QueueStatus, RECALL_MAX_LIMIT, RECALL_TOOL_NAME, type RankedMemory, type RecallContext, type RecallDegradation, type RecallDiagnostics, type RecallOptions, type RecallResult, type RecallToolCallbacks, type RecallToolOptions, type RecencyOptions, type RedactionResult, type ReflectOptions, type ReflectResult, RerankerUnavailableError, type ResumeStreamOptions, type ResumeStreamResult, type ResumeStreamWithStorageResult, type RetainAction, type RetainContext, type RetainOptions, type RetainResult, type RetainSource, SDK_SCHEMA_VERSION, SHORT_TTL_MS, STREAM_RESUMABLE_HEADER, type ScoreBreakdown, type ScreenResult, type ScreenedCandidate, type SearchSource, type SendMessageWithStorageArgs, type SendMessageWithStorageDetachedResult, type SendMessageWithStorageResult, type ServerToolsOptions, type ServerToolsResponse, type SignMessageFn, type StockPriceClassification, type StockPricePreProcessorOptions, type ChatCompletionUsage as StoredChatCompletionUsage, type StoredConversation, type StoredConversationMemory, type StoredMessage, type StoredMessageWithSimilarity, type StoredVaultFolder, VaultFolder as StoredVaultFolderModel, type StoredVaultMemory, VaultMemory as StoredVaultMemoryModel, StreamExpiredError, type StreamMetaEvent, type StreamResumeHandle, type SynthesizeProfileOptions, TOPICS_EXTRACTION_VERSION, TOPIC_EXTRACTION_BATCH_SIZE, type TextChunk, type TopicExtractOptions, type TopicExtractionInput, type TopicExtractionRunResult, type TurnCompleteEvent, type TurnSkippedEvent, type UpdateVaultFolderOptions, type UpdateVaultMemoryOptions, type UseChatStorageOptions, type UseChatStorageResult, type UseCreditsOptions, type UseCreditsResult, type UseModelsOptions, type UseModelsResult, VAULT_SIZE_HOP_CAP, type VaultEmbeddingCache, type VaultFolderOperationsContext, type VaultMemoryOperationsContext, type VaultSaveOperation, type VaultSearchResult, WalletPoller, type WeatherClassification, type WeatherPreProcessorOptions, type WebSearchClassification, type WebSearchPreProcessorOptions, addConversationMemoriesOp, archiveVaultMemoryOp, buildNotionAuthUrl, capHopsForDensity, chatStorageMigrations, chatStorageSchema, chunkAndEmbedAllMessages, chunkAndEmbedMessage, chunkText, classifyCryptoPrice, classifyCryptoPriceBatch, classifyDecay, classifyInjectionCandidates, classifyStockPrice, classifyStockPriceBatch, classifyWeather, classifyWeatherBatch, classifyWebSearch, classifyWebSearchBatch, clearAllEncryptionKeys, clearAllEncryptionState, clearConversationMemoriesOp, clearEncryptionKey, clearLazyTitleCache, clearServerToolsCache, consoleLogger, conversationMemoryToStored, cosineInt8, createAutoExtractor, createChunkVectorCache, createCryptoPricePreProcessor, createDecaySweeper, createLlmDecayClassifier, createLlmNeighborRefiner, createMemoryEngineTool, createMemoryVaultSearchTool, createMemoryVaultTool, createNotionTools, createPlatformCursorStore, createRecallTool, createStockPricePreProcessor, createStreamingDeAnonymizer, createVaultEmbeddingCache, createVaultFolderOp, createVaultMemoriesBatchOp, createVaultMemoryOp, createWeatherPreProcessor, createWebSearchPreProcessor, decryptConversationTitle, deleteAllVaultMemoriesForUserOp, deleteVaultFolderOp, deleteVaultMemoryOp, dequantizeEmbedding, discoverNotionOAuthEndpoints, eagerEmbedContent, embedAllMessages, embedMessage, ensureDefaultFoldersOp, exchangeNotionCode, extractAndLinkEntitiesForMemoriesOp, extractAndRetain, extractEntitiesForMemories, extractFacts, generateConversationId, generateEmbedding, generateEmbeddings, generateNotionPKCE, getAllVaultFoldersOp, getAllVaultMemoriesOp, getAllVaultMemoryContentsOp, getCachedServerTools, getConversationMemoriesOp, getConversationsByProjectLazyOp, getConversationsLazyOp, getConversationsPageOp, getDecayCandidatesRawOp, getLogger, getMemoriesNeedingTopicExtractionOp, getServerTools, getUnfiledVaultMemoriesOp, getVaultFolderMemoryCountOp, getVaultMemoryOp, hardDeleteDecayedOp, hasEncryptionKey, injectionSignatureCatalog, isPiiRedactor, isRerankerAvailable, moveMemoriesToFolderOp, noopLogger, onKeyAvailable, preEmbedVaultMemories, quantizeEmbedding, queueManager, recall, reflect, refreshNotionAccessToken, registerNotionClient, requestEncryptionKey, resolvePiiRedactor, restoreVaultMemoryOp, resumeStream, retain, screenCandidatesForInjection, sdkMigrations, sdkModelClasses, sdkSchema, searchVaultMemories, setLogger, shouldChunkMessage, stampTopicsExtractedAtOp, streamCancelPath, streamReplayPath, supersedeVaultMemoryOp, synthesizeProfile, traverseGraphLane, ttlForType, updateVaultFolderContextOp, updateVaultFolderOp, updateVaultMemoryEmbeddingOp, updateVaultMemoryOp, upsertMessageOp, useChat, useChatStorage, useCredits, useEncryption, useModels, xhrTransport };
8796
+ export { type AutoExtractMessage, type AutoExtractor, type Budget, type CachedChunkVectors, type CachedServerTools, Conversation as ChatConversation, Message as ChatMessage, type ChatRole, type ChunkVectorCache, type ChunkingOptions, type ConsolidationFallbackReason, type ConversationMemoryInput, ConversationMemory as ConversationMemoryModel, type ConversationMemoryOperationsContext, type CreateAutoExtractorOptions, type CreateConversationOptions, type CreateDecaySweeperOptions, type CreateMessageOptions, type CreateVaultFolderOptions, type CreateVaultMemoryOptions, type CryptoPriceClassification, type CryptoPricePreProcessorOptions, DEFAULT_CACHE_EXPIRATION_MS, DEFAULT_CHUNK_CACHE_SIZE, DEFAULT_CHUNK_OVERLAP, DEFAULT_CHUNK_SIZE, DEFAULT_DECAY_POLICY, DEFAULT_MAX_CLASSIFIER_CALLS_PER_SWEEP, DEFAULT_MIN_CHUNK_SIZE, DEFAULT_PROFILE_FACETS, DEFAULT_VAULT_CACHE_SIZE, DatabaseManager, type DatabaseManagerLogger, type DatabaseManagerOptions, type DecayCandidateRaw, type DecayClassifier, type DecayInput, type DecayPolicy, type DecaySweepResult, type DecaySweeper, type DecayVerdict, ENTITY_FANOUT, type EmbeddedWalletSignerFn, type ExtractFactsOptions, type ExtractOutcome, type ExtractedCandidate, type ExtractedEntity, type ExtractionCursorStore, type FactType, type FileMetadata, type FlushResult, type GetConversationsPageOptions, type GetMessagesPageOptions, type GraphTraversalOptions, HARD_DELETE_WINDOW_MS, INFERENCE_ID_HEADER, type InjectionClassifierOptions, type InjectionReason, type LazyStoredConversation, type LlmDecayClassifierOptions, type LlmNeighborRefinerOptions, type Logger, LoggerProvider, type LoggerProviderProps, MAX_HOPS, MEDIUM_TTL_MS, type MemoriesNeedingTopicExtraction, type EmbeddingOptions as MemoryEngineEmbeddingOptions, type MemoryEngineResult, type MemoryEngineSearchOptions, type MemoryExtractedEvent, type MemoryKind, type MemoryQuarantinedEvent, type MemoryVaultSearchOptions, type MemoryVaultToolOptions, type MessageRedactionResult, type MessageSkeleton, NEVER_TTL_MS, NODE_BUDGET, NOTION_OAUTH_CONFIG, type NeighborRefiner, type NotionAuthUrlParams, type NotionClientRegistration, type NotionExchangeCodeParams, type NotionOAuthEndpoints, type NotionPKCEChallenge, type NotionRefreshTokenParams, type NotionTokenResponse, type NowSource, type ObservationTrend, type ObservationTrendInput, PAST_EVENT_GRACE_MS, PII_PATTERNS, PROFILE_DOC_VERSION, type PiiCategory, type PiiMatch, type PiiPattern, PiiRedactor, type PiiRedactorOptions, type PlatformStorage, type PortalLlmAuth, type ProfileConfigFingerprint, type ProfileDoc, type ProfileFacet, type ProfileFacetKey, type ProfileSection, type PromptPreProcessor, type PromptPreProcessorContext, type QuantizedEmbedding, type QuarantinedMemoryInfo, QueueManager, type QueueStatus, RECALL_MAX_LIMIT, RECALL_TOOL_NAME, type RankedMemory, type RecallContext, type RecallDegradation, type RecallDiagnostics, type RecallOptions, type RecallResult, type RecallToolCallbacks, type RecallToolOptions, type RecencyOptions, type RedactionResult, type ReflectOptions, type ReflectResult, RerankerUnavailableError, type ResumeStreamOptions, type ResumeStreamResult, type ResumeStreamWithStorageResult, type RetainAction, type RetainContext, type RetainOptions, type RetainResult, type RetainSource, SDK_SCHEMA_VERSION, SHORT_TTL_MS, STREAM_RESUMABLE_HEADER, type ScoreBreakdown, type ScreenResult, type ScreenedCandidate, type SearchSource, type SendMessageWithStorageArgs, type SendMessageWithStorageDetachedResult, type SendMessageWithStorageResult, type ServerToolsOptions, type ServerToolsResponse, type SignMessageFn, type StockPriceClassification, type StockPricePreProcessorOptions, type ChatCompletionUsage as StoredChatCompletionUsage, type StoredConversation, type StoredConversationMemory, type StoredMessage, type StoredMessageWithSimilarity, type StoredVaultFolder, VaultFolder as StoredVaultFolderModel, type StoredVaultMemory, VaultMemory as StoredVaultMemoryModel, StreamExpiredError, type StreamMetaEvent, type StreamResumeHandle, type SynthesizeProfileOptions, TOPICS_EXTRACTION_VERSION, TOPIC_EXTRACTION_BATCH_SIZE, TREND_RECENT_WINDOW_DAYS, TREND_STALE_WINDOW_DAYS, type TextChunk, type TopicExtractOptions, type TopicExtractionInput, type TopicExtractionRunResult, type TurnCompleteEvent, type TurnSkippedEvent, type UpdateVaultFolderOptions, type UpdateVaultMemoryOptions, type UseChatStorageOptions, type UseChatStorageResult, type UseCreditsOptions, type UseCreditsResult, type UseModelsOptions, type UseModelsResult, VAULT_SIZE_HOP_CAP, type VaultEmbeddingCache, type VaultFolderOperationsContext, type VaultMemoryOperationsContext, type VaultSaveOperation, type VaultSearchResult, WalletPoller, type WeatherClassification, type WeatherPreProcessorOptions, type WebSearchClassification, type WebSearchPreProcessorOptions, addConversationMemoriesOp, archiveVaultMemoryOp, buildNotionAuthUrl, capHopsForDensity, chatStorageMigrations, chatStorageSchema, chunkAndEmbedAllMessages, chunkAndEmbedMessage, chunkText, classifyCryptoPrice, classifyCryptoPriceBatch, classifyDecay, classifyInjectionCandidates, classifyObservationTrend, classifyStockPrice, classifyStockPriceBatch, classifyWeather, classifyWeatherBatch, classifyWebSearch, classifyWebSearchBatch, clearAllEncryptionKeys, clearAllEncryptionState, clearConversationMemoriesOp, clearEncryptionKey, clearLazyTitleCache, clearServerToolsCache, consoleLogger, conversationMemoryToStored, cosineInt8, createAutoExtractor, createChunkVectorCache, createCryptoPricePreProcessor, createDecaySweeper, createLlmDecayClassifier, createLlmNeighborRefiner, createMemoryEngineTool, createMemoryVaultSearchTool, createMemoryVaultTool, createNotionTools, createPlatformCursorStore, createRecallTool, createStockPricePreProcessor, createStreamingDeAnonymizer, createVaultEmbeddingCache, createVaultFolderOp, createVaultMemoriesBatchOp, createVaultMemoryOp, createWeatherPreProcessor, createWebSearchPreProcessor, decryptConversationTitle, deleteAllVaultMemoriesForUserOp, deleteVaultFolderOp, deleteVaultMemoryOp, dequantizeEmbedding, discoverNotionOAuthEndpoints, eagerEmbedContent, embedAllMessages, embedMessage, ensureDefaultFoldersOp, exchangeNotionCode, extractAndLinkEntitiesForMemoriesOp, extractAndRetain, extractEntitiesForMemories, extractFacts, generateConversationId, generateEmbedding, generateEmbeddings, generateNotionPKCE, getAllVaultFoldersOp, getAllVaultMemoriesOp, getAllVaultMemoryContentsOp, getCachedServerTools, getConversationMemoriesOp, getConversationsByProjectLazyOp, getConversationsLazyOp, getConversationsPageOp, getDecayCandidatesRawOp, getLogger, getMemoriesNeedingTopicExtractionOp, getServerTools, getUnfiledVaultMemoriesOp, getVaultFolderMemoryCountOp, getVaultMemoryOp, hardDeleteDecayedOp, hasEncryptionKey, injectionSignatureCatalog, isPiiRedactor, isRerankerAvailable, moveMemoriesToFolderOp, noopLogger, onKeyAvailable, preEmbedVaultMemories, quantizeEmbedding, queueManager, recall, reflect, refreshNotionAccessToken, registerNotionClient, requestEncryptionKey, resolvePiiRedactor, restoreVaultMemoryOp, resumeStream, retain, screenCandidatesForInjection, sdkMigrations, sdkModelClasses, sdkSchema, searchVaultMemories, setLogger, shouldChunkMessage, stampTopicsExtractedAtOp, streamCancelPath, streamReplayPath, summarizeObservationTrends, supersedeVaultMemoryOp, synthesizeProfile, traverseGraphLane, ttlForType, updateVaultFolderContextOp, updateVaultFolderOp, updateVaultMemoryEmbeddingOp, updateVaultMemoryOp, upsertMessageOp, useChat, useChatStorage, useCredits, useEncryption, useModels, xhrTransport };