Skip to content

feat(server): page search results, with one ceiling for both endpoints - #14

Closed
glatinone wants to merge 1 commit into
feat/scoring-patch-limitfrom
feat/search-pagination
Closed

glatinone wants to merge 1 commit into
feat/scoring-patch-limitfrom
feat/search-pagination

Conversation

@glatinone

Copy link
Copy Markdown
Owner

feat(server): page search results, with one ceiling for both endpoints

POST /memories/search returned one page and had no way to ask for the next one,
while GET /memories had just gained offset. This closes the gap and removes the
second hard-coded page ceiling that made closing it unsafe.

  • SearchRequest gained offset, and both adapters window the ranked result by
    it. The window is applied after the access filter, the same measure the
    listing endpoints use, so a page is a page of what the caller may read
    wherever it comes from - and the adapter contract suite proves both backends
    window identically.
  • MAX_PAGE_SIZE moved beside the request models. It is part of the request
    contract: SearchRequest bounded limit with a literal 100 while the listing
    routes used their own constant, so the same client could be told one ceiling by
    one endpoint and refused by the next. One number, one home, and the paging
    module imports it rather than defining a second copy.
  • The response gained has_more and echoes offset / limit. has_more is what
    returned cannot say: a short page and the final page are indistinguishable
    without it. The route asks the adapter for one cell past the page to answer it -
    the adapter has already ranked the whole candidate set before slicing, so that
    costs one comparison and no extra query.

Also fixed: a stray "total": 1 left in the search example in
docs/api-reference.md by this chain's earlier rename. It was still documenting
the count the server has never computed, in the one place a client is most likely
to copy from.

Verified against a live server: 38/38 conformance vectors, and the Node SDK's full
19 tests run against a real server rather than skipping for lack of one. Plus 241
server tests, 25 SDK tests, ruff/mypy clean, mkdocs build --strict clean.

`POST /memories/search` returned one page and had no way to ask for the next one,
while `GET /memories` had just gained `offset`. This closes the gap and removes the
second hard-coded page ceiling that made closing it unsafe.

- `SearchRequest` gained `offset`, and both adapters window the ranked result by
  it. The window is applied *after* the access filter, the same measure the
  listing endpoints use, so a page is a page of what the caller may read
  wherever it comes from - and the adapter contract suite proves both backends
  window identically.
- `MAX_PAGE_SIZE` moved beside the request models. It is part of the request
  contract: `SearchRequest` bounded `limit` with a literal `100` while the listing
  routes used their own constant, so the same client could be told one ceiling by
  one endpoint and refused by the next. One number, one home, and the paging
  module imports it rather than defining a second copy.
- The response gained `has_more` and echoes `offset` / `limit`. `has_more` is what
  `returned` cannot say: a short page and the final page are indistinguishable
  without it. The route asks the adapter for one cell past the page to answer it -
  the adapter has already ranked the whole candidate set before slicing, so that
  costs one comparison and no extra query.

Also fixed: a stray `"total": 1` left in the search example in
`docs/api-reference.md` by this chain's earlier rename. It was still documenting
the count the server has never computed, in the one place a client is most likely
to copy from.

Verified against a live server: 38/38 conformance vectors, and the Node SDK's full
19 tests run against a real server rather than skipping for lack of one. Plus 241
server tests, 25 SDK tests, ruff/mypy clean, `mkdocs build --strict` clean.
@glatinone

Copy link
Copy Markdown
Owner Author

Landed on master in the v0.1.0 chain: the branch was fast-forward merged as part of b940905..92b88ee and released as v0.1.0. Closing so the open list matches reality - the commits are in master, and the tag points at them.

@glatinone glatinone closed this Oct 4, 2026
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.

1 participant