Skip to content

feat(recall): return 16 facts in MCP, the OpenClaw plugin and NanoClaw - #733

Draft
p-diogo wants to merge 1 commit into
mainfrom
feat/recall-top-k-16
Draft

p-diogo wants to merge 1 commit into
mainfrom
feat/recall-top-k-16

Conversation

@p-diogo

@p-diogo p-diogo commented Nov 4, 2026 •

Copy link
Copy Markdown
Collaborator

Draft: do not merge. Client merges are on hold until the audit sync, and MCP 3.5.1-rc.3 is in human QA, so main must not move under it.

Summary

Every client now returns 16 facts per recall by default. Hermes has used 16 since #365: on LOCOMO, going from 8 to 16 raised overall accuracy from 40% to 47% and multi-hop from 18% to 35%. k=24 was tested and was flat against 16. MCP, the OpenClaw plugin, NanoClaw, the TS client and the ZeroClaw crate still used 8.

An explicit caller k / maxResults still wins everywhere.

Changes

Package Before After
MCP totalreclaw_recall (managed + self-hosted) k ?? 8 k ?? getRecallTopK(): env TOTALRECLAW_RECALL_TOP_K > relay features.recall_top_k > 16
MCP tool schema / description / rerank() default 8 16
Plugin memory_search (no maxResults) DEFAULT_MAX_RESULTS = 8, closure ?? 8 closure ?? getRecallTopK() (same order), cap of 20 unchanged
Plugin before_agent_start auto-recall (subgraph + server mode) hardcoded 8 min(getRecallTopK(), 20)
Plugin rerank() / applyMMR() defaults, skill.json, README 8 16
NanoClaw beforeAgentStart(maxMemories) 8 16
@totalreclaw/client recall(query, k), applyMMR default 8 16
ZeroClaw AUTO_RECALL_TOP_K 8 16

Honouring the relay value. MCP and the plugin already cache billing features, so they now read features.recall_top_k in the same order as Python (env > server > 16):

  • MCP takes it from the billing responses it already caches (proactiveBillingFetch, totalreclaw_status). The first recall of a process, before any billing response, uses 16. subgraph/chain-config.ts (the startup lookup, recently changed for test(hermes): pin the Hermes 0.22 built-in-memory stance; fix main #689) is not touched.
  • The plugin reads it from billing-cache.json, which already stores features as received (resolveRecallTopK in billing/billing-cache.ts). Env reads stay in config.ts, and the scanner sim is clean.
  • NanoClaw, the TS client and ZeroClaw get the new default only. They have no relay lookup on this path today.

Docs: client-consistency.md (top_k 8 → 16, server-driven + env + explicit-wins), read-path and cross-agent-hooks flow diagrams, proactive-recall-best-practices.md (also removes the wrong "8/16 by tier"), beta-tester-guide-detailed.md, ironclaw-setup.md, NanoClaw SKILL.md + mcp/SKILL.md (the MCP-mode example no longer pins k). env-vars-reference.md and self-hosted-deployment.md already said 16.

CHANGELOG entries: mcp/, skill/plugin/, skill-nanoclaw/, rust/totalreclaw-memory/. client/ has no CHANGELOG.

Size limits checked

  • MCP recall output is plain JSON with no truncation or size cap. 16 memories of a few hundred bytes each fit easily. The server-instructions budget is separate and unaffected.
  • Plugin memory_search snippets stay capped at 500 chars each, so 16 hits are at most about 8 KB. The auto-recall block (formatRecallContext in core) has no count or char cap.
  • Plugin cap of 20 and MCP cap of 50 are unchanged, and 16 is under both.

Resolved: staging now serves recall_top_k = 16

Staging served 8 when first queried; its RECALL_TOP_K override was removed and the relay redeployed on 2026-11-04. Staging and production both serve 16, verified with a throwaway account, so every client returns 16 in both environments.

Deliberately left at 8

  • Parity test vectors that pass k=8 explicitly (reranker-cross-runtime-parity in MCP + plugin): they are fixtures, not defaults.
  • skill/plugin/pocv2-e2e-test.ts: a dev script that is not shipped.
  • Explicit top_k=8 examples in agent-call snippets in proactive-recall-best-practices.md (lines 44 and 68): these are caller choices, not defaults.
  • Historical design docs (retrieval-v2, tiered-retrieval, retrieval-improvements-v3, TEE notes) and the RESOLVED ZeroClaw row in CLAUDE.md.
  • Python library defaults (TotalReclaw.recall(top_k=8), agent.recall.auto_recall/recall_for_query(top_k=8), operations, reranker): out of scope here. Every Hermes path passes state.get_recall_top_k() (16), so only direct library callers get 8.

Tests

  • MCP: tsc --noEmit clean. npm run build && jest: 50/50 suites, 853 passed, 5 skipped. New tests/recall-top-k.test.ts covers the default, relay vs default, env vs relay, invalid values and explicit k winning. The k default assertions in server/tool-registration/input-validation tests changed 8 → 16.
  • Plugin: npm test gives 98/99 files pass. The one failure, llm/llm-client.test.ts (2 asserts, "no-sources"), also fails on origin/main on this machine because it depends on the environment. npm run typecheck reports 29 errors, the same 29 as origin/main. check-scanner is OK. New cases in billing/billing-cache.test.ts (42/42) and memory/memory-runtime.test.ts.
  • NanoClaw: builds clean. jest shows 106 passed, 12 failed. The same 12 agentEnd/preCompact failures occur on origin/main, and none involve beforeAgentStart.
  • Client: jest 12/12 suites, 269 passed. No new tsc errors in touched files (6 pre-existing elsewhere).
  • Rust totalreclaw-memory: cargo test --lib --test spec_compliance gives 57 + 24 passed. test_auto_recall_top_k_is_8 was renamed to _is_16.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Bd3G1BkVMFSXkcdAQ7nFax

Hermes has returned 16 facts per recall since public #365 (LOCOMO:
overall 40% -> 47%, multi-hop 18% -> 35%; k=24 was flat). MCP, the
OpenClaw plugin, NanoClaw, the TS client and the ZeroClaw crate still
defaulted to 8.

- MCP: totalreclaw_recall without k resolves env TOTALRECLAW_RECALL_TOP_K
  > relay features.recall_top_k (from the billing responses it already
  caches) > 16, in both managed and self-hosted mode. Schema default,
  tool description and reranker default say 16.
- OpenClaw plugin: memory_search without maxResults and the
  before_agent_start auto-recall use the same order via
  resolveRecallTopK (billing cache already stores features verbatim).
  memory_search no longer pins its own default. Cap of 20 unchanged.
- NanoClaw beforeAgentStart, @totalreclaw/client recall(), and the
  ZeroClaw AUTO_RECALL_TOP_K default to 16 (no relay lookup there).
- Specs and guides that stated 8 now say 16. CHANGELOG entries per
  package.

An explicit caller k / maxResults still wins.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bd3G1BkVMFSXkcdAQ7nFax

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant