JamJet
Open Source

Deployment

Ship an agent with agent.deploy(). One IR, three runtimes (local, self-host, cloud). The honest cloud model, the env vars, and what the engine actually stores.

Deployment

A finished agent ships with agent.deploy(). The same compiled IR that run_durable() builds is registered onto a JamJet engine, so one agent deploys unchanged to your laptop, your own server, or a hosted engine. The three runtimes differ only by URL and token. One IR, three URLs.

result = await agent.deploy(runtime="local")
print(f"deployed '{result.workflow_id}' to {result.runtime} ({result.url})")
print(f"  scheduled={result.scheduled}  cloud_governance={result.cloud_governance}")

deploy() registers the workflow on the engine; it does not start an execution (use run_durable() for that). A Team deploys too: team.deploy() registers each sub-agent's workflow.

The three runtimes

runtime=Engine URLAuthNotes
None / "local"http://127.0.0.1:7700nonethe jamjet dev engine; the default
"self-host"$JAMJET_RUNTIME_URL$JAMJET_RUNTIME_TOKEN (optional)your own engine
"cloud"$JAMJET_CLOUD_RUNTIME_URL$JAMJET_CLOUD_TOKEN or $JAMJET_API_KEYyour hosted engine + Cloud governance
a URL stringused directlynoneany engine endpoint

A bare agent.deploy() with no runtime always targets local, so you never hit a remote engine by accident. A remote engine is reached only when you pass its leg name or URL.

await agent.deploy(runtime="self-host")
await agent.deploy(runtime="cloud")
await agent.deploy(runtime="https://my-engine.example.com")

A named remote leg with no configured URL raises a clear error rather than falling back to local.

The honest cloud model

runtime="cloud" deploys the same IR to your hosted engine (a URL you run, for example on Fly) and also turns on JamJet Cloud governance span-push.

JamJet Cloud is the governance and observability plane, not a workflow execution engine. There is no managed multi-tenant "cell" that runs your workflows for you; runtime="cloud" is a hosted engine URL plus Cloud governance, and the deploy client is never pointed at the Cloud API. Cloud governance is never load-bearing: the deploy succeeds even if Cloud is unreachable.

Cloud is the governance plane, independent of the runtime. See Reliability for exactly what the engine guarantees, and what it does not.

Governance travels with the deploy

The agent's governance (PII redaction, signed audit, receipts, plus any budget or policy you set) is compiled into the IR and ships unchanged. Deploy never strips those knobs. See Governance.

Scheduling

Pass a cron expression to install a recurring schedule so the engine fires the workflow on that cadence:

await agent.deploy(runtime="self-host", schedule="0 9 * * *")

Cron requires the SQLite backend and an embedded cron worker on the target engine (set JAMJET_EMBED_CRON). The recurring intent belongs in the agent's instructions; a scheduled run is seeded with an empty user turn.

What a self-hosted deployment runs

A durable deployment is three processes:

  1. The engine (jamjet-server) registers IR, drives executions, and owns the state store.

  2. A tool worker runs your @tool functions. Run one or more dedicated workers against the same engine, pointed at your tool modules:

    jamjet worker --runtime $JAMJET_RUNTIME_URL --queue python_tool --modules my_tools

    Set JAMJET_EMBED_WORKERS on the engine to run an in-process worker pool instead of dedicated worker processes.

  3. The model sidecar keeps the engine's model calls on the governed seam. Run it and point the engine at it with JAMJET_MODEL_SEAM_URL. See Any model.

Locally, jamjet dev runs all three with one command.

Storage backends

The engine has exactly two storage backends, selected by STORAGE_BACKEND:

  • sqlite (the default) is the durable, single-writer store used for self-host and hosted deployments. The database URL defaults to sqlite://.jamjet/runtime.db; override it with DATABASE_URL.
  • memory is an ephemeral, per-process backend. State does not survive a restart. Useful for tests and throwaway runs.

There is no Postgres backend in the engine. Cron scheduling requires the SQLite backend.

Engine configuration

The engine is configured by environment variables:

VariableDefaultDescription
STORAGE_BACKENDsqlitesqlite (durable) or memory (ephemeral).
DATABASE_URLsqlite://.jamjet/runtime.dbSQLite connection string for the durable backend.
JAMJET_EMBED_WORKERS(unset)Run an in-process worker pool inside the engine.
JAMJET_EMBED_CRON(unset)Run the cron scheduler in-process (needs SQLite).
JAMJET_MODEL_SEAM_URL(unset)Route the engine's model calls to the governed sidecar.
OTEL_EXPORTER_OTLP_ENDPOINT(unset)Export traces and metrics over OTLP.

The deploy client reads its target from JAMJET_RUNTIME_URL / JAMJET_RUNTIME_TOKEN (self-host) and JAMJET_CLOUD_RUNTIME_URL / JAMJET_CLOUD_TOKEN or JAMJET_API_KEY (cloud). Model provider keys (ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY) are read by the model sidecar.

Health check

curl http://localhost:7700/health

Next steps

On this page