refactor(agent/side_question,review_*,thinking_timeout_guidance): flatten call sites, drop section banners

This commit is contained in:
Teknium
2026-09-02 19:19:44 -07:00
parent c8d71d9546
commit ca90cea815
4 changed files with 17 additions and 50 deletions

View File

@@ -106,8 +106,7 @@ def build_review_task(snapshot: List[Dict[str, str]], user_prompt: str = "", loa
"--- Recent conversation (oldest first) ---",
]
for message in snapshot:
label = "USER" if message["role"] == "user" else "PRIMARY AGENT"
lines += [f"[{label}]", message["text"], ""]
lines += [f"[{'USER' if message['role'] == 'user' else 'PRIMARY AGENT'}]", message["text"], ""]
lines.append("--- End of conversation excerpt ---")
if loaded_skills:
skill_list = ", ".join(loaded_skills)
@@ -135,12 +134,11 @@ def _load_review_credentials_cfg() -> Optional[Dict[str, Any]]:
and no model/base_url) so the reviewer inherits the parent's credentials."""
try:
from hermes_cli.config import load_config_readonly
review = (load_config_readonly().get("auxiliary") or {}).get("review") or {}
if not isinstance(review, dict):
return None
except Exception:
return None
if not isinstance(review, dict):
return None
cfg = {k: str(review.get(k) or "").strip() for k in ("provider", "model", "base_url", "api_key", "api_mode")}
if cfg["provider"].lower() == "auto":
@@ -156,17 +154,13 @@ def start_review(parent_agent, messages: List[Dict[str, Any]], user_prompt: str
when there is nothing to review or the dispatch is rejected/errored."""
if parent_agent is None:
raise ValueError("No active agent — send a message first.")
snapshot = snapshot_recent_messages(messages)
if not snapshot:
raise ValueError("Nothing to review yet — the conversation is empty.")
loaded_skills = collect_parent_loaded_skills(parent_agent, messages)
goal, context = build_review_task(snapshot, user_prompt, loaded_skills)
goal, context = build_review_task(snapshot, user_prompt, collect_parent_loaded_skills(parent_agent, messages))
credentials_cfg = _load_review_credentials_cfg()
from tools.delegate_tool import delegate_task
raw = delegate_task(goal=goal, context=context, background=True, parent_agent=parent_agent, credentials_cfg=credentials_cfg)
try:
result = json.loads(raw)

View File

@@ -80,8 +80,6 @@ class ReviewIdleQueue:
self._now: Callable[[], float] = time.monotonic
self._server_idle: Callable[[], bool] = _managed_server_idle
# ── turn liveness (this process) ────────────────────────────
def note_turn_started(self) -> None:
with self._lock:
self._live_turns += 1
@@ -94,8 +92,6 @@ class ReviewIdleQueue:
self._quiet_since = self._now()
self._wake.set()
# ── queue ────────────────────────────────────────────────────
def enqueue(self, agent: Any, session_key: str, kwargs: Dict[str, Any]) -> None:
"""Add (or replace — newest snapshot wins) a session's pending review, keeping the ORIGINAL
enqueue time on coalesce so a busy session cannot push its age-out forever."""
@@ -111,8 +107,6 @@ class ReviewIdleQueue:
with self._lock:
return len(self._pending)
# ── dispatcher ───────────────────────────────────────────────
def _ensure_thread(self) -> None:
with self._lock:
if self._thread is None or not self._thread.is_alive():
@@ -193,8 +187,7 @@ def _managed_server_idle() -> bool:
return True
def _get(path: str) -> Any:
req = urllib.request.Request(f"{base}{path}", headers=headers)
with urllib.request.urlopen(req, timeout=3) as r:
with urllib.request.urlopen(urllib.request.Request(f"{base}{path}", headers=headers), timeout=3) as r:
return json.loads(r.read())
loaded = [m["id"] for m in _get("/models").get("data", [])

View File

@@ -59,10 +59,7 @@ def trim_snapshot_for_fork(history: Optional[List[Dict[str, Any]]]) -> List[Dict
return msgs
def render_history_for_side_question(
history: Optional[List[Dict[str, Any]]],
char_budget: int = _TRANSCRIPT_CHAR_BUDGET,
) -> str:
def render_history_for_side_question(history: Optional[List[Dict[str, Any]]], char_budget: int = _TRANSCRIPT_CHAR_BUDGET) -> str:
"""Plain-text transcript for the fallback path: newest-biased fit to ``char_budget``,
tool calls summarized by name, tool results truncated, system prompt skipped."""
lines: List[str] = []
@@ -95,11 +92,9 @@ def _side_question_task_config() -> Dict[str, Any]:
"""Return ``auxiliary.side_question`` from config (or ``{}``)."""
try:
from hermes_cli.config import load_config_readonly
cfg = load_config_readonly()
aux = load_config_readonly().get("auxiliary")
except Exception:
return {}
aux = cfg.get("auxiliary")
task = aux.get(SIDE_QUESTION_TASK) if isinstance(aux, dict) else None
return task if isinstance(task, dict) else {}
@@ -118,18 +113,12 @@ def _answer_via_fork(parent_agent: Any, question: str, history: Optional[List[Di
fork, _rt, routed = build_cache_parity_fork(parent_agent, _side_question_task_config(),
max_iterations=_FORK_MAX_ITERATIONS, write_origin="side_question")
try:
set_thread_tool_whitelist(
set(),
deny_msg_fmt=(
"Side question (/btw) denied tool call: {tool_name}. "
"Tools are disabled here — answer directly from the conversation context."
),
)
set_thread_tool_whitelist(set(), deny_msg_fmt=(
"Side question (/btw) denied tool call: {tool_name}. "
"Tools are disabled here — answer directly from the conversation context."))
snapshot = trim_snapshot_for_fork(history)
result = fork.run_conversation(
user_message=f"{_FORK_PROMPT}\n\nSide question: {question}",
conversation_history=_digest_history(snapshot) if routed else snapshot,
)
result = fork.run_conversation(user_message=f"{_FORK_PROMPT}\n\nSide question: {question}",
conversation_history=_digest_history(snapshot) if routed else snapshot)
answer = (result or {}).get("final_response", "") or ""
if not answer and result and result.get("error"):
raise RuntimeError(str(result["error"]))
@@ -137,11 +126,8 @@ def _answer_via_fork(parent_agent: Any, question: str, history: Optional[List[Di
finally:
clear_thread_tool_whitelist()
# Attribute the fork's usage to the parent session; teardown never raises.
for step in (
lambda: _record_review_usage_to_parent(parent_agent, _snapshot_review_usage(fork)),
fork.shutdown_memory_provider,
fork.close,
):
for step in (lambda: _record_review_usage_to_parent(parent_agent, _snapshot_review_usage(fork)),
fork.shutdown_memory_provider, fork.close):
try:
step()
except Exception:
@@ -160,13 +146,8 @@ def _answer_via_oneshot(question: str, history: Optional[List[Dict[str, Any]]],
def answer_side_question(
question: str,
history: Optional[List[Dict[str, Any]]],
*,
parent_agent: Any = None,
main_runtime: Optional[Dict[str, Any]] = None,
max_tokens: int = 2048,
temperature: Optional[float] = 0.3,
question: str, history: Optional[List[Dict[str, Any]]], *, parent_agent: Any = None,
main_runtime: Optional[Dict[str, Any]] = None, max_tokens: int = 2048, temperature: Optional[float] = 0.3,
timeout: float = 180.0,
) -> str:
"""Fork when ``parent_agent`` is live, else (or on empty answer / failure) the one-shot

View File

@@ -32,8 +32,7 @@ def is_thinking_timeout(classified: object, model: str, error_msg: str) -> bool:
return False
if get_reasoning_stale_timeout_floor(model) is None:
return False
error_msg_lower = (error_msg or "").lower()
return any(p in error_msg_lower for p in _THINKING_TIMEOUT_SUBSTRINGS)
return any(p in (error_msg or "").lower() for p in _THINKING_TIMEOUT_SUBSTRINGS)
def build_thinking_timeout_guidance(provider: str, model: str, model_label: Optional[str] = None) -> str: