Skip to content

feat: add Search for the runtime's /v1/search endpoint - #79

Merged
lukekim merged 2 commits into
spiceai:trunkfrom
claudespice:feat/search
Aug 1, 2026
Merged

feat: add Search for the runtime's /v1/search endpoint#79
lukekim merged 2 commits into
spiceai:trunkfrom
claudespice:feat/search

Conversation

@claudespice

Copy link
Copy Markdown
Contributor

What

Adds SpiceClient.Search(ctx, *SearchRequest), wrapping the runtime's /v1/search endpoint — vector similarity search, with optional Keywords for a hybrid lexical + vector ranking.

limit := 3
resp, err := spice.Search(ctx, &gospice.SearchRequest{
    Text:              "tokyo plane tickets",
    Datasets:          []string{"app_messages"},
    Limit:             &limit,
    AdditionalColumns: []string{"timestamp"},
})

Why

/v1/search works on a default spice 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):

  • Matches holds a slice of values per column — one column can contribute several chunks to a single match.
  • data, primary_key, and metadata are omitted by the runtime when empty, so each decodes to an empty map rather than being required.

Errors follow the pattern in datasets.go but 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, a Limit below 1 — are checked before the request so the error names the field to fix. An empty Datasets slice is omitted rather than sent, since the runtime 400s on an empty list.

Verification

  • go build ./...
  • go vet ./...
  • gofmt -l . — clean
  • go test -run TestSearch ./... — 11 tests pass (6 top-level, 7 subtests), driven by httptest so they need no live runtime
  • Full go test ./... — not run; the rest of the suite requires a live runtime (spice run) and a cloud API key

The new tests are runtime-free, so TestSearch is added to the -run allowlist the Windows-native unit test job uses. They also run in the full post-install suite on the other platforms.

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.
@lukekim
lukekim requested review from Jeadie and Copilot August 1, 2026 20:45
@lukekim lukekim self-assigned this Aug 1, 2026
@lukekim lukekim added the enhancement New feature or request label Aug 1, 2026
@lukekim lukekim added this to the v8.0.0 milestone Aug 1, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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, and SearchMatch types plus SpiceClient.Search(ctx, req) to call POST /v1/search.
  • Adds httptest-based unit tests covering request encoding, routing/method, response decoding, validation, and error surfacing.
  • Documents Search usage in the README and updates the Windows unit-test allowlist to include TestSearch.
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.

Comment thread search.go
Comment thread search_test.go Outdated
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.
@lukekim
lukekim merged commit 096e89c into spiceai:trunk Aug 1, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants