From 640a251c0dc500362990b949ffe40e1591a0601f Mon Sep 17 00:00:00 2001 From: Sandro Gehri <sandrogehri@gmail.com> Date: Thu, 6 Jun 2024 21:34:56 +0200 Subject: [PATCH] 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<array{object: string, data: array<int, array{id: string, object: string, usage_bytes: int, created_at: int, vector_store_id: string, status: string, last_error: ?array{code: string, message: string}}>, first_id: ?string, last_id: ?string, has_more: bool}> $response */ + /** @var Response<array{object: string, data: array<int, 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'}}>, 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<array{id: string, object: string, usage_bytes: int, created_at: int, vector_store_id: string, status: string, last_error: ?array{code: string, message: string}}> $response */ + /** @var Response<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'}}> $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<array{object: string, data: array<int, array{id: string, object: string, usage_bytes: int, created_at: int, vector_store_id: string, status: string, last_error: ?array{code: string, message: string}}>, first_id: ?string, last_id: ?string, has_more: bool}> $response */ + /** @var Response<array{object: string, data: array<int, 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'}}>, 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<array{id: string, object: string, usage_bytes: int, created_at: int, vector_store_id: string, status: string, last_error: ?array{code: string, message: string}}> $response */ + /** @var Response<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'}}> $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<int, array{id: string, object: string, usage_bytes: int, created_at: int, vector_store_id: string, status: string, last_error: ?array{code: string, message: string}}>, first_id: ?string, last_id: ?string, has_more: bool} $attributes + * @param array{object: string, data: array<int, 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'}}>, 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<array{id: string, object: string, usage_bytes: int, created_at: int, vector_store_id: string, status: string, last_error: ?array{code: string, message: string}}> + * @implements ResponseContract<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'}}> */ final class VectorStoreFileResponse implements ResponseContract, ResponseHasMetaInformationContract { /** - * @use ArrayAccessible<array{id: string, object: string, usage_bytes: int, created_at: int, vector_store_id: string, status: string, last_error: ?array{code: string, message: string}}> + * @use ArrayAccessible<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'}}> */ 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 @@ +<?php + +declare(strict_types=1); + +namespace OpenAI\Responses\VectorStores\Files; + +use OpenAI\Contracts\ResponseContract; +use OpenAI\Responses\Concerns\ArrayAccessible; +use OpenAI\Testing\Responses\Concerns\Fakeable; + +/** + * @implements ResponseContract<array{type: 'other'}> + */ +final class VectorStoreFileResponseChunkingStrategyOther implements ResponseContract +{ + /** + * @use ArrayAccessible<array{type: 'other'}> + */ + 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 @@ +<?php + +declare(strict_types=1); + +namespace OpenAI\Responses\VectorStores\Files; + +use OpenAI\Contracts\ResponseContract; +use OpenAI\Responses\Concerns\ArrayAccessible; +use OpenAI\Testing\Responses\Concerns\Fakeable; + +/** + * @implements ResponseContract<array{type: 'static', static: array{max_chunk_size_tokens: int, chunk_overlap_tokens: int}}> + */ +final class VectorStoreFileResponseChunkingStrategyStatic implements ResponseContract +{ + /** + * @use ArrayAccessible<array{type: 'static', static: array{max_chunk_size_tokens: int, chunk_overlap_tokens: int}}> + */ + 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 @@ <?php use OpenAI\Responses\VectorStores\Files\VectorStoreFileResponse; +use OpenAI\Responses\VectorStores\Files\VectorStoreFileResponseChunkingStrategyStatic; test('from', function () { $result = VectorStoreFileResponse::from(vectorStoreFileResource(), meta()); @@ -12,7 +13,11 @@ ->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 () {