The production HTTP control plane for durable AI runs. Start, schedule, observe, and replay AI workflows across any client — terminal, browser, tray, Telegram, or email. Replay-first architecture with append-only ledger.
pip install abstractgateway
# Start the gateway server
export ABSTRACTGATEWAY_AUTH_TOKEN="$(python -c 'import secrets; print(secrets.token_urlsafe(32))')"
abstractgateway serve --host 127.0.0.1 --port 8080
# Or pull the Docker image
docker pull ghcr.io/lpalbou/abstractgateway-server:0.2.20
AbstractGateway is a deployable Run Gateway host for AbstractRuntime. It decouples the execution service from any specific UI, enabling multiple thin clients to connect to the same durable execution backend.
Clients render by replaying the durable ledger. Every operation is recorded as an append-only ledger record. Any client connecting at any time can reconstruct the full execution state from the ledger stream.
Clients act by submitting durable commands: pause, resume, cancel, emit events, update schedules, compact memory. Commands are persisted before processing, surviving crashes and restarts.
Built-in bearer token authentication, origin allowlists (glob patterns), and configurable rate limits. The server refuses to start without an auth token by default.
# Start a run
POST /api/gateway/runs/start
{ "bundle_id": "my-workflow", "input_data": { "prompt": "Hello" } }
# Schedule recurring runs
POST /api/gateway/runs/schedule
{ "bundle_id": "my-workflow", "start_at": "now", "interval": "1h", "repeat_count": 3 }
# Submit durable commands
POST /api/gateway/commands
{ "type": "pause|resume|cancel|emit_event|compact_memory" }
# Replay ledger (HTTP)
GET /api/gateway/runs/{run_id}/ledger?after=cursor
# Stream ledger (SSE)
GET /api/gateway/runs/{run_id}/ledger/stream?after=cursor
Everything needed to run durable AI workflows in production, from scheduling to multimodal media generation.
Runs survive crashes and restarts. File-backed or SQLite-backed stores persist run state, ledger records, artifacts, and command inbox. Split API and runner for zero-downtime upgrades.
Real-time Server-Sent Events stream every execution step. Replay-first: clients can reconstruct any run state by replaying from cursor zero. Supports cursor-based pagination.
Cron-style scheduling with immediate, delayed, and recurring modes. Repeat forever, N times, or until a date. Shared context across scheduled executions. Cancel by terminating the parent run.
Terminal TUI, browser web app, macOS tray, Telegram bot, email — all connect to the same gateway. Start on one device, continue on another. Gateway-first thin clients.
Portable .flow bundles package workflows for deployment. Upload via API or file system. Bundle discovery, version management, and deprecation controls built in.
Direct routes for TTS, STT, image generation, image editing, video generation, and music generation. All media capabilities surfaced through Runtime and discoverable via capability contracts.
Full OpenAPI spec at /openapi.json and interactive Swagger UI at /docs. Bearer token authentication built into the spec. Versioned capability discovery endpoint.
Release images on GHCR. Light server image for remote inference, experimental NVIDIA image for local GPU workloads. Compose files for production deployments with split API/runner.
Built-in KG query endpoint backed by AbstractMemory with LanceDB (vector + structured), SQLite, or in-memory stores. Semantic search and triple store for agent memory.
Three install profiles to match your deployment: remote-light, Apple Silicon native, or GPU workstation.
pip install abstractgateway
HTTP/SSE server with Runtime multimodal support, LanceDB KG, and all remote providers. Minimal hardware requirements.
pip install "abstractgateway[apple]"
Full native macOS profile with MLX, MLX-Gen, local voice, vision, and music. Optimized for M-series unified memory.
pip install "abstractgateway[gpu]"
Full local GPU profile with vLLM, HuggingFace, Diffusers, CUDA support. Also the NVIDIA Docker install profile.
# 1. Configure environment
export ABSTRACTGATEWAY_FLOWS_DIR="/path/to/bundles"
export ABSTRACTGATEWAY_DATA_DIR="$PWD/runtime/gateway"
export ABSTRACTGATEWAY_AUTH_TOKEN="$(python -c 'import secrets; print(secrets.token_urlsafe(32))')"
export ABSTRACTGATEWAY_ALLOWED_ORIGINS="http://localhost:*,http://127.0.0.1:*"
# 2. Start the gateway
abstractgateway serve --host 127.0.0.1 --port 8080
# 3. Verify
curl -sS "http://127.0.0.1:8080/api/health"
curl -sS -H "Authorization: Bearer $ABSTRACTGATEWAY_AUTH_TOKEN" \
"http://127.0.0.1:8080/api/gateway/bundles"
docker pull ghcr.io/lpalbou/abstractgateway-server:0.2.20
docker run --rm -p 127.0.0.1:8080:8080 \
-e ABSTRACTGATEWAY_AUTH_TOKEN="$ABSTRACTGATEWAY_AUTH_TOKEN" \
-e OPENAI_COMPATIBLE_BASE_URL="http://host.docker.internal:1234/v1" \
-v "$PWD/runtime/gateway:/data/gateway" \
-v "$PWD/flows/bundles:/data/flows:ro" \
ghcr.io/lpalbou/abstractgateway-server:0.2.20
For zero-downtime upgrades, run the HTTP API and runner loop as separate processes sharing the same data directory.
# Process 1: runner worker (no HTTP deps needed)
abstractgateway runner
# Process 2: HTTP API only
abstractgateway serve --no-runner --host 127.0.0.1 --port 8080
Replace directory scanning with indexed tables for better performance at scale.
export ABSTRACTGATEWAY_STORE_BACKEND=sqlite
abstractgateway serve --host 127.0.0.1 --port 8080
# Migrate existing file-backed data to SQLite
abstractgateway migrate --from=file --to=sqlite \
--data-dir runtime/gateway \
--db-path runtime/gateway/gateway.sqlite3
All endpoints are under /api/gateway/* and require bearer token authentication. Full OpenAPI spec available at /openapi.json.
POST /api/gateway/runs/start
POST /api/gateway/runs/schedule
POST /api/gateway/commands
GET /api/gateway/runs/{id}/ledger
GET /api/gateway/runs/{id}/ledger/stream
GET /api/gateway/runs/{id}/input_data
GET /api/gateway/runs/{id}/history_bundle
POST /api/gateway/runs/{id}/voice/tts
POST /api/gateway/runs/{id}/audio/transcribe
POST /api/gateway/runs/{id}/images/generate
POST /api/gateway/runs/{id}/images/edit
POST /api/gateway/runs/{id}/videos/generate
POST /api/gateway/runs/{id}/videos/from_image
POST /api/gateway/runs/{id}/music/generate
GET /api/gateway/discovery/capabilities
GET /api/gateway/bundles
POST /api/gateway/bundles/upload
GET /api/gateway/voice/voices
GET /api/gateway/audio/speech/models
GET /api/gateway/vision/models
GET /api/gateway/audio/music/models
GET /api/gateway/prompt_cache/*
GET /api/gateway/sessions/{id}/prompt_cache/*
POST /api/gateway/kg/query
GET /api/health
GET /openapi.json
GET /docs
# Start a run
curl -sS -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"bundle_id":"my-bundle","input_data":{"prompt":"Hello"}}' \
"http://127.0.0.1:8080/api/gateway/runs/start"
# Stream the ledger via SSE
curl -sS -N -H "Authorization: Bearer $TOKEN" \
"http://127.0.0.1:8080/api/gateway/runs/$RUN_ID/ledger/stream"
# Submit a durable command
curl -sS -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"run_id":"$RUN_ID","type":"resume","payload":{"response":"Yes"}}' \
"http://127.0.0.1:8080/api/gateway/commands"
# Check deployment status
abstractgateway-config status
# Bootstrap a .env file
abstractgateway config init --env-file .env
# Configure capability defaults
abstractgateway-config set-default output.text \
--provider openai-compatible \
--model your-model \
--base-url http://host.docker.internal:1234/v1