fix(api): sort /memories newest-first before pagination#995
Conversation
GET /agentmemory/memories returned rows in kv.list insertion order (oldest first) and sliced the head, so ?latest=true&limit=N served the N OLDEST memories and the viewer showed stale data once the corpus exceeded the limit. Sort the filtered list newest-first (createdAt desc, fallback updatedAt) before the offset/limit slice, mirroring the viewer-side sort already applied for the Memories tab (rohitg00#674/rohitg00#701).
|
@costajohnt is attempting to deploy a commit to the rohitg00's projects Team on Vercel. A member of the Team first needs to authorize it. |
📝 WalkthroughWalkthroughThe Memories sort fix and regression test
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related issues
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 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 |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@test/memories-latest-sort-order.test.ts`:
- Around line 35-38: The test in memories-latest-sort-order.test.ts only checks
for localeCompare usage, so it can still pass if the comparator direction is
reversed. Update the assertion around the sort comparator in the relevant test
to explicitly verify newest-first ordering by checking for
bKey.localeCompare(aKey) in the comparator logic, or by asserting the comparator
result on sample timestamps through the handler used in the test. This should be
anchored to the existing handler and sort-order expectations so the regression
lock targets the comparator direction itself.
🪄 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: 77175019-a174-4848-b912-098580a189ec
📒 Files selected for processing (2)
src/triggers/api.tstest/memories-latest-sort-order.test.ts
| it("sorts on createdAt desc with updatedAt fallback (matches the #701 viewer fix)", () => { | ||
| expect(handler).toMatch(/a\.createdAt \|\| a\.updatedAt/); | ||
| expect(handler).toMatch(/b\.createdAt \|\| b\.updatedAt/); | ||
| expect(handler).toMatch(/localeCompare/); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Assert the comparator direction explicitly.
This still passes if the implementation flips to aKey.localeCompare(bKey), which would reintroduce oldest-first ordering. Check for bKey.localeCompare(aKey) (or evaluate the comparator on sample timestamps) so the regression actually locks newest-first behavior.
Suggested tightening
it("sorts on createdAt desc with updatedAt fallback (matches the `#701` viewer fix)", () => {
expect(handler).toMatch(/a\.createdAt \|\| a\.updatedAt/);
expect(handler).toMatch(/b\.createdAt \|\| b\.updatedAt/);
- expect(handler).toMatch(/localeCompare/);
+ expect(handler).toMatch(/bKey\.localeCompare\(aKey\)/);
});📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| it("sorts on createdAt desc with updatedAt fallback (matches the #701 viewer fix)", () => { | |
| expect(handler).toMatch(/a\.createdAt \|\| a\.updatedAt/); | |
| expect(handler).toMatch(/b\.createdAt \|\| b\.updatedAt/); | |
| expect(handler).toMatch(/localeCompare/); | |
| it("sorts on createdAt desc with updatedAt fallback (matches the `#701` viewer fix)", () => { | |
| expect(handler).toMatch(/a\.createdAt \|\| a\.updatedAt/); | |
| expect(handler).toMatch(/b\.createdAt \|\| b\.updatedAt/); | |
| expect(handler).toMatch(/bKey\.localeCompare\(aKey\)/); |
🤖 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/memories-latest-sort-order.test.ts` around lines 35 - 38, The test in
memories-latest-sort-order.test.ts only checks for localeCompare usage, so it
can still pass if the comparator direction is reversed. Update the assertion
around the sort comparator in the relevant test to explicitly verify
newest-first ordering by checking for bKey.localeCompare(aKey) in the comparator
logic, or by asserting the comparator result on sample timestamps through the
handler used in the test. This should be anchored to the existing handler and
sort-order expectations so the regression lock targets the comparator direction
itself.
What
Fixes #990.
GET /agentmemory/memories?latest=true&limit=Nreturned the N oldest "latest" memories, so the viewer showed stale data once the corpus exceeded the limit.Root cause
The
api::memorieshandler (src/triggers/api.ts) builds its list fromkv.list(KV.memories)— insertion order, oldest first — filters byisLatest/agentId, then slicesoffset..offset+limit. There's no sort, so the slice takes the head (oldest).Fix
Sort the filtered list newest-first (
createdAtdesc, fallbackupdatedAt) before the slice, using the same key/localeComparepattern as the merged viewer-side fix for the Memories tab (#674/#701) — making the server endpoint consistent with what the viewer already does client-side.Test
test/memories-latest-sort-order.test.tsasserts the handler sorts on the agreed keys and that the sort runs before the slice (slicing an unsorted list is the bug), matching the source-assertion style of the existingapi::memoriespagination tests. Full vitest suite passes.Summary by CodeRabbit
Bug Fixes
Tests