Quickstart
OpenJevX is one server binary plus one model folder. The binary holds no model. 1
A release is a small binary per platform plus one model folder archive, and you unpack both into the same directory. 2
The pinned server release is 0.5.9 ("version": "0.5.9" in package.json). 3
The release downloads fetch model 0.5.2. 4 5
Pick one of the four paths below, then make your first request.
Path 1: release binary plus model folder
Section titled “Path 1: release binary plus model folder”The release has one archive per platform: openjevx-darwin-arm64.tar, openjevx-linux-amd64.tar, openjevx-linux-arm64.tar and openjevx-windows-amd64.zip. 6
The platform archives carry no openjevx.json, so a release unpacked over an old one never replaces your config or ships a password. 7
The model folder ships as openjevx-model-<version>.tar.gz, holding model/ with openjevx.w8.onnx, config.json and tokenizer.json. 8
Download the platform archive and the model archive, then unpack both into the same folder and run the server. 2 4
tar -xf openjevx-darwin-arm64.tar && tar -xzf openjevx-model-0.5.2.tar.gz && ./openjevxOn Linux (x86-64) the archive is openjevx-linux-amd64.tar; on Linux ARM (arm64, e.g. Graviton or Ampere) it is the same with openjevx-linux-arm64.tar instead. 9
The Linux builds need glibc 2.28 or later. 10
On Windows, unpack both into the same folder and run openjevx.exe. 11
There is no Intel-Mac build: ONNX Runtime 1.29 has none. 12
With no model set, the server looks next to itself for model/, then models/openjevx/, then openjevx.w8.onnx. 13 14
If none of those exists, it returns the error no model found: set "model" in openjevx.json, or put a model folder at followed by the paths it tried. 14
Path 2: the npx installer
Section titled “Path 2: the npx installer”The npx installer downloads release v0.5.9 with model 0.5.2. 15
It installs into ~/.local/share/openjevx (override with OPENJEVX_HOME) and puts the openjevx command in ~/.local/bin (override with OPENJEVX_BIN). 16
Its openjevx command does cd into the install folder and then runs the server binary. 17
It picks the archive by OS and CPU: Windows gets openjevx-windows-amd64.zip, macOS arm64 openjevx-darwin-arm64.tar, Linux x64 openjevx-linux-amd64.tar and Linux arm64 openjevx-linux-arm64.tar. 18
Any other OS and CPU stops the installer with OpenJevX: no server build for …. 19
On an Intel Mac the reason given is that ONNX Runtime 1.29 has no Intel macOS build, so OpenJevX runs on Apple Silicon only (or use Docker). 19
On an upgrade it reads your openjevx.json before unpacking and writes it back afterwards. 20
It then adds only the keys your file lacks (listen 127.0.0.1:21118, device auto); your values always win. 21 22
When it finishes, it says the dashboard password is printed once on the first start and kept in openjevx.password in the install folder. 23
Path 3: from source
Section titled “Path 3: from source”You need Go and Task. 24
task run fetches ONNX Runtime and the model folder into .local/, builds, and starts the server on http://127.0.0.1:21118/. 24
task build only builds; task test runs the tests. 24
task runtask buildtask testThe build uses cgo: CGO_ENABLED=1 go build -o .local/openjevx ./cmd/openjevx. 25
task setup supports macOS arm64, Linux x86_64 and Linux aarch64, and fails with “unsupported platform” elsewhere. 26
Path 4: the prebuilt Docker image
Section titled “Path 4: the prebuilt Docker image”The prebuilt image is for linux/amd64 and linux/arm64, tagged with each release and latest. 27
docker run -d -p 127.0.0.1:21118:21118 \ -e OPENJEVX_PASSWORD=<12+ characters> -e OPENJEVX_API_KEY=<16+ characters> \ ghcr.io/deemwar-products/openjevx:v0.5.9The image has no default credentials: it refuses to start without OPENJEVX_PASSWORD and OPENJEVX_API_KEY, or your own openjevx.json mounted at /data/openjevx.json. 28
Make a key with openssl rand -hex 24. 29
The container listens on 0.0.0.0; the api_key is on whenever the server listens beyond loopback. 30 31
First request
Section titled “First request”The server listens on 127.0.0.1:21118 unless openjevx.json says otherwise. 32 33
On that loopback address the API key is off unless you set one, so the request below needs no key. 34
Every recipe is one POST /v1/systemone with a state (the text or JSON the question is about) and named questions. 35
A noul question is a yes/no; read the probability of yes from noul. 36
The recipe call sends OPENJEVX_API_KEY; on 127.0.0.1 with no key set the server ignores the header, so the call works unchanged. 37 38
curl -s -H "Authorization: Bearer $OPENJEVX_API_KEY" localhost:21118/v1/systemone -d '{"state": "git push --force origin main", "questions": {"danger": {"type": "noul", "instructions": "Does this command overwrite history on a shared remote branch?"}}}' | jq -c .answersThe recipe recorded this answer from model 0.5.2 on server 0.5.7, CPU: 39
{"danger":{"action":{"act_probability":1},"answer_confidence":0.5513,"confidence":0.5513,"noul":0.5513,"probabilities":{"false":0.4487,"true":0.5513},"type":"noul"}}The model missed this one: P(yes) 0.55, so jevx says unsure; treat unsure as yes for anything that rewrites shared history. 40
Your inputs will score differently: copy the pattern, not the numbers, and test on your own data. 41
The full response is {"model":"openjevx","answers":...,"usage":{"input_tokens":...,"output_tokens":0,"server_ms":...}}. 42
Each response also carries a Server-Timing header with encode, wait, run and total in ms. 43 44 45
A non-POST request gets 405, and a body with no questions gets 400 questions missing. 46 47
GET /health is open, with no password. 48
curl -fsS http://127.0.0.1:21118/health/health returns status, device, model, version, sha256, source, fallback, loaded_at and dir. 49
Security defaults you must know
Section titled “Security defaults you must know”Warning
/v1/systemoneneedsAuthorization: Bearer <key>whenever the server listens beyond loopback; on127.0.0.1,::1andlocalhostthe key is off unless one is set. 50 With nolisteninopenjevx.json, the server listens on127.0.0.1:21118, a loopback address. 51 52 When you set a non-loopbacklistenand no key, the server generates one intoopenjevx.api-keybesideopenjevx.json. 34 The deploy paths all listen beyond loopback, so they need the API key and the dashboard password; there are no default credentials anywhere. 53 Their firewall still opens only SSH; the customer opens port 21118 to their own network or uses an SSH tunnel. 54
curl -H "Authorization: Bearer YOUR_API_KEY" http://<host>:21118/v1/systemone -d @body.jsonWarning
The dashboard password is always on: unset, the server generates one into
openjevx.password. 55 A start that creates it shows the value once, and only on a terminal. 56 When stderr is a log (Docker, systemd, ECS, CloudWatch), it logs the file and a fingerprint (sha256 ...37dd), never the secret, so read it from the file. 57 The routes behind that password are the dashboard/,/stats,/metricsand/recipes. 55
The old published password adminadmin (in openjevx.json up to v0.5.6) is ignored and replaced by a generated one. 58
Set your own with "password" in openjevx.json or OPENJEVX_PASSWORD. 59
With a password set, the guard accepts HTTP Basic auth (any user name) or a ?password= query parameter. 60
allow_no_password (or OPENJEVX_ALLOW_NO_PASSWORD=1) turns the dashboard password off. 61
Use it from jevx
Section titled “Use it from jevx”Use OpenJevX from the jevx CLI by adding a profile for its URL and selecting it. 62
jevx profile add openjevx http://127.0.0.1:21118/v1/systemone --model openjevxjevx profile use openjevxWith an API key (any server not on loopback), let jevx read it from the environment. 63
jevx profile add openjevx http://<host>:21118/v1/systemone --model openjevx --header 'Authorization: Bearer $OPENJEVX_API_KEY'jevx caches answers for 7 days, keyed by the profile’s model name. 64
After upgrading the OpenJevX model, run jevx cache clear, or give the profile a versioned model name such as openjevx-0.5.2. 65
jevx cache clearjevx’s default thresholds: act on noul at or above 0.8, act on the no at or below 0.2, and on confidence at or above 0.6 for a choice or score. 66
Anything in between means: narrow the question, check it yourself, or ask the user. 67
Next: Configuration covers every key, and Model from object storage covers serving the model from a bucket.
Sources
Section titled “Sources”Footnotes
Section titled “Footnotes”-
openjevx @ v0.5.9 (ee2a1f4) ·
README.mdL65 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
package.jsonL3 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
deploy/MODEL_VERSIONL1 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
scripts/package.shL5 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
scripts/package.shL37 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
scripts/package.shL6 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
README.mdL137–146 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
bin/platform.jsL1–2 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
README.mdL148–150 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
docs/adr/0011-inference-runtime.mdL30 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
cmd/openjevx/model.goL25 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
cmd/openjevx/model.goL64–70 ↩ ↩2 -
openjevx @ v0.5.9 (ee2a1f4) ·
bin/openjevx.jsL10–13 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
bin/openjevx.jsL15–16 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
bin/openjevx.jsL71–76 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
bin/platform.jsL3–7 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
bin/openjevx.jsL54–61 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
bin/config.jsL1–2 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
bin/config.jsL11–14 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
bin/openjevx.jsL82 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
Taskfile.ymlL32–36 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
Taskfile.ymlL15–19 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
README.mdL154 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
README.mdL169–170 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
README.mdL171 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
deploy/docker-entrypoint.shL16 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
cmd/openjevx/auth.goL21–23 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
cmd/openjevx/main.goL447–449 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
cmd/openjevx/main.goL474–476 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
recipes/README.mdL34–35 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
recipes/README.mdL37–39 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
recipes/07-is-this-command-dangerous.mdL7 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
recipes/README.mdL21–22 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
recipes/07-is-this-command-dangerous.mdL13 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
recipes/07-is-this-command-dangerous.mdL37 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
recipes/README.mdL50 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
cmd/openjevx/decision.goL96–100 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
cmd/openjevx/decision.goL19–20 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
cmd/openjevx/decision.goL95 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
cmd/openjevx/decision.goL112–115 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
cmd/openjevx/decision.goL23–26 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
cmd/openjevx/decision.goL56–59 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
README.mdL208 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
cmd/openjevx/main.goL190–194 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
cmd/openjevx/auth.goL22–23 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
cmd/openjevx/main.goL447–448 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
cmd/openjevx/main.goL460–462 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
docs/DEPLOY.mdL14–16 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
docs/DEPLOY.mdL19–20 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
README.mdL38–39 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
README.mdL38–40 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
README.mdL42–43 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
README.mdL202 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
cmd/openjevx/main.goL514–525 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
README.mdL34 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
README.mdL175–180 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
README.mdL182 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
recipes/README.mdL87–88 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
recipes/README.mdL87–89 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
recipes/README.mdL77–84 ↩ -
openjevx @ v0.5.9 (ee2a1f4) ·
recipes/README.mdL81 ↩