Expose Notebook source roles and distinctions

This commit is contained in:
welsberr 2026-05-08 14:05:24 -04:00
parent 56bded1313
commit c3ebe716df
2 changed files with 51 additions and 2 deletions

View File

@ -82,10 +82,21 @@ def _review_context(bundle: dict[str, Any]) -> dict[str, Any]:
qualification_candidates = 0
constraint_candidates = 0
quote_candidates = 0
distinction_candidates = []
for claim in claims:
metadata = claim.get("metadata", {}) or {}
text = str(claim.get("claim_text", "")).strip()
lowered = text.lower()
distinction = claim.get("distinction")
if isinstance(distinction, dict):
distinction_candidates.append(
{
"claim_id": distinction.get("claim_id", claim.get("claim_id", "")),
"distinction_type": distinction.get("distinction_type", ""),
"cue": distinction.get("cue", ""),
"text": distinction.get("text", text),
}
)
if metadata.get("definition_candidate") or any(token in lowered for token in (" defined as ", " refers to ", " means ", " describes ")):
definition_candidates += 1
if metadata.get("qualification_candidate") or any(token in lowered for token in ("however", "although", "unless", "only if", "may not", "does not always")):
@ -104,6 +115,8 @@ def _review_context(bundle: dict[str, Any]) -> dict[str, Any]:
"constraint_candidates": constraint_candidates,
"quote_candidates": quote_candidates,
},
"source_role_summary": bundle.get("source_role_summary", {}) or {},
"key_distinctions": distinction_candidates[:6] or (bundle.get("key_distinctions", []) or [])[:6],
"public_output_policy": {
"quotes_require_attribution": True,
"public_prose_should_be_paraphrastic": True,
@ -130,6 +143,7 @@ def _supporting_sources(bundle: dict[str, Any]) -> list[dict[str, Any]]:
"title": artifact.get("title", ""),
"path": path,
"artifact_kind": artifact.get("artifact_kind", ""),
"source_role": artifact.get("source_role", ""),
"supporting_observation_count": by_origin.get(path, 0),
}
)
@ -214,8 +228,12 @@ def build_notebook_page_from_groundrecall_bundle(bundle: dict[str, Any]) -> dict
"claim_count": len(bundle.get("relevant_claims", []) or []),
"supporting_observation_count": len(supporting_observations),
"related_concept_count": len(bundle.get("related_concepts", []) or []),
"source_role_count": len(bundle.get("source_role_summary", {}) or {}),
"distinction_count": len(bundle.get("key_distinctions", []) or []),
},
"graph_navigation": navigation,
"source_role_summary": bundle.get("source_role_summary", {}) or {},
"distinctions": (bundle.get("key_distinctions", []) or [])[:6],
"supporting_sources": _supporting_sources(bundle),
"supporting_excerpts": supporting_excerpts,
"review_context": _review_context(bundle),

View File

@ -20,8 +20,22 @@ def _sample_bundle() -> dict:
"aliases": ["selection"],
},
"relevant_claims": [
{"claim_id": "clm_001", "claim_text": "Selection can change trait frequencies."},
{"claim_id": "clm_002", "claim_text": "Selection depends on heritable variation."},
{
"claim_id": "clm_001",
"claim_text": "Selection can change trait frequencies.",
"source_roles": ["overview"],
},
{
"claim_id": "clm_002",
"claim_text": "Selection does not imply adaptation.",
"source_roles": ["overview"],
"distinction": {
"claim_id": "clm_002",
"distinction_type": "non_implication",
"cue": "does not imply",
"text": "Selection does not imply adaptation.",
},
},
],
"relations": [
{
@ -74,6 +88,16 @@ def _sample_bundle() -> dict:
"artifact_kind": "compiled_page",
"title": "Evolutionary Biology Chapter 1",
"path": "texts/futuyma/ch1.md",
"source_role": "overview",
}
],
"source_role_summary": {"overview": 1},
"key_distinctions": [
{
"claim_id": "clm_002",
"distinction_type": "non_implication",
"cue": "does not imply",
"text": "Selection does not imply adaptation.",
}
],
"review_candidates": [
@ -97,7 +121,14 @@ def test_build_notebook_page_buckets_graph_navigation() -> None:
assert page["graph_navigation"]["derivative_concepts"][0]["title"] == "Adaptation"
assert page["graph_navigation"]["closer_concepts"][0]["title"] == "Common Descent"
assert page["supporting_sources"][0]["supporting_observation_count"] == 1
assert page["supporting_sources"][0]["source_role"] == "overview"
assert page["summary"]["source_role_count"] == 1
assert page["summary"]["distinction_count"] == 1
assert page["source_role_summary"]["overview"] == 1
assert page["distinctions"][0]["distinction_type"] == "non_implication"
assert page["review_context"]["graph_codes"] == ["bridge_concept"]
assert page["review_context"]["source_role_summary"]["overview"] == 1
assert page["review_context"]["key_distinctions"][0]["distinction_type"] == "non_implication"
assert page["illustration_opportunities"]