SuperAgent is a production-grade AI agent built on Dex durable execution and the released Dex Go SDK. It combines a Go API and Worker with an independently deployable React application. OpenAPI generates both transport boundaries from one contract.
🚀 Join the SuperDurable SuperAgent community on Slack
- 💡 Share ideas and feedback
- ❓ Ask questions and get help
- 🤝 Connect with contributors and other users
- Durable conversations with typed application history
- Streaming assistant text and optionally enabled provider-authored reasoning summaries
- Plans, tool approvals, user input, steering, and durable timers
- OpenAI, Anthropic, Gemini, Groq, and deterministic mock providers
- MCP over stdio and Streamable HTTP
- Context compaction and Worker replacement recovery
- Atomic Snapshot restoration with best-effort live event reconciliation
- Separately deployable backend and frontend artifacts
The browser restores durable state through one
GET /products/ai-agent/snapshot request. It applies Stream updates for low
latency and reconciles after durable waits, server errors, explicit requests,
and a configurable visible-page Snapshot fallback that defaults to 60 seconds.
Refresh recovers only the configured recent Stream tail before resuming live
polls.
React application ── generated Fetch client ──> Go OpenAPI API
│
├── Dex Client
└── Dex Worker
│
├── model providers
└── MCP servers
The Go process never embeds or serves frontend assets. web/dist reads its API
origin from config.json, so frontend deployments can change independently of
the backend.
The reusable Go package is available at
github.com/superdurable/superagent/agent. An embedding application supplies
the provider-neutral model and tool boundaries, registers agent.NewFlow(...)
with its Dex Worker, and uses agent.NewClient(...) for typed commands,
Snapshots, history, and live events. The reference API process uses this same
public package; it does not copy or wrap the Agent loop.
The optional github.com/superdurable/superagent/model package exposes the
built-in provider router, provider adapters, and process-memory credential
store. Embedders can use it without importing SuperAgent internals.
The github.com/superdurable/superagent/toolcontract package exposes generated
DTOs, compact schemas, and strict decoders for the built-in tools. Embedding
applications can consume the exact provider and execution contracts without
copying their JSON Schema.
Embedding applications start a non-reusable FlowID with Client.Start and a
typed StartRequest. RuntimeMetadata is an optional JSON object of at most
16 KiB for trusted routing data. It is persisted across Worker replacement and
passed only to tool implementations, never to models, browser Snapshots, or
Streams. Do not put secrets in it.
Set AgentConfig.InactivityTimeoutSeconds to arm inactivity expiration across
the Agent lifecycle; zero disables it and positive values start at two minutes.
Embedders enabling the timeout must pass
agent.WithInactivityExpirationHandler(...) to agent.NewFlow. The handler
receives a stable Flow ID, Run ID, deadline, and runtime metadata for an
idempotent application cleanup request. Accepted user mutations coalesce Timer
resets within one minute. A durable_wait extends the deadline through its
target; model and ordinary tool work do not pause it.
Embedders that need admission and accounting boundaries can pass
agent.WithModelHooks(...). A non-nil configuration requires both hooks. Dex
runs BeforeModelCall, CallModelWithHooks, AfterModelCall, and
ApplyModelResult as separate Steps, so an After retry never repeats the model
call. The Call Step overwrites the ModelUsage Attribute with the provider's
exact usage for that call; the After hook receives that same value. SuperAgent
does not accumulate account usage.
flow := agent.NewFlow(modelClient, tools, agent.WithModelHooks(&agent.ModelHooksConfig{
BeforeModelCall: admitModelCall,
AfterModelCall: synchronizeModelUsage,
}))The Before hook returns false, nil for a business rejection. Hook errors use
the owning Dex Step retry policy. The After hook must be safely repeatable by
its supplied CallID.
External tool retries belong to Dex. ToolDefinition controls attempt timeout,
maximum attempts, and total duration. A registry performs exactly one call for
each Dex attempt.
Commands use Dex transactional RPC semantics. The Agent Client creates one
stable application message ID before each Send RPC and preserves it across
transport retries and steering. Snapshot exposes those IDs for exact
queued-message edit, delete, and steering. After an ambiguous network result,
clients read Snapshot to reconcile current durable state instead of consulting
stored command receipts. Client.GetArchivedMessages reads one immutable
history page without loading the current Agent interaction state.
See ARCHITECTURE.md for package boundaries and durable/live reconciliation. See docs/flow-model.md for the Flow graph and resource model.
- Go matching
go.mod - Node.js and npm compatible with
web/package-lock.json - A Dex Server
v0.12.1 - A writable directory for disposable Dex BlobCache data
Install frontend dependencies and build both deployable artifacts:
npm --prefix web ci
make build-api
make build-webStart a compatible Dex server. Dex Go SDK v0.12.1 Workers require the Server
compatibility RPC, so upgrade the Server before the Worker. Then run the API and
Worker:
SUPERAGENT_HTTP_ALLOWED_ORIGINS=http://127.0.0.1:3000 ./bin/superagentServe the frontend from a separate terminal:
node script/serve-web.mjs --directory web/dist --port 3000Open http://127.0.0.1:3000/. The local defaults are:
| Component | Address |
|---|---|
| Frontend | http://127.0.0.1:3000/ |
| API | http://127.0.0.1:8080/ |
| Dex FlowService | 127.0.0.1:8801 |
| Dex Worker | 127.0.0.1:8803 |
Use HTTPS for production deployments so browser secure-context APIs remain available.
| Variable | Purpose | Default |
|---|---|---|
SUPERAGENT_HTTP_ADDRESS |
OpenAPI bind address | 127.0.0.1:8080 |
SUPERAGENT_HTTP_ALLOWED_ORIGINS |
Exact comma-separated CORS origins | none |
SUPERAGENT_STREAM_RECOVERY_LIMIT |
Recent events read per Stream on refresh, from 1 through 1000 | 1000 |
DEX_FLOW_SERVICE_ADDRESS |
Dex FlowService address | 127.0.0.1:8801 |
DEX_WORKER_BIND_ADDRESS |
Local Worker bind address | 127.0.0.1:8803 |
DEX_WORKER_TARGET |
Worker address advertised to Dex | Worker bind address |
DEX_BLOB_CACHE_DIR |
Disposable BlobCache directory | /tmp/superagent-blob-cache |
DEX_BLOB_CACHE_MAX_BYTES |
BlobCache size limit in bytes | 536870912 |
DEX_AGENT_MCP_CONFIG |
Trusted MCP YAML path | disabled |
OPENAI_API_KEY |
OpenAI credential | unset |
OPENAI_DISABLE_MODEL_RESPONSE_STORE |
Send store=false for OpenAI Responses calls |
false |
ANTHROPIC_API_KEY |
Anthropic credential | unset |
GEMINI_API_KEY |
Gemini credential | unset |
GROQ_API_KEY |
Groq credential | unset |
Each provider accepts a trusted HTTPS origin override named
<PROVIDER>_BASE_URL. Provider credentials stay in Worker memory and are never
persisted in Dex state or logged. Copy
web/mcp-servers.example.yaml to configure
trusted MCP servers.
OpenAI Responses calls always send store explicitly. The default is
store=true; set OPENAI_DISABLE_MODEL_RESPONSE_STORE=true only when the
deployment requires provider-side response storage to be disabled. This setting
is independent of model hooks.
Each configured tool defaults to running_type: short_running. Use
long_running when more than half of expected calls exceed five seconds. This
is a Dex placement optimization, not a timeout or SLA; short-running calls may
fall back and complete normally. Every regular Step attempt uses Dex's
one-minute heartbeat timeout.
For a cross-origin frontend deployment, add its exact origin to
SUPERAGENT_HTTP_ALLOWED_ORIGINS. Wildcards and credentialed cross-origin
requests are intentionally unsupported. Serve config.json with
Cache-Control: no-store and cache fingerprinted frontend releases instead.
Its optional positive snapshotRefreshIntervalMilliseconds value configures
the visible-page Snapshot fallback. Omission selects 60000.
OpenAPI is the only HTTP contract source. Regenerate and verify both clients:
make generate
make check-generatedRun the complete credential-free quality gate:
make checkmake test-public-api also compiles a fixture as a separate Go module. This
guards the public import boundary independently of access to internal code.
Run real-server and provider verification explicitly:
DEX_FLOW_SERVICE_ADDRESS=127.0.0.1:8801 make test-dex-integration
make test-openai-liveOnly make test-openai-live reads OPENAI_API_KEY from the ignored root
.env. Default tests use deterministic fakes or local protocol fixtures.
Verify that the Go Flow Definition Graph is valid with zero diagnostics:
make check-flow-definitionRender the Go source directly:
make flow-visualizeThe command analyzes internal/agent/flow.go, opens Flow Rendering, and serves
the graph until stopped. The CI check generates JSON in a temporary directory
and rejects every visualizer diagnostic.
- CONTRIBUTING.md: setup, generation, and verification rules
- ARCHITECTURE.md: package and deployment boundaries
- docs/flow-model.md: Flow resources and transitions
Read AGENTS.md before making changes. Work involving Dex Flows,
Steps, RPCs, Channels, Streams, Timers, retries, or recovery must also follow
the installed Dex App Builder skill.