Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "spiceai"
version = "3.2.0"
version = "4.0.0"
edition = "2024"
rust-version = "1.93.1"
description = "SDK for Spice.ai, an open-source runtime and platform for building AI-driven software."
Expand Down
70 changes: 70 additions & 0 deletions docs/release_notes/v4.0.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Announcing spice-rs v4.0.0 🎉

v4.0.0 adds asynchronous query jobs, dataset refresh, mutual TLS, natural-language-to-SQL (Nsql), embedding search, active-query management, and parameterized queries — and makes one breaking change: `Client::query()` now submits a query for **asynchronous** execution instead of streaming it synchronously.

## Breaking Changes

**`Client::query()` / `Client::query_with_bindings()` are now asynchronous.**

In prior releases, `query()` was a synchronous alias that streamed results directly. It now submits the query for async execution against the runtime's `/v1/queries` API and returns a `QueryJob` handle.

```rust
// Old (v3.x) — query() streamed results directly
let mut stream = client.query("SELECT * FROM taxi_trips LIMIT 10").await?;
while let Some(batch) = stream.next().await {
// ...
}

// New (v4.0.0) — use sql() for the same synchronous, streaming behavior
let mut stream = client.sql("SELECT * FROM taxi_trips LIMIT 10").await?;
while let Some(batch) = stream.next().await {
// ...
}

// New (v4.0.0) — query() now submits an async job
let job = client.query("SELECT * FROM taxi_trips LIMIT 10").await?;
let batches = job.results().await?; // waits for completion, then fetches results
```

`query_with_bindings()` follows the same pattern — use `sql_with_bindings()` for the old synchronous behavior. `sql()`, `sql_with_params()`, and `sql_with_bindings()` are otherwise unchanged from v3.x.

`QueryJob` provides: `id()`, `status()`, `info()`, `wait()`, `wait_timeout(duration)`, `results()`, `results_stream()`, and `cancel()`. `Client::get_query(id)` rehydrates a `QueryJob` handle from a previously-submitted query ID, and `Client::queries(status_filter, limit)` lists submitted jobs. Async query jobs require `http_url()` to be configured and the runtime to be running in cluster/scheduler mode.

## What's New

### Parameterized queries and dataset refresh

- `Client::sql_with_bindings()` for common scalar parameter types via `QueryParameters`, or `QueryParameter::array(...)` to bind any Arrow array type directly.
- `Client::refresh_dataset()` / `refresh_dataset_with_options()` to trigger an accelerated dataset refresh, with control over refresh SQL, mode, and jitter.
- The SDK now re-exports `arrow` as `spiceai::arrow`, so parameter and result types stay aligned with the SDK's own Arrow version.

### Mutual TLS

`ClientBuilder::tls_client_certificate_file()` and `tls_client_key_file()` (both required together) present a client certificate; `tls_ca_certificate_file()` verifies the server against a custom CA.

### Natural language to SQL (Nsql)

`Client::nsql(request)` translates a natural-language query into SQL via the runtime's configured LLM and runs it, returning the rows alongside the generated SQL. `Client::nsql_generate_sql(request)` generates the SQL without running it — inspect or edit it, or run it through `sql()` for Arrow-typed results instead of `nsql()`'s decoded JSON rows.

### Search

`Client::search(request)` finds documents similar to a piece of text via the runtime's `/v1/search` endpoint (vector, keyword, and hybrid search), for datasets with an embedding column and a loaded embedding model. Requires `http_url()` to be configured.

### Active query management

`Client::active_queries()` lists synchronous queries currently running on the runtime, and `Client::cancel_active_query(id)` cancels one — the runtime doesn't hand a query's ID back to the client that submitted it, so listing is the only way to discover the ID cancellation needs. Distinct from `QueryJob::cancel()`, which cancels an async job.

### Runtime status

`Client::runtime_status()` reports the state of each runtime connection (http, flight, metrics, opentelemetry) individually; `Client::is_ready()` remains the simple boolean check.

### Reliability fixes

- The Flight connection is now established lazily, so an HTTP-only client (one that never calls `sql()`/`query()`/`sql_with_bindings()`) no longer requires a reachable Flight endpoint at construction time.
- The configured API key is now kept only on the origin it was set for, rather than following a redirect to a different host.

### Dependency upgrades

Arrow and `arrow-flight` upgraded to 58.3 (matching DataFusion v54), `tonic` to 0.14, Rust toolchain to 1.93.1.

**Full Changelog**: https://github.com/spiceai/spice-rs/compare/v3.0.0...v4.0.0
Loading