Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
6 changes: 5 additions & 1 deletion src/Responses/Responses/CreateStreamedResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
use OpenAI\Responses\Responses\Streaming\ReasoningSummaryPart;
use OpenAI\Responses\Responses\Streaming\ReasoningSummaryTextDelta;
use OpenAI\Responses\Responses\Streaming\ReasoningSummaryTextDone;
use OpenAI\Responses\Responses\Streaming\ReasoningTextDelta;
use OpenAI\Responses\Responses\Streaming\ReasoningTextDone;
use OpenAI\Responses\Responses\Streaming\RefusalDelta;
use OpenAI\Responses\Responses\Streaming\RefusalDone;
use OpenAI\Responses\Responses\Streaming\WebSearchCall;
Expand All @@ -50,7 +52,7 @@ final class CreateStreamedResponse implements ResponseContract

private function __construct(
public readonly string $event,
public readonly CreateResponse|OutputItem|ContentPart|OutputTextDelta|OutputTextAnnotationAdded|OutputTextDone|RefusalDelta|RefusalDone|FunctionCallArgumentsDelta|FunctionCallArgumentsDone|FileSearchCall|WebSearchCall|CodeInterpreterCall|CodeInterpreterCodeDelta|CodeInterpreterCodeDone|ReasoningSummaryPart|ReasoningSummaryTextDelta|ReasoningSummaryTextDone|McpListTools|McpListToolsInProgress|McpCall|McpCallArgumentsDelta|McpCallArgumentsDone|ImageGenerationPart|ImageGenerationPartialImage|Error $response,
public readonly CreateResponse|OutputItem|ContentPart|OutputTextDelta|OutputTextAnnotationAdded|OutputTextDone|RefusalDelta|RefusalDone|FunctionCallArgumentsDelta|FunctionCallArgumentsDone|FileSearchCall|WebSearchCall|CodeInterpreterCall|CodeInterpreterCodeDelta|CodeInterpreterCodeDone|ReasoningSummaryPart|ReasoningSummaryTextDelta|ReasoningSummaryTextDone|ReasoningTextDelta|ReasoningTextDone|McpListTools|McpListToolsInProgress|McpCall|McpCallArgumentsDelta|McpCallArgumentsDone|ImageGenerationPart|ImageGenerationPartialImage|Error $response,
) {}

/**
Expand Down Expand Up @@ -95,6 +97,8 @@ public static function from(array $attributes): self
'response.reasoning_summary_part.done' => ReasoningSummaryPart::from($attributes, $meta), // @phpstan-ignore-line
'response.reasoning_summary_text.delta' => ReasoningSummaryTextDelta::from($attributes, $meta), // @phpstan-ignore-line
'response.reasoning_summary_text.done' => ReasoningSummaryTextDone::from($attributes, $meta), // @phpstan-ignore-line
'response.reasoning_text.delta' => ReasoningTextDelta::from($attributes, $meta), // @phpstan-ignore-line
'response.reasoning_text.done' => ReasoningTextDone::from($attributes, $meta), // @phpstan-ignore-line
'response.mcp_list_tools.in_progress' => McpListToolsInProgress::from($attributes, $meta), // @phpstan-ignore-line
'response.mcp_list_tools.failed',
'response.mcp_list_tools.completed' => McpListTools::from($attributes, $meta), // @phpstan-ignore-line
Expand Down
69 changes: 69 additions & 0 deletions src/Responses/Responses/Streaming/ReasoningTextDelta.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

declare(strict_types=1);

namespace OpenAI\Responses\Responses\Streaming;

use OpenAI\Contracts\ResponseContract;
use OpenAI\Contracts\ResponseHasMetaInformationContract;
use OpenAI\Responses\Concerns\ArrayAccessible;
use OpenAI\Responses\Concerns\HasMetaInformation;
use OpenAI\Responses\Meta\MetaInformation;
use OpenAI\Testing\Responses\Concerns\Fakeable;

/**
* @phpstan-type ReasoningTextDeltaType array{content_index: int, delta: string, item_id: string, output_index: int, sequence_number: int, type: string}
*
* @implements ResponseContract<ReasoningTextDeltaType>
*/
final class ReasoningTextDelta implements ResponseContract, ResponseHasMetaInformationContract
{
/**
* @use ArrayAccessible<ReasoningTextDeltaType>
*/
use ArrayAccessible;

use Fakeable;
use HasMetaInformation;

private function __construct(
public readonly int $contentIndex,
public readonly string $delta,
public readonly string $itemId,
public readonly int $outputIndex,
public readonly int $sequenceNumber,
public readonly string $type,
private readonly MetaInformation $meta,
) {}

/**
* @param ReasoningTextDeltaType $attributes
*/
public static function from(array $attributes, MetaInformation $meta): self
{
return new self(
contentIndex: $attributes['content_index'],
delta: $attributes['delta'],
itemId: $attributes['item_id'],
outputIndex: $attributes['output_index'],
sequenceNumber: $attributes['sequence_number'],
type: $attributes['type'],
meta: $meta,
);
}

/**
* {@inheritDoc}
*/
public function toArray(): array
{
return [
'content_index' => $this->contentIndex,
'delta' => $this->delta,
'item_id' => $this->itemId,
'output_index' => $this->outputIndex,
'sequence_number' => $this->sequenceNumber,
'type' => $this->type,
];
}
}
69 changes: 69 additions & 0 deletions src/Responses/Responses/Streaming/ReasoningTextDone.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

