Specialist parser
Add a parser that cheap opt-in signature detection nominates ahead of the generic routing ladder.
A parser is nominated rather than added to every generic route. Implement the SignatureDetector protocol’s cheap detection alongside reading, and ask for it with --signatures or signature_detection=True. Here cheap_signals(), extract_text(), and extract_fields() stand for your code; everything facing indx uses the real public contracts. Package and install it as the overview describes.
from indx_interfaces import ( CapabilityId, PageOutput, ScopeKind, ScopeRef, SignatureId, SignatureMatch,)
CAPABILITY_ID = CapabilityId("acme-purchase-order")
class PurchaseOrderParser: def detect( self, content: bytes, media_type: str ) -> tuple[SignatureMatch, ...]: evidence = cheap_signals(content, media_type) if len(evidence) < 2: return () return ( SignatureMatch( scope=ScopeRef(kind=ScopeKind.DOCUMENT), signature_id=SignatureId("purchase-order"), tag="purchase_order", confidence=min(1.0, len(evidence) / 3), candidate_capability_id=CAPABILITY_ID, evidence=evidence, ), )
def read( self, content: bytes, media_type: str, pages: tuple[int, ...] ) -> tuple[PageOutput, ...]: return tuple( PageOutput( page=page, text=extract_text(content, media_type, page), metadata={ "purchase_order": extract_fields(content, page), }, ) for page in pages )Advertise this implementation with a PARSER descriptor and return it from the same Provider.create() pattern shown for the page reader. Detection runs during planning, so it must stay cheap, local, deterministic, and free of OCR, rendering, models, and network calls. A match puts the parser first while retaining the generic fallbacks.
Scope your match at DOCUMENT or PAGE. A REGION-scoped match is carried on the plan for the caller to see and nominates nothing: the plan holds document and page assignments only, so routing from one would read “there is a purchase-order table in this region” as “this page is a purchase order”.
Kind describes the work, never the door. PARSER means your capability is only correct about a document its own detect() recognized first — nomination is its one way into a route, so a media type only a parser declares, planned without signature_detection, comes back as an unsatisfied plan naming the parser and the flag. If your capability generically reads its format, declare NATIVE_EXTRACTION and ship the parser alongside it, the way the worked example pairs acme-plaintext with acme-purchase-order.
Checklist
Section titled “Checklist”- Test detector matches and non-matches without expensive work.