Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
WIP: add tests
Browse files Browse the repository at this point in the history
gehrisandro committed Nov 10, 2023
1 parent 71947dd commit 255660f
Showing 14 changed files with 326 additions and 67 deletions.
8 changes: 4 additions & 4 deletions src/Resources/Assistants.php
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@ public function create(array $parameters): AssistantResponse
{
$payload = Payload::create('assistants', $parameters);

/** @var Response<array{id: string, object: string, created_at: int, name: ?string, description: ?string, model: string, instructions: ?string, tools: array<int, array{type: 'code_interpreter'}|array{type: 'retrieval'}|array{type: 'function', function: array{description: string, name: string, parameters: string}}>, file_ids: array<int, string>, metadata: array<string, string>}> $response */
/** @var Response<array{id: string, object: string, created_at: int, name: ?string, description: ?string, model: string, instructions: ?string, tools: array<int, array{type: 'code_interpreter'}|array{type: 'retrieval'}|array{type: 'function', function: array{description: string, name: string, parameters: array<string, mixed>}}>, file_ids: array<int, string>, metadata: array<string, string>}> $response */
$response = $this->transporter->requestObject($payload);

return AssistantResponse::from($response->data(), $response->meta());
@@ -42,7 +42,7 @@ public function retrieve(string $id): AssistantResponse
{
$payload = Payload::retrieve('assistants', $id);

/** @var Response<array{id: string, object: string, created_at: int, name: ?string, description: ?string, model: string, instructions: ?string, tools: array<int, array{type: 'code_interpreter'}|array{type: 'retrieval'}|array{type: 'function', function: array{description: string, name: string, parameters: string}}>, file_ids: array<int, string>, metadata: array<string, string>}> $response */
/** @var Response<array{id: string, object: string, created_at: int, name: ?string, description: ?string, model: string, instructions: ?string, tools: array<int, array{type: 'code_interpreter'}|array{type: 'retrieval'}|array{type: 'function', function: array{description: string, name: string, parameters: array<string, mixed>}}>, file_ids: array<int, string>, metadata: array<string, string>}> $response */
$response = $this->transporter->requestObject($payload);

return AssistantResponse::from($response->data(), $response->meta());
@@ -59,7 +59,7 @@ public function modify(string $id, array $parameters): AssistantResponse
{
$payload = Payload::modify('assistants', $id, $parameters);

/** @var Response<array{id: string, object: string, created_at: int, name: ?string, description: ?string, model: string, instructions: ?string, tools: array<int, array{type: 'code_interpreter'}|array{type: 'retrieval'}|array{type: 'function', function: array{description: string, name: string, parameters: string}}>, file_ids: array<int, string>, metadata: array<string, string>}> $response */
/** @var Response<array{id: string, object: string, created_at: int, name: ?string, description: ?string, model: string, instructions: ?string, tools: array<int, array{type: 'code_interpreter'}|array{type: 'retrieval'}|array{type: 'function', function: array{description: string, name: string, parameters: array<string, mixed>}}>, file_ids: array<int, string>, metadata: array<string, string>}> $response */
$response = $this->transporter->requestObject($payload);

return AssistantResponse::from($response->data(), $response->meta());
@@ -91,7 +91,7 @@ public function list(array $parameters = []): AssistantListResponse
{
$payload = Payload::list('assistants', $parameters);

/** @var Response<array{object: string, data: array<int, array{id: string, object: string, created_at: int, name: ?string, description: ?string, model: string, instructions: ?string, tools: array<int, array{type: 'code_interpreter'}|array{type: 'retrieval'}|array{type: 'function', function: array{description: string, name: string, parameters: string}}>, file_ids: array<int, string>, metadata: array<string, string>}>, first_id: ?string, last_id: ?string, has_more: bool}> $response */
/** @var Response<array{object: string, data: array<int, array{id: string, object: string, created_at: int, name: ?string, description: ?string, model: string, instructions: ?string, tools: array<int, array{type: 'code_interpreter'}|array{type: 'retrieval'}|array{type: 'function', function: array{description: string, name: string, parameters: array<string, mixed>}}>, file_ids: array<int, string>, metadata: array<string, string>}>, first_id: ?string, last_id: ?string, has_more: bool}> $response */
$response = $this->transporter->requestObject($payload);

return AssistantListResponse::from($response->data(), $response->meta());
2 changes: 1 addition & 1 deletion src/Resources/Threads.php
Original file line number Diff line number Diff line change
@@ -46,7 +46,7 @@ public function createAndRun(array $parameters): ThreadRunResponse
{
$payload = Payload::create('threads/runs', $parameters);

/** @var Response<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<int, array{id: string, type: string, function: array{name: string, arguments: string}}>}}, 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<int, array{type: 'code_interpreter'}|array{type: 'retrieval'}|array{type: 'function', function: array{description: string, name: string, parameters: string}}>, file_ids: array<int, string>, metadata: array<string, string>}> $response */
/** @var Response<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<int, array{id: string, type: string, function: array{name: string, arguments: string}}>}}, 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<int, array{type: 'code_interpreter'}|array{type: 'retrieval'}|array{type: 'function', function: array{description: string, name: string, parameters: array<string, mixed>}}>, file_ids: array<int, string>, metadata: array<string, string>}> $response */
$response = $this->transporter->requestObject($payload);

return ThreadRunResponse::from($response->data(), $response->meta());
12 changes: 6 additions & 6 deletions src/Resources/ThreadsRuns.php
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@ public function create(string $threadId, array $parameters): ThreadRunResponse
{
$payload = Payload::create('threads/'.$threadId.'/runs', $parameters);

/** @var Response<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<int, array{id: string, type: string, function: array{name: string, arguments: string}}>}}, 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<int, array{type: 'code_interpreter'}|array{type: 'retrieval'}|array{type: 'function', function: array{description: string, name: string, parameters: string}}>, file_ids: array<int, string>, metadata: array<string, string>}> $response */
/** @var Response<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<int, array{id: string, type: string, function: array{name: string, arguments: string}}>}}, 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<int, array{type: 'code_interpreter'}|array{type: 'retrieval'}|array{type: 'function', function: array{description: string, name: string, parameters: array<string, mixed>}}>, file_ids: array<int, string>, metadata: array<string, string>}> $response */
$response = $this->transporter->requestObject($payload);

return ThreadRunResponse::from($response->data(), $response->meta());
@@ -41,7 +41,7 @@ public function retrieve(string $threadId, string $runId): ThreadRunResponse
{
$payload = Payload::retrieve('threads/'.$threadId.'/runs', $runId);

/** @var Response<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<int, array{id: string, type: string, function: array{name: string, arguments: string}}>}}, 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<int, array{type: 'code_interpreter'}|array{type: 'retrieval'}|array{type: 'function', function: array{description: string, name: string, parameters: string}}>, file_ids: array<int, string>, metadata: array<string, string>}> $response */
/** @var Response<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<int, array{id: string, type: string, function: array{name: string, arguments: string}}>}}, 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<int, array{type: 'code_interpreter'}|array{type: 'retrieval'}|array{type: 'function', function: array{description: string, name: string, parameters: array<string, mixed>}}>, file_ids: array<int, string>, metadata: array<string, string>}> $response */
$response = $this->transporter->requestObject($payload);

return ThreadRunResponse::from($response->data(), $response->meta());
@@ -58,7 +58,7 @@ public function modify(string $threadId, string $runId, array $parameters): Thre
{
$payload = Payload::modify('threads/'.$threadId.'/runs', $runId, $parameters);

/** @var Response<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<int, array{id: string, type: string, function: array{name: string, arguments: string}}>}}, 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<int, array{type: 'code_interpreter'}|array{type: 'retrieval'}|array{type: 'function', function: array{description: string, name: string, parameters: string}}>, file_ids: array<int, string>, metadata: array<string, string>}> $response */
/** @var Response<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<int, array{id: string, type: string, function: array{name: string, arguments: string}}>}}, 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<int, array{type: 'code_interpreter'}|array{type: 'retrieval'}|array{type: 'function', function: array{description: string, name: string, parameters: array<string, mixed>}}>, file_ids: array<int, string>, metadata: array<string, string>}> $response */
$response = $this->transporter->requestObject($payload);

return ThreadRunResponse::from($response->data(), $response->meta());
@@ -75,7 +75,7 @@ public function submitToolOutputs(string $threadId, string $runId, array $parame
{
$payload = Payload::create('threads/'.$threadId.'/runs/'.$runId.'/submit_tool_outputs', $parameters);

/** @var Response<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<int, array{id: string, type: string, function: array{name: string, arguments: string}}>}}, 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<int, array{type: 'code_interpreter'}|array{type: 'retrieval'}|array{type: 'function', function: array{description: string, name: string, parameters: string}}>, file_ids: array<int, string>, metadata: array<string, string>}> $response */
/** @var Response<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<int, array{id: string, type: string, function: array{name: string, arguments: string}}>}}, 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<int, array{type: 'code_interpreter'}|array{type: 'retrieval'}|array{type: 'function', function: array{description: string, name: string, parameters: array<string, mixed>}}>, file_ids: array<int, string>, metadata: array<string, string>}> $response */
$response = $this->transporter->requestObject($payload);

return ThreadRunResponse::from($response->data(), $response->meta());
@@ -90,7 +90,7 @@ public function cancel(string $threadId, string $runId): ThreadRunResponse
{
$payload = Payload::cancel('threads/'.$threadId.'/runs', $runId);

/** @var Response<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<int, array{id: string, type: string, function: array{name: string, arguments: string}}>}}, 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<int, array{type: 'code_interpreter'}|array{type: 'retrieval'}|array{type: 'function', function: array{description: string, name: string, parameters: string}}>, file_ids: array<int, string>, metadata: array<string, string>}> $response */
/** @var Response<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<int, array{id: string, type: string, function: array{name: string, arguments: string}}>}}, 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<int, array{type: 'code_interpreter'}|array{type: 'retrieval'}|array{type: 'function', function: array{description: string, name: string, parameters: array<string, mixed>}}>, file_ids: array<int, string>, metadata: array<string, string>}> $response */
$response = $this->transporter->requestObject($payload);

return ThreadRunResponse::from($response->data(), $response->meta());
@@ -107,7 +107,7 @@ public function list(string $threadId, array $parameters = []): ThreadRunListRes
{
$payload = Payload::list('threads/'.$threadId.'/runs', $parameters);

/** @var Response<array{object: string, data: array<int, 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<int, array{id: string, type: string, function: array{name: string, arguments: string}}>}}, 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<int, array{type: 'code_interpreter'}|array{type: 'retrieval'}|array{type: 'function', function: array{description: string, name: string, parameters: string}}>, file_ids: array<int, string>, metadata: array<string, string>}>, first_id: ?string, last_id: ?string, has_more: bool}> $response */
/** @var Response<array{object: string, data: array<int, 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<int, array{id: string, type: string, function: array{name: string, arguments: string}}>}}, 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<int, array{type: 'code_interpreter'}|array{type: 'retrieval'}|array{type: 'function', function: array{description: string, name: string, parameters: array<string, mixed>}}>, file_ids: array<int, string>, metadata: array<string, string>}>, first_id: ?string, last_id: ?string, has_more: bool}> $response */
$response = $this->transporter->requestObject($payload);

return ThreadRunListResponse::from($response->data(), $response->meta());
6 changes: 3 additions & 3 deletions src/Responses/Assistants/AssistantListResponse.php
Original file line number Diff line number Diff line change
@@ -12,12 +12,12 @@
use OpenAI\Testing\Responses\Concerns\Fakeable;

/**
* @implements ResponseContract<array{object: string, data: array<int, array{id: string, object: string, created_at: int, name: ?string, description: ?string, model: string, instructions: ?string, tools: array<int, array{type: string}|array{type: string}|array{type: string, function: array{description: string, name: string, parameters: string}}>, file_ids: array<int, string>, metadata: array<string, string>}>, first_id: ?string, last_id: ?string, has_more: bool}>
* @implements ResponseContract<array{object: string, data: array<int, array{id: string, object: string, created_at: int, name: ?string, description: ?string, model: string, instructions: ?string, tools: array<int, array{type: string}|array{type: string}|array{type: string, function: array{description: string, name: string, parameters: array<string, mixed>}}>, file_ids: array<int, string>, metadata: array<string, string>}>, first_id: ?string, last_id: ?string, has_more: bool}>
*/
final class AssistantListResponse implements ResponseContract, ResponseHasMetaInformationContract
{
/**
* @use ArrayAccessible<array{object: string, data: array<int, array{id: string, object: string, created_at: int, name: ?string, description: ?string, model: string, instructions: ?string, tools: array<int, array{type: string}|array{type: string}|array{type: string, function: array{description: string, name: string, parameters: string}}>, file_ids: array<int, string>, metadata: array<string, string>}>, first_id: ?string, last_id: ?string, has_more: bool}>
* @use ArrayAccessible<array{object: string, data: array<int, array{id: string, object: string, created_at: int, name: ?string, description: ?string, model: string, instructions: ?string, tools: array<int, array{type: string}|array{type: string}|array{type: string, function: array{description: string, name: string, parameters: array<string, mixed>}}>, file_ids: array<int, string>, metadata: array<string, 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<int, array{id: string, object: string, created_at: int, name: ?string, description: ?string, model: string, instructions: ?string, tools: array<int, array{type: 'code_interpreter'}|array{type: 'retrieval'}|array{type: 'function', function: array{description: string, name: string, parameters: string}}>, file_ids: array<int, string>, metadata: array<string, string>}>, first_id: ?string, last_id: ?string, has_more: bool} $attributes
* @param array{object: string, data: array<int, array{id: string, object: string, created_at: int, name: ?string, description: ?string, model: string, instructions: ?string, tools: array<int, array{type: 'code_interpreter'}|array{type: 'retrieval'}|array{type: 'function', function: array{description: string, name: string, parameters: array<string, mixed>}}>, file_ids: array<int, string>, metadata: array<string, string>}>, first_id: ?string, last_id: ?string, has_more: bool} $attributes
*/
public static function from(array $attributes, MetaInformation $meta): self
{
6 changes: 3 additions & 3 deletions src/Responses/Assistants/AssistantResponse.php
Original file line number Diff line number Diff line change
@@ -12,12 +12,12 @@
use OpenAI\Testing\Responses\Concerns\Fakeable;

/**
* @implements ResponseContract<array{id: string, object: string, created_at: int, name: ?string, description: ?string, model: string, instructions: ?string, tools: array<int, array{type: string}|array{type: string}|array{type: string, function: array{description: string, name: string, parameters: string}}>, file_ids: array<int, string>, metadata: array<string, string>}>
* @implements ResponseContract<array{id: string, object: string, created_at: int, name: ?string, description: ?string, model: string, instructions: ?string, tools: array<int, array{type: string}|array{type: string}|array{type: string, function: array{description: string, name: string, parameters: array<string, mixed>}}>, file_ids: array<int, string>, metadata: array<string, string>}>
*/
final class AssistantResponse implements ResponseContract, ResponseHasMetaInformationContract
{
/**
* @use ArrayAccessible<array{id: string, object: string, created_at: int, name: ?string, description: ?string, model: string, instructions: ?string, tools: array<int, array{type: string}|array{type: string}|array{type: string, function: array{description: string, name: string, parameters: string}}>, file_ids: array<int, string>, metadata: array<string, string>}>
* @use ArrayAccessible<array{id: string, object: string, created_at: int, name: ?string, description: ?string, model: string, instructions: ?string, tools: array<int, array{type: string}|array{type: string}|array{type: string, function: array{description: string, name: string, parameters: array<string, mixed>}}>, file_ids: array<int, string>, metadata: array<string, string>}>
*/
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, name: ?string, description: ?string, model: string, instructions: ?string, tools: array<int, array{type: 'code_interpreter'}|array{type: 'retrieval'}|array{type: 'function', function: array{description: string, name: string, parameters: string}}>, file_ids: array<int, string>, metadata: array<string, string>} $attributes
* @param array{id: string, object: string, created_at: int, name: ?string, description: ?string, model: string, instructions: ?string, tools: array<int, array{type: 'code_interpreter'}|array{type: 'retrieval'}|array{type: 'function', function: array{description: string, name: string, parameters: array<string, mixed>}}>, file_ids: array<int, string>, metadata: array<string, string>} $attributes
*/
public static function from(array $attributes, MetaInformation $meta): self
{
6 changes: 3 additions & 3 deletions src/Responses/Assistants/AssistantResponseToolFunction.php
Original file line number Diff line number Diff line change
@@ -9,12 +9,12 @@
use OpenAI\Testing\Responses\Concerns\Fakeable;

/**
* @implements ResponseContract<array{type: string, function: array{description: string, name: string, parameters: string}}>
* @implements ResponseContract<array{type: string, function: array{description: string, name: string, parameters: array<string, mixed>}}>
*/
final class AssistantResponseToolFunction implements ResponseContract
{
/**
* @use ArrayAccessible<array{type: string, function: array{description: string, name: string, parameters: string}}>
* @use ArrayAccessible<array{type: string, function: array{description: string, name: string, parameters: array<string, mixed>}}>
*/
use ArrayAccessible;

@@ -29,7 +29,7 @@ private function __construct(
/**
* Acts as static factory, and returns a new Response instance.
*
* @param array{type: 'function', function: array{description: string, name: string, parameters: string}} $attributes
* @param array{type: 'function', function: array{description: string, name: string, parameters: array<string, mixed>}} $attributes
*/
public static function from(array $attributes): self
{
Original file line number Diff line number Diff line change
@@ -9,28 +9,31 @@
use OpenAI\Testing\Responses\Concerns\Fakeable;

/**
* @implements ResponseContract<array{description: string, name: string, parameters: string}>
* @implements ResponseContract<array{description: string, name: string, parameters: array<string, mixed>}>
*/
final class AssistantResponseToolFunctionFunction implements ResponseContract
{
/**
* @use ArrayAccessible<array{description: string, name: string, parameters: string}>
* @use ArrayAccessible<array{description: string, name: string, parameters: array<string, mixed>}>
*/
use ArrayAccessible;

use Fakeable;

/**
* @param array<string, mixed> $parameters
*/
private function __construct(
public string $description,
public string $name,
public string $parameters,
public array $parameters,
) {
}

/**
* Acts as static factory, and returns a new Response instance.
*
* @param array{description: string, name: string, parameters: string} $attributes
* @param array{description: string, name: string, parameters: array<string, mixed>} $attributes
*/
public static function from(array $attributes): self
{
6 changes: 3 additions & 3 deletions src/Responses/Threads/Runs/ThreadRunListResponse.php
Original file line number Diff line number Diff line change
@@ -12,12 +12,12 @@
use OpenAI\Testing\Responses\Concerns\Fakeable;

/**
* @implements ResponseContract<array{object: string, data: array<int, 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<int, array{id: string, type: string, function: array{name: string, arguments: string}}>}}, 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<int, array{type: string}|array{type: string}|array{type: string, function: array{description: string, name: string, parameters: string}}>, file_ids: array<int, string>, metadata: array<string, string>}>, first_id: ?string, last_id: ?string, has_more: bool}>
* @implements ResponseContract<array{object: string, data: array<int, 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<int, array{id: string, type: string, function: array{name: string, arguments: string}}>}}, 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<int, array{type: string}|array{type: string}|array{type: string, function: array{description: string, name: string, parameters: array<string, mixed>}}>, file_ids: array<int, string>, metadata: array<string, string>}>, first_id: ?string, last_id: ?string, has_more: bool}>
*/
final class ThreadRunListResponse implements ResponseContract, ResponseHasMetaInformationContract
{
/**
* @use ArrayAccessible<array{object: string, data: array<int, 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<int, array{id: string, type: string, function: array{name: string, arguments: string}}>}}, 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<int, array{type: string}|array{type: string}|array{type: string, function: array{description: string, name: string, parameters: string}}>, file_ids: array<int, string>, metadata: array<string, string>}>, first_id: ?string, last_id: ?string, has_more: bool}>
* @use ArrayAccessible<array{object: string, data: array<int, 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<int, array{id: string, type: string, function: array{name: string, arguments: string}}>}}, 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<int, array{type: string}|array{type: string}|array{type: string, function: array{description: string, name: string, parameters: array<string, mixed>}}>, file_ids: array<int, string>, metadata: array<string, 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<int, 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<int, array{id: string, type: string, function: array{name: string, arguments: string}}>}}, 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<int, array{type: 'code_interpreter'}|array{type: 'retrieval'}|array{type: 'function', function: array{description: string, name: string, parameters: string}}>, file_ids: array<int, string>, metadata: array<string, string>}>, first_id: ?string, last_id: ?string, has_more: bool} $attributes
* @param array{object: string, data: array<int, 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<int, array{id: string, type: string, function: array{name: string, arguments: string}}>}}, 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<int, array{type: 'code_interpreter'}|array{type: 'retrieval'}|array{type: 'function', function: array{description: string, name: string, parameters: array<string, mixed>}}>, file_ids: array<int, string>, metadata: array<string, string>}>, first_id: ?string, last_id: ?string, has_more: bool} $attributes
*/
public static function from(array $attributes, MetaInformation $meta): self
{
6 changes: 3 additions & 3 deletions src/Responses/Threads/Runs/ThreadRunResponse.php
Original file line number Diff line number Diff line change
@@ -12,12 +12,12 @@
use OpenAI\Testing\Responses\Concerns\Fakeable;

/**
* @implements ResponseContract<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<int, array{id: string, type: string, function: array{name: string, arguments: string}}>}}, 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<int, array{type: string}|array{type: string}|array{type: string, function: array{description: string, name: string, parameters: string}}>, file_ids: array<int, string>, metadata: array<string, string>}>
* @implements ResponseContract<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<int, array{id: string, type: string, function: array{name: string, arguments: string}}>}}, 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<int, array{type: string}|array{type: string}|array{type: string, function: array{description: string, name: string, parameters: array<string, mixed>}}>, file_ids: array<int, string>, metadata: array<string, string>}>
*/
final class ThreadRunResponse implements ResponseContract, ResponseHasMetaInformationContract
{
/**
* @use ArrayAccessible<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<int, array{id: string, type: string, function: array{name: string, arguments: string}}>}}, 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<int, array{type: string}|array{type: string}|array{type: string, function: array{description: string, name: string, parameters: string}}>, file_ids: array<int, string>, metadata: array<string, string>}>
* @use ArrayAccessible<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<int, array{id: string, type: string, function: array{name: string, arguments: string}}>}}, 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<int, array{type: string}|array{type: string}|array{type: string, function: array{description: string, name: string, parameters: array<string, mixed>}}>, file_ids: array<int, string>, metadata: array<string, string>}>
*/
use ArrayAccessible;

@@ -55,7 +55,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, assistant_id: string, status: string, required_action?: array{type: string, submit_tool_outputs: array{tool_calls: array<int, array{id: string, type: string, function: array{name: string, arguments: string}}>}}, 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<int, array{type: 'code_interpreter'}|array{type: 'retrieval'}|array{type: 'function', function: array{description: string, name: string, parameters: string}}>, file_ids: array<int, string>, metadata: array<string, string>} $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<int, array{id: string, type: string, function: array{name: string, arguments: string}}>}}, 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<int, array{type: 'code_interpreter'}|array{type: 'retrieval'}|array{type: 'function', function: array{description: string, name: string, parameters: array<string, mixed>}}>, file_ids: array<int, string>, metadata: array<string, string>} $attributes
*/
public static function from(array $attributes, MetaInformation $meta): self
{
6 changes: 3 additions & 3 deletions src/Responses/Threads/Runs/ThreadRunResponseToolFunction.php
Original file line number Diff line number Diff line change
@@ -9,12 +9,12 @@
use OpenAI\Testing\Responses\Concerns\Fakeable;

/**
* @implements ResponseContract<array{type: string, function: array{description: string, name: string, parameters: string}}>
* @implements ResponseContract<array{type: string, function: array{description: string, name: string, parameters: array<string, mixed>}}>
*/
final class ThreadRunResponseToolFunction implements ResponseContract
{
/**
* @use ArrayAccessible<array{type: string, function: array{description: string, name: string, parameters: string}}>
* @use ArrayAccessible<array{type: string, function: array{description: string, name: string, parameters: array<string, mixed>}}>
*/
use ArrayAccessible;

@@ -29,7 +29,7 @@ private function __construct(
/**
* Acts as static factory, and returns a new Response instance.
*
* @param array{type: 'function', function: array{description: string, name: string, parameters: string}} $attributes
* @param array{type: 'function', function: array{description: string, name: string, parameters: array<string, mixed>}} $attributes
*/
public static function from(array $attributes): self
{
Original file line number Diff line number Diff line change
@@ -9,28 +9,31 @@
use OpenAI\Testing\Responses\Concerns\Fakeable;

/**
* @implements ResponseContract<array{description: string, name: string, parameters: string}>
* @implements ResponseContract<array{description: string, name: string, parameters: array<string, mixed>}>
*/
final class ThreadRunResponseToolFunctionFunction implements ResponseContract
{
/**
* @use ArrayAccessible<array{description: string, name: string, parameters: string}>
* @use ArrayAccessible<array{description: string, name: string, parameters: array<string, mixed>}>
*/
use ArrayAccessible;

use Fakeable;

/**
* @param array<string, mixed> $parameters
*/
private function __construct(
public string $description,
public string $name,
public string $parameters,
public array $parameters,
) {
}

/**
* Acts as static factory, and returns a new Response instance.
*
* @param array{description: string, name: string, parameters: string} $attributes
* @param array{description: string, name: string, parameters: array<string, mixed>} $attributes
*/
public static function from(array $attributes): self
{
4 changes: 2 additions & 2 deletions src/Transporters/HttpTransporter.php
Original file line number Diff line number Diff line change
@@ -49,8 +49,8 @@ public function requestObject(Payload $payload): Response
$response = $this->sendRequest(fn (): \Psr\Http\Message\ResponseInterface => $this->client->sendRequest($request));

$contents = $response->getBody()->getContents();
// echo var_export((json_decode($contents, true, 512, JSON_THROW_ON_ERROR)));
// exit();
// echo var_export((json_decode($contents, true, 512, JSON_THROW_ON_ERROR)));
// exit();

if (str_contains($response->getHeaderLine('Content-Type'), ContentType::TEXT_PLAIN->value)) {
return Response::from($contents, $response->getHeaders());
108 changes: 80 additions & 28 deletions tests/Fixtures/ThreadRun.php
Original file line number Diff line number Diff line change
@@ -32,31 +32,83 @@ function threadRunResource(): array
];
}

///**
// * @return array<string, mixed>
// */
//function threadListResource(): array
//{
// return [
// 'object' => 'list',
// 'data' => [
// threadResource(),
// threadResource(),
// ],
// 'first_id' => 'thread_agvtHUGezjTCt4SKgQg0NJ2Y',
// 'last_id' => 'thread_qVpWfffa654XBdU3tl2iUdVy',
// 'has_more' => false,
// ];
//}
//
///**
// * @return array<string, mixed>
// */
//function threadDeleteResource(): array
//{
// return [
// 'id' => 'thread_agvtHUGezjTCt4SKgQg0NJ2Y',
// 'object' => 'thread.deleted',
// 'deleted' => true,
// ];
//}
/**
* @return array<string, mixed>
*/
function threadRunWithSubmitToolOutputsResource(): array
{
return [
'id' => 'run_vqUh7mLCAIYjudfN34dMQx4b',
'object' => 'thread.run',
'created_at' => 1699626348,
'assistant_id' => 'asst_elNhDubXFZcsWQd8GuTu93vZ',
'thread_id' => 'thread_vAG0173KCY4VKDLQakucIszZ',
'status' => 'requires_action',
'started_at' => 1699626349,
'expires_at' => 1699626948,
'cancelled_at' => null,
'failed_at' => null,
'completed_at' => null,
'required_action' => [
'type' => 'submit_tool_outputs',
'submit_tool_outputs' => [
'tool_calls' => [
[
'id' => 'call_KSg14X7kZF2WDzlPhpQ168Mj',
'type' => 'function',
'function' => [
'name' => 'add',
'arguments' => '{ "a": 5, "b": 7 }',
],
],
],
],
],
'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' => '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' => [],
'metadata' => [],
];
}

/**
* @return array<string, mixed>
*/
function threadRunListResource(): array
{
return [
'object' => 'list',
'data' => [
threadRunResource(),
threadRunResource(),
],
'first_id' => 'run_4RCYyYzX9m41WQicoJtUQAb8',
'last_id' => 'run_4RCYyYzX9m41WQicoJtUQAb8',
'has_more' => false,
];
}
201 changes: 201 additions & 0 deletions tests/Resources/ThreadsRuns.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
<?php

use OpenAI\Responses\Meta\MetaInformation;
use OpenAI\Responses\Threads\Runs\ThreadRunListResponse;
use OpenAI\Responses\Threads\Runs\ThreadRunResponse;
use OpenAI\Responses\Threads\Runs\ThreadRunResponseToolCodeInterpreter;
use OpenAI\ValueObjects\Transporter\Response;

test('list', function () {
$client = mockClient('GET', 'threads/thread_agvtHUGezjTCt4SKgQg0NJ2Y/runs', [], Response::from(threadRunListResource(), metaHeaders()));

$result = $client->threads()->runs()->list('thread_agvtHUGezjTCt4SKgQg0NJ2Y');

expect($result)
->toBeInstanceOf(ThreadRunListResponse::class)
->object->toBe('list')
->data->toBeArray()->toHaveCount(2)
->data->each->toBeInstanceOf(ThreadRunResponse::class)
->firstId->toBe('run_4RCYyYzX9m41WQicoJtUQAb8')
->lastId->toBe('run_4RCYyYzX9m41WQicoJtUQAb8')
->hasMore->toBeFalse();

expect($result->meta())
->toBeInstanceOf(MetaInformation::class);
});

test('create', function () {
$client = mockClient('POST', 'threads/thread_agvtHUGezjTCt4SKgQg0NJ2Y/runs', [
'assistant_id' => 'asst_SMzoVX8XmCZEg1EbMHoAm8tc',
], Response::from(threadRunResource(), metaHeaders()));

$result = $client->threads()->runs()->create('thread_agvtHUGezjTCt4SKgQg0NJ2Y', [
'assistant_id' => 'asst_SMzoVX8XmCZEg1EbMHoAm8tc',
]);

expect($result)
->toBeInstanceOf(ThreadRunResponse::class)
->id->toBe('run_4RCYyYzX9m41WQicoJtUQAb8')
->object->toBe('thread.run')
->createdAt->toBe(1699621735)
->assistantId->toBe('asst_EopvUEMh90bxkNRYEYM81Orc')
->threadId->toBe('thread_EKt7MjGOC6bwKWmenQv5VD6r')
->status->toBe('queued')
->startedAt->toBeNull()
->expiresAt->toBe(1699622335)
->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()->toHaveCount(1)
->tools->each->toBeInstanceOf(ThreadRunResponseToolCodeInterpreter::class)
->fileIds->toBeArray()->toHaveCount(1)
->metadata->toBeArray()->toBeEmpty();

expect($result->meta())
->toBeInstanceOf(MetaInformation::class);
});

test('modify', function () {
$client = mockClient('POST', 'threads/thread_agvtHUGezjTCt4SKgQg0NJ2Y/runs/run_4RCYyYzX9m41WQicoJtUQAb8', [
'metadata' => [
'name' => 'My new run name',
],
], Response::from(threadRunResource(), metaHeaders()));

$result = $client->threads()->runs()->modify('thread_agvtHUGezjTCt4SKgQg0NJ2Y', 'run_4RCYyYzX9m41WQicoJtUQAb8', [
'metadata' => [
'name' => 'My new run name',
],
]);

expect($result)
->toBeInstanceOf(ThreadRunResponse::class)
->id->toBe('run_4RCYyYzX9m41WQicoJtUQAb8')
->object->toBe('thread.run')
->createdAt->toBe(1699621735)
->assistantId->toBe('asst_EopvUEMh90bxkNRYEYM81Orc')
->threadId->toBe('thread_EKt7MjGOC6bwKWmenQv5VD6r')
->status->toBe('queued')
->startedAt->toBeNull()
->expiresAt->toBe(1699622335)
->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()->toHaveCount(1)
->tools->each->toBeInstanceOf(ThreadRunResponseToolCodeInterpreter::class)
->fileIds->toBeArray()->toHaveCount(1)
->metadata->toBeArray()->toBeEmpty();

expect($result->meta())
->toBeInstanceOf(MetaInformation::class);
});

test('retrieve', function () {
$client = mockClient('GET', 'threads/thread_agvtHUGezjTCt4SKgQg0NJ2Y/runs/run_4RCYyYzX9m41WQicoJtUQAb8', [], Response::from(threadRunResource(), metaHeaders()));

$result = $client->threads()->runs()->retrieve('thread_agvtHUGezjTCt4SKgQg0NJ2Y', 'run_4RCYyYzX9m41WQicoJtUQAb8');

expect($result)
->toBeInstanceOf(ThreadRunResponse::class)
->id->toBe('run_4RCYyYzX9m41WQicoJtUQAb8')
->object->toBe('thread.run')
->createdAt->toBe(1699621735)
->assistantId->toBe('asst_EopvUEMh90bxkNRYEYM81Orc')
->threadId->toBe('thread_EKt7MjGOC6bwKWmenQv5VD6r')
->status->toBe('queued')
->startedAt->toBeNull()
->expiresAt->toBe(1699622335)
->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()->toHaveCount(1)
->tools->each->toBeInstanceOf(ThreadRunResponseToolCodeInterpreter::class)
->fileIds->toBeArray()->toHaveCount(1)
->metadata->toBeArray()->toBeEmpty();

expect($result->meta())
->toBeInstanceOf(MetaInformation::class);
});

test('cancel', function () {
$client = mockClient('POST', 'threads/thread_agvtHUGezjTCt4SKgQg0NJ2Y/runs/run_4RCYyYzX9m41WQicoJtUQAb8/cancel', [], Response::from(threadRunResource(), metaHeaders()));

$result = $client->threads()->runs()->cancel('thread_agvtHUGezjTCt4SKgQg0NJ2Y', 'run_4RCYyYzX9m41WQicoJtUQAb8');

expect($result)
->toBeInstanceOf(ThreadRunResponse::class)
->id->toBe('run_4RCYyYzX9m41WQicoJtUQAb8')
->object->toBe('thread.run')
->createdAt->toBe(1699621735)
->assistantId->toBe('asst_EopvUEMh90bxkNRYEYM81Orc')
->threadId->toBe('thread_EKt7MjGOC6bwKWmenQv5VD6r')
->status->toBe('queued')
->startedAt->toBeNull()
->expiresAt->toBe(1699622335)
->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()->toHaveCount(1)
->tools->each->toBeInstanceOf(ThreadRunResponseToolCodeInterpreter::class)
->fileIds->toBeArray()->toHaveCount(1)
->metadata->toBeArray()->toBeEmpty();

expect($result->meta())
->toBeInstanceOf(MetaInformation::class);
});

test('submit tool outputs', function () {
$client = mockClient('POST', 'threads/thread_agvtHUGezjTCt4SKgQg0NJ2Y/runs/run_4RCYyYzX9m41WQicoJtUQAb8/submit_tool_outputs', [
'tool_outputs' => [
[
'tool_call_id' => 'call_KSg14X7kZF2WDzlPhpQ168Mj',
'output' => '12',
],
],
], Response::from(threadRunResource(), metaHeaders()));

$result = $client->threads()->runs()->submitToolOutputs('thread_agvtHUGezjTCt4SKgQg0NJ2Y', 'run_4RCYyYzX9m41WQicoJtUQAb8', [
'tool_outputs' => [
[
'tool_call_id' => 'tool_1',
'output' => 'This is the output of tool 1',
],
],
]);

expect($result)
->toBeInstanceOf(ThreadRunResponse::class)
->id->toBe('run_4RCYyYzX9m41WQicoJtUQAb8')
->object->toBe('thread.run')
->createdAt->toBe(1699621735)
->assistantId->toBe('asst_EopvUEMh90bxkNRYEYM81Orc')
->threadId->toBe('thread_EKt7MjGOC6bwKWmenQv5VD6r')
->status->toBe('queued')
->startedAt->toBeNull()
->expiresAt->toBe(1699622335)
->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()->toHaveCount(1)
->tools->each->toBeInstanceOf(ThreadRunResponseToolCodeInterpreter::class)
->fileIds->toBeArray()->toHaveCount(1)
->metadata->toBeArray()->toBeEmpty();

expect($result->meta())
->toBeInstanceOf(MetaInformation::class);
});

0 comments on commit 255660f

Please sign in to comment.