From 662ffbe072670aa67226c1455ad265563193bb3d Mon Sep 17 00:00:00 2001 From: gehrisandro Date: Tue, 5 Dec 2023 09:07:05 +0100 Subject: [PATCH 1/9] WIP: add events --- composer.json | 3 ++- src/Client.php | 9 +++++++-- src/Contracts/DispatcherContract.php | 23 +++++++++++++++++++++++ src/Events/Dispatcher.php | 21 +++++++++++++++++++++ src/Events/RequestHandled.php | 17 +++++++++++++++++ src/Factory.php | 21 ++++++++++++++++++++- src/Resources/Assistants.php | 7 ++++++- src/Resources/Concerns/Transportable.php | 11 ++++++++++- src/ValueObjects/Transporter/Payload.php | 8 ++++---- 9 files changed, 110 insertions(+), 10 deletions(-) create mode 100644 src/Contracts/DispatcherContract.php create mode 100644 src/Events/Dispatcher.php create mode 100644 src/Events/RequestHandled.php diff --git a/composer.json b/composer.json index 437a98cc..7de32e3e 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,8 @@ "psr/http-client": "^1.0.3", "psr/http-client-implementation": "^1.0.1", "psr/http-factory-implementation": "*", - "psr/http-message": "^1.1.0|^2.0.0" + "psr/http-message": "^1.1.0|^2.0.0", + "psr/event-dispatcher": "^1.0.0" }, "require-dev": { "guzzlehttp/guzzle": "^7.8.0", diff --git a/src/Client.php b/src/Client.php index d876c55f..fea2d540 100644 --- a/src/Client.php +++ b/src/Client.php @@ -5,8 +5,10 @@ namespace OpenAI; use OpenAI\Contracts\ClientContract; +use OpenAI\Contracts\DispatcherContract; use OpenAI\Contracts\Resources\ThreadsContract; use OpenAI\Contracts\TransporterContract; +use OpenAI\Events\Dispatcher; use OpenAI\Resources\Assistants; use OpenAI\Resources\Audio; use OpenAI\Resources\Chat; @@ -26,7 +28,10 @@ final class Client implements ClientContract /** * Creates a Client instance with the given API token. */ - public function __construct(private readonly TransporterContract $transporter) + public function __construct( + private readonly TransporterContract $transporter, + private readonly DispatcherContract $events, + ) { // .. } @@ -151,7 +156,7 @@ public function images(): Images */ public function assistants(): Assistants { - return new Assistants($this->transporter); + return new Assistants($this->transporter, $this->events); } /** diff --git a/src/Contracts/DispatcherContract.php b/src/Contracts/DispatcherContract.php new file mode 100644 index 00000000..d2a2bb68 --- /dev/null +++ b/src/Contracts/DispatcherContract.php @@ -0,0 +1,23 @@ +events?->dispatch($event); + } +} diff --git a/src/Events/RequestHandled.php b/src/Events/RequestHandled.php new file mode 100644 index 00000000..55816925 --- /dev/null +++ b/src/Events/RequestHandled.php @@ -0,0 +1,17 @@ +events = $events; + + return $this; + } + /** * Creates a new Open AI Client. */ @@ -158,7 +175,9 @@ public function make(): Client $transporter = new HttpTransporter($client, $baseUri, $headers, $queryParams, $sendAsync); - return new Client($transporter); + $dispatcher = new Dispatcher($this->events); + + return new Client($transporter, $dispatcher); } /** diff --git a/src/Resources/Assistants.php b/src/Resources/Assistants.php index 2e785b06..9ee08516 100644 --- a/src/Resources/Assistants.php +++ b/src/Resources/Assistants.php @@ -6,6 +6,7 @@ use OpenAI\Contracts\Resources\AssistantsContract; use OpenAI\Contracts\Resources\AssistantsFilesContract; +use OpenAI\Events\RequestHandled; use OpenAI\Responses\Assistants\AssistantDeleteResponse; use OpenAI\Responses\Assistants\AssistantListResponse; use OpenAI\Responses\Assistants\AssistantResponse; @@ -30,7 +31,11 @@ public function create(array $parameters): AssistantResponse /** @var Response}}>, file_ids: array, metadata: array}> $response */ $response = $this->transporter->requestObject($payload); - return AssistantResponse::from($response->data(), $response->meta()); + $response = AssistantResponse::from($response->data(), $response->meta()); + + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** diff --git a/src/Resources/Concerns/Transportable.php b/src/Resources/Concerns/Transportable.php index 091511f9..27b94a22 100644 --- a/src/Resources/Concerns/Transportable.php +++ b/src/Resources/Concerns/Transportable.php @@ -4,6 +4,7 @@ namespace OpenAI\Resources\Concerns; +use OpenAI\Contracts\DispatcherContract; use OpenAI\Contracts\TransporterContract; trait Transportable @@ -11,8 +12,16 @@ trait Transportable /** * Creates a Client instance with the given API token. */ - public function __construct(private readonly TransporterContract $transporter) + public function __construct( + private readonly TransporterContract $transporter, + private readonly DispatcherContract $events, + ) { // .. } + + public function event(object $event): void + { + $this->events->dispatch($event); + } } diff --git a/src/ValueObjects/Transporter/Payload.php b/src/ValueObjects/Transporter/Payload.php index 4fcb4c5a..b1ba4f74 100644 --- a/src/ValueObjects/Transporter/Payload.php +++ b/src/ValueObjects/Transporter/Payload.php @@ -24,10 +24,10 @@ final class Payload * @param array $parameters */ private function __construct( - private readonly ContentType $contentType, - private readonly Method $method, - private readonly ResourceUri $uri, - private readonly array $parameters = [], + public readonly ContentType $contentType, + public readonly Method $method, + public readonly ResourceUri $uri, + public readonly array $parameters = [], ) { // .. } From 5aeff0d9942b9ebaac0edbc7de6530a4e56bcc4d Mon Sep 17 00:00:00 2001 From: gehrisandro Date: Tue, 5 Dec 2023 09:14:38 +0100 Subject: [PATCH 2/9] WIP: add events --- src/Factory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Factory.php b/src/Factory.php index 42c582bd..ff505c4d 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -57,7 +57,7 @@ final class Factory private ?Closure $streamHandler = null; - private Dispatcher|EventDispatcherInterface|null $events = null; + private LaravelDispatcher|EventDispatcherInterface|null $events = null; /** * Sets the API key for the requests. From 561c624b67c05499e15c91569787c5ea141a41cd Mon Sep 17 00:00:00 2001 From: gehrisandro Date: Tue, 5 Dec 2023 09:52:44 +0100 Subject: [PATCH 3/9] Add RequestHandled event --- composer.json | 1 + src/Client.php | 28 +++++------ src/Contracts/DispatcherContract.php | 7 --- src/Events/Dispatcher.php | 3 +- src/Events/RequestHandled.php | 4 +- src/Factory.php | 2 - src/Resources/Assistants.php | 48 ++++++++++++------ src/Resources/AssistantsFiles.php | 41 ++++++++++----- src/Resources/Audio.php | 35 +++++++++---- src/Resources/Chat.php | 19 +++++-- src/Resources/Completions.php | 19 +++++-- src/Resources/Concerns/Transportable.php | 3 +- src/Resources/Edits.php | 11 +++-- src/Resources/Embeddings.php | 11 +++-- src/Resources/Files.php | 47 +++++++++++++----- src/Resources/FineTunes.php | 59 +++++++++++++++------- src/Resources/FineTuning.php | 51 +++++++++++++------ src/Resources/Images.php | 31 ++++++++---- src/Resources/Models.php | 31 ++++++++---- src/Resources/Moderations.php | 11 +++-- src/Resources/Threads.php | 55 ++++++++++++++------- src/Resources/ThreadsMessages.php | 53 ++++++++++++++------ src/Resources/ThreadsMessagesFiles.php | 21 +++++--- src/Resources/ThreadsRuns.php | 63 +++++++++++++++++------- src/Resources/ThreadsRunsSteps.php | 21 +++++--- tests/Arch.php | 5 ++ tests/Pest.php | 9 +++- 27 files changed, 475 insertions(+), 214 deletions(-) diff --git a/composer.json b/composer.json index 7de32e3e..47f5ec7e 100644 --- a/composer.json +++ b/composer.json @@ -25,6 +25,7 @@ "require-dev": { "guzzlehttp/guzzle": "^7.8.0", "guzzlehttp/psr7": "^2.6.1", + "illuminate/contracts": "^9.0|^10.0", "laravel/pint": "^1.13.6", "mockery/mockery": "^1.6.6", "nunomaduro/collision": "^7.10.0", diff --git a/src/Client.php b/src/Client.php index fea2d540..6a292d39 100644 --- a/src/Client.php +++ b/src/Client.php @@ -8,7 +8,6 @@ use OpenAI\Contracts\DispatcherContract; use OpenAI\Contracts\Resources\ThreadsContract; use OpenAI\Contracts\TransporterContract; -use OpenAI\Events\Dispatcher; use OpenAI\Resources\Assistants; use OpenAI\Resources\Audio; use OpenAI\Resources\Chat; @@ -31,8 +30,7 @@ final class Client implements ClientContract public function __construct( private readonly TransporterContract $transporter, private readonly DispatcherContract $events, - ) - { + ) { // .. } @@ -44,7 +42,7 @@ public function __construct( */ public function completions(): Completions { - return new Completions($this->transporter); + return new Completions($this->transporter, $this->events); } /** @@ -54,7 +52,7 @@ public function completions(): Completions */ public function chat(): Chat { - return new Chat($this->transporter); + return new Chat($this->transporter, $this->events); } /** @@ -64,7 +62,7 @@ public function chat(): Chat */ public function embeddings(): Embeddings { - return new Embeddings($this->transporter); + return new Embeddings($this->transporter, $this->events); } /** @@ -74,7 +72,7 @@ public function embeddings(): Embeddings */ public function audio(): Audio { - return new Audio($this->transporter); + return new Audio($this->transporter, $this->events); } /** @@ -84,7 +82,7 @@ public function audio(): Audio */ public function edits(): Edits { - return new Edits($this->transporter); + return new Edits($this->transporter, $this->events); } /** @@ -94,7 +92,7 @@ public function edits(): Edits */ public function files(): Files { - return new Files($this->transporter); + return new Files($this->transporter, $this->events); } /** @@ -104,7 +102,7 @@ public function files(): Files */ public function models(): Models { - return new Models($this->transporter); + return new Models($this->transporter, $this->events); } /** @@ -114,7 +112,7 @@ public function models(): Models */ public function fineTuning(): FineTuning { - return new FineTuning($this->transporter); + return new FineTuning($this->transporter, $this->events); } /** @@ -126,7 +124,7 @@ public function fineTuning(): FineTuning */ public function fineTunes(): FineTunes { - return new FineTunes($this->transporter); + return new FineTunes($this->transporter, $this->events); } /** @@ -136,7 +134,7 @@ public function fineTunes(): FineTunes */ public function moderations(): Moderations { - return new Moderations($this->transporter); + return new Moderations($this->transporter, $this->events); } /** @@ -146,7 +144,7 @@ public function moderations(): Moderations */ public function images(): Images { - return new Images($this->transporter); + return new Images($this->transporter, $this->events); } /** @@ -166,6 +164,6 @@ public function assistants(): Assistants */ public function threads(): ThreadsContract { - return new Threads($this->transporter); + return new Threads($this->transporter, $this->events); } } diff --git a/src/Contracts/DispatcherContract.php b/src/Contracts/DispatcherContract.php index d2a2bb68..57ea23a3 100644 --- a/src/Contracts/DispatcherContract.php +++ b/src/Contracts/DispatcherContract.php @@ -4,13 +4,6 @@ namespace OpenAI\Contracts; -use OpenAI\Exceptions\ErrorException; -use OpenAI\Exceptions\TransporterException; -use OpenAI\Exceptions\UnserializableResponse; -use OpenAI\ValueObjects\Transporter\Payload; -use OpenAI\ValueObjects\Transporter\Response; -use Psr\Http\Message\ResponseInterface; - /** * @internal */ diff --git a/src/Events/Dispatcher.php b/src/Events/Dispatcher.php index f53e6d63..b061f100 100644 --- a/src/Events/Dispatcher.php +++ b/src/Events/Dispatcher.php @@ -10,8 +10,7 @@ class Dispatcher implements DispatcherContract { public function __construct( private readonly LaravelDispatcher|EventDispatcherInterface|null $events - ) - { + ) { } public function dispatch(object $event): void diff --git a/src/Events/RequestHandled.php b/src/Events/RequestHandled.php index 55816925..d228a2d8 100644 --- a/src/Events/RequestHandled.php +++ b/src/Events/RequestHandled.php @@ -8,10 +8,10 @@ class RequestHandled { + // @phpstan-ignore-next-line public function __construct( public readonly Payload $payload, public readonly ResponseContract|ResponseStreamContract|string $response, - ) - { + ) { } } diff --git a/src/Factory.php b/src/Factory.php index ff505c4d..653ee9a4 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -133,8 +133,6 @@ public function withQueryParam(string $name, string $value): self /** * Set the event dispatcher instance. - * - * @param LaravelDispatcher|EventDispatcherInterface $events */ public function withEventDispatcher(LaravelDispatcher|EventDispatcherInterface $events): self { diff --git a/src/Resources/Assistants.php b/src/Resources/Assistants.php index 9ee08516..1d061bd1 100644 --- a/src/Resources/Assistants.php +++ b/src/Resources/Assistants.php @@ -28,10 +28,10 @@ public function create(array $parameters): AssistantResponse { $payload = Payload::create('assistants', $parameters); - /** @var Response}}>, file_ids: array, metadata: array}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response}}>, file_ids: array, metadata: array}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); - $response = AssistantResponse::from($response->data(), $response->meta()); + $response = AssistantResponse::from($responseRaw->data(), $responseRaw->meta()); $this->event(new RequestHandled($payload, $response)); @@ -47,10 +47,14 @@ public function retrieve(string $id): AssistantResponse { $payload = Payload::retrieve('assistants', $id); - /** @var Response}}>, file_ids: array, metadata: array}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response}}>, file_ids: array, metadata: array}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); - return AssistantResponse::from($response->data(), $response->meta()); + $response = AssistantResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -64,10 +68,14 @@ public function modify(string $id, array $parameters): AssistantResponse { $payload = Payload::modify('assistants', $id, $parameters); - /** @var Response}}>, file_ids: array, metadata: array}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response}}>, file_ids: array, metadata: array}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); - return AssistantResponse::from($response->data(), $response->meta()); + $response = AssistantResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -79,10 +87,14 @@ public function delete(string $id): AssistantDeleteResponse { $payload = Payload::delete('assistants', $id); - /** @var Response $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); - return AssistantDeleteResponse::from($response->data(), $response->meta()); + $response = AssistantDeleteResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -96,10 +108,14 @@ public function list(array $parameters = []): AssistantListResponse { $payload = Payload::list('assistants', $parameters); - /** @var Response}}>, file_ids: array, metadata: array}>, first_id: ?string, last_id: ?string, has_more: bool}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response}}>, file_ids: array, metadata: array}>, first_id: ?string, last_id: ?string, has_more: bool}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); - return AssistantListResponse::from($response->data(), $response->meta()); + $response = AssistantListResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -109,6 +125,6 @@ public function list(array $parameters = []): AssistantListResponse */ public function files(): AssistantsFilesContract { - return new AssistantsFiles($this->transporter); + return new AssistantsFiles($this->transporter, $this->events); } } diff --git a/src/Resources/AssistantsFiles.php b/src/Resources/AssistantsFiles.php index aab3a447..e93ab140 100644 --- a/src/Resources/AssistantsFiles.php +++ b/src/Resources/AssistantsFiles.php @@ -5,6 +5,7 @@ namespace OpenAI\Resources; use OpenAI\Contracts\Resources\AssistantsFilesContract; +use OpenAI\Events\RequestHandled; use OpenAI\Responses\Assistants\Files\AssistantFileDeleteResponse; use OpenAI\Responses\Assistants\Files\AssistantFileListResponse; use OpenAI\Responses\Assistants\Files\AssistantFileResponse; @@ -26,10 +27,14 @@ public function create(string $assistantId, array $parameters): AssistantFileRes { $payload = Payload::create("assistants/$assistantId/files", $parameters); - /** @var Response $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); - return AssistantFileResponse::from($response->data(), $response->meta()); + $response = AssistantFileResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -41,10 +46,14 @@ public function retrieve(string $assistantId, string $fileId): AssistantFileResp { $payload = Payload::retrieve("assistants/$assistantId/files", $fileId); - /** @var Response $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = AssistantFileResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); - return AssistantFileResponse::from($response->data(), $response->meta()); + return $response; } /** @@ -56,10 +65,14 @@ public function delete(string $assistantId, string $fileId): AssistantFileDelete { $payload = Payload::delete("assistants/$assistantId/files", $fileId); - /** @var Response $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); - return AssistantFileDeleteResponse::from($response->data(), $response->meta()); + $response = AssistantFileDeleteResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -73,9 +86,13 @@ public function list(string $assistantId, array $parameters = []): AssistantFile { $payload = Payload::list("assistants/$assistantId/files", $parameters); - /** @var Response, first_id: ?string, last_id: ?string, has_more: bool}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response, first_id: ?string, last_id: ?string, has_more: bool}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = AssistantFileListResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); - return AssistantFileListResponse::from($response->data(), $response->meta()); + return $response; } } diff --git a/src/Resources/Audio.php b/src/Resources/Audio.php index 41bd85b6..04bf57fd 100644 --- a/src/Resources/Audio.php +++ b/src/Resources/Audio.php @@ -5,6 +5,7 @@ namespace OpenAI\Resources; use OpenAI\Contracts\Resources\AudioContract; +use OpenAI\Events\RequestHandled; use OpenAI\Responses\Audio\SpeechStreamResponse; use OpenAI\Responses\Audio\TranscriptionResponse; use OpenAI\Responses\Audio\TranslationResponse; @@ -26,7 +27,11 @@ public function speech(array $parameters): string { $payload = Payload::create('audio/speech', $parameters); - return $this->transporter->requestContent($payload); + $response = $this->transporter->requestContent($payload); + + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -40,9 +45,13 @@ public function speechStreamed(array $parameters): SpeechStreamResponse { $payload = Payload::create('audio/speech', $parameters); - $response = $this->transporter->requestStream($payload); + $responseRaw = $this->transporter->requestStream($payload); + + $response = new SpeechStreamResponse($responseRaw); + + $this->event(new RequestHandled($payload, $response)); - return new SpeechStreamResponse($response); + return $response; } /** @@ -56,10 +65,14 @@ public function transcribe(array $parameters): TranscriptionResponse { $payload = Payload::upload('audio/transcriptions', $parameters); - /** @var Response, temperature: float, avg_logprob: float, compression_ratio: float, no_speech_prob: float, transient?: bool}>, text: string}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response, temperature: float, avg_logprob: float, compression_ratio: float, no_speech_prob: float, transient?: bool}>, text: string}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); - return TranscriptionResponse::from($response->data(), $response->meta()); + $response = TranscriptionResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -73,9 +86,13 @@ public function translate(array $parameters): TranslationResponse { $payload = Payload::upload('audio/translations', $parameters); - /** @var Response, temperature: float, avg_logprob: float, compression_ratio: float, no_speech_prob: float, transient?: bool}>, text: string}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response, temperature: float, avg_logprob: float, compression_ratio: float, no_speech_prob: float, transient?: bool}>, text: string}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = TranslationResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); - return TranslationResponse::from($response->data(), $response->meta()); + return $response; } } diff --git a/src/Resources/Chat.php b/src/Resources/Chat.php index 4d4999f3..068ade9a 100644 --- a/src/Resources/Chat.php +++ b/src/Resources/Chat.php @@ -5,6 +5,7 @@ namespace OpenAI\Resources; use OpenAI\Contracts\Resources\ChatContract; +use OpenAI\Events\RequestHandled; use OpenAI\Responses\Chat\CreateResponse; use OpenAI\Responses\Chat\CreateStreamedResponse; use OpenAI\Responses\StreamResponse; @@ -29,10 +30,14 @@ public function create(array $parameters): CreateResponse $payload = Payload::create('chat/completions', $parameters); - /** @var Response}, finish_reason: string|null}>, usage: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response}, finish_reason: string|null}>, usage: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); - return CreateResponse::from($response->data(), $response->meta()); + $response = CreateResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -49,8 +54,12 @@ public function createStreamed(array $parameters): StreamResponse $payload = Payload::create('chat/completions', $parameters); - $response = $this->transporter->requestStream($payload); + $responseRaw = $this->transporter->requestStream($payload); + + $response = new StreamResponse(CreateStreamedResponse::class, $responseRaw); + + $this->event(new RequestHandled($payload, $response)); - return new StreamResponse(CreateStreamedResponse::class, $response); + return $response; } } diff --git a/src/Resources/Completions.php b/src/Resources/Completions.php index 60edcae9..00e85092 100644 --- a/src/Resources/Completions.php +++ b/src/Resources/Completions.php @@ -5,6 +5,7 @@ namespace OpenAI\Resources; use OpenAI\Contracts\Resources\CompletionsContract; +use OpenAI\Events\RequestHandled; use OpenAI\Responses\Completions\CreateResponse; use OpenAI\Responses\Completions\CreateStreamedResponse; use OpenAI\Responses\StreamResponse; @@ -29,10 +30,14 @@ public function create(array $parameters): CreateResponse $payload = Payload::create('completions', $parameters); - /** @var Response, token_logprobs: array, top_logprobs: array|null, text_offset: array}|null, finish_reason: string}>, usage: array{prompt_tokens: int, completion_tokens: int, total_tokens: int}}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response, token_logprobs: array, top_logprobs: array|null, text_offset: array}|null, finish_reason: string}>, usage: array{prompt_tokens: int, completion_tokens: int, total_tokens: int}}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); - return CreateResponse::from($response->data(), $response->meta()); + $response = CreateResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -49,8 +54,12 @@ public function createStreamed(array $parameters): StreamResponse $payload = Payload::create('completions', $parameters); - $response = $this->transporter->requestStream($payload); + $responseRaw = $this->transporter->requestStream($payload); + + $response = new StreamResponse(CreateStreamedResponse::class, $responseRaw); + + $this->event(new RequestHandled($payload, $response)); - return new StreamResponse(CreateStreamedResponse::class, $response); + return $response; } } diff --git a/src/Resources/Concerns/Transportable.php b/src/Resources/Concerns/Transportable.php index 27b94a22..b947a6f3 100644 --- a/src/Resources/Concerns/Transportable.php +++ b/src/Resources/Concerns/Transportable.php @@ -15,8 +15,7 @@ trait Transportable public function __construct( private readonly TransporterContract $transporter, private readonly DispatcherContract $events, - ) - { + ) { // .. } diff --git a/src/Resources/Edits.php b/src/Resources/Edits.php index 859f68ac..3f702f32 100644 --- a/src/Resources/Edits.php +++ b/src/Resources/Edits.php @@ -5,6 +5,7 @@ namespace OpenAI\Resources; use OpenAI\Contracts\Resources\EditsContract; +use OpenAI\Events\RequestHandled; use OpenAI\Responses\Edits\CreateResponse; use OpenAI\ValueObjects\Transporter\Payload; use OpenAI\ValueObjects\Transporter\Response; @@ -27,9 +28,13 @@ public function create(array $parameters): CreateResponse { $payload = Payload::create('edits', $parameters); - /** @var Response, usage: array{prompt_tokens: int, completion_tokens: int, total_tokens: int}}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response, usage: array{prompt_tokens: int, completion_tokens: int, total_tokens: int}}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); - return CreateResponse::from($response->data(), $response->meta()); + $response = CreateResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); + + return $response; } } diff --git a/src/Resources/Embeddings.php b/src/Resources/Embeddings.php index fd0b9467..7380fa6f 100644 --- a/src/Resources/Embeddings.php +++ b/src/Resources/Embeddings.php @@ -5,6 +5,7 @@ namespace OpenAI\Resources; use OpenAI\Contracts\Resources\EmbeddingsContract; +use OpenAI\Events\RequestHandled; use OpenAI\Responses\Embeddings\CreateResponse; use OpenAI\ValueObjects\Transporter\Payload; use OpenAI\ValueObjects\Transporter\Response; @@ -24,9 +25,13 @@ public function create(array $parameters): CreateResponse { $payload = Payload::create('embeddings', $parameters); - /** @var Response, index: int}>, usage: array{prompt_tokens: int, total_tokens: int}}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response, index: int}>, usage: array{prompt_tokens: int, total_tokens: int}}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); - return CreateResponse::from($response->data(), $response->meta()); + $response = CreateResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); + + return $response; } } diff --git a/src/Resources/Files.php b/src/Resources/Files.php index b5c53cce..e1bbf1da 100644 --- a/src/Resources/Files.php +++ b/src/Resources/Files.php @@ -5,6 +5,7 @@ namespace OpenAI\Resources; use OpenAI\Contracts\Resources\FilesContract; +use OpenAI\Events\RequestHandled; use OpenAI\Responses\Files\CreateResponse; use OpenAI\Responses\Files\DeleteResponse; use OpenAI\Responses\Files\ListResponse; @@ -25,10 +26,14 @@ public function list(): ListResponse { $payload = Payload::list('files'); - /** @var Response|string|null}>}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response|string|null}>}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); - return ListResponse::from($response->data(), $response->meta()); + $response = ListResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -40,10 +45,14 @@ public function retrieve(string $file): RetrieveResponse { $payload = Payload::retrieve('files', $file); - /** @var Response|string|null}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response|string|null}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = RetrieveResponse::from($responseRaw->data(), $responseRaw->meta()); - return RetrieveResponse::from($response->data(), $response->meta()); + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -55,7 +64,11 @@ public function download(string $file): string { $payload = Payload::retrieveContent('files', $file); - return $this->transporter->requestContent($payload); + $response = $this->transporter->requestContent($payload); + + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -69,10 +82,14 @@ public function upload(array $parameters): CreateResponse { $payload = Payload::upload('files', $parameters); - /** @var Response|string|null}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response|string|null}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = CreateResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); - return CreateResponse::from($response->data(), $response->meta()); + return $response; } /** @@ -84,9 +101,13 @@ public function delete(string $file): DeleteResponse { $payload = Payload::delete('files', $file); - /** @var Response $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = DeleteResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); - return DeleteResponse::from($response->data(), $response->meta()); + return $response; } } diff --git a/src/Resources/FineTunes.php b/src/Resources/FineTunes.php index 3d9331df..66db8c2b 100644 --- a/src/Resources/FineTunes.php +++ b/src/Resources/FineTunes.php @@ -5,6 +5,7 @@ namespace OpenAI\Resources; use OpenAI\Contracts\Resources\FineTunesContract; +use OpenAI\Events\RequestHandled; use OpenAI\Responses\FineTunes\ListEventsResponse; use OpenAI\Responses\FineTunes\ListResponse; use OpenAI\Responses\FineTunes\RetrieveResponse; @@ -30,10 +31,14 @@ public function create(array $parameters): RetrieveResponse { $payload = Payload::create('fine-tunes', $parameters); - /** @var Response, fine_tuned_model: ?string, hyperparams: array{batch_size: ?int, learning_rate_multiplier: ?float, n_epochs: int, prompt_loss_weight: float}, organization_id: string, result_files: array|string|null}>, status: string, validation_files: array|string|null}>, training_files: array|string|null}>, updated_at: int}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response, fine_tuned_model: ?string, hyperparams: array{batch_size: ?int, learning_rate_multiplier: ?float, n_epochs: int, prompt_loss_weight: float}, organization_id: string, result_files: array|string|null}>, status: string, validation_files: array|string|null}>, training_files: array|string|null}>, updated_at: int}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); - return RetrieveResponse::from($response->data(), $response->meta()); + $response = RetrieveResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -45,10 +50,14 @@ public function list(): ListResponse { $payload = Payload::list('fine-tunes'); - /** @var Response, fine_tuned_model: ?string, hyperparams: array{batch_size: ?int, learning_rate_multiplier: ?float, n_epochs: int, prompt_loss_weight: float}, organization_id: string, result_files: array|string|null}>, status: string, validation_files: array|string|null}>, training_files: array|string|null}>, updated_at: int}>}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response, fine_tuned_model: ?string, hyperparams: array{batch_size: ?int, learning_rate_multiplier: ?float, n_epochs: int, prompt_loss_weight: float}, organization_id: string, result_files: array|string|null}>, status: string, validation_files: array|string|null}>, training_files: array|string|null}>, updated_at: int}>}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = ListResponse::from($responseRaw->data(), $responseRaw->meta()); - return ListResponse::from($response->data(), $response->meta()); + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -60,10 +69,14 @@ public function retrieve(string $fineTuneId): RetrieveResponse { $payload = Payload::retrieve('fine-tunes', $fineTuneId); - /** @var Response, fine_tuned_model: ?string, hyperparams: array{batch_size: ?int, learning_rate_multiplier: ?float, n_epochs: int, prompt_loss_weight: float}, organization_id: string, result_files: array|string|null}>, status: string, validation_files: array|string|null}>, training_files: array|string|null}>, updated_at: int}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response, fine_tuned_model: ?string, hyperparams: array{batch_size: ?int, learning_rate_multiplier: ?float, n_epochs: int, prompt_loss_weight: float}, organization_id: string, result_files: array|string|null}>, status: string, validation_files: array|string|null}>, training_files: array|string|null}>, updated_at: int}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = RetrieveResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); - return RetrieveResponse::from($response->data(), $response->meta()); + return $response; } /** @@ -75,10 +88,14 @@ public function cancel(string $fineTuneId): RetrieveResponse { $payload = Payload::cancel('fine-tunes', $fineTuneId); - /** @var Response, fine_tuned_model: ?string, hyperparams: array{batch_size: ?int, learning_rate_multiplier: ?float, n_epochs: int, prompt_loss_weight: float}, organization_id: string, result_files: array|string|null}>, status: string, validation_files: array|string|null}>, training_files: array|string|null}>, updated_at: int}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response, fine_tuned_model: ?string, hyperparams: array{batch_size: ?int, learning_rate_multiplier: ?float, n_epochs: int, prompt_loss_weight: float}, organization_id: string, result_files: array|string|null}>, status: string, validation_files: array|string|null}>, training_files: array|string|null}>, updated_at: int}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); - return RetrieveResponse::from($response->data(), $response->meta()); + $response = RetrieveResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -90,10 +107,14 @@ public function listEvents(string $fineTuneId): ListEventsResponse { $payload = Payload::retrieve('fine-tunes', $fineTuneId, '/events'); - /** @var Response}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = ListEventsResponse::from($responseRaw->data(), $responseRaw->meta()); - return ListEventsResponse::from($response->data(), $response->meta()); + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -107,8 +128,12 @@ public function listEventsStreamed(string $fineTuneId): StreamResponse { $payload = Payload::retrieve('fine-tunes', $fineTuneId, '/events?stream=true'); - $response = $this->transporter->requestStream($payload); + $responseRaw = $this->transporter->requestStream($payload); + + $response = new StreamResponse(RetrieveStreamedResponseEvent::class, $responseRaw); + + $this->event(new RequestHandled($payload, $response)); - return new StreamResponse(RetrieveStreamedResponseEvent::class, $response); + return $response; } } diff --git a/src/Resources/FineTuning.php b/src/Resources/FineTuning.php index ba9fc751..59e07108 100644 --- a/src/Resources/FineTuning.php +++ b/src/Resources/FineTuning.php @@ -5,6 +5,7 @@ namespace OpenAI\Resources; use OpenAI\Contracts\Resources\FineTuningContract; +use OpenAI\Events\RequestHandled; use OpenAI\Responses\FineTuning\ListJobEventsResponse; use OpenAI\Responses\FineTuning\ListJobsResponse; use OpenAI\Responses\FineTuning\RetrieveJobResponse; @@ -28,10 +29,14 @@ public function createJob(array $parameters): RetrieveJobResponse { $payload = Payload::create('fine_tuning/jobs', $parameters); - /** @var Response, status: string, validation_file: ?string, training_file: string, trained_tokens: ?int, error: ?array{code: string, param: ?string, message: string}}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response, status: string, validation_file: ?string, training_file: string, trained_tokens: ?int, error: ?array{code: string, param: ?string, message: string}}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); - return RetrieveJobResponse::from($response->data(), $response->meta()); + $response = RetrieveJobResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -45,10 +50,14 @@ public function listJobs(array $parameters = []): ListJobsResponse { $payload = Payload::list('fine_tuning/jobs', $parameters); - /** @var Response, status: string, validation_file: ?string, training_file: string, trained_tokens: ?int, error: ?array{code: string, param: ?string, message: string}}>, has_more: bool}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response, status: string, validation_file: ?string, training_file: string, trained_tokens: ?int, error: ?array{code: string, param: ?string, message: string}}>, has_more: bool}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = ListJobsResponse::from($responseRaw->data(), $responseRaw->meta()); - return ListJobsResponse::from($response->data(), $response->meta()); + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -60,10 +69,14 @@ public function retrieveJob(string $jobId): RetrieveJobResponse { $payload = Payload::retrieve('fine_tuning/jobs', $jobId); - /** @var Response, status: string, validation_file: ?string, training_file: string, trained_tokens: ?int, error: ?array{code: string, param: ?string, message: string}}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response, status: string, validation_file: ?string, training_file: string, trained_tokens: ?int, error: ?array{code: string, param: ?string, message: string}}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = RetrieveJobResponse::from($responseRaw->data(), $responseRaw->meta()); - return RetrieveJobResponse::from($response->data(), $response->meta()); + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -75,10 +88,14 @@ public function cancelJob(string $jobId): RetrieveJobResponse { $payload = Payload::cancel('fine_tuning/jobs', $jobId); - /** @var Response, status: string, validation_file: ?string, training_file: string, trained_tokens: ?int, error: ?array{code: string, param: ?string, message: string}}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response, status: string, validation_file: ?string, training_file: string, trained_tokens: ?int, error: ?array{code: string, param: ?string, message: string}}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = RetrieveJobResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); - return RetrieveJobResponse::from($response->data(), $response->meta()); + return $response; } /** @@ -92,9 +109,13 @@ public function listJobEvents(string $jobId, array $parameters = []): ListJobEve { $payload = Payload::retrieve('fine_tuning/jobs', $jobId, '/events', $parameters); - /** @var Response, has_more: bool}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response, has_more: bool}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = ListJobEventsResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); - return ListJobEventsResponse::from($response->data(), $response->meta()); + return $response; } } diff --git a/src/Resources/Images.php b/src/Resources/Images.php index 465678c4..579a5b08 100644 --- a/src/Resources/Images.php +++ b/src/Resources/Images.php @@ -5,6 +5,7 @@ namespace OpenAI\Resources; use OpenAI\Contracts\Resources\ImagesContract; +use OpenAI\Events\RequestHandled; use OpenAI\Responses\Images\CreateResponse; use OpenAI\Responses\Images\EditResponse; use OpenAI\Responses\Images\VariationResponse; @@ -26,10 +27,14 @@ public function create(array $parameters): CreateResponse { $payload = Payload::create('images/generations', $parameters); - /** @var Response}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); - return CreateResponse::from($response->data(), $response->meta()); + $response = CreateResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -43,10 +48,14 @@ public function edit(array $parameters): EditResponse { $payload = Payload::upload('images/edits', $parameters); - /** @var Response}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = EditResponse::from($responseRaw->data(), $responseRaw->meta()); - return EditResponse::from($response->data(), $response->meta()); + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -60,9 +69,13 @@ public function variation(array $parameters): VariationResponse { $payload = Payload::upload('images/variations', $parameters); - /** @var Response}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = VariationResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); - return VariationResponse::from($response->data(), $response->meta()); + return $response; } } diff --git a/src/Resources/Models.php b/src/Resources/Models.php index f88817f4..1f0728dd 100644 --- a/src/Resources/Models.php +++ b/src/Resources/Models.php @@ -5,6 +5,7 @@ namespace OpenAI\Resources; use OpenAI\Contracts\Resources\ModelsContract; +use OpenAI\Events\RequestHandled; use OpenAI\Responses\Models\DeleteResponse; use OpenAI\Responses\Models\ListResponse; use OpenAI\Responses\Models\RetrieveResponse; @@ -24,10 +25,14 @@ public function list(): ListResponse { $payload = Payload::list('models'); - /** @var Response}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); - return ListResponse::from($response->data(), $response->meta()); + $response = ListResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -39,10 +44,14 @@ public function retrieve(string $model): RetrieveResponse { $payload = Payload::retrieve('models', $model); - /** @var Response $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = RetrieveResponse::from($responseRaw->data(), $responseRaw->meta()); - return RetrieveResponse::from($response->data(), $response->meta()); + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -54,9 +63,13 @@ public function delete(string $model): DeleteResponse { $payload = Payload::delete('models', $model); - /** @var Response $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = DeleteResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); - return DeleteResponse::from($response->data(), $response->meta()); + return $response; } } diff --git a/src/Resources/Moderations.php b/src/Resources/Moderations.php index a979e23c..de7f4138 100644 --- a/src/Resources/Moderations.php +++ b/src/Resources/Moderations.php @@ -5,6 +5,7 @@ namespace OpenAI\Resources; use OpenAI\Contracts\Resources\ModerationsContract; +use OpenAI\Events\RequestHandled; use OpenAI\Responses\Moderations\CreateResponse; use OpenAI\ValueObjects\Transporter\Payload; use OpenAI\ValueObjects\Transporter\Response; @@ -24,9 +25,13 @@ public function create(array $parameters): CreateResponse { $payload = Payload::create('moderations', $parameters); - /** @var Response, category_scores: array, flagged: bool}>}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response, category_scores: array, flagged: bool}>}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); - return CreateResponse::from($response->data(), $response->meta()); + $response = CreateResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); + + return $response; } } diff --git a/src/Resources/Threads.php b/src/Resources/Threads.php index 8966bc70..8a2b5839 100644 --- a/src/Resources/Threads.php +++ b/src/Resources/Threads.php @@ -7,6 +7,7 @@ use OpenAI\Contracts\Resources\ThreadsContract; use OpenAI\Contracts\Resources\ThreadsMessagesContract; use OpenAI\Contracts\Resources\ThreadsRunsContract; +use OpenAI\Events\RequestHandled; use OpenAI\Responses\Threads\Runs\ThreadRunResponse; use OpenAI\Responses\Threads\ThreadDeleteResponse; use OpenAI\Responses\Threads\ThreadResponse; @@ -28,10 +29,14 @@ public function create(array $parameters): ThreadResponse { $payload = Payload::create('threads', $parameters); - /** @var Response}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); - return ThreadResponse::from($response->data(), $response->meta()); + $response = ThreadResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -45,10 +50,14 @@ public function createAndRun(array $parameters): ThreadRunResponse { $payload = Payload::create('threads/runs', $parameters); - /** @var Response}}, last_error: ?array{code: string, message: string}, expires_at: ?int, started_at: ?int, cancelled_at: ?int, failed_at: ?int, completed_at: ?int, model: string, instructions: ?string, tools: array}}>, file_ids: array, metadata: array}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response}}, last_error: ?array{code: string, message: string}, expires_at: ?int, started_at: ?int, cancelled_at: ?int, failed_at: ?int, completed_at: ?int, model: string, instructions: ?string, tools: array}}>, file_ids: array, metadata: array}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = ThreadRunResponse::from($responseRaw->data(), $responseRaw->meta()); - return ThreadRunResponse::from($response->data(), $response->meta()); + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -60,10 +69,14 @@ public function retrieve(string $id): ThreadResponse { $payload = Payload::retrieve('threads', $id); - /** @var Response}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = ThreadResponse::from($responseRaw->data(), $responseRaw->meta()); - return ThreadResponse::from($response->data(), $response->meta()); + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -77,10 +90,14 @@ public function modify(string $id, array $parameters): ThreadResponse { $payload = Payload::modify('threads', $id, $parameters); - /** @var Response}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = ThreadResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); - return ThreadResponse::from($response->data(), $response->meta()); + return $response; } /** @@ -92,10 +109,14 @@ public function delete(string $id): ThreadDeleteResponse { $payload = Payload::delete('threads', $id); - /** @var Response $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = ThreadDeleteResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); - return ThreadDeleteResponse::from($response->data(), $response->meta()); + return $response; } /** @@ -105,7 +126,7 @@ public function delete(string $id): ThreadDeleteResponse */ public function messages(): ThreadsMessagesContract { - return new ThreadsMessages($this->transporter); + return new ThreadsMessages($this->transporter, $this->events); } /** @@ -115,6 +136,6 @@ public function messages(): ThreadsMessagesContract */ public function runs(): ThreadsRunsContract { - return new ThreadsRuns($this->transporter); + return new ThreadsRuns($this->transporter, $this->events); } } diff --git a/src/Resources/ThreadsMessages.php b/src/Resources/ThreadsMessages.php index 8824f8e2..9db7c56c 100644 --- a/src/Resources/ThreadsMessages.php +++ b/src/Resources/ThreadsMessages.php @@ -6,6 +6,7 @@ use OpenAI\Contracts\Resources\ThreadsMessagesContract; use OpenAI\Contracts\Resources\ThreadsMessagesFilesContract; +use OpenAI\Events\RequestHandled; use OpenAI\Responses\Threads\Messages\ThreadMessageDeleteResponse; use OpenAI\Responses\Threads\Messages\ThreadMessageListResponse; use OpenAI\Responses\Threads\Messages\ThreadMessageResponse; @@ -27,10 +28,14 @@ public function create(string $threadId, array $parameters): ThreadMessageRespon { $payload = Payload::create("threads/$threadId/messages", $parameters); - /** @var Response}}>, assistant_id: ?string, run_id: ?string, file_ids: array, metadata: array}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response}}>, assistant_id: ?string, run_id: ?string, file_ids: array, metadata: array}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); - return ThreadMessageResponse::from($response->data(), $response->meta()); + $response = ThreadMessageResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -42,10 +47,14 @@ public function retrieve(string $threadId, string $messageId): ThreadMessageResp { $payload = Payload::retrieve("threads/$threadId/messages", $messageId); - /** @var Response}}>, assistant_id: ?string, run_id: ?string, file_ids: array, metadata: array}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response}}>, assistant_id: ?string, run_id: ?string, file_ids: array, metadata: array}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = ThreadMessageResponse::from($responseRaw->data(), $responseRaw->meta()); - return ThreadMessageResponse::from($response->data(), $response->meta()); + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -59,10 +68,14 @@ public function modify(string $threadId, string $messageId, array $parameters): { $payload = Payload::modify("threads/$threadId/messages", $messageId, $parameters); - /** @var Response}}>, assistant_id: ?string, run_id: ?string, file_ids: array, metadata: array}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response}}>, assistant_id: ?string, run_id: ?string, file_ids: array, metadata: array}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = ThreadMessageResponse::from($responseRaw->data(), $responseRaw->meta()); - return ThreadMessageResponse::from($response->data(), $response->meta()); + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -74,10 +87,14 @@ public function delete(string $threadId, string $messageId): ThreadMessageDelete { $payload = Payload::delete("threads/$threadId/messages", $messageId); - /** @var Response $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = ThreadMessageDeleteResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); - return ThreadMessageDeleteResponse::from($response->data(), $response->meta()); + return $response; } /** @@ -91,10 +108,14 @@ public function list(string $threadId, array $parameters = []): ThreadMessageLis { $payload = Payload::list("threads/$threadId/messages", $parameters); - /** @var Response}}>, assistant_id: ?string, run_id: ?string, file_ids: array, metadata: array}>, first_id: ?string, last_id: ?string, has_more: bool}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response}}>, assistant_id: ?string, run_id: ?string, file_ids: array, metadata: array}>, first_id: ?string, last_id: ?string, has_more: bool}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = ThreadMessageListResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); - return ThreadMessageListResponse::from($response->data(), $response->meta()); + return $response; } /** @@ -104,6 +125,6 @@ public function list(string $threadId, array $parameters = []): ThreadMessageLis */ public function files(): ThreadsMessagesFilesContract { - return new ThreadsMessagesFiles($this->transporter); + return new ThreadsMessagesFiles($this->transporter, $this->events); } } diff --git a/src/Resources/ThreadsMessagesFiles.php b/src/Resources/ThreadsMessagesFiles.php index d3086dde..0483e9d6 100644 --- a/src/Resources/ThreadsMessagesFiles.php +++ b/src/Resources/ThreadsMessagesFiles.php @@ -5,6 +5,7 @@ namespace OpenAI\Resources; use OpenAI\Contracts\Resources\ThreadsMessagesFilesContract; +use OpenAI\Events\RequestHandled; use OpenAI\Responses\Threads\Messages\Files\ThreadMessageFileListResponse; use OpenAI\Responses\Threads\Messages\Files\ThreadMessageFileResponse; use OpenAI\ValueObjects\Transporter\Payload; @@ -23,10 +24,14 @@ public function retrieve(string $threadId, string $messageId, string $fileId): T { $payload = Payload::retrieve("threads/$threadId/messages/$messageId/files", $fileId); - /** @var Response $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); - return ThreadMessageFileResponse::from($response->data(), $response->meta()); + $response = ThreadMessageFileResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -40,9 +45,13 @@ public function list(string $threadId, string $messageId, array $parameters = [] { $payload = Payload::list("threads/$threadId/messages/$messageId/files", $parameters); - /** @var Response, first_id: ?string, last_id: ?string, has_more: bool}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response, first_id: ?string, last_id: ?string, has_more: bool}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = ThreadMessageFileListResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); - return ThreadMessageFileListResponse::from($response->data(), $response->meta()); + return $response; } } diff --git a/src/Resources/ThreadsRuns.php b/src/Resources/ThreadsRuns.php index 64e8dc00..959ee071 100644 --- a/src/Resources/ThreadsRuns.php +++ b/src/Resources/ThreadsRuns.php @@ -6,6 +6,7 @@ use OpenAI\Contracts\Resources\ThreadsRunsContract; use OpenAI\Contracts\Resources\ThreadsRunsStepsContract; +use OpenAI\Events\RequestHandled; use OpenAI\Responses\Threads\Runs\ThreadRunListResponse; use OpenAI\Responses\Threads\Runs\ThreadRunResponse; use OpenAI\ValueObjects\Transporter\Payload; @@ -26,10 +27,14 @@ public function create(string $threadId, array $parameters): ThreadRunResponse { $payload = Payload::create('threads/'.$threadId.'/runs', $parameters); - /** @var Response}}, last_error: ?array{code: string, message: string}, expires_at: ?int, started_at: ?int, cancelled_at: ?int, failed_at: ?int, completed_at: ?int, model: string, instructions: ?string, tools: array}}>, file_ids: array, metadata: array}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response}}, last_error: ?array{code: string, message: string}, expires_at: ?int, started_at: ?int, cancelled_at: ?int, failed_at: ?int, completed_at: ?int, model: string, instructions: ?string, tools: array}}>, file_ids: array, metadata: array}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); - return ThreadRunResponse::from($response->data(), $response->meta()); + $response = ThreadRunResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -41,10 +46,14 @@ public function retrieve(string $threadId, string $runId): ThreadRunResponse { $payload = Payload::retrieve('threads/'.$threadId.'/runs', $runId); - /** @var Response}}, last_error: ?array{code: string, message: string}, expires_at: ?int, started_at: ?int, cancelled_at: ?int, failed_at: ?int, completed_at: ?int, model: string, instructions: ?string, tools: array}}>, file_ids: array, metadata: array}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response}}, last_error: ?array{code: string, message: string}, expires_at: ?int, started_at: ?int, cancelled_at: ?int, failed_at: ?int, completed_at: ?int, model: string, instructions: ?string, tools: array}}>, file_ids: array, metadata: array}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = ThreadRunResponse::from($responseRaw->data(), $responseRaw->meta()); - return ThreadRunResponse::from($response->data(), $response->meta()); + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -58,10 +67,14 @@ public function modify(string $threadId, string $runId, array $parameters): Thre { $payload = Payload::modify('threads/'.$threadId.'/runs', $runId, $parameters); - /** @var Response}}, last_error: ?array{code: string, message: string}, expires_at: ?int, started_at: ?int, cancelled_at: ?int, failed_at: ?int, completed_at: ?int, model: string, instructions: ?string, tools: array}}>, file_ids: array, metadata: array}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response}}, last_error: ?array{code: string, message: string}, expires_at: ?int, started_at: ?int, cancelled_at: ?int, failed_at: ?int, completed_at: ?int, model: string, instructions: ?string, tools: array}}>, file_ids: array, metadata: array}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = ThreadRunResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); - return ThreadRunResponse::from($response->data(), $response->meta()); + return $response; } /** @@ -75,10 +88,14 @@ public function submitToolOutputs(string $threadId, string $runId, array $parame { $payload = Payload::create('threads/'.$threadId.'/runs/'.$runId.'/submit_tool_outputs', $parameters); - /** @var Response}}, last_error: ?array{code: string, message: string}, expires_at: ?int, started_at: ?int, cancelled_at: ?int, failed_at: ?int, completed_at: ?int, model: string, instructions: ?string, tools: array}}>, file_ids: array, metadata: array}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response}}, last_error: ?array{code: string, message: string}, expires_at: ?int, started_at: ?int, cancelled_at: ?int, failed_at: ?int, completed_at: ?int, model: string, instructions: ?string, tools: array}}>, file_ids: array, metadata: array}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); - return ThreadRunResponse::from($response->data(), $response->meta()); + $response = ThreadRunResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -90,10 +107,14 @@ public function cancel(string $threadId, string $runId): ThreadRunResponse { $payload = Payload::cancel('threads/'.$threadId.'/runs', $runId); - /** @var Response}}, last_error: ?array{code: string, message: string}, expires_at: ?int, started_at: ?int, cancelled_at: ?int, failed_at: ?int, completed_at: ?int, model: string, instructions: ?string, tools: array}}>, file_ids: array, metadata: array}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response}}, last_error: ?array{code: string, message: string}, expires_at: ?int, started_at: ?int, cancelled_at: ?int, failed_at: ?int, completed_at: ?int, model: string, instructions: ?string, tools: array}}>, file_ids: array, metadata: array}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = ThreadRunResponse::from($responseRaw->data(), $responseRaw->meta()); - return ThreadRunResponse::from($response->data(), $response->meta()); + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -107,10 +128,14 @@ public function list(string $threadId, array $parameters = []): ThreadRunListRes { $payload = Payload::list('threads/'.$threadId.'/runs', $parameters); - /** @var Response}}, last_error: ?array{code: string, message: string}, expires_at: ?int, started_at: ?int, cancelled_at: ?int, failed_at: ?int, completed_at: ?int, model: string, instructions: ?string, tools: array}}>, file_ids: array, metadata: array}>, first_id: ?string, last_id: ?string, has_more: bool}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response}}, last_error: ?array{code: string, message: string}, expires_at: ?int, started_at: ?int, cancelled_at: ?int, failed_at: ?int, completed_at: ?int, model: string, instructions: ?string, tools: array}}>, file_ids: array, metadata: array}>, first_id: ?string, last_id: ?string, has_more: bool}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = ThreadRunListResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); - return ThreadRunListResponse::from($response->data(), $response->meta()); + return $response; } /** @@ -120,6 +145,6 @@ public function list(string $threadId, array $parameters = []): ThreadRunListRes */ public function steps(): ThreadsRunsStepsContract { - return new ThreadsRunsSteps($this->transporter); + return new ThreadsRunsSteps($this->transporter, $this->events); } } diff --git a/src/Resources/ThreadsRunsSteps.php b/src/Resources/ThreadsRunsSteps.php index a914956f..40164ff3 100644 --- a/src/Resources/ThreadsRunsSteps.php +++ b/src/Resources/ThreadsRunsSteps.php @@ -5,6 +5,7 @@ namespace OpenAI\Resources; use OpenAI\Contracts\Resources\ThreadsRunsStepsContract; +use OpenAI\Events\RequestHandled; use OpenAI\Responses\Threads\Runs\Steps\ThreadRunStepListResponse; use OpenAI\Responses\Threads\Runs\Steps\ThreadRunStepResponse; use OpenAI\ValueObjects\Transporter\Payload; @@ -23,10 +24,14 @@ public function retrieve(string $threadId, string $runId, string $stepId): Threa { $payload = Payload::retrieve('threads/'.$threadId.'/runs/'.$runId.'/steps', $stepId); - /** @var Response}}|array{id: string, type: 'retrieval', retrieval: array}|array{id: string, type: 'function', function: array{name: string, arguments: string, output: ?string}}>}|array{type: 'message_creation', message_creation: array{message_id: string}}, last_error: ?array{code: string, message: string}, expires_at: ?int, cancelled_at: ?int, failed_at: ?int, completed_at: ?int, metadata?: array}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response}}|array{id: string, type: 'retrieval', retrieval: array}|array{id: string, type: 'function', function: array{name: string, arguments: string, output: ?string}}>}|array{type: 'message_creation', message_creation: array{message_id: string}}, last_error: ?array{code: string, message: string}, expires_at: ?int, cancelled_at: ?int, failed_at: ?int, completed_at: ?int, metadata?: array}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); - return ThreadRunStepResponse::from($response->data(), $response->meta()); + $response = ThreadRunStepResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); + + return $response; } /** @@ -40,9 +45,13 @@ public function list(string $threadId, string $runId, array $parameters = []): T { $payload = Payload::list('threads/'.$threadId.'/runs/'.$runId.'/steps', $parameters); - /** @var Response}}|array{id: string, type: 'retrieval', retrieval: array}|array{id: string, type: 'function', function: array{name: string, arguments: string, output: ?string}}>}|array{type: 'message_creation', message_creation: array{message_id: string}}, last_error: ?array{code: string, message: string}, expires_at: ?int, cancelled_at: ?int, failed_at: ?int, completed_at: ?int, metadata?: array}>, first_id: ?string, last_id: ?string, has_more: bool}> $response */ - $response = $this->transporter->requestObject($payload); + /** @var Response}}|array{id: string, type: 'retrieval', retrieval: array}|array{id: string, type: 'function', function: array{name: string, arguments: string, output: ?string}}>}|array{type: 'message_creation', message_creation: array{message_id: string}}, last_error: ?array{code: string, message: string}, expires_at: ?int, cancelled_at: ?int, failed_at: ?int, completed_at: ?int, metadata?: array}>, first_id: ?string, last_id: ?string, has_more: bool}> $responseRaw */ + $responseRaw = $this->transporter->requestObject($payload); + + $response = ThreadRunStepListResponse::from($responseRaw->data(), $responseRaw->meta()); + + $this->event(new RequestHandled($payload, $response)); - return ThreadRunStepListResponse::from($response->data(), $response->meta()); + return $response; } } diff --git a/tests/Arch.php b/tests/Arch.php index 69aa3d56..e0c1bc48 100644 --- a/tests/Arch.php +++ b/tests/Arch.php @@ -23,6 +23,7 @@ test('resources')->expect('OpenAI\Resources')->toOnlyUse([ 'OpenAI\Contracts', + 'OpenAI\Events', 'OpenAI\ValueObjects', 'OpenAI\Exceptions', 'OpenAI\Responses', @@ -31,6 +32,7 @@ test('responses')->expect('OpenAI\Responses')->toOnlyUse([ 'Http\Discovery\Psr17Factory', 'OpenAI\Enums', + 'OpenAI\Events', 'OpenAI\Exceptions\ErrorException', 'OpenAI\Contracts', 'OpenAI\Testing\Responses\Concerns', @@ -49,6 +51,7 @@ ]); test('client')->expect('OpenAI\Client')->toOnlyUse([ + 'OpenAI\Events', 'OpenAI\Resources', 'OpenAI\Contracts', ]); @@ -59,8 +62,10 @@ 'Http\Discovery\Psr17Factory', 'Http\Discovery\Psr18ClientDiscovery', 'Http\Message\MultipartStream\MultipartStreamBuilder', + 'Illuminate\Contracts\Events\Dispatcher', 'OpenAI\Contracts', 'OpenAI\Resources', + 'Psr\EventDispatcher\EventDispatcherInterface', 'Psr\Http\Client', 'Psr\Http\Message\RequestInterface', 'Psr\Http\Message\ResponseInterface', diff --git a/tests/Pest.php b/tests/Pest.php index e8d8de39..ce7f8e85 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -1,6 +1,7 @@ getUri()->getPath() === "/v1/$resource"; })->andReturn($response); - return new Client($transporter); + $dispatcher = Mockery::mock(DispatcherContract::class); + + $dispatcher + ->shouldReceive('dispatch') + ->once(); + + return new Client($transporter, $dispatcher); } function mockContentClient(string $method, string $resource, array $params, string $response, bool $validateParams = true) From b31e48c9aae741e25bb1ad603c3dbd828c7370f5 Mon Sep 17 00:00:00 2001 From: gehrisandro Date: Tue, 5 Dec 2023 14:41:53 +0100 Subject: [PATCH 4/9] Remove Laravel dependency --- composer.json | 1 - src/Events/Dispatcher.php | 3 +-- src/Factory.php | 5 ++--- tests/Arch.php | 1 - 4 files changed, 3 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index 47f5ec7e..7de32e3e 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,6 @@ "require-dev": { "guzzlehttp/guzzle": "^7.8.0", "guzzlehttp/psr7": "^2.6.1", - "illuminate/contracts": "^9.0|^10.0", "laravel/pint": "^1.13.6", "mockery/mockery": "^1.6.6", "nunomaduro/collision": "^7.10.0", diff --git a/src/Events/Dispatcher.php b/src/Events/Dispatcher.php index b061f100..1f6203fd 100644 --- a/src/Events/Dispatcher.php +++ b/src/Events/Dispatcher.php @@ -2,14 +2,13 @@ namespace OpenAI\Events; -use Illuminate\Contracts\Events\Dispatcher as LaravelDispatcher; use OpenAI\Contracts\DispatcherContract; use Psr\EventDispatcher\EventDispatcherInterface; class Dispatcher implements DispatcherContract { public function __construct( - private readonly LaravelDispatcher|EventDispatcherInterface|null $events + private readonly ?EventDispatcherInterface $events ) { } diff --git a/src/Factory.php b/src/Factory.php index 653ee9a4..37d2ad40 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -6,7 +6,6 @@ use Exception; use GuzzleHttp\Client as GuzzleClient; use Http\Discovery\Psr18ClientDiscovery; -use Illuminate\Contracts\Events\Dispatcher as LaravelDispatcher; use OpenAI\Events\Dispatcher; use OpenAI\Transporters\HttpTransporter; use OpenAI\ValueObjects\ApiKey; @@ -57,7 +56,7 @@ final class Factory private ?Closure $streamHandler = null; - private LaravelDispatcher|EventDispatcherInterface|null $events = null; + private ?EventDispatcherInterface $events = null; /** * Sets the API key for the requests. @@ -134,7 +133,7 @@ public function withQueryParam(string $name, string $value): self /** * Set the event dispatcher instance. */ - public function withEventDispatcher(LaravelDispatcher|EventDispatcherInterface $events): self + public function withEventDispatcher(EventDispatcherInterface $events): self { $this->events = $events; diff --git a/tests/Arch.php b/tests/Arch.php index e0c1bc48..3ad213c3 100644 --- a/tests/Arch.php +++ b/tests/Arch.php @@ -62,7 +62,6 @@ 'Http\Discovery\Psr17Factory', 'Http\Discovery\Psr18ClientDiscovery', 'Http\Message\MultipartStream\MultipartStreamBuilder', - 'Illuminate\Contracts\Events\Dispatcher', 'OpenAI\Contracts', 'OpenAI\Resources', 'Psr\EventDispatcher\EventDispatcherInterface', From 0aeac987c761c2fc0f9b8bd2f709f43cc9b3df90 Mon Sep 17 00:00:00 2001 From: gehrisandro Date: Tue, 5 Dec 2023 14:51:29 +0100 Subject: [PATCH 5/9] Add NullEventDispatcher --- rector.php | 2 ++ src/Events/Dispatcher.php | 4 ++-- src/Events/NullEventDispatcher.php | 13 +++++++++++++ src/Factory.php | 3 ++- 4 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 src/Events/NullEventDispatcher.php diff --git a/rector.php b/rector.php index da8a14ea..9dbddc56 100644 --- a/rector.php +++ b/rector.php @@ -7,6 +7,7 @@ use Rector\Privatization\Rector\Class_\FinalizeClassesWithoutChildrenRector; use Rector\Set\ValueObject\LevelSetList; use Rector\Set\ValueObject\SetList; +use Rector\TypeDeclaration\Rector\ClassMethod\AddVoidReturnTypeWhereNoReturnRector; return static function (RectorConfig $rectorConfig): void { $rectorConfig->paths([ @@ -15,6 +16,7 @@ $rectorConfig->skip([ __DIR__.'/src/Testing/ClientFake.php' => FinalizeClassesWithoutChildrenRector::class, + __DIR__.'/src/Events/NullEventDispatcher.php' => AddVoidReturnTypeWhereNoReturnRector::class, ]); $rectorConfig->rules([ diff --git a/src/Events/Dispatcher.php b/src/Events/Dispatcher.php index 1f6203fd..fe90640c 100644 --- a/src/Events/Dispatcher.php +++ b/src/Events/Dispatcher.php @@ -8,12 +8,12 @@ class Dispatcher implements DispatcherContract { public function __construct( - private readonly ?EventDispatcherInterface $events + private readonly EventDispatcherInterface $events ) { } public function dispatch(object $event): void { - $this->events?->dispatch($event); + $this->events->dispatch($event); } } diff --git a/src/Events/NullEventDispatcher.php b/src/Events/NullEventDispatcher.php new file mode 100644 index 00000000..5d7a5487 --- /dev/null +++ b/src/Events/NullEventDispatcher.php @@ -0,0 +1,13 @@ +events); + $dispatcher = new Dispatcher($this->events ?? new NullEventDispatcher); return new Client($transporter, $dispatcher); } From 8d5f752a708e17da6190a28818f8e27e19a1a4e6 Mon Sep 17 00:00:00 2001 From: gehrisandro Date: Tue, 5 Dec 2023 15:22:29 +0100 Subject: [PATCH 6/9] Move event handling to a dedicated Dispatchable trait --- src/Client.php | 39 ++++++++++++++++-------- src/Resources/Assistants.php | 4 ++- src/Resources/AssistantsFiles.php | 1 + src/Resources/Audio.php | 1 + src/Resources/Chat.php | 1 + src/Resources/Completions.php | 1 + src/Resources/Concerns/Dispatchable.php | 24 +++++++++++++++ src/Resources/Concerns/Transportable.php | 12 ++------ src/Resources/Edits.php | 1 + src/Resources/Embeddings.php | 1 + src/Resources/Files.php | 1 + src/Resources/FineTunes.php | 1 + src/Resources/FineTuning.php | 1 + src/Resources/Images.php | 1 + src/Resources/Models.php | 1 + src/Resources/Moderations.php | 1 + src/Resources/Threads.php | 7 +++-- src/Resources/ThreadsMessages.php | 4 ++- src/Resources/ThreadsMessagesFiles.php | 1 + src/Resources/ThreadsRuns.php | 4 ++- src/Resources/ThreadsRunsSteps.php | 1 + 21 files changed, 80 insertions(+), 28 deletions(-) create mode 100644 src/Resources/Concerns/Dispatchable.php diff --git a/src/Client.php b/src/Client.php index 6a292d39..2500c444 100644 --- a/src/Client.php +++ b/src/Client.php @@ -42,7 +42,8 @@ public function __construct( */ public function completions(): Completions { - return new Completions($this->transporter, $this->events); + return (new Completions($this->transporter)) + ->setEventDispatcher($this->events); } /** @@ -52,7 +53,8 @@ public function completions(): Completions */ public function chat(): Chat { - return new Chat($this->transporter, $this->events); + return (new Chat($this->transporter)) + ->setEventDispatcher($this->events); } /** @@ -62,7 +64,8 @@ public function chat(): Chat */ public function embeddings(): Embeddings { - return new Embeddings($this->transporter, $this->events); + return (new Embeddings($this->transporter)) + ->setEventDispatcher($this->events); } /** @@ -72,7 +75,8 @@ public function embeddings(): Embeddings */ public function audio(): Audio { - return new Audio($this->transporter, $this->events); + return (new Audio($this->transporter)) + ->setEventDispatcher($this->events); } /** @@ -82,7 +86,8 @@ public function audio(): Audio */ public function edits(): Edits { - return new Edits($this->transporter, $this->events); + return (new Edits($this->transporter)) + ->setEventDispatcher($this->events); } /** @@ -92,7 +97,8 @@ public function edits(): Edits */ public function files(): Files { - return new Files($this->transporter, $this->events); + return (new Files($this->transporter)) + ->setEventDispatcher($this->events); } /** @@ -102,7 +108,8 @@ public function files(): Files */ public function models(): Models { - return new Models($this->transporter, $this->events); + return (new Models($this->transporter)) + ->setEventDispatcher($this->events); } /** @@ -112,7 +119,8 @@ public function models(): Models */ public function fineTuning(): FineTuning { - return new FineTuning($this->transporter, $this->events); + return (new FineTuning($this->transporter)) + ->setEventDispatcher($this->events); } /** @@ -124,7 +132,8 @@ public function fineTuning(): FineTuning */ public function fineTunes(): FineTunes { - return new FineTunes($this->transporter, $this->events); + return (new FineTunes($this->transporter)) + ->setEventDispatcher($this->events); } /** @@ -134,7 +143,8 @@ public function fineTunes(): FineTunes */ public function moderations(): Moderations { - return new Moderations($this->transporter, $this->events); + return (new Moderations($this->transporter)) + ->setEventDispatcher($this->events); } /** @@ -144,7 +154,8 @@ public function moderations(): Moderations */ public function images(): Images { - return new Images($this->transporter, $this->events); + return (new Images($this->transporter)) + ->setEventDispatcher($this->events); } /** @@ -154,7 +165,8 @@ public function images(): Images */ public function assistants(): Assistants { - return new Assistants($this->transporter, $this->events); + return (new Assistants($this->transporter)) + ->setEventDispatcher($this->events); } /** @@ -164,6 +176,7 @@ public function assistants(): Assistants */ public function threads(): ThreadsContract { - return new Threads($this->transporter, $this->events); + return (new Threads($this->transporter)) + ->setEventDispatcher($this->events); } } diff --git a/src/Resources/Assistants.php b/src/Resources/Assistants.php index 1d061bd1..489e3162 100644 --- a/src/Resources/Assistants.php +++ b/src/Resources/Assistants.php @@ -15,6 +15,7 @@ final class Assistants implements AssistantsContract { + use Concerns\Dispatchable; use Concerns\Transportable; /** @@ -125,6 +126,7 @@ public function list(array $parameters = []): AssistantListResponse */ public function files(): AssistantsFilesContract { - return new AssistantsFiles($this->transporter, $this->events); + return (new AssistantsFiles($this->transporter)) + ->setEventDispatcher($this->events); } } diff --git a/src/Resources/AssistantsFiles.php b/src/Resources/AssistantsFiles.php index e93ab140..005c2c9b 100644 --- a/src/Resources/AssistantsFiles.php +++ b/src/Resources/AssistantsFiles.php @@ -14,6 +14,7 @@ final class AssistantsFiles implements AssistantsFilesContract { + use Concerns\Dispatchable; use Concerns\Transportable; /** diff --git a/src/Resources/Audio.php b/src/Resources/Audio.php index 04bf57fd..dd1d51cb 100644 --- a/src/Resources/Audio.php +++ b/src/Resources/Audio.php @@ -14,6 +14,7 @@ final class Audio implements AudioContract { + use Concerns\Dispatchable; use Concerns\Transportable; /** diff --git a/src/Resources/Chat.php b/src/Resources/Chat.php index 068ade9a..c67884dc 100644 --- a/src/Resources/Chat.php +++ b/src/Resources/Chat.php @@ -14,6 +14,7 @@ final class Chat implements ChatContract { + use Concerns\Dispatchable; use Concerns\Streamable; use Concerns\Transportable; diff --git a/src/Resources/Completions.php b/src/Resources/Completions.php index 00e85092..9d4d1c12 100644 --- a/src/Resources/Completions.php +++ b/src/Resources/Completions.php @@ -14,6 +14,7 @@ final class Completions implements CompletionsContract { + use Concerns\Dispatchable; use Concerns\Streamable; use Concerns\Transportable; diff --git a/src/Resources/Concerns/Dispatchable.php b/src/Resources/Concerns/Dispatchable.php new file mode 100644 index 00000000..d20fb812 --- /dev/null +++ b/src/Resources/Concerns/Dispatchable.php @@ -0,0 +1,24 @@ +events = $events; + + return $this; + } + + public function event(object $event): void + { + $this->events->dispatch($event); + } +} diff --git a/src/Resources/Concerns/Transportable.php b/src/Resources/Concerns/Transportable.php index b947a6f3..091511f9 100644 --- a/src/Resources/Concerns/Transportable.php +++ b/src/Resources/Concerns/Transportable.php @@ -4,7 +4,6 @@ namespace OpenAI\Resources\Concerns; -use OpenAI\Contracts\DispatcherContract; use OpenAI\Contracts\TransporterContract; trait Transportable @@ -12,15 +11,8 @@ trait Transportable /** * Creates a Client instance with the given API token. */ - public function __construct( - private readonly TransporterContract $transporter, - private readonly DispatcherContract $events, - ) { - // .. - } - - public function event(object $event): void + public function __construct(private readonly TransporterContract $transporter) { - $this->events->dispatch($event); + // .. } } diff --git a/src/Resources/Edits.php b/src/Resources/Edits.php index 3f702f32..cf8b0393 100644 --- a/src/Resources/Edits.php +++ b/src/Resources/Edits.php @@ -12,6 +12,7 @@ final class Edits implements EditsContract { + use Concerns\Dispatchable; use Concerns\Transportable; /** diff --git a/src/Resources/Embeddings.php b/src/Resources/Embeddings.php index 7380fa6f..59770804 100644 --- a/src/Resources/Embeddings.php +++ b/src/Resources/Embeddings.php @@ -12,6 +12,7 @@ final class Embeddings implements EmbeddingsContract { + use Concerns\Dispatchable; use Concerns\Transportable; /** diff --git a/src/Resources/Files.php b/src/Resources/Files.php index e1bbf1da..b440424a 100644 --- a/src/Resources/Files.php +++ b/src/Resources/Files.php @@ -15,6 +15,7 @@ final class Files implements FilesContract { + use Concerns\Dispatchable; use Concerns\Transportable; /** diff --git a/src/Resources/FineTunes.php b/src/Resources/FineTunes.php index 66db8c2b..5fe7c8bf 100644 --- a/src/Resources/FineTunes.php +++ b/src/Resources/FineTunes.php @@ -16,6 +16,7 @@ final class FineTunes implements FineTunesContract { + use Concerns\Dispatchable; use Concerns\Transportable; /** diff --git a/src/Resources/FineTuning.php b/src/Resources/FineTuning.php index 59e07108..6c734eda 100644 --- a/src/Resources/FineTuning.php +++ b/src/Resources/FineTuning.php @@ -14,6 +14,7 @@ final class FineTuning implements FineTuningContract { + use Concerns\Dispatchable; use Concerns\Transportable; /** diff --git a/src/Resources/Images.php b/src/Resources/Images.php index 579a5b08..094d5160 100644 --- a/src/Resources/Images.php +++ b/src/Resources/Images.php @@ -14,6 +14,7 @@ final class Images implements ImagesContract { + use Concerns\Dispatchable; use Concerns\Transportable; /** diff --git a/src/Resources/Models.php b/src/Resources/Models.php index 1f0728dd..269f4d4e 100644 --- a/src/Resources/Models.php +++ b/src/Resources/Models.php @@ -14,6 +14,7 @@ final class Models implements ModelsContract { + use Concerns\Dispatchable; use Concerns\Transportable; /** diff --git a/src/Resources/Moderations.php b/src/Resources/Moderations.php index de7f4138..de5cf1e2 100644 --- a/src/Resources/Moderations.php +++ b/src/Resources/Moderations.php @@ -12,6 +12,7 @@ final class Moderations implements ModerationsContract { + use Concerns\Dispatchable; use Concerns\Transportable; /** diff --git a/src/Resources/Threads.php b/src/Resources/Threads.php index 8a2b5839..0c73e2dd 100644 --- a/src/Resources/Threads.php +++ b/src/Resources/Threads.php @@ -16,6 +16,7 @@ final class Threads implements ThreadsContract { + use Concerns\Dispatchable; use Concerns\Transportable; /** @@ -126,7 +127,8 @@ public function delete(string $id): ThreadDeleteResponse */ public function messages(): ThreadsMessagesContract { - return new ThreadsMessages($this->transporter, $this->events); + return (new ThreadsMessages($this->transporter)) + ->setEventDispatcher($this->events); } /** @@ -136,6 +138,7 @@ public function messages(): ThreadsMessagesContract */ public function runs(): ThreadsRunsContract { - return new ThreadsRuns($this->transporter, $this->events); + return (new ThreadsRuns($this->transporter)) + ->setEventDispatcher($this->events); } } diff --git a/src/Resources/ThreadsMessages.php b/src/Resources/ThreadsMessages.php index 9db7c56c..8f3b7c8c 100644 --- a/src/Resources/ThreadsMessages.php +++ b/src/Resources/ThreadsMessages.php @@ -15,6 +15,7 @@ final class ThreadsMessages implements ThreadsMessagesContract { + use Concerns\Dispatchable; use Concerns\Transportable; /** @@ -125,6 +126,7 @@ public function list(string $threadId, array $parameters = []): ThreadMessageLis */ public function files(): ThreadsMessagesFilesContract { - return new ThreadsMessagesFiles($this->transporter, $this->events); + return (new ThreadsMessagesFiles($this->transporter)) + ->setEventDispatcher($this->events); } } diff --git a/src/Resources/ThreadsMessagesFiles.php b/src/Resources/ThreadsMessagesFiles.php index 0483e9d6..afb4fc18 100644 --- a/src/Resources/ThreadsMessagesFiles.php +++ b/src/Resources/ThreadsMessagesFiles.php @@ -13,6 +13,7 @@ final class ThreadsMessagesFiles implements ThreadsMessagesFilesContract { + use Concerns\Dispatchable; use Concerns\Transportable; /** diff --git a/src/Resources/ThreadsRuns.php b/src/Resources/ThreadsRuns.php index 959ee071..ebd8f2e4 100644 --- a/src/Resources/ThreadsRuns.php +++ b/src/Resources/ThreadsRuns.php @@ -14,6 +14,7 @@ final class ThreadsRuns implements ThreadsRunsContract { + use Concerns\Dispatchable; use Concerns\Transportable; /** @@ -145,6 +146,7 @@ public function list(string $threadId, array $parameters = []): ThreadRunListRes */ public function steps(): ThreadsRunsStepsContract { - return new ThreadsRunsSteps($this->transporter, $this->events); + return (new ThreadsRunsSteps($this->transporter)) + ->setEventDispatcher($this->events); } } diff --git a/src/Resources/ThreadsRunsSteps.php b/src/Resources/ThreadsRunsSteps.php index 40164ff3..d819e4e4 100644 --- a/src/Resources/ThreadsRunsSteps.php +++ b/src/Resources/ThreadsRunsSteps.php @@ -13,6 +13,7 @@ final class ThreadsRunsSteps implements ThreadsRunsStepsContract { + use Concerns\Dispatchable; use Concerns\Transportable; /** From 614d9c951c2cd9164947b80ed10e00945979a689 Mon Sep 17 00:00:00 2001 From: gehrisandro Date: Wed, 6 Dec 2023 08:30:37 +0100 Subject: [PATCH 7/9] Refactor to an abstract Resource --- src/Client.php | 39 ++++++++---------------- src/Resources/Assistants.php | 8 ++--- src/Resources/AssistantsFiles.php | 5 +-- src/Resources/Audio.php | 5 +-- src/Resources/Chat.php | 4 +-- src/Resources/Completions.php | 4 +-- src/Resources/Concerns/Dispatchable.php | 24 --------------- src/Resources/Concerns/Transportable.php | 18 ----------- src/Resources/Edits.php | 5 +-- src/Resources/Embeddings.php | 5 +-- src/Resources/Files.php | 5 +-- src/Resources/FineTunes.php | 5 +-- src/Resources/FineTuning.php | 5 +-- src/Resources/Images.php | 5 +-- src/Resources/Models.php | 5 +-- src/Resources/Moderations.php | 5 +-- src/Resources/Resource.php | 21 +++++++++++++ src/Resources/Threads.php | 11 ++----- src/Resources/ThreadsMessages.php | 8 ++--- src/Resources/ThreadsMessagesFiles.php | 5 +-- src/Resources/ThreadsRuns.php | 8 ++--- src/Resources/ThreadsRunsSteps.php | 5 +-- 22 files changed, 57 insertions(+), 148 deletions(-) delete mode 100644 src/Resources/Concerns/Dispatchable.php delete mode 100644 src/Resources/Concerns/Transportable.php create mode 100644 src/Resources/Resource.php diff --git a/src/Client.php b/src/Client.php index 2500c444..6a292d39 100644 --- a/src/Client.php +++ b/src/Client.php @@ -42,8 +42,7 @@ public function __construct( */ public function completions(): Completions { - return (new Completions($this->transporter)) - ->setEventDispatcher($this->events); + return new Completions($this->transporter, $this->events); } /** @@ -53,8 +52,7 @@ public function completions(): Completions */ public function chat(): Chat { - return (new Chat($this->transporter)) - ->setEventDispatcher($this->events); + return new Chat($this->transporter, $this->events); } /** @@ -64,8 +62,7 @@ public function chat(): Chat */ public function embeddings(): Embeddings { - return (new Embeddings($this->transporter)) - ->setEventDispatcher($this->events); + return new Embeddings($this->transporter, $this->events); } /** @@ -75,8 +72,7 @@ public function embeddings(): Embeddings */ public function audio(): Audio { - return (new Audio($this->transporter)) - ->setEventDispatcher($this->events); + return new Audio($this->transporter, $this->events); } /** @@ -86,8 +82,7 @@ public function audio(): Audio */ public function edits(): Edits { - return (new Edits($this->transporter)) - ->setEventDispatcher($this->events); + return new Edits($this->transporter, $this->events); } /** @@ -97,8 +92,7 @@ public function edits(): Edits */ public function files(): Files { - return (new Files($this->transporter)) - ->setEventDispatcher($this->events); + return new Files($this->transporter, $this->events); } /** @@ -108,8 +102,7 @@ public function files(): Files */ public function models(): Models { - return (new Models($this->transporter)) - ->setEventDispatcher($this->events); + return new Models($this->transporter, $this->events); } /** @@ -119,8 +112,7 @@ public function models(): Models */ public function fineTuning(): FineTuning { - return (new FineTuning($this->transporter)) - ->setEventDispatcher($this->events); + return new FineTuning($this->transporter, $this->events); } /** @@ -132,8 +124,7 @@ public function fineTuning(): FineTuning */ public function fineTunes(): FineTunes { - return (new FineTunes($this->transporter)) - ->setEventDispatcher($this->events); + return new FineTunes($this->transporter, $this->events); } /** @@ -143,8 +134,7 @@ public function fineTunes(): FineTunes */ public function moderations(): Moderations { - return (new Moderations($this->transporter)) - ->setEventDispatcher($this->events); + return new Moderations($this->transporter, $this->events); } /** @@ -154,8 +144,7 @@ public function moderations(): Moderations */ public function images(): Images { - return (new Images($this->transporter)) - ->setEventDispatcher($this->events); + return new Images($this->transporter, $this->events); } /** @@ -165,8 +154,7 @@ public function images(): Images */ public function assistants(): Assistants { - return (new Assistants($this->transporter)) - ->setEventDispatcher($this->events); + return new Assistants($this->transporter, $this->events); } /** @@ -176,7 +164,6 @@ public function assistants(): Assistants */ public function threads(): ThreadsContract { - return (new Threads($this->transporter)) - ->setEventDispatcher($this->events); + return new Threads($this->transporter, $this->events); } } diff --git a/src/Resources/Assistants.php b/src/Resources/Assistants.php index 489e3162..722b507a 100644 --- a/src/Resources/Assistants.php +++ b/src/Resources/Assistants.php @@ -13,11 +13,8 @@ use OpenAI\ValueObjects\Transporter\Payload; use OpenAI\ValueObjects\Transporter\Response; -final class Assistants implements AssistantsContract +final class Assistants extends Resource implements AssistantsContract { - use Concerns\Dispatchable; - use Concerns\Transportable; - /** * Create an assistant with a model and instructions. * @@ -126,7 +123,6 @@ public function list(array $parameters = []): AssistantListResponse */ public function files(): AssistantsFilesContract { - return (new AssistantsFiles($this->transporter)) - ->setEventDispatcher($this->events); + return new AssistantsFiles($this->transporter, $this->events); } } diff --git a/src/Resources/AssistantsFiles.php b/src/Resources/AssistantsFiles.php index 005c2c9b..d8a4ba48 100644 --- a/src/Resources/AssistantsFiles.php +++ b/src/Resources/AssistantsFiles.php @@ -12,11 +12,8 @@ use OpenAI\ValueObjects\Transporter\Payload; use OpenAI\ValueObjects\Transporter\Response; -final class AssistantsFiles implements AssistantsFilesContract +final class AssistantsFiles extends Resource implements AssistantsFilesContract { - use Concerns\Dispatchable; - use Concerns\Transportable; - /** * Create an assistant file by attaching a File to an assistant. * diff --git a/src/Resources/Audio.php b/src/Resources/Audio.php index dd1d51cb..cdb8a438 100644 --- a/src/Resources/Audio.php +++ b/src/Resources/Audio.php @@ -12,11 +12,8 @@ use OpenAI\ValueObjects\Transporter\Payload; use OpenAI\ValueObjects\Transporter\Response; -final class Audio implements AudioContract +final class Audio extends Resource implements AudioContract { - use Concerns\Dispatchable; - use Concerns\Transportable; - /** * Generates audio from the input text. * diff --git a/src/Resources/Chat.php b/src/Resources/Chat.php index c67884dc..d60a9b4b 100644 --- a/src/Resources/Chat.php +++ b/src/Resources/Chat.php @@ -12,11 +12,9 @@ use OpenAI\ValueObjects\Transporter\Payload; use OpenAI\ValueObjects\Transporter\Response; -final class Chat implements ChatContract +final class Chat extends Resource implements ChatContract { - use Concerns\Dispatchable; use Concerns\Streamable; - use Concerns\Transportable; /** * Creates a completion for the chat message diff --git a/src/Resources/Completions.php b/src/Resources/Completions.php index 9d4d1c12..ffec9703 100644 --- a/src/Resources/Completions.php +++ b/src/Resources/Completions.php @@ -12,11 +12,9 @@ use OpenAI\ValueObjects\Transporter\Payload; use OpenAI\ValueObjects\Transporter\Response; -final class Completions implements CompletionsContract +final class Completions extends Resource implements CompletionsContract { - use Concerns\Dispatchable; use Concerns\Streamable; - use Concerns\Transportable; /** * Creates a completion for the provided prompt and parameters diff --git a/src/Resources/Concerns/Dispatchable.php b/src/Resources/Concerns/Dispatchable.php deleted file mode 100644 index d20fb812..00000000 --- a/src/Resources/Concerns/Dispatchable.php +++ /dev/null @@ -1,24 +0,0 @@ -events = $events; - - return $this; - } - - public function event(object $event): void - { - $this->events->dispatch($event); - } -} diff --git a/src/Resources/Concerns/Transportable.php b/src/Resources/Concerns/Transportable.php deleted file mode 100644 index 091511f9..00000000 --- a/src/Resources/Concerns/Transportable.php +++ /dev/null @@ -1,18 +0,0 @@ -events->dispatch($event); + } +} diff --git a/src/Resources/Threads.php b/src/Resources/Threads.php index 0c73e2dd..21cd426b 100644 --- a/src/Resources/Threads.php +++ b/src/Resources/Threads.php @@ -14,11 +14,8 @@ use OpenAI\ValueObjects\Transporter\Payload; use OpenAI\ValueObjects\Transporter\Response; -final class Threads implements ThreadsContract +final class Threads extends Resource implements ThreadsContract { - use Concerns\Dispatchable; - use Concerns\Transportable; - /** * Create a thread. * @@ -127,8 +124,7 @@ public function delete(string $id): ThreadDeleteResponse */ public function messages(): ThreadsMessagesContract { - return (new ThreadsMessages($this->transporter)) - ->setEventDispatcher($this->events); + return new ThreadsMessages($this->transporter, $this->events); } /** @@ -138,7 +134,6 @@ public function messages(): ThreadsMessagesContract */ public function runs(): ThreadsRunsContract { - return (new ThreadsRuns($this->transporter)) - ->setEventDispatcher($this->events); + return new ThreadsRuns($this->transporter, $this->events); } } diff --git a/src/Resources/ThreadsMessages.php b/src/Resources/ThreadsMessages.php index 8f3b7c8c..720663b6 100644 --- a/src/Resources/ThreadsMessages.php +++ b/src/Resources/ThreadsMessages.php @@ -13,11 +13,8 @@ use OpenAI\ValueObjects\Transporter\Payload; use OpenAI\ValueObjects\Transporter\Response; -final class ThreadsMessages implements ThreadsMessagesContract +final class ThreadsMessages extends Resource implements ThreadsMessagesContract { - use Concerns\Dispatchable; - use Concerns\Transportable; - /** * Create a message. * @@ -126,7 +123,6 @@ public function list(string $threadId, array $parameters = []): ThreadMessageLis */ public function files(): ThreadsMessagesFilesContract { - return (new ThreadsMessagesFiles($this->transporter)) - ->setEventDispatcher($this->events); + return new ThreadsMessagesFiles($this->transporter, $this->events); } } diff --git a/src/Resources/ThreadsMessagesFiles.php b/src/Resources/ThreadsMessagesFiles.php index afb4fc18..068944a1 100644 --- a/src/Resources/ThreadsMessagesFiles.php +++ b/src/Resources/ThreadsMessagesFiles.php @@ -11,11 +11,8 @@ use OpenAI\ValueObjects\Transporter\Payload; use OpenAI\ValueObjects\Transporter\Response; -final class ThreadsMessagesFiles implements ThreadsMessagesFilesContract +final class ThreadsMessagesFiles extends Resource implements ThreadsMessagesFilesContract { - use Concerns\Dispatchable; - use Concerns\Transportable; - /** * Retrieves a message file. * diff --git a/src/Resources/ThreadsRuns.php b/src/Resources/ThreadsRuns.php index ebd8f2e4..eeae8047 100644 --- a/src/Resources/ThreadsRuns.php +++ b/src/Resources/ThreadsRuns.php @@ -12,11 +12,8 @@ use OpenAI\ValueObjects\Transporter\Payload; use OpenAI\ValueObjects\Transporter\Response; -final class ThreadsRuns implements ThreadsRunsContract +final class ThreadsRuns extends Resource implements ThreadsRunsContract { - use Concerns\Dispatchable; - use Concerns\Transportable; - /** * Create a run. * @@ -146,7 +143,6 @@ public function list(string $threadId, array $parameters = []): ThreadRunListRes */ public function steps(): ThreadsRunsStepsContract { - return (new ThreadsRunsSteps($this->transporter)) - ->setEventDispatcher($this->events); + return new ThreadsRunsSteps($this->transporter, $this->events); } } diff --git a/src/Resources/ThreadsRunsSteps.php b/src/Resources/ThreadsRunsSteps.php index d819e4e4..c85d6167 100644 --- a/src/Resources/ThreadsRunsSteps.php +++ b/src/Resources/ThreadsRunsSteps.php @@ -11,11 +11,8 @@ use OpenAI\ValueObjects\Transporter\Payload; use OpenAI\ValueObjects\Transporter\Response; -final class ThreadsRunsSteps implements ThreadsRunsStepsContract +final class ThreadsRunsSteps extends Resource implements ThreadsRunsStepsContract { - use Concerns\Dispatchable; - use Concerns\Transportable; - /** * Retrieves a run step. * From 049aa145f67d0197f813fafbaa9bb2d6f2a9b900 Mon Sep 17 00:00:00 2001 From: gehrisandro Date: Wed, 6 Dec 2023 08:32:21 +0100 Subject: [PATCH 8/9] Run lint with newest Pint release --- src/OpenAI.php | 2 +- src/Responses/Audio/SpeechStreamResponse.php | 2 +- src/Testing/ClientFake.php | 6 +++--- src/Testing/Resources/Concerns/Testable.php | 4 ++-- src/Testing/Responses/Concerns/Fakeable.php | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/OpenAI.php b/src/OpenAI.php index 14f8c05a..3ab2acdd 100644 --- a/src/OpenAI.php +++ b/src/OpenAI.php @@ -10,7 +10,7 @@ final class OpenAI /** * Creates a new Open AI Client with the given API token. */ - public static function client(string $apiKey, string $organization = null): Client + public static function client(string $apiKey, ?string $organization = null): Client { return self::factory() ->withApiKey($apiKey) diff --git a/src/Responses/Audio/SpeechStreamResponse.php b/src/Responses/Audio/SpeechStreamResponse.php index b9b3bb8f..adaadb33 100644 --- a/src/Responses/Audio/SpeechStreamResponse.php +++ b/src/Responses/Audio/SpeechStreamResponse.php @@ -36,7 +36,7 @@ public function meta(): MetaInformation return MetaInformation::from($this->response->getHeaders()); } - public static function fake(string $content = null, MetaInformation $meta = null): static + public static function fake(?string $content = null, ?MetaInformation $meta = null): static { $psr17Factory = new Psr17Factory(); $response = $psr17Factory->createResponse() diff --git a/src/Testing/ClientFake.php b/src/Testing/ClientFake.php index 6fdb54f2..fb50633d 100644 --- a/src/Testing/ClientFake.php +++ b/src/Testing/ClientFake.php @@ -45,7 +45,7 @@ public function addResponses(array $responses): void $this->responses = [...$this->responses, ...$responses]; } - public function assertSent(string $resource, callable|int $callback = null): void + public function assertSent(string $resource, callable|int|null $callback = null): void { if (is_int($callback)) { $this->assertSentTimes($resource, $callback); @@ -72,7 +72,7 @@ private function assertSentTimes(string $resource, int $times = 1): void /** * @return mixed[] */ - private function sent(string $resource, callable $callback = null): array + private function sent(string $resource, ?callable $callback = null): array { if (! $this->hasSent($resource)) { return []; @@ -88,7 +88,7 @@ private function hasSent(string $resource): bool return $this->resourcesOf($resource) !== []; } - public function assertNotSent(string $resource, callable $callback = null): void + public function assertNotSent(string $resource, ?callable $callback = null): void { PHPUnit::assertCount( 0, $this->sent($resource, $callback), diff --git a/src/Testing/Resources/Concerns/Testable.php b/src/Testing/Resources/Concerns/Testable.php index 32841b2a..e95759c6 100644 --- a/src/Testing/Resources/Concerns/Testable.php +++ b/src/Testing/Resources/Concerns/Testable.php @@ -23,12 +23,12 @@ protected function record(string $method, array $args = []): ResponseContract|Re return $this->fake->record(new TestRequest($this->resource(), $method, $args)); } - public function assertSent(callable|int $callback = null): void + public function assertSent(callable|int|null $callback = null): void { $this->fake->assertSent($this->resource(), $callback); } - public function assertNotSent(callable|int $callback = null): void + public function assertNotSent(callable|int|null $callback = null): void { $this->fake->assertNotSent($this->resource(), $callback); } diff --git a/src/Testing/Responses/Concerns/Fakeable.php b/src/Testing/Responses/Concerns/Fakeable.php index fe5935a8..86cdb81e 100644 --- a/src/Testing/Responses/Concerns/Fakeable.php +++ b/src/Testing/Responses/Concerns/Fakeable.php @@ -11,7 +11,7 @@ trait Fakeable /** * @param array $override */ - public static function fake(array $override = [], MetaInformation $meta = null): static + public static function fake(array $override = [], ?MetaInformation $meta = null): static { $class = str_replace('Responses\\', 'Testing\\Responses\\Fixtures\\', static::class).'Fixture'; From 257af343b4420af0e704830b6e8737665eb6b12a Mon Sep 17 00:00:00 2001 From: gehrisandro Date: Thu, 28 Dec 2023 18:36:49 +0100 Subject: [PATCH 9/9] add missing factory test --- tests/OpenAI.php | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/OpenAI.php b/tests/OpenAI.php index 44fdf987..58d3263b 100644 --- a/tests/OpenAI.php +++ b/tests/OpenAI.php @@ -65,6 +65,29 @@ expect($openAI)->toBeInstanceOf(Client::class); }); +it('sets a custom event dispatcher via factory', function () { + $dispatcher = new class() implements \Psr\EventDispatcher\EventDispatcherInterface + { + public $event; + + public function dispatch(object $event) + { + $this->event = $event; + } + }; + + $openAI = OpenAI::factory() + ->withEventDispatcher($dispatcher) + ->make(); + + expect($openAI)->toBeInstanceOf(Client::class); + + $openAI->chat()->event((object) ['foo' => 'bar']); + + expect($dispatcher->event) + ->foo->toBe('bar'); +}); + it('sets a custom stream handler via factory', function () { $openAI = OpenAI::factory() ->withHttpClient($client = new GuzzleClient())