declare(strict_types=1);

namespace OpenAI\Responses\Responses\Streaming;

use OpenAI\Contracts\ResponseContract;
use OpenAI\Contracts\ResponseHasMetaInformationContract;
use OpenAI\Responses\Concerns\ArrayAccessible;
use OpenAI\Responses\Concerns\HasMetaInformation;
use OpenAI\Responses\Meta\MetaInformation;
use OpenAI\Testing\Responses\Concerns\Fakeable;

/**
* @phpstan-type ReasoningTextDoneType array{content_index: int, item_id: string, output_index: int, sequence_number: int, text: string, type: string}
*
* @implements ResponseContract<ReasoningTextDoneType>
*/
final class ReasoningTextDone implements ResponseContract, ResponseHasMetaInformationContract
{
/**
* @use ArrayAccessible<ReasoningTextDoneType>
*/
use ArrayAccessible;

use Fakeable;
use HasMetaInformation;

private function __construct(
public readonly int $contentIndex,
public readonly string $itemId,
public readonly int $outputIndex,
public readonly int $sequenceNumber,
public readonly string $text,
public readonly string $type,
private readonly MetaInformation $meta,
) {}

/**
* @param ReasoningTextDoneType $attributes
*/
public static function from(array $attributes, MetaInformation $meta): self
{
return new self(
contentIndex: $attributes['content_index'],
itemId: $attributes['item_id'],
outputIndex: $attributes['output_index'],
sequenceNumber: $attributes['sequence_number'],
text: $attributes['text'],
type: $attributes['type'],
meta: $meta,
);
}

/**
* {@inheritDoc}
*/
public function toArray(): array
{
return [
'content_index' => $this->contentIndex,
'item_id' => $this->itemId,
'output_index' => $this->outputIndex,
'sequence_number' => $this->sequenceNumber,
'text' => $this->text,
'type' => $this->type,
];
}
}
10 changes: 10 additions & 0 deletions tests/Fixtures/Responses.php
Original file line number Diff line number Diff line change
Expand Up @@ -760,3 +760,13 @@ function responseCompletionSteamCreatedEvent()
{
return fopen(__DIR__.'/Streams/ResponseCreatedResponse.txt', 'r');
}

function responseReasoningTextDeltaEvent()
{
return fopen(__DIR__.'/Streams/ResponseReasoningTextDelta.txt', 'r');
}

function responseReasoningTextDoneEvent()
{
return fopen(__DIR__.'/Streams/ResponseReasoningTextDone.txt', 'r');
}
1 change: 1 addition & 0 deletions tests/Fixtures/Streams/ResponseReasoningTextDelta.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
data: {"type":"response.reasoning_text.delta","content_index":0,"delta":"Let me analyze","item_id":"item_123","output_index":0,"sequence_number":5}
1 change: 1 addition & 0 deletions tests/Fixtures/Streams/ResponseReasoningTextDone.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
data: {"type":"response.reasoning_text.done","content_index":0,"item_id":"item_123","output_index":0,"sequence_number":10,"text":"Let me analyze this problem step by step to provide the best solution."}
32 changes: 32 additions & 0 deletions tests/Responses/Responses/CreateStreamedResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

use OpenAI\Responses\Responses\CreateResponse;
use OpenAI\Responses\Responses\CreateStreamedResponse;
use OpenAI\Responses\Responses\Streaming\ReasoningTextDelta;
use OpenAI\Responses\Responses\Streaming\ReasoningTextDone;

test('fake', function () {
$response = CreateStreamedResponse::fake();
Expand All @@ -20,3 +22,33 @@
->response->toBeInstanceOf(CreateResponse::class)
->response->id->toBe('resp_67ccf18ef5fc8190b16dbee19bc54e5f087bb177ab789d5c');
});

test('reasoning text delta event', function () {
$response = CreateStreamedResponse::fake(responseReasoningTextDeltaEvent());

expect($response->getIterator()->current())
->toBeInstanceOf(CreateStreamedResponse::class)
->event->toBe('response.reasoning_text.delta')
->response->toBeInstanceOf(ReasoningTextDelta::class)
->response->delta->toBe('Let me analyze')
->response->itemId->toBe('item_123')
->response->outputIndex->toBe(0)
->response->contentIndex->toBe(0)
->response->sequenceNumber->toBe(5)
->response->type->toBe('response.reasoning_text.delta');
});

test('reasoning text done event', function () {
$response = CreateStreamedResponse::fake(responseReasoningTextDoneEvent());

expect($response->getIterator()->current())
->toBeInstanceOf(CreateStreamedResponse::class)
->event->toBe('response.reasoning_text.done')
->response->toBeInstanceOf(ReasoningTextDone::class)
->response->text->toBe('Let me analyze this problem step by step to provide the best solution.')
->response->itemId->toBe('item_123')
->response->outputIndex->toBe(0)
->response->contentIndex->toBe(0)
->response->sequenceNumber->toBe(10)
->response->type->toBe('response.reasoning_text.done');
});