# jevlang

> A Python source preprocessor that lets TypeSafe's Jev model decide every if, elif, while, and match, so conditions can be written in plain English.

jevlang is an experimental Python preprocessor by Roy Wiggins that hands every `if`, `elif`, `while`, and `match` decision to TypeSafe's Jev model. Conditions no longer have to be valid Python, so a loop can run while there are bottles left, in those exact words. Files marked with a jevlang coding line run with the normal Python command.

## What It Is

jevlang rewrites Python source before it runs, using Python's codec machinery. Each block header becomes a call to the jevlang runtime with the condition text, its line number, and the local variables. The runtime then sends Jev the variables in scope, a few surrounding lines of source, and how many times that line has run, and uses the answer to take or skip the branch. By default even ordinary Python conditions go to Jev.

## How match Works

`match` statements are rewritten too. Jev sees the subject and every case pattern and picks one, while each case is rewritten so Python's own pattern matching still binds capture variables. That lets English and real Python patterns sit in the same block, including guards. A `--show` flag prints the rewritten source so you can see exactly what will run.

## Backends

The backend is picked with an environment variable. The offline `fake` backend is the default without an API key: it runs valid Python conditions as Python and uses keyword guesses for English. The `ask` backend makes you play Jev and answer yes or no in the terminal. The `jev` backend calls the real model through the TypeSafe SDK or OpenRouter's pass-through, and is used automatically when a key is set. Any object with a `decide` method can also be plugged in.

## Probabilistic Branches and Safety Knobs

Adding a `jev: roll` comment to a header makes the branch fire with Jev's probability instead of a fixed cutoff, and a seed makes those rolls repeatable. A call budget stops a script after a set number of Jev calls with the real backend, so a runaway loop cannot drain credits. A trace mode logs every decision, and a local-Python mode, nicknamed Luddite mode in the README, evaluates valid Python conditions without asking Jev.

## Examples and Limits

The repo ships demos including 99 bottles, FizzBuzz, a spiciness sort, review sentiment matching, tic-tac-toe, and two text adventures; the README estimates roughly 230 calls per tic-tac-toe game. Only single-line block headers are rewritten, ternaries and comprehension filters stay plain Python, and stale bytecode caches must be cleared after upgrading. Tests for the Jev backend use a mocked transport, so they run without an API key.

## Features
- Natural-language if, elif, while, and match conditions in Python
- Source preprocessor built on Python's codec machinery
- Runs with plain python via a registered .pth codec
- match rewriting that keeps capture variables bound
- Backends: fake (offline), ask (interactive), jev (real model), or custom
- Probabilistic branches with a jev: roll comment
- Reproducible rolls via JEVLANG_SEED
- Call budget via JEVLANG_MAX_CALLS
- Per-decision trace logging via JEVLANG_TRACE
- Luddite mode to run valid Python conditions locally
- Configurable model and decision threshold
- CLI runner and --show to print rewritten source
- set_backend API to install a backend from code
- TypeSafe and OpenRouter API key support

## Integrations
TypeSafe SDK, OpenRouter, uv, pip

## Platforms
CLI, DEVELOPER_SDK

## Pricing
Free

## Version
0.1.0

## Links
- Website: https://github.com/RoyWiggins/jevlang
- Documentation: https://github.com/RoyWiggins/jevlang#readme
- Repository: https://github.com/RoyWiggins/jevlang
- EveryDev.ai: https://www.everydev.ai/tools/jevlang
