Files
ajarbot/docs/HEARTBEAT_HOOKS.md
Jordan Ramos a99799bf3d 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>
2026-02-13 19:06:28 -07:00

3.6 KiB

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:

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:

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

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:

# 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:

# 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):

# 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.