Skip to content

fix(mcp): route memory_recall through full search#532

Open
Lubrsy706 wants to merge 2 commits into
rohitg00:mainfrom
Lubrsy706:fix/507-memory-recall-full-format
Open

fix(mcp): route memory_recall through full search#532
Lubrsy706 wants to merge 2 commits into
rohitg00:mainfrom
Lubrsy706:fix/507-memory-recall-full-format

Conversation

@Lubrsy706
Copy link
Copy Markdown

@Lubrsy706 Lubrsy706 commented May 19, 2026

Summary

  • route standalone MCP memory_recall proxy calls to /agentmemory/search instead of /agentmemory/smart-search
  • forward format and token_budget so full, compact, and narrative recall modes work as advertised
  • align local fallback memory_recall with search-style responses while leaving memory_smart_search compact

Fixes #507

Tests

  • npm test -- test/mcp-standalone-proxy.test.ts test/mcp-standalone.test.ts
  • npm run build
  • npm test

Summary by CodeRabbit

  • New Features

    • Memory recall supports three output formats: full, compact, and narrative.
    • Improved local memory search with better matching and session extraction.
    • Token budget validation added for memory operations.
  • Behavior Changes

    • Proxy mode now forwards memory searches and returns proxied narrative responses when requested.
    • Smart-search local results return compact-mode output.
  • Tests

    • Expanded tests covering formats, proxy behavior, and token budget validation.

Review Change Stack

Signed-off-by: Lubrsy706 <lubrsy706@gmail.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 19, 2026

@Lubrsy706 is attempting to deploy a commit to the rohitg00's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 19, 2026

📝 Walkthrough

Walkthrough

Refactors memory_recall to validate token_budget, normalize format (full|compact|narrative), forward format/token_budget to the proxy (/agentmemory/search), add LocalMemory search helpers, implement format-aware local responses (compact list, narrative text, full observations), and update proxy and local tests.

Changes

Memory_recall format and token_budget support

Layer / File(s) Summary
Token budget parsing & textResponse signature
src/mcp/standalone.ts
Adds parseTokenBudget to strictly parse/validate token_budget as a positive integer and adjusts textResponse signature formatting.
LocalMemory helpers (matching & search)
src/mcp/standalone.ts
Introduces LocalMemory alias and helpers: localMemoryMatches, searchLocalMemories, and firstSessionId for local mem:memories word-based matching and limited querying.
Validate(): format & token_budget normalization
src/mcp/standalone.ts
validate() now normalizes/validates format ∈ `full
Local handle: format-aware memory_recall & smart_search
src/mcp/standalone.ts, test/mcp-standalone.test.ts
handleLocal uses searchLocalMemories; memory_smart_search returns compact-mode results; memory_recall branches by format to return compact lists, narrative text, or full observation objects. Tests updated/added for compact, narrative, full, and invalid-format / invalid-token_budget cases.
Proxy handling and proxy tests
src/mcp/standalone.ts, test/mcp-standalone-proxy.test.ts
Proxy memory_recall now POSTs to /agentmemory/search with query, limit, format, and optional token_budget. Proxy tests assert the forwarded POST body, ensure /agentmemory/smart-search is not called, and add narrative-format proxy test; local-fallback tests updated to new response schema.
handleToolsList debug formatting tweaks
src/mcp/standalone.ts
Minor reformatting of AGENTMEMORY_DEBUG derivation and refined remote response “shape” string computation used in debug logging.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant MCP as MCP.handleProxy
  participant AgentMemory as /agentmemory/search
  Client->>MCP: memory_recall(query, limit, format, token_budget)
  MCP->>AgentMemory: POST { query, limit, format, token_budget? }
  AgentMemory-->>MCP: { format, text?, results }
  MCP-->>Client: textResponse(proxyPayload, pretty=true)
Loading
sequenceDiagram
  participant Client
  participant MCPLocal as MCP.handleLocal
  participant LocalMemory as searchLocalMemories
  Client->>MCPLocal: memory_recall(query, limit, format)
  MCPLocal->>LocalMemory: searchLocalMemories(queryWords, limit)
  LocalMemory-->>MCPLocal: matched memories list
  MCPLocal-->>Client: return compact list | narrative text | full observation objects
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Possibly related PRs

  • rohitg00/agentmemory#516 — Also updates src/mcp/standalone.ts to forward format/token_budget and route memory_recall to /agentmemory/search.

Poem

🐰 I hop through code to fetch each thought,
compact, full, or story-wrought.
Budgets checked with careful art,
narratives and lists play their part.
Memory blossoms — tidy, bright, and taut.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the primary change: routing memory_recall to the full search endpoint instead of smart-search.
Linked Issues check ✅ Passed The PR fulfills all coding objectives from #507: routes memory_recall to /agentmemory/search, parses and forwards format and token_budget parameters, and adjusts local fallback responses.
Out of Scope Changes check ✅ Passed All changes in src/mcp/standalone.ts and tests are directly related to fixing the memory_recall routing and format parameter handling per issue #507.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/mcp/standalone.ts`:
- Around line 185-199: The handler currently accepts arbitrary args["format"]
and sets v.format, which lets a memory_smart_search request forward unsupported
formats upstream; enforce that when v.kind === "memory_smart_search" you ignore
or override any provided format and set v.format = "compact" (or remove/omit
format) so only compact is used, and ensure args["format"] processing (the block
referencing args["format"] / v.format) does not apply for memory_smart_search;
reference the symbols v.kind, v.format, and args["format"] to locate and change
the logic.
- Around line 190-199: The current validation checks `budget > 0` then assigns
`v.tokenBudget = Math.floor(budget)`, which allows sub-unit inputs like 0.5 to
become 0; change both branches to compute the floored value first and only
assign if that floored value is > 0: for the numeric branch compute floorN =
Math.floor(budget) and set `v.tokenBudget = floorN` only when floorN > 0; for
the string branch parse to n, compute floorN = Math.floor(n) and assign only
when floorN > 0, ensuring `v.tokenBudget` never becomes 0 from fractional inputs
while still accepting valid positive integer budgets.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 870fd25d-7a78-4cc8-9e78-5e1e1ee2b223

