Skip to main content

Scheduler

WASP's scheduler runs 41 background jobs that keep the agent active, learning, and aware — even when no user is interacting. Jobs are registered in src/main.py and each implements a simple async callable interface.

Job Registry

Job NameIntervalPurpose
health_check5 minMonitor Redis, Postgres, Ollama, disk, RAM, CPU
reflection6 hoursLLM-driven memory reflection and synthesis
memory_cleanup24 hoursRemove old episodic memories, orphaned data
audit_retention24 hoursDelete audit_log entries older than 30 days (bounded batch)
db_maintenance7 daysVACUUM ANALYZE to reclaim dead-row space and update planner stats
snapshot24 hoursFull memory snapshot to /data/memory/
reminder_checker30 secFire due reminders, trigger agent goals for recurring reminders
monitor_checker5 minCheck price/RSS monitors for threshold violations
proactive1 hourSend proactive suggestions based on user context
promotion12 hoursPromote frequent episodic memories to semantic
checkin1 hourPeriodic user check-in messages
custom_task_runner1 minExecute user-defined scheduled tasks
subscription_checker5 minCheck price/RSS subscriptions for alerts
goal_tick15 secAdvance active goal execution (up to 3 steps per tick)
goal_meta_reflection5 minAnalyze goal health, detect storms, log meta-state
agent_tick15 secAdvance active sub-agent goals
dream1 hour (gated)Consolidate memories, reflect, prefetch data, analyze failure patterns
autonomous30 minEvaluate system state and generate proactive goals
digest24 hoursGenerate daily digest for user
cpi_monitor5 minCompute Cognitive Pressure Index
self_integrity6 hoursCross-check self-model vs actual performance
perception15 minMonitor crypto prices for significant moves
behavioral_learner2 minProcess user corrections into behavioral rules
world_model15 minUpdate entity states from world_timeline
skill_evolution6 hoursSynthesize new skills from recurring patterns
vector_index30 minIndex new memory entries into memory_embeddings for semantic search
capability_evolution1 hourEvolve and merge capability definitions in the Capability Engine index
capability_learner1 hourLearn new capabilities from successful multi-step executions in audit_log
opportunity_engine2 hoursScan episodic memory for automation opportunities
opportunities_processor5 minProcess and emit queued opportunity suggestions
execution_knowledge_sync5 minFlush Redis execution knowledge cache to PostgreSQL for durability
execution_intelligence_monitor10 minDetect evidence-based patterns in recent executions
kg_insights_updater30 minUpdate KG node salience scores and tool pattern cache
procedural_pruner24 hoursRemove stale/unused procedural memory entries
kg_pruner24 hoursControl Knowledge Graph node count (cap oldest low-salience nodes)
learning_pruner7 daysTrim learning_examples table to bounded size
behavioral_pruner30 daysArchive old behavioral rules that haven't been applied recently
execution_reflection_pruner6 hoursClean up old execution reflection records
browser_session_cleanup7 daysRemove stale Chromium session profile directories
screenshot_cleanup24 hoursDelete old screenshots from /data/screenshots/
kg_insights_updater30 minUpdate KG salience + tool pattern cache

Job Architecture

Jobs implement a simple async callable:

class DbMaintenanceJob:
async def __call__(self) -> str:
# execute maintenance logic
return "ok"

Registered in main.py:

scheduler.register("db_maintenance", 604800, DbMaintenanceJob())

The Scheduler manages all jobs:

  • Tracks last run time per job in Redis (scheduler:last_run:{job})
  • Logs scheduler.job_complete with job name and duration in ms
  • Handles exceptions without crashing other jobs
  • CPI guard: skips autonomous, dream, perception when agent:cpi_high is set

Key Jobs Explained

health_check (5 min)

Uses HealthMonitor to check:

  • Redis: PING
  • PostgreSQL: simple SELECT
  • Ollama: /api/tags endpoint
  • Disk: usage percentage
  • RAM: percent used
  • CPU: percent used

When thresholds exceeded, SelfHealer triggers remediation (disk cleanup, Ollama restart, etc.).

audit_retention (24 hours)

AuditRetentionJob keeps the audit_log table bounded. Runs daily. Deletes entries older than 30 days using a bounded batch strategy:

DELETE FROM audit_log
WHERE id IN (
SELECT id FROM audit_log
WHERE timestamp < NOW() - INTERVAL '30 days'
ORDER BY timestamp ASC
LIMIT 5000
)

