Some checks failed
CI / lint (push) Successful in 39s
CI / notebooks-smoke (push) Successful in 1m42s
Deploy / notebooks (push) Has been skipped
Deploy / zotero (push) Has been skipped
CI / test (push) Failing after 2m30s
Deploy / docs (push) Has been skipped
Deploy / api (push) Has been skipped
Deploy / llm (push) Has been skipped
Deploy / mc (push) Has been skipped
Infra CI / zotero (push) Successful in 15s
Infra CI / notebooks (push) Successful in 52s
Deploy / report (push) Has been cancelled
Infra CI / api (push) Has been cancelled
Infra CI / llm (push) Has been cancelled
Infra CI / mc (push) Has been cancelled
Infra CI / docs (push) Has started running
A retrieved FR paragraph that cites a CMS manual ('Pub. 100-04,
Chapter 12, Section 30.6.4') now carries those citations on its source
(as_source iom_refs, parsed by pfs.guidance.iom_refs over the full
chunk text). llm.iomlink resolves each cited section to its indexed
manual chunk (exact section, else the first finer section under it,
else the chapter's first section) and the chat merges up to
iom_companion_max (4) of them in after the CPT manual block, labelled
'IOM 100-04 ch.12 §30.6.4', linked to the chapter PDF page, marked
'cited by [91 FR … ¶n]' in the prompt and the sources drawer; most-cited
sections first, nothing already among the sources repeated, no query
when no rule cites a manual. The search page shows 'cites IOM …' links
on rule hits that open the cited section under the manual filters, and
gains manual / chapter / section / theme fields. Rule paragraphs are
theme-stamped as well (stack llm stamp-themes --collection rules
--doctype rule: 67,340 chunks).
170 lines
6.2 KiB
Python
170 lines
6.2 KiB
Python
"""Evidence deep links: one (url, label) per retrieved chunk (pure).
|
|
|
|
- comment → regulations.gov comment page, or the attachment on the
|
|
downloads CDN with ``#page=N`` for PDFs (page located at index time,
|
|
see ``llm.pages``).
|
|
- rule → the FR paragraph anchor ``#p-N`` plus a ``:~:text=``
|
|
scroll-to-text fragment so the browser highlights the passage;
|
|
degrades to ``#page-N``, then the document URL.
|
|
- corpus → the item's own URL (``#page=N`` when it is a PDF).
|
|
|
|
Labels double as the citation tokens the model is told to emit
|
|
(``[91 FR 43949 ¶4]``, ``[CMS-2026-2377-3438 p.4]``).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from bib.frlink import text_fragment
|
|
|
|
_COMMENT = "https://www.regulations.gov/comment/{cid}"
|
|
_DOWNLOAD = "https://downloads.regulations.gov/{cid}/{name}"
|
|
_TITLE_MAX = 60
|
|
_SNIPPET_CHARS = 500
|
|
|
|
|
|
def _short(title: str) -> str:
|
|
title = " ".join(title.split())
|
|
if len(title) <= _TITLE_MAX:
|
|
return title
|
|
return title[:_TITLE_MAX].rsplit(" ", 1)[0] + "…"
|
|
|
|
|
|
def _comment(md: dict[str, str]) -> tuple[str, str]:
|
|
cid = md.get("comment_id", "")
|
|
if not cid:
|
|
return "", md.get("item_key", "")
|
|
name, page = md.get("attachment", ""), md.get("page", "")
|
|
if name:
|
|
url = _DOWNLOAD.format(cid=cid, name=name)
|
|
if page and name.lower().endswith(".pdf"):
|
|
return f"{url}#page={page}", f"{cid} p.{page}"
|
|
return url, cid
|
|
return _COMMENT.format(cid=cid), cid
|
|
|
|
|
|
def _rule(md: dict[str, str], snippet: str) -> tuple[str, str]:
|
|
base = md.get("html_url", "") or md.get("url", "")
|
|
page, p_id, ordinal, vol = (
|
|
md.get("page", ""),
|
|
md.get("p_id", ""),
|
|
md.get("ordinal", ""),
|
|
md.get("fr_volume", ""),
|
|
)
|
|
if p_id and page:
|
|
url = f"{base}#p-{p_id}"
|
|
frag = text_fragment(snippet)
|
|
if frag:
|
|
url = f"{url}:~:text={frag}"
|
|
label = f"{vol} FR {page} ¶{ordinal}" if vol and ordinal else f"p-{p_id}"
|
|
return url, label
|
|
if page:
|
|
label = f"{vol} FR {page}" if vol else f"page {page}"
|
|
return f"{base}#page-{page}", label
|
|
return base, _short(md.get("title", "")) or md.get("item_key", "")
|
|
|
|
|
|
def _corpus(md: dict[str, str]) -> tuple[str, str]:
|
|
url, page = md.get("url", ""), md.get("page", "")
|
|
if url and page and url.lower().endswith(".pdf"):
|
|
url = f"{url}#page={page}"
|
|
if md.get("doctype") == "manual":
|
|
# IOM chapter section: "IOM 100-04 ch.18 §10.1.2", linked to the
|
|
# chapter PDF page the section was located on
|
|
from llm.manuals import label as manual_label
|
|
|
|
label = manual_label(md)
|
|
if label:
|
|
return url, label
|
|
title = _short(md.get("title", ""))
|
|
year = md.get("year", "") or md.get("date", "")[:4]
|
|
if title and year:
|
|
label = f"{title} ({year})"
|
|
else:
|
|
label = title or md.get("item_key", "")
|
|
return url, label
|
|
|
|
|
|
def for_source(md: dict[str, str], snippet: str) -> tuple[str, str]:
|
|
"""``(url, label)`` for a chunk's metadata. Never raises; degrades
|
|
to whatever link the metadata supports."""
|
|
kind = md.get("kind", "") or ("comment" if md.get("comment_id") else "corpus")
|
|
if kind == "comment":
|
|
return _comment(md)
|
|
if kind == "rule":
|
|
return _rule(md, snippet)
|
|
return _corpus(md)
|
|
|
|
|
|
def iom_refs_of(text: str) -> list[dict[str, str]]:
|
|
"""``[{"pub", "chapter", "section", "label"}]`` for every CMS manual
|
|
citation in *text* ("Pub. 100-04, Chapter 12, Section 30.6.4"),
|
|
de-duplicated in order of appearance."""
|
|
from llm.manuals import label as manual_label
|
|
from pfs.guidance import iom_refs
|
|
|
|
out: list[dict[str, str]] = []
|
|
seen: set[tuple[str, str, str]] = set()
|
|
for pub, chapter, section in iom_refs(text or ""):
|
|
key = (pub, chapter, section)
|
|
if key in seen:
|
|
continue
|
|
seen.add(key)
|
|
out.append(
|
|
{
|
|
"pub": pub,
|
|
"chapter": chapter,
|
|
"section": section,
|
|
"label": manual_label(
|
|
{"manual": pub, "chapter": chapter, "iom_section": section}
|
|
),
|
|
}
|
|
)
|
|
return out
|
|
|
|
|
|
def as_source(md: dict[str, str], text: str, score: float) -> dict:
|
|
"""The source dict the chat sends to the prompt and the UI.
|
|
|
|
``item_key``, ``p_id`` (rules only; ``""`` otherwise), ``seq``
|
|
(non-rule kinds only; ``""`` for rules) and ``section`` are carried
|
|
straight from *md* so the golden evaluation can match a source back
|
|
to its chunk anchor: ``(item_key, p_id)`` for a rule paragraph,
|
|
``(item_key, seq)`` for a comment/corpus chunk.
|
|
"""
|
|
snippet = text[:_SNIPPET_CHARS].strip()
|
|
url, label = for_source(md, snippet)
|
|
kind = md.get("kind", "")
|
|
return {
|
|
"id": label,
|
|
"label": label,
|
|
"kind": kind,
|
|
# proposed / final / correction for a rule (the UI badge and the
|
|
# prompt's source line show it; the citation token stays the FR cite)
|
|
"rule_kind": md.get("rule_kind", "") if kind == "rule" else "",
|
|
"doctype": md.get("doctype", ""),
|
|
# IOM chapter coordinates for manual sections (llm.manuals)
|
|
"manual": md.get("manual", ""),
|
|
"chapter": md.get("chapter", ""),
|
|
"iom_section": md.get("iom_section", ""),
|
|
# theme slugs stamped by llm.themes (comma-joined), for filters and badges
|
|
"themes": md.get("themes", ""),
|
|
# IOM sections a rule paragraph cites (llm.iomlink pulls them in as
|
|
# companion sources; the search page links them)
|
|
"iom_refs": iom_refs_of(text) if kind == "rule" else [],
|
|
"url": url,
|
|
"title": md.get("title", ""),
|
|
"date": md.get("date", ""),
|
|
"docket": md.get("docket", ""),
|
|
"comment_id": md.get("comment_id", ""),
|
|
"snippet": snippet,
|
|
"score": round(score, 4),
|
|
"item_key": md.get("item_key", ""),
|
|
"p_id": md.get("p_id", "") if kind == "rule" else "",
|
|
"seq": md.get("seq", "") if kind != "rule" else "",
|
|
"section": md.get("section", ""),
|
|
# the PDF the chunk came from and the page it was located on
|
|
# (``llm.pages.enrich_pdf_pages``) — the UI links them to the viewer
|
|
"attachment": md.get("attachment", ""),
|
|
"page": md.get("page", ""),
|
|
}
|