Astra_Abstract_Ability
Abstract Class Astra_Abstract_Ability
Description
Source
File: inc/abilities/class-astra-abstract-ability.php
abstract class Astra_Abstract_Ability {
/**
* Ability ID (e.g. 'astra/get-font-body').
*
* @var string
*/
protected $id = '';
/**
* Ability Category.
*
* @var string
*/
protected $category = 'astra';
/**
* Ability Label.
*
* @var string
*/
protected $label = '';
/**
* Ability Description.
*
* @var string
*/
protected $description = '';
/**
* Required capability for this ability.
*
* @var string
*/
protected $capability = 'edit_theme_options';
/**
* Ability Meta Data.
*
* @var array
*/
protected $meta = array();
/**
* Tool version.
*
* @var string
*/
protected $version = '1.0.0';
/**
* Constructor.
*/
public function __construct() {
$this->configure();
}
/**
* Configure the ability (set ID, label, description, etc.).
*
* @return void
*/
abstract public function configure();
/**
* Get the input schema for the ability.
*
* @return array
*/
abstract public function get_input_schema();
/**
* Execute the ability.
*
* @param array $args Input arguments.
* @return array Result array.
*/
abstract public function execute( $args );
/**
* Get the final input schema.
*
* @return array
*/
public function get_final_input_schema() {
$schema = $this->get_input_schema();
if ( ! isset( $schema['properties'] ) ) {
$schema['properties'] = array();
}
return $schema;
}
/**
* Handle execution with error handling.
*
* @param array $args Input arguments.
* @return array Result array.
*/
public function handle_execute( $args ) {
try {
return $this->execute( $args );
} catch ( Exception $e ) {
/* translators: %s: error message */
return Astra_Abilities_Response::error( sprintf( __( 'An unexpected error occurred: %s', 'astra' ), $e->getMessage() ) );
} catch ( Error $e ) {
/* translators: %s: error message */
return Astra_Abilities_Response::error( sprintf( __( 'A system error occurred: %s', 'astra' ), $e->getMessage() ) );
}
}
/**
* Get the output schema for the ability.
*
* Override in child classes to define the data properties
* returned in the success response.
*
* @return array
*/
public function get_output_schema() {
return array();
}
/**
* Build a standardized output schema wrapping data properties
* in the Astra_Abilities_Response::success() format.
*
* @param array $data_properties Properties for the 'data' key.
* @return array Full output schema.
*/
protected function build_output_schema( $data_properties ) {
return array(
'type' => 'object',
'required' => array( 'success', 'message' ),
'properties' => array(
'success' => array(
'type' => 'boolean',
'description' => 'Whether the operation succeeded.',
),
'message' => array(
'type' => 'string',
'description' => 'Human-readable result message.',
),
'data' => array(
'type' => 'object',
'properties' => $data_properties,
),
),
);
}
/**
* Get usage examples.
*
* @return array
*/
public function get_examples() {
return array();
}
/**
* Get tool type (read, write, list).
*
* @return string
*/
public function get_tool_type() {
return 'read';
}
/**
* Get whether to show this ability in the REST API.
*
* @return bool
*/
public function get_show_in_rest() {
/**
* Filter whether to show this ability in the REST API.
*
* @param bool $show_in_rest Whether to show in REST API. Default true.
* @param string $ability_id The ability ID (e.g. 'astra/get-font-body').
* @param self $ability_instance The ability instance.
* @since 4.12.6
*/
/** @psalm-suppress TooManyArguments -- WordPress apply_filters accepts variadic args for filter callbacks. */
return apply_filters( 'astra_ability_show_in_rest', true, $this->id, $this );
}
/**
* Get MCP annotations based on tool type.
*
* Returns semantic hints for the MCP Adapter describing the ability's
* behavioral characteristics. Override in child classes for custom behavior.
*
* @return array{readonly: bool, destructive: bool, idempotent: bool}
*/
public function get_annotations() {
$tool_type = $this->get_tool_type();
// Read and list tools are readonly, write tools are not.
return array(
'readonly' => 'write' !== $tool_type,
'destructive' => false,
'idempotent' => true,
);
}
/**
* Get MCP meta configuration for this ability.
*
* Returns the MCP Adapter metadata including public visibility
* and MCP type. The public flag is filterable via 'astra_ability_mcp_public'.
*
* @return array{public: bool, type: string}
*/
public function get_mcp() {
/**
* Filter whether an Astra ability is publicly exposed via MCP.
*
* @since 4.12.6
*
* @param bool $is_public Whether the ability is public for MCP. Default true.
* @param string $ability_id The ability ID (e.g. 'astra/get-font-body').
* @param self $ability_instance The ability instance.
*/
/** @psalm-suppress TooManyArguments -- WordPress apply_filters accepts variadic args for filter callbacks. */
$is_public = apply_filters( 'astra_ability_mcp_public', true, $this->id, $this );
return array(
'public' => (bool) $is_public,
'type' => 'tool',
);
}
/**
* Check permissions.
*
* @param WP_REST_Request $request REST Request.
* @return bool|WP_Error
*/
public function check_permission( $request ) {
return current_user_can( $this->capability );
}
/**
* Get the ability ID.
*
* @return string
*/
public function get_id() {
return $this->id;
}
/**
* Get the ability label.
*
* @return string
*/
public function get_label() {
return $this->label;
}
/**
* Get the ability description.
*
* @return string
*/
public function get_description() {
return $this->description;
}
/**
* Get the category.
*
* @return string
*/
public function get_category() {
return $this->category;
}
/**
* Get the meta data.
*
* @return array
*/
public function get_meta_data() {
return $this->meta;
}
/**
* Get the tool version.
*
* @return string
*/
public function get_version() {
return $this->version;
}
/**
* Register this ability with the Abilities API.
*
* @return void
*/
public static function register() {
if ( ! function_exists( 'wp_register_ability' ) ) {
return;
}
/** @psalm-suppress UnsafeInstantiation -- Intentional: child classes share the same constructor signature. */
$instance = new static();
if ( empty( $instance->id ) ) {
return;
}
$meta = array(
'tool_type' => $instance->get_tool_type(),
'examples' => $instance->get_examples(),
'version' => $instance->get_version(),
'show_in_rest' => $instance->get_show_in_rest(),
'annotations' => $instance->get_annotations(),
'mcp' => $instance->get_mcp(),
);
$meta = array_replace_recursive( $meta, $instance->meta );
$args = array(
'label' => $instance->label,
'description' => $instance->description,
'category' => $instance->category,
'input_schema' => $instance->get_final_input_schema(),
'execute_callback' => array( $instance, 'handle_execute' ),
'permission_callback' => array( $instance, 'check_permission' ),
'meta' => $meta,
);
$output_schema = $instance->get_output_schema();
if ( ! empty( $output_schema ) ) {
$args['output_schema'] = $output_schema;
}
wp_register_ability( $instance->id, $args );
}
}
Expand full source code Collapse full source code View on Trac
Methods
- __construct — Constructor.
- build_output_schema — Build a standardized output schema wrapping data properties in the Astra_Abilities_Response::success() format.
- check_permission — Check permissions.
- configure — Configure the ability (set ID, label, description, etc.).
- execute — Execute the ability.
- get_annotations — Get MCP annotations based on tool type.
- get_category — Get the category.
- get_description — Get the ability description.
- get_examples — Get usage examples.
- get_final_input_schema — Get the final input schema.
- get_id — Get the ability ID.
- get_input_schema — Get the input schema for the ability.
- get_label — Get the ability label.
- get_mcp — Get MCP meta configuration for this ability.
- get_meta_data — Get the meta data.
- get_output_schema — Get the output schema for the ability.
- get_show_in_rest — Get whether to show this ability in the REST API.
- get_tool_type — Get tool type (read, write, list).
- get_version — Get the tool version.
- handle_execute — Handle execution with error handling.
- register — Register this ability with the Abilities API.