Skip to content

Commit 5d6cc65

Browse files
authored
fix(anthropic): provider tool use to response (#970)
1 parent efa3276 commit 5d6cc65

7 files changed

Lines changed: 76 additions & 4 deletions

File tree

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Prism\Prism\Providers\Anthropic\Concerns;
6+
7+
use Prism\Prism\ValueObjects\ProviderToolCall;
8+
9+
trait ExtractsProviderToolCalls
10+
{
11+
/**
12+
* @param array<string, mixed> $data
13+
* @return array<int, ProviderToolCall>
14+
*/
15+
protected function extractProviderToolCalls(array $data): array
16+
{
17+
$providerToolCalls = [];
18+
$contents = data_get($data, 'content', []);
19+
20+
foreach ($contents as $content) {
21+
$type = data_get($content, 'type', '');
22+
23+
if ($type === 'server_tool_use') {
24+
$providerToolCalls[] = new ProviderToolCall(
25+
id: data_get($content, 'id', ''),
26+
type: data_get($content, 'name', ''),
27+
status: 'completed',
28+
data: $content,
29+
);
30+
}
31+
32+
if (str_ends_with((string) $type, '_tool_result')) {
33+
$providerToolCalls[] = new ProviderToolCall(
34+
id: data_get($content, 'tool_use_id', ''),
35+
type: $type,
36+
status: 'result_received',
37+
data: $content,
38+
);
39+
}
40+
}
41+
42+
return $providerToolCalls;
43+
}
44+
}

src/Providers/Anthropic/Handlers/Structured.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use Prism\Prism\Enums\FinishReason;
1414
use Prism\Prism\Exceptions\PrismException;
1515
use Prism\Prism\Providers\Anthropic\Concerns\ExtractsCitations;
16+
use Prism\Prism\Providers\Anthropic\Concerns\ExtractsProviderToolCalls;
1617
use Prism\Prism\Providers\Anthropic\Concerns\ExtractsText;
1718
use Prism\Prism\Providers\Anthropic\Concerns\ExtractsThinking;
1819
use Prism\Prism\Providers\Anthropic\Concerns\HandlesHttpRequests;
@@ -38,7 +39,7 @@
3839

3940
class Structured
4041
{
41-
use CallsTools, ExtractsCitations, ExtractsText, ExtractsThinking, HandlesHttpRequests, ProcessesRateLimits;
42+
use CallsTools, ExtractsCitations, ExtractsProviderToolCalls, ExtractsText, ExtractsThinking, HandlesHttpRequests, ProcessesRateLimits;
4243

4344
protected ResponseBuilder $responseBuilder;
4445

@@ -278,6 +279,7 @@ protected function addStep(array $toolCalls, Response $tempResponse, array $tool
278279
additionalContent: $tempResponse->additionalContent,
279280
structured: $isStructuredStep ? ($tempResponse->structured ?? []) : [],
280281
toolCalls: $toolCalls,
282+
providerToolCalls: $this->extractProviderToolCalls($data),
281283
toolResults: $toolResults,
282284
raw: $data,
283285
));

src/Providers/Anthropic/Handlers/Text.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use Prism\Prism\Enums\FinishReason;
1414
use Prism\Prism\Exceptions\PrismException;
1515
use Prism\Prism\Providers\Anthropic\Concerns\ExtractsCitations;
16+
use Prism\Prism\Providers\Anthropic\Concerns\ExtractsProviderToolCalls;
1617
use Prism\Prism\Providers\Anthropic\Concerns\ExtractsText;
1718
use Prism\Prism\Providers\Anthropic\Concerns\ExtractsThinking;
1819
use Prism\Prism\Providers\Anthropic\Concerns\HandlesHttpRequests;
@@ -35,7 +36,7 @@
3536

3637
class Text
3738
{
38-
use CallsTools, ExtractsCitations, ExtractsText, ExtractsThinking, HandlesHttpRequests, ProcessesRateLimits;
39+
use CallsTools, ExtractsCitations, ExtractsProviderToolCalls, ExtractsText, ExtractsThinking, HandlesHttpRequests, ProcessesRateLimits;
3940

4041
protected Response $tempResponse;
4142

@@ -135,7 +136,7 @@ protected function addStep(array $toolResults = []): void
135136
finishReason: $this->tempResponse->finishReason,
136137
toolCalls: $this->tempResponse->toolCalls,
137138
toolResults: $toolResults,
138-
providerToolCalls: [],
139+
providerToolCalls: $this->extractProviderToolCalls($data),
139140
usage: $this->tempResponse->usage,
140141
meta: $this->tempResponse->meta,
141142
messages: $this->request->messages(),

src/Structured/ResponseBuilder.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Illuminate\Support\Collection;
88
use Prism\Prism\Enums\FinishReason;
99
use Prism\Prism\Exceptions\PrismStructuredDecodingException;
10+
use Prism\Prism\ValueObjects\ProviderToolCall;
1011
use Prism\Prism\ValueObjects\ToolCall;
1112
use Prism\Prism\ValueObjects\ToolResult;
1213
use Prism\Prism\ValueObjects\Usage;
@@ -41,6 +42,7 @@ public function toResponse(): Response
4142
usage: $this->calculateTotalUsage(),
4243
meta: $finalStep->meta,
4344
toolCalls: $this->aggregateToolCalls(),
45+
providerToolCalls: $this->aggregateProviderToolCalls(),
4446
toolResults: $this->aggregateToolResults(),
4547
additionalContent: $finalStep->additionalContent,
4648
raw: $finalStep->raw,
@@ -94,6 +96,17 @@ protected function aggregateToolCalls(): array
9496
->all();
9597
}
9698

99+
/**
100+
* @return array<int, ProviderToolCall>
101+
*/
102+
protected function aggregateProviderToolCalls(): array
103+
{
104+
return $this->steps
105+
->flatMap(fn (Step $step): array => $step->providerToolCalls)
106+
->values()
107+
->all();
108+
}
109+
97110
/**
98111
* @return array<int, ToolResult>
99112
*/

tests/Providers/Anthropic/AnthropicTextTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,11 @@
146146
->asText();
147147

148148
expect($response->text)->toContain('4/3');
149+
150+
$finalStep = $response->steps->last();
151+
expect($finalStep->providerToolCalls)->not->toBeEmpty();
152+
expect($finalStep->providerToolCalls[0]->type)->toBe('code_execution');
153+
expect($finalStep->providerToolCalls[0]->status)->toBe('completed');
149154
});
150155

