fix+docs: classifier/publisher правки, sources.yaml расширен, глоссарий CONTEXT.md + docs/agents, backup.sh; openspec post-translate/rewrite-as-author/rich-repost-card/selected-layout-stay

This commit is contained in:
kpa39l
2026-09-22 17:39:23 +00:00
parent a10ab9fa3c
commit c8ccd7e187
8 changed files with 302 additions and 94 deletions
+22 -3
View File
@@ -24,16 +24,33 @@ def classify_text(post: dict) -> dict:
пробуем LLM-уточнение (relevance/interest/summary). При недоступности LLM —
фолбэк: direction из словаря, relevance=low, interest=1, classified=False.
Если у поста задан source_slug с правилом SOURCE_RULES (например, lwn → tech) —
направление принудительное, LLM не вызывается (детерминированно, быстро).
СВОЙ контент (is_own=1): «сильный кандидат» — при словарном попадании
relevance=critical, classified=True даже без LLM (фолбэк 'dict-own').
Если словарь не дал направление — классификации нет, пост не теряется.
post: {"text": str, "views": int, "reactions_total": int, "is_own": int, ...}
post: {"text": str, "views": int, "reactions_total": int, "is_own": int, "source_slug": str|None, ...}
"""
text = (post.get("text") or "").strip()
views = int(post.get("views") or 0)
reactions = int(post.get("reactions_total") or 0)
is_own = int(post.get("is_own") or 0) == 1
source_slug = post.get("source_slug")
# правило источника (SOURCE_RULES): принудительное направление, без LLM
from classifier.keywords import source_directions
forced = source_directions(source_slug)
if forced:
return {
"direction": forced[0],
"relevance": "high",
"interest": 3,
"summary": "",
"classified": True,
"method": "source-rule",
}
direction = find_direction(text)
if not direction:
@@ -170,7 +187,9 @@ def classify_posts_in_db(db_path: str, limit: int = 200, direction: str | None =
where += f" AND direction IS NULL" # не классифицированы в этом направлении
rows = cur.execute(
f"SELECT id, text, views, reactions_total, is_own FROM posts {where} ORDER BY is_own DESC, id LIMIT ?",
f"SELECT p.id, p.text, p.views, p.reactions_total, p.is_own, s.slug AS source_slug "
f"FROM posts p LEFT JOIN sources s ON s.id = p.source_id {where} "
f"ORDER BY p.is_own DESC, p.id LIMIT ?",
(limit,),
).fetchall()
@@ -188,7 +207,7 @@ def classify_posts_in_db(db_path: str, limit: int = 200, direction: str | None =
)
# мультинаправления: все словарные попадания → classifications (для fan-out)
from classifier.keywords import find_directions_all
dirs_all = find_directions_all(row["text"] or "")
dirs_all = find_directions_all(row["text"] or "", row["source_slug"])
if res["direction"] and res["direction"] not in dirs_all:
dirs_all.append(res["direction"])
for d in dirs_all: