Skip to content

LlamaIndex

Xberg connects to LlamaIndex through a reader that turns any of 91+ file formats into Document objects, and a node parser that splits those documents into structure-aware TextNode objects for indexing — available for both Python and TypeScript.

PyPI npm License

flowchart LR
Files[Documents] --> Reader[XbergReader]
Reader --> Docs[LlamaIndex Documents]
Docs --> Parser[XbergNodeParser]
Parser --> Nodes[TextNodes]
Nodes --> Index[VectorStoreIndex]
style Reader fill:#87CEEB
style Parser fill:#FFD700
style Index fill:#90EE90
  1. ReadXbergReader extracts each source file, mapping title, MIME type, page count, detected languages, keywords, and quality score onto Document.metadata. Multiple files go through a single batched call.
  2. Chunk — With chunking enabled, Xberg’s native chunker attaches semantic chunks (heading path, page span) under _xberg_chunks.
  3. ParseXbergNodeParser turns each chunk into a TextNode with a source relationship. Without chunks, it falls back to structural elements.
  4. Index — Feed the nodes into any LlamaIndex index or ingestion pipeline.
Terminal window
pip install llama-index-readers-xberg llama-index-node-parser-xberg

Both require Python 3.10+ and llama-index-core>=0.14.23,<0.15. The reader pulls in xberg; the node parser has no direct xberg dependency.

Call loadData with a path, a list of paths, or raw bytes. Passing a list extracts many files in one batched call. By default the reader skips files that fail extraction and logs a warning; set raiseOnError (raise_on_error in Python) to propagate failures instead.

from llama_index.readers.xberg import XbergReader
reader = XbergReader()
documents = reader.load_data("report.pdf")
print(documents[0].metadata["file_type"]) # "application/pdf"
print(documents[0].metadata["total_pages"]) # 12
print(documents[0].metadata["detected_languages"]) # ["en"]
# Batch, async, and in-memory bytes
documents = reader.load_data(["report.pdf", "slides.pptx", "data.xlsx"])
documents = await reader.aload_data(["a.pdf", "b.pdf"])
documents = reader.load_data(data=pdf_bytes, mime_type="application/pdf")

XbergNodeParser prefers Xberg’s native chunks. Enable chunking on the reader, then parse the documents into nodes. If a document has no chunks, the parser uses structural elements; documents with neither pass through unchanged with a warning. Each node keeps a SOURCE relationship to its parent.

from xberg import ChunkingConfig, ExtractionConfig
from llama_index.readers.xberg import XbergReader
from llama_index.node_parser.xberg import XbergNodeParser
reader = XbergReader(
extraction_config=ExtractionConfig(
chunking=ChunkingConfig(max_characters=1000, overlap=200, prepend_heading_context=True),
)
)
documents = reader.load_data("report.pdf")
parser = XbergNodeParser()
nodes = parser.get_nodes_from_documents(documents)
print(nodes[0].metadata["chunk_type"]) # e.g. "heading"
print(nodes[0].metadata["heading_path"]) # ["Introduction"]
print(nodes[0].metadata["page_number"]) # 1

Compose reader and parser into a VectorStoreIndex or IngestionPipeline:

from llama_index.core import VectorStoreIndex
index = VectorStoreIndex.from_documents(
documents,
transformations=[XbergNodeParser()],
)

XbergReader also works as a file_extractor for SimpleDirectoryReader:

from llama_index.core import SimpleDirectoryReader
sdr = SimpleDirectoryReader(
input_dir="./documents",
file_extractor={".pdf": reader, ".docx": reader, ".html": reader},
)
documents = sdr.load_data()

For the complete options, see the package READMEs (Python, TypeScript) and the Xberg docs.