Skip to main content

Overview

OrcBot’s autonomy system enables the agent to work proactively in the background, performing scheduled tasks, following up on conversations, and optimizing its own behavior based on productivity metrics.

How Autonomy Works

Basic Configuration

Enable Autonomy

# ~/.orcbot/orcbot.config.yaml

# Enable autonomous operation
autonomyEnabled: true

# Heartbeat interval in milliseconds (5 minutes)
autonomyInterval: 300000

# Maximum number of tasks in backlog before pausing autonomy
autonomyBacklogLimit: 10

# Channels where agent can send proactive updates
autonomyAllowedChannels:
  - telegram
  - discord

Start with Autonomy

# Foreground mode
orcbot run

# Background daemon mode
orcbot run --daemon

# Check daemon status
orcbot daemon status

Smart Heartbeat System

The smart heartbeat is context-aware and productivity-driven:

Exponential Backoff

When unproductive, heartbeat intervals automatically increase:
if (!productive) {
  currentInterval *= 2;  // Double the interval
  maxInterval = autonomyInterval * 8;  // Cap at 8x base interval
}

// Example:
// Base: 5 minutes
// 1st unproductive: 10 minutes
// 2nd unproductive: 20 minutes  
// 3rd unproductive: 40 minutes
// Maximum: 40 minutes (8x base)

Productivity Tracking

The system measures actual work vs. idle cycles:
interface ProductivityMetrics {
  totalHeartbeats: number;
  productiveHeartbeats: number;
  idleHeartbeats: number;
  totalActionsCreated: number;
  avgActionsPerHeartbeat: number;
  productivityRate: number;  // Percentage
}
Productivity criteria:
  • Created new task
  • Sent message to user
  • Updated memory or journal
  • Executed skill with meaningful result
  • Made progress on existing task

Context-Aware Actions

The agent analyzes recent activity to determine relevant actions:
const recentMemories = this.memory.getRecentContext(20);
const recentConversations = this.memory.getThreadContext();
const pendingTasks = this.actionQueue.getQueue();

// Decide on action type based on context
if (hasUnfinishedConversation) {
  actionType = 'follow_up';
} else if (hasResearchTopic) {
  actionType = 'research';
} else if (shouldUpdateJournal) {
  actionType = 'maintenance';
} else if (hasScheduledTask) {
  actionType = 'scheduled';
}

Action Types

The autonomous system supports different action types:

Follow-Up Actions

Continue conversations that need closure:
action_type: follow_up
description: "Continue discussion about deployment strategy with Alice"
context:
  - Last message: 2 hours ago
  - Topic: Kubernetes migration
  - Status: Waiting for Alice's decision
Triggers:
  • Unanswered question from user
  • Task marked “pending user input”
  • Conversation ended without resolution

Outreach Actions

Proactively check in with contacts:
action_type: outreach  
description: "Check in with Bob about Q4 planning"
context:
  - Last contact: 3 days ago
  - Pending: Q4 roadmap review
  - Relationship: regular collaborator
Triggers:
  • Regular check-in schedule
  • Milestone approaching
  • Previous conversation flagged for follow-up

Research Actions

Learn about topics from recent discussions:
action_type: research
description: "Research latest developments in vector databases"
context:
  - Mentioned in: 3 conversations this week
  - User interest: high
  - Knowledge gap: identified
Triggers:
  • Topic mentioned multiple times
  • User asked for information
  • Knowledge base needs updating

Maintenance Actions

Journal updates, memory consolidation:
action_type: maintenance
description: "Consolidate episodic memories and update journal"
context:
  - Short memories: 25 (threshold: 20)
  - Last consolidation: 6 hours ago
  - Journal entries pending: 3
Triggers:
  • Memory threshold exceeded
  • Daily summary needed
  • Learning entries to process

Delegate Actions

Spawn worker agents for parallel tasks:
action_type: delegate
description: "Spawn researcher agent to analyze competitor landscape"
context:
  - Task complexity: high
  - Estimated duration: 30+ minutes
  - Parallelizable: yes