This avoids table locks that a single large DELETE would cause. Configure retention:

AUDIT_RETENTION_DAYS=90  # default: 30

db_maintenance (weekly)

DbMaintenanceJob runs VACUUM ANALYZE weekly to keep PostgreSQL healthy:

  • Reclaims dead-row space for the free-space map
  • Updates planner statistics for better query plans
  • Does not lock tables (unlike VACUUM FULL)
  • Runs outside a transaction (AUTOCOMMIT isolation)

Note: VACUUM FULL (used in Panic Reset) rewrites the entire table for maximum disk reclamation but requires an exclusive lock. VACUUM ANALYZE (weekly) is the non-disruptive version for ongoing maintenance.

reminder_checker (30 sec)

Checks Redis for due reminders. For recurring reminders with an agent_id, calls agent_orchestrator.create_agent_goal() to restart the cycle. Regular reminders fire a Telegram message.

dream (1 hour, gated)

The Dream Mode job activates only when:

  • User has been inactive for more than 2 hours
  • Time is between 1 AM and 7 AM local, OR inactive for 4+ hours
  • Has not run in the last 6 hours
  • CPI is not high (agent:cpi_high is not set)

When activated, Dream Mode runs 7 steps:

  1. PromotionEngine (episodic → semantic promotion)
  2. KG entity extraction from recent memories
  3. LLM reflection on recent events
  4. Pre-fetch crypto prices for monitored assets
  5. Log to dream_log table, update agent:dream_state
  6. Memory consolidation via MemoryManager
  7. Failure pattern analysis — queries audit_log for 7-day errors, classifies into timeout / slow_response / repeated_failure / error, upserts into self_model["known_failures"]

autonomous (30 min)

The AutonomousGoalGeneratorJob evaluates system state:

  1. Checks critical thresholds (disk >95%, RAM >95%) — no LLM needed
  2. For non-critical situations, asks the LLM for proactive recommendations
  3. If action warranted: calls goal_orchestrator.create_goal() with priority=3
  4. Rate-limited: max 1 autonomous goal per hour, 5 per day
  5. Skipped when agent:cpi_high is set

perception (15 min)

BackgroundPerceptionJob monitors crypto assets in the Knowledge Graph:

  • Fetches current prices
  • Compares vs last known price in the temporal model
  • If change >4%, asks LLM whether to notify
  • Sends Telegram alert if notable (max 3/day, respects quiet hours)
  • Skipped when agent:cpi_high is set

behavioral_learner (2 min)

Checks Redis behavioral:pending queue for user corrections:

  • Correction detection patterns: "estás alucinando", "eso está mal", etc.
  • LLM analyzes correction and extracts a rule
  • Rule saved to behavioral_rules table
  • New rules cross-checked for conflicts with existing rules before saving
  • Rule injected into every future system prompt

skill_evolution (6 hours)

Analyzes skill_patterns table for recurring multi-skill sequences:

  • Minimum 5 occurrences required (configurable)
  • LLM synthesizes a new composite skill from the pattern
  • AST validation ensures generated code is safe
  • New skill registered and available immediately

Pruner Jobs

A set of lightweight maintenance jobs keep tables bounded:

JobIntervalWhat it prunes
procedural_pruner24hStale/unused procedural memory entries
kg_pruner24hLow-salience KG nodes over the cap
learning_pruner7 daysOldest learning_examples over the cap
behavioral_pruner30 daysOld inactive behavioral rules
execution_reflection_pruner6hOld execution reflection records
browser_session_cleanup7 daysStale Chromium session profile directories
screenshot_cleanup24hOld screenshots in /data/screenshots/

Scheduler State

View job status in the dashboard at /scheduler.

Query last run times:

docker exec agent-redis redis-cli KEYS "scheduler:last_run:*" | sort

Quiet Hours

Jobs that send Telegram notifications respect quiet hours:

  • Default: no notifications between 11 PM and 8 AM
  • Configurable via PROACTIVE_QUIET_START and PROACTIVE_QUIET_END

Disabling Jobs

Individual jobs can be skipped by disabling their feature flag:

SKILL_EVOLUTION_ENABLED=false  # Skips skill_evolution job
WORLD_MODEL_ENABLED=false # Skips world_model job
VECTOR_MEMORY_ENABLED=false # Skips vector_index job
BEHAVIORAL_LEARNING_ENABLED=false # Skips behavioral_learner job

Disable the entire scheduler:

SCHEDULER_ENABLED=false