Pragmatic

The runtime.

One wrapper in your code, a journal underneath it, and replay that is exact, every time.

In your code

Durable in one wrapper.

Keep writing agents the way you already do. Wrap the run, route model turns through the Oracle, run tools as journaled effects, and Pragmatic records every realized outcome as the agent executes.

Crash on step nine of a thousand and the agent resumes on step nine, reading every prior call back from the Journal instead of paying for it again.

tool_loop.rs

use pragmatic::{Runtime, Ctx, Fault, Value};
use pragmatic_anthropic::{Conversation, Turn};

// A real tool-use agent. Every model turn and tool call is journaled once.
#[pragmatic::durable]
fn agent(ctx: &mut Ctx) -> Result<Value, Fault> {
    let mut conv = Conversation::user("What is 481 * 1063?");
    loop {
        let turn = Turn::parse(&ctx.oracle(conv.prompt())?)?;  // journaled
        conv.push_assistant(&turn);
        if !turn.wants_tools() {
            return Ok(Value::from(turn.text()));
        }
        for call in turn.tool_uses() {
            let out = ctx.effect("calculator", &call.input, calculator)?; // write-ahead
            conv.push_tool_result(&call.id, out);
        }
    }
}

let mut rt = Runtime::in_memory(oracle);  // oracle declares the tools
let answer = rt.run("agent-7", agent).unwrap();

// Crash anywhere in the loop. Resume exactly; no tool runs twice.
let resumed = rt.resume("agent-7", agent).unwrap();

// Replay the whole run, bit for bit, with zero model calls.
let audit = rt.replay("agent-7", agent).unwrap();

research_agent.py

import pragmatic

# Wrap the run. Every ctx.oracle call is journaled once.
def research(ctx):
    plan = ctx.oracle("plan the task")                     # journaled
    findings = [ctx.oracle(f"probe {i}: {plan}") for i in range(10)] # journaled
    return ctx.effect("publish", f"{len(findings)} findings",
                      lambda arg: f"s3://reports/{arg}")   # write-ahead journaled

rt = pragmatic.Runtime("./journals", oracle)

# Crash anywhere. Resume exactly, no re-sampling.
report = rt.resume("research-42", research)

# Replay the whole run for audit.
audit = rt.replay("research-42", research)

Available in Rust and Python, with stable C++, Java, Go, and Node bindings. A first-class TypeScript SDK is next on the roadmap.

A journal, not a cache. Other engines cache model outputs and trust you to keep the surrounding code deterministic. Pragmatic journals every step the agent takes, so resume and replay hold for the whole run.

Anatomy

A runtime, not an operating system.

The runtime

A library, on your infrastructure.

Pragmatic runs on the infrastructure you already have: Linux, containers, any cloud. It links into your agent as a library. There is nothing new to provision and no operating system to adopt.

The core

Oracle and Journal.

Every model call goes through the Oracle, and every realized outcome is written to an append-only, hash-chained Journal. Replay reads outcomes back instead of calling the model again, which is what makes recovery exact.

The tool loop

Tools run exactly once.

The Claude adapter journals the full multi-turn loop: the model asks for a tool, the tool executes as a write-ahead journaled effect, and the result goes back into the conversation. Each turn is recorded with its tool requests, stop reason, and token usage intact, so the Journal doubles as a cost record. Crash anywhere in the loop and the run resumes with no tool re-executed; replay reproduces the loop without calling the model at all.