Triggers:
  • Complex multi-step task
  • Independent subtasks identified
  • Main agent busy with other work

Channel Policy

Control where the agent can send proactive messages:

Direct Responses

Always allowed on any channel where user messages the bot:
User (Telegram): "What's my schedule?"
Bot  (Telegram): "You have 3 meetings today..."

✅ Allowed - Direct response to user message

Proactive Updates

Only allowed on channels in autonomyAllowedChannels:
autonomyAllowedChannels:
  - telegram  # ✅ Agent can message Telegram proactively
  - discord   # ✅ Agent can message Discord proactively
  # WhatsApp not listed → ❌ Agent won't send unprompted messages
Example:
# Scheduled reminder (proactive)
Bot (Telegram): "⏰ Reminder: Team standup in 15 minutes"
✅ Allowed - Telegram is in autonomyAllowedChannels

# Background insight (proactive) 
Bot (WhatsApp): "I noticed a pattern in your calendar..."
❌ Blocked - WhatsApp not in autonomyAllowedChannels

Default Behavior

autonomyAllowedChannels: []  # Empty list
Result: Silent in background mode
  • No proactive messages sent
  • Still processes incoming messages
  • Still executes scheduled tasks (logs only)

Scheduling System

One-Time Tasks

Use schedule_task skill:
schedule_task(
  when: "in 2 hours",
  task: "Send daily report to Frederick on Telegram"
)

schedule_task(
  when: "2024-03-15 14:00",
  task: "Remind me to join the board meeting"
)
Supported formats:
  • Relative: "in 30 minutes", "in 2 hours", "in 3 days"
  • Absolute: "2024-03-15 14:00", "March 15 at 2pm"
  • Natural: "tomorrow at 9am", "next Monday"

Recurring Tasks

Use heartbeat_schedule skill with cron syntax:
// Every weekday at 9 AM
heartbeat_schedule(
  schedule: "0 9 * * 1-5",
  task: "Send morning briefing with news and calendar"
)

// Every hour
heartbeat_schedule(
  schedule: "0 * * * *",
  task: "Check server health metrics"
)

// Every Monday at 10 AM
heartbeat_schedule(
  schedule: "0 10 * * 1",
  task: "Weekly team sync reminder"
)
Cron format: minute hour day month weekday
# Every 5 minutes
*/5 * * * *

# Every hour at :30
30 * * * *

# Every day at 6 PM
0 18 * * *

# Every weekday at 9 AM
0 9 * * 1-5

# First day of month at midnight  
0 0 1 * *

View Scheduled Tasks

User: "What tasks are scheduled?"

Bot:  Scheduled Tasks:
      
      ⏰ One-time:
      - 2024-03-15 14:00: Board meeting reminder
      - 2024-03-16 09:00: Send weekly report
      
      🔁 Recurring:
      - 0 9 * * 1-5: Morning briefing (next: tomorrow 9am)
      - 0 18 * * *: Daily summary (next: today 6pm)

Backlog Management

Backlog Limit

Prevent queue overflow:
autonomyBacklogLimit: 10
When queue size ≥ limit:
  • Autonomy pauses (no new autonomous tasks)
  • Still processes incoming user messages
  • Resumes when queue drops below limit
Logs:
Autonomy: Backlog limit reached (10 tasks). Pausing autonomous actions.
Autonomy: Queue cleared below limit (7 tasks). Resuming.

Pause/Resume Autonomy

# Temporarily disable
autonomyEnabled: false

# Re-enable (hot-reload, no restart needed)
autonomyEnabled: true
Or via skill:
manage_config({
  action: "set",
  key: "autonomyEnabled",
  value: false,
  reason: "Pausing autonomy for maintenance"
})

Completion Audit System

Prevents premature task completion:

Audit Codes

