Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 25 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,26 @@
/vendor
/logs/*
!/logs/.gitkeep
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
/vendor
/.hot
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ wp plugin activate wp-agents

## REST API

Each agent can be accessed programmatically through the WordPress REST API.
Each agent can be accessed programmatically through the WordPress REST API.

This allows external systems or front-end applications to send a message to any registered agent and receive the model’s response in JSON format.

Expand Down Expand Up @@ -65,7 +65,9 @@ curl --location 'https://example.com/wp-json/wp-agents/v1/chat' \

## Demo

https://github.com/santerref/wp-agents-demo
We now provide an admin UI that lists all registered agents. From there, you can activate the built-in **Post Taxonomy Agent** to see a working example in action.

<img width="2826" height="1162" alt="Screenshot 2025-11-07 at 8 34 29 PM" src="https://github.com/user-attachments/assets/479cc0d9-b1eb-48b4-bc9b-57bf645a7543" />

## Roadmap

Expand Down
27 changes: 27 additions & 0 deletions inc/admin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

if ( ! function_exists( 'wp_agents_admin_page' ) ) {

add_action( 'admin_menu', function () {
add_menu_page(
'WP Agents',
'WP Agents',
'manage_options',
'wp-agents',
'wp_agents_admin_page',
'data:image/svg+xml;base64,' . base64_encode( '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30" fill="currentColor" baseProfile="basic"><path d="M14.217,19.707l-1.112,2.547c-0.427,0.979-1.782,0.979-2.21,0l-1.112-2.547c-0.99-2.267-2.771-4.071-4.993-5.057 L1.73,13.292c-0.973-0.432-0.973-1.848,0-2.28l2.965-1.316C6.974,8.684,8.787,6.813,9.76,4.47l1.126-2.714 c0.418-1.007,1.81-1.007,2.228,0L14.24,4.47c0.973,2.344,2.786,4.215,5.065,5.226l2.965,1.316c0.973,0.432,0.973,1.848,0,2.28 l-3.061,1.359C16.988,15.637,15.206,17.441,14.217,19.707z"/><path d="M24.481,27.796l-0.339,0.777c-0.248,0.569-1.036,0.569-1.284,0l-0.339-0.777c-0.604-1.385-1.693-2.488-3.051-3.092 l-1.044-0.464c-0.565-0.251-0.565-1.072,0-1.323l0.986-0.438c1.393-0.619,2.501-1.763,3.095-3.195l0.348-0.84 c0.243-0.585,1.052-0.585,1.294,0l0.348,0.84c0.594,1.432,1.702,2.576,3.095,3.195l0.986,0.438c0.565,0.251,0.565,1.072,0,1.323 l-1.044,0.464C26.174,25.308,25.085,26.411,24.481,27.796z"/></svg>' )
);
} );

function wp_agents_admin_page(): void {
echo '<div id="wp-agents-app"></div>';
}

add_action( 'admin_enqueue_scripts', function ( $hook ) {
if ( $hook !== 'toplevel_page_wp-agents' ) {
return;
}
wp_agents_vite_enqueue( 'src/main.ts' );
} );

}
77 changes: 77 additions & 0 deletions inc/assets.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

if ( ! function_exists( 'wp_agents_manifest' ) ) {

function wp_agents_vite_manifest(): array {
static $manifest;

if ( isset( $manifest ) ) {
return $manifest;
}

$file = WP_AGENTS_PLUGIN_DIR . 'dist/.vite/manifest.json';
if ( ! file_exists( $file ) ) {
return [];
}

$checksum = md5_file( $file );
$cache = get_option( 'wp_agents_vite_manifest_cache' );
$cache_hash = get_option( 'wp_agents_vite_manifest_hash' );

if ( $cache && $cache_hash === $checksum ) {
$manifest = $cache;

return $manifest;
}

ob_start();
readfile( $file );
$json = ob_get_clean();
$data = json_decode( $json, true );

update_option( 'vite_manifest_cache', $data, false );
update_option( 'vite_manifest_hash', $checksum, false );

$manifest = $data;

return $data;
}

}

if ( ! function_exists( 'wp_agents_vite_enqueue' ) ) {

function wp_agents_vite_enqueue( $entry ): void {
$hot_file = WP_AGENTS_PLUGIN_DIR . '.hot';

if ( file_exists( $hot_file ) ) {
ob_start();
readfile( $hot_file );
$dev = trim( ob_get_clean() );

wp_enqueue_script_module( 'vite-client', $dev . '/@vite/client', array(), null );
wp_enqueue_script_module( 'vite-entry', $dev . '/' . $entry, array(), null );

return;
}

$manifest = wp_agents_vite_manifest();
if ( ! isset( $manifest[ $entry ] ) ) {
return;
}

$plugin_data = get_plugin_data( WP_AGENTS_PLUGIN_DIR . 'wp-agents.php' );

$asset = $manifest[ $entry ];
$base = WP_AGENTS_PLUGIN_URL . 'dist/';

if ( ! empty( $asset['css'] ) ) {
foreach ( $asset['css'] as $css ) {
wp_enqueue_style( 'wp-agents-vite-' . md5( $css ), $base . $css, array(), $plugin_data['Version'] );
}
}

wp_enqueue_script( 'wp-agents-vite-' . md5( $asset['file'] ), $base . $asset['file'], array(), $plugin_data['Version'], true );
}

}
57 changes: 57 additions & 0 deletions inc/services.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

if ( ! function_exists( 'wp_agents_tool_manager' ) ) {

function wp_agents_tool_manager() {
static $tool_manager;

if ( ! isset( $tool_manager ) ) {
$tool_manager = new Wp_Agents_Services_Tool_Manager();
}

return $tool_manager;
}

}

if ( ! function_exists( 'wp_agents_rest' ) ) {

function wp_agents_rest() {
static $rest;

if ( ! isset( $rest ) ) {
$rest = new Wp_Agents_System_Rest();
}

return $rest;
}

}

if ( ! function_exists( 'wp_agents_agent_manager' ) ) {

function wp_agents_agent_manager() {
static $agent_manager;

if ( ! isset( $agent_manager ) ) {
$agent_manager = new Wp_Agents_Services_Agent_Manager();
}

return $agent_manager;
}

}

if ( ! function_exists( 'wp_agents_provider_manager' ) ) {

function wp_agents_provider_manager() {
static $provider_manager;

if ( ! isset( $provider_manager ) ) {
$provider_manager = new Wp_Agents_Services_Provider_Manager();
}

return $provider_manager;
}

}
97 changes: 97 additions & 0 deletions lib/agent/class-abstract.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php

abstract class Wp_Agents_Agent_Abstract {

protected array $definition = array(
'model' => 'gpt-4o-mini',
'provider' => 'openai',
'json' => false,
'tools' => array(),
'memory' => null,
'memory_limit' => null,
'instructions' => '',
'id' => '',
'version' => '',
'description' => '',
'name' => '',
'hooks' => array(),
'file' => null,
'dir' => null,
);

public function __construct( array $definition ) {
$definition = apply_filters( 'wp_agents_agent_definition', $definition );

$this->definition = array_merge(
$this->definition,
$definition
);
}

public function instructions(): string {
return $this->definition['instructions'];
}

public function prompt( mixed $input ): Wp_Agents_System_Agent_Runner {
return new Wp_Agents_System_Agent_Runner(
$input,
$this
);
}

public function id(): string {
return $this->definition['id'];
}

public function get_model(): string {
return $this->definition['model'];
}

public function get_provider(): string {
return $this->definition['provider'];
}

public function json(): bool {
return $this->definition['json'];
}

public function tools(): array {
return $this->definition['tools'];
}

public function hooks(): array {
return $this->definition['hooks'];
}

public function get_file(): ?string {
return $this->definition['file'];
}

public function is_enabled(): bool {
return wp_agents_agent_manager()->is_enabled( $this->definition['id'] );
}

public function get_memory( string $session_id ): ?Wp_Agents_Memory_Abstract {
if ( $this->definition['memory'] ) {
$memory_class = $this->definition['memory'];

return new $memory_class( $this->id(), $session_id );
}

return null;
}

public function to_array(): array {
return array(
'id' => $this->definition['id'],
'model' => $this->definition['model'],
'provider' => $this->definition['provider'],
'name' => $this->definition['name'],
'description' => $this->definition['description'],
'hooks' => $this->definition['hooks'],
'tools' => $this->definition['tools'],
'version' => $this->definition['version'],
'enabled' => $this->is_enabled(),
);
}
}
5 changes: 5 additions & 0 deletions lib/agent/class-base.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

class Wp_Agents_Agent_Base extends Wp_Agents_Agent_Abstract {

}
67 changes: 0 additions & 67 deletions lib/llm/class-abstract.php

This file was deleted.

2 changes: 1 addition & 1 deletion lib/providers/class-interface.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

interface Wp_Agents_Providers_Interface {

public function chat( Wp_Agents_System_Message_Stack $message_stack, Wp_Agents_Llm_Abstract $agent ): void;
public function chat( Wp_Agents_System_Message_Stack $message_stack, Wp_Agents_Agent_Abstract $agent ): void;

public function memorizable( Wp_Agents_System_Message $message ): bool;
}
Loading