Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions agent/prompt_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -613,21 +613,23 @@ def build_skills_system_prompt(
or get_session_env("HERMES_SESSION_PLATFORM")
or ""
)
# Load disabled set before cache check so changes to skills.disabled
# invalidate the cache (fixes #12294).
disabled = get_disabled_skill_names()
cache_key = (
str(skills_dir.resolve()),
tuple(str(d) for d in external_dirs),
tuple(sorted(str(t) for t in (available_tools or set()))),
tuple(sorted(str(ts) for ts in (available_toolsets or set()))),
_platform_hint,
tuple(sorted(disabled)),
)
with _SKILLS_PROMPT_CACHE_LOCK:
cached = _SKILLS_PROMPT_CACHE.get(cache_key)
if cached is not None:
_SKILLS_PROMPT_CACHE.move_to_end(cache_key)
return cached

disabled = get_disabled_skill_names()

# ── Layer 2: disk snapshot ────────────────────────────────────────
snapshot = _load_skills_snapshot(skills_dir)

Expand Down
49 changes: 32 additions & 17 deletions gateway/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -4573,13 +4573,14 @@ async def _handle_reset_command(self, event: MessageEvent) -> str:
self._session_model_overrides.pop(session_key, None)

# Fire plugin on_session_finalize hook (session boundary)
try:
from hermes_cli.plugins import invoke_hook as _invoke_hook
_old_sid = old_entry.session_id if old_entry else None
_invoke_hook("on_session_finalize", session_id=_old_sid,
platform=source.platform.value if source.platform else "")
except Exception:
pass
if old_entry is not None:
try:
from hermes_cli.plugins import invoke_hook as _invoke_hook
_old_sid = old_entry.session_id if old_entry else None
_invoke_hook("on_session_finalize", session_id=_old_sid,
platform=source.platform.value if source.platform else "")
except Exception:
pass

# Emit session:end hook (session is ending)
await self.hooks.emit("session:end", {
Expand Down Expand Up @@ -6170,13 +6171,20 @@ def run_sync():
except Exception:
pass

# Send media files
# Send media files — route voice files through send_voice
# when available (fixes #12064).
for media_path, _is_voice in (media_files or []):
try:
await adapter.send_document(
chat_id=source.chat_id,
file_path=media_path,
)
if _is_voice and hasattr(adapter, "send_voice"):
await adapter.send_voice(
chat_id=source.chat_id,
audio_path=media_path,
)
else:
await adapter.send_document(
chat_id=source.chat_id,
file_path=media_path,
)
except Exception:
pass
else:
Expand Down Expand Up @@ -10416,18 +10424,25 @@ def restart_signal_handler():
name="cron-ticker",
)
cron_thread.start()

# Wait for shutdown
await runner.wait_for_shutdown()

_failure = False
if runner.should_exit_with_failure:
if runner.exit_reason:
logger.error("Gateway exiting with failure: %s", runner.exit_reason)
_failure = True

try:
pass
finally:
# Stop cron ticker cleanly (always, even on failure)
cron_stop.set()
cron_thread.join(timeout=5)

if _failure:
return False

# Stop cron ticker cleanly
cron_stop.set()
cron_thread.join(timeout=5)

# Close MCP server connections
try:
Expand Down