Coverage for src / quber / core / extractors / camelot / correspondence / __init__.py: 100%
2 statements
« prev ^ index » next coverage.py v7.14.0, created at 2026-09-23 22:14 -0400
« prev ^ index » next coverage.py v7.14.0, created at 2026-09-23 22:14 -0400
1"""
2CamelotCorrespondenceExtractor — the rasterized page is the arbiter of
3what is a table and where. Per page:
51. Extract + detect (concurrent): Camelot lattice and stream run on the
6 CPU; the detector agent reads the page image and returns the real
7 tables, top to bottom, each with a rough box and a description.
82. Correspondence: assign Camelot chunks to detected tables by 2D bbox
9 overlap. Lattice is tried first (trusted source); stream is the
10 fallback for tables no lattice chunk matched. One chunk that is the
11 best match for two-or-more tables -> combined (kept whole, flagged,
12 never split). A table whose best chunk is truncated is completed from
13 the leftover (orphan) chunks in step 3. Matching is deterministic —
14 no LLM reads the cell values.
153. Assemble + completeness audit: join a table's matched chunks in order,
16 then check the assembled data against the page's text layer (the same
17 source Camelot reads) within the table's region. A value-like figure in
18 the region's columns that is absent from the assembled data -> extend
19 with the next leftover chunk and re-audit; if nothing supplies it,
20 report the gap.
22Report, don't drop (with guarded recovery): a detected table neither
23flavor produced gets one targeted, region-constrained stream pass at the
24detector's box. If that yields data it is emitted as extracted; otherwise
25it is emitted with status `detected_not_extracted` — reported explicitly,
26never silently dropped.
28Camelot stays the source of truth for cell values; nothing here rewrites
29them. State is in-memory for the length of a run; there is no database.
31The package is split by what a reader needs in view at once:
33- `orchestrator` — constructor defaults, the per-page
34 flow (detect, assign, recover, audit/extend/fill, emit), and the
35 public `extract_tables` / `extract_tables_sync`.
36- `geometry` — coordinate-frame conversions (Camelot points, detector
37 0..1, top-left points) and region slicing (text-layer words, image
38 crop). Deterministic; no LLM, no Camelot.
39- `matching` — the argmax chunk-to-table assignment, combined-chunk
40 inversion, orphan queue, and grid assembly.
41- `recovery` — the targeted region-constrained stream pass and the
42 grid-locator region pairing.
43- `correction` — output-stage structure vetting against the cropped
44 table image, with the grounding guard that rejects any value absent
45 from both Camelot's grid and the page text layer.
47The Camelot layer (page rendering, both flavors in spawn-context
48subprocesses, content-empty shell detection) is shared with the
49camelot.llm extractor and lives in
50`quber.core.extractors.camelot.acquire`.
51"""
53from quber.core.extractors.camelot.correspondence.orchestrator import CamelotCorrespondenceExtractor
55__all__ = ["CamelotCorrespondenceExtractor"]