AI agent workflow platform. Define multi-step agent workflows in YAML, run them in ephemeral sandbox containers on Kubernetes or Podman, with human approval gates and durable execution via Temporal.
- Podman with Podman Desktop or
podman machine start - LLM API key —
OPENAI_API_KEYorANTHROPIC_API_KEY - An OpenShell gateway you can reach — deploying/operating the gateway is outside this repo's scope; see docs/testing-against-openshell-gateways.md for setting one up. You just need its address.
- Linux only: if
make upfails with a socket error, setexport PODMAN_SOCK=/run/user/$(id -u)/podman/podman.sock
export OPENAI_API_KEY="sk-..." # or ANTHROPIC_API_KEY
export OPENSHELL_GATEWAY_URL="<host>:<port>" # your OpenShell gateway address
make build # build 2 images (runner + sandbox)
make up # start the platform (Temporal + runner)| Container | Purpose |
|---|---|
podman-workflow-runner-1 |
REST API + Temporal Worker — interprets workflow YAML, dispatches steps |
podman-temporal-server-1 |
Temporal Server — durable workflow state, retry, signals |
podman-temporal-db-1 |
PostgreSQL — Temporal's storage backend |
podman-temporal-ui-1 |
Temporal Web UI — http://localhost:8233 |
Plus ephemeral agent-ca-* sandbox containers spawned per workflow step (complete agent loop: multi-turn LLM + tool calls, then destroyed).
graph LR
subgraph cluster["Cloud Agents Platform"]
WR["Workflow Runner<br/><i>API + Temporal Worker</i>"]
TS["Temporal Server"]
SB["Sandbox Container<br/><i>ephemeral, per step</i>"]
end
LLM["LLM Provider"]
WR -- "gRPC" --> TS
WR -- "spawn / destroy" --> SB
SB -- "HTTPS" --> LLM
Register a workflow definition:
python3 -c "import yaml,json,sys; print(json.dumps(yaml.safe_load(open(sys.argv[1]))))" \
examples/workflow-definitions/ephemeral-diagnose-workflow.yaml | \
curl -s -X POST http://localhost:8080/v1/workflows/definitions \
-H 'Content-Type: application/json' -d @-List registered workflows:
curl -s http://localhost:8080/v1/workflows/definitions | python3 -m json.toolRun a workflow:
curl -s -X POST http://localhost:8080/v1/workflows/run \
-H 'Content-Type: application/json' \
-d '{
"workflow_name": "ephemeral-diagnose",
"provider": {"name": "openai", "model": "gpt-4o", "credentials_secret": "OPENAI_API_KEY"},
"sandbox_image": "lightspeed-agentic-sandbox:latest"
}'
# → {"workflow_id": "wf-abc123"}Watch the sandbox containers spawn and execute:
# In another terminal — see containers appear and disappear
watch podman ps --filter label=spawned-by=workflow-runner
# Tail the agent loop logs inside a sandbox
podman logs -f $(podman ps --filter label=spawned-by=workflow-runner --format '{{.Names}}' | head -1)Check workflow result:
curl -s http://localhost:8080/v1/workflows/<workflow_id> | python3 -m json.toolYou can also open the Temporal UI at http://localhost:8233 to inspect workflow runs, event history, and step state.
See docs/DEPLOYMENT.md for the full API reference and Kubernetes deployment. See examples/DEMO.md for the interactive demo dashboard with MCP tools.
Run the workflow runner locally (without containers) for development and debugging.
# Install dependencies
uv sync --group dev --extra openshell
# Start Temporal (still needs containers) -- point OPENSHELL_GATEWAY_URL
# below at your own, separately-deployed OpenShell gateway
podman compose -f deploy/podman/docker-compose.yaml up -d temporal-db temporal-server
# Run the workflow runner on the host
TEMPORAL_URL=localhost:7233 \
WORKFLOW_SPAWNER=openshell \
OPENSHELL_GATEWAY_URL=<host>:<port> \
AUTH_REQUIRED=false \
uv run uvicorn cloud_agents.workflow.executor.temporal.entrypoint:app --host 0.0.0.0 --port 8080Run tests:
make test-unit # unit tests (no infra needed)
uv run pytest tests/integration/ -v # integration tests (requires Temporal — see Quick Start)- ARCHITECTURE.md — goals, requirements, design, components
- DEPLOYMENT.md — deployment options (Podman / Kind / Helm), API reference, workflow definition schema
- DEMO.md — demo dashboard, recording, terminal setup
- RBAC — authorization: policy file format, identity matching, quick start
- Implementation Plan (archived) — historical record of planned work (T1-T62); open items now tracked as GitHub issues