L’API Abilities, introdotta in WordPress 6.9, definisce un linguaggio comune che permette a tutti i componenti di WordPress — sia del core che dei plugin — di esporre le proprie funzionalità in modo unificato e comprensibile sia per le persone che per le macchine. Questo rende il tuo sito WordPress pronto per l’integrazione con strumenti di automazione esterni in modo standardizzato e sicuro.
Se ti stai chiedendo quali potrebbero essere alcuni casi d’uso dell’API Abilities, pensa a un modello di intelligenza artificiale che guida un utente attraverso il processo di acquisto e gli permette persino di completare l’acquisto senza visitare il tuo sito e-commerce. Oppure pensa a una pipeline CI/CD su GitHub Actions che elabora il testo estratto da un file audio o video e lo invia a WordPress per la pubblicazione. I casi d’uso sono infiniti.
L’API Abilities cambia il ruolo stesso di WordPress all’interno dell’ecosistema. Non è più solo un blog, né tantomeno un CMS; oggi, WordPress funge da motore di esecuzione distribuito che può essere orchestrato dall’esterno, come una sorta di sistema operativo, pronto per gli agenti autonomi.
Non vedi l’ora di saperne di più? Approfondiamo l’argomento.
A cosa serve un “ability”
Un ability, o abilità, è una funzionalità individuabile e utilizzabile su un sito WordPress che consente operazioni specifiche per entità esterne (come i modelli di AI) o componenti interni.
L’API può essere usata per cose come:
- Cercare contenuti o eseguire operazioni specifiche sul database
- Leggere le impostazioni di configurazione del sito
- Creare un post
- Convertire una struttura JSON in blocchi Gutenberg
Rendere pubblica un’abilità significa rendere interoperabile una funzionalità specifica. Prima che un’abilità possa essere individuata e utilizzata, deve essere registrata in un catalogo centralizzato. Solo così WordPress e i modelli di AI potranno individuarla, comprenderne l’intento e richiamarla quando necessario.
Per impostazione predefinita, le funzionalità dei tuoi plugin sono completamente isolate. Registrando una capacità, dichiari che la logica sottostante è disponibile come servizio per l’intero ecosistema.
Vediamo un esempio. Se il tuo plugin ha una funzione che converte un oggetto JSON iniziale in contenuto strutturato pronto per i blocchi di Gutenberg, puoi registrarla come ability. Questo permette ad altri strumenti con le autorizzazioni necessarie di attivare esattamente la stessa funzione.
Nel nostro precedente tutorial sul WordPress AI Client, il plugin gestiva la logica principale dell’invio di un file audio al modello di AI, che restituiva una risposta strutturata in JSON per generare i blocchi Gutenberg. Tuttavia, quella funzionalità rimaneva limitata al nostro plugin. Registrando questo processo come “ability”, si disaccoppia l’esecuzione e qualsiasi entità esterna può attivare l’intera logica del plugin semplicemente passando un oggetto JSON contenente l’ID di un file audio.
Un’abilità funge da contratto formale tra la logica PHP sottostante e qualsiasi entità che ne richieda l’esecuzione. Il contratto specifica i dati che l’abilità si aspetta come input, il suo intento e lo schema dei dati che restituisce come output.
Quando registri un’abilità, questa viene aggiunta al registro delle abilità del tuo sito. Da quel momento in poi, WordPress funge da gateway sicuro: verifica l’autenticazione e convalida i dati in entrata rispetto allo schema stabilito dal contratto. WordPress inoltra la richiesta alla funzione PHP sottostante solo se il payload rispetta rigorosamente il contratto.
Un’abilità è indipendente dall’entità. WordPress non ha bisogno di conoscere l’entità specifica che richiede l’accesso; verifica solo che la richiesta sia autorizzata e soddisfi i vincoli del contratto.
Registrando un’abilità, il tuo plugin non è più solo un’estensione con una propria logica interna; diventa un fornitore di servizi per l’intero ecosistema. Che si tratti di un’app mobile, di uno script di automazione come Make.com o Zapier, di un agente AI o di un server che comunica tramite il protocollo MCP, queste entità sapranno esattamente come attivare operazioni strutturate sul tuo sito.
Come funziona l’API Abilities
L’API Abilities offre un set completo di funzioni che permettono di individuare le abilità registrate sul tuo sito, attivarle, registrarle e cancellarle.
Gestire le ability del sito
Puoi recuperare un elenco di tutte le abilità registrate o recuperare un singolo oggetto abilità. Puoi anche verificare alcune condizioni, ad esempio se una specifica abilità è registrata o se l’agente ha i permessi per attivarla.
Ottieni un elenco delle abilità registrate sul tuo sito
La funzione wp_get_abilities() restituisce un array contenente tutte le abilità registrate. Puoi provarla usando WP-CLI. Una eseguita la connessione al sito tramite SSH, vai nella directory principale del sito, dove si trova il file wp-config.php, usando i seguenti comandi:
cd /path/to/your/site
ls wp-config.php
Poi, assicurati che WP-CLI riconosca l’installazione del tuo sito:
wp core is-installed
wp option get siteurl
Se ottieni l’URL del sito, puoi eseguire il comando seguente:
wp eval '$abilities = wp_get_abilities(); foreach ( $abilities as $a ) { echo $a->get_name() . PHP_EOL; }'
Questo comando esegue il codice PHP nel tuo terminale. Il codice PHP richiede i nomi di tutte le abilità registrate sul sito e, per impostazione predefinita, dovrebbe fornire la seguente risposta:
core/get-site-info
core/get-user-info
core/get-environment-info
Puoi richiedere un set di dati più completo con il seguente comando:
wp eval '
$all_abilities = wp_get_abilities();
foreach ( $all_abilities as $ability ) {
echo "Ability Name: " . esc_html( $ability->get_name() ) . "n";
echo "Label: " . esc_html( $ability->get_label() ) . "n";
echo "Category: " . esc_html( $ability->get_category() ) . "n";
echo "Description: " . esc_html( $ability->get_description() ) . "n";
echo "---n";
}
'
Quando esegui questo comando su un sito WordPress 7.0 appena installato, il terminale mostrerà la seguente risposta:
Ability Name: core/get-site-info
Label: Get Site Information
Category: site
Description: Returns site information configured in WordPress. By default returns all fields, or optionally a filtered subset.
---
Ability Name: core/get-user-info
Label: Get User Information
Category: user
Description: Returns profile details for the current authenticated user to support personalization, auditing, and access-aware behavior. By default returns all fields, or optionally a filtered subset.
---
Ability Name: core/get-environment-info
Label: Get Environment Info
Category: site
Description: Returns core details about the site's runtime context for diagnostics and compatibility (environment, PHP runtime, database server info, WordPress version). By default returns all fields, or optionally a filtered subset.
---
Ottenere un oggetto “ability”
La funzione wp_get_ability() restituisce un singolo oggetto “ability” in base al suo nome. Puoi provarla in WP-CLI con il seguente comando:
wp eval '
$ability = wp_get_ability( "core/get-site-info" );
if ( ! $ability ) {
echo "Ability not foundn";
exit( 1 );
}
echo "Name: " . $ability->get_name() . "n";
echo "Label: " . $ability->get_label() . "n";
echo "Category: " . $ability->get_category() . "n";
echo "Description: " . $ability->get_description() . "n";
echo "nInput Schema:n";
var_dump( $ability->get_input_schema() );
echo "nOutput Schema:n";
var_dump( $ability->get_output_schema() );
echo "nMeta:n";
var_dump( $ability->get_meta() );
'
Se l’abilità è registrata correttamente sul tuo sito, riceverai la seguente risposta nel tuo terminale:
Name: core/get-site-info
Label: Get Site Information
Category: site
Description: Returns site information configured in WordPress. By default returns all fields, or optionally a filtered subset.
Input Schema:
array(4) {
["type"]=>
string(6) "object"
["properties"]=>
array(1) {
["fields"]=>
array(3) {
["type"]=>
string(5) "array"
["items"]=>
array(2) {
["type"]=>
string(6) "string"
["enum"]=>
array(8) {
[0]=>
string(4) "name"
[1]=>
string(11) "description"
[2]=>
string(3) "url"
[3]=>
string(5) "wpurl"
[4]=>
string(11) "admin_email"
[5]=>
string(7) "charset"
[6]=>
string(8) "language"
[7]=>
string(7) "version"
}
}
["description"]=>
string(81) "Optional: Limit response to specific fields. If omitted, all fields are returned."
}
}
["additionalProperties"]=>
bool(false)
["default"]=>
array(0) {
}
}
Output Schema:
array(3) {
["type"]=>
string(6) "object"
["properties"]=>
array(8) {
["name"]=>
array(3) {
["type"]=>
string(6) "string"
["title"]=>
string(10) "Site Title"
["description"]=>
string(15) "The site title."
}
["description"]=>
array(3) {
["type"]=>
string(6) "string"
["title"]=>
string(7) "Tagline"
["description"]=>
string(17) "The site tagline."
}
["url"]=>
array(3) {
["type"]=>
string(6) "string"
["title"]=>
string(18) "Site Address (URL)"
["description"]=>
string(94) "The public URL where visitors access the site. May differ from the WordPress installation URL."
}
["wpurl"]=>
array(3) {
["type"]=>
string(6) "string"
["title"]=>
string(23) "WordPress Address (URL)"
["description"]=>
string(83) "The URL where WordPress core files are served. May differ from the public site URL."
}
["admin_email"]=>
array(3) {
["type"]=>
string(6) "string"
["title"]=>
string(28) "Administration Email Address"
["description"]=>
string(37) "The site administrator email address."
}
["charset"]=>
array(3) {
["type"]=>
string(6) "string"
["title"]=>
string(12) "Site Charset"
["description"]=>
string(28) "The site character encoding."
}
["language"]=>
array(3) {
["type"]=>
string(6) "string"
["title"]=>
string(13) "Site Language"
["description"]=>
string(42) "The site locale in dash form (e.g. en-US)."
}
["version"]=>
array(3) {
["type"]=>
string(6) "string"
["title"]=>
string(17) "WordPress Version"
["description"]=>
string(48) "The WordPress core version running on this site."
}
}
["additionalProperties"]=>
bool(false)
}
Meta:
array(2) {
["annotations"]=>
array(3) {
["readonly"]=>
bool(true)
["destructive"]=>
bool(false)
["idempotent"]=>
bool(true)
}
["show_in_rest"]=>
bool(true)
}
Verificare se un’abilità è registrata
La funzionewp_has_ability() ti permette di verificare se un’abilità è registrata. In WP-CLI, puoi usarla in questo modo:
wp eval '
if ( wp_has_ability( "core/get-site-info" ) ) {
echo "✓ core/get-site-info is registeredn";
} else {
echo "✗ core/get-site-info not foundn";
}
'
Se l’abilità è stata registrata, sul terminale apparirà il seguente messaggio:
✓ core/get-site-info is registered
Verificare i permessi dell’agente
Puoi verificare se l’utente corrente ha i permessi per eseguire un’abilità utilizzando il metodo check_permissions() dell’oggetto $ability. Questo restituisce “true”, “false” o un oggetto WP_Error. Proviamo a chiamare questo metodo dal terminale utilizzando il seguente comando WP-CLI:
wp --user=1 eval '
$ability = wp_get_ability( "core/get-site-info" );
if ( $ability ) {
$has_permissions = $ability->check_permissions();
if ( true === $has_permissions ) {
echo "You have permissions to execute this ability.";
} else {
if ( is_wp_error( $has_permissions ) ) {
error_log( "Permissions check failed: " . $has_permissions->get_error_message() );
}
echo "You do not have permissions to execute this ability.";
}
} else {
echo "Ability not found.";
}
'
Qui abbiamo impostato --user=1, ed è per questo che riceverai la seguente risposta:
You have permissions to execute this ability.
Registrare un’abilità
È ora il momento di registrare un’abilità. Per illustrare un caso d’uso reale, estenderemo il plugin descritto nel nostro articolo sul WordPress AI Client. Il plugin invia un file audio al modello di AI per estrarre il testo e attivare la generazione di blocchi Gutenberg. In questa sezione vedremo come registrare questo processo come ability, in modo che qualsiasi entità con i permessi necessari possa individuarlo e utilizzarlo.
Prima di registrare una nuova abilità, devi registrare una nuova categoria di ability.
Per farlo, dovrai agganciare la funzione wp_register_ability_category() all’hook wp_abilities_api_categories_init.
La funzione accetta uno slug univoco della categoria e un array associativo di argomenti.
Ecco come registrare la tua categoria ability:
function aicb_register_ability_category(): void {
if ( ! function_exists( 'wp_register_ability_category' ) ) {
return;
}
wp_register_ability_category(
'content-generation',
array(
'label' => 'Content Generation',
'description' => 'AI-powered content transformation and structuring abilities',
)
);
}
add_action( 'wp_abilities_api_categories_init', 'aicb_register_ability_category' );
Il passo successivo è registrare l’abilità. Per farlo, dovrai collegare la funzionewp_register_ability() all’azione wp_abilities_api_init.
La funzione accetta due argomenti: il nome dell’abilità, compreso il suo namespace, e un array di argomenti per la configurazione dell’abilità.
Ecco la registrazione dell’abilità per il plugin AI Content Builder:
function aicb_register_audio_to_gutenberg_blocks_ability(): void {
if ( ! function_exists( 'wp_register_ability' ) ) {
return;
}
$input_schema = array( ... );
$output_schema = array( ... );
wp_register_ability(
'ai-content-builder/audio-to-gutenberg-blocks',
array(
'category' => 'content-generation',
'label' => 'Audio to Gutenberg Blocks',
'description' => 'Transcribes audio and converts the content into WordPress Gutenberg-compatible block objects.',
'input_schema' => $input_schema,
'output_schema' => $output_schema,
'execute_callback' => 'aicb_audio_to_gutenberg_blocks_callback',
'permission_callback' => static function (): bool {
return current_user_can( 'edit_posts' );
},
'meta' => array(
'show_in_rest' => true,
'annotations' => array(
'readonly' => false,
'destructive' => false,
'idempotent' => false,
'instructions' => 'Processes an audio attachment: transcribes it, generates structured blog content via AI, and returns Gutenberg-ready block objects.',
),
),
)
);
}
add_action( 'wp_abilities_api_init', 'aicb_register_audio_to_gutenberg_blocks_ability' );
Nella chiamata alla funzione wp_register_ability, abbiamo configurato i seguenti argomenti:
category: la categoria a cui appartiene l’abilità.label: il nome visualizzato dell’abilità.description: una breve descrizione di cosa fa l’abilità e del suo scopo.input_schema: lo schema dei dati per gli argomenti di input in entrata.output_schema: lo schema dei dati fornito e restituito dall’abilità.execute_callback: la funzione di callback da eseguire quando l’abilità viene attivata.permission_callback: una funzione di callback che viene eseguita per verificare che l’agente abbia i permessi necessari per eseguire l’abilità.meta: un array di campi di metadati aggiuntivi per l’abilità.show_in_rest: determina se rendere visibile o meno l’abilità all’interno dell’API REST di WordPress.annotations: un array di elementi descrittivi che definiscono il comportamento dell’abilità.
input_schema è un array che definisce il contratto di input dell’abilità. Rappresenta la definizione dello schema JSON per la convalida dell’input dell’abilità. Nel nostro caso specifico, è definito come segue:
$input_schema = array(
'type' => 'object',
'properties' => array(
'audio_id' => array(
'type' => 'integer',
'description' => 'The ID of the audio attachment to process and convert into Gutenberg blocks.',
),
),
'required' => array( 'audio_id' ),
);
Questo JSON Schema rappresenta il formato che i dati di input devono seguire per utilizzare questa ability.
output_schema è il contratto di output restituito dall’abilità. Nel nostro esempio, ogni elemento è un oggetto che rappresenta un blocco JSON:
$output_schema = array(
'type' => 'object',
'properties' => array(
'title' => array( 'type' => 'string' ),
'sections' => array(
'type' => 'array',
'items' => array( 'type' => 'object' ),
),
'blocks' => array(
'type' => 'array',
'items' => array( 'type' => 'object' ),
),
'transcript' => array( 'type' => 'string' ),
),
'required' => array( 'blocks' ),
);
Il passo successivo è definire la funzione di callback che si esegue quando l’abilità viene attivata (guarda il codice completo su GitHub):
function aicb_audio_to_gutenberg_blocks_callback( array $args ) {
// missing code
// see GitHub
...
$structured_json = wp_ai_client_prompt( $prompt )
->using_system_instruction( $instructions )
->using_temperature( 0.4 )
->as_json_response( $schema )
->generate_text();
if ( is_wp_error( $structured_json ) ) {
return $structured_json;
}
$structured = json_decode( (string) $structured_json, true );
if ( ! is_array( $structured ) ) {
return new WP_Error(
'invalid_ai_json',
'Could not parse structured AI response.',
array( 'status' => 500 )
);
}
// Normalize the output.
$normalized = aicb_normalize_structured_post( $structured );
if ( '' === $normalized['title'] && empty( $normalized['sections'] ) ) {
return new WP_Error(
'empty_structured_content',
'The AI provider returned empty structured content.',
array( 'status' => 500 )
);
}
// Convert to Gutenberg blocks.
$blocks = aicb_sections_to_blocks( $normalized['title'], $normalized['sections'] );
return $blocks;
}
Questa funzione chiama due funzioni personalizzate. La prima (aicb_normalize_structured_post) normalizza l’output dell’AI in un formato predefinito e pulisce i dati:
function aicb_normalize_structured_post( array $structured ): array {
$title = isset( $structured['title'] )
? sanitize_text_field( (string) $structured['title'] )
: '';
$sections = array();
if ( isset( $structured['sections'] ) && is_array( $structured['sections'] ) ) {
foreach ( $structured['sections'] as $section ) {
if ( ! is_array( $section ) ) {
continue;
}
$heading = isset( $section['heading'] )
? sanitize_text_field( (string) $section['heading'] )
: '';
$level = 2;
$paragraphs = array();
if ( isset( $section['paragraphs'] ) && is_array( $section['paragraphs'] ) ) {
foreach ( $section['paragraphs'] as $paragraph ) {
$clean_paragraph = trim( sanitize_textarea_field( (string) $paragraph ) );
if ( '' !== $clean_paragraph ) {
$paragraphs[] = $clean_paragraph;
}
}
}
$bullet_points = array();
if ( isset( $section['bullet_points'] ) && is_array( $section['bullet_points'] ) ) {
foreach ( $section['bullet_points'] as $bullet_point ) {
$clean_bullet_point = trim( sanitize_text_field( (string) $bullet_point ) );
if ( '' !== $clean_bullet_point ) {
$bullet_points[] = $clean_bullet_point;
}
}
}
if ( '' === $heading || empty( $paragraphs ) ) {
continue;
}
$sections[] = array(
'heading' => $heading,
'level' => $level,
'paragraphs' => $paragraphs,
'bullet_points' => $bullet_points,
);
}
}
return array(
'title' => $title,
'sections' => $sections,
);
}
La funzione accetta un array strutturato di oggetti JSON, normalizza e pulisce i dati, quindi restituisce un array contenente il titolo e le sezioni.
La seconda funzione (aicb_sections_to_blocks) converte i dati normalizzati in oggetti descrittori di blocchi ed è definita come segue:
function aicb_sections_to_blocks( string $title, array $sections ): array {
$blocks = array();
foreach ( $sections as $section ) {
if ( ! is_array( $section ) ) {
continue;
}
$heading = isset( $section['heading'] ) ? trim( (string) $section['heading'] ) : '';
if ( '' === $heading ) {
continue;
}
$paragraphs = array();
if ( isset( $section['paragraphs'] ) && is_array( $section['paragraphs'] ) ) {
foreach ( $section['paragraphs'] as $paragraph ) {
$clean = trim( (string) $paragraph );
if ( '' !== $clean ) {
$paragraphs[] = $clean;
}
}
}
if ( empty( $paragraphs ) ) {
continue;
}
$blocks[] = array(
'name' => 'core/heading',
'attributes' => array(
'content' => $heading,
'level' => 2,
),
);
foreach ( $paragraphs as $paragraph ) {
$blocks[] = array(
'name' => 'core/paragraph',
'attributes' => array(
'content' => $paragraph,
),
);
}
if ( isset( $section['bullet_points'] ) && is_array( $section['bullet_points'] ) ) {
$bullet_items_html = '';
foreach ( $section['bullet_points'] as $bullet_point ) {
$clean_bullet = trim( sanitize_text_field( (string) $bullet_point ) );
if ( '' === $clean_bullet ) {
continue;
}
// core/list expects HTML in the `values` attribute.
$bullet_items_html .= '<li>' . esc_html( $clean_bullet ) . '</li>';
}
if ( '' !== $bullet_items_html ) {
$blocks[] = array(
'name' => 'core/list',
'attributes' => array(
'values' => '<ul>' . $bullet_items_html . '</ul>',
),
);
}
}
}
return $blocks;
}
Ecco i punti chiave di questa funzione:
- La funzione accetta 2 argomenti: una stringa che rappresenta il titolo del post e un array delle sezioni generate dal modello di AI.
- Per ogni sezione, la funzione genera un titolo e almeno un paragrafo.
- Se ci sono elenchi puntati, genera un numero corrispondente di voci dell’elenco.
- La funzione restituisce un array
$blocksdi oggetti descrittori di blocchi, che è il contratto di output restituito dall’abilità ($output_schema).
Nota che l’output della funzione non è il markup grezzo del blocco. Questo verrà generato lato client utilizzando la funzione JavaScript createBlock.
Ad esempio, l’elemento di intestazione di una sezione è rappresentato dal seguente oggetto:
if ( '' !== $heading ) {
$blocks[] = array(
'name' => 'core/heading',
'attributes' => array(
'content' => $heading,
'level' => ( 3 === $level ) ? 3 : 2,
),
);
}
Una volta registrata la tua ability, puoi eseguire nel terminale gli stessi comandi WP-CLI visti sopra per ottenere i dettagli. Il codice seguente genererà lo schema di input per la tua ability:
wp --user=1 eval '
$ability = wp_get_ability( "ai-content-builder/audio-to-gutenberg-blocks" );
if ( ! $ability ) {
echo "Ability not foundn";
exit( 1 );
}
echo "Input Schema:n";
var_dump( $ability->get_input_schema() );
'
Ecco il risultato nel terminale:
Input Schema:
array(3) {
["type"]=>
string(6) "object"
["properties"]=>
array(1) {
["audio_id"]=>
array(2) {
["type"]=>
string(7) "integer"
["description"]=>
string(76) "The ID of the audio attachment to process and convert into Gutenberg blocks."
}
}
["required"]=>
array(1) {
[0]=>
string(8) "audio_id"
}
}
Allo stesso modo, puoi recuperare lo schema di output dell’abilità:
wp --user=1 eval '
$ability = wp_get_ability( "ai-content-builder/audio-to-gutenberg-blocks" );
if ( ! $ability ) {
echo "Ability not foundn";
exit( 1 );
}
echo "Output Schema:n";
var_dump( $ability->get_output_schema() );
'
Puoi anche visualizzare l’oggetto completo della tua abilità con il seguente comando:
wp eval '
$ability = wp_get_ability( "ai-content-builder/audio-to-gutenberg-blocks" );
if ( ! $ability ) {
echo "Ability not foundn";
exit( 1 );
}
echo "Name: " . $ability->get_name() . "n";
echo "Label: " . $ability->get_label() . "n";
echo "Category: " . $ability->get_category() . "n";
echo "Description: " . $ability->get_description() . "n";
echo "nInput Schema:n";
var_dump( $ability->get_input_schema() );
echo "nOutput Schema:n";
var_dump( $ability->get_output_schema() );
'
Eseguire un’abilità
Per eseguire un’abilità, userai il metodo execute() dell’oggetto $ability. Puoi provare a eseguire il codice PHP qui sotto tramite WP-CLI per attivare l’abilità core/get-site-info:
wp --user=1 eval '
$ability = wp_get_ability( "core/get-site-info" );
if ( ! $ability ) {
echo "Ability not foundn";
exit(1);
}
$result = $ability->execute();
if ( is_wp_error( $result ) ) {
echo "ERROR: " . $result->get_error_message() . "n";
exit(1);
}
echo json_encode( $result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES ) . "n";
'
Quando esegui questo comando, l’abilità fornirà un oggetto JSON simile al seguente:
{
"name": "WordPress 7.0",
"description": "",
"url": "http://yoursite.kinsta.cloud",
"wpurl": "http://yoursite.kinsta.cloud",
"admin_email": "[email protected]",
"charset": "UTF-8",
"language": "en-US",
"version": "7.1-alpha-62550"
}
Quello che vedi sopra è solo un semplice esempio di ability che fornisce dati per il tuo sito.
Come detto prima, un ability può richiedere dati in ingresso, eseguire operazioni su quei dati e restituire un output strutturato. Possiamo vedere un esempio di questo con l’ability che abbiamo registrato nella sezione precedente.
Sempre nel tuo terminale, vai nella directory principale del sito ed esegui il seguente codice PHP:
wp --user=1 eval '
$ability = wp_get_ability( "ai-content-builder/audio-to-gutenberg-blocks" );
if ( ! $ability ) {
echo "Ability not foundn";
exit( 1 );
}
$input = array( "audio_id" => 1755 );
$result = $ability->execute( $input );
if ( is_wp_error( $result ) ) {
echo "ERROR: " . $result->get_error_message() . "n";
exit( 1 );
}
echo json_encode( $result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES ) . "n";
'
Il metodo execute passa i dati di input strutturati all’abilità, che restituisce un array di oggetti pronti per essere convertiti in blocchi Gutenberg:
[
{
"name": "core/heading",
"attributes": {
"content": "A Well-Deserved Rest Day in Marrakech",
"level": 2
}
},
{
"name": "core/paragraph",
"attributes": {
"content": "On April 24th, our group of seven motorcyclists took a break from the open road..."
}
},
{
"name": "core/heading",
"attributes": {
"content": "Exploring Jemaa el-Fnaa and the Medina",
"level": 2
}
},
{
"name": "core/paragraph",
"attributes": {
"content": "Our journey led us straight to Jemaa el-Fnaa, the legendary main square of Marrakech..."
}
},
{
"name": "core/list",
"attributes": {
"values": "<ul><li>Navigating the bustling souks and narrow alleys of the ancient Medina.</li><li>Savoring traditional Moroccan and Berber dishes.</li><li>Experiencing the vibrant street performances and food stalls of Jemaa el-Fnaa at night.</li></ul>"
}
},
...
]
Integrazione con l’API REST
L’Abilities API di WordPress offre una struttura di routing unificata che permette agli agenti esterni di interrogare a livello di programmazione le categorie di abilità disponibili (/categories), esaminare contratti di abilità specifici (/abilities/{name}) ed eseguire un’abilità specifica utilizzando l’endpoint di esecuzione standard (/abilities/{name}/run).
Ecco, ad esempio, una richiesta GET che restituisce l’elenco delle categorie dal nostro sito di prova:
https://yoursite.kinsta.cloud/wp-json/wp-abilities/v1/categories

