Support Gemini 4 Argon models across GenerateContent and Interactions APIs
This commit is contained in:
+26
-15
@@ -184,6 +184,9 @@ class SSL_GeminiTextPrompt(IO.ComfyNode):
|
||||
_context_cache_lock = threading.Lock()
|
||||
GEMINI_3_7_FLASH = "gemini-3.7-flash"
|
||||
GEMINI_3_8_FLASH = "gemini-3.8-flash"
|
||||
GEMINI_4_ARGON = "gemini-4-argon"
|
||||
GEMINI_4_ARGON_CYBER_PERMISSIVE = "gemini-4-argon-cyber-permissive"
|
||||
ARGON_MODELS = (GEMINI_4_ARGON, GEMINI_4_ARGON_CYBER_PERMISSIVE)
|
||||
VIDEO_MIME_TYPE = "video/mp4"
|
||||
VIDEO_INLINE_LIMIT_BYTES = 100 * 1024 * 1024
|
||||
VERTEX_CACHE_INLINE_LIMIT_BYTES = 10 * 1024 * 1024
|
||||
@@ -197,11 +200,11 @@ class SSL_GeminiTextPrompt(IO.ComfyNode):
|
||||
THINKING_MODELS = [
|
||||
"gemini-1.5-pro-002", "gemini-2.0-flash-thinking-exp", "gemini-2.0-flash-thinking-exp-01-21", "gemini-2.0-flash-thinking-exp-1219",
|
||||
"gemini-2.5-pro", "gemini-2.5-flash", "gemini-2.5-flash-preview-04-17", "gemini-2.5-pro-exp-03-25",
|
||||
"gemini-3-flash-preview", "gemini-3.1-pro-preview", "gemini-3.5-flash", "gemini-3.5-flash-lite", "gemini-3.6-flash", GEMINI_3_7_FLASH, GEMINI_3_8_FLASH, GEMINI_4_FLASH_PREVIEW, "gemini-pro-latest", "gemini-flash-latest", "gemini-flash-lite-latest"
|
||||
"gemini-3-flash-preview", "gemini-3.1-pro-preview", "gemini-3.5-flash", "gemini-3.5-flash-lite", "gemini-3.6-flash", GEMINI_3_7_FLASH, GEMINI_3_8_FLASH, GEMINI_4_ARGON, GEMINI_4_ARGON_CYBER_PERMISSIVE, GEMINI_4_FLASH_PREVIEW, "gemini-pro-latest", "gemini-flash-latest", "gemini-flash-lite-latest"
|
||||
]
|
||||
GEN3_THINKING_MODELS = [
|
||||
"gemini-pro-latest", "gemini-flash-latest", "gemini-3.1-pro-preview",
|
||||
"gemini-3-flash-preview", "gemini-3.5-flash", "gemini-3.5-flash-lite", "gemini-3.6-flash", GEMINI_3_7_FLASH, GEMINI_3_8_FLASH, GEMINI_4_FLASH_PREVIEW
|
||||
"gemini-3-flash-preview", "gemini-3.5-flash", "gemini-3.5-flash-lite", "gemini-3.6-flash", GEMINI_3_7_FLASH, GEMINI_3_8_FLASH, GEMINI_4_ARGON, GEMINI_4_ARGON_CYBER_PERMISSIVE, GEMINI_4_FLASH_PREVIEW
|
||||
]
|
||||
IMAGE_MODELS = [
|
||||
"gemini-2.5-flash-image",
|
||||
@@ -234,7 +237,7 @@ class SSL_GeminiTextPrompt(IO.ComfyNode):
|
||||
cls.GemConfig.Input("config"),
|
||||
IO.String.Input("prompt", multiline=True),
|
||||
IO.String.Input("system_instruction", default="You are a helpful AI assistant.", multiline=True),
|
||||
IO.Combo.Input("model", options=["gemini-1.5-pro-002", "gemini-2.0-flash", "gemini-2.0-flash-lite", "gemini-2.5-flash-preview-04-17", "gemini-2.5-pro-exp-03-25", "gemini-2.5-pro", "gemini-2.5-flash", "gemini-2.5-flash-lite", "gemini-3-flash-preview", "gemini-3.1-flash-lite", "gemini-3.1-pro-preview", "gemini-3.5-flash", "gemini-3.5-flash-lite", "gemini-3.6-flash", cls.GEMINI_3_7_FLASH, cls.GEMINI_3_8_FLASH, "gemini-3.1-flash-image", "gemini-3.1-flash-lite-image", "gemini-3-pro-image", "gemini-pro-latest", "gemini-flash-latest", "gemini-flash-lite-latest"], default="gemini-2.5-flash"),
|
||||
IO.Combo.Input("model", options=["gemini-1.5-pro-002", "gemini-2.0-flash", "gemini-2.0-flash-lite", "gemini-2.5-flash-preview-04-17", "gemini-2.5-pro-exp-03-25", "gemini-2.5-pro", "gemini-2.5-flash", "gemini-2.5-flash-lite", "gemini-3-flash-preview", "gemini-3.1-flash-lite", "gemini-3.1-pro-preview", "gemini-3.5-flash", "gemini-3.5-flash-lite", "gemini-3.6-flash", cls.GEMINI_3_7_FLASH, cls.GEMINI_3_8_FLASH, cls.GEMINI_4_ARGON, cls.GEMINI_4_ARGON_CYBER_PERMISSIVE, "gemini-3.1-flash-image", "gemini-3.1-flash-lite-image", "gemini-3-pro-image", "gemini-pro-latest", "gemini-flash-latest", "gemini-flash-lite-latest"], default="gemini-2.5-flash"),
|
||||
IO.Float.Input("temperature", default=1.0, min=0.0, max=1.0, step=0.01),
|
||||
IO.Float.Input("top_p", default=0.95, min=0.0, max=1.0, step=0.01),
|
||||
IO.Int.Input("top_k", default=40, min=1, max=100, step=1),
|
||||
@@ -438,11 +441,13 @@ class SSL_GeminiTextPrompt(IO.ComfyNode):
|
||||
@classmethod
|
||||
def _resolve_gemini_3_7_thinking_level(cls, thinking_level, model_name=None):
|
||||
if thinking_level is None or thinking_level == "None":
|
||||
if model_name == cls.GEMINI_4_ARGON_CYBER_PERMISSIVE:
|
||||
return "high"
|
||||
return "medium"
|
||||
if thinking_level == "minimal":
|
||||
if model_name == cls.GEMINI_3_8_FLASH:
|
||||
if model_name in (cls.GEMINI_3_8_FLASH, cls.GEMINI_4_ARGON, cls.GEMINI_4_ARGON_CYBER_PERMISSIVE):
|
||||
raise ValueError(
|
||||
"gemini-3.8-flash thinking_level must be low, medium, or high."
|
||||
f"{model_name} thinking_level must be low, medium, or high."
|
||||
)
|
||||
print(
|
||||
f"[WARNING] {model_name or 'Gemini 3.7 Flash'} does not support minimal "
|
||||
@@ -488,9 +493,9 @@ class SSL_GeminiTextPrompt(IO.ComfyNode):
|
||||
eff_thinking_level = "None"
|
||||
eff_thinking_budget = -1
|
||||
eff_include_thoughts = False
|
||||
eff_temperature = None if model == cls.GEMINI_3_7_FLASH else float(temperature)
|
||||
eff_top_p = None if model == cls.GEMINI_3_7_FLASH else float(top_p)
|
||||
eff_top_k = None if model == cls.GEMINI_3_7_FLASH else int(top_k)
|
||||
eff_temperature = None if model in (cls.GEMINI_3_7_FLASH, cls.GEMINI_3_8_FLASH, cls.GEMINI_4_ARGON, cls.GEMINI_4_ARGON_CYBER_PERMISSIVE) else float(temperature)
|
||||
eff_top_p = None if model in (cls.GEMINI_3_7_FLASH, cls.GEMINI_3_8_FLASH, cls.GEMINI_4_ARGON, cls.GEMINI_4_ARGON_CYBER_PERMISSIVE) else float(top_p)
|
||||
eff_top_k = None if model in (cls.GEMINI_3_7_FLASH, cls.GEMINI_3_8_FLASH, cls.GEMINI_4_ARGON, cls.GEMINI_4_ARGON_CYBER_PERMISSIVE) else int(top_k)
|
||||
|
||||
# Logic mirroring _build_generate_content_config exactly
|
||||
if include_images and model in cls.IMAGE_MODELS:
|
||||
@@ -499,7 +504,7 @@ class SSL_GeminiTextPrompt(IO.ComfyNode):
|
||||
eff_image_size = "None" if image_size in (None, "None") else str(image_size)
|
||||
# When generating images, thinking params are ignored
|
||||
|
||||
elif model in (cls.GEMINI_3_7_FLASH, cls.GEMINI_3_8_FLASH):
|
||||
elif model in (cls.GEMINI_3_7_FLASH, cls.GEMINI_3_8_FLASH, cls.GEMINI_4_ARGON, cls.GEMINI_4_ARGON_CYBER_PERMISSIVE):
|
||||
eff_thinking_level = cls._resolve_gemini_3_7_thinking_level(thinking_level, model)
|
||||
eff_include_thoughts = include_thoughts
|
||||
|
||||
@@ -750,7 +755,7 @@ class SSL_GeminiTextPrompt(IO.ComfyNode):
|
||||
system_instruction=[types.Part.from_text(text=padded_system_instruction)],
|
||||
)
|
||||
|
||||
if model in (cls.GEMINI_3_7_FLASH, cls.GEMINI_3_8_FLASH):
|
||||
if model in (cls.GEMINI_3_7_FLASH, cls.GEMINI_3_8_FLASH, cls.GEMINI_4_ARGON, cls.GEMINI_4_ARGON_CYBER_PERMISSIVE):
|
||||
return types.GenerateContentConfig(
|
||||
max_output_tokens=max_output_tokens,
|
||||
safety_settings=safety,
|
||||
@@ -1097,13 +1102,19 @@ class SSL_GeminiTextPrompt(IO.ComfyNode):
|
||||
)
|
||||
|
||||
skip_context_cache = (
|
||||
use_cache
|
||||
and video_bytes is not None
|
||||
and (config.get("use_vertexai_env", False) or config.get("vertexai_express", False))
|
||||
and context_inline_bytes > cls.VERTEX_CACHE_INLINE_LIMIT_BYTES
|
||||
(
|
||||
use_cache
|
||||
and video_bytes is not None
|
||||
and (config.get("use_vertexai_env", False) or config.get("vertexai_express", False))
|
||||
and context_inline_bytes > cls.VERTEX_CACHE_INLINE_LIMIT_BYTES
|
||||
)
|
||||
or (use_cache and model in cls.ARGON_MODELS)
|
||||
)
|
||||
if skip_context_cache:
|
||||
print("[WARNING] Vertex context cache skipped because inline cached media exceeds 10 MB; using full request")
|
||||
if use_cache and model in cls.ARGON_MODELS:
|
||||
print(f"[WARNING] Explicit context cache skipped for {model} (implicit caching only); using full request")
|
||||
else:
|
||||
print("[WARNING] Vertex context cache skipped because inline cached media exceeds 10 MB; using full request")
|
||||
|
||||
generate_content_config = cls._build_generate_content_config(
|
||||
model=model,
|
||||
|
||||
+12
-7
@@ -262,6 +262,9 @@ class SSL_GeminiInteractionsTextPrompt(IO.ComfyNode):
|
||||
_client_cache: dict = {} # Maps client_key tuple -> genai.Client instance
|
||||
GEMINI_3_7_FLASH = "gemini-3.7-flash"
|
||||
GEMINI_3_8_FLASH = "gemini-3.8-flash"
|
||||
GEMINI_4_ARGON = "gemini-4-argon"
|
||||
GEMINI_4_ARGON_CYBER_PERMISSIVE = "gemini-4-argon-cyber-permissive"
|
||||
ARGON_MODELS = (GEMINI_4_ARGON, GEMINI_4_ARGON_CYBER_PERMISSIVE)
|
||||
VIDEO_MIME_TYPE = "video/mp4"
|
||||
VIDEO_INLINE_LIMIT_BYTES = 100 * 1024 * 1024
|
||||
|
||||
@@ -283,11 +286,11 @@ class SSL_GeminiInteractionsTextPrompt(IO.ComfyNode):
|
||||
THINKING_MODELS = [
|
||||
"gemini-1.5-pro-002", "gemini-2.0-flash-thinking-exp", "gemini-2.0-flash-thinking-exp-01-21", "gemini-2.0-flash-thinking-exp-1219",
|
||||
"gemini-2.5-pro", "gemini-2.5-flash", "gemini-2.5-flash-preview-04-17", "gemini-2.5-pro-exp-03-25",
|
||||
"gemini-3-flash-preview", "gemini-3.1-pro-preview", "gemini-3.5-flash", "gemini-3.5-flash-lite", "gemini-3.6-flash", GEMINI_3_7_FLASH, GEMINI_3_8_FLASH, GEMINI_4_FLASH_PREVIEW, "gemini-pro-latest", "gemini-flash-latest", "gemini-flash-lite-latest"
|
||||
"gemini-3-flash-preview", "gemini-3.1-pro-preview", "gemini-3.5-flash", "gemini-3.5-flash-lite", "gemini-3.6-flash", GEMINI_3_7_FLASH, GEMINI_3_8_FLASH, GEMINI_4_ARGON, GEMINI_4_ARGON_CYBER_PERMISSIVE, GEMINI_4_FLASH_PREVIEW, "gemini-pro-latest", "gemini-flash-latest", "gemini-flash-lite-latest"
|
||||
]
|
||||
GEN3_THINKING_MODELS = [
|
||||
"gemini-pro-latest", "gemini-flash-latest", "gemini-3.1-pro-preview",
|
||||
"gemini-3-flash-preview", "gemini-3.5-flash", "gemini-3.5-flash-lite", "gemini-3.6-flash", GEMINI_3_7_FLASH, GEMINI_3_8_FLASH, GEMINI_4_FLASH_PREVIEW
|
||||
"gemini-3-flash-preview", "gemini-3.5-flash", "gemini-3.5-flash-lite", "gemini-3.6-flash", GEMINI_3_7_FLASH, GEMINI_3_8_FLASH, GEMINI_4_ARGON, GEMINI_4_ARGON_CYBER_PERMISSIVE, GEMINI_4_FLASH_PREVIEW
|
||||
]
|
||||
IMAGE_MODELS = [
|
||||
"gemini-2.5-flash-image",
|
||||
@@ -320,7 +323,7 @@ class SSL_GeminiInteractionsTextPrompt(IO.ComfyNode):
|
||||
cls.GemConfig.Input("config"),
|
||||
IO.String.Input("prompt", multiline=True),
|
||||
IO.String.Input("system_instruction", default="You are a helpful AI assistant.", multiline=True),
|
||||
IO.Combo.Input("model", options=["gemini-1.5-pro-002", "gemini-2.0-flash", "gemini-2.0-flash-lite", "gemini-2.5-flash-preview-04-17", "gemini-2.5-pro-exp-03-25", "gemini-2.5-pro", "gemini-2.5-flash", "gemini-2.5-flash-lite", "gemini-3-flash-preview", "gemini-3.1-flash-lite", "gemini-3.1-pro-preview", "gemini-3.5-flash", "gemini-3.5-flash-lite", "gemini-3.6-flash", cls.GEMINI_3_7_FLASH, cls.GEMINI_3_8_FLASH, "gemini-3.1-flash-image", "gemini-3.1-flash-lite-image", "gemini-3-pro-image", "gemini-pro-latest", "gemini-flash-latest", "gemini-flash-lite-latest"], default="gemini-2.5-flash"),
|
||||
IO.Combo.Input("model", options=["gemini-1.5-pro-002", "gemini-2.0-flash", "gemini-2.0-flash-lite", "gemini-2.5-flash-preview-04-17", "gemini-2.5-pro-exp-03-25", "gemini-2.5-pro", "gemini-2.5-flash", "gemini-2.5-flash-lite", "gemini-3-flash-preview", "gemini-3.1-flash-lite", "gemini-3.1-pro-preview", "gemini-3.5-flash", "gemini-3.5-flash-lite", "gemini-3.6-flash", cls.GEMINI_3_7_FLASH, cls.GEMINI_3_8_FLASH, cls.GEMINI_4_ARGON, cls.GEMINI_4_ARGON_CYBER_PERMISSIVE, "gemini-3.1-flash-image", "gemini-3.1-flash-lite-image", "gemini-3-pro-image", "gemini-pro-latest", "gemini-flash-latest", "gemini-flash-lite-latest"], default="gemini-2.5-flash"),
|
||||
IO.Float.Input("temperature", default=1.0, min=0.0, max=1.0, step=0.01, tooltip="Ignored in Interactions API"),
|
||||
IO.Float.Input("top_p", default=0.95, min=0.0, max=1.0, step=0.01, tooltip="Ignored in Interactions API"),
|
||||
IO.Int.Input("top_k", default=40, min=1, max=100, step=1, tooltip="Ignored in Interactions API"),
|
||||
@@ -525,11 +528,13 @@ class SSL_GeminiInteractionsTextPrompt(IO.ComfyNode):
|
||||
@classmethod
|
||||
def _resolve_gemini_3_7_thinking_level(cls, thinking_level, model_name=None):
|
||||
if thinking_level is None or thinking_level == "None":
|
||||
if model_name == cls.GEMINI_4_ARGON_CYBER_PERMISSIVE:
|
||||
return "high"
|
||||
return "medium"
|
||||
if thinking_level == "minimal":
|
||||
if model_name == cls.GEMINI_3_8_FLASH:
|
||||
if model_name in (cls.GEMINI_3_8_FLASH, cls.GEMINI_4_ARGON, cls.GEMINI_4_ARGON_CYBER_PERMISSIVE):
|
||||
raise ValueError(
|
||||
"gemini-3.8-flash thinking_level must be low, medium, or high."
|
||||
f"{model_name} thinking_level must be low, medium, or high."
|
||||
)
|
||||
print(
|
||||
f"[WARNING] {model_name or 'Gemini 3.7 Flash'} does not support minimal "
|
||||
@@ -606,7 +611,7 @@ class SSL_GeminiInteractionsTextPrompt(IO.ComfyNode):
|
||||
eff_aspect_ratio = str(aspect_ratio)
|
||||
eff_image_size = "None" if image_size in (None, "None") else str(image_size)
|
||||
|
||||
elif model in (cls.GEMINI_3_7_FLASH, cls.GEMINI_3_8_FLASH):
|
||||
elif model in (cls.GEMINI_3_7_FLASH, cls.GEMINI_3_8_FLASH, cls.GEMINI_4_ARGON, cls.GEMINI_4_ARGON_CYBER_PERMISSIVE):
|
||||
eff_thinking_level = cls._resolve_gemini_3_7_thinking_level(thinking_level, model)
|
||||
eff_include_thoughts = include_thoughts
|
||||
|
||||
@@ -1075,7 +1080,7 @@ class SSL_GeminiInteractionsTextPrompt(IO.ComfyNode):
|
||||
|
||||
# Assemble generation_config
|
||||
effective_thinking_level = None
|
||||
if model in (cls.GEMINI_3_7_FLASH, cls.GEMINI_3_8_FLASH):
|
||||
if model in (cls.GEMINI_3_7_FLASH, cls.GEMINI_3_8_FLASH, cls.GEMINI_4_ARGON, cls.GEMINI_4_ARGON_CYBER_PERMISSIVE):
|
||||
effective_thinking_level = cls._resolve_gemini_3_7_thinking_level(thinking_level, model)
|
||||
elif model in cls.GEN3_THINKING_MODELS and thinking_level not in (None, "None"):
|
||||
effective_thinking_level = thinking_level
|
||||
|
||||
@@ -56,6 +56,8 @@ def structured_client(monkeypatch):
|
||||
("gemini-2.5-flash", {}), ("gemini-3.1-pro-preview", {"thinking_level": "high"}),
|
||||
(gemini_nodes.SSL_GeminiTextPrompt.GEMINI_3_7_FLASH, {"thinking_level": "medium"}),
|
||||
(gemini_nodes.SSL_GeminiTextPrompt.GEMINI_3_8_FLASH, {"thinking_level": "medium"}),
|
||||
(gemini_nodes.SSL_GeminiTextPrompt.GEMINI_4_ARGON, {"thinking_level": "medium"}),
|
||||
(gemini_nodes.SSL_GeminiTextPrompt.GEMINI_4_ARGON_CYBER_PERMISSIVE, {"thinking_level": "high"}),
|
||||
])
|
||||
@pytest.mark.parametrize("client_config", [{}, {"vertexai_express": True}, {"use_vertexai_env": True, "vertexai_project": "test", "vertexai_location": "global"}])
|
||||
def test_builder_schema_reaches_generate_content(structured_client, monkeypatch, model, settings, client_config):
|
||||
@@ -1193,6 +1195,8 @@ def test_confirmed_current_models_are_visible_without_deprecated_image_aliases()
|
||||
image_size = next(input_ for input_ in schema.inputs if input_.id == "image_size")
|
||||
|
||||
for model in (
|
||||
"gemini-4-argon",
|
||||
"gemini-4-argon-cyber-permissive",
|
||||
"gemini-3.7-flash",
|
||||
"gemini-3.8-flash",
|
||||
"gemini-3.5-flash",
|
||||
@@ -1390,6 +1394,110 @@ def test_gemini_3_8_rejects_minimal_thinking_level():
|
||||
)
|
||||
|
||||
|
||||
def test_gemini_4_argon_uses_gemini_3_thinking_config():
|
||||
config = gemini_nodes.SSL_GeminiTextPrompt._build_generate_content_config(
|
||||
model="gemini-4-argon",
|
||||
temperature=0.4,
|
||||
top_p=0.8,
|
||||
top_k=20,
|
||||
max_output_tokens=1024,
|
||||
seed=7,
|
||||
include_images=False,
|
||||
response_modalities=["TEXT"],
|
||||
aspect_ratio="None",
|
||||
padded_system_instruction="system",
|
||||
thinking_level="None",
|
||||
thinking_budget=4096,
|
||||
include_thoughts=True,
|
||||
media_resolution="unspecified",
|
||||
)
|
||||
|
||||
assert config.thinking_config.thinking_level.value == "MEDIUM"
|
||||
assert config.thinking_config.thinking_budget is None
|
||||
assert config.temperature is None
|
||||
assert config.top_p is None
|
||||
assert config.top_k is None
|
||||
|
||||
# Cyber permissive variant defaults to HIGH thinking level
|
||||
config_cyber = gemini_nodes.SSL_GeminiTextPrompt._build_generate_content_config(
|
||||
model="gemini-4-argon-cyber-permissive",
|
||||
temperature=0.4,
|
||||
top_p=0.8,
|
||||
top_k=20,
|
||||
max_output_tokens=1024,
|
||||
seed=7,
|
||||
include_images=False,
|
||||
response_modalities=["TEXT"],
|
||||
aspect_ratio="None",
|
||||
padded_system_instruction="system",
|
||||
thinking_level="None",
|
||||
thinking_budget=4096,
|
||||
include_thoughts=True,
|
||||
media_resolution="unspecified",
|
||||
)
|
||||
assert config_cyber.thinking_config.thinking_level.value == "HIGH"
|
||||
assert config_cyber.thinking_config.thinking_budget is None
|
||||
assert config_cyber.temperature is None
|
||||
assert config_cyber.top_p is None
|
||||
assert config_cyber.top_k is None
|
||||
|
||||
|
||||
def test_gemini_4_argon_rejects_minimal_thinking_level():
|
||||
with pytest.raises(ValueError, match="gemini-4-argon thinking_level"):
|
||||
gemini_nodes.SSL_GeminiTextPrompt._resolve_gemini_3_7_thinking_level(
|
||||
"minimal", gemini_nodes.SSL_GeminiTextPrompt.GEMINI_4_ARGON
|
||||
)
|
||||
with pytest.raises(ValueError, match="gemini-4-argon-cyber-permissive thinking_level"):
|
||||
gemini_nodes.SSL_GeminiTextPrompt._resolve_gemini_3_7_thinking_level(
|
||||
"minimal", gemini_nodes.SSL_GeminiTextPrompt.GEMINI_4_ARGON_CYBER_PERMISSIVE
|
||||
)
|
||||
|
||||
|
||||
def test_gemini_4_argon_fingerprint_omits_sampling_params():
|
||||
common = {
|
||||
"config": {"api_key": "key", "api_version": "v1"},
|
||||
"prompt": "prompt",
|
||||
"system_instruction": "system",
|
||||
"model": "gemini-4-argon",
|
||||
"max_output_tokens": 1024,
|
||||
"include_images": False,
|
||||
"aspect_ratio": "None",
|
||||
"bypass_mode": "None",
|
||||
"use_seed": False,
|
||||
"seed": 0,
|
||||
"include_thoughts": True,
|
||||
}
|
||||
|
||||
fp1, _ = gemini_nodes.SSL_GeminiTextPrompt._compute_fingerprint_and_check_cache(
|
||||
**common,
|
||||
temperature=0.1,
|
||||
top_p=0.5,
|
||||
top_k=10,
|
||||
thinking_budget=0,
|
||||
thinking_level="medium",
|
||||
)
|
||||
fp2, _ = gemini_nodes.SSL_GeminiTextPrompt._compute_fingerprint_and_check_cache(
|
||||
**common,
|
||||
temperature=0.9,
|
||||
top_p=0.99,
|
||||
top_k=90,
|
||||
thinking_budget=1000,
|
||||
thinking_level="medium",
|
||||
)
|
||||
assert fp1 == fp2
|
||||
|
||||
|
||||
def test_gemini_4_argon_skips_explicit_context_cache(structured_client):
|
||||
structured_client.responses = [[("final", "argon response")]]
|
||||
args = _execute_kwargs(_config(use_cache=True, cache_seed=42))
|
||||
args["model"] = "gemini-4-argon"
|
||||
output = gemini_nodes.SSL_GeminiTextPrompt.execute(**args)
|
||||
assert output[0] == "argon response"
|
||||
assert len(structured_client.calls) == 1
|
||||
# Explicit cache was not set on the request config
|
||||
assert structured_client.calls[0]["config"].cached_content is None
|
||||
|
||||
|
||||
def test_gemini_3_7_fingerprint_matches_effective_request_controls():
|
||||
common = {
|
||||
"config": {"api_key": "key", "api_version": "v1"},
|
||||
|
||||
@@ -155,6 +155,10 @@ def test_interactions_define_schema():
|
||||
assert "response_schema" in input_names
|
||||
assert "image_inputs" in input_names
|
||||
|
||||
model_input = next(i for i in schema.inputs if i.id == "model")
|
||||
assert "gemini-4-argon" in model_input.options
|
||||
assert "gemini-4-argon-cyber-permissive" in model_input.options
|
||||
|
||||
output_names = [o.id for o in schema.outputs]
|
||||
assert output_names == ["text", "image", "final_actual_seed", "structured_output", "thoughts", "interaction_id"]
|
||||
|
||||
@@ -341,6 +345,47 @@ def test_thinking_and_thoughts_extraction(mock_interactions_client):
|
||||
assert call["generation_config"]["thinking_summaries"] == "auto"
|
||||
|
||||
|
||||
def test_interactions_gemini_4_argon_thinking(mock_interactions_client):
|
||||
mock_interactions_client.responses = [
|
||||
{"text": "argon 1", "thoughts": "think 1", "id": "int_argon_1"},
|
||||
{"text": "argon 2", "thoughts": "think 2", "id": "int_argon_2"},
|
||||
]
|
||||
|
||||
# gemini-4-argon defaults to medium thinking level
|
||||
args1 = _execute_kwargs(
|
||||
model="gemini-4-argon",
|
||||
thinking_level="None",
|
||||
include_thoughts=True,
|
||||
)
|
||||
interactions_nodes.SSL_GeminiInteractionsTextPrompt.execute(**args1)
|
||||
call1 = mock_interactions_client.calls[0]
|
||||
assert call1["model"] == "gemini-4-argon"
|
||||
assert call1["generation_config"]["thinking_level"] == "medium"
|
||||
assert call1["generation_config"]["thinking_summaries"] == "auto"
|
||||
|
||||
# gemini-4-argon-cyber-permissive defaults to high thinking level
|
||||
args2 = _execute_kwargs(
|
||||
model="gemini-4-argon-cyber-permissive",
|
||||
thinking_level="None",
|
||||
include_thoughts=True,
|
||||
)
|
||||
interactions_nodes.SSL_GeminiInteractionsTextPrompt.execute(**args2)
|
||||
call2 = mock_interactions_client.calls[1]
|
||||
assert call2["model"] == "gemini-4-argon-cyber-permissive"
|
||||
assert call2["generation_config"]["thinking_level"] == "high"
|
||||
|
||||
|
||||
def test_interactions_gemini_4_argon_rejects_minimal():
|
||||
with pytest.raises(ValueError, match="gemini-4-argon thinking_level"):
|
||||
interactions_nodes.SSL_GeminiInteractionsTextPrompt._resolve_gemini_3_7_thinking_level(
|
||||
"minimal", interactions_nodes.SSL_GeminiInteractionsTextPrompt.GEMINI_4_ARGON
|
||||
)
|
||||
with pytest.raises(ValueError, match="gemini-4-argon-cyber-permissive thinking_level"):
|
||||
interactions_nodes.SSL_GeminiInteractionsTextPrompt._resolve_gemini_3_7_thinking_level(
|
||||
"minimal", interactions_nodes.SSL_GeminiInteractionsTextPrompt.GEMINI_4_ARGON_CYBER_PERMISSIVE
|
||||
)
|
||||
|
||||
|
||||
def test_multi_turn_chaining(mock_interactions_client):
|
||||
mock_interactions_client.responses = [
|
||||
{"text": "Turn 1 answer", "id": "int_turn_1"},
|
||||
|
||||
Reference in New Issue
Block a user