Initial commit: Ajarbot with optimizations
Features: - Multi-platform bot (Slack, Telegram) - Memory system with SQLite FTS - Tool use capabilities (file ops, commands) - Scheduled tasks system - Dynamic model switching (/sonnet, /haiku) - Prompt caching for cost optimization Optimizations: - Default to Haiku 4.5 (12x cheaper) - Reduced context: 3 messages, 2 memory results - Optimized SOUL.md (48% smaller) - Automatic caching when using Sonnet (90% savings) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
136
docs/HEARTBEAT_HOOKS.md
Normal file
136
docs/HEARTBEAT_HOOKS.md
Normal file
@@ -0,0 +1,136 @@
|
||||
# Heartbeat & Hooks System
|
||||
|
||||
Simple Python implementation inspired by OpenClaw's automation patterns.
|
||||
|
||||
## Heartbeat
|
||||
|
||||
**What**: Periodic background check that reads `HEARTBEAT.md` and processes with LLM.
|
||||
|
||||
**How it works**:
|
||||
1. Runs every N minutes (default: 30)
|
||||
2. Only during active hours (default: 8am-10pm)
|
||||
3. Reads HEARTBEAT.md checklist
|
||||
4. Sends to LLM with context (SOUL, pending tasks, current time)
|
||||
5. Returns `HEARTBEAT_OK` if nothing needs attention
|
||||
6. Calls alert callback if action needed
|
||||
|
||||
**Files**:
|
||||
- `heartbeat.py` - Heartbeat implementation
|
||||
- `memory_workspace/HEARTBEAT.md` - Checklist (auto-created)
|
||||
|
||||
**Usage**:
|
||||
```python
|
||||
from heartbeat import Heartbeat
|
||||
|
||||
heartbeat = Heartbeat(memory, llm, interval_minutes=30, active_hours=(8, 22))
|
||||
heartbeat.on_alert = lambda msg: print(f"ALERT: {msg}")
|
||||
heartbeat.start()
|
||||
|
||||
# Test immediately
|
||||
result = heartbeat.check_now()
|
||||
```
|
||||
|
||||
## Hooks
|
||||
|
||||
**What**: Event-driven automation for agent lifecycle events.
|
||||
|
||||
**Events**:
|
||||
- `task:created` - When task added
|
||||
- `memory:synced` - After memory sync
|
||||
- `agent:startup` - Agent starts
|
||||
- `agent:shutdown` - Agent cleanup
|
||||
|
||||
**How it works**:
|
||||
1. Register handler functions for events
|
||||
2. System triggers events at key points
|
||||
3. All registered handlers run
|
||||
4. Handlers can add messages to event
|
||||
|
||||
**Files**:
|
||||
- `hooks.py` - Hooks system + example handlers
|
||||
|
||||
**Usage**:
|
||||
```python
|
||||
from hooks import HooksSystem, HookEvent
|
||||
|
||||
hooks = HooksSystem()
|
||||
|
||||
def my_hook(event: HookEvent):
|
||||
if event.type != "task" or event.action != "created":
|
||||
return
|
||||
print(f"Task: {event.context['title']}")
|
||||
event.messages.append("Logged!")
|
||||
|
||||
hooks.register("task:created", my_hook)
|
||||
hooks.trigger("task", "created", {"title": "Build feature"})
|
||||
```
|
||||
|
||||
## Integration with Agent
|
||||
|
||||
```python
|
||||
from agent import Agent
|
||||
|
||||
# Heartbeat runs in background
|
||||
agent = Agent(provider="claude", enable_heartbeat=True)
|
||||
|
||||
# Hooks auto-registered
|
||||
agent.hooks.register("task:created", my_custom_hook)
|
||||
|
||||
# Events trigger automatically
|
||||
task_id = agent.memory.add_task("Do something") # → task:created event
|
||||
|
||||
# Cleanup
|
||||
agent.shutdown() # → agent:shutdown event
|
||||
```
|
||||
|
||||
## OpenClaw Comparison
|
||||
|
||||
| Feature | OpenClaw | This Implementation |
|
||||
|---------|----------|---------------------|
|
||||
| Heartbeat | ✅ Main session, context-aware | ✅ Background thread, context-aware |
|
||||
| Interval | ✅ Configurable (default 30m) | ✅ Configurable (default 30m) |
|
||||
| Active hours | ✅ Start/end times | ✅ Start/end times (24h format) |
|
||||
| Checklist | ✅ HEARTBEAT.md | ✅ HEARTBEAT.md |
|
||||
| Alert suppression | ✅ HEARTBEAT_OK | ✅ HEARTBEAT_OK |
|
||||
| Hooks system | ✅ TypeScript, directory-based | ✅ Python, function-based |
|
||||
| Hook discovery | ✅ Auto-scan directories | ✅ Manual registration |
|
||||
| Event types | ✅ command, session, agent, gateway | ✅ task, memory, agent |
|
||||
| Async execution | ✅ In main event loop | ✅ Threading |
|
||||
|
||||
## Simple Extensions
|
||||
|
||||
**Add custom event**:
|
||||
```python
|
||||
# In your code
|
||||
agent.hooks.trigger("custom", "action", {"data": "value"})
|
||||
|
||||
# Register handler
|
||||
def on_custom(event):
|
||||
print(f"Custom: {event.context}")
|
||||
|
||||
agent.hooks.register("custom:action", on_custom)
|
||||
```
|
||||
|
||||
**Custom heartbeat checklist**:
|
||||
Edit `memory_workspace/HEARTBEAT.md`:
|
||||
```markdown
|
||||
# Heartbeat Checklist
|
||||
|
||||
- Check email (if integrated)
|
||||
- Review calendar events in next 2h
|
||||
- Check pending tasks > 24h old
|
||||
- System health check
|
||||
```
|
||||
|
||||
**Multi-check batching** (like OpenClaw):
|
||||
```python
|
||||
# Single heartbeat checks multiple things
|
||||
checklist = """
|
||||
- Email: Check inbox
|
||||
- Calendar: Events next 2h
|
||||
- Tasks: Pending > 24h
|
||||
- Memory: Sync status
|
||||
"""
|
||||
```
|
||||
|
||||
LLM processes all in one turn = more efficient than separate calls.
|
||||
Reference in New Issue
Block a user