diff --git a/src/Contracts/ResponseContract.php b/src/Contracts/ResponseContract.php index cce0cc9f..37c94912 100644 --- a/src/Contracts/ResponseContract.php +++ b/src/Contracts/ResponseContract.php @@ -51,5 +51,5 @@ public function offsetSet(mixed $offset, mixed $value): never; */ public function offsetUnset(mixed $offset): never; -// public function meta(): ResponseMetaInformation; + // public function meta(): ResponseMetaInformation; } diff --git a/src/Resources/Audio.php b/src/Resources/Audio.php index a7508961..391220ba 100644 --- a/src/Resources/Audio.php +++ b/src/Resources/Audio.php @@ -8,6 +8,7 @@ use OpenAI\Responses\Audio\TranscriptionResponse; use OpenAI\Responses\Audio\TranslationResponse; use OpenAI\ValueObjects\Transporter\Payload; +use OpenAI\ValueObjects\Transporter\Response; final class Audio implements AudioContract { @@ -24,7 +25,7 @@ public function transcribe(array $parameters): TranscriptionResponse { $payload = Payload::upload('audio/transcriptions', $parameters); - /** @var array{task: ?string, language: ?string, duration: ?float, segments: array, temperature: float, avg_logprob: float, compression_ratio: float, no_speech_prob: float, transient: bool}>, text: string}|string $result */ + /** @var Response, temperature: float, avg_logprob: float, compression_ratio: float, no_speech_prob: float, transient: bool}>, text: string}> $response */ $response = $this->transporter->requestObject($payload); return TranscriptionResponse::from($response->data(), $response->meta()); @@ -41,9 +42,9 @@ public function translate(array $parameters): TranslationResponse { $payload = Payload::upload('audio/translations', $parameters); - /** @var array{task: ?string, language: ?string, duration: ?float, segments: array, temperature: float, avg_logprob: float, compression_ratio: float, no_speech_prob: float, transient: bool}>, text: string}|string $result */ - $result = $this->transporter->requestObject($payload); + /** @var Response, temperature: float, avg_logprob: float, compression_ratio: float, no_speech_prob: float, transient: bool}>, text: string}> $response */ + $response = $this->transporter->requestObject($payload); - return TranslationResponse::from($result); + return TranslationResponse::from($response->data(), $response->meta()); } } diff --git a/src/Resources/Chat.php b/src/Resources/Chat.php index 59b66c0b..9311c3c7 100644 --- a/src/Resources/Chat.php +++ b/src/Resources/Chat.php @@ -9,6 +9,7 @@ use OpenAI\Responses\Chat\CreateStreamedResponse; use OpenAI\Responses\StreamResponse; use OpenAI\ValueObjects\Transporter\Payload; +use OpenAI\ValueObjects\Transporter\Response; final class Chat implements ChatContract { @@ -28,10 +29,10 @@ public function create(array $parameters): CreateResponse $payload = Payload::create('chat/completions', $parameters); - /** @var array{id: string, object: string, created: int, model: string, choices: array, usage: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}} $result */ - $result = $this->transporter->requestObject($payload); + /** @var Response, usage: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}}> $response */ + $response = $this->transporter->requestObject($payload); - return CreateResponse::from($result); + return CreateResponse::from($response->data(), $response->meta()); } /** diff --git a/src/Resources/Edits.php b/src/Resources/Edits.php index deaa9d3d..2b50396c 100644 --- a/src/Resources/Edits.php +++ b/src/Resources/Edits.php @@ -7,6 +7,7 @@ use OpenAI\Contracts\Resources\EditsContract; use OpenAI\Responses\Edits\CreateResponse; use OpenAI\ValueObjects\Transporter\Payload; +use OpenAI\ValueObjects\Transporter\Response; final class Edits implements EditsContract { @@ -23,9 +24,9 @@ public function create(array $parameters): CreateResponse { $payload = Payload::create('edits', $parameters); - /** @var array{object: string, created: int, choices: array, usage: array{prompt_tokens: int, completion_tokens: int, total_tokens: int}} $result */ - $result = $this->transporter->requestObject($payload); + /** @var Response, usage: array{prompt_tokens: int, completion_tokens: int, total_tokens: int}}> $response */ + $response = $this->transporter->requestObject($payload); - return CreateResponse::from($result); + return CreateResponse::from($response->data(), $response->meta()); } } diff --git a/src/Resources/Embeddings.php b/src/Resources/Embeddings.php index 6e2cf021..d8c3ecb5 100644 --- a/src/Resources/Embeddings.php +++ b/src/Resources/Embeddings.php @@ -7,6 +7,7 @@ use OpenAI\Contracts\Resources\EmbeddingsContract; use OpenAI\Responses\Embeddings\CreateResponse; use OpenAI\ValueObjects\Transporter\Payload; +use OpenAI\ValueObjects\Transporter\Response; final class Embeddings implements EmbeddingsContract { @@ -23,9 +24,9 @@ public function create(array $parameters): CreateResponse { $payload = Payload::create('embeddings', $parameters); - /** @var array{object: string, data: array, index: int}>, usage: array{prompt_tokens: int, total_tokens: int}} $result */ - $result = $this->transporter->requestObject($payload); + /** @var Response, index: int}>, usage: array{prompt_tokens: int, total_tokens: int}}> $response */ + $response = $this->transporter->requestObject($payload); - return CreateResponse::from($result); + return CreateResponse::from($response->data(), $response->meta()); } } diff --git a/src/Resources/Files.php b/src/Resources/Files.php index 1e79fb86..c46255f4 100644 --- a/src/Resources/Files.php +++ b/src/Resources/Files.php @@ -10,6 +10,7 @@ use OpenAI\Responses\Files\ListResponse; use OpenAI\Responses\Files\RetrieveResponse; use OpenAI\ValueObjects\Transporter\Payload; +use OpenAI\ValueObjects\Transporter\Response; final class Files implements FilesContract { @@ -24,7 +25,7 @@ public function list(): ListResponse { $payload = Payload::list('files'); - /** @var array{object: string, data: array|string|null}>} $result */ + /** @var Response|string|null}>}> $response */ $response = $this->transporter->requestObject($payload); return ListResponse::from($response->data(), $response->meta()); @@ -39,10 +40,10 @@ public function retrieve(string $file): RetrieveResponse { $payload = Payload::retrieve('files', $file); - /** @var array{id: string, object: string, created_at: int, bytes: int, filename: string, purpose: string, status: string, status_details: array|string|null} $result */ - $result = $this->transporter->requestObject($payload); + /** @var Response|string|null}> $response */ + $response = $this->transporter->requestObject($payload); - return RetrieveResponse::from($result); + return RetrieveResponse::from($response->data(), $response->meta()); } /** @@ -68,10 +69,10 @@ public function upload(array $parameters): CreateResponse { $payload = Payload::upload('files', $parameters); - /** @var array{id: string, object: string, created_at: int, bytes: int, filename: string, purpose: string, status: string, status_details: array|string|null} $result */ - $result = $this->transporter->requestObject($payload); + /** @var Response|string|null}> $response */ + $response = $this->transporter->requestObject($payload); - return CreateResponse::from($result); + return CreateResponse::from($response->data(), $response->meta()); } /** @@ -83,7 +84,7 @@ public function delete(string $file): DeleteResponse { $payload = Payload::delete('files', $file); - /** @var array{id: string, object: string, deleted: bool} $response */ + /** @var Response $response */ $response = $this->transporter->requestObject($payload); return DeleteResponse::from($response->data(), $response->meta()); diff --git a/src/Resources/FineTunes.php b/src/Resources/FineTunes.php index 44993611..adfb4d4d 100644 --- a/src/Resources/FineTunes.php +++ b/src/Resources/FineTunes.php @@ -11,6 +11,7 @@ use OpenAI\Responses\FineTunes\RetrieveStreamedResponseEvent; use OpenAI\Responses\StreamResponse; use OpenAI\ValueObjects\Transporter\Payload; +use OpenAI\ValueObjects\Transporter\Response; final class FineTunes implements FineTunesContract { @@ -29,10 +30,10 @@ public function create(array $parameters): RetrieveResponse { $payload = Payload::create('fine-tunes', $parameters); - /** @var array{id: string, object: string, model: string, created_at: int, events: array, 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} $result */ - $result = $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}> $response */ + $response = $this->transporter->requestObject($payload); - return RetrieveResponse::from($result); + return RetrieveResponse::from($response->data(), $response->meta()); } /** @@ -44,10 +45,10 @@ public function list(): ListResponse { $payload = Payload::list('fine-tunes'); - /** @var array{object: string, data: array, 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}>} $result */ - $result = $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}>}> $response */ + $response = $this->transporter->requestObject($payload); - return ListResponse::from($result); + return ListResponse::from($response->data(), $response->meta()); } /** @@ -59,10 +60,10 @@ public function retrieve(string $fineTuneId): RetrieveResponse { $payload = Payload::retrieve('fine-tunes', $fineTuneId); - /** @var array{id: string, object: string, model: string, created_at: int, events: array, 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} $result */ - $result = $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}> $response */ + $response = $this->transporter->requestObject($payload); - return RetrieveResponse::from($result); + return RetrieveResponse::from($response->data(), $response->meta()); } /** @@ -74,10 +75,10 @@ public function cancel(string $fineTuneId): RetrieveResponse { $payload = Payload::cancel('fine-tunes', $fineTuneId); - /** @var array{id: string, object: string, model: string, created_at: int, events: array, 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} $result */ - $result = $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}> $response */ + $response = $this->transporter->requestObject($payload); - return RetrieveResponse::from($result); + return RetrieveResponse::from($response->data(), $response->meta()); } /** @@ -89,10 +90,10 @@ public function listEvents(string $fineTuneId): ListEventsResponse { $payload = Payload::retrieve('fine-tunes', $fineTuneId, '/events'); - /** @var array{object: string, data: array} $result */ - $result = $this->transporter->requestObject($payload); + /** @var Response}> $response */ + $response = $this->transporter->requestObject($payload); - return ListEventsResponse::from($result); + return ListEventsResponse::from($response->data(), $response->meta()); } /** diff --git a/src/Resources/Images.php b/src/Resources/Images.php index 5328a510..d2be6577 100644 --- a/src/Resources/Images.php +++ b/src/Resources/Images.php @@ -9,6 +9,7 @@ use OpenAI\Responses\Images\EditResponse; use OpenAI\Responses\Images\VariationResponse; use OpenAI\ValueObjects\Transporter\Payload; +use OpenAI\ValueObjects\Transporter\Response; final class Images implements ImagesContract { @@ -25,7 +26,7 @@ public function create(array $parameters): CreateResponse { $payload = Payload::create('images/generations', $parameters); - /** @var array{created: int, data: array} $response */ + /** @var Response}> $response */ $response = $this->transporter->requestObject($payload); return CreateResponse::from($response->data(), $response->meta()); @@ -42,7 +43,7 @@ public function edit(array $parameters): EditResponse { $payload = Payload::upload('images/edits', $parameters); - /** @var array{created: int, data: array} $response */ + /** @var Response}> $response */ $response = $this->transporter->requestObject($payload); return EditResponse::from($response->data(), $response->meta()); @@ -59,7 +60,7 @@ public function variation(array $parameters): VariationResponse { $payload = Payload::upload('images/variations', $parameters); - /** @var array{created: int, data: array} $response */ + /** @var Response}> $response */ $response = $this->transporter->requestObject($payload); return VariationResponse::from($response->data(), $response->meta()); diff --git a/src/Resources/Models.php b/src/Resources/Models.php index 55d216c0..f662c24e 100644 --- a/src/Resources/Models.php +++ b/src/Resources/Models.php @@ -9,6 +9,7 @@ use OpenAI\Responses\Models\ListResponse; use OpenAI\Responses\Models\RetrieveResponse; use OpenAI\ValueObjects\Transporter\Payload; +use OpenAI\ValueObjects\Transporter\Response; final class Models implements ModelsContract { @@ -23,7 +24,7 @@ public function list(): ListResponse { $payload = Payload::list('models'); - /** @var array{object: string, data: array, root: string, parent: ?string}>} $response */ + /** @var Response, root: string, parent: ?string}>}> $response */ $response = $this->transporter->requestObject($payload); return ListResponse::from($response->data(), $response->meta()); @@ -38,7 +39,7 @@ public function retrieve(string $model): RetrieveResponse { $payload = Payload::retrieve('models', $model); - /** @var array{id: string, object: string, created: int, owned_by: string, permission: array, root: string, parent: ?string} $response */ + /** @var Response, root: string, parent: ?string}> $response */ $response = $this->transporter->requestObject($payload); return RetrieveResponse::from($response->data(), $response->meta()); @@ -53,7 +54,7 @@ public function delete(string $model): DeleteResponse { $payload = Payload::delete('models', $model); - /** @var array{id: string, object: string, deleted: bool} $response */ + /** @var Response $response */ $response = $this->transporter->requestObject($payload); return DeleteResponse::from($response->data(), $response->meta()); diff --git a/src/Resources/Moderations.php b/src/Resources/Moderations.php index 8383aa8d..4a61c884 100644 --- a/src/Resources/Moderations.php +++ b/src/Resources/Moderations.php @@ -7,6 +7,7 @@ use OpenAI\Contracts\Resources\ModerationsContract; use OpenAI\Responses\Moderations\CreateResponse; use OpenAI\ValueObjects\Transporter\Payload; +use OpenAI\ValueObjects\Transporter\Response; final class Moderations implements ModerationsContract { @@ -23,7 +24,7 @@ public function create(array $parameters): CreateResponse { $payload = Payload::create('moderations', $parameters); - /** @var array{id: string, model: string, results: array, category_scores: array, flagged: bool}>} $response */ + /** @var Response, category_scores: array, flagged: bool}>}> $response */ $response = $this->transporter->requestObject($payload); return CreateResponse::from($response->data(), $response->meta()); diff --git a/src/Responses/Audio/TranslationResponse.php b/src/Responses/Audio/TranslationResponse.php index adb686a5..7f2475eb 100644 --- a/src/Responses/Audio/TranslationResponse.php +++ b/src/Responses/Audio/TranslationResponse.php @@ -6,6 +6,7 @@ use OpenAI\Contracts\ResponseContract; use OpenAI\Responses\Concerns\ArrayAccessible; +use OpenAI\Responses\ResponseMetaInformation; use OpenAI\Testing\Responses\Concerns\Fakeable; /** @@ -29,6 +30,7 @@ private function __construct( public readonly ?float $duration, public readonly array $segments, public readonly string $text, + private readonly ResponseMetaInformation $meta, ) { } @@ -37,7 +39,7 @@ private function __construct( * * @param array{task: ?string, language: ?string, duration: ?float, segments: array, temperature: float, avg_logprob: float, compression_ratio: float, no_speech_prob: float, transient: bool}>, text: string} $attributes */ - public static function from(array|string $attributes): self + public static function from(array|string $attributes, ResponseMetaInformation $meta): self { if (is_string($attributes)) { $attributes = ['text' => $attributes]; @@ -53,6 +55,7 @@ public static function from(array|string $attributes): self $attributes['duration'] ?? null, $segments, $attributes['text'], + $meta, ); } @@ -72,4 +75,9 @@ public function toArray(): array 'text' => $this->text, ]; } + + public function meta(): ResponseMetaInformation + { + return $this->meta; + } } diff --git a/src/Responses/Chat/CreateResponse.php b/src/Responses/Chat/CreateResponse.php index fdaf08a7..b2e33020 100644 --- a/src/Responses/Chat/CreateResponse.php +++ b/src/Responses/Chat/CreateResponse.php @@ -6,6 +6,7 @@ use OpenAI\Contracts\ResponseContract; use OpenAI\Responses\Concerns\ArrayAccessible; +use OpenAI\Responses\ResponseMetaInformation; use OpenAI\Testing\Responses\Concerns\Fakeable; /** @@ -30,6 +31,7 @@ private function __construct( public readonly string $model, public readonly array $choices, public readonly CreateResponseUsage $usage, + private readonly ResponseMetaInformation $meta, ) { } @@ -38,7 +40,7 @@ private function __construct( * * @param array{id: string, object: string, created: int, model: string, choices: array, usage: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}} $attributes */ - public static function from(array $attributes): self + public static function from(array $attributes, ResponseMetaInformation $meta): self { $choices = array_map(fn (array $result): CreateResponseChoice => CreateResponseChoice::from( $result @@ -50,7 +52,8 @@ public static function from(array $attributes): self $attributes['created'], $attributes['model'], $choices, - CreateResponseUsage::from($attributes['usage']) + CreateResponseUsage::from($attributes['usage']), + $meta, ); } @@ -71,4 +74,9 @@ public function toArray(): array 'usage' => $this->usage->toArray(), ]; } + + public function meta(): ResponseMetaInformation + { + return $this->meta; + } } diff --git a/src/Responses/Edits/CreateResponse.php b/src/Responses/Edits/CreateResponse.php index 47be462d..f5aff625 100644 --- a/src/Responses/Edits/CreateResponse.php +++ b/src/Responses/Edits/CreateResponse.php @@ -6,6 +6,7 @@ use OpenAI\Contracts\ResponseContract; use OpenAI\Responses\Concerns\ArrayAccessible; +use OpenAI\Responses\ResponseMetaInformation; use OpenAI\Testing\Responses\Concerns\Fakeable; /** @@ -28,6 +29,7 @@ private function __construct( public readonly int $created, public readonly array $choices, public readonly CreateResponseUsage $usage, + private readonly ResponseMetaInformation $meta, ) { } @@ -36,7 +38,7 @@ private function __construct( * * @param array{object: string, created: int, choices: array, usage: array{prompt_tokens: int, completion_tokens: int, total_tokens: int}} $attributes */ - public static function from(array $attributes): self + public static function from(array $attributes, ResponseMetaInformation $meta): self { $choices = array_map(fn (array $result): CreateResponseChoice => CreateResponseChoice::from( $result @@ -46,7 +48,8 @@ public static function from(array $attributes): self $attributes['object'], $attributes['created'], $choices, - CreateResponseUsage::from($attributes['usage']) + CreateResponseUsage::from($attributes['usage']), + $meta, ); } @@ -65,4 +68,9 @@ public function toArray(): array 'usage' => $this->usage->toArray(), ]; } + + public function meta(): ResponseMetaInformation + { + return $this->meta; + } } diff --git a/src/Responses/Embeddings/CreateResponse.php b/src/Responses/Embeddings/CreateResponse.php index 66411d33..b0dd7128 100644 --- a/src/Responses/Embeddings/CreateResponse.php +++ b/src/Responses/Embeddings/CreateResponse.php @@ -6,6 +6,7 @@ use OpenAI\Contracts\ResponseContract; use OpenAI\Responses\Concerns\ArrayAccessible; +use OpenAI\Responses\ResponseMetaInformation; use OpenAI\Testing\Responses\Concerns\Fakeable; /** @@ -27,6 +28,7 @@ private function __construct( public readonly string $object, public readonly array $embeddings, public readonly CreateResponseUsage $usage, + private readonly ResponseMetaInformation $meta, ) { } @@ -35,7 +37,7 @@ private function __construct( * * @param array{object: string, data: array, index: int}>, usage: array{prompt_tokens: int, total_tokens: int}} $attributes */ - public static function from(array $attributes): self + public static function from(array $attributes, ResponseMetaInformation $meta): self { $embeddings = array_map(fn (array $result): CreateResponseEmbedding => CreateResponseEmbedding::from( $result @@ -44,7 +46,8 @@ public static function from(array $attributes): self return new self( $attributes['object'], $embeddings, - CreateResponseUsage::from($attributes['usage']) + CreateResponseUsage::from($attributes['usage']), + $meta, ); } @@ -62,4 +65,9 @@ public function toArray(): array 'usage' => $this->usage->toArray(), ]; } + + public function meta(): ResponseMetaInformation + { + return $this->meta; + } } diff --git a/src/Responses/Files/CreateResponse.php b/src/Responses/Files/CreateResponse.php index 14c3b0a1..386ce831 100644 --- a/src/Responses/Files/CreateResponse.php +++ b/src/Responses/Files/CreateResponse.php @@ -6,6 +6,7 @@ use OpenAI\Contracts\ResponseContract; use OpenAI\Responses\Concerns\ArrayAccessible; +use OpenAI\Responses\ResponseMetaInformation; use OpenAI\Testing\Responses\Concerns\Fakeable; /** @@ -32,6 +33,7 @@ private function __construct( public readonly string $purpose, public readonly string $status, public readonly array|string|null $statusDetails, + private readonly ResponseMetaInformation $meta, ) { } @@ -40,7 +42,7 @@ private function __construct( * * @param array{id: string, object: string, created_at: int, bytes: int, filename: string, purpose: string, status: string, status_details: array|string|null} $attributes */ - public static function from(array $attributes): self + public static function from(array $attributes, ResponseMetaInformation $meta): self { return new self( $attributes['id'], @@ -51,6 +53,7 @@ public static function from(array $attributes): self $attributes['purpose'], $attributes['status'], $attributes['status_details'], + $meta, ); } @@ -70,4 +73,9 @@ public function toArray(): array 'status_details' => $this->statusDetails, ]; } + + public function meta(): ResponseMetaInformation + { + return $this->meta; + } } diff --git a/src/Responses/Files/RetrieveResponse.php b/src/Responses/Files/RetrieveResponse.php index 6f30927a..6dc3eb85 100644 --- a/src/Responses/Files/RetrieveResponse.php +++ b/src/Responses/Files/RetrieveResponse.php @@ -6,6 +6,7 @@ use OpenAI\Contracts\ResponseContract; use OpenAI\Responses\Concerns\ArrayAccessible; +use OpenAI\Responses\ResponseMetaInformation; use OpenAI\Testing\Responses\Concerns\Fakeable; /** @@ -32,6 +33,7 @@ private function __construct( public readonly string $purpose, public readonly string $status, public readonly array|string|null $statusDetails, + private readonly ?ResponseMetaInformation $meta, ) { } @@ -40,7 +42,7 @@ private function __construct( * * @param array{id: string, object: string, created_at: int, bytes: int, filename: string, purpose: string, status: string, status_details: array|string|null} $attributes */ - public static function from(array $attributes): self + public static function from(array $attributes, ResponseMetaInformation $meta = null): self { return new self( $attributes['id'], @@ -51,6 +53,7 @@ public static function from(array $attributes): self $attributes['purpose'], $attributes['status'], $attributes['status_details'], + $meta, ); } @@ -70,4 +73,9 @@ public function toArray(): array 'status_details' => $this->statusDetails, ]; } + + public function meta(): ?ResponseMetaInformation + { + return $this->meta; + } } diff --git a/src/Responses/FineTunes/ListEventsResponse.php b/src/Responses/FineTunes/ListEventsResponse.php index 265b8d4d..5e1efd74 100644 --- a/src/Responses/FineTunes/ListEventsResponse.php +++ b/src/Responses/FineTunes/ListEventsResponse.php @@ -6,6 +6,7 @@ use OpenAI\Contracts\ResponseContract; use OpenAI\Responses\Concerns\ArrayAccessible; +use OpenAI\Responses\ResponseMetaInformation; use OpenAI\Testing\Responses\Concerns\Fakeable; /** @@ -26,6 +27,7 @@ final class ListEventsResponse implements ResponseContract private function __construct( public readonly string $object, public readonly array $data, + private readonly ResponseMetaInformation $meta, ) { } @@ -34,7 +36,7 @@ private function __construct( * * @param array{object: string, data: array} $attributes */ - public static function from(array $attributes): self + public static function from(array $attributes, ResponseMetaInformation $meta): self { $data = array_map(fn (array $result): RetrieveResponseEvent => RetrieveResponseEvent::from( $result @@ -43,6 +45,7 @@ public static function from(array $attributes): self return new self( $attributes['object'], $data, + $meta, ); } @@ -59,4 +62,9 @@ public function toArray(): array ), ]; } + + public function meta(): ResponseMetaInformation + { + return $this->meta; + } } diff --git a/src/Responses/FineTunes/ListResponse.php b/src/Responses/FineTunes/ListResponse.php index bbc89797..6075befa 100644 --- a/src/Responses/FineTunes/ListResponse.php +++ b/src/Responses/FineTunes/ListResponse.php @@ -6,6 +6,7 @@ use OpenAI\Contracts\ResponseContract; use OpenAI\Responses\Concerns\ArrayAccessible; +use OpenAI\Responses\ResponseMetaInformation; use OpenAI\Testing\Responses\Concerns\Fakeable; /** @@ -26,6 +27,7 @@ final class ListResponse implements ResponseContract private function __construct( public readonly string $object, public readonly array $data, + private readonly ResponseMetaInformation $meta, ) { } @@ -34,7 +36,7 @@ private function __construct( * * @param array{object: string, data: array, 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}>} $attributes */ - public static function from(array $attributes): self + public static function from(array $attributes, ResponseMetaInformation $meta): self { $data = array_map(fn (array $result): RetrieveResponse => RetrieveResponse::from( $result @@ -43,6 +45,7 @@ public static function from(array $attributes): self return new self( $attributes['object'], $data, + $meta, ); } @@ -59,4 +62,9 @@ public function toArray(): array ), ]; } + + public function meta(): ResponseMetaInformation + { + return $this->meta; + } } diff --git a/src/Responses/FineTunes/RetrieveResponse.php b/src/Responses/FineTunes/RetrieveResponse.php index 70f93cf7..715fbc5f 100644 --- a/src/Responses/FineTunes/RetrieveResponse.php +++ b/src/Responses/FineTunes/RetrieveResponse.php @@ -6,6 +6,7 @@ use OpenAI\Contracts\ResponseContract; use OpenAI\Responses\Concerns\ArrayAccessible; +use OpenAI\Responses\ResponseMetaInformation; use OpenAI\Testing\Responses\Concerns\Fakeable; /** @@ -40,6 +41,7 @@ private function __construct( public readonly array $validationFiles, public readonly array $trainingFiles, public readonly int $updatedAt, + private readonly ?ResponseMetaInformation $meta, ) { } @@ -48,7 +50,7 @@ private function __construct( * * @param array{id: string, object: string, model: string, created_at: int, events?: array, 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} $attributes */ - public static function from(array $attributes): self + public static function from(array $attributes, ResponseMetaInformation $meta = null): self { $events = array_map(fn (array $result): RetrieveResponseEvent => RetrieveResponseEvent::from( $result @@ -80,6 +82,7 @@ public static function from(array $attributes): self $validationFiles, $trainingFiles, $attributes['updated_at'], + $meta, ); } @@ -116,4 +119,9 @@ public function toArray(): array 'updated_at' => $this->updatedAt, ]; } + + public function meta(): ?ResponseMetaInformation + { + return $this->meta; + } } diff --git a/src/Responses/ResponseMetaInformation.php b/src/Responses/ResponseMetaInformation.php index 06c75995..7b26cfe3 100644 --- a/src/Responses/ResponseMetaInformation.php +++ b/src/Responses/ResponseMetaInformation.php @@ -6,12 +6,12 @@ use OpenAI\Responses\Concerns\ArrayAccessible; /** - * @implements ResponseMetaContract + * @implements ResponseMetaContract */ final class ResponseMetaInformation implements ResponseMetaContract { /** - * @use ArrayAccessible + * @use ArrayAccessible */ use ArrayAccessible; @@ -39,8 +39,8 @@ public static function from(array $headers): self if (isset($headers['x-ratelimit-limit-requests'][0])) { $requestLimit = RequestLimitMetaInformation::from([ - 'limit' => (int)$headers['x-ratelimit-limit-requests'][0], - 'remaining' => (int)$headers['x-ratelimit-remaining-requests'][0], + 'limit' => (int) $headers['x-ratelimit-limit-requests'][0], + 'remaining' => (int) $headers['x-ratelimit-remaining-requests'][0], 'reset' => $headers['x-ratelimit-reset-requests'][0], ]); } else { @@ -82,6 +82,6 @@ public function toArray(): array 'x-ratelimit-limit-tokens' => $this->tokenLimit->limit ?? null, 'x-ratelimit-remaining-tokens' => $this->tokenLimit->remaining ?? null, 'x-ratelimit-reset-tokens' => $this->tokenLimit->reset ?? null, - ], fn (string|null $value): bool => ! is_null($value)); + ], fn (string|int|null $value): bool => ! is_null($value)); } } diff --git a/src/Responses/StreamResponse.php b/src/Responses/StreamResponse.php index 05f6020d..121931a3 100644 --- a/src/Responses/StreamResponse.php +++ b/src/Responses/StreamResponse.php @@ -78,6 +78,7 @@ private function readLine(StreamInterface $stream): string public function meta(): ResponseMetaInformation { + // @phpstan-ignore-next-line return ResponseMetaInformation::from($this->response->getHeaders()); } } diff --git a/tests/Arch.php b/tests/Arch.php index 1f89e1e9..6c23981d 100644 --- a/tests/Arch.php +++ b/tests/Arch.php @@ -44,6 +44,7 @@ 'Psr\Http\Message\StreamInterface', 'OpenAI\Enums', 'OpenAI\Contracts', + 'OpenAI\Responses\ResponseMetaInformation', ]); test('client')->expect('OpenAI\Client')->toOnlyUse([ diff --git a/tests/Pest.php b/tests/Pest.php index 5e41ed36..1b324787 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -10,7 +10,7 @@ use OpenAI\ValueObjects\Transporter\Response; use Psr\Http\Message\ResponseInterface; -function mockClient(string $method, string $resource, array $params, Response|ResponseInterface $response, $methodName = 'requestObject') +function mockClient(string $method, string $resource, array $params, Response|ResponseInterface|string $response, $methodName = 'requestObject') { $transporter = Mockery::mock(TransporterContract::class); diff --git a/tests/Resources/Audio.php b/tests/Resources/Audio.php index e11eeaa3..c454d955 100644 --- a/tests/Resources/Audio.php +++ b/tests/Resources/Audio.php @@ -10,7 +10,7 @@ 'file' => audioFileResource(), 'model' => 'whisper-1', 'response_format' => 'text', - ], audioTranscriptionText()); + ], \OpenAI\ValueObjects\Transporter\Response::from(audioTranscriptionText(), metaHeaders())); $result = $client->audio()->transcribe([ 'file' => audioFileResource(), @@ -32,7 +32,7 @@ 'file' => audioFileResource(), 'model' => 'whisper-1', 'response_format' => 'json', - ], audioTranscriptionJson()); + ], \OpenAI\ValueObjects\Transporter\Response::from(audioTranscriptionJson(), metaHeaders())); $result = $client->audio()->transcribe([ 'file' => audioFileResource(), @@ -54,7 +54,7 @@ 'file' => audioFileResource(), 'model' => 'whisper-1', 'response_format' => 'verbose_json', - ], audioTranscriptionVerboseJson()); + ], \OpenAI\ValueObjects\Transporter\Response::from(audioTranscriptionVerboseJson(), metaHeaders())); $result = $client->audio()->transcribe([ 'file' => audioFileResource(), @@ -94,7 +94,7 @@ 'file' => audioFileResource(), 'model' => 'whisper-1', 'response_format' => 'text', - ], audioTranslationText()); + ], \OpenAI\ValueObjects\Transporter\Response::from(audioTranslationText(), metaHeaders())); $result = $client->audio()->translate([ 'file' => audioFileResource(), @@ -116,7 +116,7 @@ 'file' => audioFileResource(), 'model' => 'whisper-1', 'response_format' => 'json', - ], audioTranslationJson()); + ], \OpenAI\ValueObjects\Transporter\Response::from(audioTranslationJson(), metaHeaders())); $result = $client->audio()->translate([ 'file' => audioFileResource(), @@ -138,7 +138,7 @@ 'file' => audioFileResource(), 'model' => 'whisper-1', 'response_format' => 'verbose_json', - ], audioTranslationVerboseJson()); + ], \OpenAI\ValueObjects\Transporter\Response::from(audioTranslationVerboseJson(), metaHeaders())); $result = $client->audio()->translate([ 'file' => audioFileResource(), diff --git a/tests/Resources/Chat.php b/tests/Resources/Chat.php index c4d5c0bf..44513ad2 100644 --- a/tests/Resources/Chat.php +++ b/tests/Resources/Chat.php @@ -13,7 +13,7 @@ $client = mockClient('POST', 'chat/completions', [ 'model' => 'gpt-3.5-turbo', 'messages' => ['role' => 'user', 'content' => 'Hello!'], - ], chatCompletion()); + ], \OpenAI\ValueObjects\Transporter\Response::from(chatCompletion(), metaHeaders())); $result = $client->chat()->create([ 'model' => 'gpt-3.5-turbo', diff --git a/tests/Resources/Completions.php b/tests/Resources/Completions.php index 1acf717a..5d2bc68c 100644 --- a/tests/Resources/Completions.php +++ b/tests/Resources/Completions.php @@ -13,7 +13,7 @@ $client = mockClient('POST', 'completions', [ 'model' => 'da-vince', 'prompt' => 'hi', - ], completion()); + ], \OpenAI\ValueObjects\Transporter\Response::from(completion(), metaHeaders())); $result = $client->completions()->create([ 'model' => 'da-vince', diff --git a/tests/Resources/Edits.php b/tests/Resources/Edits.php index 442e6f46..6872b10a 100644 --- a/tests/Resources/Edits.php +++ b/tests/Resources/Edits.php @@ -9,7 +9,7 @@ 'model' => 'text-davinci-edit-001', 'input' => 'What day of the wek is it?', 'instruction' => 'Fix the spelling mistakes', - ], edit()); + ], \OpenAI\ValueObjects\Transporter\Response::from(edit(), metaHeaders())); $result = $client->edits()->create([ 'object' => 'edit', diff --git a/tests/Resources/Embeddings.php b/tests/Resources/Embeddings.php index a1f9490d..ffd1d8cb 100644 --- a/tests/Resources/Embeddings.php +++ b/tests/Resources/Embeddings.php @@ -8,7 +8,7 @@ $client = mockClient('POST', 'embeddings', [ 'model' => 'text-similarity-babbage-001', 'input' => 'The food was delicious and the waiter...', - ], embeddingList()); + ], \OpenAI\ValueObjects\Transporter\Response::from(embeddingList(), metaHeaders())); $result = $client->embeddings()->create([ 'model' => 'text-similarity-babbage-001', diff --git a/tests/Resources/Files.php b/tests/Resources/Files.php index 11f3dbba..5ee0ee23 100644 --- a/tests/Resources/Files.php +++ b/tests/Resources/Files.php @@ -6,7 +6,7 @@ use OpenAI\Responses\Files\RetrieveResponse; test('list', function () { - $client = mockClient('GET', 'files', [], fileListResource()); + $client = mockClient('GET', 'files', [], \OpenAI\ValueObjects\Transporter\Response::from(fileListResource(), metaHeaders())); $result = $client->files()->list(); @@ -18,7 +18,7 @@ }); test('retrieve', function () { - $client = mockClient('GET', 'files/file-XjGxS3KTG0uNmNOK362iJua3', [], fileResource()); + $client = mockClient('GET', 'files/file-XjGxS3KTG0uNmNOK362iJua3', [], \OpenAI\ValueObjects\Transporter\Response::from(fileResource(), metaHeaders())); $result = $client->files()->retrieve('file-XjGxS3KTG0uNmNOK362iJua3'); @@ -44,7 +44,7 @@ $client = mockClient('POST', 'files', [ 'purpose' => 'fine-tune', 'file' => fileResourceResource(), - ], fileResource()); + ], \OpenAI\ValueObjects\Transporter\Response::from(fileResource(), metaHeaders())); $result = $client->files()->upload([ 'purpose' => 'fine-tune', @@ -62,7 +62,7 @@ }); test('delete', function () { - $client = mockClient('DELETE', 'files/file-XjGxS3KTG0uNmNOK362iJua3', [], fileDeleteResource()); + $client = mockClient('DELETE', 'files/file-XjGxS3KTG0uNmNOK362iJua3', [], \OpenAI\ValueObjects\Transporter\Response::from(fileDeleteResource(), metaHeaders())); $result = $client->files()->delete('file-XjGxS3KTG0uNmNOK362iJua3'); diff --git a/tests/Resources/FineTunes.php b/tests/Resources/FineTunes.php index 0e3cc291..742d51b0 100644 --- a/tests/Resources/FineTunes.php +++ b/tests/Resources/FineTunes.php @@ -25,7 +25,7 @@ 'classification_positive_class' => null, 'classification_betas' => [], 'suffix' => null, - ], fineTuneResource()); + ], \OpenAI\ValueObjects\Transporter\Response::from(fineTuneResource(), metaHeaders())); $result = $client->fineTunes()->create([ 'training_file' => 'file-XjGxS3KTG0uNmNOK362iJua3', @@ -64,7 +64,7 @@ }); test('list', function () { - $client = mockClient('GET', 'fine-tunes', [], fineTuneListResource()); + $client = mockClient('GET', 'fine-tunes', [], \OpenAI\ValueObjects\Transporter\Response::from(fineTuneListResource(), metaHeaders())); $result = $client->fineTunes()->list(); @@ -75,7 +75,7 @@ }); test('retrieve', function () { - $client = mockClient('GET', 'fine-tunes/ft-AF1WoRqd3aJAHsqc9NY7iL8F', [], fineTuneResource()); + $client = mockClient('GET', 'fine-tunes/ft-AF1WoRqd3aJAHsqc9NY7iL8F', [], \OpenAI\ValueObjects\Transporter\Response::from(fineTuneResource(), metaHeaders())); $result = $client->fineTunes()->retrieve('ft-AF1WoRqd3aJAHsqc9NY7iL8F'); @@ -124,7 +124,7 @@ }); test('cancel', function () { - $client = mockClient('POST', 'fine-tunes/ft-AF1WoRqd3aJAHsqc9NY7iL8F/cancel', [], [...fineTuneResource(), 'status' => 'cancelled']); + $client = mockClient('POST', 'fine-tunes/ft-AF1WoRqd3aJAHsqc9NY7iL8F/cancel', [], \OpenAI\ValueObjects\Transporter\Response::from([...fineTuneResource(), 'status' => 'cancelled'], metaHeaders())); $result = $client->fineTunes()->cancel('ft-AF1WoRqd3aJAHsqc9NY7iL8F'); @@ -150,7 +150,7 @@ }); test('list events', function () { - $client = mockClient('GET', 'fine-tunes/ft-AF1WoRqd3aJAHsqc9NY7iL8F/events', [], fineTuneListEventsResource()); + $client = mockClient('GET', 'fine-tunes/ft-AF1WoRqd3aJAHsqc9NY7iL8F/events', [], \OpenAI\ValueObjects\Transporter\Response::from(fineTuneListEventsResource(), metaHeaders())); $result = $client->fineTunes()->listEvents('ft-AF1WoRqd3aJAHsqc9NY7iL8F'); diff --git a/tests/Responses/Audio/TranslationResponse.php b/tests/Responses/Audio/TranslationResponse.php index 125707df..6a50fb04 100644 --- a/tests/Responses/Audio/TranslationResponse.php +++ b/tests/Responses/Audio/TranslationResponse.php @@ -4,7 +4,7 @@ use OpenAI\Responses\Audio\TranslationResponseSegment; test('from json', function () { - $Translation = TranslationResponse::from(audioTranslationJson()); + $Translation = TranslationResponse::from(audioTranslationJson(), meta()); expect($Translation) ->toBeInstanceOf(TranslationResponse::class) @@ -16,7 +16,7 @@ }); test('from verbose json', function () { - $Translation = TranslationResponse::from(audioTranslationVerboseJson()); + $Translation = TranslationResponse::from(audioTranslationVerboseJson(), meta()); expect($Translation) ->toBeInstanceOf(TranslationResponse::class) @@ -30,7 +30,7 @@ }); test('from text', function () { - $Translation = TranslationResponse::from(audioTranslationText()); + $Translation = TranslationResponse::from(audioTranslationText(), meta()); expect($Translation) ->toBeInstanceOf(TranslationResponse::class) @@ -42,7 +42,7 @@ }); test('from srt', function () { - $Translation = TranslationResponse::from(audioTranslationSrt()); + $Translation = TranslationResponse::from(audioTranslationSrt(), meta()); expect($Translation) ->toBeInstanceOf(TranslationResponse::class) @@ -60,7 +60,7 @@ }); test('from vtt', function () { - $Translation = TranslationResponse::from(audioTranslationVtt()); + $Translation = TranslationResponse::from(audioTranslationVtt(), meta()); expect($Translation) ->toBeInstanceOf(TranslationResponse::class) @@ -79,13 +79,13 @@ }); test('as array accessible', function () { - $Translation = TranslationResponse::from(audioTranslationJson()); + $Translation = TranslationResponse::from(audioTranslationJson(), meta()); expect($Translation['text'])->toBe('Hello, how are you?'); }); test('to array', function () { - $Translation = TranslationResponse::from(audioTranslationVerboseJson()); + $Translation = TranslationResponse::from(audioTranslationVerboseJson(), meta()); expect($Translation->toArray()) ->toBeArray()