{"slug": "jev-give-any-coding-agent-claude-code-codex-opencode-a-calibrated-gut-check-a-a", "title": "jev: give any coding agent (Claude Code, Codex, OpenCode) a calibrated gut check. A zero-dependency CLI + a global skill that wraps TypeSafe's Jev decision model, so an agent can classify, filter,…", "summary": "A developer released jev, a zero-dependency Python CLI and library that wraps TypeSafe's Jev decision model so coding agents like Claude Code, Codex, and OpenCode can classify, filter, rank, or verify hundreds of items in a single ~250 ms call without loading them into context. The tool returns calibrated probabilities for yes/no, choice, and rubric-score questions at $0.042 per million input tokens, and ships with usage and cost tracking, a one-line installer, and documentation of a measured pitfall the vendor docs omit.", "body_md": "|  | #!/usr/bin/env python3 | \n|  | \"\"\"jev: calibrated, typed decisions from TypeSafe's Jev model, for agents. | \n|  |  | \n|  | Jev is a \"System One\" model. It does not generate text. You hand it a STATE | \n|  | (text or JSON) and typed QUESTIONS, and it returns typed answers with | \n|  | calibrated probabilities in ~250 ms for $0.042 per million input tokens. | \n|  |  | \n|  | noul    yes/no        -> probability that the answer is yes (0..1) | \n|  | choice  pick one      -> chosen option + probability per option + confidence | \n|  | score   rate on rubric-> position on your ordered levels + confidence | \n|  |  | \n|  | Progressive disclosure: | \n|  | jev                 short help (this) | \n|  | jev guide           the agent playbook: when to use it, how to ask, how to read | \n|  | jev guide <topic>   depth on one topic (jev guide --list) | \n|  | jev examples        copy-paste examples for the common jobs | \n|  | jev docs            live index of the vendor docs | \n|  |  | \n|  | Zero dependencies. Importable as a library: | \n|  | sys.path.insert(0, \"/path/to/dir/containing/jev.py\") | \n|  | from jev import JevClient, noul, choice, score | \n|  |  | \n|  | Auth: --api-key, else $TYPESAFE_API_KEY, else ~/.config/typesafe/api_key (0600). | \n|  | \"\"\" | \n|  |  | \n|  | from __future__ import annotations | \n|  |  | \n|  | import argparse | \n|  | import concurrent.futures as cf | \n|  | import json | \n|  | import os | \n|  | import random | \n|  | import sys | \n|  | import time | \n|  | import urllib.error | \n|  | import urllib.request | \n|  | from datetime import datetime, timedelta | \n|  | from pathlib import Path | \n|  |  | \n|  | VERSION = \"1.0.0\" | \n|  | API_BASE = os.environ.get(\"TYPESAFE_BASE_URL\", \"https://api.typesafe.ai\").rstrip(\"/\") | \n|  | DEFAULT_MODEL = os.environ.get(\"TYPESAFE_DEFAULT_MODEL\", \"jev-latest\") | \n|  | CONFIG_DIR = Path.home() / \".config\" / \"typesafe\" | \n|  | KEY_FILE = CONFIG_DIR / \"api_key\" | \n|  | USAGE_FILE = CONFIG_DIR / \"usage.jsonl\" | \n|  | CONFIG_FILE = CONFIG_DIR / \"config.json\" | \n|  | PRICE_PER_MTOK_IN = 0.042  # USD per million input tokens (jev-1.13 list price); output tokens are free | \n|  | RATE_LIMIT_RPM = 1200  # vendor-published, adjusts without notice | \n|  | RATE_LIMIT_TPS = 250_000 | \n|  | DOCS = \"https://docs.typesafe.ai\" | \n|  | MAX_CHOICE_OPTIONS = 255 | \n|  | MAX_SCORE_LEVELS = 10 | \n|  | STATE_CHAR_BUDGET = 120_000  # ~30k tokens; the state+longest-question budget is 32k tokens | \n|  |  | \n|  | # --------------------------------------------------------------------------- errors | \n|  |  | \n|  |  | \n|  | class JevError(Exception): | \n|  | exit_code = 4  # API error after retries | \n|  |  | \n|  |  | \n|  | class UsageError(JevError): | \n|  | exit_code = 2 | \n|  |  | \n|  |  | \n|  | class AuthError(JevError): | \n|  | exit_code = 3 | \n|  |  | \n|  |  | \n|  | class NetworkError(JevError): | \n|  | exit_code = 5 | \n|  |  | \n|  |  | \n|  | # --------------------------------------------------------------------------- auth | \n|  |  | \n|  |  | \n|  | def resolve_key(explicit: str \\| None = None) -> tuple[str, str]: | \n|  | \"\"\"Return (key, source). Order: explicit, $TYPESAFE_API_KEY, key file.\"\"\" | \n|  | if explicit: | \n|  | return explicit.strip(), \"--api-key\" | \n|  | env = os.environ.get(\"TYPESAFE_API_KEY\", \"\").strip() | \n|  | if env: | \n|  | return env, \"$TYPESAFE_API_KEY\" | \n|  | if KEY_FILE.exists(): | \n|  | key = KEY_FILE.read_text().strip() | \n|  | if key: | \n|  | return key, str(KEY_FILE) | \n|  | raise AuthError( | \n|  | \"no API key. Run `jev auth set <key>` (stored 0600 in \" | \n|  | f\"{KEY_FILE}) or export TYPESAFE_API_KEY. Keys: https://console.typesafe.ai/keys\" | \n|  | ) | \n|  |  | \n|  |  | \n|  | def mask(key: str) -> str: | \n|  | return key[:10] + \"…\" + key[-4:] if len(key) > 16 else \"…\" | \n|  |  | \n|  |  | \n|  | # --------------------------------------------------------------------------- question builders | \n|  |  | \n|  |  | \n|  | def noul(instructions, true=None, false=None) -> dict: | \n|  | \"\"\"Yes/no question. Returns P(yes). Optional criteria say what yes and no mean.\"\"\" | \n|  | q = {\"type\": \"noul\", \"instructions\": instructions} | \n|  | if true is not None or false is not None: | \n|  | crit = {} | \n|  | if true is not None: | \n|  | crit[\"true\"] = true | \n|  | if false is not None: | \n|  | crit[\"false\"] = false | \n|  | q[\"criteria\"] = crit | \n|  | return q | \n|  |  | \n|  |  | \n|  | def choice(instructions, options) -> dict: | \n|  | \"\"\"Pick one option. `options` is a dict {name: description\\|None} or a list of names.\"\"\" | \n|  | if isinstance(options, (list, tuple)): | \n|  | options = {str(o): None for o in options} | \n|  | return {\"type\": \"choice\", \"instructions\": instructions, \"criteria\": dict(options)} | \n|  |  | \n|  |  | \n|  | def score(instructions, levels) -> dict: | \n|  | \"\"\"Rate on an ordered rubric. `levels` is an ordered list, low to high, 2..10 entries.\"\"\" | \n|  | return {\"type\": \"score\", \"instructions\": instructions, \"criteria\": list(levels)} | \n|  |  | \n|  |  | \n|  | def validate_questions(questions: dict) -> None: | \n|  | if not isinstance(questions, dict) or not questions: | \n|  | raise UsageError(\"questions must be a non-empty map of id -> question\") | \n|  | for qid, q in questions.items(): | \n|  | if not isinstance(q, dict) or \"type\" not in q: | \n|  | raise UsageError(f\"question {qid!r}: must be an object with a `type`\") | \n|  | t = q[\"type\"] | \n|  | if t not in (\"noul\", \"choice\", \"score\"): | \n|  | raise UsageError(f\"question {qid!r}: type must be noul, choice or score, not {t!r}\") | \n|  | if \"instructions\" not in q: | \n|  | raise UsageError(f\"question {qid!r}: missing `instructions`\") | \n|  | crit = q.get(\"criteria\") | \n|  | if t == \"choice\": | \n|  | if not isinstance(crit, dict) or len(crit) < 2: | \n|  | raise UsageError(f\"choice {qid!r}: criteria must map at least 2 options to descriptions (null allowed)\") | \n|  | if len(crit) > MAX_CHOICE_OPTIONS: | \n|  | raise UsageError(f\"choice {qid!r}: at most {MAX_CHOICE_OPTIONS} options\") | \n|  | elif t == \"score\": | \n|  | if not isinstance(crit, list) or not 2 <= len(crit) <= MAX_SCORE_LEVELS: | \n|  | raise UsageError(f\"score {qid!r}: criteria must be an ordered list of 2..{MAX_SCORE_LEVELS} level descriptions\") | \n|  | elif t == \"noul\" and crit is not None: | \n|  | if not isinstance(crit, dict) or not set(crit) <= {\"true\", \"false\"}: | \n|  | raise UsageError(f\"noul {qid!r}: criteria may only have `true` and `false` keys\") | \n|  |  | \n|  |  | \n|  | # --------------------------------------------------------------------------- client | \n|  |  | \n|  |  | \n|  | class JevClient: | \n|  | \"\"\"Thin HTTP client with retries. `ask()` returns the raw API response dict.\"\"\" | \n|  |  | \n|  | def __init__(self, api_key=None, model=None, timeout=30.0, retries=5, base_url=None, record=True, label=\"lib\"): | \n|  | self.api_key, self.key_source = resolve_key(api_key) | \n|  | self.model = model or DEFAULT_MODEL | \n|  | self.timeout = timeout | \n|  | self.retries = retries | \n|  | self.base_url = (base_url or API_BASE).rstrip(\"/\") | \n|  | self.record = record | \n|  | self.label = label | \n|  | self.last_ms = 0.0 | \n|  | self.last_request_id = \"\" | \n|  | self.last_attempts = 0 | \n|  |  | \n|  | def _request(self, method: str, path: str, body=None) -> dict: | \n|  | data = json.dumps(body).encode() if body is not None else None | \n|  | headers = { | \n|  | \"Authorization\": f\"Bearer {self.api_key}\", | \n|  | \"Content-Type\": \"application/json\", | \n|  | \"User-Agent\": f\"jev-cli/{VERSION}\", | \n|  | } | \n|  | attempt = 0 | \n|  | while True: | \n|  | attempt += 1 | \n|  | req = urllib.request.Request(self.base_url + path, data=data, method=method, headers=headers) | \n|  | t0 = time.time() | \n|  | try: | \n|  | with urllib.request.urlopen(req, timeout=self.timeout) as r: | \n|  | self.last_ms = (time.time() - t0) * 1000 | \n|  | self.last_request_id = r.headers.get(\"x-typesafe-request-id\", \"\") | \n|  | self.last_attempts = attempt | \n|  | return json.loads(r.read().decode()) | \n|  | except urllib.error.HTTPError as e: | \n|  | self.last_ms = (time.time() - t0) * 1000 | \n|  | text = e.read().decode(errors=\"replace\") | \n|  | if e.code in (401, 403): | \n|  | raise AuthError(f\"HTTP {e.code}: API key rejected ({self.key_source}). {text[:300]}\") | \n|  | if e.code in (429, 529) or e.code >= 500: | \n|  | if attempt <= self.retries: | \n|  | ra = e.headers.get(\"retry-after\") | \n|  | delay = float(ra) if ra and ra.replace(\".\", \"\", 1).isdigit() else min(8.0, 0.5 * 2 ** (attempt - 1)) | \n|  | time.sleep(delay + random.uniform(0, 0.25)) | \n|  | continue | \n|  | raise JevError(f\"HTTP {e.code} after {attempt} attempts: {text[:300]}\") | \n|  | raise JevError(f\"HTTP {e.code}: {text[:600]}\") | \n|  | except (urllib.error.URLError, TimeoutError, OSError) as e: | \n|  | if attempt <= self.retries: | \n|  | time.sleep(min(8.0, 0.5 * 2 ** (attempt - 1))) | \n|  | continue | \n|  | raise NetworkError(f\"network error after {attempt} attempts: {e}\") | \n|  |  | \n|  | def models(self) -> dict: | \n|  | return self._request(\"GET\", \"/v1/models\") | \n|  |  | \n|  | def ask(self, state, questions: dict, model: str \\| None = None) -> dict: | \n|  | \"\"\"POST /v1/systemone. `state` is str\\|dict\\|list. Returns the raw response.\"\"\" | \n|  | if state is None or state == \"\" or state == {} or state == []: | \n|  | raise UsageError(\"state is empty\") | \n|  | validate_questions(questions) | \n|  | body = {\"state\": state, \"model\": model or self.model, \"questions\": questions} | \n|  | try: | \n|  | resp = self._request(\"POST\", \"/v1/systemone\", body) | \n|  | except JevError as e: | \n|  | if self.record: | \n|  | record_usage(None, self, len(questions), err=e) | \n|  | raise | \n|  | if self.record: | \n|  | record_usage(resp, self, len(questions)) | \n|  | return resp | \n|  |  | \n|  |  | \n|  | def load_config() -> dict: | \n|  | try: | \n|  | return json.loads(CONFIG_FILE.read_text()) if CONFIG_FILE.exists() else {} | \n|  | except (OSError, json.JSONDecodeError): | \n|  | return {} | \n|  |  | \n|  |  | \n|  | def save_config(cfg: dict) -> None: | \n|  | CONFIG_DIR.mkdir(parents=True, exist_ok=True) | \n|  | CONFIG_FILE.write_text(json.dumps(cfg, indent=2) + \"\\n\") | \n|  |  | \n|  |  | \n|  | def price_per_mtok() -> float: | \n|  | v = load_config().get(\"price_per_mtok_in\") | \n|  | return float(v) if v else PRICE_PER_MTOK_IN | \n|  |  | \n|  |  | \n|  | def record_usage(resp: dict \\| None, client: \"JevClient\", n_questions: int, err: Exception \\| None = None) -> None: | \n|  | \"\"\"Append one row per request (success or failure) to the local ledger.\"\"\" | \n|  | try: | \n|  | CONFIG_DIR.mkdir(parents=True, exist_ok=True) | \n|  | row = { | \n|  | \"ts\": datetime.now().isoformat(timespec=\"seconds\"), | \n|  | \"cmd\": client.label, | \n|  | \"agent\": os.environ.get(\"JEV_AGENT\") or os.environ.get(\"AGENT_ID\") or \"\", | \n|  | \"q\": n_questions, | \n|  | \"ms\": round(client.last_ms), | \n|  | } | \n|  | if resp is not None: | \n|  | u = resp.get(\"usage\") or {} | \n|  | row.update({\"model\": resp.get(\"model\"), \"in\": u.get(\"input_tokens\", 0), \"out\": u.get(\"output_tokens\", 0)}) | \n|  | if client.last_request_id: | \n|  | row[\"rid\"] = client.last_request_id | \n|  | if client.last_attempts > 1: | \n|  | row[\"attempts\"] = client.last_attempts | \n|  | else: | \n|  | msg = str(err) | \n|  | code = msg.split(\":\", 1)[0].replace(\"HTTP \", \"\").strip() if msg.startswith(\"HTTP\") else type(err).__name__ | \n|  | row.update({\"in\": 0, \"out\": 0, \"err\": code}) | \n|  | with USAGE_FILE.open(\"a\") as f: | \n|  | f.write(json.dumps(row) + \"\\n\") | \n|  | except OSError: | \n|  | pass | \n|  |  | \n|  |  | \n|  | def cost_usd(input_tokens: int) -> float: | \n|  | return input_tokens / 1_000_000 * price_per_mtok() | \n|  |  | \n|  |  | \n|  | # --------------------------------------------------------------------------- input parsing | \n|  |  | \n|  |  | \n|  | def parse_value(v: str): | \n|  | \"\"\"`@path` reads a file (.json parsed). JSON-looking text is parsed. Else string.\"\"\" | \n|  | if v.startswith(\"@\"): | \n|  | p = Path(v[1:]).expanduser() | \n|  | if not p.exists(): | \n|  | raise UsageError(f\"file not found: {p}\") | \n|  | txt = p.read_text() | \n|  | if p.suffix.lower() in (\".json\", \".jsonl\"): | \n|  | try: | \n|  | return json.loads(txt) if p.suffix.lower() == \".json\" else [json.loads(line) for line in txt.splitlines() if line.strip()] | \n|  | except json.JSONDecodeError as e: | \n|  | raise UsageError(f\"{p}: invalid JSON: {e}\") | \n|  | return txt | \n|  | s = v.strip() | \n|  | if s and s[0] in \"{[\" or s in (\"true\", \"false\", \"null\"): | \n|  | try: | \n|  | return json.loads(s) | \n|  | except json.JSONDecodeError: | \n|  | pass | \n|  | return v | \n|  |  | \n|  |  | \n|  | def build_state(args) -> object: | \n|  | srcs = [n for n in (\"state\", \"state_file\", \"state_json\") if getattr(args, n, None)] | \n|  | if len(srcs) > 1: | \n|  | raise UsageError(\"give the state one way: --state, --state-file, or --state-json (--field may be added to any of them, and becomes `text`)\") | \n|  | state = None | \n|  | if getattr(args, \"state\", None): | \n|  | state = sys.stdin.read() if args.state == \"-\" else (parse_value(args.state) if args.state.startswith(\"@\") else args.state) | \n|  | elif getattr(args, \"state_file\", None): | \n|  | state = parse_value(\"@\" + args.state_file) | \n|  | elif getattr(args, \"state_json\", None): | \n|  | try: | \n|  | state = json.loads(args.state_json) | \n|  | except json.JSONDecodeError as e: | \n|  | raise UsageError(f\"--state-json: invalid JSON: {e}\") | \n|  | if getattr(args, \"field\", None): | \n|  | obj = {} | \n|  | if state is not None: | \n|  | obj[\"text\"] = state | \n|  | for kv in args.field: | \n|  | if \"=\" not in kv: | \n|  | raise UsageError(f\"--field expects key=value, got {kv!r}\") | \n|  | k, v = kv.split(\"=\", 1) | \n|  | obj[k.strip()] = parse_value(v) | \n|  | state = obj | \n|  | if state is None: | \n|  | state = implicit_stdin() | \n|  | if not state: | \n|  | raise UsageError(\"no state. Use --state TEXT, --state-file PATH, --state-json JSON, --field k=v, or pipe text on stdin\") | \n|  | n = len(state) if isinstance(state, str) else len(json.dumps(state)) | \n|  | if n > STATE_CHAR_BUDGET: | \n|  | eprint(f\"jev: warning: state is {n:,} chars (~{n // 4:,} tokens); the per-request budget is ~32k tokens for state + longest question. Filter first, or use `jev batch`/` jev rank` which chunk.\") | \n|  | return state | \n|  |  | \n|  |  | \n|  | def implicit_stdin(timeout: float = 1.5) -> str \\| None: | \n|  | \"\"\"Read stdin only when it is not a terminal AND has data ready. A harness that leaves | \n|  | stdin open with no writer would otherwise block forever; `--state -` forces a blocking read.\"\"\" | \n|  | if sys.stdin is None or sys.stdin.isatty(): | \n|  | return None | \n|  | try: | \n|  | import select | \n|  | ready, _, _ = select.select([sys.stdin], [], [], timeout) | \n|  | if not ready: | \n|  | return None | \n|  | except (OSError, ValueError): | \n|  | pass | \n|  | return sys.stdin.read() | \n|  |  | \n|  |  | \n|  | def parse_kv_options(items: list[str]) -> dict: | \n|  | \"\"\"['billing=Payments', 'sales'] -> {'billing': 'Payments', 'sales': None}\"\"\" | \n|  | out = {} | \n|  | for it in items: | \n|  | if \"=\" in it: | \n|  | k, v = it.split(\"=\", 1) | \n|  | out[k.strip()] = parse_value(v) if v != \"\" else None | \n|  | else: | \n|  | out[it.strip()] = None | \n|  | return out | \n|  |  | \n|  |  | \n|  | class QAction(argparse.Action): | \n|  | \"\"\"Collects --noul/--choice/--score in declaration order.\"\"\" | \n|  |  | \n|  | def __call__(self, parser, ns, values, option_string=None): | \n|  | lst = getattr(ns, \"qlist\", None) or [] | \n|  | lst.append((self.dest, list(values))) | \n|  | ns.qlist = lst | \n|  |  | \n|  |  | \n|  | def questions_from_args(args) -> dict: | \n|  | qs: dict = {} | \n|  | if getattr(args, \"questions_file\", None): | \n|  | v = parse_value(\"@\" + args.questions_file) | \n|  | if not isinstance(v, dict): | \n|  | raise UsageError(\"--questions-file must contain a JSON object of id -> question\") | \n|  | qs.update(v) | \n|  | if getattr(args, \"questions_json\", None): | \n|  | try: | \n|  | qs.update(json.loads(args.questions_json)) | \n|  | except json.JSONDecodeError as e: | \n|  | raise UsageError(f\"--questions-json: invalid JSON: {e}\") | \n|  | for kind, vals in getattr(args, \"qlist\", None) or []: | \n|  | if len(vals) < 2: | \n|  | raise UsageError(f\"--{kind} needs ID INSTRUCTIONS [...]\") | \n|  | qid, instr, rest = vals[0], parse_value(vals[1]), vals[2:] | \n|  | if kind == \"noul\": | \n|  | kv = parse_kv_options(rest) | \n|  | extra = set(kv) - {\"true\", \"false\"} | \n|  | if extra: | \n|  | raise UsageError(f\"--noul {qid}: after the instructions only true=... and false=... are allowed, got {sorted(extra)}\") | \n|  | qs[qid] = noul(instr, kv.get(\"true\"), kv.get(\"false\")) | \n|  | elif kind == \"choice\": | \n|  | if len(rest) < 2: | \n|  | raise UsageError(f\"--choice {qid}: give at least 2 options as NAME or NAME=description\") | \n|  | qs[qid] = choice(instr, parse_kv_options(rest)) | \n|  | elif kind == \"score\": | \n|  | if len(rest) < 2: | \n|  | raise UsageError(f\"--score {qid}: give 2..{MAX_SCORE_LEVELS} level descriptions, low to high\") | \n|  | qs[qid] = score(instr, [parse_value(r) for r in rest]) | \n|  | if not qs: | \n|  | raise UsageError(\"no questions. Use --noul/--choice/--score, --questions-file, or --questions-json (see `jev ask --help`)\") | \n|  | return qs | \n|  |  | \n|  |  | \n|  | # --------------------------------------------------------------------------- rendering | \n|  |  | \n|  |  | \n|  | def eprint(*a, **k): | \n|  | print(*a, file=sys.stderr, **k) | \n|  |  | \n|  |  | \n|  | def describe_level(desc) -> str: | \n|  | if isinstance(desc, dict): | \n|  | for k in (\"what\", \"level\", \"description\", \"name\"): | \n|  | if k in desc: | \n|  | return str(desc[k]) | \n|  | return json.dumps(desc)[:80] | \n|  | return str(desc) | \n|  |  | \n|  |  | \n|  | def render_answer(qid: str, a: dict) -> str: | \n|  | t = a.get(\"type\") | \n|  | if t == \"noul\": | \n|  | p = a[\"noul\"] | \n|  | return f\"{qid:<24} noul    {p:.2f}   {'yes' if p >= 0.5 else 'no'}\" | \n|  | if t == \"choice\": | \n|  | probs = a.get(\"probabilities\", {}) | \n|  | best = a[\"choice\"] | \n|  | others = \", \".join(f\"{k} {v:.2f}\" for k, v in sorted(probs.items(), key=lambda kv: -kv[1]) if k != best) | \n|  | return f\"{qid:<24} choice  {best}   p={probs.get(best, 0):.2f} conf={a.get('confidence', 0):.2f}   [{others}]\" | \n|  | if t == \"score\": | \n|  | legend = a.get(\"legend\", {}) | \n|  | top = max(len(legend) - 1, 1) | \n|  | s = a[\"score\"] | \n|  | nearest = describe_level(legend.get(str(int(round(s))), \"\")) | \n|  | return f\"{qid:<24} score   {s:.2f}/{top}   conf={a.get('confidence', 0):.2f}   ≈ {nearest}\" | \n|  | return f\"{qid:<24} {t}     {json.dumps(a)}\" | \n|  |  | \n|  |  | \n|  | def render_response(resp: dict, ms: float, verbose: bool) -> str: | \n|  | lines = [render_answer(qid, a) for qid, a in resp.get(\"answers\", {}).items()] | \n|  | u = resp.get(\"usage\", {}) | \n|  | lines.append(f\"· {resp.get('model')} · {u.get('input_tokens', 0)} in / {u.get('output_tokens', 0)} out tokens · {ms:.0f} ms · ${cost_usd(u.get('input_tokens', 0)):.6f}\") | \n|  | return \"\\n\".join(lines) | \n|  |  | \n|  |  | \n|  | def emit(args, resp: dict, ms: float, extra: dict \\| None = None) -> None: | \n|  | if args.json: | \n|  | out = dict(resp) | \n|  | if extra: | \n|  | out.update(extra) | \n|  | print(json.dumps(out, indent=None if args.compact else 2)) | \n|  | else: | \n|  | print(render_response(resp, ms, args.verbose)) | \n|  |  | \n|  |  | \n|  | # --------------------------------------------------------------------------- commands | \n|  |  | \n|  |  | \n|  | def cmd_ask(args) -> int: | \n|  | state = build_state(args) | \n|  | qs = questions_from_args(args) | \n|  | c = JevClient(args.api_key, args.model, timeout=args.timeout, label=\"ask\") | \n|  | resp = c.ask(state, qs) | \n|  | emit(args, resp, c.last_ms) | \n|  | return 0 | \n|  |  | \n|  |  | \n|  | def cmd_yes(args) -> int: | \n|  | state = build_state(args) | \n|  | q = noul(parse_value(args.instructions), args.true, args.false) | \n|  | c = JevClient(args.api_key, args.model, timeout=args.timeout, label=\"yes\") | \n|  | resp = c.ask(state, {\"q\": q}) | \n|  | p = resp[\"answers\"][\"q\"][\"noul\"] | \n|  | lo, hi = (args.band if args.band else (args.threshold, args.threshold)) | \n|  | if p >= hi: | \n|  | verdict, code = \"yes\", 0 | \n|  | elif p < lo: | \n|  | verdict, code = \"no\", 1 | \n|  | else: | \n|  | verdict, code = \"uncertain\", 1 | \n|  | if args.json: | \n|  | print(json.dumps({\"noul\": p, \"verdict\": verdict, \"threshold\": args.threshold, \"band\": args.band, \"model\": resp[\"model\"], \"usage\": resp[\"usage\"]})) | \n|  | else: | \n|  | print(f\"{p:.3f} {verdict}\") | \n|  | return code | \n|  |  | \n|  |  | \n|  | def cmd_pick(args) -> int: | \n|  | state = build_state(args) | \n|  | opts = parse_kv_options(args.options) | \n|  | if len(opts) < 2: | \n|  | raise UsageError(\"pick needs at least 2 options (NAME or NAME=description)\") | \n|  | c = JevClient(args.api_key, args.model, timeout=args.timeout, label=\"pick\") | \n|  | resp = c.ask(state, {\"q\": choice(parse_value(args.instructions), opts)}) | \n|  | a = resp[\"answers\"][\"q\"] | \n|  | conf = a.get(\"confidence\", 0.0) | \n|  | ok = conf >= args.min_confidence | \n|  | if args.json: | \n|  | print(json.dumps({\"choice\": a[\"choice\"], \"confidence\": conf, \"probabilities\": a[\"probabilities\"], \"verdict\": \"ok\" if ok else \"uncertain\", \"min_confidence\": args.min_confidence, \"model\": resp[\"model\"], \"usage\": resp[\"usage\"]})) | \n|  | else: | \n|  | ranked = \", \".join(f\"{k} {v:.2f}\" for k, v in sorted(a[\"probabilities\"].items(), key=lambda kv: -kv[1])) | \n|  | if ok: | \n|  | print(f\"{a['choice']}  conf={conf:.2f}  [{ranked}]\") | \n|  | else: | \n|  | print(f\"uncertain  best={a['choice']} conf={conf:.2f} < {args.min_confidence}  [{ranked}]\") | \n|  | return 0 if ok else 1 | \n|  |  | \n|  |  | \n|  | def cmd_rate(args) -> int: | \n|  | state = build_state(args) | \n|  | levels = [parse_value(lv) for lv in args.levels] | \n|  | if not 2 <= len(levels) <= MAX_SCORE_LEVELS: | \n|  | raise UsageError(f\"rate needs 2..{MAX_SCORE_LEVELS} level descriptions, low to high\") | \n|  | c = JevClient(args.api_key, args.model, timeout=args.timeout, label=\"rate\") | \n|  | resp = c.ask(state, {\"q\": score(parse_value(args.instructions), levels)}) | \n|  | a = resp[\"answers\"][\"q\"] | \n|  | conf = a.get(\"confidence\", 0.0) | \n|  | top = len(levels) - 1 | \n|  | ok = conf >= args.min_confidence | \n|  | nearest = int(round(a[\"score\"])) | \n|  | if args.json: | \n|  | print(json.dumps({\"score\": a[\"score\"], \"top\": top, \"normalized\": a[\"score\"] / top, \"nearest_level\": nearest, \"nearest\": describe_level(levels[nearest]), \"confidence\": conf, \"probabilities\": a[\"probabilities\"], \"verdict\": \"ok\" if ok else \"uncertain\", \"model\": resp[\"model\"], \"usage\": resp[\"usage\"]})) | \n|  | else: | \n|  | flag = \"\" if ok else f\"  uncertain (conf < {args.min_confidence})\" | \n|  | print(f\"{a['score']:.2f}/{top}  conf={conf:.2f}  ≈ {describe_level(levels[nearest])}{flag}\") | \n|  | return 0 if ok else 1 | \n|  |  | \n|  |  | \n|  | def read_candidates(args) -> list: | \n|  | if args.candidates_file: | \n|  | v = parse_value(\"@\" + args.candidates_file) | \n|  | if isinstance(v, list): | \n|  | return v | \n|  | return [line for line in str(v).splitlines() if line.strip()] | \n|  | if args.candidates: | \n|  | return list(args.candidates) | \n|  | txt = implicit_stdin() | \n|  | if txt: | \n|  | return [line.rstrip(\"\\n\") for line in txt.splitlines() if line.strip()] | \n|  | raise UsageError(\"no candidates: give them as arguments, --candidates-file (lines, or a JSON array), or on stdin\") | \n|  |  | \n|  |  | \n|  | def chunk_candidates(cands: list, max_chars: int, max_n: int) -> list[list[tuple[int, object]]]: | \n|  | chunks, cur, size = [], [], 0 | \n|  | for i, c in enumerate(cands): | \n|  | n = len(c) if isinstance(c, str) else len(json.dumps(c)) | \n|  | if cur and (size + n > max_chars or len(cur) >= max_n): | \n|  | chunks.append(cur) | \n|  | cur, size = [], 0 | \n|  | cur.append((i, c)) | \n|  | size += n | \n|  | if cur: | \n|  | chunks.append(cur) | \n|  | return chunks | \n|  |  | \n|  |  | \n|  | def cmd_rank(args) -> int: | \n|  | cands = read_candidates(args) | \n|  | if not cands: | \n|  | raise UsageError(\"no candidates\") | \n|  | c = JevClient(args.api_key, args.model, timeout=args.timeout, label=\"rank\") | \n|  | levels = [parse_value(lv) for lv in args.levels] if args.levels else None | \n|  | question_text = args.instructions or (\"How well does `candidate` match `query`?\" if levels else \"Is `candidate` relevant to `query`?\") | \n|  | if \"{i}\" in question_text or \"candidates[\" in question_text: | \n|  | eprint(\"jev: warning: refer to the item as `candidate`; each question carries its own item. Positional `candidates[i]` references mis-locate past ~20 items (measured 27% wrong at 150).\") | \n|  | results: list[dict] = [] | \n|  | usage_in = usage_out = 0 | \n|  | t0 = time.time() | \n|  | chunks = chunk_candidates(cands, args.chunk_chars, args.chunk_size) | \n|  |  | \n|  | def run(chunk): | \n|  | # The item lives INSIDE its question, not at an index in the state: Jev mis-locates | \n|  | # `candidates[i]` in long arrays (measured 2026-09-18: 86/320 wrong at 150 per request, | \n|  | # 29/320 at 25) while an embedded or keyed item scored 0/320 wrong at 320 per request. | \n|  | state = {\"query\": parse_value(args.query)} | \n|  | if args.context: | \n|  | state[\"context\"] = parse_value(args.context) | \n|  | qs = {} | \n|  | for j, (i, cand) in enumerate(chunk): | \n|  | instr = {\"question\": question_text, \"candidate\": cand} | \n|  | qs[f\"c{j}\"] = score(instr, levels) if levels else noul(instr) | \n|  | resp = c.ask(state, qs) | \n|  | out = [] | \n|  | for j, (i, cand) in enumerate(chunk): | \n|  | a = resp[\"answers\"][f\"c{j}\"] | \n|  | if levels: | \n|  | top = len(levels) - 1 | \n|  | out.append({\"i\": i, \"p\": a[\"score\"] / top, \"score\": a[\"score\"], \"confidence\": a.get(\"confidence\"), \"candidate\": cand}) | \n|  | else: | \n|  | out.append({\"i\": i, \"p\": a[\"noul\"], \"candidate\": cand}) | \n|  | return out, resp.get(\"usage\", {}) | \n|  |  | \n|  | with cf.ThreadPoolExecutor(max_workers=args.concurrency) as ex: | \n|  | for out, u in ex.map(run, chunks): | \n|  | results.extend(out) | \n|  | usage_in += u.get(\"input_tokens\", 0) | \n|  | usage_out += u.get(\"output_tokens\", 0) | \n|  | results.sort(key=lambda r: -r[\"p\"]) | \n|  | if args.min is not None: | \n|  | results = [r for r in results if r[\"p\"] >= args.min] | \n|  | if args.top: | \n|  | results = results[: args.top] | \n|  | ms = (time.time() - t0) * 1000 | \n|  | if args.json: | \n|  | print(json.dumps({\"results\": results, \"n\": len(cands), \"requests\": len(chunks), \"usage\": {\"input_tokens\": usage_in, \"output_tokens\": usage_out}, \"ms\": round(ms)}, indent=None if args.compact else 2)) | \n|  | else: | \n|  | for r in results: | \n|  | cand = r[\"candidate\"] if isinstance(r[\"candidate\"], str) else json.dumps(r[\"candidate\"]) | \n|  | cand = cand.replace(\"\\n\", \" \") | \n|  | if len(cand) > args.width: | \n|  | cand = cand[: args.width - 1] + \"…\" | \n|  | print(f\"{r['p']:.3f}  #{r['i']:<4} {cand}\") | \n|  | eprint(f\"· {len(cands)} candidates · {len(chunks)} request(s) · {usage_in} in tokens · {ms:.0f} ms · ${cost_usd(usage_in):.5f}\") | \n|  | return 0 | \n|  |  | \n|  |  | \n|  | def cmd_batch(args) -> int: | \n|  | qs = questions_from_args(args) | \n|  | if args.input == \"-\": | \n|  | raw = sys.stdin.read() | \n|  | else: | \n|  | p = Path(args.input).expanduser() | \n|  | if not p.exists(): | \n|  | raise UsageError(f\"input not found: {p}\") | \n|  | raw = p.read_text() | \n|  | items = [] | \n|  | for n, line in enumerate(raw.splitlines()): | \n|  | if not line.strip(): | \n|  | continue | \n|  | if args.text_lines: | \n|  | items.append((n, None, line)) | \n|  | continue | \n|  | try: | \n|  | obj = json.loads(line) | \n|  | except json.JSONDecodeError: | \n|  | items.append((n, None, line)) | \n|  | continue | \n|  | if isinstance(obj, dict) and args.state_key: | \n|  | if args.state_key not in obj: | \n|  | raise UsageError(f\"line {n}: no key {args.state_key!r}\") | \n|  | items.append((n, obj.get(args.id_key), obj[args.state_key])) | \n|  | else: | \n|  | items.append((n, obj.get(args.id_key) if isinstance(obj, dict) else None, obj)) | \n|  | if not items: | \n|  | raise UsageError(\"no input rows\") | \n|  | c = JevClient(args.api_key, args.model, timeout=args.timeout, label=\"batch\") | \n|  | out_f = open(args.out, \"w\") if args.out else sys.stdout | \n|  | usage_in = 0 | \n|  | t0 = time.time() | \n|  | errors = 0 | \n|  |  | \n|  | def run(item): | \n|  | n, ident, state = item | \n|  | try: | \n|  | resp = c.ask(state, qs) | \n|  | row = {\"line\": n, \"answers\": resp[\"answers\"], \"usage\": resp[\"usage\"]} | \n|  | except JevError as e: | \n|  | row = {\"line\": n, \"error\": str(e)} | \n|  | if ident is not None: | \n|  | row[\"id\"] = ident | \n|  | if args.echo: | \n|  | row[\"state\"] = state | \n|  | return row | \n|  |  | \n|  | try: | \n|  | with cf.ThreadPoolExecutor(max_workers=args.concurrency) as ex: | \n|  | for row in ex.map(run, items): | \n|  | if \"error\" in row: | \n|  | errors += 1 | \n|  | else: | \n|  | usage_in += row[\"usage\"].get(\"input_tokens\", 0) | \n|  | out_f.write(json.dumps(row) + \"\\n\") | \n|  | out_f.flush() | \n|  | finally: | \n|  | if args.out: | \n|  | out_f.close() | \n|  | ms = (time.time() - t0) * 1000 | \n|  | eprint(f\"· {len(items)} rows · {errors} errors · {usage_in} in tokens · {ms:.0f} ms · ${cost_usd(usage_in):.5f}\" + (f\" · wrote {args.out}\" if args.out else \"\")) | \n|  | return 0 if errors == 0 else 4 | \n|  |  | \n|  |  | \n|  | def cmd_models(args) -> int: | \n|  | c = JevClient(args.api_key, args.model, timeout=args.timeout, record=False) | \n|  | resp = c.models() | \n|  | if args.json: | \n|  | print(json.dumps(resp, indent=2)) | \n|  | else: | \n|  | for m in resp.get(\"models\", []): | \n|  | print(f\"{m.get('name'):<14} {str(m.get('release_date', ''))[:10]}  {m.get('description', '')}\") | \n|  | return 0 | \n|  |  | \n|  |  | \n|  | def cmd_auth(args) -> int: | \n|  | if args.action == \"set\": | \n|  | key = args.key or (sys.stdin.readline().strip() if not sys.stdin.isatty() else \"\") | \n|  | if not key: | \n|  | raise UsageError(\"jev auth set <key>  (or pipe the key on stdin)\") | \n|  | CONFIG_DIR.mkdir(parents=True, exist_ok=True) | \n|  | old = os.umask(0o077) | \n|  | try: | \n|  | KEY_FILE.write_text(key.strip() + \"\\n\") | \n|  | finally: | \n|  | os.umask(old) | \n|  | os.chmod(KEY_FILE, 0o600) | \n|  | print(f\"stored {mask(key)} in {KEY_FILE} (0600)\") | \n|  | return 0 | \n|  | if args.action == \"clear\": | \n|  | if KEY_FILE.exists(): | \n|  | KEY_FILE.unlink() | \n|  | print(f\"removed {KEY_FILE}\") | \n|  | else: | \n|  | print(\"no key file\") | \n|  | return 0 | \n|  | try: | \n|  | key, src = resolve_key(args.api_key) | \n|  | except AuthError as e: | \n|  | print(f\"no key: {e}\") | \n|  | return 3 | \n|  | print(f\"key {mask(key)} from {src}\") | \n|  | if src == str(KEY_FILE): | \n|  | mode = oct(KEY_FILE.stat().st_mode & 0o777) | \n|  | print(f\"file mode {mode}\" + (\"\" if mode == \"0o600\" else \"  <- should be 0600\")) | \n|  | return 0 | \n|  |  | \n|  |  | \n|  | def cmd_doctor(args) -> int: | \n|  | ok = True | \n|  |  | \n|  | def step(name, fn): | \n|  | nonlocal ok | \n|  | try: | \n|  | msg = fn() | \n|  | print(f\"ok    {name}: {msg}\") | \n|  | except Exception as e:  # noqa: BLE001 | \n|  | ok = False | \n|  | print(f\"FAIL  {name}: {e}\") | \n|  |  | \n|  | step(\"python\", lambda: sys.version.split()[0]) | \n|  | def key(): | \n|  | k, src = resolve_key(args.api_key) | \n|  | return f\"{mask(k)} from {src}\" | \n|  |  | \n|  | step(\"key\", key) | \n|  | c = None | \n|  |  | \n|  | def models(): | \n|  | nonlocal c | \n|  | c = JevClient(args.api_key, args.model, timeout=args.timeout, record=False) | \n|  | r = c.models() | \n|  | return f\"{[m['name'] for m in r.get('models', [])]} in {c.last_ms:.0f} ms\" | \n|  |  | \n|  | step(\"GET /v1/models\", models) | \n|  |  | \n|  | def roundtrip(): | \n|  | r = c.ask(\"The export button crashes the settings page in Safari but works in Chrome.\", | \n|  | {\"is_bug\": noul(\"Does this describe a software bug?\"), | \n|  | \"severity\": score(\"How severe?\", [\"Cosmetic\", \"Degraded, workaround exists\", \"Blocking\"])}) | \n|  | a = r[\"answers\"] | \n|  | return f\"model={r['model']} is_bug={a['is_bug']['noul']:.2f} severity={a['severity']['score']:.2f} in {c.last_ms:.0f} ms, {r['usage']['input_tokens']} tokens\" | \n|  |  | \n|  | if c is not None: | \n|  | step(\"POST /v1/systemone\", roundtrip) | \n|  | step(\"usage ledger\", lambda: f\"{USAGE_FILE} ({USAGE_FILE.stat().st_size if USAGE_FILE.exists() else 0} bytes)\") | \n|  | step(\"skill\", lambda: \", \".join(str(p) for p in (Path.home() / \".claude/skills/jev\", Path.home() / \".codex/skills/jev\", Path.home() / \".config/opencode/skills/jev\") if p.exists()) or \"not linked (see `jev guide install`)\") | \n|  | print(\"healthy\" if ok else \"problems found\") | \n|  | return 0 if ok else 4 | \n|  |  | \n|  |  | \n|  | def load_ledger() -> list[dict]: | \n|  | if not USAGE_FILE.exists(): | \n|  | return [] | \n|  | rows = [] | \n|  | for line in USAGE_FILE.read_text().splitlines(): | \n|  | try: | \n|  | r = json.loads(line) | \n|  | r[\"_t\"] = datetime.fromisoformat(r[\"ts\"]) | \n|  | rows.append(r) | \n|  | except (json.JSONDecodeError, KeyError, ValueError): | \n|  | continue | \n|  | return rows | \n|  |  | \n|  |  | \n|  | def agent_names(ids: set[str]) -> dict[str, str]: | \n|  | \"\"\"Agents are attributed by $JEV_AGENT (or $AGENT_ID). Names are whatever you export.\"\"\" | \n|  | return {i: (i if i else \"(no agent)\") for i in ids} | \n|  |  | \n|  |  | \n|  | def _agg(sel: list[dict]) -> dict: | \n|  | ok = [r for r in sel if \"err\" not in r] | \n|  | tin = sum(r.get(\"in\", 0) for r in ok) | \n|  | ms = sorted(r[\"ms\"] for r in ok if r.get(\"ms\")) | \n|  | pct = lambda p: ms[min(len(ms) - 1, int(len(ms) * p))] if ms else 0  # noqa: E731 | \n|  | return { | \n|  | \"requests\": len(sel), \"errors\": len(sel) - len(ok), \"questions\": sum(r.get(\"q\", 0) for r in ok), | \n|  | \"input_tokens\": tin, \"output_tokens\": sum(r.get(\"out\", 0) for r in ok), \"usd\": round(cost_usd(tin), 6), | \n|  | \"avg_ms\": round(sum(ms) / len(ms)) if ms else 0, \"p50_ms\": pct(0.5), \"p95_ms\": pct(0.95), \"max_ms\": ms[-1] if ms else 0, | \n|  | } | \n|  |  | \n|  |  | \n|  | def _peaks(sel: list[dict]) -> dict: | \n|  | per_min: dict[str, int] = {} | \n|  | per_sec: dict[str, int] = {} | \n|  | for r in sel: | \n|  | per_min[r[\"ts\"][:16]] = per_min.get(r[\"ts\"][:16], 0) + 1 | \n|  | per_sec[r[\"ts\"]] = per_sec.get(r[\"ts\"], 0) + r.get(\"in\", 0) | \n|  | rpm = max(per_min.values()) if per_min else 0 | \n|  | tps = max(per_sec.values()) if per_sec else 0 | \n|  | return {\"peak_rpm\": rpm, \"peak_rpm_at\": max(per_min, key=per_min.get) if per_min else None, \"rpm_limit\": RATE_LIMIT_RPM, | \n|  | \"peak_tps\": tps, \"peak_tps_at\": max(per_sec, key=per_sec.get) if per_sec else None, \"tps_limit\": RATE_LIMIT_TPS} | \n|  |  | \n|  |  | \n|  | def cmd_usage(args) -> int: | \n|  | rows = load_ledger() | \n|  | if args.label: | \n|  | rows = [r for r in rows if r.get(\"cmd\") == args.label] | \n|  | if args.agent: | \n|  | rows = [r for r in rows if args.agent in (r.get(\"agent\") or \"\")] | \n|  | if args.since: | \n|  | try: | \n|  | since = datetime.fromisoformat(args.since) | \n|  | except ValueError: | \n|  | raise UsageError(\"--since expects YYYY-MM-DD or an ISO timestamp\") | \n|  | rows = [r for r in rows if r[\"_t\"] >= since] | \n|  | if not rows: | \n|  | print(\"no usage recorded\" + (\" for that filter\" if (args.label or args.agent or args.since) else \" yet\")) | \n|  | return 0 | \n|  | now = datetime.now() | \n|  | day0 = now.replace(hour=0, minute=0, second=0, microsecond=0) | \n|  | cfg = load_config() | \n|  |  | \n|  | if args.tail: | \n|  | sel = rows[-args.tail:] | \n|  | if args.json: | \n|  | print(json.dumps([{k: v for k, v in r.items() if k != \"_t\"} for r in sel], indent=2)) | \n|  | return 0 | \n|  | names = agent_names({r.get(\"agent\", \"\") for r in sel}) | \n|  | print(f\"{'ts':<19} {'cmd':<12} {'agent':<22} {'q':>4} {'in':>7} {'ms':>5}  rid/err\") | \n|  | for r in sel: | \n|  | tail = r.get(\"err\") and f\"ERR {r['err']}\" or r.get(\"rid\", \"\") | \n|  | print(f\"{r['ts']:<19} {r.get('cmd', '?')[:12]:<12} {names[r.get('agent', '')][:22]:<22} {r.get('q', 0):>4} {r.get('in', 0):>7} {r.get('ms', 0):>5}  {tail}\") | \n|  | return 0 | \n|  |  | \n|  | if args.by: | \n|  | key = args.by | \n|  | if key == \"day\": | \n|  | groups = {} | \n|  | for r in rows: | \n|  | if r[\"_t\"] >= day0 - timedelta(days=args.days - 1): | \n|  | groups.setdefault(r[\"ts\"][:10], []).append(r) | \n|  | elif key == \"hour\": | \n|  | groups = {} | \n|  | for r in rows: | \n|  | if r[\"_t\"] >= now - timedelta(hours=24): | \n|  | groups.setdefault(r[\"ts\"][:13] + \":00\", []).append(r) | \n|  | elif key in (\"cmd\", \"model\"): | \n|  | groups = {} | \n|  | for r in rows: | \n|  | groups.setdefault(str(r.get(key) or \"?\"), []).append(r) | \n|  | elif key == \"agent\": | \n|  | names = agent_names({r.get(\"agent\", \"\") for r in rows}) | \n|  | groups = {} | \n|  | for r in rows: | \n|  | groups.setdefault(names[r.get(\"agent\", \"\")], []).append(r) | \n|  | else: | \n|  | raise UsageError(\"--by expects day, hour, cmd, agent or model\") | \n|  | table = {k: _agg(v) for k, v in groups.items()} | \n|  | order = sorted(table) if key in (\"day\", \"hour\") else sorted(table, key=lambda k: -table[k][\"input_tokens\"]) | \n|  | if args.json: | \n|  | print(json.dumps({k: table[k] for k in order}, indent=2)) | \n|  | return 0 | \n|  | print(f\"{key:<24} {'requests':>8} {'errors':>6} {'questions':>9} {'in tokens':>10} {'usd':>9} {'avg ms':>6}\") | \n|  | for k in order: | \n|  | a = table[k] | \n|  | print(f\"{k[:24]:<24} {a['requests']:>8} {a['errors']:>6} {a['questions']:>9} {a['input_tokens']:>10,} {a['usd']:>9.4f} {a['avg_ms']:>6}\") | \n|  | return 0 | \n|  |  | \n|  | windows = { | \n|  | \"today\": day0, \"yesterday\": (day0 - timedelta(days=1), day0), \"7d\": now - timedelta(days=7), | \n|  | \"30d\": now - timedelta(days=30), \"month\": day0.replace(day=1), \"all\": datetime.min, | \n|  | } | \n|  | summary = {} | \n|  | for name, w in windows.items(): | \n|  | lo, hi = (w if isinstance(w, tuple) else (w, None)) | \n|  | sel = [r for r in rows if r[\"_t\"] >= lo and (hi is None or r[\"_t\"] < hi)] | \n|  | summary[name] = _agg(sel) | \n|  | last7 = [r for r in rows if r[\"_t\"] >= now - timedelta(days=7)] | \n|  | last30 = [r for r in rows if r[\"_t\"] >= now - timedelta(days=30)] | \n|  | first_ts = rows[0][\"_t\"] | \n|  | days_observed = max(1e-9, (now - first_ts).total_seconds() / 86400) | \n|  | rate7 = summary[\"7d\"][\"usd\"] / min(7, days_observed) | \n|  | rate30 = summary[\"30d\"][\"usd\"] / min(30, days_observed) | \n|  | forecast = {\"usd_per_day_7d\": round(rate7, 6), \"usd_per_day_30d\": round(rate30, 6), | \n|  | \"usd_per_month_at_7d_rate\": round(rate7 * 30, 4), \"usd_per_month_at_30d_rate\": round(rate30 * 30, 4), | \n|  | \"days_observed\": round(days_observed, 2)} | \n|  | credits = None | \n|  | if cfg.get(\"credits_usd\") is not None: | \n|  | as_of = datetime.fromisoformat(cfg.get(\"credits_as_of\") or first_ts.isoformat()) | \n|  | spent = cost_usd(sum(r.get(\"in\", 0) for r in rows if r[\"_t\"] >= as_of)) | \n|  | remaining = float(cfg[\"credits_usd\"]) - spent | \n|  | credits = {\"credits_usd\": float(cfg[\"credits_usd\"]), \"as_of\": as_of.isoformat(timespec=\"seconds\"), \"spent_since\": round(spent, 6), | \n|  | \"remaining_usd\": round(remaining, 6), \"remaining_mtok\": round(remaining / price_per_mtok(), 3) if remaining > 0 else 0.0, | \n|  | \"days_left_at_7d_rate\": round(remaining / rate7, 1) if rate7 > 0 and remaining > 0 else None} | \n|  | budget = None | \n|  | if cfg.get(\"budget_usd_month\"): | \n|  | b = float(cfg[\"budget_usd_month\"]) | \n|  | mtd = summary[\"month\"][\"usd\"] | \n|  | dim = ((day0.replace(day=28) + timedelta(days=4)).replace(day=1) - timedelta(days=1)).day | \n|  | budget = {\"budget_usd_month\": b, \"mtd_usd\": mtd, \"pct_used\": round(100 * mtd / b, 1) if b else None, | \n|  | \"projected_month_end_usd\": round(mtd + rate7 * (dim - now.day), 4), \"days_left_in_month\": dim - now.day} | \n|  | errors = {} | \n|  | for r in last7: | \n|  | if \"err\" in r: | \n|  | errors[r[\"err\"]] = errors.get(r[\"err\"], 0) + 1 | \n|  | by_cmd = {} | \n|  | for r in rows: | \n|  | by_cmd.setdefault(r.get(\"cmd\") or \"?\", []).append(r) | \n|  | names = agent_names({r.get(\"agent\", \"\") for r in rows}) | \n|  | by_agent = {} | \n|  | for r in rows: | \n|  | by_agent.setdefault(names[r.get(\"agent\", \"\")], []).append(r) | \n|  | by_model = {} | \n|  | for r in rows: | \n|  | if r.get(\"model\"): | \n|  | by_model.setdefault(r[\"model\"], []).append(r) | \n|  | peaks = _peaks(last30) | \n|  | out = { | \n|  | \"price_per_mtok_in\": price_per_mtok(), \"ledger\": str(USAGE_FILE), \"rows\": len(rows), \"first\": rows[0][\"ts\"], \"last\": rows[-1][\"ts\"], | \n|  | \"windows\": summary, \"by_cmd\": {k: _agg(v) for k, v in by_cmd.items()}, \"by_agent\": {k: _agg(v) for k, v in by_agent.items()}, | \n|  | \"by_model\": {k: _agg(v) for k, v in by_model.items()}, \"errors_7d\": errors, \"throughput_30d\": peaks, | \n|  | \"forecast\": forecast, \"credits\": credits, \"budget\": budget, | \n|  | } | \n|  | if args.json: | \n|  | print(json.dumps(out, indent=2)) | \n|  | return 0 | \n|  |  | \n|  | print(f\"jev usage · ${price_per_mtok()}/Mtok in, output free · {len(rows)} requests since {rows[0]['ts'][:16]} · {USAGE_FILE}\") | \n|  | print(f\"\\n{'window':<10} {'requests':>8} {'errors':>6} {'questions':>9} {'in tokens':>10} {'out':>7} {'usd':>9} {'avg ms':>6}\") | \n|  | for name, a in summary.items(): | \n|  | print(f\"{name:<10} {a['requests']:>8} {a['errors']:>6} {a['questions']:>9} {a['input_tokens']:>10,} {a['output_tokens']:>7,} {a['usd']:>9.4f} {a['avg_ms']:>6}\") | \n|  | a7 = summary[\"7d\"] | \n|  | print(f\"\\nlatency 7d   p50 {a7['p50_ms']} ms · p95 {a7['p95_ms']} ms · max {a7['max_ms']} ms · avg questions/request {a7['questions'] / max(1, a7['requests'] - a7['errors']):.1f} · avg tokens/request {a7['input_tokens'] / max(1, a7['requests'] - a7['errors']):,.0f}\") | \n|  | print(f\"throughput   peak {peaks['peak_rpm']} req/min ({100 * peaks['peak_rpm'] / RATE_LIMIT_RPM:.1f}% of {RATE_LIMIT_RPM}) at {peaks['peak_rpm_at']} · peak {peaks['peak_tps']:,} tok/s ({100 * peaks['peak_tps'] / RATE_LIMIT_TPS:.2f}% of {RATE_LIMIT_TPS:,}) · 30d window\") | \n|  | print(\"errors 7d    \" + (\", \".join(f\"{k} x{v}\" for k, v in sorted(errors.items(), key=lambda kv: -kv[1])) if errors else \"none\")) | \n|  | print(f\"forecast     ${forecast['usd_per_day_7d']:.4f}/day at the 7d rate -> ${forecast['usd_per_month_at_7d_rate']:.2f}/month · ${forecast['usd_per_month_at_30d_rate']:.2f}/month at the 30d rate\") | \n|  | if credits: | \n|  | dl = f\" · ~{credits['days_left_at_7d_rate']} days left at the 7d rate\" if credits[\"days_left_at_7d_rate\"] else \"\" | \n|  | print(f\"credits      ${credits['remaining_usd']:.4f} remaining of ${credits['credits_usd']:.2f} set {credits['as_of'][:16]} ({credits['remaining_mtok']:.1f} Mtok){dl}\") | \n|  | else: | \n|  | print(\"credits      not configured. The API exposes no balance; read it at https://console.typesafe.ai and run `jev config set credits <usd>`\") | \n|  | if budget: | \n|  | print(f\"budget       ${budget['mtd_usd']:.4f} of ${budget['budget_usd_month']:.2f} this month ({budget['pct_used']}%) · projected month end ${budget['projected_month_end_usd']:.2f}\") | \n|  | print(f\"\\n{'by command':<24} {'requests':>8} {'questions':>9} {'in tokens':>10} {'usd':>9}\") | \n|  | for k, v in sorted(by_cmd.items(), key=lambda kv: -sum(r.get('in', 0) for r in kv[1]))[:12]: | \n|  | a = _agg(v) | \n|  | print(f\"{k[:24]:<24} {a['requests']:>8} {a['questions']:>9} {a['input_tokens']:>10,} {a['usd']:>9.4f}\") | \n|  | print(f\"\\n{'by agent':<24} {'requests':>8} {'questions':>9} {'in tokens':>10} {'usd':>9}\") | \n|  | for k, v in sorted(by_agent.items(), key=lambda kv: -sum(r.get('in', 0) for r in kv[1]))[:12]: | \n|  | a = _agg(v) | \n|  | print(f\"{k[:24]:<24} {a['requests']:>8} {a['questions']:>9} {a['input_tokens']:>10,} {a['usd']:>9.4f}\") | \n|  | if len(by_model) > 1: | \n|  | print(\"\\nby model: \" + \", \".join(f\"{k} {len(v)}\" for k, v in by_model.items())) | \n|  | print(\"\\nmore: --by day\\|hour\\|cmd\\|agent\\|model · --tail N · --since DATE · --label X · --agent X · --json · jev config · jev cost\") | \n|  | return 0 | \n|  |  | \n|  |  | \n|  | CONFIG_KEYS = { | \n|  | \"credits\": (\"credits_usd\", float, \"prepaid balance in USD, read off https://console.typesafe.ai; `jev usage` counts down from it\"), | \n|  | \"credits_as_of\": (\"credits_as_of\", str, \"ISO timestamp the balance was read (default: when you set it)\"), | \n|  | \"budget\": (\"budget_usd_month\", float, \"monthly spend budget in USD; `jev usage` shows % used and a month-end projection\"), | \n|  | \"price\": (\"price_per_mtok_in\", float, f\"USD per million input tokens if the vendor changes it (default {PRICE_PER_MTOK_IN})\"), | \n|  | } | \n|  |  | \n|  |  | \n|  | def cmd_config(args) -> int: | \n|  | cfg = load_config() | \n|  | if args.action == \"show\" or not args.action: | \n|  | if args.json: | \n|  | print(json.dumps(cfg, indent=2)) | \n|  | return 0 | \n|  | print(f\"{CONFIG_FILE}\" + (\"\" if CONFIG_FILE.exists() else \" (not created yet)\")) | \n|  | for k, (real, _, desc) in CONFIG_KEYS.items(): | \n|  | print(f\"  {k:<14} {str(cfg.get(real, '-')):<24} {desc}\") | \n|  | return 0 | \n|  | if args.action == \"unset\": | \n|  | if not args.key or args.key not in CONFIG_KEYS: | \n|  | raise UsageError(f\"jev config unset <{'\\|'.join(CONFIG_KEYS)}>\") | \n|  | cfg.pop(CONFIG_KEYS[args.key][0], None) | \n|  | if args.key == \"credits\": | \n|  | cfg.pop(\"credits_as_of\", None) | \n|  | save_config(cfg) | \n|  | print(f\"unset {args.key}\") | \n|  | return 0 | \n|  | if args.action == \"set\": | \n|  | if not args.key or args.key not in CONFIG_KEYS or args.value is None: | \n|  | raise UsageError(f\"jev config set <{'\\|'.join(CONFIG_KEYS)}> <value>\") | \n|  | real, typ, _ = CONFIG_KEYS[args.key] | \n|  | try: | \n|  | val = typ(args.value) | \n|  | except ValueError: | \n|  | raise UsageError(f\"{args.key} expects a {typ.__name__}\") | \n|  | if args.key == \"credits_as_of\": | \n|  | try: | \n|  | datetime.fromisoformat(val) | \n|  | except ValueError: | \n|  | raise UsageError(\"credits_as_of expects an ISO timestamp, e.g. 2026-09-19T14:00\") | \n|  | cfg[real] = val | \n|  | if args.key == \"credits\": | \n|  | cfg[\"credits_as_of\"] = args.as_of or datetime.now().isoformat(timespec=\"seconds\") | \n|  | save_config(cfg) | \n|  | print(f\"set {args.key} = {val}\" + (f\" (as of {cfg['credits_as_of']})\" if args.key == \"credits\" else \"\")) | \n|  | return 0 | \n|  | raise UsageError(\"jev config [show\\|set\\|unset]\") | \n|  |  | \n|  |  | \n|  | CHARS_PER_TOKEN = 4.0  # rough English heuristic; --exact measures the real count with one tiny call | \n|  |  | \n|  |  | \n|  | def cmd_cost(args) -> int: | \n|  | \"\"\"Estimate tokens and cost for a prospective job before running it.\"\"\" | \n|  | state = build_state(args) | \n|  | text = state if isinstance(state, str) else json.dumps(state) | \n|  | est_state = int(len(text) / CHARS_PER_TOKEN) | \n|  | q_tokens = int(args.question_chars / CHARS_PER_TOKEN) | \n|  | exact = None | \n|  | if args.exact: | \n|  | c = JevClient(args.api_key, args.model, timeout=args.timeout, label=\"cost\") | \n|  | r = c.ask(state, {\"probe\": noul(\"Is this text written in English?\")}) | \n|  | exact = r[\"usage\"][\"input_tokens\"] | \n|  | est_state = max(0, exact - q_tokens - 40)  # subtract the probe question and request overhead | \n|  | per_request = est_state + args.questions * q_tokens | \n|  | fits = per_request <= 64_000 and (est_state + q_tokens) <= 32_000 | \n|  | n_items = args.items or 1 | \n|  | if args.items: | \n|  | # rank/batch shape: each item is its own request if --per-item, else items are packed with the state repeated per request | \n|  | if args.per_item: | \n|  | total = per_request * n_items | \n|  | requests = n_items | \n|  | else: | \n|  | per_req_items = max(1, min(250, (64_000 - est_state) // max(1, q_tokens))) | \n|  | requests = -(-n_items // per_req_items) | \n|  | total = requests * est_state + n_items * q_tokens | \n|  | else: | \n|  | total, requests = per_request, 1 | \n|  | out = {\"state_tokens\": est_state, \"exact\": exact is not None, \"question_tokens_each\": q_tokens, \"questions\": args.questions, | \n|  | \"tokens_per_request\": per_request, \"fits_request_budget\": fits, \"items\": n_items, \"requests\": requests, | \n|  | \"total_input_tokens\": total, \"usd\": round(cost_usd(total), 6), \"price_per_mtok_in\": price_per_mtok()} | \n|  | if args.json: | \n|  | print(json.dumps(out, indent=2)) | \n|  | return 0 | \n|  | how = \"measured\" if exact is not None else f\"estimated at {CHARS_PER_TOKEN:g} chars/token (add --exact to measure)\" | \n|  | print(f\"state        {est_state:,} tokens ({how})\") | \n|  | print(f\"per request  {per_request:,} tokens = state + {args.questions} question(s) x ~{q_tokens} · {'fits' if fits else 'EXCEEDS'} the 64k/32k request budget\") | \n|  | if args.items: | \n|  | print(f\"job          {n_items:,} items -> {requests:,} request(s), {total:,} input tokens\") | \n|  | print(f\"cost         ${cost_usd(total):.6f} at ${price_per_mtok()}/Mtok\" + (f\" (${cost_usd(total) / n_items:.7f} per item)\" if args.items else \"\")) | \n|  | return 0 | \n|  |  | \n|  |  | \n|  | def cmd_schema(args) -> int: | \n|  | print(json.dumps({ | \n|  | \"state\": \"string \\| object \\| array  (the content to judge; use an object with named fields; reference them in instructions with backticks like `ticket.message`)\", | \n|  | \"model\": \"jev-latest\", | \n|  | \"questions\": { | \n|  | \"is_urgent\": {\"type\": \"noul\", \"instructions\": \"Does `ticket.message` convey urgency?\", \"criteria\": {\"true\": \"optional: what yes means\", \"false\": \"optional: what no means\"}}, | \n|  | \"department\": {\"type\": \"choice\", \"instructions\": \"Which team should handle `ticket.message`?\", \"criteria\": {\"billing\": \"Charges, invoices, refunds\", \"technical\": \"Bugs, outages, integrations\", \"other\": None}}, | \n|  | \"frustration\": {\"type\": \"score\", \"instructions\": \"How frustrated does the customer appear in `ticket.message`?\", \"criteria\": [\"Calm and matter-of-fact\", \"Frustrated but civil\", \"Very angry or threatening to leave\"]}, | \n|  | }, | \n|  | }, indent=2)) | \n|  | print(\"\\nAnswers come back under the same ids: noul -> {noul}; choice -> {choice, probabilities, confidence}; score -> {score, legend, probabilities, confidence}.\\ninstructions and every criteria entry may be a string OR a JSON object/array (see `jev guide structure`).\") | \n|  | return 0 | \n|  |  | \n|  |  | \n|  | def cmd_docs(args) -> int: | \n|  | url = f\"{DOCS}/llms.txt\" | \n|  | try: | \n|  | with urllib.request.urlopen(urllib.request.Request(url, headers={\"User-Agent\": f\"jev-cli/{VERSION}\"}), timeout=20) as r: | \n|  | txt = r.read().decode() | \n|  | except Exception as e:  # noqa: BLE001 | \n|  | raise NetworkError(f\"could not fetch {url}: {e}\") | \n|  | if args.grep: | \n|  | needle = args.grep.lower() | \n|  | txt = \"\\n\".join(line for line in txt.splitlines() if needle in line.lower()) | \n|  | print(txt) | \n|  | return 0 | \n|  |  | \n|  |  | \n|  | def cmd_guide(args) -> int: | \n|  | if args.list: | \n|  | for k, (title, _, live) in GUIDE.items(): | \n|  | print(f\"{k:<12} {title}\" + (f\"   (live: {live if live.startswith('http') else DOCS + live + '.md'})\" if live else \"\")) | \n|  | return 0 | \n|  | topic = args.topic or \"when\" | \n|  | if topic not in GUIDE: | \n|  | raise UsageError(f\"unknown topic {topic!r}. Topics: {', '.join(GUIDE)}\") | \n|  | title, body, live = GUIDE[topic] | \n|  | if args.live or topic == \"vendor\": | \n|  | if not live: | \n|  | raise UsageError(f\"topic {topic!r} has no live page\") | \n|  | url = live if live.startswith(\"http\") else f\"{DOCS}{live}.md\" | \n|  | try: | \n|  | with urllib.request.urlopen(urllib.request.Request(url, headers={\"User-Agent\": f\"jev-cli/{VERSION}\"}), timeout=20) as r: | \n|  | print(r.read().decode()) | \n|  | except Exception as e:  # noqa: BLE001 | \n|  | raise NetworkError(f\"could not fetch {url}: {e}\") | \n|  | return 0 | \n|  | print(f\"# {title}\\n\\n{body.strip()}\\n\") | \n|  | if live: | \n|  | print(f\"Live source: {live if live.startswith('http') else DOCS + live + '.md'}   (jev guide {topic} --live)\") | \n|  | return 0 | \n|  |  | \n|  |  | \n|  | def cmd_examples(args) -> int: | \n|  | if not args.name: | \n|  | print(\"Copy-paste examples. `jev examples <name>` prints one; `jev examples all` prints everything.\\n\") | \n|  | for k, (title, _) in EXAMPLES.items(): | \n|  | print(f\"  {k:<10} {title}\") | \n|  | return 0 | \n|  | keys = list(EXAMPLES) if args.name == \"all\" else [args.name] | \n|  | for k in keys: | \n|  | if k not in EXAMPLES: | \n|  | raise UsageError(f\"unknown example {k!r}. Names: {', '.join(EXAMPLES)}\") | \n|  | title, body = EXAMPLES[k] | \n|  | print(f\"## {title}\\n{body.strip()}\\n\") | \n|  | return 0 | \n|  |  | \n|  |  | \n|  | # --------------------------------------------------------------------------- embedded docs | \n|  |  | \n|  | GUIDE: dict[str, tuple[str, str, str \\| None]] = {} | \n|  |  | \n|  | GUIDE[\"when\"] = (\"Jev playbook for agents: when to reach for it, how to ask, how to read\", r\"\"\" | \n|  | Jev is TypeSafe's System One model. It does not write text. It makes ONE narrow judgment | \n|  | per question against a state you hand it, and returns a calibrated probability. ~250 ms. | \n|  | $0.042 per million input tokens (a 1k-token item costs $0.00004). Output tokens are free. | \n|  | Same input -> same answer, run to run. It is a semantic if-statement, not a chatbot. | \n|  |  | \n|  | ## Reach for Jev when | \n|  | 1. The decision REPEATS over many items and you should not read them all into context: | \n|  | classify / filter / rank / dedupe hundreds of notes, emails, transcript segments, log | \n|  | lines, RSS items, PRs, findings. `jev rank` and `jev batch` do this in a few requests. | \n|  | 2. You want a CALIBRATED PROBABILITY, not your own vibe. Your confidence is not calibrated; | \n|  | Jev's is trained to be (RLCD). Use it to decide act / confirm / escalate. | \n|  | 3. A SCRIPT or CUE needs a judgment that runs unattended, a million times, with no agent | \n|  | loop: \"is this Ring event a delivery?\", \"is this email a receipt?\", \"is this item relevant?\" | \n|  | 4. You need an INDEPENDENT CHECK of your own output: does the source support this claim, | \n|  | does this draft break a stated rule, does this text contain an instruction aimed at an | \n|  | agent (prompt injection), is this tool call risky. | \n|  | 5. You need SPEED: real-time gates inside a request path or a UI. | \n|  |  | \n|  | ## Do NOT use Jev for | \n|  | - Generation, rewriting, summarizing, explaining. It cannot. Use yourself. | \n|  | - Math, counting, date arithmetic, numeric comparison. Keep those in code; Jev extracts | \n|  | the parts (a Choice over months/days), code does the arithmetic. | \n|  | - Multi-hop reasoning, double negatives, \"a property of a property\". | \n|  | - One small item you can judge in a glance. The call costs more than the decision. | \n|  | - Hostile input without care: state is data, and injected text can move an answer. Write | \n|  | precise criteria and test edge cases. | \n|  |  | \n|  | ## The three primitives (pick by the SHAPE of the answer your code needs) | \n|  | \\| need                         \\| type   \\| answer fields                                   \\| | \n|  | \\| is this true?                \\| noul   \\| noul = P(yes) 0..1  (no separate confidence)    \\| | \n|  | \\| which one of these?          \\| choice \\| choice, probabilities{opt: p}, confidence        \\| | \n|  | \\| where on this rubric?        \\| score  \\| score (0..N-1, may fall between), legend,        \\| | \n|  | \\|                              \\|        \\| probabilities{level: p}, confidence              \\| | \n|  |  | \n|  | ## Fast path (one question) | \n|  | jev yes  \"Does this message ask for a refund?\" --state \"I was charged twice, fix it\" | \n|  | jev pick \"Which team handles this?\" billing=\"Charges, refunds\" tech=\"Bugs\" other -s \"…\" | \n|  | jev rate \"How severe is the bug?\" \"Cosmetic\" \"Degraded, workaround exists\" \"Blocking\" -s @report.txt | \n|  | `yes` exits 0/1 on --threshold (default 0.5). `pick`/` rate` exit 1 below --min-confidence. | \n|  | Pipe text on stdin instead of --state:  cat email.txt \\| jev yes \"Is this a receipt?\" | \n|  |  | \n|  | ## Real path (many questions, one call: SPECULATIVE FAN-OUT) | \n|  | Ask EVERY question you might need in ONE request. They run in parallel and independently; | \n|  | adding questions barely changes latency and costs only the question tokens. Let code ignore | \n|  | the answers it does not need. | \n|  | jev ask --field message=@ticket.txt --field policy=@refund_policy.md \\ | \n|  | --noul   refund   'Does `message` request a refund?' \\ | \n|  | --noul   covered  'Does `policy` cover the refund requested in `message`?' \\ | \n|  | --choice team     'Which team should handle `message`?' billing=Charges tech=Bugs other \\ | \n|  | --score  anger    'How angry is `message`?' \"Calm\" \"Frustrated but civil\" \"Hostile\" --json | \n|  | Shell rule: SINGLE-QUOTE any instruction containing backticks, or zsh runs them as commands. | \n|  |  | \n|  | ## Writing a question that works (Jev reads LITERALLY) | \n|  | - One judgment per question. \"Analyze this and decide what to do\" is not a question; split | \n|  | it. \"Does `message` ask for money back?\" is. | \n|  | - Say the exact condition. If you find yourself explaining what you \"really meant\", that | \n|  | explanation belongs in the instructions or criteria. | \n|  | - Point at the field with a backticked path: `ticket.messages[0].text`. Question IDs are | \n|  | NOT sent to the model; the instructions must carry the whole meaning. | \n|  | - NEVER index into a long array (`items[137]`). Measured 2026-09-18: 27% wrong at 150 | \n|  | items per request, still 9% at 25. Key the object instead (`items.k137`) or put the | \n|  | item inside the question itself; both scored 0 wrong out of 320. `jev rank` does the | \n|  | latter for you. | \n|  | - Choice: describe each option so the boundary with its neighbour is clear; add `other` / | \n|  | `none` when the list may not cover the input. Up to 255 options. | \n|  | - Score: levels describe SITUATIONS, low to high, 2..10 of them. \"Broken but a workaround | \n|  | exists\" works; \"moderately bad\" and bare numbers do not. One dimension per score. | \n|  | - Noul: phrase it so high = yes. Optional true=/false= criteria pin a subtle boundary. | \n|  | - Send only the state the questions need. Irrelevant context lowers accuracy (context rot). | \n|  | Filter in code first. Budget: ~32k tokens for state + longest question. | \n|  |  | \n|  | ## Reading the answer | \n|  | - noul: p >= 0.5 is yes, but pick the threshold by stakes. Do not read 0.5 as \"medium\". | \n|  | - choice: `choice` is the argmax; `confidence` says how peaked the distribution is. A second | \n|  | option with real mass is signal, not noise. | \n|  | - score: a position between levels (0.7*1 + 0.3*2 = 1.3). Round for one outcome; compare or | \n|  | sort for ranking; divide by N-1 to normalize before weighting several scores together. | \n|  | - THREE BANDS: high confidence -> act; medium -> confirm or gather more; low -> do not act, | \n|  | escalate or ask. Thresholds scale with risk: read-only at 0.6, destructive at 0.9. | \n|  | - Do not carry a threshold tuned on a noul over to a choice, and do not expect P(x) and | \n|  | 1 - P(not x) from two questions to agree. Ask the question you want, one way. | \n|  | - Combine independent answers in CODE with weights you own (composite scoring). A weight | \n|  | change is a code change, not a prompt rewrite, and needs no re-inference. | \n|  |  | \n|  | ## Build it into a tool, not just a chat turn | \n|  | sys.path.insert(0, \"/path/to/dir/containing/jev.py\") | \n|  | from jev import JevClient, noul, choice, score | \n|  | r = JevClient(label=\"my_tool\").ask(state, {\"ok\": noul(\"Is `text` a receipt?\")}) | \n|  | p = r[\"answers\"][\"ok\"][\"noul\"] | \n|  | Keep the QUESTIONS and THRESHOLDS in one constant block at the top of the tool so a human | \n|  | can review them. That is the part that needs eyes; the rest is plumbing. | \n|  |  | \n|  | ## Go deeper | \n|  | jev guide --list          topics: questions choice score noul state confidence patterns | \n|  | design pitfalls structure cookbooks api library usage | \n|  | exit-codes install vendor | \n|  | jev guide design          BUILDING a tool or cron job on Jev, not just calling it once | \n|  | jev guide vendor          TypeSafe's own agent skill, fetched live | \n|  | jev guide <topic> --live  the vendor's page for that topic, current | \n|  | jev examples              copy-paste recipes: triage rank filter guardrail verify batch python | \n|  | jev docs                  live index of every vendor page and cookbook | \n|  | \"\"\", \"/concepts/how-to-build-with-system-one\") | \n|  |  | \n|  | GUIDE[\"questions\"] = (\"Writing instructions and criteria\", r\"\"\" | \n|  | A question is: an ID you choose (not sent to the model), a `type`, `instructions`, and | \n|  | `criteria` (options for choice, ordered levels for score, optional true/false for noul). | \n|  |  | \n|  | ## Rules that come from measured failure modes (jev-1.13) | \n|  | 1. LITERAL READING. Jev answers the words, not the intent. Scoping words, negations and | \n|  | implied conditions are taken at face value. Write the exact condition. Put boundary | \n|  | cases in the criteria. Split any interpretation into two literal questions. | \n|  | 2. ATOMIC. Broad questions hide several judgments behind one number. \"Is this spam?\" | \n|  | becomes: requests a credential? sender identity conflicts with domain? announces an | \n|  | unexpected reward? Then weight them in code. | \n|  | 3. NAME THE FIELD. With an object state, reference `path.to[0].field` in backticks. | \n|  | Structured state + named references removes ambiguity about what to judge. But do | \n|  | not rely on POSITIONAL indexes in long arrays: `items[137]` mis-locates (27% wrong | \n|  | at 150 items, 9% at 25, measured 2026-09-18). Use keyed objects (`items.k137`) or | \n|  | embed the item in the question; both 0% wrong at 320. | \n|  | 4. ALIGN INSTRUCTIONS AND CRITERIA. A noul where true means \"no\" confuses it. The | \n|  | criteria are an extension of the instruction, in the same direction. | \n|  | 5. CONTRASTIVE OPTIONS. For a choice, say what each option covers, what belongs to the | \n|  | neighbour instead, and 1-3 examples. Same field names on every option. | \n|  | 6. SITUATIONS, NOT DEGREES. Score levels are matched one by one against the state; the | \n|  | model does not see the level numbers or neighbours. \"Cosmetic; no impact\" beats \"1\". | \n|  | 7. COVER THE SPACE. Add `other` / `none_of_the_above` to a choice when inputs may not fit. | \n|  | For selection-from-candidates, the model cannot pick a value you did not offer. | \n|  | 8. KEEP MATH OUT. Counting, dates, magnitudes, hex colours, assembly: convert or compute in | \n|  | code, hand Jev the semantic part (\"does this colour read as a warning?\"). | \n|  | 9. LESS STATE. Send only what the question needs. Retrieve and filter first. | \n|  |  | \n|  | ## Shapes | \n|  | noul   {\"type\":\"noul\",\"instructions\":\"Does `msg` request a refund?\", | \n|  | \"criteria\":{\"true\":\"asks for money back or a credit\",\"false\":\"complains without asking for a remedy\"}} | \n|  | choice {\"type\":\"choice\",\"instructions\":\"Which team should handle `msg`?\", | \n|  | \"criteria\":{\"billing\":\"charges, invoices, refunds\",\"orders\":\"status, delivery, returns\",\"other\":null}} | \n|  | score  {\"type\":\"score\",\"instructions\":\"How severe is the bug in `report`?\", | \n|  | \"criteria\":[\"Cosmetic; no functional impact\",\"Broken, workaround exists\",\"Blocking; no workaround\"]} | \n|  |  | \n|  | instructions and every criteria entry may be a JSON object or array instead of a string | \n|  | (`jev guide structure`). Start with strings; add structure when two options keep getting | \n|  | confused or a level needs examples. | \n|  | \"\"\", \"/primitives\") | \n|  |  | \n|  | GUIDE[\"choice\"] = (\"Choice: pick one option from a defined set\", r\"\"\" | \n|  | Use when the answer is one of a known set with NO order between them: routing, category, | \n|  | language, entity type, which candidate span is the value. Up to 255 options; adding an | \n|  | option costs a few tokens, so give the FULL list rather than a shortlist. | \n|  |  | \n|  | Answer: `choice` (argmax), `probabilities` (every option, sums to 1), `confidence` | \n|  | (how peaked). Read the runner-up: 0.60 vs 0.38 means two teams want this ticket. | \n|  |  | \n|  | jev pick \"Which team should handle this?\" \\ | \n|  | returns=\"Exchanges, refunds, wrong or damaged items\" \\ | \n|  | shipping=\"Delivery status, delays, lost packages\" \\ | \n|  | billing=\"Charges, invoices, payment problems\" other \\ | \n|  | -s \"My shoes came in the wrong size and I was charged twice\" --min-confidence 0.4 | \n|  |  | \n|  | - Confusable neighbours: give each option an object {what, not_for, examples}. | \n|  | - Deep taxonomy: one choice per level, options = children, value = the subtree; walk in | \n|  | code, keep several branches alive when probabilities are close (beam search). | \n|  | - Relative vs absolute: a choice says WHICH option is best even when all are bad. Pair it | \n|  | with one noul per option (or a `none` option) to know whether ANY fits. | \n|  | - Speculative: \"If this is a return, why?\" is fine to ask on every ticket; ignore the | \n|  | answer when the department was not returns. | \n|  | \"\"\", \"/primitives/choice\") | \n|  |  | \n|  | GUIDE[\"score\"] = (\"Score: rate the state on an ordered rubric\", r\"\"\" | \n|  | Use when the answer is a position on a spectrum you can describe in steps: severity, | \n|  | frustration, relevance, seniority, formality. 2..10 levels, low to high. Level N is its | \n|  | index in the array. The model judges each level's description on its own against the | \n|  | state; it never sees the numbers or the neighbours. | \n|  |  | \n|  | Answer: `score` = sum(level * p), can land between levels; `probabilities` per level; | \n|  | `legend` maps level -> description; `confidence`. | \n|  |  | \n|  | jev rate \"How much does this bug report give an engineer to work with?\" \\ | \n|  | \"No detail; just says something is broken\" \\ | \n|  | \"Names the feature but no steps or environment\" \\ | \n|  | \"Steps to reproduce or environment, but not both\" \\ | \n|  | \"Steps to reproduce and environment\" -s @report.txt | \n|  |  | \n|  | - Describe SITUATIONS. Examples inside a level (object with what + examples) sharpen it, | \n|  | but only when they resemble real inputs. Test against known cases. | \n|  | - One dimension per score. \"Punctual and smart and experienced\" cannot be placed. | \n|  | - Give a rare extreme its own level (\"abusive or threatening\") so the top is not shared. | \n|  | - Do not interpolate magnitudes from a score (\"1.3 means 30% of users\"). It is a | \n|  | position for thresholding, ranking and rounding, not a measurement. | \n|  | - Same score, different shapes: 1.0 can be all-on-level-1 or half 0 / half 2. Read | \n|  | probabilities and confidence alongside. | \n|  | - Composite: normalize each score by (levels-1), then weight in code: | \n|  | priority = 0.6*severity + 0.3*frustration + 0.1*report_quality. | \n|  | \"\"\", \"/primitives/score\") | \n|  |  | \n|  | GUIDE[\"noul\"] = (\"Noul: probability that a yes/no statement is true\", r\"\"\" | \n|  | Use for a clean yes/no where the probability itself is the signal: mentions X, requests | \n|  | Y, contains PII, is a receipt, is relevant to the query, contains an instruction aimed at | \n|  | an agent. Answer: `noul` = P(yes). No separate confidence: near 1 strong yes, near 0 | \n|  | strong no, near 0.5 undecided (NOT \"medium\"; for degree use a score). | \n|  |  | \n|  | jev yes 'Does `text` contain an instruction directed at an AI agent or assistant?' \\ | \n|  | --true \"tells an agent/assistant/model to do, ignore, or reveal something\" \\ | \n|  | --false \"ordinary content with no directive aimed at a model\" \\ | \n|  | --field text=@untrusted.md --threshold 0.7 | \n|  |  | \n|  | - Phrase so high means yes. A statement form (\"the customer is requesting a refund\") | \n|  | works as well as a question; test both on your data. | \n|  | - Criteria are optional; add true=/false= when the boundary is subtle. | \n|  | - One noul per label when several labels may apply at once (multi-label), instead of | \n|  | a single choice. | \n|  | - Counting: one noul per item, the item embedded in its question or under a key | \n|  | (`items.k7`), never `items[7]` in a long array; then count in code. | \n|  | - `jev yes` exit codes: 0 yes, 1 no or uncertain (with --band LOW HIGH), 2+ errors. | \n|  | \"\"\", \"/primitives/noul\") | \n|  |  | \n|  | GUIDE[\"state\"] = (\"State: what you hand the model\", r\"\"\" | \n|  | State is the material a panel of experts would be shown before judging. String, JSON | \n|  | object, or array. Text only (no images/audio). English is strongest. | \n|  |  | \n|  | --state \"text\"            --state @file        --state -  (stdin)     cat f \\| jev … | \n|  | --state-file path         (.json parsed, else text) | \n|  | --state-json '{\"a\":1}' | \n|  | --field msg=@ticket.txt --field policy=@policy.md --field n=3   (builds an object) | \n|  |  | \n|  | Every shape below is state, and a question is separate from it: | \n|  |  | \n|  | \\| Shape \\| How \\| Reference it as \\| | \n|  | \\|---\\|---\\|---\\| | \n|  | \\| one string \\| `-s TEXT`, `-s @file`, stdin \\| the whole state \\| | \n|  | \\| many sources at once \\| `--field msg=@t.txt --field policy=@p.md --field orders=@o.json` \\| `msg`, `policy`, `orders` \\| | \n|  | \\| nested JSON \\| `--state-file o.json` \\| `open[0].charges`, `sla.tier` \\| | \n|  | \\| a sequence \\| `--state-json '[\"turn 1\",\"turn 2\"]'` \\| the array, in order \\| | \n|  | \\| a whole document \\| `--state-file bigdoc.md` \\| measured OK to 107k chars \\| | \n|  | \\| full control \\| `jev ask -f request.json` (state AND questions) \\| anything you wrote \\| | \n|  |  | \n|  | A `--field` value that is `@file.json` or inline JSON is PARSED, so an object stays an | \n|  | object and the model sees real structure. Mixing types in one request is fine: a text file, | \n|  | a JSON file, a JSONL file and a bare scalar side by side. | \n|  |  | \n|  | Prefer an OBJECT with named fields, then reference fields in instructions with backticked | \n|  | paths: `ticket.messages[0].text`, `policy`. Small arrays index fine; long ones do not | \n|  | (`items[137]` is wrong 27% of the time at 150 items). Key them: `{\"k137\": ...}`. | \n|  |  | \n|  | - One request = one state, any number of questions, all independent, all parallel. | \n|  | - Budget, MEASURED 2026-09-20 by binary search rather than taken from the docs: the largest | \n|  | state accepted was **107,500 chars = 32,388 input tokens** (765 ms); ~110k chars returns | \n|  | `HTTP 400 max_tokens_exceeded`. English measured at **3.32 chars/token**, not 4, so the | \n|  | real ceiling is nearer 107k chars than the 150k a 4-char rule of thumb implies. `jev` | \n|  | warns above 120k chars; `rank` and `batch` chunk under it. | \n|  | - Irrelevant material costs accuracy. Filter in code. If you cannot, ask a noul for | \n|  | relevance first and drop what fails. | \n|  | - State is data, not instructions, but adversarial text inside it can still steer an | \n|  | answer. Be explicit in criteria; test edge cases before trusting a guardrail. | \n|  | - When a later question depends on an earlier ANSWER (you need it to fetch data or pick | \n|  | the next options), make a second request. Otherwise ask everything at once. | \n|  | \"\"\", \"/concepts/state\") | \n|  |  | \n|  | GUIDE[\"confidence\"] = (\"Probabilities vs confidence, and how to act on them\", r\"\"\" | \n|  | Every choice/score answer carries `probabilities` (the distribution) and `confidence` | \n|  | (one number, 0..1, derived from how peaked that distribution is). Nouls carry only P(yes). | \n|  |  | \n|  | Calibration: across many predictions, outcomes given 0.8 happen ~80% of the time. It | \n|  | describes groups, not any single answer; confidence 1.0 is not a guarantee. | \n|  |  | \n|  | ## Three bands (draw the lines by stakes, then test on your data) | \n|  | high    act automatically | \n|  | medium  act with a confirmation, or gather more, or flag | \n|  | low     do not act: escalate to a person or a reasoning model, or ask | \n|  |  | \n|  | ## Thresholds scale with risk | \n|  | if a.confidence < 0.5:        escalate()          # genuinely unsure | \n|  | elif a.choice == \"read_only\":  do_it()             # cheap to be wrong | \n|  | elif a.choice == \"destroy\": | \n|  | if a.confidence > 0.9:     confirm_then_do() | \n|  | else:                      ask_user() | \n|  |  | \n|  | - Low choice confidence: no clear winner, OR several acceptable answers (harmless). | \n|  | - Low score confidence: levels overlap, question measures >1 thing, or the state does | \n|  | not say enough. | \n|  | - If all you need is the best option, take the argmax; thresholds are for deciding | \n|  | whether to ACT. If you have a statistical procedure in mind, use probabilities, not | \n|  | the confidence summary. | \n|  | - Aliases move (`jev-latest` -> new version). Thresholds tuned on one version: pin the | \n|  | versioned id (`jev-1.13.0`) with --model and migrate on your schedule. | \n|  | \"\"\", \"/confidence\") | \n|  |  | \n|  | GUIDE[\"patterns\"] = (\"Patterns that compose Jev into systems\", r\"\"\" | \n|  | 1. SPECULATIVE FAN-OUT. Put every question the workflow might need in one request, | \n|  | including ones that matter only on some branches. Parallel, independent, near-zero | \n|  | latency cost. 13 questions in one call measured 12x cheaper and 10x faster than 13 | \n|  | calls, with identical answers. Code decides which answers count. | \n|  | 2. CONFIDENCE-GATED ROUTING. The answer says WHAT; confidence says WHETHER to act. Gate | \n|  | each action at its own threshold by consequence. (`jev guide confidence`) | \n|  | 3. COMPOSITE SCORING. Break a judgment into atomic scores, normalize by (levels-1), | \n|  | weight in code. Weights are reviewable and tunable without re-inference. | \n|  | 4. INTENT ROUTING. Cheap classifier in front of expensive handlers: deterministic code | \n|  | for one intent, a specialist LLM for another, a human for the low-confidence rest. | \n|  | 5. SELECT, DO NOT GENERATE. Find candidate spans/values with regex or a generative model, | \n|  | then let Jev CHOOSE the right one. Extraction becomes a choice over enumerated options | \n|  | with an explicit \"not stated\". | \n|  | 6. RERANK / FILTER. Cheap retrieval (BM25, embeddings, grep) makes a shortlist; one Jev | \n|  | question per query-candidate pair grades it. `jev rank` does this in one request per | \n|  | chunk. Measured on a legal corpus: top-1 5% -> 18%, top-10 38% -> 62%. | \n|  | 7. VERIFY AND ESCALATE. Check a claim against its source (supports / contradicts / says | \n|  | nothing), an extraction against the document, a tool-call trace against its intent. | \n|  | Low confidence goes to a human or a reasoning model. Cascade: small model extracts, | \n|  | Jev verifies, big model only on the uncertain slice. | \n|  | 8. GUARDRAIL. One request per message, in and out of an LLM: a battery of nouls (jailbreak? | \n|  | harm? self-harm? instruction aimed at the model?) plus a severity score. Threshold in | \n|  | code: pass / review / block / route. | \n|  | 9. MAP-REDUCE. Thousands of items x same questions -> `jev batch`, then aggregate in code. | \n|  | Probabilities become features for a classical model when you have labels. | \n|  | 10. TWO-STAGE SELECTION. Rank everything cheaply, then re-judge the top K with fuller | \n|  | evidence and let the second stage reject all of them. (skill suggestion cookbook: | \n|  | wrong loads down by more than half.) | \n|  | \"\"\", \"/patterns\") | \n|  |  | \n|  | GUIDE[\"design\"] = (\"Designing a NEW integration (tool, cron job, pipeline)\", r\"\"\" | \n|  | Runtime use is `jev yes\\|pick\\|rate\\|ask\\|rank\\|batch`. This topic is for the other job: you | \n|  | are about to BUILD something that calls Jev on every run. Much of it is distilled from | \n|  | TypeSafe's own agent skill (github.com/typesafe-ai/skills, MIT), which is a docs-oriented | \n|  | skill for exactly this job; `jev guide vendor` fetches it live. | \n|  |  | \n|  | ## Start from the behaviour, work back to the judgments | \n|  | What will the tool show, select, change, or hand off? List the judgments that decision | \n|  | needs. Keep known rules, calculations, exact lookups and execution in code. Preserve the | \n|  | stack and scope already in place; add Jev only where semantic understanding helps. | \n|  |  | \n|  | ## Shapes beyond \"classify\" | \n|  | - Route AND fill arguments: one request selects the handler and its closed-set params. | \n|  | - Select instead of generate: code finds candidate spans/values, Jev picks the intended | \n|  | one. Check candidate COVERAGE: the model cannot choose a value you did not offer. | \n|  | - Find and judge evidence: cheap retrieval, then per-candidate relevance, then select. | \n|  | - Judgments as reusable data: score dimensions once; weights, thresholds, rankings and | \n|  | views change in code with no re-inference while the evidence and questions stand. | \n|  | - Verify and escalate: check a claim/field/tool-call against its evidence; send the | \n|  | uncertain slice to a person or a reasoning model. | \n|  | - Respond to changing state: keep INFERRED state distinct from OBSERVED facts, and check | \n|  | freshness before applying an old answer to a changed situation. | \n|  |  | \n|  | ## Atomic is not \"one fact per question\" | \n|  | A bounded action selection or a contextual interpretation is a valid single judgment. | \n|  | Split independently useful dimensions; do not split a relationship you need judged whole. | \n|  |  | \n|  | ## Policy stays explicit in code | \n|  | Weighted sums suit compensating preferences. An \"any serious violation blocks\" rule needs | \n|  | separate conditions, not a weight. Ignore uncertainty on branches you do not take. Several | \n|  | acceptable alternatives can spread probability; low confidence on a harmless preference | \n|  | choice is not a reason to stop. Typed output guarantees the INTERFACE, not truth: | \n|  | validate on your own data before trusting it unattended. | \n|  |  | \n|  | ## Ship checklist | \n|  | 1. Questions + thresholds in ONE constant block at the top of the file. Agents write | \n|  | mediocre questions; expect a human to edit them, so make them easy to find. | \n|  | 2. `--model jev-1.13.0` pinned once thresholds are tuned. `jev-latest` moves. | \n|  | 3. A handful of known cases run before the first unattended run; when one fails, separate | \n|  | missing evidence / model error / code error / service failure before changing anything. | \n|  | 4. `label=` set on the client so `jev usage` attributes the spend. | \n|  | 5. Long lists: never `items[i]`; key the object or embed the item (see `pitfalls` row 10). | \n|  | 6. Never embed the key in a web page or a repo; the CLI reads ~/.config/typesafe/api_key. | \n|  | \"\"\", \"/concepts/how-to-build-with-system-one\") | \n|  |  | \n|  | GUIDE[\"vendor\"] = (\"TypeSafe's own agent skill (fetched live from GitHub)\", r\"\"\" | \n|  | TypeSafe publishes a docs-oriented skill for agents BUILDING integrations: | \n|  | https://github.com/typesafe-ai/skills  (skills/typesafe-ai/SKILL.md, MIT, ~2.5k tokens) | \n|  | It has no executable and no runtime commands; `jev` is the runtime. Its value is the | \n|  | design guidance and the map of which vendor page to read for which task, and it is | \n|  | updated by the vendor when the API changes. `jev guide vendor --live` prints the current | \n|  | copy. `jev guide design` is our distillation, kept short. | \n|  | \"\"\", \"https://raw.githubusercontent.com/typesafe-ai/skills/main/skills/typesafe-ai/SKILL.md\") | \n|  |  | \n|  | GUIDE[\"pitfalls\"] = (\"Jagged edges of jev-1.13 (vendor-acknowledged)\", r\"\"\" | \n|  | \\| # \\| failure                              \\| do this instead                                   \\| | \n|  | \\| 1 \\| literal reading                      \\| write the exact condition; boundary cases in criteria \\| | \n|  | \\| 2 \\| math, counting, magnitudes           \\| compute in code; one noul per item then sum       \\| | \n|  | \\| 3 \\| date/time comparison                 \\| extract parts as choices; compare in code         \\| | \n|  | \\| 4 \\| indirection, double negatives        \\| direct wording; name the field                    \\| | \n|  | \\| 5 \\| large state with irrelevant detail   \\| filter first; relevance noul if you cannot        \\| | \n|  | \\| 6 \\| adversarial content in state         \\| precise criteria; test edge cases                 \\| | \n|  | \\| 7 \\| contradictory instructions/criteria  \\| align them; true must mean yes                    \\| | \n|  | \\| 8 \\| expected structural invariants       \\| P(x) and 1-P(not x) need not agree; noul vs choice thresholds differ; ask one way \\| | \n|  | \\| 9 \\| generation                           \\| it cannot; select from candidates instead         \\| | \n|  | \\| 10\\| positional index into a long array   \\| (ours, measured 2026-09-18) `items[137]` 27% wrong at 150, 9% at 25; keyed object or item-in-question 0% at 320 \\| | \n|  |  | \n|  | Numeric representations (hex colours, RGB, assembly) underperform names and high-level | \n|  | code. Non-English works but is weaker; watch confidence. Reviewed by the vendor | \n|  | 2026-09-17. Live: jev guide pitfalls --live | \n|  | \"\"\", \"/model-jaggedness/jev-1.13\") | \n|  |  | \n|  | GUIDE[\"structure\"] = (\"Structured instructions and criteria (JSON instead of strings)\", r\"\"\" | \n|  | `instructions`, every choice option description, every score level, and noul true/false | \n|  | may be a string, an object, an array, or null. The model is trained on structure; keys | \n|  | are labels it reads, so use short descriptive names (none are reserved). | \n|  |  | \n|  | \"instructions\": {\"question\": \"Does the claimed sender conflict with the domain?\", | \n|  | \"compare\": [\"`ticket.sender.display_name`\", \"` ticket.sender.email`\"], | \n|  | \"focus\": \"Compare the named organization with the email domain.\"} | \n|  |  | \n|  | \"criteria\": {\"return_policy\": {\"what\": \"rules for returns in general\", | \n|  | \"not_for\": \"the status of a specific return\", | \n|  | \"examples\": [\"Can I return sale items?\"]}, | \n|  | \"return_status\": {\"what\": \"where a specific return is\", | \n|  | \"not_for\": \"general policy questions\", | \n|  | \"examples\": [\"Where is my refund for order A-104?\"]}} | \n|  |  | \n|  | score level: {\"what\": \"Broken or degraded, workaround exists\", | \n|  | \"examples\": [\"export fails in one browser but works in another\"]} | \n|  |  | \n|  | When: a question has several parts; two options keep getting confused; a level needs | \n|  | examples; the supporting data is already JSON (schema, taxonomy, record). Use the same | \n|  | field names across options so the model compares like with like. Examples only help when | \n|  | they resemble real inputs; the wrong example changes little, the right one concentrates | \n|  | probability (measured 0.54 -> 0.90 confidence on the same ticket). | \n|  |  | \n|  | Taxonomy walk: option value = the child subtree, so the model sees what lives under a | \n|  | branch before committing. Trim large subtrees to direct children plus sample leaves. | \n|  | \"\"\", \"/primitives/advanced\") | \n|  |  | \n|  | GUIDE[\"cookbooks\"] = (\"Vendor cookbooks (worked, measured examples)\", r\"\"\" | \n|  | Each is a page under https://docs.typesafe.ai/cookbooks/<slug>.md | \n|  | parallel_questions               13 questions, one call: 12.2x cheaper, 10x faster, same answers | \n|  | skill_suggestion                 rank 182 agent skills, re-judge top 3, may reject all; wrong loads halved | \n|  | rerank_typesafe                  BM25 shortlist -> one question per pair; top-1 5% -> 18% | \n|  | semantic_find                    score 218 line ids vs a query in ONE choice; noul: is there an answer at all | \n|  | classifying_rag_passages         per passage: relevant? usable? contradicts premise? instructs the model? | \n|  | citation_check                   supports / contradicts / says nothing; confidence flags for review | \n|  | llm_guardrails                   noul battery + severity score on every LLM input and output | \n|  | function_calling                 NL request -> function name + closed-set args, confidence-aware | \n|  | pre_parsed_value_extraction      regex finds candidates, Jev selects the intended span | \n|  | date_extraction_cookbook         month/day/year as choices with \"not stated\"; code assembles and compares | \n|  | autoformat                       recover Markdown structure: line-join nouls, then block-type choices | \n|  | hierarchical_classification      beam search over choice probabilities through deep taxonomies | \n|  | entity_alignment                 one 3-level score decides merge / leave / send to curator | \n|  | sde_cascade                      mini extracts -> Jev verifies -> reasoning model only where needed | \n|  | consistency_noul_cookbook        14 nouls x 15 runs: std dev 0.0102, below every LLM; route 0.3-0.7 to review | \n|  | consistency_choice_cookbook      add an explicit `uncertain` outcome to moderation decisions | \n|  | classification_using_confidence  75 industry groups; low confidence -> report the parent division | \n|  | autoresearch_feature_discovery   propose questions, turn text into features, train CatBoost on them | \n|  | Read one with: jev docs --grep <slug>   then fetch the .md URL. | \n|  | \"\"\", \"/cookbooks/parallel_questions\") | \n|  |  | \n|  | GUIDE[\"api\"] = (\"HTTP API, limits, pricing\", r\"\"\" | \n|  | POST https://api.typesafe.ai/v1/systemone      Authorization: Bearer <key> | \n|  | body   {\"state\": str\\|obj\\|arr, \"model\": \"jev-latest\", \"questions\": {id: Question}} | \n|  | answer {\"model\": \"jev-1.13.0\", \"answers\": {id: Answer}, \"usage\": {\"input_tokens\", \"output_tokens\"}} | \n|  | GET  /v1/models   lists aliases (jev-latest, jev-preview); versioned ids like jev-1.13.0 also accepted | \n|  |  | \n|  | Errors: 401 bad key · 422 malformed request (body names the field) · 429 rate limit · | \n|  | 529 overloaded. `jev` retries 429/529/5xx with backoff and honours retry-after. | \n|  | Limits (jev-1.13, adjust without notice): 250k tokens/s, 1200 req/min; 64k tokens per | \n|  | request, 32k for state + longest question. MEASURED 2026-09-20: 107,500 chars of English | \n|  | state = 32,388 tokens went through; ~110k chars returned `400 max_tokens_exceeded`, an error | \n|  | code the docs do not list. English runs 3.32 chars/token, so budget on tokens, not on the | \n|  | 4-chars-per-token rule of thumb. Text only. | \n|  | Price: $42 per billion input tokens ($0.042/Mtok). Output free. `jev usage` shows spend, | \n|  | `jev cost` estimates a job, `jev config set credits` tracks a balance (no balance endpoint | \n|  | exists; see `jev guide usage`). | \n|  | Model is not fine-tuned per customer; you shape it through state, instructions, criteria. | \n|  | Not trained on customer traffic. `jev schema` prints a request skeleton. | \n|  | Full JSON path: jev ask -f request.json   (or `jev ask` with the JSON body on stdin) | \n|  | \"\"\", \"/api\") | \n|  |  | \n|  | GUIDE[\"library\"] = (\"Using jev from Python (tools, Cues, pipelines)\", r\"\"\" | \n|  | import sys; sys.path.insert(0, \"/path/to/dir/containing/jev.py\") | \n|  | from jev import JevClient, noul, choice, score, JevError | \n|  |  | \n|  | QUESTIONS = {                                  # keep questions + thresholds together, reviewable | \n|  | \"is_receipt\": noul(\"Is `email.body` a purchase receipt or order confirmation?\"), | \n|  | \"vendor\": choice(\"Which vendor sent `email`?\", {\"amazon\": None, \"apple\": None, \"other\": None}), | \n|  | \"urgency\": score(\"How urgent is `email.body`?\", [\"None\", \"This week\", \"Today\"]), | \n|  | } | \n|  | THRESHOLDS = {\"is_receipt\": 0.7, \"vendor_conf\": 0.6} | \n|  |  | \n|  | client = JevClient(label=\"mail_triage\")        # label shows up in `jev usage` | \n|  | r = client.ask({\"email\": {\"subject\": s, \"body\": b}}, QUESTIONS) | \n|  | a = r[\"answers\"] | \n|  | if a[\"is_receipt\"][\"noul\"] >= THRESHOLDS[\"is_receipt\"]: ... | \n|  | if a[\"vendor\"][\"confidence\"] < THRESHOLDS[\"vendor_conf\"]: escalate() | \n|  |  | \n|  | - `ask()` raises JevError (exit_code attr: 2 usage, 3 auth, 4 api, 5 network). | \n|  | - Many items: a ThreadPoolExecutor over `client.ask` (8 workers is safe), or shell out | \n|  | to `jev batch`. Every call appends one line to ~/.config/typesafe/usage.jsonl. | \n|  | - Official SDKs exist (`pip install typesafe-sdk`, `npm i @typesafe-ai/sdk`) with typed | \n|  | answers and retries; this module is the zero-dependency path that works from any agent. | \n|  | - Pin `--model jev-1.13.0` in a pipeline whose thresholds you tuned. | \n|  | \"\"\", \"/sdk/python\") | \n|  |  | \n|  | GUIDE[\"usage\"] = (\"Usage, cost, credits and rate limits\", r\"\"\" | \n|  | Every request appends one row to ~/.config/typesafe/usage.jsonl: ts, cmd (the label), agent | \n|  | ($JEV_AGENT), q (questions), in/out tokens, ms, model, rid (x-typesafe-request-id), | \n|  | attempts when retried, or err on failure. Nothing secret is in it. `record=False` on | \n|  | JevClient skips it. | \n|  |  | \n|  | jev usage                 windows (today/yesterday/7d/30d/month/all), latency p50/p95, | \n|  | peak req/min and tok/s vs the published limits, errors, forecast, | \n|  | credits countdown, budget, by command, by agent (names resolved) | \n|  | jev usage --by day        also hour, cmd, agent, model     --days N | \n|  | jev usage --tail 20       recent requests with request ids (quote a rid to the vendor) | \n|  | jev usage --since 2026-09-01 --label rank --agent 8ba5 --json | \n|  | jev cost --state-file f --questions 12 [--exact]      tokens + usd before you run it | \n|  | jev cost -s \"…\" --items 5000                          a rank-shaped job over 5,000 items | \n|  | jev config set credits 50     balance read off the console; usage counts down from it | \n|  | jev config set budget 5       monthly USD budget; usage shows % used and a projection | \n|  | jev config set price 0.042    only if the vendor changes list price | \n|  |  | \n|  | ## What the API does NOT give you (measured 2026-09-19) | \n|  | No balance, usage, or quota endpoint exists (/v1/usage, /v1/balance, /v1/account ... all | \n|  | 404) and responses carry no rate-limit headers, only x-typesafe-request-id. \"Tokens | \n|  | remaining\" therefore means one of three things here: | \n|  | 1. credits remaining: a balance YOU snapshot from https://console.typesafe.ai via | \n|  | `jev config set credits`, minus spend recorded since. Drift = calls made from | \n|  | another machine or key. Re-snapshot when you look at the console. | \n|  | 2. request budget: 64k tokens per request, 32k for state + longest question. `jev cost` | \n|  | says whether a state fits and how many items pack per request. | \n|  | 3. rate headroom: 1,200 req/min and 250k tok/s (adjust without notice). `jev usage` | \n|  | shows your measured peaks as a percentage of both. | \n|  | Price: $42 per billion input tokens ($0.042/Mtok). Output is free. A 1k-token item costs | \n|  | $0.00004; a thousand of them cost four cents. | \n|  | \"\"\", \"/models\") | \n|  |  | \n|  | GUIDE[\"exit-codes\"] = (\"Exit codes\", r\"\"\" | \n|  | 0  success / yes / confident | \n|  | 1  `yes`: no or uncertain · `pick`/` rate`: confidence below --min-confidence | \n|  | 2  usage error (bad flags, empty state, malformed question) | \n|  | 3  auth error (no key, key rejected) | \n|  | 4  API error after retries (429/529/5xx exhausted, 422) · `batch`: some rows failed | \n|  | 5  network error after retries | \n|  | Errors print one line to stderr prefixed `jev:`; with --json the line is JSON. | \n|  | \"\"\", None) | \n|  |  | \n|  | GUIDE[\"install\"] = (\"Where jev lives and how it is maintained\", r\"\"\" | \n|  | Single file      jev.py, anywhere on disk; symlink it onto PATH:  ln -s $PWD/jev.py ~/.local/bin/jev | \n|  | Requires         Python 3.10+, standard library only | \n|  | Key              jev auth set <key>   -> ~/.config/typesafe/api_key (0600), or export TYPESAFE_API_KEY | \n|  | Keys: https://console.typesafe.ai/keys | \n|  | Usage ledger     ~/.config/typesafe/usage.jsonl   (jev usage) | \n|  | Config           ~/.config/typesafe/config.json   (jev config: credits, budget, price; no secrets) | \n|  | Skill            copy the jev/ skill folder (SKILL.md) into your agent's skills dir: | \n|  | Claude Code   ~/.claude/skills/jev/ | \n|  | Codex         ~/.agents/skills/jev/  (documented user path; ~/.codex/skills/ also read) | \n|  | OpenCode      ~/.config/opencode/skills/jev/ | \n|  | One canonical copy, symlinked into each, is easiest to keep current. | \n|  | Attribution      export JEV_AGENT=<name> so `jev usage --by agent` can tell your agents apart | \n|  | Health           jev doctor | \n|  | Vendor docs      https://docs.typesafe.ai   (Markdown at any page path + .md; index at /llms.txt) | \n|  | Vendor skill     github.com/typesafe-ai/skills is a docs-orientation skill for BUILDING integrations, | \n|  | with no executable. `jev guide vendor` fetches it live. Installing both puts two skills | \n|  | on the same triggers; pick one. | \n|  | \"\"\", None) | \n|  |  | \n|  | EXAMPLES: dict[str, tuple[str, str]] = {} | \n|  |  | \n|  | EXAMPLES[\"gutcheck\"] = (\"One calibrated yes/no, usable in an `if`\", r\"\"\" | \n|  | if jev yes 'Does `text` describe a package delivery?' --field text=\"$DESC\" --threshold 0.7; then | \n|  | echo delivery | \n|  | fi | \n|  | cat draft.md \\| jev yes \"Does the text contain an em dash character or the phrase 'you're absolutely right'?\" | \n|  | # (that one is a lint, and grep does it better; use jev for judgments grep cannot make) | \n|  | cat draft.md \\| jev yes \"Does the text flatter the reader or agree without giving a reason?\" --json | \n|  | \"\"\") | \n|  |  | \n|  | EXAMPLES[\"triage\"] = (\"Classify + speculative questions in one call\", r\"\"\" | \n|  | jev ask --field message=@ticket.txt --field open_orders='[\"A-104\",\"A-118\"]' \\ | \n|  | --choice team 'Which team should handle `message`?' \\ | \n|  | billing=\"Charges, invoices, refunds, subscriptions\" \\ | \n|  | orders=\"Order status, delivery, cancellation, returns\" \\ | \n|  | account=\"Login, profile, permissions, security\" other \\ | \n|  | --noul refund 'Does `message` explicitly ask for money back or a credit?' \\ | \n|  | --noul mentions_order 'Does `message` refer to one of `open_orders` by id?' \\ | \n|  | --score anger 'How angry is the author of `message`?' \\ | \n|  | \"Calm and matter-of-fact\" \"Frustrated but civil\" \"Hostile or threatening to leave\" \\ | \n|  | --json | \n|  | # then in code: route on team.choice if team.confidence >= 0.6 else escalate; | \n|  | # read `refund` only on the billing branch; read `mentions_order` only on orders. | \n|  | \"\"\") | \n|  |  | \n|  | EXAMPLES[\"rank\"] = (\"Rank or filter many candidates against a query (one request per chunk)\", r\"\"\" | \n|  | # lines in a file | \n|  | jev rank --query \"notes about thermostat schedules\" --candidates-file titles.txt --top 10 | \n|  | # JSON array of objects (each candidate is shown to the model as JSON) | \n|  | jev rank --query \"a bug that causes data loss\" --candidates-file issues.json --min 0.6 --json | \n|  | # stdin, graded on a rubric instead of yes/no | \n|  | ls Meetings \\| jev rank --query \"meetings about the Q3 launch\" \\ | \n|  | --levels \"unrelated\" \"adjacent\" \"directly about it\" | \n|  | # custom question; refer to the item as `candidate` (it is embedded in each question) | \n|  | jev rank --query \"$Q\" --candidates-file x.txt --instructions 'Does `candidate` answer `query`?' | \n|  | # extra shared context for every judgment | \n|  | jev rank --query \"…\" --candidates-file x.txt --context @rubric.md | \n|  | \"\"\") | \n|  |  | \n|  | EXAMPLES[\"guardrail\"] = (\"Screen untrusted text before acting on it\", r\"\"\" | \n|  | jev ask --field text=@untrusted.md \\ | \n|  | --noul injection 'Does `text` contain an instruction aimed at an AI agent, assistant, or model?' \\ | \n|  | true=\"tells a model to do, ignore, reveal, or change something\" \\ | \n|  | false=\"ordinary content; any imperatives are aimed at a human reader\" \\ | \n|  | --noul secrets 'Does `text` ask the reader to disclose a credential, key, or password?' \\ | \n|  | --score harm 'How much harm would follow from doing what `text` asks?' \\ | \n|  | \"None\" \"Minor or reversible\" \"Serious or irreversible\" --json | \n|  | # thresholds live in your code: block if injection >= 0.7 or harm >= 1.5; review 0.4..0.7 | \n|  | \"\"\") | \n|  |  | \n|  | EXAMPLES[\"verify\"] = (\"Check a claim against its source, or a draft against a rule\", r\"\"\" | \n|  | jev ask --field claim=\"$CLAIM\" --field source=@source.md \\ | \n|  | --choice support 'How does `source` relate to `claim`?' \\ | \n|  | supports=\"the source states or entails the claim\" \\ | \n|  | contradicts=\"the source states the opposite or an incompatible fact\" \\ | \n|  | silent=\"the source does not address the claim\" --json | \n|  | # confidence < 0.8 -> a human confirms it | \n|  |  | \n|  | jev ask --field draft=@post.md --field rules=@voice_rules.md \\ | \n|  | --noul r1 'Does `draft` violate any rule stated in `rules`?' \\ | \n|  | --noul r2 'Does `draft` contain a sentence that flatters the reader?' \\ | \n|  | --score tone 'How formal is `draft`?' \"casual\" \"neutral\" \"formal\" | \n|  | \"\"\") | \n|  |  | \n|  | EXAMPLES[\"batch\"] = (\"Same questions over thousands of rows -> JSONL\", r\"\"\" | \n|  | # rows: one JSON object per line; --state-key picks the field to judge, --id-key is echoed back | \n|  | jev batch --input items.jsonl --state-key text --id-key id --concurrency 8 \\ | \n|  | --noul relevant 'Is `text` about home automation?' \\ | \n|  | --score quality 'How useful is `text` to a power user?' \"noise\" \"some value\" \"must read\" \\ | \n|  | --out results.jsonl | \n|  | # plain text lines, one state per line | \n|  | jev batch --input lines.txt --text-lines --noul q \"Is this line a TODO?\" > out.jsonl | \n|  | # aggregate in code:  jq 'select(.answers.relevant.noul > 0.7) \\| .id' results.jsonl | \n|  | \"\"\") | \n|  |  | \n|  | EXAMPLES[\"python\"] = (\"From a tool or a cron job\", r\"\"\" | \n|  | import sys; sys.path.insert(0, \"/path/to/dir/containing/jev.py\") | \n|  | from jev import JevClient, noul, choice, score | \n|  | Q = {\"delivery\": noul(\"Does `event.description` describe a package being delivered?\"), | \n|  | \"who\": choice(\"Who is at the door in `event.description`?\", | \n|  | {\"courier\": None, \"family\": None, \"stranger\": None, \"nobody\": None})} | \n|  | r = JevClient(label=\"ring_watch\").ask({\"event\": ev}, Q) | \n|  | if r[\"answers\"][\"delivery\"][\"noul\"] > 0.8: notify() | \n|  | \"\"\") | \n|  |  | \n|  | # --------------------------------------------------------------------------- argparse | \n|  |  | \n|  | SHORT_HELP = \"\"\"jev: calibrated, typed decisions from TypeSafe's Jev model (~250 ms, $0.042/Mtok) | \n|  |  | \n|  | jev yes  \"question?\" -s TEXT                 P(yes); exit 0 yes / 1 no | \n|  | jev pick \"which?\" a=desc b=desc other -s TEXT   one option + probabilities + confidence | \n|  | jev rate \"how much?\" \"low\" \"mid\" \"high\" -s TEXT position on your rubric + confidence | \n|  | jev ask  --noul/--choice/--score … -s TEXT   many questions, one call (fan-out), --json | \n|  | jev rank --query Q --candidates-file F       rank/filter many items, chunked | \n|  | jev batch --input rows.jsonl --noul …        same questions over many rows -> JSONL | \n|  |  | \n|  | jev guide            the playbook (read once per session)   jev guide --list | \n|  | jev examples         copy-paste recipes                     jev docs   live vendor index | \n|  | jev usage            spend, tokens, latency, throughput, credits, budget   (--by, --tail, --json) | \n|  | jev cost             estimate a job before running it   jev config   credits / budget / price | \n|  | jev doctor · models · schema · auth set\\|status\\|clear · version | \n|  |  | \n|  | State: -s/--state TEXT \\| --state-file F \\| --state-json J \\| --field k=v (v=@file) \\| stdin. | \n|  | Questions reference fields with backticks; SINGLE-QUOTE them in a shell: 'Does `message` ask for a refund?' | \n|  | \"\"\" | \n|  |  | \n|  |  | \n|  | def add_state_args(p): | \n|  | g = p.add_argument_group(\"state\") | \n|  | g.add_argument(\"-s\", \"--state\", help=\"text to judge; @path reads a file; '-' reads stdin\") | \n|  | g.add_argument(\"--state-file\", help=\"file to judge (.json is parsed, else text)\") | \n|  | g.add_argument(\"--state-json\", help=\"inline JSON state\") | \n|  | g.add_argument(\"--field\", action=\"append\", metavar=\"KEY=VALUE\", help=\"build an object state; VALUE may be @file or JSON; repeatable; combines with --state as `text`\") | \n|  |  | \n|  |  | \n|  | def add_question_args(p): | \n|  | g = p.add_argument_group(\"questions (repeatable, any mix)\") | \n|  | g.add_argument(\"--noul\", dest=\"noul\", action=QAction, nargs=\"+\", metavar=\"ARG\", help=\"ID INSTRUCTIONS [true=…] [false=…]\") | \n|  | g.add_argument(\"--choice\", dest=\"choice\", action=QAction, nargs=\"+\", metavar=\"ARG\", help=\"ID INSTRUCTIONS OPTION[=desc] OPTION[=desc] …\") | \n|  | g.add_argument(\"--score\", dest=\"score\", action=QAction, nargs=\"+\", metavar=\"ARG\", help=\"ID INSTRUCTIONS LEVEL LEVEL … (low to high, 2..10)\") | \n|  | g.add_argument(\"--questions-file\", \"-q\", help=\"JSON file: {id: question}\") | \n|  | g.add_argument(\"--questions-json\", help=\"inline JSON: {id: question}\") | \n|  |  | \n|  |  | \n|  | def add_common(p): | \n|  | p.add_argument(\"--model\", default=None, help=f\"model id or alias (default {DEFAULT_MODEL}; pin e.g. jev-1.13.0)\") | \n|  | p.add_argument(\"--api-key\", default=None, help=\"override key resolution\") | \n|  | p.add_argument(\"--timeout\", type=float, default=30.0) | \n|  | p.add_argument(\"--json\", action=\"store_true\", help=\"machine output (raw API response where applicable)\") | \n|  | p.add_argument(\"--compact\", action=\"store_true\", help=\"single-line JSON\") | \n|  | p.add_argument(\"-v\", \"--verbose\", action=\"store_true\") | \n|  |  | \n|  |  | \n|  | def build_parser() -> argparse.ArgumentParser: | \n|  | p = argparse.ArgumentParser(prog=\"jev\", description=SHORT_HELP, formatter_class=argparse.RawDescriptionHelpFormatter, add_help=True) | \n|  | p.add_argument(\"--version\", action=\"version\", version=f\"jev {VERSION}\") | \n|  | sub = p.add_subparsers(dest=\"cmd\") | \n|  |  | \n|  | a = sub.add_parser(\"ask\", help=\"many questions, one call\", description=\"Ask any mix of noul/choice/score questions about one state in ONE request (speculative fan-out). Also: `jev ask -f request.json` or a full JSON body on stdin.\", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=EXAMPLES[\"triage\"][1]) | \n|  | add_state_args(a) | \n|  | add_question_args(a) | \n|  | a.add_argument(\"-f\", \"--request\", help=\"full request JSON file (state+questions); '-' for stdin\") | \n|  | add_common(a) | \n|  | a.set_defaults(fn=cmd_ask_entry) | \n|  |  | \n|  | y = sub.add_parser(\"yes\", help=\"one yes/no -> P(yes); exit 0/1\", description=\"One noul question. Prints `<p> yes\\|no\\|uncertain`. Exit 0 when p >= --threshold (or >= HIGH of --band), else 1.\") | \n|  | y.add_argument(\"instructions\", help=\"the yes/no question; phrase so that high = yes\") | \n|  | y.add_argument(\"--true\", help=\"what a yes means (optional criteria)\") | \n|  | y.add_argument(\"--false\", help=\"what a no means (optional criteria)\") | \n|  | y.add_argument(\"--threshold\", type=float, default=0.5) | \n|  | y.add_argument(\"--band\", type=float, nargs=2, metavar=(\"LOW\", \"HIGH\"), help=\"p < LOW no · LOW..HIGH uncertain · >= HIGH yes\") | \n|  | add_state_args(y) | \n|  | add_common(y) | \n|  | y.set_defaults(fn=cmd_yes) | \n|  |  | \n|  | k = sub.add_parser(\"pick\", help=\"one choice -> option + confidence\", description=\"One choice question. Options as NAME or NAME=description (null description is fine when the name is clear). Exit 1 when confidence < --min-confidence.\") | \n|  | k.add_argument(\"instructions\") | \n|  | k.add_argument(\"options\", nargs=\"+\", metavar=\"OPTION[=desc]\") | \n|  | k.add_argument(\"--min-confidence\", type=float, default=0.0) | \n|  | add_state_args(k) | \n|  | add_common(k) | \n|  | k.set_defaults(fn=cmd_pick) | \n|  |  | \n|  | r = sub.add_parser(\"rate\", help=\"one score -> position on rubric\", description=\"One score question. Levels low to high, 2..10, each describing a situation. Exit 1 when confidence < --min-confidence.\") | \n|  | r.add_argument(\"instructions\") | \n|  | r.add_argument(\"levels\", nargs=\"+\", metavar=\"LEVEL\") | \n|  | r.add_argument(\"--min-confidence\", type=float, default=0.0) | \n|  | add_state_args(r) | \n|  | add_common(r) | \n|  | r.set_defaults(fn=cmd_rate) | \n|  |  | \n|  | rk = sub.add_parser(\"rank\", help=\"rank/filter many candidates vs a query\", description=\"Grades every candidate against --query with one question per candidate (the item embedded in its question), packed into as few requests as the token budget allows. Default: noul relevance. With --levels: a score rubric (normalized to 0..1 as p).\", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=EXAMPLES[\"rank\"][1]) | \n|  | rk.add_argument(\"--query\", required=True, help=\"what you are looking for (text, JSON, or @file)\") | \n|  | rk.add_argument(\"--candidates-file\", help=\"one candidate per line, or a .json array\") | \n|  | rk.add_argument(\"candidates\", nargs=\"*\", help=\"candidates as arguments (or stdin)\") | \n|  | rk.add_argument(\"--instructions\", help=\"the question, referring to `candidate` and `query`, e.g. 'Does `candidate` answer `query`?' (the item is embedded in each question)\") | \n|  | rk.add_argument(\"--levels\", nargs=\"+\", metavar=\"LEVEL\", help=\"use a score rubric instead of yes/no\") | \n|  | rk.add_argument(\"--context\", help=\"extra shared state (text, JSON, or @file) available as `context`\") | \n|  | rk.add_argument(\"--top\", type=int, help=\"keep the best N\") | \n|  | rk.add_argument(\"--min\", type=float, help=\"keep p >= MIN\") | \n|  | rk.add_argument(\"--chunk-size\", type=int, default=250, help=\"max candidates per request (default 250; 320 measured at 0.4 s)\") | \n|  | rk.add_argument(\"--chunk-chars\", type=int, default=90_000, help=\"max candidate chars per request (default 90k)\") | \n|  | rk.add_argument(\"--concurrency\", type=int, default=6) | \n|  | rk.add_argument(\"--width\", type=int, default=110, help=\"truncate candidate display\") | \n|  | add_common(rk) | \n|  | rk.set_defaults(fn=cmd_rank) | \n|  |  | \n|  | b = sub.add_parser(\"batch\", help=\"same questions over many rows -> JSONL\", description=\"One request per input row, in parallel. Rows: JSONL (object = state, or --state-key picks a field), or plain text lines (--text-lines). Output: JSONL with answers per row.\", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=EXAMPLES[\"batch\"][1]) | \n|  | b.add_argument(\"--input\", \"-i\", required=True, help=\"JSONL or text file; '-' for stdin\") | \n|  | b.add_argument(\"--state-key\", help=\"field of each JSON row to use as the state\") | \n|  | b.add_argument(\"--id-key\", default=\"id\", help=\"field echoed back as `id` (default id)\") | \n|  | b.add_argument(\"--text-lines\", action=\"store_true\", help=\"treat every line as a plain-text state\") | \n|  | b.add_argument(\"--echo\", action=\"store_true\", help=\"include the state in each output row\") | \n|  | b.add_argument(\"--out\", \"-o\", help=\"write JSONL here instead of stdout\") | \n|  | b.add_argument(\"--concurrency\", type=int, default=8) | \n|  | add_question_args(b) | \n|  | add_common(b) | \n|  | b.set_defaults(fn=cmd_batch) | \n|  |  | \n|  | m = sub.add_parser(\"models\", help=\"list models/aliases\") | \n|  | add_common(m) | \n|  | m.set_defaults(fn=cmd_models) | \n|  |  | \n|  | au = sub.add_parser(\"auth\", help=\"set \\| status \\| clear the API key\") | \n|  | au.add_argument(\"action\", choices=[\"set\", \"status\", \"clear\"], nargs=\"?\", default=\"status\") | \n|  | au.add_argument(\"key\", nargs=\"?\") | \n|  | add_common(au) | \n|  | au.set_defaults(fn=cmd_auth) | \n|  |  | \n|  | d = sub.add_parser(\"doctor\", help=\"check key, connectivity, one round trip\") | \n|  | add_common(d) | \n|  | d.set_defaults(fn=cmd_doctor) | \n|  |  | \n|  | u = sub.add_parser(\"usage\", help=\"spend, tokens, latency, throughput, credits and budget from the local ledger\", description=\"Every request appends a row to ~/.config/typesafe/usage.jsonl. Default prints the summary; --by breaks it down; --tail lists recent requests. Credits and budget come from `jev config` because the API exposes no balance.\") | \n|  | u.add_argument(\"--by\", choices=[\"day\", \"hour\", \"cmd\", \"agent\", \"model\"], help=\"breakdown table\") | \n|  | u.add_argument(\"--days\", type=int, default=14, help=\"days for --by day (default 14)\") | \n|  | u.add_argument(\"--tail\", type=int, metavar=\"N\", help=\"last N requests with request ids\") | \n|  | u.add_argument(\"--since\", help=\"only rows at or after YYYY-MM-DD / ISO timestamp\") | \n|  | u.add_argument(\"--label\", help=\"only rows with this cmd/label\") | \n|  | u.add_argument(\"--agent\", help=\"only rows whose agent id contains this\") | \n|  | add_common(u) | \n|  | u.set_defaults(fn=cmd_usage) | \n|  |  | \n|  | cf = sub.add_parser(\"config\", help=\"show \\| set \\| unset credits, budget, price\", description=\"Values live in ~/.config/typesafe/config.json (no secrets). `jev config set credits 50` after reading the balance off the console; `jev usage` then counts down.\") | \n|  | cf.add_argument(\"action\", nargs=\"?\", choices=[\"show\", \"set\", \"unset\"], default=\"show\") | \n|  | cf.add_argument(\"key\", nargs=\"?\", help=\"credits \\| credits_as_of \\| budget \\| price\") | \n|  | cf.add_argument(\"value\", nargs=\"?\") | \n|  | cf.add_argument(\"--as-of\", help=\"ISO timestamp the credits balance was read (with `set credits`)\") | \n|  | add_common(cf) | \n|  | cf.set_defaults(fn=cmd_config) | \n|  |  | \n|  | co = sub.add_parser(\"cost\", help=\"estimate tokens and cost for a job before running it\", description=\"Estimates from characters (4 per token) or measures with one tiny real call (--exact). --items N and --per-item model a rank/batch job.\") | \n|  | co.add_argument(\"--questions\", type=int, default=1, help=\"questions per request (default 1)\") | \n|  | co.add_argument(\"--question-chars\", type=int, default=120, help=\"average characters per question incl. criteria (default 120)\") | \n|  | co.add_argument(\"--items\", type=int, help=\"number of items for a rank/batch-shaped job\") | \n|  | co.add_argument(\"--per-item\", action=\"store_true\", help=\"each item is its own request with the full state (batch shape) rather than packed (rank shape)\") | \n|  | co.add_argument(\"--exact\", action=\"store_true\", help=\"measure the state's real token count with one tiny call (costs a fraction of a cent)\") | \n|  | add_state_args(co) | \n|  | add_common(co) | \n|  | co.set_defaults(fn=cmd_cost) | \n|  |  | \n|  | s = sub.add_parser(\"schema\", help=\"print a request skeleton\") | \n|  | s.set_defaults(fn=cmd_schema) | \n|  |  | \n|  | g = sub.add_parser(\"guide\", help=\"the agent playbook; `guide <topic>`; `guide --list`\") | \n|  | g.add_argument(\"topic\", nargs=\"?\") | \n|  | g.add_argument(\"--list\", action=\"store_true\") | \n|  | g.add_argument(\"--live\", action=\"store_true\", help=\"fetch the vendor's current page for this topic\") | \n|  | g.set_defaults(fn=cmd_guide) | \n|  |  | \n|  | e = sub.add_parser(\"examples\", help=\"copy-paste recipes; `examples <name>` or `examples all`\") | \n|  | e.add_argument(\"name\", nargs=\"?\") | \n|  | e.set_defaults(fn=cmd_examples) | \n|  |  | \n|  | dc = sub.add_parser(\"docs\", help=\"live vendor doc index (llms.txt); --grep to filter\") | \n|  | dc.add_argument(\"--grep\") | \n|  | dc.set_defaults(fn=cmd_docs) | \n|  |  | \n|  | ver = sub.add_parser(\"version\") | \n|  | ver.set_defaults(fn=lambda a: print(f\"jev {VERSION}\") or 0) | \n|  | return p | \n|  |  | \n|  |  | \n|  | def cmd_ask_entry(args) -> int: | \n|  | if args.request: | \n|  | raw = sys.stdin.read() if args.request == \"-\" else Path(args.request).expanduser().read_text() | \n|  | try: | \n|  | body = json.loads(raw) | \n|  | except json.JSONDecodeError as e: | \n|  | raise UsageError(f\"request JSON invalid: {e}\") | \n|  | if not isinstance(body, dict) or \"state\" not in body or \"questions\" not in body: | \n|  | raise UsageError(\"request JSON must have `state` and `questions`\") | \n|  | c = JevClient(args.api_key, args.model or body.get(\"model\"), timeout=args.timeout, label=\"ask\") | \n|  | resp = c.ask(body[\"state\"], body[\"questions\"]) | \n|  | emit(args, resp, c.last_ms) | \n|  | return 0 | \n|  | # a full JSON body on stdin (no flags) is also accepted | \n|  | if not (args.state or args.state_file or args.state_json or args.field) and not getattr(args, \"qlist\", None) and not args.questions_file and not args.questions_json and not sys.stdin.isatty(): | \n|  | raw = implicit_stdin() or \"\" | \n|  | try: | \n|  | body = json.loads(raw) | \n|  | if isinstance(body, dict) and \"state\" in body and \"questions\" in body: | \n|  | c = JevClient(args.api_key, args.model or body.get(\"model\"), timeout=args.timeout, label=\"ask\") | \n|  | resp = c.ask(body[\"state\"], body[\"questions\"]) | \n|  | emit(args, resp, c.last_ms) | \n|  | return 0 | \n|  | except json.JSONDecodeError: | \n|  | pass | \n|  | raise UsageError(\"stdin was not a request JSON; pass questions with --noul/--choice/--score and the state with --state or stdin\") | \n|  | return cmd_ask(args) | \n|  |  | \n|  |  | \n|  | def main(argv=None) -> int: | \n|  | parser = build_parser() | \n|  | args = parser.parse_args(argv) | \n|  | if not args.cmd: | \n|  | print(SHORT_HELP.rstrip()) | \n|  | return 0 | \n|  | if not hasattr(args, \"json\"): | \n|  | args.json = False | \n|  | if not hasattr(args, \"compact\"): | \n|  | args.compact = False | \n|  | if not hasattr(args, \"verbose\"): | \n|  | args.verbose = False | \n|  | try: | \n|  | return int(args.fn(args) or 0) | \n|  | except JevError as e: | \n|  | if getattr(args, \"json\", False): | \n|  | eprint(json.dumps({\"error\": str(e), \"exit_code\": e.exit_code})) | \n|  | else: | \n|  | eprint(f\"jev: {e}\") | \n|  | return e.exit_code | \n|  | except KeyboardInterrupt: | \n|  | return 130 | \n|  |  | \n|  |  | \n|  | if __name__ == \"__main__\": | \n|  | sys.exit(main()) |", "url": "https://wpnews.pro/news/jev-give-any-coding-agent-claude-code-codex-opencode-a-calibrated-gut-check-a-a", "canonical_source": "https://gist.github.com/pedramamini/014676fa8684d91bf7000f4623701ada", "published_at": "2026-09-19 19:09:18+00:00", "updated_at": "2026-09-21 20:22:20.781976+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "developer-tools", "ai-products"], "entities": ["TypeSafe", "Jev", "Claude Code", "Codex", "OpenCode"], "alternates": {"html": "https://wpnews.pro/news/jev-give-any-coding-agent-claude-code-codex-opencode-a-calibrated-gut-check-a-a", "markdown": "https://wpnews.pro/news/jev-give-any-coding-agent-claude-code-codex-opencode-a-calibrated-gut-check-a-a.md", "text": "https://wpnews.pro/news/jev-give-any-coding-agent-claude-code-codex-opencode-a-calibrated-gut-check-a-a.txt", "jsonld": "https://wpnews.pro/news/jev-give-any-coding-agent-claude-code-codex-opencode-a-calibrated-gut-check-a-a.jsonld"}}