Model or dataset
julep-ai/julep avatar
julep-ai/julep

Julep: Durable AI agent flows with an IR, a Temporal layer, and a CLI that treats agents like dbt models

Project brief: Julep, durable, composable AI agents. Flows that crash and resume, retry safely, and explain every step.

6,587 stars970 forksPythonApache-2.0

At a glance

What is it?
Julep 3 turns AI agent logic into composable, durable dataflows with a frozen wire-format IR, optional Temporal execution, and a CLI that discovers agents across a directory. It is a release candidate, so adoption hinges on verifying the pre-release status and the control-plane requirements.
Who is it for?
Adopt Julep if you need durable, resumable agent workflows with explicit tool control and are willing to run a release candidate. Skip it if you want a stable 1.0 or a minimal runtime, since the Temporal layer and the control plane add operational weight.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 41 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What Julep solves and who it targets

Julep addresses a specific pain: AI agents built as ad-hoc loops are hard to debug, retry, and resume after a crash. The README frames agents as durable, composable dataflows. That means a flow can stop mid-execution, resume later, and retry safely, with a derived projection that explains every step. The target user is a Python engineer building production agent systems, not someone prototyping in a notebook. The design assumes you care about auditability and tool safety. It also assumes you are comfortable with a release candidate, since Julep 3 currently requires the --pre flag. The project does not aim to be a lightweight wrapper; it compiles flow definitions into a frozen IR and optionally runs them on Temporal. That is a serious commitment, and the intended audience is teams that already think in terms of workflows and state machines.

The @flow mechanism: define-by-construction, not runtime loops

The core authoring surface is the @flow decorator. When you define a flow, ordinary Python names graph steps. Decorators like @tool and @pure register functions, but they do not execute at definition time. Instead, calls to think(...), cond(...), switch(...), each(...), and reschedule(...) append graph steps. The pipe operator | merges records, and h["key"] plucks fields. This is a define-by-construction model: the flow is built once, then frozen into a wire-format IR. The README states that the pure core stays dependency-free, while the Temporal layer is optional. That separation matters. You can run a flow locally with dry_run(...), which uses in-memory tools and deterministic fake reasoners. The same IR can later run on Temporal for durability. The design trades immediate execution for a compile-like step, which is unusual for Python agent frameworks. It forces you to think about the graph before you run it, but it also gives you a structure that can be inspected and resumed.

Getting it running: install, quickstart, and the CLI

Installation is one command: pip install --pre julep. The README warns that the --pre flag is required until 3.0.0 is final. The quickstart needs no API key and runs as a normal Python script. You define a TypedDict for the reply, register a @tool with effect="read" and idempotent=True, define a @pure function for the prompt, and then instantiate a Reasoner with a model string like "anthropic:claude-haiku-...". The CLI is called julep. It discovers every @flow or Agent(...) in a directory and treats each as a node in a cross-agent graph. Commands include julep ls, julep show triage, julep graph, julep run triage --input '"TICKET-42"', julep lint +triage, julep test triage, and julep trace <run-id>. Selectors compose: tag:support, state:modified, +agent, agent+, @agent, and intersection with commas. For production, the README recommends declaring an explicit Application object with PipelineSpec and CapabilityManifest instead of relying on discovery. That is a clear signal: the CLI is for development, and the object model is for deployment.

The Temporal layer and the control plane: optional but heavy

The Temporal layer is optional, but the production path is not trivial. The README describes a self-hosted control plane with a write-only operator vault. Values are encrypted at rest. Callers can bind short-lived, per-run credentials to whole-string secret://name MCP header references. Those values travel only in encrypted Temporal payloads and are excluded from stored run data and projections. The configuration uses a TOML section like [tool.julep.env.staging]. It requires temporal_address, release_store, worker_image, worker_context_factory, worker_service_account, and payload_encryption_secret. The payload_encryption_secret must name an existing Kubernetes Secret with keyring and active-key-id entries. That is a specific operational requirement. You need a Kubernetes cluster with Temporal and a payload codec. The README also mentions worker_secret_environment contains Kubernetes Secret references, not values, and those values exist only in the worker at runtime. This is a deliberate security boundary, but it adds complexity. If you do not already run Temporal, the onboarding cost is real.

