Skip to content

feat: plugin-hook-example, reference plugin for transform_llm_output#1

Open
mvanhorn wants to merge 1 commit into
NousResearch:mainfrom
mvanhorn:feat/plugin-hook-example
Open

feat: plugin-hook-example, reference plugin for transform_llm_output#1
mvanhorn wants to merge 1 commit into
NousResearch:mainfrom
mvanhorn:feat/plugin-hook-example

Conversation

@mvanhorn
Copy link
Copy Markdown

@mvanhorn mvanhorn commented May 10, 2026

Adds a new reference plugin that fills the gap in the showcase: every
existing plugin's plugin.yaml has hooks: [] and only registers a
slash command. The lifecycle-hook surface is documented in the
hermes-agent developer-guide but has no companion example here.

Demo

plugin-hook-example demo

12 seconds: input text with SSN + API key -> transform_llm_output hook -> redacted output -> audit log entry.

What it does

plugin-hook-example demonstrates the smallest production-shaped
plugin code that uses transform_llm_output:

  • declares hooks: [transform_llm_output] in plugin.yaml
  • redact.py: pure-function redaction for SSN (with SSA-invalid
    block filtering), Luhn-valid credit cards, OpenAI/Anthropic keys,
    AWS access keys, and GitHub tokens. Patterns favour high precision
    so false positives stay rare in normal prose.
  • __init__.py: register(ctx) wires a single transform_llm_output
    hook that returns redacted text and emits one logger.info audit
    line per scan with kind counts.
  • README.md mirrors plugin-llm-example shape: what / why / how it
    works / audit output / try it.

Stays inside the contribution rules

  • Single-surface: one ctx.register_hook call, no commands.
  • Plugin code is 184 LOC (76 + 108), under the README's ~200 LOC
    ceiling. README + manifest add 132 lines on top.
  • No new dependencies beyond hermes-agent itself.
  • Production-shaped: real types, structured logger audit, overlap
    resolution, Luhn check, conservative regexes.

Note on process

The README asks contributors to open an issue first when proposing a
new surface, in case the docs page should land first. I went straight
to PR for review feedback on the shape. Happy to close this and file
an issue instead if you'd rather discuss the surface there first, or
to wait until the Plugin Hooks docs page is ready and align the
plugin to whatever final shape that page settles on.

Built with Claude Code (Opus 4.7).

…hook

Adds a new reference plugin that fills the gap in the showcase: every
existing plugin's plugin.yaml has hooks: [] and only registers a
slash command. The lifecycle-hook surface is documented in the
hermes-agent developer-guide but has no companion example.

plugin-hook-example demonstrates the smallest production-shaped
plugin code that uses the transform_llm_output hook:

- declares `hooks: [transform_llm_output]` in plugin.yaml
- redact.py: pure-function redaction for SSN (with SSA-invalid block
  filtering), Luhn-valid credit cards (13-19 digits), OpenAI/Anthropic
  keys, AWS access keys, and GitHub tokens. Patterns favour high
  precision so false positives stay rare in normal prose.
- __init__.py: register(ctx) wires a single transform_llm_output hook
  that returns redacted text and emits one logger.info audit line per
  scan with kind counts (e.g. `redacted 2 span(s) from 1284-char
  output [openai_key=1, ssn=1]`).
- README.md mirrors plugin-llm-example shape (what / why / how it
  works / try it / license).

Stays under the README's ~200 LOC ceiling for plugin code (76 LOC in
__init__.py, 108 in redact.py). Single-surface: one ctx.register_hook
call, no commands or other registrations. No new dependencies.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@mvanhorn mvanhorn force-pushed the feat/plugin-hook-example branch from 99fe6ee to 99f7397 Compare May 10, 2026 22:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant