Don't parse your agents. Nudge them.
A typed, replayable, budget-aware programming language for LLM agents — compiles to Python & TypeScript.
Production agents are still held together with glue code: prompt chains parsed by hand, tool calls wrapped in try/except, no replay, no cost control, no regression tests. Libraries patch symptoms. Nudge fixes the layer where the problem actually lives: the language.
| Pain | Libraries | Nudge |
|---|---|---|
| Untyped LLM output | validate at runtime | schema is a type — proven at compile time |
| Hidden side effects | invisible | uses LLM, Tool, IO in every signature |
| No regression testing | record/replay bolted on | every run emits a trace; every trace is a test |
| Cost surprises | dashboards after the fact | budget is a contract, enforced by compiler + runtime |
| Async fan-out spaghetti | manual asyncio | par map / race / all, race safety proven |
type Finding = { claim: string, source: Url, confidence: float @range(0, 1) }
fn analyze(q: string, hits: [SearchResult]) -> [Finding] uses LLM {
llm"""Extract verifiable findings about {q} from: {hits}"""
with { schema: [Finding], model: "anthropic:sonnet-4.6",
budget: 0.03 USD, retry: 2 with repair }
}
test "stays within budget on recorded trace" {
let t = replay("traces/demo.jsonl")
assert t.cost_usd < 0.25 // zero tokens burned in CI
}
The compiler proves the schema matches, infers effects, and computes a static cost bound. The runtime records every call to a content-addressed trace you can diff, commit, and replay.
- Typed LLM calls — output schema is a language type; violations trigger automatic repair, never reach your code
- Effect system — pure /
LLM/Tool/IOeffects inferred and shown in signatures - Deterministic replay — full, hybrid, and live modes; traces are git-friendly JSONL
- Budget contracts — per-call, per-run, and per-repair USD ceilings (
NUDGE_REPAIR_BUDGET) with static estimation (nudgec cost) - Checkpointed agent state — crash, then
nudge resumefrom the last checkpoint - Native parallelism —
par map,par race,par allwith compile-time race safety - Prompt Clippy — the compiler lints your
llm"""blocks: vague instructions, missing output contracts, overlong prompts - MCP & Python interop — consume real MCP servers over stdio as typed tools; escape to any pip package
- Real providers — one stdlib-only adapter for OpenAI / Gemini / Groq / MiMo / Mistral / Anthropic / Ollama; free tiers and local models work at $0
- Trace viewer —
nudgec trace-view <trace.jsonl>opens a local web UI over any run: timeline, tokens, cost, repairs highlighted,parlanes color-coded (NTF v1.1branchfield) - Trace diff —
nudgec trace-diff a.jsonl b.jsonlanswers "what changed when I edited the prompt?": totals and per-record deltas - A2A agent-card export, LSP, OpenTelemetry — built in, not bolted on
| Capability | Python backend | TypeScript backend |
|---|---|---|
| Typed calls, schema validation, repair | ✅ | ✅ |
| Traces, replay, budget walls | ✅ | ✅ |
par map/all/race + branch labels (NTF v1.1) |
✅ thread pool | ✅ sequential (async codegen planned) |
Streaming (stream let) |
✅ live SSE + early-abort repair | ✅ fake parity (no live providers) |
| Real providers (OpenAI/Gemini/Groq/MiMo/Mistral/Anthropic/Ollama) | ✅ | ⬜ routes to Python |
| MCP tools, checkpoint/resume, OTel | ✅ | ⬜ |
The TypeScript backend is a deliberately scoped subset today; parity work is tracked in docs/roadmap.md.
Privacy note: traces record prompts, model outputs, and tool results verbatim — they can contain secrets or personal data. Treat trace files as sensitive artifacts; a redaction hook is on the roadmap.
cargo build # the nudgec compiler
export PYTHONPATH=$PWD/runtime # emitted code imports nudge_runtime
nudgec check examples/research_agent.ndg # type + effect verification
nudgec cost examples/research_agent.ndg # static cost report
nudgec build examples/research_agent.ndg # emit Python to out/
cd examples && nudgec test research_agent.ndg # replay the committed trace — zero tokensEverything runs against a deterministic fake provider by default: no API key, no token spend. See examples/README.md for live runs and the full walkthrough.
- Prebuilt binaries — Linux, macOS (x86_64 + Apple Silicon), Windows on the Releases page
- From source —
cargo build --release→target/release/nudgec. Zero dependencies, builds in seconds - VS Code — Nudge Language on the Marketplace: highlighting, snippets, and diagnostics via
nudgec lsp
- Language design — types, effects, replay, budgets, compiler architecture (frozen at v1.24)
- Strategy: Six Locked Doors — why Nudge exists, and the order in which it becomes indispensable
- Roadmap — shipped history and what's next (trace viewer, NTF standard, capability-based tool security)
- Examples — the self-testing research agent
Contributions welcome — see CONTRIBUTING.md and the open good first issues: new example agents, replay conformance tests, provider adapters, and editor support.
Nudge — a small, intentional push. You don't command an LLM and parse whatever comes back; you nudge it into a schema and let the language enforce the rest. Files use the .ndg extension.
MIT — see LICENSE. No SaaS, no token, no lock-in: Nudge is an open toolchain, forever.