Skip to main content

jevbrief

Clean, traceable state briefings for TypeSafe's Jev, from any source.

Other tools show what Jev decided. jevbrief shows what Jev was told, what it wasn't told, and why.

PyPI Python License: MIT Adapters

Adapters  ·  Quick start  ·  Game demo  ·  Python  ·  Viewer  ·  How it works  ·  Benchmarks  ·  Build an adapter  ·  Contributing


Animation: facts from a source flow into the rules, noise is dropped with a reason code, the rest goes to Jev, and Jev picks one


Why jevbrief

Jev turns state into typed decisions. It does its best work on small, relevant state, and it is weak at raw numbers, dates, and long lists of irrelevant detail. Real sources are the opposite: a web page has hundreds of elements, a ticket queue is full of closed and spam tickets, and an incident produces thousands of log lines.

jevbrief sits between your source and Jev. It keeps what matters, drops the rest with a reason for every drop, asks Jev one clear question, and records the whole decision so you can replay it.

Before and after: 1,395 raw log lines at 29,678 tokens become 5 log groups at 1,070 tokens, and Jev picks the config reload failure

Adapters

Read a web page, a JSON file, OpenTelemetry logs, or an NES game's memory into facts, with numbers and dates already turned into plain words.

Rules with reasons

Fixed rules drop the noise. Every dropped fact gets a reason code, so a wrong answer is debuggable.

A token budget

Up to 96% fewer input tokens on our benchmarks, with the same or better accuracy.

One clear question

Question packs ask Jev a narrow judgment and return a typed answer, a confidence, and every option's probability.

A trace per decision

One JSON line per decision: what was kept, what was dropped and why, and what Jev answered.

An animated replay

jevbrief view replays each decision step by step, in one offline HTML file.

Adapters

Adapter overview: web pages, JSON data, OpenTelemetry logs, and NES games are supported; Slack and Discord are planned; new sources are open for contribution

Source Status Install Jev answers Docs
Web pages (Playwright) Supported pip install "jevbrief[web]" Which element to click next web
JSON and JSON Lines, with a config file Supported pip install jevbrief Which item fits, or which action to take json
OpenTelemetry logs (OTLP JSON) Supported pip install jevbrief Which log group explains an incident otel
NES games (Nova the Squirrel, a free open-source platformer) Supported pip install "jevbrief[nes]" Which move to make next nes
Slack and Discord exports Planned for v0.4 jevbrief[chat] Which message answers a question roadmap
Your source Open Suggest it or build it

Quick start

pip install "jevbrief[all]"       # everything; or jevbrief (json and otel), jevbrief[web], or jevbrief[nes]
playwright install chromium       # only for web pages

inspect shows what would be kept and dropped, with no API key and no cost. ask calls Jev and writes a trace. --view opens the animated replay.

OpenTelemetry logs: find the cause of an incident
jevbrief ask logs.json --adapter otel --goal "Checkout requests started failing with 500 errors" --view
1447 log records -> 23 groups -> 5 sent to Jev
likely cause: auth: failed to load token signing key: certificate expired   (confidence 1.00)
JSON data: pick the right record
jevbrief ask tickets.json --adapter json --config tickets.toml --goal "a customer was billed twice" --view

A config maps your data to facts: which list to read, which fields to send, which rules drop noise, and what to ask. See the json docs and a complete example config.

NES games: Jev plays a platformer, live
python examples/nes_live.py --rom nova.nes --headed

The game's memory becomes facts such as Owl: ahead, near, above, Jev picks a move, and the live viewer shows each decision as it happens. Step by step: Watch Jev play a game.

Web pages: choose the next click
jevbrief ask https://news.ycombinator.com --goal "log in" --view

Get an API key at console.typesafe.ai. Set TYPESAFE_API_KEY in your environment, or put TYPESAFE_API_KEY=... in a .env file where you run the CLI. Run jevbrief adapters to list what is installed.

Watch Jev play a game

Jev plays level 1-1 of Nova the Squirrel: each frame shows the facts sent to Jev and the move it picked

Every frame is a real Jev decision. jevbrief reads the game's memory, turns it into a few facts in words (Wall ahead, low (one block), touching), and asks Jev for one move, plus whether walking right is dangerous, in the same call. The game is paused while Jev answers.

On level 1-1, the facts got Nova to block 56 in 100 moves at 713 input tokens per call. Raw memory got her to block 8.6 at 2,829 tokens (results).

Try it yourself

You need Python 3.10 or newer, a TypeSafe API key, and about five minutes.

1. Get jevbrief with the example

git clone https://github.com/parthkomalwad/jevbrief && cd jevbrief
python -m venv .venv && . .venv/bin/activate      # Windows: .venv\Scripts\activate
pip install -e ".[nes]"

