feat(briefing): cluster news by topic for thematic synthesis instead of flat headlines
This commit is contained in:
@@ -450,17 +450,38 @@ def _unified_user_prompt(internal_data: dict, external_data: dict, slot: str, te
|
|||||||
lines.append(" (Identify free blocks between events for focused work.)")
|
lines.append(" (Identify free blocks between events for focused work.)")
|
||||||
lines.append("")
|
lines.append("")
|
||||||
|
|
||||||
# News highlights (top 3 with excerpts — right panel shows full list)
|
# News — clustered by topic for thematic synthesis
|
||||||
rss = external_data.get("rss_items") or []
|
rss = external_data.get("rss_items") or []
|
||||||
if rss:
|
if rss:
|
||||||
lines.append("NEWS HIGHLIGHTS (weave 1-2 into your briefing naturally; the full list is shown separately):")
|
# Group articles by their primary topic
|
||||||
for item in rss[:3]:
|
clusters: dict[str, list[dict]] = {}
|
||||||
source = item.get("feed_title") or item.get("source") or "News"
|
uncategorized: list[dict] = []
|
||||||
title = item.get("title", "")
|
for item in rss:
|
||||||
excerpt = (item.get("content") or item.get("snippet") or "")[:500].strip()
|
topics = item.get("topics") or []
|
||||||
lines.append(f" [{source}] {title}")
|
if topics:
|
||||||
if excerpt:
|
primary = topics[0]
|
||||||
lines.append(f" {excerpt}")
|
clusters.setdefault(primary, []).append(item)
|
||||||
|
else:
|
||||||
|
uncategorized.append(item)
|
||||||
|
|
||||||
|
# Sort clusters by size (most articles = most active theme)
|
||||||
|
sorted_clusters = sorted(clusters.items(), key=lambda x: len(x[1]), reverse=True)
|
||||||
|
|
||||||
|
lines.append("NEWS THEMES (synthesize 1-2 themes into your briefing; mention article count per theme):")
|
||||||
|
for topic, items in sorted_clusters[:4]:
|
||||||
|
count = len(items)
|
||||||
|
titles = [i.get("title", "") for i in items[:3]]
|
||||||
|
sources = list({i.get("feed_title") or i.get("source") or "News" for i in items})
|
||||||
|
lines.append(f" [{topic.title()}] ({count} article{'s' if count != 1 else ''} from {', '.join(sources[:2])})")
|
||||||
|
for t in titles:
|
||||||
|
lines.append(f" • {t}")
|
||||||
|
# Include one excerpt for the top cluster
|
||||||
|
if items == sorted_clusters[0][1]:
|
||||||
|
excerpt = (items[0].get("content") or items[0].get("snippet") or "")[:400].strip()
|
||||||
|
if excerpt:
|
||||||
|
lines.append(f" > {excerpt}")
|
||||||
|
if uncategorized:
|
||||||
|
lines.append(f" [Other] ({len(uncategorized)} uncategorized article{'s' if len(uncategorized) != 1 else ''})")
|
||||||
lines.append("")
|
lines.append("")
|
||||||
|
|
||||||
return "\n".join(lines)
|
return "\n".join(lines)
|
||||||
|
|||||||
Reference in New Issue
Block a user