Make WordPress Core

Opened 4 weeks ago

Last modified 35 hours ago

#64591 assigned task (blessed)

Add WP AI Client and corresponding connectors screen

Reported by: flixos90's profile flixos90 Owned by: jason_the_adams's profile jason_the_adams
Milestone: 7.0 Priority: normal
Severity: normal Version:
Component: AI Keywords: has-patch has-unit-tests
Focuses: Cc:

Description (last modified by flixos90)

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.

Attachments (6)

anthropic-ai-provider.zip (57.5 KB) - added by flixos90 13 days ago.
Anthropic AI provider plugin
google-ai-provider.zip (66.5 KB) - added by flixos90 13 days ago.
Google AI provider plugin
openai-ai-provider.zip (60.0 KB) - added by flixos90 13 days ago.
OpenAI AI provider plugin
ai-provider-for-anthropic.zip (98.1 KB) - added by flixos90 12 days ago.
AI provider plugin for Anthropic
ai-provider-for-google.zip (101.4 KB) - added by flixos90 12 days ago.
AI provider plugin for Google
ai-provider-for-openai.zip (96.5 KB) - added by flixos90 12 days ago.
AI provider plugin for OpenAI

Download all attachments as: .zip

Change History (70)

#1 @flixos90
4 weeks ago

  • Description modified (diff)

This ticket was mentioned in Slack in #hosting by chaion07. View the logs.


4 weeks ago

#3 @schmitzoide
4 weeks ago

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/prompt or ai/completion, could this create some philosophical tension?

  1. Layer confusion - Abilities typically represent "what WordPress can do". An ability to "call an AI model" feels more like external infrastructure that WordPress uses.
  1. Meta-recursion - The API was designed for AI to orchestrate WordPress. Having "invoke AI" as a discoverable ability could create circular confusion — a bit like listing "call the chef" as a menu item.
  1. Schema considerations - Abilities have deterministic schemas. AI responses are non-deterministic.
  1. Discovery implications - Plugins that auto-discover abilities might inadvertently expose "call external LLM" as a tool — confusing UX.

