-
Notifications
You must be signed in to change notification settings - Fork 3.3k
fix: add wp_supports_ai() and related constant + filter
#11149
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: trunk
Are you sure you want to change the base?
Changes from all commits
7ff6888
26d6c92
3aa0aae
941cc8b
78b010b
a5cef8e
98b881f
e47bedb
3ee6aaa
d4b8da5
a2d738f
95a827a
b3f04fd
f7f754d
5a06aea
2b05524
ffc7e32
414588a
d0b4a03
007b572
bb965aa
eda3323
e0719a0
e8387df
bd314e7
9773705
069e6d4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -9,6 +9,29 @@ | |||||||||
|
|
||||||||||
| use WordPress\AiClient\AiClient; | ||||||||||
|
|
||||||||||
| /** | ||||||||||
| * Returns whether AI features are supported in the current environment. | ||||||||||
| * | ||||||||||
| * @since 7.0.0 | ||||||||||
| * | ||||||||||
| * @return bool Whether AI features are supported. | ||||||||||
| */ | ||||||||||
| function wp_supports_ai(): bool { | ||||||||||
| // Constant check gives a hard short-circuit for environments that cannot be overridden with a filter, such as wp-config.php settings or hosting provider configurations. | ||||||||||
| if ( defined( 'WP_AI_SUPPORT' ) && ! WP_AI_SUPPORT ) { | ||||||||||
| return false; | ||||||||||
| } | ||||||||||
|
Comment on lines
+21
to
+23
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with this, and it's established in WordPress. Relying on constants without allowing to filter them is problematic for several reasons, including testing. We shouldn't avoid this pattern because we're scared of some malicious actor enabling AI again via filter. If you have a malicious actor that can do that, you have worse problems.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, but weaponization of AI swarms is more than just about immediately API key bills, when you think about the number of abandoned WP sites and our responsibility . And there are dozens of constants in core that have no matching filter.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Regarding testing, that's the reason the function has a filter. So we just not getting coverage of a single early return. (Conversely, there's no reason to add a constant at all if it's just to serve a default. You can accomplish the same thing with a different-priority hook callback) Will also repeat the argument that plugins shouldn't be able to override user choice on this, now that we're sub thread and not top-level any more. |
||||||||||
|
|
||||||||||
| /** | ||||||||||
| * Filters whether the current request should use AI. | ||||||||||
| * | ||||||||||
| * @since 7.0.0 | ||||||||||
| * | ||||||||||
| * @param bool $is_enabled Whether the current request should use AI. Default true. | ||||||||||
| */ | ||||||||||
| return (bool) apply_filters( 'wp_supports_ai', true ); | ||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
| } | ||||||||||
|
|
||||||||||
| /** | ||||||||||
| * Creates a new AI prompt builder using the default provider registry. | ||||||||||
| * | ||||||||||
|
|
||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -332,6 +332,53 @@ function _wp_connectors_resolve_ai_provider_logo_url( string $path ): ?string { | |
| function _wp_connectors_init(): void { | ||
| $registry = new WP_Connector_Registry(); | ||
| WP_Connector_Registry::set_instance( $registry ); | ||
|
|
||
| // Only register default AI providers if AI support is enabled. | ||
| if ( wp_supports_ai() ) { | ||
| _wp_connectors_register_default_ai_providers( $registry ); | ||
| } | ||
|
Comment on lines
+336
to
+339
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added this even though there's a short-circuit on the registry because this all seems to be hooked onto |
||
|
|
||
| /** | ||
| * Fires when the connector registry is ready for plugins to register connectors. | ||
| * | ||
| * Built-in connectors and any AI providers auto-discovered from the WP AI Client | ||
| * registry have already been registered at this point and cannot be unhooked. | ||
| * | ||
| * AI provider plugins that register with the WP AI Client do not need to use | ||
| * this action — their connectors are created automatically. This action is | ||
| * primarily for registering non-AI-provider connectors or overriding metadata | ||
| * on existing connectors. | ||
| * | ||
| * Use `$registry->register()` within this action to add new connectors. | ||
| * To override an existing connector, unregister it first, then re-register | ||
| * with updated data. | ||
| * | ||
| * Example — overriding metadata on an auto-discovered connector: | ||
| * | ||
| * add_action( 'wp_connectors_init', function ( WP_Connector_Registry $registry ) { | ||
| * if ( $registry->is_registered( 'openai' ) ) { | ||
| * $connector = $registry->unregister( 'openai' ); | ||
| * $connector['description'] = __( 'Custom description for OpenAI.', 'my-plugin' ); | ||
| * $registry->register( 'openai', $connector ); | ||
| * } | ||
| * } ); | ||
| * | ||
| * @since 7.0.0 | ||
| * | ||
| * @param WP_Connector_Registry $registry Connector registry instance. | ||
| */ | ||
| do_action( 'wp_connectors_init', $registry ); | ||
| } | ||
|
|
||
| /** | ||
| * Registers connectors for the built-in AI providers. | ||
| * | ||
| * @since 7.0.0 | ||
| * @access private | ||
| * | ||
| * @param WP_Connector_Registry $registry The connector registry instance. | ||
| */ | ||
| function _wp_connectors_register_default_ai_providers( WP_Connector_Registry $registry ): void { | ||
| // Built-in connectors. | ||
| $defaults = array( | ||
| 'anthropic' => array( | ||
|
|
@@ -430,37 +477,6 @@ function _wp_connectors_init(): void { | |
| foreach ( $defaults as $id => $args ) { | ||
| $registry->register( $id, $args ); | ||
| } | ||
|
|
||
| /** | ||
| * Fires when the connector registry is ready for plugins to register connectors. | ||
| * | ||
| * Built-in connectors and any AI providers auto-discovered from the WP AI Client | ||
| * registry have already been registered at this point and cannot be unhooked. | ||
| * | ||
| * AI provider plugins that register with the WP AI Client do not need to use | ||
| * this action — their connectors are created automatically. This action is | ||
| * primarily for registering non-AI-provider connectors or overriding metadata | ||
| * on existing connectors. | ||
| * | ||
| * Use `$registry->register()` within this action to add new connectors. | ||
| * To override an existing connector, unregister it first, then re-register | ||
| * with updated data. | ||
| * | ||
| * Example — overriding metadata on an auto-discovered connector: | ||
| * | ||
| * add_action( 'wp_connectors_init', function ( WP_Connector_Registry $registry ) { | ||
| * if ( $registry->is_registered( 'openai' ) ) { | ||
| * $connector = $registry->unregister( 'openai' ); | ||
| * $connector['description'] = __( 'Custom description for OpenAI.', 'my-plugin' ); | ||
| * $registry->register( 'openai', $connector ); | ||
| * } | ||
| * } ); | ||
| * | ||
| * @since 7.0.0 | ||
| * | ||
| * @param WP_Connector_Registry $registry Connector registry instance. | ||
| */ | ||
| do_action( 'wp_connectors_init', $registry ); | ||
| } | ||
|
|
||
| /** | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| <?php | ||
| /** | ||
| * Tests for wp_supports_ai(). | ||
| * | ||
| * @group ai-client | ||
| * @covers ::wp_supports_ai | ||
| */ | ||
|
|
||
| class Tests_WP_Supports_AI extends WP_UnitTestCase { | ||
| /** | ||
| * Test that wp_supports_ai() defaults to true. | ||
| * | ||
| * @ticket 64591 | ||
| */ | ||
| public function test_defaults_to_true(): void { | ||
| $this->assertTrue( wp_supports_ai() ); | ||
| } | ||
|
|
||
| /** | ||
| * Tests that the wp_supports_ai filter can disable/enable AI features. | ||
| */ | ||
| public function test_filter_can_disable_ai_features(): void { | ||
| add_filter( 'wp_supports_ai', '__return_false' ); | ||
| $this->assertFalse( wp_supports_ai() ); | ||
|
|
||
| // Try a later filter to re-enable AI and confirm that it works. | ||
| add_filter( 'wp_supports_ai', '__return_true' ); | ||
| $this->assertTrue( wp_supports_ai() ); | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.