OneForOne
Only the failed process restarts. Siblings keep running. The default; use when processes are independent.
v3ga.dev · an orchestration runtime
Vega applies Erlang's supervision model to autonomous AI agents. When a process fails, and it will, the runtime restarts it, classifies the error, and keeps the rest of the system running.
Vega is a Go runtime that treats each AI agent as a supervised process. Spawn them by chat, by YAML, or directly from Go. They get an inbox, a budget, a retry policy, and a place in a supervision tree. The orchestrator owns their lifecycle: it starts them, watches them, restarts the ones that fail, and tells you when something is going wrong.
$ brew install everydev1618/tap/vega
$ export ANTHROPIC_API_KEY=sk-ant-...
$ vega serve
▸ orchestrator listening on :8080
▸ dashboard ready at http://localhost:8080
▸ sse stream at /api/v1/events
SQLite persistence. Anthropic by default; pluggable LLM backend. Telegram bot and cron scheduler ship in the same binary.
Borrowed wholesale from Erlang/OTP, where it has kept telephone switches running with five-nines uptime for forty years. The claim is not that AI agents are like phone calls. The claim is that anything that can crash benefits from a thing that restarts it.
Every supervisor in Vega carries one strategy. It decides what happens to a process group when any one process dies.
Only the failed process restarts. Siblings keep running. The default; use when processes are independent.
When one fails, the whole group restarts. Use when processes share state and must be brought up together.
The failed process and every process started after it restart, in order. Use for pipelines where downstream depends on upstream state.
2.4 · error classification
Failures are sorted into seven categories. Four retry with backoff. Three give up.
| RateLimit | retry · exponential backoff |
| Overloaded | retry · exponential backoff |
| Timeout | retry · linear backoff |
| Temporary | retry · linear backoff |
| Authentication | fail · operator intervention required |
| InvalidRequest | fail · code or prompt error |
| BudgetExceeded | fail · raise the budget or shrink the task |
A process supervisor restarts what dies. A reactive agent wakes to what happens. Same event bus underneath — the one the dashboard already subscribes to — now also drives cognition. The agent that wakes is the one with the memory, not the one with the open socket.
An agent declares the events it reacts to. When one fires, it wakes into an ordinary run with its own memory already attached. A salience gate stands between the event and the token spend. And when the run ends, it writes back — so the agent learns from having reacted, instead of starting from zero every time.
agents:
night-watch:
model: claude-haiku-4-5
triggers:
- on: agent.completed
where: "status == failed"
prompt: "{{.Data.agent}} failed. Note it."
Reactivity sits on the blueprint next to the system prompt and the tools — a third faculty, versioned with the rest of the agent.
# tier 1 — free, synchronous
type glob · where predicate
# tier 2 — cheap model, opt-in
gate: model → yes/no
# loop guard, always on
depth · rate · dedup
Not every event deserves a thought. Rules reject most for free; a model judges the rest. The depthguard bounds a chain of agents reacting to each other so a fleet can't run away.
event → gate
→ wake (+memory)
→ act
→ consolidate
→ memory
The run distills into an outcome-aware note. Reactions that recur get promoted into always-injected memory — repeated experience becoming disposition, without editing the authored prompt.
3.4 · where events come from
One spine. Agents react to each other, to the clock, to their own signals, and to the outside world.
| agent.completed | an agent finished a task |
| schedule.fired | a cron entry came due |
| memory.wrote | an agent recorded something |
| signal.* | emitted by an agent, or POST /api/v1/events from anything |
Same runtime, three ways in. The dashboard, the YAML DSL, and the Go library all drive the same orchestrator and write to the same SQLite database.
I need a content team that can draft blog posts and ship them to our Slack.
On it. I'll have Hera build the team. One writer, one editor, Slack tool wired in.
Done. Sofia (writer) and Marcus (editor). Channel #content is open; watch them work.
Iris is your chief of staff. Hera builds agents on the fly from natural-language descriptions.
name: ContentTeam
settings:
mcp.servers:
- name: composio
agents:
writer:
model: claude-sonnet-4-6
supervisor:
strategy: OneForOne
max_restarts: 3
tools:
- composio__slack_send
Version-controlled, reproducible, and reloadable. The supervisor block is the part most agent frameworks don't have.
import (
"github.com/everydev1618/govega"
"github.com/everydev1618/govega/llm"
)
orch := vega.NewOrchestrator(
vega.WithLLM(llm.NewAnthropic()),
vega.WithStrategy(vega.OneForOne),
)
proc, _ := orch.Spawn(vega.Agent{
Name: "sofia",
Model: "claude-sonnet-4-6",
})
resp, _ := proc.Send(ctx, msg)
The Go library is the runtime itself. Anything the dashboard does is a public API call.
Every state change goes through one event bus. The dashboard subscribes to it. So does any client that hits/api/v1/events.
Token-by-token streaming for the response. Process, workflow, and channel events for the system. One SSE endpoint, JSON payloads, no websocket plumbing.
14:02:11.044 process.started sofia <0.18.0>
14:02:11.118 chat.update sofia delta=64 tokens
14:02:11.412 tool.call sofia → composio__slack_send
14:02:12.901 tool.result sofia ← composio__slack_send ok
14:02:13.118 process.failed sofia <0.18.0> context_deadline_exceeded
14:02:13.119 supervisor.restart iris → sofia strategy=OneForOne, attempt=1/3
14:02:13.184 process.started sofia <0.18.1>
14:02:14.022 process.completed sofia <0.18.1> tokens=1284 cost=$0.018
14:02:14.117 channel.message #content sofia: "draft posted to #marketing for review"
Every agent, channel, process, and workflow is addressable. OpenAPI spec ships in the binary. Generated TS types in@vega/api-types.
| method | path | description |
|---|---|---|
| GET | /api/v1/identity | Orchestrator and builder display names |
| GET | /api/v1/agents | Every agent registered in this runtime |
| POST | /api/v1/agents/{name}/chat | DM an agent · returns the full response |
| GET | /api/v1/agents/{name}/chat/stream | Token-by-token SSE for one agent |
| GET | /api/v1/processes | Running and recently terminated processes |
| GET | /api/v1/channels | Multi-agent channels and threads |
| GET | /api/v1/inbox | Items waiting for operator review |
| GET | /api/v1/events | SSE stream for the entire runtime |
peering · opt-in
Set VEGA_PEERING_ADDR and your orchestrator can talk to other Vega orchestrators over AIRE(QUIC-native, mTLS-authenticated). Trusted peers, per-agent grants, full audit trail.
Agents don't just answer — they build. A specialist writes the files; deploy_app hosts them and hands back a URL you can open. The orchestrator only relays it.
One provider-agnostic tool. The agent says "host this, give me a URL" and never learns the backend — a subprocess on the Vega box by default, an isolated cloud machine when the host wires one.
# a worker agent, after writing pacman/index.html
deploy_app(name: "pacman", source: "pacman")
▸ hosted · https://you.v3ga.dev/apps/pacman/?sig=…
▸ capability-gated · not world-readable by default
▸ provider-neutral · local subprocess or isolated machine
Static sites are served straight from the workspace; dynamic apps run as a supervised process. Either way the link works over chat, email, or Discord — no login, but scoped by a signed token you can revoke.
Vega is an experiment by Etienne de Bruinin applying forty-year-old distributed systems patterns to a brand-new problem. The short answer so far is that they work. The longer answer is what this site is for.