Files
jeremie louvaert eda9826431 v1.2.2: image-only sample uses Gemini Style Transfer Settings node
Replaces the two StringConstantMultiline nodes in hash_vault_image_only.json
with the new GeminiStyleTransferSettings node from Gemini-Direct v1.1.0.
The Settings node keeps the real ComfyUI dropdown UX (typeahead, validation)
while still fanning style + intensity into both the Style Transfer input
and the Hash Vault any_input slot. Avoids the typo-silent cache-break mode
of free-text StringConstantMultiline.

README's image-only section rewritten to explain the UX rationale.
2026-04-19 08:43:04 +02:00

632 lines
13 KiB
JSON

{
"id": "cdb7a54f-3f88-4d2f-aa34-9034f3cb6b91",
"revision": 0,
"last_node_id": 9,
"last_link_id": 12,
"nodes": [
{
"id": 1,
"type": "Note",
"pos": [
40,
20
],
"size": [
1620,
200
],
"flags": {},
"order": 0,
"mode": 0,
"inputs": [],
"outputs": [],
"properties": {},
"widgets_values": [
"HASH VAULT (image-only API) \u2014 caching the Gemini Style Transfer node\n\nStyle Transfer takes (image, style, intensity, ...) and emits a styled image \u2014 no prompt STRING anywhere. v1.2.0 of API-Optimizer made Hash Vault's payload_string optional and added any_input_2/3/4, so we can hash purely on image + widget values.\n\nWIRING\nLoadImage routes to BOTH Style Transfer.image AND Hash Vault.any_input.\nThe Style Transfer Settings node owns the style + intensity dropdowns and emits each as a STRING. Its outputs fan out to BOTH the matching Style Transfer inputs (widgets converted to inputs) AND Hash Vault.any_input_2 / any_input_3.\n\nWhy a Settings node instead of StringConstantMultiline: the Settings node keeps the native ComfyUI dropdown UX \u2014 typeahead, validation, no typos. Typing 'Saul Leiter / Intimate' as free text into a StringConstantMultiline silently breaks the cache the moment you mistype.\n\nResult: same image + same style + same intensity \u2192 cache hit \u2192 no API call. Change any of the three \u2192 new hash \u2192 API runs once, then cached.\n\nNOT CACHED: the Style Transfer node still has its own model / seed / aspect_ratio / resolution / direction widgets that DON'T factor into the hash here. If you change those and want a fresh render, clear the matching .pt file in output/hash_vault/ first. Or wire those through additional any_input slots if you have them free.\n\nREQUIRES\nComfyUI-API-Optimizer v1.2.0+, ComfyUI-Gemini-Direct (Settings node shipped in the release that includes GeminiStyleTransferSettings)."
]
},
{
"id": 2,
"type": "LoadImage",
"pos": [
40,
240
],
"size": [
320,
320
],
"flags": {},
"order": 1,
"mode": 0,
"inputs": [
{
"localized_name": "image",
"name": "image",
"type": "COMBO",
"widget": {
"name": "image"
},
"link": null
},
{
"localized_name": "upload",
"name": "upload",
"type": "IMAGEUPLOAD",
"widget": {
"name": "upload"
},
"link": null
}
],
"outputs": [
{
"localized_name": "IMAGE",
"name": "IMAGE",
"type": "IMAGE",
"links": [
1,
2
],
"slot_index": 0
},
{
"localized_name": "MASK",
"name": "MASK",
"type": "MASK",
"links": [],
"slot_index": 1
}
],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.18.1",
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"example.png",
"image"
]
},
{
"id": 3,
"type": "GeminiStyleTransferSettings",
"pos": [
40,
600
],
"size": [
320,
120
],
"flags": {},
"order": 2,
"mode": 0,
"inputs": [
{
"localized_name": "style",
"name": "style",
"type": "COMBO",
"widget": {
"name": "style"
},
"link": null
},
{
"localized_name": "intensity",
"name": "intensity",
"type": "COMBO",
"widget": {
"name": "intensity"
},
"link": null
}
],
"outputs": [
{
"localized_name": "style",
"name": "style",
"type": "STRING",
"links": [
3,
4
],
"slot_index": 0
},
{
"localized_name": "intensity",
"name": "intensity",
"type": "STRING",
"links": [
5,
6
],
"slot_index": 1
}
],
"properties": {
"cnr_id": "comfyui-gemini-direct",
"ver": "1.1.0",
"Node name for S&R": "GeminiStyleTransferSettings",
"aux_id": "jeremieLouvaert/ComfyUI-Gemini-Direct"
},
"widgets_values": [
"Saul Leiter / Intimate",
"full"
]
},
{
"id": 5,
"type": "DeterministicHashVault",
"pos": [
420,
240
],
"size": [
340,
220
],
"flags": {},
"order": 3,
"mode": 0,
"inputs": [
{
"localized_name": "payload_string",
"name": "payload_string",
"type": "STRING",
"shape": 7,
"link": null
},
{
"localized_name": "any_input",
"name": "any_input",
"type": "*",
"shape": 7,
"link": 1
},
{
"localized_name": "any_input_2",
"name": "any_input_2",
"type": "*",
"shape": 7,
"link": 3
},
{
"localized_name": "any_input_3",
"name": "any_input_3",
"type": "*",
"shape": 7,
"link": 5
},
{
"localized_name": "any_input_4",
"name": "any_input_4",
"type": "*",
"shape": 7,
"link": null
},
{
"localized_name": "cache_ttl_hours",
"name": "cache_ttl_hours",
"type": "FLOAT",
"widget": {
"name": "cache_ttl_hours"
},
"shape": 7,
"link": null
}
],
"outputs": [
{
"localized_name": "cached_data",
"name": "cached_data",
"type": "*",
"links": [
8
],
"slot_index": 0
},
{
"localized_name": "is_cached",
"name": "is_cached",
"type": "INT",
"links": [
7
],
"slot_index": 1
},
{
"localized_name": "hash_key",
"name": "hash_key",
"type": "STRING",
"links": [
9
],
"slot_index": 2
}
],
"properties": {
"cnr_id": "comfyui-api-optimizer",
"ver": "1.2.2",
"Node name for S&R": "DeterministicHashVault",
"aux_id": "jeremieLouvaert/ComfyUI-API-Optimizer"
},
"widgets_values": [
0.0
]
},
{
"id": 6,
"type": "GeminiStyleTransfer",
"pos": [
420,
500
],
"size": [
380,
380
],
"flags": {},
"order": 4,
"mode": 0,
"inputs": [
{
"localized_name": "image",
"name": "image",
"type": "IMAGE",
"link": 2
},
{
"localized_name": "style",
"name": "style",
"type": "COMBO",
"widget": {
"name": "style"
},
"link": 4
},
{
"localized_name": "intensity",
"name": "intensity",
"type": "COMBO",
"widget": {
"name": "intensity"
},
"link": 6
},
{
"localized_name": "model",
"name": "model",
"type": "COMBO",
"widget": {
"name": "model"
},
"link": null
},
{
"localized_name": "seed",
"name": "seed",
"type": "INT",
"widget": {
"name": "seed"
},
"link": null
},
{
"localized_name": "aspect_ratio",
"name": "aspect_ratio",
"type": "COMBO",
"widget": {
"name": "aspect_ratio"
},
"link": null
},
{
"localized_name": "resolution",
"name": "resolution",
"type": "COMBO",
"widget": {
"name": "resolution"
},
"link": null
},
{
"localized_name": "direction",
"name": "direction",
"type": "STRING",
"widget": {
"name": "direction"
},
"shape": 7,
"link": null
},
{
"localized_name": "api_key",
"name": "api_key",
"type": "STRING",
"widget": {
"name": "api_key"
},
"shape": 7,
"link": null
}
],
"outputs": [
{
"localized_name": "image",
"name": "image",
"type": "IMAGE",
"links": [
10
],
"slot_index": 0
},
{
"localized_name": "cost_info",
"name": "cost_info",
"type": "STRING",
"links": [],
"slot_index": 1
},
{
"localized_name": "cache_key",
"name": "cache_key",
"type": "STRING",
"links": [],
"slot_index": 2
}
],
"properties": {
"cnr_id": "comfyui-gemini-direct",
"ver": "1.1.0",
"Node name for S&R": "GeminiStyleTransfer",
"aux_id": "jeremieLouvaert/ComfyUI-Gemini-Direct"
},
"widgets_values": [
"Saul Leiter / Intimate",
"full",
"gemini-3-pro-image-preview",
0,
"auto",
"2K",
"",
""
]
},
{
"id": 7,
"type": "HashVaultSave",
"pos": [
840,
500
],
"size": [
300,
80
],
"flags": {},
"order": 5,
"mode": 0,
"inputs": [
{
"localized_name": "hash_key",
"name": "hash_key",
"type": "STRING",
"link": 9
},
{
"localized_name": "api_output",
"name": "api_output",
"type": "*",
"link": 10
}
],
"outputs": [
{
"localized_name": "api_output",
"name": "api_output",
"type": "*",
"links": [
11
],
"slot_index": 0
}
],
"properties": {
"cnr_id": "comfyui-api-optimizer",
"ver": "1.2.2",
"Node name for S&R": "HashVaultSave",
"aux_id": "jeremieLouvaert/ComfyUI-API-Optimizer"
},
"widgets_values": []
},
{
"id": 8,
"type": "LazyAPISwitch",
"pos": [
1180,
240
],
"size": [
300,
120
],
"flags": {},
"order": 6,
"mode": 0,
"inputs": [
{
"localized_name": "is_cached",
"name": "is_cached",
"type": "INT",
"link": 7
},
{
"localized_name": "cached_data",
"name": "cached_data",
"type": "*",
"shape": 7,
"link": 8
},
{
"localized_name": "api_data",
"name": "api_data",
"type": "*",
"shape": 7,
"link": 11
}
],
"outputs": [
{
"localized_name": "final_output",
"name": "final_output",
"type": "*",
"links": [
12
],
"slot_index": 0
}
],
"properties": {
"cnr_id": "comfyui-api-optimizer",
"ver": "1.2.2",
"Node name for S&R": "LazyAPISwitch",
"aux_id": "jeremieLouvaert/ComfyUI-API-Optimizer"
},
"widgets_values": []
},
{
"id": 9,
"type": "PreviewImage",
"pos": [
1520,
240
],
"size": [
420,
500
],
"flags": {},
"order": 7,
"mode": 0,
"inputs": [
{
"localized_name": "images",
"name": "images",
"type": "IMAGE",
"link": 12
}
],
"outputs": [],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.18.1",
"Node name for S&R": "PreviewImage"
},
"widgets_values": []
}
],
"links": [
[
1,
2,
0,
5,
1,
"IMAGE"
],
[
2,
2,
0,
6,
0,
"IMAGE"
],
[
3,
3,
0,
5,
2,
"STRING"
],
[
4,
3,
0,
6,
1,
"STRING"
],
[
5,
3,
1,
5,
3,
"STRING"
],
[
6,
3,
1,
6,
2,
"STRING"
],
[
7,
5,
1,
8,
0,
"INT"
],
[
8,
5,
0,
8,
1,
"*"
],
[
9,
5,
2,
7,
0,
"STRING"
],
[
10,
6,
0,
7,
1,
"IMAGE"
],
[
11,
7,
0,
8,
2,
"*"
],
[
12,
8,
0,
9,
0,
"IMAGE"
]
],
"groups": [],
"config": {},
"extra": {},
"version": 0.4
}