PluginProbe
Extendify / 3.1.3
Extendify v3.1.3
3.2.1 3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 All 127 releases
extendify / app / Agent / AbilitiesDiscovery.php

AbilitiesDiscovery.php in Extendify 3.1.3, at app/Agent/AbilitiesDiscovery.php

99 lines 3.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Discovers WordPress Abilities registered on the site for the Agent.
5 */
6
7 namespace Extendify\Agent;
8
9 use Extendify\PartnerData;
10
11 defined('ABSPATH') || die('No direct access.');
12
13 /**
14 * Reads the Abilities API (WP 6.9+) and shapes the survivors for the Agent,
15 * grouped by category so the backend can route to a category before a tool.
16 */
17 class AbilitiesDiscovery
18 {
19 /**
20 * Discover the abilities registered on this install.
21 *
22 * @return array
23 */
24 public static function discover()
25 {
26 if (!function_exists('wp_get_abilities')) {
27 return [];
28 }
29
30 return self::shape(
31 wp_get_abilities(),
32 wp_get_ability_categories(),
33 PartnerData::setting('agentAbilitiesAllowlist')
34 );
35 }
36
37 /**
38 * Keep only REST-exposed abilities, then group their descriptors under the
39 * categories that hold at least one.
40 *
41 * No permission filtering here: an ability's permission_callback often turns
42 * on the specific input (e.g. edit_post for a given post id) which discovery
43 * doesn't have, so the /run endpoint enforces permission at call time.
44 *
45 * @param array $abilities WP_Ability objects from wp_get_abilities().
46 * @param array $categories WP_Ability_Category objects from wp_get_ability_categories().
47 * @param array|null $allowlist Namespace prefixes to keep; null keeps every namespace.
48 * @return array
49 */
50 public static function shape(array $abilities, array $categories = [], $allowlist = null)
51 {
52 $allowed = array_filter($abilities, function ($ability) use ($allowlist) {
53 if (!$ability->get_meta_item('show_in_rest')) {
54 return false;
55 }
56
57 if ($allowlist === null) {
58 return true;
59 }
60
61 return in_array(explode('/', $ability->get_name())[0], $allowlist, true);
62 });
63
64 $byCategory = [];
65 foreach ($allowed as $ability) {
66 $meta = $ability->get_meta();
67 $name = $ability->get_name();
68 $byCategory[$ability->get_category()][] = [
69 'name' => $name,
70 'label' => $ability->get_label(),
71 'description' => $ability->get_description(),
72 'inputSchema' => $ability->get_input_schema(),
73 'annotations' => $meta['annotations'] ?? null,
74 'runHref' => \rest_url('wp-abilities/v1/abilities/' . $name . '/run'),
75 ];
76 }
77
78 $categoryMeta = [];
79 foreach ($categories as $category) {
80 $categoryMeta[$category->get_slug()] = [
81 'label' => $category->get_label(),
82 'description' => $category->get_description(),
83 ];
84 }
85
86 $result = [];
87 foreach ($byCategory as $slug => $abilitiesInCategory) {
88 $result[] = [
89 'slug' => $slug,
90 'label' => $categoryMeta[$slug]['label'] ?? $slug,
91 'description' => $categoryMeta[$slug]['description'] ?? '',
92 'abilities' => $abilitiesInCategory,
93 ];
94 }
95
96 return $result;
97 }
98 }
99