Google Gemini

Auto-instrument the Google Gen AI SDK (google-genai on PyPI, @google/genai on npm). Every generateContent, generateContentStream and embedContent call inside an active run emits an llm_call event with model, token usage, cached and thinking tokens, latency, finish reason, and function calls. Cost is computed server-side from the rate card.

The older google-generativeai package and Vertex AI's own SDK are not covered. Calling Gemini through LangChain or LlamaIndex? Use the framework integration instead; it reports the same fields.

Install / enable

Python:

pip install "agentping-io[gemini]"
import agentping
from google import genai

agentping.init()
agentping.instrument_gemini()

client = genai.Client()

with agentping.run("support-triage", customer_id="acme-corp"):
    reply = client.models.generate_content(
        model="gemini-2.5-flash",
        contents="classify this ticket",
    )

instrument_gemini() patches google.genai.models.Models and AsyncModels, so client.models and client.aio.models are both covered. Idempotent and global; call it once at module load. Supported google-genai versions: 1.x and 2.x.

TypeScript:

npm install @agentping/sdk @google/genai
import { GoogleGenAI } from "@google/genai";
import * as agentping from "@agentping/sdk";

agentping.init({ apiKey: process.env.AGENTPING_API_KEY });

const run = agentping.run("answer-bot");
const gemini = agentping.instrumentGemini(
  new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY }),
  { run },
);

const reply = await gemini.models.generateContent({
  model: "gemini-2.5-flash",
  contents: "hi",
});

await run.finish({ status: "success" });

instrumentGemini returns a wrapped client whose models namespace has the same return types as the original.

What's captured

Field Source
provider gemini
model response.model_version (the concrete version that served the call), falling back to the requested model
input_tokens usage_metadata.prompt_token_count (already gross)
output_tokens usage_metadata.candidates_token_count
cached_input_tokens usage_metadata.cached_content_token_count
reasoning_tokens usage_metadata.thoughts_token_count
finish_reason candidates[0].finish_reason, as the enum name (STOP, MAX_TOKENS)
tool_calls Number of function_call parts across the candidates
latency_ms Wall-clock time of the call
stream true on generateContentStream

Gemini has no cache-creation count, so cache_creation_input_tokens is never set. Zero-valued fields are omitted.

embedContent emits an llm_call with kind: "embedding", the requested model and input_tokens from usage_metadata when the API returns it. A call that raises is recorded as an llm_call with status: "error", error and exception, then re-raised.

Streaming

Both SDKs capture generateContentStream (Python: generate_content_stream, sync and async). Usage arrives on the final chunk; the llm_call fires once the stream is fully consumed or closed, with stream: true.

with agentping.run("answer-bot"):
    for chunk in client.models.generate_content_stream(
        model="gemini-2.5-flash",
        contents="explain briefly",
    ):
        print(chunk.text, end="", flush=True)
    # llm_call is emitted here

Prompt capture and time to first token

generate_content_stream / generateContentStream calls also report ttft_ms, the time from the request to the first chunk carrying a text or function-call part. Pulse charts its p95 per agent.

Prompt and completion text are off by default. Turn them on once at init, with an optional cap per piece (default 4000 characters):

agentping.init(capture_llm_content=True, llm_content_max_chars=4000)
agentping.init({ captureLlmContent: true, llmContentMaxChars: 4000 });

Each generate_content / generateContent call then carries input, system_instructions and output. contents given as a string, or as a list of strings and parts, is one user message; a list of Content objects is a conversation, with Gemini's model role reported as assistant. config.system_instruction (config.systemInstruction in TypeScript) is the system prompt. The output is the first candidate's text parts, thought summaries excluded. Function calls, function responses and inline data appear as markers such as [function_call lookup], and each piece is clipped at the cap. The run page renders them as messages; see events for the wire shape. Embedding calls carry no content.

Source / notes

Default rates ship for current Gemini models; the full list is on the LLM API pricing page. A Gemini model that is not on the default card lands with its token counts and appears in the unpriced-models list until you add its per-million rates under Spend, Rate cards; from then on every new call is priced. See Spend.