diff --git a/README.md b/README.md index 8ad65705..95569b4d 100644 --- a/README.md +++ b/README.md @@ -526,6 +526,15 @@ foreach ($response->data as $result) { $response->toArray(); // ['object' => 'list', 'data' => [...]] ``` +You can pass additional parameters to the `listJobs` method to narrow down the results. + +```php +$response = $client->fineTuning()->listJobs([ + 'limit' => 3, // Number of jobs to retrieve (Default: 20) + 'after' => 'ft-AF1WoRqd3aJAHsqc9NY7iL8F', // Identifier for the last job from the previous pagination request. +]); +``` + #### `retrieve job` Get info about a fine-tuning job. diff --git a/src/Contracts/Resources/FineTuningContract.php b/src/Contracts/Resources/FineTuningContract.php index 7c71950a..96e0ead8 100644 --- a/src/Contracts/Resources/FineTuningContract.php +++ b/src/Contracts/Resources/FineTuningContract.php @@ -22,9 +22,11 @@ public function createJob(array $parameters): RetrieveJobResponse; /** * List your organization's fine-tuning jobs. * - * @see TODO: There is no official documentation yet + * @see https://platform.openai.com/docs/api-reference/fine-tuning/undefined + * + * @param array $parameters */ - public function listJobs(): ListJobsResponse; + public function listJobs(array $parameters = []): ListJobsResponse; /** * Get info about a fine-tuning job. diff --git a/src/Resources/FineTuning.php b/src/Resources/FineTuning.php index b718fc18..9ddd6293 100644 --- a/src/Resources/FineTuning.php +++ b/src/Resources/FineTuning.php @@ -37,13 +37,15 @@ public function createJob(array $parameters): RetrieveJobResponse /** * List your organization's fine-tuning jobs. * - * @see TODO: There is no official documentation yet + * @see https://platform.openai.com/docs/api-reference/fine-tuning/undefined + * + * @param array $parameters */ - public function listJobs(): ListJobsResponse + public function listJobs(array $parameters = []): ListJobsResponse { - $payload = Payload::list('fine_tuning/jobs'); + $payload = Payload::list('fine_tuning/jobs', $parameters); - /** @var Response, status: string, validation_file: ?string, training_file: string, trained_tokens: ?int}>}> $response */ + /** @var Response, status: string, validation_file: ?string, training_file: string, trained_tokens: ?int}>, has_more: bool}> $response */ $response = $this->transporter->requestObject($payload); return ListJobsResponse::from($response->data(), $response->meta()); @@ -52,7 +54,7 @@ public function listJobs(): ListJobsResponse /** * Gets info about the fine-tune job. * - * @see https://platform.openai.com/docs/api-reference/fine-tunes/list + * @see https://platform.openai.com/docs/api-reference/fine-tuning/retrieve */ public function retrieveJob(string $jobId): RetrieveJobResponse { @@ -90,7 +92,7 @@ public function listJobEvents(string $jobId, array $parameters = []): ListJobEve { $payload = Payload::retrieve('fine_tuning/jobs', $jobId, '/events', $parameters); - /** @var Response}> $response */ + /** @var Response, has_more: bool}> $response */ $response = $this->transporter->requestObject($payload); return ListJobEventsResponse::from($response->data(), $response->meta()); diff --git a/src/Responses/FineTuning/ListJobEventsResponse.php b/src/Responses/FineTuning/ListJobEventsResponse.php index e8f3081c..bf47b75b 100644 --- a/src/Responses/FineTuning/ListJobEventsResponse.php +++ b/src/Responses/FineTuning/ListJobEventsResponse.php @@ -12,12 +12,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}> + * @implements ResponseContract, has_more: bool}> */ final class ListJobEventsResponse implements ResponseContract, ResponseHasMetaInformationContract { /** - * @use ArrayAccessible}> + * @use ArrayAccessible, has_more: bool}> */ use ArrayAccessible; @@ -30,6 +30,7 @@ final class ListJobEventsResponse implements ResponseContract, ResponseHasMetaIn private function __construct( public readonly string $object, public readonly array $data, + public readonly bool $hasMore, private readonly MetaInformation $meta, ) { } @@ -37,7 +38,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{object: string, data: array} $attributes + * @param array{object: string, data: array, has_more: bool} $attributes */ public static function from(array $attributes, MetaInformation $meta): self { @@ -48,6 +49,7 @@ public static function from(array $attributes, MetaInformation $meta): self return new self( $attributes['object'], $data, + $attributes['has_more'], $meta, ); } @@ -63,6 +65,7 @@ public function toArray(): array static fn (ListJobEventsResponseEvent $response): array => $response->toArray(), $this->data, ), + 'has_more' => $this->hasMore, ]; } } diff --git a/src/Responses/FineTuning/ListJobsResponse.php b/src/Responses/FineTuning/ListJobsResponse.php index ba83a023..77c259b3 100644 --- a/src/Responses/FineTuning/ListJobsResponse.php +++ b/src/Responses/FineTuning/ListJobsResponse.php @@ -12,12 +12,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract, status: string, validation_file: ?string, training_file: string, trained_tokens: ?int}>}> + * @implements ResponseContract, status: string, validation_file: ?string, training_file: string, trained_tokens: ?int}>, has_more: bool}> */ final class ListJobsResponse implements ResponseContract, ResponseHasMetaInformationContract { /** - * @use ArrayAccessible, status: string, validation_file: ?string, training_file: string, trained_tokens: ?int}>}> + * @use ArrayAccessible, status: string, validation_file: ?string, training_file: string, trained_tokens: ?int}>, has_more: bool}> */ use ArrayAccessible; @@ -30,6 +30,7 @@ final class ListJobsResponse implements ResponseContract, ResponseHasMetaInforma private function __construct( public readonly string $object, public readonly array $data, + public readonly bool $hasMore, private readonly MetaInformation $meta, ) { } @@ -37,7 +38,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{object: string, data: array, status: string, validation_file: ?string, training_file: string, trained_tokens: ?int}>} $attributes + * @param array{object: string, data: array, status: string, validation_file: ?string, training_file: string, trained_tokens: ?int}>, has_more: bool} $attributes */ public static function from(array $attributes, MetaInformation $meta): self { @@ -49,6 +50,7 @@ public static function from(array $attributes, MetaInformation $meta): self return new self( $attributes['object'], $data, + $attributes['has_more'], $meta, ); } @@ -64,6 +66,7 @@ public function toArray(): array static fn (RetrieveJobResponse $response): array => $response->toArray(), $this->data, ), + 'has_more' => $this->hasMore, ]; } } diff --git a/src/Testing/Resources/FineTuningTestResource.php b/src/Testing/Resources/FineTuningTestResource.php index 28e67c98..2981c39e 100644 --- a/src/Testing/Resources/FineTuningTestResource.php +++ b/src/Testing/Resources/FineTuningTestResource.php @@ -23,7 +23,7 @@ public function createJob(array $parameters): RetrieveJobResponse return $this->record(__FUNCTION__, $parameters); } - public function listJobs(): ListJobsResponse + public function listJobs(array $parameters = []): ListJobsResponse { return $this->record(__FUNCTION__); } diff --git a/src/Testing/Responses/Fixtures/FineTuning/ListJobEventsResponseFixture.php b/src/Testing/Responses/Fixtures/FineTuning/ListJobEventsResponseFixture.php index 67a9345e..583a377e 100644 --- a/src/Testing/Responses/Fixtures/FineTuning/ListJobEventsResponseFixture.php +++ b/src/Testing/Responses/Fixtures/FineTuning/ListJobEventsResponseFixture.php @@ -17,5 +17,6 @@ final class ListJobEventsResponseFixture 'type' => 'message', ], ], + 'has_more' => false, ]; } diff --git a/src/Testing/Responses/Fixtures/FineTuning/ListJobsResponseFixture.php b/src/Testing/Responses/Fixtures/FineTuning/ListJobsResponseFixture.php index 7fb18133..7ceebe82 100644 --- a/src/Testing/Responses/Fixtures/FineTuning/ListJobsResponseFixture.php +++ b/src/Testing/Responses/Fixtures/FineTuning/ListJobsResponseFixture.php @@ -9,5 +9,6 @@ final class ListJobsResponseFixture 'data' => [ RetrieveJobResponseFixture::ATTRIBUTES, ], + 'has_more' => false, ]; } diff --git a/src/ValueObjects/Transporter/Payload.php b/src/ValueObjects/Transporter/Payload.php index 5d5497bf..3533e96e 100644 --- a/src/ValueObjects/Transporter/Payload.php +++ b/src/ValueObjects/Transporter/Payload.php @@ -34,14 +34,16 @@ private function __construct( /** * Creates a new Payload value object from the given parameters. + * + * @param array $parameters */ - public static function list(string $resource): self + public static function list(string $resource, array $parameters = []): self { $contentType = ContentType::JSON; $method = Method::GET; $uri = ResourceUri::list($resource); - return new self($contentType, $method, $uri); + return new self($contentType, $method, $uri, $parameters); } /** diff --git a/tests/Fixtures/FineTuning.php b/tests/Fixtures/FineTuning.php index 46a0e33d..52e559e3 100644 --- a/tests/Fixtures/FineTuning.php +++ b/tests/Fixtures/FineTuning.php @@ -61,6 +61,7 @@ function fineTuningJobListResource(): array fineTuningJobRetrieveResource(), fineTuningJobRetrieveResource(), ], + 'has_more' => false, ]; } @@ -111,5 +112,6 @@ function fineTuningJobListEventsResource(): array fineTuningJobMessageEventResource(), fineTuningJobMetricsEventResource(), ], + 'has_more' => true, ]; } diff --git a/tests/Resources/FineTuning.php b/tests/Resources/FineTuning.php index 4c5e9026..531d2d9d 100644 --- a/tests/Resources/FineTuning.php +++ b/tests/Resources/FineTuning.php @@ -63,6 +63,17 @@ ->toBeInstanceOf(MetaInformation::class); }); +test('list jobs with params', function () { + $client = mockClient('GET', 'fine_tuning/jobs', [], \OpenAI\ValueObjects\Transporter\Response::from(fineTuningJobListResource(), metaHeaders())); + + $result = $client->fineTuning()->listJobs(['limit' => 3]); + + expect($result) + ->toBeInstanceOf(ListJobsResponse::class) + ->data->toBeArray()->toHaveCount(2) + ->data->each->toBeInstanceOf(RetrieveJobResponse::class); +}); + test('retrieve job', function () { $client = mockClient('GET', 'fine_tuning/jobs/ft-AF1WoRqd3aJAHsqc9NY7iL8F', [], \OpenAI\ValueObjects\Transporter\Response::from(fineTuningJobRetrieveResource(), metaHeaders())); diff --git a/tests/Responses/FineTuning/ListJobEventsResponse.php b/tests/Responses/FineTuning/ListJobEventsResponse.php index e52e381b..ba8461a0 100644 --- a/tests/Responses/FineTuning/ListJobEventsResponse.php +++ b/tests/Responses/FineTuning/ListJobEventsResponse.php @@ -12,6 +12,7 @@ ->object->toBe('list') ->data->toBeArray()->toHaveCount(2) ->data->each->toBeInstanceOf(ListJobEventsResponseEvent::class) + ->hasMore->toBeTrue() ->meta()->toBeInstanceOf(MetaInformation::class); }); diff --git a/tests/Responses/FineTuning/ListJobsResponse.php b/tests/Responses/FineTuning/ListJobsResponse.php index 090ce0dd..41d294ad 100644 --- a/tests/Responses/FineTuning/ListJobsResponse.php +++ b/tests/Responses/FineTuning/ListJobsResponse.php @@ -12,6 +12,7 @@ ->object->toBe('list') ->data->toBeArray()->toHaveCount(2) ->data->each->toBeInstanceOf(RetrieveJobResponse::class) + ->hasMore->toBeFalse() ->meta()->toBeInstanceOf(MetaInformation::class); });