Skip to main content
Open source · MIT

ilmek

An agent graph runtime — state, nodes, edges, checkpointed memory, and durable human-in-the-loop. A paused node resumes on top of its work instead of redoing it.

import { graph, channel, START, END, run, resume, InMemoryCheckpointer } from "@ilmek/core";

const g = graph("checkout")
.node("checkout", async (state, ctx) => {
const order = await ctx.step("create_order", () => Orders.create()); // once, ever
const ok = await ctx.interrupt<string>({ question: "Charge?" });
await ctx.step("charge", () => Payments.charge(order, ok));
return { log: ["done"] };
})
.edge(START, "checkout").edge("checkout", END)
.compile();

Why this exists

Every graph engine that supports human-in-the-loop resumes a paused node by re-executing it from the top — so everything above the pause runs again. ilmek makes that the engine's problem, not yours.

🪡

Durable human-in-the-loop

A node that pauses for a human resumes without re-running the work above it. An interrupt is just a step whose value comes from a person — same replay rules, no special-casing.

📓

The journal

Wrap every side effect in ctx.step(...). Its recorded result replays on resume instead of running again. Charge a card once, retry the flaky call after it — no double charge.

🔁

Safe retries

Because completed steps are journaled, retry is free of double-effects. A node that charges then hits a flaky API retries the API alone — the charge replays from the journal.

🧩

Graphs are data

Every graph round-trips to a serializable spec (fromSpec / toSpec). A stored spec never carries executable text — the foundation for a drag-and-drop builder the engine knows nothing about.

📡

One stream, many views

A run is one canonical event stream with a monotonic seq and namespace path. Project it into values, updates, custom, messages, and debug modes — no second pass.

🌐

Two implementations, one spec

TypeScript (reference) and .NET, both green against the same conformance list, printing identical demo output. MODEL.md is the normative spec; the code reproduces it exactly.