maint: remove the negative prompt advisor, start a roadmap
Unreferenced, and negatives do not exist at CFG=1 where most generation happens. Drops _v2_negative_prompt_advisor and its two private helpers (131 lines); _v2_negative_text_conflicts_with_request keeps 2 live callers and stays. Tests: 968 passed, same as baseline. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
d7267ba7a8
commit
e6ea5a6ba7
-132
@@ -11333,138 +11333,6 @@ class FunPackVideoRefinerV2(FunPackVideoRefiner):
|
||||
return current_prompt, f"Advisor: no change. {analysis}".strip(), analysis, False, ""
|
||||
return advised, f"Advisor: applied repair. {analysis}".strip(), analysis, True, advised
|
||||
|
||||
def _v2_negative_advisor_prompt(
|
||||
self,
|
||||
positive_prompt,
|
||||
negative_prompt,
|
||||
intent_prompt,
|
||||
previous_run=None,
|
||||
feedback_prompt="",
|
||||
feedback_history="",
|
||||
):
|
||||
has_feedback = bool(str(feedback_prompt or "").strip())
|
||||
previous_run = previous_run if isinstance(previous_run, dict) else {}
|
||||
previous_prompt = self._v2_prompt_key(previous_run.get("encoded_prompt", "") or previous_run.get("prompt", ""))
|
||||
neg_rules = (
|
||||
"Additional rules for negative prompt repair:\n"
|
||||
"- Add only concise suppression tags for things that were wrong or harmful.\n"
|
||||
"- Never suppress requested subjects, actions, or visual intent.\n"
|
||||
"- Preserve useful existing tags.\n"
|
||||
"Output exactly two lines:\n"
|
||||
"DIAGNOSTIC: one short sentence explaining the change or why none is needed.\n"
|
||||
"NEGATIVE_PROMPT: comma-separated tags, or the current negative prompt unchanged."
|
||||
)
|
||||
user_lines = []
|
||||
if has_feedback:
|
||||
user_lines.append(f"User feedback: {str(feedback_prompt).strip()}")
|
||||
user_lines += [
|
||||
f"User intent: {self._v2_prompt_key(intent_prompt) or 'same as suggested prompt'}",
|
||||
f"Suggested prompt: {self._v2_prompt_key(positive_prompt)}",
|
||||
f"Current negative: {self._v2_prompt_key(negative_prompt) or 'empty'}",
|
||||
]
|
||||
if previous_prompt:
|
||||
user_lines.append(f"Previous prompt (what caused the feedback): {previous_prompt}")
|
||||
if feedback_history:
|
||||
user_lines.append(f"Past feedback (most recent first):\n{feedback_history}")
|
||||
if has_feedback:
|
||||
user_lines.append("Task: apply the user feedback to the negative prompt.")
|
||||
else:
|
||||
user_lines.append("Task: repair the negative prompt to suppress what went wrong.")
|
||||
return (
|
||||
V2_PROMPT_ADVISOR_SYSTEM_PROMPT.strip() + "\n" + neg_rules
|
||||
+ ("\n" + V2_PROMPT_ADVISOR_FEEDBACK_OVERRIDE.strip() if has_feedback else "")
|
||||
+ "\n\n" + "\n".join(user_lines)
|
||||
)
|
||||
|
||||
def _v2_validate_advisor_negative_prompt(
|
||||
self,
|
||||
advised_negative,
|
||||
current_positive,
|
||||
intent_prompt,
|
||||
intent_phrases=None,
|
||||
intent_family_slot=None,
|
||||
):
|
||||
advised = self._v2_prompt_key(advised_negative)
|
||||
if not advised:
|
||||
return True, "empty"
|
||||
if self._prompt_looks_like_refusal(advised):
|
||||
return False, "refusal text"
|
||||
if len(advised) > 1200:
|
||||
return False, "too long"
|
||||
for phrase in self._ordered_prompt_phrases(advised)[:32]:
|
||||
text = phrase.get("text", "")
|
||||
if not text:
|
||||
continue
|
||||
if self._v2_negative_text_conflicts_with_request(
|
||||
text,
|
||||
current_prompt=current_positive,
|
||||
intent_prompt=intent_prompt,
|
||||
intent_phrases=intent_phrases or [],
|
||||
family_slot=intent_family_slot,
|
||||
):
|
||||
return False, f"conflicts with requested text: {text}"
|
||||
return True, "validated"
|
||||
|
||||
def _v2_negative_prompt_advisor(
|
||||
self,
|
||||
clip,
|
||||
mode,
|
||||
positive_prompt,
|
||||
negative_prompt,
|
||||
intent_prompt,
|
||||
rating_profile,
|
||||
axis_feedback,
|
||||
previous_run=None,
|
||||
intent_phrases=None,
|
||||
intent_family_slot=None,
|
||||
allow_prompt_change=False,
|
||||
seed=0,
|
||||
image=None,
|
||||
thinking=True,
|
||||
feedback_prompt="",
|
||||
feedback_history="",
|
||||
max_length=800,
|
||||
):
|
||||
mode = self._v2_advisor_mode(mode)
|
||||
rating_profile = rating_profile if isinstance(rating_profile, dict) else {}
|
||||
if mode == "Off":
|
||||
return negative_prompt, "Negative advisor: off.", "", False
|
||||
reward = float(rating_profile.get("reward", 0.0))
|
||||
is_perfect = rating_profile.get("key") == "like"
|
||||
repair_signal = bool(axis_feedback.get("wrong_axes")) or rating_profile.get("key") == "awful" or reward < -0.30
|
||||
if mode in {"Only prompt", "Full"} and not repair_signal and not str(feedback_prompt or "").strip():
|
||||
return negative_prompt, "Negative advisor: skipped; no wrong/awful signal and no user feedback.", "", False
|
||||
advisor_prompt_text = self._v2_negative_advisor_prompt(
|
||||
positive_prompt,
|
||||
negative_prompt,
|
||||
intent_prompt,
|
||||
previous_run=previous_run,
|
||||
feedback_prompt=feedback_prompt,
|
||||
feedback_history=feedback_history,
|
||||
)
|
||||
raw, gen_status = self._v2_generate_advisor_text(
|
||||
clip, advisor_prompt_text, seed=seed, image=image, thinking=thinking, max_length=max_length
|
||||
)
|
||||
if not raw:
|
||||
return negative_prompt, gen_status.replace("Advisor:", "Negative advisor:", 1), "", False
|
||||
diagnostic, advised = self._v2_parse_advisor_response(raw, prompt_labels=("NEGATIVE_PROMPT", "PROMPT"))
|
||||
if mode == "Only diagnostics" or not allow_prompt_change or is_perfect:
|
||||
reason = "diagnostics only" if mode == "Only diagnostics" else ("perfect rating — analysis only" if is_perfect else "prompt changes disabled")
|
||||
return negative_prompt, f"Negative advisor: {reason}. {diagnostic or advised or 'No diagnostic returned.'}", diagnostic or advised, False
|
||||
valid, reason = self._v2_validate_advisor_negative_prompt(
|
||||
advised,
|
||||
positive_prompt,
|
||||
intent_prompt,
|
||||
intent_phrases=intent_phrases or [],
|
||||
intent_family_slot=intent_family_slot,
|
||||
)
|
||||
if not valid:
|
||||
return negative_prompt, f"Negative advisor: rejected ({reason}). {diagnostic}".strip(), diagnostic, False
|
||||
advised = self._v2_prompt_key(advised)
|
||||
if advised == self._v2_prompt_key(negative_prompt):
|
||||
return negative_prompt, f"Negative advisor: no change. {diagnostic}".strip(), diagnostic, False
|
||||
return advised, f"Negative advisor: applied. {diagnostic}".strip(), diagnostic, True
|
||||
|
||||
def _v2_encoded_prompts_output(self, positive_prompt, advisor_diagnostic="", pre_advisor_prompt="", advisor_suggested=""):
|
||||
parts = [f"Positive prompt: {str(positive_prompt or '').strip()}"]
|
||||
positive_key = self._v2_prompt_key(positive_prompt)
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
# Roadmap
|
||||
|
||||
Planned work, in no particular order. Items move to the CHANGELOG when they ship.
|
||||
|
||||
## Advisor multitool
|
||||
|
||||
Turn the prompt advisor into a general-purpose assistant surface rather than a
|
||||
prompt-repair step: a picker wheel of operations that act on whatever the user points it at.
|
||||
|
||||
Intended operations:
|
||||
- **Describe image** — look at the selected image, return text the user can copy or paste
|
||||
straight into any prompt field.
|
||||
- **Enhance prompt** — rewrite or extend the current prompt.
|
||||
- **Write** — longer-form story text for multi-scene timelines.
|
||||
- **Change settings** — act on Engine Settings by request rather than by navigation.
|
||||
|
||||
The shape is an assistant that reaches into FunPack's own state, not a text box that returns a
|
||||
string.
|
||||
|
||||
## Family-aware settings
|
||||
|
||||
Detect the model family when the loader state is saved, and hide controls the loaded model
|
||||
cannot use, instead of reporting per run that they do not apply. Owning the loaders makes the
|
||||
family known before generation starts.
|
||||
|
||||
Replaces the "this model has no cross-attention, feature X is skipped" class of log line: what
|
||||
is not wired does not appear.
|
||||
Reference in New Issue
Block a user