Skip to main content

JevKit core

Distribution jevkit-runtime, import jevkit_runtime. The PyPI name jevkit-core belongs to a different project.

One request pipeline, one answer store, one provider catalog for jgrep, jsort, jlink, jselect, and jcol. Each tool remains its own package and repository; the core imports none of them, and a tool's adapter is a few lines naming which providers it offers.

What a tool gets

from jevkit_runtime import AnswerStore, Client, catalog, resolve

PROVIDERS = catalog("typesafe", "openrouter", "gateway")
backend = resolve(PROVIDERS, name=None, model=None)          # or JEV_API / JEV_MODEL, else the first configured
async with Client(backend, store=AnswerStore()) as client:
    answers = await client.ask(state, {"q": {"type": "noul", "instructions": "..."}})

Client.ask does the whole thing: computes each question's identity, serves what the store already knows, joins an identical request already in flight, sends only the misses, validates the entire response before storing any of it, and meters the call before validation so a billed but malformed answer still counts. It returns Answers, a dict by question id whose origins say who answered each one and whether it came from the API, the store, or a shared call. Per-call policy is keyword arguments: allow_paid=False for cache-only runs, on_cost for the caller who should be charged, hedge_after to resend a slow call, and keys for callers whose reuse unit is not the request. HTTP/2 is used whenever the http2 extra is installed.

Module Owns
settings.py Every environment and filesystem convention, read in one place: XDG_*, JEV_API, JEV_URL, JEV_MODEL, JEV_PRICE_PER_MTOK, provider keys and URL files
providers.py The catalog (Provider), a tool's selection of it or its own entries, and resolve() to one Backend: endpoint, model, key
protocol.py Request bodies, typed answer validation (noul, choice, score), usage parsing, answer identity, provenance
transport.py One HTTP call with a total deadline, retries with backoff and Retry-After, structured status errors
store.py SQLite answers with their provenance in one row, one versioned schema
client.py The pipeline above, request sharing, hedging
meter.py Calls, cache hits, retries, hedges, tokens, cost, and which models actually answered
errors.py JevError, JevFatal, JevBudgetExceeded, RequestExhausted, ProviderError, ProviderFatal

Conventions every tool shares

  • Answer identity is answer_key(backend, state, question): provider, endpoint, model, state and question. An answer from one provider or model is never served for another.
  • The store lives at $XDG_CACHE_HOME/jev/answers.sqlite (default ~/.cache/jev), is created private to the user, and resets itself when it finds an older schema. Version 0.2 cannot read caches written by 0.1 tools; the first run after upgrading re-asks.
  • Credentials come from the provider's variable, then $XDG_CONFIG_HOME/jev/<provider>.key. Gateways take their URL from JEV_GATEWAY_URL or <provider>.url. JEV_URL overrides any endpoint.
  • Metering refuses malformed usage rather than under-counting; a response without a reported cost is priced from its tokens at the run's list price.
  • Errors keep their wording across tools: a fatal status reads PROVIDER said 401: detail, a bad request reads HTTP 400: detail, and exhaustion reads gave up after 15s (last failure). Both status errors carry provider, status and detail for tools that word or redact them.

Development

Keep the six checkouts as siblings. Each consumer depends on jevkit-runtime>=0.2.0,<0.3.0 and overrides it for development with jevkit-runtime = { path = "../jevkit-core", editable = true } under [tool.uv.sources].

python3 scripts/dev.py setup          # uv sync every checkout, fetch jselect's tokenizer data
python3 scripts/dev.py check          # core and consumer suites, credentials stripped, sockets blocked
python3 scripts/dev.py wheel-check    # build and exercise real wheel installs in temporary environments
python3 scripts/dev.py run jgrep -- --help

check also proves each consumer imports this exact source tree; wheel-check proves the installed wheel, not the checkout. --tool NAME limits either to one consumer and --suffix selects alternatively named checkouts. The GitHub workflows run the core suite on Python 3.10 and 3.13 and the downstream matrix against each consumer's main branch.

Releasing

Tag the verified core vX.Y.Z and dispatch the publish workflow with that tag; the workflow checks the tag matches the package version and publishes through PyPI Trusted Publishing. Then release each consumer through its own process, bumping its supported core range, lockfile, and CI core reference together.

Release files for jevkit-runtime 0.2.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 jevkit-runtime 0.2.0
File Size Uploaded
jevkit_runtime-0.2.0.tar.gz 35.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for jevkit-runtime 0.2.0
File Interpreter ABI Platform
jevkit_runtime-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 53.7 kB

Release files / jevkit_runtime-0.2.0.tar.gz

Download URL jevkit_runtime-0.2.0.tar.gz
Size 35.9 kB
Tags Source
SHA-256 checksum
How to use checksums
f57402b3ffd59f2c1b2ec05f4afc8020170cb985d31e8e44c14cf32a49d860d2
BLAKE2b-256 checksum
How to use checksums
088f7da96b236603915eea74f9a8ea71f5593a6a9e209afbd59dcc337367a0c1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","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 / jevkit_runtime-0.2.0-py3-none-any.whl

Download URL jevkit_runtime-0.2.0-py3-none-any.whl
Size 17.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8d81533c5fa1def1a5a80326dc589d171476650f311bd4f510c264227c6598f3
BLAKE2b-256 checksum
How to use checksums
82cb2b2d6ebdcf6b85b13cf812802b425d32c66bde13ee08a116476e43aecf5b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","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

0.3.1

2 release files

0.3.0

2 release files

This release

0.2.0 This release

2 release files

0.1.0

2 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