📥 Commits

Reviewing files that changed from the base of the PR and between 01030a1 and 29454e9.

📒 Files selected for processing (2)
  • src/mcp/standalone.ts
  • test/mcp-standalone-proxy.test.ts

Comment thread src/mcp/standalone.ts
Comment on lines +185 to +199
} else {
const fmt = args["format"];
if (typeof fmt === "string" && fmt.trim()) {
v.format = fmt.trim().toLowerCase();
}
const budget = args["token_budget"];
if (
typeof budget === "number" &&
Number.isFinite(budget) &&
budget > 0
) {
v.tokenBudget = Math.floor(budget);
} else if (typeof budget === "string" && budget.trim()) {
const n = Number(budget);
if (Number.isFinite(n) && n > 0) v.tokenBudget = Math.floor(n);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Keep memory_smart_search compact-only.

Issue #507 says /agentmemory/smart-search does not support format, but this path accepts arbitrary values and Line 258 forwards them upstream. That creates a proxy-only failure mode while local fallback still stays compact.

Suggested fix
       } else {
-        const fmt = args["format"];
-        if (typeof fmt === "string" && fmt.trim()) {
-          v.format = fmt.trim().toLowerCase();
-        }
         const budget = args["token_budget"];
         if (
           typeof budget === "number" &&
@@
     case "memory_smart_search": {
       const body: Record<string, unknown> = { query: v.query, limit: v.limit };
-      if (v.format != null) body["format"] = v.format;
       if (v.tokenBudget != null) body["token_budget"] = v.tokenBudget;
       const result = await handle.call("/agentmemory/smart-search", {
         method: "POST",

Also applies to: 257-259

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/mcp/standalone.ts` around lines 185 - 199, The handler currently accepts
arbitrary args["format"] and sets v.format, which lets a memory_smart_search
request forward unsupported formats upstream; enforce that when v.kind ===
"memory_smart_search" you ignore or override any provided format and set
v.format = "compact" (or remove/omit format) so only compact is used, and ensure
args["format"] processing (the block referencing args["format"] / v.format) does
not apply for memory_smart_search; reference the symbols v.kind, v.format, and
args["format"] to locate and change the logic.

Comment thread src/mcp/standalone.ts
Comment on lines +190 to +199
const budget = args["token_budget"];
if (
typeof budget === "number" &&
Number.isFinite(budget) &&
budget > 0
) {
v.tokenBudget = Math.floor(budget);
} else if (typeof budget === "string" && budget.trim()) {
const n = Number(budget);
if (Number.isFinite(n) && n > 0) v.tokenBudget = Math.floor(n);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Ignore sub-unit token_budget values before flooring.

budget > 0 followed by Math.floor(...) turns values like 0.5 into 0, so this branch can still forward a non-positive token_budget.

Suggested fix
         const budget = args["token_budget"];
-        if (
-          typeof budget === "number" &&
-          Number.isFinite(budget) &&
-          budget > 0
-        ) {
-          v.tokenBudget = Math.floor(budget);
-        } else if (typeof budget === "string" && budget.trim()) {
-          const n = Number(budget);
-          if (Number.isFinite(n) && n > 0) v.tokenBudget = Math.floor(n);
-        }
+        const n =
+          typeof budget === "number"
+            ? budget
+            : typeof budget === "string" && budget.trim()
+              ? Number(budget)
+              : undefined;
+        if (n !== undefined && Number.isFinite(n)) {
+          const floored = Math.floor(n);
+          if (floored > 0) v.tokenBudget = floored;
+        }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/mcp/standalone.ts` around lines 190 - 199, The current validation checks
`budget > 0` then assigns `v.tokenBudget = Math.floor(budget)`, which allows
sub-unit inputs like 0.5 to become 0; change both branches to compute the
floored value first and only assign if that floored value is > 0: for the
numeric branch compute floorN = Math.floor(budget) and set `v.tokenBudget =
floorN` only when floorN > 0; for the string branch parse to n, compute floorN =
Math.floor(n) and assign only when floorN > 0, ensuring `v.tokenBudget` never
becomes 0 from fractional inputs while still accepting valid positive integer
budgets.

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.

bug: memory_recall always returns compact mode — wrong endpoint + format param not forwarded in standalone.mjs

1 participant