Skip to content

Commit 07a4d7a

Browse files
itsmvdjkppr
andauthored
Migrate AI integration to unified google-genai SDK (#3695)
* Sec-Gemini timesketch compatibility fix * Use google-genai library instead of older libs * Make google-genai a default package --------- Co-authored-by: Janosch <99879757+jkppr@users.noreply.github.com>
1 parent 308e89e commit 07a4d7a

File tree

8 files changed

+256
-254
lines changed

8 files changed

+256
-254
lines changed

data/timesketch.conf

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -407,33 +407,27 @@ LLM_PROVIDER_CONFIGS = {
407407
# - ollama: Self-hosted, open-source.
408408
# To use the Ollama provider you need to download and run an Ollama server.
409409
# See instructions at: https://ollama.ai/
410-
# - vertexai: Google Cloud Vertex AI. Requires Google Cloud Project.
411-
# To use the Vertex AI provider you need to:
412-
# 1. Create and export a Service Account Key from the Google Cloud Console.
413-
# 2. Set the GOOGLE_APPLICATION_CREDENTIALS environment variable to the full path
414-
# to your service account private key file by adding it to the docker-compose.yml
415-
# under environment:
416-
# GOOGLE_APPLICATION_CREDENTIALS=/usr/local/src/timesketch/<key_file>.json
417-
# 3. Install the python libraries: $ pip3 install google-cloud-aiplatform
410+
# - google_genai: Google GenAI (supporting both Vertex AI and Gemini API).
411+
# To use the Google GenAI provider you need to:
412+
# 1. Configure either 'api_key' (for Gemini API) or 'project_id' (for Vertex AI).
413+
# 2. For Vertex AI: Set the GOOGLE_APPLICATION_CREDENTIALS environment variable
414+
# to the full path to your service account private key file.
418415
# - secgemini_log_analyzer_agent: SecGemini Log Analyzer Agent.
419416
# To use the SecGemini Log Analyzer Agent you need to:
420417
# 1. Obtain an API key from https://secgemini.com/
421418
# 2. pip3 install sec-gemini
422419
# IMPORTANT: Private keys must be kept secret. If you expose your private key it is
423420
# recommended to revoke it immediately from the Google Cloud Console.
424-
# - aistudio: Google AI Studio (API key). Get API key from Google AI Studio website.
425-
# To use Google's AI Studio simply obtain an API key from https://aistudio.google.com/
426-
# $ pip3 install google-generativeai
427421
"nl2q": {
428422
"vertexai": {
429423
"model": "gemini-2.0-flash",
430424
"project_id": "",
431425
},
432426
},
433427
"llm_summarize": {
434-
"aistudio": {
428+
"vertexai": {
435429
"model": "gemini-2.0-flash",
436-
"api_key": "",
430+
"project_id": "",
437431
},
438432
},
439433
"llm_synthesize": {

docs/guides/admin/llm-features.md

Lines changed: 20 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ the steps required to configure these features for Timesketch administrators.
1515
To use LLM features, specific Python libraries must be installed in the
1616
Timesketch container. Depending on your provider, you will need:
1717

18-
* **Vertex AI:** `google-cloud-aiplatform`
19-
* **AI Studio:** `google-generativeai`
18+
* **Google GenAI:** `google-genai` (Comes preinstalled since v20260209 -
19+
Supports both Vertex AI and Gemini API)
2020
* **Sec-Gemini:** `sec_gemini`
2121

2222
There are two ways to install these dependencies:
@@ -30,7 +30,7 @@ ensures the libraries persist across container restarts and upgrades.
3030

3131
```
3232
docker build \
33-
--build-arg EXTRA_PIP_PACKAGES="google-cloud-aiplatform google-generativeai sec_gemini" \
33+
--build-arg EXTRA_PIP_PACKAGES="sec_gemini" \
3434
-t timesketch:ai-enabled .
3535
```
3636
@@ -46,13 +46,9 @@ a running container.
4646
(e.g., during `docker compose down` and `up`).
4747
4848
```
49-
# For Vertex AI
50-
sudo docker exec timesketch-web pip install google-cloud-aiplatform==1.70.0
51-
sudo docker exec timesketch-worker pip install google-cloud-aiplatform==1.70.0
52-
53-
# For AI Studio
54-
sudo docker exec timesketch-web pip install google-generativeai
55-
sudo docker exec timesketch-worker pip install google-generativeai
49+
# For Google GenAI
50+
sudo docker exec timesketch-web pip install sec_gemini
51+
sudo docker exec timesketch-worker pip install sec_gemini
5652
```
5753
5854
## LLM Provider Configuration
@@ -75,36 +71,27 @@ LLM_PROVIDER_CONFIGS = {
7571
# - ollama: Self-hosted, open-source.
7672
# To use the Ollama provider you need to download and run an Ollama server.
7773
# See instructions at: https://ollama.ai/
78-
# - vertexai: Google Cloud Vertex AI. Requires Google Cloud Project.
79-
# To use the Vertex AI provider you need to:
80-
# 1. Create and export a Service Account Key from the Google Cloud Console.
81-
# 2. Set the GOOGLE_APPLICATION_CREDENTIALS environment variable to the full path
82-
# to your service account private key file by adding it to the docker-compose.yml
83-
# under environment:
84-
# GOOGLE_APPLICATION_CREDENTIALS=/usr/local/src/timesketch/<key_file>.json
85-
# 3. Verify your instance has the `google-cloud-aiplatform` lib installed.
86-
# * $ sudo docker exec timesketch-web pip list | grep google-cloud-aiplatform
87-
# * You can install it manually using:
88-
# $ sudo docker exec timesketch-web pip install google-cloud-aiplatform==1.70.0
74+
# - google_genai: Google GenAI (supporting both Vertex AI and Gemini API).
75+
# To use the Google GenAI provider you need to:
76+
# 1. Configure either 'api_key' (for Gemini API) or 'project_id' (for Vertex AI).
77+
# 2. For Vertex AI: Set the GOOGLE_APPLICATION_CREDENTIALS environment variable
78+
# to the full path to your service account private key file.
79+
# 3. Verify your instance has the `google-genai` lib installed.
80+
# * $ sudo docker exec timesketch-web pip list | grep google-genai
8981
#
9082
# IMPORTANT: Private keys must be kept secret. If you expose your private key it is
9183
# recommended to revoke it immediately from the Google Cloud Console.
92-
# - aistudio: Google AI Studio (API key). Get API key from Google AI Studio website.
93-
# To use Google's AI Studio simply obtain an API key from https://aistudio.google.com/
94-
# Verify your instance runs the required library:
95-
# * $ sudo docker exec timesketch-web pip list | grep google-generativeai
96-
# * You can install it manually using:
97-
# $ sudo docker exec timesketch-web pip install google-generativeai==0.8.4
9884
'nl2q': {
99-
'vertexai': {
100-
'model': 'gemini-2.0-flash-001',
101-
'project_id': '', # Required if using vertexai
85+
'google_genai': {
86+
'model': 'gemini-2.0-flash',
87+
'project_id': '', # Required if using Vertex AI
88+
'location': 'us-central1', # Optional for Vertex AI
10289
},
10390
},
10491
'llm_summarization': {
105-
'aistudio': {
106-
'model': 'gemini-2.0-flash-001', # Recommended model
107-
'api_key': '', # Required if using aistudio
92+
'google_genai': {
93+
'model': 'gemini-2.0-flash', # Recommended model
94+
'api_key': '', # Required if using Gemini API
10895
},
10996
},
11097
'default': {

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ flask_sqlalchemy==3.0.3
1414
flask_wtf==1.2.1
1515
google-auth==2.32.0
1616
google_auth_oauthlib==0.4.1
17+
google-genai
1718
gunicorn==23.0.0
1819
numpy==1.26.4
1920
oauthlib==3.1.0

timesketch/lib/llms/providers/__init__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
"""LLM providers for Timesketch."""
1515

1616
from timesketch.lib.llms.providers import ollama
17-
from timesketch.lib.llms.providers import vertexai
18-
from timesketch.lib.llms.providers import aistudio
17+
from timesketch.lib.llms.providers import google_genai
1918
from timesketch.lib.llms.providers import secgemini_log_analyzer_agent
2019
from timesketch.lib.llms.providers.contrib import azureai

timesketch/lib/llms/providers/aistudio.py

Lines changed: 0 additions & 93 deletions
This file was deleted.
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
# Copyright 2026 Google Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
"""Google GenAI LLM provider (supporting both Vertex AI and Gemini API)."""
15+
16+
import json
17+
import logging
18+
from typing import Any, Optional
19+
20+
from google import genai
21+
from google.genai import types
22+
from timesketch.lib.llms.providers import interface
23+
from timesketch.lib.llms.providers import manager
24+
25+
logger = logging.getLogger("timesketch.llm.providers.google_genai")
26+
27+
28+
class GoogleGenAI(interface.LLMProvider):
29+
"""Google GenAI LLM provider."""
30+
31+
NAME = "google_genai"
32+
33+
def __init__(self, config: dict, **kwargs: Any):
34+
"""Initialize the Google GenAI provider.
35+
36+
Args:
37+
config: The configuration for the provider.
38+
**kwargs: Additional arguments passed to the base class.
39+
40+
Raises:
41+
ValueError: If required configuration keys are missing.
42+
"""
43+
super().__init__(config, **kwargs)
44+
self._api_key = self.config.get("api_key")
45+
self._project_id = self.config.get("project_id")
46+
self._location = self.config.get("location")
47+
self._model_name = self.config.get("model")
48+
49+
if not self._model_name:
50+
raise ValueError(
51+
"Google GenAI provider requires a 'model' in its configuration."
52+
)
53+
54+
try:
55+
if self._project_id:
56+
# Vertex AI path
57+
self.client = genai.Client(
58+
vertexai=True, project=self._project_id, location=self._location
59+
)
60+
elif self._api_key:
61+
# Gemini API path
62+
self.client = genai.Client(api_key=self._api_key)
63+
else:
64+
raise ValueError(
65+
"Google GenAI provider requires either 'api_key' (for Gemini API) "
66+
"or 'project_id' (for Vertex AI) in its configuration."
67+
)
68+
except Exception as e:
69+
raise ValueError(f"Failed to initialize Google GenAI client: {e}") from e
70+
71+
def generate(self, prompt: str, response_schema: Optional[dict] = None) -> Any:
72+
"""
73+
Generate text using the Google GenAI service.
74+
75+
Args:
76+
prompt: The prompt to use for the generation.
77+
response_schema: An optional JSON schema to define the expected
78+
response format.
79+
80+
Returns:
81+
The generated text as a string (or parsed data if
82+
response_schema is provided).
83+
"""
84+
config_params = {
85+
"temperature": self.config.get("temperature"),
86+
"top_k": self.config.get("top_k"),
87+
"top_p": self.config.get("top_p"),
88+
"max_output_tokens": self.config.get("max_output_tokens"),
89+
}
90+
91+
if response_schema:
92+
config_params["response_mime_type"] = "application/json"
93+
config_params["response_schema"] = response_schema
94+
95+
generate_config = types.GenerateContentConfig(**config_params)
96+
97+
try:
98+
response = self.client.models.generate_content(
99+
model=self._model_name,
100+
contents=prompt,
101+
config=generate_config,
102+
)
103+
except Exception as e:
104+
logger.error("Error generating content with Google GenAI: %s", e)
105+
raise ValueError(f"Error generating content: {e}") from e
106+
107+
if response_schema:
108+
try:
109+
if hasattr(response, "parsed") and response.parsed is not None:
110+
return response.parsed
111+
return json.loads(response.text)
112+
except Exception as error:
113+
raise ValueError(
114+
f"Error JSON parsing text: {response.text}: {error}"
115+
) from error
116+
117+
return response.text
118+
119+
120+
manager.LLMManager.register_provider(GoogleGenAI)
121+
122+
123+
# Register aliases for backward compatibility with old configuration names.
124+
class VertexAI(GoogleGenAI):
125+
"""Alias for VertexAI."""
126+
127+
NAME = "vertexai"
128+
129+
130+
class AIStudio(GoogleGenAI):
131+
"""Alias for AI Studio."""
132+
133+
NAME = "aistudio"
134+
135+
136+
manager.LLMManager.register_provider(VertexAI)
137+
manager.LLMManager.register_provider(AIStudio)

0 commit comments

Comments
 (0)