Skip to content

Commit d61ebe8

Browse files
authored
Merge pull request #164 from jfradj/feature/new-gemini-tools
Feat: Add File Search API and Google Maps Tool SupportFeature/new gemini tools
2 parents 511aaa3 + 1d35001 commit d61ebe8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+2025
-8
lines changed

README.md

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
- [Function calling](#function-calling)
3333
- [Code Execution](#code-execution)
3434
- [Grounding with Google Search](#grounding-with-google-search)
35+
- [Grounding with Google Maps](#grounding-with-google-maps)
36+
- [Grounding with File Search](#grounding-with-file-search)
3537
- [System Instructions](#system-instructions)
3638
- [Speech generation](#speech-generation)
3739
- [Thinking Mode](#thinking-mode)
@@ -49,6 +51,17 @@
4951
- [Update Cached Content](#update-cached-content)
5052
- [Delete Cached Content](#delete-cached-content)
5153
- [Use Cached Content](#use-cached-content)
54+
- [File Search Stores](#file-search-stores)
55+
- [Create File Search Store](#create-file-search-store)
56+
- [Get File Search Store](#get-file-search-store)
57+
- [List File Search Stores](#list-file-search-stores)
58+
- [Delete File Search Store](#delete-file-search-store)
59+
- [Update File Search Store](#update-file-search-store)
60+
- [File Search Documents](#file-search-documents)
61+
- [Create File Search Document](#create-file-search-document)
62+
- [Get File Search Document](#get-file-search-document)
63+
- [List File Search Documents](#list-file-search-documents)
64+
- [Delete File Search Document](#delete-file-search-document)
5265
- [Embedding Resource](#embedding-resource)
5366
- [Models](#models)
5467
- [List Models](#list-models)
@@ -482,6 +495,59 @@ if ($groundingMetadata !== null) {
482495
}
483496
```
484497

498+
#### Grounding with Google Maps
499+
Grounding with Google Maps allows the model to utilize real-world geographical data. This enables more precise location-based responses, such as finding nearby points of interest.
500+
501+
```php
502+
use Gemini\Data\GoogleMaps;
503+
use Gemini\Data\RetrievalConfig;
504+
use Gemini\Data\Tool;
505+
use Gemini\Data\ToolConfig;
506+
507+
$tool = new Tool(
508+
googleMaps: new GoogleMaps(enableWidget: true)
509+
);
510+
511+
$toolConfig = new ToolConfig(
512+
retrievalConfig: new RetrievalConfig(
513+
latitude: 40.758896,
514+
longitude: -73.985130
515+
)
516+
);
517+
518+
$response = $client
519+
->generativeModel(model: 'gemini-2.0-flash')
520+
->withTool($tool)
521+
->withToolConfig($toolConfig)
522+
->generateContent('Find coffee shops near me');
523+
524+
echo $response->text();
525+
// (Model output referencing coffee shops)
526+
```
527+
528+
#### Grounding with File Search
529+
Grounding with File Search enables the model to retrieve and utilize information from your indexed files. This is useful for answering questions based on private or extensive document collections.
530+
531+
```php
532+
use Gemini\Data\FileSearch;
533+
use Gemini\Data\Tool;
534+
535+
$tool = new Tool(
536+
fileSearch: new FileSearch(
537+
fileSearchStoreNames: ['files/my-document-store'],
538+
metadataFilter: 'author = "Robert Graves"'
539+
)
540+
);
541+
542+
$response = $client
543+
->generativeModel(model: 'gemini-2.0-flash')
544+
->withTool($tool)
545+
->generateContent('Summarize the document about Greek myths by Robert Graves');
546+
547+
echo $response->text();
548+
// (Model output summarizing the document)
549+
```
550+
485551
#### System Instructions
486552
System instructions let you steer the behavior of the model based on your specific needs and use cases. You can set the role and personality of the model, define the format of responses, and provide goals and guardrails for model behavior.
487553

@@ -631,6 +697,7 @@ Every prompt you send to the model includes parameter values that control how th
631697

632698
Also, you can use safety settings to adjust the likelihood of getting responses that may be considered harmful. By default, safety settings block content with medium and/or high probability of being unsafe content across all dimensions. Learn more about [safety settings](https://ai.google.dev/docs/concepts#safety_setting).
633699

700+
When using tools like `GoogleMaps`, you may also provide additional configuration via `ToolConfig`, such as `RetrievalConfig` for geographical context.
634701

635702
```php
636703
use Gemini\Data\GenerationConfig;
@@ -834,6 +901,125 @@ echo "Cached tokens used: {$response->usageMetadata->cachedContentTokenCount}\n"
834901
echo "New tokens used: {$response->usageMetadata->promptTokenCount}\n";
835902
```
836903

904+
### File Search Stores
905+
906+
File search allows you to search files that were uploaded through the File API.
907+
908+
#### Create File Search Store
909+
Create a file search store.
910+
911+
```php
912+
use Gemini\Enums\FileState;
913+
use Gemini\Enums\MimeType;
914+
use Gemini\Enums\Schema;
915+
use Gemini\Enums\DataType;
916+
917+
$files = $client->files();
918+
echo "Uploading\n";
919+
$meta = $files->upload(
920+
filename: 'document.pdf',
921+
mimeType: MimeType::APPLICATION_PDF,
922+
displayName: 'Document for search'
923+
);
924+
echo "Processing";
925+
do {
926+
echo ".";
927+
sleep(2);
928+
$meta = $files->metadataGet($meta->uri);
929+
} while (! $meta->state->complete());
930+
echo "\n";
931+
932+
if ($meta->state == FileState::Failed) {
933+
die("Upload failed:\n".json_encode($meta->toArray(), JSON_PRETTY_PRINT));
934+
}
935+
936+
$fileSearchStore = $client->fileSearchStores()->create(
937+
displayName: 'My Search Store',
938+
);
939+
940+
echo "File search store created: {$fileSearchStore->name}\n";
941+
```
942+
943+
#### Get File Search Store
944+
Get a specific file search store by name.
945+
946+
```php
947+
$fileSearchStore = $client->fileSearchStores()->get('fileSearchStores/my-search-store');
948+
949+
echo "Name: {$fileSearchStore->name}\n";
950+
echo "Display Name: {$fileSearchStore->displayName}\n";
951+
```
952+
953+
#### List File Search Stores
954+
List all file search stores.
955+
956+
```php
957+
$response = $client->fileSearchStores()->list(pageSize: 10);
958+
959+
foreach ($response->fileSearchStores as $fileSearchStore) {
960+
echo "Name: {$fileSearchStore->name}\n";
961+
echo "Display Name: {$fileSearchStore->displayName}\n";
962+
echo "--- \n";
963+
}
964+
```
965+
966+
#### Delete File Search Store
967+
Delete a file search store by name.
968+
969+
```php
970+
$client->fileSearchStores()->delete('fileSearchStores/my-search-store');
971+
```
972+
973+
### File Search Documents
974+
975+
#### Upload File Search Document
976+
Upload a local file directly to a file search store.
977+
978+
```php
979+
use Gemini\Enums\MimeType;
980+
981+
$response = $client->fileSearchStores()->upload(
982+
storeName: 'fileSearchStores/my-search-store',
983+
filename: 'document2.pdf',
984+
mimeType: MimeType::APPLICATION_PDF,
985+
displayName: 'Another Search Document'
986+
);
987+
988+
echo "File search document upload operation: {$response->name}\n";
989+
```
990+
991+
#### Get File Search Document
992+
Get a specific file search document by name.
993+
994+
```php
995+
$fileSearchDocument = $client->fileSearchStores()->getDocument('fileSearchStores/my-search-store/fileSearchDocuments/my-document');
996+
997+
echo "Name: {$fileSearchDocument->name}\n";
998+
echo "Display Name: {$fileSearchDocument->displayName}\n";
999+
```
1000+
1001+
#### List File Search Documents
1002+
List all file search documents within a store.
1003+
1004+
```php
1005+
$response = $client->fileSearchStores()->listDocuments(storeName: 'fileSearchStores/my-search-store', pageSize: 10);
1006+
1007+
foreach ($response->documents as $fileSearchDocument) {
1008+
echo "Name: {$fileSearchDocument->name}\n";
1009+
echo "Display Name: {$fileSearchDocument->displayName}\n";
1010+
echo "Create Time: {$fileSearchDocument->createTime}\n";
1011+
echo "Update Time: {$fileSearchDocument->updateTime}\n";
1012+
echo "--- \n";
1013+
}
1014+
```
1015+
1016+
#### Delete File Search Document
1017+
Delete a file search document by name.
1018+
1019+
```php
1020+
$client->fileSearchStores()->deleteDocument('fileSearchStores/my-search-store/fileSearchDocuments/my-document');
1021+
```
1022+
8371023
### Embedding Resource
8381024
Embedding is a technique used to represent information as a list of floating point numbers in an array. With Gemini, you can represent text (words, sentences, and blocks of text) in a vectorized form, making it easier to compare and contrast embeddings. For example, two texts that share a similar subject matter or sentiment should have similar embeddings, which can be identified through mathematical comparison techniques such as cosine similarity.
8391025

src/Client.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@
88
use Gemini\Contracts\ClientContract;
99
use Gemini\Contracts\Resources\CachedContentsContract;
1010
use Gemini\Contracts\Resources\FilesContract;
11+
use Gemini\Contracts\Resources\FileSearchStoresContract;
1112
use Gemini\Contracts\Resources\GenerativeModelContract;
1213
use Gemini\Contracts\TransporterContract;
1314
use Gemini\Enums\ModelType;
1415
use Gemini\Resources\CachedContents;
1516
use Gemini\Resources\ChatSession;
1617
use Gemini\Resources\EmbeddingModel;
1718
use Gemini\Resources\Files;
19+
use Gemini\Resources\FileSearchStores;
1820
use Gemini\Resources\GenerativeModel;
1921
use Gemini\Resources\Models;
2022

@@ -81,4 +83,9 @@ public function cachedContents(): CachedContentsContract
8183
{
8284
return new CachedContents($this->transporter);
8385
}
86+
87+
public function fileSearchStores(): FileSearchStoresContract
88+
{
89+
return new FileSearchStores($this->transporter);
90+
}
8491
}

src/Contracts/ClientContract.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Gemini\Contracts\Resources\ChatSessionContract;
1010
use Gemini\Contracts\Resources\EmbeddingModalContract;
1111
use Gemini\Contracts\Resources\FilesContract;
12+
use Gemini\Contracts\Resources\FileSearchStoresContract;
1213
use Gemini\Contracts\Resources\GenerativeModelContract;
1314
use Gemini\Contracts\Resources\ModelContract;
1415

@@ -35,4 +36,6 @@ public function chat(BackedEnum|string $model): ChatSessionContract;
3536
public function files(): FilesContract;
3637

3738
public function cachedContents(): CachedContentsContract;
39+
40+
public function fileSearchStores(): FileSearchStoresContract;
3841
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Gemini\Contracts\Resources;
6+
7+
use Gemini\Enums\MimeType;
8+
use Gemini\Responses\FileSearchStores\Documents\DocumentResponse;
9+
use Gemini\Responses\FileSearchStores\Documents\ListResponse as DocumentListResponse;
10+
use Gemini\Responses\FileSearchStores\FileSearchStoreResponse;
11+
use Gemini\Responses\FileSearchStores\ListResponse;
12+
use Gemini\Responses\FileSearchStores\UploadResponse;
13+
14+
interface FileSearchStoresContract
15+
{
16+
/**
17+
* Create a file search store.
18+
*
19+
* @see https://ai.google.dev/api/file-search/file-search-stores#method:-fileSearchStores.create
20+
*/
21+
public function create(?string $displayName = null): FileSearchStoreResponse;
22+
23+
/**
24+
* Get a file search store.
25+
*
26+
* @see https://ai.google.dev/api/file-search/file-search-stores#method:-fileSearchStores.get
27+
*/
28+
public function get(string $name): FileSearchStoreResponse;
29+
30+
/**
31+
* List file search stores.
32+
*
33+
* @see https://ai.google.dev/api/file-search/file-search-stores#method:-fileSearchStores.list
34+
*/
35+
public function list(?int $pageSize = null, ?string $nextPageToken = null): ListResponse;
36+
37+
/**
38+
* Delete a file search store.
39+
*
40+
* @see https://ai.google.dev/api/file-search/file-search-stores#method:-fileSearchStores.delete
41+
*/
42+
public function delete(string $name, bool $force = false): void;
43+
44+
/**
45+
* Upload a file to a file search store.
46+
*
47+
* @param array<string, string|int|float|array<string>> $customMetadata
48+
*
49+
* @see https://ai.google.dev/api/file-search/file-search-stores#method:-media.uploadtofilesearchstore
50+
*/
51+
public function upload(string $storeName, string $filename, ?MimeType $mimeType = null, ?string $displayName = null, array $customMetadata = []): UploadResponse;
52+
53+
/**
54+
* List documents in a file search store.
55+
*
56+
* @see https://ai.google.dev/api/file-search/documents#method:-fileSearchStores.documents.list
57+
*/
58+
public function listDocuments(string $storeName, ?int $pageSize = null, ?string $nextPageToken = null): DocumentListResponse;
59+
60+
/**
61+
* Get a document.
62+
*
63+
* @see https://ai.google.dev/api/file-search/documents#method:-fileSearchStores.documents.get
64+
*/
65+
public function getDocument(string $name): DocumentResponse;
66+
67+
/**
68+
* Delete a document.
69+
*
70+
* @see https://ai.google.dev/api/file-search/documents#method:-fileSearchStores.documents.delete
71+
*/
72+
public function deleteDocument(string $name, bool $force = false): void;
73+
}

src/Data/Candidate.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public function __construct(
4343
) {}
4444

4545
/**
46-
* @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, groundingAttributions: ?array<array{ sourceId: array{ groundingPassage?: array{ passageId: string, partIndex: int }, semanticRetrieverChunk?: array{ source: string, chunk: string } }, 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 } }>, groundingMetadata?: array{ groundingChunks: ?array<array{ web: null|array{ title: ?string, uri: ?string } }>, groundingSupports: ?array<array{ groundingChunkIndices: array<int>|null, confidenceScores: array<float>|null, segment: ?array{ partIndex: ?int, startIndex: ?int, endIndex: ?int, text: ?string } }>, webSearchQueries: ?array<string>, searchEntryPoint?: array{ renderedContent?: string|null, sdkBlob?: string|null }, retrievalMetadata: ?array{ googleSearchDynamicRetrievalScore?: float|null } }, logprobsResult?: array{ topCandidates: array<array{ candidates: array<array{ token: string, tokenId: int, logProbability: float }> }>, chosenCandidates: array<array{ token: string, tokenId: int, logProbability: float }> }, urlRetrievalMetadata?: array{ urlRetrievalContexts: array<array{ retrievedUrl: string }> } } $attributes
46+
* @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, groundingAttributions: ?array<array{ sourceId: array{ groundingPassage?: array{ passageId: string, partIndex: int }, semanticRetrieverChunk?: array{ source: string, chunk: string } }, 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 } }>, groundingMetadata?: array{ groundingChunks: ?array<array{ web: null|array{ title: ?string, uri: ?string }, retrievedContext: null|array{ uri: ?string, title: ?string, text: ?string, fileSearchStore: ?string }, maps: null|array{ uri: ?string, title: ?string, text: ?string, placeId: ?string, placeAnswerSources: ?array{ reviewSnippets: array<array{title: ?string, googleMapsUri: ?string, reviewId: ?string}> } } }>, groundingSupports: ?array<array{ groundingChunkIndices: array<int>|null, confidenceScores: array<float>|null, segment: ?array{ partIndex: ?int, startIndex: ?int, endIndex: ?int, text: ?string } }>, webSearchQueries: ?array<string>, searchEntryPoint?: array{ renderedContent?: string|null, sdkBlob?: string|null }, retrievalMetadata: ?array{ googleSearchDynamicRetrievalScore?: float|null } }, logprobsResult?: array{ topCandidates: array<array{ candidates: array<array{ token: string, tokenId: int, logProbability: float }> }>, chosenCandidates: array<array{ token: string, tokenId: int, logProbability: float }> }, urlRetrievalMetadata?: array{ urlRetrievalContexts: array<array{ retrievedUrl: string }> } } $attributes
4747
*/
4848
public static function from(array $attributes): self
4949
{

src/Data/FileSearch.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Gemini\Data;
6+
7+
use Gemini\Contracts\Arrayable;
8+
9+
/**
10+
* FileSearch tool type. Tool to support File Search in Model.
11+
*/
12+
final class FileSearch implements Arrayable
13+
{
14+
/**
15+
* @param array<string> $fileSearchStoreNames Required. The file search store names.
16+
* @param string|null $metadataFilter Optional. A filter for metadata.
17+
*/
18+
public function __construct(
19+
public readonly array $fileSearchStoreNames,
20+
public readonly ?string $metadataFilter = null,
21+
) {}
22+
23+
/**
24+
* @param array{ fileSearchStoreNames: array<string>, metadataFilter?: string } $attributes
25+
*/
26+
public static function from(array $attributes): self
27+
{
28+
return new self(
29+
fileSearchStoreNames: $attributes['fileSearchStoreNames'],
30+
metadataFilter: $attributes['metadataFilter'] ?? null,
31+
);
32+
}
33+
34+
public function toArray(): array
35+
{
36+
$data = [
37+
'fileSearchStoreNames' => $this->fileSearchStoreNames,
38+
];
39+
40+
if ($this->metadataFilter !== null) {
41+
$data['metadataFilter'] = $this->metadataFilter;
42+
}
43+
44+
return $data;
45+
}
46+
}

0 commit comments

Comments
 (0)