Goal Engine
The Goal Engine enables WASP to execute complex, multi-step objectives asynchronously. Instead of processing a request in a single conversation turn, the Goal Engine creates persistent goals that run in the background.
Overview
User: "Monitor BTC price and alert me when it crosses $70k"
│
▼
GoalOrchestrator.create_goal()
│
▼
PlanGenerator → TaskGraph
┌─────────────────────────────┐
│ Task 1: Subscribe to BTC │
│ Task 2: Check price loop │
│ Task 3: Send alert if >70k │
└─────────────────────────────┘
│
▼ (GoalTickJob runs every 15s)
Execute tasks → update state → complete
Key Components
GoalOrchestrator (src/goal_orchestrator/orchestrator.py)
The main coordinator. Responsibilities:
- Creates and persists goals in Redis (
goalshash) - Ticks active goals via
GoalTickJob - Manages up to 3 concurrent goals (configurable)
- Handles budget enforcement (tokens, replans, memory)
- Sorts goals by priority (user=8, agent=6, autonomous=3)
PlanGenerator (src/goal_orchestrator/planner.py)
Converts a natural language objective into a TaskGraph:
- Uses the LLM with a 4,000-token planning budget
- Generates a DAG of tasks with dependencies
- Skill list in prompt is capped at 1,200 characters (
PLAN_SKILL_BUDGET) - Output is a structured JSON TaskGraph
TaskGraph
The execution plan — a directed acyclic graph of tasks:
TaskGraph(
tasks=[
Task(id="t1", description="Search for current BTC price", skill="web_search"),
Task(id="t2", description="Check if price > threshold", depends_on=["t1"]),
Task(id="t3", description="Send Telegram alert", depends_on=["t2"]),
],
parallel_groups=[["t1"]], # Tasks that can run in parallel
)
PlanCritic (src/goal_orchestrator/plan_validator.py)
A second LLM pass validates generated plans before execution:
- Checks for logical gaps, missing error handling, impossible tasks
- Can reject the plan and trigger regeneration
- Uses 1,200 tokens (fast, lightweight validation)
- Enabled via
PLAN_CRITIC_ENABLED=true(default)
Goal States
PENDING → PLANNING → ACTIVE → COMPLETED
↘ ↗
PAUSED → ACTIVE (auto-resume)
↘
FAILED
| State | Description |
|---|---|
PENDING | Goal created, not yet started |
PLANNING | PlanGenerator running |
ACTIVE | Tasks executing |
PAUSED | Backpressure or waiting (auto-resumes) |
COMPLETED | All tasks done, summary sent |
FAILED | Max replans or budget exceeded |
Budget Controls
The Goal Engine enforces strict budgets to prevent runaway execution:
| Setting | Default | Description |
|---|---|---|
GOAL_BUDGET_MAX_TOKENS_PLANNING | 4,000 | Token limit for plan generation |
GOAL_BUDGET_MAX_TOKENS_EXECUTION | 20,000 | Total execution token budget |
GOAL_BUDGET_MAX_REPLANS | 5 | Max plan regenerations per goal |
GOAL_BUDGET_MAX_MEMORY_BYTES | 1 MiB | Working memory limit per goal |
GOAL_DEFAULT_MAX_STEPS | 50 | Max task steps before forced completion |
GOAL_DEFAULT_MAX_RUNTIME | 3600s | 1-hour hard timeout |
Priority System
Goals are prioritized 1-10 and sorted before each tick:
| Source | Priority | Description |
|---|---|---|
| User request | 8 | Direct user message |
| Agent-created | 6 | From sub-agent |
| Autonomous | 3 | From AutonomousGoalGeneratorJob |
| Default | 5 | Unspecified source |
Autonomy Modes
| Mode | Description |
|---|---|
full | Execute all tasks without asking (default in Sovereign Mode) |
semi | Confirm destructive or external actions |
assist | Request approval for every action |
Completion Synthesis
When a goal completes, WASP sends a rich Telegram message:
- Summary of what was accomplished
- Key outputs from tasks
- Time taken and resources used
Example: Creating a Goal via API
# Via dashboard API
curl -X POST https://agentwasp.com/api/goals \
-H "Content-Type: application/json" \
-d '{
"objective": "Monitor ETH price hourly for 24 hours, log to memory",
"priority": 8,
"source": "user"
}'
Replan Loop
If a plan fails mid-execution, the Goal Engine can replan:
- Analyzes what failed and why
- Generates a new TaskGraph accounting for partial progress
- Resumes from the last successful task
- Limited to
GOAL_BUDGET_MAX_REPLANS(default: 5)
Stability Protections
To prevent thrashing:
REPLAN_STORM_COUNT = 6— max replans in a 10-minute windowCONSECUTIVE_FAILURE_LIMIT = 5— fail goal after 5 consecutive failures- PAUSED goals auto-resume after backoff, fail after 10 minutes paused