forked from Zakaria/hermes-agent
Hermes-agent
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import subprocess
|
||||
|
||||
|
||||
def _make_task(kb, *, assignee: str):
|
||||
return kb.Task(
|
||||
id="t_spawn_tools",
|
||||
title="spawn tools",
|
||||
body=None,
|
||||
assignee=assignee,
|
||||
status="running",
|
||||
priority=0,
|
||||
created_by="test",
|
||||
created_at=1,
|
||||
started_at=None,
|
||||
completed_at=None,
|
||||
workspace_kind="dir",
|
||||
workspace_path=None,
|
||||
claim_lock="lock",
|
||||
claim_expires=None,
|
||||
tenant=None,
|
||||
current_run_id=7,
|
||||
)
|
||||
|
||||
|
||||
def test_default_spawn_pins_assignee_profile_cli_toolsets(monkeypatch, tmp_path):
|
||||
"""Manual profile assignment should keep that profile's CLI tools.
|
||||
|
||||
Regression guard for dispatcher-spawned workers that boot with
|
||||
HERMES_KANBAN_TASK: the worker must not collapse to only kanban lifecycle
|
||||
tools when the assigned profile's top-level ``toolsets`` is the default
|
||||
composite. The spawned CLI gets an explicit --toolsets pin resolved from
|
||||
platform_toolsets.cli; model_tools appends task-scoped kanban tools later.
|
||||
"""
|
||||
root = tmp_path / ".hermes"
|
||||
profile = root / "profiles" / "elias"
|
||||
profile.mkdir(parents=True)
|
||||
profile.joinpath("config.yaml").write_text(
|
||||
"""
|
||||
platform_toolsets:
|
||||
cli:
|
||||
- clarify
|
||||
- code_execution
|
||||
- delegation
|
||||
- file
|
||||
- memory
|
||||
- session_search
|
||||
- skills
|
||||
- terminal
|
||||
- web
|
||||
toolsets:
|
||||
- hermes-cli
|
||||
agent:
|
||||
disabled_toolsets: []
|
||||
""".lstrip(),
|
||||
encoding="utf-8",
|
||||
)
|
||||
root.joinpath("config.yaml").write_text("toolsets:\n - kanban\n", encoding="utf-8")
|
||||
monkeypatch.setenv("HERMES_HOME", str(root))
|
||||
|
||||
from hermes_cli import kanban_db as kb
|
||||
|
||||
monkeypatch.setattr(kb, "_resolve_hermes_argv", lambda: ["hermes"])
|
||||
|
||||
captured = {}
|
||||
|
||||
class FakeProc:
|
||||
pid = 4242
|
||||
|
||||
def fake_popen(cmd, *args, **kwargs):
|
||||
captured["cmd"] = list(cmd)
|
||||
captured["env"] = dict(kwargs.get("env") or {})
|
||||
captured["cwd"] = kwargs.get("cwd")
|
||||
return FakeProc()
|
||||
|
||||
monkeypatch.setattr(subprocess, "Popen", fake_popen)
|
||||
|
||||
workspace = tmp_path / "workspace"
|
||||
workspace.mkdir()
|
||||
pid = kb._default_spawn(_make_task(kb, assignee="elias"), str(workspace))
|
||||
|
||||
assert pid == 4242
|
||||
assert captured["env"]["HERMES_HOME"] == str(profile)
|
||||
assert captured["env"]["HERMES_KANBAN_TASK"] == "t_spawn_tools"
|
||||
assert "--toolsets" in captured["cmd"]
|
||||
pinned = captured["cmd"][captured["cmd"].index("--toolsets") + 1].split(",")
|
||||
for required in ("terminal", "web", "file", "skills", "code_execution", "delegation"):
|
||||
assert required in pinned
|
||||
|
||||
|
||||
def test_resolve_worker_cli_toolsets_uses_profile_home_not_parent_config(monkeypatch, tmp_path):
|
||||
root = tmp_path / ".hermes"
|
||||
profile = root / "profiles" / "elias"
|
||||
profile.mkdir(parents=True)
|
||||
root.joinpath("config.yaml").write_text("platform_toolsets:\n cli:\n - kanban\n", encoding="utf-8")
|
||||
profile.joinpath("config.yaml").write_text(
|
||||
"""
|
||||
platform_toolsets:
|
||||
cli:
|
||||
- terminal
|
||||
- web
|
||||
toolsets:
|
||||
- hermes-cli
|
||||
""".lstrip(),
|
||||
encoding="utf-8",
|
||||
)
|
||||
monkeypatch.setenv("HERMES_HOME", str(root))
|
||||
|
||||
from hermes_cli import kanban_db as kb
|
||||
|
||||
resolved = kb._resolve_worker_cli_toolsets(str(profile))
|
||||
|
||||
assert resolved is not None
|
||||
assert "terminal" in resolved
|
||||
assert "web" in resolved
|
||||
assert "kanban" in resolved # recovered worker lifecycle surface
|
||||
assert resolved != ["kanban"]
|
||||
Reference in New Issue
Block a user