Repository navigation
fix(openclaw): follow list cursors and look up memories by ID - #274
loveRhythm1990 merged 3 commits into
Conversation
GET /v1/memories clamps each page to 500 rows and returns next_cursor when
more exist, but the API transport dropped the cursor and the client inferred
completeness from items.length >= requested limit. A 1000-row request
therefore returned 500 rows with partial:false, and getMemory reported IDs
beyond the first page as missing.
- MemoriaHttpTransport.list follows next_cursor up to maxListPages and
returns has_more, stopping on a non-advancing cursor.
- listMemories derives partial from has_more.
- getMemory calls GET /v1/memories/{id} instead of scanning the list, so a
null result means the API reported the memory absent.
Fixes matrixorigin#267
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Reviewed head 8988b4e. The pagination and direct-ID lookup fit #267. I did not identify a blocking issue in this static review. Three non-blocking suggestions:
I have not run the tests or reproduced these against a live service. — dot (AI-assisted review; static analysis only) |
ReviewThe issue is valid. The change looks correct.
Minor / optional
LGTM after (1). The other items are optional. |
Address review on matrixorigin#274: - Stop before appending a page whose next_cursor repeats the request cursor, so a misbehaving server cannot double-count rows; the leftover cursor still marks the result partial. - getMemory returns null unless the payload is the requested memory, so an empty-body response is never cached under a bogus ID. - Update memory_get and maxListPages descriptions in index.ts, config.ts, openclaw.plugin.json and README to match the direct ID lookup. - Route the test server explicitly (snapshots, branches, unexpected paths) and assert snapshot/branch counts and de-duplicated IDs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Follow-up: review items addressed in
|
| Item | Status |
|---|---|
| dot #1: repeated cursor double-counts a page | Fixed. The check now runs before appending, so a page whose next_cursor equals the request cursor is dropped and has_more stays true. The stalled-cursor test now also checks the returned IDs and count (1). |
dot #2 / my #4: stale memory_get and maxListPages descriptions |
Fixed in index.ts, config.ts, openclaw.plugin.json and the README. The setting is now described as the per-call page limit (≤500 rows per page) that also bounds stats and client-side type filtering. |
| dot #3: test server routes every non-ID path to the memory list | Fixed. The handler now serves /v1/snapshots and /v1/branches with their real response shapes and throws on any other path. The stats test checks snapshotCount = 0 and branchCount = 1. |
my #1: empty-body { ok: true } cached as a memory |
Fixed. getMemory returns null unless memory_id matches the requested ID. A regression test checks that nothing is cached. |
| my #2: master-key cross-user lookup | Not changed. The plugin's userId is an OpenClaw identity, not the API key owner's ID, so the client has nothing reliable to compare against. The plugin is designed for user-scoped sk- keys. |
my #3: push memory_type filtering to the server |
Deferred. This is independent of #267 and better as a follow-up PR. |
npm test: 119/119 pass. npm run test:pack passes. CI Unit Tests, Check & Clippy and test are green, and DB Tests are pending.
Fixes #267
Problem
GET /v1/memorieslimits each page to 500 rows and returnsnext_cursorwhen more rows exist. In API mode, the OpenClaw plugin dropped that cursor:MemoriaHttpTransport.listserialized onlyitemsand never requested a second page.MemoriaClient.listMemoriessetpartialfromitems.length >= scanLimit. When the requested limit was above 500, a truncated page looked complete. A request for 1000 rows came back with 500 rows andpartial: false.getMemorysearched that same truncated first page, so it returnednullfor any uncached ID that sat beyond the first 500 rows.statsbuilt on the same list, soactiveMemoryCountstopped at 500.Fix
http-client.ts:listfollowsnext_cursor. Each page asks for at most 500 rows, and the loop runs until it haslimitrows, the server returns no cursor, or it reachesmaxListPages. Until now that setting only multiplied the scan size. The method returns{ items, has_more }. It also stops if the cursor does not advance or a page comes back empty; any cursor left over still setshas_more.http-client.ts: a newmemory_getdispatch calls the existingGET /v1/memories/{id}endpoint. Like the list, that endpoint returns only active memories.client.ts:listMemoriessetspartialfromhas_more, and only falls back to the length check whenhas_moreis missing.getMemoryusesmemory_getinstead of scanning the list. It returnsnullonly when the API says the memory is absent. API errors now propagate, so they no longer read as "missing".Tests
New file
__tests__/list-pagination.test.ts(12 tests). Its fetch mock emulates the server's keyset pagination with the 500-row limit. It covers:maxListPageslimitstatscounting past the first pagegetMemoryon a later page, a not-found ID, an error response, and the cache pathhelpers.tsgainsrespondWithHandlerso a test can serve different responses depending on the URL.npm test: 118/118 pass.client.tsandhttp-client.ts, 7 of the 12 new tests fail.npm run test:packpasses.🤖 Generated with Claude Code