feat(recall): top-3 with body excerpts, per-session dedup, freshness …#6
Merged
Conversation
…+ kind markers Acts on the agent's feedback after the rerank upgrade landed: - **Top-3 instead of top-5.** Fewer, higher-quality matches. The cross- encoder rerank already trimmed noise — surfacing fewer entries with more substance beats surfacing more entries with thinner signal. - **Body excerpts on each surfaced entry.** ~250-char first-paragraph excerpt under each bullet. The agent reported reinventing weaker versions of rules it had been told via wikilink — titles alone aren't enough. Note: this revises the older ``[[projects/agent-mem/concepts/priming-surfaces-wikilinks-not-bodies]]`` preference based on direct evidence from the agent's session. - **Per-session sent-wikilink dedup.** Bounded LRU on the daemon (64 sessions × 200 wikilinks) tracks what's been surfaced per ``session_id``. Entries already shown to a session don't re-surface — they're in the agent's context. When every top-3 candidate is a repeat, the daemon returns empty markdown rather than recycling. ``session_id`` is now a fifth field on the priming RPC; the hook threads it through from the hook payload. - **Freshness marker (★)** on bullets whose frontmatter ``updated`` (or ``created``) falls inside a 7-day window. Recent thinking is usually most load-bearing for current work. - **Kind markers** ``[C]/[P]/[F]/[W]`` derived from path segment + ``severity:`` frontmatter. Lets the agent triage convention vs preference vs finding vs warning in a glance rather than parsing each title. Best-effort heuristic; falls back to no marker. - **Cross-project scope penalty.** Flipped cross-project entries from 0 bonus to -0.010. Other-project lessons now only surface when no scoped entry beats them on relevance. - **HTTP wire-log noise** silenced (claude-agent-sdk, mcp, asyncio, plus the earlier batch). Real signals from ``agent_mem_daemon.*`` no longer drowned by debug spam at ``-v``. Tests: 464 daemon + 174 search + 68 hooks pass (25 new tests covering body extraction, freshness, kind classification, scope penalty, dedup filter, and the per-session sent-cache LRU mechanics). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
nickroci
added a commit
that referenced
this pull request
May 27, 2026
…pdates them Footer addition surfaces on every priming render: *Entries are living — the curator updates them on new info. You may cite the current text; no need to maintain them yourself.* Addresses a real gap the agent could hit: an entry it consulted last turn may have a slightly different framing this turn because the Librarian/Scholar updated it from the conversation buffer. Without this note, the agent might (a) think it mis-cited, (b) distrust the entry, or (c) try to edit memory directly to "fix" the drift — the last of which would violate the existing ``no-manual-memory-writes-by-agents`` convention. The new line preempts (c) and gently licenses (a) — past versions were correct at their time; cite the current text. Wording is permissive on user's correction (``You may cite`` rather than ``Cite``) — the previous header's ``cite or follow when applicable`` already opted for that tone. Same string lands in both renderers (daemon ``priming.py::_FOOTER`` and the hook-side fallback ``_priming_client.py::_FOOTER``) so the agent sees the same framing regardless of which path served the request. Tests: - ``test_refresh_respects_char_budget`` and ``test_priming_char_budget_trims_bullets`` use deliberately-tight budgets (~400-500 chars) to exercise trim behaviour. The new footer added ~140 chars to the unconditional framing, so both budgets bumped (500→700, 400→600) to leave room for the trim test's seeded content. Production budget (1500) is unaffected. - ``test_send_request_returns_none_when_socket_missing`` had a pre-existing pyright complaint (partial ``PrimingRequest`` dict after ``session_id`` was added to the TypedDict in PR #6); fixed properly by constructing a fully-typed request rather than suppressing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.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.
…+ kind markers
Acts on the agent's feedback after the rerank upgrade landed:
Top-3 instead of top-5. Fewer, higher-quality matches. The cross- encoder rerank already trimmed noise — surfacing fewer entries with more substance beats surfacing more entries with thinner signal.
Body excerpts on each surfaced entry. ~250-char first-paragraph excerpt under each bullet. The agent reported reinventing weaker versions of rules it had been told via wikilink — titles alone aren't enough. Note: this revises the older
[[projects/agent-mem/concepts/priming-surfaces-wikilinks-not-bodies]]preference based on direct evidence from the agent's session.Per-session sent-wikilink dedup. Bounded LRU on the daemon (64 sessions × 200 wikilinks) tracks what's been surfaced per
session_id. Entries already shown to a session don't re-surface — they're in the agent's context. When every top-3 candidate is a repeat, the daemon returns empty markdown rather than recycling.session_idis now a fifth field on the priming RPC; the hook threads it through from the hook payload.Freshness marker (★) on bullets whose frontmatter
updated(orcreated) falls inside a 7-day window. Recent thinking is usually most load-bearing for current work.Kind markers
[C]/[P]/[F]/[W]derived from path segment +severity:frontmatter. Lets the agent triage convention vs preference vs finding vs warning in a glance rather than parsing each title. Best-effort heuristic; falls back to no marker.Cross-project scope penalty. Flipped cross-project entries from 0 bonus to -0.010. Other-project lessons now only surface when no scoped entry beats them on relevance.
HTTP wire-log noise silenced (claude-agent-sdk, mcp, asyncio, plus the earlier batch). Real signals from
agent_mem_daemon.*no longer drowned by debug spam at-v.Tests: 464 daemon + 174 search + 68 hooks pass (25 new tests covering body extraction, freshness, kind classification, scope penalty, dedup filter, and the per-session sent-cache LRU mechanics).