[2026-06-15] taiga-vault: personal/projects/personal-os/claude-proxy-node-internals.md
This commit is contained in:
@@ -84,21 +84,41 @@ CMD ["claude-proxy", "3456"]
|
|||||||
|
|
||||||
В режиме `print` проблема та же — proxy ждёт завершения `claude --print` и возвращает результат целиком, не транслируя промежуточный вывод.
|
В режиме `print` проблема та же — proxy ждёт завершения `claude --print` и возвращает результат целиком, не транслируя промежуточный вывод.
|
||||||
|
|
||||||
### 3. claude spawn'ит свой bash без контекста Hermes
|
### 3. Claude CLI сам исполняет инструменты вместо Hermes
|
||||||
|
|
||||||
**Механизм:** proxy запускает `claude` через `child_process.spawn('claude', args, {env: process.env})`. Ниже по цепочке:
|
**Проблема:** Claude Code CLI **сам выполняет Bash/Read/Write/Edit инструменты внутри своей сессии**, а не возвращает tool_use блоки Hermes'у для исполнения.
|
||||||
|
|
||||||
|
Текущий flow:
|
||||||
|
|
||||||
```
|
```
|
||||||
launchd → claude-proxy-start.sh → claude-proxy (node) → claude CLI (subprocess)
|
Hermes → claude-proxy (Node.js) → claude CLI
|
||||||
└── bash -c "..."
|
└── сам делает Bash, Read, Write
|
||||||
|
└── bash -c "..."
|
||||||
```
|
```
|
||||||
|
|
||||||
Claude Code CLI для выполнения инструментов (Bash, Write, Edit) внутри себя спавнит `bash -c "..."`. Этот bash:
|
Hermes видит только финальный текст ответа. Он теряет контроль над:
|
||||||
- наследует env от `claude` процесса
|
- какие файлы читаются
|
||||||
- НЕ имеет `HERMES_HOME`, кастомного `PATH`, `SHELL=/bin/zsh` с профилем Hermes
|
- какие команды выполняются
|
||||||
- использует системный `/bin/bash` или `/bin/sh`
|
- кто их логирует и аудитит
|
||||||
|
- allower/denier политики Hermes игнорируются
|
||||||
|
|
||||||
В контейнере (alpine) bash вообще может отсутствовать — claude CLI использует `/bin/sh`.
|
Правильный flow (caller-dispatched tools):
|
||||||
|
|
||||||
|
```
|
||||||
|
Hermes → claude-proxy (Node.js) → claude CLI (только генерация)
|
||||||
|
↓ текст ответа с tool_use блоками
|
||||||
|
Hermes ── парсит tool_use ── выполняет через свои инструменты ── результат → обратно в claude CLI
|
||||||
|
```
|
||||||
|
|
||||||
|
Для этого proxy должен:
|
||||||
|
1. Выключить инструменты в `claude` CLI — передать `disallowed_tools = ["Bash", "Read", "Write", "Edit", "Glob", "Grep"]`
|
||||||
|
2. Остановиться после первого assistant-сообщения
|
||||||
|
3. Отдать tool_use блоки Hermes'у как OpenAI `tool_calls`
|
||||||
|
4. Принять результат выполнения от Hermes и передать обратно в `claude` для продолжения (multi-turn)
|
||||||
|
|
||||||
|
**Текущий `openclaw-claude-proxy` не поддерживает этот flow корректно:** stream-json протокол для multi-turn interaction сломан начиная с claude CLI 2.1.141. В режиме `print` multi-turn вообще невозможен.
|
||||||
|
|
||||||
|
**Python wrapper (`claude-code-openai-wrapper`) этот flow поддерживает** — у него есть `stop_after_first_assistant` и `disallowed_tools`. Именно поэтому он активен, а Node.js — fallback.
|
||||||
|
|
||||||
## Предложенные подходы
|
## Предложенные подходы
|
||||||
|
|
||||||
@@ -113,9 +133,3 @@ Claude Code CLI для выполнения инструментов (Bash, Writ
|
|||||||
1. **Проброс stderr:** pipe'ить stderr `claude` в stderr proxy — видно в `docker logs` или launchd логах.
|
1. **Проброс stderr:** pipe'ить stderr `claude` в stderr proxy — видно в `docker logs` или launchd логах.
|
||||||
2. **Режим `print`:** переключить `CLAUDE_PROXY_RUNTIME=print` — теряется производительность stream-json, но логов больше.
|
2. **Режим `print`:** переключить `CLAUDE_PROXY_RUNTIME=print` — теряется производительность stream-json, но логов больше.
|
||||||
3. **Node.js `stream-json` мониторинг:** логировать каждую N-ную JSON строку из stdout claude для отладки.
|
3. **Node.js `stream-json` мониторинг:** логировать каждую N-ную JSON строку из stdout claude для отладки.
|
||||||
|
|
||||||
### Против изоляции shell
|
|
||||||
|
|
||||||
1. **В Docker:** установить bash в контейнер (`apk add bash`), установить `SHELL=/bin/bash` в env.
|
|
||||||
2. **Передача `HERMES_HOME`:** смонтировать `~/.hermes` в контейнер и передать `HERMES_HOME` в env claude CLI.
|
|
||||||
3. **wrapper-скрипт для claude:** заменить бинарник `claude` в контейнере на shell wrapper, который ставит профиль Hermes перед вызовом реального `claude`.
|
|
||||||
|
|||||||
Reference in New Issue
Block a user