Repository navigation
fix(memory): persist tool executions on every memory backend - #1285
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
🚧 Files skipped from review as they are similar to previous changes (5)
📝 WalkthroughWalkthroughThe change adds optional tool execution storage to conversation memory backends. The in-memory manager persists ordered tool calls and results. NeuroLink uses capability detection. A continuous test suite validates storage behavior. ChangesTool execution storage parity
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant NeuroLink
participant MemoryBackend
participant ConversationSession
NeuroLink->>MemoryBackend: storeToolExecution(sessionId, toolCalls, toolResults)
MemoryBackend->>ConversationSession: persist tool-call messages
MemoryBackend->>ConversationSession: persist tool-result messages
MemoryBackend-->>NeuroLink: complete or report failure
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ 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 |
|
Not mergeable yet, and I want to flag why the checks look the way they do, because the picture is misleading. Base is not
|
| workflow | pull_request: branches: |
|---|---|
ci.yml (test (20), build-check, lint, format) |
[release] |
yama-review.yml |
[release] |
copilot-review.yml |
[release, main] |
So on this PR nothing has been built, no tests have run, and neither AI reviewer has looked at it. Only CodeRabbit, SentinelOne and the push-triggered commit check fire. The absence of review comments here reflects the absence of a review, not a clean bill of health.
Across #1281, #1282, #1283, #1285, #1286 and #1287 that is roughly 3,900 added lines that have never been compiled or tested by CI.
Nothing to do on this PR specifically — it resolves itself once the parents land and the base becomes release. Worth knowing before anyone reads the green ticks as coverage. If you want real signal sooner, temporarily retargeting to release (or adding the stack branches to ci.yml's filter) would run the full gate.
70aa9e0 to
8539e1e
Compare
b54e066 to
5095706
Compare
8539e1e to
b7b0d18
Compare
5095706 to
23a6d4f
Compare
|
@murdore — confirmed both points, verified rather than taken on trust. Single Commit failure is a stacking artifact. Nothing to squash. It clears itself as parents land. The CI gap is real and I am not treating the green ticks as coverage. Verified the gating you listed:
So on this PR nothing has been built or tested by CI, and that is the accurate reading. What has run, locally on the stack tip (so every branch's code compiled together) after the latest rebase:
That is local signal, not CI signal, and I would rather say so plainly than let the tick count imply otherwise. Merging bottom-up closes the gap for real: each PR's base becomes |
b7b0d18 to
2343787
Compare
23a6d4f to
936d6a6
Compare
|
#1280 is merged ( #1281 was One real conflict, in The build was broken, and
|
| branch | build |
|---|---|
fix/token-accounting |
✅ |
fix/cache-aware-compaction |
✅ |
fix/loop-guard-parity |
✅ |
fix/session-persistence |
✅ |
fix/redis-append-only |
✅ |
fix/loop-guard-completion |
✅ |
On the tip: pnpm run check → 4939 files, 0 errors; pnpm run lint → 0 errors, 48 warnings, all pre-existing max-lines-per-function in files this stack does not touch (claudeProxyRoutes.ts, toolRoutes.ts, csvProcessor.ts); all nine suites → 95 tests, 0 failures, 0 skips.
Still local signal, not CI signal — except on #1281, which now targets release and is running the full gate.
2343787 to
451fe2b
Compare
936d6a6 to
ca47f28
Compare
|
#1281 is merged ( Rebase — one commit each, no conflicts: #1282 was Verification — each branch independently, not just the tip:
67 tests, 0 failures, 0 skips. Review comments: no unresolved inline findings on this PR. The only review activity to date is CodeRabbit's auto-generated walkthrough and @murdore's note about the check count, which is answered above — that gap closes as each PR's base becomes |
451fe2b to
6659c02
Compare
ca47f28 to
df82fe3
Compare
6659c02 to
90d393c
Compare
df82fe3 to
31edd8e
Compare
|
Re-cascaded onto the amended #1283. #1283 was amended to carry three CodeRabbit findings (batch splitting at the protected-tail boundary, byte-vs- Rebase fidelity — Verified after the rebase: No review comments to resolve. CodeRabbit posted "Review skipped — auto reviews are disabled on base/target branches other than the default branch", so the absence of findings here is absence of review, not approval. It will review for real once the base becomes
|
31edd8e to
7a65b20
Compare
|
#1283 merged ( GitHub auto-retargeted this PR to
Content is unchanged by the rebase: Verified at the rebased tree: Now that the base is |
✅ Single Commit Policy - COMPLIANTStatus: Policy requirements met • 1 commit • Valid format • Ready for merge 📊 View validation details📝 Commit Details
✅ Validation Results
🤖 Automated validation by NeuroLink Single Commit Enforcement |
🤖 AI Review & Build Compliance ✅Status: AI analysis complete • Build rules validated • Ready for review 📊 View detailed analysis results🛡️ Analysis Complete
📋 Ready for Merge When
🤖 AI analysis complete - check individual code comments for specific feedback |
Review Summary for PR #1285: Tool Storage Parity FixDecision: ✅ APPROVEDThis PR fixes a critical parity issue where tool execution was only persisted on Redis storage backend, causing different history shapes depending on Findings SummaryNo issues found. This is a straightforward correctness fix with comprehensive test coverage. Changes Overview
Impact Analysis
Quality Assessment✅ TypeScript types properly defined ConclusionThis is a solid, well-tested parity fix that brings in-memory storage up to Redis storage's contract. All downstream paths that reason about tool batches (compaction, pruning, pair repair) will now see consistent history regardless of Recommendation: APPROVE and merge |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
test/continuous-test-suite-tool-storage-parity.ts (1)
157-174: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winVerify ID-to-result mapping for parallel batches.
This test only checks role ordering and equal call/result counts. It passes if parallel results use swapped
toolCallIdvalues or tool names. Assert that eachtool_resulthas the expectedtoolCallIdand resolved tool name.🤖 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 `@test/continuous-test-suite-tool-storage-parity.ts` around lines 157 - 174, Extend the parallel-batch test around storeBatch and repairToolPairs to validate each tool_result’s toolCallId and resolved tool name, not just counts and roles. Assert that t1, t2, and t3 retain their corresponding read_file, grep, and ls mappings after repair, while preserving the existing healthy-batch assertions.
🤖 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.
Nitpick comments:
In `@test/continuous-test-suite-tool-storage-parity.ts`:
- Around line 157-174: Extend the parallel-batch test around storeBatch and
repairToolPairs to validate each tool_result’s toolCallId and resolved tool
name, not just counts and roles. Assert that t1, t2, and t3 retain their
corresponding read_file, grep, and ls mappings after repair, while preserving
the existing healthy-batch assertions.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: e6de29c7-d18c-4c15-b472-36b3c187efec
📒 Files selected for processing (5)
package.jsonsrc/lib/core/conversationMemoryManager.tssrc/lib/neurolink.tssrc/lib/types/conversationMemoryInterface.tstest/continuous-test-suite-tool-storage-parity.ts
7a65b20 to
5825991
Compare
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
|
CodeRabbit's nitpick is resolved — it was a real gap, not just style. The finding. The parallel-batch test asserted role ordering and equal call/result counts only, so it would have passed with two parallel results holding each other's The fix. A/B-verified against the real defect class, not just re-run. Patching the in-memory Amended into the single commit —
|
🤖 AI Review & Build Compliance ✅Status: AI analysis complete • Build rules validated • Ready for review 📊 View detailed analysis results🛡️ Analysis Complete
📋 Ready for Merge When
🤖 AI analysis complete - check individual code comments for specific feedback |
|
🎉 This PR is included in version 10.10.6 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Description
storeToolExecutionexisted only onRedisConversationMemoryManager, andNeuroLink.storeToolExecutionsreached it with a cast:isToolExecutionStorageAvailable()compounded it, requiringSTORAGE_TYPE === "redis"and a class-name match. So on in-memory storage tool activity never becametool_call/tool_resultmessages at all.That left two divergent history shapes. Everything downstream that reasons about tool batches — compaction, tool-output pruning, and the id-based pair repair from #1280 — behaved differently depending on
STORAGE_TYPE, and the in-memory shape was the barely-exercised one.Type of Change
Changes
storeToolExecutiondeclared onIConversationMemoryManager(optional, so third-party backends stay valid)ConversationMemoryManager, mirroring the Redis contract exactly: calls written before results,toolCallIdcarried on both sides sorepairToolPairscan match by id rather than adjacency, tool name resolved onto the result via that id, non-string output serialized with a guarded fallback,result.success/result.errorrecordedisToolExecutionStorageAvailable()is capability-based rather than Redis-specificTesting
pnpm run test:tool-storage-parity— 10/10, no Redis required. Covers the contract, batch ordering, id propagation, serialization and error recording, session creation, empty batches, appending onto an existing turn, and a parallel batch round-tripping throughrepairToolPairsuntouched.Verified to fail loudly (
✗, exit 1) on a deliberately broken assertion, per the CLAUDE.md hazard whereisExpectedProviderError()can downgrade a real failure to⊘.Regressions, all green:
test:tool-pairing15/15,test:token-accounting10/10,test:step-guard6/6,test:loop-guard-core11/11,test:openai-compat-guard9/9,test:anthropic-guard10/10.tsc --noEmit --strict0 errors,eslint0 errors, prettier clean.Scope: append-only Redis storage is NOT in this PR
The planned O(n²) fix for
storeConversationTurnis deliberately excluded. I measured it against local Redis first:So the problem is real but only at multi-MB scale — which is the agentic tool-output profile, so it is worth fixing.
I built the split-storage design (
{key}:msgsLIST + small metadata blob, with a marker so legacy blobs are read as-is and converted on next write) and then reverted it, because implementing it surfaced a hazard the plan had not accounted for:getStats()andlistAllSessions()scan keys by prefix andGETeach one. New:msgsLIST keys live under that same prefix, so those scans would hitWRONGTYPE. The code already special-cases:sessionskeys, which shows this collision class is a known trap in this file.Combined with 12 varied read sites, two-key TTL, and
clearSessionneeding to delete both keys, it is a larger and more delicate change than one PR should absorb alongside this one. A half-migrated storage layer would make split-written sessions read as empty on unrouted paths — strictly worse than not starting. It deserves its own focused PR with a real-Redis test suite.Top of the stack: #1280 → #1281 → #1282 → #1283 → this.
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Tests