Connectors: Dynamically register providers from WP AI Client registry#76014
Connectors: Dynamically register providers from WP AI Client registry#76014
Conversation
|
I tested it by installing https://github.com/saarnilauri/ai-provider-for-mistral from the zip file included on the relase page:
One implementation note to keep in mind regarding our direction is that the API key is currently auto-generated,so allow customization if needed. This is what I am currently passing to the client, which will likely evolve, but we could change it before WP 7.0 Beta 3: <script
id="wp-script-module-data-connectors-wp-admin"
type="application/json"
>
{
"providers": {
"google": {
"name": "Google",
"description": "Content generation, translation, and vision with Google's Gemini.",
"credentialsUrl": "https://aistudio.google.com/app/api-keys",
"settings": ["connectors_ai_google_api_key"]
},
"openai": {
"name": "OpenAI",
"description": "Text, image, and code generation with GPT and DALL-E.",
"credentialsUrl": "https://platform.openai.com/api-keys",
"settings": ["connectors_ai_openai_api_key"]
},
"anthropic": {
"name": "Anthropic",
"description": "Writing, research, and analysis with Claude.",
"credentialsUrl": "https://console.anthropic.com/settings/keys",
"settings": ["connectors_ai_anthropic_api_key"]
},
"mistral": {
"name": "AI Provider for Mistral",
"description": "",
"credentialsUrl": "https://console.mistral.ai/api-keys",
"settings": ["connectors_ai_mistral_api_key"]
}
}
}
</script> |
|
Size Change: 0 B Total Size: 6.87 MB ℹ️ View Unchanged
|
| ), | ||
| ); | ||
|
|
||
| $registry = \WordPress\AiClient\AiClient::defaultRegistry(); |
There was a problem hiding this comment.
Adding a filter here would be valuable to allow plugin authors to opt out of the Connectors UI if they do not want their integration surfaced on this screen.
There was a problem hiding this comment.
What would be the rationale for that?
The purpose of the screen is to make connector UI centrally discoverable. Having a way to opt out of it sounds like it would defeat the purpose.
There was a problem hiding this comment.
The rational I see for that would be a provider that has a very special UI to connect and would not fit any of the default we provide, it would register a custom component as a connector. But for that I guess we can have JS function that overwrites just the UI.
There was a problem hiding this comment.
I'll explore in a follow-up whether we could a filter that changes what we pass to the client, or even earlier when using AI provider settings to register settings. This way, we could allow extensibility for the Connectors screen.
There was a problem hiding this comment.
Yes, that is also one of the reasons I was thinking about a filter.
In cases where a provider requires a very specific connection flow or UI that does not fit the default connector interface, the plugin might prefer to manage the connection entirely within its own settings page. While overriding the UI via JS is possible, the provider would still appear in the Connectors screen, which may not reflect how the integration is intended to be configured.
Having a filter at the registration level would give plugin authors the flexibility to opt out of the Connectors UI when the default workflow does not apply, while still allowing them to use the AI Client registry internally.
There was a problem hiding this comment.
I drafted a proposal to keep the discussion going: WordPress/wordpress-develop#11175.
There was a problem hiding this comment.
I tried this PR against grok ai provider https://github.com/aslamdoctor/ai-provider-for-grok, and mistral https://github.com/saarnilauri/ai-provider-for-mistral/releases/tag/v1.0.1 and the options are not appearing on the connectors screen, we may be missing something, or something may be wrong at the providers level. It is not an issue of this PR see more info bellow.
|
After debugging the issue of mistral and xAI not appearing seems to be because when both Gutenberg and latest beta are active, the screen code that seems to be loaded is the latest beta not Gutenberg not gutenberg. That should be fixed on a different PR when I tested with WordPress develop at WordPress/wordpress-develop@33688bb things worked: There is an issue where for Grok it says install while it is already installed but other than that things loaded well. |
| } else { | ||
| $providers[ $provider_id ] = array_merge( | ||
| array( | ||
| 'name' => '', |
There was a problem hiding this comment.
Ideally there would be a Way for providers to pass their logo.
There was a problem hiding this comment.
+1; though I'm happy for us to add that in a follow up PR
There was a problem hiding this comment.
Right, this one needs some further thinking on how to register and expose logos from AI providers.
jorgefilipecosta
left a comment
There was a problem hiding this comment.
Awesome work, things tested well for me 👍 Left some comments which I think we can consider before the merge but other than that it worked well.
felixarntz
left a comment
There was a problem hiding this comment.
@gziolo This looks great - though I think we should make this more clear around that it's not all about AI, and that API key is not the only authentication method in existence :)
| } else { | ||
| $providers[ $provider_id ] = array_merge( | ||
| array( | ||
| 'name' => '', |
There was a problem hiding this comment.
+1; though I'm happy for us to add that in a follow up PR
felixarntz
left a comment
There was a problem hiding this comment.
@shaunandrews Apologies if you're not the right person to ping here, but maybe you came up with the three current provider descriptions?
They are very arbitrary, and even misleading when shown next to each other. For example, they make it sound like only OpenAI can do code and image generation, or only Gemini can do vision - neither of which is the case.
Leaving some more concrete comments below. I think these need iteration, maybe simply to become more generic - especially since they will be hard-coded in Core, and we won't be able to iterate on them easily.
|
Flaky tests detected in 5248929. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/22570185250
|
47eb4e0 to
62652e7
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 If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
Addressed feedback and applied refactoringsPHP (
TSX (
New structure passed to the client from the server: <script id="wp-script-module-data-connectors-wp-admin" type="application/json">
{
"connectors": {
"google": {
"name": "Google",
"description": "Content generation, translation, and vision with Google's Gemini.",
"type": "ai_provider",
"authentication": {
"method": "api_key",
"settingName": "connectors_ai_google_api_key",
"credentialsUrl": "https://aistudio.google.com/app/api-keys"
}
},
"openai": {
"name": "OpenAI",
"description": "Text, image, and code generation with GPT and DALL-E.",
"type": "ai_provider",
"authentication": {
"method": "api_key",
"settingName": "connectors_ai_openai_api_key",
"credentialsUrl": "https://platform.openai.com/api-keys"
}
},
"anthropic": {
"name": "Anthropic",
"description": "Writing, research, and analysis with Claude.",
"type": "ai_provider",
"authentication": {
"method": "api_key",
"settingName": "connectors_ai_anthropic_api_key",
"credentialsUrl": "https://console.anthropic.com/settings/keys"
}
},
"grok": {
"name": "Grok (xAI)",
"description": "",
"type": "ai_provider",
"authentication": {
"method": "api_key",
"settingName": "connectors_ai_grok_api_key",
"credentialsUrl": "https://console.x.ai/"
}
},
"mistral": {
"name": "AI Provider for Mistral",
"description": "",
"type": "ai_provider",
"authentication": {
"method": "api_key",
"settingName": "connectors_ai_mistral_api_key",
"credentialsUrl": "https://console.mistral.ai/api-keys"
}
}
}
}
</script>Still open for follow-up PRs
|
…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>
…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>
…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>
…i_key_valid The function is AI-provider-specific, so the name should reflect that. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ent-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>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
|
I think I addressed all the feedback raised after the last round of changes. |
|
I just cherry-picked this PR to the wp/7.0 branch to get it included in the next release: 3763f32 |


Summary
Polyfills WordPress/wordpress-develop#11080 for the Gutenberg plugin and wires up the frontend to consume provider data dynamically.
_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).name,description,credentials_urlat the top level andsettingsas a nested array.api_key._gutenberg_validate_connector_keys_in_rest,_gutenberg_register_default_connector_settings,_gutenberg_pass_default_connector_keys_to_ai_client) to use the new structure.connectors-wp-adminscript module via thescript_module_datafilter.Test plan
AiClient::defaultRegistry()->registerProvider()with API key auth appears in the settings.🤖 Generated with Claude Code