# Chat & Responses

> Mention an agent in Slack, Discord, Zulip or Telegram and it works in the thread with your team. Alerts can open a conversation by themselves.

Agents can live in your team's chat. Mention Ryph's bot in Slack, Discord, Zulip or Telegram, and an agent picks up the request and works on it right there in the thread. Anyone allowed to can mention it again to steer it, and it answers in the same thread.

An agent in chat can do everything it does anywhere else. It reads and changes code, ships pull requests, opens issues, runs checks, publishes artifacts, posts screenshots from its [browser](https://ryph.ai/docs/browser.md), shares [previews](https://ryph.ai/docs/previews.md) of your app and uses its tools.

One Slack thread, from the mention that starts a run to Ryph’s closing line:

- **Sam:** @ryph ada why do EU customers see prices in USD since this morning? — A mention starts a run.
- **Ryph:** Ada is on it. Mention @ryph in this thread to reach it. — Ryph ties the thread to the run.
- **Ryph:** [Ada] Found it. The currency middleware reads the country from a header the CDN stopped sending yesterday, so everyone falls back to USD. *(with a screenshot: Checkout, opened from Berlin)* — The agent posts as the bot, signed with its name.
- **Priya:** @ryph fix it, and open an issue for the CDN config — A teammate steers the same run.
- **Ryph:** [Ada] Opened PR #214 with a fallback to the billing address, and issue #88 for the CDN header. — Patches and issues, as anywhere else.
- **Jo:** @ryph thanks! can you write up the fix as a page for the incident review? — Anyone allowed can ask for more.
- **Ryph:** [Ada] Here it is: “EU prices shown in USD, Oct 14”. It covers the cause, the fix in PR #214 and what to change in the CDN. *(links an artifact: EU prices shown in USD, Oct 14)* — It publishes an artifact and links it.
- **Ryph:** Ada finished. Patch: PR #214. Issues: #88. Run r-7f3a. — Ryph closes the thread with where the work went.

The thread is the run’s conversation: every mention in it reaches the same run, and the agent answers there. Zulip topics and Telegram groups work the same way.

Conversations can also start without anyone asking. A **response** is an [automation](https://ryph.ai/docs/automations.md) that opens a thread in your channel when something happens, such as an alert firing, and puts an agent in it with your team.

## Summon an agent

Mention the bot and say what you need:

```
@ryph why do EU customers see prices in USD since this morning?
@ryph ada look into the flaky checkout test
```

The first word after the mention can name one of the room's agents. Otherwise the room's default agent takes it. Only a real mention counts, as the chat platform marks it, and messages from bots are ignored. On Telegram, a reply to one of the bot's messages counts as a mention too. On Discord, so does a reply to the bot's opening line at the top of a channel.

Before anything runs, Ryph works through the mention:

1. **May this person ask?**

   Ryph checks the sender against the room's rule, live, on every mention. A sender who isn't allowed gets no answer at all.

2. **Is something already running here?**

   If an agent is already working in this thread, the mention joins that run as a new message. Naming a different agent while one is working is refused until the first one finishes.

3. **Which repository?**

   The channel's target decides: a repository or a workspace, set per channel, with a default for the rest of the room.

4. **Is the channel allowed to see it?**

   A public channel can only start work on public repositories, because everything the agent posts there is public too.

5. **The run starts**

   It runs on behalf of the room's owner, with the sender recorded as the person who asked. Ryph reacts with 👀 on Slack, Discord and Zulip, and posts an opening line in the thread.

## One thread, one run

A run belongs to the conversation it started in: a Slack or Discord thread, a Zulip topic or a Telegram group. Mentions in that conversation reach the run, and the agent answers there.

- **It reads the thread.** The agent gets the conversation so far as quoted context, up to 200 messages, so "look into this" works.
- **It sees your images.** Screenshots attached to a mention reach the agent, up to 10 per message.
- **It posts as the bot.** Every post is signed with the agent's name. Screenshots from its browser go into the thread as images.
- **It stays around.** After it answers, the run waits for the next mention. It ends when the agent finishes, when someone ends it from its page in Ryph, or after a quiet stretch: 5 minutes, or 30 once someone has talked to it. Responses wait longer, as [below](#responses).
- **It closes with a summary.** Ryph's closing line says how the run went and links its pull requests, the issues it opened and the run itself.

Topics get renamed and moved on Zulip, and the agent keeps posting wherever its topic is now.

## Everything an agent can do

A run from chat is an ordinary run of the agent, with the same tools and limits:

- **Code.** It works in its own sandbox and ships [patches](https://ryph.ai/docs/secure-forge-interactions.md). Patches are approved in Ryph, by whoever the repository's policy names.
- **Issues and reviews.** With [forge tools](https://ryph.ai/docs/secure-forge-interactions.md#working-with-issues-and-pull-requests) on, it can open an issue and post the link in the thread. The issue's footer says it was asked for by the sender, in chat.
- **Checks.** It runs the repository's [checks](https://ryph.ai/docs/checks.md) before it ships.
- **Artifacts.** It can publish a [page](https://ryph.ai/docs/artifacts.md) for a longer answer. A later mention in the same thread updates that page.
- **Its tools.** Whatever MCP tools its policy allows, such as your telemetry or your issue tracker.

## Set up a command room

A chat room becomes a **command room** once an admin gives it a chat command. In Ryph, go to **Triggers**, click **New trigger**, and pick the room under **Chat command in**. The same flow opens from the room's menu on the **Chat** page, under **Chat command**.

1. **Agents**

   Tick the agents a mention may name. With more than one, choose the **Default agent** that takes a mention naming none.

2. **Code**

   Under **Repo or workspace**, pick what the room works on by default. Under **Channel targets**, click **Add a channel** to give a channel its own. With no default, only the listed channels are served.

3. **Access**

   Choose who may ask: **Members of a user group** (on Discord, **Everyone with a role**), checked live on every mention, or **Everyone in the room (private channels only)**. Telegram rooms have no groups, so there it's everyone in the group. Set **Runs per hour**, which counts runs started. Mentions that join a running thread don't count.

4. **Review**

   Check it over and click **Create chat command**.

Runs act for the room's owner, so they can only reach repositories the owner can.

> [!WARNING]
> **Public channels publish everything**
>
> Anyone can read what an agent posts in a public channel, so a public channel can only start work on public repositories. Ryph checks the channel's and the repositories' visibility live when a run starts. A Slack channel shared with another organization counts as public. Keep the group allowed to ask small: everyone in it can spend the owner's budget and steer an agent that has a checkout.

## Responses

A response is an [automation](https://ryph.ai/docs/automations.md) whose runs stay open to be talked to. When it fires, Ryph opens a thread in a channel you pick, posts the opening line, and puts the agent in it. Your team steers it by mention, like any chat run.

A response in an incident channel, from the alert firing to the run closing:

- **@IRM:** Firing: CheckoutLatencyHigh. Checkout p99 has been above 1 s for 5 minutes.
- **Responder:** On it. Checkout p99 jumped from 180 ms to 2.4 s at 14:02, a minute after payments-api deploy 4411. *(after calling `telemetry__query_metrics`)*
- **Responder:** Deploy 4411 put the session id into the price cache key, so every request misses. Hit rate is 0%. *(after calling `telemetry__search_logs`)*
- **Sam:** did the same change ship to the storefront?
- **Responder:** No, only payments-api builds that key. I'm writing the fix there.
- **Responder:** Opened PR #412 in payments-api: build the price cache key without the session id.
- **Responder:** PR #412 was merged. Watching checkout latency.
- **@IRM:** Resolved: CheckoutLatencyHigh.
- **Responder:** p99 is back at 190 ms and the hit rate is 96%. I'm done here. *(after calling `telemetry__query_metrics`)*
- **Ryph:** Responder finished: succeeded. payments-api patch: merged.

Responses fit alerts best. Point your alerting at the automation's webhook, and pick what sends it: Grafana, Prometheus Alertmanager, Grafana IRM, PagerDuty, Opsgenie, Sentry, incident.io, Datadog, or a custom format. Ryph reads each alert's status, its title and which alert it is, and can post the alert itself under the opening line, so the room sees what fired without opening anything.

To set one up, go to **Triggers**, click **New trigger** and choose **Webhook or schedule**:

1. **Trigger**

   Under **Starts when**, choose **Another service sends a request**, then pick your tool under **What sends it?**. Ryph fills in how requests are verified for you. **Something else** lets you map a custom payload's fields.

2. **Response**

   Choose what a request does. The wording follows the tool you picked. **Start a run** gives each request a plain run with no conversation. The other options open a conversation, and decide which one a later request joins:

   | Option                       | What happens                                                                   |
   | ---------------------------- | ------------------------------------------------------------------------------ |
   | One conversation per alert   | Requests about the same alert join its thread. Different alerts get their own. |
   | One conversation per request | Every request opens a new thread with a new run.                               |
   | One shared conversation      | While a conversation is open, every request joins it.                          |

   Under **Where it talks**, pick the **Chatroom** and **Channel**, and tick **Post the alert in the first message** if the room should see what came in. **No chatroom, just the run page** keeps the conversation in Ryph. **When it ends** sets how many minutes of quiet the run waits for, before and after someone replies: 30 and 60 by default.

3. **Agent and code**

   Pick the **Agent**, and what it **Checks out**: a repository and branch, or a workspace.

4. **Instructions and review**

   Tell the agent what to do when something comes in, then click **Create automation**.

5. **Connect your tool**

   Ryph shows the URL and values to paste into your tool, step by step. For tools that sign with their own secret, paste it under **Paste the signing secret**. Ryph waits for the first request and links its run.

A fire that says the alert resolved joins its thread, so the agent can check that its fix held, and starts nothing when no thread is open. An update such as "acknowledged" never starts a run.
A response posts into a private channel, since everyone in it can steer the agent and read what it finds. Each response opens a new thread or topic there by default. Tick **Post every response in one topic** (or thread) to keep them all in one place, such as a daily report's.

## Connect a chat platform

In Ryph, go to **Chat**, under Integrations in the sidebar, and click **Add chatroom**. Pick the **Platform**, give the room a **Name**, paste what the platform gave you, and click **Add**.

All four platforms connect outward from Ryph, so none of them need a public URL. That includes Ryph on your laptop.

| Platform | What you need                                                                                                                                                                                                                                                                                                                                                                                      |
| -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Slack    | An app made from [Ryph's manifest](https://github.com/ryph-hq/ryph/blob/main/packages/chat/setup/slack-app-manifest.yml), which uses Socket Mode. Paste its **Bot token** and **App-level token**, and invite the bot to every channel it should serve.                                                                                                                                            |
| Zulip    | A generic bot. Paste the **Organization URL**, **Bot email** and **API key**. It hears mentions in public channels by itself, and needs to be subscribed to private ones. Adding a Zulip room takes an admin.                                                                                                                                                                                      |
| Discord  | An application in the Discord Developer Portal with a bot. On the Bot page, turn on **Message Content Intent** and turn off **Public Bot**, then invite it to your server with View Channels, Send Messages, Send Messages in Threads, Create Public Threads, Read Message History, Add Reactions and Attach Files. Paste its **Bot token** and the **Server ID**. Use one application per server. |
| Telegram | A bot from BotFather with privacy mode turned off, added to your group. Paste its **Bot token**, then mention the bot once in the group with the code the room's row shows under **Where**.                                                                                                                                                                                                        |

Bot tokens are sealed in Ryph's database and never reach a run. If one leaks, replace it on the platform and add the new one as a new room.
