Skip to content

Commit f56b7f7

Browse files
committed
AI Client: Skip non-ability function calls in execute_abilities()
`WP_AI_Client_Ability_Function_Resolver::execute_abilities()` should only respond to function calls that are ability calls. Previously, non-ability tool calls were passed to `execute_ability()` and received an `invalid_ability_call` response, preventing other tool handlers from processing them. This updates `execute_abilities()` to mirror `has_ability_calls()` by checking `is_ability_call()` before executing, and adds regression coverage for mixed ability and non-ability calls. Props khokansardar, jigar-bhanushali. Fixes #65504. git-svn-id: https://develop.svn.wordpress.org/trunk@62555 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 3cbba16 commit f56b7f7

2 files changed

Lines changed: 49 additions & 1 deletion

File tree

src/wp-includes/ai-client/class-wp-ai-client-ability-function-resolver.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ public function execute_abilities( Message $message ): Message {
190190
foreach ( $message->getParts() as $part ) {
191191
if ( $part->getType()->isFunctionCall() ) {
192192
$function_call = $part->getFunctionCall();
193-
if ( $function_call instanceof FunctionCall ) {
193+
if ( $function_call instanceof FunctionCall && $this->is_ability_call( $function_call ) ) {
194194
$function_response = $this->execute_ability( $function_call );
195195
$response_parts[] = new MessagePart( $function_response );
196196
}

tests/phpunit/tests/ai-client/wpAiClientAbilityFunctionResolver.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,54 @@ public function test_execute_abilities_with_mixed_content() {
666666
$this->assertInstanceOf( FunctionResponse::class, $response );
667667
}
668668

669+
/**
670+
* Test execute_abilities ignores non-ability function calls.
671+
*
672+
* A message may contain function calls for tools handled elsewhere (not
673+
* prefixed with `wpab__`). Those must be left untouched rather than answered
674+
* with a spurious `invalid_ability_call` error response, matching the parts
675+
* that has_ability_calls() reports.
676+
*
677+
* @ticket 65504
678+
*/
679+
public function test_execute_abilities_ignores_non_ability_function_calls() {
680+
$resolver = new WP_AI_Client_Ability_Function_Resolver( 'wpaiclienttests/simple' );
681+
682+
$ability_call = new FunctionCall(
683+
'call-ability',
684+
'wpab__wpaiclienttests__simple',
685+
array()
686+
);
687+
688+
$other_call = new FunctionCall(
689+
'call-other',
690+
'some_other_tool',
691+
array()
692+
);
693+
694+
$message = new ModelMessage(
695+
array(
696+
new MessagePart( $ability_call ),
697+
new MessagePart( $other_call ),
698+
)
699+
);
700+
701+
$result = $resolver->execute_abilities( $message );
702+
703+
$this->assertInstanceOf( UserMessage::class, $result );
704+
$parts = $result->getParts();
705+
// Only the ability call should produce a response; the other tool is left alone.
706+
$this->assertCount( 1, $parts );
707+
708+
$response = $parts[0]->getFunctionResponse();
709+
$this->assertInstanceOf( FunctionResponse::class, $response );
710+
$this->assertSame( 'wpab__wpaiclienttests__simple', $response->getName() );
711+
$data = $response->getResponse();
712+
$this->assertArrayNotHasKey( 'code', $data );
713+
$this->assertArrayHasKey( 'success', $data );
714+
$this->assertTrue( $data['success'] );
715+
}
716+
669717
/**
670718
* Test execute_abilities with ability that has parameters.
671719
*

0 commit comments

Comments
 (0)