Skip to content

AbstractGateway — Getting started

AbstractGateway is a deployable HTTP/SSE host for durable AbstractRuntime runs: - clients start runs and submit durable commands - clients render by replaying/streaming the durable ledger (replay-first)

This guide starts with the zero-configuration path on your own machine, then runs the gateway with explicit configuration, starts and schedules runs, and covers file vs SQLite durability and a best-effort file → SQLite migration.

AbstractFramework ecosystem (context)

AbstractGateway is one component in the larger AbstractFramework ecosystem: - AbstractRuntime (required): durable runs + workflow registry + stores - AbstractCore, AbstractAgent, AbstractMemory (installed with the gateway): Runtime owns the LLM/tool/media integration boundary; Gateway uses its discovery and run facades for prompt-cache controls, generated and edited media, voice, audio and music, and KG-backed bundle execution

Related repos: - AbstractFramework: https://github.com/lpalbou/AbstractFramework - AbstractCore: https://github.com/lpalbou/abstractcore - AbstractRuntime: https://github.com/lpalbou/abstractruntime

Prerequisites

  • Python >=3.10 (see pyproject.toml)
  • AbstractRuntime 0.8.2 or later, installed with the gateway; the gateway refuses to start on an older runtime and names the version to install
  • Workflows: none needed to start. The gateway serves its shipped bundles (shipped-workflows.md); you can point it at your own .flow bundles or upload them after startup (POST /api/gateway/bundles/upload, see below)

Install

# Remote-light server package (HTTP/SSE + runner + stores + KG memory)
pip install abstractgateway

# Native Apple local engines
pip install "abstractgateway[apple]"

# Native/container GPU local engines, also used by the NVIDIA Docker image
pip install "abstractgateway[gpu]"

# Desktop menu bar / system tray icon for `serve` (macOS, Windows, Linux)
pip install "abstractgateway[tray]"

With the base install and a configured provider stack, Gateway can surface run-scoped direct TTS, STT, image generation, image edit, and music generation for higher apps through one shared capability contract.

0) Fastest start on your own machine

abstractgateway serve

With no auth configured, this binds 127.0.0.1:8080, enables user auth, creates default/admin, keeps data in your OS's per-user data folder, and prints a one-time First run: open http://127.0.0.1:8080/console#claim=... link that signs you into the console and opens the first-run guide. See first-run.md, including abstractgateway claim and abstractgateway service install. To let other devices on your network reach it, use abstractgateway network set lan (see configuration.md). The rest of this guide uses explicit configuration.

1) Run with explicit configuration (file-backed stores)

File-backed stores are the default and easiest for development.

export ABSTRACTGATEWAY_DATA_DIR="$PWD/runtime/gateway"

# Optional: set only for a custom bundle registry. When unset, Gateway uses
# the packaged shipped bundle directory containing basic-agent.
# export ABSTRACTGATEWAY_FLOWS_DIR="/path/to/bundles"

# User accounts: the sign-in path for the console and the browser apps.
export ABSTRACTGATEWAY_USER_AUTH=1

abstractgateway serve --host 127.0.0.1 --port 8080

On first local start, Gateway creates default/admin, writes the browser-login token to $ABSTRACTGATEWAY_DATA_DIR/auth/bootstrap-admin-token (mode 0600), prints that token, and prints a one-time console sign-in link. Use the token with user admin for browser apps. abstractgateway serve --no-print-token keeps the token out of the startup output (it stays in the file); on a non-loopback bind it is hidden by default and --print-token shows it. ABSTRACTGATEWAY_AUTH_TOKEN is a shared server/operator bearer token; it is not a browser sign-in token.

Browser origins other than http://localhost:* and http://127.0.0.1:* are a setting: abstractgateway network set --allowed-origins https://your.host.

OpenAPI docs (Swagger UI): http://127.0.0.1:8080/docs (use Authorize with a Gateway user token)

Smoke checks:

