diff --git a/conditioning.py b/conditioning.py index fda78835..ca908fec 100644 --- a/conditioning.py +++ b/conditioning.py @@ -11727,14 +11727,17 @@ class FunPackVideoRefinerV2(FunPackVideoRefiner): landed[_t] = _w out.append([cond, meta] if isinstance(entry, list) else (cond, meta)) if applied: - # Names what was APPLIED. Reporting the candidate list meant phrases that are no - # longer in the prompt were named as weighted when they had matched nothing. - top = sorted(landed.items(), key=lambda p: -p[1])[:3] + # COUNTS AND WEIGHTS ONLY — never the phrases themselves. The log is the thing + # the user copies out to send somewhere, and the phrases are their prompt: naming + # three of them puts prompt text into every paste. The strongest weight is what + # the number is for, and it says the same thing about whether emphasis is doing + # too much without quoting anything. + strongest = max(landed.values()) if landed else 0.0 _log.note_on_change( "h3:token_weights", "FunPackStudio", f"rating-derived phrase emphasis: {len(landed)} of {len(weighted)} learned " f"phrase(s) are in this prompt and were weighted across {applied} scene(s)" - + (" (e.g. " + ", ".join(f"{t!r} x{w:.2f}" for t, w in top) + ")" if top else "") + + (f", strongest x{strongest:.2f}" if landed else "") + " — applied as an attention bias on H3's packed stream, where the attn2 " "K/V emphasis has nothing to hook.") return out diff --git a/tests/test_logs_do_not_quote_the_prompt.py b/tests/test_logs_do_not_quote_the_prompt.py new file mode 100644 index 00000000..2aec3eb6 --- /dev/null +++ b/tests/test_logs_do_not_quote_the_prompt.py @@ -0,0 +1,44 @@ +"""No log line prints the user's own words back at them. + +The log is the thing that gets copied out and sent somewhere. Phrase memory holds the user's +prompt, so a line naming three learned phrases puts prompt text into every paste — which the +user then has to strip by hand, every time, and will eventually forget to. + +Counts and weights say everything the line is for. The phrases say nothing that a count does +not, and they are the half that cannot be un-sent. +""" +import inspect +import re +import sys + +sys.path.insert(0, ".") + + +def _source(): + import conditioning + return inspect.getsource(conditioning.FunPackVideoRefinerV2._v2_apply_h3_token_weights) + + +def test_the_emphasis_line_reports_counts_not_phrases(): + src = _source() + assert "of {len(weighted)} learned" in src # the count survives + assert "strongest x" in src # so does the magnitude + assert "{t!r}" not in src # the phrases do not + assert "e.g." not in src + + +def test_no_log_line_in_the_refiner_joins_phrase_text(): + """A guard on the shape, not on one message: `", ".join(...)` over phrase-ish values + inside a log call is how this came back the first time.""" + import conditioning + src = inspect.getsource(conditioning) + offenders = [m.group(0) for m in re.finditer(r'"\s*\(e\.g\.\s*"\s*\+\s*", "\.join', src)] + assert offenders == [] + + +def test_the_sampler_reports_the_same_way(): + """The sampler prints its own emphasis line; it must follow the same rule.""" + import samplers + src = inspect.getsource(samplers) + assert "strongest x{strongest:.2f}" in src + assert "token span(s) biased" in src