Spaces:
Running
Running
| """Parse bullet lists with optional [verdict] tags and <c>comment</c> tags.""" | |
| from __future__ import annotations | |
| import re | |
| _BULLET_RE = re.compile(r"^\s*[-*•]\s+(.*\S)\s*$") | |
| _COMMENT_RE = re.compile(r"<c>(.*?)</c>", re.IGNORECASE | re.DOTALL) | |
| _VERDICT_RE = re.compile( | |
| r"^\[(supported|uncertain|contradicted)\]\s*", | |
| re.IGNORECASE, | |
| ) | |
| _VALID_VERDICTS = frozenset({"supported", "uncertain", "contradicted"}) | |
| def parse_bullets(text: str) -> list[tuple[str, str, str]]: | |
| """Return [(point_text, comment, verdict), ...] from a bullet markdown block. | |
| Optional leading tags: `[supported]`, `[uncertain]`, `[contradicted]`. | |
| Default verdict is `uncertain` (needs web check). | |
| """ | |
| points: list[tuple[str, str, str]] = [] | |
| for line in (text or "").splitlines(): | |
| match = _BULLET_RE.match(line) | |
| if not match: | |
| continue | |
| body = match.group(1).strip() | |
| comments = _COMMENT_RE.findall(body) | |
| comment = " ".join(c.strip() for c in comments if c.strip()) | |
| clean = _COMMENT_RE.sub("", body).strip() | |
| verdict = "uncertain" | |
| verdict_match = _VERDICT_RE.match(clean) | |
| if verdict_match: | |
| verdict = verdict_match.group(1).lower() | |
| clean = clean[verdict_match.end() :].strip() | |
| if clean: | |
| points.append((clean, comment, verdict)) | |
| return points | |
| def bullets_to_claims( | |
| *, | |
| message_id: str, | |
| rewritten: str, | |
| citations: list | None = None, | |
| start_order: int = 0, | |
| ) -> list[dict]: | |
| """Turn rewritten bullets into Claim dicts (preliminary verdict from tags).""" | |
| cites = citations or [] | |
| claims: list[dict] = [] | |
| points = parse_bullets(rewritten) | |
| if not points: | |
| # Fallback: whole rewrite as one uncertain factual point | |
| raw = (rewritten or "").strip() | |
| if not raw: | |
| return [] | |
| return [ | |
| { | |
| "id": f"{message_id}-0", | |
| "message_id": message_id, | |
| "order": 0, | |
| "text": raw, | |
| "is_claim": True, | |
| "comment": "", | |
| "verdict": "uncertain", | |
| "reason": "non-bullet fallback", | |
| "citations": cites, | |
| } | |
| ] | |
| for i, (text, comment, verdict) in enumerate(points): | |
| if verdict not in _VALID_VERDICTS: | |
| verdict = "uncertain" | |
| reason = comment or ( | |
| "common knowledge" if verdict == "supported" else "needs web check" | |
| ) | |
| claims.append( | |
| { | |
| "id": f"{message_id}-{start_order + i}", | |
| "message_id": message_id, | |
| "order": start_order + i, | |
| "text": text, | |
| "is_claim": True, | |
| "comment": comment, | |
| "verdict": verdict, | |
| "reason": reason, | |
| "citations": list(cites) if verdict == "uncertain" else [], | |
| } | |
| ) | |
| return claims | |