When OrcBot blocks completion, logs include an audit code:
AUDIT_BLOCK: ACK_ONLY+UNSENT_RESULTS
CodeMeaningFix
NO_SENDNo user-visible reply sentSend message before completing
UNSENT_RESULTSTool output not delivered to userSend final results message
NO_SUBSTANTIVEOnly status updates sentSend concrete findings
ACK_ONLYOnly acknowledgment sentFollow with detailed response
ERROR_UNRESOLVEDTool error without recoveryExplain failure or retry
GENERICUncategorized issueCheck action memories

Example Audit Flow

// User asks for research
User: "Find the latest price of Bitcoin"

// Agent performs web search
Action: web_search("Bitcoin price")
Result: "$52,340 USD as of March 2024"

// Agent tries to complete without sending result
Action: complete_task()

// ❌ Blocked by audit system
Audit: "UNSENT_RESULTS - Search results not delivered to user"

// Agent sends results first
Action: send_message("Bitcoin is currently $52,340 USD")

// ✅ Now completion allowed
Action: complete_task()

View Audit Logs

# Search daemon logs for audit blocks
tail -f ~/.orcbot/daemon.log | grep AUDIT_BLOCK

# Check action memories
grep "completion-audit-blocked" ~/.orcbot/memory.json

Multi-Agent Orchestration

Spawn worker agents for parallel tasks:

Spawn Worker Agent

spawn_agent(
  name: "researcher",
  role: "worker"
)

Delegate Task

delegate_task(
  task: "Analyze competitor pricing strategies",
  priority: 5
)

Worker Process Management

Workers appear in TUI:
┌─── Workers ──────────────┐
│ PID    | Name       | Status  │
├────────────────────────┤
│ 12345  | researcher | Running │
│ 12346  | analyst    | Running │
└────────────────────────┘
Features:
  • Real Node.js child processes via fork()
  • IPC communication with main agent
  • Shared configuration
  • Isolated execution
  • Automatic cleanup on completion

Productivity Metrics

Track Productivity

View productivity stats:
User: "Show autonomy metrics"

Bot:  Autonomy Productivity:
      
      Total Heartbeats: 50
      Productive: 32 (64%)
      Idle: 18 (36%)
      
      Actions Created: 45
      Avg per Heartbeat: 0.9
      
      Current Interval: 5 minutes
      Next Heartbeat: in 3m 12s

Interpret Metrics

Indicators:
  • Creating useful tasks regularly
  • Following up on conversations
  • Maintaining knowledge base
Action: Maintain current settings

Advanced Configuration

Fine-Tune Intervals

# Base heartbeat interval (milliseconds)
autonomyInterval: 300000  # 5 minutes

# Custom intervals for different scenarios
autonomyIntervalWhenIdle: 600000      # 10 min when idle
autonomyIntervalWhenBusy: 180000      # 3 min when busy
autonomyMaxBackoffMultiplier: 8       # Max 8x base interval

Context Limits

# How much context to analyze during heartbeat
autonomyContextLimit: 20              # Recent memories to review
autonomyThreadContextLimit: 10        # Conversation threads
autonomyJournalContextLimit: 500      # Journal chars to consider

Action Selection

# Prefer certain action types
autonomyPreferredActions:
  - maintenance   # Prioritize memory consolidation
  - research      # Then knowledge updates
  - follow_up     # Then conversation follow-ups

Best Practices

Start Conservative

Begin with longer intervals and fewer allowed channels:
autonomyInterval: 600000  # 10 minutes
autonomyAllowedChannels:
  - telegram  # Just one channel
Gradually tune based on productivity metrics.

Monitor Backlog

Keep backlog limit reasonable:
autonomyBacklogLimit: 10  # Prevents queue overflow
If frequently hitting limit, either:
  • Increase limit
  • Increase interval
  • Reduce autonomous task creation

Use Channel Policy

Don’t spam users with proactive messages:
autonomyAllowedChannels:
  - telegram  # Your personal channel only
# Don't add work Slack/Discord

Review Audit Logs

