OMH Plugin (v2)

April 21, 2026 · View on GitHub

The optional Hermes plugin at plugins/omh/ adds custom tools and lifecycle hooks that eliminate infrastructure plumbing from skill prose. Skills work without it; the plugin reduces boilerplate and enables token-efficient role injection.

Install to ~/.hermes/plugins/omh/. Requires Python 3.10+ and pyyaml.

Role Prompts

Nine shared role prompts give subagents precise behavioral instructions:

RolePurposeUsed By
PlannerTask decomposition, sequencing, risk flagsralplan
ArchitectStructural review, boundary clarity, long-term maintainabilityralplan, ralph (final review)
CriticAdversarial challenge, assumption testing, stress testingralplan
ExecutorCode implementation, test-first, minimal changesralph
VerifierEvidence-based completion checking, read-only, pass/failralph
AnalystRequirements extraction, hidden constraints, acceptance criteriadeep-interview, autopilot
Security ReviewerVulnerabilities, trust boundaries, injection vectorsautopilot (validation phase)
Test EngineerTest strategy, coverage, edge cases, flaky test hardeningautopilot (QA phase)
Code ReviewerDiff review, conventions, holistic qualityautopilot (validation phase)
DebuggerRoot cause analysis, hypothesis testing, minimal targeted fixesralph (error diagnosis)

Source files: plugins/omh/references/role-{name}.md.

How Role Injection Works

With the v2 plugin installed, skills use [omh-role:NAME] markers in the delegate_task goal string instead of embedding role prompt text inline:

delegate_task(
    goal="[omh-role:executor] Implement the following task:\n\n<task>...",
    context="<project context only>"
)

The Hermes pre_llm_call hook fires at the start of each subagent session, detects the marker in user_message (which equals the goal string), loads the matching role file from plugins/omh/references/role-{name}.md, and injects it into the subagent's system prompt via {"context": ...}. The role text never passes through the parent agent's context window.

A pre_tool_call hook validates [omh-role:NAME] markers before the subagent starts, warning immediately on unknown role names (fail-fast for typos).

Fallback: omh_state(action="load_role", role="NAME") returns the role prompt as a string for skills that need it explicitly.

Debug mode: Set OMH_DEBUG=1 (env var) or debug: true in config.yaml to see injection events:

[OMH DEBUG] pre_tool_call: delegate_task with role 'executor' detected
[OMH DEBUG] pre_llm_call: injecting role 'executor' into subagent system prompt

Components

ComponentWhat It DoesStatus
omh_state tool (8 actions)Atomic read/write/check/cancel for .omh/ state files; load_role action for explicit role loadingShipped
omh_gather_evidence toolRuns build/test/lint commands from an allowlist, captures + truncates outputShipped
pre_llm_call hookDetects [omh-role:NAME] in subagent user_message; injects matching role prompt into system contextShipped
pre_tool_call hookValidates [omh-role:NAME] markers in delegate_task goals before subagents start; warns on unknown rolesShipped
on_session_end hookWrites _interrupted_at to active mode state on unexpected exitShipped
Model tier routingMaps roles to Haiku/Sonnet/Opus via configRoadmap

The key architectural insight for role injection: delegate_task passes goal as user_message to the subagent's run_conversation(). The pre_llm_call hook receives this as user_message on is_first_turn=True, making it the natural injection point — no new Hermes primitives required.

v1 vs v2 Skill Prose

Skills express intent instead of mechanism. Compare delegation between the two versions:

# v1 skill prose (verbose — role text inlined, state loaded manually)
Load the executor role from ~/.hermes/skills/omh-ralplan/references/role-executor.md
and pass it in the context field of delegate_task alongside the task definition...

# v2 skill prose (concise — hook handles injection)
delegate_task(goal="[omh-role:executor] Implement: {task}", context="{project context}")

Development

pip install -e ".[dev]"
python -m pytest plugins/omh/tests/