Robin Fernandes
1126284c97
Merge branch 'main' into rewbs/tool-use-charge-to-subscription
2026-03-31 09:29:43 +09:00
Robin Fernandes
6e4598ce1e
Merge branch 'main' into rewbs/tool-use-charge-to-subscription
2026-03-31 08:48:54 +09:00
Wing Lian
efae525dc5
feat(plugins): add inject_message interface for remote message injection ( #3778 )
2026-03-30 02:48:06 -07:00
Robin Fernandes
1cbb1b99cc
Gate tool-gateway behind an env var, so it's not in users' faces until we're ready. Even if users enable it, it'll be blocked server-side for now, until we unlock for non-admin users on tool-gateway.
2026-03-30 13:28:10 +09:00
Teknium
0df4d1278e
feat(plugins): add enable/disable commands + interactive toggle UI ( #3747 )
...
Adds plugin management with three interfaces:
hermes plugins # interactive curses checklist (like hermes tools)
hermes plugins enable # non-interactive enable
hermes plugins disable # non-interactive disable
hermes plugins list # table with status column
Disabled plugins are stored in config.yaml under plugins.disabled and
skipped during discovery. Uses the same curses_checklist component as
hermes tools for the interactive UI.
Changes:
- hermes_cli/plugins.py: _get_disabled_plugins() + skip disabled during
discover_and_load()
- hermes_cli/plugins_cmd.py: cmd_toggle() interactive UI, cmd_enable(),
cmd_disable(), updated cmd_list() with status column
- hermes_cli/main.py: enable/disable subparser entries
- website/docs/reference/cli-commands.md: updated plugins section
- website/docs/user-guide/features/plugins.md: updated managing section
2026-03-29 10:39:57 -07:00
Teknium
455bf2e853
feat: activate plugin lifecycle hooks (pre/post_llm_call, session start/end) ( #3542 )
...
The plugin system defined six lifecycle hooks but only pre_tool_call and
post_tool_call were invoked. This activates the remaining four so that
external plugins (e.g. memory systems) can hook into the conversation
loop without touching core code.
Hook semantics:
- on_session_start: fires once when a new session is created
- pre_llm_call: fires once per turn before the tool-calling loop;
plugins can return {"context": "..."} to inject into the ephemeral
system prompt (not cached, not persisted)
- post_llm_call: fires once per turn after the loop completes, with
user_message and assistant_response for sync/storage
- on_session_end: fires at the end of every run_conversation call
invoke_hook() now returns a list of non-None callback return values,
enabling pre_llm_call context injection while remaining backward
compatible (existing hooks that return None are unaffected).
Salvaged from PR #2823 .
Co-authored-by: Nicolò Boschi <boschi1997@gmail.com >
2026-03-28 11:14:54 -07:00
Teknium
34be3f8be6
revert: remove trailing empty assistant message stripping
...
Reverts the sanitizer addition from PR #2466 (originally #2129 ).
We already have _empty_content_retries handling for reasoning-only
responses. The trailing strip risks silently eating valid messages
and is redundant with existing empty-content handling.
2026-03-22 04:55:34 -07:00
Teknium
8da410ed95
feat(plugins): add slash command registration for plugins ( #2359 )
...
Plugins can now register slash commands via ctx.register_command()
in their register() function. Commands automatically appear in:
- /help and COMMANDS_BY_CATEGORY (under 'Plugins' category)
- Tab autocomplete in CLI
- Telegram bot menu
- Slack subcommand mapping
- Gateway dispatch
Handler signature: handler(args: str) -> str | None
Async handlers are supported in gateway context.
Changes:
- commands.py: add register_plugin_command() and rebuild_lookups()
- plugins.py: add register_command() to PluginContext, track in
PluginManager._plugin_commands and LoadedPlugin.commands_registered
- cli.py: dispatch plugin commands in process_command()
- gateway/run.py: dispatch plugin commands before skill commands
- tests: 5 new tests for registration, help, tracking, handler, gateway
- docs: update plugins feature page and build guide
2026-03-21 16:00:30 -07:00
Test
10d719ac1b
fix(security): require opt-in for project plugin discovery
2026-03-20 20:50:30 -07:00
Teknium
97990e7ad5
feat: first-class plugin architecture ( #1555 )
...
Plugin system for extending Hermes with custom tools, hooks, and
integrations — no source code changes required.
Core system (hermes_cli/plugins.py):
- Plugin discovery from ~/.hermes/plugins/, .hermes/plugins/, and
pip entry_points (hermes_agent.plugins group)
- PluginContext with register_tool() and register_hook()
- 6 lifecycle hooks: pre/post tool_call, pre/post llm_call,
on_session_start/end
- Namespace package handling for relative imports in plugins
- Graceful error isolation — broken plugins never crash the agent
Integration (model_tools.py):
- Plugin discovery runs after built-in + MCP tools
- Plugin tools bypass toolset filter via get_plugin_tool_names()
- Pre/post tool call hooks fire in handle_function_call()
CLI:
- /plugins command shows loaded plugins, tool counts, status
- Added to COMMANDS dict for autocomplete
Docs:
- Getting started guide (build-a-hermes-plugin.md) — full tutorial
building a calculator plugin step by step
- Reference page (features/plugins.md) — quick overview + tables
- Covers: file structure, schemas, handlers, hooks, data files,
bundled skills, env var gating, pip distribution, common mistakes
Tests: 16 tests covering discovery, loading, hooks, tool visibility.
2026-03-16 07:17:36 -07:00