mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-28 01:21:43 +00:00
feat: add Claude Code CLI bridge tool
WHY: - Claude Code CLI succeeds on local Claude Team auth when Hermes native Anthropic path can fail - we need a stable local wrapper and a first-class Hermes entry point for that path HOW: - add a structured Claude CLI bridge script and local wrapper - register claude_cli_run tool under the terminal toolset and cover it with tests
This commit is contained in:
parent
334b7dcb8f
commit
6527c6d0a1
3 changed files with 392 additions and 0 deletions
52
tests/tools/test_claude_cli_tool.py
Normal file
52
tests/tools/test_claude_cli_tool.py
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
import json
|
||||
import subprocess
|
||||
|
||||
import tools.claude_cli_tool as claude_cli_tool
|
||||
|
||||
|
||||
def test_coerce_allowed_tools_from_list():
|
||||
assert claude_cli_tool._coerce_allowed_tools(["Read", "Bash(git *)"]) == "Read,Bash(git *)"
|
||||
|
||||
|
||||
def test_claude_cli_run_tool_parses_success(monkeypatch):
|
||||
monkeypatch.setattr(claude_cli_tool, "BRIDGE_SCRIPT_PATH", claude_cli_tool.Path("/tmp/bridge.py"))
|
||||
monkeypatch.setattr(claude_cli_tool, "_path_exists", lambda _path: True)
|
||||
monkeypatch.setattr(claude_cli_tool.shutil, "which", lambda name: "/usr/bin/claude" if name == "claude" else None)
|
||||
monkeypatch.setattr(claude_cli_tool, "WRAPPER_PATH", claude_cli_tool.Path("/tmp/hermes-call-claude"))
|
||||
|
||||
def _fake_run(cmd, capture_output, text, timeout):
|
||||
payload = {
|
||||
"success": True,
|
||||
"result": "OK",
|
||||
"session_id": "abc123",
|
||||
"command": cmd,
|
||||
}
|
||||
return subprocess.CompletedProcess(cmd, 0, stdout=json.dumps(payload), stderr="")
|
||||
|
||||
monkeypatch.setattr(claude_cli_tool.subprocess, "run", _fake_run)
|
||||
result = json.loads(
|
||||
claude_cli_tool.claude_cli_run_tool(
|
||||
prompt="Reply with exactly: OK",
|
||||
workdir="/tmp",
|
||||
allowed_tools=["Read", "Bash(git *)"],
|
||||
timeout_seconds=30,
|
||||
)
|
||||
)
|
||||
assert result["success"] is True
|
||||
assert result["result"] == "OK"
|
||||
assert "--allowed-tools" in result["command"]
|
||||
|
||||
|
||||
def test_claude_cli_run_tool_returns_error_on_non_json(monkeypatch):
|
||||
monkeypatch.setattr(claude_cli_tool, "BRIDGE_SCRIPT_PATH", claude_cli_tool.Path("/tmp/bridge.py"))
|
||||
monkeypatch.setattr(claude_cli_tool, "_path_exists", lambda _path: True)
|
||||
monkeypatch.setattr(claude_cli_tool.shutil, "which", lambda name: "/usr/bin/claude" if name == "claude" else None)
|
||||
monkeypatch.setattr(claude_cli_tool, "WRAPPER_PATH", claude_cli_tool.Path("/tmp/hermes-call-claude"))
|
||||
|
||||
def _fake_run(cmd, capture_output, text, timeout):
|
||||
return subprocess.CompletedProcess(cmd, 1, stdout="not-json", stderr="boom")
|
||||
|
||||
monkeypatch.setattr(claude_cli_tool.subprocess, "run", _fake_run)
|
||||
result = json.loads(claude_cli_tool.claude_cli_run_tool(prompt="hi"))
|
||||
assert "error" in result
|
||||
assert "non-JSON" in result["error"]
|
||||
Loading…
Add table
Add a link
Reference in a new issue