mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
docs: update tool-adding instructions for auto-discovery
- AGENTS.md: 3 files → 2 files, remove _discover_tools() step - adding-tools.md: remove Step 3, note auto-discovery - architecture.md: update discovery description - tools-runtime.md: replace manual list with discover_builtin_tools() docs - hermes-agent skill: remove manual import step
This commit is contained in:
parent
fc6cb5b970
commit
ef04de3e98
5 changed files with 24 additions and 47 deletions
|
|
@ -13,7 +13,7 @@ source venv/bin/activate # ALWAYS activate before running Python
|
|||
```
|
||||
hermes-agent/
|
||||
├── run_agent.py # AIAgent class — core conversation loop
|
||||
├── model_tools.py # Tool orchestration, _discover_tools(), handle_function_call()
|
||||
├── model_tools.py # Tool orchestration, discover_builtin_tools(), handle_function_call()
|
||||
├── toolsets.py # Toolset definitions, _HERMES_CORE_TOOLS list
|
||||
├── cli.py # HermesCLI class — interactive CLI orchestrator
|
||||
├── hermes_state.py # SessionDB — SQLite session store (FTS5 search)
|
||||
|
|
@ -181,7 +181,7 @@ if canonical == "mycommand":
|
|||
|
||||
## Adding New Tools
|
||||
|
||||
Requires changes in **3 files**:
|
||||
Requires changes in **2 files**:
|
||||
|
||||
**1. Create `tools/your_tool.py`:**
|
||||
```python
|
||||
|
|
@ -204,9 +204,9 @@ registry.register(
|
|||
)
|
||||
```
|
||||
|
||||
**2. Add import** in `model_tools.py` `_discover_tools()` list.
|
||||
**2. Add to `toolsets.py`** — either `_HERMES_CORE_TOOLS` (all platforms) or a new toolset.
|
||||
|
||||
**3. Add to `toolsets.py`** — either `_HERMES_CORE_TOOLS` (all platforms) or a new toolset.
|
||||
Auto-discovery: any `tools/*.py` file with a top-level `registry.register()` call is imported automatically — no manual import list to maintain.
|
||||
|
||||
The registry handles schema collection, dispatch, availability checking, and error wrapping. All handlers MUST return a JSON string.
|
||||
|
||||
|
|
|
|||
|
|
@ -650,9 +650,9 @@ registry.register(
|
|||
)
|
||||
```
|
||||
|
||||
**2. Add import** in `model_tools.py` → `_discover_tools()` list.
|
||||
**2. Add to `toolsets.py`** → `_HERMES_CORE_TOOLS` list.
|
||||
|
||||
**3. Add to `toolsets.py`** → `_HERMES_CORE_TOOLS` list.
|
||||
Auto-discovery: any `tools/*.py` file with a top-level `registry.register()` call is imported automatically — no manual list needed.
|
||||
|
||||
All handlers must return JSON strings. Use `get_hermes_home()` for paths, never hardcode `~/.hermes`.
|
||||
|
||||
|
|
|
|||
|
|
@ -14,11 +14,12 @@ Make it a **Tool** when it requires end-to-end integration with API keys, custom
|
|||
|
||||
## Overview
|
||||
|
||||
Adding a tool touches **3 files**:
|
||||
Adding a tool touches **2 files**:
|
||||
|
||||
1. **`tools/your_tool.py`** — handler, schema, check function, `registry.register()` call
|
||||
2. **`toolsets.py`** — add tool name to `_HERMES_CORE_TOOLS` (or a specific toolset)
|
||||
3. **`model_tools.py`** — add `"tools.your_tool"` to the `_discover_tools()` list
|
||||
|
||||
Any `tools/*.py` file with a top-level `registry.register()` call is auto-discovered at startup — no manual import list required.
|
||||
|
||||
## Step 1: Create the Tool File
|
||||
|
||||
|
|
@ -124,19 +125,9 @@ _HERMES_CORE_TOOLS = [
|
|||
},
|
||||
```
|
||||
|
||||
## Step 3: Add Discovery Import
|
||||
## ~~Step 3: Add Discovery Import~~ (No longer needed)
|
||||
|
||||
In `model_tools.py`, add the module to the `_discover_tools()` list:
|
||||
|
||||
```python
|
||||
def _discover_tools():
|
||||
_modules = [
|
||||
...
|
||||
"tools.weather_tool", # <-- add here
|
||||
]
|
||||
```
|
||||
|
||||
This import triggers the `registry.register()` call at the bottom of your tool file.
|
||||
Tool modules with a top-level `registry.register()` call are auto-discovered by `discover_builtin_tools()` in `tools/registry.py`. No manual import list to maintain — just create your file in `tools/` and it's picked up at startup.
|
||||
|
||||
## Async Handlers
|
||||
|
||||
|
|
|
|||
|
|
@ -275,4 +275,4 @@ model_tools.py (imports tools/registry + triggers tool discovery)
|
|||
run_agent.py, cli.py, batch_runner.py, environments/
|
||||
```
|
||||
|
||||
This chain means tool registration happens at import time, before any agent instance is created. Adding a new tool requires an import in `model_tools.py`'s `_discover_tools()` list.
|
||||
This chain means tool registration happens at import time, before any agent instance is created. Any `tools/*.py` file with a top-level `registry.register()` call is auto-discovered — no manual import list needed.
|
||||
|
|
|
|||
|
|
@ -42,37 +42,23 @@ registry.register(
|
|||
|
||||
Each call creates a `ToolEntry` stored in the singleton `ToolRegistry._tools` dict keyed by tool name. If a name collision occurs across toolsets, a warning is logged and the later registration wins.
|
||||
|
||||
### Discovery: `_discover_tools()`
|
||||
### Discovery: `discover_builtin_tools()`
|
||||
|
||||
When `model_tools.py` is imported, it calls `_discover_tools()` which imports every tool module in order:
|
||||
When `model_tools.py` is imported, it calls `discover_builtin_tools()` from `tools/registry.py`. This function scans every `tools/*.py` file using AST parsing to find modules that contain top-level `registry.register()` calls, then imports them:
|
||||
|
||||
```python
|
||||
_modules = [
|
||||
"tools.web_tools",
|
||||
"tools.terminal_tool",
|
||||
"tools.file_tools",
|
||||
"tools.vision_tools",
|
||||
"tools.mixture_of_agents_tool",
|
||||
"tools.image_generation_tool",
|
||||
"tools.skills_tool",
|
||||
"tools.skill_manager_tool",
|
||||
"tools.browser_tool",
|
||||
"tools.cronjob_tools",
|
||||
"tools.rl_training_tool",
|
||||
"tools.tts_tool",
|
||||
"tools.todo_tool",
|
||||
"tools.memory_tool",
|
||||
"tools.session_search_tool",
|
||||
"tools.clarify_tool",
|
||||
"tools.code_execution_tool",
|
||||
"tools.delegate_tool",
|
||||
"tools.process_registry",
|
||||
"tools.send_message_tool",
|
||||
# "tools.honcho_tools", # Removed — Honcho is now a memory provider plugin
|
||||
"tools.homeassistant_tool",
|
||||
]
|
||||
# tools/registry.py (simplified)
|
||||
def discover_builtin_tools(tools_dir=None):
|
||||
tools_path = Path(tools_dir) if tools_dir else Path(__file__).parent
|
||||
for path in sorted(tools_path.glob("*.py")):
|
||||
if path.name in {"__init__.py", "registry.py", "mcp_tool.py"}:
|
||||
continue
|
||||
if _module_registers_tools(path): # AST check for top-level registry.register()
|
||||
importlib.import_module(f"tools.{path.stem}")
|
||||
```
|
||||
|
||||
This auto-discovery means new tool files are picked up automatically — no manual list to maintain. The AST check only matches top-level `registry.register()` calls (not calls inside functions), so helper modules in `tools/` are not imported.
|
||||
|
||||
Each import triggers the module's `registry.register()` calls. Errors in optional tools (e.g., missing `fal_client` for image generation) are caught and logged — they don't prevent other tools from loading.
|
||||
|
||||
After core tool discovery, MCP tools and plugin tools are also discovered:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue