feat(agent-memory): Phase 8 — self-optimization config reads#256
Open
jamby77 wants to merge 3 commits into
Open
feat(agent-memory): Phase 8 — self-optimization config reads#256jamby77 wants to merge 3 commits into
jamby77 wants to merge 3 commits into
Conversation
eea7699 to
ee647cc
Compare
524f3a8 to
e58dbb7
Compare
14b6e7c to
9412e5a
Compare
e58dbb7 to
0d89d67
Compare
9412e5a to
37c7a4b
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 37c7a4b. Configure here.
- MemoryStore reads {name}:__mem_config on an opt-in configRefresh
interval and live-applies recall.threshold, recall.weights.*,
recall.halfLifeSeconds, and maxItemsPerScope without a restart
- Absent fields fall back to constructor values; invalid values are
ignored; reads are best-effort and never throw
- Reject an all-zero weight vector to keep recall ordering well-defined
- Add currentConfig() to expose the effective tunables; close() also
stops the refresh interval
- Refresh is off by default (opt-in) so a standalone store never polls
Capture halfLifeSeconds with threshold/weights before the first await so a concurrent configRefresh can't score a single recall with a mix of config versions.
0d89d67 to
73d91d7
Compare
37c7a4b to
06b56f6
Compare
enforceCapacity read weights and halfLifeSeconds from instance fields at selectEvictions time, several awaits after the capacity check. With opt-in configRefresh a refresh could land mid-pass and score victims with a different tunable set. Snapshot weights and halfLifeSeconds at entry, matching the recall snapshot, so a pass uses one consistent config.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Stacked on #255 (Phase 7 — discovery marker).
What
Phase 8 of
@betterdb/agent-memory: runtime-tunable recall/eviction knobs, so BetterDB Monitor's cache-proposals engine can retune a memory store without a restart (same pattern as semantic-cache'sconfigRefresh).MemoryStorereads{name}:__mem_configand live-applies:recall.threshold(cosine-distance ceiling, 0..2)recall.weights.similarity/recall.weights.recency/recall.weights.importancerecall.halfLifeSecondsmaxItemsPerScoperefreshConfig()(public, manual tick) reads the hash and applies it;currentConfig()exposes the effective tunables.Opt-in
configRefresh?: boolean | { enabled?, intervalMs? }enables an immediate read plus an unref'd interval (default 30s, min 1s);close()stops it.Design / review notes
.callsequences.initialWeightsis copied so the sharedDEFAULT_WEIGHTSconstant can't be aliased.recall()captures threshold+weights into locals before its firstawait, so an interval refresh can't tear an in-flight recall.Tests (
MemoryStore.config.test.ts, 12)defaults snapshot · threshold · weights · halfLifeSeconds+maxItemsPerScope · partial config leaves others default · field-removal reverts · invalid ignored · all-zero weights rejected · live threshold affects recall end-to-end · no polling when disabled · immediate+interval read & stop on close (fake timers) · best-effort on read failure.
77/77 package tests green ·
tscclean · prettier clean.Note
Medium Risk
Changes live recall scoring, eviction victim selection, and capacity limits when external config is applied; validation and snapshots limit bad states, but mis-tuned remote values can still alter memory behavior at runtime.
Overview
Adds opt-in runtime tuning for
MemoryStoreby reading{name}:__mem_configfrom Valkey, mirroring semantic-cache’sconfigRefreshpattern so Monitor can retune recall/eviction without a restart.refreshConfig()andcurrentConfig()expose manual reads and the effective snapshot (threshold, weights, half-life,maxItemsPerScope). WithconfigRefreshenabled, the store polls on an interval (default 30s, min 1s), runs an immediate read at startup, andclose()stops the timer. Refresh is off by default so existing stores never poll unless opted in.Each refresh rebuilds from constructor defaults plus only fields present in the hash; removed fields revert. Invalid values are ignored; all-zero weight vectors are rejected.
recall()andenforceCapacity()snapshot tunables before async work so concurrent refresh cannot mix config versions mid-operation.New
MemoryStore.config.test.tscoverage and an eviction test for mid-pass refresh; public types exported fromindex.ts.Reviewed by Cursor Bugbot for commit 7d0fa87. Bugbot is set up for automated code reviews on this repo. Configure here.