Opened 13 days ago
Last modified 2 days ago
#64591 assigned feature request
Add WP AI Client
| Reported by: |
|
Owned by: |
|
|---|---|---|---|
| Milestone: | 7.0 | Priority: | normal |
| Severity: | normal | Version: | |
| Component: | AI | Keywords: | has-patch has-unit-tests |
| Focuses: | Cc: |
Description (last modified by )
This ticket is for merging the WP AI Client into Core.
Technically, this means bundling the PHP AI Client as an external dependency in Core (similar to e.g. the Requests library), while the WP AI Client will become a direct part of Core. The package for the latter will most likely be discontinued after the merge.
See the merge proposal for additional context.
Change History (23)
This ticket was mentioned in Slack in #hosting by chaion07. View the logs.
13 days ago
This ticket was mentioned in Slack in #core by audrasjb. View the logs.
12 days ago
This ticket was mentioned in Slack in #hosting by amykamala. View the logs.
12 days ago
This ticket was mentioned in PR #10881 on WordPress/wordpress-develop by @jason_the_adams.
10 days ago
#6
- Keywords has-patch added; needs-patch removed
Trac ticket: https://core.trac.wordpress.org/ticket/64591
Merge Proposal: https://make.wordpress.org/core/2026/02/03/proposal-for-merging-wp-ai-client-into-wordpress-7-0
## Summary
Adds a provider-agnostic AI Client, enabling developers to interact with generative AI services through a single, fluent API — without needing to know which provider is configured.
This PR includes three layers:
- PHP AI Client SDK (
php-ai-client): The upstream SDK fromWordPress/php-ai-client, bundled intowp-includes/php-ai-client/with all third-party dependencies (PSR interfaces, HTTPlug) scoped toWordPress\AiClientDependencies\*to avoid conflicts with plugins shipping their own versions.
- Import tooling (
tools/php-ai-client/): An installer script and PHP-Scoper configuration that fetches, scopes, and reorganizes the SDK for bundling. Runningbash tools/php-ai-client/installer.shreproduces the bundled output deterministically.
- WP AI Client (
ai-client-utils/,ai-client.php): The WordPress integration layer. This provides minimal PSR-7/PSR-17 implementations backed by string buffers andwp_parse_url(), an HTTP client adapter that routes requests throughwp_remote_request(), a discovery strategy so the SDK automatically finds these implementations, and an event dispatcher that bridges PSR-14 events to WordPress hooks.
The public API is a single function:
$summary = wp_ai_client_prompt( 'Summarize this post' )
->with_text( $post->post_content )
->generate_text();
WP_AI_Client_Prompt_Builder wraps the SDK's fluent builder with WordPress conventions — snake_case methods, WP_Error returns instead of exceptions, and using_abilities() for connecting the Abilities API to AI function calling.
The wp_ai_client_prevent_prompt filter gives site owners and plugins centralized control over AI availability. When a prompt is prevented, generating methods return WP_Error while is_supported_* methods return false — giving plugin developers a graceful way to hide AI features entirely when AI is not available.
This gives plugin and theme developers a stable, provider-neutral way to add AI features without bundling their own HTTP clients or managing provider-specific SDKs.
## Follow up PRs
There will be a couple more PRs. I broke up the WP AI Client, introducing only the main core files in this one. Following PRs will be:
- The REST API
- The provider credentials settings screen
## Use of AI Tools
This is a compilation of work from the PHP AI Client and WP AI Client repositories, with some changes made in porting to core. Claude Code was used in both the original development of those packages as well as the porting over and creation of the tooling. All code was generated by Claude Code and reviewed by myself and @felixarntz.
@johnbillion commented on PR #10881:
5 days ago
#7
Might any of these 3p libraries potentially be used outside of the AI client in the future? ie. they might benefit from being in the higher level WordPress namespace rather than WordPress\AiClient.
Extenders might refer to that 3p code as soon as it's in, so we can't change the namespace at a later date.
@swissspidy commented on PR #10881:
5 days ago
#8
FYI there are 50+ Method ReflectionProperty::setAccessible() is deprecated since 8.5, as it has no effect since PHP 8.1 deprecation notices introduced by this PR.
@jason_the_adams commented on PR #10881:
5 days ago
#9
I was fixing that as you posted the comment, @swissspidy. 😄
@jason_the_adams commented on PR #10881:
5 days ago
#10
Might any of these 3p libraries potentially be used outside of the AI client in the future? ie. they might benefit from being in the higher level
WordPressnamespace rather thanWordPress\AiClient.
Extenders might refer to that 3p code as soon as it's in, so we can't change the namespace at a later date.
I'm certainly open to this! What libraries are you thinking of, specifically?
@jason_the_adams commented on PR #10881:
5 days ago
#11
Thanks for looking over this, @dkotter! I've resolved most of what you raised. I'm temporarily shifting to get the settings screen PR in place so we can start testing!
This ticket was mentioned in PR #10904 on WordPress/wordpress-develop by @jason_the_adams.
5 days ago
#12
Trac ticket: https://core.trac.wordpress.org/ticket/64591
Merge Proposal: https://make.wordpress.org/core/2026/02/03/proposal-for-merging-wp-ai-client-into-wordpress-7-0
This is a part of #10881. I meant for this to stack on that so the changes in this are clear, but unfortunately I can't stack because both branches are in my forked repo.
## Summary
Adds an AI Services settings screen under Settings > AI Services where site administrators can enter API credentials for AI providers. Without this, wp_ai_client_prompt() has no way to authenticate with any provider.
WP_AI_Client_Credentials_Managercollects provider metadata from the SDK, registers the credentials option with sanitization, and passes stored API keys to the SDK on each request- The settings page renders a password field for each registered cloud provider, with links to the provider's API key management page
- Provider collection and credential passing happen after
initso plugins that register providers are picked up - Includes PHPUnit tests for the credentials manager
Ported from the API_Credentials_Manager and API_Credentials_Settings_Screen in the wp-ai-client plugin, adapted to core conventions (no namespaces, _doing_it_wrong() instead of exceptions, no text domain, etc.).
## Open question
The Settings > AI Services menu item is currently hidden when no cloud providers are registered (since the page would be empty). Is this the right behavior, or should the page always be visible with a message like "No AI providers are currently available"? Hiding it is cleaner but could be confusing if someone is looking for the page before installing a provider plugin.
## Test plan
- [ ] Install a provider plugin (e.g. Google AI provider), navigate to Settings > AI Services, verify fields appear
- [ ] Enter an API key, save, reload — verify value persists
- [ ] Verify
wp_ai_client_prompt()can authenticate using the stored key - [ ] Deactivate all provider plugins — verify menu item disappears
- [ ]
npm run test:php -- --group ai-client
Trac ticket:
## Use of AI Tools
@desrosj commented on PR #10881:
5 days ago
#13
So I updated the test coverage workflow to run every time this PR is updated (please revert this before a final commit to SVN. In the status checks, you'll find two codecov lines.
Surprisingly, it seems that 96%+ of this PR is actually covered by tests (which excludes the bundled library parts of this PR based on the PHPUnit configuration file changes), and this PR actually _increases_ overall test coverages by roughly 2-tenths of a percent.
Chatting it through with @aaronjorbin, @jeffpaul, and @felixarntz just now, this _seems_ to make sense. The wp-ai-client is essentially a pass through, so it's not difficult to have "coverage". But it's unlikely that a high percentage of the underlying PHP SDK is being tested through the wp-ai-client tests here.
I do feel a bit better about the test coverage part of this. I think this will need to be a blended approach. There should be a high level of coverage for the non-bundled library code here combined with the test coverage within the PHP SDK library. @aaronjorbin has created an issue to follow up with adding test coverage reporting to the php-ai-client repository to track and confirm this.
@jason_the_adams commented on PR #10904:
5 days ago
#14
Given how merging works in WordPress (a single SVN commit) I'm switching this to a draft PR. It's useful for testing!
@jason_the_adams commented on PR #10904:
5 days ago
#15
Is there actually an AI provider plugin that's installable? I looked at the Google AI Provider repo, but all it has is a readme.
I just released 1.0.0 of three providers which can be used as plugins:
- OpenAI: https://github.com/WordPress/openai-ai-provider
- Anthropic: https://github.com/WordPress/anthropic-ai-provider
- Google: https://github.com/WordPress/google-ai-provider
This ticket was mentioned in Slack in #core-test by juanmaguitar. View the logs.
4 days ago
@dkotter commented on PR #10904:
4 days ago
#17
The Settings > AI Services menu item is currently hidden when no cloud providers are registered (since the page would be empty). Is this the right behavior, or should the page always be visible with a message like "No AI providers are currently available"? Hiding it is cleaner but could be confusing if someone is looking for the page before installing a provider plugin.
I know there's been discussion around discoverability in regards to the individual AI providers. Could make a case that instead of hiding the page when no providers are registered we instead update the page to provide instructions on how to find and install a provider?
@peterwilsoncc commented on PR #10881:
4 days ago
#18
This ticket was mentioned in PR #10915 on WordPress/wordpress-develop by @jason_the_adams.
4 days ago
#19
Trac ticket: https://core.trac.wordpress.org/ticket/64591
Merge Proposal: https://make.wordpress.org/core/2026/02/03/proposal-for-merging-wp-ai-client-into-wordpress-7-0
This is a part of https://github.com/WordPress/wordpress-develop/pull/10881. I meant for this to stack on that so the changes in this are clear, but unfortunately I can't stack because both branches are in my forked repo.
## Summary
Ports the REST API, JavaScript client, and capabilities system from the WP AI Client plugin into WordPress Core.
This gives WordPress a complete client-side AI API that mirrors the server-side wp_ai_client_prompt() API already in Core, along with REST endpoints that the JavaScript layer (and any external consumer) can use.
### What's being ported
REST API (wp-ai/v1)
POST /wp-ai/v1/generate— Sends a prompt to an AI model and returns aGenerativeAiResult. Accepts messages, model config, provider/model selection, model preferences, and request options.POST /wp-ai/v1/is-supported— Checks whether the current prompt configuration is supported by any available model, without actually running the generation.GET /wp-ai/v1/providers— Lists all registered AI providers.GET /wp-ai/v1/providers/{id}— Retrieves a single provider's metadata.GET /wp-ai/v1/providers/{id}/models— Lists models available from a specific provider (requires the provider to be configured with credentials).GET /wp-ai/v1/providers/{id}/models/{modelId}— Retrieves a single model's metadata.
The generate/is-supported endpoints wrap wp_ai_client_prompt() — the same public API that server-side PHP consumers use — so behavior is consistent between PHP and JS.
JavaScript Client (wp-ai-client)
A wp.aiClient global (registered as the wp-ai-client script handle) that provides:
wp.aiClient.prompt()— A fluentPromptBuilderclass mirroring the PHP API:.withText(),.usingModel(),.usingTemperature(),.generateText(),.generateImage(),.isSupported(), etc. All generation methods return Promises that call the REST endpoints.- Provider/model data store — A
@wordpress/datastore (wp-ai-client/providers-models) with selectors/resolvers forgetProviders(),getProvider(),getProviderModels(),getProviderModel(). Data is fetched lazily via the REST API and cached in the store. - Enums — JS constants for
Capability,MessageRole,FileType,FinishReason,Modality,ProviderType, etc., matching the PHP SDK enums. GenerativeAiResultwrapper with convenience extraction methods (toText(),toTexts(),toFile(),toImageFile(),toAudioFile(), etc.).
Capabilities
Three new meta-capabilities gate access to the REST endpoints:
| Capability | Gates | Default |
|---|---|---|
prompt_ai | generate, is-supported | Granted to users with manage_options
|
list_ai_providers | providers (list & single) | Granted to users with manage_options
|
list_ai_models | providers/{id}/models routes | Granted to users with manage_options
|
These are implemented as user_has_cap filter callbacks (same pattern as install_languages, resume_plugins, etc.) so they can be removed and replaced by plugins or site-specific code.
JSON Schema Converter
A small utility (WP_AI_Client_JSON_Schema_Converter) that converts standard JSON Schema required arrays into the per-property required: true booleans that WordPress REST API validation expects. Used to bridge the SDK's getJsonSchema() output into valid WP REST args.
### Open question: capabilities direction
The current approach follows the upstream plugin exactly — three separate meta-capabilities dynamically granted via user_has_cap filters to anyone with manage_options. This is simple and removable, but worth discussing:
- Should
prompt_aidefault to all administrators, or be more restrictive? AI generation can have cost implications (API credits), and the current gate (manage_options) means any admin on a multisite network could generate content. Tying it to a more specific primitive capability or making it opt-in might be more appropriate for Core. - Are
list_ai_providersandlist_ai_modelsworth separating fromprompt_ai? In practice, anyone who can prompt also needs to know what's available. Merging them into a single capability (or making listing public to all authenticated users) would simplify the permission model. - Should these use
map_meta_capinstead ofuser_has_cap? Theuser_has_capfilter pattern works but is less discoverable than amap_meta_capmapping. The Abilities API uses primitive capabilities stored in roles, which is the more conventional Core pattern.
## Test plan
- [ ]
npm run test:php -- --group ai-client— all 326 tests pass - [ ]
composer lint:errorson new PHP files — 0 errors - [ ]
npm run build:dev—ai-client.jsandai-client.min.jsgenerated - [ ] Verify REST endpoint discovery:
GET /wp-json/wp-ai/v1returns route listing - [ ] Verify capability gating: subscriber gets
rest_forbidden, admin gets through - [ ] Verify
wp-ai-clientscript is registered withwp-api-fetchandwp-dataas dependencies
Use of AI Tools
This is a compilation of work from the PHP AI Client and WP AI Client repositories, with some changes made in porting to core. Claude Code was used in both the original development of those packages as well as the porting over and creation of the tooling. All code was generated by Claude Code and reviewed by myself and @felixarntz.
@jason_the_adams commented on PR #10915:
4 days ago
#20
As a note, I wouldn't consider this something critical to get into core. If we don't want this on 7.0 it shouldn't hold up #10881. I'm porting this over for consideration since it does exist in the WP AI Client.
@jason_the_adams commented on PR #10881:
4 days ago
#21
@peterwilsoncc Done!
First off, this is a fantastic proposal. Having a provider-agnostic AI foundation in Core is exactly what the ecosystem needs, it will reduce fragmentation and give plugin developers a stable base to build on. Really excited to see this moving forward.
That said, I wanted to raise one potential design consideration regarding how WP AI Client might interact with the Abilities API.
The Question
If WP AI Client registers abilities like
ai/promptorai/completion, could this create some philosophical tension?Possible Solutions
is_infrastructuremetadata flag for filteringai/*for internal use)Again, great work on this proposal. Just wanted to flag this early in case it's helpful for the design. Happy to discuss further!