@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.
@@ -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 };
@@ -12,6 +12,8 @@ import {
12
12
  NODE_BUDGET,
13
13
  RerankerUnavailableError,
14
14
  TOPICS_EXTRACTION_VERSION,
15
+ TREND_RECENT_WINDOW_DAYS,
16
+ TREND_STALE_WINDOW_DAYS,
15
17
  VAULT_SIZE_HOP_CAP,
16
18
  archiveVaultMemoryOp,
17
19
  assertVaultScopeForSweep,
@@ -19,6 +21,7 @@ import {
19
21
  chunkAndEmbedAllMessages,
20
22
  chunkAndEmbedMessage,
21
23
  chunkText,
24
+ classifyObservationTrend,
22
25
  clearAllEncryptionKeys,
23
26
  clearAllEncryptionState,
24
27
  clearEncryptionKey,
@@ -87,6 +90,7 @@ import {
87
90
  shouldChunkMessage,
88
91
  stampTopicsExtractedAtOp,
89
92
  stripToolCalls,
93
+ summarizeObservationTrends,
90
94
  supersedeVaultMemoryOp,
91
95
  traverseGraphLane,
92
96
  updateConversationPinnedOp,
@@ -99,7 +103,7 @@ import {
99
103
  upsertMessageOp,
100
104
  useEncryption,
101
105
  vaultMemoryToStored
102
- } from "./chunk-EIHIZ5L4.mjs";
106
+ } from "./chunk-C7PGRFBG.mjs";
103
107
  import {
104
108
  PII_PATTERNS,
105
109
  PiiRedactor,
@@ -8604,6 +8608,13 @@ async function synthesizeProfile(ctx, options = {}) {
8604
8608
  includeSuperseded: true
8605
8609
  });
8606
8610
  const watermark = computeVaultWatermark(memories);
8611
+ const observationTrends = summarizeObservationTrends(
8612
+ memories.filter((m) => !m.isDeleted && m.supersededBy === null).map((m) => ({
8613
+ createdAt: m.createdAt,
8614
+ lastObservedAt: m.lastObservedAt,
8615
+ proofCount: m.proofCount
8616
+ }))
8617
+ );
8607
8618
  const presentIds = new Set(memories.map((m) => m.uniqueId));
8608
8619
  const hasStaleSections = previous?.sections.some((s) => s.stale);
8609
8620
  const citesMissingFact = previous?.sections.some(
@@ -8611,10 +8622,14 @@ async function synthesizeProfile(ctx, options = {}) {
8611
8622
  );
8612
8623
  if (previous && previous.vaultWatermark === watermark && !hasStaleSections && !citesMissingFact) {
8613
8624
  const sameOrder = previous.sections.length === facets.length && facets.every((f, i) => previous.sections[i]?.key === f.key);
8614
- if (sameOrder) return previous;
8625
+ if (sameOrder) {
8626
+ if (trendsEqual(previous.observationTrends, observationTrends)) return previous;
8627
+ return { ...previous, observationTrends };
8628
+ }
8615
8629
  return {
8616
8630
  ...previous,
8617
- sections: facets.map((f) => previous.sections.find((s) => s.key === f.key))
8631
+ sections: facets.map((f) => previous.sections.find((s) => s.key === f.key)),
8632
+ observationTrends
8618
8633
  };
8619
8634
  }
8620
8635
  const staleKeys = await computeStaleFacetKeys(ctx, memories, facets, previous, watermark);
@@ -8647,6 +8662,7 @@ async function synthesizeProfile(ctx, options = {}) {
8647
8662
  sections,
8648
8663
  vaultWatermark: watermark,
8649
8664
  config,
8665
+ observationTrends,
8650
8666
  generatedAt: Date.now()
8651
8667
  };
8652
8668
  }
@@ -8657,6 +8673,10 @@ function configMatches(a, b) {
8657
8673
  function facetsSignature(facets) {
8658
8674
  return facets.map((f) => JSON.stringify([f.key, f.label, f.query, f.guidance])).sort().join("\n");
8659
8675
  }
8676
+ function trendsEqual(a, b) {
8677
+ if (!a) return false;
8678
+ return a.new === b.new && a.strengthening === b.strengthening && a.stable === b.stable && a.weakening === b.weakening && a.stale === b.stale;
8679
+ }
8660
8680
  function changeTime(m) {
8661
8681
  return Math.max(m.updatedAt.getTime(), m.supersededAt ?? 0, m.lastObservedAt ?? 0);
8662
8682
  }
@@ -14375,6 +14395,8 @@ export {
14375
14395
  StreamExpiredError,
14376
14396
  TOPICS_EXTRACTION_VERSION,
14377
14397
  TOPIC_EXTRACTION_BATCH_SIZE,
14398
+ TREND_RECENT_WINDOW_DAYS,
14399
+ TREND_STALE_WINDOW_DAYS,
14378
14400
  VAULT_SIZE_HOP_CAP,
14379
14401
  WalletPoller,
14380
14402
  addConversationMemoriesOp,
@@ -14390,6 +14412,7 @@ export {
14390
14412
  classifyCryptoPriceBatch,
14391
14413
  classifyDecay,
14392
14414
  classifyInjectionCandidates,
14415
+ classifyObservationTrend,
14393
14416
  classifyStockPrice,
14394
14417
  classifyStockPriceBatch,
14395
14418
  classifyWeather,
@@ -14489,6 +14512,7 @@ export {
14489
14512
  stampTopicsExtractedAtOp,
14490
14513
  streamCancelPath,
14491
14514
  streamReplayPath,
14515
+ summarizeObservationTrends,
14492
14516
  supersedeVaultMemoryOp,
14493
14517
  synthesizeProfile,
14494
14518
  traverseGraphLane,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  recall
3
- } from "./chunk-EIHIZ5L4.mjs";
3
+ } from "./chunk-C7PGRFBG.mjs";
4
4
  import "./chunk-DFVCS3QQ.mjs";
5
5
  import "./chunk-GYKJOWEO.mjs";
6
6
  export {
@@ -4501,6 +4501,7 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
4501
4501
  createdAt: m.createdAt,
4502
4502
  updatedAt: m.updatedAt,
4503
4503
  proofCount: m.proofCount,
4504
+ lastObservedAt: m.lastObservedAt,
4504
4505
  eventTimeStart: m.eventTimeStart,
4505
4506
  sourceChunkIds: m.sourceChunkIds,
4506
4507
  eventTimeEnd: m.eventTimeEnd,
@@ -4517,13 +4518,27 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
4517
4518
  );
4518
4519
  }
4519
4520
  }
4520
- const timestampById = new Map(
4521
- memories.map((m) => [m.uniqueId, { createdAt: m.createdAt, updatedAt: m.updatedAt }])
4521
+ const metaById = new Map(
4522
+ memories.map((m) => [
4523
+ m.uniqueId,
4524
+ {
4525
+ createdAt: m.createdAt,
4526
+ updatedAt: m.updatedAt,
4527
+ proofCount: m.proofCount,
4528
+ lastObservedAt: m.lastObservedAt
4529
+ }
4530
+ ])
4522
4531
  );
4523
4532
  const stampTimestamps = (out) => {
4524
4533
  const results2 = out.results.map((r) => {
4525
- const ts = timestampById.get(r.uniqueId);
4526
- return ts ? { ...r, createdAt: ts.createdAt, updatedAt: ts.updatedAt } : r;
4534
+ const meta = metaById.get(r.uniqueId);
4535
+ return meta ? {
4536
+ ...r,
4537
+ createdAt: meta.createdAt,
4538
+ updatedAt: meta.updatedAt,
4539
+ proofCount: meta.proofCount,
4540
+ lastObservedAt: meta.lastObservedAt
4541
+ } : r;
4527
4542
  });
4528
4543
  return {
4529
4544
  results: results2,
@@ -4717,7 +4732,7 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
4717
4732
  legacy.map((r) => ({ id: r.uniqueId, content: r.content, score: r.similarity }))
4718
4733
  );
4719
4734
  }
4720
- const { recall: recall2 } = await import("./recall-FZVV5XUU.mjs");
4735
+ const { recall: recall2 } = await import("./recall-OTUNGQHQ.mjs");
4721
4736
  const result = await recall2(
4722
4737
  query,
4723
4738
  { vaultCtx, embeddingOptions, vaultCache: cache },
@@ -4981,6 +4996,42 @@ Which should be expanded?`,
4981
4996
  };
4982
4997
  }
4983
4998
 
4999
+ // src/lib/memory/observationTrend.ts
5000
+ var DAY_MS2 = 1e3 * 60 * 60 * 24;
5001
+ var TREND_RECENT_WINDOW_DAYS = 30;
5002
+ var TREND_STALE_WINDOW_DAYS = 90;
5003
+ function toMs(value) {
5004
+ return value instanceof Date ? value.getTime() : value;
5005
+ }
5006
+ function classifyObservationTrend(input, now = Date.now()) {
5007
+ const createdMs = toMs(input.createdAt);
5008
+ if (!Number.isFinite(createdMs) || !Number.isFinite(now)) return "stable";
5009
+ const lastMsRaw = input.lastObservedAt;
5010
+ const lastMs = lastMsRaw !== null && lastMsRaw !== void 0 && Number.isFinite(lastMsRaw) ? Math.max(createdMs, lastMsRaw) : createdMs;
5011
+ const proofs = Math.max(1, input.proofCount ?? 1);
5012
+ const ageDays = Math.max(0, (now - createdMs) / DAY_MS2);
5013
+ const daysSinceLast = Math.max(0, (now - lastMs) / DAY_MS2);
5014
+ if (daysSinceLast >= TREND_STALE_WINDOW_DAYS) return "stale";
5015
+ if (daysSinceLast >= TREND_RECENT_WINDOW_DAYS) return "weakening";
5016
+ if (ageDays <= TREND_RECENT_WINDOW_DAYS && proofs <= 2) return "new";
5017
+ if (proofs >= 3) return "strengthening";
5018
+ if (proofs >= 2 && ageDays > TREND_RECENT_WINDOW_DAYS) return "strengthening";
5019
+ return "stable";
5020
+ }
5021
+ function summarizeObservationTrends(inputs, now = Date.now()) {
5022
+ const counts = {
5023
+ new: 0,
5024
+ strengthening: 0,
5025
+ stable: 0,
5026
+ weakening: 0,
5027
+ stale: 0
5028
+ };
5029
+ for (const input of inputs) {
5030
+ counts[classifyObservationTrend(input, now)]++;
5031
+ }
5032
+ return counts;
5033
+ }
5034
+
4984
5035
  // src/lib/memory/queryTemporal.ts
4985
5036
  var RELATIVE_DAY_ENTRIES = [
4986
5037
  [/\btoday\b/, "today", 0],
@@ -5375,7 +5426,7 @@ async function recall(query, ctx, options = {}) {
5375
5426
  const fuseStart = nowMs();
5376
5427
  if (types.length === 1 || factResults.length === 0 || chunkResults.length === 0) {
5377
5428
  const memories2 = [
5378
- ...factResults.map(toFactMemory),
5429
+ ...factResults.map((r) => toFactMemory(r, options.now)),
5379
5430
  ...chunkResults.map(toChunkMemory)
5380
5431
  ];
5381
5432
  memories2.sort((a, b) => b.score - a.score);
@@ -5396,7 +5447,7 @@ async function recall(query, ctx, options = {}) {
5396
5447
  const fused = rrfFuse([factRanking, chunkRanking], options.rrfK);
5397
5448
  const byId = /* @__PURE__ */ new Map();
5398
5449
  for (const r of factResults) {
5399
- const m = toFactMemory(r);
5450
+ const m = toFactMemory(r, options.now);
5400
5451
  m.score = fused.get(`fact:${r.uniqueId}`) ?? 0;
5401
5452
  if (!m.scoreBreakdown) m.scoreBreakdown = {};
5402
5453
  m.scoreBreakdown.fused = r.similarity;
@@ -5445,7 +5496,10 @@ async function recall(query, ctx, options = {}) {
5445
5496
  ...vaultSize !== void 0 && { vaultSize }
5446
5497
  };
5447
5498
  }
5448
- function toFactMemory(r) {
5499
+ function toFactMemory(r, now) {
5500
+ const createdAt = r.createdAt ?? /* @__PURE__ */ new Date(0);
5501
+ const proofCount = r.proofCount ?? void 0;
5502
+ const lastObservedAt = r.lastObservedAt ?? null;
5449
5503
  return {
5450
5504
  id: r.uniqueId,
5451
5505
  kind: "fact",
@@ -5461,6 +5515,18 @@ function toFactMemory(r) {
5461
5515
  // (and UI reading them) carry the fact's type. Undefined when untyped.
5462
5516
  ...r.factType !== void 0 && { factType: r.factType },
5463
5517
  ...r.sourceChunkIds !== void 0 && r.sourceChunkIds !== null && { sourceChunkIds: r.sourceChunkIds },
5518
+ ...proofCount !== void 0 && proofCount !== null && { proofCount },
5519
+ ...lastObservedAt !== null && { lastObservedAt },
5520
+ // C2 — algorithmic trend from evidence timestamps (no LLM). Honor
5521
+ // RecallOptions.now so back-dated eval harnesses get consistent labels.
5522
+ observationTrend: classifyObservationTrend(
5523
+ {
5524
+ createdAt,
5525
+ lastObservedAt,
5526
+ proofCount
5527
+ },
5528
+ now ?? Date.now()
5529
+ ),
5464
5530
  // r.similarity from searchVaultMemoriesWithSize is the fused score
5465
5531
  // (cosine + BM25 + RRF + recency + proof) when useFusion=true (the
5466
5532
  // default) and pure cosine when useFusion=false. The breakdown
@@ -5469,7 +5535,7 @@ function toFactMemory(r) {
5469
5535
  content: r.content,
5470
5536
  score: r.similarity,
5471
5537
  scoreBreakdown: { fused: r.similarity },
5472
- createdAt: r.createdAt ?? /* @__PURE__ */ new Date(0),
5538
+ createdAt,
5473
5539
  updatedAt: r.updatedAt ?? /* @__PURE__ */ new Date(0)
5474
5540
  };
5475
5541
  }
@@ -5663,6 +5729,10 @@ export {
5663
5729
  capHopsForDensity,
5664
5730
  traverseGraphLane,
5665
5731
  createLlmNeighborRefiner,
5732
+ TREND_RECENT_WINDOW_DAYS,
5733
+ TREND_STALE_WINDOW_DAYS,
5734
+ classifyObservationTrend,
5735
+ summarizeObservationTrends,
5666
5736
  recall,
5667
5737
  preEmbedVaultMemories,
5668
5738
  eagerEmbedContent,