"""A table fragment with no name of its own takes the heading above it (v1.1 C3). The proposer names a table block that has no heading of its own after the line it starts on (`Tabell linje `, `rule:table-block`). That is a position, not a name: searched, it matches no question, and shown, it tells a reader nothing about what the table is. `okf consume` reads such a concept under the heading it stands under -- the nearest concept ABOVE it in the same source document -- both in what is ranked and in what the excerpt shows, and the excerpt keeps the concept's own title beside it as `own_title`, so the name shown is never mistaken for the one in the file. Nothing in a bundle moves: the inheritance is a reading, done in `consume`. """ from __future__ import annotations import sys from pathlib import Path import pytest from llm_ingestion_okf import consume, contract_check from llm_ingestion_okf import skill as okf_skill TOOLS = Path(__file__).resolve().parent.parent / "tools" if str(TOOLS) not in sys.path: sys.path.insert(0, str(TOOLS)) import okf_retrieval_gate as retrieval # noqa: E402 TABLE = "| Room | Heater |\n| --- | --- |\n| Hall | Panel |\n| Loft | Stove |" #: (slug, title, body, first line, last line), in document order. CABIN = ( ("water", "Water", "The well is drained in autumn.", 1, 10), ("tabell-linje-11", "Tabell linje 11", TABLE, 11, 14), ("heating", "Heating", "The cabin is kept warm through the winter.", 15, 20), ("tabell-linje-21", "Tabell linje 21", TABLE, 21, 24), ) #: A document whose FIRST concept is a table: nothing stands above it. LEDGER = (("tabell-linje-1", "Tabell linje 1", TABLE, 1, 4),) def _write(root: Path) -> Path: spec = retrieval.BundleSpec( "table-titles", tuple( retrieval.DocumentSpec( name, f"{name}.md", tuple( retrieval.ConceptSpec(slug=slug, title=title, body=body) for slug, title, body, _, _ in rows ), ) for name, rows in (("cabin", CABIN), ("ledger", LEDGER)) ), ) bundle = retrieval.build_bundle(root, spec) for name, rows in (("cabin", CABIN), ("ledger", LEDGER)): for slug, title, body, first, last in rows: path = bundle / name / f"{slug}.md" text = path.read_text(encoding="utf-8") text = text.replace( f"source_file: {name}.md\n", f"source_file: {name}.md\nsource_lines: [{first}, {last}]\n", ) if title.startswith("Tabell linje"): # A real table block carries no heading line of its own. text = text.replace(f"## {title}\n\n", "") path.write_text(text, encoding="utf-8") return bundle @pytest.fixture(scope="module") def bundle(tmp_path_factory: pytest.TempPathFactory) -> Path: return _write(tmp_path_factory.mktemp("table-titles") / "bundle") def _excerpts(bundle: Path, question: str) -> dict[str, dict[str, object]]: payload = consume.build_payload(bundle, question=question, k=8, source_quota=None) excerpts = payload["excerpts"] assert isinstance(excerpts, list) return {str(excerpt["concept_id"]): excerpt for excerpt in excerpts} def test_a_table_fragment_shows_the_heading_it_stands_under(bundle: Path) -> None: excerpts = _excerpts(bundle, "room heater") heating_table = excerpts["cabin/tabell-linje-21"] water_table = excerpts["cabin/tabell-linje-11"] assert heating_table["title"] == "Heating" assert heating_table["own_title"] == "Tabell linje 21" assert water_table["title"] == "Water" assert water_table["own_title"] == "Tabell linje 11" def test_a_concept_with_a_name_of_its_own_is_untouched(bundle: Path) -> None: excerpt = _excerpts(bundle, "cabin warm winter")["cabin/heating"] assert excerpt["title"] == "Heating" assert "own_title" not in excerpt def test_a_table_with_nothing_above_it_keeps_its_own_title(bundle: Path) -> None: excerpt = _excerpts(bundle, "room heater")["ledger/tabell-linje-1"] assert excerpt["title"] == "Tabell linje 1" assert "own_title" not in excerpt def test_the_inherited_heading_is_searched(bundle: Path) -> None: """Two identical tables; the question names the heading ONE stands under. Without the inheritance they tie and the id decides, which puts the table under `Water` first (`tabell-linje-11` sorts before `tabell-linje-21`). """ payload = consume.build_payload(bundle, question="heating room", k=8, source_quota=None) order = [str(excerpt["concept_id"]) for excerpt in payload["excerpts"]] # type: ignore[union-attr] assert order.index("cabin/tabell-linje-21") < order.index("cabin/tabell-linje-11") def test_the_near_misses_name_the_inherited_heading(bundle: Path) -> None: payload = consume.build_payload(bundle, question="room heater", k=1, source_quota=None) withheld = payload["withheld"] assert isinstance(withheld, dict) titles = {entry["concept_id"]: entry["title"] for entry in withheld["nearest"]} assert titles.get("cabin/tabell-linje-11", "Water") == "Water" assert titles.get("cabin/tabell-linje-21", "Heating") == "Heating" assert "Tabell linje 11" not in titles.values() assert "Tabell linje 21" not in titles.values() def test_the_contract_checker_accepts_it(bundle: Path) -> None: payload = consume.build_payload(bundle, question="room heater") assert contract_check.check(okf_skill.render_generic(), payload).findings == () def test_the_mechanical_name_is_the_proposers() -> None: """The pattern read here is the one `propose` writes, held against its output.""" from llm_ingestion_okf import propose text = "Intro line.\n\n| a | b |\n| --- | --- |\n| 1 | 2 |\n" titles = [candidate.title for candidate in propose.find_candidates(text)] table_titles = [title for title in titles if "linje" in title] assert table_titles, "the premise: the proposer names a table block" assert all(consume.MECHANICAL_TITLE.fullmatch(title) for title in table_titles)