A customer writes: "I used SAVE10 and got charged $106.38. That's way more than 10% off a $100 order?"
In most teams, that message starts a relay race. Someone reads it in chat, pastes it into a coding agent, copies the diagnosis into a doc, asks another tool to draft a reply, then pastes everything back. Every handoff loses context, and nobody can see where the case stands.
For the Flip the Switch hackathon I built Escalation Room: three AI agents and one person working the whole case in a Telegram chat, with nothing shipped until the person says so.
🎥 Demo: https://youtu.be/2IY_HKrFonw 💻 Repo: https://github.com/Olacode01/escalation-room
The team
Who What they do
Intake agent Numbers every customer message, classifies it (bug, billing, question), answers from the support policy, escalates bugs
Engineer agent (Claude Code) Clones the shop repo, writes a failing test that reproduces the customer's problem, finds the cause, fixes it on a branch
Comms agent Works out what the customer is owed under the policy and drafts the reply
Me Types APPROVED #1. Only then is the fix merged and the reply sent
They work across two Telegram groups: acme-support, where customers post, and acme-war-room, a private group where diffs, diagnosis and draft replies stay out of the customer's sight.
What Switch does here
Switch is open-source infrastructure for putting AI agents into team chat. Each chat becomes a room: a shared log every person and agent reads from. Switch doesn't ship agents or models. You bring your own (I used Claude Code), and Switch connects them to the chat.
Three Switch features carry the whole workflow:
Rooms are the shared context. The engineer sees the customer's exact words because it's in the same room history. No copy-paste.
Mentions are the routing. A Switch agent only acts when someone @-mentions it. At first that surprised me, then it became the design. The escalation protocol is just who gets mentioned when:
ESCALATION #1 (intake → @acme-engineer)
FIX READY #1 (engineer → @acme-comms)
DRAFT REPLY #1 (comms → me)
APPROVED #1 (me → @acme-engineer @acme-comms)
- Addressing rules are the guardrail. Intake is addressing: anyone, so customers can reach it. The engineer and comms are owner-agents: only I and my other agents can instruct them. A customer can't tell the engineer to merge something.
The whole team is one YAML file
Switch templates describe agents, rooms and their instructions in one document, and Switch Console turns it into a form. Here's the shape of mine (trimmed):
yaml
agents:
- name: "{team}-intake" addressing: anyone provider: "{provider}" # claude, codex or opencode instructions: | For every new customer message: give it the next case number, classify it, answer from the policy or escalate... join: ["{support_room}", "{war_room}"]
- name: "{team}-engineer" addressing: owner-agents repo: "{shop_repo}" instructions: | Reproduce it with a failing test. Never report a result you did not run. Do not merge. Wait for "APPROVED #n"... join: ["{war_room}"]
Anyone can import it, type a team name, pick two groups and get the same team. Switch's template linter also caught a real mistake in my first draft (a list default on a user param) before anything ran.
The demo shop has real bugs
The engineer needs something to fix, so the repo includes a tiny Python checkout with two planted bugs that overcharge customers:
The SAVE10 coupon only discounts the first line item (a $100 order gets $1.50 off instead of $10)
Orders of exactly $75 still pay shipping (> instead of >=)
The existing tests pass anyway, so the engineer has to write a test that catches the customer's case before it can claim a fix.
What I learned
Telegram bots can't create chats. My first template created two rooms, which works on Slack, Discord or Mattermost but not Telegram. The fix was a Telegram edition that uses room params and join: so the agents join groups I made first. The repo has both.
Link your chat account. Agents set to answer only their owner can't recognise you until you link your Telegram account in Switch Console.
Setting up the chat app was the slowest part. The built-in Mattermost needs Docker, and Telegram needs Group Privacy turned off before the bot joins a group.
Keep the human gate in chat. Approving by typing one message, from anywhere, is what makes it feel like a teammate rather than a pipeline.
What's next
A billing agent with read-only Stripe access, so approved refunds are actually issued
An approver role so any on-call person can sign off
A weekly summary of the case log
If you want to try it, the README walks through the Telegram setup in about 15 minutes.
Built for the Flip the Switch hackathon. #HowISwitch
Top comments (0)