Opened 3 weeks ago
Last modified 6 days ago
#64872 new enhancement
WP AI Client: Add AI REST API Endpoints (`wp-ai/v1`)
| Reported by: |
|
Owned by: | |
|---|---|---|---|
| Milestone: | 7.1 | Priority: | normal |
| Severity: | normal | Version: | trunk |
| Component: | AI | Keywords: | ai-client has-patch has-unit-tests 2nd-opinion |
| Focuses: | rest-api | Cc: |
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 (6)
This ticket was mentioned in PR #10915 on WordPress/wordpress-develop by @jason_the_adams.
3 weeks ago
#1
@gziolo commented on PR #10915:
3 weeks 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
@
3 weeks ago
- Summary changed from Add AI REST API Endpoints (`wp-ai/v1`) to WP AI Client: Add AI REST API Endpoints (`wp-ai/v1`)
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.