Opened 4 months ago
Last modified 9 days ago
#64872 new enhancement
WP AI Client: Add AI REST API Endpoints (`wp-ai/v1`)
| Reported by: | gziolo | Owned by: | |
|---|---|---|---|
| Priority: | normal | Milestone: | Future Release |
| Component: | AI | Version: | |
| Severity: | normal | Keywords: | ai-client has-patch has-unit-tests 2nd-opinion |
| Cc: | Focuses: | rest-api |
Description
This ticket tracks landing the AI REST API endpoints (wp-ai/v1) into WordPress Core as a discrete unit of work for the WordPress 7.1 cycle. The endpoints were originally proposed as part of the broader WP AI Client merge (#64591) and have an existing implementation in PR #10915, but did not land in 7.0. This ticket scopes the REST API surface for focused review and iteration. The JS client is intentionally out of scope here and will be addressed in a separate ticket.
Proposed Endpoints
| Route | Method | Description |
/wp-ai/v1/generate | POST | Sends a prompt to an AI model and returns a GenerativeAiResult. Accepts messages, model config, provider/model selection, model preferences, and request options.
|
/wp-ai/v1/is-supported | POST | Checks whether a prompt configuration is supportable without running generation. |
/wp-ai/v1/providers | GET | Lists all registered AI providers. |
/wp-ai/v1/providers/{id} | GET | Retrieves a single provider's metadata. |
/wp-ai/v1/providers/{id}/models | GET | Lists models available from a specific provider (requires the provider to be configured with credentials). |
/wp-ai/v1/providers/{id}/models/{modelId} | GET | Retrieves a single model's metadata. |
The generate and is-supported endpoints wrap wp_ai_client_prompt() directly, ensuring consistent behavior — including the wp_ai_client_allow_prompt filter and provider resolution — between PHP and REST consumers.
Capabilities
Access is gated via three meta-capabilities:
| Capability | Guards | Current Default |
prompt_ai | generate, is-supported | manage_options
|
list_ai_providers | providers routes | manage_options
|
list_ai_models | providers/{id}/models routes | 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.
References
- PR #10915 — existing implementation (REST + JS client combined; JS client out of scope here)
- #64591 — original WP AI Client merge proposal and discussion
- Make post: Proposal for merging WP AI Client into WordPress 7.0
Change History (12)
This ticket was mentioned in PR #10915 on WordPress/wordpress-develop by @jason_the_adams.
4 months ago
#1
@gziolo commented on PR #10915:
4 months ago
#2
New dedicated Trac ticket created for REST API line of work: https://core.trac.wordpress.org/ticket/64872. I also updated the reference in the ticket to point at new PR.
#3
@
4 months ago
- Summary Add AI REST API Endpoints (`wp-ai/v1`) → WP AI Client: Add AI REST API Endpoints (`wp-ai/v1`)
This ticket was mentioned in Slack in #core-ai by gziolo. View the logs.
4 months ago
#6
@
4 months ago
- Keywords 2nd-opinion added
@jason_the_adams and @flixos90, is it something we still want to add to WordPress Core? I flagged this ticket as needing opinion before we proceed.
#7
@
3 months ago
The REST API endpoints look well-structured and consistent with wp_ai_client_prompt(), which is great for keeping parity across PHP and REST usage. Also agree with the earlier suggestion in the PR to keep REST and JS client as separate concerns for easier review.
On capabilities, manage_options for prompt_ai feels a bit broad given potential cost implications. A more restrictive or opt-in approach might be safer. Also, separating list_ai_providers and list_ai_models seems unnecessary and could be simplified.
Using map_meta_cap instead of user_has_cap would also align better with Core standards.
Overall, this is a solid foundation and worth continuing to iterate on for Core inclusion.
#8
@
3 months ago
Following up on the previous feedback, I looked into a few areas that might help improve this further:
1. Capability handling
Using manage_options for prompt_ai feels a bit too broad, especially since AI usage can have cost implications.
It might be better to introduce a separate capability like use_ai_features and map it using map_meta_cap(). This would:
- Give more control over who can use AI features
- Make it easier to adjust permissions in the future (per role or per site)
- Follow how capabilities are usually handled in Core
2. Providers and models endpoints
Right now, list_ai_providers and list_ai_models are separate. This might be more complex than needed.
We could simplify this by having a single endpoint (for example /ai/providers) that returns providers along with their models. This would:
- Reduce duplicate logic
- Avoid multiple API calls from the client
If there’s a reason to keep them separate (like performance or different auth needs), it would be helpful to mention that.
3. Capability checks implementation
Using map_meta_cap instead of user_has_cap would be more in line with Core standards and ensure consistent behavior.
#9
@
2 months ago
Removing trunk version as this is not going to be shipped with WP 7.0 but in the next releases.
#10
@
2 months ago
- Version trunk
Since this is an enhancement, there's no first version of WordPress this can be reproduced in. Removing trunk version.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)
Trac ticket: https://core.trac.wordpress.org/ticket/64872
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.aiClientglobal (registered as thewp-ai-clientscript 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.@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.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:
prompt_aigenerate,is-supportedmanage_optionslist_ai_providersproviders(list & single)manage_optionslist_ai_modelsproviders/{id}/modelsroutesmanage_optionsThese are implemented as
user_has_capfilter callbacks (same pattern asinstall_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 Schemarequiredarrays into the per-propertyrequired: truebooleans that WordPress REST API validation expects. Used to bridge the SDK'sgetJsonSchema()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_capfilters to anyone withmanage_options. This is simple and removable, but worth discussing: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.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.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 passcomposer lint:errorson new PHP files — 0 errorsnpm run build:dev—ai-client.jsandai-client.min.jsgeneratedGET /wp-json/wp-ai/v1returns route listingrest_forbidden, admin gets throughwp-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.