Conversation
…#254) Hermes stores handle_tool_call's return value as the tool result `content` field in the session history. Anthropic-protocol LLM providers reject non-string content on the next request with: Failed to deserialize the JSON body into the target type: messages[N]: content should be a string or a list at line 1 column XXXXX Once triggered, every subsequent request in that session 400s until the session JSON is manually cleaned. The plugin's handle_tool_call returned raw Python dicts in all 4 paths (memory_recall, memory_save, memory_search, unknown-tool fallback). Wrap each return in json.dumps so the result is always a string. This matches the contract that agentmemory's own MCP server already honors in src/mcp/standalone.ts: { type: "text", text: JSON.stringify(payload, null, ...) } Tightens the return-type annotation on both the abstract base and the concrete class from Any -> str so mypy / type checkers catch any future regression. Reported by @KyoMio with full Anthropic-protocol repro.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe PR updates the ChangesTool Result String Serialization
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
Bug-fix patch focused on search recall correctness and plugin compatibility. Pins iii-engine to v0.11.2 because v0.11.6 introduces a new sandbox-everything-via-`iii worker add` model that agentmemory hasn't been refactored for yet — pin lifts once that refactor lands. Adds a hard guard against silent vector-index corruption, fixes BM25 indexing for memories saved via memory_save, and lands four Hermes plugin fixes. Per AGENTS.md release checklist: - package.json version 0.9.4 -> 0.9.5 - src/version.ts VERSION constant - src/types.ts ExportData version union - src/functions/export-import.ts supportedVersions Set - test/export-import.test.ts assertion - plugin/.claude-plugin/plugin.json version - CHANGELOG.md detailed entries with contributor shoutouts Headlines (full detail in CHANGELOG): Fixed: - BM25 search now indexes memories saved via memory_save (#258, #257) Thanks @Nizar-BenHamida for the precise repro. - Embedding providers no longer silently corrupt the vector index when an API returns wrong-dimension vectors (#248, #247, #256) Thanks @AmmarSaleh50 for issue + fix + tests. - Hermes handle_tool_call returns JSON strings, not raw dicts (#255, #254) Thanks @KyoMio for the Anthropic-protocol repro. - Hermes status reflects real service state on systemd installs (#253, #250) Thanks @OptionalCoin for tracing it to env-source divergence. - Hermes hooks accept passthrough kwargs (#252, #249) Thanks @OptionalCoin again for the log analysis. - agentmemory demo now seeds observations correctly (#251, #229) Thanks @seishonagon for root-cause analysis. - LLM compression / summarization timeouts increased (#213) Thanks @xuli500177. - Pi / OpenClaw / Hermes integration plugin fixes (#230) Thanks @deepmroot. Changed: - iii-engine pinned to v0.11.2 across every install path (#260). v0.11.6 introduces a new `iii worker add` sandbox model that agentmemory still pre-dates; pin lifts when we refactor agentmemory to register as a sandboxed worker. Override with AGENTMEMORY_III_VERSION=<version> for users who've migrated manually. - README documents iii worker add extension surface (#242). - README iii Console install/launch commands corrected (#243). Validated: 852/852 tests pass, npm run build clean.
Bug-fix patch focused on search recall correctness and plugin compatibility. Pins iii-engine to v0.11.2 because v0.11.6 introduces a new sandbox-everything-via-`iii worker add` model that agentmemory hasn't been refactored for yet — pin lifts once that refactor lands. Adds a hard guard against silent vector-index corruption, fixes BM25 indexing for memories saved via memory_save, and lands four Hermes plugin fixes. Per AGENTS.md release checklist: - package.json version 0.9.4 -> 0.9.5 - src/version.ts VERSION constant - src/types.ts ExportData version union - src/functions/export-import.ts supportedVersions Set - test/export-import.test.ts assertion - plugin/.claude-plugin/plugin.json version - CHANGELOG.md detailed entries with contributor shoutouts Headlines (full detail in CHANGELOG): Fixed: - BM25 search now indexes memories saved via memory_save (#258, #257) Thanks @Nizar-BenHamida for the precise repro. - Embedding providers no longer silently corrupt the vector index when an API returns wrong-dimension vectors (#248, #247, #256) Thanks @AmmarSaleh50 for issue + fix + tests. - Hermes handle_tool_call returns JSON strings, not raw dicts (#255, #254) Thanks @KyoMio for the Anthropic-protocol repro. - Hermes status reflects real service state on systemd installs (#253, #250) Thanks @OptionalCoin for tracing it to env-source divergence. - Hermes hooks accept passthrough kwargs (#252, #249) Thanks @OptionalCoin again for the log analysis. - agentmemory demo now seeds observations correctly (#251, #229) Thanks @seishonagon for root-cause analysis. - LLM compression / summarization timeouts increased (#213) Thanks @xuli500177. - Pi / OpenClaw / Hermes integration plugin fixes (#230) Thanks @deepmroot. Changed: - iii-engine pinned to v0.11.2 across every install path (#260). v0.11.6 introduces a new `iii worker add` sandbox model that agentmemory still pre-dates; pin lifts when we refactor agentmemory to register as a sandboxed worker. Override with AGENTMEMORY_III_VERSION=<version> for users who've migrated manually. - README documents iii worker add extension surface (#242). - README iii Console install/launch commands corrected (#243). Validated: 852/852 tests pass, npm run build clean.
Bug-fix patch focused on search recall correctness and plugin compatibility. Pins iii-engine to v0.11.2 because v0.11.6 introduces a new sandbox-everything-via-`iii worker add` model that agentmemory hasn't been refactored for yet — pin lifts once that refactor lands. Adds a hard guard against silent vector-index corruption, fixes BM25 indexing for memories saved via memory_save, and lands four Hermes plugin fixes. Per AGENTS.md release checklist: - package.json version 0.9.4 -> 0.9.5 - src/version.ts VERSION constant - src/types.ts ExportData version union - src/functions/export-import.ts supportedVersions Set - test/export-import.test.ts assertion - plugin/.claude-plugin/plugin.json version - CHANGELOG.md detailed entries with contributor shoutouts Headlines (full detail in CHANGELOG): Fixed: - BM25 search now indexes memories saved via memory_save (#258, #257) Thanks @Nizar-BenHamida for the precise repro. - Embedding providers no longer silently corrupt the vector index when an API returns wrong-dimension vectors (#248, #247, #256) Thanks @AmmarSaleh50 for issue + fix + tests. - Hermes handle_tool_call returns JSON strings, not raw dicts (#255, #254) Thanks @KyoMio for the Anthropic-protocol repro. - Hermes status reflects real service state on systemd installs (#253, #250) Thanks @OptionalCoin for tracing it to env-source divergence. - Hermes hooks accept passthrough kwargs (#252, #249) Thanks @OptionalCoin again for the log analysis. - agentmemory demo now seeds observations correctly (#251, #229) Thanks @seishonagon for root-cause analysis. - LLM compression / summarization timeouts increased (#213) Thanks @xuli500177. - Pi / OpenClaw / Hermes integration plugin fixes (#230) Thanks @deepmroot. Changed: - iii-engine pinned to v0.11.2 across every install path (#260). v0.11.6 introduces a new `iii worker add` sandbox model that agentmemory still pre-dates; pin lifts when we refactor agentmemory to register as a sandboxed worker. Override with AGENTMEMORY_III_VERSION=<version> for users who've migrated manually. - README documents iii worker add extension surface (#242). - README iii Console install/launch commands corrected (#243). Validated: 852/852 tests pass, npm run build clean.
Closes #254.
What
Hermes stores
handle_tool_call's return value verbatim as the tool resultcontentin the session history. When Hermes is configured with an Anthropic-protocol LLM backend (provider: anthropic, plus any Anthropic-compatible proxy), the API rejects non-stringcontentwith a 400 on the next request:Once that happens, every subsequent request in the affected session 400s until the session JSON is hand-cleaned — a real cliff.
Fix
Wrap all four return paths in
json.dumps:memory_recall(empty + populated branches)memory_savememory_search(empty + populated branches)Tighten the return-type annotation on both the abstract base and the concrete class from
Any→strso a future regression surfaces at type-check time.Why this is the right contract
agentmemory's own MCP server already returns JSON strings — see
src/mcp/standalone.ts:The Hermes integration is the outlier here, not the rule. After this PR, every agentmemory tool surface (REST, MCP, OpenClaw plugin, OpenCode plugin once #237 lands, Hermes plugin) hands back a string.
Test plan
handle_tool_callpath returns astrthat round-trips throughjson.loads.src/mcp/standalone.ts) so the Hermes plugin is now consistent with native MCP behavior.memory_recallin a Hermes session withprovider: anthropic, continue conversation past the tool turn, no 400.Credit to @KyoMio for the precise root-cause analysis (4 dict returns flagged with before/after diffs) and the Anthropic-protocol-specific repro that pinpointed why the bug is invisible on OpenAI-protocol backends.
Note re: KyoMio's secondary point about
session_idin hook signaturesKyoMio also flagged that
prefetch/queue_prefetch/sync_turnwere missing*, session_id: str = ""for gateway multi-session contexts. That's already addressed by #252 (merged this morning) which added**kwargs: Anyto all those hooks pluson_session_end/on_pre_compress/on_memory_write/shutdown.**kwargsis a strict superset of the keyword-onlysession_idproposal — accepts that key plus any other future Hermes-passed context kwargs without further patches.Summary by CodeRabbit