Use first list seed for fingerprint basis and preserve cache_seed unmodified
This commit is contained in:
+9
-25
@@ -1018,13 +1018,15 @@ class SSL_GeminiTextPrompt(IO.ComfyNode):
|
||||
image_inputs: IO.Autogrow.Type | None = None,
|
||||
response_schema: ResponseSchema.Type | None = None,
|
||||
prepared_images: dict[str, Any] | None = None,
|
||||
precomputed_video: Tuple[bytes | None, str | None, str | None, int | None] | None = None) -> IO.NodeOutput:
|
||||
precomputed_video: Tuple[bytes | None, str | None, str | None, int | None] | None = None,
|
||||
fingerprint_seed: int | None = None) -> IO.NodeOutput:
|
||||
|
||||
cls._check_interrupt()
|
||||
print(f"[INFO] SSL_GeminiTextPrompt execute called, model: {model}")
|
||||
use_cache = bool(config.get("use_cache", False))
|
||||
cache_ttl_minutes = int(config.get("cache_ttl_minutes", 60))
|
||||
cache_seed = int(config.get("cache_seed", 0))
|
||||
fp_seed = int(seed if fingerprint_seed is None else fingerprint_seed)
|
||||
schema_identity = None
|
||||
schema_snapshot = None
|
||||
if response_schema is not None:
|
||||
@@ -1056,7 +1058,7 @@ class SSL_GeminiTextPrompt(IO.ComfyNode):
|
||||
precomputed_image_hashes = prepared_images["image_hashes"] if prepared_images is not None else None
|
||||
fingerprint, cached = cls._compute_fingerprint_and_check_cache(
|
||||
config, prompt, system_instruction, model, temperature, top_p, top_k, max_output_tokens,
|
||||
include_images, aspect_ratio, bypass_mode, thinking_budget, use_seed, seed,
|
||||
include_images, aspect_ratio, bypass_mode, thinking_budget, use_seed, fp_seed,
|
||||
video_hash, video_mime_type, video_fps,
|
||||
image_inputs,
|
||||
use_proxy, proxy_host, proxy_port, timeout,
|
||||
@@ -1724,37 +1726,18 @@ class SSL_GeminiTextPrompt(IO.ComfyNode):
|
||||
timeout_fb_val = str(_unwrap_scalar(timeout_fallback_text, ""))
|
||||
img_size_val = str(_unwrap_scalar(image_size, "None"))
|
||||
resp_schema_val = _unwrap_scalar(response_schema, None)
|
||||
has_multi_seed_input = is_seed_list and len(seed_list) > 1
|
||||
base_seed = int(seed_list[0]) if (is_seed_list and len(seed_list) > 0) else int(_unwrap_scalar(seed, 0))
|
||||
has_distinct_item_inputs = (is_prompt_list and len(prompt_list) > 1) or (is_video_list and len(video_list) > 1)
|
||||
|
||||
def make_item_kwargs(idx, prepared_imgs=None, precomp_vid=None):
|
||||
p = prompt_list[min(idx, len(prompt_list) - 1)] if prompt_list else ""
|
||||
v = video_list[min(idx, len(video_list) - 1)] if video_list else None
|
||||
|
||||
if has_multi_seed_input:
|
||||
if idx < len(seed_list):
|
||||
s = int(seed_list[idx])
|
||||
else:
|
||||
base_s = int(seed_list[-1])
|
||||
s = (base_s + (idx - len(seed_list) + 1)) if base_s != 0 else 0
|
||||
elif is_seed_list and len(seed_list) == 1:
|
||||
base_s = int(seed_list[0])
|
||||
s = (base_s + idx) if (base_s != 0 and batch_count > 1) else base_s
|
||||
elif not is_seed_list and seed != 0:
|
||||
s = (int(seed) + idx) if batch_count > 1 else int(seed)
|
||||
else:
|
||||
s = int(_unwrap_scalar(seed, 0))
|
||||
s = (base_seed + idx) if (base_seed != 0 and batch_count > 1) else base_seed
|
||||
fp_seed = base_seed if has_distinct_item_inputs else s
|
||||
|
||||
raw_cfg = _get_aligned(config_list, idx, config_val)
|
||||
item_cfg = dict(raw_cfg) if isinstance(raw_cfg, dict) else dict(config_val)
|
||||
if item_cfg.get("use_cache"):
|
||||
if has_multi_seed_input:
|
||||
item_cfg["cache_seed"] = s
|
||||
elif batch_count > 1 and not (is_config_list and len(config_list) > 1):
|
||||
base_cs = int(item_cfg.get("cache_seed", 0))
|
||||
if base_cs != 0:
|
||||
item_cfg["cache_seed"] = base_cs + idx
|
||||
elif s != 0:
|
||||
item_cfg["cache_seed"] = s
|
||||
|
||||
sys_inst = _get_aligned(system_instruction, idx, "You are a helpful AI assistant.")
|
||||
|
||||
@@ -1789,6 +1772,7 @@ class SSL_GeminiTextPrompt(IO.ComfyNode):
|
||||
"response_schema": resp_schema_val,
|
||||
"prepared_images": prepared_imgs,
|
||||
"precomputed_video": precomp_vid,
|
||||
"fingerprint_seed": fp_seed,
|
||||
}
|
||||
|
||||
if batch_count == 1:
|
||||
|
||||
+9
-25
@@ -861,7 +861,8 @@ class SSL_GeminiInteractionsTextPrompt(IO.ComfyNode):
|
||||
response_schema: ResponseSchema.Type | None = None,
|
||||
prepared_images: dict[str, Any] | None = None,
|
||||
precomputed_video: Tuple[bytes | None, str | None, str | None, int | None] | None = None,
|
||||
chained_previous_id: str = "") -> IO.NodeOutput:
|
||||
chained_previous_id: str = "",
|
||||
fingerprint_seed: int | None = None) -> IO.NodeOutput:
|
||||
|
||||
cls._check_interrupt()
|
||||
print(f"[INFO] SSL_GeminiInteractionsTextPrompt execute called, model: {model}")
|
||||
@@ -911,6 +912,7 @@ class SSL_GeminiInteractionsTextPrompt(IO.ComfyNode):
|
||||
use_cache = bool(config.get("use_cache", False))
|
||||
cache_ttl_minutes = int(config.get("cache_ttl_minutes", 60))
|
||||
cache_seed = int(config.get("cache_seed", 0))
|
||||
fp_seed = int(seed if fingerprint_seed is None else fingerprint_seed)
|
||||
|
||||
schema_identity = None
|
||||
schema_snapshot = None
|
||||
@@ -959,7 +961,7 @@ class SSL_GeminiInteractionsTextPrompt(IO.ComfyNode):
|
||||
precomputed_image_hashes = prepared_images["image_hashes"] if prepared_images is not None else None
|
||||
fingerprint, cached = cls._compute_fingerprint_and_check_cache(
|
||||
config, prompt, system_instruction, model, max_output_tokens,
|
||||
include_images, aspect_ratio, bypass_mode, use_seed, seed,
|
||||
include_images, aspect_ratio, bypass_mode, use_seed, fp_seed,
|
||||
video_hash, video_mime_type, video_fps,
|
||||
image_inputs,
|
||||
use_proxy, proxy_host, proxy_port, timeout,
|
||||
@@ -1613,37 +1615,18 @@ class SSL_GeminiInteractionsTextPrompt(IO.ComfyNode):
|
||||
store_val = cls._normalize_store_mode(_unwrap_scalar(store, "new"))
|
||||
resp_schema_val = _unwrap_scalar(response_schema, None)
|
||||
is_prev_id_list = _is_list_arg(previous_interaction_id) and len(previous_interaction_id) > 1
|
||||
has_multi_seed_input = is_seed_list and len(seed_list) > 1
|
||||
base_seed = int(seed_list[0]) if (is_seed_list and len(seed_list) > 0) else int(_unwrap_scalar(seed, 0))
|
||||
has_distinct_item_inputs = (is_prompt_list and len(prompt_list) > 1) or (is_video_list and len(video_list) > 1)
|
||||
|
||||
def make_item_kwargs(idx, chained_prev_id="", prepared_imgs=None, precomp_vid=None):
|
||||
p = prompt_list[min(idx, len(prompt_list) - 1)] if prompt_list else ""
|
||||
v = video_list[min(idx, len(video_list) - 1)] if video_list else None
|
||||
|
||||
if has_multi_seed_input:
|
||||
if idx < len(seed_list):
|
||||
s = int(seed_list[idx])
|
||||
else:
|
||||
base_s = int(seed_list[-1])
|
||||
s = (base_s + (idx - len(seed_list) + 1)) if base_s != 0 else 0
|
||||
elif is_seed_list and len(seed_list) == 1:
|
||||
base_s = int(seed_list[0])
|
||||
s = (base_s + idx) if (base_s != 0 and batch_count > 1) else base_s
|
||||
elif not is_seed_list and seed != 0:
|
||||
s = (int(seed) + idx) if batch_count > 1 else int(seed)
|
||||
else:
|
||||
s = int(_unwrap_scalar(seed, 0))
|
||||
s = (base_seed + idx) if (base_seed != 0 and batch_count > 1) else base_seed
|
||||
fp_seed = base_seed if has_distinct_item_inputs else s
|
||||
|
||||
raw_cfg = _get_aligned(config_list, idx, config_val)
|
||||
item_cfg = dict(raw_cfg) if isinstance(raw_cfg, dict) else dict(config_val)
|
||||
if item_cfg.get("use_cache"):
|
||||
if has_multi_seed_input:
|
||||
item_cfg["cache_seed"] = s
|
||||
elif batch_count > 1 and not (is_config_list and len(config_list) > 1):
|
||||
base_cs = int(item_cfg.get("cache_seed", 0))
|
||||
if base_cs != 0:
|
||||
item_cfg["cache_seed"] = base_cs + idx
|
||||
elif s != 0:
|
||||
item_cfg["cache_seed"] = s
|
||||
|
||||
sys_inst = _get_aligned(system_instruction, idx, "You are a helpful AI assistant.")
|
||||
eff_store = "previous" if (store_val == "new" and idx > 0) else store_val
|
||||
@@ -1689,6 +1672,7 @@ class SSL_GeminiInteractionsTextPrompt(IO.ComfyNode):
|
||||
"prepared_images": prepared_imgs,
|
||||
"precomputed_video": precomp_vid,
|
||||
"chained_previous_id": chained_prev_id,
|
||||
"fingerprint_seed": fp_seed,
|
||||
}
|
||||
|
||||
if batch_count == 1:
|
||||
|
||||
@@ -1761,8 +1761,8 @@ def test_gemini_batch_seeds(structured_client):
|
||||
[("final", "Resp 1")],
|
||||
[("final", "Resp 2")],
|
||||
]
|
||||
args = _execute_kwargs(_config(use_cache=True, cache_seed=615665156))
|
||||
args.update(prompt="Single prompt", use_seed=True, seed=[[101, 102]])
|
||||
args = _execute_kwargs(_config())
|
||||
args.update(prompt=["Prompt 1", "Prompt 2"], use_seed=True, seed=[[101, 999]])
|
||||
output = gemini_nodes.SSL_GeminiTextPrompt.execute(**args)
|
||||
|
||||
assert isinstance(output[0], list) and len(output[0]) == 2
|
||||
@@ -1771,6 +1771,11 @@ def test_gemini_batch_seeds(structured_client):
|
||||
assert len(structured_client.calls) == 2
|
||||
assert structured_client.calls[0]["config"].seed == 101
|
||||
assert structured_client.calls[1]["config"].seed == 102
|
||||
assert all(fp[14] == 101 for fp in gemini_nodes.SSL_GeminiTextPrompt._cache)
|
||||
|
||||
repeat = gemini_nodes.SSL_GeminiTextPrompt.execute(**args)
|
||||
assert repeat[0] == ["Resp 1", "Resp 2"]
|
||||
assert len(structured_client.calls) == 2
|
||||
|
||||
|
||||
def test_gemini_batch_single_list_element(structured_client):
|
||||
|
||||
@@ -794,8 +794,7 @@ def test_interactions_batch_seeds(mock_interactions_client):
|
||||
{"text": "A1", "id": "i1"},
|
||||
{"text": "A2", "id": "i2"},
|
||||
]
|
||||
config = _config(use_cache=True, cache_seed=615665156)
|
||||
args = _execute_kwargs(config=config, prompt="Single", use_seed=True, seed=[[501, 502]], store="new")
|
||||
args = _execute_kwargs(prompt=["Prompt 1", "Prompt 2"], use_seed=True, seed=[[501, 999]], store="new")
|
||||
output = interactions_nodes.SSL_GeminiInteractionsTextPrompt.execute(**args)
|
||||
|
||||
assert isinstance(output[0], list) and len(output[0]) == 2
|
||||
@@ -806,6 +805,11 @@ def test_interactions_batch_seeds(mock_interactions_client):
|
||||
assert mock_interactions_client.calls[1]["generation_config"]["seed"] == 502
|
||||
assert "previous_interaction_id" not in mock_interactions_client.calls[0]
|
||||
assert mock_interactions_client.calls[1]["previous_interaction_id"] == "i1"
|
||||
assert all(fp[10] == 501 for fp in interactions_nodes.SSL_GeminiInteractionsTextPrompt._cache)
|
||||
|
||||
repeat = interactions_nodes.SSL_GeminiInteractionsTextPrompt.execute(**args)
|
||||
assert repeat[0] == ["A1", "A2"]
|
||||
assert len(mock_interactions_client.calls) == 2
|
||||
|
||||
|
||||
def test_interactions_batch_videos(mock_interactions_client):
|
||||
|
||||
Reference in New Issue
Block a user