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:
digital-garbage
2026-08-22 18:35:56 +03:00
co-authored by Claude Opus 5
parent d7267ba7a8
commit e6ea5a6ba7
2 changed files with 27 additions and 132 deletions
-132
View File
@@ -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)
+27
View File
@@ -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.