The WordPress coreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress. development team builds WordPress! Follow this site forย general updates, status reports, and the occasional code debate. Thereโs lots of ways to contribute:
Found a bugbugA bug is an error or unexpected result. Performance improvements, code optimization, and are considered enhancements, not defects. After feature freeze, only bugs are dealt with, with regressions (adverse changes from the previous version) being the highest priority.?Create a ticket in the bug tracker.
This updates the expectations and policies that should be followed through the final release of WordPress 7.0 following the previous post and the release of RC2 on 26 March.
These policies mainly cover how and when CoreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress. committers can commit. For non-committing contributors, this post may help explain why Core committers make certain decisions.
TrunktrunkA directory in Subversion containing the latest development code in preparation for the next major release cycle. If you are running "trunk", then you are on the latest revision. is now WordPress 7.1-alpha
WordPress 7.0 has been copied to its own branch, trunk is now open for commits for the next version of the software.
Backporting to the 7.0 branchbranchA directory in Subversion. WordPress uses branches to store the latest development code for each major release (3.9, 4.0, etc.). Branches are then updated with code for any minor releases of that branch. Sometimes, a major version of WordPress and its minor versions are collectively referred to as a "branch", such as "the 4.0 branch".
Backporting commits of production code (that is, anything that ends up in the zip file) now requires double sign-off by two core committers. The dev-feedback keyword should be used to request a second committercommitterA developer with commit access. WordPress has five lead developers and four permanent core developers with commit access. Additionally, the project usually has a few guest or component committers - a developer receiving commit access, generally for a single release cycle (sometimes renewed) and/or for a specific component.โs review, dev-reviewed should be added to indicate a second committer has reviewed and approved the commit to the 7.0 branch.
String Freeze
The RC1 release marked the hard string freeze point of the release cycle and that continues. Strings will be available for Polyglots contributors shortly. Please subscribe to the Make Polyglots blog for updates.
No new strings are permitted. Exceptions can be made for critical strings (the About page, for example) provided they are properly tagged with the i18n-change keyword in TracTracAn open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. and the Polyglot team is made aware. Existing strings can be removed and/or duplicated as necessary.
Seek guidance from the Polyglots team reps for any strings reported as buggy. A buggy string is one that can not be translated to all languages in its current form.ย
Tickets on the WordPress 7.0 milestone
For the remainder of the cycle, only two types of tickets may be placed on/remain on the 7.0 milestone:
Regressions: bugs that have been introduced during the WordPress 7.0 development cycle, either to existing or new features.
Test suite expansion: tests can be committed at any time without regard to code or string freezes. This can cover either new or existing features.
Please make sure to observe all code freezes, which applies to changes of any kind. Coordinate with the release squad in the #7-0-release-leads channel in SlackSlackSlack is a Collaborative Group Chat Platform https://slack.com/. The WordPress community has its own Slack Channel at https://make.wordpress.org/chat/ if there is a change you feel should be committed during a freeze.
Note: The 7.0 branchbranchA directory in Subversion. WordPress uses branches to store the latest development code for each major release (3.9, 4.0, etc.). Branches are then updated with code for any minor releases of that branch. Sometimes, a major version of WordPress and its minor versions are collectively referred to as a "branch", such as "the 4.0 branch". was created on 26 March. This post should be considered obsolete for the RCrelease candidateOne of the final stages in the version release cycle, this version signals the potential to be a final release to the public. Also see alpha (beta). phase of the 7.0 release cycle. Refer to the updated post for expectations and policies in place.
These policies mainly cover how and when CoreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress. committers can commit. For non-committing contributors, this post may help explain why Core committers make certain decisions.
Committing to TrunktrunkA directory in Subversion containing the latest development code in preparation for the next major release cycle. If you are running "trunk", then you are on the latest revision.
Due to a technical issue that must be resolved before the 7.0 branch is created, branching has been delayed until RC2 later this week (see #64393 and the relevant pull request for background on the issue).
As a result, all commits to trunk will require double sign-off by two core committers until the 7.0 branch is created.
The dev-feedback keyword should be used to request a second committercommitterA developer with commit access. WordPress has five lead developers and four permanent core developers with commit access. Additionally, the project usually has a few guest or component committers - a developer receiving commit access, generally for a single release cycle (sometimes renewed) and/or for a specific component.โs review, dev-reviewed should be added to indicate a second committer has reviewed and approved the commit to the 7.0 branch. Commits to the test suite do not require double sign-off.
String Freeze
RC1 release marks the hard string freeze point of the release cycle. While this normally means the Polyglots teamPolyglots TeamPolyglots Team is a group of multilingual translators who work on translating plugins, themes, documentation, and front-facing marketing copy. https://make.wordpress.org/polyglots/teams/ can begin translating strings from the upcoming release into their local language, a version-specific branch is required. As a result, strings will not be available for translationtranslationThe process (or result) of changing text, words, and display formatting to support another language. Also see localization, internationalization. until the 7.0 branch is created.
Despite this, the normal rules for hard string freeze will be followed:
No new strings are permitted. Exceptions can be made for critical strings (the About page, for example) provided they are properly tagged with the i18n-change keyword in TracTracAn open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. and the Polyglot team is made aware.
Existing strings can be removed and/or duplicated if needed.
Seek guidance from the Polyglots team reps for any strings reported as buggy. A buggy string is one that can not be translated to all languages in its current form.ย
Tickets on the WordPress 7.0 milestone
For the remainder of the cycle, only two types of tickets may be placed on/remain on the 7.0 milestone:
Regressions: bugs that have been introduced during the WordPress 7.0 development cycle, either to existing or new features.
Test suite expansion: tests can be committed at any time without regard to code or string freezes. This can cover either new or existing features.
Bumping Trunk to WordPress 7.1-alpha
After the 7.0 branch is created following RC2, a follow-up post will be published announcing that trunk is open for commits related to the next version of the software.
WordPress 6.9 introduced the Abilities API. The APIAPIAn API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways. provides a common interface that AI agents, workflow automation tools, and plugins can use to interact with WordPress. In WordPress 7.0 we continued that work and now provide a counterpart JavaScriptJavaScriptJavaScript or JS is an object-oriented computer programming language commonly used to create interactive effects within web browsers. WordPress makes extensive use of JS for a better user experience. While PHP is executed on the server, JS executes within a userโs browser.
https://www.javascript.com API that can be used to implement client-side abilities like navigating, or inserting blocks. This work is fundamental to integrate with browser agents/extensions and WebMCP.
Two packages
The client-side Abilities API is split into two packages:
@wordpress/abilities: A pure state management package with no WordPress server dependencies. It provides the store, registration functions, querying, and execution logic. Use this when you only need the abilities store without loading server-registered abilities. This package could also be used in non-WordPress projects.
@wordpress/core-abilities :The WordPress integration layer. When loaded, it automatically fetches all abilities and categories registered on the server via the REST APIREST APIThe REST API is an acronym for the RESTful Application Program Interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application (think โphone appโ or โwebsiteโ) can communicate with the data store (think โdatabaseโ or โfile systemโ)
https://developer.wordpress.org/rest-api/ (/wp-abilities/v1/) and registers them in the @wordpress/abilities store with appropriate callbacks.
Getting started
To use the Abilities API in your pluginPluginA plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party., you need to enqueue the appropriate script module.
When your plugin needs server-registered abilities
If your plugin needs access to abilities registered on the server (e.g., coreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress. abilities), enqueue @wordpress/core-abilities. This is the most common case:
This will load both @wordpress/core-abilities and its dependency @wordpress/abilities, and automatically fetch and register all server-side abilities.
When your plugin only registers client-side abilities
If your plugin only needs to register and work with its own client-side abilities on a specific page, without needing server-registered abilities, you can enqueue just @wordpress/abilities:
If your client code is also a script module relying on @wordpress/scripts, you can just use the following code like any other import:
import {
registerAbility,
registerAbilityCategory,
getAbilities,
executeAbility,
} from '@wordpress/abilities';
Registering abilities
Register a categoryCategoryThe 'category' taxonomy lets you group posts / content together that share a common bond. Categories are pre-defined and broad ranging. first
Abilities are organized into categories. Before registering an ability, its category must exist. Server-side categories are loaded automatically when @wordpress/core-abilities is enqueued. To register a client-side category:
Abilities should define JSONJSONJSON, or JavaScript Object Notation, is a minimal, readable format for structuring data. It is used primarily to transmit data between a server and web application, as an alternative to XML. Schema (draft-04) for input validation and output validation:
registerAbility( {
name: 'my-plugin/create-item',
label: 'Create Item',
description: 'Creates a new item with the given title and content',
category: 'my-plugin-actions',
input_schema: {
type: 'object',
properties: {
title: { type: 'string', description: 'The title of the item', minLength: 1 },
content: { type: 'string', description: 'The content of the item' },
status: { type: 'string', description: 'The publish status of the item', enum: [ 'draft', 'publish' ] },
},
required: [ 'title' ],
},
output_schema: {
type: 'object',
properties: {
id: { type: 'number', description: 'The unique identifier of the created item' },
title: { type: 'string', description: 'The title of the created item' },
},
required: [ 'id' ],
},
callback: async ( { title, content, status = 'draft' } ) => {
// Create the item...
return { id: 123, title };
},
} );
When executeAbility is called, the input is validated against input_schema before execution and the output is validated against output_schema after execution. If validation fails, an error is thrown with the code ability_invalid_input or ability_invalid_output.
Permission callbacks
Abilities can include a permissionCallback that is checked before execution:
registerAbility( {
name: 'my-plugin/admin-action',
label: 'Admin Action',
description: 'An action only available to administrators',
category: 'my-plugin-actions',
permissionCallback: () => {
return currentUserCan( 'manage_options' );
},
callback: async () => {
// Only runs if permissionCallback returns true
return { success: true };
},
} );
If the permission callback returns false, an error with code ability_permission_denied is thrown.
Querying abilities
Direct function calls
const {
getAbilities,
getAbility,
getAbilityCategories,
getAbilityCategory,
} = await import( '@wordpress/abilities' );
// Get all registered abilities
const abilities = getAbilities();
// Filter abilities by category
const dataAbilities = getAbilities( { category: 'data-retrieval' } );
// Get a specific ability by name
const ability = getAbility( 'my-plugin/create-item' );
// Get all categories
const categories = getAbilityCategories();
// Get a specific category
const category = getAbilityCategory( 'data-retrieval' );
Using with ReactReactReact is a JavaScript library that makes it easy to reason about, construct, and maintain stateless and stateful user interfaces.
https://reactjs.org and @wordpress/data
The abilities store (core/abilities) integrates with @wordpress/data, so you can use useSelect for reactive queries in React components:
import { useSelect } from '@wordpress/data';
import { store as abilitiesStore } from '@wordpress/abilities';
function AbilitiesList() {
// Get all abilities reactively
const abilities = useSelect(
( select ) => select( abilitiesStore ).getAbilities(),
[]
);
// Filter by category
const dataAbilities = useSelect(
( select ) =>
select( abilitiesStore ).getAbilities( {
category: 'data-retrieval',
} ),
[]
);
// abilities and dataAbilities update automatically when the store changes
}
Executing abilities
Use executeAbility to run any registered ability, whether client-side or server-side:
import { executeAbility } from '@wordpress/abilities';
try {
const result = await executeAbility( 'my-plugin/create-item', {
title: 'New Item',
content: 'Item content',
status: 'draft',
} );
console.log( 'Created item:', result.id );
} catch ( error ) {
switch ( error.code ) {
case 'ability_permission_denied':
console.error( 'You do not have permission to run this ability.' );
break;
case 'ability_invalid_input':
console.error( 'Invalid input:', error.message );
break;
case 'ability_invalid_output':
console.error( 'Unexpected output:', error.message );
break;
default:
console.error( 'Execution failed:', error.message );
}
}
For server-side abilities (those registered via PHPPHPThe web scripting language in which WordPress is primarily architected. WordPress requires PHP 7.4 or higher and loaded by @wordpress/core-abilities), execution is handled automatically via the REST API. The HTTPHTTPHTTP is an acronym for Hyper Text Transfer Protocol. HTTP is the underlying protocol used by the World Wide Web and this protocol defines how messages are formatted and transmitted, and what actions Web servers and browsers should take in response to various commands. method used depends on the abilityโs annotations:
readonly: true: uses GET
destructive: true + idempotent: true: uses DELETE
All other cases: uses POST
Annotations
Abilities support metadata annotations that describe their behavior:
Abilities registered on the server via the PHP API (wp_register_ability(), wp_register_ability_category()) are automatically made available on the client when @wordpress/core-abilities is loaded. WordPress core enqueues @wordpress/core-abilities on all adminadmin(and super admin) pages, so server abilities are available by default in the admin.
Plugins that register server-side abilities do not need any additional client-side setup. The abilities will be fetched from the REST API and registered in the client store automatically.
WordPress 7.0 includes a built-in AI Client โ a provider-agnostic PHPPHPThe web scripting language in which WordPress is primarily architected. WordPress requires PHP 7.4 or higherAPIAPIAn API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways. that lets plugins send prompts to AI models and receive results through a consistent interface. Your pluginPluginA plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party. describes what it needs and how it needs it. WordPress handles routing the request to a suitable model from a provider the site owner has configured.
This post explains the API surface, walks through code examples, and covers what plugin developers need to know.
The entry point: wp_ai_client_prompt()
Every interaction starts with:
$builder = wp_ai_client_prompt();
This returns a WP_AI_Client_Prompt_Builder object, a fluent builder that offers a myriad of ways to customize your prompt. You chain configuration methods and then call a generation method to receive a result:
$text = wp_ai_client_prompt( 'Summarize the benefits of caching in WordPress.' )
->using_temperature( 0.7 )
->generate_text();
You can pass the prompt text directly as a parameter to wp_ai_client_prompt() for convenience, though alternatively the with_text() method is available for building the prompt incrementally.
Text generation
Hereโs a basic text generation example:
$text = wp_ai_client_prompt( 'Write a haiku about WordPress.' )
->generate_text();
if ( is_wp_error( $text ) ) {
// Handle error.
return;
}
echo wp_kses_post( $text );
You can pass a JSONJSONJSON, or JavaScript Object Notation, is a minimal, readable format for structuring data. It is used primarily to transmit data between a server and web application, as an alternative to XML. schema so that the model returns structured data as a JSON string:
For richer metadata, e.g. covering provider and model information, use generate_*_result() instead. For example, for image generation:
$result = wp_ai_client_prompt( 'A serene mountain landscape.' )
->generate_image_result();
This returns a GenerativeAiResult object that provides several pieces of additional information, including token usage and which provider and which model responded to the prompt. The most relevant methods for this additional metadata are:
getTokenUsage(): Returns the token usage, broken down by input, output, and optionally thinking.
getProviderMetadata(): Returns metadata about the provider that handled the request.
getModelMetadata(): Returns metadata about the model that handled the request (through the provider).
The GenerativeAiResult object is serializable and can be passed directly to rest_ensure_response(), making it straightforward to expose AI features through the REST APIREST APIThe REST API is an acronym for the RESTful Application Program Interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application (think โphone appโ or โwebsiteโ) can communicate with the data store (think โdatabaseโ or โfile systemโ)
https://developer.wordpress.org/rest-api/.
Available generate_*_result() methods:
generate_text_result()
generate_image_result()
convert_text_to_speech_result()
generate_speech_result()
generate_video_result()
Use the appropriate method for the modality you are working with. Each returns a GenerativeAiResult object with rich metadata.
Model preferences
The models available on each WordPress site depends on which AI providers the administrators of that site have configured in the Settings > Connectors screen.
Since your plugin doesnโt control which providers are available on each site, use using_model_preference() to indicate which models would be ideal. The AI Client will use the first model from that list that is available, falling back to any compatible model if none are available:
$text_result = wp_ai_client_prompt( 'Summarize the history of the printing press.' )
->using_temperature( 0.1 )
->using_model_preference(
'claude-sonnet-4-6',
'gemini-3.1-pro-preview',
'gpt-5.4'
)
->generate_text_result();
This is a preference, not a requirement. Your plugin should function without it. Keep in mind that you can test or verify which model was used by looking at the full result object, under the providerMetadata and modelMetadata properties.
If you donโt specify a model preference, the first model encountered across the configured providers that is suitable will be used. It is up to the individual provider implementations to sort the providerโs models in a reasonable manner, e.g. so that more recent models appear before older models of the same model family. The three initial official provider plugins (see below) organize models in that way, as recommended.
Feature detection
Not every WordPress site will have an AI provider configured, and not every provider supports every capabilitycapabilityAย capabilityย is permission to perform one or more types of task. Checking if a user has a capability is performed by the current_user_can function. Each user of a WordPress site might have some permissions but not others, depending on theirย role. For example, users who have the Author role usually have permission to edit their own posts (the โedit_postsโ capability), but not permission to edit other usersโ posts (the โedit_others_postsโ capability). and every option. Before showing AI-powered UIUIUser interface, check whether the feature can work:
$builder = wp_ai_client_prompt( 'test' )
->using_temperature( 0.7 );
if ( $builder->is_supported_for_text_generation() ) {
// Safe to show text generation UI.
}
These checks do not make API calls. They use deterministic logic to match the builderโs configuration against the capabilitiescapabilityAย capabilityย is permission to perform one or more types of task. Checking if a user has a capability is performed by the current_user_can function. Each user of a WordPress site might have some permissions but not others, depending on theirย role. For example, users who have the Author role usually have permission to edit their own posts (the โedit_postsโ capability), but not permission to edit other usersโ posts (the โedit_others_postsโ capability). of available models. As such, they are fast to run and there is no cost incurred by calling them.
Available support check methods:
is_supported_for_text_generation()
is_supported_for_image_generation()
is_supported_for_text_to_speech_conversion()
is_supported_for_speech_generation()
is_supported_for_video_generation()
Use these to conditionally load your UI, show a helpful notice when the feature is unavailable, or skip registering UI altogether. Never assume that AI features will be available just because WordPress 7.0 is installed.
Advanced configuration
System instructions
$text = wp_ai_client_prompt( 'Explain caching.' )
->using_system_instruction( 'You are a WordPress developer writing documentation.' )
->generate_text();
use WordPress\AiClient\Files\Enums\FileTypeEnum;
use WordPress\AiClient\Files\Enums\MediaOrientationEnum;
$result = wp_ai_client_prompt()
->with_text( 'A vibrant sunset over the ocean.' )
->as_output_file_type( FileTypeEnum::inline() )
->as_output_media_orientation( MediaOrientationEnum::from( 'landscape' ) )
->generate_image_result();
Multimodal output
use WordPress\AiClient\Messages\Enums\ModalityEnum;
$result = wp_ai_client_prompt( 'Create a recipe for a chocolate cake and include photos for the steps.' )
->as_output_modalities( ModalityEnum::text(), ModalityEnum::image() )
->generate_result();
if ( is_wp_error( $result ) ) {
// Handle error.
return;
}
foreach ( $result->toMessage()->getParts() as $part ) {
if ( $part->isText() ) {
echo wp_kses_post( $part->getText() );
} elseif ( $part->isFile() && $part->getFile()->isImage() ) {
echo '<img src="' . esc_url( $part->getFile()->getDataUri() ) . '">';
}
}
Additional builder methods
The full list of configuration methods is available via the WP_AI_Client_Prompt_Builder class. Key methods include:
Configuration
Method
Prompt text
with_text()
File input
with_file()
Conversation history (relevant for multi-turn / chats)
with_history()
System instruction
using_system_instruction()
Temperature
using_temperature()
Max tokens
using_max_tokens()
Top-p / Top-k
using_top_p(), using_top_k()
Stop sequences
using_stop_sequences()
Model preference
using_model_preference()
Output modalities
as_output_modalities()
Output file type
as_output_file_type()
JSON response
as_json_response()
Error handling
wp_ai_client_prompt() generator methods return WP_Error on failure, following WordPress conventions:
$text = wp_ai_client_prompt( 'Hello' )
->generate_text();
if ( is_wp_error( $text ) ) {
// Handle the error.
}
When used in a REST API callback, both GenerativeAiResult and WP_Error can be passed to rest_ensure_response() directly:
If an error occurs, it will automatically have a semantically meaningful HTTPHTTPHTTP is an acronym for Hyper Text Transfer Protocol. HTTP is the underlying protocol used by the World Wide Web and this protocol defines how messages are formatted and transmitted, and what actions Web servers and browsers should take in response to various commands. response code attached to it.
Controlling AI availability
For granular control, the wp_ai_client_prevent_promptfilterFilterFilters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output. allows preventing specific prompts from executing:
add_filter(
'wp_ai_client_prevent_prompt',
function ( bool $prevent, WP_AI_Client_Prompt_Builder $builder ): bool {
// Example: Block all prompts for non-admin users.
if ( ! current_user_can( 'manage_options' ) ) {
return true;
}
return $prevent;
},
10,
2
);
When a prompt is prevented:
No AI call is attempted.
is_supported_*() methods return false, allowing plugins to gracefully hide their UI.
generate_*() methods return a WP_Error.
Architecture
The AI Client in WordPress 7.0 consists of two layers:
PHP AI Client (wordpress/php-ai-client) โ A provider-agnostic PHP SDK bundled in CoreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress. as an external library. This is the engine that handles provider communication, model selection, and response normalization. Since it is technically a WordPress agnostic PHP SDK which other PHP projects can use too, it uses camelCase method naming and makes use of exceptions.
WordPress wrapper โ Coreโs WP_AI_Client_Prompt_Builder class wraps the PHP AI Client with WordPress conventions: snake_case methods, WP_Error returns, and integration with WordPress HTTP transport, the Abilities API, the Connectors/Settings infrastructure, and the WordPress hooksHooksIn WordPress theme and development, hooks are functions that can be applied to an action or a Filter in WordPress. Actions are functions performed when a certain event occurs in WordPress. Filters allow you to modify certain functions. Arguments used to hook both filters and actions look the same. system.
The wp_ai_client_prompt() function is the recommended entry point. It returns a WP_AI_Client_Prompt_Builder instance that catches exceptions from the underlying SDK and converts them to WP_Error objects.
Credential management
API keys are managed through the Connectors API. AI provider plugins that register with the PHP AI Clientโs provider registry get automatic connector integration โ including the Settings > Connectorsadminadmin(and super admin) UI for API key management. Plugin developers using the AI Client to build features do not need to handle credentials at all.
Official provider plugins
WordPress Core does not bundle any AI providers directly. Instead, they are developed and maintained as plugins, which allows for more flexible and rapid iteration speed, in accordance with how fast AI evolves. The AI Client in WordPress Core provides the stable foundation, and as an abstraction layer is sufficiently detached from provider specific requirements that may change overnight.
While anyone is able to implement new provider plugins, the WordPress project itself has developed three initial flagship implementations, to integrate with the most popular AI providers. These plugins are:
Separately available: Client-side JavaScriptJavaScriptJavaScript or JS is an object-oriented computer programming language commonly used to create interactive effects within web browsers. WordPress makes extensive use of JS for a better user experience. While PHP is executed on the server, JS executes within a userโs browser.
https://www.javascript.com API
A JavaScript API with a similar fluent prompt builder is available via the wp-ai-client package. It uses REST endpoints under the hood to connect to the server-side infrastructure. This API is not part of Core, and it is still being evaluated whether this approach is scalable for general use. Because the API allows arbitrary prompt execution from the client-side, it requires a high-privilege capability check, which by default is only granted to administrators. This restriction is necessary to prevent untrusted users from sending any prompt to any configured AI provider. As such, using this approach in a distributed plugin is not recommended.
For now, the recommended approach is to implement individual REST API endpoints for each specific AI feature your plugin provides, and have your JavaScript functionality call those endpoints. This allows you to enforce granular permission checks and limit the scope of what can be executed from the client-side. It also keeps the actual AI prompt handling and configuration fully scoped to be server-side only.
MigrationMigrationMoving the code, database and media files for a website site from one server to another. Most typically done when changing hosting companies. from php-ai-client and wp-ai-client
If you have been using these packages in your plugin(s) before, hereโs what to know.
Recommended: require WordPress 7.0
The simplest path is to update your pluginโs Requires at least headerHeaderThe header of your site is typically the first thing people will experience. The masthead or header art located across the top of your page is part of the look and feel of your website. It can influence a visitorโs opinion about your content and you/ your organizationโs brand. It may also look different on different screen sizes. to 7.0 and remove the Composer dependencies on wordpress/php-ai-client and its transitive dependencies.
Replace any AI_Client::prompt() calls with wp_ai_client_prompt().
For the wordpress/wp-ai-client package, if you are not using the packageโs REST API endpoints or JavaScript API, you can simply remove it as a dependency, since everything else it does is now part of WordPress Core.
If you must support WordPress < 7.0
PHP AI Client (wordpress/php-ai-client)
If your plugin still needs to run on WordPress versions before 7.0 while also bundling wordpress/php-ai-client, you will need a conditional autoloader workaround. The PHP AI Client and its dependencies are now loaded by Core on 7.0+, so loading them again via Composer will cause conflicts (duplicate class definitions).
The solution: only register your Composer autoloader for these dependencies when running on WordPress versions before 7.0:
Due to how Composerโs autoloader works โ loading all dependencies at once rather than selectively โ a more granular approach was not feasible. This means the conditional check needs to wrap the entire autoloader. Alternatively, break your PHP dependencies apart in two separate Composer setups, one that can always be autoloaded, and another one for the wordpress/php-ai-client package and its dependencies only, which would be conditionally autoloaded.
WP AI Client (wordpress/wp-ai-client)
The wordpress/wp-ai-client package handles the WordPress 7.0 transition automatically. On 7.0+, it disables its own PHP SDK infrastructure (since Core handles it natively) but keeps the REST API endpoints and JavaScript API active, as those arenโt in Core yet.
You can continue loading this package unconditionally. It detects the WordPress version and only activates the parts that arenโt already provided by Core. No conditional loading needed. However, make sure to stay up to date on this package, because it will likely be discontinued soon, in favor of moving the REST API endpoints and JavaScript API into GutenbergGutenbergThe Gutenberg project is the new Editor Interface for WordPress. The editor improves the process and experience of creating new content, making writing rich content much simpler. It uses โblocksโ to add richness rather than shortcodes, custom HTML etc.
https://wordpress.org/gutenberg/. There are ongoing discussions on whether these should be merged into Core too, see #64872 and #64873.
TracTracAn open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress.ticketticketCreated for both bug reports and feature development on the bug tracker.: #64591
The live meeting will focus on the discussion for upcoming releases, and have an open floor section.
The various curated agenda sections below refer to additional items. If you haveย ticketticketCreated for both bug reports and feature development on the bug tracker.ย requests for help, please continue to post details in the comments section at the end of this agenda or bring them up during the dev chat.
New Dev Notesdev noteEach important change in WordPress Core is documented in a developers note, (usually called dev note). Good dev notes generally include a description of the change, the decision that led to this change, and a description of how developers are supposed to work with that change. Dev notes are published on Make/Core blog during the beta phase of WordPress release cycle. Publishing dev notes is particularly important when plugin/theme authors and WordPress developers need to be aware of those changes.In general, all dev notes are compiled into a Field Guide at the beginning of the release candidate phase.:
The discussion section of the agenda is for discussing important topics affecting the upcoming release or larger initiatives that impact the CoreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress. Team. To nominate a topic for discussion, please leave a comment on this agenda with a summary of the topic, any relevant links that will help people get context for the discussion, and what kind of feedback you are looking for from others participating in the discussion.
Open floor ย ๐๏ธ
Any topic can be raised for discussion in the comments, as well as requests for assistance on tickets. Tickets in the milestone for the next major or maintenance release will be prioritized.
Please include details of tickets / PRs and the links in the comments, and indicate whether you intend to be available during the meeting for discussion or will be async.
The decision was made to delay the 7.0 RC1 release to Tuesday, March 24th, 2026 at 15:00 UTC to allow time to address concerns and review any necessary work to ensure a quality release.ย
The rest of the 7.0 release cycle schedule is unchanged.
WordPress 7.0 introduces the Connectors APIAPIAn API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways. โ a new framework for registering and managing connections to external services. The initial focus is on AI providers, giving WordPress a standardized way to handle API key management, provider discovery, and adminadmin(and super admin)UIUIUser interface for configuring AI services.
This post walks through what the Connectors API does, how it works under the hood, and what pluginPluginA plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party. developers need to know.
A connector represents a connection to an external service. Each connector carries standardized metadata โ a display name, description, logo, authentication configuration, and an optional association with a WordPress.orgWordPress.orgThe community site where WordPress code is created and shared by the users. This is where you can download the source code for WordPress core, plugins and themes as well as the central location for community conversations and organization. https://wordpress.org/ plugin. The system currently focuses on providers that authenticate with an API key, but the architecture is designed to support additional connector types in future releases.
WordPress 7.0 comes with three featured connectorsโAnthropic, Google, and OpenAIโaccessible from the newย Settings โ Connectorsย screen, making installation seamless.
Each connector is stored as an associative array with the following shape:
If youโre building an AI provider plugin that integrates with the WP AI Client, you donโt need to register a connector manually. The Connectors API automatically discovers providers from the WP AI Clientโs default registry and creates connectors with the correct metadata.
Hereโs what happens during initialization:
Built-in connectors (Anthropic, Google, OpenAI) are registered with hardcoded defaults.
The system queries the AiClient::defaultRegistry() for all registered providers.
For each provider, metadata (name, description, logo, authentication method) is merged on top of the defaults, with provider registry values taking precedence.
The wp_connectors_init action fires so plugins can override metadata or register additional connectors.
In short: if your AI provider plugin registers with the WP AI Client, the connector is created for you. No additional code is needed.
The Settings > Connectors admin screen
Registered connectors appear on a new Settings > Connectors admin screen. The screen renders each connector as a card, and the registry data drives whatโs displayed:
name, description, and logo_url are shown on the card.
plugin.file โ the value is the pluginโs main file path relative to the plugins directory (e.g.,ย akismet/akismet.phpย orย hello.php). The screen uses it to check whether the associated plugin is installed and active, and shows the appropriate action button.
authentication.credentials_url is rendered as a link directing users to the providerโs site to obtain API credentials.
For api_key connectors, the screen shows the current key source (environment variable, PHPPHPThe web scripting language in which WordPress is primarily architected. WordPress requires PHP 7.4 or higher constant, or database) and connection status.
Connectors with other authentication methods are stored in the PHP registry and exposed via the script module data, but currently require a client-side JavaScriptJavaScriptJavaScript or JS is an object-oriented computer programming language commonly used to create interactive effects within web browsers. WordPress makes extensive use of JS for a better user experience. While PHP is executed on the server, JS executes within a userโs browser.
https://www.javascript.com registration for custom frontend UI.
Authentication and API key management
Connectors support two authentication methods:
api_key โ Requires an API key, which can be provided via environment variable, PHP constant, or the database (checked in that order).
none โ No authentication required.
The authentication method (api_key or none) is determined by the authentication metadata registered with the connector. For providers using api_key, a database setting name is automatically generated using the pattern connectors_{$provider_type}_{$provider_id}_api_key. Itโs also possible to set a custom name using setting_name property. API keys stored in the database are not encrypted but are masked in the user interface. Encryption is being explored in a follow-up ticketticketCreated for both bug reports and feature development on the bug tracker.:ย #64789.
For AI providers, there is a specific naming convention in place for environment variables and PHP constants: {PROVIDER_ID}_API_KEY (e.g., the anthropic provider maps to ANTHROPIC_API_KEY). For other types of providers, an environment variable (env_var_name) and a PHP constant (constant_name) can be optionally set to any value.
API key source priority
For api_key connectors, the system looks for a setting value in this order:
Returns an associative array with keys: name, description, type, authentication, and optionally logo_url and plugin. Returns null if the connector is not registered.
wp_get_connectors()
Retrieves all registered connectors, keyed by connector ID:
The wp_connectors_init action fires after all built-in and auto-discovered connectors have been registered. Plugins can use this hook to override metadata on existing connectors.
Since the registry rejects duplicate IDs, overriding requires an unregister, modify, register sequence:
Always check is_registered() before calling unregister() โ calling unregister() on a non-existent connector triggers a _doing_it_wrong() notice.
unregister() returns the connector data, which you can modify and pass back to register().
Connector IDs must match the pattern /^[a-z0-9_-]+$/ (lowercase alphanumeric, underscores, and hyphens only).
Registry methods
Within the wp_connectors_init callback, the WP_Connector_Registry instance provides these methods:
Method
Description
register( $id, $args )
Register a new connector. Returns the connector data or null on failure.
unregister( $id )
Remove a connector and return its data. Returns null if not found.
is_registered( $id )
Check if a connector exists.
get_registered( $id )
Retrieve a single connectorโs data.
get_all_registered()
Retrieve all registered connectors.
Outside of the wp_connectors_init callback, use the public API functions (wp_get_connector(), wp_get_connectors(), wp_is_connector_registered()) instead of accessing the registry directly.
The initialization lifecycle
Understanding the initialization sequence helps when deciding where to hook in:
During the init action, _wp_connectors_init() runs and:
Creates the WP_Connector_Registry singleton.
Registers built-in connectors (Anthropic, Google, OpenAI) with hardcoded defaults.
Auto-discovers providers from the WP AI Client registry and merges their metadata on top of defaults.
Fires the wp_connectors_init action โ this is where plugins override metadata or register additional connectors.
The wp_connectors_init action is the only supported entry point for modifying the registry. Attempting to set the registry instance outside of init triggers a _doing_it_wrong() notice.
Looking ahead
The Connectors API in WordPress 7.0 was optimized for AI providers, but the underlying architecture is designed to grow. Currently, only connectors with api_key authentication receive the full admin UI treatment. The PHP registry already accepts any connector type โ whatโs missing is the frontend integration for connectors with different authentication mechanisms.
Future releases are expected to:
Expand support for additional authentication methods beyond api_key and none.
Offer more built-in UI integrations beyond api_key.
Provide a client-side JavaScript registration API for custom connector UI.
When those capabilitiescapabilityAย capabilityย is permission to perform one or more types of task. Checking if a user has a capability is performed by the current_user_can function. Each user of a WordPress site might have some permissions but not others, depending on theirย role. For example, users who have the Author role usually have permission to edit their own posts (the โedit_postsโ capability), but not permission to edit other usersโ posts (the โedit_others_postsโ capability). land, the wp_connectors_init action will be the primary hook for registering new connector types.
Props to @jorgefilipecosta, @shaunandrews, @flixos90, @westonruter, @justlevine, and others for contributing to the Connectors screen and this dev notedev noteEach important change in WordPress Core is documented in a developers note, (usually called dev note). Good dev notes generally include a description of the change, the decision that led to this change, and a description of how developers are supposed to work with that change. Dev notes are published on Make/Core blog during the beta phase of WordPress release cycle. Publishing dev notes is particularly important when plugin/theme authors and WordPress developers need to be aware of those changes.In general, all dev notes are compiled into a Field Guide at the beginning of the release candidate phase..
The live meeting will focus on the discussion for upcoming releases, and have an open floor section.
The various curated agenda sections below refer to additional items. If you haveย ticketticketCreated for both bug reports and feature development on the bug tracker.ย requests for help, please continue to post details in the comments section at the end of this agenda or bring them up during the dev chat.
New Dev Notesdev noteEach important change in WordPress Core is documented in a developers note, (usually called dev note). Good dev notes generally include a description of the change, the decision that led to this change, and a description of how developers are supposed to work with that change. Dev notes are published on Make/Core blog during the beta phase of WordPress release cycle. Publishing dev notes is particularly important when plugin/theme authors and WordPress developers need to be aware of those changes.In general, all dev notes are compiled into a Field Guide at the beginning of the release candidate phase.:
The discussion section of the agenda is for discussing important topics affecting the upcoming release or larger initiatives that impact the CoreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress. Team. To nominate a topic for discussion, please leave a comment on this agenda with a summary of the topic, any relevant links that will help people get context for the discussion, and what kind of feedback you are looking for from others participating in the discussion.
Open floor ย ๐๏ธ
Any topic can be raised for discussion in the comments, as well as requests for assistance on tickets. Tickets in the milestone for the next major or maintenance release will be prioritized.
Please include details of tickets / PRs and the links in the comments, and indicate whether you intend to be available during the meeting for discussion or will be async.
As of WordPress 7.0, any blockBlockBlock is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. attribute that supports Block Bindings also supports Pattern Overrides. So now, you can use Pattern Overrides for any block you want โ even custom blocks โ the previous limit to a hardcoded set of CoreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress. blocks no longer holds you back. To get started, opt in through the server-side block_bindings_supported_attributes filter(s).
The underlying Block Bindings mechanism will make sure that:
In dynamic blocks, the correct, bound attribute values will be passed to render_callback().
In static blocks, the HTMLHTMLHyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers.APIAPIAn API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways. is used to locate attributes sourced from html, rich-text, or attribute sources via their selectors in the persisted markup, replacing their values with the respective bound attribute values.
Bound attribute values should appear correctly in the rendered blocksโ markup in these cases. You shouldnโt need any other modifications.
For static blocks with unsourced attributes, or with sourced attributes whose selectors are more complex than the HTML API currently understands, you might need to add a render_callback() or a render_blockfilterFilterFilters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output. to make sure bound attribute values are correctly handled. Itโs best if you first try without (i.e. by only adding the attribute via block_bindings_supported_attributes filter). Then, if the bound attribute value doesnโt render, add the callback or the filter that guarantees the render.
Props to @fabiankaegy and @marybaum for reviewing this dev notedev noteEach important change in WordPress Core is documented in a developers note, (usually called dev note). Good dev notes generally include a description of the change, the decision that led to this change, and a description of how developers are supposed to work with that change. Dev notes are published on Make/Core blog during the beta phase of WordPress release cycle. Publishing dev notes is particularly important when plugin/theme authors and WordPress developers need to be aware of those changes.In general, all dev notes are compiled into a Field Guide at the beginning of the release candidate phase.!
WordPress 7.0 expandsย contentOnlyย editing to unsynced patterns and template parts.
The key behavioral change is that unsynced patterns and template parts inserted into the editor now default toย contentOnlyย mode, prioritizing the editing of text and media without exposing the deeper blockBlockBlock is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. structure or style controls.
Pattern-level editing modes
At times a user will want to make design changes to a pattern, and this works differently depending on the type of pattern.
Unsynced โ A user can click an โEdit patternโ button or double click the body of a pattern, and a spotlight mode engages. In this mode users have full editing capabilitiescapabilityAย capabilityย is permission to perform one or more types of task. Checking if a user has a capability is performed by the current_user_can function. Each user of a WordPress site might have some permissions but not others, depending on theirย role. For example, users who have the Author role usually have permission to edit their own posts (the โedit_postsโ capability), but not permission to edit other usersโ posts (the โedit_others_postsโ capability)..
Synced (synced patterns / template parts) โ Users can click the โEdit originalโ button and are taken into an isolated editor when they can make any changes to the underlying pattern. The editor headerHeaderThe header of your site is typically the first thing people will experience. The masthead or header art located across the top of your page is part of the look and feel of your website. It can influence a visitorโs opinion about your content and you/ your organizationโs brand. It may also look different on different screen sizes. provides navigation back to the originating document. Changes to synced patterns apply globally.
What developers need to do
Block authors
If your block is nested in aย contentOnlyย pattern and should be editable, ensure attributes that represent a blockโs content haveย "role": "content"ย set inย block.json. This is unchanged from WordPress 6.7, but is now more important asย contentOnlyย mode is applied more broadly by default.
Blocks without anyย "role": "content"ย attributes will be hidden from List View and non-selectable inside aย contentOnlyย container.
At times a block may not have an appropriate attribute to which to applyย "role": "content". Aย "contentRole": trueย property can be added to the block supports declaration, and this has the same effect asย "role": "content".
{
"supports": {
"contentRole": true
}
}
Developers should preferย "role": "content"ย where possible.
Parent / child contentOnly blocks
Many blocks are considered โcontentโ, but consist of both parent and child block types. Some examples of CoreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress. blocks are:
List and List Item
Gallery and Image
Buttons and Button
Whenever both a parent and child block have aย "role": "content"ย attribute orย "contentRole": trueย block supports,ย contentOnlyย mode allows insertion of child blocks. This behavior has been present since WordPress 6.9, but is now more prominent.
Block developers can take advantage of this behavior.
List View block support
New for WordPress 7.0, block developers can add aย "listView": trueย block supports declaration. This adds a List View tab to the block inspector with a dedicated List View UIUIUser interface for the block that allows users to easily rearrange and add inner blocks. This List View is also displayed in Patterns and is recommended for any block that acts as a container for a list of child blocks.
{
"supports": {
"listView": true
}
}
Theme / pattern authors
Patterns that previously relied on unrestricted editing of their inner blocks will now be presented to users inย contentOnlyย mode by default. Review your registered patterns and consider:
Testing that the content users are expected to change is accessible inย contentOnlyย mode.
Auditing patterns containing Buttons, List, Social Icons, and Navigation blocks specifically โ these have had targetedย contentOnlyย improvements and may behave differently than before.
Restrict the allowed blocks if users shouldnโt be able to insert blocks in a specific area of a pattern. If assembling a pattern in a block editor, this can be done using the โManage allowed blocksโ feature in the Advanced section of the block inspector for any blocks that haveย "allowedBlocks": trueย block support. Through code, theย "allowedBlocks":[]ย attribute can be added to prevent insertion of inner blocks.
Site admins
A new block editor setting,ย disableContentOnlyForUnsyncedPatterns, allows opting out ofย contentOnlyย mode for unsynced patterns. Via PHPPHPThe web scripting language in which WordPress is primarily architected. WordPress requires PHP 7.4 or higher, use theย block_editor_settings_allย filterFilterFilters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output.:
Or via JavaScriptJavaScriptJavaScript or JS is an object-oriented computer programming language commonly used to create interactive effects within web browsers. WordPress makes extensive use of JS for a better user experience. While PHP is executed on the server, JS executes within a userโs browser.
https://www.javascript.com:
Whenย disableContentOnlyForUnsyncedPatternsย isย true, blocks withย patternNameย metadata are no longer treated as section blocks and their children are not placed intoย contentOnlyย editing mode. Template parts and synced patterns (core/block) are unaffected โ they remain section blocks regardless of this setting.
PluginPluginA plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party. developers
If your plugin interacts with pattern editing state โ toolbar controls, sidebarSidebarA sidebar in WordPress is referred to a widget-ready area used by WordPress themes to display information that is not a part of the main content. It is not always a vertical column on the side. It can be a horizontal rectangle below or above the content area, footer, header, or any where in the theme. panels, List View visibility, or entity navigation โ test against the new editing modes. Theย contentOnlyย state is now applied more broadly, and UI components that assume full block access inside patterns may not render as expected.
Props to @talldanwpย and @andrewserong for helping to write this dev notedev noteEach important change in WordPress Core is documented in a developers note, (usually called dev note). Good dev notes generally include a description of the change, the decision that led to this change, and a description of how developers are supposed to work with that change. Dev notes are published on Make/Core blog during the beta phase of WordPress release cycle. Publishing dev notes is particularly important when plugin/theme authors and WordPress developers need to be aware of those changes.In general, all dev notes are compiled into a Field Guide at the beginning of the release candidate phase..