feat: add Search for the runtime's /v1/search endpoint - #79
Conversation
Adds SpiceClient.Search, exposing vector, keyword, and hybrid search from Go. Previously only spice.js could reach /v1/search; users of every other SDK had to hand-roll the HTTP call. Response types are modelled on the runtime's actual wire shape: Matches holds a slice per column because one column can contribute several chunks to a match, and data / primary_key / metadata are omitted by the runtime when empty. Errors carry the runtime's plain-text explanation alongside the status code, and arguments the runtime would reject with a 400 are validated before the request so the error names the field to fix. The new tests need no live runtime, so they join the runtime-free unit test allowlist the Windows CI job runs.
There was a problem hiding this comment.
🟡 Not ready to approve
Response map fields documented as decoding to empty maps will currently decode as nil when omitted, which can violate the intended API contract and surprise callers.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.
Pull request overview
Adds first-class Go SDK support for the Spice runtime /v1/search endpoint by introducing a typed SpiceClient.Search API, along with runtime-free unit tests and accompanying documentation/CI updates to keep capabilities aligned across SDKs.
Changes:
- Introduces
SearchRequest,SearchResponse, andSearchMatchtypes plusSpiceClient.Search(ctx, req)to callPOST /v1/search. - Adds
httptest-based unit tests covering request encoding, routing/method, response decoding, validation, and error surfacing. - Documents
Searchusage in the README and updates the Windows unit-test allowlist to includeTestSearch.
File summaries
| File | Description |
|---|---|
| search.go | Implements the SpiceClient.Search method and associated request/response types for /v1/search. |
| search_test.go | Adds runtime-free tests for request/response behavior and error/validation handling. |
| README.md | Documents how to use Search and explains key request/response fields. |
| .github/workflows/go.yml | Extends the Windows-native unit test allowlist to run TestSearch. |
Review details
- Files reviewed: 4/4 changed files
- Comments generated: 2
- Review effort level: Lite
We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.
The runtime omits primary_key, data and metadata from a match that has none, so json.Unmarshal leaves those maps nil. The doc comments said "Empty", which reads as an allocated empty map and hides that assigning into one panics. Say nil explicitly and assert it in the test: len == 0 also passes for an allocated empty map, so it did not pin down what a caller receives.
What
Adds
SpiceClient.Search(ctx, *SearchRequest), wrapping the runtime's/v1/searchendpoint — vector similarity search, with optionalKeywordsfor a hybrid lexical + vector ranking.Why
/v1/searchworks on a defaultspice run, but of the six client SDKs only spice.js could reach it. Go users had to hand-roll the HTTP call, including the response shape.Part of aligning capabilities across the SDKs against the runtime's own API surface.
Two details the response types encode, taken from the runtime's wire format rather than the OpenAPI example (which is out of date on the first point):
Matchesholds a slice of values per column — one column can contribute several chunks to a single match.data,primary_key, andmetadataare omitted by the runtime when empty, so each decodes to an empty map rather than being required.Errors follow the pattern in
datasets.gobut also read the response body: the runtime explains search failures in plain text ("No data sources provided"), which a status code alone loses. Arguments the runtime would reject with a 400 — empty text, aLimitbelow 1 — are checked before the request so the error names the field to fix. An emptyDatasetsslice is omitted rather than sent, since the runtime 400s on an empty list.Verification
go build ./...go vet ./...gofmt -l .— cleango test -run TestSearch ./...— 11 tests pass (6 top-level, 7 subtests), driven byhttptestso they need no live runtimego test ./...— not run; the rest of the suite requires a live runtime (spice run) and a cloud API keyThe new tests are runtime-free, so
TestSearchis added to the-runallowlist the Windows-native unit test job uses. They also run in the full post-install suite on the other platforms.