Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented function calls #67

Open
wants to merge 4 commits into
base: beta
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/Contracts/Resources/GenerativeModelContract.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
use Gemini\Data\Content;
use Gemini\Data\GenerationConfig;
use Gemini\Data\SafetySetting;
use Gemini\Data\Tool;
use Gemini\Data\ToolConfig;
use Gemini\Resources\ChatSession;
use Gemini\Responses\GenerativeModel\CountTokensResponse;
use Gemini\Responses\GenerativeModel\GenerateContentResponse;
Expand Down Expand Up @@ -41,4 +43,8 @@ public function startChat(array $history = []): ChatSession;
public function withSafetySetting(SafetySetting $safetySetting): self;

public function withGenerationConfig(GenerationConfig $generationConfig): self;

public function withTool(Tool $tool): self;

public function withToolConfig(ToolConfig $toolConfig): self;
}
2 changes: 1 addition & 1 deletion src/Data/Candidate.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public function __construct(
) {}

/**
* @param array{ content: ?array{ parts: array{ array{ text: ?string, inlineData: array{ mimeType: string, data: string }, fileData: array{ fileUri: string, mimeType: string } } }, role: string }, finishReason: ?string, safetyRatings: ?array{ array{ category: string, probability: string, blocked: ?bool } }, citationMetadata: ?array{ citationSources: array{ array{ startIndex: int, endIndex: int, uri: ?string, license: ?string} } }, index: ?int, tokenCount: ?int, avgLogprobs: ?float } $attributes
* @param array{ content: ?array{ parts: array{ array{ text: ?string, inlineData: ?array{ mimeType: string, data: string }, fileData: ?array{ fileUri: string, mimeType: string }, functionCall: ?array{ name: string, args: array<string, mixed>|null }, functionResponse: ?array{ name: string, response: array<string, mixed> } } }, role: string }, finishReason: ?string, safetyRatings: ?array{ array{ category: string, probability: string, blocked: ?bool } }, citationMetadata: ?array{ citationSources: array{ array{ startIndex: int, endIndex: int, uri: ?string, license: ?string} } }, index: ?int, tokenCount: ?int, avgLogprobs: ?float } $attributes
*/
public static function from(array $attributes): self
{
Expand Down
2 changes: 1 addition & 1 deletion src/Data/Content.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public static function parse(string|Blob|array|Content|UploadedFile $part, Role
}

/**
* @param array{ parts: array{ array{ text: ?string, inlineData: array{ mimeType: string, data: string }, fileData: array{ fileUri: string, mimeType: string } } }, role: string } $attributes
* @param array{ parts: array{ array{ text: ?string, inlineData: ?array{ mimeType: string, data: string }, fileData: ?array{ fileUri: string, mimeType: string }, functionCall: ?array{ name: string, args: array<string, mixed>|null }, functionResponse: ?array{ name: string, response: array<string, mixed> } } }, role: string } $attributes
*/
public static function from(array $attributes): self
{
Expand Down
43 changes: 43 additions & 0 deletions src/Data/FunctionCall.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);

namespace Gemini\Data;

use Gemini\Contracts\Arrayable;

/**
* A predicted FunctionCall returned from the model that contains a string representing the FunctionDeclaration.name with the arguments and their values.
*
* https://ai.google.dev/api/caching#FunctionCall
*/
final class FunctionCall implements Arrayable
{
/**
* @param string $name The name of the function to call. Must be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length of 63.
* @param array<string, mixed> $args The function parameters and values to pass to the function.
*/
public function __construct(
public string $name,
public array $args,
) {}

/**
* @param array{ name: string, args: array<string, mixed>|null } $attributes
*/
public static function from(array $attributes): self
{
return new self(
name: $attributes['name'],
args: $attributes['args'] ?? [],
);
}

public function toArray(): array
{
return [
'name' => $this->name,
'args' => $this->args,
];
}
}
33 changes: 33 additions & 0 deletions src/Data/FunctionCallingConfig.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace Gemini\Data;

use Gemini\Contracts\Arrayable;
use Gemini\Enums\Mode;

/**
* Configuration for specifying function calling behavior.
*
* https://ai.google.dev/api/caching#FunctionCallingConfig
*/
final class FunctionCallingConfig implements Arrayable
{
/**
* @param Mode $mode Specifies the mode in which function calling should execute.
* @param array<array-key, string>|null $allowedFunctionNames A set of function names that, when provided, limits the functions the model will call.
*/
public function __construct(
public Mode $mode,
public ?array $allowedFunctionNames = null,
) {}

public function toArray(): array
{
return [
'mode' => $this->mode->value,
'allowedFunctionNames' => $this->allowedFunctionNames,
];
}
}
35 changes: 35 additions & 0 deletions src/Data/FunctionDeclaration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

namespace Gemini\Data;

use Gemini\Contracts\Arrayable;

/**
* Structured representation of a function declaration.
*
* https://ai.google.dev/api/caching#FunctionDeclaration
*/
final class FunctionDeclaration implements Arrayable
{
/**
* @param string $name The name of the function. Must be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length of 63.
* @param string $description A brief description of the function.
* @param Schema|null $parameters Describes the parameters to this function. Supports only `type`, `properties`, and `required` fields.
*/
public function __construct(
public string $name,
public string $description,
public ?Schema $parameters = null,
) {}

public function toArray(): array
{
return [
'name' => $this->name,
'description' => $this->description,
'parameters' => $this->parameters?->toArray(),
];
}
}
43 changes: 43 additions & 0 deletions src/Data/FunctionResponse.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);

