settings = $settings; $this->tools = $tools; $this->scanner = $scanner; } /** * Register hooks. Hooks are harmless on pre-6.9 WordPress versions. * * @return void */ public function init() { add_action( 'wp_abilities_api_categories_init', array( $this, 'register_category' ) ); add_action( 'wp_abilities_api_init', array( $this, 'register_abilities' ) ); } /** * Whether the Abilities API is available. * * @return bool */ public function is_available() { return function_exists( 'wp_register_ability' ) && function_exists( 'wp_register_ability_category' ); } /** * Whether plugin abilities are enabled. * * @return bool */ public function is_enabled() { return (bool) $this->settings->get( 'abilities_enabled', 1 ); } /** * Register category. * * @return void */ public function register_category() { if ( ! $this->is_available() || ! $this->is_enabled() ) { return; } wp_register_ability_category( 'agizoai-agentic', array( 'label' => __( 'AgizoAI Agentic Browsing', 'agizoai-agentic-browsing-optimizer' ), 'description' => __( 'Read-only site discovery and agent-readiness abilities provided by AgizoAI Agentic Browsing Optimizer.', 'agizoai-agentic-browsing-optimizer' ), ) ); } /** * Register abilities. * * @return void */ public function register_abilities() { if ( ! $this->is_available() || ! $this->is_enabled() ) { return; } $public = (bool) $this->settings->get( 'abilities_public_enabled', 1 ); $meta = array( 'public' => $public, 'show_in_rest' => $public, 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true, ), 'mcp' => array( 'public' => $public, 'type' => 'tool', ), ); wp_register_ability( 'agizoai-agentic/get-site-profile', array( 'label' => __( 'Get public site profile', 'agizoai-agentic-browsing-optimizer' ), 'description' => __( 'Returns the public site identity, language, discovery URLs, selected public content types and SEO integration summary.', 'agizoai-agentic-browsing-optimizer' ), 'category' => 'agizoai-agentic', 'output_schema' => $this->generic_object_schema(), 'execute_callback' => array( $this, 'execute_site_profile' ), 'permission_callback' => array( $this, 'public_permission' ), 'meta' => $meta, ) ); wp_register_ability( 'agizoai-agentic/search-public-content', array( 'label' => __( 'Search public content', 'agizoai-agentic-browsing-optimizer' ), 'description' => __( 'Searches the published public content selected for agent discovery. Private, draft, password-protected and excluded content is not returned.', 'agizoai-agentic-browsing-optimizer' ), 'category' => 'agizoai-agentic', 'input_schema' => array( 'type' => 'object', 'properties' => array( 'query' => array( 'type' => 'string', 'description' => __( 'Search phrase.', 'agizoai-agentic-browsing-optimizer' ) ), 'post_type' => array( 'type' => 'string', 'description' => __( 'Optional selected public post type.', 'agizoai-agentic-browsing-optimizer' ) ), 'per_page' => array( 'type' => 'integer', 'minimum' => 1, 'maximum' => 20, 'description' => __( 'Maximum results.', 'agizoai-agentic-browsing-optimizer' ) ), ), ), 'output_schema' => $this->generic_object_schema(), 'execute_callback' => array( $this, 'execute_search' ), 'permission_callback' => array( $this, 'public_permission' ), 'meta' => $meta, ) ); wp_register_ability( 'agizoai-agentic/get-public-content', array( 'label' => __( 'Get public content summary', 'agizoai-agentic-browsing-optimizer' ), 'description' => __( 'Returns the safe public summary and metadata for one published item selected for agent discovery.', 'agizoai-agentic-browsing-optimizer' ), 'category' => 'agizoai-agentic', 'input_schema' => array( 'type' => 'object', 'properties' => array( 'id' => array( 'type' => 'integer', 'minimum' => 1, 'description' => __( 'Public WordPress content ID.', 'agizoai-agentic-browsing-optimizer' ) ), ), 'required' => array( 'id' ), ), 'output_schema' => $this->generic_object_schema(), 'execute_callback' => array( $this, 'execute_content' ), 'permission_callback' => array( $this, 'public_permission' ), 'meta' => $meta, ) ); $admin_meta = $meta; $admin_meta['public'] = $public; $admin_meta['show_in_rest'] = $public; $admin_meta['mcp']['public'] = $public; wp_register_ability( 'agizoai-agentic/get-readiness-report', array( 'label' => __( 'Get agentic readiness report', 'agizoai-agentic-browsing-optimizer' ), 'description' => __( 'Runs and returns the AgizoAI agentic-readiness scan. Execution requires an authenticated administrator.', 'agizoai-agentic-browsing-optimizer' ), 'category' => 'agizoai-agentic', 'output_schema' => $this->generic_object_schema(), 'execute_callback' => array( $this, 'execute_readiness' ), 'permission_callback' => array( $this, 'admin_permission' ), 'meta' => $admin_meta, ) ); } /** Public ability permission. */ public function public_permission( $input = null ) { unset( $input ); return $this->is_enabled() && $this->tools->is_enabled(); } /** Admin-only readiness permission. */ public function admin_permission( $input = null ) { unset( $input ); return $this->is_enabled() && current_user_can( 'manage_options' ); } /** Execute site profile. */ public function execute_site_profile( $input = null ) { unset( $input ); return $this->response_to_data( $this->tools->rest_site() ); } /** Execute public search. */ public function execute_search( $input = null ) { $input = is_array( $input ) ? $input : array(); $request = new WP_REST_Request( 'GET', '/agizoai-agentic/v1/search' ); $request->set_param( 'query', isset( $input['query'] ) ? sanitize_text_field( $input['query'] ) : '' ); $request->set_param( 'post_type', isset( $input['post_type'] ) ? sanitize_key( $input['post_type'] ) : '' ); $request->set_param( 'per_page', isset( $input['per_page'] ) ? absint( $input['per_page'] ) : 10 ); return $this->response_to_data( $this->tools->rest_search( $request ) ); } /** Execute one public content lookup. */ public function execute_content( $input = null ) { $input = is_array( $input ) ? $input : array(); $id = isset( $input['id'] ) ? absint( $input['id'] ) : 0; if ( $id < 1 ) { return new WP_Error( 'agizoai_agentic_invalid_content_id', __( 'A valid public content ID is required.', 'agizoai-agentic-browsing-optimizer' ) ); } $request = new WP_REST_Request( 'GET', '/agizoai-agentic/v1/content/' . $id ); $request->set_param( 'id', $id ); return $this->response_to_data( $this->tools->rest_content( $request ) ); } /** Execute admin readiness scan. */ public function execute_readiness( $input = null ) { unset( $input ); return $this->scanner->scan(); } /** * Convert REST response to plain ability output. * * @param mixed $response Response. * @return mixed */ private function response_to_data( $response ) { if ( is_wp_error( $response ) ) { return $response; } if ( $response instanceof WP_REST_Response ) { if ( $response->get_status() >= 400 ) { $data = $response->get_data(); return new WP_Error( 'agizoai_agentic_ability_request_failed', isset( $data['message'] ) ? $data['message'] : __( 'The public tool request failed.', 'agizoai-agentic-browsing-optimizer' ), $data ); } return $response->get_data(); } return $response; } /** Generic object schema suitable for dynamic public metadata. */ private function generic_object_schema() { return array( 'type' => 'object', 'additionalProperties' => true, ); } }