2. Get the game. Download nova.nes (free) from the author's v1.0.6a release. Nova the Squirrel is an open-source NES platformer by NovaSquirrel: GPL-3.0 code, CC BY-NC-SA 4.0 graphics and levels. jevbrief never ships or downloads ROMs, and commercial games such as Super Mario Bros are not supported.

3. Add your key. Put TYPESAFE_API_KEY=... in a .env file in the jevbrief folder. Get one at console.typesafe.ai.

4. Play

python examples/nes_live.py --rom path/to/nova.nes --headed

Your browser opens the live viewer at http://127.0.0.1:8765/:

  • Bottom right: the game, as it plays.
  • Left: one row per decision, colored by Jev's confidence.
  • Middle: what Jev was told, what was dropped and why, the frame with boxes, and how sure Jev was of each move.

The terminal prints one line per decision, such as jump_right 0.89 -> jump_right x=7.3 health=4. Replay a run later with jevbrief view traces/nes.jsonl.

The live viewer during a game: decisions on the left, the frame Jev saw with boxes in the middle, and the running game in the corner

Options and troubleshooting
Option Default What it does
--decisions 150 How many moves to play
--headed off Open the viewer in your browser
--timeout 3 Seconds before a slow Jev call is retried
--danger 0.7 Wait instead of walking right when Jev's danger answer is at least this
--port 8765 Port of the live viewer
--trace traces/nes.jsonl Where the trace is written
  • A few slow decisions at the start: the first Jev calls after a quiet period can take several seconds. The game waits, so play is not affected, and calls speed up to a few hundred milliseconds.
  • "jevbrief warns the ROM is not the release": use nova.nes from v1.0.6a; other builds may use a different memory layout.
  • Port in use: pass --port 8770.
  • Nova gets stuck: she often stops at a tall wall around block 56, where the path continues below a thin ledge. Jev is not a game-playing model; the trace shows exactly what it was told at that point.

Add another NES game: skills/jevbrief-nes-game/SKILL.md is a step-by-step guide, for you or a coding agent such as Claude Code, from a legal ROM to a tested adapter. It includes ram_search.py, which finds a game's memory addresses by watching which bytes change.

Use it in Python

Every adapter works the same way: create a Briefing, extract, decide.

from jevbrief import Briefing
from jevbrief.adapters.otel import OtelAdapter

brief = Briefing(OtelAdapter(), goal="Checkout requests started failing with 500 errors", trace="traces/incident.jsonl")
brief.extract("logs.json")
decision = brief.decide()
if decision.fact:
    print("likely cause:", decision.fact.label, decision.fact.attrs)
Web shortcut for Playwright agents
from jevbrief import Brief

brief = Brief(goal="add this item to the cart", trace="traces/agent.jsonl")
await brief.from_page(page)                 # or brief.from_page_sync(page)
decision = brief.next_click()
if decision.fact:
    await page.locator(decision.fact.selector).click()

Every decision comes back in the same shape:

decision.outcome Meaning Your code should
applied Jev answered at or above min_confidence (default 0.5) Act on decision.choice, and on decision.fact when the options are facts
reused The facts did not change, so the last answer was reused with no API call Act, but stop if nothing changes
low_confidence Below min_confidence, or Jev chose "none" Take no action
error The API call failed Take no action

Examples: nes_live.py · otel_incident.py · json_triage.py · click_agent.py

See every decision

jevbrief ask ... --view opens the viewer after a run, and jevbrief view opens the newest trace. Each decision starts with an animated replay: every fact read, the dropped ones struck out with their reason, the ones sent to Jev, Jev's answer, and a plain-English summary of what it means.

The viewer replaying a JSON decision: facts read, dropped with reasons, sent to Jev, and Jev's answer

Each adapter chooses the view that fits its source.

Timeline, for logs: one bar per log group, with the incident start marked.

Timeline view: the config error is a single mark at the incident start, followed by many symptom errors

Snapshot, for web pages: the page with Jev's pick outlined.

Web view: a screenshot of the page with boxes on every element

Live, for games: jevbrief view --live traces/nes.jsonl serves the same viewer on 127.0.0.1, adds each decision as it is written, and shows the running game in a corner panel. See the game demo.

The viewer is a single HTML file with the trace and images embedded. It needs no server and no network, so it can be attached to a bug report.

Watch the web adapter drive a browser

An agent adds an item to the cart and checks out, then the viewer replays what Jev was told

How it works

Step What happens
1. Extract The adapter reads the source into facts. Each fact has a kind, a label, attrs sent to Jev, and meta kept private. Numbers, counts, and dates become words here.
2. Rules A RuleSet scores each fact and drops noise. Core rules are shared, adapters add their own, and you can remove, add, or reorder rules without forking.
3. Budget Kept facts are sorted by score and cut to a token budget (default 2,000) and an option cap (default 60).
4. Fingerprint If the kept facts have not changed, the previous answer is reused and Jev is not called.
5. Ask Jev A question pack builds one or more questions (Choice, Noul, or Score) in a single call. Options are either the facts or a fixed set of actions.
6. Trace One JSON line per decision, with a legend of every reason code used. Images are stored next to the trace.
Reason codes

