Skip to content

Agent Engine

Harish Dhanraj Sugandhi edited this page Mar 4, 2026 · 1 revision

Agent Engine

The Agent_Engine (inc/Agent/Agent_Engine.php) is the brain of OpenWP. It transforms natural language prompts into structured actions by orchestrating LLM providers and the action execution pipeline.

Two Execution Modes

Synchronous (execute_prompt)

$engine = new Agent_Engine();
$result = $engine->execute_prompt('Create a blog post about AI', [
    'provider' => 'openai',
    'model'    => 'gpt-5.2',
]);

Streaming (execute_prompt_stream)

$engine->execute_prompt_stream('Create a blog post', $args, function($event) {
    // SSE events: thinking, action, step, result, tokens, approval
});

Execution Flow

1. Validate prompt (non-empty)
2. Check kill switches (OPENWP_DISABLE_AGENT, settings kill_switch)
3. Resolve provider and model (from args or settings defaults)
4. Create provider client via Provider_Factory
5. Rate limiter enforcement
6. Build system prompt
7. Request agent decision from LLM
8. Parse and validate JSON response
9. Expand action plan (single or multi-action)
10. Execute each action via Action_Executor
11. Record token usage
12. Return result

System Prompt Construction

The system prompt is dynamically built with:

  1. Base instructions - Strict JSON output format, no markdown
  2. ACTION_CATALOG - JSON array of all registered actions with schemas
  3. SITE_CONTEXT - Site name, URL, post types, plugins, themes, active theme, brand palette
  4. MCP_TOOL_CATALOG - Available MCP tools (if MCP is enabled)
  5. MEMORY_CONTEXT - Relevant agent memories (up to 8 items, 1200 chars)
  6. CONVERSATION_CONTEXT - Previous conversation turns (up to 3 turns, 3000 chars)

Content Generation Instructions

The system prompt includes detailed instructions for generating Gutenberg block markup:

  • Use wp:heading, wp:paragraph, wp:list, wp:columns, wp:buttons, etc.
  • Generate real Unsplash URLs or placehold.co for images
  • Apply brand palette colors via inline styles
  • Include at least one CTA button per page

Agent Response Schema

The LLM must return exactly this JSON structure:

{
    "thought": "string (max 200 chars)",
    "action": "string (registered action key or 'none')",
    "params": {},
    "confidence": 0.0-1.0,
    "actions": [                    // Optional: ordered multi-action plan
        {
            "action": "string",
            "params": {},
            "thought": "string",
            "confidence": 0.0-1.0
        }
    ]
}

Response Normalization

The engine handles various LLM response formats through normalization:

  • Unwraps nested containers (response, agent, result, data)
  • Maps alternative field names (action_name/tool/functionaction)
  • Maps alternative param names (arguments/args/inputparams)
  • Maps alternative thought names (reasoning/explanationthought)
  • Handles string-encoded params (JSON decode)
  • Truncates thoughts to 200 characters

Multi-Action Plans

The agent can return up to 6 ordered actions in a single response. The engine:

  1. Extracts the actions[] array (or steps[])
  2. Executes each action sequentially via Action_Executor
  3. Stops on first failure or approval requirement
  4. Streams progress events for each step

SSE Event Types

When using streaming mode, these events are emitted:

Event Type Fields Description
thinking content LLM text delta (streaming thought)
action action, params About to execute an action
step step, total, status Multi-step progress
result status, message Action execution result
approval approval_id, action, risk Action queued for approval
tokens input, output Token usage summary

Special Behaviors

User Delete Coercion

When a prompt mentions "delete" + "user" + contains an email, the engine coerces wp_get_users to delete_user directly, skipping the lookup step.

No-Action Response

When the LLM returns action: "none", the engine returns the reply or thought field as a message without executing any action.

Default Provider/Model Resolution

Provider Default Model
OpenAI gpt-5.2
Anthropic claude-3-5-sonnet-latest
GLM glm-5
OpenRouter anthropic/claude-sonnet-4-5

All defaults are configurable via settings.

Clone this wiki locally