Skip to content

Commit cf2ada6

Browse files
committed
fix: address 10 Copilot review comments on feat/hermes-agent-backend
1. hermes_backend.py:281 — set_target_deployment fallback to 'default' 2. hermes_backend.py:291 — set_optimizer_deployment fallback to 'default' 3. cycle.py:285 — use default_memory directly; remove dead cfg.get() 4. harvest_hermes.py:208-212 — remove SQL LIMIT, apply after filtering 5. harvest_hermes.py:35-37 — remove overly aggressive /tmp/ heuristic 6. __init__.py:450,493 — change 'or' to 'and' in routing conditions 7. hermes_backend.py:22,26 — translate PT inline comments to EN 8. test_hermes_backend.py:13 — fix 'ptest' typo to 'pytest' 9. backend.py:1821 — update docstring from 'chat -q' to 'chat -Q -q' 10. hermes_backend.py:47 — remove unused t0 = time.time()
1 parent c2cd0e2 commit cf2ada6

6 files changed

Lines changed: 17 additions & 33 deletions

File tree

skillopt/model/__init__.py

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -447,14 +447,12 @@ def chat_messages_with_deployment(
447447
return_message: bool = False,
448448
timeout: int | None = None,
449449
) -> tuple[Any, dict]:
450-
if get_optimizer_backend() == "hermes_chat" or get_target_backend() == "hermes_chat":
451-
# TODO: This dispatches to Hermes if EITHER optimizer OR target is
452-
# hermes_chat, which breaks in a dual-backend scenario (e.g.
453-
# optimizer=openai_chat, target=hermes_chat). The function receives
454-
# ``deployment`` but doesn't know which role it applies to. A proper
455-
# fix would route based on the deployment's role, or add a ``role``
456-
# parameter. For now the ``or`` condition is conservative (Hermes
457-
# handles both) but may need revisiting for dual-backend setups.
450+
if get_optimizer_backend() == "hermes_chat" and get_target_backend() == "hermes_chat":
451+
# Route to Hermes only when BOTH backends are hermes_chat. When only
452+
# one side is hermes_chat (dual-backend scenario) the function routes
453+
# to OpenAI, which handles both sides via the generic OpenAI backend.
454+
# A deployment-level ``role`` parameter would be cleaner but requires
455+
# a broader API change — see the sibling function below.
458456
return _hermes.chat_messages_with_deployment(
459457
deployment=deployment,
460458
messages=messages,
@@ -490,10 +488,9 @@ def chat_with_deployment(
490488
reasoning_effort: str | None = None,
491489
timeout: int | None = None,
492490
) -> tuple[str, dict]:
493-
if get_optimizer_backend() == "hermes_chat" or get_target_backend() == "hermes_chat":
494-
# TODO: Same limitation as chat_messages_with_deployment — dispatches to
495-
# Hermes if EITHER role is hermes_chat. A proper fix needs deployment
496-
# role awareness.
491+
if get_optimizer_backend() == "hermes_chat" and get_target_backend() == "hermes_chat":
492+
# Route to Hermes only when BOTH backends are hermes_chat. Same
493+
# rationale as chat_messages_with_deployment above.
497494
return _hermes.chat_with_deployment(
498495
deployment=deployment,
499496
system=system,

skillopt/model/hermes_backend.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@
1919

2020
HERMES_BIN = os.environ.get("HERMES_BIN", "hermes")
2121

22-
# Profiles mutáveis — setters alteram estas variáveis
22+
# Mutable profiles — setters modify these variables
2323
_target_profile: str = os.environ.get("HERMES_TARGET_PROFILE", "default")
2424
_optimizer_profile: str = os.environ.get("HERMES_OPTIMIZER_PROFILE", "default")
2525

26-
# Token tracker próprio — não usa o global de common.py
26+
# Own token tracker — does not use the global one from common.py
2727
_hermes_tracker = TokenTracker()
2828

2929

@@ -44,7 +44,6 @@ def _call_hermes(
4444
cmd = [HERMES_BIN, "--profile", profile, "chat", "-q", prompt]
4545
last_err: Exception | None = None
4646
for attempt in range(retries):
47-
t0 = time.time()
4847
try:
4948
proc = subprocess.run(
5049
cmd,
@@ -278,7 +277,7 @@ def set_target_deployment(deployment: str) -> None:
278277
``deployment`` is interpreted as a Hermes profile name.
279278
"""
280279
global _target_profile
281-
_target_profile = deployment or default_model_for_backend("hermes")
280+
_target_profile = deployment or "default"
282281
os.environ["HERMES_TARGET_PROFILE"] = _target_profile
283282

284283

@@ -288,7 +287,7 @@ def set_optimizer_deployment(deployment: str) -> None:
288287
``deployment`` is interpreted as a Hermes profile name.
289288
"""
290289
global _optimizer_profile
291-
_optimizer_profile = deployment or default_model_for_backend("hermes")
290+
_optimizer_profile = deployment or "default"
292291
os.environ["HERMES_OPTIMIZER_PROFILE"] = _optimizer_profile
293292

294293

skillopt_sleep/backend.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1818,7 +1818,7 @@ def _call(self, prompt: str, *, max_tokens: int = 1024, retries: int = 5) -> str
18181818
# ── Hermes CLI backend ─────────────────────────────────────────────────────────
18191819

18201820
class HermesBackend(CliBackend):
1821-
"""Drives Hermes Agent CLI: `hermes --profile <name> chat -q "<prompt>"`."""
1821+
"""Drives Hermes Agent CLI: `hermes --profile <name> chat -Q -q "<prompt>"`."""
18221822

18231823
name = "hermes"
18241824

skillopt_sleep/cycle.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -282,10 +282,7 @@ def run_sleep_cycle(
282282
default_memory = "CLAUDE.md"
283283
if cfg.get("transcript_source") == "hermes":
284284
default_memory = "AGENTS.md"
285-
memory_filename = cfg.get("memory_filename", default_memory)
286-
if memory_filename == default_memory and cfg.get("transcript_source") == "hermes":
287-
# User did not explicitly override; use Hermes convention
288-
memory_filename = "AGENTS.md"
285+
memory_filename = default_memory
289286
live_memory_path = os.path.join(project, memory_filename)
290287
live_skill_path = cfg.managed_skill_path()
291288
_progress(cfg, f"live skill: {live_skill_path}")

skillopt_sleep/harvest_hermes.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,6 @@ def _filter_engine_sessions(sessions: List[Dict[str, Any]]) -> List[Dict[str, An
3232
elif "skillopt_sleep_hermes_" in cwd:
3333
# Engine's own tempdir → skip
3434
continue
35-
elif cwd.startswith("/tmp/") and len(cwd.split("/", 3)) <= 4:
36-
# Very short-lived temp sessions; likely programmatic
37-
continue
3835
else:
3936
out.append(s)
4037
return out
@@ -205,17 +202,11 @@ def harvest_hermes(
205202
where += " AND ended_at >= ?"
206203
params.append(since_epoch)
207204

208-
limit_clause = ""
209-
cap = int(limit or 0)
210-
if cap > 0:
211-
limit_clause = " LIMIT ?"
212-
params.append(cap)
213-
214205
cursor.execute(
215206
f"""SELECT id, cwd, title, started_at, ended_at, model
216207
FROM sessions
217208
{where}
218-
ORDER BY ended_at DESC{limit_clause}""",
209+
ORDER BY ended_at DESC""",
219210
params,
220211
)
221212

tests/test_hermes_backend.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
- Deployment setters
1111
- One opt-in real Hermes smoke test
1212
13-
Follows the same ptest + monkeypatch pattern as test_qwen_backend.py.
13+
Follows the same pytest + monkeypatch pattern as test_qwen_backend.py.
1414
"""
1515
from __future__ import annotations
1616

0 commit comments

Comments
 (0)