Skip to content

Commit 097e8c9

Browse files
authored
Merge pull request #3 from jeffreyvr/feature/add-response-format-support
✨ Added support for response formats
2 parents 5e00b6c + 5907527 commit 097e8c9

5 files changed

Lines changed: 58 additions & 14 deletions

File tree

README.md

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
![Grok PHP Client](assets/images/grok-client.png)
44

5-
**A lightweight, framework-agnostic PHP client for interacting with Grok AI APIs.**
5+
**A lightweight, framework-agnostic PHP client for interacting with Grok AI APIs.**
66
Supports **PHP 8.2+**, built with **OOP best practices**, and **fully type-safe**.
77

88
[![Latest Version](https://img.shields.io/packagist/v/grok-php/client)](https://packagist.org/packages/grok-php/client)
@@ -22,6 +22,7 @@ Supports **PHP 8.2+**, built with **OOP best practices**, and **fully type-safe*
2222
- [Advanced Configuration](#advanced-configuration)
2323
- [Available Grok AI Models](#available-grok-ai-models)
2424
- [Streaming Responses](#streaming-responses)
25+
- [Response format](#response-format)
2526
- [Error Handling](#error-handling)
2627
- [Testing](#testing)
2728
- [Security](#security)
@@ -34,10 +35,10 @@ Supports **PHP 8.2+**, built with **OOP best practices**, and **fully type-safe*
3435

3536
![Grok PHP Client Demo](assets/images/demo.gif)
3637

37-
- **Easy Integration** – Seamlessly connects with Grok AI APIs.
38-
- **Modern PHP Features** – Utilizes PHP 8.2+ features like enums and traits.
39-
- **Framework Agnostic** – Works with any PHP project, CLI scripts, or web applications.
40-
- **Streaming Support** – Built-in support for real-time responses.
38+
- **Easy Integration** – Seamlessly connects with Grok AI APIs.
39+
- **Modern PHP Features** – Utilizes PHP 8.2+ features like enums and traits.
40+
- **Framework Agnostic** – Works with any PHP project, CLI scripts, or web applications.
41+
- **Streaming Support** – Built-in support for real-time responses.
4142
- **Lightweight & Efficient** – Optimized with PSR-4 autoloading and minimal dependencies.
4243

4344
---
@@ -139,7 +140,7 @@ $messages = [
139140
// Custom API settings
140141
$options = new ChatOptions(
141142
model: Model::GROK_2_LATEST,
142-
temperature: 1.2,
143+
temperature: 1.2,
143144
stream: false
144145
);
145146

@@ -151,8 +152,8 @@ echo "AI Says: " . $response['choices'][0]['message']['content'];
151152

152153
## **Available Grok AI Models**
153154

154-
Grok AI offers multiple models optimized for different use cases.
155-
These models are available in the `Model` enum inside our package:
155+
Grok AI offers multiple models optimized for different use cases.
156+
These models are available in the `Model` enum inside our package:
156157
📄 `src/Enums/Model.php`
157158

158159
| Model Enum | API Model Name | Description |
@@ -172,7 +173,7 @@ These models are available in the `Model` enum inside our package:
172173

173174
## **Streaming Responses**
174175

175-
The Grok API supports streaming responses for real-time interaction.
176+
The Grok API supports streaming responses for real-time interaction.
176177
Enable it by setting `stream: true`:
177178

178179
```php
@@ -183,9 +184,20 @@ Streaming can be useful for chatbots, real-time applications, and CLI assistants
183184

184185
---
185186

187+
## **Response format**
188+
189+
The Grok API supports setting a response format, also refered to structured outputs, for the `grok-2-1212` model.
190+
191+
```php
192+
$options = new ChatOptions(model: Model::GROK_2_1212, temperature: 0.7, stream: false, responseFormat: ['type' => 'json_object']);
193+
$response = $client->chat($messages, $options);
194+
```
195+
196+
---
197+
186198
## **Error Handling**
187199

188-
This package includes built-in error handling with a dedicated exception class.
200+
This package includes built-in error handling with a dedicated exception class.
189201
Common errors and their messages:
190202

191203
| Error Type | HTTP Code | Message |
@@ -221,7 +233,7 @@ vendor/bin/phpunit
221233

222234
## **Security**
223235

224-
If you discover a security vulnerability, please report it via email:
236+
If you discover a security vulnerability, please report it via email:
225237
📩 [thefeqy@gmail.com](mailto:thefeqy@gmail.com)
226238

227239
---

src/Clients/GrokClient.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ public function chat(array $messages, ChatOptions $options): array
6969
'messages' => $messages,
7070
'temperature' => $options->temperature,
7171
'stream' => $options->stream,
72+
'response_format' => $options->responseFormat,
7273
]);
7374
}
7475

src/Config/ChatOptions.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,21 @@ class ChatOptions
1616

1717
public bool $stream;
1818

19+
public ?array $responseFormat;
20+
1921
public function __construct(
2022
?Model $model = null,
2123
?float $temperature = null,
22-
?bool $stream = null
24+
?bool $stream = null,
25+
?array $responseFormat = null
2326
) {
2427

2528
$this->model = $model ?: Model::tryFrom(DefaultConfig::MODEL->value) ?: Model::GROK_2;
2629

2730
$this->temperature = $temperature ?? (float) DefaultConfig::TEMPERATURE->value;
2831

2932
$this->stream = $stream ?? filter_var(DefaultConfig::STREAMING->value, FILTER_VALIDATE_BOOLEAN);
33+
34+
$this->responseFormat = $responseFormat ? (array) $responseFormat : null;
3035
}
3136
}

src/Testing/ClientFake.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class ClientFake
1212
*
1313
* @throws JsonException
1414
*/
15-
public static function fakeSuccessResponse(): Response
15+
public static function fakeSuccessResponse(?array $data = null): Response
1616
{
1717
return new Response(200, ['Content-Type' => 'application/json'], json_encode([
1818
'id' => '7c51076a-e4cc-4855-8dbe-66c26818e35f',
@@ -24,7 +24,7 @@ public static function fakeSuccessResponse(): Response
2424
'index' => 0,
2525
'message' => [
2626
'role' => 'assistant',
27-
'content' => json_encode([
27+
'content' => json_encode($data ?? [
2828
'framework_name' => 'Laravel',
2929
'release_date' => '2011',
3030
'programming_language' => 'PHP',

tests/Feature/GrokClientTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,30 @@ public function test_chat_request_returns_response(): void
5858
$this->assertSame('2011', $decodedContent['release_date']);
5959
$this->assertSame('PHP', $decodedContent['programming_language']);
6060
}
61+
62+
public function test_chat_request_returns_response_in_specific_format(): void
63+
{
64+
$this->client->setHttpClient(new Client(['handler' => HandlerStack::create(new MockHandler([
65+
ClientFake::fakeSuccessResponse([
66+
'name' => 'Taylor',
67+
'city' => 'Little Rock'
68+
]),
69+
]))]));
70+
71+
$messages = [
72+
['role' => 'system', 'content' => 'You are a helpful assistant.'],
73+
['role' => 'user', 'content' => 'Return a json object with a random name (string) and random city (string).'],
74+
];
75+
76+
$options = new ChatOptions(model: Model::GROK_2_1212, temperature: 0.7, stream: false, responseFormat: ['type' => 'json_object']);
77+
$response = $this->client->chat($messages, $options);
78+
$content = $response['choices'][0]['message']['content'];
79+
$decodedContent = json_decode($response['choices'][0]['message']['content'], true, 512, JSON_THROW_ON_ERROR);
80+
81+
$this->assertJson($content);
82+
$this->assertArrayHasKey('name', $decodedContent);
83+
$this->assertArrayHasKey('city', $decodedContent);
84+
$this->assertSame('Taylor', $decodedContent['name']);
85+
$this->assertSame('Little Rock', $decodedContent['city']);
86+
}
6187
}

0 commit comments

Comments
 (0)