Skip to content

Commit bc1d2ca

Browse files
committed
feat(llmo): support Vertex AI
1 parent 09dad81 commit bc1d2ca

File tree

2 files changed

+132
-10
lines changed

2 files changed

+132
-10
lines changed

posthog/ai/gemini/gemini.py

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ class Client:
4242
def __init__(
4343
self,
4444
api_key: Optional[str] = None,
45+
vertexai: Optional[bool] = None,
46+
credentials: Optional[Any] = None,
47+
project: Optional[str] = None,
48+
location: Optional[str] = None,
49+
debug_config: Optional[Any] = None,
50+
http_options: Optional[Any] = None,
4551
posthog_client: Optional[PostHogClient] = None,
4652
posthog_distinct_id: Optional[str] = None,
4753
posthog_properties: Optional[Dict[str, Any]] = None,
@@ -51,7 +57,13 @@ def __init__(
5157
):
5258
"""
5359
Args:
54-
api_key: Google AI API key. If not provided, will use GOOGLE_API_KEY or API_KEY environment variable
60+
api_key: Google AI API key. If not provided, will use GOOGLE_API_KEY or API_KEY environment variable (not required for Vertex AI)
61+
vertexai: Whether to use Vertex AI authentication
62+
credentials: Vertex AI credentials object
63+
project: GCP project ID for Vertex AI
64+
location: GCP location for Vertex AI
65+
debug_config: Debug configuration for the client
66+
http_options: HTTP options for the client
5567
posthog_client: PostHog client for tracking usage
5668
posthog_distinct_id: Default distinct ID for all calls (can be overridden per call)
5769
posthog_properties: Default properties for all calls (can be overridden per call)
@@ -66,6 +78,12 @@ def __init__(
6678

6779
self.models = Models(
6880
api_key=api_key,
81+
vertexai=vertexai,
82+
credentials=credentials,
83+
project=project,
84+
location=location,
85+
debug_config=debug_config,
86+
http_options=http_options,
6987
posthog_client=self._ph_client,
7088
posthog_distinct_id=posthog_distinct_id,
7189
posthog_properties=posthog_properties,
@@ -85,6 +103,12 @@ class Models:
85103
def __init__(
86104
self,
87105
api_key: Optional[str] = None,
106+
vertexai: Optional[bool] = None,
107+
credentials: Optional[Any] = None,
108+
project: Optional[str] = None,
109+
location: Optional[str] = None,
110+
debug_config: Optional[Any] = None,
111+
http_options: Optional[Any] = None,
88112
posthog_client: Optional[PostHogClient] = None,
89113
posthog_distinct_id: Optional[str] = None,
90114
posthog_properties: Optional[Dict[str, Any]] = None,
@@ -94,7 +118,13 @@ def __init__(
94118
):
95119
"""
96120
Args:
97-
api_key: Google AI API key. If not provided, will use GOOGLE_API_KEY or API_KEY environment variable
121+
api_key: Google AI API key. If not provided, will use GOOGLE_API_KEY or API_KEY environment variable (not required for Vertex AI)
122+
vertexai: Whether to use Vertex AI authentication
123+
credentials: Vertex AI credentials object
124+
project: GCP project ID for Vertex AI
125+
location: GCP location for Vertex AI
126+
debug_config: Debug configuration for the client
127+
http_options: HTTP options for the client
98128
posthog_client: PostHog client for tracking usage
99129
posthog_distinct_id: Default distinct ID for all calls
100130
posthog_properties: Default properties for all calls
@@ -113,16 +143,40 @@ def __init__(
113143
self._default_privacy_mode = posthog_privacy_mode
114144
self._default_groups = posthog_groups
115145

116-
# Handle API key - try parameter first, then environment variables
117-
if api_key is None:
118-
api_key = os.environ.get("GOOGLE_API_KEY") or os.environ.get("API_KEY")
146+
# Build genai.Client arguments
147+
client_args = {}
148+
149+
# Add Vertex AI parameters if provided
150+
if vertexai is not None:
151+
client_args["vertexai"] = vertexai
152+
if credentials is not None:
153+
client_args["credentials"] = credentials
154+
if project is not None:
155+
client_args["project"] = project
156+
if location is not None:
157+
client_args["location"] = location
158+
if debug_config is not None:
159+
client_args["debug_config"] = debug_config
160+
if http_options is not None:
161+
client_args["http_options"] = http_options
162+
163+
# Handle API key authentication
164+
if vertexai:
165+
# For Vertex AI, api_key is optional
166+
if api_key is not None:
167+
client_args["api_key"] = api_key
168+
else:
169+
# For non-Vertex AI mode, api_key is required (backwards compatibility)
170+
if api_key is None:
171+
api_key = os.environ.get("GOOGLE_API_KEY") or os.environ.get("API_KEY")
119172

120-
if api_key is None:
121-
raise ValueError(
122-
"API key must be provided either as parameter or via GOOGLE_API_KEY/API_KEY environment variable"
123-
)
173+
if api_key is None:
174+
raise ValueError(
175+
"API key must be provided either as parameter or via GOOGLE_API_KEY/API_KEY environment variable"
176+
)
177+
client_args["api_key"] = api_key
124178

125-
self._client = genai.Client(api_key=api_key)
179+
self._client = genai.Client(**client_args)
126180
self._base_url = "https://generativelanguage.googleapis.com"
127181

128182
def _merge_posthog_params(

posthog/test/ai/gemini/test_gemini.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,3 +318,71 @@ def test_new_client_override_defaults(
318318
assert props["team"] == "ai" # from defaults
319319
assert props["feature"] == "chat" # from call
320320
assert props["urgent"] is True # from call
321+
322+
323+
def test_vertex_ai_parameters_passed_through(mock_client, mock_google_genai_client, mock_gemini_response):
324+
"""Test that Vertex AI parameters are properly passed to genai.Client"""
325+
mock_google_genai_client.models.generate_content.return_value = mock_gemini_response
326+
327+
# Mock credentials object
328+
mock_credentials = MagicMock()
329+
mock_debug_config = MagicMock()
330+
mock_http_options = MagicMock()
331+
332+
# Create client with Vertex AI parameters
333+
Client(
334+
vertexai=True,
335+
credentials=mock_credentials,
336+
project="test-project",
337+
location="us-central1",
338+
debug_config=mock_debug_config,
339+
http_options=mock_http_options,
340+
posthog_client=mock_client,
341+
)
342+
343+
# Verify genai.Client was called with correct parameters
344+
google_genai.Client.assert_called_once_with(
345+
vertexai=True,
346+
credentials=mock_credentials,
347+
project="test-project",
348+
location="us-central1",
349+
debug_config=mock_debug_config,
350+
http_options=mock_http_options
351+
)
352+
353+
354+
def test_api_key_mode(mock_client, mock_google_genai_client):
355+
"""Test API key authentication mode"""
356+
357+
# Create client with just API key (traditional mode)
358+
Client(
359+
api_key="test-api-key",
360+
posthog_client=mock_client,
361+
)
362+
363+
# Verify genai.Client was called with only api_key
364+
google_genai.Client.assert_called_once_with(api_key="test-api-key")
365+
366+
367+
def test_vertex_ai_mode_with_optional_api_key(mock_client, mock_google_genai_client, mock_gemini_response):
368+
"""Test Vertex AI mode with optional API key"""
369+
mock_google_genai_client.models.generate_content.return_value = mock_gemini_response
370+
371+
mock_credentials = MagicMock()
372+
373+
# Create client with Vertex AI + API key
374+
Client(
375+
vertexai=True,
376+
api_key="test-api-key",
377+
credentials=mock_credentials,
378+
project="test-project",
379+
posthog_client=mock_client,
380+
)
381+
382+
# Verify genai.Client was called with both Vertex AI params and API key
383+
google_genai.Client.assert_called_once_with(
384+
vertexai=True,
385+
api_key="test-api-key",
386+
credentials=mock_credentials,
387+
project="test-project"
388+
)

0 commit comments

Comments
 (0)