[2026-06-15] claude-proxy-node-internals — fix problem 3: caller-dispatched tools vs claude self-execution
This commit is contained in:
@@ -84,21 +84,41 @@ CMD ["claude-proxy", "3456"]
|
||||
|
||||
В режиме `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)
|
||||
└── bash -c "..."
|
||||
Hermes → claude-proxy (Node.js) → claude CLI
|
||||
└── сам делает Bash, Read, Write
|
||||
└── bash -c "..."
|
||||
```
|
||||
|
||||
Claude Code CLI для выполнения инструментов (Bash, Write, Edit) внутри себя спавнит `bash -c "..."`. Этот bash:
|
||||
- наследует env от `claude` процесса
|
||||
- НЕ имеет `HERMES_HOME`, кастомного `PATH`, `SHELL=/bin/zsh` с профилем Hermes
|
||||
- использует системный `/bin/bash` или `/bin/sh`
|
||||
Hermes видит только финальный текст ответа. Он теряет контроль над:
|
||||
- какие файлы читаются
|
||||
- какие команды выполняются
|
||||
- кто их логирует и аудитит
|
||||
- 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 логах.
|
||||
2. **Режим `print`:** переключить `CLAUDE_PROXY_RUNTIME=print` — теряется производительность stream-json, но логов больше.
|
||||
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