Skip to content

Commit 02e7de8

Browse files
authored
Merge pull request #6 from nickroci/feat/recall
feat(recall): top-3 with body excerpts, per-session dedup, freshness …
2 parents d4ed0cb + 5dcaaae commit 02e7de8

8 files changed

Lines changed: 705 additions & 73 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ The agent can't afford to query the library for everything it's about to do, and
5454

5555
| Tier | Cognitive analog | Latency | Trigger | What it does |
5656
|---|---|---|---|---|
57-
| **1. Ambient priming** | Familiarity / spreading activation (Collins & Loftus, 1975) | <2s (Unix-socket round trip to warm daemon; budget enforced by the hook) | Hook fires a priming RPC to the daemon on every UserPromptSubmit | Top 5 most-relevant entries injected as `additionalContext` on every UserPromptSubmit. Agent has them "in mind" without asking. Three-stage retrieval: BM25 + sentence-transformer embeddings (nomic-embed-text-v1.5) → RRF fusion → cross-encoder rerank (ms-marco-MiniLM-L-12-v2), boosted by `reinforced` counter + project-scope prior. ≤1500 char budget. |
57+
| **1. Ambient priming** | Familiarity / spreading activation (Collins & Loftus, 1975) | <2s (Unix-socket round trip to warm daemon; budget enforced by the hook) | Hook fires a priming RPC to the daemon on every UserPromptSubmit | Top **3** most-relevant entries injected as `additionalContext` on every UserPromptSubmit, **each with a short body excerpt** so the agent can cite the actual rule rather than guess from the title. Bullets carry freshness (`` for entries updated in the last 7 days) and kind markers (`[C]` convention, `[P]` preference, `[F]` finding, `[W]` warn). **Per-session dedup**: entries already surfaced this session don't re-surface — once shown, they're in the agent's context. Three-stage retrieval: BM25 + sentence-transformer embeddings (nomic-embed-text-v1.5) → RRF fusion → cross-encoder rerank (ms-marco-MiniLM-L-12-v2), boosted by `reinforced` counter, project-scope prior (current-project bonus, cross-project penalty). ≤1500 char budget. |
5858
| **2. Deliberate recall** | Hippocampal recollection (Yonelinas, 2002) | 30-60s | `/ultan-advisor <question>` invocation | Sonnet Librarian searches deeply, Opus Scholar synthesises a referenced answer. The drill-down when the priming snippet isn't enough. |
5959
| **3. Acute notice** | Orbital-PFC stop signal (Aron et al., 2014) | <100ms synchronous | PreToolUse hook on every tool call | Default `advise`: pattern-matches the tool call against entries with `block_triggers`; on match, emits an `additionalContext` FYI — *"📚 Library note: [[X]] applies here"* — and the tool proceeds. **The agent decides.** Opt-in `severity: block` is reserved for genuinely dangerous actions (`rm -rf /`, force-push to main); only then does the hook hard-deny. Like a human noticing a relevant memory mid-action: noticed, not paralysed. |
6060

@@ -66,7 +66,7 @@ The library is structurally a graph: folder hierarchy gives the tree, wikilinks
6666

6767
Retrieval over the graph is split across tiers:
6868

69-
- **Tier 1 (priming) is text-only** — three-stage retrieval: BM25 + sentence-transformer embeddings (nomic-embed-text-v1.5) fused via RRF, then re-ordered by a cross-encoder reranker (ms-marco-MiniLM-L-12-v2) co-attending over each `(query, body)` pair, and finally boosted by the `reinforced` counter plus project-scope prior. The retriever does not traverse the graph; it returns top-k entries by relevance, with wikilinks appearing in the output as *hints*.
69+
- **Tier 1 (priming) is text-only** — three-stage retrieval: BM25 + sentence-transformer embeddings (nomic-embed-text-v1.5) fused via RRF, then re-ordered by a cross-encoder reranker (ms-marco-MiniLM-L-12-v2) co-attending over each `(query, body)` pair, and finally boosted by the `reinforced` counter plus project-scope prior (current-project bonus + cross-project penalty). The top 3 survivors are rendered with body excerpts, freshness markers, and one-character kind tags; per-session dedup suppresses entries already shown to the agent. The retriever does not traverse the graph; it returns top-k entries by relevance, with wikilinks appearing in the output as *hints*.
7070
- **Tier 2 (deliberate recall) is agent-driven graph traversal.** The agent sees wikilinks in priming context and follows them via the `ultan-search` skill, which returns the entry plus its local neighborhood — siblings, subfolders, parent README — in one read. The agent decides which edges to follow and when to stop, the same "memory as tools" pattern Letta and Wire have shown beats pre-baked retrieval expansion on cross-document queries.
7171

7272
The deliberate choice: deterministic-and-cheap text retrieval at always-on Tier 1, semantic-and-expensive graph traversal at on-demand Tier 2. PageRank-style structural expansion at Tier 1 is a possible addition (see *Roadmap*), not a current capability.

daemon/agent_mem_daemon/logging_setup.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,21 @@ def configure(
111111
"transformers",
112112
"filelock",
113113
"markdown_it",
114+
# claude-agent-sdk internals — at -v these emit a stream of
115+
# "Waiting for first result", "Using bundled CLI", and per-message
116+
# transport debug lines for every Librarian/Scholar call. The
117+
# signal we actually care about (call started, finished, cost,
118+
# parsed_ok) is logged separately by ``agent_mem_daemon.*``.
119+
"claude_agent_sdk",
120+
"claude_agent_sdk._internal",
121+
"claude_agent_sdk._internal.query",
122+
"claude_agent_sdk._internal.transport",
123+
"claude_agent_sdk._internal.transport.subprocess_cli",
124+
"mcp",
125+
"mcp.server",
126+
"mcp.server.lowlevel",
127+
"mcp.server.lowlevel.server",
128+
"asyncio",
114129
)
115130
for name in _NOISY_LOGGERS:
116131
logging.getLogger(name).setLevel(logging.WARNING)

0 commit comments

Comments
 (0)