Repository navigation
feat(forgetting): opt-in LLM judge that can veto decay deletions - #33
Closed
Nitjsefnie wants to merge 3 commits into
Closed
Nitjsefnie wants to merge 3 commits into
Nitjsefnie wants to merge 3 commits into
Conversation
Add MNEMA_SMART_FORGET_ENABLED (default off) plus judge model/key/URL config, a new mnema.judge module (pure prompt/verdict helpers and a thin OpenAI-compatible httpx client), and wire it into apply_decay: the judge can only rescue formula-selected candidates, and any failure keeps the memory. When disabled no judge is constructed and no LLM call is possible. Co-Authored-By: Kimi K3 <noreply@kimi.com>
Add a scripted FakeJudge to the fakes, unit tests for the pure prompt and verdict helpers plus the httpx-mocked OpenAI-compatible client, service tests proving the judge only rescues and fails safe to KEEP, and config tests for the MNEMA_JUDGE_MODEL requirement. No network, no API key. Co-Authored-By: Kimi K3 <noreply@kimi.com>
Add a 'Smart forgetting (opt-in)' subsection covering the four MNEMA_JUDGE_*/MNEMA_SMART_FORGET_ENABLED env vars, the rescue-only and fail-safe-KEEP guarantees, and a local Ollama example. Co-Authored-By: Kimi K3 <noreply@kimi.com>
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.
Summary
Adds opt-in, LLM-assisted forgetting: when enabled, a configured judge can veto the decay formula's
deletion candidates, so a memory the heuristic would drop can be rescued. Disabled by default β with
no configuration the behaviour is byte-for-byte what it is today, and no LLM is ever constructed or
called.
Related issue
Closes #14
Changes
mnema.judgeβ an OpenAI-compatible chat judge overhttpx(already a core dependency, sothis adds nothing to install). Split pure from I/O the way
decay.pyandsummarize.pyare: theprompt builder and
parse_forget_verdictare pure functions, only the client touches the network.make_judgefactory β the single construction site, gated onsmart_forget_enabled. Whensmart forgetting is off, no judge object exists at all.
MemoryService.apply_decaywiring β one injection point, so the CLI, the dream loop, the APIand the dashboard all inherit the behaviour with zero route changes.
MNEMA_SMART_FORGET_ENABLEDplusMNEMA_JUDGE_*settings, validated inconfig.py.README.mdsection covering the flags and the veto-only semantics.tests/test_judge.py, aTestSmartForgettingclass intests/test_service.py, configcases, and a
FakeJudgeintests/fakes.py.The judge can only rescue, never delete. Candidates are still selected purely by
score <= threshold; the judge is handed that list and may only remove entries from it. There is nopath by which enabling this deletes something the formula would have kept.
Fail-safe is KEEP. Any error, timeout, non-JSON body, wrong-shaped JSON, empty
choices, nullcontent, HTTP 500, or an unparseable verdict results in keeping the memory. This follows the repo's
existing conservative-deletion posture (
dry_run=Trueby default, the importance floor, thedeliberately conservative Dreamer).
Checklist
ruff check .is cleanpytestpasses (with the relevant[extra]installed if you touched a backend)README.md,SKILL.md,docs/) if user-facing behavior changed__init__.py::make_*),added an
[extra]inpyproject.toml, and added a test class β partially: it is registeredvia a
make_judgefactory and has its own test class, but it needs no[extra]because itintroduces no new dependency. See the note below.
Bugs Discovered
apiextra exists, somnema-mcp[api](which the CLI recommends) fails and 15 REST-API tests never run in CIΒ #32 Noapiextra exists, somnema-mcp[api](which the CLI recommends) fails and 15 REST-API tests never run in CINotes for reviewer
Design calls I made from your own precedent β overrule any of them and I will change it:
rescue. Judging every memory, or judging above-threshold records, is a wider behaviour change and
felt like your call, not mine.
httpx. Modelled onembeddings/ollama.pyandthe Cohere worked example in
CONTRIBUTING. It works against a local Ollama, so it needs no paidkey. Because
httpxis already a core dependency, adding apyproject.tomlextra would declare adependency that does not exist β which is why that checklist box is only partly ticked rather than
ticked or ignored.
FakeJudgeplus thehttpxmonkeypatch pattern fromtests/test_embeddings.py, so this is exercised with no key and no connection.Deliberately out of scope, as follow-ups for you to decide on rather than things I bundled in:
LLM-assisted merging ("should these two be merged?"), judging above-threshold records, batching /
caching / cost caps, and any CLI, MCP or dashboard surface for smart mode.
Verification detail, in case it is useful: the new tests were checked for bite by reverting
service.pyandconfig.pytomainwhile keeping the tests β 19 fail and 20 error, including therescue and the never-construct-when-disabled cases. The fail-safe paths were exercised against a real
local HTTP server and a real connect timeout rather than mocks. The whole branch was also verified
from a
git archiveof the commit rather than the working tree, to be sure nothing that only existslocally is needed to run it.
Footer
Generated by Kimi K3 (brief, implementation, verification), Claude Opus 5 (1M context) (review)