Skip to main content

sqlite-jev

Natural-language predicates, classification, and scoring for SQLite, powered by TypeSafe Jev. It is inspired by pg-jev, but shaped around SQLite's loadable-extension and virtual-table APIs.

.load ./build/jev

SELECT t.id, t.subject, round(j.probability, 3) AS urgency
FROM jev_rows(
  'tickets',
  'The customer explicitly expresses urgency or says work is blocked',
  'noul',
  NULL,
  json_array('subject', 'message')
) AS j
JOIN tickets AS t ON t.rowid = j.source_rowid
WHERE j.probability >= 0.6;

jev_rows reads the selected columns, puts up to 40 rows in one shared state, asks one question per row, and returns a virtual table that can be joined to the source by rowid. Results are cached for the lifetime of the SQLite connection.

Build

Requirements:

  • SQLite 3.45 or newer, built with JSON support and loadable extensions
  • A C11 compiler and make
  • The libcurl runtime (libcurl.so.4 on Linux or libcurl.4.dylib on macOS)
  • A TypeSafe API key

The current development machine already has all of these; no extra system package is needed.

make
export TYPESAFE_API_KEY=...
sqlite3 my.db

Inside SQLite:

.load ./build/jev
SELECT jev_version();

TYPESAFE_API_KEY is the only environment variable used for the API key.

Batched table queries

The signature is:

jev_rows(table_name, question [, kind [, criteria [, columns]]])

It returns source_rowid, answer, probability, choice, score, and confidence. Columns that do not apply to the chosen primitive are NULL.

Boolean judgment (Noul)

SELECT
  t.id,
  j.probability AS yes_probability,
  1.0 - j.probability AS no_probability,
  CASE WHEN j.probability >= 0.7 THEN 'yes' ELSE 'no' END AS answer
FROM jev_rows(
  'tickets',
  'The ticket explicitly asks for a refund',
  'noul',
  NULL,
  json_array('subject', 'message')
) AS j
JOIN tickets AS t ON t.rowid = j.source_rowid
ORDER BY t.id;

A Noul returns the probability of yes; no is its complement. Choosing the larger one is equivalent to a 0.5 threshold. Keep the threshold in SQL so it can rise with the cost of a false positive. The scalar jev(state, condition) uses 0.5 unless given a third argument.

Classification (Choice)

SELECT t.id, j.choice AS team, j.confidence
FROM jev_rows(
  'tickets',
  'Which team should handle the main request?',
  'choice',
  json_object(
    'billing', 'Charges, invoices, payment methods, or refunds',
    'technical', 'Bugs, failures, or integrations',
    'sales', 'Pricing, plans, demos, or new purchases',
    'other', 'Anything outside those teams'
  ),
  json_array('subject', 'message')
) AS j
JOIN tickets AS t ON t.rowid = j.source_rowid;

Ordered rating (Score)

SELECT t.id, j.score, j.confidence
FROM jev_rows(
  'tickets',
  'How frustrated is the customer?',
  'score',
  json_array('Calm and factual', 'Frustrated but civil', 'Very angry or abusive'),
  json_array('message')
) AS j
JOIN tickets AS t ON t.rowid = j.source_rowid;

For accuracy and cost, include only the columns the judgment needs. jev_rows requires a rowid table. To prefilter a large data set, materialize the filtered rows into a temporary table and evaluate that table.

Scalar functions

Scalar functions are convenient for one record. When scanning a table, prefer jev_rows so Jev can evaluate many questions in a single request.

Function Result
jev(state, condition [, threshold]) Boolean Noul predicate; default threshold is 0.5
jev_prob(state, condition) Noul probability from 0 to 1
jev_choice(state, question, criteria_json) Most likely Choice key
jev_score(state, question, levels_json) Probability-weighted Score level
jev_score_norm(state, question, levels_json) Score normalized to 0 through 1
jev_confidence(state, question, kind, criteria_json) Choice or Score confidence
jev_eval(state, question [, kind [, criteria_json]]) Full answer JSON
jev_stats() Connection-local usage and cache statistics
jev_cache_clear() Clears the connection-local answer cache
jev_version() Extension version

Pass structured state with SQLite JSON functions:

SELECT jev_prob(
  json_object('subject', subject, 'message', message),
  'The customer explicitly expresses urgency'
)
FROM tickets
WHERE id = 42;

Configuration

Configuration is connection-local:

SELECT jev_config('model', 'jev-latest');
SELECT jev_config('batch_size', 40);
SELECT jev_config('max_rows', 500);
SELECT jev_config('timeout', 90);
SELECT jev_config('api_url', 'https://api.typesafe.ai/v1/systemone');
SELECT jev_config('api_key', '...');

max_rows is a spend guard. A jev_rows scan above the limit fails before sending any data. The API key is never returned by jev_config; it reports only set or unset.

Python

Add the platform package to a project and load it with the Python wrapper:

uv add sqlite-jev
import sqlite3
import sqlite_jev

connection = sqlite_jev.load(sqlite3.connect(":memory:"))

The package contains the same native extension as the standalone release, has no runtime Python dependencies, and supports maintained Python versions starting with Python 3.10. The interpreter's sqlite3 module must have loadable-extension support enabled.

To load a standalone build manually instead:

import sqlite3

connection = sqlite3.connect(":memory:")
connection.enable_load_extension(True)
connection.load_extension("/path/to/jev.so")  # use jev.dylib on macOS
connection.enable_load_extension(False)

