[2026-06-17] hermes-eagle-mac.md: rewrite — schema, plugin setup, zulip-router history
This commit is contained in:
@@ -1,19 +1,3 @@
|
||||
---
|
||||
title: Hermes на Eagle (Mac M4 Max) — Настройка и подводные камни
|
||||
type: reference
|
||||
namespace: work
|
||||
tags:
|
||||
- hermes
|
||||
- mac
|
||||
- eagle
|
||||
- claude-proxy
|
||||
- zulip
|
||||
- pitfalls
|
||||
created: '2026-05-21'
|
||||
updated: '2026-05-22'
|
||||
last_synced: '2026-05-22'
|
||||
confidence: 0.9
|
||||
---
|
||||
# Hermes на Eagle (Mac M4 Max) — Настройка и подводные камни
|
||||
|
||||
Hermes работает нативно (не в Docker) на Mac через `hermes gateway`.
|
||||
@@ -225,10 +209,6 @@ Claude падает с "Failed to spawn process". Проверить логи:
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## Схема маршрутизации сообщений
|
||||
|
||||
```
|
||||
@@ -257,14 +237,10 @@ Zulip Events API
|
||||
credentials Eagle для поллинга Zulip Events API, но Eagle сам в Zulip
|
||||
не поллит.
|
||||
|
||||
### Что не так (проблема trigger=owner)
|
||||
### Что не так
|
||||
|
||||
Роутер после установки ownership шлёт ВСЕ сообщения из треда владельцу,
|
||||
даже если @mention адресован другому боту. Пример:
|
||||
|
||||
1. Пользователь пишет `@Валера привет` → ownership = Валера
|
||||
2. Пользователь пишет `@Кит а как там` → роутер всё ещё шлёт Валере
|
||||
(trigger=owner), хотя @mention адресован Киту
|
||||
даже если @mention адресован другому боту.
|
||||
|
||||
**Должно быть:** если @mention другого бота — ownership обновляется,
|
||||
НО НЕ форвардить. Бот получит сообщение через свой outgoing webhook
|
||||
@@ -272,129 +248,14 @@ credentials Eagle для поллинга Zulip Events API, но Eagle сам в
|
||||
|
||||
---
|
||||
|
||||
## План работ: Eagle и Whale (2026-06-17)
|
||||
## Настройка Eagle через zulip-router (2026-06-17)
|
||||
|
||||
### Текущее состояние
|
||||
|
||||
Eagle и Кит (Whale) — два отдельных gateway на одном Mac.
|
||||
У каждого свой конфиг:
|
||||
|
||||
| Компонент | Конфиг | Порт webhook |
|
||||
|-----------|--------|-------------|
|
||||
| **Eagle** | `~/.hermes/config.yaml` | 8645 |
|
||||
| **Кит (Whale)** | `~/.hermes/hermes-whale/config.yaml` | 8645 (надо сменить) |
|
||||
|
||||
**Проблема:** оба настроены на порт 8645. Кто первый стартанул — тот на 8645,
|
||||
второй берёт следующий свободный (8644). Сейчас Кит сидит на 8645, Eagle на 8644.
|
||||
|
||||
**Надо:** Eagle → 8645, Кит → 8646.
|
||||
|
||||
### Шаг 1. Сменить порт Кита
|
||||
|
||||
Файл: `~/.hermes/hermes-whale/config.yaml`
|
||||
|
||||
Поменять порт webhook с 8645 на 8646:
|
||||
|
||||
```yaml
|
||||
platforms:
|
||||
webhook:
|
||||
extra:
|
||||
port: 8646 # было 8645
|
||||
```
|
||||
|
||||
### Шаг 2. Убить второй gateway (PID 96351)
|
||||
|
||||
Это дубль — запущен руками из того же конфига, сидит на 8644:
|
||||
|
||||
```bash
|
||||
kill 96351
|
||||
```
|
||||
|
||||
PID актуальный — проверить перед kill.
|
||||
|
||||
### Шаг 3. Перезапустить Eagle на 8645
|
||||
|
||||
Через Eagle Dashboard (или `launchctl kickstart ai.hermes.gateway` — только
|
||||
по явной команде).
|
||||
|
||||
### Шаг 4. Проверить
|
||||
|
||||
1. `curl -s http://127.0.0.1:8645` → 200 (Eagle жив)
|
||||
2. `curl -s -X POST http://127.0.0.1:8645/webhooks/eagle -d '{"message":"test"}'`
|
||||
→ 202 Accepted
|
||||
3. `@**Орёл**` в Zulip → Eagle отвечает
|
||||
4. Роутер шлёт на `host.docker.internal:8645/webhooks/eagle` — проверить логи
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
### Шаг 5. Поправить роутер — route `/webhooks/whale`
|
||||
|
||||
В конфиге роутера (`~/Docker/zulip-router/config.yaml`) добавить бота `Кит`
|
||||
с webhook на новый порт (8646):
|
||||
|
||||
```yaml
|
||||
bots:
|
||||
- name: "Кит"
|
||||
aliases: ["Whale", "whale", "кит"]
|
||||
webhook: "http://host.docker.internal:8646/webhooks/whale"
|
||||
```
|
||||
|
||||
### Шаг 6. Проверить @mention всех ботов
|
||||
|
||||
- `@**Орёл**` → Eagle отвечает
|
||||
- `@**Кит**` → Кит отвечает
|
||||
- `@**Валера**` → Валера отвечает (через роутер)
|
||||
- `@**Клавдий**` → Клавдий отвечает (через роутер)
|
||||
|
||||
### Шаг 7. Обновить доку zulip-router.md
|
||||
|
||||
Записать:
|
||||
- Актуальную схему роутинга с портами
|
||||
- Статус TODO (проверено/не проверено)
|
||||
- Проблему с trigger=owner
|
||||
|
||||
---
|
||||
|
||||
## Что сделано по zulip-router (история)
|
||||
|
||||
### 2026-06-16 — деплой zulip-router
|
||||
|
||||
- Написан код роутера (`~/Developer/zulip-router/`, Go, ~260 LOC)
|
||||
- Создан compose (`~/Docker/zulip-router/docker-compose.yaml`)
|
||||
- Сеть `balda_default` (external) — чтобы видел balda-контейнеры
|
||||
- `.env` с API key Eagle (`eagle-bot@zulip.qentra.top`)
|
||||
- `docker-compose up -d` — запущен
|
||||
- Events API polling отключён у обоих balda-ботов (`events_polling.enabled: false`)
|
||||
|
||||
### 2026-06-17 — отладка
|
||||
|
||||
- Eagle добавлен в конфиг роутера как бот, webhook на `:8644`
|
||||
- Кит добавлен в конфиг роутера как бот, webhook на `:8644`
|
||||
- Выяснено: роутер форвардит все сообщения из треда с ownership,
|
||||
даже если @mention адресован другому боту (проблема trigger=owner)
|
||||
- Актуальный код роутера в контейнере не совпадает с кодом в репе
|
||||
|
||||
### Статус проблем
|
||||
|
||||
- [ ] **trigger=owner** — роутер не фильтрует @mention другого бота.
|
||||
Должен: если @mention другого бота — ownership ставится, но НЕ форвардить.
|
||||
- [ ] **Код в репе vs контейнере** — рассинхронизация.
|
||||
Надо синхронизировать: `~/Developer/zulip-router/` → контейнер.
|
||||
|
||||
---
|
||||
|
||||
## Связанные страницы
|
||||
|
||||
Eagle использует webhook platform для приёма сообщений от zulip-router.
|
||||
Напрямую в Zulip через Events API Eagle **не подписан** — все сообщения
|
||||
приходят через роутер.
|
||||
|
||||
### Конфигурация
|
||||
|
||||
`~/.hermes/config.yaml` (секция `platforms`):
|
||||
Напрямую в Zulip через Events API Eagle не подписан.
|
||||
|
||||
**Конфиг Eagle:** `~/.hermes/config.yaml`
|
||||
```yaml
|
||||
platforms:
|
||||
webhook:
|
||||
@@ -409,44 +270,37 @@ platforms:
|
||||
deliver: zulip
|
||||
```
|
||||
|
||||
### Порт 8645
|
||||
**Проблема:** Eagle не отвечает на `@**Орёл**`. Роутер шлёт на `:8644`,
|
||||
Eagle слушает на `:8645`. Второй gateway (PID 96351) запущен вручную,
|
||||
занял порт 8644.
|
||||
|
||||
Eagle слушает webhook на **127.0.0.1:8645**. Это **единственный** порт Eagle.
|
||||
### План
|
||||
|
||||
### Схема работы
|
||||
1. **Сменить порт Кита** — в `~/.hermes/hermes-whale/config.yaml` сменить
|
||||
webhook порт с 8645 на 8646, чтобы освободить 8645 для Eagle
|
||||
2. **Убить дубль** — `kill 96351`
|
||||
3. **Перезапустить Eagle** — `launchctl kickstart ai.hermes.gateway`
|
||||
(Eagle встанет на 8645, так как порт свободен)
|
||||
4. **Проверить** — curl, потом `@**Орёл**`
|
||||
|
||||
```
|
||||
Zulip
|
||||
└── Events API → [zulip-router] (Go, Docker)
|
||||
├── @Валера → POST balda-agent:8091
|
||||
├── @Клавдий → POST claudio-agent:8092
|
||||
└── @Орёл / @Кит → POST host.docker.internal:8645/webhooks/{eagle,whale}
|
||||
```
|
||||
### Что сделано по zulip-router
|
||||
|
||||
- Роутер использует credentials Eagle (`eagle-bot@zulip.qentra.top`)
|
||||
- Eagle принимает сообщения **только через webhook** — не через Zulip поллинг
|
||||
- `@**Орёл**` в Zulip → роутер подхватывает → POST `/webhooks/eagle` → Eagle отвечает
|
||||
**2026-06-16 — деплой:**
|
||||
- Написан код роутера (`~/Developer/zulip-router/`, Go, ~260 LOC)
|
||||
- Создан compose (`~/Docker/zulip-router/docker-compose.yaml`)
|
||||
- `.env` с API key Eagle
|
||||
- Запущен, Events API polling отключён у balda-ботов
|
||||
|
||||
### Проблема (2026-06-17)
|
||||
**2026-06-17 — отладка:**
|
||||
- Eagle добавлен в роутер (webhook на `:8644`)
|
||||
- Кит добавлен в роутер (webhook на `:8644`)
|
||||
- Обнаружена проблема trigger=owner
|
||||
- Конфиг Eagle исправлен: порт 8645, webhook route `eagle`
|
||||
|
||||
Eagle не отвечал на `@**Орёл**`. Причины:
|
||||
### Статус проблем
|
||||
|
||||
1. **Второй gateway (PID 96351)** был запущен вручную из того же `~/.hermes/` и
|
||||
занял порт 8644, так как 8645 был уже занят Китом (PID 90402).
|
||||
2. Кит (Whale) по ошибке сидел на порту 8645 — порту Eagle.
|
||||
3. Роутер слал на `:8644`, а Eagle ждал на `:8645`.
|
||||
|
||||
**Что сделано:**
|
||||
- Конфиг Eagle приведён к состоянию: порт 8645, webhook с route `eagle`
|
||||
- Второй gateway (PID 96351) — удалить (дубликат)
|
||||
- Кита пересадить на другой порт (не 8645)
|
||||
|
||||
### TODO
|
||||
|
||||
- [ ] Пересадить Кита с 8645 на другой порт (8646?)
|
||||
- [ ] Убить PID 96351 (дубль)
|
||||
- [ ] Перезапустить Eagle на 8645
|
||||
- [ ] Проверить `@**Орёл**` через роутер
|
||||
- [ ] **trigger=owner** — роутер не фильтрует @mention другого бота
|
||||
- [ ] **Код в репе vs контейнере** — рассинхронизация
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user