Temporal-backed workflow runtime for Claude Code skills
Project description
sagaflow
Durable execution for long-running agent workflows, on top of Temporal.
You write a Python workflow that calls models, runs tools, and writes artifacts. sagaflow runs each step as a Temporal activity, so when the worker dies — or a 40-minute fan-out crashes halfway — the next launch resumes from the last completed step instead of starting over. Results land in ~/.sagaflow/INBOX.md whether or not you're still attached to the session that started them.
Quick start
pip install sagaflow
temporal server start-dev &
export ANTHROPIC_API_KEY=sk-ant-...
sagaflow launch hello-world --name alice --await
# → hello, alice
Kill the terminal mid-run and re-launch the same workflow ID: it picks up from where the worker died.
What you get
- Resumes after crashes. Activity-level checkpointing via Temporal — workers, sessions, and laptops can all die without losing in-flight work.
- Decoupled from the caller. Fire-and-forget submissions land in an append-only inbox; a session-start hook surfaces unread results next time you open Claude Code.
- Provider-agnostic transport. Anthropic SDK by default; point
ANTHROPIC_BASE_URLat Bedrock, a model gateway, or any compatible proxy. - Auto-managed worker. First
sagaflow launchspawns a worker daemon;sagaflow doctorreports health.
Install
pip install sagaflow
Requirements:
- Python 3.11+
- Temporal CLI running locally:
brew install temporal && temporal server start-dev - An Anthropic API key (or a compatible proxy via
ANTHROPIC_BASE_URL)
Authoring a workflow
from sagaflow import workflow, generate_text, parallel, write_file
@workflow(name="code-review", phases=["Critique", "Synthesize"])
async def run(diff: str):
findings = await parallel(
generate_text("security-critic", variables={"diff": diff}),
generate_text("perf-critic", variables={"diff": diff}),
)
report = await generate_text("synth", variables={"findings": str(findings)})
await write_file("report.md", report)
return report
Prompts live in prompts/<name>.prompt next to the workflow file. Each generate_text and write_file call is a Temporal activity with its own retry policy and replay log.
CLI
sagaflow launch <name> --arg key=value [--await] # submit a workflow
sagaflow inbox # list unread results
sagaflow dismiss <run-id> # mark as read
sagaflow doctor # diagnose temporal/worker/hook
How it works
sagaflow launch
│
▼
preflight (install hook, spawn worker if missing)
│
▼
Temporal (localhost:7233) ── workflow ID ── worker daemon
│
▼
activities:
• model calls
• file I/O
• inbox emit
│
▼
~/.sagaflow/INBOX.md + desktop notify
│
▼
next session: SessionStart
hook surfaces unread runs
If the worker crashes mid-run, the next sagaflow launch (or the next worker poll) resumes from the last completed activity. Activities that already succeeded don't re-execute.
Development
git clone https://github.com/npow/sagaflow
cd sagaflow
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
ruff check sagaflow tests
mypy sagaflow
pytest
# Opt-in end-to-end tests (require live Temporal + real Anthropic access)
SAGAFLOW_E2E=1 pytest
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sagaflow-0.10.9.tar.gz.
File metadata
- Download URL: sagaflow-0.10.9.tar.gz
- Upload date:
- Size: 529.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6b7dc75bbac56a74af52b8e4bf5155a9f70cde13dc852c7bc4fce26f06ac54b0
|
|
| MD5 |
d2ad2b4ac0c56c2e60ef8bb1d1436b3a
|
|
| BLAKE2b-256 |
dda2ff6222c5e224ec414d8456d62bda0c4e335df86c7b3ee36b96f8b39479a2
|
Provenance
The following attestation bundles were made for sagaflow-0.10.9.tar.gz:
Publisher:
publish.yml on npow/sagaflow
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sagaflow-0.10.9.tar.gz -
Subject digest:
6b7dc75bbac56a74af52b8e4bf5155a9f70cde13dc852c7bc4fce26f06ac54b0 - Sigstore transparency entry: 1469551107
- Sigstore integration time:
-
Permalink:
npow/sagaflow@106387fed60cee6329263f5b6eacb59691e06f0b -
Branch / Tag:
refs/tags/v0.10.9 - Owner: https://github.com/npow
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@106387fed60cee6329263f5b6eacb59691e06f0b -
Trigger Event:
release
-
Statement type:
File details
Details for the file sagaflow-0.10.9-py3-none-any.whl.
File metadata
- Download URL: sagaflow-0.10.9-py3-none-any.whl
- Upload date:
- Size: 252.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
97a1fa78098147cbecbadd9a9095276d358d1f30357d74a94362dc2fe8370843
|
|
| MD5 |
75ed1c2d6ddb6e3859a9f02dd6a6ebc1
|
|
| BLAKE2b-256 |
73cc62f2f9d5b85784db8f2fbc6388ca988ed4f17363a9dcdc78a1ea66d83bd9
|
Provenance
The following attestation bundles were made for sagaflow-0.10.9-py3-none-any.whl:
Publisher:
publish.yml on npow/sagaflow
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sagaflow-0.10.9-py3-none-any.whl -
Subject digest:
97a1fa78098147cbecbadd9a9095276d358d1f30357d74a94362dc2fe8370843 - Sigstore transparency entry: 1469551472
- Sigstore integration time:
-
Permalink:
npow/sagaflow@106387fed60cee6329263f5b6eacb59691e06f0b -
Branch / Tag:
refs/tags/v0.10.9 - Owner: https://github.com/npow
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@106387fed60cee6329263f5b6eacb59691e06f0b -
Trigger Event:
release
-
Statement type: