From 48be8a324cb2e4f44e10aa2fdba90154712efa1b Mon Sep 17 00:00:00 2001 From: Sandro Gehri Date: Sat, 25 May 2024 00:36:23 +0200 Subject: [PATCH 01/15] Implement vector store endpoints Co-authored-by: Kyle Nash --- src/Client.php | 12 ++ src/Contracts/ClientContract.php | 8 ++ .../Resources/VectorStoresContract.php | 63 +++++++++ .../VectorStoresFileBatchesContract.php | 39 ++++++ .../Resources/VectorStoresFilesContract.php | 40 ++++++ src/Resources/VectorStores.php | 118 +++++++++++++++++ src/Resources/VectorStoresFileBatches.php | 78 +++++++++++ src/Resources/VectorStoresFiles.php | 79 ++++++++++++ .../VectorStoreFileBatchResponse.php | 71 ++++++++++ .../Files/VectorStoreFileDeleteResponse.php | 61 +++++++++ .../Files/VectorStoreFileListResponse.php | 80 ++++++++++++ .../Files/VectorStoreFileResponse.php | 73 +++++++++++ .../VectorStoreFileResponseLastError.php | 52 ++++++++ .../VectorStoreDeleteResponse.php | 61 +++++++++ .../VectorStores/VectorStoreListResponse.php | 80 ++++++++++++ .../VectorStores/VectorStoreResponse.php | 90 +++++++++++++ .../VectorStoreResponseExpiresAfter.php | 52 ++++++++ .../VectorStoreResponseFileCounts.php | 61 +++++++++ src/Testing/ClientFake.php | 7 + .../VectorStoresFileBatchesTestResource.php | 39 ++++++ .../VectorStoresFilesTestResource.php | 40 ++++++ .../Resources/VectorStoresTestResource.php | 57 +++++++++ .../VectorStoreFileDeleteResponseFixture.php | 12 ++ .../VectorStoreFileListResponseFixture.php | 24 ++++ .../Files/VectorStoreFileResponseFixture.php | 16 +++ .../VectorStoreDeleteResponseFixture.php | 12 ++ .../VectorStoreListResponseFixture.php | 53 ++++++++ .../VectorStoreResponseFixture.php | 26 ++++ tests/Fixtures/VectorStore.php | 85 ++++++++++++ tests/Fixtures/VectorStoreFile.php | 65 ++++++++++ tests/Fixtures/VectorStoreFileBatch.php | 22 ++++ tests/Resources/VectorStores.php | 121 ++++++++++++++++++ tests/Resources/VectorStoresFileBatches.php | 80 ++++++++++++ tests/Resources/VectorStoresFiles.php | 78 +++++++++++ .../VectorStoreFileBatchResponse.php | 30 +++++ .../Files/VectorStoreFileDeleteResponse.php | 47 +++++++ .../Files/VectorStoreFileListResponse.php | 30 +++++ .../Files/VectorStoreFileResponse.php | 30 +++++ .../VectorStoreFileResponseLastError.php | 25 ++++ .../VectorStoreDeleteResponse.php | 47 +++++++ .../VectorStores/VectorStoreListResponse.php | 30 +++++ .../VectorStores/VectorStoreResponse.php | 36 ++++++ .../VectorStoreResponseExpiresAfter.php | 25 ++++ .../VectorStoreResponseFileCounts.php | 28 ++++ 44 files changed, 2183 insertions(+) create mode 100644 src/Contracts/Resources/VectorStoresContract.php create mode 100644 src/Contracts/Resources/VectorStoresFileBatchesContract.php create mode 100644 src/Contracts/Resources/VectorStoresFilesContract.php create mode 100644 src/Resources/VectorStores.php create mode 100644 src/Resources/VectorStoresFileBatches.php create mode 100644 src/Resources/VectorStoresFiles.php create mode 100644 src/Responses/VectorStores/FileBatches/VectorStoreFileBatchResponse.php create mode 100644 src/Responses/VectorStores/Files/VectorStoreFileDeleteResponse.php create mode 100644 src/Responses/VectorStores/Files/VectorStoreFileListResponse.php create mode 100644 src/Responses/VectorStores/Files/VectorStoreFileResponse.php create mode 100644 src/Responses/VectorStores/Files/VectorStoreFileResponseLastError.php create mode 100644 src/Responses/VectorStores/VectorStoreDeleteResponse.php create mode 100644 src/Responses/VectorStores/VectorStoreListResponse.php create mode 100644 src/Responses/VectorStores/VectorStoreResponse.php create mode 100644 src/Responses/VectorStores/VectorStoreResponseExpiresAfter.php create mode 100644 src/Responses/VectorStores/VectorStoreResponseFileCounts.php create mode 100644 src/Testing/Resources/VectorStoresFileBatchesTestResource.php create mode 100644 src/Testing/Resources/VectorStoresFilesTestResource.php create mode 100644 src/Testing/Resources/VectorStoresTestResource.php create mode 100644 src/Testing/Responses/Fixtures/VectorStores/Files/VectorStoreFileDeleteResponseFixture.php create mode 100644 src/Testing/Responses/Fixtures/VectorStores/Files/VectorStoreFileListResponseFixture.php create mode 100644 src/Testing/Responses/Fixtures/VectorStores/Files/VectorStoreFileResponseFixture.php create mode 100644 src/Testing/Responses/Fixtures/VectorStores/VectorStoreDeleteResponseFixture.php create mode 100644 src/Testing/Responses/Fixtures/VectorStores/VectorStoreListResponseFixture.php create mode 100644 src/Testing/Responses/Fixtures/VectorStores/VectorStoreResponseFixture.php create mode 100644 tests/Fixtures/VectorStore.php create mode 100644 tests/Fixtures/VectorStoreFile.php create mode 100644 tests/Fixtures/VectorStoreFileBatch.php create mode 100644 tests/Resources/VectorStores.php create mode 100644 tests/Resources/VectorStoresFileBatches.php create mode 100644 tests/Resources/VectorStoresFiles.php create mode 100644 tests/Responses/VectorStores/FileBatches/VectorStoreFileBatchResponse.php create mode 100644 tests/Responses/VectorStores/Files/VectorStoreFileDeleteResponse.php create mode 100644 tests/Responses/VectorStores/Files/VectorStoreFileListResponse.php create mode 100644 tests/Responses/VectorStores/Files/VectorStoreFileResponse.php create mode 100644 tests/Responses/VectorStores/Files/VectorStoreFileResponseLastError.php create mode 100644 tests/Responses/VectorStores/VectorStoreDeleteResponse.php create mode 100644 tests/Responses/VectorStores/VectorStoreListResponse.php create mode 100644 tests/Responses/VectorStores/VectorStoreResponse.php create mode 100644 tests/Responses/VectorStores/VectorStoreResponseExpiresAfter.php create mode 100644 tests/Responses/VectorStores/VectorStoreResponseFileCounts.php diff --git a/src/Client.php b/src/Client.php index 6e6a8b3c..b70268e2 100644 --- a/src/Client.php +++ b/src/Client.php @@ -6,6 +6,7 @@ use OpenAI\Contracts\ClientContract; use OpenAI\Contracts\Resources\ThreadsContract; +use OpenAI\Contracts\Resources\VectorStoresContract; use OpenAI\Contracts\TransporterContract; use OpenAI\Resources\Assistants; use OpenAI\Resources\Audio; @@ -21,6 +22,7 @@ use OpenAI\Resources\Models; use OpenAI\Resources\Moderations; use OpenAI\Resources\Threads; +use OpenAI\Resources\VectorStores; final class Client implements ClientContract { @@ -174,4 +176,14 @@ public function batches(): Batches { return new Batches($this->transporter); } + + /** + * Create and update vector stores that assistants can interact with + * + * @see https://platform.openai.com/docs/api-reference/vector-stores + */ + public function vectorStores(): VectorStoresContract + { + return new VectorStores($this->transporter); + } } diff --git a/src/Contracts/ClientContract.php b/src/Contracts/ClientContract.php index 92a1ac66..9b624dd9 100644 --- a/src/Contracts/ClientContract.php +++ b/src/Contracts/ClientContract.php @@ -16,6 +16,7 @@ use OpenAI\Contracts\Resources\ModelsContract; use OpenAI\Contracts\Resources\ModerationsContract; use OpenAI\Contracts\Resources\ThreadsContract; +use OpenAI\Contracts\Resources\VectorStoresContract; interface ClientContract { @@ -121,4 +122,11 @@ public function threads(): ThreadsContract; * @see https://platform.openai.com/docs/api-reference/batch */ public function batches(): BatchesContract; + + /** + * Create and update vector stores that assistants can interact with + * + * @see https://platform.openai.com/docs/api-reference/vector-stores + */ + public function vectorStores(): VectorStoresContract; } diff --git a/src/Contracts/Resources/VectorStoresContract.php b/src/Contracts/Resources/VectorStoresContract.php new file mode 100644 index 00000000..39e7fae9 --- /dev/null +++ b/src/Contracts/Resources/VectorStoresContract.php @@ -0,0 +1,63 @@ + $parameters + */ + public function create(array $parameters): VectorStoreResponse; + + /** + * Returns a list of vector stores. + * + * @see https://platform.openai.com/docs/api-reference/vector-stores/list + */ + public function list(): VectorStoreListResponse; + + /** + * Retrieves a vector store. + * + * @see https://platform.openai.com/docs/api-reference/vector-stores/retrieve + */ + public function retrieve(string $vectorStore): VectorStoreResponse; + + /** + * Modify a vector store + * + * @see https://platform.openai.com/docs/api-reference/vector-stores/modify + * + * @param array $parameters + */ + public function modify(string $vectorStore, array $parameters): VectorStoreResponse; + + /** + * Delete a vector store. + * + * https://platform.openai.com/docs/api-reference/vector-stores/delete + */ + public function delete(string $vectorStore): VectorStoreDeleteResponse; + + /** + * Manage the files related to the vector store + * + * @see https://platform.openai.com/docs/api-reference/vector-stores-files + */ + public function files(): VectorStoresFilesContract; + + /** + * Manage the file batches related to the vector store + * + * @see https://platform.openai.com/docs/api-reference/vector-stores-file-batches + */ + public function batches(): VectorStoresFileBatchesContract; +} diff --git a/src/Contracts/Resources/VectorStoresFileBatchesContract.php b/src/Contracts/Resources/VectorStoresFileBatchesContract.php new file mode 100644 index 00000000..4ebb35a3 --- /dev/null +++ b/src/Contracts/Resources/VectorStoresFileBatchesContract.php @@ -0,0 +1,39 @@ + $parameters + */ + public function create(string $vectorStoreId, array $parameters): VectorStoreFileBatchResponse; + + /** + * Retrieves a file batch within a vector store. + * + * @see https://platform.openai.com/docs/api-reference/vector-stores-file-batches/getBatch + */ + public function retrieve(string $vectorStoreId, string $fileBatchId): VectorStoreFileBatchResponse; + + /** + * Cancel a vector store file batch + * + * @see https://platform.openai.com/docs/api-reference/vector-stores-file-batches/cancelBatch + */ + public function cancel(string $vectorStoreId, string $fileBatchId): VectorStoreFileBatchResponse; + + /** + * Lists the files within a file batch within a vector store + * + * @see https://platform.openai.com/docs/api-reference/vector-stores-file-batches/listBatchFiles + */ + public function listFiles(string $vectorStoreId, string $fileBatchId): VectorStoreFileListResponse; +} diff --git a/src/Contracts/Resources/VectorStoresFilesContract.php b/src/Contracts/Resources/VectorStoresFilesContract.php new file mode 100644 index 00000000..7e6386b4 --- /dev/null +++ b/src/Contracts/Resources/VectorStoresFilesContract.php @@ -0,0 +1,40 @@ + $parameters + */ + public function create(string $vectorStoreId, array $parameters): VectorStoreFileResponse; + + /** + * Returns a list of files within a vector store. + * + * @see https://platform.openai.com/docs/api-reference/vector-stores-files/listFiles + */ + public function list(string $vectorStoreId): VectorStoreFileListResponse; + + /** + * Retrieves a file within a vector store. + * + * @see https://platform.openai.com/docs/api-reference/vector-stores-files/getFile + */ + public function retrieve(string $vectorStoreId, string $fileId): VectorStoreFileResponse; + + /** + * Delete a file within a vector store. + * + * https://platform.openai.com/docs/api-reference/vector-stores/delete + */ + public function delete(string $vectorStoreId, string $fileId): VectorStoreFileDeleteResponse; +} diff --git a/src/Resources/VectorStores.php b/src/Resources/VectorStores.php new file mode 100644 index 00000000..257cd942 --- /dev/null +++ b/src/Resources/VectorStores.php @@ -0,0 +1,118 @@ + $parameters + */ + public function create(array $parameters): VectorStoreResponse + { + $payload = Payload::create('vector_stores', $parameters); + + /** @var Response}> $response */ + $response = $this->transporter->requestObject($payload); + + return VectorStoreResponse::from($response->data(), $response->meta()); + } + + /** + * Returns a list of vector stores. + * + * @see https://platform.openai.com/docs/api-reference/vector-stores/list + */ + public function list(): VectorStoreListResponse + { + $payload = Payload::list('vector_stores'); + + /** @var Response}>, first_id: ?string, last_id: ?string, has_more: bool}> $response */ + $response = $this->transporter->requestObject($payload); + + return VectorStoreListResponse::from($response->data(), $response->meta()); + } + + /** + * Retrieves a vector store. + * + * @see https://platform.openai.com/docs/api-reference/vector-stores/retrieve + */ + public function retrieve(string $vectorStore): VectorStoreResponse + { + $payload = Payload::retrieve('vector_stores', $vectorStore); + + /** @var Response}> $response */ + $response = $this->transporter->requestObject($payload); + + return VectorStoreResponse::from($response->data(), $response->meta()); + } + + /** + * Modify a vector store + * + * @see https://platform.openai.com/docs/api-reference/vector-stores/modify + * + * @param array $parameters + */ + public function modify(string $vectorStore, array $parameters): VectorStoreResponse + { + $payload = Payload::modify('vector_stores', $vectorStore, $parameters); + + /** @var Response}> $response */ + $response = $this->transporter->requestObject($payload); + + return VectorStoreResponse::from($response->data(), $response->meta()); + } + + /** + * Delete a vector store. + * + * https://platform.openai.com/docs/api-reference/vector-stores/delete + */ + public function delete(string $vectorStore): VectorStoreDeleteResponse + { + $payload = Payload::delete('vector_stores', $vectorStore); + + /** @var Response $response */ + $response = $this->transporter->requestObject($payload); + + return VectorStoreDeleteResponse::from($response->data(), $response->meta()); + } + + /** + * Manage the files related to the vector store + * + * @see https://platform.openai.com/docs/api-reference/vector-stores-files + */ + public function files(): VectorStoresFilesContract + { + return new VectorStoresFiles($this->transporter); + } + + /** + * Manage the file batches related to the vector store + * + * @see https://platform.openai.com/docs/api-reference/vector-stores-file-batches + */ + public function batches(): VectorStoresFileBatchesContract + { + return new VectorStoresFileBatches($this->transporter); + } +} diff --git a/src/Resources/VectorStoresFileBatches.php b/src/Resources/VectorStoresFileBatches.php new file mode 100644 index 00000000..3fce48c0 --- /dev/null +++ b/src/Resources/VectorStoresFileBatches.php @@ -0,0 +1,78 @@ + $parameters + */ + public function create(string $vectorStoreId, array $parameters): VectorStoreFileBatchResponse + { + $payload = Payload::create("vector_stores/$vectorStoreId/file_batches", $parameters); + + /** @var Response $response */ + $response = $this->transporter->requestObject($payload); + + return VectorStoreFileBatchResponse::from($response->data(), $response->meta()); + } + + /** + * Retrieves a file batch within a vector store. + * + * @see https://platform.openai.com/docs/api-reference/vector-stores-file-batches/getBatch + */ + public function retrieve(string $vectorStoreId, string $fileBatchId): VectorStoreFileBatchResponse + { + $payload = Payload::retrieve("vector_stores/$vectorStoreId/file_batches", $fileBatchId); + + /** @var Response $response */ + $response = $this->transporter->requestObject($payload); + + return VectorStoreFileBatchResponse::from($response->data(), $response->meta()); + } + + /** + * Lists the files within a file batch within a vector store + * + * @see https://platform.openai.com/docs/api-reference/vector-stores-file-batches/listBatchFiles + */ + public function listFiles(string $vectorStoreId, string $fileBatchId): VectorStoreFileListResponse + { + $payload = Payload::list("vector_stores/$vectorStoreId/file_batches/$fileBatchId/files"); + + /** @var Response, first_id: ?string, last_id: ?string, has_more: bool}> $response */ + $response = $this->transporter->requestObject($payload); + + return VectorStoreFileListResponse::from($response->data(), $response->meta()); + } + + /** + * Cancel a vector store file batch + * + * @see https://platform.openai.com/docs/api-reference/vector-stores-file-batches/cancelBatch + */ + public function cancel(string $vectorStoreId, string $fileBatchId): VectorStoreFileBatchResponse + { + $payload = Payload::delete("vector_stores/$vectorStoreId/file_batches", $fileBatchId); + + /** @var Response $response */ + $response = $this->transporter->requestObject($payload); + + return VectorStoreFileBatchResponse::from($response->data(), $response->meta()); + } +} diff --git a/src/Resources/VectorStoresFiles.php b/src/Resources/VectorStoresFiles.php new file mode 100644 index 00000000..264288b9 --- /dev/null +++ b/src/Resources/VectorStoresFiles.php @@ -0,0 +1,79 @@ + $parameters + */ + public function create(string $vectorStoreId, array $parameters): VectorStoreFileResponse + { + $payload = Payload::create("vector_stores/$vectorStoreId/files", $parameters); + + /** @var Response $response */ + $response = $this->transporter->requestObject($payload); + + return VectorStoreFileResponse::from($response->data(), $response->meta()); + } + + /** + * Returns a list of files within a vector store. + * + * @see https://platform.openai.com/docs/api-reference/vector-stores-files/listFiles + */ + public function list(string $vectorStoreId): VectorStoreFileListResponse + { + $payload = Payload::list("vector_stores/$vectorStoreId/files"); + + /** @var Response, first_id: ?string, last_id: ?string, has_more: bool}> $response */ + $response = $this->transporter->requestObject($payload); + + return VectorStoreFileListResponse::from($response->data(), $response->meta()); + } + + /** + * Retrieves a file within a vector store. + * + * @see https://platform.openai.com/docs/api-reference/vector-stores-files/getFile + */ + public function retrieve(string $vectorStoreId, string $fileId): VectorStoreFileResponse + { + $payload = Payload::retrieve("vector_stores/$vectorStoreId/files", $fileId); + + /** @var Response $response */ + $response = $this->transporter->requestObject($payload); + + return VectorStoreFileResponse::from($response->data(), $response->meta()); + } + + /** + * Delete a file within a vector store. + * + * https://platform.openai.com/docs/api-reference/vector-stores/delete + */ + public function delete(string $vectorStoreId, string $fileId): VectorStoreFileDeleteResponse + { + $payload = Payload::delete("vector_stores/$vectorStoreId/files", $fileId); + + /** @var Response $response */ + $response = $this->transporter->requestObject($payload); + + return VectorStoreFileDeleteResponse::from($response->data(), $response->meta()); + } +} diff --git a/src/Responses/VectorStores/FileBatches/VectorStoreFileBatchResponse.php b/src/Responses/VectorStores/FileBatches/VectorStoreFileBatchResponse.php new file mode 100644 index 00000000..6f60bd82 --- /dev/null +++ b/src/Responses/VectorStores/FileBatches/VectorStoreFileBatchResponse.php @@ -0,0 +1,71 @@ + + */ +final class VectorStoreFileBatchResponse implements ResponseContract, ResponseHasMetaInformationContract +{ + /** + * @use ArrayAccessible + */ + use ArrayAccessible; + + use Fakeable; + use HasMetaInformation; + + private function __construct( + public readonly string $id, + public readonly string $object, + public readonly int $createdAt, + public readonly string $vectorStoreId, + public readonly string $status, + public readonly VectorStoreResponseFileCounts $fileCounts, + private readonly MetaInformation $meta, + ) { + } + + /** + * Acts as static factory, and returns a new Response instance. + * + * @param array{id: string, object: string, created_at: int, vector_store_id: string, status: string, file_counts: array{in_progress: int, completed: int, failed: int, cancelled: int, total: int}} $attributes + */ + public static function from(array $attributes, MetaInformation $meta): self + { + return new self( + $attributes['id'], + $attributes['object'], + $attributes['created_at'], + $attributes['vector_store_id'], + $attributes['status'], + VectorStoreResponseFileCounts::from($attributes['file_counts']), + $meta, + ); + } + + /** + * {@inheritDoc} + */ + public function toArray(): array + { + return [ + 'id' => $this->id, + 'object' => $this->object, + 'created_at' => $this->createdAt, + 'vector_store_id' => $this->vectorStoreId, + 'status' => $this->status, + 'file_counts' => $this->fileCounts->toArray(), + ]; + } +} diff --git a/src/Responses/VectorStores/Files/VectorStoreFileDeleteResponse.php b/src/Responses/VectorStores/Files/VectorStoreFileDeleteResponse.php new file mode 100644 index 00000000..c35b3a1e --- /dev/null +++ b/src/Responses/VectorStores/Files/VectorStoreFileDeleteResponse.php @@ -0,0 +1,61 @@ + + */ +final class VectorStoreFileDeleteResponse implements ResponseContract, ResponseHasMetaInformationContract +{ + /** + * @use ArrayAccessible + */ + use ArrayAccessible; + + use Fakeable; + use HasMetaInformation; + + private function __construct( + public readonly string $id, + public readonly string $object, + public readonly bool $deleted, + private readonly MetaInformation $meta, + ) { + } + + /** + * Acts as static factory, and returns a new Response instance. + * + * @param array{id: string, object: string, deleted: bool} $attributes + */ + public static function from(array $attributes, MetaInformation $meta): self + { + return new self( + $attributes['id'], + $attributes['object'], + $attributes['deleted'], + $meta, + ); + } + + /** + * {@inheritDoc} + */ + public function toArray(): array + { + return [ + 'id' => $this->id, + 'object' => $this->object, + 'deleted' => $this->deleted, + ]; + } +} diff --git a/src/Responses/VectorStores/Files/VectorStoreFileListResponse.php b/src/Responses/VectorStores/Files/VectorStoreFileListResponse.php new file mode 100644 index 00000000..4e38a31c --- /dev/null +++ b/src/Responses/VectorStores/Files/VectorStoreFileListResponse.php @@ -0,0 +1,80 @@ +, first_id: ?string, last_id: ?string, has_more: bool}> + */ +final class VectorStoreFileListResponse implements ResponseContract, ResponseHasMetaInformationContract +{ + /** + * @use ArrayAccessible, first_id: ?string, last_id: ?string, has_more: bool}> + */ + use ArrayAccessible; + + use Fakeable; + use HasMetaInformation; + + /** + * @param array $data + */ + private function __construct( + public readonly string $object, + public readonly array $data, + public readonly ?string $firstId, + public readonly ?string $lastId, + public readonly bool $hasMore, + private readonly MetaInformation $meta, + ) { + } + + /** + * Acts as static factory, and returns a new Response instance. + * + * @param array{object: string, data: array, first_id: ?string, last_id: ?string, has_more: bool} $attributes + */ + public static function from(array $attributes, MetaInformation $meta): self + { + $data = array_map(fn (array $result): VectorStoreFileResponse => VectorStoreFileResponse::from( + $result, + $meta, + ), $attributes['data']); + + return new self( + $attributes['object'], + $data, + $attributes['first_id'], + $attributes['last_id'], + $attributes['has_more'], + $meta, + ); + } + + /** + * {@inheritDoc} + * + * @return array{object: string, data: array, first_id: string|null, last_id: string|null, has_more: bool} + */ + public function toArray(): array + { + return [ + 'object' => $this->object, + 'data' => array_map( + static fn (VectorStoreFileResponse $response): array => $response->toArray(), + $this->data, + ), + 'first_id' => $this->firstId, + 'last_id' => $this->lastId, + 'has_more' => $this->hasMore, + ]; + } +} diff --git a/src/Responses/VectorStores/Files/VectorStoreFileResponse.php b/src/Responses/VectorStores/Files/VectorStoreFileResponse.php new file mode 100644 index 00000000..5af86260 --- /dev/null +++ b/src/Responses/VectorStores/Files/VectorStoreFileResponse.php @@ -0,0 +1,73 @@ + + */ +final class VectorStoreFileResponse implements ResponseContract, ResponseHasMetaInformationContract +{ + /** + * @use ArrayAccessible + */ + use ArrayAccessible; + + use Fakeable; + use HasMetaInformation; + + private function __construct( + public readonly string $id, + public readonly string $object, + public readonly int $usageBytes, + public readonly int $createdAt, + public readonly string $vectorStoreId, + public readonly string $status, + public readonly ?VectorStoreFileResponseLastError $lastError, + private readonly MetaInformation $meta, + ) { + } + + /** + * Acts as static factory, and returns a new Response instance. + * + * @param array{id: string, object: string, usage_bytes: int, created_at: int, vector_store_id: string, status: string, last_error: ?array{code: string, message: string}} $attributes + */ + public static function from(array $attributes, MetaInformation $meta): self + { + return new self( + $attributes['id'], + $attributes['object'], + $attributes['usage_bytes'], + $attributes['created_at'], + $attributes['vector_store_id'], + $attributes['status'], + isset($attributes['last_error']) ? VectorStoreFileResponseLastError::from($attributes['last_error']) : null, + $meta, + ); + } + + /** + * {@inheritDoc} + */ + public function toArray(): array + { + return [ + 'id' => $this->id, + 'object' => $this->object, + 'usage_bytes' => $this->usageBytes, + 'created_at' => $this->createdAt, + 'vector_store_id' => $this->vectorStoreId, + 'status' => $this->status, + 'last_error' => $this->lastError instanceof VectorStoreFileResponseLastError ? $this->lastError->toArray() : null, + ]; + } +} diff --git a/src/Responses/VectorStores/Files/VectorStoreFileResponseLastError.php b/src/Responses/VectorStores/Files/VectorStoreFileResponseLastError.php new file mode 100644 index 00000000..9b174951 --- /dev/null +++ b/src/Responses/VectorStores/Files/VectorStoreFileResponseLastError.php @@ -0,0 +1,52 @@ + + */ +final class VectorStoreFileResponseLastError implements ResponseContract +{ + /** + * @use ArrayAccessible + */ + use ArrayAccessible; + + use Fakeable; + + private function __construct( + public readonly string $code, + public readonly string $message, + ) { + } + + /** + * Acts as static factory, and returns a new Response instance. + * + * @param array{code: string, message: string} $attributes + */ + public static function from(array $attributes): self + { + return new self( + $attributes['code'], + $attributes['message'], + ); + } + + /** + * {@inheritDoc} + */ + public function toArray(): array + { + return [ + 'code' => $this->code, + 'message' => $this->message, + ]; + } +} diff --git a/src/Responses/VectorStores/VectorStoreDeleteResponse.php b/src/Responses/VectorStores/VectorStoreDeleteResponse.php new file mode 100644 index 00000000..98c66e79 --- /dev/null +++ b/src/Responses/VectorStores/VectorStoreDeleteResponse.php @@ -0,0 +1,61 @@ + + */ +final class VectorStoreDeleteResponse implements ResponseContract, ResponseHasMetaInformationContract +{ + /** + * @use ArrayAccessible + */ + use ArrayAccessible; + + use Fakeable; + use HasMetaInformation; + + private function __construct( + public readonly string $id, + public readonly string $object, + public readonly bool $deleted, + private readonly MetaInformation $meta, + ) { + } + + /** + * Acts as static factory, and returns a new Response instance. + * + * @param array{id: string, object: string, deleted: bool} $attributes + */ + public static function from(array $attributes, MetaInformation $meta): self + { + return new self( + $attributes['id'], + $attributes['object'], + $attributes['deleted'], + $meta, + ); + } + + /** + * {@inheritDoc} + */ + public function toArray(): array + { + return [ + 'id' => $this->id, + 'object' => $this->object, + 'deleted' => $this->deleted, + ]; + } +} diff --git a/src/Responses/VectorStores/VectorStoreListResponse.php b/src/Responses/VectorStores/VectorStoreListResponse.php new file mode 100644 index 00000000..f5d56557 --- /dev/null +++ b/src/Responses/VectorStores/VectorStoreListResponse.php @@ -0,0 +1,80 @@ +}>, first_id: ?string, last_id: ?string, has_more: bool}> + */ +final class VectorStoreListResponse implements ResponseContract, ResponseHasMetaInformationContract +{ + /** + * @use ArrayAccessible}>, first_id: ?string, last_id: ?string, has_more: bool}> + */ + use ArrayAccessible; + + use Fakeable; + use HasMetaInformation; + + /** + * @param array $data + */ + private function __construct( + public readonly string $object, + public readonly array $data, + public readonly ?string $firstId, + public readonly ?string $lastId, + public readonly bool $hasMore, + private readonly MetaInformation $meta, + ) { + } + + /** + * Acts as static factory, and returns a new Response instance. + * + * @param array{object: string, data: array}>, first_id: ?string, last_id: ?string, has_more: bool} $attributes + */ + public static function from(array $attributes, MetaInformation $meta): self + { + $data = array_map(fn (array $result): VectorStoreResponse => VectorStoreResponse::from( + $result, + $meta, + ), $attributes['data']); + + return new self( + $attributes['object'], + $data, + $attributes['first_id'], + $attributes['last_id'], + $attributes['has_more'], + $meta, + ); + } + + /** + * {@inheritDoc} + * + * @return array{object: string, data: array, first_id: string|null, last_id: string|null, has_more: bool} + */ + public function toArray(): array + { + return [ + 'object' => $this->object, + 'data' => array_map( + static fn (VectorStoreResponse $response): array => $response->toArray(), + $this->data, + ), + 'first_id' => $this->firstId, + 'last_id' => $this->lastId, + 'has_more' => $this->hasMore, + ]; + } +} diff --git a/src/Responses/VectorStores/VectorStoreResponse.php b/src/Responses/VectorStores/VectorStoreResponse.php new file mode 100644 index 00000000..e90f67af --- /dev/null +++ b/src/Responses/VectorStores/VectorStoreResponse.php @@ -0,0 +1,90 @@ +}> + */ +final class VectorStoreResponse implements ResponseContract, ResponseHasMetaInformationContract +{ + /** + * @use ArrayAccessible}> + */ + use ArrayAccessible; + + use Fakeable; + use HasMetaInformation; + + /** + * @param array $metadata + */ + private function __construct( + public readonly string $id, + public readonly string $object, + public readonly int $createdAt, + public readonly ?string $name, + public readonly int $usageBytes, + public readonly VectorStoreResponseFileCounts $fileCounts, + public readonly string $status, + public readonly ?VectorStoreResponseExpiresAfter $expiresAfter, + public readonly ?int $expiresAt, + public readonly ?int $lastActiveAt, + public readonly array $metadata, + private readonly MetaInformation $meta, + ) { + } + + /** + * Acts as static factory, and returns a new Response instance. + * + * @param array{id: string, object: string, created_at: int, name: ?string, usage_bytes: int, file_counts: array{in_progress: int, completed: int, failed: int, cancelled: int, total: int}, status: string, expires_after: ?array{anchor: string, days: int}, expires_at: ?int, last_active_at: ?int, metadata: array} $attributes + */ + public static function from(array $attributes, MetaInformation $meta): self + { + return new self( + $attributes['id'], + $attributes['object'], + $attributes['created_at'], + $attributes['name'], + $attributes['usage_bytes'], + VectorStoreResponseFileCounts::from($attributes['file_counts']), + $attributes['status'], + isset($attributes['expires_after']) ? VectorStoreResponseExpiresAfter::from($attributes['expires_after']) : null, + $attributes['expires_at'], + $attributes['last_active_at'], + $attributes['metadata'], + $meta, + ); + } + + /** + * {@inheritDoc} + * + * @return array{id: string, object: string, name: string|null, status: string, usage_bytes: int, created_at: int, file_counts: array{in_progress: int, completed: int, failed: int, cancelled: int, total: int}, metadata: mixed[], expires_after: array{anchor: string, days: int}|null, expires_at: int|null, last_active_at: int|null} + */ + public function toArray(): array + { + return [ + 'id' => $this->id, + 'object' => $this->object, + 'name' => $this->name, + 'status' => $this->status, + 'usage_bytes' => $this->usageBytes, + 'created_at' => $this->createdAt, + 'file_counts' => $this->fileCounts->toArray(), + 'metadata' => $this->metadata, + 'expires_after' => $this->expiresAfter?->toArray(), + 'expires_at' => $this->expiresAt, + 'last_active_at' => $this->lastActiveAt, + ]; + } +} diff --git a/src/Responses/VectorStores/VectorStoreResponseExpiresAfter.php b/src/Responses/VectorStores/VectorStoreResponseExpiresAfter.php new file mode 100644 index 00000000..1bd88382 --- /dev/null +++ b/src/Responses/VectorStores/VectorStoreResponseExpiresAfter.php @@ -0,0 +1,52 @@ + + */ +final class VectorStoreResponseExpiresAfter implements ResponseContract +{ + /** + * @use ArrayAccessible + */ + use ArrayAccessible; + + use Fakeable; + + private function __construct( + public readonly string $anchor, + public readonly int $days, + ) { + } + + /** + * Acts as static factory, and returns a new Response instance. + * + * @param array{anchor: string, days: int} $attributes + */ + public static function from(array $attributes): self + { + return new self( + $attributes['anchor'], + $attributes['days'], + ); + } + + /** + * {@inheritDoc} + */ + public function toArray(): array + { + return [ + 'anchor' => $this->anchor, + 'days' => $this->days, + ]; + } +} diff --git a/src/Responses/VectorStores/VectorStoreResponseFileCounts.php b/src/Responses/VectorStores/VectorStoreResponseFileCounts.php new file mode 100644 index 00000000..e7c6c211 --- /dev/null +++ b/src/Responses/VectorStores/VectorStoreResponseFileCounts.php @@ -0,0 +1,61 @@ + + */ +final class VectorStoreResponseFileCounts implements ResponseContract +{ + /** + * @use ArrayAccessible + */ + use ArrayAccessible; + + use Fakeable; + + private function __construct( + public readonly int $inProgress, + public readonly int $completed, + public readonly int $failed, + public readonly int $cancelled, + public readonly int $total, + ) { + } + + /** + * Acts as static factory, and returns a new Response instance. + * + * @param array{in_progress: int, completed: int, failed: int, cancelled: int, total: int} $attributes + */ + public static function from(array $attributes): self + { + return new self( + $attributes['in_progress'], + $attributes['completed'], + $attributes['cancelled'], + $attributes['failed'], + $attributes['total'], + ); + } + + /** + * {@inheritDoc} + */ + public function toArray(): array + { + return [ + 'in_progress' => $this->inProgress, + 'completed' => $this->completed, + 'failed' => $this->failed, + 'cancelled' => $this->cancelled, + 'total' => $this->total, + ]; + } +} diff --git a/src/Testing/ClientFake.php b/src/Testing/ClientFake.php index 0a6a1605..a44e54af 100644 --- a/src/Testing/ClientFake.php +++ b/src/Testing/ClientFake.php @@ -3,6 +3,7 @@ namespace OpenAI\Testing; use OpenAI\Contracts\ClientContract; +use OpenAI\Contracts\Resources\VectorStoresContract; use OpenAI\Contracts\ResponseContract; use OpenAI\Contracts\ResponseStreamContract; use OpenAI\Responses\StreamResponse; @@ -21,6 +22,7 @@ use OpenAI\Testing\Resources\ModelsTestResource; use OpenAI\Testing\Resources\ModerationsTestResource; use OpenAI\Testing\Resources\ThreadsTestResource; +use OpenAI\Testing\Resources\VectorStoresTestResource; use PHPUnit\Framework\Assert as PHPUnit; use Throwable; @@ -201,4 +203,9 @@ public function batches(): BatchesTestResource { return new BatchesTestResource($this); } + + public function vectorStores(): VectorStoresContract + { + return new VectorStoresTestResource($this); + } } diff --git a/src/Testing/Resources/VectorStoresFileBatchesTestResource.php b/src/Testing/Resources/VectorStoresFileBatchesTestResource.php new file mode 100644 index 00000000..f45e66cc --- /dev/null +++ b/src/Testing/Resources/VectorStoresFileBatchesTestResource.php @@ -0,0 +1,39 @@ +record(__FUNCTION__, func_get_args()); + } + + public function cancel(string $vectorStoreId, string $fileBatchId): VectorStoreFileBatchResponse + { + return $this->record(__FUNCTION__, func_get_args()); + } + + public function create(string $vectorStoreId, array $parameters): VectorStoreFileBatchResponse + { + return $this->record(__FUNCTION__, func_get_args()); + } + + public function listFiles(string $vectorStoreId, string $fileBatchId): VectorStoreFileListResponse + { + return $this->record(__FUNCTION__, func_get_args()); + } +} diff --git a/src/Testing/Resources/VectorStoresFilesTestResource.php b/src/Testing/Resources/VectorStoresFilesTestResource.php new file mode 100644 index 00000000..d0652362 --- /dev/null +++ b/src/Testing/Resources/VectorStoresFilesTestResource.php @@ -0,0 +1,40 @@ +record(__FUNCTION__, func_get_args()); + } + + public function delete(string $vectorStoreId, string $fileId): VectorStoreFileDeleteResponse + { + return $this->record(__FUNCTION__, func_get_args()); + } + + public function create(string $vectorStoreId, array $parameters): VectorStoreFileResponse + { + return $this->record(__FUNCTION__, func_get_args()); + } + + public function list(string $vectorStoreId): VectorStoreFileListResponse + { + return $this->record(__FUNCTION__, func_get_args()); + } +} diff --git a/src/Testing/Resources/VectorStoresTestResource.php b/src/Testing/Resources/VectorStoresTestResource.php new file mode 100644 index 00000000..fd92ce4e --- /dev/null +++ b/src/Testing/Resources/VectorStoresTestResource.php @@ -0,0 +1,57 @@ +record(__FUNCTION__, func_get_args()); + } + + public function retrieve(string $vectorStore): VectorStoreResponse + { + return $this->record(__FUNCTION__, func_get_args()); + } + + public function delete(string $vectorStore): VectorStoreDeleteResponse + { + return $this->record(__FUNCTION__, func_get_args()); + } + + public function create(array $parameters): VectorStoreResponse + { + return $this->record(__FUNCTION__, func_get_args()); + } + + public function list(): VectorStoreListResponse + { + return $this->record(__FUNCTION__, func_get_args()); + } + + public function files(): VectorStoresFilesContract + { + return new VectorStoresFilesTestResource($this); + } + + public function batches(): VectorStoresFileBatchesContract + { + return new VectorStoresFileBatchesTestResource($this); + } +} diff --git a/src/Testing/Responses/Fixtures/VectorStores/Files/VectorStoreFileDeleteResponseFixture.php b/src/Testing/Responses/Fixtures/VectorStores/Files/VectorStoreFileDeleteResponseFixture.php new file mode 100644 index 00000000..1abb557a --- /dev/null +++ b/src/Testing/Responses/Fixtures/VectorStores/Files/VectorStoreFileDeleteResponseFixture.php @@ -0,0 +1,12 @@ + 'file-HuwUghQzWasTZeX3uRRawY5R', + 'object' => 'vector_store.file.deleted', + 'deleted' => true, + ]; +} diff --git a/src/Testing/Responses/Fixtures/VectorStores/Files/VectorStoreFileListResponseFixture.php b/src/Testing/Responses/Fixtures/VectorStores/Files/VectorStoreFileListResponseFixture.php new file mode 100644 index 00000000..b585f401 --- /dev/null +++ b/src/Testing/Responses/Fixtures/VectorStores/Files/VectorStoreFileListResponseFixture.php @@ -0,0 +1,24 @@ + 'list', + 'data' => [ + [ + 'id' => 'file-HuwUghQzWasTZeX3uRRawY5R', + 'object' => 'vector_store.file', + 'usage_bytes' => 29882, + 'created_at' => 1_715_956_697, + 'vector_store_id' => 'vs_xds05V7ep0QMGI5JmYnWsJwb', + 'status' => 'completed', + 'last_error' => null, + ], + ], + 'first_id' => 'file-HuwUghQzWasTZeX3uRRawY5R', + 'last_id' => 'file-HuwUghQzWasTZeX3uRRawY5R', + 'has_more' => false, + ]; +} diff --git a/src/Testing/Responses/Fixtures/VectorStores/Files/VectorStoreFileResponseFixture.php b/src/Testing/Responses/Fixtures/VectorStores/Files/VectorStoreFileResponseFixture.php new file mode 100644 index 00000000..df2e57bc --- /dev/null +++ b/src/Testing/Responses/Fixtures/VectorStores/Files/VectorStoreFileResponseFixture.php @@ -0,0 +1,16 @@ + 'file-HuwUghQzWasTZeX3uRRawY5R', + 'object' => 'vector_store.file', + 'usage_bytes' => 29882, + 'created_at' => 1_715_956_697, + 'vector_store_id' => 'vs_xds05V7ep0QMGI5JmYnWsJwb', + 'status' => 'completed', + 'last_error' => null, + ]; +} diff --git a/src/Testing/Responses/Fixtures/VectorStores/VectorStoreDeleteResponseFixture.php b/src/Testing/Responses/Fixtures/VectorStores/VectorStoreDeleteResponseFixture.php new file mode 100644 index 00000000..21ef1ca9 --- /dev/null +++ b/src/Testing/Responses/Fixtures/VectorStores/VectorStoreDeleteResponseFixture.php @@ -0,0 +1,12 @@ + 'vs_xzlnkCbIQE50B9A8RzmcFmtP', + 'object' => 'vector_store.deleted', + 'deleted' => true, + ]; +} diff --git a/src/Testing/Responses/Fixtures/VectorStores/VectorStoreListResponseFixture.php b/src/Testing/Responses/Fixtures/VectorStores/VectorStoreListResponseFixture.php new file mode 100644 index 00000000..0c532f4e --- /dev/null +++ b/src/Testing/Responses/Fixtures/VectorStores/VectorStoreListResponseFixture.php @@ -0,0 +1,53 @@ + 'list', + 'data' => [ + [ + 'id' => 'vs_8VE2cQq1jTFlH7FizhYCzUz0', + 'object' => 'vector_store', + 'name' => 'Product Knowledge Base', + 'status' => 'completed', + 'usage_bytes' => 29882, + 'created_at' => 1_715_953_317, + 'file_counts' => [ + 'in_progress' => 0, + 'completed' => 1, + 'failed' => 0, + 'cancelled' => 0, + 'total' => 1, + ], + 'metadata' => [], + 'expires_after' => null, + 'expires_at' => null, + 'last_active_at' => 1_715_953_317, + ], + [ + 'id' => 'vs_xzlnkCbIQE50B9A8RzmcFmtP', + 'object' => 'vector_store', + 'name' => null, + 'status' => 'completed', + 'usage_bytes' => 0, + 'created_at' => 1_710_869_420, + 'file_counts' => [ + 'in_progress' => 0, + 'completed' => 1, + 'failed' => 0, + 'cancelled' => 0, + 'total' => 1, + ], + 'metadata' => [], + 'expires_after' => null, + 'expires_at' => null, + 'last_active_at' => 1_710_869_420, + ], + ], + 'first_id' => 'vs_8VE2cQq1jTFlH7FizhYCzUz0', + 'last_id' => 'vs_xzlnkCbIQE50B9A8RzmcFmtP', + 'has_more' => true, + ]; +} diff --git a/src/Testing/Responses/Fixtures/VectorStores/VectorStoreResponseFixture.php b/src/Testing/Responses/Fixtures/VectorStores/VectorStoreResponseFixture.php new file mode 100644 index 00000000..44561d4a --- /dev/null +++ b/src/Testing/Responses/Fixtures/VectorStores/VectorStoreResponseFixture.php @@ -0,0 +1,26 @@ + 'vs_8VE2cQq1jTFlH7FizhYCzUz0', + 'object' => 'vector_store', + 'name' => 'Product Knowledge Base', + 'status' => 'in_progress', + 'usage_bytes' => 0, + 'created_at' => 1_715_953_317, + 'file_counts' => [ + 'in_progress' => 1, + 'completed' => 0, + 'failed' => 0, + 'cancelled' => 0, + 'total' => 1, + ], + 'metadata' => [], + 'expires_after' => null, + 'expires_at' => null, + 'last_active_at' => 1_715_953_317, + ]; +} diff --git a/tests/Fixtures/VectorStore.php b/tests/Fixtures/VectorStore.php new file mode 100644 index 00000000..2c46163f --- /dev/null +++ b/tests/Fixtures/VectorStore.php @@ -0,0 +1,85 @@ + + */ +function vectorStoreResource(): array +{ + return [ + 'id' => 'vs_8VE2cQq1jTFlH7FizhYCzUz0', + 'object' => 'vector_store', + 'name' => 'Product Knowledge Base', + 'status' => 'completed', + 'usage_bytes' => 29882, + 'created_at' => 1715953317, + 'file_counts' => [ + 'in_progress' => 0, + 'completed' => 1, + 'failed' => 0, + 'cancelled' => 0, + 'total' => 1, + ], + 'metadata' => [], + 'expires_after' => null, + 'expires_at' => null, + 'last_active_at' => 1715953317, + ]; +} + +/** + * @return array + */ +function vectorStoreWithExpiresAfterResource(): array +{ + return [ + 'id' => 'vs_8VE2cQq1jTFlH7FizhYCzUz0', + 'object' => 'vector_store', + 'name' => 'Product Knowledge Base', + 'status' => 'completed', + 'usage_bytes' => 29882, + 'created_at' => 1715953317, + 'file_counts' => [ + 'in_progress' => 0, + 'completed' => 1, + 'failed' => 0, + 'cancelled' => 0, + 'total' => 1, + ], + 'metadata' => [], + 'expires_after' => [ + 'anchor' => 'last_active_at', + 'days' => 7, + ], + 'expires_at' => null, + 'last_active_at' => 1715953317, + ]; +} + +/** + * @return array + */ +function vectorStoreListResource(): array +{ + return [ + 'object' => 'list', + 'data' => [ + vectorStoreResource(), + vectorStoreResource(), + ], + 'first_id' => 'vs_8VE2cQq1jTFlH7FizhYCzUz0', + 'last_id' => 'vs_8VE2cQq1jTFlH7FizhYCzUz0', + 'has_more' => false, + ]; +} + +/** + * @return array + */ +function vectorStoreDeleteResource(): array +{ + return [ + 'id' => 'vs_xzlnkCbIQE50B9A8RzmcFmtP', + 'object' => 'vector_store.deleted', + 'deleted' => true, + ]; +} diff --git a/tests/Fixtures/VectorStoreFile.php b/tests/Fixtures/VectorStoreFile.php new file mode 100644 index 00000000..ba94382a --- /dev/null +++ b/tests/Fixtures/VectorStoreFile.php @@ -0,0 +1,65 @@ + + */ +function vectorStoreFileResource(): array +{ + return [ + 'id' => 'file-HuwUghQzWasTZeX3uRRawY5R', + 'object' => 'vector_store.file', + 'usage_bytes' => 29882, + 'created_at' => 1715956697, + 'vector_store_id' => 'vs_xds05V7ep0QMGI5JmYnWsJwb', + 'status' => 'completed', + 'last_error' => null, + ]; +} + +/** + * @return array + */ +function vectorStoreFileWithLastErrorResource(): array +{ + return [ + 'id' => 'file-HuwUghQzWasTZeX3uRRawY5R', + 'object' => 'vector_store.file', + 'usage_bytes' => 29882, + 'created_at' => 1715956697, + 'vector_store_id' => 'vs_xds05V7ep0QMGI5JmYnWsJwb', + 'status' => 'completed', + 'last_error' => [ + 'code' => 'error-001', + 'message' => 'Error scanning file', + ], + ]; +} + +/** + * @return array + */ +function vectorStoreFileListResource(): array +{ + return [ + 'object' => 'list', + 'data' => [ + vectorStoreFileResource(), + vectorStoreFileResource(), + ], + 'first_id' => 'file-HuwUghQzWasTZeX3uRRawY5R', + 'last_id' => 'file-HuwUghQzWasTZeX3uRRawY5R', + 'has_more' => false, + ]; +} + +/** + * @return array + */ +function vectorStoreFileDeleteResource(): array +{ + return [ + 'id' => 'file-HuwUghQzWasTZeX3uRRawY5R', + 'object' => 'vector_store.file.deleted', + 'deleted' => true, + ]; +} diff --git a/tests/Fixtures/VectorStoreFileBatch.php b/tests/Fixtures/VectorStoreFileBatch.php new file mode 100644 index 00000000..57b3f035 --- /dev/null +++ b/tests/Fixtures/VectorStoreFileBatch.php @@ -0,0 +1,22 @@ + + */ +function vectorStoreFileBatchResource(): array +{ + return [ + 'id' => 'vsfb_abc123', + 'object' => 'vector_store.file_batch', + 'created_at' => 1699061776, + 'vector_store_id' => 'vs_abc123', + 'status' => 'cancelling', + 'file_counts' => [ + 'in_progress' => 12, + 'completed' => 3, + 'failed' => 0, + 'cancelled' => 0, + 'total' => 15, + ], + ]; +} diff --git a/tests/Resources/VectorStores.php b/tests/Resources/VectorStores.php new file mode 100644 index 00000000..07a2bf63 --- /dev/null +++ b/tests/Resources/VectorStores.php @@ -0,0 +1,121 @@ +vectorStores()->create([]); + + expect($result) + ->toBeInstanceOf(VectorStoreResponse::class) + ->id->toBe('vs_8VE2cQq1jTFlH7FizhYCzUz0') + ->object->toBe('vector_store') + ->name->toBe('Product Knowledge Base') + ->status->toBe('completed') + ->usageBytes->toBe(29882) + ->createdAt->toBe(1715953317) + ->fileCounts->toBeInstanceOf(VectorStoreResponseFileCounts::class) + ->expiresAfter->toBeNull() + ->expiresAt->toBeNull() + ->lastActiveAt->toBe(1715953317) + ->metadata->toBeArray() + ->metadata->toBeEmpty(); + + expect($result->meta()) + ->toBeInstanceOf(MetaInformation::class); +}); + +test('list', function () { + $client = mockClient('GET', 'vector_stores', [], Response::from(vectorStoreListResource(), metaHeaders())); + + $result = $client->vectorStores()->list(); + + expect($result) + ->toBeInstanceOf(VectorStoreListResponse::class) + ->object->toBe('list') + ->data->toBeArray()->toHaveCount(2) + ->data->{0}->toBeInstanceOf(VectorStoreResponse::class) + ->firstId->toBe('vs_8VE2cQq1jTFlH7FizhYCzUz0') + ->lastId->toBe('vs_8VE2cQq1jTFlH7FizhYCzUz0') + ->hasMore->toBe(false); + + expect($result->meta()) + ->toBeInstanceOf(MetaInformation::class); +}); + +test('modify', function () { + $client = mockClient('POST', 'vector_stores/vs_8VE2cQq1jTFlH7FizhYCzUz0', [ + 'metadata' => [ + 'modified_by' => 'Jane Doe', + ], + ], Response::from(vectorStoreResource(), metaHeaders())); + + $result = $client->vectorStores()->modify('vs_8VE2cQq1jTFlH7FizhYCzUz0', [ + 'metadata' => [ + 'modified_by' => 'Jane Doe', + ], + ]); + + expect($result) + ->toBeInstanceOf(VectorStoreResponse::class) + ->id->toBe('vs_8VE2cQq1jTFlH7FizhYCzUz0') + ->object->toBe('vector_store') + ->name->toBe('Product Knowledge Base') + ->status->toBe('completed') + ->usageBytes->toBe(29882) + ->createdAt->toBe(1715953317) + ->fileCounts->toBeInstanceOf(VectorStoreResponseFileCounts::class) + ->expiresAfter->toBeNull() + ->expiresAt->toBeNull() + ->lastActiveAt->toBe(1715953317) + ->metadata->toBeArray() + ->metadata->toBeEmpty(); + + expect($result->meta()) + ->toBeInstanceOf(MetaInformation::class); +}); + +test('retrieve', function () { + $client = mockClient('GET', 'vector_stores/vs_8VE2cQq1jTFlH7FizhYCzUz0', [], Response::from(vectorStoreResource(), metaHeaders())); + + $result = $client->vectorStores()->retrieve('vs_8VE2cQq1jTFlH7FizhYCzUz0'); + + expect($result) + ->toBeInstanceOf(VectorStoreResponse::class) + ->id->toBe('vs_8VE2cQq1jTFlH7FizhYCzUz0') + ->object->toBe('vector_store') + ->name->toBe('Product Knowledge Base') + ->status->toBe('completed') + ->usageBytes->toBe(29882) + ->createdAt->toBe(1715953317) + ->fileCounts->toBeInstanceOf(VectorStoreResponseFileCounts::class) + ->expiresAfter->toBeNull() + ->expiresAt->toBeNull() + ->lastActiveAt->toBe(1715953317) + ->metadata->toBeArray() + ->metadata->toBeEmpty(); + + expect($result->meta()) + ->toBeInstanceOf(MetaInformation::class); +}); + +test('delete', function () { + $client = mockClient('DELETE', 'vector_stores/vs_xzlnkCbIQE50B9A8RzmcFmtP', [], Response::from(vectorStoreDeleteResource(), metaHeaders())); + + $result = $client->vectorStores()->delete('vs_xzlnkCbIQE50B9A8RzmcFmtP'); + + expect($result) + ->toBeInstanceOf(VectorStoreDeleteResponse::class) + ->id->toBe('vs_xzlnkCbIQE50B9A8RzmcFmtP') + ->object->toBe('vector_store.deleted') + ->deleted->toBe(true); + + expect($result->meta()) + ->toBeInstanceOf(MetaInformation::class); +}); diff --git a/tests/Resources/VectorStoresFileBatches.php b/tests/Resources/VectorStoresFileBatches.php new file mode 100644 index 00000000..a4f3f9fb --- /dev/null +++ b/tests/Resources/VectorStoresFileBatches.php @@ -0,0 +1,80 @@ +vectorStores()->batches()->create('vs_abc123', []); + + expect($result) + ->toBeInstanceOf(VectorStoreFileBatchResponse::class) + ->id->toBe('vsfb_abc123') + ->object->toBe('vector_store.file_batch') + ->createdAt->toBe(1699061776) + ->vectorStoreId->toBe('vs_abc123') + ->status->toBe('cancelling') + ->fileCounts->toBeInstanceOf(VectorStoreResponseFileCounts::class); + + expect($result->meta()) + ->toBeInstanceOf(MetaInformation::class); +}); + +test('retrieve', function () { + $client = mockClient('GET', 'vector_stores/vs_abc123/file_batches/vsfb_abc123', [], Response::from(vectorStoreFileBatchResource(), metaHeaders())); + + $result = $client->vectorStores()->batches()->retrieve('vs_abc123', 'vsfb_abc123'); + + expect($result) + ->toBeInstanceOf(VectorStoreFileBatchResponse::class) + ->id->toBe('vsfb_abc123') + ->object->toBe('vector_store.file_batch') + ->createdAt->toBe(1699061776) + ->vectorStoreId->toBe('vs_abc123') + ->status->toBe('cancelling') + ->fileCounts->toBeInstanceOf(VectorStoreResponseFileCounts::class); + + expect($result->meta()) + ->toBeInstanceOf(MetaInformation::class); +}); + +test('cancel', function () { + $client = mockClient('DELETE', 'vector_stores/vs_abc123/file_batches/vsfb_abc123', [], Response::from(vectorStoreFileBatchResource(), metaHeaders())); + + $result = $client->vectorStores()->batches()->cancel('vs_abc123', 'vsfb_abc123'); + + expect($result) + ->toBeInstanceOf(VectorStoreFileBatchResponse::class) + ->id->toBe('vsfb_abc123') + ->object->toBe('vector_store.file_batch') + ->createdAt->toBe(1699061776) + ->vectorStoreId->toBe('vs_abc123') + ->status->toBe('cancelling') + ->fileCounts->toBeInstanceOf(VectorStoreResponseFileCounts::class); + + expect($result->meta()) + ->toBeInstanceOf(MetaInformation::class); +}); + +test('list', function () { + $client = mockClient('GET', 'vector_stores/vs_abc123/file_batches/vsfb_abc123/files', [], Response::from(vectorStoreFileListResource(), metaHeaders())); + + $result = $client->vectorStores()->batches()->listFiles('vs_abc123', 'vsfb_abc123'); + + expect($result) + ->toBeInstanceOf(VectorStoreFileListResponse::class) + ->object->toBe('list') + ->data->toBeArray()->toHaveCount(2) + ->data->{0}->toBeInstanceOf(VectorStoreFileResponse::class) + ->firstId->toBe('file-HuwUghQzWasTZeX3uRRawY5R') + ->lastId->toBe('file-HuwUghQzWasTZeX3uRRawY5R') + ->hasMore->toBe(false); + + expect($result->meta()) + ->toBeInstanceOf(MetaInformation::class); +}); diff --git a/tests/Resources/VectorStoresFiles.php b/tests/Resources/VectorStoresFiles.php new file mode 100644 index 00000000..a52b1fef --- /dev/null +++ b/tests/Resources/VectorStoresFiles.php @@ -0,0 +1,78 @@ +vectorStores()->files()->create('vs_xds05V7ep0QMGI5JmYnWsJwb', []); + + expect($result) + ->toBeInstanceOf(VectorStoreFileResponse::class) + ->id->toBe('file-HuwUghQzWasTZeX3uRRawY5R') + ->object->toBe('vector_store.file') + ->usageBytes->toBe(29882) + ->createdAt->toBe(1715956697) + ->vectorStoreId->toBe('vs_xds05V7ep0QMGI5JmYnWsJwb') + ->status->toBe('completed') + ->lastError->toBeNull(); + + expect($result->meta()) + ->toBeInstanceOf(MetaInformation::class); +}); + +test('list', function () { + $client = mockClient('GET', 'vector_stores/vs_xds05V7ep0QMGI5JmYnWsJwb/files', [], Response::from(vectorStoreFileListResource(), metaHeaders())); + + $result = $client->vectorStores()->files()->list('vs_xds05V7ep0QMGI5JmYnWsJwb'); + + expect($result) + ->toBeInstanceOf(VectorStoreFileListResponse::class) + ->object->toBe('list') + ->data->toBeArray()->toHaveCount(2) + ->data->{0}->toBeInstanceOf(VectorStoreFileResponse::class) + ->firstId->toBe('file-HuwUghQzWasTZeX3uRRawY5R') + ->lastId->toBe('file-HuwUghQzWasTZeX3uRRawY5R') + ->hasMore->toBe(false); + + expect($result->meta()) + ->toBeInstanceOf(MetaInformation::class); +}); + +test('retrieve', function () { + $client = mockClient('GET', 'vector_stores/vs_8VE2cQq1jTFlH7FizhYCzUz0/files/file-HuwUghQzWasTZeX3uRRawY5R', [], Response::from(vectorStoreFileResource(), metaHeaders())); + + $result = $client->vectorStores()->files()->retrieve('vs_8VE2cQq1jTFlH7FizhYCzUz0', 'file-HuwUghQzWasTZeX3uRRawY5R'); + + expect($result) + ->toBeInstanceOf(VectorStoreFileResponse::class) + ->id->toBe('file-HuwUghQzWasTZeX3uRRawY5R') + ->object->toBe('vector_store.file') + ->usageBytes->toBe(29882) + ->createdAt->toBe(1715956697) + ->vectorStoreId->toBe('vs_xds05V7ep0QMGI5JmYnWsJwb') + ->status->toBe('completed') + ->lastError->toBeNull(); + + expect($result->meta()) + ->toBeInstanceOf(MetaInformation::class); +}); + +test('delete', function () { + $client = mockClient('DELETE', 'vector_stores/vs_xzlnkCbIQE50B9A8RzmcFmtP/files/file-HuwUghQzWasTZeX3uRRawY5R', [], Response::from(vectorStoreFileDeleteResource(), metaHeaders())); + + $result = $client->vectorStores()->files()->delete('vs_xzlnkCbIQE50B9A8RzmcFmtP', 'file-HuwUghQzWasTZeX3uRRawY5R'); + + expect($result) + ->toBeInstanceOf(VectorStoreFileDeleteResponse::class) + ->id->toBe('file-HuwUghQzWasTZeX3uRRawY5R') + ->object->toBe('vector_store.file.deleted') + ->deleted->toBe(true); + + expect($result->meta()) + ->toBeInstanceOf(MetaInformation::class); +}); diff --git a/tests/Responses/VectorStores/FileBatches/VectorStoreFileBatchResponse.php b/tests/Responses/VectorStores/FileBatches/VectorStoreFileBatchResponse.php new file mode 100644 index 00000000..3eb393ce --- /dev/null +++ b/tests/Responses/VectorStores/FileBatches/VectorStoreFileBatchResponse.php @@ -0,0 +1,30 @@ +id->toBe('vsfb_abc123') + ->object->toBe('vector_store.file_batch') + ->createdAt->toBe(1699061776) + ->vectorStoreId->toBe('vs_abc123') + ->status->toBe('cancelling') + ->fileCounts->toBeInstanceOf(VectorStoreResponseFileCounts::class); +}); + +test('as array accessible', function () { + $result = VectorStoreFileBatchResponse::from(vectorStoreFileBatchResource(), meta()); + + expect($result['vector_store_id']) + ->toBe('vs_abc123'); +}); + +test('to array', function () { + $result = VectorStoreFileBatchResponse::from(vectorStoreFileBatchResource(), meta()); + + expect($result->toArray()) + ->toBe(vectorStoreFileBatchResource()); +}); diff --git a/tests/Responses/VectorStores/Files/VectorStoreFileDeleteResponse.php b/tests/Responses/VectorStores/Files/VectorStoreFileDeleteResponse.php new file mode 100644 index 00000000..f4bae137 --- /dev/null +++ b/tests/Responses/VectorStores/Files/VectorStoreFileDeleteResponse.php @@ -0,0 +1,47 @@ +id->toBe('file-HuwUghQzWasTZeX3uRRawY5R') + ->object->toBe('vector_store.file.deleted') + ->deleted->toBe(true) + ->meta()->toBeInstanceOf(MetaInformation::class); +}); + +test('as array accessible', function () { + $result = VectorStoreFileDeleteResponse::from(vectorStoreFileDeleteResource(), meta()); + + expect($result['id']) + ->toBe('file-HuwUghQzWasTZeX3uRRawY5R'); +}); + +test('to array', function () { + $result = VectorStoreFileDeleteResponse::from(vectorStoreFileDeleteResource(), meta()); + + expect($result->toArray()) + ->toBe(vectorStoreFileDeleteResource()); +}); + +test('fake', function () { + $response = VectorStoreFileDeleteResponse::fake(); + + expect($response) + ->id->toBe('file-HuwUghQzWasTZeX3uRRawY5R') + ->deleted->toBe(true); +}); + +test('fake with override', function () { + $response = VectorStoreFileDeleteResponse::fake([ + 'id' => 'file-1234', + 'deleted' => false, + ]); + + expect($response) + ->id->toBe('file-1234') + ->deleted->toBe(false); +}); diff --git a/tests/Responses/VectorStores/Files/VectorStoreFileListResponse.php b/tests/Responses/VectorStores/Files/VectorStoreFileListResponse.php new file mode 100644 index 00000000..4ab309f6 --- /dev/null +++ b/tests/Responses/VectorStores/Files/VectorStoreFileListResponse.php @@ -0,0 +1,30 @@ +object->toBe('list') + ->data->toBeArray()->toHaveCount(2) + ->data->{0}->toBeInstanceOf(VectorStoreFileResponse::class) + ->firstId->toBe('file-HuwUghQzWasTZeX3uRRawY5R') + ->lastId->toBe('file-HuwUghQzWasTZeX3uRRawY5R') + ->hasMore->toBe(false); +}); + +test('as array accessible', function () { + $result = VectorStoreFileListResponse::from(vectorStoreFileListResource(), meta()); + + expect($result['first_id']) + ->toBe('file-HuwUghQzWasTZeX3uRRawY5R'); +}); + +test('to array', function () { + $result = VectorStoreFileListResponse::from(vectorStoreFileListResource(), meta()); + + expect($result->toArray()) + ->toBe(vectorStoreFileListResource()); +}); diff --git a/tests/Responses/VectorStores/Files/VectorStoreFileResponse.php b/tests/Responses/VectorStores/Files/VectorStoreFileResponse.php new file mode 100644 index 00000000..8d093df1 --- /dev/null +++ b/tests/Responses/VectorStores/Files/VectorStoreFileResponse.php @@ -0,0 +1,30 @@ +id->toBe('file-HuwUghQzWasTZeX3uRRawY5R') + ->object->toBe('vector_store.file') + ->usageBytes->toBe(29882) + ->createdAt->toBe(1715956697) + ->vectorStoreId->toBe('vs_xds05V7ep0QMGI5JmYnWsJwb') + ->status->toBe('completed') + ->lastError->toBeNull(); +}); + +test('as array accessible', function () { + $result = VectorStoreFileResponse::from(vectorStoreFileResource(), meta()); + + expect($result['vector_store_id']) + ->toBe('vs_xds05V7ep0QMGI5JmYnWsJwb'); +}); + +test('to array', function () { + $result = VectorStoreFileResponse::from(vectorStoreFileResource(), meta()); + + expect($result->toArray()) + ->toBe(vectorStoreFileResource()); +}); diff --git a/tests/Responses/VectorStores/Files/VectorStoreFileResponseLastError.php b/tests/Responses/VectorStores/Files/VectorStoreFileResponseLastError.php new file mode 100644 index 00000000..b2d06caa --- /dev/null +++ b/tests/Responses/VectorStores/Files/VectorStoreFileResponseLastError.php @@ -0,0 +1,25 @@ +code->toBe('error-001') + ->message->toBe('Error scanning file'); +}); + +test('as array accessible', function () { + $result = VectorStoreFileResponseLastError::from(vectorStoreFileWithLastErrorResource()['last_error'], meta()); + + expect($result['message']) + ->toBe('Error scanning file'); +}); + +test('to array', function () { + $result = VectorStoreFileResponseLastError::from(vectorStoreFileWithLastErrorResource()['last_error'], meta()); + + expect($result->toArray()) + ->toBe(vectorStoreFileWithLastErrorResource()['last_error']); +}); diff --git a/tests/Responses/VectorStores/VectorStoreDeleteResponse.php b/tests/Responses/VectorStores/VectorStoreDeleteResponse.php new file mode 100644 index 00000000..601bb7fd --- /dev/null +++ b/tests/Responses/VectorStores/VectorStoreDeleteResponse.php @@ -0,0 +1,47 @@ +id->toBe('vs_xzlnkCbIQE50B9A8RzmcFmtP') + ->object->toBe('vector_store.deleted') + ->deleted->toBe(true) + ->meta()->toBeInstanceOf(MetaInformation::class); +}); + +test('as array accessible', function () { + $result = VectorStoreDeleteResponse::from(vectorStoreDeleteResource(), meta()); + + expect($result['id']) + ->toBe('vs_xzlnkCbIQE50B9A8RzmcFmtP'); +}); + +test('to array', function () { + $result = VectorStoreDeleteResponse::from(vectorStoreDeleteResource(), meta()); + + expect($result->toArray()) + ->toBe(vectorStoreDeleteResource()); +}); + +test('fake', function () { + $response = VectorStoreDeleteResponse::fake(); + + expect($response) + ->id->toBe('vs_xzlnkCbIQE50B9A8RzmcFmtP') + ->deleted->toBe(true); +}); + +test('fake with override', function () { + $response = VectorStoreDeleteResponse::fake([ + 'id' => 'vz_1234', + 'deleted' => false, + ]); + + expect($response) + ->id->toBe('vz_1234') + ->deleted->toBe(false); +}); diff --git a/tests/Responses/VectorStores/VectorStoreListResponse.php b/tests/Responses/VectorStores/VectorStoreListResponse.php new file mode 100644 index 00000000..aaebc5a8 --- /dev/null +++ b/tests/Responses/VectorStores/VectorStoreListResponse.php @@ -0,0 +1,30 @@ +object->toBe('list') + ->data->toBeArray()->toHaveCount(2) + ->data->{0}->toBeInstanceOf(VectorStoreResponse::class) + ->firstId->toBe('vs_8VE2cQq1jTFlH7FizhYCzUz0') + ->lastId->toBe('vs_8VE2cQq1jTFlH7FizhYCzUz0') + ->hasMore->toBe(false); +}); + +test('as array accessible', function () { + $result = VectorStoreListResponse::from(vectorStoreListResource(), meta()); + + expect($result['first_id']) + ->toBe('vs_8VE2cQq1jTFlH7FizhYCzUz0'); +}); + +test('to array', function () { + $result = VectorStoreListResponse::from(vectorStoreListResource(), meta()); + + expect($result->toArray()) + ->toBe(vectorStoreListResource()); +}); diff --git a/tests/Responses/VectorStores/VectorStoreResponse.php b/tests/Responses/VectorStores/VectorStoreResponse.php new file mode 100644 index 00000000..6dea06a3 --- /dev/null +++ b/tests/Responses/VectorStores/VectorStoreResponse.php @@ -0,0 +1,36 @@ +id->toBe('vs_8VE2cQq1jTFlH7FizhYCzUz0') + ->object->toBe('vector_store') + ->name->toBe('Product Knowledge Base') + ->status->toBe('completed') + ->usageBytes->toBe(29882) + ->createdAt->toBe(1715953317) + ->fileCounts->toBeInstanceOf(VectorStoreResponseFileCounts::class) + ->expiresAfter->toBeNull() + ->expiresAt->toBeNull() + ->lastActiveAt->toBe(1715953317) + ->metadata->toBeArray() + ->metadata->toBeEmpty(); +}); + +test('as array accessible', function () { + $result = VectorStoreResponse::from(vectorStoreResource(), meta()); + + expect($result['usage_bytes']) + ->toBe(29882); +}); + +test('to array', function () { + $result = VectorStoreResponse::from(vectorStoreResource(), meta()); + + expect($result->toArray()) + ->toBe(vectorStoreResource()); +}); diff --git a/tests/Responses/VectorStores/VectorStoreResponseExpiresAfter.php b/tests/Responses/VectorStores/VectorStoreResponseExpiresAfter.php new file mode 100644 index 00000000..4fc0865b --- /dev/null +++ b/tests/Responses/VectorStores/VectorStoreResponseExpiresAfter.php @@ -0,0 +1,25 @@ +anchor->toBe('last_active_at') + ->days->toBe(7); +}); + +test('as array accessible', function () { + $result = VectorStoreResponseExpiresAfter::from(vectorStoreWithExpiresAfterResource()['expires_after']); + + expect($result['anchor']) + ->toBe('last_active_at'); +}); + +test('to array', function () { + $result = VectorStoreResponseExpiresAfter::from(vectorStoreWithExpiresAfterResource()['expires_after']); + + expect($result->toArray()) + ->toBe(vectorStoreWithExpiresAfterResource()['expires_after']); +}); diff --git a/tests/Responses/VectorStores/VectorStoreResponseFileCounts.php b/tests/Responses/VectorStores/VectorStoreResponseFileCounts.php new file mode 100644 index 00000000..87faa60e --- /dev/null +++ b/tests/Responses/VectorStores/VectorStoreResponseFileCounts.php @@ -0,0 +1,28 @@ +inProgress->toBe(0) + ->completed->toBe(1) + ->failed->toBe(0) + ->cancelled->toBe(0) + ->total->toBe(1); +}); + +test('as array accessible', function () { + $result = VectorStoreResponseFileCounts::from(vectorStoreResource()['file_counts']); + + expect($result['total']) + ->toBe(1); +}); + +test('to array', function () { + $result = VectorStoreResponseFileCounts::from(vectorStoreResource()['file_counts']); + + expect($result->toArray()) + ->toBe(vectorStoreResource()['file_counts']); +}); From 2f3aa159745a5ca7700924848310ab8a35d86fa3 Mon Sep 17 00:00:00 2001 From: beliven-daniele-sarnari <131280766+beliven-daniele-sarnari@users.noreply.github.com> Date: Sun, 26 May 2024 20:55:28 +0200 Subject: [PATCH 02/15] fix: expect delta to not exist --- src/Responses/Chat/CreateStreamedResponseChoice.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Responses/Chat/CreateStreamedResponseChoice.php b/src/Responses/Chat/CreateStreamedResponseChoice.php index 6e4f7886..33b07350 100644 --- a/src/Responses/Chat/CreateStreamedResponseChoice.php +++ b/src/Responses/Chat/CreateStreamedResponseChoice.php @@ -20,7 +20,7 @@ public static function from(array $attributes): self { return new self( $attributes['index'], - CreateStreamedResponseDelta::from($attributes['delta']), + CreateStreamedResponseDelta::from($attributes['delta'] ?? []), $attributes['finish_reason'] ?? null, ); } From b74b254e7b2f43c2b4b7d60a829281dabafd4f14 Mon Sep 17 00:00:00 2001 From: Sandro Gehri Date: Sun, 26 May 2024 23:19:17 +0200 Subject: [PATCH 03/15] Update assistants API to v2 --- README.md | 231 +++++++----------- .../Resources/AssistantsContract.php | 9 +- .../Resources/AssistantsFilesContract.php | 42 ---- .../Resources/ThreadsMessagesContract.php | 7 - .../ThreadsMessagesFilesContract.php | 25 -- src/OpenAI.php | 2 +- src/Resources/Assistants.php | 21 +- src/Resources/AssistantsFiles.php | 81 ------ src/Resources/Threads.php | 8 +- src/Resources/ThreadsMessages.php | 19 +- src/Resources/ThreadsMessagesFiles.php | 48 ---- src/Resources/ThreadsRuns.php | 12 +- src/Resources/ThreadsRunsSteps.php | 4 +- .../Assistants/AssistantListResponse.php | 6 +- .../Assistants/AssistantResponse.php | 36 ++- .../AssistantResponseResponseFormat.php | 49 ++++ ...> AssistantResponseResponseFormatText.php} | 4 +- .../AssistantResponseToolFileSearch.php | 49 ++++ ...antResponseToolResourceCodeInterpreter.php | 52 ++++ ...ssistantResponseToolResourceFileSearch.php | 52 ++++ .../AssistantResponseToolResources.php | 52 ++++ .../Files/AssistantFileDeleteResponse.php | 61 ----- .../Files/AssistantFileListResponse.php | 78 ------ .../Files/AssistantFileResponse.php | 64 ----- .../Delta/ThreadMessageDeltaObject.php | 6 +- .../Delta/ThreadMessageDeltaResponse.php | 6 +- ...ageDeltaResponseContentImageFileObject.php | 6 +- .../ThreadMessageDeltaResponseContentText.php | 12 +- ...dMessageDeltaResponseContentTextObject.php | 6 +- .../Files/ThreadMessageFileListResponse.php | 78 ------ .../Files/ThreadMessageFileResponse.php | 64 ----- .../Messages/ThreadMessageListResponse.php | 6 +- .../Messages/ThreadMessageResponse.php | 41 +++- .../ThreadMessageResponseAttachment.php | 63 +++++ ...eResponseAttachmentCodeInterpreterTool.php | 52 ++++ ...essageResponseAttachmentFileSearchTool.php | 52 ++++ .../ThreadMessageResponseContentImageFile.php | 13 +- ...dMessageResponseContentImageFileObject.php | 6 +- .../ThreadMessageResponseContentImageUrl.php | 52 ++++ ...adMessageResponseContentImageUrlObject.php | 55 +++++ ...ThreadMessageResponseContentTextObject.php | 9 +- ...ThreadMessageResponseIncompleteDetails.php | 49 ++++ .../Steps/Delta/ThreadRunStepDeltaObject.php | 6 +- .../Delta/ThreadRunStepDeltaResponse.php | 6 +- .../Runs/Steps/ThreadRunStepListResponse.php | 6 +- .../Runs/Steps/ThreadRunStepResponse.php | 9 +- .../ThreadRunStepResponseCodeInterpreter.php | 35 +-- .../ThreadRunStepResponseCodeToolCall.php | 6 +- ...readRunStepResponseFileSearchToolCall.php} | 18 +- ...eadRunStepResponseToolCallsStepDetails.php | 14 +- .../Runs/Steps/ThreadRunStepResponseUsage.php | 55 +++++ .../Threads/Runs/ThreadRunListResponse.php | 6 +- .../Threads/Runs/ThreadRunResponse.php | 47 +++- ...al.php => ThreadRunResponseFileSearch.php} | 4 +- .../ThreadRunResponseIncompleteDetails.php | 49 ++++ .../Runs/ThreadRunResponseToolChoice.php | 57 +++++ .../ThreadRunResponseToolChoiceFunction.php | 49 ++++ .../ThreadRunResponseTruncationStrategy.php | 52 ++++ src/Responses/Threads/ThreadResponse.php | 10 +- .../Resources/AssistantsFilesTestResource.php | 40 --- .../Resources/AssistantsTestResource.php | 5 - .../ThreadsMessagesFilesTestResource.php | 29 --- .../Resources/ThreadsMessagesTestResource.php | 5 - .../AssistantListResponseFixture.php | 5 +- .../Assistants/AssistantResponseFixture.php | 5 +- .../AssistantFileDeleteResponseFixture.php | 12 - .../AssistantFileListResponseFixture.php | 21 -- .../Files/AssistantFileResponseFixture.php | 13 - .../ThreadMessageFileListResponseFixture.php | 21 -- .../ThreadMessageFileResponseFixture.php | 13 - .../ThreadMessageListResponseFixture.php | 11 +- .../Messages/ThreadMessageResponseFixture.php | 11 +- .../ThreadRunStepListResponseFixture.php | 5 + .../Steps/ThreadRunStepResponseFixture.php | 5 + .../Runs/ThreadRunListResponseFixture.php | 14 +- .../Threads/Runs/ThreadRunResponseFixture.php | 14 +- tests/Fixtures/Assistant.php | 86 ++++++- tests/Fixtures/AssistantFile.php | 43 ---- tests/Fixtures/Thread.php | 1 + tests/Fixtures/ThreadMessage.php | 18 +- tests/Fixtures/ThreadMessageFile.php | 31 --- tests/Fixtures/ThreadRun.php | 162 +++++++++++- tests/Fixtures/ThreadRunSteps.php | 19 +- tests/Resources/Assistants.php | 21 +- tests/Resources/AssistantsFiles.php | 76 ------ tests/Resources/Threads.php | 1 - tests/Resources/ThreadsMessages.php | 33 ++- tests/Resources/ThreadsMessagesFiles.php | 40 --- tests/Resources/ThreadsRuns.php | 5 - .../Assistants/AssistantResponse.php | 59 ++++- .../AssistantResponseResponseFormat.php | 24 ++ .../AssistantResponseToolFileSearch.php | 24 ++ ...antResponseToolResourceCodeInterpreter.php | 24 ++ ...ssistantResponseToolResourceFileSearch.php | 24 ++ .../AssistantResponseToolRetrieval.php | 24 -- .../Files/AssistantFileDeleteResponse.php | 47 ---- .../Files/AssistantFileListResponse.php | 50 ---- .../Files/AssistantFileResponse.php | 45 ---- .../Files/ThreadMessageFileListResponse.php | 50 ---- .../Files/ThreadMessageFileResponse.php | 45 ---- .../Messages/ThreadMessageResponse.php | 5 +- .../ThreadMessageResponseAttachment.php | 29 +++ ...eResponseAttachmentCodeInterpreterTool.php | 24 ++ ...essageResponseAttachmentFileSearchTool.php | 24 ++ .../ThreadMessageResponseContentImageUrl.php | 27 ++ ...adMessageResponseContentImageUrlObject.php | 28 +++ .../Runs/Steps/ThreadRunStepResponse.php | 4 +- ...ThreadRunStepResponseRetrievalToolCall.php | 12 +- .../Runs/Steps/ThreadRunStepResponseUsage.php | 25 ++ .../Threads/Runs/ThreadRunResponse.php | 52 +++- .../ThreadRunResponseIncompleteDetails.php | 23 ++ .../Runs/ThreadRunResponseToolChoice.php | 26 ++ .../ThreadRunResponseToolChoiceFunction.php | 24 ++ .../Runs/ThreadRunResponseToolRetrieval.php | 12 +- .../ThreadRunResponseTruncationStrategy.php | 24 ++ .../Resources/AssistantsFilesTestResource.php | 72 ------ .../ThreadsMessagesFilesTestResource.php | 46 ---- 117 files changed, 1977 insertions(+), 1678 deletions(-) delete mode 100644 src/Contracts/Resources/AssistantsFilesContract.php delete mode 100644 src/Contracts/Resources/ThreadsMessagesFilesContract.php delete mode 100644 src/Resources/AssistantsFiles.php delete mode 100644 src/Resources/ThreadsMessagesFiles.php create mode 100644 src/Responses/Assistants/AssistantResponseResponseFormat.php rename src/Responses/Assistants/{AssistantResponseToolRetrieval.php => AssistantResponseResponseFormatText.php} (87%) create mode 100644 src/Responses/Assistants/AssistantResponseToolFileSearch.php create mode 100644 src/Responses/Assistants/AssistantResponseToolResourceCodeInterpreter.php create mode 100644 src/Responses/Assistants/AssistantResponseToolResourceFileSearch.php create mode 100644 src/Responses/Assistants/AssistantResponseToolResources.php delete mode 100644 src/Responses/Assistants/Files/AssistantFileDeleteResponse.php delete mode 100644 src/Responses/Assistants/Files/AssistantFileListResponse.php delete mode 100644 src/Responses/Assistants/Files/AssistantFileResponse.php delete mode 100644 src/Responses/Threads/Messages/Files/ThreadMessageFileListResponse.php delete mode 100644 src/Responses/Threads/Messages/Files/ThreadMessageFileResponse.php create mode 100644 src/Responses/Threads/Messages/ThreadMessageResponseAttachment.php create mode 100644 src/Responses/Threads/Messages/ThreadMessageResponseAttachmentCodeInterpreterTool.php create mode 100644 src/Responses/Threads/Messages/ThreadMessageResponseAttachmentFileSearchTool.php create mode 100644 src/Responses/Threads/Messages/ThreadMessageResponseContentImageUrl.php create mode 100644 src/Responses/Threads/Messages/ThreadMessageResponseContentImageUrlObject.php create mode 100644 src/Responses/Threads/Messages/ThreadMessageResponseIncompleteDetails.php rename src/Responses/Threads/Runs/Steps/{ThreadRunStepResponseRetrievalToolCall.php => ThreadRunStepResponseFileSearchToolCall.php} (58%) create mode 100644 src/Responses/Threads/Runs/Steps/ThreadRunStepResponseUsage.php rename src/Responses/Threads/Runs/{ThreadRunResponseToolRetrieval.php => ThreadRunResponseFileSearch.php} (87%) create mode 100644 src/Responses/Threads/Runs/ThreadRunResponseIncompleteDetails.php create mode 100644 src/Responses/Threads/Runs/ThreadRunResponseToolChoice.php create mode 100644 src/Responses/Threads/Runs/ThreadRunResponseToolChoiceFunction.php create mode 100644 src/Responses/Threads/Runs/ThreadRunResponseTruncationStrategy.php delete mode 100644 src/Testing/Resources/AssistantsFilesTestResource.php delete mode 100644 src/Testing/Resources/ThreadsMessagesFilesTestResource.php delete mode 100644 src/Testing/Responses/Fixtures/Assistants/Files/AssistantFileDeleteResponseFixture.php delete mode 100644 src/Testing/Responses/Fixtures/Assistants/Files/AssistantFileListResponseFixture.php delete mode 100644 src/Testing/Responses/Fixtures/Assistants/Files/AssistantFileResponseFixture.php delete mode 100644 src/Testing/Responses/Fixtures/Threads/Messages/Files/ThreadMessageFileListResponseFixture.php delete mode 100644 src/Testing/Responses/Fixtures/Threads/Messages/Files/ThreadMessageFileResponseFixture.php delete mode 100644 tests/Fixtures/AssistantFile.php delete mode 100644 tests/Fixtures/ThreadMessageFile.php delete mode 100644 tests/Resources/AssistantsFiles.php delete mode 100644 tests/Resources/ThreadsMessagesFiles.php create mode 100644 tests/Responses/Assistants/AssistantResponseResponseFormat.php create mode 100644 tests/Responses/Assistants/AssistantResponseToolFileSearch.php create mode 100644 tests/Responses/Assistants/AssistantResponseToolResourceCodeInterpreter.php create mode 100644 tests/Responses/Assistants/AssistantResponseToolResourceFileSearch.php delete mode 100644 tests/Responses/Assistants/AssistantResponseToolRetrieval.php delete mode 100644 tests/Responses/Assistants/Files/AssistantFileDeleteResponse.php delete mode 100644 tests/Responses/Assistants/Files/AssistantFileListResponse.php delete mode 100644 tests/Responses/Assistants/Files/AssistantFileResponse.php delete mode 100644 tests/Responses/Threads/Messages/Files/ThreadMessageFileListResponse.php delete mode 100644 tests/Responses/Threads/Messages/Files/ThreadMessageFileResponse.php create mode 100644 tests/Responses/Threads/Messages/ThreadMessageResponseAttachment.php create mode 100644 tests/Responses/Threads/Messages/ThreadMessageResponseAttachmentCodeInterpreterTool.php create mode 100644 tests/Responses/Threads/Messages/ThreadMessageResponseAttachmentFileSearchTool.php create mode 100644 tests/Responses/Threads/Messages/ThreadMessageResponseContentImageUrl.php create mode 100644 tests/Responses/Threads/Messages/ThreadMessageResponseContentImageUrlObject.php create mode 100644 tests/Responses/Threads/Runs/Steps/ThreadRunStepResponseUsage.php create mode 100644 tests/Responses/Threads/Runs/ThreadRunResponseIncompleteDetails.php create mode 100644 tests/Responses/Threads/Runs/ThreadRunResponseToolChoice.php create mode 100644 tests/Responses/Threads/Runs/ThreadRunResponseToolChoiceFunction.php create mode 100644 tests/Responses/Threads/Runs/ThreadRunResponseTruncationStrategy.php delete mode 100644 tests/Testing/Resources/AssistantsFilesTestResource.php delete mode 100644 tests/Testing/Resources/ThreadsMessagesFilesTestResource.php diff --git a/README.md b/README.md index 568e3082..146efd23 100644 --- a/README.md +++ b/README.md @@ -27,10 +27,8 @@ - [Moderations Resource](#moderations-resource) - [Images Resource](#images-resource) - [Assistants Resource](#assistants-resource) - - [Assistants Files Resource](#assistants-files-resource) - [Threads Resource](#threads-resource) - [Threads Messages Resource](#threads-messages-resource) - - [Threads Messages Files Resource](#threads-messages-files-resource) - [Threads Runs Resource](#threads-runs-resource) - [Threads Runs Steps Resource](#threads-runs-steps-resource) - [Batches Resource](#batches-resource) @@ -943,7 +941,7 @@ $response->toArray(); // ['created' => 1589478378, data => ['url' => 'https://oa > **Note:** If you are creating the client manually from the factory. Make sure you provide the necessary header: > ```php -> $factory->withHttpHeader('OpenAI-Beta', 'assistants=v1') +> $factory->withHttpHeader('OpenAI-Beta', 'assistants=v2') > ``` #### `create` @@ -970,8 +968,11 @@ $response->instructions; // 'You are a personal math tutor. When asked a questio $response->model; // 'gpt-4' $response->description; // null $response->tools[0]->type; // 'code_interpreter' -$response->fileIds; // [] +$response->toolResources; // [] $response->metadata; // [] +$response->temperature: // null +$response->topP: // null +$response->format: // 'auto' $response->toArray(); // ['id' => 'asst_gxzBkD1wkKEloYqZ410pT5pd', ...] ``` @@ -991,8 +992,11 @@ $response->instructions; // 'You are a personal math tutor. When asked a questio $response->model; // 'gpt-4' $response->description; // null $response->tools[0]->type; // 'code_interpreter' -$response->fileIds; // [] +$response->toolResources; // [] $response->metadata; // [] +$response->temperature: // null +$response->topP: // null +$response->format: // 'auto' $response->toArray(); // ['id' => 'asst_gxzBkD1wkKEloYqZ410pT5pd', ...] ``` @@ -1014,8 +1018,11 @@ $response->instructions; // 'You are a personal math tutor. When asked a questio $response->model; // 'gpt-4' $response->description; // null $response->tools[0]->type; // 'code_interpreter' -$response->fileIds; // [] +$response->toolResources; // [] $response->metadata; // [] +$response->temperature: // null +$response->topP: // null +$response->format: // 'auto' $response->toArray(); // ['id' => 'asst_gxzBkD1wkKEloYqZ410pT5pd', ...] ``` @@ -1056,81 +1063,6 @@ foreach ($response->data as $result) { $response->toArray(); // ['object' => 'list', ...]] ``` -### `Assistants Files` Resource - -#### `create` - -Create an assistant file by attaching a file to an assistant. - -```php -$response = $client->assistants()->files()->create('asst_gxzBkD1wkKEloYqZ410pT5pd', [ - 'file_id' => 'file-wB6RM6wHdA49HfS2DJ9fEyrH', -]); - -$response->id; // 'file-wB6RM6wHdA49HfS2DJ9fEyrH' -$response->object; // 'assistant.file' -$response->createdAt; // 1623936000 -$response->assistantId; // 'asst_gxzBkD1wkKEloYqZ410pT5pd' - -$response->toArray(); // ['id' => 'file-wB6RM6wHdA49HfS2DJ9fEyrH', ...] -``` - -#### `retrieve` - -Retrieves an AssistantFile. - -```php -$response = $client->assistants()->files()->retrieve( - assistantId: 'asst_gxzBkD1wkKEloYqZ410pT5pd', - fileId: 'file-wB6RM6wHdA49HfS2DJ9fEyrH' -); - -$response->id; // 'file-wB6RM6wHdA49HfS2DJ9fEyrH' -$response->object; // 'assistant.file' -$response->createdAt; // 1623936000 -$response->assistantId; // 'asst_gxzBkD1wkKEloYqZ410pT5pd' - -$response->toArray(); // ['id' => 'file-wB6RM6wHdA49HfS2DJ9fEyrH', ...] -``` - -#### `delete` - -Delete an assistant file. - -```php -$response = $client->assistants()->files()->delete( - assistantId: 'asst_gxzBkD1wkKEloYqZ410pT5pd', - fileId: 'file-wB6RM6wHdA49HfS2DJ9fEyrH' -); - -$response->id; // 'file-wB6RM6wHdA49HfS2DJ9fEyrH' -$response->object; // 'assistant.file.deleted' -$response->deleted; // true - -$response->toArray(); // ['id' => 'file-wB6RM6wHdA49HfS2DJ9fEyrH', ...] -``` - -#### `list` - -Returns a list of assistant files. - -```php -$response = $client->assistants()->files()->list('asst_gxzBkD1wkKEloYqZ410pT5pd', [ - 'limit' => 2, -]); - -$response->object; // 'list' -$response->firstId; // 'file-wB6RM6wHdA49HfS2DJ9fEyrH' -$response->lastId; // 'file-6EsV79Y261TEmi0PY5iHbZdS' -$response->hasMore; // true - -foreach ($response->data as $result) { - $result->id; // 'file-wB6RM6wHdA49HfS2DJ9fEyrH' - // ... -} - -$response->toArray(); // ['object' => 'list', ...] -``` ### `Threads` Resource @@ -1144,6 +1076,7 @@ $response = $client->threads()->create([]); $response->id; // 'thread_tKFLqzRN9n7MnyKKvc1Q7868' $response->object; // 'thread' $response->createdAt; // 1623936000 +$response->toolResources; // null $response->metadata; // [] $response->toArray(); // ['id' => 'thread_tKFLqzRN9n7MnyKKvc1Q7868', ...] @@ -1175,17 +1108,27 @@ $response->createdAt; // 1623936000 $response->assistantId; // 'asst_gxzBkD1wkKEloYqZ410pT5pd' $response->threadId; // 'thread_tKFLqzRN9n7MnyKKvc1Q7868' $response->status; // 'queued' +$response->requiredAction; // null +$response->lastError; // null $response->startedAt; // null $response->expiresAt; // 1699622335 $response->cancelledAt; // null $response->failedAt; // null $response->completedAt; // null +$response->incompleteDetails; // null $response->lastError; // null $response->model; // 'gpt-4' $response->instructions; // null $response->tools; // [] -$response->fileIds; // [] $response->metadata; // [] +$response->usage->total_tokens; // 579 +$response->temperature; // null +$response->topP; // null +$response->maxPromptTokens; // 1000 +$response->maxCompletionTokens; // 1000 +$response->truncationStrategy->type; // 'auto' +$response->responseFormat; // 'auto' +$response->toolChoice; // 'auto' $response->toArray(); // ['id' => 'run_4RCYyYzX9m41WQicoJtUQAb8', ...] ``` @@ -1200,6 +1143,7 @@ $response = $client->threads()->retrieve('thread_tKFLqzRN9n7MnyKKvc1Q7868'); $response->id; // 'thread_tKFLqzRN9n7MnyKKvc1Q7868' $response->object; // 'thread' $response->createdAt; // 1623936000 +$response->toolResources; // null $response->metadata; // [] $response->toArray(); // ['id' => 'thread_tKFLqzRN9n7MnyKKvc1Q7868', ...] @@ -1219,6 +1163,7 @@ $response = $client->threads()->modify('thread_tKFLqzRN9n7MnyKKvc1Q7868', [ $response->id; // 'thread_tKFLqzRN9n7MnyKKvc1Q7868' $response->object; // 'thread' $response->createdAt; // 1623936000 +$response->toolResources; // null $response->metadata; // ['name' => 'My new thread name'] $response->toArray(); // ['id' => 'thread_tKFLqzRN9n7MnyKKvc1Q7868', ...] @@ -1254,13 +1199,17 @@ $response->id; // 'msg_SKYwvF3zcigxthfn6F4hnpdU' $response->object; // 'thread.message' $response->createdAt; // 1623936000 $response->threadId; // 'thread_tKFLqzRN9n7MnyKKvc1Q7868' +$response->status; // 'in_progress +$response->incompleteDetails; // null +$response->completedAt; // null +$response->incompleteAt; // null $response->role; // 'user' $response->content[0]->type; // 'text' $response->content[0]->text->value; // 'What is the sum of 5 and 7?' $response->content[0]->text->annotations; // [] $response->assistantId; // null $response->runId; // null -$response->fileIds; // [] +$response->attachments; // [] $response->metadata; // [] $response->toArray(); // ['id' => 'msg_SKYwvF3zcigxthfn6F4hnpdU', ...] @@ -1280,13 +1229,17 @@ $response->id; // 'msg_SKYwvF3zcigxthfn6F4hnpdU' $response->object; // 'thread.message' $response->createdAt; // 1623936000 $response->threadId; // 'thread_tKFLqzRN9n7MnyKKvc1Q7868' +$response->status; // 'in_progress +$response->incompleteDetails; // null +$response->completedAt; // null +$response->incompleteAt; // null $response->role; // 'user' $response->content[0]->type; // 'text' $response->content[0]->text->value; // 'What is the sum of 5 and 7?' $response->content[0]->text->annotations; // [] $response->assistantId; // null $response->runId; // null -$response->fileIds; // [] +$response->attachments; // [] $response->metadata; // [] $response->toArray(); // ['id' => 'msg_SKYwvF3zcigxthfn6F4hnpdU', ...] @@ -1311,13 +1264,17 @@ $response->id; // 'msg_SKYwvF3zcigxthfn6F4hnpdU' $response->object; // 'thread.message' $response->createdAt; // 1623936000 $response->threadId; // 'thread_tKFLqzRN9n7MnyKKvc1Q7868' +$response->status; // 'in_progress +$response->incompleteDetails; // null +$response->completedAt; // null +$response->incompleteAt; // null $response->role; // 'user' $response->content[0]->type; // 'text' $response->content[0]->text->value; // 'What is the sum of 5 and 7?' $response->content[0]->text->annotations; // [] $response->assistantId; // null $response->runId; // null -$response->fileIds; // [] +$response->attachments; // [] $response->metadata; // ['name' => 'My new message name'] $response->toArray(); // ['id' => 'msg_SKYwvF3zcigxthfn6F4hnpdU', ...] @@ -1345,52 +1302,6 @@ foreach ($response->data as $result) { $response->toArray(); // ['object' => 'list', ...]] ``` -### `Threads Messages Files` Resource - -#### `retrieve` - -Retrieves a message file. - -```php -$response = $client->threads()->messages()->files()->retrieve( - threadId: 'thread_tKFLqzRN9n7MnyKKvc1Q7868', - messageId: 'msg_SKYwvF3zcigxthfn6F4hnpdU', - fileId: 'file-DhxjnFCaSHc4ZELRGKwTMFtI', -); - -$response->id; // 'file-DhxjnFCaSHc4ZELRGKwTMFtI' -$response->object; // 'thread.message.file' -$response->createdAt; // 1623936000 -$response->threadId; // 'msg_SKYwvF3zcigxthfn6F4hnpdU' - -$response->toArray(); // ['id' => 'file-DhxjnFCaSHc4ZELRGKwTMFtI', ...] -``` - -#### `list` - -Returns a list of message files. - -```php -$response = $client->threads()->messages()->files()->list( - threadId: 'thread_tKFLqzRN9n7MnyKKvc1Q7868', - messageId: 'msg_SKYwvF3zcigxthfn6F4hnpdU', - parameters: [ - 'limit' => 10, - ], -); - -$response->object; // 'list' -$response->firstId; // 'file-DhxjnFCaSHc4ZELRGKwTMFtI' -$response->lastId; // 'file-DhxjnFCaSHc4ZELRGKwTMFtI' -$response->hasMore; // false - -foreach ($response->data as $result) { - $result->id; // 'file-DhxjnFCaSHc4ZELRGKwTMFtI' - // ... -} - -$response->toArray(); // ['object' => 'list', ...]] -``` ### `Threads Runs` Resource @@ -1417,12 +1328,20 @@ $response->expiresAt; // 1699622335 $response->cancelledAt; // null $response->failedAt; // null $response->completedAt; // null +$response->incompleteDetails; // null $response->lastError; // null $response->model; // 'gpt-4' $response->instructions; // null -$response->tools[0]->type; // 'code_interpreter' -$response->fileIds; // [] +$response->tools; // [] $response->metadata; // [] +$response->usage->total_tokens; // 579 +$response->temperature; // null +$response->topP; // null +$response->maxPromptTokens; // 1000 +$response->maxCompletionTokens; // 1000 +$response->truncationStrategy->type; // 'auto' +$response->toolChoice; // 'auto' +$response->responseFormat; // 'auto' $response->toArray(); // ['id' => 'run_4RCYyYzX9m41WQicoJtUQAb8', ...] ``` @@ -1524,16 +1443,22 @@ $response->expiresAt; // 1699622335 $response->cancelledAt; // null $response->failedAt; // null $response->completedAt; // null +$response->incompleteDetails; // null $response->lastError; // null $response->model; // 'gpt-4' $response->instructions; // null -$response->tools[0]->type; // 'code_interpreter' -$response->fileIds; // [] +$response->tools; // [] $response->metadata; // [] - $response->usage->promptTokens; // 25, $response->usage->completionTokens; // 32, $response->usage->totalTokens; // 57 +$response->temperature; // null +$response->topP; // null +$response->maxPromptTokens; // 1000 +$response->maxCompletionTokens; // 1000 +$response->truncationStrategy->type; // 'auto' +$response->toolChoice; // 'auto' +$response->responseFormat; // 'auto' $response->toArray(); // ['id' => 'run_4RCYyYzX9m41WQicoJtUQAb8', ...] ``` @@ -1564,11 +1489,19 @@ $response->expiresAt; // 1699622335 $response->cancelledAt; // null $response->failedAt; // null $response->completedAt; // null +$response->incompleteDetails; // null $response->lastError; // null $response->model; // 'gpt-4' $response->instructions; // null -$response->tools[0]->type; // 'code_interpreter' -$response->fileIds; // [] +$response->tools; // [] +$response->usage->total_tokens; // 579 +$response->temperature; // null +$response->topP; // null +$response->maxPromptTokens; // 1000 +$response->maxCompletionTokens; // 1000 +$response->truncationStrategy->type; // 'auto' +$response->toolChoice; // 'auto' +$response->responseFormat; // 'auto' $response->metadata; // ['name' => 'My new run name'] $response->toArray(); // ['id' => 'run_4RCYyYzX9m41WQicoJtUQAb8', ...] @@ -1595,11 +1528,19 @@ $response->expiresAt; // 1699622335 $response->cancelledAt; // null $response->failedAt; // null $response->completedAt; // null +$response->incompleteDetails; // null $response->lastError; // null $response->model; // 'gpt-4' $response->instructions; // null -$response->tools[0]->type; // 'code_interpreter' -$response->fileIds; // [] +$response->tools; // [] +$response->usage?->total_tokens; // 579 +$response->temperature; // null +$response->topP; // null +$response->maxPromptTokens; // 1000 +$response->maxCompletionTokens; // 1000 +$response->truncationStrategy->type; // 'auto' +$response->toolChoice; // 'auto' +$response->responseFormat; // 'auto' $response->metadata; // [] $response->toArray(); // ['id' => 'run_4RCYyYzX9m41WQicoJtUQAb8', ...] @@ -1634,11 +1575,19 @@ $response->expiresAt; // 1699622335 $response->cancelledAt; // null $response->failedAt; // null $response->completedAt; // null +$response->incompleteDetails; // null $response->lastError; // null $response->model; // 'gpt-4' $response->instructions; // null +$response->usage->total_tokens; // 579 +$response->temperature; // null +$response->topP; // null +$response->maxPromptTokens; // 1000 +$response->maxCompletionTokens; // 1000 +$response->truncationStrategy->type; // 'auto' +$response->responseFormat; // 'auto' $response->tools[0]->type; // 'function' -$response->fileIds; // [] +$response->toolChoice; // 'auto' $response->metadata; // [] $response->toArray(); // ['id' => 'run_4RCYyYzX9m41WQicoJtUQAb8', ...] diff --git a/src/Contracts/Resources/AssistantsContract.php b/src/Contracts/Resources/AssistantsContract.php index 1680319a..54ca08ef 100644 --- a/src/Contracts/Resources/AssistantsContract.php +++ b/src/Contracts/Resources/AssistantsContract.php @@ -11,7 +11,7 @@ interface AssistantsContract /** * Create an assistant with a model and instructions. * - * @see https://platform.openai.com/docs/api-reference/assistants/object + * @see https://platform.openai.com/docs/api-reference/assistants/createAssistant * * @param array $parameters */ @@ -48,11 +48,4 @@ public function delete(string $id): AssistantDeleteResponse; * @param array $parameters */ public function list(array $parameters = []): AssistantListResponse; - - /** - * Manage files attached to an assistant. - * - * @see https://platform.openai.com/docs/api-reference/assistants - */ - public function files(): AssistantsFilesContract; } diff --git a/src/Contracts/Resources/AssistantsFilesContract.php b/src/Contracts/Resources/AssistantsFilesContract.php deleted file mode 100644 index 0c4370ef..00000000 --- a/src/Contracts/Resources/AssistantsFilesContract.php +++ /dev/null @@ -1,42 +0,0 @@ - $parameters - */ - public function create(string $assistantId, array $parameters): AssistantFileResponse; - - /** - * Retrieves an AssistantFile. - * - * @see https://platform.openai.com/docs/api-reference/assistants/getAssistantFile - */ - public function retrieve(string $assistantId, string $fileId): AssistantFileResponse; - - /** - * Delete an assistant file. - * - * @see https://platform.openai.com/docs/api-reference/assistants/deleteAssistantFile - */ - public function delete(string $assistantId, string $fileId): AssistantFileDeleteResponse; - - /** - * Returns a list of assistant files. - * - * @see https://platform.openai.com/docs/api-reference/assistants/listAssistantFiles - * - * @param array $parameters - */ - public function list(string $assistantId, array $parameters = []): AssistantFileListResponse; -} diff --git a/src/Contracts/Resources/ThreadsMessagesContract.php b/src/Contracts/Resources/ThreadsMessagesContract.php index 741844b3..288ecdd9 100644 --- a/src/Contracts/Resources/ThreadsMessagesContract.php +++ b/src/Contracts/Resources/ThreadsMessagesContract.php @@ -40,11 +40,4 @@ public function modify(string $threadId, string $messageId, array $parameters): * @param array $parameters */ public function list(string $threadId, array $parameters = []): ThreadMessageListResponse; - - /** - * Manage files attached to a thread message. - * - * @see https://platform.openai.com/docs/api-reference/messages/file-object - */ - public function files(): ThreadsMessagesFilesContract; } diff --git a/src/Contracts/Resources/ThreadsMessagesFilesContract.php b/src/Contracts/Resources/ThreadsMessagesFilesContract.php deleted file mode 100644 index 1f9e4aa5..00000000 --- a/src/Contracts/Resources/ThreadsMessagesFilesContract.php +++ /dev/null @@ -1,25 +0,0 @@ - $parameters - */ - public function list(string $threadId, string $messageId, array $parameters = []): ThreadMessageFileListResponse; -} diff --git a/src/OpenAI.php b/src/OpenAI.php index 3ab2acdd..952e7bd0 100644 --- a/src/OpenAI.php +++ b/src/OpenAI.php @@ -15,7 +15,7 @@ public static function client(string $apiKey, ?string $organization = null): Cli return self::factory() ->withApiKey($apiKey) ->withOrganization($organization) - ->withHttpHeader('OpenAI-Beta', 'assistants=v1') + ->withHttpHeader('OpenAI-Beta', 'assistants=v2') ->make(); } diff --git a/src/Resources/Assistants.php b/src/Resources/Assistants.php index 2e785b06..33a801b0 100644 --- a/src/Resources/Assistants.php +++ b/src/Resources/Assistants.php @@ -5,7 +5,6 @@ namespace OpenAI\Resources; use OpenAI\Contracts\Resources\AssistantsContract; -use OpenAI\Contracts\Resources\AssistantsFilesContract; use OpenAI\Responses\Assistants\AssistantDeleteResponse; use OpenAI\Responses\Assistants\AssistantListResponse; use OpenAI\Responses\Assistants\AssistantResponse; @@ -19,7 +18,7 @@ final class Assistants implements AssistantsContract /** * Create an assistant with a model and instructions. * - * @see https://platform.openai.com/docs/api-reference/assistants/object + * @see https://platform.openai.com/docs/api-reference/assistants/createAssistant * * @param array $parameters */ @@ -27,7 +26,7 @@ public function create(array $parameters): AssistantResponse { $payload = Payload::create('assistants', $parameters); - /** @var Response}}>, file_ids: array, metadata: array}> $response */ + /** @var Response}}>, tool_resources: array{code_interpreter?: array{file_ids: array}, file_search?: array{vector_store_ids: array}}, metadata: array, temperature: ?float, top_p: ?float, response_format: string|array{type: 'text'|'json_object'}}> $response */ $response = $this->transporter->requestObject($payload); return AssistantResponse::from($response->data(), $response->meta()); @@ -42,7 +41,7 @@ public function retrieve(string $id): AssistantResponse { $payload = Payload::retrieve('assistants', $id); - /** @var Response}}>, file_ids: array, metadata: array}> $response */ + /** @var Response}}>, tool_resources: array{code_interpreter?: array{file_ids: array}, file_search?: array{vector_store_ids: array}}, metadata: array, temperature: ?float, top_p: ?float, response_format: string|array{type: 'text'|'json_object'}}> $response */ $response = $this->transporter->requestObject($payload); return AssistantResponse::from($response->data(), $response->meta()); @@ -59,7 +58,7 @@ public function modify(string $id, array $parameters): AssistantResponse { $payload = Payload::modify('assistants', $id, $parameters); - /** @var Response}}>, file_ids: array, metadata: array}> $response */ + /** @var Response}}>, tool_resources: array{code_interpreter?: array{file_ids: array}, file_search?: array{vector_store_ids: array}}, metadata: array, temperature: ?float, top_p: ?float, response_format: string|array{type: 'text'|'json_object'}}> $response */ $response = $this->transporter->requestObject($payload); return AssistantResponse::from($response->data(), $response->meta()); @@ -91,19 +90,9 @@ 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 */ + /** @var Response}}>, tool_resources: array{code_interpreter?: array{file_ids: array}, file_search?: array{vector_store_ids: array}}, metadata: array, temperature: ?float, top_p: ?float, response_format: string|array{type: 'text'|'json_object'}}>, first_id: ?string, last_id: ?string, has_more: bool}> $response */ $response = $this->transporter->requestObject($payload); return AssistantListResponse::from($response->data(), $response->meta()); } - - /** - * Manage files attached to an assistant. - * - * @see https://platform.openai.com/docs/api-reference/assistants - */ - public function files(): AssistantsFilesContract - { - return new AssistantsFiles($this->transporter); - } } diff --git a/src/Resources/AssistantsFiles.php b/src/Resources/AssistantsFiles.php deleted file mode 100644 index aab3a447..00000000 --- a/src/Resources/AssistantsFiles.php +++ /dev/null @@ -1,81 +0,0 @@ - $parameters - */ - public function create(string $assistantId, array $parameters): AssistantFileResponse - { - $payload = Payload::create("assistants/$assistantId/files", $parameters); - - /** @var Response $response */ - $response = $this->transporter->requestObject($payload); - - return AssistantFileResponse::from($response->data(), $response->meta()); - } - - /** - * Retrieves an AssistantFile. - * - * @see https://platform.openai.com/docs/api-reference/assistants/getAssistantFile - */ - public function retrieve(string $assistantId, string $fileId): AssistantFileResponse - { - $payload = Payload::retrieve("assistants/$assistantId/files", $fileId); - - /** @var Response $response */ - $response = $this->transporter->requestObject($payload); - - return AssistantFileResponse::from($response->data(), $response->meta()); - } - - /** - * Delete an assistant file. - * - * @see https://platform.openai.com/docs/api-reference/assistants/deleteAssistantFile - */ - public function delete(string $assistantId, string $fileId): AssistantFileDeleteResponse - { - $payload = Payload::delete("assistants/$assistantId/files", $fileId); - - /** @var Response $response */ - $response = $this->transporter->requestObject($payload); - - return AssistantFileDeleteResponse::from($response->data(), $response->meta()); - } - - /** - * Returns a list of assistant files. - * - * @see https://platform.openai.com/docs/api-reference/assistants/listAssistantFiles - * - * @param array $parameters - */ - public function list(string $assistantId, array $parameters = []): AssistantFileListResponse - { - $payload = Payload::list("assistants/$assistantId/files", $parameters); - - /** @var Response, first_id: ?string, last_id: ?string, has_more: bool}> $response */ - $response = $this->transporter->requestObject($payload); - - return AssistantFileListResponse::from($response->data(), $response->meta()); - } -} diff --git a/src/Resources/Threads.php b/src/Resources/Threads.php index 700cdf96..95859e07 100644 --- a/src/Resources/Threads.php +++ b/src/Resources/Threads.php @@ -31,7 +31,7 @@ public function create(array $parameters): ThreadResponse { $payload = Payload::create('threads', $parameters); - /** @var Response}> $response */ + /** @var Response}, file_search?: array{vector_store_ids: array}}, metadata: array}> $response */ $response = $this->transporter->requestObject($payload); return ThreadResponse::from($response->data(), $response->meta()); @@ -48,7 +48,7 @@ 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 */ + /** @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}}>, metadata: array, usage?: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}, incomplete_details: ?array{reason: string}, temperature: float|int|null, top_p: null|float|int, max_prompt_tokens: ?int, max_completion_tokens: ?int, truncation_strategy: array{type: string, last_messages: ?int}, tool_choice: string|array{type: string, function?: array{name: string}}, response_format: string|array{type: 'text'|'json_object'}}> $response */ $response = $this->transporter->requestObject($payload); return ThreadRunResponse::from($response->data(), $response->meta()); @@ -82,7 +82,7 @@ public function retrieve(string $id): ThreadResponse { $payload = Payload::retrieve('threads', $id); - /** @var Response}> $response */ + /** @var Response}, file_search?: array{vector_store_ids: array}}, metadata: array}> $response */ $response = $this->transporter->requestObject($payload); return ThreadResponse::from($response->data(), $response->meta()); @@ -99,7 +99,7 @@ public function modify(string $id, array $parameters): ThreadResponse { $payload = Payload::modify('threads', $id, $parameters); - /** @var Response}> $response */ + /** @var Response}, file_search?: array{vector_store_ids: array}}, metadata: array}> $response */ $response = $this->transporter->requestObject($payload); return ThreadResponse::from($response->data(), $response->meta()); diff --git a/src/Resources/ThreadsMessages.php b/src/Resources/ThreadsMessages.php index 9388a311..0de612b4 100644 --- a/src/Resources/ThreadsMessages.php +++ b/src/Resources/ThreadsMessages.php @@ -5,7 +5,6 @@ namespace OpenAI\Resources; use OpenAI\Contracts\Resources\ThreadsMessagesContract; -use OpenAI\Contracts\Resources\ThreadsMessagesFilesContract; use OpenAI\Responses\Threads\Messages\ThreadMessageListResponse; use OpenAI\Responses\Threads\Messages\ThreadMessageResponse; use OpenAI\ValueObjects\Transporter\Payload; @@ -26,7 +25,7 @@ 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 */ + /** @var Response}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}> $response */ $response = $this->transporter->requestObject($payload); return ThreadMessageResponse::from($response->data(), $response->meta()); @@ -41,7 +40,7 @@ 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 */ + /** @var Response}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}> $response */ $response = $this->transporter->requestObject($payload); return ThreadMessageResponse::from($response->data(), $response->meta()); @@ -58,7 +57,7 @@ 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 */ + /** @var Response}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}> $response */ $response = $this->transporter->requestObject($payload); return ThreadMessageResponse::from($response->data(), $response->meta()); @@ -75,19 +74,9 @@ 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 */ + /** @var Response}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}>, first_id: ?string, last_id: ?string, has_more: bool}> $response */ $response = $this->transporter->requestObject($payload); return ThreadMessageListResponse::from($response->data(), $response->meta()); } - - /** - * Manage files attached to a thread message. - * - * @see https://platform.openai.com/docs/api-reference/messages/file-object - */ - public function files(): ThreadsMessagesFilesContract - { - return new ThreadsMessagesFiles($this->transporter); - } } diff --git a/src/Resources/ThreadsMessagesFiles.php b/src/Resources/ThreadsMessagesFiles.php deleted file mode 100644 index d3086dde..00000000 --- a/src/Resources/ThreadsMessagesFiles.php +++ /dev/null @@ -1,48 +0,0 @@ - $response */ - $response = $this->transporter->requestObject($payload); - - return ThreadMessageFileResponse::from($response->data(), $response->meta()); - } - - /** - * Returns a list of message files. - * - * @see https://platform.openai.com/docs/api-reference/messages/listMessageFiles - * - * @param array $parameters - */ - public function list(string $threadId, string $messageId, array $parameters = []): ThreadMessageFileListResponse - { - $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); - - return ThreadMessageFileListResponse::from($response->data(), $response->meta()); - } -} diff --git a/src/Resources/ThreadsRuns.php b/src/Resources/ThreadsRuns.php index 9d55fea4..0bd44c54 100644 --- a/src/Resources/ThreadsRuns.php +++ b/src/Resources/ThreadsRuns.php @@ -29,7 +29,7 @@ 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 */ + /** @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}}>, metadata: array, usage?: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}, incomplete_details: ?array{reason: string}, temperature: float|int|null, top_p: null|float|int, max_prompt_tokens: ?int, max_completion_tokens: ?int, truncation_strategy: array{type: string, last_messages: ?int}, tool_choice: string|array{type: string, function?: array{name: string}}, response_format: string|array{type: 'text'|'json_object'}}> $response */ $response = $this->transporter->requestObject($payload); return ThreadRunResponse::from($response->data(), $response->meta()); @@ -63,7 +63,7 @@ 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, usage?: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}}> $response */ + /** @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}}>, metadata: array, usage?: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}, incomplete_details: ?array{reason: string}, temperature: float|int|null, top_p: null|float|int, max_prompt_tokens: ?int, max_completion_tokens: ?int, truncation_strategy: array{type: string, last_messages: ?int}, tool_choice: string|array{type: string, function?: array{name: string}}, response_format: string|array{type: 'text'|'json_object'}}> $response */ $response = $this->transporter->requestObject($payload); return ThreadRunResponse::from($response->data(), $response->meta()); @@ -80,7 +80,7 @@ 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, usage?: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}}> $response */ + /** @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}}>, metadata: array, usage?: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}, incomplete_details: ?array{reason: string}, temperature: float|int|null, top_p: null|float|int, max_prompt_tokens: ?int, max_completion_tokens: ?int, truncation_strategy: array{type: string, last_messages: ?int}, tool_choice: string|array{type: string, function?: array{name: string}}, response_format: string|array{type: 'text'|'json_object'}}> $response */ $response = $this->transporter->requestObject($payload); return ThreadRunResponse::from($response->data(), $response->meta()); @@ -97,7 +97,7 @@ 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, usage?: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}}> $response */ + /** @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}}>, metadata: array, usage?: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}, incomplete_details: ?array{reason: string}, temperature: float|int|null, top_p: null|float|int, max_prompt_tokens: ?int, max_completion_tokens: ?int, truncation_strategy: array{type: string, last_messages: ?int}, tool_choice: string|array{type: string, function?: array{name: string}}, response_format: string|array{type: 'text'|'json_object'}}> $response */ $response = $this->transporter->requestObject($payload); return ThreadRunResponse::from($response->data(), $response->meta()); @@ -132,7 +132,7 @@ 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, usage?: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}}> $response */ + /** @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}}>, metadata: array, usage?: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}, incomplete_details: ?array{reason: string}, temperature: float|int|null, top_p: null|float|int, max_prompt_tokens: ?int, max_completion_tokens: ?int, truncation_strategy: array{type: string, last_messages: ?int}, tool_choice: string|array{type: string, function?: array{name: string}}, response_format: string|array{type: 'text'|'json_object'}}> $response */ $response = $this->transporter->requestObject($payload); return ThreadRunResponse::from($response->data(), $response->meta()); @@ -149,7 +149,7 @@ 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 */ + /** @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}}>, metadata: array, usage?: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}, incomplete_details: ?array{reason: string}, temperature: float|int|null, top_p: null|float|int, max_prompt_tokens: ?int, max_completion_tokens: ?int, truncation_strategy: array{type: string, last_messages: ?int}, tool_choice: string|array{type: string, function?: array{name: string}}, response_format: string|array{type: 'text'|'json_object'}}>, first_id: ?string, last_id: ?string, has_more: bool}> $response */ $response = $this->transporter->requestObject($payload); return ThreadRunListResponse::from($response->data(), $response->meta()); diff --git a/src/Resources/ThreadsRunsSteps.php b/src/Resources/ThreadsRunsSteps.php index 39c014d5..c25cdcbd 100644 --- a/src/Resources/ThreadsRunsSteps.php +++ b/src/Resources/ThreadsRunsSteps.php @@ -23,7 +23,7 @@ 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 */ + /** @var Response}}|array{id: string, type: 'file_search', file_search: 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, usage: ?array{prompt_tokens: int, completion_tokens: int, total_tokens: int}}> $response */ $response = $this->transporter->requestObject($payload); return ThreadRunStepResponse::from($response->data(), $response->meta()); @@ -40,7 +40,7 @@ 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 */ + /** @var Response}}|array{id: string, type: 'file_search', file_search: 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, usage: ?array{prompt_tokens: int, completion_tokens: int, total_tokens: int}}>, first_id: ?string, last_id: ?string, has_more: bool}> $response */ $response = $this->transporter->requestObject($payload); return ThreadRunStepListResponse::from($response->data(), $response->meta()); diff --git a/src/Responses/Assistants/AssistantListResponse.php b/src/Responses/Assistants/AssistantListResponse.php index d54b46fd..455b8f96 100644 --- a/src/Responses/Assistants/AssistantListResponse.php +++ b/src/Responses/Assistants/AssistantListResponse.php @@ -12,12 +12,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}}>, file_ids: array, metadata: array}>, first_id: ?string, last_id: ?string, has_more: bool}> + * @implements ResponseContract}}>, tool_resources: ?array{code_interpreter?: array{file_ids: array}, file_search?: array{vector_store_ids: array}}, metadata: array, temperature: ?float, top_p: ?float, response_format: string|array{type: string}}>, first_id: ?string, last_id: ?string, has_more: bool}> */ final class AssistantListResponse implements ResponseContract, ResponseHasMetaInformationContract { /** - * @use ArrayAccessible}}>, file_ids: array, metadata: array}>, first_id: ?string, last_id: ?string, has_more: bool}> + * @use ArrayAccessible}}>, tool_resources: ?array{code_interpreter?: array{file_ids: array}, file_search?: array{vector_store_ids: array}}, metadata: array, temperature: ?float, top_p: ?float, response_format: string|array{type: string}}>, first_id: ?string, last_id: ?string, has_more: bool}> */ use ArrayAccessible; @@ -40,7 +40,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{object: string, data: array}}>, file_ids: array, metadata: array}>, first_id: ?string, last_id: ?string, has_more: bool} $attributes + * @param array{object: string, data: array}}>, tool_resources: ?array{code_interpreter?: array{file_ids: array}, file_search?: array{vector_store_ids: array}}, metadata: array, temperature: ?float, top_p: ?float, response_format: string|array{type: 'text'|'json_object'}}>, first_id: ?string, last_id: ?string, has_more: bool} $attributes */ public static function from(array $attributes, MetaInformation $meta): self { diff --git a/src/Responses/Assistants/AssistantResponse.php b/src/Responses/Assistants/AssistantResponse.php index 6b4bb481..4164b421 100644 --- a/src/Responses/Assistants/AssistantResponse.php +++ b/src/Responses/Assistants/AssistantResponse.php @@ -12,12 +12,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}}>, file_ids: array, metadata: array}> + * @implements ResponseContract}}>, tool_resources: ?array{code_interpreter?: array{file_ids: array}, file_search?: array{vector_store_ids: array}}, metadata: array, temperature: ?float, top_p: ?float, response_format: string|array{type: string}}> */ final class AssistantResponse implements ResponseContract, ResponseHasMetaInformationContract { /** - * @use ArrayAccessible}}>, file_ids: array, metadata: array}> + * @use ArrayAccessible}}>, tool_resources: ?array{code_interpreter?: array{file_ids: array}, file_search?: array{vector_store_ids: array}}, metadata: array, temperature: ?float, top_p: ?float, response_format: string|array{type: string}}> */ use ArrayAccessible; @@ -25,8 +25,7 @@ final class AssistantResponse implements ResponseContract, ResponseHasMetaInform use HasMetaInformation; /** - * @param array $tools - * @param array $fileIds + * @param array $tools * @param array $metadata */ private function __construct( @@ -38,8 +37,11 @@ private function __construct( public string $model, public ?string $instructions, public array $tools, - public array $fileIds, + public ?AssistantResponseToolResources $toolResources, public array $metadata, + public ?float $temperature, + public ?float $topP, + public string|AssistantResponseResponseFormat $responseFormat, private readonly MetaInformation $meta, ) { } @@ -47,19 +49,23 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{id: string, object: string, created_at: int, name: ?string, description: ?string, model: string, instructions: ?string, tools: array}}>, file_ids: array, metadata: array} $attributes + * @param array{id: string, object: string, created_at: int, name: ?string, description: ?string, model: string, instructions: ?string, tools: array}}>, tool_resources: ?array{code_interpreter?: array{file_ids: array}, file_search?: array{vector_store_ids: array}}, metadata: array, temperature: ?float, top_p: ?float, response_format: string|array{type: 'text'|'json_object'}} $attributes */ public static function from(array $attributes, MetaInformation $meta): self { $tools = array_map( - fn (array $tool): AssistantResponseToolCodeInterpreter|AssistantResponseToolRetrieval|AssistantResponseToolFunction => match ($tool['type']) { + fn (array $tool): AssistantResponseToolCodeInterpreter|AssistantResponseToolFileSearch|AssistantResponseToolFunction => match ($tool['type']) { 'code_interpreter' => AssistantResponseToolCodeInterpreter::from($tool), - 'retrieval' => AssistantResponseToolRetrieval::from($tool), + 'file_search' => AssistantResponseToolFileSearch::from($tool), 'function' => AssistantResponseToolFunction::from($tool), }, $attributes['tools'], ); + $responseFormat = is_array($attributes['response_format']) ? + AssistantResponseResponseFormat::from($attributes['response_format']) : + $attributes['response_format']; + return new self( $attributes['id'], $attributes['object'], @@ -69,9 +75,12 @@ public static function from(array $attributes, MetaInformation $meta): self $attributes['model'], $attributes['instructions'], $tools, - $attributes['file_ids'], + isset($attributes['tool_resources']) ? AssistantResponseToolResources::from($attributes['tool_resources']) : null, $attributes['metadata'], - $meta, + $attributes['temperature'], + $attributes['top_p'], + $responseFormat, + $meta ); } @@ -88,9 +97,12 @@ public function toArray(): array 'description' => $this->description, 'model' => $this->model, 'instructions' => $this->instructions, - 'tools' => array_map(fn (AssistantResponseToolCodeInterpreter|AssistantResponseToolRetrieval|AssistantResponseToolFunction $tool): array => $tool->toArray(), $this->tools), - 'file_ids' => $this->fileIds, + 'tools' => array_map(fn (AssistantResponseToolCodeInterpreter|AssistantResponseToolFileSearch|AssistantResponseToolFunction $tool): array => $tool->toArray(), $this->tools), + 'tool_resources' => $this->toolResources?->toArray(), 'metadata' => $this->metadata, + 'temperature' => $this->temperature, + 'top_p' => $this->topP, + 'response_format' => is_string($this->responseFormat) ? $this->responseFormat : $this->responseFormat->toArray(), ]; } } diff --git a/src/Responses/Assistants/AssistantResponseResponseFormat.php b/src/Responses/Assistants/AssistantResponseResponseFormat.php new file mode 100644 index 00000000..edfdec4b --- /dev/null +++ b/src/Responses/Assistants/AssistantResponseResponseFormat.php @@ -0,0 +1,49 @@ + + */ +final class AssistantResponseResponseFormat implements ResponseContract +{ + /** + * @use ArrayAccessible + */ + use ArrayAccessible; + + use Fakeable; + + private function __construct( + public string $type, + ) { + } + + /** + * Acts as static factory, and returns a new Response instance. + * + * @param array{type: 'text'|'json_object'} $attributes + */ + public static function from(array $attributes): self + { + return new self( + $attributes['type'], + ); + } + + /** + * {@inheritDoc} + */ + public function toArray(): array + { + return [ + 'type' => $this->type, + ]; + } +} diff --git a/src/Responses/Assistants/AssistantResponseToolRetrieval.php b/src/Responses/Assistants/AssistantResponseResponseFormatText.php similarity index 87% rename from src/Responses/Assistants/AssistantResponseToolRetrieval.php rename to src/Responses/Assistants/AssistantResponseResponseFormatText.php index 7c7f5ba0..6bc1ee64 100644 --- a/src/Responses/Assistants/AssistantResponseToolRetrieval.php +++ b/src/Responses/Assistants/AssistantResponseResponseFormatText.php @@ -11,7 +11,7 @@ /** * @implements ResponseContract */ -final class AssistantResponseToolRetrieval implements ResponseContract +final class AssistantResponseResponseFormatText implements ResponseContract { /** * @use ArrayAccessible @@ -28,7 +28,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{type: 'retrieval'} $attributes + * @param array{type: 'text'} $attributes */ public static function from(array $attributes): self { diff --git a/src/Responses/Assistants/AssistantResponseToolFileSearch.php b/src/Responses/Assistants/AssistantResponseToolFileSearch.php new file mode 100644 index 00000000..a6df847f --- /dev/null +++ b/src/Responses/Assistants/AssistantResponseToolFileSearch.php @@ -0,0 +1,49 @@ + + */ +final class AssistantResponseToolFileSearch implements ResponseContract +{ + /** + * @use ArrayAccessible + */ + use ArrayAccessible; + + use Fakeable; + + private function __construct( + public string $type, + ) { + } + + /** + * Acts as static factory, and returns a new Response instance. + * + * @param array{type: 'file_search'} $attributes + */ + public static function from(array $attributes): self + { + return new self( + $attributes['type'], + ); + } + + /** + * {@inheritDoc} + */ + public function toArray(): array + { + return [ + 'type' => $this->type, + ]; + } +} diff --git a/src/Responses/Assistants/AssistantResponseToolResourceCodeInterpreter.php b/src/Responses/Assistants/AssistantResponseToolResourceCodeInterpreter.php new file mode 100644 index 00000000..e4ee438d --- /dev/null +++ b/src/Responses/Assistants/AssistantResponseToolResourceCodeInterpreter.php @@ -0,0 +1,52 @@ +}> + */ +final class AssistantResponseToolResourceCodeInterpreter implements ResponseContract +{ + /** + * @use ArrayAccessible}> + */ + use ArrayAccessible; + + use Fakeable; + + /** + * @param array $fileIds + */ + private function __construct( + public array $fileIds, + ) { + } + + /** + * Acts as static factory, and returns a new Response instance. + * + * @param array{file_ids: array} $attributes + */ + public static function from(array $attributes): self + { + return new self( + $attributes['file_ids'], + ); + } + + /** + * {@inheritDoc} + */ + public function toArray(): array + { + return [ + 'file_ids' => $this->fileIds, + ]; + } +} diff --git a/src/Responses/Assistants/AssistantResponseToolResourceFileSearch.php b/src/Responses/Assistants/AssistantResponseToolResourceFileSearch.php new file mode 100644 index 00000000..07af77c4 --- /dev/null +++ b/src/Responses/Assistants/AssistantResponseToolResourceFileSearch.php @@ -0,0 +1,52 @@ +}> + */ +final class AssistantResponseToolResourceFileSearch implements ResponseContract +{ + /** + * @use ArrayAccessible}> + */ + use ArrayAccessible; + + use Fakeable; + + /** + * @param array $vectorStoreIds + */ + private function __construct( + public array $vectorStoreIds, + ) { + } + + /** + * Acts as static factory, and returns a new Response instance. + * + * @param array{vector_store_ids: array} $attributes + */ + public static function from(array $attributes): self + { + return new self( + $attributes['vector_store_ids'], + ); + } + + /** + * {@inheritDoc} + */ + public function toArray(): array + { + return [ + 'vector_store_ids' => $this->vectorStoreIds, + ]; + } +} diff --git a/src/Responses/Assistants/AssistantResponseToolResources.php b/src/Responses/Assistants/AssistantResponseToolResources.php new file mode 100644 index 00000000..7da0db02 --- /dev/null +++ b/src/Responses/Assistants/AssistantResponseToolResources.php @@ -0,0 +1,52 @@ +}, file_search?: array{vector_store_ids: array}}> + */ +final class AssistantResponseToolResources implements ResponseContract +{ + /** + * @use ArrayAccessible}, file_search?: array{vector_store_ids: array}}> + */ + use ArrayAccessible; + + use Fakeable; + + private function __construct( + public ?AssistantResponseToolResourceCodeInterpreter $codeInterpreter, + public ?AssistantResponseToolResourceFileSearch $fileSearch, + ) { + } + + /** + * Acts as static factory, and returns a new Response instance. + * + * @param array{code_interpreter?: array{file_ids: array}, file_search?: array{vector_store_ids: array}} $attributes + */ + public static function from(array $attributes): self + { + return new self( + isset($attributes['code_interpreter']) ? AssistantResponseToolResourceCodeInterpreter::from($attributes['code_interpreter']) : null, + isset($attributes['file_search']) ? AssistantResponseToolResourceFileSearch::from($attributes['file_search']) : null, + ); + } + + /** + * {@inheritDoc} + */ + public function toArray(): array + { + return array_filter([ + 'code_interpreter' => $this->codeInterpreter?->toArray(), + 'file_search' => $this->fileSearch?->toArray(), + ]); + } +} diff --git a/src/Responses/Assistants/Files/AssistantFileDeleteResponse.php b/src/Responses/Assistants/Files/AssistantFileDeleteResponse.php deleted file mode 100644 index 0f8fdd42..00000000 --- a/src/Responses/Assistants/Files/AssistantFileDeleteResponse.php +++ /dev/null @@ -1,61 +0,0 @@ - - */ -final class AssistantFileDeleteResponse implements ResponseContract, ResponseHasMetaInformationContract -{ - /** - * @use ArrayAccessible - */ - use ArrayAccessible; - - use Fakeable; - use HasMetaInformation; - - private function __construct( - public readonly string $id, - public readonly string $object, - public readonly bool $deleted, - private readonly MetaInformation $meta, - ) { - } - - /** - * Acts as static factory, and returns a new Response instance. - * - * @param array{id: string, object: string, deleted: bool} $attributes - */ - public static function from(array $attributes, MetaInformation $meta): self - { - return new self( - $attributes['id'], - $attributes['object'], - $attributes['deleted'], - $meta, - ); - } - - /** - * {@inheritDoc} - */ - public function toArray(): array - { - return [ - 'id' => $this->id, - 'object' => $this->object, - 'deleted' => $this->deleted, - ]; - } -} diff --git a/src/Responses/Assistants/Files/AssistantFileListResponse.php b/src/Responses/Assistants/Files/AssistantFileListResponse.php deleted file mode 100644 index 09d506b8..00000000 --- a/src/Responses/Assistants/Files/AssistantFileListResponse.php +++ /dev/null @@ -1,78 +0,0 @@ -, first_id: ?string, last_id: ?string, has_more: bool}> - */ -final class AssistantFileListResponse implements ResponseContract, ResponseHasMetaInformationContract -{ - /** - * @use ArrayAccessible, first_id: ?string, last_id: ?string, has_more: bool}> - */ - use ArrayAccessible; - - use Fakeable; - use HasMetaInformation; - - /** - * @param array $data - */ - private function __construct( - public readonly string $object, - public readonly array $data, - public readonly ?string $firstId, - public readonly ?string $lastId, - public readonly bool $hasMore, - private readonly MetaInformation $meta, - ) { - } - - /** - * Acts as static factory, and returns a new Response instance. - * - * @param array{object: string, data: array, first_id: ?string, last_id: ?string, has_more: bool} $attributes - */ - public static function from(array $attributes, MetaInformation $meta): self - { - $data = array_map(fn (array $result): AssistantFileResponse => AssistantFileResponse::from( - $result, - $meta, - ), $attributes['data']); - - return new self( - $attributes['object'], - $data, - $attributes['first_id'], - $attributes['last_id'], - $attributes['has_more'], - $meta, - ); - } - - /** - * {@inheritDoc} - */ - public function toArray(): array - { - return [ - 'object' => $this->object, - 'data' => array_map( - static fn (AssistantFileResponse $response): array => $response->toArray(), - $this->data, - ), - 'first_id' => $this->firstId, - 'last_id' => $this->lastId, - 'has_more' => $this->hasMore, - ]; - } -} diff --git a/src/Responses/Assistants/Files/AssistantFileResponse.php b/src/Responses/Assistants/Files/AssistantFileResponse.php deleted file mode 100644 index 829f8b56..00000000 --- a/src/Responses/Assistants/Files/AssistantFileResponse.php +++ /dev/null @@ -1,64 +0,0 @@ - - */ -final class AssistantFileResponse implements ResponseContract, ResponseHasMetaInformationContract -{ - /** - * @use ArrayAccessible - */ - use ArrayAccessible; - - use Fakeable; - use HasMetaInformation; - - private function __construct( - public string $id, - public string $object, - public int $createdAt, - public string $assistantId, - private readonly MetaInformation $meta, - ) { - } - - /** - * Acts as static factory, and returns a new Response instance. - * - * @param array{id: string, object: string, created_at: int, assistant_id: string} $attributes - */ - public static function from(array $attributes, MetaInformation $meta): self - { - return new self( - $attributes['id'], - $attributes['object'], - $attributes['created_at'], - $attributes['assistant_id'], - $meta, - ); - } - - /** - * {@inheritDoc} - */ - public function toArray(): array - { - return [ - 'id' => $this->id, - 'object' => $this->object, - 'created_at' => $this->createdAt, - 'assistant_id' => $this->assistantId, - ]; - } -} diff --git a/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaObject.php b/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaObject.php index a9e89a05..1c211491 100644 --- a/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaObject.php +++ b/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaObject.php @@ -9,12 +9,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}}>, file_ids: ?array}> + * @implements ResponseContract}}>, file_ids: ?array}> */ final class ThreadMessageDeltaObject implements ResponseContract { /** - * @use ArrayAccessible}}>, file_ids: ?array}> + * @use ArrayAccessible}}>, file_ids: ?array}> */ use ArrayAccessible; @@ -34,7 +34,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{role?: string, content: array}}>, file_ids?: array} $attributes + * @param array{role?: string, content: array}}>, file_ids?: array} $attributes */ public static function from(array $attributes): self { diff --git a/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaResponse.php b/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaResponse.php index 29da03c6..4b68f7b0 100644 --- a/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaResponse.php +++ b/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaResponse.php @@ -9,12 +9,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}}>, file_ids: array|null}}> + * @implements ResponseContract}}>, file_ids: array|null}}> */ final class ThreadMessageDeltaResponse implements ResponseContract { /** - * @use ArrayAccessible}}>, file_ids: array|null}}> + * @use ArrayAccessible}}>, file_ids: array|null}}> */ use ArrayAccessible; @@ -30,7 +30,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{id: string, object: string, delta: array{role?: string, content: array}}>, file_ids?: array}} $attributes + * @param array{id: string, object: string, delta: array{role?: string, content: array}}>, file_ids?: array}} $attributes */ public static function from(array $attributes): self { diff --git a/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaResponseContentImageFileObject.php b/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaResponseContentImageFileObject.php index d406ce09..55a6e333 100644 --- a/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaResponseContentImageFileObject.php +++ b/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaResponseContentImageFileObject.php @@ -10,12 +10,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract + * @implements ResponseContract */ final class ThreadMessageDeltaResponseContentImageFileObject implements ResponseContract { /** - * @use ArrayAccessible + * @use ArrayAccessible */ use ArrayAccessible; @@ -34,7 +34,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{index: int, type: 'image_file', image_file: array{file_id: string}} $attributes + * @param array{index: int, type: 'image_file', image_file: array{file_id: string, detail?: string}} $attributes */ public static function from(array $attributes): self { diff --git a/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaResponseContentText.php b/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaResponseContentText.php index e5ac798d..be099322 100644 --- a/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaResponseContentText.php +++ b/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaResponseContentText.php @@ -11,22 +11,22 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}> + * @implements ResponseContract}> */ final class ThreadMessageDeltaResponseContentText implements ResponseContract { /** - * @use ArrayAccessible}> + * @use ArrayAccessible}> */ use ArrayAccessible; use Fakeable; /** - * @param array $annotations + * @param \OpenAI\Responses\Threads\Messages\ThreadMessageResponseContentTextAnnotationFilePathObject[]|\OpenAI\Responses\Threads\Messages\ThreadMessageResponseContentTextAnnotationFileCitationObject[] $annotations */ private function __construct( - public string $value, + public ?string $value, public array $annotations, ) { } @@ -34,7 +34,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{value: string, annotations?: array} $attributes + * @param array{value?: string, annotations?: array} $attributes */ public static function from(array $attributes): self { @@ -47,7 +47,7 @@ public static function from(array $attributes): self ); return new self( - $attributes['value'], + $attributes['value'] ?? null, $annotations, ); } diff --git a/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaResponseContentTextObject.php b/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaResponseContentTextObject.php index 00dc4cc8..a48c166a 100644 --- a/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaResponseContentTextObject.php +++ b/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaResponseContentTextObject.php @@ -9,12 +9,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}}> + * @implements ResponseContract}}> */ final class ThreadMessageDeltaResponseContentTextObject implements ResponseContract { /** - * @use ArrayAccessible}}> + * @use ArrayAccessible}}> */ use ArrayAccessible; @@ -33,7 +33,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{index: int, type: 'text', text: array{value: string, annotations: array}} $attributes + * @param array{index: int, type: 'text', text: array{value?: string, annotations: array}} $attributes */ public static function from(array $attributes): self { diff --git a/src/Responses/Threads/Messages/Files/ThreadMessageFileListResponse.php b/src/Responses/Threads/Messages/Files/ThreadMessageFileListResponse.php deleted file mode 100644 index ae738993..00000000 --- a/src/Responses/Threads/Messages/Files/ThreadMessageFileListResponse.php +++ /dev/null @@ -1,78 +0,0 @@ -, first_id: ?string, last_id: ?string, has_more: bool}> - */ -final class ThreadMessageFileListResponse implements ResponseContract, ResponseHasMetaInformationContract -{ - /** - * @use ArrayAccessible, first_id: ?string, last_id: ?string, has_more: bool}> - */ - use ArrayAccessible; - - use Fakeable; - use HasMetaInformation; - - /** - * @param array $data - */ - private function __construct( - public readonly string $object, - public readonly array $data, - public readonly ?string $firstId, - public readonly ?string $lastId, - public readonly bool $hasMore, - private readonly MetaInformation $meta, - ) { - } - - /** - * Acts as static factory, and returns a new Response instance. - * - * @param array{object: string, data: array, first_id: ?string, last_id: ?string, has_more: bool} $attributes - */ - public static function from(array $attributes, MetaInformation $meta): self - { - $data = array_map(fn (array $result): ThreadMessageFileResponse => ThreadMessageFileResponse::from( - $result, - $meta, - ), $attributes['data']); - - return new self( - $attributes['object'], - $data, - $attributes['first_id'], - $attributes['last_id'], - $attributes['has_more'], - $meta, - ); - } - - /** - * {@inheritDoc} - */ - public function toArray(): array - { - return [ - 'object' => $this->object, - 'data' => array_map( - static fn (ThreadMessageFileResponse $response): array => $response->toArray(), - $this->data, - ), - 'first_id' => $this->firstId, - 'last_id' => $this->lastId, - 'has_more' => $this->hasMore, - ]; - } -} diff --git a/src/Responses/Threads/Messages/Files/ThreadMessageFileResponse.php b/src/Responses/Threads/Messages/Files/ThreadMessageFileResponse.php deleted file mode 100644 index a0688197..00000000 --- a/src/Responses/Threads/Messages/Files/ThreadMessageFileResponse.php +++ /dev/null @@ -1,64 +0,0 @@ - - */ -final class ThreadMessageFileResponse implements ResponseContract, ResponseHasMetaInformationContract -{ - /** - * @use ArrayAccessible - */ - use ArrayAccessible; - - use Fakeable; - use HasMetaInformation; - - private function __construct( - public string $id, - public string $object, - public int $createdAt, - public string $messageId, - private readonly MetaInformation $meta, - ) { - } - - /** - * Acts as static factory, and returns a new Response instance. - * - * @param array{id: string, object: string, created_at: int, message_id: string} $attributes - */ - public static function from(array $attributes, MetaInformation $meta): self - { - return new self( - $attributes['id'], - $attributes['object'], - $attributes['created_at'], - $attributes['message_id'], - $meta, - ); - } - - /** - * {@inheritDoc} - */ - public function toArray(): array - { - return [ - 'id' => $this->id, - 'object' => $this->object, - 'created_at' => $this->createdAt, - 'message_id' => $this->messageId, - ]; - } -} diff --git a/src/Responses/Threads/Messages/ThreadMessageListResponse.php b/src/Responses/Threads/Messages/ThreadMessageListResponse.php index 55849de2..7deed379 100644 --- a/src/Responses/Threads/Messages/ThreadMessageListResponse.php +++ b/src/Responses/Threads/Messages/ThreadMessageListResponse.php @@ -12,12 +12,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}}>, assistant_id: ?string, run_id: ?string, file_ids: array, metadata: array}>, first_id: ?string, last_id: ?string, has_more: bool}> + * @implements ResponseContract}}|array{type: string, image_file: array{file_id: string}}|array{type: 'image_url', image_url: array{file_id: string, detail?: string}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}>, first_id: ?string, last_id: ?string, has_more: bool}> */ final class ThreadMessageListResponse implements ResponseContract, ResponseHasMetaInformationContract { /** - * @use ArrayAccessible}}>, assistant_id: ?string, run_id: ?string, file_ids: array, metadata: array}>, first_id: ?string, last_id: ?string, has_more: bool}> + * @use ArrayAccessible}}|array{type: string, image_file: array{file_id: string}}|array{type: 'image_url', image_url: array{file_id: string, detail?: string}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}>, first_id: ?string, last_id: ?string, has_more: bool}> */ use ArrayAccessible; @@ -40,7 +40,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{object: string, data: array}}>, assistant_id: ?string, run_id: ?string, file_ids: array, metadata: array}>, first_id: ?string, last_id: ?string, has_more: bool} $attributes + * @param array{object: string, data: array}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}>, first_id: ?string, last_id: ?string, has_more: bool} $attributes */ public static function from(array $attributes, MetaInformation $meta): self { diff --git a/src/Responses/Threads/Messages/ThreadMessageResponse.php b/src/Responses/Threads/Messages/ThreadMessageResponse.php index a99d3820..ba3810a8 100644 --- a/src/Responses/Threads/Messages/ThreadMessageResponse.php +++ b/src/Responses/Threads/Messages/ThreadMessageResponse.php @@ -12,12 +12,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}}>, assistant_id: ?string, run_id: ?string, file_ids: array, metadata: array}> + * @implements ResponseContract}}|array{type: string, image_file: array{file_id: string, detail?: string}}|array{type: 'image_url', image_url: array{file_id: string, detail?: string}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}> */ final class ThreadMessageResponse implements ResponseContract, ResponseHasMetaInformationContract { /** - * @use ArrayAccessible}}>, assistant_id: ?string, run_id: ?string, file_ids: array, metadata: array}> + * @use ArrayAccessible}}|array{type: string, image_file: array{file_id: string, detail?: string}}|array{type: 'image_url', image_url: array{file_id: string, detail?: string}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}> */ use ArrayAccessible; @@ -25,8 +25,8 @@ final class ThreadMessageResponse implements ResponseContract, ResponseHasMetaIn use HasMetaInformation; /** - * @param array $content - * @param array $fileIds + * @param array $content + * @param array $attachments * @param array $metadata */ private function __construct( @@ -34,11 +34,15 @@ private function __construct( public string $object, public int $createdAt, public string $threadId, + public string $status, + public ?ThreadMessageResponseIncompleteDetails $incompleteDetails, + public ?int $completedAt, + public ?int $incompleteAt, public string $role, public array $content, public ?string $assistantId, public ?string $runId, - public array $fileIds, + public array $attachments, public array $metadata, private readonly MetaInformation $meta, ) { @@ -47,28 +51,38 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{id: string, object: string, created_at: int, thread_id: string, role: string, content: array}}>, assistant_id: ?string, run_id: ?string, file_ids: array, metadata: array} $attributes + * @param array{id: string, object: string, created_at: int, thread_id: string, status: string, incomplete_details: ?array{reason: string}, completed_at: ?int, incomplete_at: ?int, role: string, content: array}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array} $attributes */ public static function from(array $attributes, MetaInformation $meta): self { $content = array_map( - fn (array $content): \OpenAI\Responses\Threads\Messages\ThreadMessageResponseContentTextObject|\OpenAI\Responses\Threads\Messages\ThreadMessageResponseContentImageFileObject => match ($content['type']) { + fn (array $content): ThreadMessageResponseContentTextObject|ThreadMessageResponseContentImageFileObject|ThreadMessageResponseContentImageUrlObject => match ($content['type']) { 'text' => ThreadMessageResponseContentTextObject::from($content), 'image_file' => ThreadMessageResponseContentImageFileObject::from($content), + 'image_url' => ThreadMessageResponseContentImageUrlObject::from($content), }, $attributes['content'], ); + $attachments = array_map( + fn (array $attachment): ThreadMessageResponseAttachment => ThreadMessageResponseAttachment::from($attachment), + $attributes['attachments'] + ); + return new self( $attributes['id'], $attributes['object'], $attributes['created_at'], $attributes['thread_id'], + $attributes['status'], + $attributes['incomplete_details'] !== null ? ThreadMessageResponseIncompleteDetails::from($attributes['incomplete_details']) : null, + $attributes['completed_at'], + $attributes['incomplete_at'], $attributes['role'], $content, $attributes['assistant_id'], $attributes['run_id'], - $attributes['file_ids'], + $attachments, $attributes['metadata'], $meta, ); @@ -84,12 +98,19 @@ public function toArray(): array 'object' => $this->object, 'created_at' => $this->createdAt, 'thread_id' => $this->threadId, + 'status' => $this->status, + 'incomplete_details' => $this->incompleteDetails?->toArray(), + 'completed_at' => $this->completedAt, + 'incomplete_at' => $this->incompleteAt, 'role' => $this->role, 'content' => array_map( - fn (ThreadMessageResponseContentImageFileObject|ThreadMessageResponseContentTextObject $content): array => $content->toArray(), + fn (ThreadMessageResponseContentImageFileObject|ThreadMessageResponseContentTextObject|ThreadMessageResponseContentImageUrlObject $content): array => $content->toArray(), $this->content, ), - 'file_ids' => $this->fileIds, + 'attachments' => array_map( + fn (ThreadMessageResponseAttachment $attachment): array => $attachment->toArray(), + $this->attachments + ), 'assistant_id' => $this->assistantId, 'run_id' => $this->runId, 'metadata' => $this->metadata, diff --git a/src/Responses/Threads/Messages/ThreadMessageResponseAttachment.php b/src/Responses/Threads/Messages/ThreadMessageResponseAttachment.php new file mode 100644 index 00000000..019142bc --- /dev/null +++ b/src/Responses/Threads/Messages/ThreadMessageResponseAttachment.php @@ -0,0 +1,63 @@ +}> + */ +final class ThreadMessageResponseAttachment implements ResponseContract +{ + /** + * @use ArrayAccessible}> + */ + use ArrayAccessible; + + use Fakeable; + + /** + * @param array $tools + */ + private function __construct( + public string $fileId, + public array $tools, + ) { + } + + /** + * Acts as static factory, and returns a new Response instance. + * + * @param array{file_id: string, tools: array} $attributes + */ + public static function from(array $attributes): self + { + $tools = array_map(fn (array $tool): ThreadMessageResponseAttachmentFileSearchTool|ThreadMessageResponseAttachmentCodeInterpreterTool => match ($tool['type']) { + 'file_search' => ThreadMessageResponseAttachmentFileSearchTool::from($tool), + 'code_interpreter' => ThreadMessageResponseAttachmentCodeInterpreterTool::from($tool), + }, $attributes['tools']); + + return new self( + $attributes['file_id'], + $tools, + ); + } + + /** + * {@inheritDoc} + */ + public function toArray(): array + { + return [ + 'file_id' => $this->fileId, + 'tools' => array_map( + fn (ThreadMessageResponseAttachmentCodeInterpreterTool|ThreadMessageResponseAttachmentFileSearchTool $tool): array => $tool->toArray(), + $this->tools, + ), + ]; + } +} diff --git a/src/Responses/Threads/Messages/ThreadMessageResponseAttachmentCodeInterpreterTool.php b/src/Responses/Threads/Messages/ThreadMessageResponseAttachmentCodeInterpreterTool.php new file mode 100644 index 00000000..12f69501 --- /dev/null +++ b/src/Responses/Threads/Messages/ThreadMessageResponseAttachmentCodeInterpreterTool.php @@ -0,0 +1,52 @@ + + */ +final class ThreadMessageResponseAttachmentCodeInterpreterTool implements ResponseContract +{ + /** + * @use ArrayAccessible + */ + use ArrayAccessible; + + use Fakeable; + + /** + * @param 'code_interpreter' $type + */ + private function __construct( + public string $type, + ) { + } + + /** + * Acts as static factory, and returns a new Response instance. + * + * @param array{type: 'code_interpreter'} $attributes + */ + public static function from(array $attributes): self + { + return new self( + $attributes['type'], + ); + } + + /** + * {@inheritDoc} + */ + public function toArray(): array + { + return [ + 'type' => $this->type, + ]; + } +} diff --git a/src/Responses/Threads/Messages/ThreadMessageResponseAttachmentFileSearchTool.php b/src/Responses/Threads/Messages/ThreadMessageResponseAttachmentFileSearchTool.php new file mode 100644 index 00000000..efd5771e --- /dev/null +++ b/src/Responses/Threads/Messages/ThreadMessageResponseAttachmentFileSearchTool.php @@ -0,0 +1,52 @@ + + */ +final class ThreadMessageResponseAttachmentFileSearchTool implements ResponseContract +{ + /** + * @use ArrayAccessible + */ + use ArrayAccessible; + + use Fakeable; + + /** + * @param 'file_search' $type + */ + private function __construct( + public string $type, + ) { + } + + /** + * Acts as static factory, and returns a new Response instance. + * + * @param array{type: 'file_search'} $attributes + */ + public static function from(array $attributes): self + { + return new self( + $attributes['type'], + ); + } + + /** + * {@inheritDoc} + */ + public function toArray(): array + { + return [ + 'type' => $this->type, + ]; + } +} diff --git a/src/Responses/Threads/Messages/ThreadMessageResponseContentImageFile.php b/src/Responses/Threads/Messages/ThreadMessageResponseContentImageFile.php index 2b9e1338..96151469 100644 --- a/src/Responses/Threads/Messages/ThreadMessageResponseContentImageFile.php +++ b/src/Responses/Threads/Messages/ThreadMessageResponseContentImageFile.php @@ -9,12 +9,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract + * @implements ResponseContract */ final class ThreadMessageResponseContentImageFile implements ResponseContract { /** - * @use ArrayAccessible + * @use ArrayAccessible */ use ArrayAccessible; @@ -22,18 +22,20 @@ final class ThreadMessageResponseContentImageFile implements ResponseContract private function __construct( public string $fileId, + public ?string $detail, ) { } /** * Acts as static factory, and returns a new Response instance. * - * @param array{file_id: string} $attributes + * @param array{file_id: string, detail?: string} $attributes */ public static function from(array $attributes): self { return new self( $attributes['file_id'], + $attributes['detail'] ?? null, ); } @@ -42,8 +44,9 @@ public static function from(array $attributes): self */ public function toArray(): array { - return [ + return array_filter([ 'file_id' => $this->fileId, - ]; + 'detail' => $this->detail, + ], fn (?string $value): bool => $value !== null); } } diff --git a/src/Responses/Threads/Messages/ThreadMessageResponseContentImageFileObject.php b/src/Responses/Threads/Messages/ThreadMessageResponseContentImageFileObject.php index f5667717..520c9898 100644 --- a/src/Responses/Threads/Messages/ThreadMessageResponseContentImageFileObject.php +++ b/src/Responses/Threads/Messages/ThreadMessageResponseContentImageFileObject.php @@ -9,12 +9,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract + * @implements ResponseContract */ final class ThreadMessageResponseContentImageFileObject implements ResponseContract { /** - * @use ArrayAccessible + * @use ArrayAccessible */ use ArrayAccessible; @@ -29,7 +29,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{type: string, image_file: array{file_id: string}} $attributes + * @param array{type: string, image_file: array{file_id: string, detail?: string}} $attributes */ public static function from(array $attributes): self { diff --git a/src/Responses/Threads/Messages/ThreadMessageResponseContentImageUrl.php b/src/Responses/Threads/Messages/ThreadMessageResponseContentImageUrl.php new file mode 100644 index 00000000..5eca0dde --- /dev/null +++ b/src/Responses/Threads/Messages/ThreadMessageResponseContentImageUrl.php @@ -0,0 +1,52 @@ + + */ +final class ThreadMessageResponseContentImageUrl implements ResponseContract +{ + /** + * @use ArrayAccessible + */ + use ArrayAccessible; + + use Fakeable; + + private function __construct( + public string $fileId, + public ?string $detail, + ) { + } + + /** + * Acts as static factory, and returns a new Response instance. + * + * @param array{file_id: string, detail?: string} $attributes + */ + public static function from(array $attributes): self + { + return new self( + $attributes['file_id'], + $attributes['detail'] ?? null, + ); + } + + /** + * {@inheritDoc} + */ + public function toArray(): array + { + return array_filter([ + 'file_id' => $this->fileId, + 'detail' => $this->detail, + ], fn (?string $value): bool => $value !== null); + } +} diff --git a/src/Responses/Threads/Messages/ThreadMessageResponseContentImageUrlObject.php b/src/Responses/Threads/Messages/ThreadMessageResponseContentImageUrlObject.php new file mode 100644 index 00000000..acb58b86 --- /dev/null +++ b/src/Responses/Threads/Messages/ThreadMessageResponseContentImageUrlObject.php @@ -0,0 +1,55 @@ + + */ +final class ThreadMessageResponseContentImageUrlObject implements ResponseContract +{ + /** + * @use ArrayAccessible + */ + use ArrayAccessible; + + use Fakeable; + + /** + * @param 'image_url' $type + */ + private function __construct( + public string $type, + public ThreadMessageResponseContentImageUrl $imageFile, + ) { + } + + /** + * Acts as static factory, and returns a new Response instance. + * + * @param array{type: 'image_url', image_url: array{file_id: string, detail?: string}} $attributes + */ + public static function from(array $attributes): self + { + return new self( + $attributes['type'], + ThreadMessageResponseContentImageUrl::from($attributes['image_url']), + ); + } + + /** + * {@inheritDoc} + */ + public function toArray(): array + { + return [ + 'type' => $this->type, + 'image_url' => $this->imageFile->toArray(), + ]; + } +} diff --git a/src/Responses/Threads/Messages/ThreadMessageResponseContentTextObject.php b/src/Responses/Threads/Messages/ThreadMessageResponseContentTextObject.php index 28f3bdfb..29179622 100644 --- a/src/Responses/Threads/Messages/ThreadMessageResponseContentTextObject.php +++ b/src/Responses/Threads/Messages/ThreadMessageResponseContentTextObject.php @@ -9,17 +9,20 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}}> + * @implements ResponseContract}}> */ final class ThreadMessageResponseContentTextObject implements ResponseContract { /** - * @use ArrayAccessible}}> + * @use ArrayAccessible}}> */ use ArrayAccessible; use Fakeable; + /** + * @param 'text' $type + */ private function __construct( public string $type, public ThreadMessageResponseContentText $text, @@ -29,7 +32,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{type: string, text: array{value: string, annotations: array}} $attributes + * @param array{type: 'text', text: array{value: string, annotations: array}} $attributes */ public static function from(array $attributes): self { diff --git a/src/Responses/Threads/Messages/ThreadMessageResponseIncompleteDetails.php b/src/Responses/Threads/Messages/ThreadMessageResponseIncompleteDetails.php new file mode 100644 index 00000000..cc3ae601 --- /dev/null +++ b/src/Responses/Threads/Messages/ThreadMessageResponseIncompleteDetails.php @@ -0,0 +1,49 @@ + + */ +final class ThreadMessageResponseIncompleteDetails implements ResponseContract +{ + /** + * @use ArrayAccessible + */ + use ArrayAccessible; + + use Fakeable; + + private function __construct( + public string $reason, + ) { + } + + /** + * Acts as static factory, and returns a new Response instance. + * + * @param array{reason: string} $attributes + */ + public static function from(array $attributes): self + { + return new self( + $attributes['reason'], + ); + } + + /** + * {@inheritDoc} + */ + public function toArray(): array + { + return [ + 'reason' => $this->reason, + ]; + } +} diff --git a/src/Responses/Threads/Runs/Steps/Delta/ThreadRunStepDeltaObject.php b/src/Responses/Threads/Runs/Steps/Delta/ThreadRunStepDeltaObject.php index c5c8aa72..153957fd 100644 --- a/src/Responses/Threads/Runs/Steps/Delta/ThreadRunStepDeltaObject.php +++ b/src/Responses/Threads/Runs/Steps/Delta/ThreadRunStepDeltaObject.php @@ -11,12 +11,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}}|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}}}> + * @implements ResponseContract}}|array{id: string, type: 'file_search', file_search: array}|array{id: ?string, type: 'function', function: array{name: ?string, arguments: string, output: ?string}}>}|array{type: 'message_creation', message_creation: array{message_id: string}}}> */ final class ThreadRunStepDeltaObject implements ResponseContract { /** - * @use ArrayAccessible}}|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}}}> + * @use ArrayAccessible}}|array{id: string, type: 'file_search', file_search: array}|array{id: ?string, type: 'function', function: array{name: ?string, arguments: string, output: ?string}}>}|array{type: 'message_creation', message_creation: array{message_id: string}}}> */ use ArrayAccessible; @@ -30,7 +30,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{step_details: array{type: 'tool_calls', tool_calls: array}}|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}}} $attributes + * @param array{step_details: array{type: 'tool_calls', tool_calls: array}}|array{id: string, type: 'file_search', file_search: array}|array{id?: string, type: 'function', function: array{name?: string, arguments: string, output?: ?string}}>}|array{type: 'message_creation', message_creation: array{message_id: string}}} $attributes */ public static function from(array $attributes): self { diff --git a/src/Responses/Threads/Runs/Steps/Delta/ThreadRunStepDeltaResponse.php b/src/Responses/Threads/Runs/Steps/Delta/ThreadRunStepDeltaResponse.php index 73705f38..cf8f9a8b 100644 --- a/src/Responses/Threads/Runs/Steps/Delta/ThreadRunStepDeltaResponse.php +++ b/src/Responses/Threads/Runs/Steps/Delta/ThreadRunStepDeltaResponse.php @@ -9,12 +9,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}}|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}}}}> + * @implements ResponseContract}}|array{id: string, type: 'file_search', file_search: array}|array{id: ?string, type: 'function', function: array{name: ?string, arguments: string, output: ?string}}>}|array{type: 'message_creation', message_creation: array{message_id: string}}}}> */ final class ThreadRunStepDeltaResponse implements ResponseContract { /** - * @use ArrayAccessible}}|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}}}}> + * @use ArrayAccessible}}|array{id: string, type: 'file_search', file_search: array}|array{id: ?string, type: 'function', function: array{name: ?string, arguments: string, output: ?string}}>}|array{type: 'message_creation', message_creation: array{message_id: string}}}}> */ use ArrayAccessible; @@ -30,7 +30,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{id?: string, object: string, delta: array{step_details: array{type: 'tool_calls', tool_calls: array}}|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}}}} $attributes + * @param array{id?: string, object: string, delta: array{step_details: array{type: 'tool_calls', tool_calls: array}}|array{id: string, type: 'file_search', file_search: array}|array{id?: string, type: 'function', function: array{name?: string, arguments: string, output?: ?string}}>}|array{type: 'message_creation', message_creation: array{message_id: string}}}} $attributes */ public static function from(array $attributes): self { diff --git a/src/Responses/Threads/Runs/Steps/ThreadRunStepListResponse.php b/src/Responses/Threads/Runs/Steps/ThreadRunStepListResponse.php index cc9bd223..0546fda8 100644 --- a/src/Responses/Threads/Runs/Steps/ThreadRunStepListResponse.php +++ b/src/Responses/Threads/Runs/Steps/ThreadRunStepListResponse.php @@ -12,12 +12,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}}|array{id: string, type: 'retrieval', retrieval: array}|array{id: ?string, type: string, 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}> + * @implements ResponseContract}}|array{id: string, type: 'file_search', file_search: 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, usage: ?array{prompt_tokens: int, completion_tokens: int, total_tokens: int}}>, first_id: ?string, last_id: ?string, has_more: bool}> */ final class ThreadRunStepListResponse implements ResponseContract, ResponseHasMetaInformationContract { /** - * @use ArrayAccessible}}|array{id: string, type: 'retrieval', retrieval: array}|array{id: ?string, type: string, 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}> + * @use ArrayAccessible}}|array{id: string, type: 'file_search', file_search: 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, usage: ?array{prompt_tokens: int, completion_tokens: int, total_tokens: int}}>, first_id: ?string, last_id: ?string, has_more: bool}> */ use ArrayAccessible; @@ -40,7 +40,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{object: string, data: array}}|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} $attributes + * @param array{object: string, data: array}}|array{id: string, type: 'file_search', file_search: 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, usage: ?array{prompt_tokens: int, completion_tokens: int, total_tokens: int}}>, first_id: ?string, last_id: ?string, has_more: bool} $attributes */ public static function from(array $attributes, MetaInformation $meta): self { diff --git a/src/Responses/Threads/Runs/Steps/ThreadRunStepResponse.php b/src/Responses/Threads/Runs/Steps/ThreadRunStepResponse.php index abcf46a5..55c429a7 100644 --- a/src/Responses/Threads/Runs/Steps/ThreadRunStepResponse.php +++ b/src/Responses/Threads/Runs/Steps/ThreadRunStepResponse.php @@ -12,12 +12,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}}|array{id: string, type: 'retrieval', retrieval: array}|array{id: ?string, type: string, 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}> + * @implements ResponseContract}}|array{id: string, type: 'file_search', file_search: 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, usage: ?array{prompt_tokens: int, completion_tokens: int, total_tokens: int}}> */ final class ThreadRunStepResponse implements ResponseContract { /** - * @use ArrayAccessible}}|array{id: string, type: 'retrieval', retrieval: array}|array{id: ?string, type: string, 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}> + * @use ArrayAccessible}}|array{id: string, type: 'file_search', file_search: 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, usage: ?array{prompt_tokens: int, completion_tokens: int, total_tokens: int}}> */ use ArrayAccessible; @@ -44,13 +44,14 @@ private function __construct( public ?int $completedAt, public array $metadata, private readonly MetaInformation $meta, + public ?ThreadRunStepResponseUsage $usage ) { } /** * Acts as static factory, and returns a new Response instance. * - * @param array{id: string, object: string, created_at: int, thread_id: string, assistant_id: string, run_id: string, type: string, status: string, step_details: array{type: 'tool_calls', tool_calls: array}}|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} $attributes + * @param array{id: string, object: string, created_at: int, thread_id: string, assistant_id: string, run_id: string, type: string, status: string, step_details: array{type: 'tool_calls', tool_calls: array}}|array{id: string, type: 'file_search', file_search: 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, usage: ?array{prompt_tokens: int, completion_tokens: int, total_tokens: int}} $attributes */ public static function from(array $attributes, MetaInformation $meta): self { @@ -76,6 +77,7 @@ public static function from(array $attributes, MetaInformation $meta): self $attributes['completed_at'], $attributes['metadata'] ?? [], $meta, + empty($attributes['usage']) ? null : ThreadRunStepResponseUsage::from($attributes['usage']), ); } @@ -99,6 +101,7 @@ public function toArray(): array 'failed_at' => $this->failedAt, 'last_error' => $this->lastError?->toArray(), 'step_details' => $this->stepDetails->toArray(), + 'usage' => $this->usage?->toArray(), ]; if ($this->metadata !== []) { diff --git a/src/Responses/Threads/Runs/Steps/ThreadRunStepResponseCodeInterpreter.php b/src/Responses/Threads/Runs/Steps/ThreadRunStepResponseCodeInterpreter.php index f50d2cb4..b55dff0b 100644 --- a/src/Responses/Threads/Runs/Steps/ThreadRunStepResponseCodeInterpreter.php +++ b/src/Responses/Threads/Runs/Steps/ThreadRunStepResponseCodeInterpreter.php @@ -9,43 +9,43 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}> + * @implements ResponseContract}> */ final class ThreadRunStepResponseCodeInterpreter implements ResponseContract { /** - * @use ArrayAccessible}> + * @use ArrayAccessible}> */ use ArrayAccessible; use Fakeable; /** - * @param array $outputs + * @param \OpenAI\Responses\Threads\Runs\Steps\ThreadRunStepResponseCodeInterpreterOutputLogs[]|\OpenAI\Responses\Threads\Runs\Steps\ThreadRunStepResponseCodeInterpreterOutputImage[]|null $outputs */ private function __construct( - public string $input, - public array $outputs, + public ?string $input, + public ?array $outputs, ) { } /** * Acts as static factory, and returns a new Response instance. * - * @param array{input: string, outputs: array} $attributes + * @param array{input?: string, outputs?: array} $attributes */ public static function from(array $attributes): self { - $outputs = array_map( + $outputs = isset($attributes['outputs']) ? array_map( fn (array $output): \OpenAI\Responses\Threads\Runs\Steps\ThreadRunStepResponseCodeInterpreterOutputImage|\OpenAI\Responses\Threads\Runs\Steps\ThreadRunStepResponseCodeInterpreterOutputLogs => match ($output['type']) { 'image' => ThreadRunStepResponseCodeInterpreterOutputImage::from($output), 'logs' => ThreadRunStepResponseCodeInterpreterOutputLogs::from($output), }, $attributes['outputs'], - ); + ) : null; return new self( - $attributes['input'], + $attributes['input'] ?? null, $outputs, ); } @@ -55,12 +55,19 @@ public static function from(array $attributes): self */ public function toArray(): array { - return [ - 'input' => $this->input, - 'outputs' => array_map( + $response = []; + + if (! is_null($this->input)) { + $response['input'] = $this->input; + } + + if ($this->outputs) { + $response['outputs'] = array_map( fn (ThreadRunStepResponseCodeInterpreterOutputImage|ThreadRunStepResponseCodeInterpreterOutputLogs $output): array => $output->toArray(), $this->outputs, - ), - ]; + ); + } + + return $response; } } diff --git a/src/Responses/Threads/Runs/Steps/ThreadRunStepResponseCodeToolCall.php b/src/Responses/Threads/Runs/Steps/ThreadRunStepResponseCodeToolCall.php index 42847b5a..8d7c6c21 100644 --- a/src/Responses/Threads/Runs/Steps/ThreadRunStepResponseCodeToolCall.php +++ b/src/Responses/Threads/Runs/Steps/ThreadRunStepResponseCodeToolCall.php @@ -9,12 +9,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}}> + * @implements ResponseContract}}> */ final class ThreadRunStepResponseCodeToolCall implements ResponseContract { /** - * @use ArrayAccessible}}> + * @use ArrayAccessible}}> */ use ArrayAccessible; @@ -33,7 +33,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{id?: string, type: 'code_interpreter', code_interpreter: array{input: string, outputs: array}} $attributes + * @param array{id?: string, type: 'code_interpreter', code_interpreter: array{input?: string, outputs?: array}} $attributes */ public static function from(array $attributes): self { diff --git a/src/Responses/Threads/Runs/Steps/ThreadRunStepResponseRetrievalToolCall.php b/src/Responses/Threads/Runs/Steps/ThreadRunStepResponseFileSearchToolCall.php similarity index 58% rename from src/Responses/Threads/Runs/Steps/ThreadRunStepResponseRetrievalToolCall.php rename to src/Responses/Threads/Runs/Steps/ThreadRunStepResponseFileSearchToolCall.php index bf12ee70..b4b6463f 100644 --- a/src/Responses/Threads/Runs/Steps/ThreadRunStepResponseRetrievalToolCall.php +++ b/src/Responses/Threads/Runs/Steps/ThreadRunStepResponseFileSearchToolCall.php @@ -9,39 +9,39 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}> + * @implements ResponseContract}> */ -final class ThreadRunStepResponseRetrievalToolCall implements ResponseContract +final class ThreadRunStepResponseFileSearchToolCall implements ResponseContract { /** - * @use ArrayAccessible}> + * @use ArrayAccessible}> */ use ArrayAccessible; use Fakeable; /** - * @param 'retrieval' $type - * @param array $retrieval + * @param 'file_search' $type + * @param array $file_search */ private function __construct( public string $id, public string $type, - public array $retrieval, + public array $file_search, ) { } /** * Acts as static factory, and returns a new Response instance. * - * @param array{id: string, type: 'retrieval', retrieval: array} $attributes + * @param array{id: string, type: 'file_search', file_search: array} $attributes */ public static function from(array $attributes): self { return new self( $attributes['id'], $attributes['type'], - $attributes['retrieval'], + $attributes['file_search'], ); } @@ -53,7 +53,7 @@ public function toArray(): array return [ 'id' => $this->id, 'type' => $this->type, - 'retrieval' => $this->retrieval, + 'file_search' => $this->file_search, ]; } } diff --git a/src/Responses/Threads/Runs/Steps/ThreadRunStepResponseToolCallsStepDetails.php b/src/Responses/Threads/Runs/Steps/ThreadRunStepResponseToolCallsStepDetails.php index 40998a93..77df93da 100644 --- a/src/Responses/Threads/Runs/Steps/ThreadRunStepResponseToolCallsStepDetails.php +++ b/src/Responses/Threads/Runs/Steps/ThreadRunStepResponseToolCallsStepDetails.php @@ -9,12 +9,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}}|array{id: string, type: 'retrieval', retrieval: array}|array{id: ?string, type: 'function', function: array{name: ?string, arguments: string, output: ?string}}>}> + * @implements ResponseContract}}|array{id: string, type: 'file_search', file_search: array}|array{id: ?string, type: 'function', function: array{name: ?string, arguments: string, output: ?string}}>}> */ final class ThreadRunStepResponseToolCallsStepDetails implements ResponseContract { /** - * @use ArrayAccessible}}|array{id: string, type: 'retrieval', retrieval: array}|array{id: ?string, type: 'function', function: array{name: ?string, arguments: string, output: ?string}}>}> + * @use ArrayAccessible}}|array{id: string, type: 'file_search', file_search: array}|array{id: ?string, type: 'function', function: array{name: ?string, arguments: string, output: ?string}}>}> */ use ArrayAccessible; @@ -22,7 +22,7 @@ final class ThreadRunStepResponseToolCallsStepDetails implements ResponseContrac /** * @param 'tool_calls' $type - * @param array $toolCalls + * @param array $toolCalls */ private function __construct( public string $type, @@ -33,14 +33,14 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{type: 'tool_calls', tool_calls: array}}|array{id: string, type: 'retrieval', retrieval: array}|array{id?: string, type: 'function', function: array{name?: string, arguments: string, output?: ?string}}>} $attributes + * @param array{type: 'tool_calls', tool_calls: array}}|array{id: string, type: 'file_search', file_search: array}|array{id?: string, type: 'function', function: array{name?: string, arguments: string, output?: ?string}}>} $attributes */ public static function from(array $attributes): self { $toolCalls = array_map( - fn (array $toolCall): ThreadRunStepResponseCodeToolCall|ThreadRunStepResponseRetrievalToolCall|ThreadRunStepResponseFunctionToolCall => match ($toolCall['type']) { + fn (array $toolCall): ThreadRunStepResponseCodeToolCall|ThreadRunStepResponseFileSearchToolCall|ThreadRunStepResponseFunctionToolCall => match ($toolCall['type']) { 'code_interpreter' => ThreadRunStepResponseCodeToolCall::from($toolCall), - 'retrieval' => ThreadRunStepResponseRetrievalToolCall::from($toolCall), + 'file_search' => ThreadRunStepResponseFileSearchToolCall::from($toolCall), 'function' => ThreadRunStepResponseFunctionToolCall::from($toolCall), }, $attributes['tool_calls'], @@ -60,7 +60,7 @@ public function toArray(): array return [ 'type' => $this->type, 'tool_calls' => array_map( - fn (ThreadRunStepResponseCodeToolCall|ThreadRunStepResponseRetrievalToolCall|ThreadRunStepResponseFunctionToolCall $toolCall): array => $toolCall->toArray(), + fn (ThreadRunStepResponseCodeToolCall|ThreadRunStepResponseFileSearchToolCall|ThreadRunStepResponseFunctionToolCall $toolCall): array => $toolCall->toArray(), $this->toolCalls, ), ]; diff --git a/src/Responses/Threads/Runs/Steps/ThreadRunStepResponseUsage.php b/src/Responses/Threads/Runs/Steps/ThreadRunStepResponseUsage.php new file mode 100644 index 00000000..bc764849 --- /dev/null +++ b/src/Responses/Threads/Runs/Steps/ThreadRunStepResponseUsage.php @@ -0,0 +1,55 @@ + + */ +final class ThreadRunStepResponseUsage implements ResponseContract +{ + /** + * @use ArrayAccessible + */ + use ArrayAccessible; + + use Fakeable; + + private function __construct( + public int $completionTokens, + public int $promptTokens, + public int $totalTokens, + ) { + } + + /** + * Acts as static factory, and returns a new Response instance. + * + * @param array{prompt_tokens: int, completion_tokens: int, total_tokens: int} $attributes + */ + public static function from(array $attributes): self + { + return new self( + $attributes['completion_tokens'], + $attributes['prompt_tokens'], + $attributes['total_tokens'], + ); + } + + /** + * {@inheritDoc} + */ + public function toArray(): array + { + return [ + 'prompt_tokens' => $this->promptTokens, + 'completion_tokens' => $this->completionTokens, + 'total_tokens' => $this->totalTokens, + ]; + } +} diff --git a/src/Responses/Threads/Runs/ThreadRunListResponse.php b/src/Responses/Threads/Runs/ThreadRunListResponse.php index 48f0fc15..a41daf9d 100644 --- a/src/Responses/Threads/Runs/ThreadRunListResponse.php +++ b/src/Responses/Threads/Runs/ThreadRunListResponse.php @@ -12,12 +12,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}}, 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}> + * @implements ResponseContract}}, 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}}>, metadata: array, usage?: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}, incomplete_details: null|array{reason: string}, temperature: float|int|null, top_p: null|float|int, max_prompt_tokens: ?int, max_completion_tokens: ?int, truncation_strategy: ?array{type: string, last_messages: ?int}, tool_choice: null|string|array{type: string, function?: array{name: string}}, response_format: null|string|array{type: string}}>, first_id: ?string, last_id: ?string, has_more: bool}> */ final class ThreadRunListResponse implements ResponseContract, ResponseHasMetaInformationContract { /** - * @use ArrayAccessible}}, 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}> + * @use ArrayAccessible}}, 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}}>, metadata: array, usage?: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}, incomplete_details: null|array{reason: string}, temperature: float|int|null, top_p: null|float|int, max_prompt_tokens: ?int, max_completion_tokens: ?int, truncation_strategy: ?array{type: string, last_messages: ?int}, tool_choice: null|string|array{type: string, function?: array{name: string}}, response_format: null|string|array{type: string}}>, first_id: ?string, last_id: ?string, has_more: bool}> */ use ArrayAccessible; @@ -40,7 +40,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{object: string, data: array}}, 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} $attributes + * @param array{object: string, data: array}}, 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}}>, metadata: array, usage?: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}, incomplete_details: ?array{reason: string}, temperature: float|int|null, top_p: null|float|int, max_prompt_tokens: ?int, max_completion_tokens: ?int, truncation_strategy: array{type: string, last_messages: ?int}, tool_choice: string|array{type: string, function?: array{name: string}}, response_format: string|array{type: 'text'|'json_object'}}>, first_id: ?string, last_id: ?string, has_more: bool} $attributes */ public static function from(array $attributes, MetaInformation $meta): self { diff --git a/src/Responses/Threads/Runs/ThreadRunResponse.php b/src/Responses/Threads/Runs/ThreadRunResponse.php index 92f6252c..84133e69 100644 --- a/src/Responses/Threads/Runs/ThreadRunResponse.php +++ b/src/Responses/Threads/Runs/ThreadRunResponse.php @@ -6,18 +6,19 @@ use OpenAI\Contracts\ResponseContract; use OpenAI\Contracts\ResponseHasMetaInformationContract; +use OpenAI\Responses\Assistants\AssistantResponseResponseFormat; use OpenAI\Responses\Concerns\ArrayAccessible; use OpenAI\Responses\Concerns\HasMetaInformation; use OpenAI\Responses\Meta\MetaInformation; use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}}, 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, usage?: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}}> + * @implements ResponseContract}}, 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}}>, metadata: array, usage?: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}, incomplete_details: null|array{reason: string}, temperature: float|int|null, top_p: null|float|int, max_prompt_tokens: ?int, max_completion_tokens: ?int, truncation_strategy: ?array{type: string, last_messages: ?int}, tool_choice: null|string|array{type: string, function?: array{name: string}}, response_format: null|string|array{type: string}}> */ final class ThreadRunResponse implements ResponseContract, ResponseHasMetaInformationContract { /** - * @use ArrayAccessible}}, 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, usage?: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}}> + * @use ArrayAccessible}}, 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}}>, metadata: array, usage?: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}, incomplete_details: ?array{reason: string}, temperature: float|int|null, top_p: null|float|int, max_prompt_tokens: ?int, max_completion_tokens: ?int, truncation_strategy: ?array{type: string, last_messages: ?int}, tool_choice: null|string|array{type: string, function?: array{name: string}}, response_format: null|string|array{type: string}}> */ use ArrayAccessible; @@ -25,8 +26,7 @@ final class ThreadRunResponse implements ResponseContract, ResponseHasMetaInform use HasMetaInformation; /** - * @param array $tools - * @param array $fileIds + * @param array $tools * @param array $metadata */ private function __construct( @@ -43,12 +43,19 @@ private function __construct( public ?int $cancelledAt, public ?int $failedAt, public ?int $completedAt, + public ?ThreadRunResponseIncompleteDetails $incompleteDetails, public string $model, public ?string $instructions, public array $tools, - public array $fileIds, public array $metadata, public ?ThreadRunResponseUsage $usage, + public ?float $temperature, + public ?float $topP, + public ?int $maxPromptTokens, + public ?int $maxCompletionTokens, + public ?ThreadRunResponseTruncationStrategy $truncationStrategy, + public null|string|ThreadRunResponseToolChoice $toolChoice, + public null|string|AssistantResponseResponseFormat $responseFormat, private readonly MetaInformation $meta, ) { } @@ -56,19 +63,23 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{id: string, object: string, created_at: int, thread_id: string, assistant_id: string, status: string, required_action?: array{type: string, submit_tool_outputs: array{tool_calls: array}}, 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, usage?: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}} $attributes + * @param array{id: string, object: string, created_at: int, thread_id: string, assistant_id: string, status: string, required_action?: array{type: string, submit_tool_outputs: array{tool_calls: array}}, 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}}>, metadata: array, usage?: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}, incomplete_details: ?array{reason: string}, temperature: float|int|null, top_p: null|float|int, max_prompt_tokens: ?int, max_completion_tokens: ?int, truncation_strategy: ?array{type: string, last_messages: ?int}, tool_choice: null|string|array{type: string, function?: array{name: string}}, response_format: null|string|array{type: 'text'|'json_object'}} $attributes */ public static function from(array $attributes, MetaInformation $meta): self { $tools = array_map( - fn (array $tool): ThreadRunResponseToolCodeInterpreter|ThreadRunResponseToolRetrieval|ThreadRunResponseToolFunction => match ($tool['type']) { + fn (array $tool): ThreadRunResponseToolCodeInterpreter|ThreadRunResponseFileSearch|ThreadRunResponseToolFunction => match ($tool['type']) { 'code_interpreter' => ThreadRunResponseToolCodeInterpreter::from($tool), - 'retrieval' => ThreadRunResponseToolRetrieval::from($tool), + 'file_search' => ThreadRunResponseFileSearch::from($tool), 'function' => ThreadRunResponseToolFunction::from($tool), }, $attributes['tools'], ); + $responseFormat = is_array($attributes['response_format']) ? + AssistantResponseResponseFormat::from($attributes['response_format']) : + $attributes['response_format']; + return new self( $attributes['id'], $attributes['object'], @@ -83,12 +94,19 @@ public static function from(array $attributes, MetaInformation $meta): self $attributes['cancelled_at'], $attributes['failed_at'], $attributes['completed_at'], + isset($attributes['incomplete_details']) ? ThreadRunResponseIncompleteDetails::from($attributes['incomplete_details']) : null, $attributes['model'], $attributes['instructions'], $tools, - $attributes['file_ids'], $attributes['metadata'], isset($attributes['usage']) ? ThreadRunResponseUsage::from($attributes['usage']) : null, + $attributes['temperature'] ?? null, + $attributes['top_p'] ?? null, + $attributes['max_prompt_tokens'] ?? null, + $attributes['max_completion_tokens'] ?? null, + $attributes['truncation_strategy'] !== null ? ThreadRunResponseTruncationStrategy::from($attributes['truncation_strategy']) : null, + is_array($attributes['tool_choice']) ? ThreadRunResponseToolChoice::from($attributes['tool_choice']) : $attributes['tool_choice'], + $responseFormat, $meta, ); } @@ -110,17 +128,24 @@ public function toArray(): array 'cancelled_at' => $this->cancelledAt, 'failed_at' => $this->failedAt, 'completed_at' => $this->completedAt, + 'incomplete_details' => $this->incompleteDetails?->toArray(), 'required_action' => $this->requiredAction?->toArray(), 'last_error' => $this->lastError?->toArray(), 'model' => $this->model, 'instructions' => $this->instructions, 'tools' => array_map( - fn (ThreadRunResponseToolCodeInterpreter|ThreadRunResponseToolRetrieval|ThreadRunResponseToolFunction $tool): array => $tool->toArray(), + fn (ThreadRunResponseToolCodeInterpreter|ThreadRunResponseFileSearch|ThreadRunResponseToolFunction $tool): array => $tool->toArray(), $this->tools, ), - 'file_ids' => $this->fileIds, 'metadata' => $this->metadata, 'usage' => $this->usage?->toArray(), + 'temperature' => $this->temperature, + 'top_p' => $this->topP, + 'max_prompt_tokens' => $this->maxPromptTokens, + 'max_completion_tokens' => $this->maxCompletionTokens, + 'truncation_strategy' => $this->truncationStrategy?->toArray(), + 'tool_choice' => $this->toolChoice instanceof ThreadRunResponseToolChoice ? $this->toolChoice->toArray() : $this->toolChoice, + 'response_format' => $this->responseFormat instanceof AssistantResponseResponseFormat ? $this->responseFormat->toArray() : $this->responseFormat, ]; if ($data['required_action'] === null) { diff --git a/src/Responses/Threads/Runs/ThreadRunResponseToolRetrieval.php b/src/Responses/Threads/Runs/ThreadRunResponseFileSearch.php similarity index 87% rename from src/Responses/Threads/Runs/ThreadRunResponseToolRetrieval.php rename to src/Responses/Threads/Runs/ThreadRunResponseFileSearch.php index d7578f22..7c49409a 100644 --- a/src/Responses/Threads/Runs/ThreadRunResponseToolRetrieval.php +++ b/src/Responses/Threads/Runs/ThreadRunResponseFileSearch.php @@ -11,7 +11,7 @@ /** * @implements ResponseContract */ -final class ThreadRunResponseToolRetrieval implements ResponseContract +final class ThreadRunResponseFileSearch implements ResponseContract { /** * @use ArrayAccessible @@ -28,7 +28,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{type: 'retrieval'} $attributes + * @param array{type: 'file_search'} $attributes */ public static function from(array $attributes): self { diff --git a/src/Responses/Threads/Runs/ThreadRunResponseIncompleteDetails.php b/src/Responses/Threads/Runs/ThreadRunResponseIncompleteDetails.php new file mode 100644 index 00000000..43719326 --- /dev/null +++ b/src/Responses/Threads/Runs/ThreadRunResponseIncompleteDetails.php @@ -0,0 +1,49 @@ + + */ +final class ThreadRunResponseIncompleteDetails implements ResponseContract +{ + /** + * @use ArrayAccessible + */ + use ArrayAccessible; + + use Fakeable; + + private function __construct( + public string $reason, + ) { + } + + /** + * Acts as static factory, and returns a new Response instance. + * + * @param array{reason: string} $attributes + */ + public static function from(array $attributes): self + { + return new self( + $attributes['reason'], + ); + } + + /** + * {@inheritDoc} + */ + public function toArray(): array + { + return [ + 'reason' => $this->reason, + ]; + } +} diff --git a/src/Responses/Threads/Runs/ThreadRunResponseToolChoice.php b/src/Responses/Threads/Runs/ThreadRunResponseToolChoice.php new file mode 100644 index 00000000..608dc573 --- /dev/null +++ b/src/Responses/Threads/Runs/ThreadRunResponseToolChoice.php @@ -0,0 +1,57 @@ + + */ +final class ThreadRunResponseToolChoice implements ResponseContract +{ + /** + * @use ArrayAccessible + */ + use ArrayAccessible; + + use Fakeable; + + private function __construct( + public string $type, + public ?ThreadRunResponseToolChoiceFunction $function + ) { + } + + /** + * Acts as static factory, and returns a new Response instance. + * + * @param array{type: string, function?: array{name: string}} $attributes + */ + public static function from(array $attributes): self + { + return new self( + $attributes['type'], + empty($attributes['function']) ? null : ThreadRunResponseToolChoiceFunction::from($attributes['function']), + ); + } + + /** + * {@inheritDoc} + */ + public function toArray(): array + { + $response = [ + 'type' => $this->type, + ]; + + if ($this->function instanceof \OpenAI\Responses\Threads\Runs\ThreadRunResponseToolChoiceFunction) { + $response['function'] = $this->function->toArray(); + } + + return $response; + } +} diff --git a/src/Responses/Threads/Runs/ThreadRunResponseToolChoiceFunction.php b/src/Responses/Threads/Runs/ThreadRunResponseToolChoiceFunction.php new file mode 100644 index 00000000..8c71a8c9 --- /dev/null +++ b/src/Responses/Threads/Runs/ThreadRunResponseToolChoiceFunction.php @@ -0,0 +1,49 @@ + + */ +final class ThreadRunResponseToolChoiceFunction implements ResponseContract +{ + /** + * @use ArrayAccessible + */ + use ArrayAccessible; + + use Fakeable; + + private function __construct( + public string $name, + ) { + } + + /** + * Acts as static factory, and returns a new Response instance. + * + * @param array{name: string} $attributes + */ + public static function from(array $attributes): self + { + return new self( + $attributes['name'], + ); + } + + /** + * {@inheritDoc} + */ + public function toArray(): array + { + return [ + 'name' => $this->name, + ]; + } +} diff --git a/src/Responses/Threads/Runs/ThreadRunResponseTruncationStrategy.php b/src/Responses/Threads/Runs/ThreadRunResponseTruncationStrategy.php new file mode 100644 index 00000000..d53690d7 --- /dev/null +++ b/src/Responses/Threads/Runs/ThreadRunResponseTruncationStrategy.php @@ -0,0 +1,52 @@ + + */ +final class ThreadRunResponseTruncationStrategy implements ResponseContract +{ + /** + * @use ArrayAccessible + */ + use ArrayAccessible; + + use Fakeable; + + private function __construct( + public string $type, + public ?int $lastMessages, + ) { + } + + /** + * Acts as static factory, and returns a new Response instance. + * + * @param array{type: string, last_messages: ?int} $attributes + */ + public static function from(array $attributes): self + { + return new self( + $attributes['type'], + $attributes['last_messages'], + ); + } + + /** + * {@inheritDoc} + */ + public function toArray(): array + { + return [ + 'type' => $this->type, + 'last_messages' => $this->lastMessages, + ]; + } +} diff --git a/src/Responses/Threads/ThreadResponse.php b/src/Responses/Threads/ThreadResponse.php index f3e83929..b7f6865b 100644 --- a/src/Responses/Threads/ThreadResponse.php +++ b/src/Responses/Threads/ThreadResponse.php @@ -6,18 +6,19 @@ use OpenAI\Contracts\ResponseContract; use OpenAI\Contracts\ResponseHasMetaInformationContract; +use OpenAI\Responses\Assistants\AssistantResponseToolResources; use OpenAI\Responses\Concerns\ArrayAccessible; use OpenAI\Responses\Concerns\HasMetaInformation; use OpenAI\Responses\Meta\MetaInformation; use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}> + * @implements ResponseContract}, file_search?: array{vector_store_ids: array}}, metadata: array}> */ final class ThreadResponse implements ResponseContract, ResponseHasMetaInformationContract { /** - * @use ArrayAccessible}> + * @use ArrayAccessible}, file_search?: array{vector_store_ids: array}}, metadata: array}> */ use ArrayAccessible; @@ -31,6 +32,7 @@ private function __construct( public string $id, public string $object, public int $createdAt, + public ?AssistantResponseToolResources $toolResources, public array $metadata, private readonly MetaInformation $meta, ) { @@ -39,7 +41,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{id: string, object: string, created_at: int, metadata: array} $attributes + * @param array{id: string, object: string, created_at: int, tool_resources: ?array{code_interpreter?: array{file_ids: array}, file_search?: array{vector_store_ids: array}}, metadata: array} $attributes */ public static function from(array $attributes, MetaInformation $meta): self { @@ -47,6 +49,7 @@ public static function from(array $attributes, MetaInformation $meta): self $attributes['id'], $attributes['object'], $attributes['created_at'], + isset($attributes['tool_resources']) ? AssistantResponseToolResources::from($attributes['tool_resources']) : null, $attributes['metadata'], $meta, ); @@ -61,6 +64,7 @@ public function toArray(): array 'id' => $this->id, 'object' => $this->object, 'created_at' => $this->createdAt, + 'tool_resources' => $this->toolResources?->toArray(), 'metadata' => $this->metadata, ]; } diff --git a/src/Testing/Resources/AssistantsFilesTestResource.php b/src/Testing/Resources/AssistantsFilesTestResource.php deleted file mode 100644 index bc158e56..00000000 --- a/src/Testing/Resources/AssistantsFilesTestResource.php +++ /dev/null @@ -1,40 +0,0 @@ -record(__FUNCTION__, func_get_args()); - } - - public function retrieve(string $assistantId, string $fileId): AssistantFileResponse - { - return $this->record(__FUNCTION__, func_get_args()); - } - - public function delete(string $assistantId, string $fileId): AssistantFileDeleteResponse - { - return $this->record(__FUNCTION__, func_get_args()); - } - - public function list(string $assistantId, array $parameters = []): AssistantFileListResponse - { - return $this->record(__FUNCTION__, func_get_args()); - } -} diff --git a/src/Testing/Resources/AssistantsTestResource.php b/src/Testing/Resources/AssistantsTestResource.php index 8b4c771b..a97603b4 100644 --- a/src/Testing/Resources/AssistantsTestResource.php +++ b/src/Testing/Resources/AssistantsTestResource.php @@ -42,9 +42,4 @@ public function list(array $parameters = []): AssistantListResponse { return $this->record(__FUNCTION__, func_get_args()); } - - public function files(): AssistantsFilesTestResource - { - return new AssistantsFilesTestResource($this->fake); - } } diff --git a/src/Testing/Resources/ThreadsMessagesFilesTestResource.php b/src/Testing/Resources/ThreadsMessagesFilesTestResource.php deleted file mode 100644 index 00f651ca..00000000 --- a/src/Testing/Resources/ThreadsMessagesFilesTestResource.php +++ /dev/null @@ -1,29 +0,0 @@ -record(__FUNCTION__, func_get_args()); - } - - public function list(string $threadId, string $messageId, array $parameters = []): ThreadMessageFileListResponse - { - return $this->record(__FUNCTION__, func_get_args()); - } -} diff --git a/src/Testing/Resources/ThreadsMessagesTestResource.php b/src/Testing/Resources/ThreadsMessagesTestResource.php index 965a4240..6556ba17 100644 --- a/src/Testing/Resources/ThreadsMessagesTestResource.php +++ b/src/Testing/Resources/ThreadsMessagesTestResource.php @@ -36,9 +36,4 @@ public function list(string $threadId, array $parameters = []): ThreadMessageLis { return $this->record(__FUNCTION__, func_get_args()); } - - public function files(): ThreadsMessagesFilesTestResource - { - return new ThreadsMessagesFilesTestResource($this->fake); - } } diff --git a/src/Testing/Responses/Fixtures/Assistants/AssistantListResponseFixture.php b/src/Testing/Responses/Fixtures/Assistants/AssistantListResponseFixture.php index c5b9d68a..66b44dca 100644 --- a/src/Testing/Responses/Fixtures/Assistants/AssistantListResponseFixture.php +++ b/src/Testing/Responses/Fixtures/Assistants/AssistantListResponseFixture.php @@ -16,8 +16,11 @@ final class AssistantListResponseFixture 'model' => 'gpt-4', 'instructions' => 'You are a personal math tutor.', 'tools' => [], - 'file_ids' => [], + 'tool_resources' => [], 'metadata' => [], + 'temperature' => 0.7, + 'top_p' => 1.0, + 'response_format' => 'text', ], ], 'first_id' => 'asst_SMzoVX8XmCZEg1EbMHoAm8tc', diff --git a/src/Testing/Responses/Fixtures/Assistants/AssistantResponseFixture.php b/src/Testing/Responses/Fixtures/Assistants/AssistantResponseFixture.php index 6e5b23a8..1be20129 100644 --- a/src/Testing/Responses/Fixtures/Assistants/AssistantResponseFixture.php +++ b/src/Testing/Responses/Fixtures/Assistants/AssistantResponseFixture.php @@ -13,7 +13,10 @@ final class AssistantResponseFixture 'model' => 'gpt-4', 'instructions' => 'You are a personal math tutor.', 'tools' => [], - 'file_ids' => [], + 'tool_resources' => [], 'metadata' => [], + 'temperature' => 0.7, + 'top_p' => 1.0, + 'response_format' => 'text', ]; } diff --git a/src/Testing/Responses/Fixtures/Assistants/Files/AssistantFileDeleteResponseFixture.php b/src/Testing/Responses/Fixtures/Assistants/Files/AssistantFileDeleteResponseFixture.php deleted file mode 100644 index a19a649a..00000000 --- a/src/Testing/Responses/Fixtures/Assistants/Files/AssistantFileDeleteResponseFixture.php +++ /dev/null @@ -1,12 +0,0 @@ - 'file-6EsV79Y261TEmi0PY5iHbZdS', - 'object' => 'assistant.file.deleted', - 'deleted' => true, - ]; -} diff --git a/src/Testing/Responses/Fixtures/Assistants/Files/AssistantFileListResponseFixture.php b/src/Testing/Responses/Fixtures/Assistants/Files/AssistantFileListResponseFixture.php deleted file mode 100644 index ca580189..00000000 --- a/src/Testing/Responses/Fixtures/Assistants/Files/AssistantFileListResponseFixture.php +++ /dev/null @@ -1,21 +0,0 @@ - 'list', - 'data' => [ - [ - 'id' => 'file-6EsV79Y261TEmi0PY5iHbZdS', - 'object' => 'assistant.file', - 'created_at' => 1_699_620_898, - 'assistant_id' => 'asst_y49lAdZDiaQUxEBR6zrG846Q', - ], - ], - 'first_id' => 'file-6EsV79Y261TEmi0PY5iHbZdS', - 'last_id' => 'file-6EsV79Y261TEmi0PY5iHbZdS', - 'has_more' => false, - ]; -} diff --git a/src/Testing/Responses/Fixtures/Assistants/Files/AssistantFileResponseFixture.php b/src/Testing/Responses/Fixtures/Assistants/Files/AssistantFileResponseFixture.php deleted file mode 100644 index d922327a..00000000 --- a/src/Testing/Responses/Fixtures/Assistants/Files/AssistantFileResponseFixture.php +++ /dev/null @@ -1,13 +0,0 @@ - 'file-6EsV79Y261TEmi0PY5iHbZdS', - 'object' => 'assistant.file', - 'created_at' => 1_699_620_898, - 'assistant_id' => 'asst_y49lAdZDiaQUxEBR6zrG846Q', - ]; -} diff --git a/src/Testing/Responses/Fixtures/Threads/Messages/Files/ThreadMessageFileListResponseFixture.php b/src/Testing/Responses/Fixtures/Threads/Messages/Files/ThreadMessageFileListResponseFixture.php deleted file mode 100644 index 2a6a19c6..00000000 --- a/src/Testing/Responses/Fixtures/Threads/Messages/Files/ThreadMessageFileListResponseFixture.php +++ /dev/null @@ -1,21 +0,0 @@ - 'list', - 'data' => [ - [ - 'id' => 'file-DhxjnFCaSHc4ZELRGKwTMFtI', - 'object' => 'thread.message.file', - 'created_at' => 1_699_624_660, - 'message_id' => 'msg_KNsDDwE41BUAHhcPNpDkdHWZ', - ], - ], - 'first_id' => 'file-DhxjnFCaSHc4ZELRGKwTMFtI', - 'last_id' => 'file-DhxjnFCaSHc4ZELRGKwTMFtI', - 'has_more' => false, - ]; -} diff --git a/src/Testing/Responses/Fixtures/Threads/Messages/Files/ThreadMessageFileResponseFixture.php b/src/Testing/Responses/Fixtures/Threads/Messages/Files/ThreadMessageFileResponseFixture.php deleted file mode 100644 index f9e6e707..00000000 --- a/src/Testing/Responses/Fixtures/Threads/Messages/Files/ThreadMessageFileResponseFixture.php +++ /dev/null @@ -1,13 +0,0 @@ - 'file-DhxjnFCaSHc4ZELRGKwTMFtI', - 'object' => 'thread.message.file', - 'created_at' => 1_699_624_660, - 'message_id' => 'msg_KNsDDwE41BUAHhcPNpDkdHWZ', - ]; -} diff --git a/src/Testing/Responses/Fixtures/Threads/Messages/ThreadMessageListResponseFixture.php b/src/Testing/Responses/Fixtures/Threads/Messages/ThreadMessageListResponseFixture.php index c4137930..60243172 100644 --- a/src/Testing/Responses/Fixtures/Threads/Messages/ThreadMessageListResponseFixture.php +++ b/src/Testing/Responses/Fixtures/Threads/Messages/ThreadMessageListResponseFixture.php @@ -12,6 +12,10 @@ final class ThreadMessageListResponseFixture 'object' => 'thread.message', 'created_at' => 1_699_623_839, 'thread_id' => 'thread_agvtHUGezjTCt4SKgQg0NJ2Y', + 'status' => 'in_progress', + 'incomplete_details' => null, + 'completed_at' => null, + 'incomplete_at' => null, 'role' => 'user', 'content' => [ [ @@ -23,8 +27,11 @@ final class ThreadMessageListResponseFixture ], ], ], - 'file_ids' => [ - 'file-DhxjnFCaSHc4ZELRGKwTMFtI', + 'attachments' => [ + [ + 'file_id' => 'file-DhxjnFCaSHc4ZELRGKwTMFtI', + 'tools' => [['type' => 'file_search']], + ], ], 'assistant_id' => null, 'run_id' => null, diff --git a/src/Testing/Responses/Fixtures/Threads/Messages/ThreadMessageResponseFixture.php b/src/Testing/Responses/Fixtures/Threads/Messages/ThreadMessageResponseFixture.php index b80dc8fe..ad111fda 100644 --- a/src/Testing/Responses/Fixtures/Threads/Messages/ThreadMessageResponseFixture.php +++ b/src/Testing/Responses/Fixtures/Threads/Messages/ThreadMessageResponseFixture.php @@ -9,6 +9,10 @@ final class ThreadMessageResponseFixture 'object' => 'thread.message', 'created_at' => 1_699_623_839, 'thread_id' => 'thread_agvtHUGezjTCt4SKgQg0NJ2Y', + 'status' => 'in_progress', + 'incomplete_details' => null, + 'completed_at' => null, + 'incomplete_at' => null, 'role' => 'user', 'content' => [ [ @@ -20,8 +24,11 @@ final class ThreadMessageResponseFixture ], ], ], - 'file_ids' => [ - 'file-DhxjnFCaSHc4ZELRGKwTMFtI', + 'attachments' => [ + [ + 'file_id' => 'file-DhxjnFCaSHc4ZELRGKwTMFtI', + 'tools' => [['type' => 'file_search']], + ], ], 'assistant_id' => null, 'run_id' => null, diff --git a/src/Testing/Responses/Fixtures/Threads/Runs/Steps/ThreadRunStepListResponseFixture.php b/src/Testing/Responses/Fixtures/Threads/Runs/Steps/ThreadRunStepListResponseFixture.php index 0e71a4b8..dbb1f199 100644 --- a/src/Testing/Responses/Fixtures/Threads/Runs/Steps/ThreadRunStepListResponseFixture.php +++ b/src/Testing/Responses/Fixtures/Threads/Runs/Steps/ThreadRunStepListResponseFixture.php @@ -27,6 +27,11 @@ final class ThreadRunStepListResponseFixture 'message_id' => 'msg_i404PxKbB92d0JAmdOIcX7vA', ], ], + 'usage' => [ + 'prompt_tokens' => 123, + 'completion_tokens' => 456, + 'total_tokens' => 579, + ], ], ], 'first_id' => 'step_1spQXgbAabXFm1YXrwiGIMUz', diff --git a/src/Testing/Responses/Fixtures/Threads/Runs/Steps/ThreadRunStepResponseFixture.php b/src/Testing/Responses/Fixtures/Threads/Runs/Steps/ThreadRunStepResponseFixture.php index 1e4105ac..dfdd1485 100644 --- a/src/Testing/Responses/Fixtures/Threads/Runs/Steps/ThreadRunStepResponseFixture.php +++ b/src/Testing/Responses/Fixtures/Threads/Runs/Steps/ThreadRunStepResponseFixture.php @@ -24,5 +24,10 @@ final class ThreadRunStepResponseFixture 'message_id' => 'msg_i404PxKbB92d0JAmdOIcX7vA', ], ], + 'usage' => [ + 'prompt_tokens' => 123, + 'completion_tokens' => 456, + 'total_tokens' => 579, + ], ]; } diff --git a/src/Testing/Responses/Fixtures/Threads/Runs/ThreadRunListResponseFixture.php b/src/Testing/Responses/Fixtures/Threads/Runs/ThreadRunListResponseFixture.php index a7034caa..c1ac7ca5 100644 --- a/src/Testing/Responses/Fixtures/Threads/Runs/ThreadRunListResponseFixture.php +++ b/src/Testing/Responses/Fixtures/Threads/Runs/ThreadRunListResponseFixture.php @@ -27,10 +27,18 @@ final class ThreadRunListResponseFixture 'type' => 'code_interpreter', ], ], - 'file_ids' => [ - 'file-6EsV79Y261TEmi0PY5iHbZdS', - ], 'metadata' => [], + 'incomplete_details' => null, + 'temperature' => 1, + 'top_p' => 1, + 'max_prompt_tokens' => 600, + 'max_completion_tokens' => 500, + 'truncation_strategy' => [ + 'type' => 'auto', + 'last_messages' => null, + ], + 'tool_choice' => 'none', + 'response_format' => 'auto', ], ], 'first_id' => 'run_4RCYyYzX9m41WQicoJtUQAb8', diff --git a/src/Testing/Responses/Fixtures/Threads/Runs/ThreadRunResponseFixture.php b/src/Testing/Responses/Fixtures/Threads/Runs/ThreadRunResponseFixture.php index 276cdd1b..e2ceaeee 100644 --- a/src/Testing/Responses/Fixtures/Threads/Runs/ThreadRunResponseFixture.php +++ b/src/Testing/Responses/Fixtures/Threads/Runs/ThreadRunResponseFixture.php @@ -24,14 +24,22 @@ final class ThreadRunResponseFixture 'type' => 'code_interpreter', ], ], - 'file_ids' => [ - 'file-6EsV79Y261TEmi0PY5iHbZdS', - ], 'metadata' => [], 'usage' => [ 'prompt_tokens' => 5, 'completion_tokens' => 7, 'total_tokens' => 12, ], + 'incomplete_details' => null, + 'temperature' => 1, + 'top_p' => 1, + 'max_prompt_tokens' => 600, + 'max_completion_tokens' => 500, + 'truncation_strategy' => [ + 'type' => 'auto', + 'last_messages' => null, + ], + 'tool_choice' => 'none', + 'response_format' => 'auto', ]; } diff --git a/tests/Fixtures/Assistant.php b/tests/Fixtures/Assistant.php index b73c59d7..6d802208 100644 --- a/tests/Fixtures/Assistant.php +++ b/tests/Fixtures/Assistant.php @@ -18,15 +18,18 @@ function assistantResource(): array 'type' => 'code_interpreter', ], ], - 'file_ids' => [], + 'tool_resources' => null, 'metadata' => [], + 'temperature' => 0.7, + 'top_p' => 1.0, + 'response_format' => 'text', ]; } /** * @return array */ -function assistantWithFunctionToolResource(): array +function assistantWithJsonObjectResponseFormat(): array { return [ 'id' => 'asst_reHHtAM0jKLDIxanM6gP6DaR', @@ -60,31 +63,56 @@ function assistantWithFunctionToolResource(): array ], ], ], - 'file_ids' => [], + 'tool_resources' => [], 'metadata' => [], + 'temperature' => 0.7, + 'top_p' => 1.0, + 'response_format' => ['type' => 'json_object'], ]; } /** * @return array */ -function assistantWithRetrievalToolResource(): array +function assistantWithFunctionToolResource(): array { return [ - 'id' => 'asst_3jHvDyRbElRz2yig9RrPT9cX', + 'id' => 'asst_reHHtAM0jKLDIxanM6gP6DaR', 'object' => 'assistant', - 'created_at' => 1699642972, + 'created_at' => 1699642651, 'name' => 'Math Tutor', 'description' => null, - 'model' => 'gpt-4-1106-preview', + 'model' => 'gpt-4', 'instructions' => 'You are a personal math tutor. When asked a question, write and run Python code to answer the question.', 'tools' => [ [ - 'type' => 'retrieval', + 'type' => 'function', + 'function' => [ + 'name' => 'add', + 'description' => 'Returns the sum of two numbers', + 'parameters' => [ + 'type' => 'object', + 'properties' => [ + 'a' => [ + 'type' => 'number', + ], + 'b' => [ + 'type' => 'number', + ], + ], + 'required' => [ + 'a', + 'b', + ], + ], + ], ], ], - 'file_ids' => [], + 'tool_resources' => [], 'metadata' => [], + 'temperature' => 0.7, + 'top_p' => 1.0, + 'response_format' => 'text', ]; } @@ -106,7 +134,7 @@ function assistantWithAllToolsResource(): array 'type' => 'code_interpreter', ], [ - 'type' => 'retrieval', + 'type' => 'file_search', ], [ 'type' => 'function', @@ -131,8 +159,44 @@ function assistantWithAllToolsResource(): array ], ], ], - 'file_ids' => [], + 'tool_resources' => [], + 'metadata' => [], + 'temperature' => 0.7, + 'top_p' => 1.0, + 'response_format' => 'text', + ]; +} + +/** + * @return array + */ +function assistantWithToolResources(): array +{ + return [ + 'id' => 'asst_SMzoVX8XmCZEg1EbMHoAm8tc', + 'object' => 'assistant', + 'created_at' => 1699619403, + 'name' => 'Math Tutor', + 'description' => null, + 'model' => 'gpt-4', + 'instructions' => 'You are a personal math tutor.', + 'tools' => [ + [ + 'type' => 'file_search', + ], + ], + 'tool_resources' => [ + 'code_interpreter' => [ + 'file_ids' => ['file-test0001'], + ], + 'file_search' => [ + 'vector_store_ids' => ['vector-store-test0001'], + ], + ], 'metadata' => [], + 'temperature' => 0.7, + 'top_p' => 1.0, + 'response_format' => 'text', ]; } diff --git a/tests/Fixtures/AssistantFile.php b/tests/Fixtures/AssistantFile.php deleted file mode 100644 index 8c5a19fb..00000000 --- a/tests/Fixtures/AssistantFile.php +++ /dev/null @@ -1,43 +0,0 @@ - - */ -function assistantFileResource(): array -{ - return [ - 'id' => 'file-6EsV79Y261TEmi0PY5iHbZdS', - 'object' => 'assistant.file', - 'created_at' => 1699620898, - 'assistant_id' => 'asst_y49lAdZDiaQUxEBR6zrG846Q', - ]; -} - -/** - * @return array - */ -function assistantFileListResource(): array -{ - return [ - 'object' => 'list', - 'data' => [ - assistantFileResource(), - assistantFileResource(), - ], - 'first_id' => 'file-6EsV79Y261TEmi0PY5iHbZdS', - 'last_id' => 'file-6EsV79Y261TEmi0PY5iHbZdS', - 'has_more' => false, - ]; -} - -/** - * @return array - */ -function assistantFileDeleteResource(): array -{ - return [ - 'id' => 'file-6EsV79Y261TEmi0PY5iHbZdS', - 'object' => 'assistant.file.deleted', - 'deleted' => true, - ]; -} diff --git a/tests/Fixtures/Thread.php b/tests/Fixtures/Thread.php index e3e4cd65..3ba60f01 100644 --- a/tests/Fixtures/Thread.php +++ b/tests/Fixtures/Thread.php @@ -9,6 +9,7 @@ function threadResource(): array 'id' => 'thread_agvtHUGezjTCt4SKgQg0NJ2Y', 'object' => 'thread', 'created_at' => 1699621778, + 'tool_resources' => [], 'metadata' => [], ]; } diff --git a/tests/Fixtures/ThreadMessage.php b/tests/Fixtures/ThreadMessage.php index 7e18006c..92dc676c 100644 --- a/tests/Fixtures/ThreadMessage.php +++ b/tests/Fixtures/ThreadMessage.php @@ -10,6 +10,10 @@ function threadMessageResource(): array 'object' => 'thread.message', 'created_at' => 1699623839, 'thread_id' => 'thread_agvtHUGezjTCt4SKgQg0NJ2Y', + 'status' => 'in_progress', + 'incomplete_details' => null, + 'completed_at' => null, + 'incomplete_at' => null, 'role' => 'user', 'content' => [ [ @@ -45,9 +49,19 @@ function threadMessageResource(): array 'file_id' => 'file-DhxjnFCaSHc4ZELRGKwTMFtI', ], ], + [ + 'type' => 'image_url', + 'image_url' => [ + 'file_id' => 'file-VKxjnFCaSHc4ZELRGKwTMFtI', + 'detail' => 'high', + ], + ], ], - 'file_ids' => [ - 'file-DhxjnFCaSHc4ZELRGKwTMFtI', + 'attachments' => [ + [ + 'file_id' => 'file-DhxjnFCaSHc4ZELRGKwTMFtI', + 'tools' => [['type' => 'file_search'], ['type' => 'code_interpreter']], + ], ], 'assistant_id' => null, 'run_id' => null, diff --git a/tests/Fixtures/ThreadMessageFile.php b/tests/Fixtures/ThreadMessageFile.php deleted file mode 100644 index 8a0283e0..00000000 --- a/tests/Fixtures/ThreadMessageFile.php +++ /dev/null @@ -1,31 +0,0 @@ - - */ -function threadMessageFileResource(): array -{ - return [ - 'id' => 'file-DhxjnFCaSHc4ZELRGKwTMFtI', - 'object' => 'thread.message.file', - 'created_at' => 1699624660, - 'message_id' => 'msg_KNsDDwE41BUAHhcPNpDkdHWZ', - ]; -} - -/** - * @return array - */ -function threadMessageFileListResource(): array -{ - return [ - 'object' => 'list', - 'data' => [ - threadMessageFileResource(), - threadMessageFileResource(), - ], - 'first_id' => 'file-DhxjnFCaSHc4ZELRGKwTMFtI', - 'last_id' => 'file-DhxjnFCaSHc4ZELRGKwTMFtI', - 'has_more' => false, - ]; -} diff --git a/tests/Fixtures/ThreadRun.php b/tests/Fixtures/ThreadRun.php index 3137f04e..8559cf45 100644 --- a/tests/Fixtures/ThreadRun.php +++ b/tests/Fixtures/ThreadRun.php @@ -17,6 +17,7 @@ function threadRunResource(): array 'cancelled_at' => null, 'failed_at' => null, 'completed_at' => null, + 'incomplete_details' => null, 'last_error' => null, 'model' => 'gpt-4', 'instructions' => 'You are a personal math tutor. When asked a question, write and run Python code to answer the question.', @@ -25,10 +26,17 @@ function threadRunResource(): array 'type' => 'code_interpreter', ], ], - 'file_ids' => [ - 'file-6EsV79Y261TEmi0PY5iHbZdS', - ], 'metadata' => [], + 'temperature' => 1.0, + 'top_p' => 1.0, + 'max_prompt_tokens' => 600, + 'max_completion_tokens' => 500, + 'truncation_strategy' => [ + 'type' => 'auto', + 'last_messages' => null, + ], + 'tool_choice' => 'none', + 'response_format' => 'auto', ]; } @@ -54,13 +62,66 @@ function threadRunWithRetrievalToolResource(): array 'instructions' => 'You are a personal math tutor. When asked a question, write and run Python code to answer the question.', 'tools' => [ [ - 'type' => 'retrieval', + 'type' => 'file_search', ], ], - 'file_ids' => [ - 'file-6EsV79Y261TEmi0PY5iHbZdS', + 'metadata' => [], + 'incomplete_details' => null, + 'temperature' => 1, + 'top_p' => 1, + 'max_prompt_tokens' => 600, + 'max_completion_tokens' => 500, + 'truncation_strategy' => [ + 'type' => 'auto', + 'last_messages' => null, + ], + 'tool_choice' => 'none', + 'response_format' => 'auto', + ]; +} + +/** + * @return array + */ +function threadRunWithToolChoiceFunction(): array +{ + return [ + 'id' => 'run_4RCYyYzX9m41WQicoJtUQAb8', + 'object' => 'thread.run', + 'created_at' => 1699621735, + 'assistant_id' => 'asst_EopvUEMh90bxkNRYEYM81Orc', + 'thread_id' => 'thread_EKt7MjGOC6bwKWmenQv5VD6r', + 'status' => 'queued', + 'started_at' => null, + 'expires_at' => 1699622335, + 'cancelled_at' => null, + 'failed_at' => null, + 'completed_at' => null, + 'last_error' => null, + 'model' => 'gpt-4', + 'instructions' => 'You are a personal math tutor. When asked a question, write and run Python code to answer the question.', + 'tools' => [ + [ + 'type' => 'file_search', + ], ], 'metadata' => [], + 'incomplete_details' => null, + 'temperature' => 1, + 'top_p' => 1, + 'max_prompt_tokens' => 600, + 'max_completion_tokens' => 500, + 'truncation_strategy' => [ + 'type' => 'auto', + 'last_messages' => null, + ], + 'tool_choice' => [ + 'type' => 'function', + 'function' => [ + 'name' => 'calculate_sum', + ], + ], + 'response_format' => 'auto', ]; } @@ -92,10 +153,18 @@ function threadRunWithLasErrorResource(): array 'type' => 'code_interpreter', ], ], - 'file_ids' => [ - 'file-6EsV79Y261TEmi0PY5iHbZdS', - ], 'metadata' => [], + 'incomplete_details' => null, + 'temperature' => 1, + 'top_p' => 1, + 'max_prompt_tokens' => 600, + 'max_completion_tokens' => 500, + 'truncation_strategy' => [ + 'type' => 'auto', + 'last_messages' => null, + ], + 'tool_choice' => 'none', + 'response_format' => 'auto', ]; } @@ -116,6 +185,7 @@ function threadRunWithSubmitToolOutputsResource(): array 'cancelled_at' => null, 'failed_at' => null, 'completed_at' => null, + 'incomplete_details' => null, 'required_action' => [ 'type' => 'submit_tool_outputs', 'submit_tool_outputs' => [ @@ -158,11 +228,22 @@ function threadRunWithSubmitToolOutputsResource(): array ], ], [ - 'type' => 'retrieval', + 'type' => 'file_search', ], ], - 'file_ids' => [], 'metadata' => [], + 'temperature' => 1.0, + 'top_p' => 1.0, + 'max_prompt_tokens' => 600, + 'max_completion_tokens' => 500, + 'truncation_strategy' => [ + 'type' => 'auto', + 'last_messages' => null, + ], + 'tool_choice' => 'none', + 'response_format' => [ + 'type' => 'json_object', + ], ]; } @@ -183,6 +264,7 @@ function threadRunWithUsageResource(): array 'cancelled_at' => null, 'failed_at' => null, 'completed_at' => null, + 'incomplete_details' => null, 'last_error' => null, 'model' => 'gpt-4', 'instructions' => 'You are a personal math tutor. When asked a question, write and run Python code to answer the question.', @@ -191,8 +273,49 @@ function threadRunWithUsageResource(): array 'type' => 'code_interpreter', ], ], - 'file_ids' => [ - 'file-6EsV79Y261TEmi0PY5iHbZdS', + 'metadata' => [], + 'usage' => [ + 'prompt_tokens' => 1, + 'completion_tokens' => 16, + 'total_tokens' => 17, + ], + 'temperature' => 1.0, + 'top_p' => 1.0, + 'max_prompt_tokens' => 600, + 'max_completion_tokens' => 500, + 'truncation_strategy' => [ + 'type' => 'auto', + 'last_messages' => null, + ], + 'tool_choice' => 'none', + 'response_format' => 'auto', + ]; +} + +/** + * @return array + */ +function threadRunWithIncompleteDetails(): array +{ + return [ + 'id' => 'run_4RCYyYzX9m41WQicoJtUQAb8', + 'object' => 'thread.run', + 'created_at' => 1699621735, + 'assistant_id' => 'asst_EopvUEMh90bxkNRYEYM81Orc', + 'thread_id' => 'thread_EKt7MjGOC6bwKWmenQv5VD6r', + 'status' => 'incomplete', + 'started_at' => null, + 'expires_at' => 1699622335, + 'cancelled_at' => null, + 'failed_at' => null, + 'completed_at' => null, + 'last_error' => null, + 'model' => 'gpt-4', + 'instructions' => 'You are a personal math tutor. When asked a question, write and run Python code to answer the question.', + 'tools' => [ + [ + 'type' => 'code_interpreter', + ], ], 'metadata' => [], 'usage' => [ @@ -200,6 +323,19 @@ function threadRunWithUsageResource(): array 'completion_tokens' => 16, 'total_tokens' => 17, ], + 'incomplete_details' => [ + 'reason' => 'Input tokens exceeded', + ], + 'temperature' => 1, + 'top_p' => 1, + 'max_prompt_tokens' => 600, + 'max_completion_tokens' => 500, + 'truncation_strategy' => [ + 'type' => 'auto', + 'last_messages' => null, + ], + 'tool_choice' => 'none', + 'response_format' => 'auto', ]; } diff --git a/tests/Fixtures/ThreadRunSteps.php b/tests/Fixtures/ThreadRunSteps.php index 73c28206..10043540 100644 --- a/tests/Fixtures/ThreadRunSteps.php +++ b/tests/Fixtures/ThreadRunSteps.php @@ -25,6 +25,11 @@ function threadRunStepResource(): array 'message_id' => 'msg_i404PxKbB92d0JAmdOIcX7vA', ], ], + 'usage' => [ + 'prompt_tokens' => 123, + 'completion_tokens' => 456, + 'total_tokens' => 579, + ], ]; } @@ -80,12 +85,17 @@ function threadRunStepWithCodeInterpreterOutputResource(): array ], [ 'id' => 'call_mNs14X7kZF2WDzlPhpQ163Co', - 'type' => 'retrieval', - 'retrieval' => [], + 'type' => 'file_search', + 'file_search' => [], ], ], ], 'metadata' => ['name' => 'the step name'], + 'usage' => [ + 'prompt_tokens' => 123, + 'completion_tokens' => 456, + 'total_tokens' => 579, + ], ]; } @@ -122,6 +132,11 @@ function threadRunStepWithFunctionCallPendingOutputResource(): array ], ], 'metadata' => ['name' => 'the step name'], + 'usage' => [ + 'prompt_tokens' => 123, + 'completion_tokens' => 456, + 'total_tokens' => 579, + ], ]; } diff --git a/tests/Resources/Assistants.php b/tests/Resources/Assistants.php index b17f01ed..a4cd78d8 100644 --- a/tests/Resources/Assistants.php +++ b/tests/Resources/Assistants.php @@ -51,8 +51,11 @@ ->instructions->toBe('You are a personal math tutor.') ->tools->toBeArray()->toHaveCount(1) ->tools->each->toBeInstanceOf(AssistantResponseToolCodeInterpreter::class) - ->fileIds->toBeArray()->toBeEmpty() - ->metadata->toBeArray()->toBeEmpty(); + ->toolResources->toBeNull() + ->metadata->toBeArray()->toBeEmpty() + ->temperature->toBe(0.7) + ->topP->toBe(1.0) + ->responseFormat->toBe('text'); expect($result->meta()) ->toBeInstanceOf(MetaInformation::class); @@ -78,8 +81,11 @@ ->instructions->toBe('You are a personal math tutor.') ->tools->toBeArray()->toHaveCount(1) ->tools->each->toBeInstanceOf(AssistantResponseToolCodeInterpreter::class) - ->fileIds->toBeArray()->toBeEmpty() - ->metadata->toBeArray()->toBeEmpty(); + ->toolResources->toBeNull() + ->metadata->toBeArray()->toBeEmpty() + ->temperature->toBe(0.7) + ->topP->toBe(1.0) + ->responseFormat->toBe('text'); expect($result->meta()) ->toBeInstanceOf(MetaInformation::class); @@ -101,8 +107,11 @@ ->instructions->toBe('You are a personal math tutor.') ->tools->toBeArray()->toHaveCount(1) ->tools->each->toBeInstanceOf(AssistantResponseToolCodeInterpreter::class) - ->fileIds->toBeArray()->toBeEmpty() - ->metadata->toBeArray()->toBeEmpty(); + ->toolResources->toBeNull() + ->metadata->toBeArray()->toBeEmpty() + ->temperature->toBe(0.7) + ->topP->toBe(1.0) + ->responseFormat->toBe('text'); expect($result->meta()) ->toBeInstanceOf(MetaInformation::class); diff --git a/tests/Resources/AssistantsFiles.php b/tests/Resources/AssistantsFiles.php deleted file mode 100644 index 4569850a..00000000 --- a/tests/Resources/AssistantsFiles.php +++ /dev/null @@ -1,76 +0,0 @@ -assistants()->files()->list('asst_SMzoVX8XmCZEg1EbMHoAm8tc'); - - expect($result) - ->toBeInstanceOf(AssistantFileListResponse::class) - ->object->toBe('list') - ->data->toBeArray()->toHaveCount(2) - ->data->each->toBeInstanceOf(AssistantFileResponse::class) - ->firstId->toBe('file-6EsV79Y261TEmi0PY5iHbZdS') - ->lastId->toBe('file-6EsV79Y261TEmi0PY5iHbZdS') - ->hasMore->toBeFalse(); - - expect($result->meta()) - ->toBeInstanceOf(MetaInformation::class); -}); - -test('create', function () { - $client = mockClient('POST', 'assistants/asst_SMzoVX8XmCZEg1EbMHoAm8tc/files', [ - 'file_id' => 'file-6EsV79Y261TEmi0PY5iHbZdS', - ], Response::from(assistantFileResource(), metaHeaders())); - - $result = $client->assistants()->files()->create('asst_SMzoVX8XmCZEg1EbMHoAm8tc', [ - 'file_id' => 'file-6EsV79Y261TEmi0PY5iHbZdS', - ]); - - expect($result) - ->toBeInstanceOf(AssistantFileResponse::class) - ->id->toBe('file-6EsV79Y261TEmi0PY5iHbZdS') - ->object->toBe('assistant.file') - ->createdAt->toBe(1699620898) - ->assistantId->toBe('asst_y49lAdZDiaQUxEBR6zrG846Q'); - - expect($result->meta()) - ->toBeInstanceOf(MetaInformation::class); -}); - -test('retrieve', function () { - $client = mockClient('GET', 'assistants/asst_SMzoVX8XmCZEg1EbMHoAm8tc/files/file-6EsV79Y261TEmi0PY5iHbZdS', [], Response::from(assistantFileResource(), metaHeaders())); - - $result = $client->assistants()->files()->retrieve('asst_SMzoVX8XmCZEg1EbMHoAm8tc', 'file-6EsV79Y261TEmi0PY5iHbZdS'); - - expect($result) - ->toBeInstanceOf(AssistantFileResponse::class) - ->id->toBe('file-6EsV79Y261TEmi0PY5iHbZdS') - ->object->toBe('assistant.file') - ->createdAt->toBe(1699620898) - ->assistantId->toBe('asst_y49lAdZDiaQUxEBR6zrG846Q'); - - expect($result->meta()) - ->toBeInstanceOf(MetaInformation::class); -}); - -test('delete', function () { - $client = mockClient('DELETE', 'assistants/asst_SMzoVX8XmCZEg1EbMHoAm8tc/files/file-6EsV79Y261TEmi0PY5iHbZdS', [], Response::from(assistantFileDeleteResource(), metaHeaders())); - - $result = $client->assistants()->files()->delete('asst_SMzoVX8XmCZEg1EbMHoAm8tc', 'file-6EsV79Y261TEmi0PY5iHbZdS'); - - expect($result) - ->toBeInstanceOf(AssistantFileDeleteResponse::class) - ->id->toBe('file-6EsV79Y261TEmi0PY5iHbZdS') - ->object->toBe('assistant.file.deleted') - ->deleted->toBeTrue(); - - expect($result->meta()) - ->toBeInstanceOf(MetaInformation::class); -}); diff --git a/tests/Resources/Threads.php b/tests/Resources/Threads.php index 70b63c04..c1ddedca 100644 --- a/tests/Resources/Threads.php +++ b/tests/Resources/Threads.php @@ -67,7 +67,6 @@ ->instructions->toBe('You are a personal math tutor. When asked a question, write and run Python code to answer the question.') ->tools->toBeArray()->toHaveCount(1) ->tools->each->toBeInstanceOf(ThreadRunResponseToolCodeInterpreter::class) - ->fileIds->toBeArray()->toHaveCount(1) ->metadata->toBeArray()->toBeEmpty(); expect($result->meta()) diff --git a/tests/Resources/ThreadsMessages.php b/tests/Resources/ThreadsMessages.php index a328aa5d..924fdd80 100644 --- a/tests/Resources/ThreadsMessages.php +++ b/tests/Resources/ThreadsMessages.php @@ -3,6 +3,7 @@ use OpenAI\Responses\Meta\MetaInformation; use OpenAI\Responses\Threads\Messages\ThreadMessageListResponse; use OpenAI\Responses\Threads\Messages\ThreadMessageResponse; +use OpenAI\Responses\Threads\Messages\ThreadMessageResponseAttachment; use OpenAI\Responses\Threads\Messages\ThreadMessageResponseContentImageFileObject; use OpenAI\Responses\Threads\Messages\ThreadMessageResponseContentTextObject; use OpenAI\ValueObjects\Transporter\Response; @@ -29,16 +30,22 @@ $client = mockClient('POST', 'threads/thread_agvtHUGezjTCt4SKgQg0NJ2Y/messages', [ 'role' => 'user', 'content' => 'How does AI work? Explain it in simple terms.', - 'file_ids' => [ - 'file-DhxjnFCaSHc4ZELRGKwTMFtI', + 'attachments' => [ + [ + 'file_id' => 'file-DhxjnFCaSHc4ZELRGKwTMFtI', + 'tools' => [['type' => 'file_search']], + ], ], ], Response::from(threadMessageResource(), metaHeaders())); $result = $client->threads()->messages()->create('thread_agvtHUGezjTCt4SKgQg0NJ2Y', [ 'role' => 'user', 'content' => 'How does AI work? Explain it in simple terms.', - 'file_ids' => [ - 'file-DhxjnFCaSHc4ZELRGKwTMFtI', + 'attachments' => [ + [ + 'file_id' => 'file-DhxjnFCaSHc4ZELRGKwTMFtI', + 'tools' => [['type' => 'file_search']], + ], ], ]); @@ -50,11 +57,11 @@ ->threadId->toBe('thread_agvtHUGezjTCt4SKgQg0NJ2Y') ->role->toBe('user') ->content->toBeArray() - ->content->toHaveCount(2) + ->content->toHaveCount(3) ->content->{0}->toBeInstanceOf(ThreadMessageResponseContentTextObject::class) ->content->{1}->toBeInstanceOf(ThreadMessageResponseContentImageFileObject::class) - ->fileIds->toBeArray() - ->fileIds->toBe(['file-DhxjnFCaSHc4ZELRGKwTMFtI']) + ->attachments->toBeArray() + ->attachments->{0}->toBeInstanceOf(ThreadMessageResponseAttachment::class) ->assistantId->toBeNull() ->runId->toBeNull() ->metadata->toBeArray() @@ -85,11 +92,11 @@ ->threadId->toBe('thread_agvtHUGezjTCt4SKgQg0NJ2Y') ->role->toBe('user') ->content->toBeArray() - ->content->toHaveCount(2) + ->content->toHaveCount(3) ->content->{0}->toBeInstanceOf(ThreadMessageResponseContentTextObject::class) ->content->{1}->toBeInstanceOf(ThreadMessageResponseContentImageFileObject::class) - ->fileIds->toBeArray() - ->fileIds->toBe(['file-DhxjnFCaSHc4ZELRGKwTMFtI']) + ->attachments->toBeArray() + ->attachments->{0}->toBeInstanceOf(ThreadMessageResponseAttachment::class) ->assistantId->toBeNull() ->runId->toBeNull() ->metadata->toBeArray() @@ -112,11 +119,11 @@ ->threadId->toBe('thread_agvtHUGezjTCt4SKgQg0NJ2Y') ->role->toBe('user') ->content->toBeArray() - ->content->toHaveCount(2) + ->content->toHaveCount(3) ->content->{0}->toBeInstanceOf(ThreadMessageResponseContentTextObject::class) ->content->{1}->toBeInstanceOf(ThreadMessageResponseContentImageFileObject::class) - ->fileIds->toBeArray() - ->fileIds->toBe(['file-DhxjnFCaSHc4ZELRGKwTMFtI']) + ->attachments->toBeArray() + ->attachments->{0}->toBeInstanceOf(ThreadMessageResponseAttachment::class) ->assistantId->toBeNull() ->runId->toBeNull() ->metadata->toBeArray() diff --git a/tests/Resources/ThreadsMessagesFiles.php b/tests/Resources/ThreadsMessagesFiles.php deleted file mode 100644 index bb8692f2..00000000 --- a/tests/Resources/ThreadsMessagesFiles.php +++ /dev/null @@ -1,40 +0,0 @@ -threads()->messages()->files()->list('thread_agvtHUGezjTCt4SKgQg0NJ2Y', 'msg_KNsDDwE41BUAHhcPNpDkdHWZ'); - - expect($result) - ->toBeInstanceOf(ThreadMessageFileListResponse::class) - ->object->toBe('list') - ->data->toBeArray()->toHaveCount(2) - ->data->each->toBeInstanceOf(ThreadMessageFileResponse::class) - ->firstId->toBe('file-DhxjnFCaSHc4ZELRGKwTMFtI') - ->lastId->toBe('file-DhxjnFCaSHc4ZELRGKwTMFtI') - ->hasMore->toBeFalse(); - - expect($result->meta()) - ->toBeInstanceOf(MetaInformation::class); -}); - -test('retrieve', function () { - $client = mockClient('GET', 'threads/thread_agvtHUGezjTCt4SKgQg0NJ2Y/messages/msg_KNsDDwE41BUAHhcPNpDkdHWZ/files/file-DhxjnFCaSHc4ZELRGKwTMFtI', [], Response::from(threadMessageFileResource(), metaHeaders())); - - $result = $client->threads()->messages()->files()->retrieve('thread_agvtHUGezjTCt4SKgQg0NJ2Y', 'msg_KNsDDwE41BUAHhcPNpDkdHWZ', 'file-DhxjnFCaSHc4ZELRGKwTMFtI'); - - expect($result) - ->toBeInstanceOf(ThreadMessageFileResponse::class) - ->id->toBe('file-DhxjnFCaSHc4ZELRGKwTMFtI') - ->object->toBe('thread.message.file') - ->createdAt->toBe(1699624660) - ->messageId->toBe('msg_KNsDDwE41BUAHhcPNpDkdHWZ'); - - expect($result->meta()) - ->toBeInstanceOf(MetaInformation::class); -}); diff --git a/tests/Resources/ThreadsRuns.php b/tests/Resources/ThreadsRuns.php index 2c238fb0..6294040a 100644 --- a/tests/Resources/ThreadsRuns.php +++ b/tests/Resources/ThreadsRuns.php @@ -51,7 +51,6 @@ ->instructions->toBe('You are a personal math tutor. When asked a question, write and run Python code to answer the question.') ->tools->toBeArray()->toHaveCount(1) ->tools->each->toBeInstanceOf(ThreadRunResponseToolCodeInterpreter::class) - ->fileIds->toBeArray()->toHaveCount(1) ->metadata->toBeArray()->toBeEmpty(); expect($result->meta()) @@ -89,7 +88,6 @@ ->instructions->toBe('You are a personal math tutor. When asked a question, write and run Python code to answer the question.') ->tools->toBeArray()->toHaveCount(1) ->tools->each->toBeInstanceOf(ThreadRunResponseToolCodeInterpreter::class) - ->fileIds->toBeArray()->toHaveCount(1) ->metadata->toBeArray()->toBeEmpty(); expect($result->meta()) @@ -119,7 +117,6 @@ ->instructions->toBe('You are a personal math tutor. When asked a question, write and run Python code to answer the question.') ->tools->toBeArray()->toHaveCount(1) ->tools->each->toBeInstanceOf(ThreadRunResponseToolCodeInterpreter::class) - ->fileIds->toBeArray()->toHaveCount(1) ->metadata->toBeArray()->toBeEmpty(); expect($result->meta()) @@ -149,7 +146,6 @@ ->instructions->toBe('You are a personal math tutor. When asked a question, write and run Python code to answer the question.') ->tools->toBeArray()->toHaveCount(1) ->tools->each->toBeInstanceOf(ThreadRunResponseToolCodeInterpreter::class) - ->fileIds->toBeArray()->toHaveCount(1) ->metadata->toBeArray()->toBeEmpty(); expect($result->meta()) @@ -193,7 +189,6 @@ ->instructions->toBe('You are a personal math tutor. When asked a question, write and run Python code to answer the question.') ->tools->toBeArray()->toHaveCount(1) ->tools->each->toBeInstanceOf(ThreadRunResponseToolCodeInterpreter::class) - ->fileIds->toBeArray()->toHaveCount(1) ->metadata->toBeArray()->toBeEmpty(); expect($result->meta()) diff --git a/tests/Responses/Assistants/AssistantResponse.php b/tests/Responses/Assistants/AssistantResponse.php index 59769714..f5ead5ee 100644 --- a/tests/Responses/Assistants/AssistantResponse.php +++ b/tests/Responses/Assistants/AssistantResponse.php @@ -1,7 +1,10 @@ instructions->toBe('You are a personal math tutor.') ->tools->toBeArray() ->tools->{0}->toBeInstanceOf(AssistantResponseToolCodeInterpreter::class) - ->fileIds->toBeArray() + ->toolResources->toBeInstanceOf(AssistantResponseToolResources::class) ->metadata->toBeArray() - ->meta()->toBeInstanceOf(MetaInformation::class); + ->meta()->toBeInstanceOf(MetaInformation::class) + ->temperature->toBe(0.7) + ->topP->toBe(1.0) + ->responseFormat->toBe('text'); +}); + +test('with file search', function () { + $result = AssistantResponse::from(assistantWithToolResources(), meta()); + + expect($result) + ->id->toBe('asst_SMzoVX8XmCZEg1EbMHoAm8tc') + ->object->toBe('assistant') + ->createdAt->toBe(1699619403) + ->name->toBe('Math Tutor') + ->description->toBeNull() + ->model->toBe('gpt-4') + ->instructions->toBe('You are a personal math tutor.') + ->tools->toBeArray() + ->tools->{0}->toBeInstanceOf(AssistantResponseToolFileSearch::class) + ->toolResources->toBeInstanceOf(AssistantResponseToolResources::class) + ->metadata->toBeArray() + ->meta()->toBeInstanceOf(MetaInformation::class) + ->temperature->toBe(0.7) + ->topP->toBe(1.0) + ->responseFormat->toBe('text'); +}); + +test('with code interpreter', function () { + $result = AssistantResponse::from(assistantWithToolResources(), meta()); + + expect($result) + ->id->toBe('asst_SMzoVX8XmCZEg1EbMHoAm8tc') + ->object->toBe('assistant') + ->createdAt->toBe(1699619403) + ->name->toBe('Math Tutor') + ->description->toBeNull() + ->model->toBe('gpt-4') + ->instructions->toBe('You are a personal math tutor.') + ->tools->toBeArray() + ->tools->{0}->toBeInstanceOf(AssistantResponseToolFileSearch::class) + ->toolResources->toBeInstanceOf(AssistantResponseToolResources::class) + ->metadata->toBeArray() + ->meta()->toBeInstanceOf(MetaInformation::class) + ->temperature->toBe(0.7) + ->topP->toBe(1.0) + ->responseFormat->toBe('text'); +}); + +test('with json object response format', function () { + $result = AssistantResponse::from(assistantWithJsonObjectResponseFormat(), meta()); + + expect($result) + ->responseFormat->toBeInstanceOf(AssistantResponseResponseFormat::class); }); test('as array accessible', function () { diff --git a/tests/Responses/Assistants/AssistantResponseResponseFormat.php b/tests/Responses/Assistants/AssistantResponseResponseFormat.php new file mode 100644 index 00000000..0e27cb62 --- /dev/null +++ b/tests/Responses/Assistants/AssistantResponseResponseFormat.php @@ -0,0 +1,24 @@ +type->toBe('json_object'); +}); + +test('as array accessible', function () { + $result = AssistantResponseResponseFormat::from(assistantWithJsonObjectResponseFormat()['response_format']); + + expect($result['type']) + ->toBe('json_object'); +}); + +test('to array', function () { + $result = AssistantResponseResponseFormat::from(assistantWithJsonObjectResponseFormat()['response_format']); + + expect($result->toArray()) + ->toBe(assistantWithJsonObjectResponseFormat()['response_format']); +}); diff --git a/tests/Responses/Assistants/AssistantResponseToolFileSearch.php b/tests/Responses/Assistants/AssistantResponseToolFileSearch.php new file mode 100644 index 00000000..e3fbcf50 --- /dev/null +++ b/tests/Responses/Assistants/AssistantResponseToolFileSearch.php @@ -0,0 +1,24 @@ +type->toBe('file_search'); +}); + +test('as array accessible', function () { + $result = AssistantResponseToolFileSearch::from(assistantWithToolResources()['tools'][0]); + + expect($result['type']) + ->toBe('file_search'); +}); + +test('to array', function () { + $result = AssistantResponseToolFileSearch::from(assistantWithToolResources()['tools'][0]); + + expect($result->toArray()) + ->toBe(assistantWithToolResources()['tools'][0]); +}); diff --git a/tests/Responses/Assistants/AssistantResponseToolResourceCodeInterpreter.php b/tests/Responses/Assistants/AssistantResponseToolResourceCodeInterpreter.php new file mode 100644 index 00000000..8fac6803 --- /dev/null +++ b/tests/Responses/Assistants/AssistantResponseToolResourceCodeInterpreter.php @@ -0,0 +1,24 @@ +fileIds->toBeArray()->toHaveLength(1); +}); + +test('as array accessible', function () { + $result = AssistantResponseToolResourceCodeInterpreter::from(assistantWithToolResources()['tool_resources']['code_interpreter']); + + expect($result['file_ids']) + ->toBeArray()->toHaveLength(1); +}); + +test('to array', function () { + $result = AssistantResponseToolResourceCodeInterpreter::from(assistantWithToolResources()['tool_resources']['code_interpreter']); + + expect($result->toArray()) + ->toBe(assistantWithToolResources()['tool_resources']['code_interpreter']); +}); diff --git a/tests/Responses/Assistants/AssistantResponseToolResourceFileSearch.php b/tests/Responses/Assistants/AssistantResponseToolResourceFileSearch.php new file mode 100644 index 00000000..1e96b9c4 --- /dev/null +++ b/tests/Responses/Assistants/AssistantResponseToolResourceFileSearch.php @@ -0,0 +1,24 @@ +vectorStoreIds->toBeArray()->toHaveLength(1); +}); + +test('as array accessible', function () { + $result = AssistantResponseToolResourceFileSearch::from(assistantWithToolResources()['tool_resources']['file_search']); + + expect($result['vector_store_ids']) + ->toBeArray()->toHaveLength(1); +}); + +test('to array', function () { + $result = AssistantResponseToolResourceFileSearch::from(assistantWithToolResources()['tool_resources']['file_search']); + + expect($result->toArray()) + ->toBe(assistantWithToolResources()['tool_resources']['file_search']); +}); diff --git a/tests/Responses/Assistants/AssistantResponseToolRetrieval.php b/tests/Responses/Assistants/AssistantResponseToolRetrieval.php deleted file mode 100644 index 12351969..00000000 --- a/tests/Responses/Assistants/AssistantResponseToolRetrieval.php +++ /dev/null @@ -1,24 +0,0 @@ -type->toBe('retrieval'); -}); - -test('as array accessible', function () { - $result = AssistantResponseToolRetrieval::from(assistantWithRetrievalToolResource()['tools'][0]); - - expect($result['type']) - ->toBe('retrieval'); -}); - -test('to array', function () { - $result = AssistantResponseToolRetrieval::from(assistantWithRetrievalToolResource()['tools'][0]); - - expect($result->toArray()) - ->toBe(assistantWithRetrievalToolResource()['tools'][0]); -}); diff --git a/tests/Responses/Assistants/Files/AssistantFileDeleteResponse.php b/tests/Responses/Assistants/Files/AssistantFileDeleteResponse.php deleted file mode 100644 index 2600ac6d..00000000 --- a/tests/Responses/Assistants/Files/AssistantFileDeleteResponse.php +++ /dev/null @@ -1,47 +0,0 @@ -id->toBe('file-6EsV79Y261TEmi0PY5iHbZdS') - ->object->toBe('assistant.file.deleted') - ->deleted->toBe(true) - ->meta()->toBeInstanceOf(MetaInformation::class); -}); - -test('as array accessible', function () { - $result = AssistantFileDeleteResponse::from(assistantFileDeleteResource(), meta()); - - expect($result['id']) - ->toBe('file-6EsV79Y261TEmi0PY5iHbZdS'); -}); - -test('to array', function () { - $result = AssistantFileDeleteResponse::from(assistantFileDeleteResource(), meta()); - - expect($result->toArray()) - ->toBe(assistantFileDeleteResource()); -}); - -test('fake', function () { - $response = AssistantFileDeleteResponse::fake(); - - expect($response) - ->id->toBe('file-6EsV79Y261TEmi0PY5iHbZdS') - ->deleted->toBe(true); -}); - -test('fake with override', function () { - $response = AssistantFileDeleteResponse::fake([ - 'id' => 'file-1234', - 'deleted' => false, - ]); - - expect($response) - ->id->toBe('file-1234') - ->deleted->toBe(false); -}); diff --git a/tests/Responses/Assistants/Files/AssistantFileListResponse.php b/tests/Responses/Assistants/Files/AssistantFileListResponse.php deleted file mode 100644 index bab4604a..00000000 --- a/tests/Responses/Assistants/Files/AssistantFileListResponse.php +++ /dev/null @@ -1,50 +0,0 @@ -toBeInstanceOf(AssistantFileListResponse::class) - ->object->toBe('list') - ->data->toBeArray()->toHaveCount(2) - ->data->each->toBeInstanceOf(AssistantFileResponse::class) - ->meta()->toBeInstanceOf(MetaInformation::class); -}); - -test('as array accessible', function () { - $response = AssistantFileListResponse::from(assistantFileListResource(), meta()); - - expect($response['object'])->toBe('list'); -}); - -test('to array', function () { - $response = AssistantFileListResponse::from(assistantFileListResource(), meta()); - - expect($response->toArray()) - ->toBeArray() - ->toBe(assistantFileListResource()); -}); - -test('fake', function () { - $response = AssistantFileListResponse::fake(); - - expect($response['data'][0]) - ->id->toBe('file-6EsV79Y261TEmi0PY5iHbZdS'); -}); - -test('fake with override', function () { - $response = AssistantFileListResponse::fake([ - 'data' => [ - [ - 'id' => 'file-1234', - ], - ], - ]); - - expect($response['data'][0]) - ->id->toBe('file-1234'); -}); diff --git a/tests/Responses/Assistants/Files/AssistantFileResponse.php b/tests/Responses/Assistants/Files/AssistantFileResponse.php deleted file mode 100644 index 947b9fca..00000000 --- a/tests/Responses/Assistants/Files/AssistantFileResponse.php +++ /dev/null @@ -1,45 +0,0 @@ -id->toBe('file-6EsV79Y261TEmi0PY5iHbZdS') - ->object->toBe('assistant.file') - ->createdAt->toBe(1699620898) - ->assistantId->toBe('asst_y49lAdZDiaQUxEBR6zrG846Q') - ->meta()->toBeInstanceOf(MetaInformation::class); -}); - -test('as array accessible', function () { - $result = AssistantFileResponse::from(assistantFileResource(), meta()); - - expect($result['id']) - ->toBe('file-6EsV79Y261TEmi0PY5iHbZdS'); -}); - -test('to array', function () { - $result = AssistantFileResponse::from(assistantFileResource(), meta()); - - expect($result->toArray()) - ->toBe(assistantFileResource()); -}); - -test('fake', function () { - $response = AssistantFileResponse::fake(); - - expect($response) - ->id->toBe('file-6EsV79Y261TEmi0PY5iHbZdS'); -}); - -test('fake with override', function () { - $response = AssistantFileResponse::fake([ - 'id' => 'file-1234', - ]); - - expect($response) - ->id->toBe('file-1234'); -}); diff --git a/tests/Responses/Threads/Messages/Files/ThreadMessageFileListResponse.php b/tests/Responses/Threads/Messages/Files/ThreadMessageFileListResponse.php deleted file mode 100644 index 18546287..00000000 --- a/tests/Responses/Threads/Messages/Files/ThreadMessageFileListResponse.php +++ /dev/null @@ -1,50 +0,0 @@ -toBeInstanceOf(ThreadMessageFileListResponse::class) - ->object->toBe('list') - ->data->toBeArray()->toHaveCount(2) - ->data->each->toBeInstanceOf(ThreadMessageFileResponse::class) - ->meta()->toBeInstanceOf(MetaInformation::class); -}); - -test('as array accessible', function () { - $response = ThreadMessageFileListResponse::from(threadMessageFileListResource(), meta()); - - expect($response['object'])->toBe('list'); -}); - -test('to array', function () { - $response = ThreadMessageFileListResponse::from(threadMessageFileListResource(), meta()); - - expect($response->toArray()) - ->toBeArray() - ->toBe(threadMessageFileListResource()); -}); - -test('fake', function () { - $response = ThreadMessageFileListResponse::fake(); - - expect($response['data'][0]) - ->id->toBe('file-DhxjnFCaSHc4ZELRGKwTMFtI'); -}); - -test('fake with override', function () { - $response = ThreadMessageFileListResponse::fake([ - 'data' => [ - [ - 'id' => 'file-1234', - ], - ], - ]); - - expect($response['data'][0]) - ->id->toBe('file-1234'); -}); diff --git a/tests/Responses/Threads/Messages/Files/ThreadMessageFileResponse.php b/tests/Responses/Threads/Messages/Files/ThreadMessageFileResponse.php deleted file mode 100644 index a8f87aaa..00000000 --- a/tests/Responses/Threads/Messages/Files/ThreadMessageFileResponse.php +++ /dev/null @@ -1,45 +0,0 @@ -id->toBe('file-DhxjnFCaSHc4ZELRGKwTMFtI') - ->object->toBe('thread.message.file') - ->createdAt->toBe(1699624660) - ->messageId->toBe('msg_KNsDDwE41BUAHhcPNpDkdHWZ') - ->meta()->toBeInstanceOf(MetaInformation::class); -}); - -test('as array accessible', function () { - $result = ThreadMessageFileResponse::from(threadMessageFileResource(), meta()); - - expect($result['id']) - ->toBe('file-DhxjnFCaSHc4ZELRGKwTMFtI'); -}); - -test('to array', function () { - $result = ThreadMessageFileResponse::from(threadMessageFileResource(), meta()); - - expect($result->toArray()) - ->toBe(threadMessageFileResource()); -}); - -test('fake', function () { - $response = ThreadMessageFileResponse::fake(); - - expect($response) - ->id->toBe('file-DhxjnFCaSHc4ZELRGKwTMFtI'); -}); - -test('fake with override', function () { - $response = ThreadMessageFileResponse::fake([ - 'id' => 'file-1234', - ]); - - expect($response) - ->id->toBe('file-1234'); -}); diff --git a/tests/Responses/Threads/Messages/ThreadMessageResponse.php b/tests/Responses/Threads/Messages/ThreadMessageResponse.php index 662830d2..fc3e375b 100644 --- a/tests/Responses/Threads/Messages/ThreadMessageResponse.php +++ b/tests/Responses/Threads/Messages/ThreadMessageResponse.php @@ -2,6 +2,7 @@ use OpenAI\Responses\Meta\MetaInformation; use OpenAI\Responses\Threads\Messages\ThreadMessageResponse; +use OpenAI\Responses\Threads\Messages\ThreadMessageResponseAttachment; use OpenAI\Responses\Threads\Messages\ThreadMessageResponseContentImageFileObject; use OpenAI\Responses\Threads\Messages\ThreadMessageResponseContentTextObject; @@ -17,7 +18,9 @@ ->content->toBeArray() ->content->{0}->toBeInstanceOf(ThreadMessageResponseContentTextObject::class) ->content->{1}->toBeInstanceOf(ThreadMessageResponseContentImageFileObject::class) - ->fileIds->toBe(['file-DhxjnFCaSHc4ZELRGKwTMFtI']) + ->content->{2}->toBeInstanceOf(\OpenAI\Responses\Threads\Messages\ThreadMessageResponseContentImageUrlObject::class) + ->attachments->toBeArray() + ->attachments->{0}->toBeInstanceOf(ThreadMessageResponseAttachment::class) ->assistantId->toBeNull() ->runId->toBeNull() ->metadata->toBe([]) diff --git a/tests/Responses/Threads/Messages/ThreadMessageResponseAttachment.php b/tests/Responses/Threads/Messages/ThreadMessageResponseAttachment.php new file mode 100644 index 00000000..a22f18a8 --- /dev/null +++ b/tests/Responses/Threads/Messages/ThreadMessageResponseAttachment.php @@ -0,0 +1,29 @@ +fileId->toEqual('file-DhxjnFCaSHc4ZELRGKwTMFtI') + ->tools->toBeArray() + ->tools->{0}->toBeInstanceOf(ThreadMessageResponseAttachmentFileSearchTool::class) + ->tools->{0}->type->toBe('file_search'); + +}); + +test('as array accessible', function () { + $result = ThreadMessageResponseAttachment::from(threadMessageResource()['attachments'][0]); + + expect($result['file_id']) + ->toBe('file-DhxjnFCaSHc4ZELRGKwTMFtI'); +}); + +test('to array', function () { + $result = ThreadMessageResponseAttachment::from(threadMessageResource()['attachments'][0]); + + expect($result->toArray()) + ->toBe(threadMessageResource()['attachments'][0]); +}); diff --git a/tests/Responses/Threads/Messages/ThreadMessageResponseAttachmentCodeInterpreterTool.php b/tests/Responses/Threads/Messages/ThreadMessageResponseAttachmentCodeInterpreterTool.php new file mode 100644 index 00000000..50aae1ac --- /dev/null +++ b/tests/Responses/Threads/Messages/ThreadMessageResponseAttachmentCodeInterpreterTool.php @@ -0,0 +1,24 @@ +type->toEqual('code_interpreter'); +}); + +test('as array accessible', function () { + $result = ThreadMessageResponseAttachmentCodeInterpreterTool::from(threadMessageResource()['attachments'][0]['tools'][1]); + + expect($result['type']) + ->toBe('code_interpreter'); +}); + +test('to array', function () { + $result = ThreadMessageResponseAttachmentCodeInterpreterTool::from(threadMessageResource()['attachments'][0]['tools'][1]); + + expect($result->toArray()) + ->toBe(threadMessageResource()['attachments'][0]['tools'][1]); +}); diff --git a/tests/Responses/Threads/Messages/ThreadMessageResponseAttachmentFileSearchTool.php b/tests/Responses/Threads/Messages/ThreadMessageResponseAttachmentFileSearchTool.php new file mode 100644 index 00000000..3a30efe5 --- /dev/null +++ b/tests/Responses/Threads/Messages/ThreadMessageResponseAttachmentFileSearchTool.php @@ -0,0 +1,24 @@ +type->toEqual('file_search'); +}); + +test('as array accessible', function () { + $result = ThreadMessageResponseAttachmentFileSearchTool::from(threadMessageResource()['attachments'][0]['tools'][0]); + + expect($result['type']) + ->toBe('file_search'); +}); + +test('to array', function () { + $result = ThreadMessageResponseAttachmentFileSearchTool::from(threadMessageResource()['attachments'][0]['tools'][0]); + + expect($result->toArray()) + ->toBe(threadMessageResource()['attachments'][0]['tools'][0]); +}); diff --git a/tests/Responses/Threads/Messages/ThreadMessageResponseContentImageUrl.php b/tests/Responses/Threads/Messages/ThreadMessageResponseContentImageUrl.php new file mode 100644 index 00000000..87beb9d2 --- /dev/null +++ b/tests/Responses/Threads/Messages/ThreadMessageResponseContentImageUrl.php @@ -0,0 +1,27 @@ +fileId->toBe('file-VKxjnFCaSHc4ZELRGKwTMFtI') + ->detail->toBe('high'); +}); + +test('as array accessible', function () { + $result = ThreadMessageResponseContentImageUrl::from(threadMessageResource()['content'][2]['image_url']); + + expect($result['file_id']) + ->toBe('file-VKxjnFCaSHc4ZELRGKwTMFtI') + ->and($result['detail']) + ->toBe('high'); +}); + +test('to array', function () { + $result = ThreadMessageResponseContentImageUrl::from(threadMessageResource()['content'][2]['image_url']); + + expect($result->toArray()) + ->toBe(threadMessageResource()['content'][2]['image_url']); +}); diff --git a/tests/Responses/Threads/Messages/ThreadMessageResponseContentImageUrlObject.php b/tests/Responses/Threads/Messages/ThreadMessageResponseContentImageUrlObject.php new file mode 100644 index 00000000..f037b19d --- /dev/null +++ b/tests/Responses/Threads/Messages/ThreadMessageResponseContentImageUrlObject.php @@ -0,0 +1,28 @@ +type->toBe('image_url') + ->imageFile->toBeInstanceOf(ThreadMessageResponseContentImageUrl::class); +}); + +test('as array accessible', function () { + $result = ThreadMessageResponseContentImageUrlObject::from(threadMessageResource()['content'][2]); + + expect($result['type']) + ->toBe('image_url') + ->and($result['image_url']) + ->toBeArray(); +}); + +test('to array', function () { + $result = ThreadMessageResponseContentImageUrlObject::from(threadMessageResource()['content'][2]); + + expect($result->toArray()) + ->toBe(threadMessageResource()['content'][2]); +}); diff --git a/tests/Responses/Threads/Runs/Steps/ThreadRunStepResponse.php b/tests/Responses/Threads/Runs/Steps/ThreadRunStepResponse.php index 4cc1000a..3a33b2b8 100644 --- a/tests/Responses/Threads/Runs/Steps/ThreadRunStepResponse.php +++ b/tests/Responses/Threads/Runs/Steps/ThreadRunStepResponse.php @@ -4,6 +4,7 @@ use OpenAI\Responses\Threads\Runs\Steps\ThreadRunStepResponse; use OpenAI\Responses\Threads\Runs\Steps\ThreadRunStepResponseMessageCreationStepDetails; use OpenAI\Responses\Threads\Runs\Steps\ThreadRunStepResponseToolCallsStepDetails; +use OpenAI\Responses\Threads\Runs\Steps\ThreadRunStepResponseUsage; test('from', function () { $result = ThreadRunStepResponse::from(threadRunStepResource(), meta()); @@ -24,7 +25,8 @@ ->last_error->toBeNull() ->stepDetails->toBeInstanceOf(ThreadRunStepResponseMessageCreationStepDetails::class) ->metadata->toBe([]) - ->meta()->toBeInstanceOf(MetaInformation::class); + ->meta()->toBeInstanceOf(MetaInformation::class) + ->usage->toBeInstanceOf(ThreadRunStepResponseUsage::class); }); test('from resource with submit tool outputs', function () { diff --git a/tests/Responses/Threads/Runs/Steps/ThreadRunStepResponseRetrievalToolCall.php b/tests/Responses/Threads/Runs/Steps/ThreadRunStepResponseRetrievalToolCall.php index de4e964e..6b21ae66 100644 --- a/tests/Responses/Threads/Runs/Steps/ThreadRunStepResponseRetrievalToolCall.php +++ b/tests/Responses/Threads/Runs/Steps/ThreadRunStepResponseRetrievalToolCall.php @@ -1,24 +1,24 @@ id->toBe('call_mNs14X7kZF2WDzlPhpQ163Co') - ->type->toBe('retrieval') - ->retrieval->toBe([]); + ->type->toBe('file_search') + ->file_search->toBe([]); }); test('as array accessible', function () { - $result = ThreadRunStepResponseRetrievalToolCall::from(threadRunStepWithCodeInterpreterOutputResource()['step_details']['tool_calls'][2]); + $result = ThreadRunStepResponseFileSearchToolCall::from(threadRunStepWithCodeInterpreterOutputResource()['step_details']['tool_calls'][2]); expect($result['id']) ->toBe('call_mNs14X7kZF2WDzlPhpQ163Co'); }); test('to array', function () { - $result = ThreadRunStepResponseRetrievalToolCall::from(threadRunStepWithCodeInterpreterOutputResource()['step_details']['tool_calls'][2]); + $result = ThreadRunStepResponseFileSearchToolCall::from(threadRunStepWithCodeInterpreterOutputResource()['step_details']['tool_calls'][2]); expect($result->toArray()) ->toBe(threadRunStepWithCodeInterpreterOutputResource()['step_details']['tool_calls'][2]); diff --git a/tests/Responses/Threads/Runs/Steps/ThreadRunStepResponseUsage.php b/tests/Responses/Threads/Runs/Steps/ThreadRunStepResponseUsage.php new file mode 100644 index 00000000..4de8ca38 --- /dev/null +++ b/tests/Responses/Threads/Runs/Steps/ThreadRunStepResponseUsage.php @@ -0,0 +1,25 @@ +promptTokens->toBe(123) + ->completionTokens->toBe(456) + ->totalTokens->toBe(579); +}); + +test('as array accessible', function () { + $result = ThreadRunStepResponseUsage::from(threadRunStepResource()['usage']); + + expect($result['prompt_tokens']) + ->toBe(123); +}); + +test('to array', function () { + $result = ThreadRunStepResponseUsage::from(threadRunStepResource()['usage']); + + expect($result->toArray()) + ->toBe(threadRunStepResource()['usage']); +}); diff --git a/tests/Responses/Threads/Runs/ThreadRunResponse.php b/tests/Responses/Threads/Runs/ThreadRunResponse.php index 09989ee6..98b46631 100644 --- a/tests/Responses/Threads/Runs/ThreadRunResponse.php +++ b/tests/Responses/Threads/Runs/ThreadRunResponse.php @@ -1,10 +1,12 @@ tools->toBeArray() ->tools->tohaveCount(1) ->tools->{0}->toBeInstanceOf(ThreadRunResponseToolCodeInterpreter::class) - ->fileIds->toBe(['file-6EsV79Y261TEmi0PY5iHbZdS']) ->metadata->toBe([]) ->usage->toBeNull() - ->meta()->toBeInstanceOf(MetaInformation::class); + ->meta()->toBeInstanceOf(MetaInformation::class) + ->incomplete_details->toBeNull() + ->temperature->tobe(1.0) + ->topP->toBe(1.0) + ->maxPromptTokens->toBe(600) + ->maxCompletionTokens->toBe(500) + ->toolChoice->toBe('none') + ->responseFormat->toBe('auto'); +}); + +test('from json object output', function () { + $result = ThreadRunResponse::from(threadRunWithSubmitToolOutputsResource(), meta()); + + expect($result) + ->id->toBe('run_vqUh7mLCAIYjudfN34dMQx4b') + ->object->toBe('thread.run') + ->createdAt->toBe(1699626348) + ->threadId->toBe('thread_vAG0173KCY4VKDLQakucIszZ') + ->assistantId->toBe('asst_elNhDubXFZcsWQd8GuTu93vZ') + ->status->toBe('requires_action') + ->startedAt->toBe(1699626349) + ->expiresAt->toBe(1699626948) + ->cancelledAt->toBeNull() + ->failedAt->toBeNull() + ->completedAt->toBeNull() + ->lastError->toBeNull() + ->model->toBe('gpt-4') + ->instructions->toBe('You are a personal math tutor. When asked a question, write and run Python code to answer the question.') + ->tools->toBeArray() + ->tools->tohaveCount(2) + ->tools->{0}->toBeInstanceOf(ThreadRunResponseToolFunction::class) + ->tools->{1}->toBeInstanceOf(ThreadRunResponseFileSearch::class) + ->metadata->toBe([]) + ->meta()->toBeInstanceOf(MetaInformation::class) + ->responseFormat->toBeInstanceOf(AssistantResponseResponseFormat::class); }); test('from with submit tool outputs', function () { @@ -55,12 +90,19 @@ ->tools->toBeArray() ->tools->tohaveCount(2) ->tools->{0}->toBeInstanceOf(ThreadRunResponseToolFunction::class) - ->tools->{1}->toBeInstanceOf(ThreadRunResponseToolRetrieval::class) - ->fileIds->toBe([]) + ->tools->{1}->toBeInstanceOf(ThreadRunResponseFileSearch::class) ->metadata->toBe([]) ->meta()->toBeInstanceOf(MetaInformation::class); }); +test('from with incomplete details', function () { + $result = ThreadRunResponse::from(threadRunWithIncompleteDetails(), meta()); + + expect($result) + ->incompleteDetails->toBeInstanceOf(ThreadRunResponseIncompleteDetails::class) + ->incompleteDetails->reason->toBe('Input tokens exceeded'); +}); + test('from with usage', function () { $result = ThreadRunResponse::from(threadRunWithUsageResource(), meta()); diff --git a/tests/Responses/Threads/Runs/ThreadRunResponseIncompleteDetails.php b/tests/Responses/Threads/Runs/ThreadRunResponseIncompleteDetails.php new file mode 100644 index 00000000..e54f7904 --- /dev/null +++ b/tests/Responses/Threads/Runs/ThreadRunResponseIncompleteDetails.php @@ -0,0 +1,23 @@ +reason->toBe('Input tokens exceeded'); +}); + +test('as array accessible', function () { + $result = ThreadRunResponseIncompleteDetails::from(threadRunWithIncompleteDetails()['incomplete_details']); + + expect($result['reason']) + ->toBe('Input tokens exceeded'); +}); + +test('to array', function () { + $result = ThreadRunResponseIncompleteDetails::from(threadRunWithIncompleteDetails()['incomplete_details']); + + expect($result->toArray()) + ->toBe(threadRunWithIncompleteDetails()['incomplete_details']); +}); diff --git a/tests/Responses/Threads/Runs/ThreadRunResponseToolChoice.php b/tests/Responses/Threads/Runs/ThreadRunResponseToolChoice.php new file mode 100644 index 00000000..b09ec685 --- /dev/null +++ b/tests/Responses/Threads/Runs/ThreadRunResponseToolChoice.php @@ -0,0 +1,26 @@ +type->toBe('function') + ->function->toBeInstanceOf(ThreadRunResponseToolChoiceFunction::class); +}); + +test('as array accessible', function () { + $result = ThreadRunResponseToolChoice::from(threadRunWithToolChoiceFunction()['tool_choice']); + + expect($result['type']) + ->toBe('function'); +}); + +test('to array', function () { + $result = ThreadRunResponseToolChoice::from(threadRunWithToolChoiceFunction()['tool_choice']); + + expect($result->toArray()) + ->toBe(threadRunWithToolChoiceFunction()['tool_choice']); +}); diff --git a/tests/Responses/Threads/Runs/ThreadRunResponseToolChoiceFunction.php b/tests/Responses/Threads/Runs/ThreadRunResponseToolChoiceFunction.php new file mode 100644 index 00000000..44a32676 --- /dev/null +++ b/tests/Responses/Threads/Runs/ThreadRunResponseToolChoiceFunction.php @@ -0,0 +1,24 @@ +name->toBe('calculate_sum'); +}); + +test('as array accessible', function () { + $result = ThreadRunResponseToolChoiceFunction::from(threadRunWithToolChoiceFunction()['tool_choice']['function']); + + expect($result['name']) + ->toBe('calculate_sum'); +}); + +test('to array', function () { + $result = ThreadRunResponseToolChoiceFunction::from(threadRunWithToolChoiceFunction()['tool_choice']['function']); + + expect($result->toArray()) + ->toBe(threadRunWithToolChoiceFunction()['tool_choice']['function']); +}); diff --git a/tests/Responses/Threads/Runs/ThreadRunResponseToolRetrieval.php b/tests/Responses/Threads/Runs/ThreadRunResponseToolRetrieval.php index 899cd179..371791a6 100644 --- a/tests/Responses/Threads/Runs/ThreadRunResponseToolRetrieval.php +++ b/tests/Responses/Threads/Runs/ThreadRunResponseToolRetrieval.php @@ -1,23 +1,23 @@ type->toBe('retrieval'); + ->type->toBe('file_search'); }); test('as array accessible', function () { - $result = ThreadRunResponseToolRetrieval::from(threadRunWithRetrievalToolResource()['tools'][0]); + $result = ThreadRunResponseFileSearch::from(threadRunWithRetrievalToolResource()['tools'][0]); expect($result['type']) - ->toBe('retrieval'); + ->toBe('file_search'); }); test('to array', function () { - $result = ThreadRunResponseToolRetrieval::from(threadRunWithRetrievalToolResource()['tools'][0]); + $result = ThreadRunResponseFileSearch::from(threadRunWithRetrievalToolResource()['tools'][0]); expect($result->toArray()) ->toBe(threadRunWithRetrievalToolResource()['tools'][0]); diff --git a/tests/Responses/Threads/Runs/ThreadRunResponseTruncationStrategy.php b/tests/Responses/Threads/Runs/ThreadRunResponseTruncationStrategy.php new file mode 100644 index 00000000..5fbe58e8 --- /dev/null +++ b/tests/Responses/Threads/Runs/ThreadRunResponseTruncationStrategy.php @@ -0,0 +1,24 @@ +type->toBe('auto') + ->lastMessages->toBeNull(); +}); + +test('as array accessible', function () { + $result = ThreadRunResponseTruncationStrategy::from(threadRunResource()['truncation_strategy']); + + expect($result['type']) + ->toBe('auto'); +}); + +test('to array', function () { + $result = ThreadRunResponseTruncationStrategy::from(threadRunResource()['truncation_strategy']); + + expect($result->toArray()) + ->toBe(threadRunResource()['truncation_strategy']); +}); diff --git a/tests/Testing/Resources/AssistantsFilesTestResource.php b/tests/Testing/Resources/AssistantsFilesTestResource.php deleted file mode 100644 index 99f7feaa..00000000 --- a/tests/Testing/Resources/AssistantsFilesTestResource.php +++ /dev/null @@ -1,72 +0,0 @@ -assistants()->files()->create('asst_gxzBkD1wkKEloYqZ410pT5pd', [ - 'file_id' => 'file-wB6RM6wHdA49HfS2DJ9fEyrH', - ]); - - $fake->assertSent(AssistantsFiles::class, function ($method, $assistantId, $parameters) { - return $method === 'create' && - $assistantId === 'asst_gxzBkD1wkKEloYqZ410pT5pd' && - $parameters['file_id'] === 'file-wB6RM6wHdA49HfS2DJ9fEyrH'; - }); -}); - -it('records an assistant file retrieve request', function () { - $fake = new ClientFake([ - AssistantFileResponse::fake(), - ]); - - $fake->assistants()->files()->retrieve( - assistantId: 'asst_gxzBkD1wkKEloYqZ410pT5pd', - fileId: 'file-wB6RM6wHdA49HfS2DJ9fEyrH' - ); - - $fake->assertSent(AssistantsFiles::class, function ($method, $assistantId, $fileId) { - return $method === 'retrieve' && - $assistantId === 'asst_gxzBkD1wkKEloYqZ410pT5pd' && - $fileId === 'file-wB6RM6wHdA49HfS2DJ9fEyrH'; - }); -}); - -it('records an assistant file delete request', function () { - $fake = new ClientFake([ - AssistantFileDeleteResponse::fake(), - ]); - - $fake->assistants()->files()->delete( - assistantId: 'asst_gxzBkD1wkKEloYqZ410pT5pd', - fileId: 'file-wB6RM6wHdA49HfS2DJ9fEyrH' - ); - - $fake->assertSent(AssistantsFiles::class, function ($method, $assistantId, $fileId) { - return $method === 'delete' && - $assistantId === 'asst_gxzBkD1wkKEloYqZ410pT5pd' && - $fileId === 'file-wB6RM6wHdA49HfS2DJ9fEyrH'; - }); -}); - -it('records an assistant file list request', function () { - $fake = new ClientFake([ - AssistantFileListResponse::fake(), - ]); - - $fake->assistants()->files()->list('asst_gxzBkD1wkKEloYqZ410pT5pd', [ - 'limit' => 2, - ]); - - $fake->assertSent(AssistantsFiles::class, function ($method, $assistantId) { - return $method === 'list' && - $assistantId === 'asst_gxzBkD1wkKEloYqZ410pT5pd'; - }); -}); diff --git a/tests/Testing/Resources/ThreadsMessagesFilesTestResource.php b/tests/Testing/Resources/ThreadsMessagesFilesTestResource.php deleted file mode 100644 index 3d4d4de9..00000000 --- a/tests/Testing/Resources/ThreadsMessagesFilesTestResource.php +++ /dev/null @@ -1,46 +0,0 @@ -threads()->messages()->files()->retrieve( - threadId: 'thread_tKFLqzRN9n7MnyKKvc1Q7868', - messageId: 'msg_SKYwvF3zcigxthfn6F4hnpdU', - fileId: 'file-DhxjnFCaSHc4ZELRGKwTMFtI', - ); - - $fake->assertSent(ThreadsMessagesFiles::class, function ($method, $threadId, $messageId, $fileId) { - return $method === 'retrieve' && - $threadId === 'thread_tKFLqzRN9n7MnyKKvc1Q7868' && - $messageId === 'msg_SKYwvF3zcigxthfn6F4hnpdU' && - $fileId === 'file-DhxjnFCaSHc4ZELRGKwTMFtI'; - }); -}); - -it('records a thread message file list request', function () { - $fake = new ClientFake([ - ThreadMessageFileListResponse::fake(), - ]); - - $fake->threads()->messages()->files()->list( - threadId: 'thread_tKFLqzRN9n7MnyKKvc1Q7868', - messageId: 'msg_SKYwvF3zcigxthfn6F4hnpdU', - parameters: [ - 'limit' => 10, - ], - ); - - $fake->assertSent(ThreadsMessagesFiles::class, function ($method, $threadId, $messageId, $parameters) { - return $method === 'list' && - $threadId === 'thread_tKFLqzRN9n7MnyKKvc1Q7868' && - $messageId === 'msg_SKYwvF3zcigxthfn6F4hnpdU' && - $parameters['limit'] === 10; - }); -}); From 4111934cda025abbe310a6aace5831d8873da496 Mon Sep 17 00:00:00 2001 From: Sandro Gehri Date: Mon, 27 May 2024 19:35:31 +0200 Subject: [PATCH 04/15] Remove non-existing fields from ThreadMessageResponse --- src/Resources/ThreadsMessages.php | 8 ++++---- .../Messages/ThreadMessageListResponse.php | 2 +- .../Threads/Messages/ThreadMessageResponse.php | 18 +++--------------- tests/Fixtures/ThreadMessage.php | 4 ---- 4 files changed, 8 insertions(+), 24 deletions(-) diff --git a/src/Resources/ThreadsMessages.php b/src/Resources/ThreadsMessages.php index 0de612b4..74bca573 100644 --- a/src/Resources/ThreadsMessages.php +++ b/src/Resources/ThreadsMessages.php @@ -25,7 +25,7 @@ public function create(string $threadId, array $parameters): ThreadMessageRespon { $payload = Payload::create("threads/$threadId/messages", $parameters); - /** @var Response}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}> $response */ + /** @var Response}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}> $response */ $response = $this->transporter->requestObject($payload); return ThreadMessageResponse::from($response->data(), $response->meta()); @@ -40,7 +40,7 @@ public function retrieve(string $threadId, string $messageId): ThreadMessageResp { $payload = Payload::retrieve("threads/$threadId/messages", $messageId); - /** @var Response}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}> $response */ + /** @var Response}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}> $response */ $response = $this->transporter->requestObject($payload); return ThreadMessageResponse::from($response->data(), $response->meta()); @@ -57,7 +57,7 @@ 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, attachments: array}>, metadata: array}> $response */ + /** @var Response}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}> $response */ $response = $this->transporter->requestObject($payload); return ThreadMessageResponse::from($response->data(), $response->meta()); @@ -74,7 +74,7 @@ public function list(string $threadId, array $parameters = []): ThreadMessageLis { $payload = Payload::list("threads/$threadId/messages", $parameters); - /** @var Response}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}>, first_id: ?string, last_id: ?string, has_more: bool}> $response */ + /** @var Response}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}>, first_id: ?string, last_id: ?string, has_more: bool}> $response */ $response = $this->transporter->requestObject($payload); return ThreadMessageListResponse::from($response->data(), $response->meta()); diff --git a/src/Responses/Threads/Messages/ThreadMessageListResponse.php b/src/Responses/Threads/Messages/ThreadMessageListResponse.php index 7deed379..87771f23 100644 --- a/src/Responses/Threads/Messages/ThreadMessageListResponse.php +++ b/src/Responses/Threads/Messages/ThreadMessageListResponse.php @@ -40,7 +40,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{object: string, data: array}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}>, first_id: ?string, last_id: ?string, has_more: bool} $attributes + * @param array{object: string, data: array}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}>, first_id: ?string, last_id: ?string, has_more: bool} $attributes */ public static function from(array $attributes, MetaInformation $meta): self { diff --git a/src/Responses/Threads/Messages/ThreadMessageResponse.php b/src/Responses/Threads/Messages/ThreadMessageResponse.php index ba3810a8..fadd72f3 100644 --- a/src/Responses/Threads/Messages/ThreadMessageResponse.php +++ b/src/Responses/Threads/Messages/ThreadMessageResponse.php @@ -12,12 +12,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}}|array{type: string, image_file: array{file_id: string, detail?: string}}|array{type: 'image_url', image_url: array{file_id: string, detail?: string}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}> + * @implements ResponseContract}}|array{type: string, image_file: array{file_id: string, detail?: string}}|array{type: 'image_url', image_url: array{file_id: string, detail?: string}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}> */ final class ThreadMessageResponse implements ResponseContract, ResponseHasMetaInformationContract { /** - * @use ArrayAccessible}}|array{type: string, image_file: array{file_id: string, detail?: string}}|array{type: 'image_url', image_url: array{file_id: string, detail?: string}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}> + * @use ArrayAccessible}}|array{type: string, image_file: array{file_id: string, detail?: string}}|array{type: 'image_url', image_url: array{file_id: string, detail?: string}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}> */ use ArrayAccessible; @@ -34,10 +34,6 @@ private function __construct( public string $object, public int $createdAt, public string $threadId, - public string $status, - public ?ThreadMessageResponseIncompleteDetails $incompleteDetails, - public ?int $completedAt, - public ?int $incompleteAt, public string $role, public array $content, public ?string $assistantId, @@ -51,7 +47,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{id: string, object: string, created_at: int, thread_id: string, status: string, incomplete_details: ?array{reason: string}, completed_at: ?int, incomplete_at: ?int, role: string, content: array}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array} $attributes + * @param array{id: string, object: string, created_at: int, thread_id: string, role: string, content: array}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array} $attributes */ public static function from(array $attributes, MetaInformation $meta): self { @@ -74,10 +70,6 @@ public static function from(array $attributes, MetaInformation $meta): self $attributes['object'], $attributes['created_at'], $attributes['thread_id'], - $attributes['status'], - $attributes['incomplete_details'] !== null ? ThreadMessageResponseIncompleteDetails::from($attributes['incomplete_details']) : null, - $attributes['completed_at'], - $attributes['incomplete_at'], $attributes['role'], $content, $attributes['assistant_id'], @@ -98,10 +90,6 @@ public function toArray(): array 'object' => $this->object, 'created_at' => $this->createdAt, 'thread_id' => $this->threadId, - 'status' => $this->status, - 'incomplete_details' => $this->incompleteDetails?->toArray(), - 'completed_at' => $this->completedAt, - 'incomplete_at' => $this->incompleteAt, 'role' => $this->role, 'content' => array_map( fn (ThreadMessageResponseContentImageFileObject|ThreadMessageResponseContentTextObject|ThreadMessageResponseContentImageUrlObject $content): array => $content->toArray(), diff --git a/tests/Fixtures/ThreadMessage.php b/tests/Fixtures/ThreadMessage.php index 92dc676c..1f8091fb 100644 --- a/tests/Fixtures/ThreadMessage.php +++ b/tests/Fixtures/ThreadMessage.php @@ -10,10 +10,6 @@ function threadMessageResource(): array 'object' => 'thread.message', 'created_at' => 1699623839, 'thread_id' => 'thread_agvtHUGezjTCt4SKgQg0NJ2Y', - 'status' => 'in_progress', - 'incomplete_details' => null, - 'completed_at' => null, - 'incomplete_at' => null, 'role' => 'user', 'content' => [ [ From 628918f050e83739ddd21cfc247635b83a37d829 Mon Sep 17 00:00:00 2001 From: Sandro Gehri Date: Mon, 27 May 2024 21:48:16 +0200 Subject: [PATCH 05/15] quote parameter on file citation is sometimes missing --- src/Resources/ThreadsMessages.php | 8 ++++---- .../Messages/Delta/ThreadMessageDeltaObject.php | 6 +++--- .../Messages/Delta/ThreadMessageDeltaResponse.php | 6 +++--- .../ThreadMessageDeltaResponseContentText.php | 6 +++--- ...ThreadMessageDeltaResponseContentTextObject.php | 6 +++--- .../Threads/Messages/ThreadMessageListResponse.php | 6 +++--- .../Threads/Messages/ThreadMessageResponse.php | 6 +++--- .../Messages/ThreadMessageResponseContentText.php | 6 +++--- ...geResponseContentTextAnnotationFileCitation.php | 14 +++++++------- ...onseContentTextAnnotationFileCitationObject.php | 6 +++--- .../ThreadMessageResponseContentTextObject.php | 6 +++--- 11 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/Resources/ThreadsMessages.php b/src/Resources/ThreadsMessages.php index 74bca573..9a98514e 100644 --- a/src/Resources/ThreadsMessages.php +++ b/src/Resources/ThreadsMessages.php @@ -25,7 +25,7 @@ public function create(string $threadId, array $parameters): ThreadMessageRespon { $payload = Payload::create("threads/$threadId/messages", $parameters); - /** @var Response}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}> $response */ + /** @var Response}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}> $response */ $response = $this->transporter->requestObject($payload); return ThreadMessageResponse::from($response->data(), $response->meta()); @@ -40,7 +40,7 @@ public function retrieve(string $threadId, string $messageId): ThreadMessageResp { $payload = Payload::retrieve("threads/$threadId/messages", $messageId); - /** @var Response}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}> $response */ + /** @var Response}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}> $response */ $response = $this->transporter->requestObject($payload); return ThreadMessageResponse::from($response->data(), $response->meta()); @@ -57,7 +57,7 @@ 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, attachments: array}>, metadata: array}> $response */ + /** @var Response}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}> $response */ $response = $this->transporter->requestObject($payload); return ThreadMessageResponse::from($response->data(), $response->meta()); @@ -74,7 +74,7 @@ public function list(string $threadId, array $parameters = []): ThreadMessageLis { $payload = Payload::list("threads/$threadId/messages", $parameters); - /** @var Response}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}>, first_id: ?string, last_id: ?string, has_more: bool}> $response */ + /** @var Response}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}>, first_id: ?string, last_id: ?string, has_more: bool}> $response */ $response = $this->transporter->requestObject($payload); return ThreadMessageListResponse::from($response->data(), $response->meta()); diff --git a/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaObject.php b/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaObject.php index 1c211491..7c0a0305 100644 --- a/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaObject.php +++ b/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaObject.php @@ -9,12 +9,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}}>, file_ids: ?array}> + * @implements ResponseContract}}>, file_ids: ?array}> */ final class ThreadMessageDeltaObject implements ResponseContract { /** - * @use ArrayAccessible}}>, file_ids: ?array}> + * @use ArrayAccessible}}>, file_ids: ?array}> */ use ArrayAccessible; @@ -34,7 +34,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{role?: string, content: array}}>, file_ids?: array} $attributes + * @param array{role?: string, content: array}}>, file_ids?: array} $attributes */ public static function from(array $attributes): self { diff --git a/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaResponse.php b/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaResponse.php index 4b68f7b0..32ccf337 100644 --- a/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaResponse.php +++ b/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaResponse.php @@ -9,12 +9,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}}>, file_ids: array|null}}> + * @implements ResponseContract}}>, file_ids: array|null}}> */ final class ThreadMessageDeltaResponse implements ResponseContract { /** - * @use ArrayAccessible}}>, file_ids: array|null}}> + * @use ArrayAccessible}}>, file_ids: array|null}}> */ use ArrayAccessible; @@ -30,7 +30,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{id: string, object: string, delta: array{role?: string, content: array}}>, file_ids?: array}} $attributes + * @param array{id: string, object: string, delta: array{role?: string, content: array}}>, file_ids?: array}} $attributes */ public static function from(array $attributes): self { diff --git a/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaResponseContentText.php b/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaResponseContentText.php index be099322..de897d13 100644 --- a/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaResponseContentText.php +++ b/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaResponseContentText.php @@ -11,12 +11,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}> + * @implements ResponseContract}> */ final class ThreadMessageDeltaResponseContentText implements ResponseContract { /** - * @use ArrayAccessible}> + * @use ArrayAccessible}> */ use ArrayAccessible; @@ -34,7 +34,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{value?: string, annotations?: array} $attributes + * @param array{value?: string, annotations?: array} $attributes */ public static function from(array $attributes): self { diff --git a/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaResponseContentTextObject.php b/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaResponseContentTextObject.php index a48c166a..18e81488 100644 --- a/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaResponseContentTextObject.php +++ b/src/Responses/Threads/Messages/Delta/ThreadMessageDeltaResponseContentTextObject.php @@ -9,12 +9,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}}> + * @implements ResponseContract}}> */ final class ThreadMessageDeltaResponseContentTextObject implements ResponseContract { /** - * @use ArrayAccessible}}> + * @use ArrayAccessible}}> */ use ArrayAccessible; @@ -33,7 +33,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{index: int, type: 'text', text: array{value?: string, annotations: array}} $attributes + * @param array{index: int, type: 'text', text: array{value?: string, annotations: array}} $attributes */ public static function from(array $attributes): self { diff --git a/src/Responses/Threads/Messages/ThreadMessageListResponse.php b/src/Responses/Threads/Messages/ThreadMessageListResponse.php index 87771f23..5cb3fe55 100644 --- a/src/Responses/Threads/Messages/ThreadMessageListResponse.php +++ b/src/Responses/Threads/Messages/ThreadMessageListResponse.php @@ -12,12 +12,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}}|array{type: string, image_file: array{file_id: string}}|array{type: 'image_url', image_url: array{file_id: string, detail?: string}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}>, first_id: ?string, last_id: ?string, has_more: bool}> + * @implements ResponseContract}}|array{type: string, image_file: array{file_id: string}}|array{type: 'image_url', image_url: array{file_id: string, detail?: string}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}>, first_id: ?string, last_id: ?string, has_more: bool}> */ final class ThreadMessageListResponse implements ResponseContract, ResponseHasMetaInformationContract { /** - * @use ArrayAccessible}}|array{type: string, image_file: array{file_id: string}}|array{type: 'image_url', image_url: array{file_id: string, detail?: string}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}>, first_id: ?string, last_id: ?string, has_more: bool}> + * @use ArrayAccessible}}|array{type: string, image_file: array{file_id: string}}|array{type: 'image_url', image_url: array{file_id: string, detail?: string}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}>, first_id: ?string, last_id: ?string, has_more: bool}> */ use ArrayAccessible; @@ -40,7 +40,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{object: string, data: array}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}>, first_id: ?string, last_id: ?string, has_more: bool} $attributes + * @param array{object: string, data: array}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}>, first_id: ?string, last_id: ?string, has_more: bool} $attributes */ public static function from(array $attributes, MetaInformation $meta): self { diff --git a/src/Responses/Threads/Messages/ThreadMessageResponse.php b/src/Responses/Threads/Messages/ThreadMessageResponse.php index fadd72f3..a828adaa 100644 --- a/src/Responses/Threads/Messages/ThreadMessageResponse.php +++ b/src/Responses/Threads/Messages/ThreadMessageResponse.php @@ -12,12 +12,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}}|array{type: string, image_file: array{file_id: string, detail?: string}}|array{type: 'image_url', image_url: array{file_id: string, detail?: string}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}> + * @implements ResponseContract}}|array{type: string, image_file: array{file_id: string, detail?: string}}|array{type: 'image_url', image_url: array{file_id: string, detail?: string}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}> */ final class ThreadMessageResponse implements ResponseContract, ResponseHasMetaInformationContract { /** - * @use ArrayAccessible}}|array{type: string, image_file: array{file_id: string, detail?: string}}|array{type: 'image_url', image_url: array{file_id: string, detail?: string}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}> + * @use ArrayAccessible}}|array{type: string, image_file: array{file_id: string, detail?: string}}|array{type: 'image_url', image_url: array{file_id: string, detail?: string}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array}> */ use ArrayAccessible; @@ -47,7 +47,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{id: string, object: string, created_at: int, thread_id: string, role: string, content: array}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array} $attributes + * @param array{id: string, object: string, created_at: int, thread_id: string, role: string, content: array}}>, assistant_id: ?string, run_id: ?string, attachments: array}>, metadata: array} $attributes */ public static function from(array $attributes, MetaInformation $meta): self { diff --git a/src/Responses/Threads/Messages/ThreadMessageResponseContentText.php b/src/Responses/Threads/Messages/ThreadMessageResponseContentText.php index 1d802a8c..8669bfe0 100644 --- a/src/Responses/Threads/Messages/ThreadMessageResponseContentText.php +++ b/src/Responses/Threads/Messages/ThreadMessageResponseContentText.php @@ -9,12 +9,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}> + * @implements ResponseContract}> */ final class ThreadMessageResponseContentText implements ResponseContract { /** - * @use ArrayAccessible}> + * @use ArrayAccessible}> */ use ArrayAccessible; @@ -32,7 +32,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{value: string, annotations: array} $attributes + * @param array{value: string, annotations: array} $attributes */ public static function from(array $attributes): self { diff --git a/src/Responses/Threads/Messages/ThreadMessageResponseContentTextAnnotationFileCitation.php b/src/Responses/Threads/Messages/ThreadMessageResponseContentTextAnnotationFileCitation.php index 7d3ddc0c..aef25a6c 100644 --- a/src/Responses/Threads/Messages/ThreadMessageResponseContentTextAnnotationFileCitation.php +++ b/src/Responses/Threads/Messages/ThreadMessageResponseContentTextAnnotationFileCitation.php @@ -9,12 +9,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract + * @implements ResponseContract */ final class ThreadMessageResponseContentTextAnnotationFileCitation implements ResponseContract { /** - * @use ArrayAccessible + * @use ArrayAccessible */ use ArrayAccessible; @@ -22,20 +22,20 @@ final class ThreadMessageResponseContentTextAnnotationFileCitation implements Re private function __construct( public string $fileId, - public string $quote, + public ?string $quote, ) { } /** * Acts as static factory, and returns a new Response instance. * - * @param array{file_id: string, quote: string} $attributes + * @param array{file_id: string, quote?: string} $attributes */ public static function from(array $attributes): self { return new self( $attributes['file_id'], - $attributes['quote'], + $attributes['quote'] ?? null, ); } @@ -44,9 +44,9 @@ public static function from(array $attributes): self */ public function toArray(): array { - return [ + return array_filter([ 'file_id' => $this->fileId, 'quote' => $this->quote, - ]; + ], fn (?string $value): bool => $value !== null); } } diff --git a/src/Responses/Threads/Messages/ThreadMessageResponseContentTextAnnotationFileCitationObject.php b/src/Responses/Threads/Messages/ThreadMessageResponseContentTextAnnotationFileCitationObject.php index a74379ac..8b7b8143 100644 --- a/src/Responses/Threads/Messages/ThreadMessageResponseContentTextAnnotationFileCitationObject.php +++ b/src/Responses/Threads/Messages/ThreadMessageResponseContentTextAnnotationFileCitationObject.php @@ -9,12 +9,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract + * @implements ResponseContract */ final class ThreadMessageResponseContentTextAnnotationFileCitationObject implements ResponseContract { /** - * @use ArrayAccessible + * @use ArrayAccessible */ use ArrayAccessible; @@ -35,7 +35,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{type: 'file_citation', text: string, file_citation: array{file_id: string, quote: string}, start_index: int, end_index: int} $attributes + * @param array{type: 'file_citation', text: string, file_citation: array{file_id: string, quote?: string}, start_index: int, end_index: int} $attributes */ public static function from(array $attributes): self { diff --git a/src/Responses/Threads/Messages/ThreadMessageResponseContentTextObject.php b/src/Responses/Threads/Messages/ThreadMessageResponseContentTextObject.php index 29179622..96062d29 100644 --- a/src/Responses/Threads/Messages/ThreadMessageResponseContentTextObject.php +++ b/src/Responses/Threads/Messages/ThreadMessageResponseContentTextObject.php @@ -9,12 +9,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}}> + * @implements ResponseContract}}> */ final class ThreadMessageResponseContentTextObject implements ResponseContract { /** - * @use ArrayAccessible}}> + * @use ArrayAccessible}}> */ use ArrayAccessible; @@ -32,7 +32,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{type: 'text', text: array{value: string, annotations: array}} $attributes + * @param array{type: 'text', text: array{value: string, annotations: array}} $attributes */ public static function from(array $attributes): self { From 18c9eea2dec3d5769db1a0f22644db35da478134 Mon Sep 17 00:00:00 2001 From: Sandro Gehri Date: Mon, 27 May 2024 21:56:02 +0200 Subject: [PATCH 06/15] release: v0.10.0-beta.1 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52b0c6ad..99bf0fbd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## v0.10.0-beta.1 (2024-05-27) +### Added +- Add support for Assistants API v2 and Vector Stores endpoint ([#405](https://github.com/openai-php/client/pull/405)) + ## v0.9.2 (2024-05-27) ### Added - Support for usage stream option on chat endpoint ([#398](https://github.com/openai-php/client/pull/398)) From 05a40617ea57babd8c33f7521b036d19c555d17c Mon Sep 17 00:00:00 2001 From: Sandro Gehri Date: Mon, 27 May 2024 22:15:11 +0200 Subject: [PATCH 07/15] Add 0.10.x hint to README --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 568e3082..9957de4a 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,10 @@ - Nuno Maduro: **[github.com/sponsors/nunomaduro](https://github.com/sponsors/nunomaduro)** - Sandro Gehri: **[github.com/sponsors/gehrisandro](https://github.com/sponsors/gehrisandro)** +> **Looking for Assistants v2 support?** +> +> Check out the [0.10.x release](https://github.com/openai-php/client/releases/tag/v0.10.0-beta.1) (beta) + ## Table of Contents - [Get Started](#get-started) - [Usage](#usage) From 284bd7810a5aa34a8bd82fe562595915a985a65b Mon Sep 17 00:00:00 2001 From: sebapastore Date: Mon, 27 May 2024 17:48:43 -0400 Subject: [PATCH 08/15] remove comment --- src/Resources/Concerns/Transportable.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Resources/Concerns/Transportable.php b/src/Resources/Concerns/Transportable.php index 091511f9..203aa6ee 100644 --- a/src/Resources/Concerns/Transportable.php +++ b/src/Resources/Concerns/Transportable.php @@ -8,9 +8,6 @@ trait Transportable { - /** - * Creates a Client instance with the given API token. - */ public function __construct(private readonly TransporterContract $transporter) { // .. From ff83da9ae5be525d3d8fdc9de7d17d59f22ded76 Mon Sep 17 00:00:00 2001 From: Sandro Gehri Date: Tue, 28 May 2024 23:13:40 +0200 Subject: [PATCH 09/15] update doc blocks --- src/Responses/Chat/CreateStreamedResponseChoice.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Responses/Chat/CreateStreamedResponseChoice.php b/src/Responses/Chat/CreateStreamedResponseChoice.php index 33b07350..d4bc9d91 100644 --- a/src/Responses/Chat/CreateStreamedResponseChoice.php +++ b/src/Responses/Chat/CreateStreamedResponseChoice.php @@ -14,7 +14,7 @@ private function __construct( } /** - * @param array{index: int, delta: array{role?: string, content?: string}, finish_reason: string|null} $attributes + * @param array{index: int, delta?: array{role?: string, content?: string}, finish_reason: string|null} $attributes */ public static function from(array $attributes): self { From 6a57c7811f9a6e861446e379840544c35e1a6851 Mon Sep 17 00:00:00 2001 From: Sandro Gehri Date: Tue, 28 May 2024 23:32:22 +0200 Subject: [PATCH 10/15] Fix faking response metadata --- src/Testing/Responses/Concerns/Fakeable.php | 6 +----- tests/Responses/Assistants/AssistantResponse.php | 7 ++++++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Testing/Responses/Concerns/Fakeable.php b/src/Testing/Responses/Concerns/Fakeable.php index d2876679..da0b117f 100644 --- a/src/Testing/Responses/Concerns/Fakeable.php +++ b/src/Testing/Responses/Concerns/Fakeable.php @@ -35,12 +35,8 @@ private static function buildAttributes(array $original, array $override): array unset($override[$key]); } - // we are going to append all remaining overrides with numeric keys + // we are going to append all remaining overrides foreach ($override as $key => $value) { - if (! is_numeric($key)) { - continue; - } - $new[$key] = $value; } diff --git a/tests/Responses/Assistants/AssistantResponse.php b/tests/Responses/Assistants/AssistantResponse.php index 59769714..1c6a078a 100644 --- a/tests/Responses/Assistants/AssistantResponse.php +++ b/tests/Responses/Assistants/AssistantResponse.php @@ -46,8 +46,13 @@ test('fake with override', function () { $response = AssistantResponse::fake([ 'id' => 'asst_1234', + 'metadata' => [ + 'key' => 'value', + ], ]); expect($response) - ->id->toBe('asst_1234'); + ->id->toBe('asst_1234') + ->metadata->toBeArray() + ->metadata->key->toBe('value'); }); From 728a944eee05d1d78af64c223de3ed4c9f9e2b20 Mon Sep 17 00:00:00 2001 From: Sandro Gehri Date: Thu, 6 Jun 2024 21:02:29 +0200 Subject: [PATCH 11/15] Add thread messages delete endpoint --- README.md | 17 ++++++ .../Resources/ThreadsMessagesContract.php | 8 +++ src/Resources/ThreadsMessages.php | 16 +++++ .../Messages/ThreadMessageDeleteResponse.php | 61 +++++++++++++++++++ .../Resources/ThreadsMessagesTestResource.php | 6 ++ tests/Fixtures/ThreadMessage.php | 12 ++++ tests/Resources/ThreadsMessages.php | 16 +++++ .../Messages/ThreadMessageDeleteResponse.php | 47 ++++++++++++++ .../Resources/ThreadsMessagesTestResource.php | 14 +++++ 9 files changed, 197 insertions(+) create mode 100644 src/Responses/Threads/Messages/ThreadMessageDeleteResponse.php create mode 100644 tests/Responses/Threads/Messages/ThreadMessageDeleteResponse.php diff --git a/README.md b/README.md index 146efd23..df1486a3 100644 --- a/README.md +++ b/README.md @@ -1280,6 +1280,23 @@ $response->metadata; // ['name' => 'My new message name'] $response->toArray(); // ['id' => 'msg_SKYwvF3zcigxthfn6F4hnpdU', ...] ``` +#### `delete` + +Deletes a message. + +```php +$response = $client->threads()->messages()->delete( + threadId: 'thread_tKFLqzRN9n7MnyKKvc1Q7868', + messageId: 'msg_SKYwvF3zcigxthfn6F4hnpdU' +); + +$response->id; // 'msg_SKYwvF3zcigxthfn6F4hnpdU' +$response->object; // 'thread.message.deleted' +$response->deleted; // true + +$response->toArray(); // ['id' => 'msg_SKYwvF3zcigxthfn6F4hnpdU', ...] +``` + #### `list` Returns a list of messages for a given thread. diff --git a/src/Contracts/Resources/ThreadsMessagesContract.php b/src/Contracts/Resources/ThreadsMessagesContract.php index 288ecdd9..ea5bcbb6 100644 --- a/src/Contracts/Resources/ThreadsMessagesContract.php +++ b/src/Contracts/Resources/ThreadsMessagesContract.php @@ -2,6 +2,7 @@ namespace OpenAI\Contracts\Resources; +use OpenAI\Responses\Threads\Messages\ThreadMessageDeleteResponse; use OpenAI\Responses\Threads\Messages\ThreadMessageListResponse; use OpenAI\Responses\Threads\Messages\ThreadMessageResponse; @@ -32,6 +33,13 @@ public function retrieve(string $threadId, string $messageId): ThreadMessageResp */ public function modify(string $threadId, string $messageId, array $parameters): ThreadMessageResponse; + /** + * Deletes a message. + * + * @see https://platform.openai.com/docs/api-reference/messages/deleteMessage + */ + public function delete(string $threadId, string $messageId): ThreadMessageDeleteResponse; + /** * Returns a list of messages for a given thread. * diff --git a/src/Resources/ThreadsMessages.php b/src/Resources/ThreadsMessages.php index 9a98514e..da1b1adb 100644 --- a/src/Resources/ThreadsMessages.php +++ b/src/Resources/ThreadsMessages.php @@ -5,6 +5,7 @@ namespace OpenAI\Resources; use OpenAI\Contracts\Resources\ThreadsMessagesContract; +use OpenAI\Responses\Threads\Messages\ThreadMessageDeleteResponse; use OpenAI\Responses\Threads\Messages\ThreadMessageListResponse; use OpenAI\Responses\Threads\Messages\ThreadMessageResponse; use OpenAI\ValueObjects\Transporter\Payload; @@ -63,6 +64,21 @@ public function modify(string $threadId, string $messageId, array $parameters): return ThreadMessageResponse::from($response->data(), $response->meta()); } + /** + * Deletes a message. + * + * @see https://platform.openai.com/docs/api-reference/messages/deleteMessage + */ + public function delete(string $threadId, string $messageId): ThreadMessageDeleteResponse + { + $payload = Payload::delete("threads/$threadId/messages", $messageId); + + /** @var Response $response */ + $response = $this->transporter->requestObject($payload); + + return ThreadMessageDeleteResponse::from($response->data(), $response->meta()); + } + /** * Returns a list of messages for a given thread. * diff --git a/src/Responses/Threads/Messages/ThreadMessageDeleteResponse.php b/src/Responses/Threads/Messages/ThreadMessageDeleteResponse.php new file mode 100644 index 00000000..a9a62385 --- /dev/null +++ b/src/Responses/Threads/Messages/ThreadMessageDeleteResponse.php @@ -0,0 +1,61 @@ + + */ +final class ThreadMessageDeleteResponse implements ResponseContract, ResponseHasMetaInformationContract +{ + /** + * @use ArrayAccessible + */ + use ArrayAccessible; + + use Fakeable; + use HasMetaInformation; + + private function __construct( + public readonly string $id, + public readonly string $object, + public readonly bool $deleted, + private readonly MetaInformation $meta, + ) { + } + + /** + * Acts as static factory, and returns a new Response instance. + * + * @param array{id: string, object: string, deleted: bool} $attributes + */ + public static function from(array $attributes, MetaInformation $meta): self + { + return new self( + $attributes['id'], + $attributes['object'], + $attributes['deleted'], + $meta, + ); + } + + /** + * {@inheritDoc} + */ + public function toArray(): array + { + return [ + 'id' => $this->id, + 'object' => $this->object, + 'deleted' => $this->deleted, + ]; + } +} diff --git a/src/Testing/Resources/ThreadsMessagesTestResource.php b/src/Testing/Resources/ThreadsMessagesTestResource.php index 6556ba17..6c090127 100644 --- a/src/Testing/Resources/ThreadsMessagesTestResource.php +++ b/src/Testing/Resources/ThreadsMessagesTestResource.php @@ -4,6 +4,7 @@ use OpenAI\Contracts\Resources\ThreadsMessagesContract; use OpenAI\Resources\ThreadsMessages; +use OpenAI\Responses\Threads\Messages\ThreadMessageDeleteResponse; use OpenAI\Responses\Threads\Messages\ThreadMessageListResponse; use OpenAI\Responses\Threads\Messages\ThreadMessageResponse; use OpenAI\Testing\Resources\Concerns\Testable; @@ -32,6 +33,11 @@ public function modify(string $threadId, string $messageId, array $parameters): return $this->record(__FUNCTION__, func_get_args()); } + public function delete(string $threadId, string $messageId): ThreadMessageDeleteResponse + { + return $this->record(__FUNCTION__, func_get_args()); + } + public function list(string $threadId, array $parameters = []): ThreadMessageListResponse { return $this->record(__FUNCTION__, func_get_args()); diff --git a/tests/Fixtures/ThreadMessage.php b/tests/Fixtures/ThreadMessage.php index 1f8091fb..d0f47567 100644 --- a/tests/Fixtures/ThreadMessage.php +++ b/tests/Fixtures/ThreadMessage.php @@ -81,3 +81,15 @@ function threadMessageListResource(): array 'has_more' => false, ]; } + +/** + * @return array + */ +function threadMessageDeleteResource(): array +{ + return [ + 'id' => 'msg_KNsDDwE41BUAHhcPNpDkdHWZ', + 'object' => 'thread.message.deleted', + 'deleted' => true, + ]; +} diff --git a/tests/Resources/ThreadsMessages.php b/tests/Resources/ThreadsMessages.php index 924fdd80..ef68732a 100644 --- a/tests/Resources/ThreadsMessages.php +++ b/tests/Resources/ThreadsMessages.php @@ -1,6 +1,7 @@ meta()) ->toBeInstanceOf(MetaInformation::class); }); + +test('delete', function () { + $client = mockClient('DELETE', 'threads/thread_agvtHUGezjTCt4SKgQg0NJ2Y/messages/msg_KNsDDwE41BUAHhcPNpDkdHWZ', [], Response::from(threadMessageDeleteResource(), metaHeaders())); + + $result = $client->threads()->messages()->delete('thread_agvtHUGezjTCt4SKgQg0NJ2Y', 'msg_KNsDDwE41BUAHhcPNpDkdHWZ'); + + expect($result) + ->toBeInstanceOf(ThreadMessageDeleteResponse::class) + ->id->toBe('msg_KNsDDwE41BUAHhcPNpDkdHWZ') + ->object->toBe('thread.message.deleted') + ->deleted->toBe(true); + + expect($result->meta()) + ->toBeInstanceOf(MetaInformation::class); +}); diff --git a/tests/Responses/Threads/Messages/ThreadMessageDeleteResponse.php b/tests/Responses/Threads/Messages/ThreadMessageDeleteResponse.php new file mode 100644 index 00000000..b1cc78a2 --- /dev/null +++ b/tests/Responses/Threads/Messages/ThreadMessageDeleteResponse.php @@ -0,0 +1,47 @@ +id->toBe('msg_KNsDDwE41BUAHhcPNpDkdHWZ') + ->object->toBe('thread.message.deleted') + ->deleted->toBe(true) + ->meta()->toBeInstanceOf(MetaInformation::class); +}); + +test('as array accessible', function () { + $result = ThreadMessageDeleteResponse::from(threadMessageDeleteResource(), meta()); + + expect($result['id']) + ->toBe('msg_KNsDDwE41BUAHhcPNpDkdHWZ'); +}); + +test('to array', function () { + $result = ThreadMessageDeleteResponse::from(threadMessageDeleteResource(), meta()); + + expect($result->toArray()) + ->toBe(threadMessageDeleteResource()); +}); + +test('fake', function () { + $response = ThreadMessageDeleteResponse::fake(); + + expect($response) + ->id->toBe('msg_KNsDDwE41BUAHhcPNpDkdHWZ') + ->deleted->toBe(true); +}); + +test('fake with override', function () { + $response = ThreadMessageDeleteResponse::fake([ + 'id' => 'msg_1234', + 'deleted' => false, + ]); + + expect($response) + ->id->toBe('msg_1234') + ->deleted->toBe(false); +}); diff --git a/tests/Testing/Resources/ThreadsMessagesTestResource.php b/tests/Testing/Resources/ThreadsMessagesTestResource.php index 7a45e37e..43f0482d 100644 --- a/tests/Testing/Resources/ThreadsMessagesTestResource.php +++ b/tests/Testing/Resources/ThreadsMessagesTestResource.php @@ -65,6 +65,20 @@ }); }); +it('records a thread message delete request', function () { + $fake = new ClientFake([ + \OpenAI\Responses\Threads\Messages\ThreadMessageDeleteResponse::fake(), + ]); + + $fake->threads()->messages()->delete('thread_tKFLqzRN9n7MnyKKvc1Q7868', 'msg_KNsDDwE41BUAHhcPNpDkdHWZ'); + + $fake->assertSent(ThreadsMessages::class, function ($method, $threadId, $messageId) { + return $method === 'delete' && + $threadId === 'thread_tKFLqzRN9n7MnyKKvc1Q7868' && + $messageId === 'msg_KNsDDwE41BUAHhcPNpDkdHWZ'; + }); +}); + it('records a thread message list request', function () { $fake = new ClientFake([ ThreadMessageListResponse::fake(), From ebbc0e63bd07fa19dee28fdb515333ea7120d0ac Mon Sep 17 00:00:00 2001 From: Sandro Gehri Date: Thu, 6 Jun 2024 21:34:56 +0200 Subject: [PATCH 12/15] Add chunking strategy on VectorStoreFileResponse --- src/Resources/VectorStoresFileBatches.php | 2 +- src/Resources/VectorStoresFiles.php | 6 +- .../Files/VectorStoreFileListResponse.php | 2 +- .../Files/VectorStoreFileResponse.php | 9 ++- ...StoreFileResponseChunkingStrategyOther.php | 52 ++++++++++++++++ ...toreFileResponseChunkingStrategyStatic.php | 60 +++++++++++++++++++ tests/Fixtures/VectorStoreFile.php | 7 +++ .../Files/VectorStoreFileResponse.php | 7 ++- 8 files changed, 136 insertions(+), 9 deletions(-) create mode 100644 src/Responses/VectorStores/Files/VectorStoreFileResponseChunkingStrategyOther.php create mode 100644 src/Responses/VectorStores/Files/VectorStoreFileResponseChunkingStrategyStatic.php diff --git a/src/Resources/VectorStoresFileBatches.php b/src/Resources/VectorStoresFileBatches.php index 3fce48c0..f612f8ac 100644 --- a/src/Resources/VectorStoresFileBatches.php +++ b/src/Resources/VectorStoresFileBatches.php @@ -55,7 +55,7 @@ public function listFiles(string $vectorStoreId, string $fileBatchId): VectorSto { $payload = Payload::list("vector_stores/$vectorStoreId/file_batches/$fileBatchId/files"); - /** @var Response, first_id: ?string, last_id: ?string, has_more: bool}> $response */ + /** @var Response, first_id: ?string, last_id: ?string, has_more: bool}> $response */ $response = $this->transporter->requestObject($payload); return VectorStoreFileListResponse::from($response->data(), $response->meta()); diff --git a/src/Resources/VectorStoresFiles.php b/src/Resources/VectorStoresFiles.php index 264288b9..eb1c9c2d 100644 --- a/src/Resources/VectorStoresFiles.php +++ b/src/Resources/VectorStoresFiles.php @@ -26,7 +26,7 @@ public function create(string $vectorStoreId, array $parameters): VectorStoreFil { $payload = Payload::create("vector_stores/$vectorStoreId/files", $parameters); - /** @var Response $response */ + /** @var Response $response */ $response = $this->transporter->requestObject($payload); return VectorStoreFileResponse::from($response->data(), $response->meta()); @@ -41,7 +41,7 @@ public function list(string $vectorStoreId): VectorStoreFileListResponse { $payload = Payload::list("vector_stores/$vectorStoreId/files"); - /** @var Response, first_id: ?string, last_id: ?string, has_more: bool}> $response */ + /** @var Response, first_id: ?string, last_id: ?string, has_more: bool}> $response */ $response = $this->transporter->requestObject($payload); return VectorStoreFileListResponse::from($response->data(), $response->meta()); @@ -56,7 +56,7 @@ public function retrieve(string $vectorStoreId, string $fileId): VectorStoreFile { $payload = Payload::retrieve("vector_stores/$vectorStoreId/files", $fileId); - /** @var Response $response */ + /** @var Response $response */ $response = $this->transporter->requestObject($payload); return VectorStoreFileResponse::from($response->data(), $response->meta()); diff --git a/src/Responses/VectorStores/Files/VectorStoreFileListResponse.php b/src/Responses/VectorStores/Files/VectorStoreFileListResponse.php index 4e38a31c..67d06b0c 100644 --- a/src/Responses/VectorStores/Files/VectorStoreFileListResponse.php +++ b/src/Responses/VectorStores/Files/VectorStoreFileListResponse.php @@ -40,7 +40,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{object: string, data: array, first_id: ?string, last_id: ?string, has_more: bool} $attributes + * @param array{object: string, data: array, first_id: ?string, last_id: ?string, has_more: bool} $attributes */ public static function from(array $attributes, MetaInformation $meta): self { diff --git a/src/Responses/VectorStores/Files/VectorStoreFileResponse.php b/src/Responses/VectorStores/Files/VectorStoreFileResponse.php index 5af86260..9c5ff3dd 100644 --- a/src/Responses/VectorStores/Files/VectorStoreFileResponse.php +++ b/src/Responses/VectorStores/Files/VectorStoreFileResponse.php @@ -12,12 +12,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract + * @implements ResponseContract */ final class VectorStoreFileResponse implements ResponseContract, ResponseHasMetaInformationContract { /** - * @use ArrayAccessible + * @use ArrayAccessible */ use ArrayAccessible; @@ -32,6 +32,7 @@ private function __construct( public readonly string $vectorStoreId, public readonly string $status, public readonly ?VectorStoreFileResponseLastError $lastError, + public readonly VectorStoreFileResponseChunkingStrategyStatic|VectorStoreFileResponseChunkingStrategyOther $chunkingStrategy, private readonly MetaInformation $meta, ) { } @@ -39,7 +40,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{id: string, object: string, usage_bytes: int, created_at: int, vector_store_id: string, status: string, last_error: ?array{code: string, message: string}} $attributes + * @param array{id: string, object: string, usage_bytes: int, created_at: int, vector_store_id: string, status: string, last_error: ?array{code: string, message: string}, chunking_strategy: array{type: 'static', static: array{max_chunk_size_tokens: int, chunk_overlap_tokens: int}}|array{type: 'other'}} $attributes */ public static function from(array $attributes, MetaInformation $meta): self { @@ -51,6 +52,7 @@ public static function from(array $attributes, MetaInformation $meta): self $attributes['vector_store_id'], $attributes['status'], isset($attributes['last_error']) ? VectorStoreFileResponseLastError::from($attributes['last_error']) : null, + $attributes['chunking_strategy']['type'] === 'static' ? VectorStoreFileResponseChunkingStrategyStatic::from($attributes['chunking_strategy']) : VectorStoreFileResponseChunkingStrategyOther::from($attributes['chunking_strategy']), $meta, ); } @@ -68,6 +70,7 @@ public function toArray(): array 'vector_store_id' => $this->vectorStoreId, 'status' => $this->status, 'last_error' => $this->lastError instanceof VectorStoreFileResponseLastError ? $this->lastError->toArray() : null, + 'chunking_strategy' => $this->chunkingStrategy->toArray(), ]; } } diff --git a/src/Responses/VectorStores/Files/VectorStoreFileResponseChunkingStrategyOther.php b/src/Responses/VectorStores/Files/VectorStoreFileResponseChunkingStrategyOther.php new file mode 100644 index 00000000..37ed2146 --- /dev/null +++ b/src/Responses/VectorStores/Files/VectorStoreFileResponseChunkingStrategyOther.php @@ -0,0 +1,52 @@ + + */ +final class VectorStoreFileResponseChunkingStrategyOther implements ResponseContract +{ + /** + * @use ArrayAccessible + */ + use ArrayAccessible; + + use Fakeable; + + /** + * @param 'other' $type + */ + private function __construct( + public readonly string $type, + ) { + } + + /** + * Acts as static factory, and returns a new Response instance. + * + * @param array{type: 'other'} $attributes + */ + public static function from(array $attributes): self + { + return new self( + $attributes['type'], + ); + } + + /** + * {@inheritDoc} + */ + public function toArray(): array + { + return [ + 'type' => $this->type, + ]; + } +} diff --git a/src/Responses/VectorStores/Files/VectorStoreFileResponseChunkingStrategyStatic.php b/src/Responses/VectorStores/Files/VectorStoreFileResponseChunkingStrategyStatic.php new file mode 100644 index 00000000..2b4264a6 --- /dev/null +++ b/src/Responses/VectorStores/Files/VectorStoreFileResponseChunkingStrategyStatic.php @@ -0,0 +1,60 @@ + + */ +final class VectorStoreFileResponseChunkingStrategyStatic implements ResponseContract +{ + /** + * @use ArrayAccessible + */ + use ArrayAccessible; + + use Fakeable; + + /** + * @param 'static' $type + */ + private function __construct( + public readonly string $type, + public readonly int $maxChunkSizeTokens, + public readonly int $chunkOverlapTokens, + ) { + } + + /** + * Acts as static factory, and returns a new Response instance. + * + * @param array{type: 'static', static: array{max_chunk_size_tokens: int, chunk_overlap_tokens: int}} $attributes + */ + public static function from(array $attributes): self + { + return new self( + $attributes['type'], + $attributes['static']['max_chunk_size_tokens'], + $attributes['static']['chunk_overlap_tokens'], + ); + } + + /** + * {@inheritDoc} + */ + public function toArray(): array + { + return [ + 'type' => $this->type, + 'static' => [ + 'max_chunk_size_tokens' => $this->maxChunkSizeTokens, + 'chunk_overlap_tokens' => $this->chunkOverlapTokens, + ], + ]; + } +} diff --git a/tests/Fixtures/VectorStoreFile.php b/tests/Fixtures/VectorStoreFile.php index ba94382a..e22917e1 100644 --- a/tests/Fixtures/VectorStoreFile.php +++ b/tests/Fixtures/VectorStoreFile.php @@ -13,6 +13,13 @@ function vectorStoreFileResource(): array 'vector_store_id' => 'vs_xds05V7ep0QMGI5JmYnWsJwb', 'status' => 'completed', 'last_error' => null, + 'chunking_strategy' => [ + 'type' => 'static', + 'static' => [ + 'max_chunk_size_tokens' => 800, + 'chunk_overlap_tokens' => 400, + ], + ], ]; } diff --git a/tests/Responses/VectorStores/Files/VectorStoreFileResponse.php b/tests/Responses/VectorStores/Files/VectorStoreFileResponse.php index 8d093df1..ed5aef57 100644 --- a/tests/Responses/VectorStores/Files/VectorStoreFileResponse.php +++ b/tests/Responses/VectorStores/Files/VectorStoreFileResponse.php @@ -1,6 +1,7 @@ createdAt->toBe(1715956697) ->vectorStoreId->toBe('vs_xds05V7ep0QMGI5JmYnWsJwb') ->status->toBe('completed') - ->lastError->toBeNull(); + ->lastError->toBeNull() + ->chunkingStrategy->toBeInstanceOf(VectorStoreFileResponseChunkingStrategyStatic::class) + ->chunkingStrategy->type->toBe('static') + ->chunkingStrategy->maxChunkSizeTokens->toBe(800) + ->chunkingStrategy->chunkOverlapTokens->toBe(400); }); test('as array accessible', function () { From 667134cedcca89cbb0dfe5448e95666b98d74de8 Mon Sep 17 00:00:00 2001 From: Sandro Gehri Date: Thu, 6 Jun 2024 22:22:12 +0200 Subject: [PATCH 13/15] Add parameters to vector store list functions --- .../Resources/VectorStoresContract.php | 10 ++++++---- .../VectorStoresFileBatchesContract.php | 4 +++- .../Resources/VectorStoresFilesContract.php | 4 +++- src/Resources/VectorStores.php | 18 ++++++++++-------- src/Resources/VectorStoresFileBatches.php | 6 ++++-- src/Resources/VectorStoresFiles.php | 6 ++++-- .../VectorStoresFileBatchesTestResource.php | 2 +- .../VectorStoresFilesTestResource.php | 2 +- .../Resources/VectorStoresTestResource.php | 8 ++++---- 9 files changed, 36 insertions(+), 24 deletions(-) diff --git a/src/Contracts/Resources/VectorStoresContract.php b/src/Contracts/Resources/VectorStoresContract.php index 39e7fae9..2d2010ed 100644 --- a/src/Contracts/Resources/VectorStoresContract.php +++ b/src/Contracts/Resources/VectorStoresContract.php @@ -21,15 +21,17 @@ public function create(array $parameters): VectorStoreResponse; * Returns a list of vector stores. * * @see https://platform.openai.com/docs/api-reference/vector-stores/list + * + * @param array $parameters */ - public function list(): VectorStoreListResponse; + public function list(array $parameters = []): VectorStoreListResponse; /** * Retrieves a vector store. * * @see https://platform.openai.com/docs/api-reference/vector-stores/retrieve */ - public function retrieve(string $vectorStore): VectorStoreResponse; + public function retrieve(string $vectorStoreId): VectorStoreResponse; /** * Modify a vector store @@ -38,14 +40,14 @@ public function retrieve(string $vectorStore): VectorStoreResponse; * * @param array $parameters */ - public function modify(string $vectorStore, array $parameters): VectorStoreResponse; + public function modify(string $vectorStoreId, array $parameters): VectorStoreResponse; /** * Delete a vector store. * * https://platform.openai.com/docs/api-reference/vector-stores/delete */ - public function delete(string $vectorStore): VectorStoreDeleteResponse; + public function delete(string $vectorStoreId): VectorStoreDeleteResponse; /** * Manage the files related to the vector store diff --git a/src/Contracts/Resources/VectorStoresFileBatchesContract.php b/src/Contracts/Resources/VectorStoresFileBatchesContract.php index 4ebb35a3..acbcff2d 100644 --- a/src/Contracts/Resources/VectorStoresFileBatchesContract.php +++ b/src/Contracts/Resources/VectorStoresFileBatchesContract.php @@ -34,6 +34,8 @@ public function cancel(string $vectorStoreId, string $fileBatchId): VectorStoreF * Lists the files within a file batch within a vector store * * @see https://platform.openai.com/docs/api-reference/vector-stores-file-batches/listBatchFiles + * + * @param array $parameters */ - public function listFiles(string $vectorStoreId, string $fileBatchId): VectorStoreFileListResponse; + public function listFiles(string $vectorStoreId, string $fileBatchId, array $parameters = []): VectorStoreFileListResponse; } diff --git a/src/Contracts/Resources/VectorStoresFilesContract.php b/src/Contracts/Resources/VectorStoresFilesContract.php index 7e6386b4..f75a833f 100644 --- a/src/Contracts/Resources/VectorStoresFilesContract.php +++ b/src/Contracts/Resources/VectorStoresFilesContract.php @@ -21,8 +21,10 @@ public function create(string $vectorStoreId, array $parameters): VectorStoreFil * Returns a list of files within a vector store. * * @see https://platform.openai.com/docs/api-reference/vector-stores-files/listFiles + * + * @param array $parameters */ - public function list(string $vectorStoreId): VectorStoreFileListResponse; + public function list(string $vectorStoreId, array $parameters = []): VectorStoreFileListResponse; /** * Retrieves a file within a vector store. diff --git a/src/Resources/VectorStores.php b/src/Resources/VectorStores.php index 257cd942..bb951b74 100644 --- a/src/Resources/VectorStores.php +++ b/src/Resources/VectorStores.php @@ -38,10 +38,12 @@ public function create(array $parameters): VectorStoreResponse * Returns a list of vector stores. * * @see https://platform.openai.com/docs/api-reference/vector-stores/list + * + * @param array $parameters */ - public function list(): VectorStoreListResponse + public function list(array $parameters = []): VectorStoreListResponse { - $payload = Payload::list('vector_stores'); + $payload = Payload::list('vector_stores', $parameters); /** @var Response}>, first_id: ?string, last_id: ?string, has_more: bool}> $response */ $response = $this->transporter->requestObject($payload); @@ -54,9 +56,9 @@ public function list(): VectorStoreListResponse * * @see https://platform.openai.com/docs/api-reference/vector-stores/retrieve */ - public function retrieve(string $vectorStore): VectorStoreResponse + public function retrieve(string $vectorStoreId): VectorStoreResponse { - $payload = Payload::retrieve('vector_stores', $vectorStore); + $payload = Payload::retrieve('vector_stores', $vectorStoreId); /** @var Response}> $response */ $response = $this->transporter->requestObject($payload); @@ -71,9 +73,9 @@ public function retrieve(string $vectorStore): VectorStoreResponse * * @param array $parameters */ - public function modify(string $vectorStore, array $parameters): VectorStoreResponse + public function modify(string $vectorStoreId, array $parameters): VectorStoreResponse { - $payload = Payload::modify('vector_stores', $vectorStore, $parameters); + $payload = Payload::modify('vector_stores', $vectorStoreId, $parameters); /** @var Response}> $response */ $response = $this->transporter->requestObject($payload); @@ -86,9 +88,9 @@ public function modify(string $vectorStore, array $parameters): VectorStoreRespo * * https://platform.openai.com/docs/api-reference/vector-stores/delete */ - public function delete(string $vectorStore): VectorStoreDeleteResponse + public function delete(string $vectorStoreId): VectorStoreDeleteResponse { - $payload = Payload::delete('vector_stores', $vectorStore); + $payload = Payload::delete('vector_stores', $vectorStoreId); /** @var Response $response */ $response = $this->transporter->requestObject($payload); diff --git a/src/Resources/VectorStoresFileBatches.php b/src/Resources/VectorStoresFileBatches.php index f612f8ac..1dd9293f 100644 --- a/src/Resources/VectorStoresFileBatches.php +++ b/src/Resources/VectorStoresFileBatches.php @@ -50,10 +50,12 @@ public function retrieve(string $vectorStoreId, string $fileBatchId): VectorStor * Lists the files within a file batch within a vector store * * @see https://platform.openai.com/docs/api-reference/vector-stores-file-batches/listBatchFiles + * + * @param array $parameters */ - public function listFiles(string $vectorStoreId, string $fileBatchId): VectorStoreFileListResponse + public function listFiles(string $vectorStoreId, string $fileBatchId, array $parameters = []): VectorStoreFileListResponse { - $payload = Payload::list("vector_stores/$vectorStoreId/file_batches/$fileBatchId/files"); + $payload = Payload::list("vector_stores/$vectorStoreId/file_batches/$fileBatchId/files", $parameters); /** @var Response, first_id: ?string, last_id: ?string, has_more: bool}> $response */ $response = $this->transporter->requestObject($payload); diff --git a/src/Resources/VectorStoresFiles.php b/src/Resources/VectorStoresFiles.php index eb1c9c2d..2b58912c 100644 --- a/src/Resources/VectorStoresFiles.php +++ b/src/Resources/VectorStoresFiles.php @@ -36,10 +36,12 @@ public function create(string $vectorStoreId, array $parameters): VectorStoreFil * Returns a list of files within a vector store. * * @see https://platform.openai.com/docs/api-reference/vector-stores-files/listFiles + * + * @param array $parameters */ - public function list(string $vectorStoreId): VectorStoreFileListResponse + public function list(string $vectorStoreId, array $parameters = []): VectorStoreFileListResponse { - $payload = Payload::list("vector_stores/$vectorStoreId/files"); + $payload = Payload::list("vector_stores/$vectorStoreId/files", $parameters); /** @var Response, first_id: ?string, last_id: ?string, has_more: bool}> $response */ $response = $this->transporter->requestObject($payload); diff --git a/src/Testing/Resources/VectorStoresFileBatchesTestResource.php b/src/Testing/Resources/VectorStoresFileBatchesTestResource.php index f45e66cc..9fe488dd 100644 --- a/src/Testing/Resources/VectorStoresFileBatchesTestResource.php +++ b/src/Testing/Resources/VectorStoresFileBatchesTestResource.php @@ -32,7 +32,7 @@ public function create(string $vectorStoreId, array $parameters): VectorStoreFil return $this->record(__FUNCTION__, func_get_args()); } - public function listFiles(string $vectorStoreId, string $fileBatchId): VectorStoreFileListResponse + public function listFiles(string $vectorStoreId, string $fileBatchId, array $parameters = []): VectorStoreFileListResponse { return $this->record(__FUNCTION__, func_get_args()); } diff --git a/src/Testing/Resources/VectorStoresFilesTestResource.php b/src/Testing/Resources/VectorStoresFilesTestResource.php index d0652362..3b927d1f 100644 --- a/src/Testing/Resources/VectorStoresFilesTestResource.php +++ b/src/Testing/Resources/VectorStoresFilesTestResource.php @@ -33,7 +33,7 @@ public function create(string $vectorStoreId, array $parameters): VectorStoreFil return $this->record(__FUNCTION__, func_get_args()); } - public function list(string $vectorStoreId): VectorStoreFileListResponse + public function list(string $vectorStoreId, array $parameters = []): VectorStoreFileListResponse { return $this->record(__FUNCTION__, func_get_args()); } diff --git a/src/Testing/Resources/VectorStoresTestResource.php b/src/Testing/Resources/VectorStoresTestResource.php index fd92ce4e..01feeebc 100644 --- a/src/Testing/Resources/VectorStoresTestResource.php +++ b/src/Testing/Resources/VectorStoresTestResource.php @@ -20,17 +20,17 @@ public function resource(): string return VectorStores::class; } - public function modify(string $vectorStore, array $parameters): VectorStoreResponse + public function modify(string $vectorStoreId, array $parameters): VectorStoreResponse { return $this->record(__FUNCTION__, func_get_args()); } - public function retrieve(string $vectorStore): VectorStoreResponse + public function retrieve(string $vectorStoreId): VectorStoreResponse { return $this->record(__FUNCTION__, func_get_args()); } - public function delete(string $vectorStore): VectorStoreDeleteResponse + public function delete(string $vectorStoreId): VectorStoreDeleteResponse { return $this->record(__FUNCTION__, func_get_args()); } @@ -40,7 +40,7 @@ public function create(array $parameters): VectorStoreResponse return $this->record(__FUNCTION__, func_get_args()); } - public function list(): VectorStoreListResponse + public function list(array $parameters = []): VectorStoreListResponse { return $this->record(__FUNCTION__, func_get_args()); } From a428fcd48267371442201539b4f37e253bf1cf81 Mon Sep 17 00:00:00 2001 From: Sandro Gehri Date: Thu, 6 Jun 2024 22:22:23 +0200 Subject: [PATCH 14/15] Add Vector Store documentation --- README.md | 333 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 333 insertions(+) diff --git a/README.md b/README.md index df1486a3..e4357ed5 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,9 @@ - [Threads Messages Resource](#threads-messages-resource) - [Threads Runs Resource](#threads-runs-resource) - [Threads Runs Steps Resource](#threads-runs-steps-resource) + - [Vector Stores Resource](#vector-stores-resource) + - [Vector Stores Files Resource](#vector-store-files-resource) + - [Vector Stores File Batches Resource](#vector-store-file-batches-resource) - [Batches Resource](#batches-resource) - [FineTunes Resource (deprecated)](#finetunes-resource-deprecated) - [Edits Resource (deprecated)](#edits-resource-deprecated) @@ -1820,6 +1823,336 @@ foreach ($response->data as $result) { $response->toArray(); // ['object' => 'list', ...]] ``` + +### `Vector Stores` Resource + +#### `create` + +Create a vector store. + +```php +$response = $client->vectorStores()->create([ + 'file_ids' => [ + 'file-fUU0hFRuQ1GzhOweTNeJlCXG', + ], + 'name' => 'My first Vector Store', +]); + +$response->id; // 'vs_vzfQhlTWVUl38QGqQAoQjeDF' +$response->object; // 'vector_store' +$response->createdAt; // 1717703267 +$response->name; // 'My first Vector Store' +$response->usageBytes; // 0 +$response->fileCounts->inProgress; // 1 +$response->fileCounts->completed; // 0 +$response->fileCounts->failed; // 0 +$response->fileCounts->cancelled; // 0 +$response->fileCounts->total; // 1 +$response->status; // 'in_progress' +$response->expiresAfter; // null +$response->expiresAt; // null +$response->lastActiveAt; // 1717703267 + +$response->toArray(); // ['id' => 'vs_vzfQhlTWVUl38QGqQAoQjeDF', ...] +``` + +#### `retrieve` + +Retrieves a vector store. + +```php +$response = $client->vectorStores()->retrieve( + vectorStoreId: 'vs_vzfQhlTWVUl38QGqQAoQjeDF', +); + +$response->id; // 'vs_vzfQhlTWVUl38QGqQAoQjeDF' +$response->object; // 'vector_store' +$response->createdAt; // 1717703267 +$response->name; // 'My first Vector Store' +$response->usageBytes; // 0 +$response->fileCounts->inProgress; // 1 +$response->fileCounts->completed; // 0 +$response->fileCounts->failed; // 0 +$response->fileCounts->cancelled; // 0 +$response->fileCounts->total; // 1 +$response->status; // 'in_progress' +$response->expiresAfter; // null +$response->expiresAt; // null +$response->lastActiveAt; // 1717703267 + +$response->toArray(); // ['id' => 'vs_vzfQhlTWVUl38QGqQAoQjeDF', ...] +``` + +#### `modify` + +Modifies a vector store. + +```php +$response = $client->vectorStores()->modify( + vectorStoreId: 'vs_vzfQhlTWVUl38QGqQAoQjeDF', + parameters: [ + 'name' => 'New name', + ], +); + +$response->id; // 'vs_vzfQhlTWVUl38QGqQAoQjeDF' +$response->object; // 'vector_store' +$response->createdAt; // 1717703267 +$response->name; // 'New name' +$response->usageBytes; // 0 +$response->fileCounts->inProgress; // 1 +$response->fileCounts->completed; // 0 +$response->fileCounts->failed; // 0 +$response->fileCounts->cancelled; // 0 +$response->fileCounts->total; // 1 +$response->status; // 'in_progress' +$response->expiresAfter; // null +$response->expiresAt; // null +$response->lastActiveAt; // 1717703267 + +$response->toArray(); // ['id' => 'vs_vzfQhlTWVUl38QGqQAoQjeDF', ...] +``` + +#### `delete` + +Delete a vector store. + +```php +$response = $client->vectorStores()->delete( + vectorStoreId: 'vs_vzfQhlTWVUl38QGqQAoQjeDF', +); + +$response->id; // 'vs_vzfQhlTWVUl38QGqQAoQjeDF' +$response->object; // 'vector_store.deleted' +$response->deleted; // true + +$response->toArray(); // ['id' => 'vs_vzfQhlTWVUl38QGqQAoQjeDF', ...] +``` + +#### `list` + +Returns a list of vector stores. + +```php +$response = $client->vectorStores()->list( + parameters: [ + 'limit' => 10, + ], +); + +$response->object; // 'list' +$response->firstId; // 'vs_vzfQhlTWVUl38QGqQAoQjeDF' +$response->lastId; // 'vs_D5DPOgBxSoEBTmYBgUESdPpa' +$response->hasMore; // true + +foreach ($response->data as $result) { + $result->id; // 'vs_vzfQhlTWVUl38QGqQAoQjeDF' + // ... +} + +$response->toArray(); // ['object' => 'list', ...]] +``` + + +### `Vector Store Files` Resource + +#### `create` + +Create a vector store file by attaching a File to a vector store. + +```php +$response = $client->vectorStores()->files()->create( + vectorStoreId: 'vs_vzfQhlTWVUl38QGqQAoQjeDF', + parameters: [ + 'file_id' => 'file-fUU0hFRuQ1GzhOweTNeJlCXG', + ] +); + +$response->id; // 'file-fUU0hFRuQ1GzhOweTNeJlCXG' +$response->object; // 'vector_store.file' +$response->usageBytes; // 4553 +$response->createdAt; // 1717703267 +$response->vectorStoreId; // 'vs_vzfQhlTWVUl38QGqQAoQjeDF' +$response->status; // 'completed' +$response->lastError; // null +$response->chunkingStrategy->type; // 'static' +$response->chunkingStrategy->maxChunkSizeTokens; // 800 +$response->chunkingStrategy->chunkOverlapTokens; // 400 + +$response->toArray(); // ['id' => 'file-fUU0hFRuQ1GzhOweTNeJlCXG', ...] +``` + +#### `retrieve` + +Retrieves a vector store file. + +```php +$response = $client->vectorStores()->files()->retrieve( + vectorStoreId: 'vs_vzfQhlTWVUl38QGqQAoQjeDF', + fileId: 'file-fUU0hFRuQ1GzhOweTNeJlCXG', +); + +$response->id; // 'file-fUU0hFRuQ1GzhOweTNeJlCXG' +$response->object; // 'vector_store.file' +$response->usageBytes; // 4553 +$response->createdAt; // 1717703267 +$response->vectorStoreId; // 'vs_vzfQhlTWVUl38QGqQAoQjeDF' +$response->status; // 'completed' +$response->lastError; // null +$response->chunkingStrategy->type; // 'static' +$response->chunkingStrategy->maxChunkSizeTokens; // 800 +$response->chunkingStrategy->chunkOverlapTokens; // 400 + +$response->toArray(); // ['id' => 'file-fUU0hFRuQ1GzhOweTNeJlCXG', ...] +``` + +#### `delete` + +Delete a vector store file. This will remove the file from the vector store but the file itself will not be deleted. To delete the file, use the delete file endpoint. + +```php +$response = $client->vectorStores()->files()->delete( + vectorStoreId: 'vs_vzfQhlTWVUl38QGqQAoQjeDF', + fileId: 'file-fUU0hFRuQ1GzhOweTNeJlCXG', +); + +$response->id; // 'file-fUU0hFRuQ1GzhOweTNeJlCXG' +$response->object; // 'vector_store.file.deleted' +$response->deleted; // true + +$response->toArray(); // ['id' => 'file-fUU0hFRuQ1GzhOweTNeJlCXG', ...] +``` + +#### `list` + +Returns a list of vector store files. + +```php +$response = $client->vectorStores()->files()->list( + vectorStoreId: 'vs_vzfQhlTWVUl38QGqQAoQjeDF', + parameters: [ + 'limit' => 10, + ], +); + +$response->object; // 'list' +$response->firstId; // 'file-fUU0hFRuQ1GzhOweTNeJlCXG' +$response->lastId; // 'file-D5DPOgBxSoEBTmYBgUESdPpa' +$response->hasMore; // true + +foreach ($response->data as $result) { + $result->id; // 'file-fUU0hFRuQ1GzhOweTNeJlCXG' + // ... +} + +$response->toArray(); // ['object' => 'list', ...]] +``` + + +### `Vector Store File Batches` Resource + +#### `create` + +Create a vector store file batch. + +```php +$response = $client->vectorStores()->batches()->create( + vectorStoreId: 'vs_vzfQhlTWVUl38QGqQAoQjeDF', + parameters: [ + 'file_ids' => [ + 'file-fUU0hFRuQ1GzhOweTNeJlCXG', + ], + ] +); + +$response->id; // 'vsfb_123' +$response->object; // 'vector_store.files_batch' +$response->createdAt; // 1698107661 +$response->vectorStoreId; // 'vs_vzfQhlTWVUl38QGqQAoQjeDF' +$response->status; // 'completed' +$response->fileCounts->inProgress; // 1 +$response->fileCounts->completed; // 0 +$response->fileCounts->failed; // 0 +$response->fileCounts->cancelled; // 0 +$response->fileCounts->total; // 1 + +$response->toArray(); // ['id' => 'vsfb_123', ...] +``` + +#### `retrieve` + +Retrieves a vector store file batch. + +```php +$response = $client->vectorStores()->batches()->retrieve( + vectorStoreId: 'vs_vzfQhlTWVUl38QGqQAoQjeDF', + fileBatchId: 'vsfb_123', +); + +$response->id; // 'vsfb_123' +$response->object; // 'vector_store.files_batch' +$response->createdAt; // 1698107661 +$response->vectorStoreId; // 'vs_vzfQhlTWVUl38QGqQAoQjeDF' +$response->status; // 'completed' +$response->fileCounts->inProgress; // 1 +$response->fileCounts->completed; // 0 +$response->fileCounts->failed; // 0 +$response->fileCounts->cancelled; // 0 +$response->fileCounts->total; // 1 + +$response->toArray(); // ['id' => 'vsfb_123', ...] +``` + +#### `cancel` + +Cancel a vector store file batch. This attempts to cancel the processing of files in this batch as soon as possible. + +```php +$response = $client->vectorStores()->batches()->cancel( + vectorStoreId: 'vs_vzfQhlTWVUl38QGqQAoQjeDF', + fileBatchId: 'vsfb_123', +); + +$response->id; // 'vsfb_123' +$response->object; // 'vector_store.files_batch' +$response->createdAt; // 1698107661 +$response->vectorStoreId; // 'vs_vzfQhlTWVUl38QGqQAoQjeDF' +$response->status; // 'cancelling' +$response->fileCounts->inProgress; // 1 +$response->fileCounts->completed; // 0 +$response->fileCounts->failed; // 0 +$response->fileCounts->cancelled; // 0 +$response->fileCounts->total; // 1 + +$response->toArray(); // ['id' => 'vsfb_123', ...] +``` + +#### `list` + +Returns a list of vector store files. + +```php +$response = $client->vectorStores()->batches()->listFiles( + vectorStoreId: 'vs_vzfQhlTWVUl38QGqQAoQjeDF', + fileBatchId: 'vsfb_123', + parameters: [ + 'limit' => 10, + ], +); + +$response->object; // 'list' +$response->firstId; // 'file-fUU0hFRuQ1GzhOweTNeJlCXG' +$response->lastId; // 'file-D5DPOgBxSoEBTmYBgUESdPpa' +$response->hasMore; // true + +foreach ($response->data as $result) { + $result->id; // 'file-fUU0hFRuQ1GzhOweTNeJlCXG' + // ... +} + +$response->toArray(); // ['object' => 'list', ...]] +``` + ### `Edits` Resource (deprecated) > OpenAI has deprecated the Edits API and will stop working by January 4, 2024. From 8b63d27a2f009a7ce4714fda77769e93d883c8da Mon Sep 17 00:00:00 2001 From: Sandro Gehri Date: Thu, 6 Jun 2024 22:27:51 +0200 Subject: [PATCH 15/15] release: v0.10.1 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 99bf0fbd..85e743ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## v0.10.1 (2024-06-06) +### Added +- Add support for Assistants API v2 and Vector Stores endpoints ([#420](https://github.com/openai-php/client/pull/420)) + +### Docs +- Add vector store endpoints documentation ([#420](https://github.com/openai-php/client/pull/420)) + ## v0.10.0-beta.1 (2024-05-27) ### Added - Add support for Assistants API v2 and Vector Stores endpoint ([#405](https://github.com/openai-php/client/pull/405))