Core codes are shared by every adapter. Adapter codes are namespaced, so adapters never collide.

Code Meaning
hidden Not observable right now
disabled Exists but cannot be acted on
unlabeled No usable label, so Jev could not tell what it is
duplicate Same kind and label as a higher-scored fact
low_score Scored below the keep threshold
budget Would have been kept, cut only to fit the token or option budget
<adapter>.<code> Adapter rules such as web.not_interactive, json.closed, otel.healthcheck, or nes.far_ahead, each described in the trace

Force-keep facts with pins=["<fact id>"]. Fact IDs are stable across decisions.

Benchmarks

Benchmark chart: median input tokens, raw state against jevbrief, for web, JSON, and OpenTelemetry logs

Adapter Tasks Raw accuracy jevbrief accuracy Raw tokens jevbrief tokens
web 10 pages 100% (30/30) 100% (30/30) 5,400 2,344 (−57%)
json 9 queries 89% (24/27) 100% (27/27) 3,848 2,002 (−48%)
otel 6 incidents 83% (15/18) 100% (18/18) 29,678 1,070 (−96%)
nes Nova the Squirrel 1-1, 100 moves reached x 8.6 reached x 56.4 2,829 713 (−75%)

Same Jev (jev-1.13.0), same question, three runs per task, median input tokens. The raw arm sends what a naive integration would send: every element, every record, or the most recent log lines. The data is synthetic and built to resemble real sources, and some rules were designed while building these sets, so treat the numbers as illustrations rather than general results. For nes, accuracy is how far Nova got in 100 moves (median of 3 runs, level map 256 blocks); neither arm finished the level. Details: web · json · otel · nes. Reproduce them with jevbrief bench.

Build your own adapter

An adapter is one class with extract, rules, packs, and optionally state. Adding one never changes the core, and removing one never breaks anything.

  1. Copy contrib/adapter_template and its test.
  2. Follow ADAPTERS.md for facts, rules, the question pack, and the benchmark.
  3. Pass the shared contract test: check_adapter(MyAdapter(), "sample.json", goal="...").
  4. Ship it here in a pull request, or as your own package with a jevbrief.adapters entry point, which jevbrief discovers automatically.

Working with a coding agent? Copy skills/jevbrief/SKILL.md into its skills folder (for Claude Code, .claude/skills/jevbrief/SKILL.md).

Contributing

To Do this
Suggest a source Open an adapter request. Upvote the ones you want; the most requested are built first.
Build an adapter Open a proposal, then follow ADAPTERS.md.
Report a wrong decision Open a bug report and attach the trace.
Ask a question or share an idea Start a discussion.
git clone https://github.com/parthkomalwad/jevbrief && cd jevbrief
python -m venv .venv && . .venv/bin/activate    # Windows: .venv\Scripts\activate
pip install -e ".[dev]" && playwright install chromium
pytest -q

Privacy

  • The API key is read from the environment or .env and is never printed, logged, or written to a trace.
  • Adapters send only what they list. The web adapter never sends form values, the json adapter sends only the configured fields and buckets, and the otel adapter sends message templates with IDs, emails, and addresses replaced.
  • Traces contain labels, source names, and, for web pages, a screenshot. Treat them like logs, and use --no-screenshot for private pages.

License

MIT. Community project, not affiliated with TypeSafe AI.

Release files for jevbrief 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for jevbrief 0.2.0
File Size Uploaded
jevbrief-0.2.0.tar.gz 72.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for jevbrief 0.2.0
File Interpreter ABI Platform
jevbrief-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 135.8 kB

Release files / jevbrief-0.2.0.tar.gz

Download URL jevbrief-0.2.0.tar.gz
Size 72.1 kB
Tags Source
SHA-256 checksum
How to use checksums
5105a167a2d537d61ae6915e146ad8840ed6c2e931576a5fb08348fce7781456
BLAKE2b-256 checksum
How to use checksums
d38899080807bbb9818ebcdf22550f99c4559f92d32ac9660cf32754b336b7a1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release files / jevbrief-0.2.0-py3-none-any.whl

Download URL jevbrief-0.2.0-py3-none-any.whl
Size 63.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5ed42e8a17f4b80a7183959ddd0cca77b320e4a8b7d9139a839e27879745730f
BLAKE2b-256 checksum
How to use checksums
8818128c4d3add130ca4470c8a665cf468c1d7a9e6aa576076dac11b2ffe5e5b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.0

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page