Typed decisions for software.
Send context. Ask choice, score, or noul.
Get calibrated probabilities — not a paragraph to parse.
Install · Docs site · Quick start · Benchmarks · Why Kev · Playground · SDKs · Migrate from Jev
npm install @kev-ai/sdk
npm install -g @kev-ai/server @kev-ai/cli| Package | What | npm |
|---|---|---|
@kev-ai/sdk |
TypeScript client (choice / score / noul) |
npmjs.com/package/@kev-ai/sdk |
@kev-ai/server |
Decision API + playground → kev-server |
npmjs.com/package/@kev-ai/server |
@kev-ai/cli |
CLI + MCP → kev / kev-mcp |
npmjs.com/package/@kev-ai/cli |
kev-server # http://127.0.0.1:3000 (+ /playground/)
kev demo
kev healthLangChain / LlamaIndex: @kev-ai/sdk/langchain · @kev-ai/sdk/llamaindex
PyPI coming later.
curl -s http://127.0.0.1:3000/v1/systemone \
-H 'Content-Type: application/json' \
-d '{
"state": "Charged twice. I am furious.",
"questions": {
"topic": {
"type": "choice",
"instructions": "Which team?",
"criteria": {
"billing": "charges and refunds",
"technical": "bugs and outages"
}
},
"escalate": {
"type": "noul",
"instructions": "Escalate to a human now?"
}
}
}'{
"answers": {
"topic": {
"type": "choice",
"choice": "billing",
"confidence": 0.97,
"probabilities": { "billing": 0.97, "technical": 0.03 }
},
"escalate": { "type": "noul", "noul": 0.86 }
}
}if (answers.escalate.noul > 0.7) routeToHuman();
else assign(answers.topic.choice);NotJev : Kev is an open-source System One decision engine: Apache-2.0, self-hosted, Jev-style wire format. Bring your own model (Ollama, vLLM, OpenAI-compatible) — or start with the built-in mock.
Independent project. Not affiliated with TypeSafe AI or OpenJev.
Product docs, benchmark write-ups, and a fixed Try it workbench live in the companion Next.js site (sibling repo / folder NotJev-Kev-Website):
cd ../NotJev-Kev-Website # or clone your website repo
npm install && npm run devRoutes: / · /docs · /docs/benchmarks · /docs/why · /try (showcase workbench).
GitHub on that site always points here — engine source stays in this repo.
NotJev : Kev turns an LLM into a typed classifier / gate / scorer your app can trust:
| Primitive | Returns | Use for |
|---|---|---|
choice |
Winning key + full distribution | Routing, intent, triage (≤255 options; cascade for larger) |
score |
Ordinal level + distribution | Urgency, quality, sentiment |
noul |
Probability in [0, 1] |
Escalate? Toxic? Block? Page on-call? |
You do not train models. You do not parse chat. You threshold numbers.
| You need | Chat gives you | Kev gives you |
|---|---|---|
| A label | Prose you must regex | A typed key + probabilities |
| A gate | “I think so…” | noul you can threshold |
| Confidence | Vibes | Concentration of the distribution |
| Many judgments | N serial prompts | One request, questions in parallel |
| Control | Vendor lock-in | Your GPU / API / laptop |
| Hosted Jev / OpenJev | NotJev : Kev | |
|---|---|---|
| License | Proprietary / mixed | Apache-2.0 |
| Deploy | Their cloud / their weights | Self-host anywhere |
| Models | Fixed stack | BYO — Ollama, vLLM, OpenAI, Gemini-compat, … |
| Wire format | System One | Same shape (choice / score / noul) |
| Offline | No | Mock backend for CI & demos |
| DX | API key | Playground · SDK · CLI · MCP · LangChain / LlamaIndex |
| Training | N/A for you | None — inference + API only |
NotJev : Kev is the open control plane. The intelligence is whatever model you point it at.
Same public held-out suite used around OpenJev: s1lv3rj1nx/openjev-heldout.
Model: qwen3.5:9b via Ollama · 100% GPU.
| Task | Primitive | Kev | Chance | Reference |
|---|---|---|---|---|
| Banking77 | choice (77) · n=600 | 83% | 1.3% | Jev ~82% held-out · JevBench 80.3% |
| CLINC OOS | choice (151) · n=600 | 86% | 0.7% | — |
| AG News | choice (4) · n=600 | 86.5% | 25.0% | — |
| SST-5 | score (5) · n=600 | 89.5% within-1 | 20.0% | ordinal ±1 |
| Civil Comments | noul · n=600 | 81% | 50.0% | — |
OpenJev’s private 10k mix (cite only): Jev 85.4% · OpenJev 84.0% — questions not fully public, so we don’t invent a fake score against it.
Kev’s preferred path is letter-token readout when the backend exposes logprobs; on Ollama that falls back to constrained decode (still first-shot, no JSON retries). Measured on qwen3.5:9b · 100% GPU:
| Metric | qwen3.5:9b (warm GPU) |
|---|---|
| p50 / p95 (2 questions) | 504 / 803 ms |
| Parse-fail / format hallucination | 0% |
| Rerun agreement flip / KL | 0% / 0 |
| Multi-Q @15 parse-fail | 0% |
| Multi-Q @1 → @15 p50 | 443 → 8011 ms (~linear) |
| Confidence @15 vs @1 | ~1.17× (no drop) |
# Accuracy (held-out)
pnpm bench:heldout -- --mode api --base-url http://127.0.0.1:3000 \
--tasks banking77,clinc_oos,ag_news,sst5,civil_comments_toxicity
# Speed + agreement + multi-Q
pnpm bench:ops -- --mode api --base-url http://127.0.0.1:3000 --trials 10Details: benchmarks/RESULTS.md · benchmarks/METHODOLOGY.md
Requirements: Node 20+, pnpm 9.
git clone https://github.com/arjun988/Kev.git
cd Kev
pnpm install
pnpm build
cp .env.example .env
pnpm --filter @kev-ai/server start| Open | URL |
|---|---|
| Playground | http://127.0.0.1:3000/playground/ |
| Health | http://127.0.0.1:3000/health |
| OpenAPI | http://127.0.0.1:3000/openapi.json |
Use a real local model (Ollama)
ollama pull qwen3.5:9b # or llama3.2, etc.KEV_BACKEND=ollama
KEV_OLLAMA_MODEL=qwen3.5:9bRestart the server. Confirm GPU with ollama ps → 100% GPU.
Windows: corepack enable fails with EPERM?
iwr https://get.pnpm.io/install.ps1 -useb | iex
# restart the terminal, then pnpm install && pnpm buildPython SDK
cd python && pip install -e . && cd ..A built-in UI for support routing, moderation, content scoring, vision triage, and intent — with probability bars and raw JSON.
→ http://127.0.0.1:3000/playground/
Published packages (npm org @kev-ai · PyPI kev):
npm install @kev-ai/sdk
npm install -g @kev-ai/server @kev-ai/cli # API + playground + CLI/MCP
pip install kevSee PUBLISH.md if you maintain the packages.
import { Choice, KevClient, Noul, Score } from "@kev-ai/sdk";
const client = new KevClient({ baseUrl: "http://127.0.0.1:3000" });
const res = await client.systemOne({
state: "Package stuck in transit for a week. Tracking frozen.",
questions: {
topic: Choice("Which team?", {
billing: "charges",
shipping: "delivery / tracking",
technical: "bugs",
}),
severity: Score("How urgent?", [
"can wait",
"this week",
"today",
"right now",
]),
escalate: Noul("Page a human?"),
},
});
console.log(res.answers.topic.choice, res.answers.escalate.noul);LangChain / LlamaIndex (same package):
import { createLangChainKevTool } from "@kev-ai/sdk/langchain";
import { createLlamaIndexKevTool } from "@kev-ai/sdk/llamaindex";from kev import KevClient, Choice, Noul
client = KevClient(base_url="http://127.0.0.1:3000")
res = client.system_one(
state="Charged twice. Furious.",
questions={
"topic": Choice("Which team?", {"billing": "charges", "technical": "bugs"}),
"escalate": Noul("Escalate now?"),
},
)
print(res.answers["topic"].choice, res.answers["escalate"].noul)kev-server # Decision API + playground
kev health
kev demo
kev ask --state "Charged twice" --trace
kev-mcp # MCP stdio (Cursor / agents){
"mcpServers": {
"kev": {
"command": "kev-mcp",
"env": { "KEV_BASE_URL": "http://127.0.0.1:3000" }
}
}
}From a clone (without global install):
pnpm --filter @kev-ai/cli exec kev demo
pnpm --filter @kev-ai/cli exec kev eval stability --trials 20
pnpm --filter @kev-ai/cli exec kev eval agreement --trials 20
pnpm --filter @kev-ai/cli exec kev eval multiq --multi-trials 5
pnpm bench:opsYour app ──POST /v1/systemone──► Kev server
▲ state + questions │
│ ├─ validate (schema)
│ ├─ decide (strategy)
└──── typed answers + probs ────────┘
│
┌──────────────────────────┼──────────────────────────┐
▼ ▼ ▼
logprob readout constrained JSON parallel micro-score
(when available) (JSON mode) (fallback)
└──────────────────────────┬──────────────────────────┘
▼
Ollama · vLLM · OpenAI-compatible · mock
KEV_STRATEGY=auto picks the best path for your backend. Large choice sets cascade when needed. Optional: batch API, cache, rate limits, audit, traces.
- System One primitives —
choice·score·noulwith calibrated distributions - Self-host first — Docker-friendly, playground, OpenAPI
- BYO model — mock · Ollama · any OpenAI-compatible endpoint
- Production knobs — API keys, rate limits, LRU cache, audit log, OTel-style spans
- Agent-ready — MCP server, LangChain / LlamaIndex adapters,
images[]in state - Scale —
cascadeChoice()for big taxonomies - Honest eval — held-out suite, ops latency/agreement/multi-Q, stability tests, published fixtures
KEV_BACKEND |
When |
|---|---|
mock |
Offline demos & CI |
ollama |
Local GPU/CPU models |
openai |
OpenAI, vLLM, Groq, Together, Gemini OpenAI-compat, MLX, … |
KEV_BACKEND=ollama
KEV_OLLAMA_MODEL=qwen3.5:9bModel recipes: models/cards/
| Install | |
|---|---|
| TypeScript SDK | npm i @kev-ai/sdk |
| Server + playground | npm i -g @kev-ai/server → kev-server |
| CLI + MCP | npm i -g @kev-ai/cli → kev / kev-mcp |
| Python | pip install kev |
| LangChain / LlamaIndex | @kev-ai/sdk/langchain · @kev-ai/sdk/llamaindex |
| Recipes | awesome-kev/ |
| Snippets | .vscode/kev.code-snippets |
Publish notes: PUBLISH.md
Point the base URL at NotJev : Kev. Re-tune thresholds on your labels.
export TYPESAFE_BASE_URL=http://127.0.0.1:3000
# or
export KEV_BASE_URL=http://127.0.0.1:3000Full guide: MIGRATION.md
apps/server Decision API + playground host
apps/playground Local workbench UI
apps/mcp MCP server
packages/* schema · core · backends · sdk · cli · eval · adapters
python/kev Python client
benchmarks/ Held-out suite + fixtures
awesome-kev/ Recipes
models/ Model cards · calibration · dataset notes
Kev 1.0 freezes the System One HTTP contract in GET /openapi.json.
| MAJOR | Breaking wire changes |
| MINOR | Additive endpoints / fields |
| PATCH | Fixes and docs |
See CHANGELOG.md.
Kev — decisions software can trust.
Ask for a label. Get a distribution.