Skip to content
Closed
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
17 changes: 17 additions & 0 deletions src/Runtime/class-wp-agent-provider-turn-result.php
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,16 @@ private static function extract_json_tool_calls( string $text ): array {
}
}

// Some providers emit a bare JSON tool-call object as the entire message
// with no fence or tag wrapper. Treat a trimmed text that is a single JSON
// object as a payload candidate so those calls are not dropped.
if ( empty( $payloads ) ) {
$trimmed = trim( $text );
if ( '' !== $trimmed && '{' === $trimmed[0] && '}' === substr( $trimmed, -1 ) ) {
$payloads[] = $trimmed;
}
}

return self::tool_calls_from_json_payloads( $payloads, 'json-tool-call' );
}

Expand Down Expand Up @@ -363,6 +373,13 @@ private static function tool_calls_from_json_payloads( array $payloads, string $
continue;
}

// Some providers wrap the call in a `function_call` object, often
// tagged with `{"type":"function_call", ...}`. Use that inner object
// as the call source so its name/arguments are read correctly.
if ( isset( $call['function_call'] ) && is_array( $call['function_call'] ) ) {
$call = $call['function_call'];
}

$function = isset( $call['function'] ) && is_array( $call['function'] ) ? $call['function'] : array();
$raw_name = $function['name'] ?? ( $call['name'] ?? '' );
$name = is_string( $raw_name ) ? self::clean_tool_name( $raw_name ) : '';
Expand Down
8 changes: 8 additions & 0 deletions tests/provider-turn-adapter-smoke.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,14 @@ public function getText(): string {
agents_api_smoke_assert_equals( 'json-1', $json_turn['tool_calls'][0]['id'] ?? '', 'fenced JSON fallback preserves id', $failures, $passes );
agents_api_smoke_assert_equals( 'json', $json_turn['tool_calls'][0]['parameters']['query'] ?? '', 'fenced JSON fallback decodes function arguments', $failures, $passes );

$function_call_turn = AgentsAPI\AI\WP_Agent_Provider_Turn_Result::normalize(
array(
'content' => '{"type":"function_call","function_call":{"name":"client/lookup","arguments":{"query":"wrapped"}}}',
)
);
agents_api_smoke_assert_equals( 'client/lookup', $function_call_turn['tool_calls'][0]['name'] ?? '', 'function_call wrapper extracts tool name', $failures, $passes );
agents_api_smoke_assert_equals( 'wrapped', $function_call_turn['tool_calls'][0]['parameters']['query'] ?? '', 'function_call wrapper decodes object arguments', $failures, $passes );

$tag_turn = AgentsAPI\AI\WP_Agent_Provider_Turn_Result::normalize(
array(
'content' => '<tool_call name="client/lookup">{"query":"tag"}</tool_call>',
Expand Down
Loading