How to Combine Google Search, Google Maps, and Custom Functions in a Single Gemini API Call With Context Circulation, Parallel Tool IDs, and Multi-Step Agentic Chains


import subprocess, sys


subprocess.check_call(
   [sys.executable, "-m", "pip", "install", "-qU", "google-genai"],
   stdout=subprocess.DEVNULL,
   stderr=subprocess.DEVNULL,
)


import getpass, json, textwrap, os, time
from google import genai
from google.genai import types


if "GOOGLE_API_KEY" not in os.environ:
   os.environ["GOOGLE_API_KEY"] = getpass.getpass("Enter your Gemini API key: ")


client = genai.Client(api_key=os.environ["GOOGLE_API_KEY"])


TOOL_COMBO_MODEL = "gemini-3-flash-preview"
MAPS_MODEL       = "gemini-2.5-flash"


DIVIDER = "=" * 72


def heading(title: str):
   print(f"\n{DIVIDER}")
   print(f"  {title}")
   print(DIVIDER)


def wrap(text: str, width: int = 80):
   for line in text.splitlines():
       print(textwrap.fill(line, width=width) if line.strip() else "")


def describe_parts(response):
   parts = response.candidates[0].content.parts
   fc_ids = {}
   for i, part in enumerate(parts):
       prefix = f"   Part {i:2d}:"
       if hasattr(part, "tool_call") and part.tool_call:
           tc = part.tool_call
           print(f"{prefix} [toolCall]        type={tc.tool_type}  id={tc.id}")
       if hasattr(part, "tool_response") and part.tool_response:
           tr = part.tool_response
           print(f"{prefix} [toolResponse]    type={tr.tool_type}  id={tr.id}")
       if hasattr(part, "executable_code") and part.executable_code:
           code = part.executable_code.code[:90].replace("\n", " ↵ ")
           print(f"{prefix} [executableCode]  {code}...")
       if hasattr(part, "code_execution_result") and part.code_execution_result:
           out = (part.code_execution_result.output or "")[:90]
           print(f"{prefix} [codeExecResult]  {out}")
       if hasattr(part, "function_call") and part.function_call:
           fc = part.function_call
           fc_ids[fc.name] = fc.id
           print(f"{prefix} [functionCall]    name={fc.name}  id={fc.id}")
           print(f"              └─ args: {dict(fc.args)}")
       if hasattr(part, "text") and part.text:
           snippet = part.text[:110].replace("\n", " ")
           print(f"{prefix} [text]            {snippet}...")
       if hasattr(part, "thought_signature") and part.thought_signature:
           print(f"              └─ thought_signature present ✓")
   return fc_ids




heading("DEMO 1: Combine Google Search + Custom Function in One Request")


print("""
This demo shows the flagship new feature: passing BOTH a built-in tool
(Google Search) and a custom function declaration in a single API call.


Gemini will:
 Turn 1 → Search the web for real-time info, then request our custom
          function to get weather data.
 Turn 2 → We supply the function response; Gemini synthesizes everything.


Key points:
 • google_search and function_declarations go in the SAME Tool object
 • include_server_side_tool_invocations must be True (on ToolConfig)
 • Return ALL parts (incl. thought_signatures) in subsequent turns
""")


get_weather_func = types.FunctionDeclaration(
   name="getWeather",
   description="Gets the current weather for a requested city.",
   parameters=types.Schema(
       type="OBJECT",
       properties={
           "city": types.Schema(
               type="STRING",
               description="The city and state, e.g. Utqiagvik, Alaska",
           ),
       },
       required=["city"],
   ),
)


print("▶  Turn 1: Sending prompt with Google Search + getWeather tools...\n")


response_1 = client.models.generate_content(
   model=TOOL_COMBO_MODEL,
   contents=(
       "What is the northernmost city in the United States? "
       "What's the weather like there today?"
   ),
   config=types.GenerateContentConfig(
       tools=[
           types.Tool(
               google_search=types.GoogleSearch(),
               function_declarations=[get_weather_func],
           ),
       ],
       tool_config=types.ToolConfig(
           include_server_side_tool_invocations=True,
       ),
   ),
)


print("   Parts returned by the model:\n")
fc_ids = describe_parts(response_1)


function_call_id = fc_ids.get("getWeather")
print(f"\n   ✅ Captured function_call id for getWeather: {function_call_id}")


print("\n▶  Turn 2: Returning function result & requesting final synthesis...\n")


history = [
   types.Content(
       role="user",
       parts=[
           types.Part(
               text=(
                   "What is the northernmost city in the United States? "
                   "What's the weather like there today?"
               )
           )
       ],
   ),
   response_1.candidates[0].content,
   types.Content(
       role="user",
       parts=[
           types.Part(
               function_response=types.FunctionResponse(
                   name="getWeather",
                   response={"response": "Very cold. 22°F / -5.5°C with strong Arctic winds."},
                   id=function_call_id,
               )
           )
       ],
   ),
]


response_2 = client.models.generate_content(
   model=TOOL_COMBO_MODEL,
   contents=history,
   config=types.GenerateContentConfig(
       tools=[
           types.Tool(
               google_search=types.GoogleSearch(),
               function_declarations=[get_weather_func],
           ),
       ],
       tool_config=types.ToolConfig(
           include_server_side_tool_invocations=True,
       ),
   ),
)


print("   ✅ Final synthesized response:\n")
for part in response_2.candidates[0].content.parts:
   if hasattr(part, "text") and part.text:
       wrap(part.text)



Source link

  • Related Posts

    Teaching LLMs to Update Beliefs for Efficient Long-Horizon Interaction – The Berkeley Artificial Intelligence Research Blog

    Overview of ABBEL compared to traditional recursive summarization. Beliefs replace the full interaction history as the agent’s working context, and belief grading improves performance by supervising the contents of each…

    Black Forest Labs Releases FLUX 3: A Multimodal Flow Model for Image, Video, Audio and Robot Action Prediction

    Black Forest Labs (BFL) has released FLUX 3, a multimodal foundation model that learns from images, videos and audio inside a single architecture. It is also the first FLUX model…

    Leave a Reply

    Your email address will not be published. Required fields are marked *