diff --git a/src/Responses/Responses/Streaming/OutputItem.php b/src/Responses/Responses/Streaming/OutputItem.php index 68e03745..c93c02c3 100644 --- a/src/Responses/Responses/Streaming/OutputItem.php +++ b/src/Responses/Responses/Streaming/OutputItem.php @@ -20,6 +20,8 @@ use OpenAI\Responses\Responses\Output\OutputMcpListTools; use OpenAI\Responses\Responses\Output\OutputMessage; use OpenAI\Responses\Responses\Output\OutputReasoning; +use OpenAI\Responses\Responses\Output\OutputToolSearchCall; +use OpenAI\Responses\Responses\Output\OutputToolSearchOutput; use OpenAI\Responses\Responses\Output\OutputWebSearchToolCall; use OpenAI\Testing\Responses\Concerns\Fakeable; @@ -36,8 +38,10 @@ * @phpstan-import-type OutputMcpCallType from OutputMcpCall * @phpstan-import-type OutputCodeInterpreterToolCallType from OutputCodeInterpreterToolCall * @phpstan-import-type OutputCompactionType from OutputCompaction + * @phpstan-import-type OutputToolSearchCallType from OutputToolSearchCall + * @phpstan-import-type OutputToolSearchOutputType from OutputToolSearchOutput * - * @phpstan-type OutputItemType array{type: string, output_index: int, sequence_number: int, item: OutputCodeInterpreterToolCallType|OutputComputerToolCallType|OutputFileSearchToolCallType|OutputFunctionToolCallType|OutputMessageType|OutputReasoningType|OutputWebSearchToolCallType|OutputMcpListToolsType|OutputMcpApprovalRequestType|OutputMcpCallType|OutputImageGenerationToolCallType|OutputCompactionType} + * @phpstan-type OutputItemType array{type: string, output_index: int, sequence_number: int, item: OutputCodeInterpreterToolCallType|OutputComputerToolCallType|OutputFileSearchToolCallType|OutputFunctionToolCallType|OutputMessageType|OutputReasoningType|OutputWebSearchToolCallType|OutputMcpListToolsType|OutputMcpApprovalRequestType|OutputMcpCallType|OutputImageGenerationToolCallType|OutputCompactionType|OutputToolSearchCallType|OutputToolSearchOutputType} * * @implements ResponseContract */ @@ -55,7 +59,7 @@ private function __construct( public readonly string $type, public readonly int $outputIndex, public readonly int $sequenceNumber, - public readonly OutputMessage|OutputCodeInterpreterToolCall|OutputFileSearchToolCall|OutputFunctionToolCall|OutputWebSearchToolCall|OutputComputerToolCall|OutputReasoning|OutputMcpListTools|OutputMcpApprovalRequest|OutputMcpCall|OutputImageGenerationToolCall|OutputCompaction $item, + public readonly OutputMessage|OutputCodeInterpreterToolCall|OutputFileSearchToolCall|OutputFunctionToolCall|OutputWebSearchToolCall|OutputComputerToolCall|OutputReasoning|OutputMcpListTools|OutputMcpApprovalRequest|OutputMcpCall|OutputImageGenerationToolCall|OutputCompaction|OutputToolSearchCall|OutputToolSearchOutput $item, private readonly MetaInformation $meta, ) {} @@ -77,6 +81,8 @@ public static function from(array $attributes, MetaInformation $meta): self 'mcp_call' => OutputMcpCall::from($attributes['item']), 'code_interpreter_call' => OutputCodeInterpreterToolCall::from($attributes['item']), 'compaction' => OutputCompaction::from($attributes['item']), + 'tool_search_call' => OutputToolSearchCall::from($attributes['item']), + 'tool_search_output' => OutputToolSearchOutput::from($attributes['item']), }; return new self( diff --git a/tests/Fixtures/Responses.php b/tests/Fixtures/Responses.php index 4da44a0f..c0cc1e68 100644 --- a/tests/Fixtures/Responses.php +++ b/tests/Fixtures/Responses.php @@ -1047,3 +1047,13 @@ function responseOutputItemCompactionDoneEvent() { return fopen(__DIR__.'/Streams/ResponseOutputItemCompactionDone.txt', 'r'); } + +function responseOutputItemToolSearchCallAddedEvent() +{ + return fopen(__DIR__.'/Streams/ResponseOutputItemToolSearchCallAdded.txt', 'r'); +} + +function responseOutputItemToolSearchOutputDoneEvent() +{ + return fopen(__DIR__.'/Streams/ResponseOutputItemToolSearchOutputDone.txt', 'r'); +} diff --git a/tests/Fixtures/Streams/ResponseOutputItemToolSearchCallAdded.txt b/tests/Fixtures/Streams/ResponseOutputItemToolSearchCallAdded.txt new file mode 100644 index 00000000..d8245bbb --- /dev/null +++ b/tests/Fixtures/Streams/ResponseOutputItemToolSearchCallAdded.txt @@ -0,0 +1 @@ +data: {"type":"response.output_item.added","output_index":0,"sequence_number":12,"item":{"id":"tsc_67ccf18f64008190a39b619f4c8455ef087bb177ab789d5c","arguments":[],"call_id":"call_67ccf18f64008190a39b619f4c8455ef087bb177ab789d5c","execution":"server","status":"in_progress","type":"tool_search_call","created_by":"user_123"}} diff --git a/tests/Fixtures/Streams/ResponseOutputItemToolSearchOutputDone.txt b/tests/Fixtures/Streams/ResponseOutputItemToolSearchOutputDone.txt new file mode 100644 index 00000000..ea027dd2 --- /dev/null +++ b/tests/Fixtures/Streams/ResponseOutputItemToolSearchOutputDone.txt @@ -0,0 +1 @@ +data: {"type":"response.output_item.done","output_index":1,"sequence_number":13,"item":{"id":"tso_67ccf18f64008190a39b619f4c8455ef087bb177ab789d5c","call_id":"call_67ccf18f64008190a39b619f4c8455ef087bb177ab789d5c","execution":"server","status":"completed","tools":[{"type":"web_search","search_context_size":"low","user_location":null}],"type":"tool_search_output","created_by":"user_123"}} diff --git a/tests/Responses/Responses/CreateStreamedResponse.php b/tests/Responses/Responses/CreateStreamedResponse.php index 907243fb..ee32775f 100644 --- a/tests/Responses/Responses/CreateStreamedResponse.php +++ b/tests/Responses/Responses/CreateStreamedResponse.php @@ -3,11 +3,14 @@ use OpenAI\Responses\Responses\CreateResponse; use OpenAI\Responses\Responses\CreateStreamedResponse; use OpenAI\Responses\Responses\Output\OutputCompaction; +use OpenAI\Responses\Responses\Output\OutputToolSearchCall; +use OpenAI\Responses\Responses\Output\OutputToolSearchOutput; use OpenAI\Responses\Responses\Streaming\OutputItem; use OpenAI\Responses\Responses\Streaming\RateLimits; use OpenAI\Responses\Responses\Streaming\ReasoningTextDelta; use OpenAI\Responses\Responses\Streaming\ReasoningTextDone; use OpenAI\Responses\Responses\Streaming\Response; +use OpenAI\Responses\Responses\Tool\WebSearchTool; test('fake', function () { $response = CreateStreamedResponse::fake(); @@ -85,3 +88,34 @@ ->response->item->encryptedContent->toBe('encrypted_string_value') ->response->item->createdBy->toBe('user_123'); }); + +test('output item added event with tool search call item', function () { + $response = CreateStreamedResponse::fake(responseOutputItemToolSearchCallAddedEvent()); + + expect($response->getIterator()->current()) + ->toBeInstanceOf(CreateStreamedResponse::class) + ->event->toBe('response.output_item.added') + ->response->toBeInstanceOf(OutputItem::class) + ->response->outputIndex->toBe(0) + ->response->sequenceNumber->toBe(12) + ->response->item->toBeInstanceOf(OutputToolSearchCall::class) + ->response->item->id->toBe('tsc_67ccf18f64008190a39b619f4c8455ef087bb177ab789d5c') + ->response->item->callId->toBe('call_67ccf18f64008190a39b619f4c8455ef087bb177ab789d5c') + ->response->item->type->toBe('tool_search_call'); +}); + +test('output item done event with tool search output item', function () { + $response = CreateStreamedResponse::fake(responseOutputItemToolSearchOutputDoneEvent()); + + expect($response->getIterator()->current()) + ->toBeInstanceOf(CreateStreamedResponse::class) + ->event->toBe('response.output_item.done') + ->response->toBeInstanceOf(OutputItem::class) + ->response->outputIndex->toBe(1) + ->response->sequenceNumber->toBe(13) + ->response->item->toBeInstanceOf(OutputToolSearchOutput::class) + ->response->item->id->toBe('tso_67ccf18f64008190a39b619f4c8455ef087bb177ab789d5c') + ->response->item->tools->toHaveCount(1) + ->response->item->tools->{0}->toBeInstanceOf(WebSearchTool::class) + ->response->item->type->toBe('tool_search_output'); +});