# Hermes Chatto Plugin

A [Chatto](https://github.com/chattocorp/chatto) platform adapter plugin for [Hermes Agent](https://github.com/NousResearch/hermes-agent). Connects your self-hosted Chatto server to Hermes so you can interact with the agent through chat rooms and DMs.

## Install

```bash
hermes plugins install jrimmer/hermes-chatto-plugin
```

Or with the full URL:

```bash
hermes plugins install https://github.com/jrimmer/hermes-chatto-plugin.git
```

Then add your Chatto credentials to `~/.hermes/.env`:

```bash
CHATTO_URL=https://chat.example.com
CHATTO_LOGIN=max
CHATTO_PASSWORD=your-password
CHATTO_HOME_CHANNEL=REljMv5Pgolo6Y9
```

Enable the plugin (if not auto-enabled during install):

```bash
hermes plugins enable chatto-platform
```

Restart the gateway:

```bash
hermes gateway restart
```

## Configuration

### Environment Variables

| Variable | Required | Description |
|----------|----------|-------------|
| `CHATTO_URL` | Yes | Base URL of your Chatto server |
| `CHATTO_LOGIN` | Yes | Chatto username |
| `CHATTO_PASSWORD` | Yes | Chatto password |
| `CHATTO_HOME_CHANNEL` | No | **Cron-Job-Zielkanal**: Legt den Standard-Raum fest, in den geplante Cron-Jobs (z. B. „tägliche Nachricht um 9 Uhr“) ihre Ergebnisse ausliefern. Wenn nicht gesetzt, nimmt der Bot die erste Room-ID, in der er gelistet ist. Beispiel: `CHATTO_HOME_CHANNEL=RbmwiHk4vs9a3Ql` |
| `CHATTO_CHANNELS` | No | Comma-separated room IDs to watch (default: all joined rooms) |
| `CHATTO_REQUIRE_MENTION` | No | Only respond to @mentions in rooms (default: true). DMs always respond. |
| `CHATTO_AUTO_THREAD` | No | Auto-create threads for replies in rooms (default: true) |
| `CHATTO_FREE_RESPONSE_CHANNELS` | No | Comma-separated room IDs where bot responds without being tagged |
| `CHATTO_ALLOWED_USERS` | No | Comma-separated Chatto logins allowed to talk to the bot |
| `CHATTO_ALLOW_ALL_USERS` | No | Allow any Chatto user to talk to the bot (true/false) |

### YAML Config (optional)

You can also configure via `~/.hermes/config.yaml` instead of env vars:

```yaml
gateway:
  platforms:
    chatto:
      enabled: true
      extra:
        url: https://chat.example.com
        require_mention: true
        home_channel: REljMv5Pgolo6Y9
        free_response_channels: []
```

## Features

- **Realtime via chattolib** — uses the chattolib library for WebSocket realtime connections
- **ConnectRPC via chattolib** — uses chattolib's high-level API for all outbound operations over ConnectRPC
- **Thread support** — `GetThreadEvents` for thread replies, auto-thread creation, proper `threadRootEventId` handling
- **DM support** — DMs always get a response, no threading in DM rooms
- **Mention filtering** — `require_mention` (default true) with `free_response_channels` for no-tag rooms
- **Dynamic room discovery** — auto-joins new rooms without gateway restart (watches `room_created` / `user_joined_room` events)
- **Event handling** — `message_posted`, `mention_notification`, `new_dm_notification`, `session_terminated` (force reconnect), `message_retracted`, `user_left_room`
- **Presence broadcasting** — periodic presence refresh
- **Standalone cron delivery** — works outside the gateway process

## How It Works

The adapter uses the chattolib library to connect to Chatto, which handles both WebSocket realtime connections for inbound events and ConnectRPC over HTTP for outbound operations.

When a message is received, chattolib processes the event, the message is dispatched to the Hermes agent, and the response is sent back via chattolib's messaging API with proper threading.

## Tested Against

Chatto v0.4.19 with chattolib >=0.4.19.

## License

MIT — see [LICENSE](LICENSE).
