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 () {