Periodically check for completion blocks:
grep AUDIT_BLOCK ~/.orcbot/daemon.log
Frequent blocks indicate agent is trying to complete tasks prematurely.

Troubleshooting

Autonomy Not Running

1

Check Config

autonomyEnabled: true  # Must be enabled
2

Check Daemon

orcbot daemon status
# Should show: "Running (PID: 12345)"
3

Check Logs

tail -f ~/.orcbot/daemon.log | grep -i autonomy
Should see heartbeat ticks every interval
4

Check Backlog

orcbot ui
# View queue in TUI
If backlog ≥ limit, autonomy is paused

Too Many Autonomous Tasks

Symptoms:
  • Queue constantly full
  • Hitting backlog limit frequently
  • Agent seems “spammy”
Solutions:
  1. Increase interval:
    autonomyInterval: 900000  # 15 minutes
    
  2. Reduce allowed channels:
    autonomyAllowedChannels:
      - telegram  # Remove others
    
  3. Increase backlog limit temporarily:
    autonomyBacklogLimit: 20
    

Low Productivity

Symptoms:
  • Productivity rate < 40%
  • Interval backed off to maximum
  • Few actions created
Possible causes:
  1. No pending work:
    • Agent has nothing to do
    • This is normal during quiet periods
  2. Empty allowed channels:
    autonomyAllowedChannels: []  # Nothing allowed!
    
    Add at least one channel.
  3. Waiting for user input:
    • Agent is blocked on clarification
    • Check for pending questions

Heartbeat Not Firing

# Check event bus
grep "scheduler:tick" ~/.orcbot/logs/orcbot.log

# Should see ticks every interval
If no ticks:
  • Scheduler may not be initialized
  • Check for errors in startup logs
  • Restart OrcBot

Example Workflows

Daily Briefing

# Config
autonomyEnabled: true
autonomyAllowedChannels:
  - telegram

# Scheduled task
heartbeat_schedule(
  schedule: "0 8 * * 1-5",  # Weekdays at 8 AM
  task: "Send daily briefing: weather, news, calendar, and reminders"
)
Result:
Every weekday at 8 AM:

Bot (Telegram):
  🌤️ Good morning! Here's your daily briefing:
  
  Weather: 72°F, Partly cloudy
  
  📰 Top News:
  - AI regulation update
  - Tech stocks rally
  
  📅 Today's Calendar:
  - 10:00 AM: Team standup
  - 2:00 PM: Client call
  - 4:00 PM: Code review
  
  ⏰ Reminders:
  - Finish Q1 report (due tomorrow)

Background Research

# Agent notices repeated topic mentions
Topic detected: "Rust programming language"
Mentioned in: 4 conversations this week

# Autonomous research action
Action: research
Description: "Learn about Rust programming language and its use cases"

# Agent performs web search, reads docs, updates learning

# Later in conversation
User: "Should we use Rust for the new service?"

Bot:  Based on my research:
      
      Rust Strengths:
      - Memory safety without garbage collection
      - High performance (comparable to C++)
      - Strong concurrency support
      
      Trade-offs:
      - Steeper learning curve
      - Slower compilation times
      - Smaller ecosystem than Go/Node.js
      
      Recommendation: Good fit if performance and safety
      are critical. Consider Go if team velocity is priority.

Conversation Follow-Up

# Morning conversation
User: "I need to decide on the cloud provider by Friday"
Bot:  "I'll help you research options. AWS, GCP, or Azure?"
User: "Compare all three for our use case"
Bot:  "I'll prepare a comparison. Talk later!"

# Autonomous follow-up (3 hours later)
Action: follow_up
Context: "User needs cloud provider decision by Friday (2 days away)"

# Agent performs research

# Proactive update
Bot (Telegram):
  I've completed the cloud provider comparison you requested:
  
  [Sends detailed report with pricing, features, pros/cons]
  
  Based on your requirements, I recommend GCP:
  - 23% cheaper for your workload
  - Better Kubernetes integration
  - Simpler pricing structure
  
  Would you like me to prepare a migration plan?