{"slug": "probably-a-programming-language-for-llm-workflows-powered-by-jev", "title": "Probably – a programming language for LLM workflows, powered by Jev", "summary": "TypeSafe.ai released Probably 0.1, a small programming language for LLM workflows that is executed by a TypeScript interpreter and powered by Jev for judgments and probabilities. The language uses `feels` for confidence-thresholded yes/no judgments, `match` to choose among 2-8 descriptions, `llm` to call a text-generation model through Cloudflare AI Gateway, and `while`/`repeat` loops capped at five iterations. Probably 0.1 has no confidence gate on `match`, uses a default 50% threshold for `feels`, and lets users replay the last completed run without calling a model.", "body_md": "[probably∿](https://probably-lang.southpolesteve.workers.dev/)A small language for uncertain times.\n\n# A programming language for LLM workflows, powered by [Jev](https://typesafe.ai/blog/introducing-system-one-models-and-jev). Determinism is overrated.\n\nReplay repeats the last completed run without calling a model. Download run JSON saves its source, input and decisions.\n\nYour output will appear here.\n\nEach judgment shows its probabilities and the exact value it saw.\n\n## The language, in a few minutes.\n\nProbably 0.1\nProbably is its own small language. A TypeScript interpreter executes the code; [Jev](https://typesafe.ai/blog/introducing-system-one-models-and-jev) supplies judgments and probabilities. A separate text model generates prose. `feels` asks a question, `match` picks a description, and `llm` generates text. Run is a playground button, not a language keyword.\n\n**Try the inbox department:** Jev checks urgency and routes the email. Each branch gives the LLM a different reply strategy. A loop edits the tone, a confidence check flags uncertainty, and a final LLM call writes a subject from the finished reply. The last output is your draft. When running locally, change the input to a sales pitch or meeting request to see the route change. This example drafts replies; it does not send email.\n\n## 1. Values, input and output\n\n`let` declares a variable. Assign again to update it. Values are strings, nonnegative numbers or booleans; comments start with `//`. `input()` reads the input box and `print()` adds a line to output.\n\n``` js\nlet message = input()\nlet attempts = 3\nlet optimistic = true\nmessage = \"Everything is probably fine.\"\nprint(message)\n```\n\nVariables belong to their block. Assignment can update a variable in an outer block. Strings use double quotes and escapes such as `\\n`. Semicolons are optional.\n\n## 2. Call a language model with llm\n\n`llm` sends an instruction to a text-generation LLM through Cloudflare AI Gateway and returns its response as a string. `using` passes the value to work on. Only that value is passed as context; the model does not see all your variables.\n\n``` js\nlet draft = llm \"Explain this in one sentence.\" using input()\nprint(draft)\n```\n\nYou can omit `using` when the instruction needs no context. `print` only displays a value; it never calls a model. Older programs can still use `write` as an alias for `llm`.\n\n## 3. Make a judgment with if … feels\n\n`feels` compares a value with a quoted description. Normally the higher-probability yes/no answer wins. Add a confidence threshold to handle ambiguity explicitly.\n\n```\nif message feels \"genuinely urgent\" with confidence 80% {\n  print(\"Drop everything.\")\n} otherwise maybe {\n  print(\"Ask a follow-up question.\")\n} else {\n  print(\"It can wait.\")\n}\n```\n\nAt 80%, a 90% yes takes the first branch, a 90% no takes `else`, and a 60/40 split takes `otherwise maybe`. The threshold uses the winning answer’s probability. It is a model estimate, not a guarantee of truth. Thresholds range from 50–100%; the default is 50%. If you omit the maybe block, an uncertain result runs neither branch.\n\n## 4. Choose a branch with match\n\n`match` asks Jev to choose among 2–8 distinct descriptions. The highest-probability label wins, even when no label is a great fit. Include an “other” label when useful.\n\n``` js\nmatch message {\n  \"a bug report\" => { print(\"Investigate.\") }\n  \"a feature request\" => { print(\"Add to the wishlist.\") }\n  \"something else\" => { print(\"Ask a human.\") }\n}\n```\n\nThere is no confidence gate on `match` in 0.1. Ties use the first label; yes wins a tied `if`.\n\n## 5. Keep trying with while and repeat\n\n`while … feels` asks Jev before every iteration, including after the last rewrite. `repeat` runs a fixed number of times without asking a model.\n\n```\nwhile draft feels \"full of corporate jargon\" {\n  draft = llm \"Rewrite plainly.\" using draft\n}\nprint(draft)\n\nrepeat 3 {\n  print(\"This is definitely helping.\")\n}\n```\n\nWhile loops allow at most five iterations and report an error if the condition is still true. `repeat` accepts a literal integer from 1 to 5. The complete run also has a 12-model-call budget, so elaborate programs can hit that limit first.\n\n## 6. Embrace chaos, then replay it\n\nInside `chaos`, judgments sample from their probabilities. A 20% answer has a 20% chance of being chosen. Any confidence gate is checked before sampling.\n\n```\nchaos {\n  if input() feels \"a sensible business idea\" {\n    print(\"Fund it.\")\n  } else {\n    print(\"Fund it, but ironically.\")\n  }\n}\n```\n\nHosted examples stream the same cached results on each run. Locally, Run again makes fresh calls and may produce the same result. Replay uses the last completed run’s original source, input, model results and random draws. It makes no model calls. Download run JSON saves that recording; replay a saved file locally with `bun run run --replay recording.json`. Recordings contain your input and generated text.\n\n## What 0.1 supports—and where it stops\n\nThis is an experimental language for playful workflows. It has no arithmetic, arrays, objects, functions, imports, network tools or JavaScript execution. `feels` is a condition inside `if` or `while`, not a standalone expression. The `.prob` extension simply identifies a Probably source file; filenames do not affect execution.\n\nRuns stop at 12 model calls, 200 statements or 90 seconds. Source is limited to 12,000 characters, input to 6,000 and nesting to 12 blocks. Errors stop the program; earlier output remains visible. Stop cancels interpretation, although an already-dispatched model request may still finish remotely.\n\nThe hosted Worker streams previously recorded Jev judgments and generated text for the exact bundled examples. Custom code or inputs have no cached result and are rejected without calling a model. Run locally to execute your own programs with live providers.\n\n## Run it yourself.\n\n[Download source ↓](https://probably-lang.southpolesteve.workers.dev/probably-source.zip)\n\nRun the live interpreter locally, or deploy the cached playground to [Cloudflare Workers](https://developers.cloudflare.com/workers/). Local model calls use [AI Gateway](https://developers.cloudflare.com/ai-gateway/get-started/).\n\n1. ### Get the code and connect Cloudflare.Install [Bun](https://bun.sh/) , download and unzip the source, then open its folder in your terminal. In your Cloudflare account, create an AI Gateway called`default` . Add Gateway credits or a[Jev provider key](https://developers.cloudflare.com/ai-gateway/configuration/bring-your-own-keys/) with alias`default` so Jev can run.\n\n```\ncd probably\nbun install\n```\n\n2. ### Run locally.Copy the example settings, then open `.env` and fill in your Cloudflare account ID and API token. Use the permissions in the[Gateway setup guide](https://developers.cloudflare.com/ai-gateway/get-started/) . Keep`GATEWAY_ID=default` .\n\n```\ncp .env.example .env\nbun run dev\n```\n\n Open the localhost URL printed in your terminal. The interpreter runs on your machine; the models run remotely.\n3. ### Deploy to Cloudflare.Choose a unique Worker name in `wrangler.jsonc` , then run:\n\n```\nbunx wrangler login\nbun run deploy\n```\n\n This deploys the cached playground. The Worker streams bundled recordings and requires no model bindings or provider credentials. Use the local server or CLI for live model execution.\n\nThe source includes the interpreter, playground, examples, tests and a full README. Model calls use your Cloudflare or provider account’s quota and billing.", "url": "https://wpnews.pro/news/probably-a-programming-language-for-llm-workflows-powered-by-jev", "canonical_source": "https://probably-lang.southpolesteve.workers.dev/", "published_at": "2026-09-18 09:17:41+00:00", "updated_at": "2026-09-18 09:26:07.304581+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "large-language-models", "ai-tools"], "entities": ["Probably", "Jev", "TypeSafe.ai", "Cloudflare AI Gateway"], "alternates": {"html": "https://wpnews.pro/news/probably-a-programming-language-for-llm-workflows-powered-by-jev", "markdown": "https://wpnews.pro/news/probably-a-programming-language-for-llm-workflows-powered-by-jev.md", "text": "https://wpnews.pro/news/probably-a-programming-language-for-llm-workflows-powered-by-jev.txt", "jsonld": "https://wpnews.pro/news/probably-a-programming-language-for-llm-workflows-powered-by-jev.jsonld"}}