From 874f28737689d62bd84be497010db29cdbbfc935 Mon Sep 17 00:00:00 2001 From: gehrisandro Date: Thu, 20 Apr 2023 23:43:10 +0200 Subject: [PATCH 1/2] Fix: the toArray() on streamed chat response deltas should only filter fields which are null - fixes #104 --- .../Chat/CreateStreamedResponseDelta.php | 8 ++-- tests/Fixtures/Chat.php | 38 +++++++++++++++++++ .../Chat/CreateStreamdResponseChoice.php | 20 ++++++++++ .../Responses/Chat/CreateStreamedResponse.php | 28 ++++++++++++++ .../Chat/CreateStreamedResponseDelta.php | 33 ++++++++++++++++ 5 files changed, 123 insertions(+), 4 deletions(-) create mode 100644 tests/Responses/Chat/CreateStreamdResponseChoice.php create mode 100644 tests/Responses/Chat/CreateStreamedResponseDelta.php diff --git a/src/Responses/Chat/CreateStreamedResponseDelta.php b/src/Responses/Chat/CreateStreamedResponseDelta.php index d43f12c1..257cd52d 100644 --- a/src/Responses/Chat/CreateStreamedResponseDelta.php +++ b/src/Responses/Chat/CreateStreamedResponseDelta.php @@ -28,9 +28,9 @@ public static function from(array $attributes): self */ public function toArray(): array { - return array_filter([ - 'role' => $this->role, - 'content' => $this->content, - ]); + return array_filter([ + 'role' => $this->role, + 'content' => $this->content, + ], fn ($value): bool => ! is_null($value)); } } diff --git a/tests/Fixtures/Chat.php b/tests/Fixtures/Chat.php index 25213daf..33bd796f 100644 --- a/tests/Fixtures/Chat.php +++ b/tests/Fixtures/Chat.php @@ -28,6 +28,44 @@ function chatCompletion(): array ]; } +function chatCompletionStreamFirstChunk(): array +{ + return [ + 'id' => 'chatcmpl-6wdIE4DsUtqf1srdMTsfkJp0VWZgz', + 'object' => 'chat.completion.chunk', + 'created' => 1679432086, + 'model' => 'gpt-4-0314', + 'choices' => [ + [ + 'index' => 0, + 'delta' => [ + 'role' => 'assistant', + ], + 'finish_reason' => null, + ], + ], + ]; +} + +function chatCompletionStreamContentChunk(): array +{ + return [ + 'id' => 'chatcmpl-6wdIE4DsUtqf1srdMTsfkJp0VWZgz', + 'object' => 'chat.completion.chunk', + 'created' => 1679432086, + 'model' => 'gpt-4-0314', + 'choices' => [ + [ + 'index' => 0, + 'delta' => [ + 'content' => 'Hello', + ], + 'finish_reason' => null, + ], + ], + ]; +} + /** * @return resource */ diff --git a/tests/Responses/Chat/CreateStreamdResponseChoice.php b/tests/Responses/Chat/CreateStreamdResponseChoice.php new file mode 100644 index 00000000..d99bd51e --- /dev/null +++ b/tests/Responses/Chat/CreateStreamdResponseChoice.php @@ -0,0 +1,20 @@ +index->toBe(0) + ->delta->toBeInstanceOf(CreateStreamedResponseDelta::class) + ->finishReason->toBeIn(['stop', null]); +}); + +test('to array', function () { + $result = CreateStreamedResponseChoice::from(chatCompletionStreamFirstChunk()['choices'][0]); + + expect($result->toArray()) + ->toBe(chatCompletionStreamFirstChunk()['choices'][0]); +}); diff --git a/tests/Responses/Chat/CreateStreamedResponse.php b/tests/Responses/Chat/CreateStreamedResponse.php index 43b821ca..8a5ab31b 100644 --- a/tests/Responses/Chat/CreateStreamedResponse.php +++ b/tests/Responses/Chat/CreateStreamedResponse.php @@ -1,6 +1,34 @@ toBeInstanceOf(CreateStreamedResponse::class) + ->id->toBe('chatcmpl-6wdIE4DsUtqf1srdMTsfkJp0VWZgz') + ->object->toBe('chat.completion.chunk') + ->created->toBe(1679432086) + ->model->toBe('gpt-4-0314') + ->choices->toBeArray()->toHaveCount(1) + ->choices->each->toBeInstanceOf(CreateStreamedResponseChoice::class); +}); + +test('as array accessible', function () { + $completion = CreateStreamedResponse::from(chatCompletionStreamFirstChunk()); + + expect($completion['id'])->toBe('chatcmpl-6wdIE4DsUtqf1srdMTsfkJp0VWZgz'); +}); + +test('to array', function () { + $completion = CreateStreamedResponse::from(chatCompletionStreamFirstChunk()); + + expect($completion->toArray()) + ->toBeArray() + ->toBe(chatCompletionStreamFirstChunk()); +}); test('fake', function () { $response = CreateStreamedResponse::fake(); diff --git a/tests/Responses/Chat/CreateStreamedResponseDelta.php b/tests/Responses/Chat/CreateStreamedResponseDelta.php new file mode 100644 index 00000000..6ac4ca36 --- /dev/null +++ b/tests/Responses/Chat/CreateStreamedResponseDelta.php @@ -0,0 +1,33 @@ +role->toBe('assistant') + ->content->toBeNull(); +}); + +test('from content chunk', function () { + $result = CreateStreamedResponseDelta::from(chatCompletionStreamContentChunk()['choices'][0]['delta']); + + expect($result) + ->role->toBeNull() + ->content->toBe('Hello'); +}); + +test('to array from first chunk', function () { + $result = CreateStreamedResponseDelta::from(chatCompletionStreamFirstChunk()['choices'][0]['delta']); + + expect($result->toArray()) + ->toBe(chatCompletionStreamFirstChunk()['choices'][0]['delta']); +}); + +test('to array for a content chunk', function () { + $result = CreateStreamedResponseDelta::from(chatCompletionStreamContentChunk()['choices'][0]['delta']); + + expect($result->toArray()) + ->toBe(chatCompletionStreamContentChunk()['choices'][0]['delta']); +}); From a592fd8c75a2a126f28e83003d920223a395f33d Mon Sep 17 00:00:00 2001 From: gehrisandro Date: Thu, 20 Apr 2023 23:45:55 +0200 Subject: [PATCH 2/2] apply the latest Pint rules --- tests/Responses/FineTunes/ListEventsResponse.php | 2 +- tests/Responses/Models/ListResponse.php | 2 +- tests/Responses/Models/RetrieveResponse.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Responses/FineTunes/ListEventsResponse.php b/tests/Responses/FineTunes/ListEventsResponse.php index 3dfd85bc..7fcf70b0 100644 --- a/tests/Responses/FineTunes/ListEventsResponse.php +++ b/tests/Responses/FineTunes/ListEventsResponse.php @@ -33,7 +33,7 @@ expect($response) ->object->toBe('list') ->and($response['data'][0]) - ->level->toBe('info'); + ->level->toBe('info'); }); test('fake with override', function () { diff --git a/tests/Responses/Models/ListResponse.php b/tests/Responses/Models/ListResponse.php index a8ac6732..ce1cecad 100644 --- a/tests/Responses/Models/ListResponse.php +++ b/tests/Responses/Models/ListResponse.php @@ -31,7 +31,7 @@ $response = ListResponse::fake(); expect($response) - ->object->toBe('list') + ->object->toBe('list') ->and($response->data[0]) ->id->toBe('text-babbage:001'); }); diff --git a/tests/Responses/Models/RetrieveResponse.php b/tests/Responses/Models/RetrieveResponse.php index 297cc845..2340f621 100644 --- a/tests/Responses/Models/RetrieveResponse.php +++ b/tests/Responses/Models/RetrieveResponse.php @@ -36,7 +36,7 @@ expect($response) ->id->toBe('text-babbage:001') - ->and($response->permission[0]) + ->and($response->permission[0]) ->allowCreateEngine->toBeFalse(); });