Make WordPress Core


Ignore:
Timestamp:
03/19/2026 01:55:45 PM (7 months ago)
Author:
SergeyBiryukov
Message:

AI: Introduce wp_supports_ai() function to control LLM-related features.

This includes a WP_AI_SUPPORT constant and a wp_supports_ai filter.

When false,

  • _wp_connectors_get_provider_settings() will return an empty array (short-circuiting the other functionality).
  • WP_AI_Client_Prompt_Builder() will short-circuit the construction with a WP_Error(). wp_ai_client_prompt() will still return an instance, to allow for fluidity to remain intact.

Priority: WP_AI_SUPPORT > add_filter( 'wp_supports_ai', ...) > (default: true)

Follow-up to [61943], [61749], [61943].

Props justlevine, westonruter, gziolo, flixos90, romainmrhenry, ahortin, chrismcelroyseo, SergeyBiryukov.
See #64706.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/connectors.php

    r62032 r62067  
    11<?php
    22/**
    3  * Connectors API: core functions for registering and managing connectors.
    4  *
    5  * The Connectors API provides a unified framework for registering and managing
    6  * external service integrations within WordPress. A "connector" represents a
    7  * connection to an external service — currently focused on AI providers — with
    8  * standardized metadata, authentication configuration, and plugin association.
    9  *
    10  * ## Overview
    11  *
    12  * The Connectors API enables developers to:
    13  *
    14  *  - Register AI provider connectors with standardized interfaces.
    15  *  - Define authentication methods and credential sources.
    16  *  - Associate connectors with WordPress.org plugins for install/activate UI.
    17  *  - Expose connector settings through the REST API with automatic key masking.
    18  *
    19  * ## AI Provider Plugins
    20  *
    21  * AI provider plugins that register with the WP AI Client's `ProviderRegistry`
    22  * get automatic connector integration — no explicit connector registration is
    23  * needed. The system discovers providers from the WP AI Client registry and
    24  * creates connectors with the correct name, description, logo, authentication
    25  * method, and setting name derived from the provider's configuration.
    26  *
    27  * The authentication method (`api_key` or `none`) is determined by the provider's
    28  * metadata in the WP AI Client. For `api_key` providers, a `setting_name` is
    29  * automatically generated following the same naming convention used for environment
    30  * variables and PHP constants (e.g., provider `openai` maps to `OPENAI_API_KEY`
    31  * for env/constant lookup).
    32  *
    33  * @see WordPress\AiClient\Providers\ProviderRegistry
    34  *
    35  * ## Admin UI Integration
    36  *
    37  * Registered `ai_provider` connectors appear on the Settings → Connectors
    38  * admin screen. The screen renders each connector as a card using the
    39  * registry data:
    40  *
    41  *  - `name`, `description`, and `logo_url` are displayed on the card.
    42  *  - `plugin.slug` enables install/activate controls — the screen checks
    43  *    whether the plugin is installed and active, and shows the appropriate
    44  *    action button.
    45  *  - `authentication.credentials_url` is rendered as a link directing users
    46  *    to the provider's site to obtain API credentials.
    47  *  - For `api_key` connectors, the screen shows the current key source
    48  *    (environment variable, PHP constant, or database) and connection status.
    49  *
    50  * On the backend, `api_key` connectors also receive automatic settings
    51  * registration via the Settings API (`show_in_rest`), API key masking in
    52  * REST API responses, and key validation against the provider on update.
    53  *
    54  * Connectors with other authentication methods or types are registered in the PHP
    55  * registry and exposed via the script module data, but require a client-side
    56  * JavaScript registration for custom frontend UI. Support for additional
    57  * authentication methods and connector types is planned for future releases.
    58  *
    59  * ## Custom Connectors
    60  *
    61  * The `wp_connectors_init` action hook allows plugins to override metadata on
    62  * existing connectors. AI provider connectors are auto-discovered from the WP
    63  * AI Client registry and should not be manually registered here.
    64  *
    65  * Example — overriding the description of an auto-discovered connector:
    66  *
    67  *     add_action( 'wp_connectors_init', function ( WP_Connector_Registry $registry ) {
    68  *         if ( $registry->is_registered( 'openai' ) ) {
    69  *             $connector = $registry->unregister( 'openai' );
    70  *             $connector['description'] = __( 'Custom description for OpenAI.', 'my-plugin' );
    71  *             $registry->register( 'openai', $connector );
    72  *         }
    73  *     } );
    74  *
    75  * Non-AI-provider connector types are not yet fully supported. The PHP registry
    76  * accepts any connector type, but only `ai_provider` connectors with `api_key`
    77  * authentication receive automatic admin UI. Support for additional connector
    78  * types with dedicated frontend integration is planned for future releases.
    79  * When available, this action will be the primary hook for registering those
    80  * new connector types.
    81  *
    82  * ## Initialization Lifecycle
    83  *
    84  * During `init`, the system:
    85  *
    86  *  1. Creates the `WP_Connector_Registry` singleton.
    87  *  2. Registers built-in connectors (Anthropic, Google, OpenAI) with hardcoded defaults.
    88  *  3. Auto-discovers providers from the WP AI Client registry and merges their
    89  *     metadata (name, description, logo, authentication) on top of defaults,
    90  *     with registry values taking precedence.
    91  *  4. Fires the `wp_connectors_init` action so plugins can override metadata
    92  *     on existing connectors or register additional connectors.
    93  *  5. Registers settings and passes stored API keys to the WP AI Client.
    94  *
    95  * ## Authentication
    96  *
    97  * Connectors support two authentication methods:
    98  *
    99  *  - `api_key`: Requires an API key, which can be provided via environment variable,
    100  *    PHP constant, or the database (checked in that order).
    101  *  - `none`: No authentication required.
    102  *
    103  * API keys stored in the database are automatically masked in REST API responses
    104  * and validated against the provider on update.
     3 * Connectors API.
    1054 *
    1065 * @package WordPress
    … …  
    11514 * Checks if a connector is registered.
    11615 *
    117  * Example:
    118  *
    119  *     if ( wp_is_connector_registered( 'openai' ) ) {
    120  *         // The OpenAI connector is available.
    121  *     }
    122  *
    12316 * @since 7.0.0
    12417 *
    12518 * @see WP_Connector_Registry::is_registered()
    126  * @see wp_get_connector()
    127  * @see wp_get_connectors()
    12819 *
    12920 * @param string $id The connector identifier.
    … …  
    14233 * Retrieves a registered connector.
    14334 *
    144  * Example:
    145  *
    146  *     $connector = wp_get_connector( 'openai' );
    147  *     if ( $connector ) {
    148  *         echo $connector['name']; // 'OpenAI'
    149  *     }
    150  *
    15135 * @since 7.0.0
    15236 *
    15337 * @see WP_Connector_Registry::get_registered()
    154  * @see wp_is_connector_registered()
    155  * @see wp_get_connectors()
    15638 *
    15739 * @param string $id The connector identifier.
    … …  
    20486 * Retrieves all registered connectors.
    20587 *
    206  * Example:
    207  *
    208  *     $connectors = wp_get_connectors();
    209  *     foreach ( $connectors as $id => $connector ) {
    210  *         printf( '%s: %s', $connector['name'], $connector['description'] );
    211  *     }
    212  *
    21388 * @since 7.0.0
    21489 *
    21590 * @see WP_Connector_Registry::get_all_registered()
    216  * @see wp_is_connector_registered()
    217  * @see wp_get_connector()
    21891 *
    21992 * @return array {
    … …  
    311184 * Initializes the connector registry with default connectors and fires the registration action.
    312185 *
    313  * This function orchestrates the full connector initialization sequence:
    314  *
    315  *  1. Creates the `WP_Connector_Registry` singleton instance.
    316  *  2. Defines built-in connectors (Anthropic, Google, OpenAI) with hardcoded defaults
    317  *     including name, description, type, plugin slug, and authentication configuration.
    318  *  3. Merges metadata from the WP AI Client provider registry on top of defaults.
    319  *     Registry values (from provider plugins) take precedence over hardcoded fallbacks
    320  *     for name, description, logo URL, and authentication method.
    321  *  4. Registers all connectors (built-in and AI Client-discovered) on the registry.
    322  *  5. Fires the `wp_connectors_init` action for plugins to override metadata
    323  *     on existing connectors or register additional connectors.
    324  *
    325  * Built-in connectors are registered before the action fires and cannot be unhooked.
    326  * Plugins should use the `wp_connectors_init` action to override metadata or
    327  * register new connectors via `$registry->register()`.
     186 * Creates the registry instance, registers built-in connectors (which cannot be unhooked),
     187 * and then fires the `wp_connectors_init` action for plugins to register their own connectors.
    328188 *
    329189 * @since 7.0.0
    … …  
    333193        $registry = new WP_Connector_Registry();
    334194        WP_Connector_Registry::set_instance( $registry );
     195
     196        // Only register default AI providers if AI support is enabled.
     197        if ( wp_supports_ai() ) {
     198                _wp_connectors_register_default_ai_providers( $registry );
     199        }
     200
     201        /**
     202         * Fires when the connector registry is ready for plugins to register connectors.
     203         *
     204         * Built-in connectors and any AI providers auto-discovered from the WP AI Client
     205         * registry have already been registered at this point and cannot be unhooked.
     206         *
     207         * AI provider plugins that register with the WP AI Client do not need to use
     208         * this action — their connectors are created automatically. This action is
     209         * primarily for registering non-AI-provider connectors or overriding metadata
     210         * on existing connectors.
     211         *
     212         * Use `$registry->register()` within this action to add new connectors.
     213         * To override an existing connector, unregister it first, then re-register
     214         * with updated data.
     215         *
     216         * Example — overriding metadata on an auto-discovered connector:
     217         *
     218         *     add_action( 'wp_connectors_init', function ( WP_Connector_Registry $registry ) {
     219         *         if ( $registry->is_registered( 'openai' ) ) {
     220         *             $connector = $registry->unregister( 'openai' );
     221         *             $connector['description'] = __( 'Custom description for OpenAI.', 'my-plugin' );
     222         *             $registry->register( 'openai', $connector );
     223         *         }
     224         *     } );
     225         *
     226         * @since 7.0.0
     227         *
     228         * @param WP_Connector_Registry $registry Connector registry instance.
     229         */
     230        do_action( 'wp_connectors_init', $registry );
     231}
     232
     233/**
     234 * Registers connectors for the built-in AI providers.
     235 *
     236 * @since 7.0.0
     237 * @access private
     238 *
     239 * @param WP_Connector_Registry $registry The connector registry instance.
     240 */
     241function _wp_connectors_register_default_ai_providers( WP_Connector_Registry $registry ): void {
    335242        // Built-in connectors.
    336243        $defaults = array(
    … …  
    431338                $registry->register( $id, $args );
    432339        }
    433 
    434         /**
    435          * Fires when the connector registry is ready for plugins to register connectors.
    436          *
    437          * Built-in connectors and any AI providers auto-discovered from the WP AI Client
    438          * registry have already been registered at this point and cannot be unhooked.
    439          *
    440          * AI provider plugins that register with the WP AI Client do not need to use
    441          * this action — their connectors are created automatically. This action is
    442          * primarily for registering non-AI-provider connectors or overriding metadata
    443          * on existing connectors.
    444          *
    445          * Use `$registry->register()` within this action to add new connectors.
    446          * To override an existing connector, unregister it first, then re-register
    447          * with updated data.
    448          *
    449          * Example — overriding metadata on an auto-discovered connector:
    450          *
    451          *     add_action( 'wp_connectors_init', function ( WP_Connector_Registry $registry ) {
    452          *         if ( $registry->is_registered( 'openai' ) ) {
    453          *             $connector = $registry->unregister( 'openai' );
    454          *             $connector['description'] = __( 'Custom description for OpenAI.', 'my-plugin' );
    455          *             $registry->register( 'openai', $connector );
    456          *         }
    457          *     } );
    458          *
    459          * @since 7.0.0
    460          *
    461          * @param WP_Connector_Registry $registry Connector registry instance.
    462          */
    463         do_action( 'wp_connectors_init', $registry );
    464340}
    465341
    … …  
    628504/**
    629505 * Registers default connector settings.
    630  *
    631  * Only registers settings for `ai_provider` connectors with `api_key`
    632  * authentication whose provider is present in the WP AI Client registry.
    633  * Each setting is registered with `show_in_rest` enabled, making it
    634  * accessible through the `/wp/v2/settings` REST endpoint.
    635506 *
    636507 * @since 7.0.0
    … …  
    721592
    722593/**
    723  * Provides connector data to the Settings → Connectors admin screen.
    724  *
    725  * This function is the bridge between the PHP connector registry and the
    726  * frontend admin UI. It transforms each registered connector into the data
    727  * structure consumed by the `options-connectors-wp-admin` script module,
    728  * enriching registry data with runtime state:
    729  *
    730  *  - Plugin install/activate status (via `get_plugins()` and `is_plugin_active()`).
    731  *  - API key source detection (`env`, `constant`, `database`, or `none`).
    732  *  - Connection status for `api_key` connectors (via the WP AI Client registry).
    733  *
    734  * Hooked to the `script_module_data_options-connectors-wp-admin` filter.
    735  *
    736  * @since 7.0.0
    737  * @access private
    738  *
    739  * @see _wp_connectors_get_api_key_source()
     594 * Exposes connector settings to the connectors-wp-admin script module.
     595 *
     596 * @since 7.0.0
     597 * @access private
    740598 *
    741599 * @param array<string, mixed> $data Existing script module data.
    742  * @return array<string, mixed> Script module data with a `connectors` key added,
    743  *                              keyed by connector ID and sorted alphabetically.
     600 * @return array<string, mixed> Script module data with connectors added.
    744601 */
    745602function _wp_connectors_get_connector_script_module_data( array $data ): array {
Note: See TracChangeset for help on using the changeset viewer.