jev

v2026.09.25

Get a fast, cheap, typed judgment over text or JSON from the jev CLI — a yes/no probability, one choice among labels, or an ordinal score — bare calibrated answers, never prose or explanations. Runs now from a shell or agent, in bulk (one decision per line) and in pipelines (exit codes, semantic grep). Use to classify, triage, route, screen, rank, filter or bulk-label items such as emails, customer feedback, chat or group messages, tweets, logs, git diffs or user requests, and as a cheap pre-filter before expensive LLM reading, a guardrail check, or a model/agent router. 适用:分类、筛选、分诊、路由、打分、是非判断、批量打标签、语义过滤——只要结论,不要解释。Not for judgments that must come with an explanation, analysis or a written reply; not for writing, summarizing or extracting text; not for math or date arithmetic. To design or code a TypeSafe integration inside an application, use the official `typesafe-ai` skill. Unofficial; calls TypeSafe's Jev model through the TypeSafe API (default) or OpenRouter.

GitHub
安装命令
npx skhub add okooo5km/jev
Markdown
SKILL.md

jev

jev turns a judgment call into a typed answer with a calibrated probability. It reads a state (text or JSON) and answers named questions of three kinds — noul (P(yes)), choice (one of N), score (ordinal scale, at most 10 levels). It never generates text. A call costs about $0.00002, so 1,000 decisions run about 2 cents: use it wherever a script or an agent needs a quick, consistent verdict, and keep LLM reasoning for what survives the filter.

Setup

  1. Run jev --version. If the command is missing, the CLI ships with this skill at scripts/jev (Python 3.9+, standard library only). Link it with mkdir -p ~/.local/bin && ln -sf "<this skill's directory>/scripts/jev" ~/.local/bin/jev, or call it by its absolute path.
  2. Keys: TYPESAFE_API_KEY (default provider) or OPENROUTER_API_KEY, read from the environment, then $JEV_ENV_FILE, then <config dir>/.env. Provider: --provider → $JEV_PROVIDER → the default pinned with jev provider default ID → auto (TypeSafe if its key exists, else OpenRouter). jev provider list, jev auth status and jev auth check are read-only and never print a key — run them freely. On a missing key or a 401/403, ask the user to run jev auth set (plus --provider openrouter for that key) in their own terminal: it needs a TTY and hidden input, so you cannot run it for them. Never ask for a key in chat, pass one as an argument, pipe one into auth set --stdin, read or print a key file, or run jev auth remove unless the user asks.

For designing the questions themselves (choosing noul/choice/score, writing criteria, confidence and calibration semantics), see TypeSafe's own docs: primitives, confidence, full index at llms.txt.

Choose the verb

NeedCommandPlain stdoutExit code
Yes/nojev yes "QUESTION"yes\t0.970 yes · 1 no · 2 error
One of Njev pick "QUESTION" a="desc" b="desc" [--other]a0 · 1 below --min-confidence · 2 error
Ordinal scorejev score "QUESTION" low mid high or --range 1-51.43\tmid0 · 2 error
Keep matching linesjev filter "QUESTION"the matching input lines0 some · 1 none · 2 error
Several questions at oncejev run SPECaligned table0 · 2 error
Raw API bodyjev raw < body.jsonresponse JSON0 · 2 error
  • Input comes from stdin, -s "TEXT" or -s @file. JSON objects and arrays go out as structured state (--text turns that off).
  • -l makes one decision per input line: concurrent (-j 8), order preserved, streamed. For JSONL, --field KEY names the field to judge. filter always works per line.
  • Add --json whenever you parse results (JSONL with -l): each answer has type plus noul and yes, or choice, or score and label; choice and score also carry probabilities and confidence. Plain output suits humans and shell tests.
  • --verbose prints provider, model, latency, tokens and cost to stderr (≈$ when the cost is an estimate).
  • Speed: a single call opens a new connection, about 0.5–1 s in total. -l keeps each worker's connection open, so later calls take about 0.3–0.4 s. For more than a handful of items use -l or filter instead of looping single calls; raise -j for large batches (≤16).
  • yes and filter take -t P (threshold, default 0.5) and --true / --false to spell out what yes and no mean. pick -p and score -p print the whole distribution.
