Skip to content

Repository files navigation

Volt

License

Self-hosted agent runtime in TypeScript. A port of Aegra's server layer to Node — it speaks Agent Protocol v2, so the official @langchain/langgraph-sdk client, Agent Chat UI and LangGraph Studio talk to it unmodified.

Graph execution itself is @langchain/langgraph; checkpointing is @langchain/langgraph-checkpoint-postgres. What lives here is the server: HTTP protocol, persistence, run orchestration, streaming, auth, crons.

Stack

Concern Choice
HTTP Hono + @hono/node-server
DB Postgres (pgvector) via Drizzle ORM
Graphs @langchain/langgraph
Checkpoints PostgresSaver
Validation Zod
Auth pluggable — noop / jwt (jose) / custom

Unlike Aegra there is no Redis dependency: the queue and cross-instance fan-out are planned on Postgres (FOR UPDATE SKIP LOCKED + LISTEN/NOTIFY).

Quick start

git clone https://github.com/volt-eq/volt.git
cd volt

pnpm install
cp .env.example .env
pnpm volt dev

volt dev starts Postgres if it is not running, applies migrations, then boots the runtime with reload on change. Talk to a graph without leaving the terminal:

pnpm volt chat echo
volt · chat · echo

  Thread    6895d1e4-0127-42dc-bd6f-f721ee1efa45
  Commands  /state  /history  /new  /exit

you › hola
bot › echo: hola

volt chat speaks to the HTTP API through the official SDK, so what you see is what any other client sees. An interrupt() pauses the session and asks:

  ⏸  Approve "delete the staging bucket"?
     options: approve, reject
resume › approve
bot › Approved. Executed: delete the staging bucket

CLI

Command Does
volt dev Preflight, then the runtime with reload on change
volt serve The runtime without a watcher
volt chat [graph] Interactive session against a running runtime
volt graphs The graphs this project declares, and what is being served
volt up / volt down Docker services; down --volumes erases the database

Using Volt from your own project

A project is any directory with a volt.json. It needs the graph dependencies, nothing else — the runtime and its migrations come from wherever the CLI was installed.

mkdir my-agent && cd my-agent
pnpm init
pnpm add @langchain/core @langchain/langgraph
// volt.json
{ "graphs": { "agent": "./agent.ts:graph" } }
volt dev            # in one terminal
volt chat agent     # in another

volt dev runs the Compose service only when the project ships a docker-compose.yml. Elsewhere, point DATABASE_URL at a Postgres you already have.

Smoke test:

curl localhost:2026/info
curl -X POST localhost:2026/assistants \
  -H 'content-type: application/json' \
  -d '{"graph_id":"echo","name":"echo"}'

Graph manifest

volt.json maps a protocol graph_id to a module export:

{
  "graphs": {
    "echo": "./examples/echo-agent/src/graph.ts:graph",
    "agent": "./examples/react-agent/src/graph.ts:graph"
  }
}

The export may be a compiled graph or a factory returning one. Prefer the factory: it keeps provider credentials out of module import time. POST /assistants resolves the graph before writing the row, so a bad graph_id — or a graph whose provider key is missing — fails at create time rather than on the first run.

Roadmap

Detailed status lives in context/plan/02-roadmap.md; the endpoint-by-endpoint table is in context/plan/03-agent-protocol.md.

Phase Scope Status
0 Scaffold, Postgres, migrations done
1 Schema: assistants, threads, runs, crons done
2 Graph registry + manifest done
3 Assistants + threads CRUD, /info, /health done
3b Assistant versions, thread state + history partial (state + history done)
4 Run executor, SSE, cancel, join, stateless runs done
5 Human-in-the-loop interrupts and resume done
6 JWT / OAuth / custom auth handlers partial (noop, jwt)
7 Cron scheduler, worker leases, crash recovery todo
8 Store: KV + pgvector semantic search todo
9 CLI (volt dev/serve/up), Docker, OpenTelemetry todo

Tests

pnpm db:up          # the suite uses a real Postgres, in a volt_test database
pnpm test

129 tests, around 13 seconds. They call app.fetch directly rather than binding a port, and run against real Postgres rather than a mock — jsonb containment, the conditional-update claim, cascade deletes and the checkpointer are the parts most worth exercising for real.

pnpm test:unit          # serialisation, event broker, graph registry
pnpm test:integration   # protocol endpoints, streaming, human-in-the-loop, auth
pnpm typecheck

Compatibility

The acceptance criterion is that the official client works unmodified. With the server running:

pnpm tsx scripts/sdk-smoke.ts

drives a real @langchain/langgraph-sdk through assistants, threads, runs, streaming, and an approval gate with resume.

Layout

volt.json              graph manifest
docker-compose.yml         Postgres + pgvector
context/                   plan and progress notes
tests/                     unit and integration suites
scripts/sdk-smoke.ts       compatibility check against the real SDK
packages/cli/                the `volt` command
packages/server/
  src/
    app.ts                 Hono app, error mapping, route mounting
    index.ts               entrypoint, graceful shutdown
    config.ts              env parsing (Zod)
    api/                   protocol routes (the only snake_case in the codebase)
    auth/                  pluggable identity middleware
    db/                    Drizzle schema, pool, checkpointer
    graphs/registry.ts     graph_id -> compiled graph
    runs/                  executor, event broker, message serialisation
  drizzle/                 generated migrations
examples/
  echo-agent/              credential-free graphs for tests (echo, slow)
  approval-agent/          human-in-the-loop approval gate
  react-agent/             ReAct agent (needs ANTHROPIC_API_KEY)

About

Self-hosted agent runtime in TypeScript. Agent Protocol v2 over Postgres, compatible with the LangGraph SDK.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Contributors

Languages