DEMO VIDEO: https://www.loom.com/share/7eca7385078c43e0914508d255dd8f17

Inspiration

On-call at 3am is a ritual nobody wants. An alert fires, someone drags themselves out of bed, reads a stack trace, hunts for a fix, tests it, opens a PR, and waits for review. Most of that work is mechanical: read the error, find the offending file, write the code, run the tests. The engineer is only needed for one thing: deciding whether to ship the fix.

VoiceSRE automates the mechanical parts so the engineer only wakes up for the decision. And they make that decision by speaking two words into their phone instead of opening a laptop.

## What it does

VoiceSRE is an autonomous AI SRE that runs the full incident response loop:

  1. Listens for production incidents via Sentry webhooks and CI failures via GitHub Actions webhooks.
  2. Feeds the stack trace to an LLM that diagnoses the root cause and generates a git patch.
  3. Spins up a Daytona cloud sandbox, clones the repo, applies the patch, and runs the test suite to confirm the fix doesn't break anything.
  4. Scores the patch on three axes: functional correctness (did tests pass), security (no hardcoded secrets), and code cleanliness (diff size).
  5. Opens a GitHub PR right away so the code is ready.
  6. Calls the on-call engineer through ElevenLabs + Twilio and reads the root cause and confidence score. The engineer says "approve" or "reject" and hangs up.
  7. Broadcasts a Discord notification with the PR link.

A live Next.js dashboard shows every incident moving through the pipeline with a terminal-style log stream, eval scorecards, and a CopilotKit sidebar for asking questions about incidents in progress.

## How we built it

The frontend is Next.js 16 (App Router, React 19, TypeScript) styled with Tailwind. Incidents stream to the dashboard over Server-Sent Events from an in-memory store. A CopilotKit sidebar wired to the same Fireworks LLM lets operators query the system in natural language.

Six service modules plug into a shared pipeline orchestrator:

  • Fireworks AI (Llama 3.3 70B) builds a structured diagnosis and unified diff from the stack trace.
  • Daytona spins up an ephemeral cloud sandbox, clones the repo, applies the patch, and runs pnpm test.
  • Braintrust evaluates the patch with three deterministic scorers: test pass/fail for function, a regex for secrets in the diff, and a line-count heuristic for cleanliness. The overall confidence is a weighted blend.
  • ElevenLabs + Twilio run the voice call. The ElevenLabs Conversational AI agent reads the summary and listens for approval or rejection. The transcript hits a Next.js webhook that classifies the response and updates the pipeline.
  • Octokit creates a GitHub branch and PR from the patch, then fires a Discord webhook.
  • A standalone Fastify bridge (bridge/server.mjs) handles the Twilio Media Streams <-> ElevenLabs WebSocket relay because Next.js can't do raw WebSocket upgrades.

The whole pipeline runs end-to-end in under two minutes. Most of the pipeline is covered by pure-function unit tests that don't touch any API.

Challenges we ran into

The biggest one was the phone call loop. Twilio Media Streams gives you raw audio packets over WebSocket, and ElevenLabs Conversational AI expects a signed WebSocket on the other end. Next.js App Router can't upgrade a request to WebSocket, so we had to run a separate Fastify process just as a relay bridge. Getting the bidirectional streaming right and mapping the end-of-call transcript back to the right incident ID took a few late nights.

Sentry webhooks don't carry a repository URL. The Sentry payload tells you what crashed but not where the code lives. We had to add a DEFAULT_REPO_URL fallback and flag it clearly in the dashboard.

Patch generation is inherently flaky. The LLM sometimes produces a diff that won't apply cleanly, or it patches the wrong file, or it hallucinates a fix. We added the sandbox test step as a fast feedback loop: if the tests pass, the patch is at least syntactically valid. But catching semantic errors before the PR hits a human reviewer is still an open problem.

Accomplishments that we're proud of

The pipeline works. From webhook receipt to a PR sitting on GitHub with a phone call in progress, the whole thing runs without human touch. During the demo we triggered a real Sentry alert, watched it stream through the dashboard, and thirty seconds later my phone rang with an AI voice reading the root cause.

The evaluator scorers are 100% deterministic and testable offline. We didn't want "vibes-based" safety scores, so we built them as pure functions: a regex catches hardcoded API keys, a line-count heuristic penalizes monster diffs, and test pass/fail gate function. Braintrust telemetry logs are best-effort and never block the pipeline.

The dashboard is genuinely fun to watch. Incidents fade in, status badges cycle through the pipeline, logs scroll in a terminal font, and eval scores pop up as colored cards. It feels like a real command center, not just a polished demo.

What we learned

Voice UX is harder than it looks. The ElevenLabs agent prompt has to be tight: state the incident, give the confidence, and ask for a decision. If the prompt is too long or wordy, the AI agent drifts into small talk and the call drags on. We iterated through four versions of the prompt before landing on something that felt natural and stayed under 30 seconds.

Sandboxes are the right abstraction for testing AI-generated code. Daytona lets us spin up an isolated environment, run the full test suite, and tear it down, all in about 20 seconds. That's fast enough to be a real gate in the pipeline rather than a retrospective check.

A universal incident ingestion format matters. Sentry and GitHub Actions have totally different payload shapes, but once we mapped both to IncidentPayload, the rest of the pipeline didn't care where the incident came from. Every new source just needs a normalizer function and a webhook route.

What's next for VoiceSRE

The obvious next step is closing the loop: when the sandbox tests pass and the engineer approves, automatically merge the PR. Right now we open the PR and notify, but a human still has to click merge. We'd add a CodeRabbit review as a final gate before auto-merge.

Multi-language support. The pipeline currently works for Node/TypeScript repos because the sandbox runs pnpm test. Adding Python, Go, and Rust just means detecting the project language and running the right test command in the sandbox.

Learning from rejections. When an engineer says "reject," we should feed that back so the patching LLM gets better over time. A fine-tuning loop on rejected vs. approved patches would close a lot of the semantic correctness gap.

A Slack integration and a PagerDuty escalation path so teams can plug VoiceSRE into their existing on-call rotation without changing workflows.

Built With

  • braintrust
  • coderabbit
  • copilotkit
  • daytona
  • elevenlabs
  • fireworksai
  • nextjs
Share this project:

Updates