Revert "feat: make default fun level actually surface comedy (#272)" (#273)

This reverts commit bad1d312ef.

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
This commit is contained in:
Matt Van Horn
2026-04-17 08:39:56 -04:00
committed by GitHub
parent bad1d312ef
commit 371f62a403
5 changed files with 36 additions and 349 deletions
+30 -75
View File
@@ -18,9 +18,9 @@ SOURCE_LABELS = {
_FUN_LEVELS = {
"low": {"threshold": 75.0, "limit": 2},
"medium": {"threshold": 55.0, "limit": 5},
"high": {"threshold": 40.0, "limit": 8},
"low": {"threshold": 80.0, "limit": 2},
"medium": {"threshold": 70.0, "limit": 5},
"high": {"threshold": 55.0, "limit": 8},
}
_AI_SAFETY_NOTE = (
@@ -60,11 +60,6 @@ def render_compact(report: schema.Report, cluster_limit: int = 8, fun_level: str
lines.extend(f"- {warning}" for warning in report.warnings)
lines.append("")
fun_params = _FUN_LEVELS.get(fun_level, _FUN_LEVELS["medium"])
best_takes = _render_best_takes(report.ranked_candidates, limit=fun_params["limit"], threshold=fun_params["threshold"])
if best_takes:
lines.extend(best_takes + [""])
lines.append("## Ranked Evidence Clusters")
lines.append("")
candidate_by_id = {candidate.candidate_id: candidate for candidate in report.ranked_candidates}
@@ -85,6 +80,11 @@ def render_compact(report: schema.Report, cluster_limit: int = 8, fun_level: str
lines.extend(_render_stats(report))
fun_params = _FUN_LEVELS.get(fun_level, _FUN_LEVELS["medium"])
best_takes = _render_best_takes(report.ranked_candidates, limit=fun_params["limit"], threshold=fun_params["threshold"])
if best_takes:
lines.extend([""] + best_takes)
lines.extend(_render_source_coverage(report))
return "\n".join(lines).strip() + "\n"
@@ -654,78 +654,33 @@ def _source_label(source: str) -> str:
def _render_best_takes(candidates, limit=5, threshold=70.0):
# Build a unified list of gems: candidate-level entries and comment-level entries,
# each tagged by type so they can share the sort but render with different attribution.
gems: list[tuple[str, float, object]] = []
for candidate in candidates:
if candidate.fun_score is not None and candidate.fun_score >= threshold:
gems.append(("candidate", candidate.fun_score, candidate))
for item in candidate.source_items:
for comment in item.metadata.get("top_comments", []) or []:
if not isinstance(comment, dict):
continue
comment_score = comment.get("fun_score")
if comment_score is None or comment_score < threshold:
continue
gems.append(("comment", float(comment_score), (candidate, item, comment)))
if not gems:
gems = sorted(
(c for c in candidates if c.fun_score is not None and c.fun_score >= threshold),
key=lambda c: -(c.fun_score or 0),
)
if len(gems) < 2:
return []
gems.sort(key=lambda g: -g[1])
lines = ["## Best Takes", ""]
for kind, score, payload in gems[:limit]:
if kind == "candidate":
lines.append(_render_candidate_gem(payload))
else:
candidate, item, comment = payload
lines.append(_render_comment_gem(candidate, item, comment))
for candidate in gems[:limit]:
text = candidate.title.strip()
for item in candidate.source_items:
for comment in item.metadata.get("top_comments", [])[:3]:
body = (comment.get("body") or comment.get("text") or "") if isinstance(comment, dict) else str(comment)
body = body.strip()
if body and len(body) < len(text) and len(body) > 10:
text = body
source_label = _source_label(candidate.source)
author = candidate.source_items[0].author if candidate.source_items else None
attribution = f"@{author} on {source_label}" if author and candidate.source in ("x", "tiktok", "instagram", "threads") else f"{source_label}"
if author and candidate.source == "reddit":
container = candidate.source_items[0].container if candidate.source_items else None
attribution = f"r/{container} comment" if container else "Reddit"
score_tag = f"(fun:{candidate.fun_score:.0f})"
reason = f" -- {candidate.fun_explanation}" if candidate.fun_explanation and candidate.fun_explanation != "heuristic-fallback" else ""
lines.append(f'- "{_truncate(text, 280)}" -- {attribution} {score_tag}{reason}')
return lines
def _render_candidate_gem(candidate) -> str:
text = candidate.title.strip()
for item in candidate.source_items:
for comment in item.metadata.get("top_comments", [])[:3]:
body = (comment.get("body") or comment.get("excerpt") or comment.get("text") or "") if isinstance(comment, dict) else str(comment)
body = body.strip()
if body and len(body) < len(text) and len(body) > 10:
text = body
source_label = _source_label(candidate.source)
author = candidate.source_items[0].author if candidate.source_items else None
attribution = f"@{author} on {source_label}" if author and candidate.source in ("x", "tiktok", "instagram", "threads") else f"{source_label}"
if author and candidate.source == "reddit":
container = candidate.source_items[0].container if candidate.source_items else None
attribution = f"r/{container} comment" if container else "Reddit"
score_tag = f"(fun:{candidate.fun_score:.0f})"
reason = f" -- {candidate.fun_explanation}" if candidate.fun_explanation and candidate.fun_explanation != "heuristic-fallback" else ""
return f'- "{_truncate(text, 280)}" -- {attribution} {score_tag}{reason}'
def _render_comment_gem(candidate, item, comment) -> str:
body = (comment.get("body") or comment.get("excerpt") or comment.get("text") or "").strip()
upvotes = comment.get("score") or comment.get("ups") or comment.get("upvotes") or comment.get("likes") or 0
source_label = _source_label(candidate.source)
parent_title = (candidate.title or "").strip()
comment_author = comment.get("author")
vote_label = _vote_label_for(candidate.source)
fun_tag = f"(fun:{comment.get('fun_score', 0):.0f})"
if candidate.source == "reddit":
container = item.container if item else None
source_attribution = f"r/{container}" if container else source_label
elif comment_author:
source_attribution = f"@{comment_author} on {source_label}"
else:
source_attribution = source_label
vote_suffix = ""
if isinstance(upvotes, int) and upvotes:
vote_suffix = f" ({upvotes:,} {vote_label})"
in_clause = f' in "{_truncate(parent_title, 100)}"' if parent_title else ""
return f'- "{_truncate(body, 280)}" -- {source_attribution}{in_clause}{vote_suffix} {fun_tag}'
def _truncate(text: str, limit: int) -> str:
text = text.strip()
if len(text) <= limit:
-68
View File
@@ -285,13 +285,11 @@ def _apply_fun_scores(candidates: list[schema.Candidate], payload: dict) -> None
c.fun_score, c.fun_explanation = scores[c.candidate_id]
else:
_apply_single_fun_fallback(c)
_score_comments_per_candidate(c)
def _apply_fun_fallback(candidates: list[schema.Candidate]) -> None:
for c in candidates:
_apply_single_fun_fallback(c)
_score_comments_per_candidate(c)
def _apply_single_fun_fallback(candidate: schema.Candidate) -> None:
@@ -306,72 +304,6 @@ def _apply_single_fun_fallback(candidate: schema.Candidate) -> None:
candidate.fun_explanation = "heuristic-fallback"
_FUN_MARKERS = ("lol", "lmao", "dead", "hilarious", "funny", "bruh", "ratio",
"nah", "bro", "ain't no way", "i'm crying", "rent free")
def _comment_body(comment: dict) -> str:
for key in ("body", "excerpt", "text"):
value = comment.get(key) if isinstance(comment, dict) else None
if value:
return str(value).strip()
return ""
def _comment_upvotes(comment: dict) -> int:
for key in ("score", "ups", "upvotes", "likes"):
value = comment.get(key) if isinstance(comment, dict) else None
if value is not None:
try:
return int(value)
except (TypeError, ValueError):
continue
return 0
def _parent_raw_upvotes(candidate: schema.Candidate) -> int:
for item in candidate.source_items:
eng = item.engagement
if isinstance(eng, dict):
for key in ("score", "ups", "upvotes", "likes"):
value = eng.get(key)
if value is not None:
try:
return int(value)
except (TypeError, ValueError):
continue
elif isinstance(eng, (int, float)) and eng:
return int(eng)
return 0
def _score_comments_per_candidate(candidate: schema.Candidate) -> None:
"""Annotate each of the top 3 comments on this candidate with its own fun_score.
Scoring: (ratio-to-parent bonus, capped 50) + shortness bonus (0-30) + marker bonus (0-20).
A comment with high upvotes relative to its parent thread dominates an absolute-high
comment on a dominant parent thread, which is the viral-wit signal.
"""
parent_upvotes = _parent_raw_upvotes(candidate)
for item in candidate.source_items:
comments = item.metadata.get("top_comments") or []
if not isinstance(comments, list):
continue
for comment in comments[:3]:
if not isinstance(comment, dict):
continue
body = _comment_body(comment)
if not body:
continue
upvotes = _comment_upvotes(comment)
ratio = upvotes / max(parent_upvotes, 1) if parent_upvotes else min(upvotes / 100.0, 2.5)
ratio_bonus = min(ratio * 20.0, 50.0)
body_len = len(body)
shortness_bonus = max(0.0, (200 - body_len) / 200.0) * 30.0
marker_bonus = 20.0 if any(m in body.lower() for m in _FUN_MARKERS) else 0.0
comment["fun_score"] = max(0.0, min(100.0, ratio_bonus + shortness_bonus + marker_bonus))
def _normalized_rrf(rrf_score: float) -> float:
# Empirical ceiling for normalized RRF scores at the pool sizes we use.
# Max single-stream RRF at rank 1 is 1/(K+1) ~ 0.016; multi-stream