151156
it('handles a provider tool with a user defined tool', function (): void {

tests/Providers/Anthropic/StructuredWithToolsTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,10 @@
400400
->and($response->structured)->toHaveKeys(['summary', 'recommendation'])
401401
->and($response->structured['summary'])->toBeString()
402402
->and($response->structured['recommendation'])->toBeString();
403+
404+
expect($response->providerToolCalls)->not->toBeEmpty();
405+
expect($response->providerToolCalls[0]->type)->toBe('web_search');
406+
expect($response->providerToolCalls[0]->status)->toBe('completed');
403407
});
404408

405409
it('can generate structured output with provider tools using tool calling mode', function (): void {
@@ -427,6 +431,10 @@
427431
->and($response->structured)->toHaveKeys(['summary', 'recommendation'])
428432
->and($response->structured['summary'])->toBeString()
429433
->and($response->structured['recommendation'])->toBeString();
434+
435+
expect($response->providerToolCalls)->not->toBeEmpty();
436+
expect($response->providerToolCalls[0]->type)->toBe('web_search');
437+
expect($response->providerToolCalls[0]->status)->toBe('completed');
430438
});
431439

432440
it('includes provider tools in native output format payload', function (): void {

tests/Providers/Perplexity/StreamTest.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030

3131
if ($event instanceof TextDeltaEvent) {
3232
$text .= $event->delta;
33-
echo $text;
3433
}
3534
}
3635

0 commit comments

Comments
 (0)