Connectors: Dynamically register providers from WP AI Client registry#11080
Connectors: Dynamically register providers from WP AI Client registry#11080gziolo wants to merge 14 commits intoWordPress:trunkfrom
Conversation
|
@felixarntz, there are still some things to address, but it's close to ready to include all basic metadata that we could expose to the client to automatically expose their cards for registered plugins that implement AI providers. We would always show 3 featured AI providers by default, but their metadata would be replaced as soon as the corresponding plugin gets installed. For all other AI providers, they would show up on the Connectors screen only after they get installed, solely based on the metadata used during registration. |
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Core Committers: Use this line as a base for the props when committing in SVN: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
Polyfills WordPress/wordpress-develop#11080 for the Gutenberg plugin: - Expand `_gutenberg_get_provider_settings()` to dynamically fetch registered providers from the AI Client registry, in addition to the three hardcoded featured providers (Gemini, OpenAI, Claude). - Restructure the return value to be keyed by provider ID with `name`, `description`, `credentials_url` at the top level and `settings` as a nested array. - Filter out providers whose authentication method is not `api_key`. - Update all consumer functions to use the new structure. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3d53c9c to
e625773
Compare
|
I synced changes from WordPress/gutenberg#76014 based on the feedback provided there. To land these changes, we will have to sync the JS changes applied in the Gutenberg plugin, too. |
e625773 to
b78d7dd
Compare
jorgefilipecosta
left a comment
There was a problem hiding this comment.
Awesome work here things tested well for me.
In order to test with the JS/TS changes I applied the following patch:
diff --git a/package.json b/package.json
index acbe679d2f..1ada94f47c 100644
--- a/package.json
+++ b/package.json
@@ -6,9 +6,9 @@
"type": "svn",
"url": "https://develop.svn.wordpress.org/trunk"
},
"gutenberg": {
- "ref": "022d8dd3d461f91b15c1f0410649d3ebb027207f"
+ "ref": "853d89e66761c1bc60c2fae1c239261fc8c3b9cf"
},
"engines": {
"node": ">=20.10.0",
"npm": ">=10.2.3"
Left just some minor comments which can be considered before the merge.
tests/phpunit/tests/connectors/wpConnectorsGetProviderSettings.php
Outdated
Show resolved
Hide resolved
Polyfills WordPress/wordpress-develop#11080 for the Gutenberg plugin: - Expand `_gutenberg_get_provider_settings()` to dynamically fetch registered providers from the AI Client registry, in addition to the three hardcoded featured providers (Gemini, OpenAI, Claude). - Restructure the return value to be keyed by provider ID with `name`, `description`, `credentials_url` at the top level and `settings` as a nested array. - Filter out providers whose authentication method is not `api_key`. - Update all consumer functions to use the new structure. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…#76014) * Connectors: Dynamically register providers from WP AI Client registry Polyfills WordPress/wordpress-develop#11080 for the Gutenberg plugin: - Expand `_gutenberg_get_provider_settings()` to dynamically fetch registered providers from the AI Client registry, in addition to the three hardcoded featured providers (Gemini, OpenAI, Claude). - Restructure the return value to be keyed by provider ID with `name`, `description`, `credentials_url` at the top level and `settings` as a nested array. - Filter out providers whose authentication method is not `api_key`. - Update all consumer functions to use the new structure. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Expose provider settings to the script module Pass provider data (name, description, credentials URL, setting keys) to the `connectors-wp-admin` script module via the `script_module_data` filter, making it available as inline JSON for the frontend to consume. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Register connectors dynamically from server-provided data Replace hardcoded per-provider connector components with a single dynamic loop that reads provider data from the script module data JSON tag. Known providers retain their SVG logos via a client-side map; third-party providers from the registry render without a logo. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Connectors: Use ucwords fallback for empty provider name When a third-party provider from the AI Client registry has no name, fall back to ucwords( $provider_id ) for a reasonable display label. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Add authentication_method to provider data structure Expose authentication_method ('api_key' or 'none') in provider settings instead of silently filtering out non-API-key providers. This makes the public-facing interfaces extensible for future authentication methods while still only implementing api_key support for now. - Include all registered providers regardless of auth method - Conditionally generate settings sub-array only for api_key providers - Expose authenticationMethod in script module data for the frontend - Skip non-api_key providers in the frontend registration loop - Rename ProviderConnector to ApiKeyProviderConnector for clarity Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Add type field to distinguish AI providers from other connectors Add a 'type' field ('ai_provider') to the provider data structure so credentials are only passed to the WP AI Client for AI providers. The frontend also filters by type, only rendering connectors for AI providers. This separates AI providers from future non-AI connectors and makes the intent of the API explicit. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Group authentication fields into sub-object and eliminate settings duplication Restructure provider data so credentials_url, setting_name, and method live together in an authentication sub-object rather than as flat top-level fields. Remove the redundant settings array from _gutenberg_get_provider_settings() and move register_setting logic (label, description, sanitize) into the consumer function. Update all PHP consumers to read from authentication directly. On the frontend, change ProviderAuthentication to a discriminated union type for type-safe access after narrowing on method. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Rename _gutenberg_get_provider_settings to _gutenberg_get_connector_settings Use the domain term "connector" consistently with the rest of the codebase (settings group, option names, script module filter). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Clarify authentication docblock for none method Document that credentials_url and setting_name are only present when method is 'api_key' and absent when method is 'none'. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Use URL hostname for help label instead of regex stripping Replace manual regex URL stripping with new URL().hostname for a cleaner, more robust extraction of the domain name used as the help link label. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Use type-based namespace for connector names Derive the connector name namespace from data.type instead of hardcoding 'core/'. Sanitize both parts to only allow letters, numbers, and hyphens. This produces names like 'ai-provider/google'. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Rename ApiKeyProviderConnector and derive helpLabel internally Rename ApiKeyProviderConnector to ApiKeyConnector and move helpLabel derivation from the registration loop into the component itself, since it already receives helpUrl. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Connectors: Rename _gutenberg_is_api_key_valid to _gutenberg_is_ai_api_key_valid The function is AI-provider-specific, so the name should reflect that. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Move sanitize helper outside the loop Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Pass plugin data from server instead of deriving slug client-side Hardcode plugin slugs for the three featured AI providers in PHP within a `plugin` sub-object and pass them to the client via script module data. When no plugin data is provided (e.g. dynamically registered providers), the install/activate UI is skipped and the connector assumes the plugin is already active. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add backport changelog entry for Core PR #11080 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Add remove_filter for Core script module data function Ensures the Gutenberg version overrides the equivalent Core function (_wp_connectors_get_connector_script_module_data), consistent with the pattern used by the other connector functions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Felix Arntz <flixos90@gmail.com> Co-authored-by: gziolo <gziolo@git.wordpress.org> Co-authored-by: raftaar1191 <raftaar1191@git.wordpress.org> Co-authored-by: jorgefilipecosta <jorgefilipecosta@git.wordpress.org> Co-authored-by: felixarntz <flixos90@git.wordpress.org>
…#76014) * Connectors: Dynamically register providers from WP AI Client registry Polyfills WordPress/wordpress-develop#11080 for the Gutenberg plugin: - Expand `_gutenberg_get_provider_settings()` to dynamically fetch registered providers from the AI Client registry, in addition to the three hardcoded featured providers (Gemini, OpenAI, Claude). - Restructure the return value to be keyed by provider ID with `name`, `description`, `credentials_url` at the top level and `settings` as a nested array. - Filter out providers whose authentication method is not `api_key`. - Update all consumer functions to use the new structure. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Expose provider settings to the script module Pass provider data (name, description, credentials URL, setting keys) to the `connectors-wp-admin` script module via the `script_module_data` filter, making it available as inline JSON for the frontend to consume. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Register connectors dynamically from server-provided data Replace hardcoded per-provider connector components with a single dynamic loop that reads provider data from the script module data JSON tag. Known providers retain their SVG logos via a client-side map; third-party providers from the registry render without a logo. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Connectors: Use ucwords fallback for empty provider name When a third-party provider from the AI Client registry has no name, fall back to ucwords( $provider_id ) for a reasonable display label. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Add authentication_method to provider data structure Expose authentication_method ('api_key' or 'none') in provider settings instead of silently filtering out non-API-key providers. This makes the public-facing interfaces extensible for future authentication methods while still only implementing api_key support for now. - Include all registered providers regardless of auth method - Conditionally generate settings sub-array only for api_key providers - Expose authenticationMethod in script module data for the frontend - Skip non-api_key providers in the frontend registration loop - Rename ProviderConnector to ApiKeyProviderConnector for clarity Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Add type field to distinguish AI providers from other connectors Add a 'type' field ('ai_provider') to the provider data structure so credentials are only passed to the WP AI Client for AI providers. The frontend also filters by type, only rendering connectors for AI providers. This separates AI providers from future non-AI connectors and makes the intent of the API explicit. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Group authentication fields into sub-object and eliminate settings duplication Restructure provider data so credentials_url, setting_name, and method live together in an authentication sub-object rather than as flat top-level fields. Remove the redundant settings array from _gutenberg_get_provider_settings() and move register_setting logic (label, description, sanitize) into the consumer function. Update all PHP consumers to read from authentication directly. On the frontend, change ProviderAuthentication to a discriminated union type for type-safe access after narrowing on method. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Rename _gutenberg_get_provider_settings to _gutenberg_get_connector_settings Use the domain term "connector" consistently with the rest of the codebase (settings group, option names, script module filter). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Clarify authentication docblock for none method Document that credentials_url and setting_name are only present when method is 'api_key' and absent when method is 'none'. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Use URL hostname for help label instead of regex stripping Replace manual regex URL stripping with new URL().hostname for a cleaner, more robust extraction of the domain name used as the help link label. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Use type-based namespace for connector names Derive the connector name namespace from data.type instead of hardcoding 'core/'. Sanitize both parts to only allow letters, numbers, and hyphens. This produces names like 'ai-provider/google'. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Rename ApiKeyProviderConnector and derive helpLabel internally Rename ApiKeyProviderConnector to ApiKeyConnector and move helpLabel derivation from the registration loop into the component itself, since it already receives helpUrl. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Connectors: Rename _gutenberg_is_api_key_valid to _gutenberg_is_ai_api_key_valid The function is AI-provider-specific, so the name should reflect that. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Move sanitize helper outside the loop Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Pass plugin data from server instead of deriving slug client-side Hardcode plugin slugs for the three featured AI providers in PHP within a `plugin` sub-object and pass them to the client via script module data. When no plugin data is provided (e.g. dynamically registered providers), the install/activate UI is skipped and the connector assumes the plugin is already active. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add backport changelog entry for Core PR #11080 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Add remove_filter for Core script module data function Ensures the Gutenberg version overrides the equivalent Core function (_wp_connectors_get_connector_script_module_data), consistent with the pattern used by the other connector functions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Felix Arntz <flixos90@gmail.com> Co-authored-by: gziolo <gziolo@git.wordpress.org> Co-authored-by: raftaar1191 <raftaar1191@git.wordpress.org> Co-authored-by: jorgefilipecosta <jorgefilipecosta@git.wordpress.org> Co-authored-by: felixarntz <flixos90@git.wordpress.org>
a5a5d22 to
3d72894
Compare
|
@jorgefilipecosta, I synced all the changes from the Gutenberg plugin merged with WordPress/gutenberg#76014, and addressed all your feedback.
|
|
@ellatrix, would it be possible to sync Gutenberg plugin changes (WordPress/gutenberg@3763f32) as part of this PR? They are necessary so these changes continue to work. |
|
Yes, but if you can, I'd do an update up until (and excluding) the commit you need that includes a log of all changes that were made in Gutenberg. Then you could update the sha as part of this PR that just bumps it by one commit. We currently don't have a good process for this because it's all new. How would we have done it for packages? Cc @desrosj because I know you really like to have the changelog in the commit message. |
…WordPress#76014) * Connectors: Dynamically register providers from WP AI Client registry Polyfills WordPress/wordpress-develop#11080 for the Gutenberg plugin: - Expand `_gutenberg_get_provider_settings()` to dynamically fetch registered providers from the AI Client registry, in addition to the three hardcoded featured providers (Gemini, OpenAI, Claude). - Restructure the return value to be keyed by provider ID with `name`, `description`, `credentials_url` at the top level and `settings` as a nested array. - Filter out providers whose authentication method is not `api_key`. - Update all consumer functions to use the new structure. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Expose provider settings to the script module Pass provider data (name, description, credentials URL, setting keys) to the `connectors-wp-admin` script module via the `script_module_data` filter, making it available as inline JSON for the frontend to consume. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Register connectors dynamically from server-provided data Replace hardcoded per-provider connector components with a single dynamic loop that reads provider data from the script module data JSON tag. Known providers retain their SVG logos via a client-side map; third-party providers from the registry render without a logo. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Connectors: Use ucwords fallback for empty provider name When a third-party provider from the AI Client registry has no name, fall back to ucwords( $provider_id ) for a reasonable display label. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Add authentication_method to provider data structure Expose authentication_method ('api_key' or 'none') in provider settings instead of silently filtering out non-API-key providers. This makes the public-facing interfaces extensible for future authentication methods while still only implementing api_key support for now. - Include all registered providers regardless of auth method - Conditionally generate settings sub-array only for api_key providers - Expose authenticationMethod in script module data for the frontend - Skip non-api_key providers in the frontend registration loop - Rename ProviderConnector to ApiKeyProviderConnector for clarity Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Add type field to distinguish AI providers from other connectors Add a 'type' field ('ai_provider') to the provider data structure so credentials are only passed to the WP AI Client for AI providers. The frontend also filters by type, only rendering connectors for AI providers. This separates AI providers from future non-AI connectors and makes the intent of the API explicit. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Group authentication fields into sub-object and eliminate settings duplication Restructure provider data so credentials_url, setting_name, and method live together in an authentication sub-object rather than as flat top-level fields. Remove the redundant settings array from _gutenberg_get_provider_settings() and move register_setting logic (label, description, sanitize) into the consumer function. Update all PHP consumers to read from authentication directly. On the frontend, change ProviderAuthentication to a discriminated union type for type-safe access after narrowing on method. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Rename _gutenberg_get_provider_settings to _gutenberg_get_connector_settings Use the domain term "connector" consistently with the rest of the codebase (settings group, option names, script module filter). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Clarify authentication docblock for none method Document that credentials_url and setting_name are only present when method is 'api_key' and absent when method is 'none'. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Use URL hostname for help label instead of regex stripping Replace manual regex URL stripping with new URL().hostname for a cleaner, more robust extraction of the domain name used as the help link label. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Use type-based namespace for connector names Derive the connector name namespace from data.type instead of hardcoding 'core/'. Sanitize both parts to only allow letters, numbers, and hyphens. This produces names like 'ai-provider/google'. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Rename ApiKeyProviderConnector and derive helpLabel internally Rename ApiKeyProviderConnector to ApiKeyConnector and move helpLabel derivation from the registration loop into the component itself, since it already receives helpUrl. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Connectors: Rename _gutenberg_is_api_key_valid to _gutenberg_is_ai_api_key_valid The function is AI-provider-specific, so the name should reflect that. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Move sanitize helper outside the loop Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Pass plugin data from server instead of deriving slug client-side Hardcode plugin slugs for the three featured AI providers in PHP within a `plugin` sub-object and pass them to the client via script module data. When no plugin data is provided (e.g. dynamically registered providers), the install/activate UI is skipped and the connector assumes the plugin is already active. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add backport changelog entry for Core PR WordPress#11080 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Add remove_filter for Core script module data function Ensures the Gutenberg version overrides the equivalent Core function (_wp_connectors_get_connector_script_module_data), consistent with the pattern used by the other connector functions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Felix Arntz <flixos90@gmail.com> Co-authored-by: gziolo <gziolo@git.wordpress.org> Co-authored-by: raftaar1191 <raftaar1191@git.wordpress.org> Co-authored-by: jorgefilipecosta <jorgefilipecosta@git.wordpress.org> Co-authored-by: felixarntz <flixos90@git.wordpress.org>
… (#76014) * Connectors: Dynamically register providers from WP AI Client registry Polyfills WordPress/wordpress-develop#11080 for the Gutenberg plugin: - Expand `_gutenberg_get_provider_settings()` to dynamically fetch registered providers from the AI Client registry, in addition to the three hardcoded featured providers (Gemini, OpenAI, Claude). - Restructure the return value to be keyed by provider ID with `name`, `description`, `credentials_url` at the top level and `settings` as a nested array. - Filter out providers whose authentication method is not `api_key`. - Update all consumer functions to use the new structure. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Expose provider settings to the script module Pass provider data (name, description, credentials URL, setting keys) to the `connectors-wp-admin` script module via the `script_module_data` filter, making it available as inline JSON for the frontend to consume. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Register connectors dynamically from server-provided data Replace hardcoded per-provider connector components with a single dynamic loop that reads provider data from the script module data JSON tag. Known providers retain their SVG logos via a client-side map; third-party providers from the registry render without a logo. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Connectors: Use ucwords fallback for empty provider name When a third-party provider from the AI Client registry has no name, fall back to ucwords( $provider_id ) for a reasonable display label. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Add authentication_method to provider data structure Expose authentication_method ('api_key' or 'none') in provider settings instead of silently filtering out non-API-key providers. This makes the public-facing interfaces extensible for future authentication methods while still only implementing api_key support for now. - Include all registered providers regardless of auth method - Conditionally generate settings sub-array only for api_key providers - Expose authenticationMethod in script module data for the frontend - Skip non-api_key providers in the frontend registration loop - Rename ProviderConnector to ApiKeyProviderConnector for clarity Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Add type field to distinguish AI providers from other connectors Add a 'type' field ('ai_provider') to the provider data structure so credentials are only passed to the WP AI Client for AI providers. The frontend also filters by type, only rendering connectors for AI providers. This separates AI providers from future non-AI connectors and makes the intent of the API explicit. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Group authentication fields into sub-object and eliminate settings duplication Restructure provider data so credentials_url, setting_name, and method live together in an authentication sub-object rather than as flat top-level fields. Remove the redundant settings array from _gutenberg_get_provider_settings() and move register_setting logic (label, description, sanitize) into the consumer function. Update all PHP consumers to read from authentication directly. On the frontend, change ProviderAuthentication to a discriminated union type for type-safe access after narrowing on method. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Rename _gutenberg_get_provider_settings to _gutenberg_get_connector_settings Use the domain term "connector" consistently with the rest of the codebase (settings group, option names, script module filter). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Clarify authentication docblock for none method Document that credentials_url and setting_name are only present when method is 'api_key' and absent when method is 'none'. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Use URL hostname for help label instead of regex stripping Replace manual regex URL stripping with new URL().hostname for a cleaner, more robust extraction of the domain name used as the help link label. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Use type-based namespace for connector names Derive the connector name namespace from data.type instead of hardcoding 'core/'. Sanitize both parts to only allow letters, numbers, and hyphens. This produces names like 'ai-provider/google'. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Rename ApiKeyProviderConnector and derive helpLabel internally Rename ApiKeyProviderConnector to ApiKeyConnector and move helpLabel derivation from the registration loop into the component itself, since it already receives helpUrl. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Connectors: Rename _gutenberg_is_api_key_valid to _gutenberg_is_ai_api_key_valid The function is AI-provider-specific, so the name should reflect that. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Move sanitize helper outside the loop Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Pass plugin data from server instead of deriving slug client-side Hardcode plugin slugs for the three featured AI providers in PHP within a `plugin` sub-object and pass them to the client via script module data. When no plugin data is provided (e.g. dynamically registered providers), the install/activate UI is skipped and the connector assumes the plugin is already active. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add backport changelog entry for Core PR #11080 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Add remove_filter for Core script module data function Ensures the Gutenberg version overrides the equivalent Core function (_wp_connectors_get_connector_script_module_data), consistent with the pattern used by the other connector functions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Felix Arntz <flixos90@gmail.com> Co-authored-by: gziolo <gziolo@git.wordpress.org> Co-authored-by: raftaar1191 <raftaar1191@git.wordpress.org> Co-authored-by: jorgefilipecosta <jorgefilipecosta@git.wordpress.org> Co-authored-by: felixarntz <flixos90@git.wordpress.org> Source: WordPress/gutenberg@7f7f2ea
… (#76014) * Connectors: Dynamically register providers from WP AI Client registry Polyfills WordPress/wordpress-develop#11080 for the Gutenberg plugin: - Expand `_gutenberg_get_provider_settings()` to dynamically fetch registered providers from the AI Client registry, in addition to the three hardcoded featured providers (Gemini, OpenAI, Claude). - Restructure the return value to be keyed by provider ID with `name`, `description`, `credentials_url` at the top level and `settings` as a nested array. - Filter out providers whose authentication method is not `api_key`. - Update all consumer functions to use the new structure. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Expose provider settings to the script module Pass provider data (name, description, credentials URL, setting keys) to the `connectors-wp-admin` script module via the `script_module_data` filter, making it available as inline JSON for the frontend to consume. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Register connectors dynamically from server-provided data Replace hardcoded per-provider connector components with a single dynamic loop that reads provider data from the script module data JSON tag. Known providers retain their SVG logos via a client-side map; third-party providers from the registry render without a logo. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Connectors: Use ucwords fallback for empty provider name When a third-party provider from the AI Client registry has no name, fall back to ucwords( $provider_id ) for a reasonable display label. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Add authentication_method to provider data structure Expose authentication_method ('api_key' or 'none') in provider settings instead of silently filtering out non-API-key providers. This makes the public-facing interfaces extensible for future authentication methods while still only implementing api_key support for now. - Include all registered providers regardless of auth method - Conditionally generate settings sub-array only for api_key providers - Expose authenticationMethod in script module data for the frontend - Skip non-api_key providers in the frontend registration loop - Rename ProviderConnector to ApiKeyProviderConnector for clarity Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Add type field to distinguish AI providers from other connectors Add a 'type' field ('ai_provider') to the provider data structure so credentials are only passed to the WP AI Client for AI providers. The frontend also filters by type, only rendering connectors for AI providers. This separates AI providers from future non-AI connectors and makes the intent of the API explicit. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Group authentication fields into sub-object and eliminate settings duplication Restructure provider data so credentials_url, setting_name, and method live together in an authentication sub-object rather than as flat top-level fields. Remove the redundant settings array from _gutenberg_get_provider_settings() and move register_setting logic (label, description, sanitize) into the consumer function. Update all PHP consumers to read from authentication directly. On the frontend, change ProviderAuthentication to a discriminated union type for type-safe access after narrowing on method. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Rename _gutenberg_get_provider_settings to _gutenberg_get_connector_settings Use the domain term "connector" consistently with the rest of the codebase (settings group, option names, script module filter). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Clarify authentication docblock for none method Document that credentials_url and setting_name are only present when method is 'api_key' and absent when method is 'none'. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Use URL hostname for help label instead of regex stripping Replace manual regex URL stripping with new URL().hostname for a cleaner, more robust extraction of the domain name used as the help link label. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Use type-based namespace for connector names Derive the connector name namespace from data.type instead of hardcoding 'core/'. Sanitize both parts to only allow letters, numbers, and hyphens. This produces names like 'ai-provider/google'. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Rename ApiKeyProviderConnector and derive helpLabel internally Rename ApiKeyProviderConnector to ApiKeyConnector and move helpLabel derivation from the registration loop into the component itself, since it already receives helpUrl. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Update lib/experimental/connectors/default-connectors.php Co-authored-by: Felix Arntz <flixos90@gmail.com> * Connectors: Rename _gutenberg_is_api_key_valid to _gutenberg_is_ai_api_key_valid The function is AI-provider-specific, so the name should reflect that. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Move sanitize helper outside the loop Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Pass plugin data from server instead of deriving slug client-side Hardcode plugin slugs for the three featured AI providers in PHP within a `plugin` sub-object and pass them to the client via script module data. When no plugin data is provided (e.g. dynamically registered providers), the install/activate UI is skipped and the connector assumes the plugin is already active. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add backport changelog entry for Core PR #11080 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Connectors: Add remove_filter for Core script module data function Ensures the Gutenberg version overrides the equivalent Core function (_wp_connectors_get_connector_script_module_data), consistent with the pattern used by the other connector functions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Felix Arntz <flixos90@gmail.com> Co-authored-by: gziolo <gziolo@git.wordpress.org> Co-authored-by: raftaar1191 <raftaar1191@git.wordpress.org> Co-authored-by: jorgefilipecosta <jorgefilipecosta@git.wordpress.org> Co-authored-by: felixarntz <flixos90@git.wordpress.org> Source: WordPress/gutenberg@3763f32
@gziolo @jorgefilipecosta I'm catching up - did the rest of the feedback from the initial WordPress/gutenberg#75833 make it in too? Particularly on my mind is the unencrypted API key storage. |
felixarntz
left a comment
There was a problem hiding this comment.
Thanks @gziolo for bringing this over here, and all the iterations.
LGTM, except for a few notes. Once you've address these, I think this is good to commit. I'm preemptively approving.
Expand `_wp_connectors_get_provider_settings()` to fetch registered providers from the AI Client registry alongside the hardcoded featured providers. Restructure the return value to be keyed by provider ID with `name`, `description`, `credentials_url`, and nested `settings`. Filter out providers that don't use API key authentication. Update all consumer functions and tests accordingly. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…callback. Filter out empty registry values before merging so hardcoded fallbacks (e.g. credentials_url, description) are preserved when the registry doesn't provide them. Replace per-setting $config['mask'] references with direct '_wp_connectors_mask_api_key' calls since the callback is always the same. Make REST settings test resilient to dynamically registered connector providers by querying get_registered_settings(). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… changes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…and expose to script module. Polyfills WordPress/gutenberg#76014: - Rename _wp_connectors_get_provider_settings() to _wp_connectors_get_connector_settings() with a restructured return format: type field, authentication sub-object (method, credentials_url, setting_name) replacing the nested settings array. - Include all registered providers regardless of auth method (api_key or none) instead of filtering out non-API-key providers. - Move label, description, and sanitize logic into consumer functions. - Add ucwords() fallback for providers with no name. - Add _wp_connectors_get_connector_script_module_data() to expose connector data to the connectors-wp-admin script module. - Update all consumer functions and tests to use the new structure. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
getDescription() is now part of the provider metadata API contract, so the defensive method_exists() guard is no longer needed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…rovider names. - Add plugin sub-object with WordPress.org slugs to featured connector definitions for install/activate UI support. - Expose plugin data in script module output for the frontend. - Rename _wp_connectors_is_api_key_valid to _wp_connectors_is_ai_api_key_valid to reflect AI-provider scope. - Update provider names and descriptions to match Gutenberg PR #76014. - Add type check for 'ai_provider' in REST validation function. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Renames Tests_Connectors_WpConnectorsGetProviderSettings to Tests_Connectors_WpConnectorsGetConnectorSettings and the file from wpConnectorsGetProviderSettings.php to wpConnectorsGetConnectorSettings.php to match the renamed _wp_connectors_get_connector_settings() function. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… changes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…om fixtures. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…rity 20. This ensures plugins registering AI providers at default priority have completed before connector settings are built from the registry. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… re-init. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Addresses review feedback: - Reorder default providers alphabetically (Anthropic, Google, OpenAI). - Sort all registered providers with `ksort()` for neutral ordering. - Add `ai_provider` type check in settings registration to prevent AI-specific sanitize/description logic from applying to other types. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
838bea4 to
1aec060
Compare
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Core Committers: Use this line as a base for the props when committing in SVN: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
It's now tracked in https://core.trac.wordpress.org/ticket/64789 with the list of proposed actions to keep the discussion going. |
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replaces `_wp_connectors_get_provider_settings()` with `_wp_connectors_get_connector_settings()` that returns a richer structure keyed by connector ID, including name, description, type, plugin slug, and an authentication sub-object (method, credentials_url, setting_name). The new function merges hardcoded defaults for featured providers (Anthropic, Google, OpenAI) with metadata from the WP AI Client registry, allowing dynamically registered providers to appear alongside built-in ones. Providers are sorted alphabetically with `ksort()`. Additionally: * Renames `_wp_connectors_is_api_key_valid()` to `_wp_connectors_is_ai_api_key_valid()`. * Adds `_wp_connectors_get_connector_script_module_data()` to expose connector settings to the `connectors-wp-admin` script module. * Includes plugin slug data for featured connectors to support install/activate UI. * Removes redundant `class_exists` checks for `AiClient`. * Runs `init` hooks at priority 20 so provider plugins registered at default priority are available. * Unhooks connector registration during tests to prevent duplicate registrations. Synced from WordPress/gutenberg#76014. Developed in #11080. Follow-up to [61749]. Props gziolo, jorgefilipecosta, justlevine, flixos90, ellatrix. Fixes #64730. git-svn-id: https://develop.svn.wordpress.org/trunk@61824 602fd350-edb4-49c9-b593-d223f7449a82
Replaces `_wp_connectors_get_provider_settings()` with `_wp_connectors_get_connector_settings()` that returns a richer structure keyed by connector ID, including name, description, type, plugin slug, and an authentication sub-object (method, credentials_url, setting_name). The new function merges hardcoded defaults for featured providers (Anthropic, Google, OpenAI) with metadata from the WP AI Client registry, allowing dynamically registered providers to appear alongside built-in ones. Providers are sorted alphabetically with `ksort()`. Additionally: * Renames `_wp_connectors_is_api_key_valid()` to `_wp_connectors_is_ai_api_key_valid()`. * Adds `_wp_connectors_get_connector_script_module_data()` to expose connector settings to the `connectors-wp-admin` script module. * Includes plugin slug data for featured connectors to support install/activate UI. * Removes redundant `class_exists` checks for `AiClient`. * Runs `init` hooks at priority 20 so provider plugins registered at default priority are available. * Unhooks connector registration during tests to prevent duplicate registrations. Synced from WordPress/gutenberg#76014. Developed in WordPress/wordpress-develop#11080. Follow-up to [61749]. Props gziolo, jorgefilipecosta, justlevine, flixos90, ellatrix. Fixes #64730. Built from https://develop.svn.wordpress.org/trunk@61824 git-svn-id: http://core.svn.wordpress.org/trunk@61111 1a063a9b-81f0-0310-95a4-ce76da25c4cd

Trac ticket: https://core.trac.wordpress.org/ticket/64730
Follow-up for #11056.
Synced from WordPress/gutenberg#76014.
Summary
_wp_connectors_get_provider_settings()to dynamically fetch registered providers from the AI Client registry, in addition to the three hardcoded featured providers (Gemini, OpenAI, Claude).name,description,credentials_urlat the top level andsettingsas a nested array.api_key._wp_connectors_validate_keys_in_rest,_wp_register_default_connector_settings,_wp_connectors_pass_default_keys_to_ai_client) to use the new structure.Test plan
npm run test:php -- --group connectorspasses (14 tests, 64 assertions).AiClient::defaultRegistry()->registerProvider()with API key auth appears in the settings.🤖 Generated with Claude Code