diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5bcd7163c..e12dc5a1d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
# Change Log for SD.Next
+## Update for 2025-12-12
+
+- Google models support for both Dev and Vertex access methods
+ see [docs](https://vladmandic.github.io/sdnext-docs/Google-GenAI/) for details
+
## Update for 2025-12-11
### Highlights for 2025-12-11
diff --git a/modules/shared.py b/modules/shared.py
index 4f834b320..a1c58706a 100644
--- a/modules/shared.py
+++ b/modules/shared.py
@@ -164,6 +164,11 @@ options_templates.update(options_section(('sd', "Model Loading"), {
options_templates.update(options_section(('model_options', "Model Options"), {
"model_modular_sep": OptionInfo("
Modular Pipelines
", "", gr.HTML),
"model_modular_enable": OptionInfo(False, "Enable modular pipelines (experimental)"),
+ "model_google_sep": OptionInfo("Google GenAI
", "", gr.HTML),
+ "google_use_vertexai": OptionInfo(False, "Google cloud use VertexAI endpoints"),
+ "google_api_key": OptionInfo("", "Google cloud API key", gr.Textbox),
+ "google_project_id": OptionInfo("", "Google Cloud project ID", gr.Textbox),
+ "google_location_id": OptionInfo("", "Google Cloud location ID", gr.Textbox),
"model_sd3_sep": OptionInfo("Stable Diffusion 3.x
", "", gr.HTML),
"model_sd3_disable_te5": OptionInfo(False, "Disable T5 text encoder"),
"model_h1_sep": OptionInfo("HiDream
", "", gr.HTML),
diff --git a/modules/video_models/google_veo.py b/modules/video_models/google_veo.py
index 92ee43a2e..6e7f25a37 100644
--- a/modules/video_models/google_veo.py
+++ b/modules/video_models/google_veo.py
@@ -69,17 +69,38 @@ class GoogleVeoVideoPipeline():
image=genai.types.Image(image_bytes=image_bytes.getvalue(), mime_type='image/jpeg'),
)
+ def get_args(self):
+ from modules.shared import opts
+ api_key = os.getenv("GOOGLE_API_KEY") or opts.google_api_key
+ vertex_credentials = os.getenv("GOOGLE_APPLICATION_CREDENTIALS")
+ if (api_key is None or len(api_key) == 0) and (vertex_credentials is None or len(vertex_credentials) == 0):
+ log.error(f'Cloud: model="{self.model}" API key not provided')
+ return None
+ use_vertexai = (os.getenv("GOOGLE_GENAI_USE_VERTEXAI") is not None) or opts.google_use_vertexai
+ project_id = os.getenv("GOOGLE_CLOUD_PROJECT") or opts.google_project_id
+ location_id = os.getenv("GOOGLE_CLOUD_LOCATION") or opts.google_location_id
+ args = {
+ 'api_key': api_key,
+ 'vertexai': use_vertexai,
+ 'project': project_id if len(project_id) > 0 else None,
+ 'location': location_id if len(location_id) > 0 else None,
+ }
+ args_copy = args.copy()
+ args_copy['api_key'] = '...' + args_copy['api_key'][-4:] # last 4 chars
+ args_copy['credentials'] = vertex_credentials
+ log.debug(f'Cloud: model="{self.model}" args={args_copy}')
+ return args
+
def __call__(self, prompt: list[str], width: int, height: int, image: Image.Image = None, num_frames: int = 4*24):
from google import genai
if isinstance(prompt, list) and len(prompt) > 0:
prompt = prompt[0]
if self.client is None:
- api_key = os.getenv("GOOGLE_API_KEY", None)
- if api_key is None:
- log.error(f'Cloud: model="{self.model}" GOOGLE_API_KEY environment variable not set')
+ args = self.get_args()
+ if args is None:
return None
- self.client = genai.Client(api_key=api_key, vertexai=False)
+ self.client = genai.Client(**args)
resolution, aspect_ratio = get_size_buckets(width, height)
duration = num_frames // 24
diff --git a/pipelines/model_google.py b/pipelines/model_google.py
index 89089f211..ea608575e 100644
--- a/pipelines/model_google.py
+++ b/pipelines/model_google.py
@@ -67,14 +67,35 @@ class GoogleNanoBananaPipeline():
],
)
+ def get_args(self):
+ from modules.shared import opts
+ api_key = os.getenv("GOOGLE_API_KEY") or opts.google_api_key
+ vertex_credentials = os.getenv("GOOGLE_APPLICATION_CREDENTIALS")
+ if (api_key is None or len(api_key) == 0) and (vertex_credentials is None or len(vertex_credentials) == 0):
+ log.error(f'Cloud: model="{self.model}" API key not provided')
+ return None
+ use_vertexai = (os.getenv("GOOGLE_GENAI_USE_VERTEXAI") is not None) or opts.google_use_vertexai
+ project_id = os.getenv("GOOGLE_CLOUD_PROJECT") or opts.google_project_id
+ location_id = os.getenv("GOOGLE_CLOUD_LOCATION") or opts.google_location_id
+ args = {
+ 'api_key': api_key,
+ 'vertexai': use_vertexai,
+ 'project': project_id if len(project_id) > 0 else None,
+ 'location': location_id if len(location_id) > 0 else None,
+ }
+ args_copy = args.copy()
+ args_copy['api_key'] = '...' + args_copy['api_key'][-4:] # last 4 chars
+ args_copy['credentials'] = vertex_credentials
+ log.debug(f'Cloud: model="{self.model}" args={args_copy}')
+ return args
+
def __call__(self, prompt: list[str], width: int, height: int, image: Image.Image = None):
from google import genai
if self.client is None:
- api_key = os.getenv("GOOGLE_API_KEY", None)
- if api_key is None:
- log.error(f'Cloud: model="{self.model}" GOOGLE_API_KEY environment variable not set')
+ args = self.get_args()
+ if args is None:
return None
- self.client = genai.Client(api_key=api_key, vertexai=False)
+ self.client = genai.Client(**args)
image_size, aspect_ratio = get_size_buckets(width, height)
if 'gemini-3' in self.model:
@@ -85,7 +106,7 @@ class GoogleNanoBananaPipeline():
response_modalities=["IMAGE"],
image_config=image_config
)
- log.debug(f'Cloud: prompt="{prompt}" size={image_size} ar={aspect_ratio} image={image} model="{self.model}"')
+ log.debug(f'Cloud: model="{self.model}" prompt="{prompt}" size={image_size} ar={aspect_ratio} image={image}')
# log.debug(f'Cloud: config={self.config}')
try:
diff --git a/wiki b/wiki
index 12af554d2..e77ba0086 160000
--- a/wiki
+++ b/wiki
@@ -1 +1 @@
-Subproject commit 12af554d26d12ce84d43e35f81da89bdbeac4057
+Subproject commit e77ba0086cdcfd5ae07aa7c4f5a7bb5c2203c0fb