Google GenAI Adapter
In shortUse the GoogleGenAIConverter to integrate raw google-genai SDK calls into 10xGraph's message format, including streaming.
- 3 min read
- 11 sections
- Updated
- v0.9.2
- Markdown
Source example: examples/google_genai_example.py
What you will build
Three standalone examples that demonstrate how to use the GoogleGenAIConverter adapter:
- Standard response — convert a single
generate_contentresponse into an 10xGraphMessage. - Streaming response — consume a
generate_content_streamand yieldStreamChunkmessages as they arrive. - Function calling — inspect tool call blocks from a model response.
Prerequisites
-
Python 3.12 or later
-
10xgraphinstalled -
google-genaiSDK installed:Terminal pip install google-genai -
GEMINI_API_KEYorGOOGLE_API_KEYset in your environment (or.envfile)
Adapter architecture
flowchart LR
A[google-genai SDK\nResponse / Stream] -->|GoogleGenAIConverter| B[10xGraph Message]
B --> C[StateGraph / context]
subgraph 10xGraph
B
C
end
style A fill:#4A90D9,color:#fff
style B fill:#7B68EE,color:#fff
style C fill:#50C878,color:#fff
The GoogleGenAIConverter lives in tenxgraph.runtime.adapters.llm. It is the bridge between the raw SDK objects (which are provider-specific) and the provider-neutral Message format that the rest of 10xGraph operates on.
Example 1 — Standard response
import asyncio
import os
from tenxgraph.runtime.adapters.llm import GoogleGenAIConverter
from google import genai
from google.genai import types
async def standard_response_example():
api_key = os.getenv("GEMINI_API_KEY") or os.getenv("GOOGLE_API_KEY")
client = genai.Client(api_key=api_key)
try:
response = client.models.generate_content(
model="gemini-2.0-flash-exp",
contents="Write a haiku about Python programming",
config=types.GenerateContentConfig(temperature=0.7, max_output_tokens=100),
)
converter = GoogleGenAIConverter()
message = await converter.convert_response(response)
print(f"Message ID : {message.message_id}")
print(f"Role : {message.role}")
print(f"Token usage : {message.usages}")
for block in message.content:
if hasattr(block, "text"):
print(f"Text : {block.text}")
finally:
client.close()
asyncio.run(standard_response_example())What convert_response returns
classDiagram
class Message {
+str message_id
+str role
+list~ContentBlock~ content
+list~ToolCall~ tools_calls
+dict metadata
+UsageInfo usages
}
class ContentBlock {
+str text
}
class ToolCallBlock {
+str name
+dict args
}
Message --> ContentBlock : contains
Message --> ToolCallBlock : contains (function calls)
Example 2 — Streaming response
async def streaming_response_example():
api_key = os.getenv("GEMINI_API_KEY") or os.getenv("GOOGLE_API_KEY")
client = genai.Client(api_key=api_key)
try:
stream = client.models.generate_content_stream(
model="gemini-2.0-flash-exp",
contents="Count from 1 to 5, one number at a time",
config=types.GenerateContentConfig(temperature=0.7),
)
converter = GoogleGenAIConverter()
config = {"thread_id": "example-thread"}
async for message in converter.convert_streaming_response(
config=config,
node_name="google_genai_node",
response=stream,
):
if message.delta:
# Streaming chunk — print text as it arrives
for block in message.content:
if hasattr(block, "text"):
print(block.text, end="", flush=True)
else:
# Final assembled message
print(f"\nFinal message ID: {message.message_id}")
finally:
client.close()Streaming event flow
sequenceDiagram
participant App
participant Converter as GoogleGenAIConverter
participant SDK as google-genai SDK
App->>SDK: generate_content_stream(...)
SDK-->>Converter: raw chunk 1
Converter-->>App: Message(delta=True, content=[TextBlock("1")])
SDK-->>Converter: raw chunk 2
Converter-->>App: Message(delta=True, content=[TextBlock("2")])
SDK-->>Converter: raw chunk N
Converter-->>App: Message(delta=True, content=[TextBlock("N")])
Converter-->>App: Message(delta=False) — final assembled message
The delta flag distinguishes streaming chunks from the final assembled Message. Your code should buffer or display delta messages and store/use the final one.
Example 3 — Function calling
async def function_calling_example():
api_key = os.getenv("GEMINI_API_KEY") or os.getenv("GOOGLE_API_KEY")
client = genai.Client(api_key=api_key)
try:
def get_weather(location: str) -> str:
"""Get the weather for a location."""
return "sunny"
response = client.models.generate_content(
model="gemini-2.0-flash-exp",
contents="What's the weather like in Boston?",
config=types.GenerateContentConfig(
tools=[get_weather],
automatic_function_calling=types.AutomaticFunctionCallingConfig(disable=True),
),
)
converter = GoogleGenAIConverter()
message = await converter.convert_response(response)
print(f"Tool calls: {len(message.tools_calls or [])}")
if message.tools_calls:
for tc in message.tools_calls:
print(f" Function : {tc['function']['name']}")
print(f" Arguments: {tc['function']['arguments']}")
finally:
client.close()Running all examples
import asyncio
asyncio.run(standard_response_example())
asyncio.run(streaming_response_example())
asyncio.run(function_calling_example())When to use GoogleGenAIConverter directly
The Agent class already handles Google GenAI internally when you set provider="google". Use GoogleGenAIConverter directly when:
- You need to call the SDK outside of a
StateGraph(e.g. in a background job). - You want fine-grained control over model config parameters that
Agentdoes not expose. - You are building a custom node that calls the SDK and needs to produce 10xGraph-compatible messages.
For the common case — an LLM that calls tools inside a graph — use the Agent class instead. See Agent Class Pattern.
Key concepts
| Concept | Details |
|---|---|
GoogleGenAIConverter |
Translates google-genai SDK responses into 10xGraph Message objects |
convert_response() |
Awaitable — converts a single completed response |
convert_streaming_response() |
Async generator — yields delta messages and a final assembled message |
message.delta |
True for streaming chunks, False for the final complete message |
message.tools_calls |
List of tool call dicts when the LLM requested function execution |
What you learned
- How to install and import
GoogleGenAIConverter. - How to convert both standard and streaming google-genai responses into
Messageobjects. - How to detect and inspect function call responses.
- When to use the converter directly vs. using the
Agentclass.
Next step
→ Tool Decorator — use the @tool decorator to attach metadata, tags, and capabilities to your tool functions.