fix(hermes): settle Claude prompts in HERDR
This commit is contained in:
parent
c4e0ec3d60
commit
b311afe60b
@ -24,7 +24,7 @@ spec:
|
||||
ai.bstein.dev/execution: Herdr-supervised Codex and Claude Code
|
||||
ai.bstein.dev/model-policy: difficulty-aware low through xhigh, cross-provider fallback
|
||||
ai.bstein.dev/placement: rpi5 preferred; Jetson deferred until state storage is available
|
||||
ai.bstein.dev/config-rev: "20260808-herdr-browser-tui"
|
||||
ai.bstein.dev/config-rev: "20260808-herdr-browser-tui-prompt-ready"
|
||||
vault.hashicorp.com/agent-inject: "true"
|
||||
vault.hashicorp.com/role: hermes-agent
|
||||
vault.hashicorp.com/agent-inject-secret-anthropic-token: kv/data/atlas/hermes/agent-tokens
|
||||
|
||||
@ -8,6 +8,7 @@ import json
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import time
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
@ -16,6 +17,7 @@ ALLOWED_EFFORTS = ("low", "medium", "high", "xhigh")
|
||||
ROUTING_PATH = Path("/opt/data/workspace/coordinator/model-routing.json")
|
||||
HERDR_BIN = Path("/opt/data/tools/bin/herdr")
|
||||
CODEX_AUTH = Path("/opt/data/home/.codex/auth.json")
|
||||
CLAUDE_PROMPT_SETTLE_SECONDS = 3
|
||||
|
||||
|
||||
def _load_routes(path: Path) -> dict[str, Any]:
|
||||
@ -178,8 +180,28 @@ def launch_worker(
|
||||
started = _run(command, env)
|
||||
result = {**plan, "agent": agent_name, "pane": pane, "started": started}
|
||||
if prompt:
|
||||
# Claude reports interactive readiness just before its prompt finishes
|
||||
# drawing. Give that terminal a moment so the submitted Enter is not lost.
|
||||
if plan["worker"] == "claude":
|
||||
time.sleep(CLAUDE_PROMPT_SETTLE_SECONDS)
|
||||
result["prompted"] = _run(
|
||||
[str(HERDR_BIN), "agent", "prompt", agent_name, prompt], env
|
||||
[
|
||||
str(HERDR_BIN),
|
||||
"agent",
|
||||
"prompt",
|
||||
agent_name,
|
||||
prompt,
|
||||
"--wait",
|
||||
"--until",
|
||||
"working",
|
||||
"--until",
|
||||
"done",
|
||||
"--until",
|
||||
"blocked",
|
||||
"--timeout",
|
||||
"15000",
|
||||
],
|
||||
env,
|
||||
)
|
||||
return result
|
||||
|
||||
|
||||
@ -49,6 +49,52 @@ def test_herdr_plan_chooses_task_shape_and_caps_effort():
|
||||
dispatch.select_plan(status, "review", "max")
|
||||
|
||||
|
||||
def test_claude_worker_waits_for_prompt_readiness(tmp_path: Path, monkeypatch):
|
||||
herdr = tmp_path / "herdr"
|
||||
herdr.touch()
|
||||
project = tmp_path / "project"
|
||||
project.mkdir()
|
||||
calls = []
|
||||
sleeps = []
|
||||
|
||||
def fake_run(command, env):
|
||||
calls.append(command)
|
||||
if command[1:3] == ["workspace", "create"]:
|
||||
return {"result": {"root_pane": {"pane_id": "w2:p1"}}}
|
||||
return {"result": {"ok": True}}
|
||||
|
||||
monkeypatch.setattr(dispatch, "HERDR_BIN", herdr)
|
||||
monkeypatch.setattr(dispatch, "_run", fake_run)
|
||||
monkeypatch.setattr(dispatch.time, "sleep", sleeps.append)
|
||||
plan = {
|
||||
"worker": "claude",
|
||||
"model": "claude-haiku-4-5-20251001",
|
||||
"effort": "low",
|
||||
}
|
||||
|
||||
dispatch.launch_worker(plan, project, "review", "Check the implementation.")
|
||||
|
||||
assert sleeps == [dispatch.CLAUDE_PROMPT_SETTLE_SECONDS]
|
||||
prompt = calls[-1]
|
||||
assert prompt[1:5] == [
|
||||
"agent",
|
||||
"prompt",
|
||||
"claude-review",
|
||||
"Check the implementation.",
|
||||
]
|
||||
assert prompt[-9:] == [
|
||||
"--wait",
|
||||
"--until",
|
||||
"working",
|
||||
"--until",
|
||||
"done",
|
||||
"--until",
|
||||
"blocked",
|
||||
"--timeout",
|
||||
"15000",
|
||||
]
|
||||
|
||||
|
||||
def test_auth_patch_honors_explicit_shared_store(tmp_path: Path):
|
||||
source = tmp_path / "auth.py"
|
||||
destination = tmp_path / "patched" / "auth.py"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user