Initial commit: kage-research project files
This commit is contained in:
335
hermes-tool-guide.md
Normal file
335
hermes-tool-guide.md
Normal file
@@ -0,0 +1,335 @@
|
||||
# Hermes Tool Implementation Guide
|
||||
|
||||
## Overview
|
||||
|
||||
This document explains how to create a Hermes tool that integrates with external services (like Pi agent).
|
||||
|
||||
---
|
||||
|
||||
## What is a Hermes Tool?
|
||||
|
||||
A Hermes tool is a Python function that:
|
||||
1. **Hermes calls** when the agent decides to use it
|
||||
2. **Receives parameters** from the LLM
|
||||
3. **Does work** (calls external services, runs commands, etc.)
|
||||
4. **Returns a string** that Hermes shows to the agent
|
||||
|
||||
---
|
||||
|
||||
## Tool Structure
|
||||
|
||||
Every Hermes tool needs:
|
||||
|
||||
```python
|
||||
def my_tool(param1: str, param2: Optional[int] = None) -> str:
|
||||
"""
|
||||
Tool description that LLM sees.
|
||||
|
||||
Args:
|
||||
param1: Description
|
||||
param2: Description
|
||||
|
||||
Returns:
|
||||
What the tool returns
|
||||
"""
|
||||
# Do work here
|
||||
return "result"
|
||||
|
||||
def check_my_tool_requirements() -> bool:
|
||||
"""Check if tool can be used (e.g., external service available)."""
|
||||
return True
|
||||
|
||||
# Schema for LLM
|
||||
MY_TOOL_SCHEMA = {
|
||||
"name": "my_tool",
|
||||
"description": "What the tool does",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"param1": {"type": "string", "description": "..."},
|
||||
},
|
||||
"required": ["param1"]
|
||||
}
|
||||
}
|
||||
|
||||
# Register
|
||||
registry.register(
|
||||
name="my_tool",
|
||||
toolset="my_toolset", # Group in Hermes config
|
||||
schema=MY_TOOL_SCHEMA,
|
||||
handler=lambda args, **kw: my_tool(**args),
|
||||
check_fn=check_my_tool_requirements,
|
||||
emoji="📦",
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Key Components
|
||||
|
||||
### 1. Function Handler
|
||||
```python
|
||||
def my_tool(param1: str, ...) -> str:
|
||||
# Work
|
||||
return "result as string"
|
||||
```
|
||||
|
||||
### 2. Requirements Check
|
||||
```python
|
||||
def check_my_tool_requirements() -> bool:
|
||||
# Check external service, API key, etc.
|
||||
return True # or False if not available
|
||||
```
|
||||
|
||||
### 3. Schema (JSON)
|
||||
```python
|
||||
MY_TOOL_SCHEMA = {
|
||||
"name": "tool_name",
|
||||
"description": "What it does (LLM reads this!)",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"param1": {"type": "string", "description": "..."},
|
||||
},
|
||||
"required": ["param1"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Registry
|
||||
```python
|
||||
registry.register(
|
||||
name="tool_name",
|
||||
toolset="toolset_name", # Enable in config
|
||||
schema=SCHEMA,
|
||||
handler=lambda args, **kw: my_tool(**args),
|
||||
check_fn=check_requirements,
|
||||
emoji="📦",
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Example: Pi Agent Tool
|
||||
|
||||
See `pi_agent_tool.py` for a working example.
|
||||
|
||||
### Flow
|
||||
```
|
||||
User: "Fix the bug in auth.py"
|
||||
↓
|
||||
Hermes Agent decides to use pi_agent tool
|
||||
↓
|
||||
Calls pi_agent_tool(message="Fix the bug...")
|
||||
↓
|
||||
Tool calls HTTP server (Level 4)
|
||||
↓
|
||||
HTTP server runs Pi agent
|
||||
↓
|
||||
Returns response to Hermes
|
||||
↓
|
||||
Hermes shows to user
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## How to Use
|
||||
|
||||
### 1. Start Pi Server (Level 4)
|
||||
```bash
|
||||
npx tsx level4.ts
|
||||
```
|
||||
|
||||
### 2. Add Tool to Hermes
|
||||
|
||||
Option A: Copy to Hermes tools
|
||||
```bash
|
||||
cp pi_agent_tool.py ~/.hermes/hermes-agent/tools/
|
||||
```
|
||||
|
||||
Option B: Add to Python path or custom tools directory
|
||||
|
||||
### 3. Enable in Hermes Config
|
||||
|
||||
```yaml
|
||||
# In config.yaml
|
||||
toolset:
|
||||
- pi_agent
|
||||
```
|
||||
|
||||
### 4. Use in Conversation
|
||||
|
||||
```
|
||||
User: Can you fix the bug in auth.py?
|
||||
|
||||
Hermes: *uses pi_agent tool*
|
||||
|
||||
Tool result: Fixed the bug by changing line 42...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tool Best Practices
|
||||
|
||||
### 1. Always Return a String
|
||||
```python
|
||||
# Good
|
||||
return "Result: found 5 files"
|
||||
|
||||
# Bad
|
||||
return {"result": "found 5"} # JSON must be stringified
|
||||
```
|
||||
|
||||
### 2. Handle Errors Gracefully
|
||||
```python
|
||||
try:
|
||||
# Do work
|
||||
return result
|
||||
except Exception as e:
|
||||
return f"Error: {str(e)}"
|
||||
```
|
||||
|
||||
### 3. Add Requirements Check
|
||||
```python
|
||||
def check_requirements() -> bool:
|
||||
# Check API keys, services, etc.
|
||||
return api_key is not None
|
||||
```
|
||||
|
||||
### 4. Write Clear Descriptions
|
||||
```python
|
||||
# Good - LLM knows when to use
|
||||
"""
|
||||
Analyze the codebase for security vulnerabilities.
|
||||
Use after finding potential issues.
|
||||
"""
|
||||
|
||||
# Bad - LLM confused
|
||||
"""Do something"""
|
||||
```
|
||||
|
||||
### 5. Keep Schema Simple
|
||||
- Only include needed parameters
|
||||
- Mark required parameters
|
||||
- Add descriptions for each parameter
|
||||
|
||||
---
|
||||
|
||||
## Testing
|
||||
|
||||
### 1. Test the Function Directly
|
||||
```python
|
||||
# In Python
|
||||
result = pi_agent_tool(message="Say hello")
|
||||
print(result)
|
||||
```
|
||||
|
||||
### 2. Test with curl
|
||||
```bash
|
||||
curl -X POST http://localhost:3000/message \
|
||||
-d '{"message": "Hello"}'
|
||||
```
|
||||
|
||||
### 3. Test with Hermes
|
||||
- Add to toolset
|
||||
- Ask Hermes to use the tool
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Tool Not Found
|
||||
- Check tool is in `~/.hermes/hermes-agent/tools/`
|
||||
- Check it's in the toolset config
|
||||
|
||||
### Tool Not Available
|
||||
- Check `check_*_requirements()` returns `True`
|
||||
- Check external service is running
|
||||
|
||||
### Tool Called but No Response
|
||||
- Check tool returns a string
|
||||
- Check for exceptions in handler
|
||||
|
||||
---
|
||||
|
||||
## Integration Options: HTTP vs Direct Spawn
|
||||
|
||||
There are two ways to integrate Pi agent with Hermes:
|
||||
|
||||
### Option 1: HTTP Server (Current Implementation)
|
||||
|
||||
```
|
||||
Hermes → Python Tool → HTTP Request → Node/TS Server → Pi Agent
|
||||
```
|
||||
|
||||
```python
|
||||
# In tool
|
||||
import requests
|
||||
response = requests.post("http://localhost:3000/message", json={"message": "..."})
|
||||
return response.json()["response"]
|
||||
```
|
||||
|
||||
**Pros:**
|
||||
- Easy to test/debug (curl, logs)
|
||||
- Stateful (agent stays alive between calls)
|
||||
- Reuses connections
|
||||
- Easier monitoring/rate-limiting
|
||||
|
||||
**Cons:**
|
||||
- More complex (two services)
|
||||
- HTTP overhead (~50ms per call)
|
||||
- Server must stay running
|
||||
|
||||
### Option 2: Direct Spawn (Alternative)
|
||||
|
||||
```
|
||||
Hermes → Python Tool → Spawn Process → Pi Wrapper
|
||||
```
|
||||
|
||||
```python
|
||||
# In tool
|
||||
import subprocess
|
||||
process = subprocess.Popen(["npx", "tsx", "pi-wrapper.ts", message],
|
||||
stdout=subprocess.PIPE)
|
||||
stdout, _ = process.communicate(timeout=300)
|
||||
return stdout.decode()
|
||||
```
|
||||
|
||||
**Pros:**
|
||||
- Simpler (one process per call)
|
||||
- No server to maintain
|
||||
- Matches Kugetsu's current pattern
|
||||
- Good for low traffic
|
||||
|
||||
**Cons:**
|
||||
- Slow startup (~100-500ms per call)
|
||||
- No state between calls
|
||||
- Harder to debug
|
||||
- Resource heavy under load
|
||||
|
||||
### Comparison Table
|
||||
|
||||
| Factor | HTTP Server | Direct Spawn |
|
||||
|--------|-------------|--------------|
|
||||
| Latency | ~50ms | ~100-500ms |
|
||||
| Memory | Persistent (50-100MB) | Per-call |
|
||||
| State | Yes | No |
|
||||
| Complexity | Higher | Lower |
|
||||
| Debugging | Network logs | Process logs |
|
||||
| Best For | Production | POC/Simple |
|
||||
|
||||
### Recommendation
|
||||
|
||||
- **High load / Production**: HTTP Server
|
||||
- **Low load / POC**: Direct Spawn
|
||||
- **Matches Kugetsu pattern**: Direct Spawn
|
||||
|
||||
---
|
||||
|
||||
## Files in This Project
|
||||
|
||||
| File | Description |
|
||||
|------|-------------|
|
||||
| `pi_agent_tool.py` | Working Hermes tool (HTTP approach) |
|
||||
| `level4.ts` | HTTP server |
|
||||
| `hermes-tool-guide.md` | This document |
|
||||
Reference in New Issue
Block a user