Anti-Hallucination / agent /bullets.py
MHRDYN7's picture
Deploy Anti-Hallucination Chat to personal Space
f3793b5 verified
Raw
History Blame Contribute Delete
2.98 kB
"""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