Skip to content

About

Minimal Jev judgment core for Pi and other TypeScript apps: noul/choice/score across TypeSafe, OpenRouter, Cloudflare, Vercel, and local llama-server (JevK5)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

pi-jev-core

English | 简体中文

A minimal, standalone Pi extension: it connects to a Jev API and registers a jev_evaluate tool supporting three structured judgment types — noul, choice, and score. It contains no tool routing, auto mode, skill discovery, or context compaction.

Install

Install from a local checkout, or straight from GitHub:

pi install /path/to/pi-jev-core                # local checkout
pi install git:github.com/morler/pi-jev-core   # from GitHub

Once published to npm:

pi install npm:pi-jev-core

This package ships pure TypeScript source, loaded by pi's extension loader (jiti). For programmatic use (via a loader such as tsx/jiti), import the entry point directly: import { JevClient } from "pi-jev-core". Deep imports (e.g. pi-jev-core/src/jev.ts) remain available when you only need one layer.

Platforms

TypeSafe is the default. Set JEV_PLATFORM and provide the matching credential; credentials may also live in the secret files listed below under ~/.pi/agent/secrets/.

JEV_PLATFORM Credential env var Pi secret file Default model
typesafe (default) TYPESAFE_API_KEY typesafe_api_key jev-latest
openrouter OPENROUTER_API_KEY openrouter_api_key typesafe/jev-1.13
cloudflare CLOUDFLARE_API_TOKEN cloudflare_api_token typesafe/jev
vercel AI_GATEWAY_API_KEY ai_gateway_api_key typesafe-ai/jev
local JEV_LOCAL_PORT (port, no API key) — jev-latest
custom JEV_CUSTOM_ENDPOINT (+ optional JEV_CUSTOM_API_KEY) jev_custom_api_key JEV_CUSTOM_MODEL (optional, defaults to jev-latest)
Cloudflare additionally requires CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_GATEWAY_ID. Use JEV_MODEL to override the model; the TypeSafe platform also honors TYPESAFE_DEFAULT_MODEL. Never commit API keys or send them to the model.
The local platform talks to a Jev API server on localhost: set the port with /jev-platform local <port> (persisted as localPort in the same config file) or JEV_LOCAL_PORT. It POSTs {model, state, questions} to http://127.0.0.1:<port>/v1/systemone and expects {answers, model?, usage?} back; no API key is required.
The custom platform talks to a Jev-compatible endpoint of your own. JEV_CUSTOM_ENDPOINT (or /jev-platform custom <endpoint-url> [model], which persists them as customEndpoint and customModel) is the URL that receives the request, used as given — so include the path (for example https://jev.example.com/v1/systemone). It POSTs {model, state, questions} there and expects {answers, model?, usage?} back — the local contract, plus Authorization: Bearer <key> when JEV_CUSTOM_API_KEY (or the jev_custom_api_key secret file) is set; the key is optional because a self-hosted endpoint may be open. The model resolves as JEV_MODEL, then JEV_CUSTOM_MODEL or the persisted customModel, then jev-latest. The endpoint has to be set before the platform can be switched to.

Switch the active platform at runtime with the /jev-platform command: with no argument it lists every platform with its credential origin and marks the active one; /jev-platform <name> switches and persists (for local, /jev-platform local <port> also sets the port; for custom, /jev-platform custom <endpoint-url> [model] also sets both) the choice to ~/.pi/agent/pi-jev-core.json (path overridable via JEV_CONFIG_FILE); the /jev-platform log on|off switch persists to the same JSON file. Resolution order: JEV_PLATFORM env, then the persisted choice, then typesafe.

The jev_evaluate tool

The tool sends a state plus multiple named questions to the active Jev platform and returns answers, the model, usage, elapsed time, and each provider's raw answer. Question types:

  • noul: a yes/no judgment; returns the probability of yes.
  • choice: picks from candidates in the criteria object; keys are option IDs, values are descriptions.
  • score: rates along the criteria array, listed from lowest to highest level; at least two levels (the array index is the score, starting at 0 — the response's legend field mirrors this mapping).

Example request:

{
  "state": {
    "change": "Added a required field to the public request type"
  },
  "questions": {
    "breaking": {
      "type": "noul",
      "instructions": "Does `change` break an existing caller?"
    },
    "kind": {
      "type": "choice",
      "instructions": "What best describes `change`?",
      "criteria": {
        "api": "Public API change",
        "bug": "Bug fix",
        "other": "Other"
      }
    },
    "severity": {
      "type": "score",
      "instructions": "Rate the impact of `change`",
      "criteria": ["Critical", "High", "Medium", "Low"]
    }
  }
}

state may be a string or a JSON object. For object state, each question must reference the fields it needs with backticks, such as `change`; missing or unsafe paths are rejected. String state is sent as the text field for compatibility. One request can carry multiple independent questions. noul needs no criteria. Only referenced object fields are transmitted to the configured platform.

Skill: building-with-jev

The repo ships the building-with-jev agent skill at skills/building-with-jev/SKILL.md, adapted from dbreunig/building-with-jev-skill (which targets the Python typesafe_sdk) to this package's API. It covers question design for noul/choice/score, minimal-state construction, confidence-gated composition patterns, and a symptom → cause → fix table for wrong or low-confidence answers.

Adaptations from upstream:

  • All examples use JevClient.evaluate / jev_evaluate; answers are read uniformly via .value (the choice label, or the score/noul number), with .distribution for the full probability spread.
  • instructions accepts a string only — the upstream object/array form (question/focus/inspect keys) is inlined as sentences; extending src/types.ts and src/jev.ts is the documented upgrade path.
  • Noul true/false criteria are not passed through (noul(instructions) takes the question only); when the boundary is subtle, state both sides inside the instruction.
  • Optional-field guard pattern: value/confidence can be undefined when the provider gave no answer — route missing answers to a fallback instead of coercing them to 0, and use the exported noulProbability(raw) to tell "no answer" apart from "answered 0".

All three adaptations were verified against live responses (model jev-1.13.0): choice/score carry confidence while noul does not, and a score's value is the probability-weighted mean of the level indexes.

Install the skill for your agent:

cp -r skills/building-with-jev ~/.pi/agent/skills/

Development checks

npm install
npm test
npm run typecheck

The API client and platform adapters are extracted and trimmed from the MIT-licensed pi-jev; see LICENSE for the original notice.

About

Minimal Jev judgment core for Pi and other TypeScript apps: noul/choice/score across TypeSafe, OpenRouter, Cloudflare, Vercel, and local llama-server (JevK5)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages