> ## Documentation Index
> Fetch the complete documentation index at: https://praison.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bot Status Reactions

> Show agent run progress as an emoji reaction on the user's message

<Note>
  Bot platform adapters now ship in the `praisonai-bot` package. `praisonai bot serve` still works exactly as documented here; for a standalone install see [praisonai-bot Migration](/docs/guides/praisonai-bot-migration).
</Note>

Status reactions update an emoji on the user's message to reflect run state — queued, thinking, tool execution, done, or error — and add a **"still working…" ⏳ / "taking longer than expected" ⚠️** signal when a run goes quiet, all without reading reply text.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent
from praisonai.bots import TelegramBot

agent = Agent(name="assistant", instructions="Helpful assistant")
bot = TelegramBot(token="...", agent=agent, status_reactions=True)
bot.start()
```

The user sends a message on Telegram; emoji reactions update through queued, thinking, tool, done, or error states.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    Q[👀 Queued] --> T[🧠 Thinking]
    T --> Tool[🛠️ Tool]
    Tool --> D[✅ Done]
    T --> E[❌ Error]
    Tool --> E
    T -.quiet 20s.-> Soft[⏳ Still working…]
    Tool -.quiet 20s.-> Soft
    Soft -.quiet 60s.-> Hard[⚠️ Taking longer than expected]

    classDef done fill:#10B981,stroke:#7C90A0,color:#fff
    classDef phase fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef stall fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef error fill:#8B0000,stroke:#7C90A0,color:#fff

    class D done
    class Q,T,Tool phase
    class Soft,Hard stall
    class E error
```

## Quick Start

<Steps>
  <Step title="Enable with one flag">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents import Agent
    from praisonai.bots import TelegramBot

    agent = Agent(name="assistant", instructions="Helpful assistant")
    bot = TelegramBot(token="...", agent=agent, status_reactions=True)
    bot.start()
    ```
  </Step>

  <Step title="Customise emoji via dict">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    bot = TelegramBot(
        token="...",
        agent=agent,
        status_reactions={
            "thinking_emoji": "💭",
            "tool_emoji": "⚙️",
            "done_emoji": "🎉",
            "debounce_delay": 1.0,
        },
    )
    ```
  </Step>

  <Step title="Full control with StatusConfig">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonai.bots import TelegramBot, StatusConfig

    bot = TelegramBot(
        token="...",
        agent=agent,
        status_reactions=StatusConfig(
            thinking_emoji="💭",
            immediate_terminal=True,
        ),
    )
    ```
  </Step>
</Steps>

## How It Works

The user sends a message and watches a single emoji on that message move through each run stage.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant User
    participant Agent
    participant StatusManager
    participant Channel

    User->>Agent: Send message
    Agent->>StatusManager: Queued
    StatusManager->>Channel: React ⏳
    Agent->>StatusManager: Thinking
    StatusManager->>Channel: React 🤔
    Agent->>StatusManager: Tool call
    StatusManager->>Channel: React 🔧
    Agent-->>StatusManager: Done
    StatusManager->>Channel: React ✅
    Agent-->>User: Reply
```

## Stall Signals

When the agent falls quiet for too long — a slow LLM or a stuck tool — the same reaction slot switches to ⏳ after `stall_soft_s` (default 20 s) and ⚠️ after `stall_hard_s` (default 60 s), and any real progress clears the signal immediately.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent
from praisonai.bots import TelegramBot

agent = Agent(name="assistant", instructions="Helpful assistant")
bot = TelegramBot(
    token="...",
    agent=agent,
    status_reactions={
        "stall_soft_s": 15,   # ⏳ after 15s of silence
        "stall_hard_s": 45,   # ⚠️ after 45s
    },
)
bot.start()
```

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant Agent
    participant StatusManager
    participant Channel

    Agent->>StatusManager: Tool call
    StatusManager->>Channel: React 🛠️
    Note over StatusManager: quiet 20s
    StatusManager->>Channel: React ⏳
    Note over StatusManager: quiet 60s
    StatusManager->>Channel: React ⚠️
    Agent->>StatusManager: Thinking (progress)
    StatusManager->>Channel: React 🧠
```

## Label Fallback (channels without reactions)

On channels where `capabilities["reactions"]` is `False` — WhatsApp, Email, and Slack in "label" mode — the same phase state machine renders as a single status label the bot edits in place (`queued → thinking… → using a tool… → done`) instead of an emoji reaction, and the adapter picks the mode automatically from the channel's capabilities with no extra config.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph TB
    Phase[Run phase] --> Caps{capabilities.reactions?}
    Caps -->|Yes| React[Set emoji reaction 🛠️]
    Caps -->|No| Label[Edit status label &quot;using a tool…&quot;]

    classDef phase fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef decision fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef react fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef label fill:#10B981,stroke:#7C90A0,color:#fff

    class Phase phase
    class Caps decision
    class React react
    class Label label
```

## Configuration Options

| Option               | Type    | Default | Description                                                                                   |
| -------------------- | ------- | ------- | --------------------------------------------------------------------------------------------- |
| `queued_emoji`       | `str`   | `"⏳"`   | Shown when the run is queued                                                                  |
| `thinking_emoji`     | `str`   | `"🤔"`  | Shown while the LLM is generating                                                             |
| `tool_emoji`         | `str`   | `"🔧"`  | Shown during tool execution                                                                   |
| `done_emoji`         | `str`   | `"✅"`   | Terminal: success                                                                             |
| `error_emoji`        | `str`   | `"❌"`   | Terminal: failure                                                                             |
| `debounce_delay`     | `float` | `0.5`   | Seconds before applying intermediate states                                                   |
| `immediate_terminal` | `bool`  | `True`  | Apply done/error immediately                                                                  |
| `stall_soft_s`       | `float` | `20.0`  | Seconds without progress before ⏳ "still working…"                                            |
| `stall_hard_s`       | `float` | `60.0`  | Seconds without progress before ⚠️ "taking longer than expected"                              |
| `enabled`            | `bool`  | `False` | Master switch — off by default; the bot adapter opts in when you pass `status_reactions=True` |

<Note>
  Reactions auto-skip on channels where `capabilities["reactions"]` is `False` (WhatsApp, Email). On Slack, Unicode emoji map to Slack `:text_name:` form (e.g. 🤔 → `thinking_face`).
</Note>

<Warning>
  Telegram's reaction API is set-based — `remove_reaction` clears all bot reactions on the message rather than a specific emoji. This is a Telegram API limitation.
</Warning>

## Best Practices

<AccordionGroup>
  <Accordion title="Keep debounce_delay at 0.3s or higher on shared channels">
    Avoids hitting reaction rate limits on busy Telegram groups.
  </Accordion>

  <Accordion title="Use distinct emoji for tool vs thinking">
    Helps users tell when an external API call is in progress.
  </Accordion>

  <Accordion title="Leave immediate_terminal enabled">
    Users see done/error states instantly without debounce delay.
  </Accordion>

  <Accordion title="Tune stall thresholds to your longest reasonable tool call">
    If a legitimate tool takes 40 s (web scraping, image generation), raise `stall_soft_s` to 45–60 s so users don't see ⏳ while everything is still healthy.
  </Accordion>

  <Accordion title="Trust the automatic fallback on Email / WhatsApp">
    Reactions silently degrade to a status label edit — no per-channel code required.
  </Accordion>

  <Accordion title="Custom integrators: use RunStatusController directly">
    See [Run Status Controller](/docs/features/bot-run-status-controller) for the low-level API.
  </Accordion>
</AccordionGroup>

## Related

<CardGroup cols={3}>
  <Card title="Channel Capabilities" icon="list-check" href="/docs/features/channel-capabilities">
    Which channels support reactions
  </Card>

  <Card title="Typing Indicators" icon="keyboard" href="/docs/features/bot-typing-indicators">
    Complementary typing feedback
  </Card>

  <Card title="Streaming Replies" icon="bolt" href="/docs/features/bot-streaming-replies">
    Live token-by-token responses
  </Card>
</CardGroup>
