Skip to content
namtran1812Public

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

4 Commits

Folders and files

Repository files navigation

Relay

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.

Why Relay?

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.

Architecture

                    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.

Features

Event-sourced 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.

Typed async tools

Tools declare Pydantic input and output models.

Before and after execution, Relay validates the tool boundary:

  1. Resolve the requested tool.
  2. Validate its arguments.
  3. Execute the asynchronous handler.
  4. Validate the returned result.

The registry also generates deterministic JSON schemas for registered tools.

Durable execution

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.

PostgreSQL persistence

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.

Recovery

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.

Project Structure

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/

Development

Relay requires Python 3.11+.

Install dependencies:

uv sync --all-extras

Run tests:

uv run pytest -q

Run static analysis:

uv run ruff check .
uv run mypy relay

PostgreSQL

Start PostgreSQL:

docker compose up -d postgres

Check readiness:

docker compose exec postgres pg_isready -U relay -d relay

Apply migrations:

uv run alembic upgrade head

Run 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 -vv

Correctness Model

Relay 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.

Technology

Python, AsyncIO, Pydantic, SQLAlchemy, asyncpg, PostgreSQL, Alembic, Pytest, Ruff, mypy, Docker

Roadmap

  • 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

Design Principles

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.

Status

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.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages