Hermes
Hermes loads the xmsg plugin (extensions/hermes/plugin.yaml and extensions/hermes/__init__.py)
from $HERMES_HOME/plugins/ when plugins.enabled includes "xmsg". Like opencode, the Hermes
plugin holds one multiplexed register.sock connection per Hermes process.
Registration and tools
Section titled “Registration and tools”- Registration: A session registers at the first
pre_llm_callhook orxmsgtool call that carries itssession_id. - Delegates (
delegate_task): Adelegate_tasksubagent (whosepre_llm_callnames its parent) acts as its root conversationPand does not bind a separate sub-address. - Tools (
xmsgtoolset): Exposesxmsg_list,xmsg_send,xmsg_reply, andxmsg_replies, sent as frames onregister.sockunder the callingsession_id. Because Hermes defers plugin tools behind its Tool Search bridge (tools.tool_search) by default, models discover and invoke them throughtool_searchandtool_call.
Session lifecycle and compaction
Section titled “Session lifecycle and compaction”- Ending a session (
on_session_finalize): Closing a desktop session, running/new, or exiting the CLI releases the session’s address (410 gone). Any late tool call from an ended session’s background delegate returnsgonewithout re-registering the old session. - Switching sessions in the CLI:
/newends the old session and registers the new one (on_session_reset). For/resumeand/branch(which fire no plugin hook), the plugin detects the changedsession_idon the next hook, tool call, or push and releases the old address so one session’s message is never injected into another. - Compression (
continues): Hermes’s default in-place compaction preservessession_idand itsxmsgaddress. Whencompression.in_place: falseis used, compression creates a newsession_id; the plugin readsSessionDB(read_only=True).get_compression_chainand sends acontinuesframe onregister.sockto move thexmsgaddress to the new session ID.
Push delivery and busy modes
Section titled “Push delivery and busy modes”- Classic CLI: While a turn is running, delivered messages route through the CLI’s busy-input
handler according to
display.busy_input_mode(or/busy):queueruns it as the next turn,interruptredirects the running turn, andsteerinjects it after the current tool call. When idle, it starts a new turn. - TUI and desktop host: Hermes’s
inject_messagequeues incoming messages on the session in all busy modes so a notification never cancels in-flight work. Requiresplugins.entries.xmsg.allow_gateway_injection: truein Hermes settings. - Acknowledgments: The plugin sends
ackonly after Hermes accepts the message.
Home Manager switch
Section titled “Home Manager switch”Set programs.xmsg.harnesses.hermes.enable = true (requires services.hermes-agent enabled) to
link the plugin into services.hermes-agent.extraPlugins, append "xmsg" to
settings.plugins.enabled, enable allow_gateway_injection, and install the xmsg skill. See
NixOS & Home Manager.
Palettes adapted from Catppuccin (Macchiato) (MIT), Tokyo Night (Apache-2.0), gruvbox (MIT), Catppuccin (Latte) (MIT), Rosé Pine (Dawn) (MIT).