Server
Environment
Configuration comes from environment variables. Only DATABASE_URL is required; basic auth, LiveKit Bearer auth, and S3 are opt-in and enable themselves when both vars in their pair are set.
| Prop | Type | Default | Description |
|---|---|---|---|
DATABASE_URLrequired | | — | Postgres connection string. Example: postgres://user:password@localhost:5432/agent_observability |
PORT | | 9090 | HTTP port the server listens on. |
AUTO_MIGRATE | | true | Run SQL migrations in migrations/ on startup. Set to false if you manage migrations externally (e.g. goose). |
AGENT_OBSERVABILITY_USER | | — | Basic-auth username. Paired with _PASS. |
AGENT_OBSERVABILITY_PASS | | — | Basic-auth password. When both user + pass are set, the dashboard API (/api/*) and the eval ingest route are gated; native ingest routes accept Basic credentials too (or a LiveKit Bearer JWT — see below). |
LIVEKIT_API_KEY | | — | LiveKit JWT issuer claim. Paired with _SECRET. |
LIVEKIT_API_SECRET | | — | LiveKit JWT HS256 signing secret. When both LIVEKIT_API_KEY and _SECRET are set, native ingest routes (recordings, OTLP) accept Bearer JWTs minted with this pair (payload must carry observability.write === true). Use the same pair the LiveKit SDK signs with on the agent side. |
ALERT_SWEEPER | | inline | Where the alert sweeper runs. inline = inside the API process (zero-config single-container default). Set to off when the dedicated worker (bun run start:worker) is deployed, so exactly one sweeper is active. |
GOAL_ANALYZER | | inline | Where the conversation-goal analyzer runs. Mirrors ALERT_SWEEPER: inline on the API by default, off when the dedicated worker is deployed. Regardless of placement, the analyzer is a no-op until OPENAI_API_KEY is set. |
OPENAI_API_KEY | | — | Enables the conversation-goal analyzer. Unset = goal tags are stored but never judged (one startup log notes the analyzer is disabled). |
JUDGE_LLM_MODEL | | — | Goal-judge model override. Precedence: JUDGE_LLM_MODEL → OPENAI_MODEL → gpt-4.1-mini — the same contract as the Python SDK judge helper. |
OPENAI_MODEL | | — | Fallback judge model name when JUDGE_LLM_MODEL is unset. |
S3_BUCKET | | — | Target bucket for uploaded audio recordings. S3 upload is enabled only when the bucket and credentials are all set. |
S3_REGION | | us-east-1 | AWS region for S3_BUCKET. |
S3_ACCESS_KEY_ID | | — | AWS access key ID. |
S3_SECRET_ACCESS_KEY | | — | AWS secret access key. |
S3_ENDPOINT | | — | Custom S3-compatible endpoint (e.g. MinIO). Leave blank for AWS S3. |
S3_PREFIX | | recordings | Object-key prefix for uploaded recordings. |
Quickstart
Run the Agent Observability server. It receives session reports from the agent-transport SDKs, stores them in Postgres, and serves the dashboard UI.
API routes
HTTP surface exposed by the server. The /observability/* routes are inbound (SDKs call them); the /api/* routes power the dashboard and anything else that needs to read back captured data.