Skip to content

Commit

Permalink
Merge branch 'beta' into main-beta-conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
aydinfatih authored Oct 11, 2024
2 parents a13b109 + 1f3a155 commit 1612ecd
Show file tree
Hide file tree
Showing 37 changed files with 245 additions and 47 deletions.
54 changes: 53 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
- [Text-and-image Input](#text-and-image-input)
- [Multi-turn Conversations (Chat)](#multi-turn-conversations-chat)
- [Stream Generate Content](#stream-generate-content)
- [Structured Output](#structured-output)
- [Count tokens](#count-tokens)
- [Configuration](#configuration)
- [Embedding Resource](#embedding-resource)
Expand Down Expand Up @@ -98,7 +99,7 @@ $yourApiKey = getenv('YOUR_API_KEY');

$client = Gemini::factory()
->withApiKey($yourApiKey)
->withBaseUrl('https://generativelanguage.example.com/v1') // default: https://generativelanguage.googleapis.com/v1/
->withBaseUrl('https://generativelanguage.example.com/v1beta') // default: https://generativelanguage.googleapis.com/v1beta/
->withHttpHeader('X-My-Header', 'foo')
->withQueryParam('my-param', 'bar')
->withHttpClient(new \GuzzleHttp\Client([])) // default: HTTP client found using PSR-18 HTTP Client Discovery
Expand Down Expand Up @@ -175,6 +176,57 @@ foreach ($stream as $response) {
}
```

#### Structured Output
Gemini generates unstructured text by default, but some applications require structured text. For these use cases, you can constrain Gemini to respond with JSON, a structured data format suitable for automated processing. You can also constrain the model to respond with one of the options specified in an enum.

```php
$result = $client
->geminiFlash()
->withGenerationConfig(
generationConfig: new GenerationConfig(
responseMimeType: ResponseMimeType::APPLICATION_JSON,
responseSchema: new Schema(
type: DataType::ARRAY,
items: new Schema(
type: DataType::OBJECT,
properties: [
"recipe_name" => new Schema(type: DataType::STRING),
"cooking_time_in_minutes" => new Schema(type: DataType::INTEGER)
]
)
)
)
)
->generateContent("List 5 popular cookie recipes with cooking time");


$result->json();

//[
// {
// +"cooking_time_in_minutes": 10,
// +"recipe_name": "Chocolate Chip Cookies",
// },
// {
// +"cooking_time_in_minutes": 12,
// +"recipe_name": "Oatmeal Raisin Cookies",
// },
// {
// +"cooking_time_in_minutes": 10,
// +"recipe_name": "Peanut Butter Cookies",
// },
// {
// +"cooking_time_in_minutes": 10,
// +"recipe_name": "Snickerdoodles",
// },
// {
// +"cooking_time_in_minutes": 12,
// +"recipe_name": "Sugar Cookies",
// },
// ]

```

#### Count tokens
When using long prompts, it might be useful to count tokens before sending any content to the model.

Expand Down
2 changes: 1 addition & 1 deletion src/Data/Blob.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
/**
* Raw media bytes.
*
* https://ai.google.dev/api/rest/v1/Content#blob
* https://ai.google.dev/api/rest/v1beta/Content#blob
*/
final class Blob implements Arrayable
{
Expand Down
2 changes: 1 addition & 1 deletion src/Data/Candidate.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
/**
* A response candidate generated from the model.
*
* https://ai.google.dev/api/rest/v1/GenerateContentResponse#candidate
* https://ai.google.dev/api/rest/v1beta/GenerateContentResponse#candidate
*/
final class Candidate implements Arrayable
{
Expand Down
2 changes: 1 addition & 1 deletion src/Data/CitationMetadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
/**
* A collection of source attributions for a piece of content.
*
* https://ai.google.dev/api/rest/v1/GenerateContentResponse#citationmetadata
* https://ai.google.dev/api/rest/v1beta/GenerateContentResponse#citationmetadata
*/
final class CitationMetadata implements Arrayable
{
Expand Down
2 changes: 1 addition & 1 deletion src/Data/CitationSource.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
/**
* A citation to a source for a portion of a specific response.
*
* https://ai.google.dev/api/rest/v1/GenerateContentResponse#citationsource
* https://ai.google.dev/api/rest/v1beta/GenerateContentResponse#citationsource
*/
final class CitationSource implements Arrayable
{
Expand Down
2 changes: 1 addition & 1 deletion src/Data/Content.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
* A Content includes a role field designating the producer of the Content and a parts
* field containing multi-part data that contains the content of the message turn.
*
* https://ai.google.dev/api/rest/v1/Content
* https://ai.google.dev/api/rest/v1beta/Content
*/
final class Content implements Arrayable
{
Expand Down
2 changes: 1 addition & 1 deletion src/Data/ContentEmbedding.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
/**
* A list of floats representing an embedding.
*
* https://ai.google.dev/api/rest/v1/ContentEmbedding
* https://ai.google.dev/api/rest/v1beta/ContentEmbedding
*/
final class ContentEmbedding implements Arrayable
{
Expand Down
19 changes: 19 additions & 0 deletions src/Data/DataFormat.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace Gemini\Data;

enum DataFormat: string
{
// for Number
case FLOAT = 'float';
case DOUBLE = 'double';

// for Integer
case INT32 = 'int32';
case INT64 = 'int64';

// for String
case ENUM = 'enum';
}
39 changes: 30 additions & 9 deletions src/Data/GenerationConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
namespace Gemini\Data;

use Gemini\Contracts\Arrayable;
use Gemini\Enums\ResponseMimeType;

/**
* Configuration options for model generation and outputs.
*
* https://ai.google.dev/api/rest/v1/GenerationConfig
* https://ai.google.dev/api/rest/v1beta/GenerationConfig
*/
final class GenerationConfig implements Arrayable
{
Expand All @@ -20,6 +21,12 @@ final class GenerationConfig implements Arrayable
* @param float|null $temperature Controls the randomness of the output.
* @param float|null $topP The maximum cumulative probability of tokens to consider when sampling.
* @param int|null $topK The maximum number of tokens to consider when sampling.
* @param ResponseMimeType|null $responseMimeType MIME type of the generated candidate text.
* @param Schema|null $responseSchema Output schema of the generated candidate text.
* @param float|null $presencePenalty Presence penalty applied to the next token's logprobs if the token has already been seen in the response.
* @param float|null $frequencyPenalty Frequency penalty applied to the next token's logprobs, multiplied by the number of times each token has been seen in the respponse so far.
* @param bool|null $responseLogprobs If true, export the logprobs results in response.
* @param int|null $logprobs Only valid if responseLogprobs=True. This sets the number of top logprobs to return at each decoding step in the Candidate.logprobs_result.
*/
public function __construct(
public readonly int $candidateCount = 1,
Expand All @@ -28,17 +35,31 @@ public function __construct(
public readonly ?float $temperature = null,
public readonly ?float $topP = null,
public readonly ?int $topK = null,
public readonly ?ResponseMimeType $responseMimeType = ResponseMimeType::TEXT_PLAIN,
public readonly ?Schema $responseSchema = null,
public readonly ?float $presencePenalty = null,
public readonly ?float $frequencyPenalty = null,
public readonly ?bool $responseLogprobs = null,
public readonly ?int $logprobs = null,
) {}

public function toArray(): array
{
return [
'candidateCount' => $this->candidateCount,
'stopSequences' => $this->stopSequences,
'maxOutputTokens' => $this->maxOutputTokens,
'temperature' => $this->temperature,
'topP' => $this->topP,
'topK' => $this->topK,
];
return array_filter(
array: [
'candidateCount' => $this->candidateCount,
'stopSequences' => $this->stopSequences,
'maxOutputTokens' => $this->maxOutputTokens,
'temperature' => $this->temperature,
'topP' => $this->topP,
'topK' => $this->topK,
'responseMimeType' => $this->responseMimeType?->value,
'responseSchema' => $this->responseSchema?->toArray(),
'presencePenalty' => $this->presencePenalty,
'frequencyPenalty' => $this->frequencyPenalty,
'responseLogprobs' => $this->responseLogprobs,
'logprobs' => $this->logprobs,
]
);
}
}
2 changes: 1 addition & 1 deletion src/Data/Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
/**
* Information about a Generative Language Model.
*
* https://ai.google.dev/api/rest/v1/models#resource:-model
* https://ai.google.dev/api/rest/v1beta/models#resource:-model
*/
final class Model implements Arrayable
{
Expand Down
2 changes: 1 addition & 1 deletion src/Data/PromptFeedback.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
/**
* A set of the feedback metadata the prompt specified in GenerateContentRequest.content.
*
* https://ai.google.dev/api/rest/v1/GenerateContentResponse#promptfeedback
* https://ai.google.dev/api/rest/v1beta/GenerateContentResponse#promptfeedback
*/
final class PromptFeedback implements Arrayable
{
Expand Down
2 changes: 1 addition & 1 deletion src/Data/SafetyRating.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* for a piece of content. Content is classified for safety across a number of harm categories
* and the probability of the harm classification is included here.
*
* https://ai.google.dev/api/rest/v1/GenerateContentResponse#safetyrating
* https://ai.google.dev/api/rest/v1beta/GenerateContentResponse#safetyrating
*/
final class SafetyRating implements Arrayable
{
Expand Down
2 changes: 1 addition & 1 deletion src/Data/SafetySetting.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
/**
* Safety setting, affecting the safety-blocking behavior.
*
* https://ai.google.dev/api/rest/v1/SafetySetting
* https://ai.google.dev/api/rest/v1beta/SafetySetting
*/
final class SafetySetting implements Arrayable
{
Expand Down
61 changes: 61 additions & 0 deletions src/Data/Schema.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

declare(strict_types=1);

namespace Gemini\Data;

use Gemini\Contracts\Arrayable;
use Gemini\Enums\DataType;

/**
* https://ai.google.dev/api/caching#Schema
*
* The Schema object allows the definition of input and output data types.
*/
class Schema implements Arrayable
{
/**
* The Schema object allows the definition of input and output data types.
*
* @param DataType $type Data type.
* @param DataFormat|null $format The format of the data. This is used only for primitive datatypes.
* @param string|null $description A brief description of the parameter.
* @param bool|null $nullable Indicates if the value may be null.
* @param array<string>|null $enum Possible values of the element of Type.STRING with enum format.
* @param string|null $maxItems Maximum number of the elements for Type.ARRAY.
* @param string|null $minItems Minimum number of the elements for Type.ARRAY.
* @param array<string, Schema>|null $properties Properties of Type.OBJECT.
* @param array<string>|null $required Required properties of Type.OBJECT.
* @param Schema|null $items Schema of the elements of Type.ARRAY.
*/
public function __construct(
public readonly DataType $type,
public readonly ?DataFormat $format = null,
public readonly ?string $description = null,
public readonly ?bool $nullable = null,
public readonly ?array $enum = null,
public readonly ?string $maxItems = null,
public readonly ?string $minItems = null,
public readonly ?array $properties = null,
public readonly ?array $required = null,
public readonly ?Schema $items = null
) {}

public function toArray(): array
{
return array_filter(
array: [
'type' => $this->type->value,
'format' => $this->format,
'description' => $this->description,
'nullable' => $this->nullable,
'enum' => $this->enum,
'maxItems' => $this->maxItems,
'minItems' => $this->minItems,
'properties' => array_map(fn ($property) => $property->toArray(), $this->properties ?? []),
'required' => $this->required,
'items' => $this->items?->toArray(),
]
);
}
}
2 changes: 1 addition & 1 deletion src/Data/UsageMetadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,4 @@ public function toArray(): array
'cachedContentTokenCount' => $this->cachedContentTokenCount,
];
}
}
}
2 changes: 1 addition & 1 deletion src/Enums/BlockReason.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
/**
* Specifies what was the reason why prompt was blocked.
*
* https://ai.google.dev/api/rest/v1/GenerateContentResponse#blockreason
* https://ai.google.dev/api/rest/v1beta/GenerateContentResponse#blockreason
*/
enum BlockReason: string
{
Expand Down
21 changes: 21 additions & 0 deletions src/Enums/DataType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace Gemini\Enums;

/**
* Type contains the list of OpenAPI data types as defined by https://spec.openapis.org/oas/v3.0.3#data-types
*
* https://ai.google.dev/api/caching#Type
*/
enum DataType: string
{
case TYPE_UNSPECIFIED = 'TYPE_UNSPECIFIED';
case STRING = 'STRING';
case NUMBER = 'NUMBER';
case INTEGER = 'INTEGER';
case BOOLEAN = 'BOOLEAN';
case ARRAY = 'ARRAY';
case OBJECT = 'OBJECT';
}
2 changes: 1 addition & 1 deletion src/Enums/FinishReason.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
/**
* Defines the reason why the model stopped generating tokens.
*
* https://ai.google.dev/api/rest/v1/GenerateContentResponse#finishreason
* https://ai.google.dev/api/rest/v1beta/GenerateContentResponse#finishreason
*/
enum FinishReason: string
{
Expand Down
2 changes: 1 addition & 1 deletion src/Enums/HarmBlockThreshold.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
/**
* Controls the probability threshold at which harm is blocked.
*
* https://ai.google.dev/api/rest/v1/SafetySetting#harmblockthreshold
* https://ai.google.dev/api/rest/v1beta/SafetySetting#harmblockthreshold
*/
enum HarmBlockThreshold: int
{
Expand Down
2 changes: 1 addition & 1 deletion src/Enums/HarmCategory.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* The category of a rating.
* These categories cover various kinds of harms that developers may wish to adjust.
*
* https://ai.google.dev/api/rest/v1/HarmCategory
* https://ai.google.dev/api/rest/v1beta/HarmCategory
*/
enum HarmCategory: string
{
Expand Down
2 changes: 1 addition & 1 deletion src/Enums/HarmProbability.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* The probability that a piece of content is harmful.
* The classification system gives the probability of the content being unsafe. This does not indicate the severity of harm for a piece of content.
*
* https://ai.google.dev/api/rest/v1/GenerateContentResponse#harmprobability
* https://ai.google.dev/api/rest/v1beta/GenerateContentResponse#harmprobability
*/
enum HarmProbability: string
{
Expand Down
2 changes: 1 addition & 1 deletion src/Enums/MimeType.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
/**
* The IANA standard MIME type of the source data.
*
* https://ai.google.dev/api/rest/v1/Content#blob
* https://ai.google.dev/api/rest/v1beta/Content#blob
*/
enum MimeType: string
{
Expand Down
Loading

0 comments on commit 1612ecd

Please sign in to comment.