close

Make WordPress Core

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: gziolo's profile gziolo 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_ai default 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_providers and list_ai_models worth separating from prompt_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_cap instead of user_has_cap? The user_has_cap filter pattern works but is less discoverable than a map_meta_cap mapping. The Abilities API uses primitive capabilities stored in roles, which is the more conventional Core pattern.

References

Change History (6)

Image

This ticket was mentioned in PR #10915 on WordPress/wordpress-develop by @jason_the_adams.


3 weeks ago
#1

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 a GenerativeAiResult. 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 fluent PromptBuilder class 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/data store (wp-ai-client/providers-models) with selectors/resolvers for getProviders(), 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.
  • GenerativeAiResult wrapper 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_ai default 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_providers and list_ai_models worth separating from prompt_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_cap instead of user_has_cap? The user_has_cap filter pattern works but is less discoverable than a map_meta_cap mapping. 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:errors on new PHP files — 0 errors
  • [ ] npm run build:devai-client.js and ai-client.min.js generated
  • [ ] Verify REST endpoint discovery: GET /wp-json/wp-ai/v1 returns route listing
  • [ ] Verify capability gating: subscriber gets rest_forbidden, admin gets through
  • [ ] Verify wp-ai-client script is registered with wp-api-fetch and wp-data as 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.

Image

@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 Image @gziolo
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`)

#4 Image @JeffPaul
2 weeks ago

  • Keywords ai-client added

Image

This ticket was mentioned in Slack in #core-ai by gziolo. View the logs.


12 days ago

#6 Image @gziolo
6 days 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.

Note: See TracTickets for help on using tickets.