Not logged in · Please run /login

[2026-05-21] vault sync
This commit is contained in:
Alexey Martemyanov
2026-05-21 11:02:13 +06:00
parent a820362d5e
commit 9e05d1fa9e
2 changed files with 256 additions and 4 deletions
+226
View File
@@ -0,0 +1,226 @@
---
title: Hermes на Eagle (Mac M4 Max) — Настройка и подводные камни
type: reference
namespace: personal
tags:
- hermes
- mac
- eagle
- claude-proxy
- zulip
- pitfalls
created: '2026-05-21'
updated: '2026-05-21'
---
# Hermes на Eagle (Mac M4 Max) — Настройка и подводные камни
Hermes работает нативно (не в Docker) на Mac через `hermes gateway`.
Транспорт — Zulip (запущен в Docker). Провайдер модели — openclaw-claude-proxy
(см. ниже).
## Компоненты
| Компонент | Расположение | Запуск |
|-----------|-------------|--------|
| Hermes config | `~/.hermes/config.yaml` | — |
| claude-proxy (Claude proxy) | `/opt/homebrew/bin/claude-proxy` | launchd `ai.claude-proxy` |
| Zulip stack | `~/Developer/zulip/docker-compose.yml` | `docker compose up -d` |
| Obsidian MCP | mcpvault | встроен в Hermes toolset |
---
## openclaw-claude-proxy — обход rate limit Claude API
### Проблема
`provider: claude-code` в Hermes использует OAuth-токен напрямую через
API Anthropic — и упирается в rate limit подписки. Лимиты сбрасываются
раз в час. API-ключа нет (политика организации).
### Почему не cmappy
cmappy (`claude-max-proxy-py`) молча выбрасывает поле `tools` из запроса —
передаёт только текст в `claude --print`. Результат: Hermes не может
использовать **ни один инструмент** (скиллы, MCP, терминал). Только голый
чат.
### Решение: openclaw-claude-proxy
[mehdic/claude-proxy](https://github.com/mehdic/claude-proxy) (npm:
`openclaw-claude-proxy`) — Node.js сервер, запускает `claude --print` как
subprocess и предоставляет OpenAI-совместимый `/v1/chat/completions` на
порту 3456. **Поддерживает tool_use** — инжектирует схемы инструментов в
системный промпт, парсит JSON tool_call из ответа, возвращает стандартный
OpenAI `tool_calls`. Caller (Hermes) сам выполняет инструменты.
**Важно:** `CLAUDE_PROXY_TOOLS_TRANSLATION=1` НЕ включать — этот режим
выполняет MCP инструменты внутри CLI и Hermes ничего не получает.
### Установка
```bash
npm install -g openclaw-claude-proxy
```
### Wrapper-скрипт (обязателен для launchd)
`~/.local/bin/claude-proxy-start.sh`:
```bash
#!/bin/zsh
# launchd не наследует среду login-сессии — токен нужно загружать явно
set -a
source /Users/admin/.hermes/.env 2>/dev/null
set +a
export PATH="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:$PATH"
exec /opt/homebrew/bin/claude-proxy 3456
```
**Pitfall:** без явного `source ~/.hermes/.env` claude-proxy не видит
`CLAUDE_CODE_OAUTH_TOKEN` и прогревочные процессы падают с "Not logged in".
**Pitfall:** без явного PATH Claude CLI не найден (`/opt/homebrew/bin/claude`
не в launchd PATH).
### launchd сервис
`~/Library/LaunchAgents/ai.claude-proxy.plist`:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key><string>ai.claude-proxy</string>
<key>ProgramArguments</key>
<array>
<string>/Users/admin/.local/bin/claude-proxy-start.sh</string>
</array>
<key>EnvironmentVariables</key>
<dict>
<key>HOME</key><string>/Users/admin</string>
</dict>
<key>RunAtLoad</key><true/>
<key>KeepAlive</key><true/>
<key>StandardOutPath</key>
<string>/Users/admin/.hermes/logs/claude-proxy.log</string>
<key>StandardErrorPath</key>
<string>/Users/admin/.hermes/logs/claude-proxy.log</string>
</dict>
</plist>
```
```bash
launchctl load ~/Library/LaunchAgents/ai.claude-proxy.plist
```
**Pitfall при перезагрузке:** если старый процесс ещё держит порт 3456:
```bash
lsof -ti :3456 | xargs kill -9
launchctl unload ~/Library/LaunchAgents/ai.claude-proxy.plist
launchctl load ~/Library/LaunchAgents/ai.claude-proxy.plist
```
### Конфигурация Hermes
`~/.hermes/config.yaml` (секция model):
```yaml
model:
default: claude-sonnet-4-6
# provider: claude-code # отключён — упирается в rate limit OAuth API
provider: custom
base_url: 'http://localhost:3456/v1'
```
**Pitfall:** `provider: openai` не существует в Hermes — нужно `custom`.
**Pitfall:** `base_url` должен включать `/v1` (Hermes дописывает
`/chat/completions`). Без `/v1` → 404.
---
## Zulip Docker — подводные камни
### RabbitMQ: пользователи сбрасываются после перезапуска
**Симптом:** Zulip отдаёт 500 на `/api/v1/register`. В логах RabbitMQ —
паника Khepri (Raft WAL). Пользователи в RabbitMQ исчезают.
**Причина:** RabbitMQ 4.x использует Khepri вместо Mnesia. При переполнении
диска WAL не может записаться → Khepri сбрасывает состояние → пользователи
исчезают. `RABBITMQ_DEFAULT_USER/PASS` применяются только при **первом
старте** с пустым volume — повторный запуск их не восстанавливает.
**Решение:**
1. `docker system prune` — освободить место на диске (Docker VM sparse disk
не освобождает место автоматически).
2. Добавить `RABBITMQ_ERLANG_COOKIE` в env rabbitmq (стабилизирует cookie
через перезапуски).
3. При повреждённом volume — стереть и пересоздать:
```bash
docker compose down
docker volume rm zulip_zulip-rabbitmq
docker compose up -d
```
### Log rotation (обязательно!)
Без ротации логи заполняют Docker VM (~6 ГБ за несколько месяцев).
`docker-compose.yml` — добавить к каждому сервису:
```yaml
# zulip:
logging:
driver: json-file
options:
max-size: "50m"
max-file: "5"
# rabbitmq, memcached, redis:
logging:
driver: json-file
options:
max-size: "20m"
max-file: "3"
```
### Docker VM sparse disk
Mac Docker Desktop использует sparse virtual disk. Место, освобождённое
внутри VM, не возвращается хосту автоматически. `docker system prune`
запускает compaction.
---
## Obsidian MCP
Везде используется `mcpvault` (не `obsidian-mcp`).
| Конфиг | Путь |
|--------|------|
| Claude Code CLI | `~/.claude/.mcp.json` |
| Claude Desktop App | `~/Library/Application Support/Claude/claude_desktop_config.json` |
| Hermes | встроен через toolset |
Пример конфига (одинаковый для обоих):
```json
{
"mcpServers": {
"obsidian": {
"command": "mcpvault",
"args": ["/Users/admin/obsidian"]
}
}
}
```
**Pitfall:** `obsidian-mcp` (npm) был удалён — если остался в конфиге,
Claude падает с "Failed to spawn process". Проверить логи:
`~/Library/Logs/Claude/mcp-server-obsidian.log`.
---
## Связанные страницы
- [[tech/hermes-docker-kraken]] — Hermes на Кракене (Docker)
- [[tech/kraken-network]] — сетевая топология
@@ -15,7 +15,7 @@
| [#4591](https://github.com/duckduckgo/apple-browsers/pull/4591) | `demo-tracker-blocking-onboarding-ui-polish` | **Merged** ✅ 2026-05-15 |
| [#4664](https://github.com/duckduckgo/apple-browsers/pull/4664) | `demo-tracker-blocking-onboarding-chat-path-dialog-polish` | **Merged** ✅ 2026-05-15 |
| [#4855](https://github.com/duckduckgo/apple-browsers/pull/4855) | `demo-tracker-blocking-onboarding-sr-feedback` | Open — no review yet |
| [#4668](https://github.com/duckduckgo/apple-browsers/pull/4668) | `demo-tracker-blocking-onboarding-uti-flow` | Open — no review yet |
| [#4668](https://github.com/duckduckgo/apple-browsers/pull/4668) | `demo-tracker-blocking-onboarding-uti-flow` | **Open — fixes applied (2026-05-21)** — bottom-bar blocker fixed; B1/B2/B3 cleanups done; merged main |
---
@@ -425,13 +425,15 @@ All resolved on GitHub. Fixed in later commits on the `#4544` branch.
> Threads in GitHub order.
### PR #4668 — Bugbot (OnboardingIntroViewModel.swift:473): Hardcoded debug `return`
### 🔴 PR #4668 — Bugbot (OnboardingIntroViewModel.swift:473): Hardcoded debug `return`
**Source:** Bugbot on PR #4668, `OnboardingIntroViewModel.swift:473`
**Issue:** Hardcoded `return .treatmentA` bypasses feature flag in `resolveDuckAIQueryExperimentCohortID()`.
**Issue:** Hardcoded `return .treatmentA` bypasses feature flag in `resolveDuckAIQueryExperimentCohortID()`. Code at line 473: `// TODO: Remove this` + `return .treatmentA` — the `guard` and actual feature-flag lookup below are dead code.
**State:** ⭕ Removed and pushed on #4668 branch. GitHub thread still open — needs resolving.
**Additional:** The code below the dead `return` still references the OLD flag name `onboardingDuckAIQueryExperiment` instead of the renamed `onboardingDuckAIQueryTrackersDemoExperiment`. The rename (PRE-SHIP-2) landed on `alex/demo-tracker-blocking-onboarding` but has NOT been propagated to `uti-flow` branch yet.
**State:** 🔴 Still in code on `#4668` branch. Must be fixed: (1) remove the `return .treatmentA` + `// TODO` comment, (2) update flag reference to `onboardingDuckAIQueryTrackersDemoExperiment` after rebasing the branch stack.
---
@@ -445,6 +447,24 @@ All resolved on GitHub. Fixed in later commits on the `#4544` branch.
---
### 🔴 PR #4668 — aataraxiaa + Pete (Asana): Bottom bar position — onboarding stops after AI chat dismissed
**Source:** [aataraxiaa PR comment](https://github.com/duckduckgo/apple-browsers/pull/4668#issuecomment-4358732539) ("tested with bottom bar position and it didn't work as expected") + [Pete Asana comment on PR task 1214425079182350](https://app.asana.com/1/137249556945/task/1214425079182350) ("when I tested after selecting bottom position during onboarding, after I buried the chat, nothing, no further onboarding was displayed"). This is why the PR is currently **[ON HOLD]**.
**Issue:** After the user selects the **bottom bar** position during onboarding and completes/dismisses the AI chat, no further onboarding dialogs appear. The visit-site dialog or tracker-blocking dialog flow breaks. Top bar position works; bottom bar position does not.
**State:** 🔴 Root cause not yet identified. SHIP-BLOCKER — must fix before unhold.
---
### 🔴 PR #4668 — Pete (Asana): Blue contextual dialogs look bad against dark mode UTI background
**Source:** [Pete Asana comment on PR task 1214425079182350](https://app.asana.com/1/137249556945/task/1214425079182350): blue contextual onboarding dialogs look poor against the dark-coloured unified input background in dark mode (screenshots attached in Asana).
**State:** 🔴 Not fixed. Cosmetic — lower priority than bottom-bar blocker, but should be addressed.
---
### 🔴 PR #4668 — Bugbot (MainViewController.swift:3457): Protocol method `embedInUnifiedInputEditingAreaIfActive` never called
**Source:** Bugbot on PR #4668, `MainViewController.swift:3457`
@@ -646,6 +666,12 @@ All resolved on GitHub. Fixed in later commits on the `#4544` branch.
**O-N Live Onboarding Experiment Details ([task 1214601039604921](https://app.asana.com/1/137249556945/task/1214601039604921))** 🔴 Still needs filling: add `onboardingDuckAIQueryTrackersDemoExperiment` into [O-N Live Onboarding Experiment Details](https://app.asana.com/1/137249556945/task/1214601039604921) and [O-J <> O-N Coordination](https://app.asana.com/1/137249556945/project/1214157224317277/task/1214288645859692).
**UTI bottom bar position (SHIP-BLOCKER)** 🔴 After selecting bottom bar position in onboarding and dismissing AI chat, no further onboarding dialogs appear. Blocks unhold of PR #4668. Root cause TBD.
**UTI dark mode dialogs (cosmetic)** 🔴 Blue dialogs look poor against dark UTI background. Lower priority; should address before ship.
**PR #4668 pre-ship cleanups** 🔴 Three items must be fixed before #4668 can merge: (1) remove `return .treatmentA` hardcode + update flag name to `onboardingDuckAIQueryTrackersDemoExperiment`, (2) restore `unifiedToggleInput` FeatureFlag config (remove `defaultValue: .enabled` + dead comment), (3) deal with unused `embedInUnifiedInputEditingAreaIfActive` protocol method.
**Alessandro's May 15 QA** — Tested PR #4855 against test cases in [task 1214683268207880](https://app.asana.com/1/137249556945/task/1214683268207880). Test run: [task 1214794564106677](https://app.asana.com/1/137249556945/project/1206329551987282/task/1214794564106677). Left notes in test run and new comments in PR (see PR #4855 — Alessandro line 450 item above).
**Merge approved PRs** — Alessandro recommends merging #4591 and #4664 (both approved) into the main feature branch (#4544) to avoid propagating main-branch merges through each PR separately.