Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions py/src/braintrust/integrations/google_genai/test_google_genai.py
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let’s avoid tests with mocks and use vcr based cassette tests instead.

I have to improve the agent skills so that this becomes the default.

Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import logging
import os
import time
from pathlib import Path
Expand Down Expand Up @@ -715,6 +716,112 @@ class TestModel(BaseModel):
assert copied["context_file"] is attachment


def test_serialize_content_item_with_content_and_binary_part():
from braintrust.integrations.google_genai.tracing import _serialize_content_item
from braintrust.logger import Attachment

image_data = b"\x89PNG\r\n\x1a\n"
content = types.Content(
role="user",
parts=[
types.Part.from_bytes(data=image_data, mime_type="image/png"),
types.Part.from_text(text="What color is this image?"),
],
)

serialized = _serialize_content_item(content)

assert serialized["role"] == "user"
assert len(serialized["parts"]) == 2
assert serialized["parts"][1] == {"text": "What color is this image?"}

attachment = serialized["parts"][0]["image_url"]["url"]
assert isinstance(attachment, Attachment)
assert attachment.reference["content_type"] == "image/png"
assert attachment.reference["filename"] == "file.png"


def test_serialize_tools_fallback_for_callable(monkeypatch, caplog):
from braintrust.integrations.google_genai import tracing as google_genai_tracing

class MockApiClient:
vertexai = False

def get_weather(location: str, unit: str = "celsius") -> str:
"""Get the current weather for a location."""

return f"22 degrees {unit} and sunny in {location}"

def _raise(*args, **kwargs):
raise RuntimeError("serializer broke")

monkeypatch.setattr(google_genai_tracing, "_serialize_tools_with_google", _raise)

config = types.GenerateContentConfig(tools=[get_weather], max_output_tokens=100)
with caplog.at_level(logging.DEBUG, logger=google_genai_tracing.__name__):
serialized = google_genai_tracing._serialize_tools(MockApiClient(), {"config": config})

assert serialized is not None
declaration = serialized[0]["functionDeclarations"][0]
assert declaration["name"] == "get_weather"
assert declaration["description"] == "Get the current weather for a location."
assert declaration["parameters"]["type"] == "OBJECT"
assert declaration["parameters"]["required"] == ["location"]
assert declaration["parameters"]["properties"]["location"]["type"] == "STRING"
assert declaration["parameters"]["properties"]["unit"]["type"] == "STRING"
assert declaration["parameters"]["properties"]["unit"]["default"] == "celsius"
assert any("Failed to serialize tools via Google SDK" in message for message in caplog.messages)


def test_serialize_tools_fallback_for_declared_tool(monkeypatch):
from braintrust.integrations.google_genai import tracing as google_genai_tracing

class MockApiClient:
vertexai = False

function = types.FunctionDeclaration(
name="calculate",
description="Perform a mathematical calculation",
parameters_json_schema={
"type": "object",
"properties": {
"a": {"type": "number"},
"b": {"type": "number"},
},
"required": ["a", "b"],
},
)
tool = types.Tool(function_declarations=[function])

def _raise(*args, **kwargs):
raise RuntimeError("serializer broke")

monkeypatch.setattr(google_genai_tracing, "_serialize_tools_with_google", _raise)

serialized = google_genai_tracing._serialize_tools(
MockApiClient(), {"config": types.GenerateContentConfig(tools=[tool], max_output_tokens=100)}
)

assert serialized == [
{
"functionDeclarations": [
{
"name": "calculate",
"description": "Perform a mathematical calculation",
"parameters": {
"type": "object",
"properties": {
"a": {"type": "number"},
"b": {"type": "number"},
},
"required": ["a", "b"],
},
}
]
}
]


class TestAutoInstrumentGoogleGenAI:
"""Tests for auto_instrument() with Google GenAI."""

Expand Down
Loading
Loading