feat(memory): say when a turn used stored memory, and which - #417
Merged
Conversation
Recalled memory was prepended to every prompt with nothing on any surface
saying so. An answer shaped by a remembered fact read as if the model simply
knew it, and an operator had no way to tell the difference — or to find the
entry responsible.
- `build_memory_context` returns a `MemoryContext { block, keys }`. The keys
are carried rather than parsed back out of the block: the block's shape is a
prompt-formatting decision, and a reader deriving keys from it would break
the next time that shape changed.
- The agent emits `AgentEvent::MemoryRecalled { keys }` before the first chunk,
and only when something was injected — an empty recall stays silent.
- TUI renders it as a muted tool-log line: memory is background activity, not
something to act on.
- Gateway forwards it as `memory_recalled` on the chat stream.
- Channels take `.block` only: a remote transport has no event stream to
surface it on.
Both directions are covered: removing the emit fails the test, and emitting
unconditionally fails its control.
Driving the new line showed it filling the width with
`user_msg_23f4b294-…` — five uuids that identify nothing to the reader.
Same defect the console's memory panel had with generated keys.
Auto-saved turns are now counted ("3 from this conversation"); memories a
person named are still named. Adds `memory::is_autosave_key` for the test.
Also switches the notice onto `append_system_message`: `scrollback_queue`
and `commit_message_to_scrollback` still exist but nothing reads them any
more, so the first version rendered nowhere at all.
PR intake checks found warnings (non-blocking)Fast safe checks found advisory issues. CI lint/test/build gates still enforce merge quality.
Action items:
Run logs: https://github.com/RantAI-dev/RantAIClaw/actions/runs/31082831161 Detected blocking line issues (sample):
Detected advisory line issues (sample):
|
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.
Problem
Recalled memory was prepended to every prompt with nothing on any surface
saying so. An answer shaped by a remembered fact read as if the model simply
knew it, and an operator had no way to tell the difference — or to find the
entry responsible. This was raised as the one gap left open by the memory
UI/UX sweep (#414, #415, claw-ui #50).
Change
build_memory_contextreturnsMemoryContext { block, keys }. The keys arecarried rather than parsed back out of the block: the block's shape is a
prompt-formatting decision, and a reader deriving keys from it would break
the next time that shape changed.
AgentEvent::MemoryRecalled { keys }before the first chunk,and only when something was injected — an empty recall stays silent.
↺ recalled N memories: ….memory_recalledon the chat stream (consumed byclaw-ui, separate PR).
.blockonly: a remote transport has no event stream tosurface it on.
Auto-saved turns are counted, not named. Their keys are
user_msg_<uuid>,and the first version of this line filled the terminal width with hex while
saying less than "3 from this conversation" does — the same defect the console's
memory panel had with generated keys.
Validation
cargo test --lib memory:: / tui::app / agent:: / gateway::api_v1and--test agent_e2e— 629 passed across the affected areas.emitting unconditionally fails its control.
completes:
Two things this surfaced
The first version rendered nowhere. It pushed to
scrollback_queue, which— along with
commit_message_to_scrollback— nothing insrc/reads any more.Only driving the binary caught it. Both are left in place rather than removed
here: dead code is worth a separate, deliberate change.
What actually gets injected is conversation echo. In the run above, all
five recalled entries were auto-saved turns; the curated
deploy_windowfactnever reached the prompt, although a direct
memory recallranks it at 100%.recall_layeredputs conversation-scoped hits first and they fill the entrybudget. That is pre-existing behaviour and changing it changes what every turn
sends to the model, so it is not touched here — but it is worth deciding on,
and it was invisible until this landed.
Risk / rollback
Medium: one new event variant, one changed return type with three call sites.
No config or schema change. Revert the commits.