sqlrite-ask — natural-language → SQL adapter for SQLRite.
Phase 7g.1 (foundational). One sync call:
use sqlrite::Connection;
use sqlrite_ask::{ask, AskConfig};
let conn = Connection::open("foo.sqlrite")?;
let config = AskConfig::from_env()?; // reads SQLRITE_LLM_API_KEY etc.
let response = ask(&conn, "How many users are over 30?", &config)?;
println!("Generated SQL: {}", response.sql);
println!("Why: {}", response.explanation);
# Ok::<(), sqlrite_ask::AskError>(())
What this crate is
- Reflects the schema of an open
Connectioninto CREATE TABLE text the LLM can ground on. - Wraps that schema in a stable system prompt with an
cache_control: ephemeralbreakpoint so the schema dump is served from Anthropic's prompt cache after the first call. - Sends one HTTP POST to the LLM provider per
ask()call. - Parses the response into
AskResponse { sql, explanation }.
What this crate is NOT
- Not an executor. The library deliberately does not run the
generated SQL — the caller decides whether to execute it. SDK
layers (
Python.Connection.ask_run,Node.db.askRun, etc.) add a one-shot generate-and-execute helper for the common case, but the default API is "generate, return, let me decide". - Not multi-turn. Stateless — every call is a fresh prompt.
- Not multi-provider yet. Anthropic-first per Phase 7 plan
Q4. OpenAI + Ollama follow-ups slot into [
provider] without changing the public surface.
Configuration
[AskConfig] resolves in this priority order:
- Explicit values you set on the struct (
AskConfig { api_key: Some(...), .. }) - Environment variables (
SQLRITE_LLM_*) - Built-in defaults (model =
claude-sonnet-4-6, max_tokens = 1024, cache TTL = 5 min)