Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/wp-includes/ai-client.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
*/

use WordPress\AiClient\AiClient;
use WordPress\AiClient\Messages\DTO\Message;
use WordPress\AiClient\Messages\DTO\MessagePart;

/**
* Returns whether AI features are supported in the current environment.
Expand Down Expand Up @@ -55,6 +57,6 @@ function wp_supports_ai(): bool {
* conversations. Default null.
* @return WP_AI_Client_Prompt_Builder The prompt builder instance.
*/
function wp_ai_client_prompt( $prompt = null ) {
function wp_ai_client_prompt( $prompt = null ): WP_AI_Client_Prompt_Builder {
return new WP_AI_Client_Prompt_Builder( AiClient::defaultRegistry(), $prompt );
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public function clear(): bool {
* @param mixed $default_value Default value to return for keys that do not exist.
* @return array<string, mixed> A list of key => value pairs.
*/
public function getMultiple( $keys, $default_value = null ) {
public function getMultiple( $keys, $default_value = null ): array {
/**
* Keys array.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,15 @@ class WP_AI_Client_HTTP_Client implements ClientInterface, ClientWithOptionsInte
* Response factory instance.
*
* @since 7.0.0
* @var ResponseFactoryInterface
*/
private $response_factory;
private ResponseFactoryInterface $response_factory;

/**
* Stream factory instance.
*
* @since 7.0.0
* @var StreamFactoryInterface
*/
private $stream_factory;
private StreamFactoryInterface $stream_factory;

/**
* Constructor.
Expand Down
22 changes: 20 additions & 2 deletions src/wp-includes/ai-client/class-wp-ai-client-prompt-builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -190,14 +190,32 @@ public function __construct( ProviderRegistry $registry, $prompt = null ) {
$this->error = $this->exception_to_wp_error( $e );
}

$default_timeout = 30.0;

/**
* Filters the default request timeout in seconds for AI Client HTTP requests.
*
* @since 7.0.0
*
* @param int $default_timeout The default timeout in seconds.
* @param float|null $default_timeout The default timeout in seconds, or null to disable the timeout.
* If not null, must be greater than or equal to zero.
*/
$default_timeout = (int) apply_filters( 'wp_ai_client_default_request_timeout', 30 );
$timeout = apply_filters( 'wp_ai_client_default_request_timeout', $default_timeout );
if ( is_numeric( $timeout ) && (float) $timeout >= 0.0 ) {
$default_timeout = (float) $timeout;
} elseif ( null === $timeout ) {
$default_timeout = null;
} else {
_doing_it_wrong(
__METHOD__,
sprintf(
/* translators: %s: wp_ai_client_default_request_timeout */
__( 'The %s filter must return a non-negative number or null.' ),
'<code>wp_ai_client_default_request_timeout</code>'
),
'7.0.0'
);
}

$this->builder->usingRequestOptions(
RequestOptions::fromArray(
Expand Down
69 changes: 65 additions & 4 deletions tests/phpunit/tests/ai-client/wpAiClientPromptBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -192,15 +192,16 @@ public function test_constructor_sets_default_request_timeout() {
}

/**
* Test that the constructor allows overriding the default request timeout.
* Test that the constructor allows overriding the default request timeout with a higher value.
*
* @ticket 64591
* @ticket 65094
*/
public function test_constructor_allows_overriding_request_timeout() {
public function test_constructor_allows_overriding_request_timeout_with_higher_value() {
add_filter(
'wp_ai_client_default_request_timeout',
static function () {
return 45;
return 45.5;
}
);

Expand All @@ -210,7 +211,67 @@ static function () {
$request_options = $this->get_wrapped_prompt_builder_property_value( $builder, 'requestOptions' );

$this->assertInstanceOf( RequestOptions::class, $request_options );
$this->assertEquals( 45, $request_options->getTimeout() );
$this->assertEquals( 45.5, $request_options->getTimeout() );
}

/**
* Test that the constructor allows overriding the default request timeout with null.
*
* @ticket 65094
*/
public function test_constructor_allows_overriding_request_timeout_with_null() {
add_filter( 'wp_ai_client_default_request_timeout', '__return_null' );

$builder = new WP_AI_Client_Prompt_Builder( AiClient::defaultRegistry() );

/** @var RequestOptions $request_options */
$request_options = $this->get_wrapped_prompt_builder_property_value( $builder, 'requestOptions' );

$this->assertInstanceOf( RequestOptions::class, $request_options );
$this->assertNull( $request_options->getTimeout() );
}

/**
* Test that the constructor disallows overriding the default request timeout with a invalid value.
*
* @ticket 65094
*
* @expectedIncorrectUsage WP_AI_Client_Prompt_Builder::__construct
*/
public function test_constructor_disallows_overriding_with_negative_request_timeout() {
add_filter(
'wp_ai_client_default_request_timeout',
static function () {
return -1;
}
);

$builder = new WP_AI_Client_Prompt_Builder( AiClient::defaultRegistry() );

/** @var RequestOptions $request_options */
$request_options = $this->get_wrapped_prompt_builder_property_value( $builder, 'requestOptions' );

$this->assertInstanceOf( RequestOptions::class, $request_options );
$this->assertEquals( 30, $request_options->getTimeout() );
}

/**
* Test that the constructor disallows overriding the default request timeout with a invalid value.
*
* @ticket 65094
*
* @expectedIncorrectUsage WP_AI_Client_Prompt_Builder::__construct
*/
public function test_constructor_disallows_overriding_with_bad_request_timeout_type() {
add_filter( 'wp_ai_client_default_request_timeout', '__return_empty_array' );

$builder = new WP_AI_Client_Prompt_Builder( AiClient::defaultRegistry() );

/** @var RequestOptions $request_options */
$request_options = $this->get_wrapped_prompt_builder_property_value( $builder, 'requestOptions' );

$this->assertInstanceOf( RequestOptions::class, $request_options );
$this->assertEquals( 30, $request_options->getTimeout() );
}

/**
Expand Down
Loading