The agent kit that's durable and governed by default.

Build an agent in nine lines. Ship it to production without rewriting. Every run is durable, every tool call is policy-checked, every action lands in a signed audit trail.

$ pip install jamjet
agent.py Python 3.11+
from jamjet import Agent, tool

@tool
def get_weather(city: str) -> str:
    return fetch_weather(city)

weather = Agent(
    model="anthropic/claude-opus-4-8",
    instructions="Answer weather questions.",
    tools=[get_weather],
)

print(weather.run("What should I pack for Tokyo this weekend?"))

Durable. Governed. Audited. Replayable. You wrote none of it.

  • crash recovery
  • policy enforced
  • approval-ready
  • receipt minted

Kill the worker. The agent finishes.

JamJet checkpoints every turn to a durable event log. When the process dies, another worker restores from the last checkpoint and continues. The completed run mints a verifiable receipt.

jamjet · crash recovery demo
$ python agent.py
  run_id: run_8f2a1c · worker_id: w-01
  [turn 1]  model call started...
  [turn 1]  tool: get_weather("Tokyo")  ok
  [turn 1]  checkpoint committed
  [turn 2]  model call started...
  SIGTERM received · worker w-01 terminated

  scheduler: lease expired on run_8f2a1c
  worker w-02: restoring from checkpoint...
  [turn 2]  resumed from turn-1 snapshot
  [turn 2]  tool: get_weather("Tokyo")  skipped (idempotent)
  [turn 2]  model call completed
  run complete · receipt: ab3f7c91...

Recorded simulation of the crash-recovery sequence. The idempotency key on get_weather prevents the tool from re-running on resume.

01

Lost state on crash

A worker dies mid-run. JamJet restores from the last committed turn and continues. No work is lost; no step reruns unnecessarily.

02

Skipped approvals

A risky tool reaches for production. The run pauses at a durable hold. Once a person approves, it continues from exactly that point.

03

Runaway cost

A reflection loop keeps calling the model. Budget caps and loop-detection halt the run before it crosses the configured ceiling.

Up and running in five minutes.

Install the SDK, write nine lines, run your agent. Durable execution and governance are on by default. No config files, no infrastructure.

  1. Install
    $ pip install jamjet
  2. Write your agent

    Nine lines. from jamjet import Agent, tool. Done.

  3. Run it

    Every run checkpoints turns, checks policy, and emits a receipt. You wrote none of that.

Read the quickstart guide
five-minute quickstart
$ pip install jamjet

$ python -c "from jamjet import Agent, tool; print('ok')"
ok

# Write agent.py (nine lines), then run it:
$ python agent.py
  run_id: run_4a8b2f
  Tokyo: 27C, sunny. Pack light layers and sunscreen.
  receipt: 3e9f1d2a...

Agents, tools, teams, memory.

The authoring surface stays out of your way. One import, one class, one decorator. Add capabilities by adding arguments.

Agent

The front door for most agents. Supply a model, instructions, and tools. Everything else is defaults you can override.

agent = Agent(
  model="openai/gpt-4o",
  instructions="...",
  tools=[search, file_read],
)
result = agent.run("Summarise last week's reports")

@tool

Any Python function becomes a governed tool. The runtime handles schema inference, idempotency keys, and audit on every call.

@tool
def send_email(to: str, body: str) -> str:
    # policy-checked, idempotent, audited
    return mailer.send(to, body)

Sessions and memory

A session is a long-running, resumable conversation thread. Engram bridges long-term memory so context persists across restarts and sessions without you managing it.

session = agent.session(id="user-42")
session.run("What did we discuss last week?")

MCP tools

Any MCP server's tools are usable directly. JamJet can also expose your agents and tools as an MCP server for other clients.

agent = Agent(
  tools=[
    MCPClient("github", "npx @github/mcp"),
    MCPClient("postgres", "npx @pg/mcp"),
  ]
)

Policy. Approval. Audit. Receipts.

Every agent runs under policy. Risky tool calls wait for a human. Every decision lands in a signed audit trail. The whole loop shipped. You add it with arguments.

  • Policy Declarative YAML rules: block/allow/approve by tool, model, cost, or regex. Sane defaults on; tighten per agent.
  • Approval / HITL Mark a tool approval_required and the run holds durably. Approve via API, CLI, or the Cloud dashboard. The run resumes at exactly that point.
  • Budget caps Per-run and per-tenant token/cost ceilings. The runtime halts before the cap is crossed. No after-the-fact surprises.
  • Receipts Every run emits a signed AgentBoundary receipt with content hashes. Externally verifiable. On by default.
governed_agent.py
agent = Agent(
  model="anthropic/claude-opus-4-8",
  tools=[search, send_email, book_flight],
  policy="policies/travel.yaml",
  budget="$2.00/run",
  approval_required=[book_flight],
)
policies/travel.yaml
rules:
  - tool: send_email
    action: audit
  - tool: book_flight
    action: approve
  - model: "*"
    pii_redaction: true

