Convention-correct helper library for registering hermes-agent plugin
commands, tools, middleware, hooks, and skills.
This repository is an installable Python package, not a path-loaded runtime
plugin.
- Keep
@tool, slash-default@command, andregister_allbackward compatible. Use@command(type="cli")for terminal subcommands and@command(type="slash")for explicit in-session commands; use@middleware,@hook,plugin_skill, andregister_pluginfor full plugin lifecycle registration. - Use
load_plugin_configfor effectiveplugins.<name>runtime settings; current HermesPluginManifestobjects do not expose profile config. Useconfigure_stderr_loggingfor operator-gated registration receipts instead of rebuilding per-plugin stderr handlers. - Keep lifecycle registration receipts centralized in
log_registration_summary; preserve its stable field order and actual command, tool, middleware, hook, skill, and skipped optional skill names.register_pluginmust emit exactly one receipt through that helper. - Use
@tool(schema=...)when a consumer already owns a valid Hermes function schema; do not translate it through a second argument-spec format. Keepschemaandparamsexclusive, deep-copy supplied schemas, and preserve schema-required fields even whenvalidate_required=Falsedelegates missing-argument errors to a legacy handler. - Runtime-gated consumers should pass their active decorated callables to
register_pluginwith an explicit receipt identity. Iterable registration must retain module registration's duplicate checks, deterministic ordering, skills, andRegistrationSummarycontract. - Use
resolve_capability_selectionwhen several runtime-gated surfaces form one authorization unit. Capability membership belongs to the plugin, not deployment configuration; explicit-name selection remains mutually exclusive for narrow legacy surfaces. Registration preflight must finish before the firstctx.register_*mutation, and receipts must name selected capabilities. - Consumer plugins must pin this package to an immutable commit, not a moving branch. Profiles that install multiple plugins into one Python environment must keep every consumer on the same kit revision.
- Use
invoke_host_toolfor host-managed capabilities such assend_message; do not assume every Hermes capability is registered intools.registry. Nested host calls must remain visible topre_tool_callandpost_tool_call. - Keep host invocation grounded in the real Hermes contract suite. For media delivery, exercise target parsing and platform formatting and mock only the final network client rather than replacing the host handler.
- Plugins must use
MediaPayload+deliver_mediafor attachments. The kit owns Hermes media directives, task-localoriginresolution, route redaction, the typed result, successful-send final-response suppression, and the narrow Telegramspoiler=Truephoto extension. Spoiler delivery must retain Hermes pre/post-tool hooks, route privacy, topic forwarding, and explicit Bot client shutdown; normal media must remain on host-managedsend_message. Consumers must registertransform_media_delivery_outputas Hermes'transform_llm_outputhook andclear_media_delivery_stateason_session_end; they must not recreate those contracts or substitute OpenClaw response shapes. - Use
tool_name(namespace, verb, noun)for new tools and prefer explicit verbs such asread,write, andpatch. Do not use Hermes agent-loop names (memory,todo,session_search,delegate_task) as plugin tools. - Preserve the Hermes tool schema convention: arguments live under
function.parameters, never as flattened top-level schema fields. - Tool handlers must accept
(args, **kwargs)and return JSON-compatible dictionaries unless deliberately returning an already-encoded string. - Keep validation errors instructive for model-facing callers, including the missing argument name and example when available.
- Keep stateful Hermes provider ABCs as provider instances: register memory, image-generation, and video-generation providers through their specialized contexts instead of decorating provider methods as general plugin surfaces.
- Register at most one real Hermes
ContextEnginethroughregister_plugin. Finish every registrar, identity, type, declaration, and provider preflight before submitting it or mutating another host registry. Keep engine schemas and recovery dispatch onget_tool_schemas/handle_tool_call; do not duplicate native engine tools through@tool. - Redact secret-looking values in logs and avoid logging full untrusted payloads.
- Use
uvand thejustfilefor local development:just install,just test,just test-one tests.test_kit.SchemaConventionTests, andjust build.
When changing conventions or exported helpers, update README.md examples and
tests together so consuming Hermes plugins have a reliable migration path.
Keep skills/hermes-plugins/references/plugin-kit.md aligned with public API
and contract changes so the repo-owned authoring skill does not teach stale
behavior.