diff --git a/README.md b/README.md
index 944bc3b..d2f2393 100644
--- a/README.md
+++ b/README.md
@@ -1,19 +1,22 @@
-
+
-
-
-
+
+
+
# Gemini API PHP Client
+This library is a fork of [gemini-api-php/client](https://github.com/gemini-api-php/client) adding system instructions and updating api to v1beta.
+
Gemini API PHP Client allows you to use the Google's generative AI models, like Gemini Pro and Gemini Pro Vision.
_This library is not developed or endorsed by Google._
- Erdem Köse - **[github.com/erdemkose](https://github.com/erdemkose)**
+- Alexandre Vega - **[github.com/alexandrevega](https://github.com/alexandrevega)**
## Table of Contents
- [Installation](#installation)
@@ -24,6 +27,7 @@ _This library is not developed or endorsed by Google._
- [Chat Session with history](#chat-session-with-history)
- [Streaming responses](#streaming-responses)
- [Streaming Chat Session](#streaming-chat-session)
+ - [System Instruction](#system-instruction)
- [Tokens counting](#tokens-counting)
- [Listing models](#listing-models)
- [Advanced Usages](#advanced-usages)
@@ -39,7 +43,7 @@ _This library is not developed or endorsed by Google._
First step is to install the Gemini API PHP client with Composer.
```shell
-composer require gemini-api-php/client
+composer require alexandrevega/gemini-api-client
```
Gemini API PHP client does not come with an HTTP client.
@@ -257,6 +261,58 @@ Response #1
This code will print "Hello World!" to the standard output.
```
+### System Instruction
+You can add [System Instructions](https://ai.google.dev/gemini-api/docs/system-instructions?hl=en&lang=web) to steer the behaviour of Gemini.
+
+```php
+use GeminiAPI\Client;
+use GeminiAPI\Enums\Role;
+use GeminiAPI\Resources\Content;
+use GeminiAPI\Resources\Parts\TextPart;
+
+$history = [
+ Content::text('Hello World in PHP', Role::User),
+ Content::text(
+ <<
+
+ This code will print "Hello World!" to the standard output.
+ TEXT,
+ Role::Model,
+ ),
+];
+
+$client = new Client('GEMINI_API_KEY');
+$chat = $client->geminiPro()
+ ->withSystemInstruction("You're an expert developer")
+ ->startChat()
+ ->withHistory($history);
+
+$response = $chat->sendMessage(new TextPart('in Go'));
+print $response->text();
+```
+
+```text
+Response #0
+package main
+
+import "fmt"
+
+func main() {
+
+Response #1
+ fmt.Println("Hello World!")
+}
+
+This code will print "Hello World!" to the standard output.
+```
+
+
+
+
+
### Embed Content
```php
diff --git a/composer.json b/composer.json
index 7a94437..6ff0169 100644
--- a/composer.json
+++ b/composer.json
@@ -1,5 +1,5 @@
{
- "name": "gemini-api-php/client",
+ "name": "alexandrevega/gemini-api-client",
"description": "API client for Google's Gemini API",
"keywords": [
"php",
@@ -17,6 +17,10 @@
{
"name": "Erdem Köse",
"email": "erdemkose@gmail.com"
+ },
+ {
+ "name": "Carlos Ramos",
+ "email": "contact@cramos.dev"
}
],
"require": {
diff --git a/src/Client.php b/src/Client.php
index c4a3544..8cb32da 100644
--- a/src/Client.php
+++ b/src/Client.php
@@ -103,7 +103,7 @@ public function embeddingModel(ModelName $modelName): EmbeddingModel
);
}
- /**
+ /**x
* @throws ClientExceptionInterface
*/
public function generateContent(GenerateContentRequest $request): GenerateContentResponse
@@ -163,7 +163,7 @@ public function generateContentStream(
}
}
- curl_setopt($ch, CURLOPT_URL, "{$this->baseUrl}/v1/{$request->getOperation()}");
+ curl_setopt($ch, CURLOPT_URL, "{$this->baseUrl}/v1beta/{$request->getOperation()}");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($request));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headerLines);
@@ -250,7 +250,7 @@ private function doRequest(RequestInterface $request): string
throw new RuntimeException('Missing client or factory for Gemini API operation');
}
- $uri = "{$this->baseUrl}/v1/{$request->getOperation()}";
+ $uri = "{$this->baseUrl}/v1beta/{$request->getOperation()}";
$httpRequest = $this->requestFactory
->createRequest($request->getHttpMethod(), $uri);
diff --git a/src/GenerativeModel.php b/src/GenerativeModel.php
index 0108f35..b56d752 100644
--- a/src/GenerativeModel.php
+++ b/src/GenerativeModel.php
@@ -11,6 +11,7 @@
use GeminiAPI\Requests\CountTokensRequest;
use GeminiAPI\Requests\GenerateContentRequest;
use GeminiAPI\Requests\GenerateContentStreamRequest;
+use GeminiAPI\Resources\Parts\TextPart;
use GeminiAPI\Responses\CountTokensResponse;
use GeminiAPI\Responses\GenerateContentResponse;
use GeminiAPI\Resources\Content;
@@ -25,6 +26,8 @@ class GenerativeModel
/** @var SafetySetting[] */
private array $safetySettings = [];
+ private ?array $systemInstruction = null;
+
private ?GenerationConfig $generationConfig = null;
public function __construct(
@@ -56,6 +59,7 @@ public function generateContentWithContents(array $contents): GenerateContentRes
$contents,
$this->safetySettings,
$this->generationConfig,
+ $this->systemInstruction
);
return $this->client->generateContent($request);
@@ -97,6 +101,7 @@ public function generateContentStreamWithContents(
$contents,
$this->safetySettings,
$this->generationConfig,
+ $this->systemInstruction
);
$this->client->generateContentStream($request, $callback, $ch);
@@ -136,4 +141,13 @@ public function withGenerationConfig(GenerationConfig $generationConfig): self
return $clone;
}
+
+ public function withSystemInstruction(?string $instruction = null): self
+ {
+
+ $clone = clone $this;
+ $clone->systemInstruction['parts'] = [new TextPart($instruction)];
+
+ return $clone;
+ }
}
diff --git a/src/Requests/GenerateContentRequest.php b/src/Requests/GenerateContentRequest.php
index a421e3e..a557e76 100644
--- a/src/Requests/GenerateContentRequest.php
+++ b/src/Requests/GenerateContentRequest.php
@@ -22,12 +22,14 @@ class GenerateContentRequest implements JsonSerializable, RequestInterface
* @param Content[] $contents
* @param SafetySetting[] $safetySettings
* @param GenerationConfig|null $generationConfig
+ * @param string|null $systemInstructions
*/
public function __construct(
public readonly ModelName $modelName,
public readonly array $contents,
public readonly array $safetySettings = [],
public readonly ?GenerationConfig $generationConfig = null,
+ public ?array $systemInstructions = null
) {
$this->ensureArrayOfType($this->contents, Content::class);
$this->ensureArrayOfType($this->safetySettings, SafetySetting::class);
@@ -71,6 +73,10 @@ public function jsonSerialize(): array
$arr['generationConfig'] = $this->generationConfig;
}
+ if ($this->systemInstructions) {
+ $arr['systemInstruction'] = $this->systemInstructions;
+ }
+
return $arr;
}
diff --git a/src/Requests/GenerateContentStreamRequest.php b/src/Requests/GenerateContentStreamRequest.php
index 74aac7b..df7f16d 100644
--- a/src/Requests/GenerateContentStreamRequest.php
+++ b/src/Requests/GenerateContentStreamRequest.php
@@ -22,12 +22,15 @@ class GenerateContentStreamRequest implements JsonSerializable, RequestInterface
* @param Content[] $contents
* @param SafetySetting[] $safetySettings
* @param GenerationConfig|null $generationConfig
+ * @param string|null $systemInstruction
*/
public function __construct(
public readonly ModelName $modelName,
public readonly array $contents,
public readonly array $safetySettings = [],
public readonly ?GenerationConfig $generationConfig = null,
+ public ?array $systemInstructions = null
+
) {
$this->ensureArrayOfType($this->contents, Content::class);
$this->ensureArrayOfType($this->safetySettings, SafetySetting::class);
@@ -71,6 +74,10 @@ public function jsonSerialize(): array
$arr['generationConfig'] = $this->generationConfig;
}
+ if ($this->systemInstructions) {
+ $arr['systemInstruction'] = $this->systemInstructions;
+ }
+
return $arr;
}
diff --git a/tests/Unit/ClientTest.php b/tests/Unit/ClientTest.php
index 1e13609..f5ec68d 100644
--- a/tests/Unit/ClientTest.php
+++ b/tests/Unit/ClientTest.php
@@ -78,7 +78,7 @@ public function testGenerateContent()
{
$httpRequest = new Request(
'POST',
- 'https://generativelanguage.googleapis.com/v1/models/gemini-pro:generateContent',
+ 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent',
);
$httpResponse = new Response(
body: <<createMock(RequestFactoryInterface::class);
$requestFactory->expects(self::once())
->method('createRequest')
- ->with('POST', 'https://generativelanguage.googleapis.com/v1/models/gemini-pro:generateContent')
+ ->with('POST', 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent')
->willReturn($httpRequest);
$httpRequest = $httpRequest
@@ -155,7 +155,7 @@ public function testEmbedContent()
{
$httpRequest = new Request(
'POST',
- 'https://generativelanguage.googleapis.com/v1/models/embedding-001:embedContent',
+ 'https://generativelanguage.googleapis.com/v1beta/models/embedding-001:embedContent',
);
$httpResponse = new Response(
body: <<createMock(RequestFactoryInterface::class);
$requestFactory->expects(self::once())
->method('createRequest')
- ->with('POST', 'https://generativelanguage.googleapis.com/v1/models/embedding-001:embedContent')
+ ->with('POST', 'https://generativelanguage.googleapis.com/v1beta/models/embedding-001:embedContent')
->willReturn($httpRequest);
$httpRequest = $httpRequest
@@ -210,7 +210,7 @@ public function testCountTokens()
{
$httpRequest = new Request(
'POST',
- 'https://generativelanguage.googleapis.com/v1/models/gemini-pro:countTokens',
+ 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:countTokens',
);
$httpResponse = new Response(
body: <<createMock(RequestFactoryInterface::class);
$requestFactory->expects(self::once())
->method('createRequest')
- ->with('POST', 'https://generativelanguage.googleapis.com/v1/models/gemini-pro:countTokens')
+ ->with('POST', 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:countTokens')
->willReturn($httpRequest);
$httpRequest = $httpRequest
@@ -260,7 +260,7 @@ public function testListModels()
{
$httpRequest = new Request(
'GET',
- 'https://generativelanguage.googleapis.com/v1/models',
+ 'https://generativelanguage.googleapis.com/v1beta/models',
);
$httpResponse = new Response(
body: <<createMock(RequestFactoryInterface::class);
$requestFactory->expects(self::once())
->method('createRequest')
- ->with('GET', 'https://generativelanguage.googleapis.com/v1/models')
+ ->with('GET', 'https://generativelanguage.googleapis.com/v1beta/models')
->willReturn($httpRequest);
$httpRequest = $httpRequest