jev yes "用户在要求退款吗?" -s "Zipic 一打开就闪退,钱退我!"          # yes	0.97
jev pick "该交给谁处理" code="写代码或改项目" research="需要联网查资料" --other -s "$request" --json
jev score "这条评价给几星" --range 1-5 -s @review.txt                  # 3.30	3
tail -f app.log | jev filter "日志表示用户可见的故障" --false "调试信息、正常请求"
jev run feedback -l --field text --json < tickets.jsonl > labeled.jsonl

Write questions Jev can answer

Jev reads conditions literally and does not infer intent. In testing, filter "包含具体可行动的信息" passed an ad ("加微信领取免费 AI 课程,限时三天") at about 0.9, because an ad is literally actionable. filter "消息给出了具体的技术、产品或行业信息" --false "闲聊、问候、广告、引流、卖课" excluded it.

  • State observable conditions, not goals. Define both sides with --true / --false.
  • Describe every option (name="description"); add --other when the list may not cover every input. Order score labels low to high, 2–10 of them.
  • Put questions about the same input into one spec: one call answers all of them for that input (-l still makes one call per line).
  • Trim the state to what the question needs, well below the context limit — irrelevant text dilutes the signal; do math and date arithmetic in code and put the result into the state.
  • Gate actions on certainty: act on high confidence or probability, ask the user or escalate on low ones (pick --min-confidence 0.7, yes -t 0.8). Jev only decides — narrow the set with it, then read, write or summarize the survivors yourself.

Specs

jev run lists the specs; jev run NAME or jev run path/to/spec.json runs one. Built-ins: mail (category, urgency, needs reply, promo), feedback (intent, sentiment, needs human, churn risk), signal (worth reading, topic, novelty for chat messages, tweets, RSS), commit (Conventional Commit type, secret leak, breaking change, risk for git diff --cached), route (handler, complexity, needs web, needs private data for a user request). Built-ins ship as JSON so every Python 3.9+ can load them. A spec's own model (if set) is normalized for whichever provider is active.

A spec mirrors the API body. Save new ones under <config dir>/specs/ (~/.config/jev/specs/ unless XDG_CONFIG_HOME is set), which survives reinstalling the skill. JSON works on every supported Python; TOML needs Python 3.11+ (tomllib) and errors clearly below that:

{
  "description": "One line shown by `jev run`",
  "threshold": 0.5,
  "questions": {
    "category": { "type": "choice", "instructions": "Which kind of request is this?",
      "criteria": { "bug": "Crash or broken feature", "billing": "Payment or license problem", "other": "None of the above" } },
    "urgency": { "type": "score", "instructions": "How soon must someone act?",
      "criteria": ["can wait", "this week", "today", "now"] },
    "needs_reply": { "type": "noul", "instructions": "The sender expects a personal reply",
      "criteria": { "true": "Asks a question or waits for a decision", "false": "Notice or receipt only" } }
  }
}

criteria differs by type: choice and noul take a {name: description} map (noul needs both true and false), score takes an ordered array, low to high. A question may hold only type, instructions and criteria; anything else is rejected before a request is sent.

Limits

  • Decisions only: no text, no field extraction. score allows at most 10 levels.
  • TypeSafe native: 64K token context per request, 32K for state + the longest question, about 1,200 requests/min. OpenRouter: https://openrouter.ai/api/alpha/decisions is an alpha endpoint and may move — override with JEV_BASE_URL if it does.
  • The CLI retries 429/5xx with backoff on both providers; errors go to stderr as jev: API 错误 (HTTP n): …, exit code 2.

Full option reference, provider table, exit codes, error shapes and recipes: references/cli.md.

发现
标签

此技能尚未发布标签。

版本
最新版本元数据

版本

v2026.09.25

发布时间

Sep 25, 2026

分类

未分类

许可证

Apache-2.0

源路径

jev

默认分支

main

最新提交

2d4c4a0

Tree SHA

1f41053