Skip to content

teff.rag.pdf_tool

teff.rag.pdf_tool

PDF extraction tool — turn a PDF into per-page text for RAG.

Classes:

Name Description
PDFTool

Extract text from a PDF file, one section per page.

PDFTool

Bases: Tool

Extract text from a PDF file, one section per page.

Text-based PDFs are read with pypdf (extra teff[rag-pdf]). Scanned / image-only pages yield no text — feed those pages to :class:~teff.rag.image_tool.ImageTool instead.

Parameters:

Name Type Description Default
config dict | None

Optional dict. max_chars sets the default output limit (default 50000). Kept for config parity with other tools in a workflow tools: block.

None

Methods:

Name Description
run

Return the PDF text as --- page N --- sections.

Source code in teff/rag/pdf_tool.py
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class PDFTool(Tool):
    """Extract text from a PDF file, one section per page.

    Text-based PDFs are read with ``pypdf`` (extra ``teff[rag-pdf]``).
    Scanned / image-only pages yield no text — feed those pages to
    :class:`~teff.rag.image_tool.ImageTool` instead.

    Args:
        config: Optional dict.  ``max_chars`` sets the default output
            limit (default 50000).  Kept for config parity with other
            tools in a workflow ``tools:`` block.
    """

    name = "pdf"
    description = "Extract text from a PDF file, one section per page"

    def __init__(self, config: dict | None = None):
        self.max_chars: int = 50000
        if isinstance(config, dict):
            self.max_chars = int(config.get("max_chars", 50000))

    def run(self, path: str, max_chars: int | None = None) -> str:  # type: ignore[override]
        """Return the PDF text as ``--- page N ---`` sections."""
        if not path:
            raise ValueError("path is required")
        docs = load_documents_pdf(path)
        if not docs:
            return "no text found in pdf"
        parts = [f"--- page {meta['page']} ---\n{text}" for text, meta in docs]
        result = "\n".join(parts)
        limit = max_chars if max_chars is not None else self.max_chars
        if limit and limit > 0:
            return result[:limit]
        return result

run

run(path, max_chars=None)

Return the PDF text as --- page N --- sections.

Source code in teff/rag/pdf_tool.py
28
29
30
31
32
33
34
35
36
37
38
39
40
def run(self, path: str, max_chars: int | None = None) -> str:  # type: ignore[override]
    """Return the PDF text as ``--- page N ---`` sections."""
    if not path:
        raise ValueError("path is required")
    docs = load_documents_pdf(path)
    if not docs:
        return "no text found in pdf"
    parts = [f"--- page {meta['page']} ---\n{text}" for text, meta in docs]
    result = "\n".join(parts)
    limit = max_chars if max_chars is not None else self.max_chars
    if limit and limit > 0:
        return result[:limit]
    return result