opensourceprojects.dev

A broadsheet for software that doesn't ask for your email

AI agents as durable flows that crash and resume
GitHub RepoViews6

Project Description

View on GitHub

Your AI Agent Crashed Mid-Run. Now What?

You've built an agent that calls tools, branches on results, and retries flaky APIs. Then a worker dies halfway through, and you're left staring at a half-finished run with no clean way to pick up where it left off. Julep takes a different approach: it treats agents as durable, composable dataflows, so flows can crash and resume, retry safely, and explain every step they took.

What It Does

Julep builds agents as dataflows rather than ad-hoc loops. The main authoring surface is a define-by-construction @flow decorator: you write ordinary Python, and names in your code graph the steps. Registered tools, pures, reasoners, branches, fan-out, retries, and timeouts all compile to the same frozen wire-format IR. The pure core is dependency-free, and the Temporal layer is optional—so you can start simple and add durability infrastructure when you need it.

Deployment works by freezing the tool and reasoner surface at deploy(...) time, which lets Julep deny any tool the model wasn't explicitly allowed to call. There's also a self-hosted control plane with a write-only operator vault (values encrypted at rest), short-lived per-run credentials bound to secret://name MCP header references, and worker-side MCP preflight checks that validate the frozen tool surface before user effects run. The project currently ships as a release candidate (3.0.0 isn't final yet).

Why It's Cool

The authoring model is genuinely unusual. With @flow, your function runs once at definition time with data handles. Calls like lookup_ticket(...), think(...), cond(...), and each(...) don't execute—they append graph steps. Operators like | merge records and h["key"] plucks fields. You're writing Python that reads like code but compiles into a graph, which is a neat trick once it clicks.

Dry runs without an API key. deployment.dry_run(...) executes locally with in-memory tools and deterministic fake reasoners. You can pass a fake function for each reasoner and get a full result—no network, no credentials, no cost. That's a low-friction way to validate flow logic before touching a real model.

Safety is built into the deployment boundary. Because deploy(...) freezes the tool and reasoner surface, the model can't call anything you didn't hand it. For MCP, preflight checks the transitively reachable tool surface before user effects, and new releases default to exact pin comparison—with explicit names and off escape hatches if you need them. Mid-run tool removal or schema rejection fails terminally as typed surface drift, which is the kind of failure you actually want: loud and specific.

Secrets stay out of stored data. Run-bound credentials travel only in encrypted Temporal payloads and are excluded from stored run data and projections. If you've ever worried about a token leaking into a run log, that design choice matters.

It's modular. The pure core has no dependencies; Temporal is optional. You're not forced into a heavy stack just to get retries and timeouts.

How to Try It

Julep 3 is a release candidate, so the --pre flag is required for now:

pip install --pre julep

Then run the quickstart as a normal script—it takes about ten minutes and needs no API key. The README example defines a @tool for ticket lookup, a @pure for prompt shaping, a Reasoner, and a @flow that chains them with retries and timeouts:

@flow
def triage(ticket: str) -> dict[str, str]:
    hit = lookup_ticket(ticket, retries=2, timeout_s=5)
    prompt = ticket_prompt(hit)
    answer = think(support_reply, prompt, timeout_s=10)
    return hit | answer

Deploy it, then dry-run it with a fake reasoner:

deployment = deploy(triage, tools=[lookup_ticket], reasoners=[support_reply])
result = deployment.dry_run(
    "Customer was charged twice.",
    reasoners={"support_reply": fake_support_reply},
)

For MCP, use mcp_tool(server, tool) inside @flow—its schemas and behavior contract come from a frozen MCP snapshot. The repo includes larger examples in examples/episode_summary_flow.py and examples/cluster_labeling_flow.py. There's also a julep CLI for managing a whole module of agents, and a control-plane guide covering vault configuration, run-secret limits, and MCP policy behavior.

Grab it from github.com/julep-ai/julep.

Final Thoughts

Julep is aimed at people who've felt the pain of agents that fail halfway and leave no clean recovery path—and who want the safety properties (frozen tool surfaces, pinned MCP contracts, secrets excluded from stored data) to come from the framework rather than from careful discipline. The define-by-construction authoring style takes some adjustment, and the release-candidate status means you should expect rough edges. But if durable, inspectable agent flows are what you've been hand-rolling, this is worth a look before you write another retry wrapper.


Follow @githubprojects for more developer tools and open source projects.

Back to Projects
Project ID: julepLast updated: November 6, 2026 at 02:48 AM