PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3
Jetpack – WP Security, Backup, Speed, & Growth v16.3
16.3 16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 All 508 releases
← All changes | jetpack_vendor/automattic/jetpack-agents-manager/src/class-agents-manager.php +24 -425 16.2 → 16.3 View file →
@@ -19,18 +19,11 @@
19 19 * The package version of the Agents Manager package.
20 20 *
21 21 * @var string
22 22 */
23 - const PACKAGE_VERSION = '0.12.0';
23 + const PACKAGE_VERSION = '0.12.4';
24 24
25 25 /**
26 - * Help Center URL for disconnected variants.
27 - *
28 - * @var string
29 - */
30 - private const HELP_CENTER_URL = 'https://wordpress.com/help?help-center=home';
31 -
32 - /**
33 26 * Class instance.
34 27 *
35 28 * @var Agents_Manager
36 29 */
@@ -44,191 +37,27 @@
44 37 add_filter( 'calypso_preferences_update', array( $this, 'calypso_preferences_update' ) );
45 38
46 39 add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ), 101 );
47 40 add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ), 101 );
48 - add_action( 'next_admin_init', array( $this, 'enqueue_scripts' ), 1001 );
49 41
50 - // Runs after Help Center's own admin_bar_menu callback, so add_help_menu() can replace its node.
51 42 add_action( 'admin_bar_menu', array( $this, 'add_admin_bar_nodes' ), 100 );
52 43
53 - add_filter( 'agents_manager_use_unified_experience', array( $this, 'should_use_unified_experience' ) );
54 -
55 44 Sidebar_Open_Preservation::init();
56 45 }
57 46
58 47 /**
59 - * Check if the agents manager menu panel should be displayed.
48 + * Get the SVG icon markup for the AI chat button.
60 49 *
61 - * @return bool True if the menu panel should be displayed.
62 - */
63 - public function should_display_menu_panel() {
64 - return self::is_unified_experience();
65 - }
66 -
67 - /**
68 - * Get the SVG icon markup for a given icon name.
69 - *
70 - * @param string $icon_name The name of the icon to retrieve.
71 50 * @return string The SVG markup.
72 51 */
73 - private function get_icon( $icon_name ) {
52 + private function get_ai_icon() {
74 53 // Not cached: the sparkle icon's aria-label is translated, and the locale can switch mid-request.
75 - $icons = array(
76 - 'comment' => '<svg class="help-center-menu-icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M18 4H6c-1.1 0-2 .9-2 2v12.9c0 .6.5 1.1 1.1 1.1.3 0 .5-.1.8-.3L8.5 17H18c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm.5 11c0 .3-.2.5-.5.5H7.9l-2.4 2.4V6c0-.3.2-.5.5-.5h12c.3 0 .5.2.5.5v9z" /></svg>',
77 - 'backup' => '<svg class="help-center-menu-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M5.5 12h1.75l-2.5 3-2.5-3H4a8 8 0 113.134 6.35l.907-1.194A6.5 6.5 0 105.5 12zm9.53 1.97l-2.28-2.28V8.5a.75.75 0 00-1.5 0V12a.747.747 0 00.218.529l1.282-.84-1.28.842 2.5 2.5a.75.75 0 101.06-1.061z" /></svg>',
78 - 'page' => '<svg class="help-center-menu-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.5 7.5h-7V9h7V7.5Zm-7 3.5h7v1.5h-7V11Zm7 3.5h-7V16h7v-1.5Z" /><path d="M17 4H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2ZM7 5.5h10a.5.5 0 0 1 .5.5v12a.5.5 0 0 1-.5.5H7a.5.5 0 0 1-.5-.5V6a.5.5 0 0 1 .5-.5Z" /></svg>',
79 - 'video' => '<svg class="help-center-menu-icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M18.7 3H5.3C4 3 3 4 3 5.3v13.4C3 20 4 21 5.3 21h13.4c1.3 0 2.3-1 2.3-2.3V5.3C21 4 20 3 18.7 3zm.8 15.7c0 .4-.4.8-.8.8H5.3c-.4 0-.8-.4-.8-.8V5.3c0-.4.4-.8.8-.8h13.4c.4 0 .8.4.8.8v13.4zM10 15l5-3-5-3v6z" /></svg>',
80 - 'rss' => '<svg class="help-center-menu-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M5 10.2h-.8v1.5H5c1.9 0 3.8.8 5.1 2.1 1.4 1.4 2.1 3.2 2.1 5.1v.8h1.5V19c0-2.3-.9-4.5-2.6-6.2-1.6-1.6-3.8-2.6-6.1-2.6zm10.4-1.6C12.6 5.8 8.9 4.2 5 4.2h-.8v1.5H5c3.5 0 6.9 1.4 9.4 3.9s3.9 5.8 3.9 9.4v.8h1.5V19c0-3.9-1.6-7.6-4.4-10.4zM4 20h3v-3H4v3z" /></svg>',
81 - 'help' => '<svg id="agents-manager-icon" class="ab-icon" width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
82 - <path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2zm-1 16v-2h2v2h-2zm2-3v-1.141A3.991 3.991 0 0016 10a4 4 0 00-8 0h2c0-1.103.897-2 2-2s2 .897 2 2-.897 2-2 2a1 1 0 00-1 1v2h2z" />
83 - </svg>',
84 - 'sparkle' => '<svg class="ab-icon" role="img" aria-label="' . esc_attr__( 'Agent', 'jetpack-agents-manager' ) . '" width="24" height="24" viewBox="-45 -45 490 490" xmlns="http://www.w3.org/2000/svg">
54 + return '<svg class="ab-icon" role="img" aria-label="' . esc_attr__( 'Agent', 'jetpack-agents-manager' ) . '" width="24" height="24" viewBox="-45 -45 490 490" xmlns="http://www.w3.org/2000/svg">
85 55 <path fill="currentColor" d="M391.528 188.061L309.455 159.75C276.997 148.597 251.403 123.003 240.25 90.5451L211.939 8.47185C208.079 -2.82395 191.921 -2.82395 188.061 8.47185L159.75 90.5451C148.597 123.003 123.003 148.597 90.5451 159.75L8.47185 188.061C-2.82395 191.921 -2.82395 208.079 8.47185 211.939L90.5451 240.25C123.003 251.403 148.597 276.997 159.75 309.455L188.061 391.528C191.921 402.824 208.079 402.824 211.939 391.528L240.25 309.455C251.403 276.997 276.997 251.403 309.455 240.25L391.528 211.939C402.824 208.079 402.824 191.921 391.528 188.061ZM295.728 206.077L254.692 220.232C238.391 225.809 225.666 238.677 220.089 254.835L205.934 295.871C203.932 301.591 195.925 301.591 193.923 295.871L179.768 254.835C174.191 238.534 161.323 225.809 145.165 220.232L104.129 206.077C98.4093 204.075 98.4093 196.068 104.129 194.066L145.165 179.911C161.466 174.334 174.191 161.466 179.768 145.308L193.923 104.272C195.925 98.5523 203.932 98.5523 205.934 104.272L220.089 145.308C225.666 161.609 238.534 174.334 254.692 179.911L295.728 194.066C301.448 196.068 301.448 204.075 295.728 206.077Z" />
86 - </svg>',
87 - );
88 -
89 - return $icons[ $icon_name ] ?? '';
56 + </svg>';
90 57 }
91 58
92 59 /**
93 - * Add the Agents Manager Help "?" node (`agents-manager`) to the admin bar, replacing the
94 - * legacy Help Center node (`help-center`).
95 - *
96 - * @param \WP_Admin_Bar $wp_admin_bar The WP_Admin_Bar instance.
97 - * @param bool $use_disconnected Disconnected variants link straight to the Help Center instead of opening the dropdown.
98 - */
99 - public function add_help_menu( $wp_admin_bar, $use_disconnected ) {
100 - $wp_admin_bar->remove_node( 'help-center' );
101 -
102 - $menu_args = array(
103 - 'id' => 'agents-manager',
104 - 'title' => '<span title="' . esc_attr__( 'Help Center', 'jetpack-agents-manager' ) . '">' . $this->get_icon( 'help' ) . '</span>',
105 - 'parent' => 'top-secondary',
106 - );
107 -
108 - if ( $use_disconnected ) {
109 - $menu_args['href'] = self::HELP_CENTER_URL;
110 - $menu_args['meta'] = array(
111 - 'menu_title' => __( 'Help Center', 'jetpack-agents-manager' ),
112 - 'icon' => 'help',
113 - 'target' => '_blank',
114 - 'rel' => 'noopener noreferrer',
115 - );
116 - } else {
117 - $menu_args['meta'] = array(
118 - 'menu_title' => __( 'Help Center', 'jetpack-agents-manager' ),
119 - 'icon' => 'help',
120 - 'class' => 'menupop',
121 - );
122 - }
123 -
124 - $wp_admin_bar->add_menu( $menu_args );
125 - }
126 -
127 - /**
128 - * Add the agents manager menu panel to the admin bar.
129 - *
130 - * @param \WP_Admin_Bar $wp_admin_bar The WP_Admin_Bar instance.
131 - */
132 - public function add_menu_panel( $wp_admin_bar ) {
133 - // Add chat support group
134 - $wp_admin_bar->add_group(
135 - array(
136 - 'parent' => 'agents-manager',
137 - 'id' => 'agents-manager-menu-panel-chat',
138 - 'meta' => array(
139 - 'class' => 'ab-sub-secondary',
140 - ),
141 - )
142 - );
143 -
144 - // Add chat support menu item
145 - $wp_admin_bar->add_node(
146 - array(
147 - 'parent' => 'agents-manager-menu-panel-chat',
148 - 'id' => 'agents-manager-chat-support',
149 - 'title' => $this->get_icon( 'comment' ) . '<span>' . __( 'Chat support', 'jetpack-agents-manager' ) . '</span>',
150 - 'meta' => array(
151 - 'menu_title' => __( 'Chat support', 'jetpack-agents-manager' ),
152 - 'icon' => 'comment',
153 - 'route' => '/chat',
154 - ),
155 - )
156 - );
157 -
158 - // Add chat history menu item
159 - $wp_admin_bar->add_node(
160 - array(
161 - 'parent' => 'agents-manager-menu-panel-chat',
162 - 'id' => 'agents-manager-chat-history',
163 - 'title' => $this->get_icon( 'backup' ) . '<span>' . __( 'Chat history', 'jetpack-agents-manager' ) . '</span>',
164 - 'meta' => array(
165 - 'menu_title' => __( 'Chat history', 'jetpack-agents-manager' ),
166 - 'icon' => 'backup',
167 - 'route' => '/history',
168 - ),
169 - )
170 - );
171 -
172 - // Add links group
173 - $wp_admin_bar->add_group(
174 - array(
175 - 'parent' => 'agents-manager',
176 - 'id' => 'agents-manager-menu-panel-links',
177 - 'meta' => array(
178 - 'class' => 'ab-sub-secondary',
179 - ),
180 - )
181 - );
182 -
183 - // Add support guides menu item
184 - $wp_admin_bar->add_node(
185 - array(
186 - 'parent' => 'agents-manager-menu-panel-links',
187 - 'id' => 'agents-manager-support-guides',
188 - 'title' => $this->get_icon( 'page' ) . '<span>' . __( 'Support guides', 'jetpack-agents-manager' ) . '</span>',
189 - 'meta' => array(
190 - 'menu_title' => __( 'Support guides', 'jetpack-agents-manager' ),
191 - 'icon' => 'page',
192 - 'route' => '/support-guides',
193 - ),
194 - )
195 - );
196 -
197 - // Add courses menu item
198 - $wp_admin_bar->add_node(
199 - array(
200 - 'parent' => 'agents-manager-menu-panel-links',
201 - 'id' => 'agents-manager-courses',
202 - 'title' => $this->get_icon( 'video' ) . '<span>' . __( 'Courses', 'jetpack-agents-manager' ) . '</span>',
203 - 'href' => 'https://wordpress.com/support/courses/',
204 - 'meta' => array(
205 - 'menu_title' => __( 'Courses', 'jetpack-agents-manager' ),
206 - 'icon' => 'video',
207 - 'target' => '_blank',
208 - 'rel' => 'noopener noreferrer',
209 - ),
210 - )
211 - );
212 -
213 - // Add product updates menu item
214 - $wp_admin_bar->add_node(
215 - array(
216 - 'parent' => 'agents-manager-menu-panel-links',
217 - 'id' => 'agents-manager-product-updates',
218 - 'title' => $this->get_icon( 'rss' ) . '<span>' . __( 'Product updates', 'jetpack-agents-manager' ) . '</span>',
219 - 'href' => 'https://wordpress.com/blog/category/product-features/',
220 - 'meta' => array(
221 - 'menu_title' => __( 'Product updates', 'jetpack-agents-manager' ),
222 - 'icon' => 'rss',
223 - 'target' => '_blank',
224 - 'rel' => 'noopener noreferrer',
225 - ),
226 - )
227 - );
228 - }
229 -
230 - /**
231 60 * Add the standalone AI chat button to the admin bar.
232 61 *
233 62 * @param \WP_Admin_Bar $wp_admin_bar The WP_Admin_Bar instance.
234 63 */
@@ -251,9 +80,9 @@
251 80 $wp_admin_bar->add_menu(
252 81 array(
253 82 'id' => 'agents-manager-ai-chat',
254 83 'parent' => 'top-secondary',
255 - 'title' => '<span title="' . esc_attr__( 'Agent', 'jetpack-agents-manager' ) . '">' . $this->get_icon( 'sparkle' ) . '</span>'
84 + 'title' => '<span title="' . esc_attr__( 'Agent', 'jetpack-agents-manager' ) . '">' . $this->get_ai_icon() . '</span>'
256 85 . '<span class="agents-manager-ai-chat-label" aria-hidden="true"><span>' . esc_html__( 'Agent', 'jetpack-agents-manager' ) . '</span></span>',
257 86 'meta' => $meta,
258 87 )
259 88 );
@@ -263,9 +92,9 @@
263 92 * The Agents Manager context for this request, or null when it should not load.
264 93 *
265 94 * Shared by `add_admin_bar_nodes()` and `enqueue_scripts()`.
266 95 *
267 - * @return array{variant: string, disconnected: bool, gutenberg: bool, unified: bool, ciab: bool, enabled: bool}|null
96 + * @return array{variant: string, disconnected: bool, gutenberg: bool, enabled: bool}|null
268 97 */
269 98 private function get_active_context() {
270 99 // P2 frontends get neither the admin bar entry points nor the app.
271 100 $stylesheet = get_stylesheet();
@@ -284,10 +113,8 @@
284 113 return array(
285 114 'variant' => $variant,
286 115 'disconnected' => str_contains( $variant, 'disconnected' ),
287 116 'gutenberg' => $this->is_block_editor(),
288 - 'unified' => self::is_unified_experience(),
289 - 'ciab' => $this->is_ciab_environment(),
290 117 'enabled' => self::is_enabled(),
291 118 );
292 119 }
293 120
@@ -305,23 +132,10 @@
305 132 if ( null === $context ) {
306 133 return;
307 134 }
308 135
309 - // For non-Gutenberg, non-CIAB environments, add to the admin bar. Gutenberg uses JS when
310 - // no admin bar is visible and the server-side branch below when one is available. CIAB
311 - // hides the admin bar and uses its own Site Hub.
312 - if ( ! $context['gutenberg'] && ! $context['ciab'] ) {
313 - // Disconnected variants are Help-only. Full variants take over Help
314 - // only when the unified experience is active.
315 - if ( $context['disconnected'] || $context['unified'] ) {
316 - $this->add_help_menu( $wp_admin_bar, $context['disconnected'] );
317 - }
318 -
319 - // Initialize the Help menu panel only for the full unified experience.
320 - if ( ! $context['disconnected'] && $context['unified'] ) {
321 - $this->add_menu_panel( $wp_admin_bar );
322 - }
323 -
136 + // Gutenberg uses JS when no admin bar is visible and the server-side branch below when one is available.
137 + if ( ! $context['gutenberg'] ) {
324 138 // Standalone AI chat button, shown whenever the full Agents Manager app is enabled.
325 139 if ( ! $context['disconnected'] && $context['enabled'] ) {
326 140 $this->add_ai_chat_button( $wp_admin_bar );
327 141 }
@@ -326,19 +140,10 @@
326 140 $this->add_ai_chat_button( $wp_admin_bar );
327 141 }
328 142 }
329 143
330 - // When the block editor exposes the WordPress admin bar, add the entry points there.
331 - // CIAB is excluded — it has its own Site Hub UI.
332 - // Mirroring wp-admin: the Help "?" dropdown shows only in the full unified experience;
333 - // the AI chat button shows whenever Agents Manager is enabled in this editor.
334 - if ( ! $context['ciab'] && ! $context['disconnected'] && self::is_admin_bar_in_editor() ) {
335 - // Help "?" node + dropdown panel first, matching the wp-admin admin bar order.
336 - if ( $context['unified'] ) {
337 - $this->add_help_menu( $wp_admin_bar, false );
338 - $this->add_menu_panel( $wp_admin_bar );
339 - }
340 -
144 + // When the block editor exposes the WordPress admin bar, add the entry point there.
145 + if ( ! $context['disconnected'] && self::is_admin_bar_in_editor() ) {
341 146 if ( $context['enabled'] ) {
342 147 $this->add_ai_chat_button( $wp_admin_bar );
343 148 }
344 149 }
@@ -354,18 +159,8 @@
354 159 }
355 160
356 161 $variant = $context['variant'];
357 162
358 - // In Gutenberg, dequeue Help Center so we don't end up with two buttons — but only
359 - // in the full unified experience, where Agents Manager takes over the Help Center.
360 - // In block-editor-only mode (e.g. ?flags=unified-big-sky) Agents Manager replaces
361 - // Big Sky's native UI and Help Center should remain available.
362 - // Agents Manager fires at priority 101, after Help Center at 100, so HC is already enqueued.
363 - if ( $context['gutenberg'] && $context['unified'] ) {
364 - wp_dequeue_script( 'help-center' );
365 - wp_dequeue_style( 'help-center-style' );
366 - }
367 -
368 163 /**
369 164 * Filter to register agent provider modules for the Agents Manager.
370 165 *
371 166 * Plugins can hook into this filter to register script module IDs that export
@@ -378,9 +173,9 @@
378 173
379 174 /**
380 175 * Filter the default agent ID for the Agents Manager.
381 176 *
382 - * Allows host applications (e.g., CIAB, WooCommerce AI) to specify a custom
177 + * Allows host applications (e.g., WooCommerce AI) to specify a custom
383 178 * workflow agent instead of the default orchestrator. The value is passed to
384 179 * the frontend as `agentsManagerData.agentId` and consumed by `useAgentConfig()`.
385 180 *
386 181 * @param string|null $agent_id The agent ID to use, or null for default behavior.
@@ -389,17 +184,15 @@
389 184
390 185 $script_version = $this->enqueue_script( $variant );
391 186
392 187 $inline_data = array(
393 - 'agentProviders' => $agent_providers,
394 - 'useUnifiedExperience' => $context['unified'],
395 - 'isDevMode' => self::is_dev_mode(),
396 - 'isA11n' => self::is_tracking_automattician(),
397 - 'isWpcomPlatform' => ( new \Automattic\Jetpack\Status\Host() )->is_wpcom_platform(),
398 - 'sectionName' => apply_filters( 'agents_manager_section_name', $variant ),
399 - 'currentUser' => $this->get_current_user_data(),
400 - 'site' => $this->get_current_site(),
401 - 'helpCenterUrl' => self::HELP_CENTER_URL,
188 + 'agentProviders' => $agent_providers,
189 + 'isDevMode' => self::is_dev_mode(),
190 + 'isA11n' => self::is_tracking_automattician(),
191 + 'isWpcomPlatform' => ( new \Automattic\Jetpack\Status\Host() )->is_wpcom_platform(),
192 + 'sectionName' => apply_filters( 'agents_manager_section_name', $variant ),
193 + 'currentUser' => $this->get_current_user_data(),
194 + 'site' => $this->get_current_site(),
402 195 );
403 196
404 197 if ( null !== $script_version ) {
405 198 $inline_data['version'] = $variant . ':' . $script_version;
@@ -479,18 +272,10 @@
479 272 *
480 273 * @return string|null The variant name, or null if scripts should not be loaded.
481 274 */
482 275 private static function get_variant() {
483 - // CIAB: Load either the connected or disconnected variants if enabled.
484 - if ( self::is_ciab_environment() && self::is_enabled() ) {
485 - return self::is_jetpack_disconnected() ? 'ciab-disconnected' : 'ciab';
486 - }
487 -
488 - // Frontend: load disconnected variant for eligible logged-in editors.
276 + // Agents Manager does not render on the frontend.
489 277 if ( ! is_admin() ) {
490 - if ( self::is_loading_on_frontend() && self::is_enabled() ) {
491 - return 'wp-admin-disconnected';
492 - }
493 278 return null;
494 279 }
495 280
496 281 // Apply wp-admin exclusions (customizer, asset, and preview contexts).
@@ -507,34 +292,12 @@
507 292 if ( self::is_block_editor() ) {
508 293 return $disconnected ? 'gutenberg-disconnected' : 'gutenberg';
509 294 }
510 295
511 - return $disconnected ? 'wp-admin-disconnected' : 'wp-admin';
296 + return $disconnected ? null : 'wp-admin';
512 297 }
513 298
514 299 /**
515 - * Whether the unified experience — the Help Center takeover — is active.
516 - *
517 - * "Unified" here means Agents Manager takes over the Help Center, unifying Odie and
518 - * Dolly (the orchestrator) into a single chat experience. This is distinct from
519 - * block-editor-only enablement, which replaces Big Sky's native UI without taking
520 - * over the Help Center.
521 - *
522 - * @return bool
523 - */
524 - public static function is_unified_experience() {
525 - /**
526 - * Filter to determine if the user should see the unified chat experience.
527 - *
528 - * When true, Help Center will render UnifiedAIAgent instead of traditional UI.
529 - * The filter is hooked by should_use_unified_experience() in this class.
530 - *
531 - * @param bool $use_unified_experience Whether to use unified experience. Default false.
532 - */
533 - return (bool) apply_filters( 'agents_manager_use_unified_experience', false );
534 - }
535 -
536 - /**
537 300 * Returns true if the Agents Manager should be loaded in the current context.
538 301 *
539 302 * @return bool
540 303 */
@@ -540,21 +303,9 @@
540 303 */
541 304 public static function is_enabled() {
542 305 $enabled = false;
543 306
544 - // CIAB: Agents Manager is the default AI experience — enabled unless explicitly
545 - // disabled via filter (e.g. for debugging or gradual rollout).
546 - if ( self::is_ciab_environment() ) {
547 - /**
548 - * Filter whether Agents Manager is enabled in CIAB (Next Admin) environments.
549 - *
550 - * @param bool $enabled Whether Agents Manager should load. Default true.
551 - */
552 - $enabled = (bool) apply_filters( 'agents_manager_enabled_in_ciab', true );
553 - } elseif ( self::is_unified_experience() ) {
554 - // Full unified experience: Agents Manager with support guides, Help Center takeover, etc.
555 - $enabled = true;
556 - } elseif ( self::is_block_editor() && apply_filters( 'agents_manager_enabled_in_block_editor', false ) ) {
307 + if ( self::is_block_editor() && apply_filters( 'agents_manager_enabled_in_block_editor', false ) ) {
557 308 // Block editor only: Agents Manager replaces Big Sky's native UI. Hooked by Big Sky.
558 309 $enabled = true;
559 310 }
560 311
@@ -655,9 +406,9 @@
655 406 */
656 407 apply_filters( 'agents_manager_enqueue_script_strategy', true, 'agents-manager' )
657 408 );
658 409
659 - if ( 'gutenberg-disconnected' !== $variant && 'ciab-disconnected' !== $variant ) {
410 + if ( 'gutenberg-disconnected' !== $variant ) {
660 411 wp_enqueue_style(
661 412 'agents-manager-style',
662 413 'https://widgets.wp.com/agents-manager/agents-manager-' . $variant . ( is_rtl() ? '.rtl.css' : '.css' ),
663 414 array(),
@@ -874,9 +625,9 @@
874 625 case 1:
875 626 case 2:
876 627 case 3: // Pressable
877 628 case 32:
878 - case 118: // Commerce garden client (ciab)
629 + case 118: // Commerce garden client.
879 630 return true;
880 631 }
881 632 }
882 633
@@ -891,149 +642,8 @@
891 642 ( new REST_Jetpack_AI_JWT() )->register_rest_route();
892 643 }
893 644
894 645 /**
895 - * Determine if user should see unified experience.
896 - *
897 - * @param bool $use_unified_experience Whether to use unified experience.
898 - * @return bool
899 - */
900 - public function should_use_unified_experience( $use_unified_experience = false ) {
901 - // Early return for non-proxied/dev mode requests.
902 - // This feature is currently only available to Automattic employees testing via proxy.
903 - if ( ! self::is_dev_mode() ) {
904 - return false;
905 - }
906 -
907 - $user_id = get_current_user_id();
908 -
909 - if ( ! $user_id ) {
910 - return false;
911 - }
912 -
913 - $is_simple_site = ( new \Automattic\Jetpack\Status\Host() )->is_wpcom_simple();
914 - if ( $is_simple_site ) {
915 - // On Simple sites, evaluate locally.
916 - // Check Automattician and opt-in setting.
917 - $is_automattician = function_exists( '\is_automattician' ) && \is_automattician( $user_id );
918 - if ( $is_automattician && $this->has_unified_chat_opt_in_enabled( $user_id ) ) {
919 - return true;
920 - }
921 - }
922 -
923 - // On WoA and Garden sites, delegate to wpcom via the /agents-manager/state endpoint.
924 - // This avoids duplicating rollout logic and handles cases where
925 - // wpcom-specific functions (like get_user_attribute) aren't available.
926 - if ( $this->fetch_unified_experience_preference() ) {
927 - return true;
928 - }
929 -
930 - // Default to false, for now.
931 - // In the future: users with a big sky site (similar to https://github.a8c.com/Automattic/wpcom/pull/196449/files), a big-sky free trial or a paid plan.
932 - return $use_unified_experience;
933 - }
934 -
935 - /**
936 - * Check if user has enabled unified chat opt-in in their Automattician options.
937 - *
938 - * This checks the unified_ai_chat calypso preference set via the wpcom profile settings.
939 - * Only used on Simple sites where get_user_attribute is available.
940 - *
941 - * @param int $user_id User ID.
942 - *
943 - * @return bool
944 - */
945 - private function has_unified_chat_opt_in_enabled( $user_id ) {
946 - if ( ! function_exists( '\get_user_attribute' ) ) {
947 - return false;
948 - }
949 -
950 - $calypso_prefs = \get_user_attribute( $user_id, 'calypso_preferences' );
951 - return ! empty( $calypso_prefs['unified_ai_chat'] );
952 - }
953 -
954 - /**
955 - * Fetch unified experience preference from wpcom via Jetpack Connection.
956 - *
957 - * Used on Atomic sites to delegate the decision to wpcom, which has
958 - * access to user attributes and can evaluate the rollout logic.
959 - *
960 - * Calls /agents-manager/state endpoint which is accessible via Jetpack user tokens.
961 - *
962 - * @return bool Whether user should see unified experience.
963 - */
964 - private function fetch_unified_experience_preference() {
965 - $user_id = get_current_user_id();
966 - if ( ! $user_id ) {
967 - return false;
968 - }
969 -
970 - // Check transient cache first (per-user cache).
971 - $cache_key = 'unified-experience-' . $user_id;
972 - $cached_result = get_transient( $cache_key );
973 - if ( false !== $cached_result ) {
974 - return (bool) $cached_result;
975 - }
976 -
977 - // Check if user is connected before making API call.
978 - if ( ! ( new Connection_Manager() )->is_user_connected( $user_id ) ) {
979 - return false;
980 - }
981 -
982 - // Call dedicated agents-manager/state endpoint.
983 - $wpcom_request = \Automattic\Jetpack\Connection\Client::wpcom_json_api_request_as_user(
984 - '/agents-manager/state?key=unified_ai_chat',
985 - '2',
986 - array( 'method' => 'GET' )
987 - );
988 -
989 - if ( is_wp_error( $wpcom_request ) ) {
990 - // Cache failures too to avoid hammering the API.
991 - set_transient( $cache_key, 0, MINUTE_IN_SECONDS );
992 - return false;
993 - }
994 -
995 - $response_code = wp_remote_retrieve_response_code( $wpcom_request );
996 - if ( 200 !== $response_code ) {
997 - set_transient( $cache_key, 0, MINUTE_IN_SECONDS );
998 - return false;
999 - }
1000 -
1001 - $body = wp_remote_retrieve_body( $wpcom_request );
1002 - $decoded_body = json_decode( $body, true );
1003 -
1004 - // The response is { "unified_ai_chat": true/false } when using key param.
1005 - $result = is_array( $decoded_body ) && ! empty( $decoded_body['unified_ai_chat'] );
1006 -
1007 - // Cache for 1 minute.
1008 - set_transient( $cache_key, $result ? 1 : 0, MINUTE_IN_SECONDS );
1009 -
1010 - return $result;
1011 - }
1012 -
1013 - /**
1014 - * Returns true if the current request is on the frontend and the user can edit posts.
1015 - *
1016 - * Mirrors Help_Center::is_loading_on_frontend().
1017 - *
1018 - * @return bool True if loading on the frontend for an eligible user.
1019 - */
1020 - private static function is_loading_on_frontend() {
1021 - // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This is a context check, not a form submission.
1022 - if ( isset( $_GET['na_site_preview'] ) || isset( $_GET['preview_overlay'] ) ) {
1023 - return false;
1024 - }
1025 -
1026 - // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This is a context check, not a form submission.
1027 - if ( isset( $_GET['preview'] ) && 'true' === sanitize_text_field( wp_unslash( $_GET['preview'] ) ) ) {
1028 - return false;
1029 - }
1030 -
1031 - $can_edit_posts = current_user_can( 'edit_posts' ) && is_user_member_of_blog();
1032 - return ! is_admin() && ! self::is_block_editor() && $can_edit_posts;
1033 - }
1034 -
1035 - /**
1036 646 * Returns true if the current screen is the block editor.
1037 647 *
1038 648 * @return bool True if the current screen is the block editor.
1039 649 */
@@ -1057,19 +667,8 @@
1057 667 * @return bool
1058 668 */
1059 669 private static function is_admin_bar_in_editor() {
1060 670 return self::is_block_editor() && is_admin_bar_showing();
1061 - }
1062 -
1063 - /**
1064 - * Check if current environment is CIAB (Commerce in a Box) / Next Admin.
1065 - *
1066 - * Uses the same detection method as Help Center: checks if next_admin_init has fired.
1067 - *
1068 - * @return bool True if CIAB/Next Admin environment.
1069 - */
1070 - private static function is_ciab_environment() {
1071 - return (bool) did_action( 'next_admin_init' );
1072 671 }
1073 672
1074 673 /**
1075 674 * Returns true if the current user is NOT connected through Jetpack.