1# Chapter 16: jevcrates — one post office for four towns 2 3Four projects ask [Jev](https://docs.typesafe.ai) questions: postjevsql (a 4Postgres extension), jevsnes (Jev plays a SNES game), jevhooks (Jev judges 5Claude Code hooks) and lmjtfy (the site you may be reading this on). Jev is 6TypeSafe AI's "System One" model. It does not write text. It answers typed 7questions (`Noul`, `Choice`, `Score`) with calibrated probabilities. This 8repository is the one copy of the code that asks it, and every one of those 9projects uses it. 10 11Think of it as a post office shared by four towns. Each town used to run its 12own: its own idea of how to address an envelope, how long to wait for a 13reply, and when to give up and send it again. Now there is one post office, 14and the towns differ only in the road the mail van takes (a raw HTTP/2 15connection, a Postgres backend, or a Cloudflare Worker's `fetch`). 16 17> **Aside.** If you come from JavaScript: a *crate* is a package (one 18> `Cargo.toml`, the way an npm package has one `package.json`), and this 19> repository is a *Cargo workspace*, which is what pnpm or npm workspaces 20> are to a monorepo. A *trait* is close to a TypeScript `interface`. The 21> crates here are libraries only; nothing in this repository is a program you 22> run. 23 24## Use it in your own project 25 26You do not need a GitHub account, or to clone anything by hand. Cargo fetches 27the crates straight from the lmjtfy site, which serves this repository: 28 29```toml 30[dependencies] 31jev-protocol = { git = "https://lmjtfy.fun/jevcrates.git", rev = "46514413a1e73ad848fc2b1f106cca83eaf081f1" } 32jev-http = { git = "https://lmjtfy.fun/jevcrates.git", rev = "46514413a1e73ad848fc2b1f106cca83eaf081f1" } 33tokio = { version = "1", features = ["macros", "rt-multi-thread"] } 34``` 35 36Pick the crates by where your code runs (the table below has the detail): 37 38- **A native program** (a CLI, a server, a bot): `jev-protocol` and `jev-http`. 39- **A Cloudflare Worker**: `jev-protocol` and `jev-worker`. 40- **Anywhere else**, with your own way of sending a request (a database's 41 HTTP, a sandbox): `jev-protocol` and `jev-client`, and implement its two 42 ports. 43 44`rev` pins the commit, so a new commit here never changes your build until 45you move it. The front page at <https://lmjtfy.fun/jevcrates.git> 46shows these lines with the latest commit filled in. 47 48Then, with `TYPESAFE_API_KEY` set: 49 50```rust 51use jev_http::Jev; 52use jev_protocol::{Json, ModelId, Noul, Questions}; 53 54#[tokio::main] 55async fn main() -> Result<(), Box<dyn std::error::Error>> { 56 // TYPESAFE_API_KEY from the environment; None when it is not set. 57 let Some(jev) = Jev::from_env("usejev", ModelId::pinned("jev-1.13.0")?) else { 58 return Err("set TYPESAFE_API_KEY".into()); 59 }; 60 let jev = jev?; 61 let mut questions = Questions::new(); 62 let good = questions.noul("good", Noul::new(Json::text("Is this a good retirement plan?")))?; 63 let state = Json::text("Put it all on red at the casino."); 64 let answered = jev.ask(&state, &questions, "trying it out").await?; 65 println!("p(yes) = {:.2}", answered.response.get(good).noul); 66 Ok(()) 67} 68``` 69 70`jev-http` keeps a spend ledger under `$XDG_STATE_HOME/jev` that every 71program on the machine shares, and refuses a request before sending it when 72the shared limits say so (chapter 20). The third argument to `ask` is why the 73money was spent, and it is written into that ledger. 74 75## How the crates fit 76 77The crates are split along one line: whether they do I/O. The two at the 78bottom never touch a network, a file or a clock, so they compile anywhere, 79WebAssembly included. The ones above them supply the network for one kind of 80host. 81 82```mermaid 83flowchart BT 84 protocol["jev-protocol<br/>what to ask, what came back"] 85 client["jev-client<br/>retries, timeouts, redials"] 86 worker["jev-worker<br/>a Cloudflare Worker's fetch"] 87 http["jev-http<br/>HTTP/2 on tokio + spend ledger"] 88 mock["jev-mock<br/>a fake Jev for tests"] 89 client --> protocol 90 worker --> client 91 http --> client 92 http -. "tests only" .-> mock 93``` 94 95| Crate | What it does | I/O | 96| --- | --- | --- | 97| [jev-protocol/](jev-protocol/) | The questions and answers, the exact request bytes, response verification, error classification, the retry policy and the price. | none; builds for wasm | 98| [jev-client/](jev-client/) | Runs the retry policy: budgets, per-attempt timeouts, never-sent redials, request ids. Reaches the world through two ports, `Transport` and `Runtime`. | none | 99| [jev-worker/](jev-worker/) | The two ports for a Cloudflare Worker (wasm32, workers-rs). No ledger. | network | 100| [jev-http/](jev-http/) | The two ports for a native process (HTTP/2 over pure-Rust TLS on tokio), and `Jev`, which has an on-disk spend ledger admit every request. | network, files | 101| [jev-mock/](jev-mock/) | A local HTTP/2 TLS stand-in for the endpoint, with fixture replay and recording. | loopback | 102 103Who uses what: postjevsql uses `jev-protocol`, `jev-client` and `jev-mock`, 104with its own Postgres transport. jevsnes and jevhooks use `jev-http`. lmjtfy's 105Worker uses `jev-worker`, and its `tools/eval` uses `jev-http`. 106 107> **Aside.** The crates moved here on 2026-10-01 from postjevsql 108> (`jev-protocol`, `jev-client`, `jev-mock`) and jevsnes (`jev`, `jev-http`), 109> with their git history, and the two protocol layers (`jev` and 110> `jev-protocol`) were merged into one. 111 112## Try it 113 114``` 115cargo test --workspace 116``` 117 118Every test runs offline. The ones that need a server start `jev-mock` on 119loopback; the retry tests run on a virtual clock and finish instantly. 120 121The chapters follow the stack from the bottom up: start with 122[jev-protocol](jev-protocol/), the vocabulary every other crate speaks. 123 124## For the people who maintain it 125 126### In this folder 127 128| Path | What | 129| --- | --- | 130| [jev-protocol/](jev-protocol/) | Chapter 17: the wire protocol, no I/O. | 131| [jev-client/](jev-client/) | Chapter 18: the retry policy, behind two ports. | 132| [jev-worker/](jev-worker/) | Chapter 19: the ports on a Cloudflare Worker. | 133| [jev-http/](jev-http/) | Chapter 20: the ports on tokio, and the spend ledger. | 134| [jev-mock/](jev-mock/) | Chapter 21: the fake endpoint for tests. | 135| [Cargo.toml](Cargo.toml) | The workspace: its members, and every dependency's version, declared once and inherited by the crates. | 136| [CLAUDE.md](CLAUDE.md) | What an agent working here must not break. | 137| [.gitignore](.gitignore) | Ignores `target/`, Cargo's build output. | 138 139All five crates are version `0.0.1`, edition 2024, `publish = false`, and 140licensed MIT OR Apache-2.0. 141 142← Previous: lmjtfy's third-party/ chapter · Next: [Chapter 17: jev-protocol](jev-protocol/) →