A rating re-runs the same seed for every learner, not only the Attention explorer

The taste module now fingerprints rated rows into the load node's cache key.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RnrTBt9b8CdJwub5roffF3
This commit is contained in:
Claude
2026-10-25 20:44:59 +00:00
parent 0fc20bbc3d
commit 71b9a1f514
3 changed files with 23 additions and 19 deletions
+1 -13
View File
@@ -219,16 +219,4 @@ def install(patcher, values, key):
return f"{len(groups)} depth groups over {len(blocks)} blocks, {size}"
def cache_key():
"""Changes whenever a rating reaches this kind. ComfyUI skips a graph whose inputs did not
change, and a rating is not an input: the same seed rated and sent again would run nothing."""
try:
ask = registry.current().ask
key = ask("taste_latest_key")
stat = ask("taste_kind", key, KIND).path().stat() if key else None
return f"{stat.st_mtime_ns}:{stat.st_size}" if stat else ""
except Exception: # noqa: BLE001 -- a fingerprint must never fail a run
return ""
PROVIDES = {"modifier": install, "cache_key": cache_key}
PROVIDES = {"modifier": install}
@@ -138,17 +138,18 @@ def test_a_block_list_with_nothing_usable_is_refused(tiny_h3):
assert "attention_bandit: failed to install" in status
def test_a_rating_changes_the_cache_key_so_the_same_seed_runs_again(tiny_h3, monkeypatch):
def test_a_rating_changes_the_taste_cache_key_so_the_same_seed_runs_again(tiny_h3, monkeypatch):
from modules.sampling import attention_bandit as m
from modules.system.taste import store
from modules.system.taste import cache_key, store
patched, _ = _load(tiny_h3, blocks="0-3")
assert m.cache_key() == ""
assert cache_key() == ""
monkeypatch.setattr(m, "draw", lambda table, rng=random: [0] * len(table))
_run(_outer(patched), lambda: tiny_h3.run(patched))
assert cache_key() == "" # a waiting capture is not a rating
store.rate("run-1", "liked")
first = m.cache_key()
first = cache_key()
assert first
monkeypatch.setattr(store, "current_prompt_id", lambda: "run-2")
_run(_outer(patched), lambda: tiny_h3.run(patched))
store.rate("run-2", "liked")
assert m.cache_key() != first
assert cache_key() != first
+16 -1
View File
@@ -151,6 +151,21 @@ def taste_latest_key():
return store.latest_key()
def cache_key():
"""Changes whenever a rating reaches the latest key. ComfyUI skips a graph whose inputs did not
change, and a rating is not an input: the same seed rated and sent again would run nothing, for
every module that learns from ratings. Waiting captures are left out: every run writes one."""
try:
key = store.latest_key()
folder = store._dir(key) if key else None
if folder is None or not folder.is_dir():
return ""
return "|".join(f"{p.name}:{p.stat().st_mtime_ns}:{p.stat().st_size}"
for p in sorted(folder.glob("*.pt")) if ".pending." not in p.name)
except Exception: # noqa: BLE001 -- a fingerprint must never fail a run
return ""
def taste_kind(key, kind):
return Kind(key, kind)
@@ -298,4 +313,4 @@ def routes(table, base, web):
return web.json_response({"imported": name, "kinds": count, "keys": store.keys()})
PROVIDES = {"modifier": install, "taste_store": taste_store, "taste_kind": taste_kind, "taste_latest_key": taste_latest_key, "routes": routes}
PROVIDES = {"modifier": install, "taste_store": taste_store, "taste_kind": taste_kind, "taste_latest_key": taste_latest_key, "cache_key": cache_key, "routes": routes}