Quando abbiamo registrato l’ability nell’esempio precedente, abbiamo impostato il parametro show_in_rest su true. In questo modo, abbiamo reso la nostra ability automaticamente accessibile tramite questi endpoint nativi dell’API REST di WordPress all’interno dello spazio dei nomi centralizzato del core (wp-abilities/v1).
Questo significa che non devi registrare manualmente percorsi personalizzati da zero per richiamare un’abilità da un ambiente esterno. Gli agenti esterni possono individuare ed eseguire la tua abilità utilizzando richieste HTTP standard.
Puoi esaminare il contratto specifico della nostra abilità con la seguente richiesta GET:
https://yoursite.kinsta.cloud/wp-json/wp-abilities/v1/abilities/ai-content-builder/audio-to-gutenberg-blocks
Infine, puoi attivare l’ability con una richiesta POST autenticata:
https://yoursite.kinsta.cloud/wp-json/wp-abilities/v1/abilities/ai-content-builder/audio-to-gutenberg-blocks/run
Quando invii questo tipo di richiesta, assicurati di aver specificato i dati di input. Nel nostro esempio, abbiamo impostato il seguente JSON nel corpo della richiesta:
{
"input": {
"audio_id": YOUR_AUDIO_ID
}
}

La nostra abilità ha elaborato l’audio e l’ha inviato al modello di AI configurato sul sito. Il modello ha restituito un output strutturato che è stato successivamente normalizzato e sanificato, restituendo infine il seguente array di oggetti contenente gli attributi del blocco:
{
"blocks": [
{
"name": "core/heading",
"attributes": { "content": "A Welcome Rest Day in Marrakech", "level": 2 }
},
{
"name": "core/paragraph",
"attributes": { "content": "On April 24, our group of seven motorcyclists paused our journey..." }
}
]
}
Ed è proprio questo il risultato che volevamo ottenere.
Il futuro di WordPress è “agentico”
Mentre l’AI Client e la nuova architettura dei connettori portano le capacità di elaborazione dell’AI all’interno di WordPress, l’Abilities API ridefinisce il modo in cui WordPress interagisce con il mondo esterno. Stiamo assistendo a un drastico cambiamento di paradigma, passando da un’architettura web tradizionale — basata sull’interazione manuale dell’utente, in cui ogni integrazione richiedeva endpoint personalizzati e mappature manuali — a un’architettura basata sull’intento, progettata da zero per l’automazione.
Per gli sviluppatori di WordPress, la nuova API Abilities rappresenta una svolta architettonica, caratterizzata dal disaccoppiamento delle funzionalità dai plugin che ne contengono la logica, dal rafforzamento della sicurezza attraverso il contratto di input/output e dall’abilitazione dell’interoperabilità nativa nell’intero ecosistema.
Nel loro insieme, queste caratteristiche assicurano che l’API Abilities non sia solo l’ennesima API, ma un vero e proprio motore di esecuzione distribuito che offre uno sguardo su un futuro sempre più “agentico” per WordPress.