Possible Solutions

  • Option A: is_infrastructure metadata flag for filtering
  • Option B: Namespace convention (ai/* for internal use)
  • Option C: Keep WP AI Client as developer infrastructure without Abilities exposure

Again, great work on this proposal. Just wanted to flag this early in case it's helpful for the design. Happy to discuss further!

Version 1, edited 4 weeks ago by schmitzoide (previous) (next) (diff)

This ticket was mentioned in Slack in #core by audrasjb. View the logs.


4 weeks ago

This ticket was mentioned in Slack in #hosting by amykamala. View the logs.


4 weeks ago

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


4 weeks 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 from WordPress/php-ai-client, bundled into wp-includes/php-ai-client/ with all third-party dependencies (PSR interfaces, HTTPlug) scoped to WordPress\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. Running bash tools/php-ai-client/installer.sh reproduces 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 and wp_parse_url(), an HTTP client adapter that routes requests through wp_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:


3 weeks 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:


3 weeks 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:


3 weeks ago
#9

I was fixing that as you posted the comment, @swissspidy. 😄

@jason_the_adams commented on PR #10881:


3 weeks 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 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.

I'm certainly open to this! What libraries are you thinking of, specifically?

@jason_the_adams commented on PR #10881:


3 weeks 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.


3 weeks 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_Manager collects 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 init so 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.).

https://github.com/user-attachments/assets/fdc6c4c1-f64d-4704-a41b-ca9bdf74ae35

## 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:


3 weeks 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:


3 weeks 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:


3 weeks 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:

This ticket was mentioned in Slack in #core-test by juanmaguitar. View the logs.


3 weeks ago

@dkotter commented on PR #10904:


3 weeks 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:


3 weeks ago
#18

@JasonTheAdams Are you able to add some testing notes to the PR description. I'm having trouble finguring out what needs to be done to add providers to the settings screen with the AI Experiments plugin installed. The menu page is available but without any form fields.

https://github.com/user-attachments/assets/aca5ab82-a353-4674-9a43-5b7f1e0d1020

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


3 weeks 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 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.

@jason_the_adams commented on PR #10915:


3 weeks 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:


3 weeks ago
#21

@peterwilsoncc Done!

#22 @flixos90
3 weeks ago

  • Owner set to jason_the_adams
  • Status changed from new to assigned

#23 @flixos90
3 weeks ago

  • Keywords has-unit-tests added; needs-unit-tests removed

@jorgefilipecosta commented on PR #10881:


2 weeks ago
#24

For other people testing probably the easier way to test this PR is using some provider like https://github.com/WordPress/google-ai-provider, and then hardcoding a key e.g:putenv('GOOGLE_API_KEY='); this way the settings PR is not needed for testing this one.

#25 @flixos90
2 weeks ago

  • Summary changed from Add WP AI Client to Add WP AI Client and corresponding connectors screen
  • Type changed from feature request to task (blessed)

Renaming the ticket to clarify scope based on the product review meeting earlier today.

@flixos90 commented on PR #10881:


2 weeks ago
#26

@jorgefilipecosta

left a small note as a reminder that probably should be changed before merging).

Not sure which one you mean - can you clarify? Apologies if I missed it.

@flixos90 commented on PR #10881:


2 weeks ago
#27

@peterwilsoncc Responding to your points individually:

My reading of the code is that the following classes would not be required if the API had been written solely with the eventual goal in mind: to include the code in WordPress Core:

  • WP_AI_Client_Event_Dispatcher
  • WP_AI_Client_HTTP_Client
  • WP_AI_Client_PSR17_Factory
  • WP_AI_Client_PSR7_Request
  • WP_AI_Client_PSR7_Response
  • WP_AI_Client_PSR7_Stream
  • WP_AI_Client_PSR7_Uri

This is correct. However, we're not the only ecosystem in PHP world that lacks a provider agnostic AI client library. Building a client that cannot only used by ourselves was an intentional design decision for the php-ai-client to support both WordPress and the PHP ecosystem it is a part of.

Although it has been developed internally, the https://github.com/WordPress/wp-ai-client is been claimed as being an external library https://github.com/WordPress/wordpress-develop/pull/10881/changes#r2791160306.

This is not quite correct - not sure if it's a misunderstanding or you just pasted the wrong link :)

WordPress/php-ai-client is what we've been calling an external library - WordPress/wp-ai-client is not, and the code that comes from it which is in this PR will all be direct part of Core. Only what's in src/wp-includes/php-ai-client is from the 3P library WordPress/php-ai-client.

While it may have initially been intended for wider use, work on the WP-AI-client repo was started very soon after and the goal I mention above, inclusion in WP, became clear. Work to include the code in core began about 8 or so weeks later.

See above, the PHP AI Client was and still is intended for wider use - the WP AI Client was meant only for WordPress from the start.

As it uses PSR standards rather than existing WordPress code, it loses the advantage of a good number of existing HTTP APIs. WP_HTTP, the existing Requests library, etc.

The use of PSR HTTP interfaces rather than these existing APIs is what results in the need for the additional, AI client dedicated HTTP APIs.

This is not actually the case. PSR standards are merely adapters, they don't define how the functionality should work. The implementation present here uses all the common WordPress APIs - requests are made with WP_HTTP etc.

The Requests library you mention is actually what we've modeled this approach after: Just like WordPress/php-ai-client, WordPress/Requests is an external library bundled by Core that is however separately maintained and WordPress agnostic. All the wiring of WordPress specific code (e.g. actions and filters) also happens in WordPress Core's own code, while the bundled Requests library is agnostic and provides only the necessary abstractions and contracts for WordPress to plug in its own primitives.

@jorgefilipecosta commented on PR #10881:


2 weeks ago
#28

@jorgefilipecosta

left a small note as a reminder that probably should be changed before merging).

Not sure which one you mean - can you clarify? Apologies if I missed it.

Sorry it was just the not you left https://github.com/WordPress/wordpress-develop/pull/10881#discussion_r2807847635, I should have linked.

@jorgefilipecosta commented on PR #10881:


2 weeks ago
#29

@jorgefilipecosta

left a small note as a reminder that probably should be changed before merging).

Not sure which one you mean - can you clarify? Apologies if I missed it.

Sorry it was just the note you left https://github.com/WordPress/wordpress-develop/pull/10881#discussion_r2807847635, I should have linked.

It said: TODO: Revert before commit (just leaving this here as a reminder

@flixos90 commented on PR #10881:


13 days ago
#30

Based on some of the feedback so far, @JasonTheAdams and I found a way to simplify the WordPress-owned code in terms of those PSR7 and PSR-17 classes - they are boilerplate code needed to work with PSR-7 and PSR-17 standards, but they can be part of WordPress/php-ai-client itself, as there's nothing WordPress-y about them.

This is being handled in https://github.com/WordPress/php-ai-client/pull/208. We'll publish a new release after and pull that in here.

@flixos90
13 days ago

Anthropic AI provider plugin

@flixos90
13 days ago

Google AI provider plugin

@flixos90
13 days ago

OpenAI AI provider plugin

#31 @flixos90
13 days ago

I just uploaded the packaged plugins for the three AI providers we have:

These can be used for testing for now. We're working on getting those plugins into the official plugin repository.

Last edited 12 days ago by flixos90 (previous) (diff)

#32 @flixos90
13 days ago

In 61700:

AI: Add the WordPress AI Client.

The WordPress AI Client is a provider-agnostic API for WordPress code to call generative AI models via a consistent interface. Plugins and Core can use it to provide AI driven features for users, while users maintain full autonomy in choosing which AI provider(s) they want to rely on and how they configure them.

This changeset merges the technical foundation for the WordPress AI Client into Core. This foundation was originally implemented in the https://github.com/WordPress/wp-ai-client package, which will be sunset going forward. The underlying https://github.com/WordPress/php-ai-client package is bundled with this changeset and will remain a separate library maintained by the WordPress project, for WordPress Core and the PHP ecosystem.

No AI providers are bundled out of the box. Without explicit configuration and explicit calling code, WordPress will not send prompts or data to any external service. Site owners will be able to install plugins to enable usage of specific AI providers, built on top of this foundation.

This is the first changeset of two that are most relevant for the AI Client feature. The subsequent change will introduce a configuration screen for different AI providers, where users can install provider plugins, configure their credentials, and enable the canonical WordPress AI plugin. Together, this infrastructure and UI will enable the WordPress ecosystem to build AI features in a seamless and interoperable way.

Original merge proposal: https://make.wordpress.org/core/2026/02/03/proposal-for-merging-wp-ai-client-into-wordpress-7-0/

Props jason_the_adams, flixos90, desrosj, dkotter, jorgefilipecosta, peterwilsoncc, johnbillion, jorbin, swissspidy, isotropic.
See #64591.

@gziolo commented on PR #10881:


13 days ago
#33

Awesome work. I'm catching up after a longer break and I would like to offer my help to bring the remaining work to the finish line. I see that this PR was committed by @felixarntz in 52e3c30 (svn changeset https://core.trac.wordpress.org/changeset/61700).

@gziolo commented on PR #10881:


13 days ago
#34

I have minor additional feedback from my reviews sessions with Claude Code:

src/wp-includes/php-ai-client/src/polyfills.php appears to be dead code. It is never loaded — the generated autoloader only handles class autoloading, and neither wp-settings.php nor any other file requires it. The four functions it polyfills (array_is_list, str_starts_with, str_contains, str_ends_with) are already provided by WordPress Core in src/wp-includes/compat.php, which loads during bootstrap. I suggest adding rm -f "$TARGET_DIR/src/polyfills.php" (or equivalent) to tools/php-ai-client/installer.sh after the third-party cleanup step so it's stripped during the library update.

@gziolo commented on PR #10881:


13 days ago
#35

Really like how using_abilities() on the prompt builder integrates the Abilities API into function calling — the conversion from WP_Ability to FunctionDeclaration via the wpab__ naming convention is clean, and it makes exposing WordPress capabilities to AI models feel natural and consistent.

On the response side, my understanding from studying the code is that execute_ability(), execute_abilities(), and has_ability_calls() on WP_AI_Client_Ability_Function_Resolver are not referenced anywhere in Core outside their own test file. The unit test coverage is solid, so the logic is well-validated — but I'm curious about the intended usage pattern. Is the expectation that the consumer (plugin or Core feature) explicitly builds the tool-calling loop, something like (AI generated example):

$result = $builder->using_abilities( 'core/get-site-info' )->generate_text_result();

while ( WP_AI_Client_Ability_Function_Resolver::has_ability_calls( $result->getMessage() ) ) {
    $response = WP_AI_Client_Ability_Function_Resolver::execute_abilities( $result->getMessage() );
    $result = $builder->with_history( $result->getMessage(), $response )->generate_text_result();
}

Or is there a plan to provide a higher-level helper that handles this loop automatically? Would be great to understand the design vision here.

@gziolo commented on PR #10881:


13 days ago
#36

One more minor finding for consideration. The WP_AI_Client_Prompt_Builder wraps SDK exceptions into WP_Error through the __call() magic method, which is great for WordPress developers. However, this wrapping doesn't cover the constructor. When invalid input is passed to wp_ai_client_prompt(), the SDK's PromptBuilder constructor throws an InvalidArgumentException directly:

// This throws InvalidArgumentException instead of returning a WP_Error from generate_text().
wp_ai_client_prompt( '   ' )->generate_text();

The same applies to other invalid constructor inputs like wp_ai_client_prompt( array() ) or wp_ai_client_prompt( 123 ) — these are already covered by tests in wpAiClientPromptBuilder.php in test_parse_message_empty_string_returns_wp_error which acknowledge the gap with try/catch blocks.

A possible fix would be wrapping the new prompt builder call in the constructor with a try/catch, storing the exception as a WP_Error in $this->error, so it surfaces consistently through the fluent chain when a generating method is called.

Here's a test case that documents the current behavior:

/**
 * Test that wp_ai_client_prompt() with an empty string throws an InvalidArgumentException.
 *
 * The SDK's PromptBuilder constructor throws immediately for empty strings,
 * bypassing the WP_Error wrapping provided by __call(). This means invalid
 * input to wp_ai_client_prompt() surfaces as an uncaught exception rather
 * than a WP_Error from a generating method.
 *
 * @ticket 64591
 */
public function test_empty_string_throws_exception() {
      $this->expectException( InvalidArgumentException::class );
      $this->expectExceptionMessage( 'Cannot create a message from an empty string' );

      wp_ai_client_prompt( '   ' );
}

@jorgefilipecosta commented on PR #10881:


13 days ago
#37

Awesome work moving this big project forward @JasonTheAdams and @felixarntz! Thank you for the way you iterated fast and addressed the comments during the review process.

#38 @westonruter
13 days ago

In 61712:

AI: Fix errors for PHPStan rule level 0 after php-ai-client merge.

Developed in https://github.com/WordPress/wordpress-develop/pull/10990

Follow-up to r61699, r61700.

Props westonruter, SirLouen, jason_the_adams.
See #64591, #61175.

@westonruter commented on PR #10990:


13 days ago
#39

Committed in r61712 (97e30d9)

#40 @JeffPaul
12 days ago

following

@flixos90
12 days ago

AI provider plugin for Anthropic

@flixos90
12 days ago

AI provider plugin for Google

@flixos90
12 days ago

AI provider plugin for OpenAI

@peterwilsoncc commented on PR #10881:


11 days ago
#41

@felixarntz

This is not quite correct - not sure if it's a misunderstanding or you just pasted the wrong link :)

Yeah, wrong link. I was referring to WordPress/php-ai-client -- I had a lot of links open doing archeology.

_Mainly posting this for logging purposes, even though the PR has been merged._

@jason_the_adams commented on PR #10881:


10 days ago
#42

Or is there a plan to provide a higher-level helper that handles this loop automatically? Would be great to understand the design vision here.

To start we decided not to get too deep into agent-like behavior, as we'd tossed around an ->auto_resolve_abiliites() type of method, which could automatically handle AI function calls tied to abilities. I still think it's a cool idea, but for now we decided to expose the system that would handle that, giving advanced dev cases a clear path forward when using using_abilities().

One more minor finding for consideration. The WP_AI_Client_Prompt_Builder wraps SDK exceptions into WP_Error through the __call() magic method, which is great for WordPress developers. However, this wrapping doesn't cover the constructor. When invalid input is passed to wp_ai_client_prompt(), the SDK's PromptBuilder constructor throws an InvalidArgumentException directly:

That's a fair point! Typically, I'd say this is appropriate behavior, but given that all the constructor's parameter does is the same as with_text(), but that method stores a WP_Error, then it's odd not to be consistent.

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


8 days ago
#43

This pull request makes minor cleanup changes to the test files by removing unused import statements. No functionality is affected.

Trac ticket: https://core.trac.wordpress.org/ticket/64591

#44 follow-up: @justlevine
8 days ago

I'm concerned that it's the day before Beta 2, and the only progress I can find towards a connectors screen is a draft PR in https://github.com/WordPress/gutenberg/pull/75833 .

(I also have concerns about what's in that draft PR, but it's hard to know whether that's because it's currently in draft state or whether it's intended direction)

Last edited 8 days ago by justlevine (previous) (diff)

This ticket was mentioned in Slack in #core by desrosj. View the logs.


8 days ago

#46 in reply to: ↑ 44 @desrosj
8 days ago

Replying to justlevine:

I'm concerned that it's the day before Beta 2, and the only progress I can find towards a connectors screen is a draft PR in https://github.com/WordPress/gutenberg/pull/7583 .

(I also have concerns about what's in that draft PR, but it's hard to know whether that's because it's currently in draft state or whether it's intended direction)

Just noting that the PR URL is missing a number: https://github.com/WordPress/gutenberg/pull/75833.

This ticket was mentioned in Slack in #hosting by amykamala. View the logs.


8 days ago

#49 @flixos90
4 days ago

In 61776:

AI: Update PHP AI Client package to 1.2.1.

This package update allows registered providers to have a description, and it fixes an issue with Redis compatibility.

Props jason_the_adams, laurisaarni.
See #64591.

#51 @flixos90
4 days ago

In 61777:

AI: Remove unused use statements in tests.

Follow up to [61700].

Props soean.
See #64591.

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


3 days ago
#54

## Summary

  • Removes src/wp-includes/php-ai-client/src/polyfills.php which is dead code — the generated autoloader only handles class autoloading, so this function-only file is never loaded
  • The four polyfilled functions (array_is_list, str_starts_with, str_contains, str_ends_with) are already provided by WordPress Core in wp-includes/compat.php
  • Updates tools/php-ai-client/installer.sh to strip the file during future library updates

Follow-up to https://github.com/WordPress/wordpress-develop/pull/10881#issuecomment-3933921861.

🤖 Generated with Claude Code

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


3 days ago
#55

## Summary

  • Wraps the SDK's PromptBuilder constructor call in a try/catch inside WP_AI_Client_Prompt_Builder::__construct(), so invalid input (empty string, empty array, invalid type) is stored as a WP_Error instead of throwing an InvalidArgumentException
  • The error surfaces consistently through the fluent chain when a generating method is called, matching the existing __call() behavior
  • Updates three existing tests to assert WP_Error directly instead of catching exceptions
  • Adds a new test verifying wp_ai_client_prompt( ' ' ) returns a builder that yields WP_Error from generate_text()

Follow-up to https://github.com/WordPress/wordpress-develop/pull/10881#issuecomment-3934854584.

## Test plan

  • [ ] Verify npm run test:php -- --group ai-client passes (209 tests)

🤖 Generated with Claude Code

#57 @flixos90
2 days ago

In 61786:

AI: Remove unnecessary PHP AI Client polyfills file.

These functions, which are needed for the package, are already polyfilled by WordPress Core. They were never loaded by the custom autoloader in Core anyway, so they are dead code that is safe to remove.

Props gziolo.
See #64591.

#59 @flixos90
2 days ago

In 61787:

AI: Catch exceptions in WP_AI_Client_Prompt_Builder::__construct().

Exceptions were already caught and transformed into WP_Error objects in all instance methods of WP_AI_Client_Prompt_Builder, but not in the constructor. This meant that if an exception was thrown during construction, it would not be caught and would cause a fatal error instead of returning a WP_Error object.

Props gziolo.
See #64591.

#61 @justlevine
39 hours ago

For folks like me looking for the followup work regarding the Connectors screen, I believe it's in https://core.trac.wordpress.org/ticket/64730

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


35 hours ago
#62

This is a follow-up to https://github.com/WordPress/wordpress-develop/pull/10990 (r61712). The library update in r61776 re-introduced the following PHPStan issues which had previously been fixed:

 ------ ---------------------------------------------------------------------------------------------- 
  Line   wp-includes/php-ai-client/src/Providers/Http/Enums/RequestAuthenticationMethod.php            
 ------ ---------------------------------------------------------------------------------------------- 
  33     No error with identifier missingType.generics is reported on line 33.                         
         at src/wp-includes/php-ai-client/src/Providers/Http/Enums/RequestAuthenticationMethod.php:33  
 ------ ---------------------------------------------------------------------------------------------- 

 ------ ----------------------------------------------------------------------------- 
  Line   wp-includes/php-ai-client/src/Providers/Http/HttpTransporter.php             
 ------ ----------------------------------------------------------------------------- 
  263    No error to ignore is reported on line 263.                                  
         at src/wp-includes/php-ai-client/src/Providers/Http/HttpTransporter.php:263  
 ------ ----------------------------------------------------------------------------- 

I wasn't fully aware that src/wp-includes/php-ai-client is all a third party library pulled in from another source, not just src/wp-includes/php-ai-client/third-party. So in 6aee2e58e544e89417758fd6242fd46b45ccc4f6 the former path is excluded instead.

This also re-sorts the paths for third-party libraries in 56b149fa4fd804ead5e60082ae8d04963edf96c0.

Trac ticket: https://core.trac.wordpress.org/ticket/64591

## Use of AI Tools

n/a

#63 @westonruter
35 hours ago

In 61808:

AI: Exclude php-api-client from PHPStan analysis since analyzed upstream.

Third-party paths are also re-sorted in the PHPStan config.

Developed in https://github.com/WordPress/wordpress-develop/pull/11150

Follow up to r61776, r61712, r61699.

Props justlevine, flixos90, westonruter.
See #64591, #61175.

@westonruter commented on PR #11150:


35 hours ago
#64

Committed in r61808 (0738208)

Note: See TracTickets for help on using tickets.