The end-to-end approval loop is shipped: runtime hold, Cloud approval endpoint, and CLI/dashboard. See docs.jamjet.dev.

One string, any provider.

Pass a provider-routed string as the model. The ADK routes through a governed model seam that enforces policy, logs token usage, and applies PII redaction on every call, regardless of provider.

Anthropic anthropic/claude-opus-4-8
OpenAI openai/gpt-4o
Gemini gemini/gemini-2.0-flash
Bedrock bedrock/meta.llama3-70b
Ollama ollama/llama3.2

User code never calls a provider directly. The seam is the enforcement point: every call passes the policy middleware, budget check, and audit node before it reaches the wire.

Provider breadth and the governed seam are the first track in the ADK build, alongside the Agent loop facade.

Built for production failures, not just sunny paths.

Model calls are hundreds of milliseconds. Durable turn commits are sub-millisecond. Per-step durability and governance cost essentially nothing against model latency.

Crash recovery

shipped

Every turn commits atomically to a durable event log. On worker death, another worker restores from the last committed turn and continues. O(1) resume from the latest snapshot.

Exactly-once tools

shipped

Each tool call gets a deterministic idempotency key from (run_id, segment, step). On resume the runtime skips already-completed side effects. Paying twice after a crash is not a failure mode.

Budget caps and loop detection

shipped

Per-run and per-tenant cost ceilings are engine-enforced, not suggestions. Reflection loops are detected and halted before they cross the cap.

Durable waits on provider outage

shipped

When a model provider returns 429 or goes down, the run parks as a durable wait with backoff rather than failing. It resumes automatically on recovery, freeing the worker in the meantime.

Residency by design

shipped

Run state and payloads stay in the region where the agent was dispatched. Only content hashes travel for the global audit index. Residency requirements are a first-class design property, not an afterthought.

Determinism contract

in progress

The boundary between recorded outputs (model responses, tool results, time, randomness) and deterministic orchestration is explicit and tested. Replay-based regression lets you diff a run against a new model or prompt with a deterministic test.

Replay-based regression is in the v1 build.

Python now. Java next.

Available now

Python

The primary authoring surface. pip install jamjet. The Agent, @tool, sessions, Engram memory bridge, policy, approval, and audit all run from the Python SDK.

$ pip install jamjet
pypi.org/project/jamjet ↗
Fast-follow

Java

First-class Java authoring is the differentiated fast-follow track. The JVM runtime already runs in production with zero-sidecar @DurableAgent support. A Java authoring surface matching the Python API is the next track.

$ pip install jamjet # today
JVM runtime docs ↗
TypeScript

TypeScript

The @jamjet/cloud SDK provides TypeScript bindings for the Cloud APIs and governance checks. A full authoring surface matching the Python Agent API is planned after Java.

$ npm install @jamjet/cloud
npmjs.com/@jamjet/cloud ↗

Local. Self-host. Cloud.

The IR artifact runs identically across all three. Start on SQLite, ship to a cell. No rewriting.

Local

pip install + run

SQLite. Zero infrastructure. Your laptop. The same IR runs identically here as in production.

$ pip install jamjet && python agent.py

Self-host

Docker + Postgres

Docker Compose or Kubernetes. Bring Postgres for the event log and artifact store. You own the infra.

$ docker compose up jamjet-runtime

JamJet Cloud

Managed cells

Managed control plane on Fly.io. Policy dashboard, approval inbox, cost analytics, Engram memory, multi-tenant. No infra to run.

$ app.jamjet.dev/signup

One artifact (the IR) runs identically across all three tiers. Develop on SQLite, ship to a cell when you're ready.

Keep your framework. Add JamJet where it counts.

LangGraph, CrewAI, Spring AI, Claude Code, OpenAI Agents SDK: keep what you have. Drop JamJet at the tool boundary for policy, approval, and audit. No rewrites.

@jamjet/mcp-shim

Drop governance onto any MCP client (Claude Desktop, Cursor, any MCP host) without touching the client code.

$ npx -y @jamjet/mcp-shim

@jamjet/claude-code-hook

PreToolUse hook for Claude Code. Every tool call passes JamJet policy before execution.

$ npm i -g @jamjet/claude-code-hook

@jamjet/openai-guardrail

Guardrail wrapper for the OpenAI Agents SDK. Same policy engine, different host.

$ npm i @jamjet/openai-guardrail

jamjet.integrations

Python guardrail for the OpenAI Agents SDK. Already in the jamjet package.

$ pip install jamjet

The same policy engine that governs JamJet ADK agents runs as an ext-authz PDP / guardrail webhook for other frameworks. One policy plane across all your agents.

Start building.

Install the SDK, write nine lines, get durable execution and governed tool calls out of the box. Apache 2.0. No account needed to start.

$ pip install jamjet