Documentation Index
Fetch the complete documentation index at: https://raindrop.ai/docs/llms.txt
Use this file to discover all available pages before exploring further.
Installation
pip install raindrop-google-adk google-adk
Quick Start
from raindrop_google_adk import setup_google_adk
from google.adk import Runner
from google.adk.agents import LlmAgent
from google.adk.sessions import InMemorySessionService
from google.genai import types
# Enable automatic tracing for all ADK Runner interactions
rd = setup_google_adk(api_key="your-write-key")
def get_weather(city: str) -> dict:
"""Get weather for a city."""
return {"temperature": 72, "condition": "sunny", "city": city}
agent = LlmAgent(
name="weather_assistant",
tools=[get_weather],
model="gemini-2.5-flash",
instruction="You are a helpful assistant that can check weather.",
)
session_service = InMemorySessionService()
runner = Runner(app_name="weather_app", agent=agent, session_service=session_service)
user_msg = types.Content(
parts=[types.Part(text="What's the weather in New York?")],
role="user",
)
for event in runner.run(user_id="user123", session_id="session123", new_message=user_msg):
if event.is_final_response():
print(event.content.parts[0].text)
What Gets Traced
The Google ADK integration automatically captures:
- Runner invocations — input message, user_id, session_id, app_name
- Agent responses — final output text from the agent
- Token usage — prompt_tokens, completion_tokens, total_tokens from usage metadata
- Tool calls — individual tool spans with name, input, output, duration, and error
- Model info — model version when available (e.g.,
gemini-2.5-flash)
- Agent identity — agent name, author from events
- Finish reason — why generation stopped (e.g., STOP, SAFETY, MAX_TOKENS)
- Errors — captured (with error message) and re-raised to the caller
- Async support — both
run() (sync) and run_async() (async) are instrumented
Configuration
Auto-instrumentation (recommended)
Use setup_google_adk() to automatically patch all ADK Runner instances:
from raindrop_google_adk import setup_google_adk
rd = setup_google_adk(
api_key="your-write-key", # Required: your Raindrop API key. If None, telemetry is disabled.
user_id="user-123", # Optional: default user ID for all events
convo_id="convo-456", # Optional: conversation/thread ID
tracing_enabled=True, # Optional: enable/disable OTEL tracing (default: True)
bypass_otel_for_tools=True, # Optional: bypass OTEL for tool calls (default: True)
)
# All Runner.run() and Runner.run_async() calls are now automatically traced
# Call rd.shutdown() before process exit
Manual wrapping
Use create_raindrop_google_adk() to wrap specific Runner instances:
from raindrop_google_adk import create_raindrop_google_adk
rd = create_raindrop_google_adk(
api_key="your-write-key",
user_id="user-123",
)
wrapped_runner = rd.wrap(runner)
for event in wrapped_runner.run(user_id="user123", session_id="s1", new_message=msg):
print(event)
rd.shutdown()
Class-based API
from raindrop_google_adk import RaindropGoogleADK
rd = RaindropGoogleADK(
api_key="your-write-key",
user_id="user-123",
tracing_enabled=True,
bypass_otel_for_tools=True,
debug=False,
)
# Auto-patch all Runner instances
rd.setup()
# Or wrap a specific runner
wrapped = rd.wrap(runner)
# Cleanup
rd.shutdown()
Debug Mode
Enable verbose logging to troubleshoot integration issues:
rd = RaindropGoogleADK(
api_key="your-write-key",
debug=True, # Enables DEBUG-level logging for the integration
)
When debug=True, internal telemetry operations (event extraction, interaction lifecycle) are logged at the DEBUG level via Python’s standard logging module.
Identify
Associate a user with traits for downstream analysis:
rd.identify(
user_id="user-123",
traits={"plan": "pro", "company": "Acme"},
)
Track Signal
Track feedback, edits, or custom signals tied to a specific event:
rd.track_signal(
event_id="evt-abc123",
name="thumbs_up",
signal_type="feedback",
sentiment="POSITIVE",
comment="Great response!",
)
When your agent uses tools, individual tool spans are captured automatically with name, input, output, duration, and error status:
def get_stock_price(symbol: str) -> str:
"""Get the current stock price."""
return "189.50"
agent = LlmAgent(
name="stock_agent",
tools=[get_stock_price],
model="gemini-2.5-flash",
instruction="Answer questions about stock prices.",
)
# Tool calls are tracked as individual spans and counted in event properties as
# google_adk.tool_calls_count and google_adk.tool_call_names
Multi-Agent Workflows
Google ADK supports complex agent topologies — sequential agents, parallel agents,
and nested sub-agents. The integration captures the top-level Runner invocations
regardless of agent complexity:
from google.adk.agents import LlmAgent, SequentialAgent, ParallelAgent
researcher = LlmAgent(name="researcher", model="gemini-2.5-flash",
instruction="Research the topic.", tools=[search_tool])
writer = LlmAgent(name="writer", model="gemini-2.5-flash",
instruction="Write a summary based on research.")
pipeline = SequentialAgent(name="research_pipeline", sub_agents=[researcher, writer])
runner = Runner(app_name="research_app", agent=pipeline, session_service=session_service)
# Runner invocations are automatically traced with input/output capture
Async Usage
The wrapper supports both sync and async runner usage:
import asyncio
async def main():
user_msg = types.Content(
parts=[types.Part(text="What's the weather?")],
role="user",
)
async for event in runner.run_async(
user_id="user123",
session_id="session123",
new_message=user_msg,
):
if event.is_final_response():
print(event.content.parts[0].text)
rd.shutdown()
asyncio.run(main())
Finish Reason Tracking
The integration captures the finish_reason from model responses, indicating why generation stopped. Common values include:
| Value | Meaning |
|---|
STOP | Normal completion |
SAFETY | Blocked by safety filters |
MAX_TOKENS | Hit token limit |
RECITATION | Blocked for recitation |
This is available in event properties as google_adk.finish_reason.
Token Tracking
Token usage is accumulated across all model calls within a single Runner.run() invocation. The following fields are captured:
| Property | Description |
|---|
ai.usage.prompt_tokens | Total input tokens across all model calls |
ai.usage.completion_tokens | Total output tokens across all model calls |
ai.usage.total_tokens | Total tokens (prompt + completion) |
ai.usage.cached_tokens | Cached content token count |
ai.usage.thoughts_tokens | Thinking/reasoning token count |
Captured Properties
Each event includes the following properties when available:
| Property | Description |
|---|
ai.usage.prompt_tokens | Input token count |
ai.usage.completion_tokens | Output token count |
ai.usage.total_tokens | Total token count |
ai.usage.cached_tokens | Cached content token count |
ai.usage.thoughts_tokens | Thinking/reasoning token count |
google_adk.app_name | Runner app name |
google_adk.user_id | User ID from the runner call |
google_adk.session_id | Session ID from the runner call |
google_adk.author | Event author (agent name) |
google_adk.agent_name | Agent name from the event |
google_adk.tool_calls_count | Number of tool calls in the run |
google_adk.tool_call_names | JSON list of tool names called |
google_adk.finish_reason | Why generation stopped (STOP, SAFETY, etc.) |
google_adk.error | Whether a Python exception occurred |
google_adk.error_message | Python exception message if applicable |
google_adk.error_code | LLM-level error code (e.g. SAFETY, QUOTA) |
google_adk.llm_error_message | LLM-level error message |
google_adk.agent_branch | Agent hierarchy path for multi-agent setups |
Flushing and Shutdown
Always call shutdown() before your process exits to ensure all telemetry is shipped:
rd.flush() # flush pending events without releasing resources
rd.shutdown() # flush + release resources
Factory Function (backward compat)
The setup_google_adk() and create_raindrop_google_adk() factory functions return RaindropGoogleADK instances and accept the same parameters:
from raindrop_google_adk import setup_google_adk, create_raindrop_google_adk
# Auto-patch all Runner instances
rd = setup_google_adk(api_key="your-write-key")
# Or create without auto-patching
rd = create_raindrop_google_adk(api_key="your-write-key")
wrapped = rd.wrap(runner)
The RaindropGoogleADK class provides identify() and track_signal() methods directly, so you don’t need to import the core SDK separately.