Add Extended Providers experiment#148
Add Extended Providers experiment#148Jameswlepage wants to merge 5 commits intoWordPress:developfrom
Conversation
Adds additional AI provider integrations: - Cloudflare Workers AI - Cohere - DeepSeek - Fal.ai - HuggingFace - Ollama - OpenRouter - xAI (Grok) Includes provider credentials UI and metadata registry.
- Initialize HTTP discovery strategy before experiments load - Register extended providers immediately instead of on late init hook - Initialize Provider_Credentials_UI for enhanced credentials display - Reorder initialization: HTTP client → experiments → AI_Client The wp-ai-client package collects providers during AI_Client::init(). Extended providers must be registered before that collection occurs.
- Add phpcs:disable/enable blocks for exception escaping false positives - Add phpcs:ignore for DisallowMultiConstantDefinition false positives - Update @return annotations to use fully qualified class names - Fix variable alignment spacing issues - Add missing translators comment for placeholder
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## develop #148 +/- ##
==============================================
- Coverage 46.89% 22.98% -23.91%
- Complexity 208 543 +335
==============================================
Files 19 49 +30
Lines 1271 2619 +1348
==============================================
+ Hits 596 602 +6
- Misses 675 2017 +1342
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR adds an Extended Providers experiment that registers 9 additional AI provider integrations (Cloudflare, Cohere, DeepSeek, Fal.ai, Grok, Groq, HuggingFace, Ollama, OpenRouter) alongside the core providers (OpenAI, Anthropic, Google). It includes enhanced UI for provider credentials with custom branding, icons, and tooltips.
Key changes:
- New Extended Providers experiment with provider class registration system
- Enhanced credentials UI with React components for provider icons and interactive tooltips
- Provider implementations for 9 additional AI services
- Provider metadata registry for custom branding per provider
- Bootstrap initialization reordered to register providers before AI Client initialization
Reviewed changes
Copilot reviewed 54 out of 54 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| webpack.config.js | Adds provider-credentials entry point for admin UI assets |
| src/admin/provider-credentials/* | React components and styles for enhanced credentials screen with provider icons and tooltips |
| src/admin/components/provider-icons.tsx | Icon component registry mapping provider IDs to SVG icon components |
| src/admin/components/icons/* | SVG icon components for all providers (Anthropic, OpenAI, Google, etc.) |
| src/admin/components/ProviderTooltipContent.tsx | Tooltip component displaying provider metadata and available models |
| includes/bootstrap.php | Reorders initialization to register extended providers before AI Client init |
| includes/Providers/*/ | Provider implementations for OpenRouter, Ollama, HuggingFace, Groq, Grok, FalAi, DeepSeek, Cohere, and Cloudflare |
| includes/Experiments/Extended_Providers/* | Experiment class implementing provider registration with filtering and selection UI |
| includes/Experiment_Loader.php | Registers Extended_Providers experiment in default list |
| includes/Admin/Provider_Metadata_Registry.php | Central registry providing structured metadata and branding for all providers |
| includes/Admin/Provider_Credentials_UI.php | Initializes enhanced credentials UI assets |
| docs/experiments/extended-providers.md | Documentation for Extended Providers experiment features and usage |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| */ | ||
| private static function get_initials( string $name ): string { | ||
| $parts = preg_split( '/\s+/', trim( $name ) ); | ||
| if ( empty( $parts ) ) { |
There was a problem hiding this comment.
The preg_split function should have its return value validated. If preg_split fails (returns false), it should be handled to prevent type errors. Consider adding error handling or using an alternative approach with explode.
| if ( empty( $parts ) ) { | |
| if ( false === $parts || empty( $parts ) ) { |
| $request = new Request( | ||
| HttpMethodEnum::POST(), | ||
| rtrim( OllamaProvider::get_base_url(), '/api' ) . '/api/chat', |
There was a problem hiding this comment.
The URL construction logic using rtrim to remove '/api' and then appending '/api/chat' is fragile. If the base URL doesn't end with '/api', this will result in an incorrect URL. Consider using a more robust URL construction approach or documenting the expected format of the base URL.
| $request = new Request( | |
| HttpMethodEnum::POST(), | |
| rtrim( OllamaProvider::get_base_url(), '/api' ) . '/api/chat', | |
| $base_url = rtrim( OllamaProvider::get_base_url(), '/' ); | |
| if ( preg_match( '#/api/?$#', $base_url ) === 1 ) { | |
| $base_url = preg_replace( '#/api/?$#', '', $base_url ); | |
| } | |
| $endpoint = $base_url . '/api/chat'; | |
| $request = new Request( | |
| HttpMethodEnum::POST(), | |
| $endpoint, |
| $request = new Request( | ||
| HttpMethodEnum::GET(), | ||
| rtrim( OllamaProvider::get_base_url(), '/api' ) . '/api/tags' |
There was a problem hiding this comment.
The URL construction logic using rtrim to remove '/api' and then appending '/api/tags' is fragile and duplicates the same pattern from OllamaTextGenerationModel. If the base URL doesn't end with '/api', this will result in an incorrect URL. Consider extracting this logic to a helper method in the OllamaProvider class.
| $request = new Request( | |
| HttpMethodEnum::GET(), | |
| rtrim( OllamaProvider::get_base_url(), '/api' ) . '/api/tags' | |
| $base_url = rtrim( OllamaProvider::get_base_url(), '/' ); | |
| // Ensure the base URL ends with '/api' exactly once before appending '/tags'. | |
| if ( substr( $base_url, -4 ) !== '/api' ) { | |
| $base_url .= '/api'; | |
| } | |
| $request = new Request( | |
| HttpMethodEnum::GET(), | |
| $base_url . '/tags' |
| */ | ||
| import domReady from '@wordpress/dom-ready'; | ||
| import { Popover } from '@wordpress/components'; | ||
| import { useRef, useState, useEffect } from '@wordpress/element'; |
There was a problem hiding this comment.
Unused import useEffect.
|
@Jameswlepage can you add tests here like was done in https://github.com/WordPress/ai/pull/147/changes#diff-0cf348eda48cae411ad9d44a2e5b449603a971f2313b0a849893ff4cf8280c46? |
|
What?
Adds a new Extended Providers experiment that registers 9 additional AI provider integrations:
Also includes provider credentials UI enhancements and a metadata registry for custom branding per provider.
Why?
The core wp-ai-client package ships with OpenAI, Anthropic, and Google. Users want access to additional providers—especially local options like Ollama and cost-effective alternatives like Groq and DeepSeek.
How?
Extended_Providersexperiment class that registers all 9 providers with the wp-ai-client registryProvider_Metadata_Registryfor custom branding (icons, colors, API key URLs)Provider_Credentials_UIinitialization to display enhanced credentials screenTesting Instructions