Google Gemini

Gate Gemini function calls and tool invocations behind a human approval checkpoint using the Cheqpoint SDK. Works with the Google Generative AI Python SDK and the Vertex AI SDK.

How it works

Gemini supports function calling — the model outputs a structured function call which your application executes. Cheqpoint sits between the model output and the execution: before your code runs the function, it submits an approval request and blocks until a human decides.

Prerequisites

  • Python 3.9+ environment.
  • google-generativeai package and a Gemini API key.
  • Cheqpoint Connection Key.

Steps

  1. Define your Gemini tools (function declarations) as normal.
  2. When Gemini returns a function_call in its response, extract the function name and arguments.
  3. Before executing, call cheq.request_sync() with the function name and arguments as the payload.
  4. If approved, execute the function (using modifiedDetails if the reviewer modified the payload).
  5. If rejected, return an error message to Gemini in the function response so it can inform the user.

Installation

bash
pip install cheqpoint google-generativeai

Sample request payload

json
{
  "action": "send_refund",
  "summary": "Gemini requesting refund of £125 for order ORD-4821",
  "details": {
    "orderId": "ORD-4821",
    "amount": 12500,
    "currency": "GBP",
    "reason": "Item not received"
  }
}

Sample Cheqpoint response

json
{
  "status": "approved",
  "modifiedDetails": null,
  "decisionNote": "Verified order. Refund approved."
}

Python — intercepting Gemini function calls

import os
import google.generativeai as genai
from cheqpoint import CheqpointClient

genai.configure(api_key=os.environ["GEMINI_API_KEY"])
cheq = CheqpointClient(api_key=os.environ["CQ_API_KEY"])

# Define your tool
send_refund_fn = genai.protos.Tool(function_declarations=[
    genai.protos.FunctionDeclaration(
        name="send_refund",
        description="Process a refund for a given order",
        parameters=genai.protos.Schema(
            type=genai.protos.Type.OBJECT,
            properties={
                "orderId": genai.protos.Schema(type=genai.protos.Type.STRING),
                "amount": genai.protos.Schema(type=genai.protos.Type.INTEGER),
            },
            required=["orderId", "amount"],
        ),
    )
])

model = genai.GenerativeModel("gemini-1.5-pro", tools=[send_refund_fn])
chat = model.start_chat()
response = chat.send_message("Issue a £125 refund for order ORD-4821")

# Handle function call
for part in response.candidates[0].content.parts:
    if fn := part.function_call:
        args = dict(fn.args)

        # Gate behind Cheqpoint
        approval = cheq.request_sync(
            action=fn.name,
            summary=f"Gemini requesting {fn.name} with args {args}",
            details=args,
            timeout_ms=30_000,
        )

        if approval["status"] == "approved":
            effective = approval.get("modifiedDetails") or args
            result = your_execute_function(fn.name, effective)
            # Return result back to Gemini
            response = chat.send_message(
                genai.protos.Content(parts=[genai.protos.Part(
                    function_response=genai.protos.FunctionResponse(
                        name=fn.name,
                        response={"result": result}
                    )
                )])
            )
        else:
            note = approval.get("decisionNote", "blocked by human oversight")
            response = chat.send_message(
                genai.protos.Content(parts=[genai.protos.Part(
                    function_response=genai.protos.FunctionResponse(
                        name=fn.name,
                        response={"error": f"Action rejected: {note}"}
                    )
                )])
            )

Vertex AI

The same pattern applies when using Gemini via Vertex AI SDK (vertexai). Intercept the function_calls list on the response candidate and gate each one through Cheqpoint before dispatching.

Get your Connection Key at cheqpoint.co/signup.