From 4415acd08110dd15ed750a9e5dd56f3d135819fc Mon Sep 17 00:00:00 2001 From: rxrw <9566402+rxrw@users.noreply.github.com> Date: Thu, 13 Mar 2025 16:55:33 +0800 Subject: [PATCH] feat: add reasoning_content field to chat completions response Add support for the reasoning_content field in chat completions API responses. This field is added at the same level as content in both streaming and non-streaming requests. The field is marked as optional to handle cases where it's not present in the API response. --- src/Responses/Chat/CreateResponse.php | 6 +++--- src/Responses/Chat/CreateResponseChoice.php | 7 ++----- src/Responses/Chat/CreateResponseMessage.php | 10 ++++++++-- src/Responses/Chat/CreateStreamedResponse.php | 6 +++--- src/Responses/Chat/CreateStreamedResponseChoice.php | 4 ++-- src/Responses/Chat/CreateStreamedResponseDelta.php | 7 +++++-- 6 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/Responses/Chat/CreateResponse.php b/src/Responses/Chat/CreateResponse.php index 57c1b654..15a2a833 100644 --- a/src/Responses/Chat/CreateResponse.php +++ b/src/Responses/Chat/CreateResponse.php @@ -12,12 +12,12 @@ use OpenAI\Testing\Responses\Concerns\Fakeable; /** - * @implements ResponseContract}, logprobs: ?array{content: ?array}>}, finish_reason: string|null}>, usage: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}}> + * @implements ResponseContract}, finish_reason: string|null}>, usage: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}}> */ final class CreateResponse implements ResponseContract, ResponseHasMetaInformationContract { /** - * @use ArrayAccessible}, logprobs: ?array{content: ?array}>}, finish_reason: string|null}>, usage: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}}> + * @use ArrayAccessible}, finish_reason: string|null}>, usage: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}}> */ use ArrayAccessible; @@ -41,7 +41,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{id: string, object: string, created: int, model: string, system_fingerprint?: string, choices: array}, logprobs: ?array{content: ?array}>}, finish_reason: string|null}>, usage: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int, prompt_tokens_details?:array{cached_tokens:int}, completion_tokens_details?:array{audio_tokens?:int, reasoning_tokens:int, accepted_prediction_tokens:int, rejected_prediction_tokens:int}}} $attributes + * @param array{id: string, object: string, created: int, model: string, system_fingerprint?: string, choices: array}, finish_reason: string|null}>, usage: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int, prompt_tokens_details?:array{cached_tokens:int}, completion_tokens_details?:array{audio_tokens?:int, reasoning_tokens:int, accepted_prediction_tokens:int, rejected_prediction_tokens:int}}} $attributes */ public static function from(array $attributes, MetaInformation $meta): self { diff --git a/src/Responses/Chat/CreateResponseChoice.php b/src/Responses/Chat/CreateResponseChoice.php index eb875f1e..44a2168f 100644 --- a/src/Responses/Chat/CreateResponseChoice.php +++ b/src/Responses/Chat/CreateResponseChoice.php @@ -9,32 +9,29 @@ final class CreateResponseChoice private function __construct( public readonly int $index, public readonly CreateResponseMessage $message, - public readonly ?CreateResponseChoiceLogprobs $logprobs, public readonly ?string $finishReason, ) {} /** - * @param array{index: int, message: array{role: string, content: ?string, function_call: ?array{name: string, arguments: string}, tool_calls: ?array}, logprobs: ?array{content: ?array}>}, finish_reason: string|null} $attributes + * @param array{index: int, message: array{role: string, content: ?string, reasoning_content?: ?string, function_call: ?array{name: string, arguments: string}, tool_calls: ?array}, finish_reason: string|null} $attributes */ public static function from(array $attributes): self { return new self( $attributes['index'], CreateResponseMessage::from($attributes['message']), - $attributes['logprobs'] ? CreateResponseChoiceLogprobs::from($attributes['logprobs']) : null, $attributes['finish_reason'] ?? null, ); } /** - * @return array{index: int, message: array{role: string, content: string|null, function_call?: array{name: string, arguments: string}, tool_calls?: array}, logprobs: ?array{content: ?array}>}, finish_reason: string|null} + * @return array{index: int, message: array{role: string, content: string|null, reasoning_content?: string|null, function_call?: array{name: string, arguments: string}, tool_calls?: array}, finish_reason: string|null} */ public function toArray(): array { return [ 'index' => $this->index, 'message' => $this->message->toArray(), - 'logprobs' => $this->logprobs?->toArray(), 'finish_reason' => $this->finishReason, ]; } diff --git a/src/Responses/Chat/CreateResponseMessage.php b/src/Responses/Chat/CreateResponseMessage.php index 48ae6293..2c936ae5 100644 --- a/src/Responses/Chat/CreateResponseMessage.php +++ b/src/Responses/Chat/CreateResponseMessage.php @@ -13,11 +13,12 @@ private function __construct( public readonly string $role, public readonly ?string $content, public readonly array $toolCalls, + public readonly ?string $reasoningContent, public readonly ?CreateResponseFunctionCall $functionCall, ) {} /** - * @param array{role: string, content: ?string, function_call: ?array{name: string, arguments: string}, tool_calls: ?array} $attributes + * @param array{role: string, content: ?string, reasoning_content?: ?string, function_call: ?array{name: string, arguments: string}, tool_calls: ?array} $attributes */ public static function from(array $attributes): self { @@ -29,12 +30,13 @@ public static function from(array $attributes): self $attributes['role'], $attributes['content'] ?? null, $toolCalls, + $attributes['reasoning_content'] ?? null, isset($attributes['function_call']) ? CreateResponseFunctionCall::from($attributes['function_call']) : null, ); } /** - * @return array{role: string, content: string|null, function_call?: array{name: string, arguments: string}, tool_calls?: array} + * @return array{role: string, content: string|null, reasoning_content?: string|null, function_call?: array{name: string, arguments: string}, tool_calls?: array} */ public function toArray(): array { @@ -43,6 +45,10 @@ public function toArray(): array 'content' => $this->content, ]; + if ($this->reasoningContent !== null) { + $data['reasoning_content'] = $this->reasoningContent; + } + if ($this->functionCall instanceof CreateResponseFunctionCall) { $data['function_call'] = $this->functionCall->toArray(); } diff --git a/src/Responses/Chat/CreateStreamedResponse.php b/src/Responses/Chat/CreateStreamedResponse.php index adce31d7..04ab9694 100644 --- a/src/Responses/Chat/CreateStreamedResponse.php +++ b/src/Responses/Chat/CreateStreamedResponse.php @@ -9,12 +9,12 @@ use OpenAI\Testing\Responses\Concerns\FakeableForStreamedResponse; /** - * @implements ResponseContract, usage?: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}}> + * @implements ResponseContract, usage?: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}}> */ final class CreateStreamedResponse implements ResponseContract { /** - * @use ArrayAccessible, usage?: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}}> + * @use ArrayAccessible, usage?: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}}> */ use ArrayAccessible; @@ -35,7 +35,7 @@ private function __construct( /** * Acts as static factory, and returns a new Response instance. * - * @param array{id: string, object: string, created: int, model: string, choices: array, usage?: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}} $attributes + * @param array{id: string, object: string, created: int, model: string, choices: array, usage?: array{prompt_tokens: int, completion_tokens: int|null, total_tokens: int}} $attributes */ public static function from(array $attributes): self { diff --git a/src/Responses/Chat/CreateStreamedResponseChoice.php b/src/Responses/Chat/CreateStreamedResponseChoice.php index 40f15a51..590c3e8b 100644 --- a/src/Responses/Chat/CreateStreamedResponseChoice.php +++ b/src/Responses/Chat/CreateStreamedResponseChoice.php @@ -13,7 +13,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, reasoning_content?: string}, finish_reason: string|null} $attributes */ public static function from(array $attributes): self { @@ -25,7 +25,7 @@ public static function from(array $attributes): self } /** - * @return array{index: int, delta: array{role?: string, content?: string}|array{role?: string, content: null, function_call: array{name?: string, arguments?: string}}, finish_reason: string|null} + * @return array{index: int, delta: array{role?: string, content?: string, reasoning_content?: string}|array{role?: string, content: null, reasoning_content?: string, function_call: array{name?: string, arguments?: string}}, finish_reason: string|null} */ public function toArray(): array { diff --git a/src/Responses/Chat/CreateStreamedResponseDelta.php b/src/Responses/Chat/CreateStreamedResponseDelta.php index 6439122e..4fd7bbdd 100644 --- a/src/Responses/Chat/CreateStreamedResponseDelta.php +++ b/src/Responses/Chat/CreateStreamedResponseDelta.php @@ -13,11 +13,12 @@ private function __construct( public readonly ?string $role, public readonly ?string $content, public readonly array $toolCalls, + public readonly ?string $reasoningContent, public readonly ?CreateStreamedResponseFunctionCall $functionCall, ) {} /** - * @param array{role?: string, content?: string, function_call?: array{name?: ?string, arguments?: ?string}, tool_calls?: array} $attributes + * @param array{role?: string, content?: string, reasoning_content?: string, function_call?: array{name?: ?string, arguments?: ?string}, tool_calls?: array} $attributes */ public static function from(array $attributes): self { @@ -29,18 +30,20 @@ public static function from(array $attributes): self $attributes['role'] ?? null, $attributes['content'] ?? null, $toolCalls, + $attributes['reasoning_content'] ?? null, isset($attributes['function_call']) ? CreateStreamedResponseFunctionCall::from($attributes['function_call']) : null, ); } /** - * @return array{role?: string, content?: string}|array{role?: string, content: null, function_call: array{name?: string, arguments?: string}} + * @return array{role?: string, content?: string, reasoning_content?: string}|array{role?: string, content: null, reasoning_content?: string, function_call: array{name?: string, arguments?: string}} */ public function toArray(): array { $data = array_filter([ 'role' => $this->role, 'content' => $this->content, + 'reasoning_content' => $this->reasoningContent, ], fn (?string $value): bool => ! is_null($value)); if ($this->functionCall instanceof CreateStreamedResponseFunctionCall) {