A durable, evidence-grounded agent runtime for software investigations.
Relay is an AI engineering workspace for running multi-step software investigations across models, tools, and repository evidence without treating an agent run as an ephemeral request.
The runtime records execution as structured events, persists checkpoints, validates typed tool boundaries, and resumes interrupted workflows without replaying already committed work.
Long-running agent workflows fail differently from ordinary request/response applications.
A worker can crash halfway through an investigation. A tool may already have completed. A run may need human approval before continuing. An investigation may need to resume later on a completely different worker.
Relay treats execution state as a first-class system primitive.
Instead of restarting an investigation from the beginning, Relay maintains a durable history of what happened and where execution should continue.
Relay
|
Durable Executor
|
+-----------+-----------+
| |
Tool Registry Event Stream
| |
Typed async tools Immutable events
| |
+-----------+-----------+
|
StateStore
|
+-----------+-----------+
| |
Checkpoints Events
| |
+-----------+-----------+
|
PostgreSQL
DurableExecutor depends on the StateStore protocol rather than directly on PostgreSQL. This keeps execution semantics independent of persistence and allows the same runtime to use an in-memory store for unit tests and PostgreSQL for durable execution.
Relay represents execution transitions as immutable AgentEvent records.
Events cover:
- investigation lifecycle
- model requests and responses
- tool requests, starts, completions, and failures
- discovered evidence
Every event belongs to one investigation and receives a monotonically increasing sequence number. Replay rejects sequence gaps and events belonging to another investigation.
Tools declare Pydantic input and output models.
Before and after execution, Relay validates the tool boundary:
- Resolve the requested tool.
- Validate its arguments.
- Execute the asynchronous handler.
- Validate the returned result.
The registry also generates deterministic JSON schemas for registered tools.
Each run maintains a checkpoint containing:
- investigation ID
- run ID
- execution status
- next step
- tool invocation history
- committed results
After an interruption, Relay can reconstruct the checkpoint and continue from the next unfinished step.
Relay provides an asynchronous SQLAlchemy and asyncpg persistence layer for events and checkpoints.
Database constraints enforce runtime invariants such as unique event sequence numbers within each investigation.
A persisted checkpoint prevents completed steps from being unnecessarily replayed after an interruption.
step 0 ---- committed
step 1 ---- committed
step 2 ---- committed
|
crash
|
restart
|
step 0 ---- skip
step 1 ---- skip
step 2 ---- skip
step 3 ---- resume
The executor can therefore be reconstructed against durable state instead of relying on the memory of the worker that originally started the run.
relay/
├── agent/
│ ├── events.py
│ └── journal.py
├── models/
│ └── client.py
├── persistence/
│ ├── database.py
│ ├── models.py
│ └── postgres.py
├── runtime/
│ ├── executor.py
│ ├── state.py
│ └── store.py
└── tools/
└── registry.py
tests/
├── integration/
└── test_*.py
alembic/
└── versions/
Relay requires Python 3.11+.
Install dependencies:
uv sync --all-extrasRun tests:
uv run pytest -qRun static analysis:
uv run ruff check .
uv run mypy relayStart PostgreSQL:
docker compose up -d postgresCheck readiness:
docker compose exec postgres pg_isready -U relay -d relayApply migrations:
uv run alembic upgrade headRun the PostgreSQL recovery integration test:
RELAY_TEST_DATABASE_URL="postgresql+asyncpg://relay:relay@localhost:5432/relay" \
uv run pytest tests/integration/test_postgres_recovery.py -vvRelay currently guarantees that a tool step whose checkpoint has been successfully persisted will not be re-executed when the same run is restored.
This is different from guaranteeing exactly-once external side effects.
If an external operation succeeds but the worker crashes before Relay persists the corresponding checkpoint, that operation may be retried. Exactly-once behavior across arbitrary external systems generally requires cooperation from those systems.
Relay is designed to make these boundaries explicit rather than hiding them behind an assumed exactly-once guarantee.
Python, AsyncIO, Pydantic, SQLAlchemy, asyncpg, PostgreSQL, Alembic, Pytest, Ruff, mypy, Docker
- Invocation-level idempotency
- Redis-backed worker coordination
- FastAPI execution API
- Live execution event streaming
- OpenAI Agents SDK integration
- Human approval checkpoints
- React investigation interface
- Repository and filesystem investigation tools
- Failure-injection benchmarks
- Distributed worker recovery
Durability over hidden state. Important execution state should survive worker failure.
Evidence over opaque output. Investigations should preserve the events and tool outputs that produced a result.
Explicit failure semantics. Recovery behavior should be defined and tested rather than assumed.
Typed boundaries. Tools validate both what enters and what leaves the runtime.
Deterministic replay. Persisted state should be sufficient to reconstruct and inspect execution.
Relay is under active development.
The event protocol, typed tool registry, resumable execution core, and PostgreSQL persistence layer form the current foundation. API, model orchestration, distributed coordination, and user-interface layers are planned next.