sqlrite 0.1.23__tar.gz → 0.1.24__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sqlrite-0.1.23 → sqlrite-0.1.24}/Cargo.lock +6 -6
- {sqlrite-0.1.23 → sqlrite-0.1.24}/Cargo.toml +1 -1
- {sqlrite-0.1.23 → sqlrite-0.1.24}/PKG-INFO +1 -1
- {sqlrite-0.1.23 → sqlrite-0.1.24}/desktop/package.json +1 -1
- {sqlrite-0.1.23 → sqlrite-0.1.24}/docs/phase-7-plan.md +1 -1
- {sqlrite-0.1.23 → sqlrite-0.1.24}/docs/roadmap.md +1 -1
- {sqlrite-0.1.23 → sqlrite-0.1.24}/pyproject.toml +1 -1
- {sqlrite-0.1.23 → sqlrite-0.1.24}/sdk/python/Cargo.toml +1 -1
- {sqlrite-0.1.23 → sqlrite-0.1.24}/sqlrite-ask/Cargo.toml +23 -2
- {sqlrite-0.1.23 → sqlrite-0.1.24}/sqlrite-ask/src/lib.rs +22 -4
- {sqlrite-0.1.23 → sqlrite-0.1.24}/sqlrite-ask/src/provider/mod.rs +6 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/ask/mod.rs +21 -3
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/lib.rs +8 -1
- {sqlrite-0.1.23 → sqlrite-0.1.24}/.github/workflows/ci.yml +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/.github/workflows/release-pr.yml +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/.github/workflows/release.yml +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/.github/workflows/rust.yml +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/.gitignore +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/CODE_OF_CONDUCT.md +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/LICENSE +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/MAINTAINERS +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/Makefile +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/README.md +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/desktop/index.html +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/desktop/package-lock.json +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/desktop/src/App.svelte +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/desktop/src/app.css +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/desktop/src/main.ts +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/desktop/src/vite-env.d.ts +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/desktop/svelte.config.js +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/desktop/tsconfig.json +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/desktop/vite.config.ts +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/docs/_index.md +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/docs/architecture.md +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/docs/design-decisions.md +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/docs/desktop.md +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/docs/embedding.md +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/docs/file-format.md +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/docs/getting-started.md +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/docs/pager.md +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/docs/release-plan.md +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/docs/release-secrets.md +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/docs/smoke-test.md +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/docs/sql-engine.md +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/docs/storage-model.md +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/docs/supported-sql.md +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/docs/usage.md +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/examples/README.md +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/examples/c/Makefile +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/examples/c/hello.c +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/examples/go/go.mod +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/examples/go/hello.go +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/examples/nodejs/hello.mjs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/examples/python/hello.py +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/examples/rust/quickstart.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/examples/wasm/Makefile +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/examples/wasm/index.html +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/images/SQLRite - Desktop.png +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/images/SQLRite Data Structures.png +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/images/SQLRite Simple SQL Execution High Level Diagram.png +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/images/SQLRite Simple SQL INSERT Execution High Level Diagram (Insert Row).png +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/images/SQLRite Simple SQL INSERT Execution High Level Diagram.png +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/images/SQLRite_logo.png +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/images/architecture.png +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/rust-toolchain.toml +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/samples/AST.delete.example +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/samples/AST.insert.exemple +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/samples/AST.select.example +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/samples/AST.update.example +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/samples/CREATE TABLE sqlrite_schema.sql +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/samples/CREATE_TABLE with duplicate.sql +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/samples/CREATE_TABLE.sql +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/samples/INSERT.sql +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/scripts/bump-version.sh +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/sdk/go/README.md +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/sdk/go/ask.go +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/sdk/go/ask_test.go +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/sdk/go/conn.go +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/sdk/go/go.mod +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/sdk/go/rows.go +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/sdk/go/sqlrite.go +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/sdk/go/sqlrite_test.go +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/sdk/go/stmt.go +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/sdk/python/README.md +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/sdk/python/src/lib.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/sdk/python/tests/test_ask.py +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/sdk/python/tests/test_sqlrite.py +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/sqlrite-ask/src/prompt.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/sqlrite-ask/src/provider/anthropic.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/sqlrite-ask/src/provider/mock.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/sqlrite-ask/tests/anthropic_http.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/ask/schema.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/connection.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/error.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/main.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/meta_command/mod.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/repl/mod.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/sql/db/database.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/sql/db/mod.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/sql/db/secondary_index.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/sql/db/table.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/sql/executor.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/sql/hnsw.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/sql/mod.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/sql/pager/cell.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/sql/pager/file.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/sql/pager/header.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/sql/pager/hnsw_cell.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/sql/pager/index_cell.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/sql/pager/interior_page.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/sql/pager/mod.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/sql/pager/overflow.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/sql/pager/page.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/sql/pager/pager.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/sql/pager/table_page.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/sql/pager/varint.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/sql/pager/wal.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/sql/parser/create.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/sql/parser/insert.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/sql/parser/mod.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/sql/parser/select.rs +0 -0
- {sqlrite-0.1.23 → sqlrite-0.1.24}/src/sql/tokenizer.rs +0 -0
|
@@ -3804,7 +3804,7 @@ dependencies = [
|
|
|
3804
3804
|
|
|
3805
3805
|
[[package]]
|
|
3806
3806
|
name = "sqlrite-ask"
|
|
3807
|
-
version = "0.1.
|
|
3807
|
+
version = "0.1.24"
|
|
3808
3808
|
dependencies = [
|
|
3809
3809
|
"serde",
|
|
3810
3810
|
"serde_json",
|
|
@@ -3815,7 +3815,7 @@ dependencies = [
|
|
|
3815
3815
|
|
|
3816
3816
|
[[package]]
|
|
3817
3817
|
name = "sqlrite-desktop"
|
|
3818
|
-
version = "0.1.
|
|
3818
|
+
version = "0.1.24"
|
|
3819
3819
|
dependencies = [
|
|
3820
3820
|
"serde",
|
|
3821
3821
|
"serde_json",
|
|
@@ -3827,7 +3827,7 @@ dependencies = [
|
|
|
3827
3827
|
|
|
3828
3828
|
[[package]]
|
|
3829
3829
|
name = "sqlrite-engine"
|
|
3830
|
-
version = "0.1.
|
|
3830
|
+
version = "0.1.24"
|
|
3831
3831
|
dependencies = [
|
|
3832
3832
|
"clap",
|
|
3833
3833
|
"env_logger",
|
|
@@ -3844,7 +3844,7 @@ dependencies = [
|
|
|
3844
3844
|
|
|
3845
3845
|
[[package]]
|
|
3846
3846
|
name = "sqlrite-ffi"
|
|
3847
|
-
version = "0.1.
|
|
3847
|
+
version = "0.1.24"
|
|
3848
3848
|
dependencies = [
|
|
3849
3849
|
"cbindgen",
|
|
3850
3850
|
"serde",
|
|
@@ -3854,7 +3854,7 @@ dependencies = [
|
|
|
3854
3854
|
|
|
3855
3855
|
[[package]]
|
|
3856
3856
|
name = "sqlrite-nodejs"
|
|
3857
|
-
version = "0.1.
|
|
3857
|
+
version = "0.1.24"
|
|
3858
3858
|
dependencies = [
|
|
3859
3859
|
"napi",
|
|
3860
3860
|
"napi-build",
|
|
@@ -3864,7 +3864,7 @@ dependencies = [
|
|
|
3864
3864
|
|
|
3865
3865
|
[[package]]
|
|
3866
3866
|
name = "sqlrite-python"
|
|
3867
|
-
version = "0.1.
|
|
3867
|
+
version = "0.1.24"
|
|
3868
3868
|
dependencies = [
|
|
3869
3869
|
"pyo3",
|
|
3870
3870
|
"sqlrite-engine",
|
|
@@ -27,7 +27,7 @@ resolver = "3"
|
|
|
27
27
|
# `package =` key so the import name stays `sqlrite` internally:
|
|
28
28
|
# sqlrite = { package = "sqlrite-engine", path = "…" }
|
|
29
29
|
name = "sqlrite-engine"
|
|
30
|
-
version = "0.1.
|
|
30
|
+
version = "0.1.24"
|
|
31
31
|
authors = ["Joao Henrique Machado Silva <joaoh82@gmail.com>"]
|
|
32
32
|
edition = "2024"
|
|
33
33
|
rust-version = "1.85"
|
|
@@ -255,7 +255,7 @@ let rows = conn.execute(&resp.sql)?;
|
|
|
255
255
|
- **✅ 7g.4 — Python SDK `conn.ask` / `ask_run` / `AskConfig`.** PyO3 wrappers over `sqlrite::ask::*`. New `Connection.ask(question, config=None)` returns an `AskResponse` (`.sql` / `.explanation` / `.usage` with cache-hit fields). `Connection.ask_run(question, config=None)` generates SQL then immediately executes via cursor — convenience for one-shot scripts/notebooks. `Connection.set_ask_config(cfg)` stashes a per-connection config. `AskConfig(api_key=..., model=..., max_tokens=..., cache_ttl=..., base_url=...)` constructor + `AskConfig.from_env()` static method. Three precedence layers: per-call > per-connection > env > defaults. `AskConfig.__repr__` and `AskResponse.__repr__` deliberately omit the API key — printing config in logs won't leak it. Empty SQL response (model declined) on `ask_run()` raises `SQLRiteError` with the model's explanation rather than executing the empty string. ~370 LOC of Rust binding + 415 LOC of pytest tests across 20 cases (config construction, env-var parsing, error paths, full happy-path through a localhost HTTP mock built on Python's stdlib `http.server`). README rewritten — three precedence layers explained, defaults enumerated, errors documented.
|
|
256
256
|
- **✅ 7g.5 — Node.js SDK `db.ask` / `askRun` / `AskConfig`.** napi-rs wrappers over `sqlrite::ask::*`. `db.ask(question, config?)` returns `AskResponse { sql, explanation, usage }`. `db.askRun(question, config?)` generates SQL then immediately executes — returns rows directly (`Array<Object>`); throws on empty-SQL response (model declined) with the model's explanation, rather than executing the empty string. `db.setAskConfig(config)` stashes per-connection config (pass `null` to clear). `new AskConfig({apiKey, model, maxTokens, cacheTtl, baseUrl})` constructor + `AskConfig.fromEnv()` static. Three precedence layers: per-call > per-connection > env > defaults — same shape as the Python SDK, with idiomatic JS option-object instead of kwargs (camelCase: `maxTokens`/`cacheTtl`/`baseUrl`). `AskConfig.toString()` deliberately omits the API key value (shows `<set>` or `null`). Auto-generated TypeScript types in `index.d.ts` — `AskConfigOptions`, `AskResponse`, `AskUsage` interfaces. ~370 LOC of Rust binding + 380 LOC of node:test cases (30 total — 19 new for ask plus the original 11). Mock HTTP server runs in a `worker_thread` so napi-rs's blocking sync POST on the main thread doesn't deadlock the response — same insight as Python's GIL deadlock, different mitigation. README rewritten — three-layer precedence, defaults table, error behavior, what AskResponse carries, the no-key-in-toString guarantee, full TypeScript shapes.
|
|
257
257
|
- **✅ 7g.6 — Go SDK `sqlrite.Ask` / `AskRun` / `AskConfig`.** cgo wrapper. New FFI function `sqlrite_ask(conn, question, config_json, *out)` accepts the AskConfig as a JSON string (smaller, more extensible C ABI than 6+ separate parameters) and returns `{sql, explanation, usage}` as JSON. Go side: `Ask(db *sql.DB, question, *AskConfig) (*AskResponse, error)` plus `AskContext(ctx, ...)` for context-aware connection-pool acquisition, `AskRun(db, question, *AskConfig) (*sql.Rows, error)` (and `AskRunContext`) that generates and executes in one call. `AskConfigFromEnv()` reads `SQLRITE_LLM_*`. `AskConfig.String()` deliberately omits the API key value (shows `<set>` or `<unset>`). Plumbs through `db.Conn(ctx).Raw()` to reach the underlying `*conn`'s opaque `*C.SqlriteConnection` handle. ~310 LOC of Go + ~200 LOC of Rust FFI extension + 380 LOC of Go tests (11 cases — config defaults / from-env / overrides / invalid-max-tokens, error paths for nil-db / missing-key / closed-db, full happy-path through `httptest.Server`, AskRun execution, empty-SQL declined-model, 4xx error surfacing). `httptest.Server` runs on a Go runtime goroutine, so unlike the Python (GIL) and Node (event-loop) SDKs there's no deadlock concern with synchronous cgo calls — Go test setup is the cleanest of the three. README rewritten — three-layer precedence, context-aware variants documented, errors enumerated, AskResponse type signatures shown.
|
|
258
|
-
-
|
|
258
|
+
- **✅ 7g.7 — WASM SDK `db.askPrompt()` / `db.askParse()` (Q9 split shape).** The WASM module does the schema-aware prompt construction in-page; the JS caller does the actual HTTP call (typically routed through their own backend that holds the API key). Two-step JS API: `db.askPrompt(question, options?)` returns Anthropic's `/v1/messages` request body shape; the caller POSTs that to their backend which forwards to Anthropic; `db.askParse(rawApiResponse)` parses the response back into `{ sql, explanation, usage }`. Browser never sees the API key, never POSTs to a third-party LLM endpoint, never deals with CORS. **Required structural refactor that 7g.7 unlocked:** feature-gated `ureq` on `sqlrite-ask` behind a default-on `http` feature; un-gated `sqlrite::ask::schema` so wasm-safe consumers get the schema dump without pulling in the HTTP transport; made `sqlrite_ask::parse_response` public for the WASM SDK to call. Net effect: `sqlrite-ask` builds clean for `wasm32-unknown-unknown` (verified via `wasm-pack build --target web`), and the WASM SDK reuses the canonical prompt rules + response parser without code duplication. ~250 LOC of WASM-side wrapper + the documented browser → backend → LLM provider → WASM example in `sdk/wasm/README.md` (Q9 doc requirement: complete worked example with a minimal Node/Express backend proxy showing where the API key lives).
|
|
259
259
|
- **7g.8 — MCP server `ask` tool (~50 LOC).** Wires the existing tool framework from 7h to a single new tool that calls into `sqlrite-ask`.
|
|
260
260
|
|
|
261
261
|
**Configuration:** the same config struct is accepted everywhere, with sensible env-var defaults:
|
|
@@ -476,7 +476,7 @@ Approved sub-phases (Q1–Q10 resolved):
|
|
|
476
476
|
- **✅ 7d — HNSW ANN index** — three PRs: 7d.1 (algorithm w/ recall@10 ≥ 0.95), 7d.2 (SQL integration + query optimizer), 7d.3 (persistence + DELETE/UPDATE rebuild). `CREATE INDEX … USING hnsw (col)`; fixed defaults `M=16, ef_construction=200, ef_search=50` (Q2). New `KIND_HNSW` cell tag.
|
|
477
477
|
- **✅ 7e — JSON column type + path queries** — `JSON` data type stored as canonical text (validated via `serde_json::from_str` at INSERT/UPDATE time; SQLite-JSON1-style — Q3 scope correction since bincode was removed in Phase 3c). Functions: `json_extract` / `json_type` / `json_array_length` / `json_object_keys`. Path subset supports `$`, `.key`, `[N]`, chained. `json_object_keys` returns a JSON-array text rather than a table-valued result (no set-returning functions in the executor yet).
|
|
478
478
|
- **7f — ~~Full-text search with BM25~~** — **deferred to Phase 8** (Q1).
|
|
479
|
-
- **7g — `ask()` API across the product surface** — natural-language → SQL via Anthropic API (Q4), Anthropic-first then OpenAI + Ollama follow-ups. Foundational **✅ 7g.1** introduces a new `sqlrite-ask` crate (Q10 — separate crate, not a feature flag) — `ask_with_schema()` over `&str` inputs (Phase 7g.2 made it pure — see retrospective below), sync `ureq` POST to `/v1/messages`, schema-aware prompt with prompt-caching on the schema dump (Sonnet 4.6 default; configurable). **✅ 7g.2** wires the REPL's `.ask` meta-command (`MetaCommand::Ask(String)` + confirm-and-run UX) and adds the `sqlrite::ask` module on the engine side (gated under a new `ask` feature) carrying `ConnectionAskExt` + the schema introspection helper. **✅ 7g.3** adds the desktop "Ask…" composer (slide-in panel above the editor; Tauri command runs the LLM call in the Rust backend so the API key stays out of the webview). **✅ 7g.4** ships the Python SDK surface — `conn.ask(question, config=None)` returns an `AskResponse(.sql, .explanation, .usage)`; `conn.ask_run()` adds the one-shot generate-and-execute convenience; `AskConfig` carries the three-layer precedence (per-call > per-connection > env > defaults). **✅ 7g.5** ships the Node.js SDK surface — `db.ask(question, config?)`, `db.askRun(question, config?)`, `db.setAskConfig(cfg)`, `new AskConfig({apiKey, model, maxTokens, cacheTtl, baseUrl})` + `AskConfig.fromEnv()`. Same three-layer precedence; idiomatic JS camelCase option-object. **✅ 7g.6** ships the Go SDK surface via cgo — `sqlrite.Ask(db, q, *AskConfig)` / `AskRun(...)` plus `AskContext`/`AskRunContext` for context-aware variants. The FFI grew one new C function (`sqlrite_ask`) that takes the config as a JSON string and returns the response as JSON — smaller, more extensible ABI than plumbing 6+ struct fields across cgo.
|
|
479
|
+
- **7g — `ask()` API across the product surface** — natural-language → SQL via Anthropic API (Q4), Anthropic-first then OpenAI + Ollama follow-ups. Foundational **✅ 7g.1** introduces a new `sqlrite-ask` crate (Q10 — separate crate, not a feature flag) — `ask_with_schema()` over `&str` inputs (Phase 7g.2 made it pure — see retrospective below), sync `ureq` POST to `/v1/messages`, schema-aware prompt with prompt-caching on the schema dump (Sonnet 4.6 default; configurable). **✅ 7g.2** wires the REPL's `.ask` meta-command (`MetaCommand::Ask(String)` + confirm-and-run UX) and adds the `sqlrite::ask` module on the engine side (gated under a new `ask` feature) carrying `ConnectionAskExt` + the schema introspection helper. **✅ 7g.3** adds the desktop "Ask…" composer (slide-in panel above the editor; Tauri command runs the LLM call in the Rust backend so the API key stays out of the webview). **✅ 7g.4** ships the Python SDK surface — `conn.ask(question, config=None)` returns an `AskResponse(.sql, .explanation, .usage)`; `conn.ask_run()` adds the one-shot generate-and-execute convenience; `AskConfig` carries the three-layer precedence (per-call > per-connection > env > defaults). **✅ 7g.5** ships the Node.js SDK surface — `db.ask(question, config?)`, `db.askRun(question, config?)`, `db.setAskConfig(cfg)`, `new AskConfig({apiKey, model, maxTokens, cacheTtl, baseUrl})` + `AskConfig.fromEnv()`. Same three-layer precedence; idiomatic JS camelCase option-object. **✅ 7g.6** ships the Go SDK surface via cgo — `sqlrite.Ask(db, q, *AskConfig)` / `AskRun(...)` plus `AskContext`/`AskRunContext` for context-aware variants. The FFI grew one new C function (`sqlrite_ask`) that takes the config as a JSON string and returns the response as JSON — smaller, more extensible ABI than plumbing 6+ struct fields across cgo. **✅ 7g.7** ships the WASM SDK with the JS-callback shape per Q9 — `db.askPrompt(q, opts?)` returns the LLM-API request body, JS caller routes through their own backend, `db.askParse(rawResponse)` returns `{sql, explanation, usage}`. Required structurally: `sqlrite-ask` got an `http` feature flag (default-on, off for wasm); engine's `sqlrite::ask::schema` un-gated so wasm-safe consumers can introspect schemas without the HTTP transport; `sqlrite_ask::parse_response` made public. The remaining 7g.8 covers the MCP `ask` tool — folded in alongside the SDK README catch-up for VECTOR / JSON / HNSW capabilities.
|
|
480
480
|
- **7h — MCP server adapter** — new `sqlrite-mcp` binary, hand-rolled JSON-RPC + tool framework (Q5).
|
|
481
481
|
|
|
482
482
|
Total scope budget: ~3-4 kLOC of new Rust across the wave. Each sub-phase ships as its own PR + release wave through the Phase 6 pipeline. The Phase 7 wave will likely close out **v0.2.0** (first minor bump after the 0.1.x Phase 6 cycle). Two new product lines added to lockstep versioning: `sqlrite-ask` and `sqlrite-mcp`.
|
|
@@ -4,7 +4,7 @@ build-backend = "maturin"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "sqlrite"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.24"
|
|
8
8
|
description = "Python bindings for SQLRite — a small, embeddable SQLite clone written in Rust."
|
|
9
9
|
authors = [{ name = "Joao Henrique Machado Silva", email = "joaoh82@gmail.com" }]
|
|
10
10
|
license = { text = "MIT" }
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
# Published to crates.io as `sqlrite-ask`. Joins the lockstep release
|
|
11
11
|
# wave (`sqlrite-ask-vX.Y.Z` tag) — see `docs/release-plan.md`.
|
|
12
12
|
name = "sqlrite-ask"
|
|
13
|
-
version = "0.1.
|
|
13
|
+
version = "0.1.24"
|
|
14
14
|
authors = ["Joao Henrique Machado Silva <joaoh82@gmail.com>"]
|
|
15
15
|
edition = "2024"
|
|
16
16
|
rust-version = "1.85"
|
|
@@ -48,13 +48,34 @@ serde_json = "1"
|
|
|
48
48
|
# exactly one POST to api.anthropic.com, so the sync surface is a
|
|
49
49
|
# perfect fit. Rolling our own JSON types over ureq is ~120 LOC
|
|
50
50
|
# vs. ~400 LOC + tokio + reqwest::blocking via an SDK.
|
|
51
|
-
|
|
51
|
+
#
|
|
52
|
+
# **Optional behind the `http` feature** (default-on) as of Phase
|
|
53
|
+
# 7g.7. The WASM SDK pulls this crate in with `default-features =
|
|
54
|
+
# false` to use just the prompt construction + response parsing —
|
|
55
|
+
# ureq's sync HTTP + rustls don't compile to wasm32. WASM ships its
|
|
56
|
+
# own `db.askPrompt()` / `db.askParse()` shape per Q9, where the
|
|
57
|
+
# browser hands the prompt to the caller's JS HTTP function and
|
|
58
|
+
# parses the result back through this crate.
|
|
59
|
+
ureq = { version = "2", features = ["json", "tls"], optional = true }
|
|
52
60
|
|
|
53
61
|
# Typed errors. (Same crate the engine uses, so consumers that
|
|
54
62
|
# enable the engine's `ask` feature can layer their own thiserror
|
|
55
63
|
# wrapper without version skew.)
|
|
56
64
|
thiserror = "2"
|
|
57
65
|
|
|
66
|
+
[features]
|
|
67
|
+
# Default is full HTTP-capable build — the engine's `ask` feature
|
|
68
|
+
# (and the Python / Node / Go SDKs) all go through `ask_with_schema`,
|
|
69
|
+
# which calls into the AnthropicProvider. Disabling `http` keeps
|
|
70
|
+
# only the wasm-safe parts: prompt construction (`build_system`,
|
|
71
|
+
# system rules), response parsing (`parse_response`), config types
|
|
72
|
+
# (`AskConfig`, `AskResponse`, `AskUsage`, `AskError`), and the
|
|
73
|
+
# generic `ask_with_schema_and_provider<P>` entry that takes a
|
|
74
|
+
# caller-supplied provider. The WASM SDK is the only consumer that
|
|
75
|
+
# turns this off today.
|
|
76
|
+
default = ["http"]
|
|
77
|
+
http = ["dep:ureq"]
|
|
78
|
+
|
|
58
79
|
[dev-dependencies]
|
|
59
80
|
# Throwaway tiny localhost HTTP server for the integration test
|
|
60
81
|
# that exercises the real ureq path. Avoids hitting api.anthropic.com
|
|
@@ -73,9 +73,15 @@
|
|
|
73
73
|
|
|
74
74
|
use std::env;
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
76
|
+
// `prompt` and parts of `provider` are wasm-safe (pure serde +
|
|
77
|
+
// trait definitions); `provider::anthropic` is HTTP-only and lives
|
|
78
|
+
// behind the `http` feature flag. Phase 7g.7 made these modules
|
|
79
|
+
// `pub` so the WASM SDK can reuse `build_system` / `parse_response`
|
|
80
|
+
// / `Usage` without duplicating them.
|
|
81
|
+
pub mod prompt;
|
|
82
|
+
pub mod provider;
|
|
83
|
+
|
|
84
|
+
#[cfg(feature = "http")]
|
|
79
85
|
pub use provider::anthropic::AnthropicProvider;
|
|
80
86
|
pub use provider::{Provider, Request, Response, Usage};
|
|
81
87
|
|
|
@@ -275,6 +281,13 @@ pub enum AskError {
|
|
|
275
281
|
///
|
|
276
282
|
/// The library does **not** execute the returned SQL — that's the
|
|
277
283
|
/// caller's call. See module docs for rationale.
|
|
284
|
+
///
|
|
285
|
+
/// **Feature-gated under `http`** (default-on) — wraps the built-in
|
|
286
|
+
/// `AnthropicProvider`, which uses ureq and isn't wasm-safe. WASM
|
|
287
|
+
/// callers should use [`ask_with_schema_and_provider`] with a
|
|
288
|
+
/// caller-supplied provider, or skip this crate entirely and use
|
|
289
|
+
/// the WASM SDK's `db.askPrompt()` / `db.askParse()` shape (Q9).
|
|
290
|
+
#[cfg(feature = "http")]
|
|
278
291
|
pub fn ask_with_schema(
|
|
279
292
|
schema_dump: &str,
|
|
280
293
|
question: &str,
|
|
@@ -328,7 +341,12 @@ pub fn ask_with_schema_and_provider<P: Provider>(
|
|
|
328
341
|
/// because real LLM output drifts even with strict instructions. The
|
|
329
342
|
/// fence/prose tolerance matches what real callers do (better-sqlite3,
|
|
330
343
|
/// rusqlite, etc.) when interfacing with model output.
|
|
331
|
-
|
|
344
|
+
///
|
|
345
|
+
/// **Public as of Phase 7g.7** so the WASM SDK can call this on the
|
|
346
|
+
/// model-text portion of an LLM API response that JS retrieved (per
|
|
347
|
+
/// Q9 the WASM module never makes the HTTP call itself; the JS
|
|
348
|
+
/// caller hands the raw response back through `db.askParse()`).
|
|
349
|
+
pub fn parse_response(raw: &str, usage: Usage) -> Result<AskResponse, AskError> {
|
|
332
350
|
// 1. Strip markdown fences if the model wrapped its JSON.
|
|
333
351
|
let trimmed = raw.trim();
|
|
334
352
|
let body = strip_markdown_fence(trimmed).unwrap_or(trimmed);
|
|
@@ -14,6 +14,12 @@
|
|
|
14
14
|
use crate::AskError;
|
|
15
15
|
use crate::prompt::{SystemBlock, UserMessage};
|
|
16
16
|
|
|
17
|
+
// Anthropic adapter is HTTP-based (sync ureq POST). The `http`
|
|
18
|
+
// feature gates the whole module so wasm32 builds — which can't
|
|
19
|
+
// link ureq + rustls — skip it cleanly. The WASM SDK uses Q9's
|
|
20
|
+
// JS-callback shape (caller does the HTTP from JS) and never
|
|
21
|
+
// instantiates this provider.
|
|
22
|
+
#[cfg(feature = "http")]
|
|
17
23
|
pub mod anthropic;
|
|
18
24
|
|
|
19
25
|
#[cfg(test)]
|
|
@@ -38,19 +38,28 @@
|
|
|
38
38
|
//! for callers who don't want to bring the trait into scope, or
|
|
39
39
|
//! who hold a `&Database` directly (the REPL binary does this).
|
|
40
40
|
|
|
41
|
+
// Schema dump is always available (no sqlrite-ask dep). The
|
|
42
|
+
// `ConnectionAskExt` trait + free helper functions below are gated
|
|
43
|
+
// under the engine's `ask` feature because they pull in `sqlrite-ask`
|
|
44
|
+
// (HTTP transport).
|
|
45
|
+
pub mod schema;
|
|
46
|
+
|
|
47
|
+
#[cfg(feature = "ask")]
|
|
41
48
|
use sqlrite_ask::{ask_with_schema, ask_with_schema_and_provider};
|
|
42
49
|
|
|
50
|
+
#[cfg(feature = "ask")]
|
|
43
51
|
use crate::Connection;
|
|
52
|
+
#[cfg(feature = "ask")]
|
|
44
53
|
use crate::sql::db::database::Database;
|
|
45
54
|
|
|
46
|
-
pub mod schema;
|
|
47
|
-
|
|
48
55
|
// Re-export the public surface from sqlrite-ask. Lets callers reach
|
|
49
56
|
// these without listing `sqlrite-ask` as a direct dep — convenient
|
|
50
57
|
// for the Tauri desktop app, the SDK adapters, and any Rust embedder
|
|
51
58
|
// who already pulls the engine in. They can keep saying
|
|
52
59
|
// `use sqlrite::ask::AskConfig` instead of dragging the second crate
|
|
53
|
-
// in just for one type.
|
|
60
|
+
// in just for one type. Gated under `ask` because that's the feature
|
|
61
|
+
// that pulls `sqlrite-ask` into the dep graph in the first place.
|
|
62
|
+
#[cfg(feature = "ask")]
|
|
54
63
|
pub use sqlrite_ask::{
|
|
55
64
|
AnthropicProvider, AskConfig, AskError, AskResponse, CacheTtl, Provider, ProviderKind, Request,
|
|
56
65
|
Response, Usage,
|
|
@@ -60,6 +69,10 @@ pub use sqlrite_ask::{
|
|
|
60
69
|
/// [`crate::Connection`]. Bring it into scope with
|
|
61
70
|
/// `use sqlrite::ConnectionAskExt;` (the engine re-exports it at
|
|
62
71
|
/// the crate root).
|
|
72
|
+
///
|
|
73
|
+
/// Gated under the `ask` feature — pulls in `sqlrite-ask` and its
|
|
74
|
+
/// HTTP transport. WASM and other lean builds skip this entirely.
|
|
75
|
+
#[cfg(feature = "ask")]
|
|
63
76
|
pub trait ConnectionAskExt {
|
|
64
77
|
/// Generate SQL from a natural-language question.
|
|
65
78
|
///
|
|
@@ -80,6 +93,7 @@ pub trait ConnectionAskExt {
|
|
|
80
93
|
fn ask(&self, question: &str, config: &AskConfig) -> Result<AskResponse, AskError>;
|
|
81
94
|
}
|
|
82
95
|
|
|
96
|
+
#[cfg(feature = "ask")]
|
|
83
97
|
impl ConnectionAskExt for Connection {
|
|
84
98
|
fn ask(&self, question: &str, config: &AskConfig) -> Result<AskResponse, AskError> {
|
|
85
99
|
ask(self, question, config)
|
|
@@ -88,6 +102,7 @@ impl ConnectionAskExt for Connection {
|
|
|
88
102
|
|
|
89
103
|
/// Free-function form of [`ConnectionAskExt::ask`]. Equivalent —
|
|
90
104
|
/// pick whichever shape reads better at the call site.
|
|
105
|
+
#[cfg(feature = "ask")]
|
|
91
106
|
pub fn ask(conn: &Connection, question: &str, config: &AskConfig) -> Result<AskResponse, AskError> {
|
|
92
107
|
ask_with_database(conn.database(), question, config)
|
|
93
108
|
}
|
|
@@ -96,6 +111,7 @@ pub fn ask(conn: &Connection, question: &str, config: &AskConfig) -> Result<AskR
|
|
|
96
111
|
///
|
|
97
112
|
/// Used by the REPL binary's `.ask` meta-command, which holds a
|
|
98
113
|
/// `&mut Database` rather than a `&Connection`.
|
|
114
|
+
#[cfg(feature = "ask")]
|
|
99
115
|
pub fn ask_with_database(
|
|
100
116
|
db: &Database,
|
|
101
117
|
question: &str,
|
|
@@ -108,6 +124,7 @@ pub fn ask_with_database(
|
|
|
108
124
|
/// Lower-level entry — same flow as [`ask`] but you supply the
|
|
109
125
|
/// provider. For test harnesses + advanced callers driving custom
|
|
110
126
|
/// backends.
|
|
127
|
+
#[cfg(feature = "ask")]
|
|
111
128
|
pub fn ask_with_provider<P: Provider>(
|
|
112
129
|
conn: &Connection,
|
|
113
130
|
question: &str,
|
|
@@ -119,6 +136,7 @@ pub fn ask_with_provider<P: Provider>(
|
|
|
119
136
|
|
|
120
137
|
/// Lower-level entry taking `&Database` and a provider. Canonical
|
|
121
138
|
/// inner function — the others reduce to this one.
|
|
139
|
+
#[cfg(feature = "ask")]
|
|
122
140
|
pub fn ask_with_database_and_provider<P: Provider>(
|
|
123
141
|
db: &Database,
|
|
124
142
|
question: &str,
|
|
@@ -50,7 +50,14 @@
|
|
|
50
50
|
#[macro_use]
|
|
51
51
|
extern crate prettytable;
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
// `sqlrite::ask` is always available — its `schema` submodule (the
|
|
54
|
+
// CREATE TABLE dump used to ground the LLM's prompt) is pure-engine
|
|
55
|
+
// and useful even for builds that don't enable the `ask` feature.
|
|
56
|
+
// The `ConnectionAskExt` trait + `ask` / `ask_with_database`
|
|
57
|
+
// helpers inside the module are gated under the feature, since
|
|
58
|
+
// they pull in `sqlrite-ask`. The WASM SDK uses
|
|
59
|
+
// `sqlrite::ask::schema::dump_schema_for_database` to introspect a
|
|
60
|
+
// browser-side `Connection` without needing the HTTP transport.
|
|
54
61
|
pub mod ask;
|
|
55
62
|
pub mod connection;
|
|
56
63
|
pub mod error;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sqlrite-0.1.23 → sqlrite-0.1.24}/images/SQLRite Simple SQL Execution High Level Diagram.png
RENAMED
|
File without changes
|
|
File without changes
|
{sqlrite-0.1.23 → sqlrite-0.1.24}/images/SQLRite Simple SQL INSERT Execution High Level Diagram.png
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|