Skip to content

Commit ab43500

Browse files
committed
bug #387 [Platform] Fix VertexAI server tools (valtzu)
This PR was merged into the main branch. Discussion ---------- [Platform] Fix VertexAI server tools | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | Docs? | yes | Issues | Fix #386 | License | MIT 1. Align "Gemini via VertexAI" server tools configuration with Gemini platform - This makes it easier to migrate from Gemini -> Vertex and vice-versa 3. Fix the server tools example to actually use server tools 4. Fix how server tools are provided to VertexAI Worth noting that unlike Gemini API, it seems VertexAI does not support client-side tools when using server-side tools, the api is returning `Multiple tools are supported only when they are all search tools`. This is why the `Clock` & `Toolbox` was removed from the example. Commits ------- ea0cbe5 [Platform] Fix VertexAI server tools
2 parents 631027f + ea0cbe5 commit ab43500

File tree

4 files changed

+61
-23
lines changed

4 files changed

+61
-23
lines changed

examples/vertexai/server-tools.php

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@
1010
*/
1111

1212
use Symfony\AI\Agent\Agent;
13-
use Symfony\AI\Agent\Toolbox\AgentProcessor;
14-
use Symfony\AI\Agent\Toolbox\Tool\Clock;
15-
use Symfony\AI\Agent\Toolbox\Toolbox;
1613
use Symfony\AI\Platform\Bridge\VertexAi\Gemini\Model;
1714
use Symfony\AI\Platform\Bridge\VertexAi\PlatformFactory;
1815
use Symfony\AI\Platform\Message\Message;
@@ -22,15 +19,15 @@
2219

2320
$platform = PlatformFactory::create(env('GOOGLE_CLOUD_LOCATION'), env('GOOGLE_CLOUD_PROJECT'), adc_aware_http_client());
2421

25-
$model = new Model(Model::GEMINI_2_5_PRO);
22+
$model = new Model(Model::GEMINI_2_5_PRO, ['server_tools' => ['url_context' => true]]);
23+
$agent = new Agent($platform, $model, [], [], logger());
2624

27-
$toolbox = new Toolbox([new Clock()], logger: logger());
28-
$processor = new AgentProcessor($toolbox);
29-
$agent = new Agent($platform, $model, [$processor], [$processor], logger());
30-
31-
$content = file_get_contents('https://www.euribor-rates.eu/en/current-euribor-rates/4/euribor-rate-12-months/');
3225
$messages = new MessageBag(
33-
Message::ofUser("Based on the following page content, what was the 12-month Euribor rate a week ago?\n\n".$content)
26+
Message::ofUser(
27+
<<<'PROMPT'
28+
What's the latest 12-month Euribor rate based on https://www.euribor-rates.eu/en/current-euribor-rates/4/euribor-rate-12-months/
29+
PROMPT,
30+
),
3431
);
3532

3633
$result = $agent->call($messages);

src/platform/doc/vertexai-server-tools.rst

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,10 @@ The URL Context tool allows the model to fetch and analyze content from specifie
2828

2929
::
3030

31-
$model = new VertexAi\Gemini\Model('gemini-2.5-pro');
31+
$model = new VertexAi\Gemini\Model('gemini-2.5-pro', ['server_tools' => ['url_context' => true]]);
3232

33-
$content = file_get_contents('https://www.euribor-rates.eu/en/current-euribor-rates/4/euribor-rate-12-months/');
3433
$messages = new MessageBag(
35-
Message::ofUser("Based on the following page content, what was the 12-month Euribor rate a week ago?\n\n".$content)
34+
Message::ofUser("Based on https://www.euribor-rates.eu/en/current-euribor-rates/4/euribor-rate-12-months/, what is the latest 12-month Euribor rate?"),
3635
);
3736

3837
$result = $platform->invoke($model, $messages);
@@ -51,9 +50,9 @@ More info can be found at https://cloud.google.com/vertex-ai/generative-ai/docs/
5150
::
5251

5352
$model = new VertexAi\Gemini\Model('gemini-2.5-pro', [
54-
'tools' => [[
55-
'googleSearch' => new \stdClass()
56-
]]
53+
'server_tools' => [
54+
'google_search' => true,
55+
],
5756
]);
5857

5958
$messages = new MessageBag(
@@ -70,9 +69,9 @@ More info can be found at https://cloud.google.com/vertex-ai/generative-ai/docs/
7069
::
7170

7271
$model = new Gemini('gemini-2.5-pro-preview-03-25', [
73-
'tools' => [[
74-
'codeExecution' => new \stdClass()
75-
]]
72+
'server_tools' => [
73+
'code_execution' => true,
74+
],
7675
]);
7776

7877
$messages = new MessageBag(
@@ -88,10 +87,10 @@ Using Multiple Server Tools
8887
You can enable multiple tools in a single request::
8988

9089
$model = new Gemini('gemini-2.5-pro-preview-03-25', [
91-
'tools' => [[
92-
'googleSearch' => new \stdClass(),
93-
'codeExecution' => new \stdClass()
94-
]]
90+
'server_tools' => [
91+
'google_search' => true,
92+
'code_execution' => true,
93+
],
9594
]);
9695

9796
Example

src/platform/src/Bridge/VertexAi/Gemini/ModelClient.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,17 @@ public function request(BaseModel $model, array|string $payload, array $options
7676
$options['tools'][] = ['functionDeclarations' => $tools];
7777
}
7878

79+
if (isset($options['server_tools'])) {
80+
foreach ($options['server_tools'] as $tool => $params) {
81+
if (!$params) {
82+
continue;
83+
}
84+
85+
$options['tools'][] = [$tool => true === $params ? new \ArrayObject() : $params];
86+
}
87+
unset($options['server_tools']);
88+
}
89+
7990
if (\is_string($payload)) {
8091
$payload = [
8192
'contents' => [

src/platform/tests/Bridge/VertexAi/Gemini/ModelClientTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,35 @@ public function testItInvokesTheTextModelsSuccessfully()
5757
);
5858
$this->assertSame($expectedResponse, $data);
5959
}
60+
61+
public function testItPassesServerToolsFromOptions()
62+
{
63+
$payload = [
64+
'content' => [
65+
['parts' => ['text' => 'Server tool test']],
66+
],
67+
];
68+
$httpClient = new MockHttpClient(
69+
function ($method, $url, $options) {
70+
self::assertJsonStringEqualsJsonString(
71+
<<<'JSON'
72+
{
73+
"tools": [
74+
{"google_search": {}}
75+
],
76+
"content": [
77+
{"parts":{"text":"Server tool test"}}
78+
]
79+
}
80+
JSON,
81+
$options['body'],
82+
);
83+
84+
return new JsonMockResponse('{}');
85+
}
86+
);
87+
88+
$client = new ModelClient($httpClient, 'global', 'test');
89+
$client->request(new Model(Model::GEMINI_2_0_FLASH), $payload, ['server_tools' => ['google_search' => true]]);
90+
}
6091
}

0 commit comments

Comments
 (0)