-
Notifications
You must be signed in to change notification settings - Fork 0
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.
$engine = new Agent_Engine();
$result = $engine->execute_prompt('Create a blog post about AI', [
'provider' => 'openai',
'model' => 'gpt-5.2',
]);$engine->execute_prompt_stream('Create a blog post', $args, function($event) {
// SSE events: thinking, action, step, result, tokens, approval
});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
The system prompt is dynamically built with:
- Base instructions - Strict JSON output format, no markdown
- ACTION_CATALOG - JSON array of all registered actions with schemas
- SITE_CONTEXT - Site name, URL, post types, plugins, themes, active theme, brand palette
- MCP_TOOL_CATALOG - Available MCP tools (if MCP is enabled)
- MEMORY_CONTEXT - Relevant agent memories (up to 8 items, 1200 chars)
- CONVERSATION_CONTEXT - Previous conversation turns (up to 3 turns, 3000 chars)
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
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
}
]
}The engine handles various LLM response formats through normalization:
- Unwraps nested containers (
response,agent,result,data) - Maps alternative field names (
action_name/tool/function→action) - Maps alternative param names (
arguments/args/input→params) - Maps alternative thought names (
reasoning/explanation→thought) - Handles string-encoded params (JSON decode)
- Truncates thoughts to 200 characters
The agent can return up to 6 ordered actions in a single response. The engine:
- Extracts the
actions[]array (orsteps[]) - Executes each action sequentially via
Action_Executor - Stops on first failure or approval requirement
- Streams progress events for each step
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 |
When a prompt mentions "delete" + "user" + contains an email, the engine coerces wp_get_users to delete_user directly, skipping the lookup step.
When the LLM returns action: "none", the engine returns the reply or thought field as a message without executing any action.
| 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.
OpenWP v0.1.4 | GitHub Repository | GPLv2+