curl -sS "http://127.0.0.1:8080/api/health"

curl -sS -H "Authorization: Bearer $(cat "$ABSTRACTGATEWAY_DATA_DIR/auth/bootstrap-admin-token")" \
  "http://127.0.0.1:8080/api/gateway/bundles"

If bundles.items is empty (see also troubleshooting.md), either: - point ABSTRACTGATEWAY_FLOWS_DIR at the shipped bundle directory or another directory containing *.flow files (or a single .flow file), or - upload a bundle via the API:

curl -sS -H "Authorization: Bearer $(cat "$ABSTRACTGATEWAY_DATA_DIR/auth/bootstrap-admin-token")" \
  -F "file=@./my-bundle@0.1.0.flow" \
  -F "overwrite=false" \
  -F "reload=true" \
  "http://127.0.0.1:8080/api/gateway/bundles/upload"

You can also create a local env file and inspect readiness with:

abstractgateway-config init --env-file .env
abstractgateway-config status

2) Start a run (bundle mode)

First, discover entrypoints from GET /api/gateway/bundles. Then start a run:

curl -sS -H "Authorization: Bearer $(cat "$ABSTRACTGATEWAY_DATA_DIR/auth/bootstrap-admin-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"

Notes: - If a bundle has multiple entrypoints and no default, you must pass flow_id. - To run the gateway's default agent for an interface instead of naming a bundle, send {"flow_id": "@default", "interface": "abstractcode.agent.v1", ...} (configuration.md). - Add "_runtime": {"stream": true} to input_data to receive the model's reply live on the ledger stream (api.md). - Every start answers resolved_workflow, the workflow the run really runs. - See api.md for ledger replay/stream and durable commands.

2b) (Optional) Run a workflow on a schedule

To run a workflow again and again, create an automation. Each run is kept as a chat turn, and the automation stays quiet unless a run asks for attention or fails:

curl -sS -H "Authorization: Bearer $(cat "$ABSTRACTGATEWAY_DATA_DIR/auth/bootstrap-admin-token")" -H "Content-Type: application/json" \
  -d '{"request_id":"memory-monitor-1","title":"Memory every 2 minutes","target":{"flow_id":"@default","interface":"abstractcode.agent.v1","input_data":{"prompt":"Report the memory use of this computer."}},"trigger":{"source_id":"schedule","source_version":1,"config":{"every":"2m"}}}' \
  "http://127.0.0.1:8080/api/gateway/automations"

Read its runs with GET /api/gateway/automations/{automation_id}/occurrences, and pause, resume, run now or archive it with POST /api/gateway/automations/{automation_id}/commands. Tools run without asking by default (creating the automation is the consent). See automations.md.

For a plain scheduled parent run without these controls, use POST /api/gateway/runs/schedule:

curl -sS -H "Authorization: Bearer $(cat "$ABSTRACTGATEWAY_DATA_DIR/auth/bootstrap-admin-token")" -H "Content-Type: application/json" \
  -d '{"bundle_id":"my-bundle","flow_id":"ac-echo","input_data":{"prompt":"Ping"},"start_at":"now","interval":"1h","repeat_count":3}' \
  "http://127.0.0.1:8080/api/gateway/runs/schedule"

Tip: to stop a schedule, cancel the scheduled parent run (POST /api/gateway/commands, type cancel).

By default, abstractgateway serve starts the HTTP API and the runner loop in the same process.

To restart the HTTP API without pausing durable execution, run two processes sharing the same ABSTRACTGATEWAY_DATA_DIR:

# 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

3b) Docker / Compose

For a containerized remote-light deployment with AbstractRuntime, Runtime-owned provider/tool and multimodal support, KG memory, and provider/session prompt-cache controls included. Remote embeddings are available in this profile when embedding.text points at a remote provider, an OpenAI-compatible embeddings endpoint, or a remote AbstractCore server; local HuggingFace/sentence-transformer embeddings require abstractgateway[embeddings].