version = connection.execute("select jev_version()").fetchone()[0]

Demo and tests

The deterministic suite uses a local mock server and never calls TypeSafe:

make test

The ticket-triage demo makes two live API requests, one for urgency and one for routing:

make live-test

See examples/ticket_triage.sql for the complete query.

make integration-test runs a smaller live smoke test. In GitHub Actions it runs once every two months and on manual dispatch using the TYPESAFE_API_KEY repository secret. It checks the API contract, batching, and answer shapes; semantic expectations remain in the deterministic mock suite so normal model variation cannot make pull requests flaky.

Releases

Tags named vX.Y.Z build and publish four archives through GitHub Actions:

  • Linux x86_64 and arm64
  • macOS Intel and Apple Silicon

Each archive contains the native extension, this README, and its pyproject.toml. The release also includes a py3-none-<platform> Python wheel and SHA256SUMS. CI installs each wheel with cibuildwheel and verifies that sqlite_jev.load() enables the SQL API. The same tag publishes the wheels and source distribution to PyPI through trusted publishing.

Important limits

  • Row contents are sent to TypeSafe. Do not evaluate data you are not allowed to share.
  • This is a semantic full scan, not an index. Apply deterministic SQLite filters first and materialize a small candidate table.
  • Cache entries live only for the current database connection and are keyed by row content, model, question, primitive, and criteria.
  • Jev should make narrow judgments. Keep counting, arithmetic, and date comparison in SQL.
  • Text stored in a row can steer model behavior. Test adversarial content and use conservative probability or confidence thresholds before automating consequential actions.
  • libcurl is loaded dynamically so building does not require the curl development headers. Linux and macOS are the currently tested platforms.

Release files for sqlite-jev 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sqlite-jev 0.1.0
File Size Uploaded
sqlite_jev-0.1.0.tar.gz 24.4 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for sqlite-jev 0.1.0
File
sqlite_jev-0.1.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl Python 3 none Linux glibc 2.28+ x86-64, Linux glibc 2.17+ x86-64 Details
sqlite_jev-0.1.0-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl Python 3 none Linux glibc 2.28+ ARM64, Linux glibc 2.17+ ARM64 Details
sqlite_jev-0.1.0-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details
sqlite_jev-0.1.0-py3-none-macosx_10_9_x86_64.whl Python 3 none macOS 10.9+ x86-64 Details

Total release size: 111.4 kB

Release files / sqlite_jev-0.1.0.tar.gz

Download URL sqlite_jev-0.1.0.tar.gz
Size 24.4 kB
Tags Source
SHA-256 checksum
How to use checksums
dc505afe094f49e882e39f8d4e46b8c69235bbe7cddce84293629e5d0de51fab
BLAKE2b-256 checksum
How to use checksums
4bb1dc2c46ee4f30195eb88388388a7ff7a7402f35dd6322d65cf120f9bf9b75
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.16 {"installer":{"name":"uv","version":"0.12.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / sqlite_jev-0.1.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl

Download URL sqlite_jev-0.1.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Size 22.6 kB
Tags Linux glibc 2.17+ x86-64 Linux glibc 2.28+ x86-64 Python 3
SHA-256 checksum
How to use checksums
069ed9ed25d950f6d8881985dfb560d89cb923147bd4613e387baa1c8fbdc932
BLAKE2b-256 checksum
How to use checksums
6892bc098bc3c909f666784efb47d73b98c168981f6b35cae06aea694e2f6906
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.16 {"installer":{"name":"uv","version":"0.12.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / sqlite_jev-0.1.0-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl

Download URL sqlite_jev-0.1.0-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Size 23.2 kB
Tags Linux glibc 2.17+ ARM64 Linux glibc 2.28+ ARM64 Python 3
SHA-256 checksum
How to use checksums
0e7ed6c971f5bbd0eab6d62c1c6457baf53d06d99f1158b8470efaff70048e31
BLAKE2b-256 checksum
How to use checksums
96ff7f0cdbb2b32eece3f8853a4a26c15a8405413dc241e3cb9c355932cfb917
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.16 {"installer":{"name":"uv","version":"0.12.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / sqlite_jev-0.1.0-py3-none-macosx_11_0_arm64.whl

Download URL sqlite_jev-0.1.0-py3-none-macosx_11_0_arm64.whl
Size 20.6 kB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
12a93b87e908e2b5488b19c9bcc705f071b7a45a2e8521225b50b42290cecdff
BLAKE2b-256 checksum
How to use checksums
2d706fe3047ddaea9785eb748707131e854784bc5de9068b3e037f357051b3f5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.16 {"installer":{"name":"uv","version":"0.12.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / sqlite_jev-0.1.0-py3-none-macosx_10_9_x86_64.whl

Download URL sqlite_jev-0.1.0-py3-none-macosx_10_9_x86_64.whl
Size 20.7 kB
Tags Python 3 macOS 10.9+ x86-64
SHA-256 checksum
How to use checksums
7eafde96a69fb04d1caca95c3254df26639d237bc4d533a62803c77797c99c23
BLAKE2b-256 checksum
How to use checksums
801ad142281f2a73a72dbd57b3e9df271fb6e9ec9a2f10630e500c8a0afc2e3f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.16 {"installer":{"name":"uv","version":"0.12.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.1.0 This release

5 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page