Gemini Live tracing with Future AGI

Trace Gemini Live sessions from the Google GenAI Python SDK in Future AGI, including conversation turns, tool calls, token usage and resumed connections.

Use the maintained traceAI-google-genai-live package to trace sessions your application opens with client.aio.live.connect(...). Each session becomes one Future AGI trace with setup, user turns, model turns and tool calls.

For generate_content and generate_content_stream, use Google GenAI tracing. If a framework manages the Live connection, use its LiveKit or Pipecat integration instead.

Prerequisites

Warning

This integration traces the Gemini Developer API, not Vertex AI Live or ephemeral-token clients. Native-audio models require response_modalities: ["AUDIO"]; requesting TEXT can close the connection with an API error.

Install

pip install "traceAI-google-genai-live==0.1.0" "google-genai==2.31.0" "fi-instrumentation-otel==1.2.3"

Configure credentials and content capture

export FI_API_KEY="your-futureagi-api-key"
export FI_SECRET_KEY="your-futureagi-secret-key"
export GEMINI_API_KEY="your-gemini-api-key"
export GEMINI_LIVE_MODEL="your-live-audio-model"

Replace your-live-audio-model with a model available to your Gemini account from the Live API model list.

Text content is captured by default, including system instructions, transcriptions, tool arguments and tool results. For metadata-only traces, set these before starting your application:

export FI_HIDE_INPUTS=true
export FI_HIDE_OUTPUTS=true

With both settings enabled, model names, timings, tool names, token counts and close codes remain available, but conversation text and raw error messages are omitted. See privacy for the capture boundaries.

Run a session

Save this as gemini_live.py. It registers tracing before opening a Live connection, sends a typed question and prints the transcription of the audio response. It does not play or save audio.

import asyncio
import os

from fi_instrumentation import register
from fi_instrumentation.fi_types import ProjectType
from google import genai
from traceai_google_genai_live import instrument

trace_provider = register(
    project_type=ProjectType.OBSERVE,
    project_name="my-voice-agent",
)
instrument(tracer_provider=trace_provider)


async def main():
    client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
    async with client.aio.live.connect(
        model=os.environ["GEMINI_LIVE_MODEL"],
        config={
            "response_modalities": ["AUDIO"],
            "output_audio_transcription": {},
        },
    ) as session:
        await session.send_client_content(
            turns={
                "role": "user",
                "parts": [{"text": "Suggest one thing to see in Paris."}],
            },
            turn_complete=True,
        )
        async for message in session.receive():
            content = message.server_content
            if content and content.output_transcription:
                print(content.output_transcription.text or "", end="", flush=True)
    print()


try:
    asyncio.run(asyncio.wait_for(main(), timeout=60))
finally:
    trace_provider.force_flush()
python gemini_live.py

session.receive() yields one complete model turn. Applications with tools must answer calls using send_tool_response and continue receiving subsequent turns. The maintained voice and tool example shows tool responses, PCM input and session resumption.

To stream microphone audio, use send_realtime_input with 16 kHz, 16-bit mono PCM and enable input_audio_transcription in the Live configuration. See Google’s Live API guide for audio input handling.

Inspect the trace

Open Observe, select my-voice-agent, and open the session trace after the connection closes. The example produces this span structure:

gemini.live.session
├── gemini.live.setup
├── gemini.live.user_turn
└── gemini.live.model_turn

Inspect the model turn for the model name, token counts supplied by Gemini and response text when output capture is enabled. Tool-enabled applications also produce gemini.live.tool spans beneath model turns.

Audio sessions have a CONVERSATION root with call.duration, completed-turn count and a transcript when both content directions are enabled. call.talk_ratio is present only when user and model speech durations can both be measured; a typed question has no user speech. Text-only sessions use a CHAIN root instead. The integration does not attach audio recordings.

Captured data

SpanData
SessionModel, session ID, optional user ID, response modalities, voice and tool names, input count, reconnect count and close code
SetupWebSocket path without host or query string; system instruction when input capture is enabled
User turnTurn boundaries and user text or input transcription when input capture is enabled
Model turnModel, prompt/completion/total token counts, interruption flags, audio duration and captured prompt or response text
ToolTool name, call ID, cancellation state, and arguments or results when the corresponding content capture is enabled

turnComplete closes a model turn; generationComplete alone does not. An interruption closes it immediately with gemini.interrupted=true. Audio chunks are counted rather than traced individually. Usage values are copied from Gemini, not summed: the latest usage message on a model turn sets that turn’s token counts.

To group calls or associate an end user, wrap connect in fi_instrumentation.using_session("call-42") or fi_instrumentation.using_user("user-42"). Without a supplied session ID, the integration uses a server-provided ID or generates one. It does not invent a user ID.

Privacy

The standard FI_HIDE_INPUTS and FI_HIDE_OUTPUTS switches control this integration. You can instead replace the example’s instrument(...) call with:

from fi_instrumentation import TraceConfig

instrument(
    tracer_provider=trace_provider,
    config=TraceConfig(hide_inputs=True, hide_outputs=True),
)
DataDefaultBoth hide settings enabled
System instruction, user text, transcriptions, model text, tool arguments and resultsCapturedOmitted
Conversation transcript and raw API error textCapturedOmitted
Model, voice name, timings, tool names, IDs, flags, token counts and close codesCapturedCaptured
Raw audio, connection credentials, WebSocket host/query, resumption handle and stack tracesNot copied into trace fieldsNot copied into trace fields

Set just one hide setting to omit that direction. FI_HIDE_INPUT_MESSAGES / FI_HIDE_INPUT_TEXT and their output equivalents also suppress the corresponding direction. The combined conversation transcript and raw error text require both directions to allow capture.

These controls apply to this instrumentor, not your application logs or custom span attributes. The example still prints the response locally when trace content is hidden. Keep sensitive data out of tool names and session/user IDs, which remain metadata, and do not put credentials or resumption handles into captured text or tool results.

Dropped connections and resumption

Enable session_resumption in the Live configuration and save the latest resumable handle from session_resumption_update. Your application must reconnect with that handle; the instrumentor does not reconnect for you. See Google’s session management guide.

After goAway or a dropped connection, a session with a resumable handle waits up to resume_window_seconds (default 30). A reconnect in the same process with that stored handle continues the trace and adds gemini.live.reconnect. An unknown handle or an expired window starts a new trace. A clean exit without goAway closes the session immediately.

Treat handles as credentials: they can resume the conversation. The instrumentor keeps them in memory, not in span attributes or log messages.

Compatibility and troubleshooting

This package does not instrument google-genai 3.x, the deprecated send() / start_stream() methods, or the Node.js SDK. Use send_client_content, send_realtime_input, send_tool_response and receive with the supported Python SDK. Evaluations that require an audio recording need a separate recording attachment; this integration supplies no recording or currency-cost value.

SymptomAction
No spans and an unsupported-client warningUse a Gemini Developer API key, not Vertex AI or an ephemeral token.
No session in the projectCall register() before instrument() and both before connect. Flush the provider before a short script exits.
Setup fails with setup_rejectedCheck the Gemini key and model name. The SDK error is re-raised to your application.
Connection closes with socket_closedInspect gemini.close_code and check that the model supports the requested response modality.
No transcriptEnable input/output audio transcription as needed. Allow both input and output capture only if your privacy policy permits it.
Two traces after a reconnectReconnect in the same process with the latest stored resumable handle before the resume window expires.
Session span appears lateIt may be waiting for a reconnect. Set resume_window_seconds on instrument() to match your application’s retry window.
Was this page helpful?

Questions & Discussion