docker run --rm --name abstractgateway \
  -p 8080:8080 \
  -v "$PWD/runtime:/data" \
  -e ABSTRACTGATEWAY_DATA_DIR=/data \
  -e ABSTRACTGATEWAY_USER_AUTH=1 \
  ghcr.io/lpalbou/abstractgateway:latest

See deployment.md for Compose, provider keys, and image customization.

On first start, the container creates default/admin and writes the token to runtime/auth/bootstrap-admin-token. NVIDIA hosts can try ghcr.io/lpalbou/abstractgateway:0.13.0-gpu with the compose overlay in docker/abstractgateway-server/compose.nvidia.yml. It is experimental until a real CUDA build/smoke gate is part of release validation. Apple MLX inference should run natively on macOS rather than in Docker because Linux containers do not get access to Apple's Metal/MLX runtime. The container can still use native macOS inference through an OpenAI-compatible endpoint: point OPENAI_BASE_URL at Docker Model Runner on http://model-runner.docker.internal/engines/v1 or mlx_lm.server. For named local providers, set LMSTUDIO_BASE_URL=http://host.docker.internal:1234/v1 or OLLAMA_BASE_URL=http://host.docker.internal:11434 when the native Ollama model path uses MLX. For native non-Docker installs, use pip install "abstractgateway[apple]" on Apple Silicon, and pip install "abstractgateway[gpu]" on GPU workstations or NVIDIA Docker builds.

4) What’s stored in ABSTRACTGATEWAY_DATA_DIR (file backend)

When ABSTRACTGATEWAY_STORE_BACKEND=file (default), the gateway persists (via abstractruntime stores): - run_<run_id>.json (checkpointed run state) - ledger_<run_id>.jsonl (append-only step records) - commands.jsonl and commands_cursor.json (durable inbox + runner cursor) - artifacts/ (offloaded blobs/attachments) - dynamic_flows/ (gateway-generated wrapper flows, e.g. schedules) - workspaces/ (per-run workspaces created at run start when workspace_root is not provided)

5) Enable SQLite-backed stores

SQLite-backed stores eliminate directory scanning and move run/ledger/inbox data into indexed tables.

Artifacts remain file-backed under ABSTRACTGATEWAY_DATA_DIR/artifacts/.

export ABSTRACTGATEWAY_STORE_BACKEND=sqlite

# Optional; when omitted, defaults to: <ABSTRACTGATEWAY_DATA_DIR>/gateway.sqlite3
export ABSTRACTGATEWAY_DB_PATH="$PWD/runtime/gateway/gateway.sqlite3"
#
# Safety invariant: when using sqlite, the DB file must live under ABSTRACTGATEWAY_DATA_DIR.
# The gateway will refuse to start if ABSTRACTGATEWAY_DB_PATH points outside (prevents UAT/prod cross-wiring).

abstractgateway serve --host 127.0.0.1 --port 8080

6) Migrate an existing file-backed data dir → SQLite

This is a best-effort local migration (abstractgateway migrate) that reads: - run_*.json - ledger_*.jsonl - commands.jsonl - commands_cursor.json

and writes a single SQLite DB file. It does not delete the original files.

cp -a runtime/gateway "runtime/gateway.file-backup.$(date +%Y%m%d-%H%M%S)"

abstractgateway migrate --from=file --to=sqlite \
  --data-dir runtime/gateway \
  --db-path runtime/gateway/gateway.sqlite3

7) (Optional) Use the gateway from an OpenAI SDK

An admin turns on the OpenAI-compatible API on the console's OpenAI API page (sidebar Models). Then any OpenAI SDK reaches this gateway's models with your gateway token as the API key:

from openai import OpenAI

client = OpenAI(base_url="http://127.0.0.1:8080/v1", api_key="YOUR_GATEWAY_TOKEN")
print(client.models.list())

See openai-api.md for the supported surface, access settings and the request log.