Skip to content

Commit 856e8a0

Browse files
authored
Merge pull request #92 from markmcd/maps-grnd
Maps grounding examples
2 parents 9f5adb7 + 18287c5 commit 856e8a0

6 files changed

Lines changed: 214 additions & 27 deletions

File tree

javascript/grounding.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/**
2+
* @license
3+
* Copyright 2025 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
import { GoogleGenAI } from "@google/genai";
19+
20+
// Ensure the API key is set in your environment variables
21+
if (!process.env.GEMINI_API_KEY) {
22+
throw new Error("GEMINI_API_KEY environment variable not set.");
23+
}
24+
25+
// Define the thinking model centrally
26+
const MODEL_ID = "gemini-2.5-flash";
27+
28+
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
29+
30+
export async function groundingWithMaps() {
31+
// [START grounding_maps]
32+
/**
33+
* Generates text using Google Maps as a grounding tool.
34+
*/
35+
36+
const prompt =
37+
"What are the best Italian restaurants within a 15-minute walk from here?";
38+
39+
const locationContext = {
40+
latLng: {
41+
latitude: 34.050481,
42+
longitude: -118.248526,
43+
},
44+
};
45+
46+
const response = await ai.models.generateContent({
47+
model: MODEL_ID,
48+
contents: prompt,
49+
config: {
50+
tools: [{ googleMaps: {} }],
51+
toolConfig: {
52+
retrievalConfig: locationContext,
53+
},
54+
},
55+
});
56+
57+
console.log(response.text);
58+
59+
const grounding = response.candidates[0]?.groundingMetadata;
60+
if (grounding?.groundingChunks) {
61+
console.log("-".repeat(40));
62+
console.log("Sources:");
63+
for (const chunk of grounding.groundingChunks) {
64+
if (chunk.maps) {
65+
console.log(`- [${chunk.maps.title}](${chunk.maps.uri})`);
66+
}
67+
}
68+
}
69+
70+
return response;
71+
// [END grounding_maps]
72+
}
73+

javascript/grounding.test.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* @license
3+
* Copyright 2025 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
import assert from "node:assert";
19+
import { test, describe } from "node:test";
20+
21+
import {
22+
groundingWithMaps
23+
} from "./grounding.js";
24+
25+
describe("grounding", { timeout: 300000 }, () => {
26+
test("groundingWithMaps", async () => {
27+
const result = await groundingWithMaps();
28+
assert.ok(
29+
result?.text?.length > 0,
30+
"Test failed: No result or empty result"
31+
);
32+
// TODO: test for grounding data in response
33+
});
34+
});
35+

javascript/package-lock.json

Lines changed: 14 additions & 26 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

javascript/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"description": "",
1212
"type": "module",
1313
"dependencies": {
14-
"@google/genai": "^0.9.0"
14+
"@google/genai": "^1.24.0"
1515
},
1616
"devDependencies": {
1717
"prettier": "^3.5.3"

python/grounding.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# -*- coding: utf-8 -*-
2+
# Copyright 2025 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
from absl.testing import absltest
17+
18+
MODEL_ID = "gemini-2.5-flash"
19+
20+
21+
class GroundingUnitTests(absltest.TestCase):
22+
23+
def test_grounding_maps(self):
24+
# [START grounding_maps]
25+
"""Generates text using Google Maps as a grounding tool."""
26+
from google import genai
27+
from google.genai.types import GenerateContentConfig, GoogleMaps, LatLng, RetrievalConfig, Tool, ToolConfig
28+
29+
client = genai.Client()
30+
31+
maps_tool = Tool(
32+
google_maps=GoogleMaps()
33+
)
34+
35+
location_context = RetrievalConfig(
36+
lat_lng=LatLng(latitude=34.050481, longitude=-118.248526)
37+
)
38+
39+
prompt = "What are the best Italian restaurants within a 15-minute walk from here?"
40+
41+
response = client.models.generate_content(
42+
model=MODEL_ID,
43+
contents=prompt,
44+
config=GenerateContentConfig(
45+
tools=[maps_tool],
46+
tool_config=ToolConfig(retrieval_config=location_context),
47+
)
48+
)
49+
50+
# Display the text output.
51+
print(response.text)
52+
53+
# Display the grounding sources.
54+
if grounding := response.candidates[0].grounding_metadata:
55+
if grounding.grounding_chunks:
56+
print('-' * 40)
57+
print("Sources:")
58+
for chunk in grounding.grounding_chunks:
59+
print(f'- [{chunk.maps.title}]({chunk.maps.uri})')
60+
61+
if widget_token := grounding.google_maps_widget_context_token:
62+
print('-' * 40)
63+
print(f'Maps token: {widget_token[:14]}...')
64+
# [END grounding_maps]
65+
66+
if __name__ == "__main__":
67+
absltest.main()
68+

rest/grounding.sh

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
set -eu
2+
3+
echo "[START grounding_maps]"
4+
# [START grounding_maps]
5+
curl -X POST 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent' \
6+
-H 'Content-Type: application/json' \
7+
-H "x-goog-api-key: ${GEMINI_API_KEY}" \
8+
-d '{
9+
"contents": [{
10+
"role": "user",
11+
"parts": [{
12+
"text": "What are the best Italian restaurants within a 15-minute walk from here?"
13+
}]
14+
}],
15+
"tools": [{"googleMaps": {}}],
16+
"toolConfig": {
17+
"retrievalConfig": {
18+
"latLng": {"latitude": 34.050481, "longitude": -118.248526}
19+
}
20+
}
21+
}'
22+
23+
# [END grounding_maps]

0 commit comments

Comments
 (0)