Tool safety and MCP: preflight checks and pin comparison

Julep takes tool safety seriously. The README states that before user effects, worker-side MCP preflight checks the frozen, transitively reachable tool surface. New releases default to exact pin comparison, with explicit names and off escape hatches. Mid-run tool removal or post-validation schema rejection fails terminally as typed surface drift. That means if a tool disappears or its schema changes after validation, the run fails rather than silently proceeding. This is a strong guarantee, but it can be a source of operational friction. If your MCP servers change schemas frequently, you will hit terminal failures. The mcp_tool(server, tool) function inside @flow creates an MCP reference, and its schemas come from a frozen MCP snapshot. The README shows an example with a local mcp_call fake for testing. The pin comparison is a concrete mechanism: it compares the exact tool surface, not a fuzzy match. This is a deliberate trade-off between safety and flexibility. Teams that need strict control will appreciate it; teams that iterate quickly on tools may find it restrictive.

Limitations and failure modes

The most obvious limitation is the release candidate status. The README says the --pre flag is required until 3.0.0 is final. That implies API changes are possible. The second limitation is the operational complexity of the production path. The control plane, the Kubernetes Secret requirements, and the Temporal integration are not something you can set up in ten minutes. The quickstart is simple, but the production deployment is not. The README also notes that secret-backed worker variables are intentionally absent from the snapshot_source callback. The callback receives a read-only mapping of [vars] and [worker_environment], but not worker_secret_environment. That means schema discovery cannot use secrets, which is a deliberate boundary but also a constraint. If your MCP server requires a secret to list tools, you need a non-secret control-plane mechanism to pass credentials. Another failure mode is typed surface drift: if a tool is removed or its schema changes after validation, the run fails terminally. That is safe but unforgiving. For teams that want to evolve tools without redeploying, this could be the wrong tool.

Alternatives and how Julep differs

The closest alternative is a plain Temporal workflow with an LLM step. Temporal gives you durability, retries, and resumption, but you write the orchestration yourself. Julep compiles @flow definitions into IR and then runs that IR on Temporal, so you get a higher-level abstraction. The difference is in the authoring model: Julep's define-by-construction @flow is declarative, whereas a raw Temporal workflow is imperative. Another alternative is a framework like LangGraph, which also models agents as graphs. LangGraph typically runs in-process and does not compile to a frozen IR. Julep's IR and the optional Temporal layer are the key differentiators. The CLI is also distinct: treating a directory of agents as a dbt-style module is not something LangGraph or raw Temporal offers. If you already have a Temporal deployment and want a declarative layer on top, Julep fits. If you want a lightweight in-process graph, Julep's control plane and Temporal requirements will feel heavy.

Maintenance and upgrade cost

The README does not provide a changelog or release history, so the upgrade path is unclear. The project is pre-1.0, so breaking changes are likely. The IR is described as frozen, which suggests stability once defined, but the framework itself is still moving. The CLI and the control plane are separate surfaces, each with its own configuration. Upgrading may require regenerating the IR or updating the TOML config. The license is Apache-2.0, which is permissive for commercial use, but it does not grant any warranty. The maintenance cost is tied to the Temporal and Kubernetes infrastructure. You must keep the worker image updated, manage the payload encryption secret, and monitor for typed surface drift. The README mentions julep plan and julep apply for drift detection, which is a useful operational tool. Before committing, verify that the project is actively maintained and that the release candidate moves to a stable 3.0.0 in a reasonable timeframe.

Editorial conclusion

Adopt Julep if you need durable, resumable agent workflows with explicit tool control and are willing to run a release candidate. Skip it if you want a stable 1.0 or a minimal runtime, since the Temporal layer and the control plane add operational weight. Before adopting, verify that the --pre install matches your deployment environment, confirm the control-plane vault and payload encryption setup, and test the exact pin comparison for MCP tools against your tool schemas.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
Community notes

Community notes