Algorithmic first - AI only when stuck

Catalogue in. Product catalog out.
It knows when it can't.

Point terbium at any vendor catalogue, furniture, rugs, lamps, bags, handwash, anything, and get back a table of products: name, SKU, materials or ingredients, and the product photo, extracted and named. Not markdown to re-parse, commerce-ready records. It rebuilds structure from raw geometry, scores its own confidence on every row, and only reaches for an AI model when it is genuinely stuck. No key? It will not fail silently or burn tokens, it tells you what is missing, by name.

What one vendor PDF actually hides catalogue.pdf
192
Pages
964
Unique SKUs
505
Dimension rows
1157
Images
The one thing terbium does

One call. One clean product table.

Each product photo anchors a row: terbium extracts the image, names it from the label beneath it, and mines the nearby text for the SKU and the materials. Then a CSV, ready for a PIM, Shopify, or a marketplace feed.

pythonbuild_catalog
import terbium

rows = terbium.build_catalog("vendor_catalogue.pdf", images_dir="images/")
terbium.to_catalog_csv(rows, "catalogue.csv")
# {"sku": "RG-1001", "name": "Anatolia Kilim",
#  "materials": "wool", "image": "Anatolia_Kilim.jpeg", "page": 12}
Confidence, not guesswork

It asks for help by name.

Every run ends with a verdict, not a stack trace. When the layout carries the data, terbium finishes cold with zero tokens spent. When a catalogue buries its facts in photos or prose, it says exactly what is missing, where the data actually lives, and what to hand it next.

terbium - run summary
terbium: 8/121 products have a name, 0 a SKU, 9 materials/ingredients.
82 page(s) are image-only (1, 5, 6, 7, 8, ...) - the data lives in the photos, not the text.
-> set ANTHROPIC_API_KEY or pass ai=terbium.AI(...)   ·   recommended tier: Opus (vision)
Four formats, one model of the page

Every file, reduced to columns, rows, and matrices.

PDFGeometry engine

Word-level geometry

Reads the raw x/y position of every word and rebuilds the columns, rows, and 2-D matrices the page never labelled. This is where the full structural engine runs.

PPTXNative structure

Native slides, tables, images

Walks the real slide tree, pulling text frames, native tables, and embedded images straight from the deck's own structure.

XLSXNative structure

Cells, merged ranges, shape

Resolves merged ranges and detects whether a sheet is wide or long, so tables land in the right orientation without a guess.

CSVNative structure

Delimiter, encoding, types

Infers the delimiter, the encoding, and the type of each column before it reads a single row, so messy exports parse cleanly.

PDF gets the full geometry engine because a PDF throws its structure away, terbium has to rebuild it. PPTX, XLSX, and CSV already carry native structure, so terbium leans on it and parses them cleanly and cheaply.

The detector is content-agnostic. Any column-aligned table, a pricelist, a spec sheet, a size x finish matrix, reconstructs the same way, whatever the category. The universal product schema then maps the columns to product fields by header meaning: a bag gets capacity, a lamp gets wattage, a rug gets pile, without a hand-written schema per category.

Not every PDF is a matrix. A lookbook, a grid of photos with a name under each, is reconstructed as a label grid: one record per product, grouped by collection. And when a page is image-only, terbium does not return nothing, it reports exactly which pages need the vision lane.

Not just the text

Pull out the product images, named by product.

terbium extracts every product photo losslessly and names each file after the product it sits beneath, dropping icons, thin banners, and logos that repeat across pages. One call, no AI key needed.

pythonexport_images
import terbium
manifest = terbium.export_images("lookbook.pdf", "out/")
# out/Kyoto_Bedside_Table.jpeg, out/Meadow_Bedside_Table.jpeg, ...

# or from the shell, with a manifest.csv alongside the photos
$ terbium lookbook.pdf --images out/

Per image: product, collection, page, format, pixel size, colorspace, effective dpi, dominant colour, and position, written to a manifest.csv.

Quickstart

Parse first. Add a key only when it asks.

Install, point it at a catalogue, and read the table. Wire up an AI key when, and only when, terbium tells you the data lives somewhere the algorithm cannot reach.

shellpypi
pip install terbium-parse
terbium catalogue.pdf --csv out.csv        # the product table + images/, no AI
pythonexample.py
import terbium

rows = terbium.build_catalog("catalogue.pdf", images_dir="images/")   # algorithmic only

rows = terbium.build_catalog("lookbook.pdf", images_dir="images/",
                             ai=terbium.AI(anthropic_key=...))       # vision fills the blanks

doc = terbium.parse("pricelist.xlsx", schema="product")              # raw records API
When it does call AI, it routes

The hard page gets the strong model. Nothing else does.

terbium matches the difficulty of a page to the cheapest model that can actually solve it, so you never pay Opus prices for a page Haiku could clear.

Trivial
Haiku

A stray label or an obvious cell. Cleared for pennies.

Moderate
Sonnet

A table whose alignment is plausible but not certain.

Hard
Opus

Ambiguous matrices, orphan SKUs, image-only lookbook pages. The real work.

Images, material icons and finish swatches, are read by a vision model and folded back into the record.