namespace Gemini\Data;

use Gemini\Contracts\Arrayable;

/**
* The result output from a FunctionCall.
*
* https://ai.google.dev/api/caching#FunctionResponse
*/
final class FunctionResponse implements Arrayable
{
/**
* @param string $name The name of the function to call. Must be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length of 63.
* @param array<string, mixed> $response The function response in JSON object format.
*/
public function __construct(
public string $name,
public array $response,
) {}

/**
* @param array{ name: string, response: array<string, mixed> } $attributes
*/
public static function from(array $attributes): self
{
return new self(
name: $attributes['name'],
response: $attributes['response'],
);
}

public function toArray(): array
{
return [
'name' => $this->name,
'response' => $this->response,
];
}
}
16 changes: 15 additions & 1 deletion src/Data/Part.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,28 @@ final class Part implements Arrayable
* @param string|null $text Inline text.
* @param Blob|null $inlineData Inline media bytes.
* @param UploadedFile|null $fileData Uploaded file information.
* @param FunctionCall|null $functionCall Function call.
* @param FunctionResponse|null $functionResponse Function call response.
*/
public function __construct(
public readonly ?string $text = null,
public readonly ?Blob $inlineData = null,
public readonly ?UploadedFile $fileData = null,
public readonly ?FunctionCall $functionCall = null,
public readonly ?FunctionResponse $functionResponse = null,
) {}

/**
* @param array{ text: ?string, inlineData: ?array{ mimeType: string, data: string }, fileData: ?array{ fileUri: string, mimeType: string } } $attributes
* @param array{ text: ?string, inlineData: ?array{ mimeType: string, data: string }, fileData: ?array{ fileUri: string, mimeType: string }, functionCall: ?array{ name: string, args: array<string, mixed>|null }, functionResponse: ?array{ name: string, response: array<string, mixed> } } $attributes
*/
public static function from(array $attributes): self
{
return new self(
text: $attributes['text'] ?? null,
inlineData: isset($attributes['inlineData']) ? Blob::from($attributes['inlineData']) : null,
fileData: isset($attributes['fileData']) ? UploadedFile::from($attributes['fileData']) : null,
functionCall: isset($attributes['functionCall']) ? FunctionCall::from($attributes['functionCall']) : null,
functionResponse: isset($attributes['functionResponse']) ? FunctionResponse::from($attributes['functionResponse']) : null,
);
}

Expand All @@ -50,6 +56,14 @@ public function toArray(): array
$data['fileData'] = $this->fileData;
}

if ($this->functionCall !== null) {
$data['functionCall'] = $this->functionCall;
}

if ($this->functionResponse !== null) {
$data['functionResponse'] = $this->functionResponse;
}

return $data;
}
}
29 changes: 29 additions & 0 deletions src/Data/Tool.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace Gemini\Data;

use Gemini\Contracts\Arrayable;

