[2026-06-16] zulip-router: detailed routing logic — @mention sources, bot vs human, ownership, config.yaml
This commit is contained in:
@@ -27,22 +27,77 @@ Zulip
|
||||
```
|
||||
Zulip Event Queue
|
||||
↓ poll (credentials Eagle из ~/.hermes/config.yaml)
|
||||
[zulip-router] (~/Docker/zulip-router/)
|
||||
├── @Валера / @Valera → POST http://balda-agent-valera-1:8091/zulip/webhook
|
||||
├── @Клавдий / @Klavdiy → POST http://claudio-agent-claudio-1:8092/zulip/webhook
|
||||
└── (default / unknown) → POST http://balda-agent-valera-1:8091/zulip/webhook
|
||||
↕ ownership: stream+topic → bot (TTL 24h, persisted to /data/ownership.json)
|
||||
[zulip-router]
|
||||
│
|
||||
├── @mention бота от человека → POST owner-боту + ownership
|
||||
├── @mention любого бота (включая другого) → ownership, НЕ форвардить
|
||||
├── трейд с ownership → POST owner-боту
|
||||
├── новый тред без @mention → default-боту (из конфига)
|
||||
└── reset / system → только владельцу треда
|
||||
```
|
||||
|
||||
**Ключевое:** credentials — Eagle/Орла (не новый бот). Роутер регистрирует свою event queue (отдельную от очереди Eagle).
|
||||
|
||||
## Правила маршрутизации
|
||||
## Правила маршрутизации (пошагово)
|
||||
|
||||
1. `@Валера` или `@Valera` в тексте → Валера (+ ownership обновляется)
|
||||
2. `@Клавдий` или `@Klavdiy` в тексте → Клавдий (+ ownership обновляется)
|
||||
3. Топик уже у кого-то → туда же (TTL refreshed)
|
||||
4. Новый топик без @mention → Валера (default)
|
||||
5. `reset` без @mention → только владельцу топика
|
||||
Для каждого сообщения из event queue:
|
||||
|
||||
1. **Извлечь @mention** — найти все `@**Name**` в тексте (Zulip-формат). Игнорировать `@**all**` и `@**everyone**`.
|
||||
|
||||
2. **Проверить источник @mention:**
|
||||
- Если сообщение от **человека** (sender_id не из списка ботов) и содержит `@**<бот>**`:
|
||||
- Записать этого бота как владельца треда (stream+topic)
|
||||
- FORWARD сообщение этому боту
|
||||
- Если сообщение от **человека** и содержит @mention **другого бота** (из конфига, но не того, что стал бы овнером):
|
||||
- Всё равно записать этого бота как владельца треда
|
||||
- НЕ форвардить (Zulip сам отправит webhook целевому боту по @mention)
|
||||
- Если сообщение от **бота** (из конфига) и содержит @mention другого бота:
|
||||
- Обновить ownership, но НЕ форвардить (Zulip сам доставит)
|
||||
|
||||
3. **Нет @mention, но тред уже закреплён за ботом:**
|
||||
- FORWARD владельцу треда
|
||||
|
||||
4. **Новый тред без @mention:**
|
||||
- FORWARD default-боту (из конфига)
|
||||
|
||||
5. **reset / system-команды без @mention:**
|
||||
- FORWARD только владельцу треда
|
||||
|
||||
### Важный нюанс: @mention от другого бота
|
||||
|
||||
Когда один бот пишет `@Валера` (например, Eagle), Zulip отправляет outgoing webhook Валере напрямую — роутер не должен дублировать это сообщение. Поэтому:
|
||||
|
||||
- Роутер **ставит ownership**, но **не форвардит** если в сообщении есть @mention любого бота из его конфига
|
||||
- Целевой бот получит сообщение через свой собственный outgoing webhook от Zulip
|
||||
|
||||
## Конфиг роутера (`~/Docker/zulip-router/config.yaml`)
|
||||
|
||||
```yaml
|
||||
zulip:
|
||||
bot_email: "eagle-bot@zulip.qentra.top"
|
||||
api_key: "${ZULIP_API_KEY}"
|
||||
server_url: "https://zulip.qentra.top"
|
||||
|
||||
bots:
|
||||
- name: "Валера"
|
||||
aliases: ["Valera"]
|
||||
webhook: "http://balda-agent-valera-1:8091/zulip/webhook"
|
||||
- name: "Клавдий"
|
||||
aliases: ["Klavdiy"]
|
||||
webhook: "http://claudio-agent-claudio-1:8092/zulip/webhook"
|
||||
|
||||
# bot_ids — sender_id ботов в Zulip (чтобы отличать сообщения человека от бота)
|
||||
bot_ids:
|
||||
- 8 # Eagle / Орёл (Hermes)
|
||||
- 9 # Валера
|
||||
- 10 # Клавдий
|
||||
|
||||
default_bot: "Валера"
|
||||
|
||||
ownership:
|
||||
ttl: 24h
|
||||
persist_path: "/data/ownership.json"
|
||||
```
|
||||
|
||||
## Что меняется в balda
|
||||
|
||||
@@ -54,7 +109,7 @@ zulip:
|
||||
enabled: false
|
||||
```
|
||||
|
||||
Сообщения приходят **только через webhook** от роутера.
|
||||
Сообщения приходят **только через webhook** от роутера (плюс outgoing webhook от Zulip при @mention напрямую).
|
||||
|
||||
## Код
|
||||
|
||||
@@ -74,6 +129,8 @@ zulip:
|
||||
|
||||
**Compose:** `~/Docker/zulip-router/docker-compose.yaml`
|
||||
|
||||
**Сеть:** `balda_default` (external) — чтобы видеть balda-agent-valera-1 и claudio-agent-claudio-1 по Docker DNS.
|
||||
|
||||
### Credentials: Eagle, не новый бот
|
||||
|
||||
Роутер использует credentials Eagle/Орла из `~/.hermes/config.yaml` → `platforms.zulip`.
|
||||
@@ -86,12 +143,7 @@ zulip:
|
||||
|
||||
```env
|
||||
# Credentials Eagle/Орла — из ~/.hermes/config.yaml
|
||||
ZULIP_BOT_EMAIL=eagle-bot@zulip.qentra.top
|
||||
ZULIP_API_KEY=<скопировать из конфига Eagle>
|
||||
|
||||
# Куда форвардить (Docker DNS, сеть balda_default)
|
||||
VALERA_WEBHOOK=http://balda-agent-valera-1:8091/zulip/webhook
|
||||
CLAUDIO_WEBHOOK=http://claudio-agent-claudio-1:8092/zulip/webhook
|
||||
```
|
||||
|
||||
### Запуск
|
||||
@@ -109,6 +161,7 @@ docker logs zulip-router --tail 20 # проверить poll loop
|
||||
- [ ] Набить `.env` с credentials Eagle (из `~/.hermes/config.yaml`)
|
||||
- [ ] `docker-compose up -d`
|
||||
- [ ] Проверить логи: `docker logs zulip-router --tail 50`
|
||||
- [ ] Протестировать: @Клавдий и @Валера в разных топиках
|
||||
- [ ] Протестировать: @Клавдий и @Валера в разных топиках (человеком)
|
||||
- [ ] Проверить ownership: сообщение в топик без @mention → последний бот
|
||||
- [ ] Проверить @mention бота от другого бота → ownership ставится, дубляж нет
|
||||
- [ ] Удалить `extractOtherMention()` патч из кода (больше не нужен)
|
||||
|
||||
Reference in New Issue
Block a user