You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A recalled memory says where it came from: MemoryUnit.SourceRef and MemoryUnit.DerivedFrom.RememberAsync(…, sourceRef) / EncodeRequest.SourceRef take the caller's message or turn id and a recalled memory hands it back; a summary,
a merge or a reflection lists the memories it was made from (DerivedFrom, read from the summary_of / merged_from / source_ids metadata those already wrote). Both live in Metadata, so every store keeps them with no schema change. Breaking for implementers of IMemoryService (one more optional parameter before cancellationToken).
Changed
Recall no longer favours a long memory for containing the query's words because it is long. The keyword part of the
combined score counted each query word a memory contains, whatever its length, so a long answer that mentions most
words outranked a short statement that is the answer. A contained word now counts by BM25's term-frequency and length
factor (k1 1.2, b 0.75, relative to the candidates' average length), capped at its old value — an average-length
memory scores as before. Measured with bge-m3: BEAM 100K NDCG@10 +0.013 [+0.007, +0.019]; LongMemEval_S (120 questions)
NDCG@10 +0.007 [−0.005, +0.020], no type significantly lower.
Fixed
A promoted fact no longer erases what the profile already held under its key. Fast-track promotion wrote every fact with IArchiveStore.SetAsync, so a fact that replaced an earlier one left no history (GetHistoryAsync returned only the new
value) and the same fact promoted again reset its confirmation count to 1. A different value now supersedes the current one
through ArchiveAndUpdateAsync (the earlier value stays, inactive, with its ValidTo), and the same value is a confirmation
(ConfirmAsync).
Forgetting a user (ForgetUserAsync) removes the user's profile too. The facts promoted into IArchiveStore survived
the GDPR deletion and stayed readable through the profile and conflict APIs. Breaking for implementers of IArchiveStore: RemoveAllAsync(userId) is new.
The profile (IArchiveStore) is kept in the configured memory store, so it survives a restart. It lived in a
process-local dictionary, so with the SQLite or VectorStore store every promoted fact, confirmation and version history
was lost when the process stopped. Each entry is now a memory under the user key ArchiveUserKey.For(userId) — every store
partitions by user, so profile entries never appear in the user's recall — and fact validation during promotion sees the
profile's active entries, so a fact that contradicts the profile is detected. A read's time is kept (at most one write per
entry per hour), as retention and decay read it. Breaking: ArchiveStoreService's constructor takes the IMemoryStore
first; for implementers of IArchiveStore, GetStatsAsync and HasProfileAsync replace the
synchronous GetStats and HasProfile. Breaking for code that enumerates IMemoryStore.GetUserIdsAsync: profile keys
are listed there — skip them with ArchiveUserKey.IsArchiveKey (a store migration keeps copying them, which carries the
profiles).
Removed
Breaking: the memory lineage tracker (IMemoryLineageTracker, InMemoryLineageTracker and their event, option and
enum types). It was registered by AddMemoryIndexer() but nothing recorded into it, so every lineage query answered
empty. Where a memory came from is now on the memory itself — MemoryUnit.SourceRef and MemoryUnit.DerivedFrom above.
Breaking: the virtual context manager (IVirtualContextManager, VirtualContextManager, VCMOptions and their
result, state and enum types — VirtualContextState, EvictionResult, ConsolidationResult in MemoryIndexer.Interfaces, TierMigrationResult, SessionEndResult, ContextUsageStatistics, ContextActionRecommendation, ContextSaturationLevel).
It was registered by AddMemoryIndexer() but used by nothing in the library, and it held one conversation's paging state in
a singleton, so a process could page for only one conversation. The MemoryIndexer:VCM:WorkingMemory and MemoryIndexer:VCM:SemanticStore sections keep working; the other MemoryIndexer:VCM settings are no longer read.
Breaking: IScopeManager keeps only ResolveScopeAsync. The topic-tracking members (CurrentState, InitializeAsync, RecordTurnAsync, DetectTopicChangeAsync, GetCurrentTopicId, FilterByScope, EndSessionAsync, GetStatistics), ScopeState, ScopeResolution, ScopeBoundaryType, ScopeStatistics and ScopeManagerOptions (MemoryIndexer:ScopeManager)
are gone — nothing in the remember/recall path read them since topic tracking stopped running there in 0.38.0. ScopeManager
is stateless and its constructor takes only the logger. Migration: an implementer of IScopeManager keeps only ResolveScopeAsync.