Skip to content

Commit 266e13b

Browse files
authored
feat(OpenAI): Add 'tool_search' functionality. (#772)
* feat(OpenAI): Add 'tool_search' functionality * test(OpenAI): Add 'tool_search' functionality * fix(OpenAI): chore add custom_tool * fix(OpenAI): chore add namespace * chore(OpenAI): fix issue with phpstan ignores * chore(OpenAI): add typing for tools * chore(OpenAI): throw on unknown * chore(OpenAI): cleaner message
1 parent 02109a7 commit 266e13b

21 files changed

Lines changed: 962 additions & 16 deletions
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace OpenAI\Actions\Responses;
6+
7+
use OpenAI\Responses\Responses\Tool\CustomToolInputs\GrammarInput;
8+
use OpenAI\Responses\Responses\Tool\CustomToolInputs\TextInput;
9+
10+
/**
11+
* @phpstan-import-type TextInputType from TextInput
12+
* @phpstan-import-type GrammarInputType from GrammarInput
13+
*
14+
* @phpstan-type CustomToolInputTypes TextInputType|GrammarInputType
15+
* @phpstan-type CustomToolInputReturnType TextInput|GrammarInput
16+
*/
17+
final class CustomToolInputObjects
18+
{
19+
/**
20+
* @param CustomToolInputTypes $attributes
21+
*/
22+
public static function parse(array $attributes): TextInput|GrammarInput
23+
{
24+
return match ($attributes['type']) {
25+
'text' => TextInput::from($attributes),
26+
'grammar' => GrammarInput::from($attributes),
27+
};
28+
}
29+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace OpenAI\Actions\Responses;
6+
7+
use OpenAI\Responses\Responses\Tool\NamespaceTools\CustomTool;
8+
use OpenAI\Responses\Responses\Tool\NamespaceTools\FunctionTool;
9+
10+
/**
11+
* @phpstan-import-type FunctionToolType from FunctionTool
12+
* @phpstan-import-type CustomToolType from CustomTool
13+
*
14+
* @phpstan-type ResponseNamespaceToolObjectTypes array<int, FunctionToolType|CustomToolType>
15+
* @phpstan-type ResponseNamespaceToolObjectReturnType array<int, FunctionTool|CustomTool>
16+
*/
17+
final class NamespaceToolObjects
18+
{
19+
/**
20+
* @param ResponseNamespaceToolObjectTypes $toolItems
21+
* @return ResponseNamespaceToolObjectReturnType
22+
*/
23+
public static function parse(array $toolItems): array
24+
{
25+
return array_map(
26+
fn (array $tool): FunctionTool|CustomTool => match ($tool['type']) {
27+
'function' => FunctionTool::from($tool),
28+
'custom' => CustomTool::from($tool),
29+
},
30+
$toolItems,
31+
);
32+
}
33+
}

src/Actions/Responses/OutputObjects.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
use OpenAI\Responses\Responses\Output\OutputMcpListTools;
1717
use OpenAI\Responses\Responses\Output\OutputMessage;
1818
use OpenAI\Responses\Responses\Output\OutputReasoning;
19+
use OpenAI\Responses\Responses\Output\OutputToolSearchCall;
20+
use OpenAI\Responses\Responses\Output\OutputToolSearchOutput;
1921
use OpenAI\Responses\Responses\Output\OutputWebSearchToolCall;
2022

2123
/**
@@ -32,9 +34,11 @@
3234
* @phpstan-import-type OutputCodeInterpreterToolCallType from OutputCodeInterpreterToolCall
3335
* @phpstan-import-type OutputLocalShellCallType from OutputLocalShellCall
3436
* @phpstan-import-type OutputCustomToolCallType from OutputCustomToolCall
37+
* @phpstan-import-type OutputToolSearchCallType from OutputToolSearchCall
38+
* @phpstan-import-type OutputToolSearchOutputType from OutputToolSearchOutput
3539
*
36-
* @phpstan-type ResponseOutputObjectTypes array<int, OutputComputerToolCallType|OutputFileSearchToolCallType|OutputFunctionToolCallType|OutputMessageType|OutputReasoningType|OutputWebSearchToolCallType|OutputMcpListToolsType|OutputMcpApprovalRequestType|OutputMcpCallType|OutputImageGenerationToolCallType|OutputCodeInterpreterToolCallType|OutputLocalShellCallType|OutputCustomToolCallType>
37-
* @phpstan-type ResponseOutputObjectReturnType array<int, OutputMessage|OutputComputerToolCall|OutputFileSearchToolCall|OutputWebSearchToolCall|OutputFunctionToolCall|OutputReasoning|OutputMcpListTools|OutputMcpApprovalRequest|OutputMcpCall|OutputImageGenerationToolCall|OutputCodeInterpreterToolCall|OutputLocalShellCall|OutputCustomToolCall>
40+
* @phpstan-type ResponseOutputObjectTypes array<int, OutputComputerToolCallType|OutputFileSearchToolCallType|OutputFunctionToolCallType|OutputMessageType|OutputReasoningType|OutputWebSearchToolCallType|OutputMcpListToolsType|OutputMcpApprovalRequestType|OutputMcpCallType|OutputImageGenerationToolCallType|OutputCodeInterpreterToolCallType|OutputLocalShellCallType|OutputCustomToolCallType|OutputToolSearchCallType|OutputToolSearchOutputType>
41+
* @phpstan-type ResponseOutputObjectReturnType array<int, OutputMessage|OutputComputerToolCall|OutputFileSearchToolCall|OutputWebSearchToolCall|OutputFunctionToolCall|OutputReasoning|OutputMcpListTools|OutputMcpApprovalRequest|OutputMcpCall|OutputImageGenerationToolCall|OutputCodeInterpreterToolCall|OutputLocalShellCall|OutputCustomToolCall|OutputToolSearchCall|OutputToolSearchOutput>
3842
*/
3943
final class OutputObjects
4044
{
@@ -45,7 +49,7 @@ final class OutputObjects
4549
public static function parse(array $outputItems): array
4650
{
4751
return array_map(
48-
fn (array $item): OutputMessage|OutputComputerToolCall|OutputFileSearchToolCall|OutputWebSearchToolCall|OutputFunctionToolCall|OutputReasoning|OutputMcpListTools|OutputMcpApprovalRequest|OutputMcpCall|OutputImageGenerationToolCall|OutputCodeInterpreterToolCall|OutputLocalShellCall|OutputCustomToolCall => match ($item['type']) {
52+
fn (array $item): OutputMessage|OutputComputerToolCall|OutputFileSearchToolCall|OutputWebSearchToolCall|OutputFunctionToolCall|OutputReasoning|OutputMcpListTools|OutputMcpApprovalRequest|OutputMcpCall|OutputImageGenerationToolCall|OutputCodeInterpreterToolCall|OutputLocalShellCall|OutputCustomToolCall|OutputToolSearchCall|OutputToolSearchOutput => match ($item['type']) {
4953
'message' => OutputMessage::from($item),
5054
'file_search_call' => OutputFileSearchToolCall::from($item),
5155
'function_call' => OutputFunctionToolCall::from($item),
@@ -59,6 +63,9 @@ public static function parse(array $outputItems): array
5963
'code_interpreter_call' => OutputCodeInterpreterToolCall::from($item),
6064
'local_shell_call' => OutputLocalShellCall::from($item),
6165
'custom_tool_call' => OutputCustomToolCall::from($item),
66+
'tool_search_call' => OutputToolSearchCall::from($item),
67+
'tool_search_output' => OutputToolSearchOutput::from($item),
68+
default => throw new \UnexpectedValueException('Uh oh! We do not recognize this type. Please submit a bug to openai-php/client on GitHub!'),
6269
},
6370
$outputItems,
6471
);

src/Actions/Responses/ToolObjects.php

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,29 @@
66

77
use OpenAI\Responses\Responses\Tool\CodeInterpreterTool;
88
use OpenAI\Responses\Responses\Tool\ComputerUseTool;
9+
use OpenAI\Responses\Responses\Tool\CustomTool;
910
use OpenAI\Responses\Responses\Tool\FileSearchTool;
1011
use OpenAI\Responses\Responses\Tool\FunctionTool;
1112
use OpenAI\Responses\Responses\Tool\ImageGenerationTool;
13+
use OpenAI\Responses\Responses\Tool\NamespaceTool;
1214
use OpenAI\Responses\Responses\Tool\RemoteMcpTool;
15+
use OpenAI\Responses\Responses\Tool\ToolSearchTool;
1316
use OpenAI\Responses\Responses\Tool\WebSearchTool;
1417

1518
/**
19+
* @phpstan-import-type CodeInterpreterToolType from CodeInterpreterTool
1620
* @phpstan-import-type ComputerUseToolType from ComputerUseTool
21+
* @phpstan-import-type CustomToolType from CustomTool
1722
* @phpstan-import-type FileSearchToolType from FileSearchTool
23+
* @phpstan-import-type FunctionToolType from FunctionTool
1824
* @phpstan-import-type ImageGenerationToolType from ImageGenerationTool
25+
* @phpstan-import-type NamespaceToolType from NamespaceTool
1926
* @phpstan-import-type RemoteMcpToolType from RemoteMcpTool
20-
* @phpstan-import-type FunctionToolType from FunctionTool
27+
* @phpstan-import-type ToolSearchToolType from ToolSearchTool
2128
* @phpstan-import-type WebSearchToolType from WebSearchTool
22-
* @phpstan-import-type CodeInterpreterToolType from CodeInterpreterTool
2329
*
24-
* @phpstan-type ResponseToolObjectTypes array<int, ComputerUseToolType|FileSearchToolType|FunctionToolType|WebSearchToolType|ImageGenerationToolType|RemoteMcpToolType|CodeInterpreterToolType>
25-
* @phpstan-type ResponseToolObjectReturnType array<int, ComputerUseTool|FileSearchTool|FunctionTool|WebSearchTool|ImageGenerationTool|RemoteMcpTool|CodeInterpreterTool>
30+
* @phpstan-type ResponseToolObjectTypes array<int, CodeInterpreterToolType|ComputerUseToolType|CustomToolType|FileSearchToolType|FunctionToolType|ImageGenerationToolType|NamespaceToolType|RemoteMcpToolType|ToolSearchToolType|WebSearchToolType>
31+
* @phpstan-type ResponseToolObjectReturnType array<int, CodeInterpreterTool|ComputerUseTool|CustomTool|FileSearchTool|FunctionTool|ImageGenerationTool|NamespaceTool|RemoteMcpTool|ToolSearchTool|WebSearchTool>
2632
*/
2733
final class ToolObjects
2834
{
@@ -33,14 +39,17 @@ final class ToolObjects
3339
public static function parse(array $toolItems): array
3440
{
3541
return array_map(
36-
fn (array $tool): ComputerUseTool|FileSearchTool|FunctionTool|WebSearchTool|ImageGenerationTool|RemoteMcpTool|CodeInterpreterTool => match ($tool['type']) {
42+
fn (array $tool): CodeInterpreterTool|ComputerUseTool|CustomTool|FileSearchTool|FunctionTool|ImageGenerationTool|NamespaceTool|RemoteMcpTool|ToolSearchTool|WebSearchTool => match ($tool['type']) {
3743
'file_search' => FileSearchTool::from($tool),
3844
'web_search', 'web_search_preview', 'web_search_preview_2025_03_11' => WebSearchTool::from($tool),
3945
'function' => FunctionTool::from($tool),
4046
'computer_use_preview' => ComputerUseTool::from($tool),
4147
'image_generation' => ImageGenerationTool::from($tool),
4248
'mcp' => RemoteMcpTool::from($tool),
4349
'code_interpreter' => CodeInterpreterTool::from($tool),
50+
'tool_search' => ToolSearchTool::from($tool),
51+
'namespace' => NamespaceTool::from($tool),
52+
'custom' => CustomTool::from($tool),
4453
},
4554
$toolItems,
4655
);

src/Responses/Responses/CreateResponse.php

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,18 @@
2525
use OpenAI\Responses\Responses\Output\OutputMcpListTools;
2626
use OpenAI\Responses\Responses\Output\OutputMessage;
2727
use OpenAI\Responses\Responses\Output\OutputReasoning;
28+
use OpenAI\Responses\Responses\Output\OutputToolSearchCall;
29+
use OpenAI\Responses\Responses\Output\OutputToolSearchOutput;
2830
use OpenAI\Responses\Responses\Output\OutputWebSearchToolCall;
2931
use OpenAI\Responses\Responses\Tool\CodeInterpreterTool;
3032
use OpenAI\Responses\Responses\Tool\ComputerUseTool;
33+
use OpenAI\Responses\Responses\Tool\CustomTool;
3134
use OpenAI\Responses\Responses\Tool\FileSearchTool;
3235
use OpenAI\Responses\Responses\Tool\FunctionTool;
3336
use OpenAI\Responses\Responses\Tool\ImageGenerationTool;
37+
use OpenAI\Responses\Responses\Tool\NamespaceTool;
3438
use OpenAI\Responses\Responses\Tool\RemoteMcpTool;
39+
use OpenAI\Responses\Responses\Tool\ToolSearchTool;
3540
use OpenAI\Responses\Responses\Tool\WebSearchTool;
3641
use OpenAI\Responses\Responses\ToolChoice\FunctionToolChoice;
3742
use OpenAI\Responses\Responses\ToolChoice\HostedToolChoice;
@@ -47,6 +52,9 @@
4752
* @phpstan-import-type ResponseOutputObjectTypes from OutputObjects
4853
* @phpstan-import-type ResponseToolChoiceTypes from ToolChoiceObjects
4954
* @phpstan-import-type ResponseToolObjectTypes from ToolObjects
55+
* @phpstan-import-type ResponseOutputObjectReturnType from OutputObjects
56+
* @phpstan-import-type ResponseToolChoiceReturnType from ToolChoiceObjects
57+
* @phpstan-import-type ResponseToolObjectReturnType from ToolObjects
5058
*
5159
* @phpstan-type InstructionsType array<int, mixed>|string|null
5260
* @phpstan-type CreateResponseType array{id: string, background?: bool|null, object: 'response', created_at: int, status: 'completed'|'failed'|'in_progress'|'incomplete', error: ErrorType|null, incomplete_details?: IncompleteDetailsType|null, instructions: InstructionsType, max_output_tokens?: int|null, max_tool_calls?: int|null, model: string, output: ResponseOutputObjectTypes, output_text: string|null, parallel_tool_calls: bool, previous_response_id?: string|null, prompt: ReferencePromptObjectType|null, prompt_cache_key?: string|null, reasoning?: ReasoningType|null, safety_identifier?: string|null, service_tier?: string|null, store?: bool|null, temperature?: float|null, text?: ResponseFormatType|null, tool_choice: ResponseToolChoiceTypes, tools: ResponseToolObjectTypes, top_logprobs?: int|null, top_p?: float|null, truncation?: 'auto'|'disabled'|null, usage?: UsageType|null, user?: string|null, verbosity?: string|null, metadata?: array<string, string>|null}
@@ -67,8 +75,8 @@ final class CreateResponse implements ResponseContract, ResponseHasMetaInformati
6775
* @param 'response' $object
6876
* @param 'completed'|'failed'|'in_progress'|'incomplete' $status
6977
* @param array<int, mixed>|string|null $instructions
70-
* @param array<int, OutputMessage|OutputComputerToolCall|OutputFileSearchToolCall|OutputWebSearchToolCall|OutputFunctionToolCall|OutputReasoning|OutputMcpListTools|OutputMcpApprovalRequest|OutputMcpCall|OutputImageGenerationToolCall|OutputCodeInterpreterToolCall|OutputLocalShellCall|OutputCustomToolCall> $output
71-
* @param array<int, ComputerUseTool|FileSearchTool|FunctionTool|WebSearchTool|ImageGenerationTool|RemoteMcpTool|ImageGenerationTool|CodeInterpreterTool> $tools
78+
* @param ResponseOutputObjectReturnType $output
79+
* @param ResponseToolObjectReturnType $tools
7280
* @param 'auto'|'disabled'|null $truncation
7381
* @param array<string, string> $metadata
7482
*/
@@ -187,7 +195,7 @@ public function toArray(): array
187195
'metadata' => $this->metadata ?? [],
188196
'model' => $this->model,
189197
'output' => array_map(
190-
fn (OutputMessage|OutputComputerToolCall|OutputFileSearchToolCall|OutputWebSearchToolCall|OutputFunctionToolCall|OutputReasoning|OutputMcpListTools|OutputMcpApprovalRequest|OutputMcpCall|OutputImageGenerationToolCall|OutputCodeInterpreterToolCall|OutputLocalShellCall|OutputCustomToolCall $output): array => $output->toArray(),
198+
fn (OutputMessage|OutputComputerToolCall|OutputFileSearchToolCall|OutputWebSearchToolCall|OutputFunctionToolCall|OutputReasoning|OutputMcpListTools|OutputMcpApprovalRequest|OutputMcpCall|OutputImageGenerationToolCall|OutputCodeInterpreterToolCall|OutputLocalShellCall|OutputCustomToolCall|OutputToolSearchCall|OutputToolSearchOutput $output): array => $output->toArray(),
191199
$this->output
192200
),
193201
'parallel_tool_calls' => $this->parallelToolCalls,
@@ -204,7 +212,7 @@ public function toArray(): array
204212
? $this->toolChoice
205213
: $this->toolChoice->toArray(),
206214
'tools' => array_map(
207-
fn (ComputerUseTool|FileSearchTool|FunctionTool|WebSearchTool|ImageGenerationTool|RemoteMcpTool|CodeInterpreterTool $tool): array => $tool->toArray(),
215+
fn (ComputerUseTool|FileSearchTool|FunctionTool|WebSearchTool|ImageGenerationTool|RemoteMcpTool|CodeInterpreterTool|ToolSearchTool|NamespaceTool|CustomTool $tool): array => $tool->toArray(),
208216
$this->tools
209217
),
210218
'top_logprobs' => $this->topLogProbs,
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace OpenAI\Responses\Responses\Output;
6+
7+
use OpenAI\Contracts\ResponseContract;
8+
use OpenAI\Responses\Concerns\ArrayAccessible;
9+
use OpenAI\Testing\Responses\Concerns\Fakeable;
10+
11+
/**
12+
* @phpstan-type OutputToolSearchCallType array{id: string, arguments: mixed, call_id: ?string, execution: 'server'|'client', status: 'in_progress'|'completed'|'incomplete', type: 'tool_search_call', created_by?: ?string}
13+
*
14+
* @implements ResponseContract<OutputToolSearchCallType>
15+
*/
16+
final class OutputToolSearchCall implements ResponseContract
17+
{
18+
/**
19+
* @use ArrayAccessible<OutputToolSearchCallType>
20+
*/
21+
use ArrayAccessible;
22+
23+
use Fakeable;
24+
25+
/**
26+
* @param 'server'|'client' $execution
27+
* @param 'in_progress'|'completed'|'incomplete' $status
28+
* @param 'tool_search_call' $type
29+
*/
30+
private function __construct(
31+
public readonly string $id,
32+
public readonly mixed $arguments,
33+
public readonly ?string $callId,
34+
public readonly string $execution,
35+
public readonly string $status,
36+
public readonly string $type,
37+
public readonly ?string $createdBy,
38+
) {}
39+
40+
/**
41+
* @param OutputToolSearchCallType $attributes
42+
*/
43+
public static function from(array $attributes): self
44+
{
45+
return new self(
46+
id: $attributes['id'],
47+
arguments: $attributes['arguments'],
48+
callId: $attributes['call_id'] ?? null,
49+
execution: $attributes['execution'],
50+
status: $attributes['status'],
51+
type: $attributes['type'],
52+
createdBy: $attributes['created_by'] ?? null,
53+
);
54+
}
55+
56+
/**
57+
* {@inheritDoc}
58+
*/
59+
public function toArray(): array
60+
{
61+
return [
62+
'id' => $this->id,
63+
'arguments' => $this->arguments,
64+
'call_id' => $this->callId,
65+
'execution' => $this->execution,
66+
'status' => $this->status,
67+
'type' => $this->type,
68+
'created_by' => $this->createdBy,
69+
];
70+
}
71+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace OpenAI\Responses\Responses\Output;
6+
7+
use OpenAI\Actions\Responses\ToolObjects;
8+
use OpenAI\Contracts\ResponseContract;
9+
use OpenAI\Responses\Concerns\ArrayAccessible;
10+
use OpenAI\Responses\Responses\Tool\CodeInterpreterTool;
11+
use OpenAI\Responses\Responses\Tool\ComputerUseTool;
12+
use OpenAI\Responses\Responses\Tool\CustomTool;
13+
use OpenAI\Responses\Responses\Tool\FileSearchTool;
14+
use OpenAI\Responses\Responses\Tool\FunctionTool;
15+
use OpenAI\Responses\Responses\Tool\ImageGenerationTool;
16+
use OpenAI\Responses\Responses\Tool\NamespaceTool;
17+
use OpenAI\Responses\Responses\Tool\RemoteMcpTool;
18+
use OpenAI\Responses\Responses\Tool\ToolSearchTool;
19+
use OpenAI\Responses\Responses\Tool\WebSearchTool;
20+
use OpenAI\Testing\Responses\Concerns\Fakeable;
21+
22+
/**
23+
* @phpstan-import-type ResponseToolObjectTypes from ToolObjects
24+
* @phpstan-import-type ResponseToolObjectReturnType from ToolObjects
25+
*
26+
* @phpstan-type OutputToolSearchOutputType array{id: string, call_id: ?string, execution: 'server'|'client', status: 'in_progress'|'completed'|'incomplete', tools: ResponseToolObjectTypes, type: 'tool_search_output', created_by?: ?string}
27+
*
28+
* @implements ResponseContract<OutputToolSearchOutputType>
29+
*/
30+
final class OutputToolSearchOutput implements ResponseContract
31+
{
32+
/**
33+
* @use ArrayAccessible<OutputToolSearchOutputType>
34+
*/
35+
use ArrayAccessible;
36+
37+
use Fakeable;
38+
39+
/**
40+
* @param 'server'|'client' $execution
41+
* @param 'in_progress'|'completed'|'incomplete' $status
42+
* @param ResponseToolObjectReturnType $tools
43+
* @param 'tool_search_output' $type
44+
*/
45+
private function __construct(
46+
public readonly string $id,
47+
public readonly ?string $callId,
48+
public readonly string $execution,
49+
public readonly string $status,
50+
public readonly array $tools,
51+
public readonly string $type,
52+
public readonly ?string $createdBy,
53+
) {}
54+
55+
/**
56+
* @param OutputToolSearchOutputType $attributes
57+
*/
58+
public static function from(array $attributes): self
59+
{
60+
return new self(
61+
id: $attributes['id'],
62+
callId: $attributes['call_id'] ?? null,
63+
execution: $attributes['execution'],
64+
status: $attributes['status'],
65+
tools: ToolObjects::parse($attributes['tools']),
66+
type: $attributes['type'],
67+
createdBy: $attributes['created_by'] ?? null,
68+
);
69+
}
70+
71+
/**
72+
* {@inheritDoc}
73+
*/
74+
public function toArray(): array
75+
{
76+
return [
77+
'id' => $this->id,
78+
'call_id' => $this->callId,
79+
'execution' => $this->execution,
80+
'status' => $this->status,
81+
'tools' => array_map(
82+
fn (CodeInterpreterTool|ComputerUseTool|CustomTool|FileSearchTool|FunctionTool|ImageGenerationTool|NamespaceTool|RemoteMcpTool|ToolSearchTool|WebSearchTool $tool): array => $tool->toArray(),
83+
$this->tools,
84+
),
85+
'type' => $this->type,
86+
'created_by' => $this->createdBy,
87+
];
88+
}
89+
}

0 commit comments

Comments
 (0)