Skip to content

Hermes Integration

Séance integrates with Hermes Agent through a Python plugin. Unlike other agents that use TypeScript plugins, Hermes uses a Python-based hook system.

How It Works

  1. Plugin auto-installs on Séance startup to ~/.hermes/plugins/seance/
  2. Plugin registers hooks with Hermes's callback system, forwarding events to Séance
  3. Wrapper script intercepts hermes launches, tracks PID, and fires session-end on exit

Hook Event Mapping

Hermes HookFires FromSéance CommandWhat It Shows
on_session_startconversation loopsession-startRunning
pre_llm_callturn contextprompt-submitRunning
pre_tool_callmodel toolspre-tool-useRunning
post_tool_callmodel toolspost-tool-useRunning
post_llm_callturn finalizerllm-completeIdle
pre_approval_requestapproval toolsapproval-requestNeeds input
post_approval_responseapproval toolsapproval-response(no-op)
on_session_endsession finalizesession-end(cleared)
on_session_resetslash commandsinterruptIdle

Features

  • Approval detection — shows "Pending approval" when Hermes asks for permission to run a command
  • Clarify tool detection — when Hermes asks a question via its clarify tool, Séance shows "Waiting for user input"
  • Interrupt handling/reset and /new slash commands reset stuck "Running" status back to "Idle"
  • Desktop notifications — notifies on completion and input requests (via Hermes-specific handlers)

Configuration

Toggle integration on or off in config.toml:

toml
hermes-hooks = true

Limitations

  • No session directory — Hermes doesn't expose session directory information
  • Interrupt coverage — a raw Ctrl-C cancel without /reset may not reset status, since Hermes doesn't fire a hook for that path
  • TUI session persistence — in TUI mode, status persists after Hermes exits because the session outlives individual agent processes

For Contributors

Integration Approach

Hermes uses a Python plugin (~/.hermes/plugins/seance/) with plugin.yaml manifest and __init__.py hook registration. The plugin registers callbacks via ctx.register_hook(event, callback), and each callback calls seance ctl hermes-hook <event> with a JSON payload.

Why Python instead of TypeScript: Hermes's plugin callbacks fire from the shared core, covering CLI, TUI, gateway, desktop, and dashboard surfaces. An earlier shell-hooks design only worked on the CLI surface because the TUI backend never called register_from_config.

A wrapper script (resources/bin/hermes) intercepts launches for PID tracking and session-end on exit.

Event Mapping

Hermes HookSeance HookUI Status
on_session_startsession-startRunning
pre_llm_callprompt-submitRunning
pre_tool_callpre-tool-useRunning
post_tool_callpost-tool-useRunning
post_llm_callllm-completeIdle
pre_approval_requestapproval-requestNeeds input
post_approval_responseapproval-response(no-op)
on_session_endsession-end(cleared)
on_session_resetinterruptIdle

Note: Hermes uses custom hook types (llm-complete, approval-request, approval-response, interrupt) rather than the standard set used by other agents.

Custom Hook Types

Hermes uses four custom hook types not found in other agents:

Custom HookPurpose
llm-completeLLM call finished — sets status to Idle
approval-requestPermission requested — sets status to Needs input
approval-responsePermission granted/denied — no-op
interruptSession reset via /reset or /new — sets status to Idle

Clarify Tool Detection

Hermes has a clarify tool that asks the user for clarification. The plugin detects when this tool is invoked and shows "Waiting for user input" instead of the generic "Running" status.

Key Implementation Details

  • Status mode: Per-surface. Status key prefix hermes, mode surface.
  • clear_status_on_end is false — unique among all agents.
  • has_notification_hook is true.
  • Auto-install target: ~/.hermes/plugins/seance/ directory with plugin.yaml + __init__.py.

Why clear_status_on_end = false

Hermes sessions outlive individual agent processes. The session continues after the agent exits, so clearing status on session-end would incorrectly clear status for a session that may restart. Instead, llm-complete is used for idle detection — when the LLM finishes a call, the status goes to Idle regardless of session lifecycle.

Upstream Framework Events

Source: hermes-agent.nousresearch.com/docs/user-guide/features/hooks

Hermes has multiple hook systems: gateway hooks, plugin hooks, and shell hooks:

EventDescriptionSéance Handles?
on_session_startSession beginsYes
on_session_endSession terminatesYes
on_session_resetSession reset via /reset or /newYes
pre_llm_callBefore LLM callYes
post_llm_callAfter LLM callYes
pre_tool_callBefore tool callYes
post_tool_callAfter tool callYes
pre_approval_requestPermission requestedYes
post_approval_responsePermission responseYes
agent:startAgent activity startsNo
agent:endAgent activity endsNo
agent:stepAgent step completedNo
subagent_startSubagent spawnedNo
subagent_stopSubagent finishesNo

Missing Event Coverage

Events that Hermes can emit but Séance does not currently handle:

EventPotential Use for Séance
agent:start / agent:endAgent activity tracking
agent:stepStep-level tracking
subagent_start / subagent_stopSubagent lifecycle tracking

Impact: Hermes has comprehensive hook support. Séance's built-in integration uses custom approval-request instead of standard hooks.

MIT Licensed