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>
8.0 KiB
Control & Configuration Guide
❓ Key Question: What Does the Agent Control vs What Do I Control?
✅ You Control (100% of monitoring decisions)
| What | How |
|---|---|
| What to monitor | You define pulse checks in code/config |
| When to monitor | You set interval_seconds for each check |
| When to invoke brain | You define conditions (disk > 90%, errors found, etc.) |
| What prompts to use | You write the prompt templates |
| Where to send alerts | You specify platform and channel |
❌ Agent Does NOT Control
- ❌ The agent cannot decide what to monitor
- ❌ The agent cannot add new checks on its own
- ❌ The agent cannot change monitoring intervals
- ❌ The agent cannot start monitoring something you didn't ask for
🤖 Agent Only Does This
When YOU trigger the brain (via condition or schedule), the agent:
- ✅ Analyzes the data you give it
- ✅ Responds to the prompt you wrote
- ✅ Provides recommendations
The agent is a tool you invoke, not an autonomous system that picks tasks.
🎯 Three Levels of Control
Level 1: Use Example Checks (Easiest)
The default PulseBrain includes example checks:
pb = PulseBrain(agent)
pb.start()
What monitors by default:
- Disk space (every 5 min)
- Memory tasks (every 10 min)
- Log errors (every 1 min)
- Morning briefing (8:00 AM)
- Evening summary (6:00 PM)
You can disable any:
pb = PulseBrain(agent)
# Remove checks you don't want
pb.pulse_checks = [c for c in pb.pulse_checks if c.name != "log-errors"]
pb.brain_tasks = [t for t in pb.brain_tasks if t.name != "morning-briefing"]
pb.start()
Level 2: Start Clean, Add Only What You Want (Recommended)
pb = PulseBrain(agent)
# Clear all defaults
pb.pulse_checks = []
pb.brain_tasks = []
# Add ONLY what you want to monitor
pb.pulse_checks.append(
PulseCheck("my-check", my_function, interval_seconds=300)
)
pb.start()
Now it ONLY monitors what you explicitly added.
Level 3: Message-Driven (Most Control)
The agent only monitors when you send a message:
from agent import Agent
agent = Agent(provider="claude")
# No Pulse & Brain at all
# No TaskScheduler
# No automated monitoring
# Agent only responds when YOU message it:
response = agent.chat("Check if the server is running")
Zero automation. Full manual control.
📝 Configuration Examples
Example 1: Only Monitor Disk Space
pb = PulseBrain(agent)
pb.pulse_checks = [] # Clear all
pb.brain_tasks = []
# Add ONE check
def check_disk():
import shutil
usage = shutil.disk_usage(".")
percent = (usage.used / usage.total) * 100
return {
"status": "error" if percent > 90 else "ok",
"percent": percent
}
pb.pulse_checks.append(PulseCheck("disk", check_disk, 600))
# Add ONE brain task
pb.brain_tasks.append(BrainTask(
name="disk-alert",
check_type=CheckType.CONDITIONAL,
prompt_template="Disk is {percent:.1f}% full. What should I delete?",
condition_func=lambda data: data["status"] == "error"
))
pb.start()
Result:
- Pulse checks disk every 10 minutes (zero cost)
- Brain ONLY invokes if disk > 90%
- Nothing else happens
Example 2: Only Morning Briefing (No Monitoring)
pb = PulseBrain(agent)
pb.pulse_checks = [] # No monitoring
pb.brain_tasks = []
# ONE scheduled brain task
pb.brain_tasks.append(BrainTask(
name="briefing",
check_type=CheckType.SCHEDULED,
schedule_time="08:00",
prompt_template="Good morning! What are my pending tasks?",
send_to_platform="slack",
send_to_channel="C12345"
))
pb.start()
Result:
- No pulse checks (zero monitoring)
- Brain invokes once per day at 8:00 AM
- Sends to Slack
Example 3: Zero Automation (Pure Chat Bot)
# Don't use Pulse & Brain at all
# Don't use TaskScheduler at all
from agent import Agent
from adapters.runtime import AdapterRuntime
agent = Agent(provider="claude")
runtime = AdapterRuntime(agent)
runtime.add_adapter(slack_adapter)
await runtime.start()
# Now the bot ONLY responds to user messages
# No monitoring, no automation, no scheduled tasks
Result:
- Bot only responds when users message it
- Zero background activity
- Zero automated brain invocations
🔍 How to Know What's Running
Check Configuration Before Starting
pb = PulseBrain(agent)
print("Pulse checks that will run:")
for check in pb.pulse_checks:
print(f" - {check.name} (every {check.interval_seconds}s)")
print("\nBrain tasks that will run:")
for task in pb.brain_tasks:
if task.check_type == CheckType.SCHEDULED:
print(f" - {task.name} (scheduled {task.schedule_time})")
else:
print(f" - {task.name} (conditional)")
# If you don't like what you see, modify before starting:
# pb.pulse_checks = [...]
# pb.brain_tasks = [...]
pb.start()
Monitor Runtime Activity
pb.start()
# Check how many times brain was invoked
status = pb.get_status()
print(f"Brain invoked {status['brain_invocations']} times")
print(f"Latest pulse data: {status['latest_pulse_data']}")
🛡️ Safety Guardrails
1. Explicit Configuration Required
Nothing monitors unless you:
- Define a
PulseCheckfunction - Add it to
pb.pulse_checks - Call
pb.start()
# This does NOTHING:
def my_check():
return {"status": "ok"}
# You must explicitly add it:
pb.pulse_checks.append(PulseCheck("my-check", my_check, 60))
2. Brain Only Invokes on YOUR Conditions
# Brain will NOT run unless:
BrainTask(
condition_func=lambda data: YOUR_CONDITION_HERE
# or
schedule_time="YOUR_TIME_HERE"
)
The agent cannot change these conditions.
3. No Self-Modification
The Pulse & Brain system cannot:
- Add new checks while running
- Modify intervals while running
- Change conditions while running
To change monitoring, you must:
- Stop the system
- Modify configuration
- Restart
pb.stop()
pb.pulse_checks.append(new_check)
pb.start()
💡 Recommended Approach
For Most Users: Start Clean
from agent import Agent
from pulse_brain import PulseBrain, PulseCheck, BrainTask, CheckType
agent = Agent(provider="claude")
pb = PulseBrain(agent)
# Remove all defaults
pb.pulse_checks = []
pb.brain_tasks = []
print("Starting with zero checks.")
print("Now YOU add only what you want to monitor.")
# Add checks one by one, with full understanding
pb.pulse_checks.append(PulseCheck(
name="thing-i-want-to-monitor",
check_func=my_check_function,
interval_seconds=300
))
pb.start()
Advanced: Use Configuration File
Create my_monitoring_config.py:
from pulse_brain import PulseCheck, BrainTask, CheckType
def check_server():
# Your check here
return {"status": "ok"}
MY_PULSE_CHECKS = [
PulseCheck("server", check_server, 60)
]
MY_BRAIN_TASKS = [
BrainTask(
name="server-down",
check_type=CheckType.CONDITIONAL,
prompt_template="Server is down. Help!",
condition_func=lambda d: d["status"] == "error"
)
]
Then in your main script:
from my_monitoring_config import MY_PULSE_CHECKS, MY_BRAIN_TASKS
pb = PulseBrain(agent)
pb.pulse_checks = MY_PULSE_CHECKS # Your config
pb.brain_tasks = MY_BRAIN_TASKS # Your config
pb.start()
Now your monitoring is:
- Version controlled
- Reviewable
- Explicit
- Under YOUR control
🎯 Summary
| Question | Answer |
|---|---|
| Who decides what to monitor? | YOU (via code/config) |
| Can agent add monitors? | NO |
| Can agent change intervals? | NO |
| Can agent modify conditions? | NO |
| What does agent control? | Only its responses to YOUR prompts |
| Can I start with zero automation? | YES (clear pulse_checks and brain_tasks) |
| Can I disable defaults? | YES (remove from lists before calling start()) |
Bottom line: The Pulse & Brain system is a framework YOU configure. The agent is a tool that executes YOUR monitoring strategy, not an autonomous system that decides what to watch.
You are in complete control. 🎛️