/**
* Tool details that the model may use to generate response.
*
* https://ai.google.dev/api/caching#Tool
*/
final class Tool implements Arrayable
{
/**
* @param array<array-key, FunctionDeclaration> $functionDeclarations A list of FunctionDeclarations available to the model that can be used for function calling.
*/
public function __construct(
public ?array $functionDeclarations = null,
) {}

public function toArray(): array
{
return [
'functionDeclarations' => array_map(static fn (FunctionDeclaration $functionDeclaration) => $functionDeclaration->toArray(), $this->functionDeclarations ?? []),
];
}
}
26 changes: 26 additions & 0 deletions src/Data/ToolConfig.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Gemini\Data;

use Gemini\Contracts\Arrayable;

/**
* The Tool configuration containing parameters for specifying Tool use in the request.
*
* https://ai.google.dev/api/caching#ToolConfig
*/
final class ToolConfig implements Arrayable
{
public function __construct(
public ?FunctionCallingConfig $functionCallingConfig = null,
) {}

public function toArray(): array
{
return [
'functionCallingConfig' => $this->functionCallingConfig?->toArray(),
];
}
}
11 changes: 11 additions & 0 deletions src/Enums/Mode.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace Gemini\Enums;

enum Mode: string
{
case MODE_UNSPECIFIED = 'MODE_UNSPECIFIED';
case AUTO = 'AUTO';
case ANY = 'ANY';
case NONE = 'NONE';
}
12 changes: 11 additions & 1 deletion src/Requests/GenerativeModel/GenerateContentRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
use Gemini\Data\Content;
use Gemini\Data\GenerationConfig;
use Gemini\Data\SafetySetting;
use Gemini\Data\Tool;
use Gemini\Data\ToolConfig;
use Gemini\Data\UploadedFile;
use Gemini\Enums\Method;
use Gemini\Foundation\Request;
Expand All @@ -24,13 +26,16 @@ class GenerateContentRequest extends Request
/**
* @param array<string|Blob|array<string|Blob|UploadedFile>|Content|UploadedFile> $parts
* @param array<SafetySetting> $safetySettings
* @param array<array-key, Tool> $tools
*/
public function __construct(
protected readonly string $model,
protected readonly array $parts,
protected readonly array $safetySettings = [],
protected readonly ?GenerationConfig $generationConfig = null,
protected readonly ?Content $systemInstruction = null
protected readonly ?Content $systemInstruction = null,
protected readonly array $tools = [],
protected readonly ?ToolConfig $toolConfig = null,
) {}

public function resolveEndpoint(): string
Expand All @@ -56,6 +61,11 @@ protected function defaultBody(): array
),
'generationConfig' => $this->generationConfig?->toArray(),
'systemInstruction' => $this->systemInstruction?->toArray(),
'tools' => array_map(
static fn (Tool $tool): array => $tool->toArray(),
$this->tools ?? []
),
'toolConfig' => $this->toolConfig?->toArray(),
];
}
}
14 changes: 13 additions & 1 deletion src/Requests/GenerativeModel/StreamGenerateContentRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
use Gemini\Data\Content;
use Gemini\Data\GenerationConfig;
use Gemini\Data\SafetySetting;
use Gemini\Data\Tool;
use Gemini\Data\ToolConfig;
use Gemini\Enums\Method;
use Gemini\Foundation\Request;
use Gemini\Requests\Concerns\HasJsonBody;
Expand All @@ -26,12 +28,16 @@ class StreamGenerateContentRequest extends Request
/**
* @param array<string|Blob|array<string|Blob>|Content> $parts
* @param array<SafetySetting> $safetySettings
* @param array<Tool> $tools
*/
public function __construct(
protected readonly string $model,
protected readonly array $parts,
protected readonly array $safetySettings = [],
protected readonly ?GenerationConfig $generationConfig = null
protected readonly ?GenerationConfig $generationConfig = null,
protected readonly ?Content $systemInstruction = null,
protected readonly array $tools = [],
protected readonly ?ToolConfig $toolConfig = null,
) {}

public function resolveEndpoint(): string
Expand All @@ -56,6 +62,12 @@ protected function defaultBody(): array
$this->safetySettings ?? []
),
'generationConfig' => $this->generationConfig?->toArray(),
'systemInstruction' => $this->systemInstruction?->toArray(),
'tools' => array_map(
static fn (Tool $tool): array => $tool->toArray(),
$this->tools ?? []
),
'toolConfig' => $this->toolConfig?->toArray(),
];
}
}
Loading
Loading