feat(files): gescannte/bildbasierte PDFs als Bilder rendern (Vision)
read_file gab bei Scan-PDFs (kein extrahierbarer Text) nur nutzlose Rohbytes zurueck -> claude.ai konnte sie nicht lesen. Jetzt: PyMuPDF rendert die Seiten als PNG (150 dpi, max 20 Seiten) -> ImageContent, das LLM liest sie per Vision. Verschluesselte/kaputte PDFs bleiben graceful. TestFileTypes scanned.pdf -> image. Produktiv-Fix fuer alle User. Dep: pymupdf (requirements-extra.txt). 76 Tests gruen.
This commit is contained in:
+19
-4
@@ -127,10 +127,25 @@ def read_file(
|
||||
text = "\n\n".join(pages)
|
||||
if text.strip():
|
||||
return [TextContent(type="text", text=f"[PDF: {path}]\n\n{text[:200000]}")]
|
||||
return [
|
||||
TextContent(type="text", text=f"[PDF '{path}' enthaelt keinen extrahierbaren Text (vermutlich Scan). Rohdaten folgen.]"),
|
||||
EmbeddedResource(type="resource", resource=BlobResourceContents(uri=f"file://{path}", blob=base64.b64encode(r.content).decode(), mimeType=ct)),
|
||||
]
|
||||
# Kein extrahierbarer Text -> bildbasiert/gescannt: Seiten als Bilder
|
||||
# rendern, damit das LLM sie per Vision lesen kann (statt nutzloser Rohbytes).
|
||||
try:
|
||||
import fitz # PyMuPDF
|
||||
doc = fitz.open(stream=r.content, filetype="pdf")
|
||||
n = doc.page_count
|
||||
MAX_PAGES = 20
|
||||
out = [TextContent(type="text", text=f"[PDF '{path}' ist bildbasiert/gescannt ({n} Seite(n)) — als Bilder gerendert:]")]
|
||||
for i in range(min(n, MAX_PAGES)):
|
||||
pix = doc[i].get_pixmap(dpi=150)
|
||||
out.append(ImageContent(type="image", data=base64.b64encode(pix.tobytes("png")).decode(), mimeType="image/png"))
|
||||
if n > MAX_PAGES:
|
||||
out.append(TextContent(type="text", text=f"[... {n - MAX_PAGES} weitere Seiten ausgelassen (Limit {MAX_PAGES}).]"))
|
||||
return out
|
||||
except Exception as e:
|
||||
return [
|
||||
TextContent(type="text", text=f"[PDF '{path}' ist bildbasiert; Rendern fehlgeschlagen ({e}). Rohdaten folgen.]"),
|
||||
EmbeddedResource(type="resource", resource=BlobResourceContents(uri=f"file://{path}", blob=base64.b64encode(r.content).decode(), mimeType=ct)),
|
||||
]
|
||||
except Exception as e:
|
||||
return [TextContent(type="text", text=f"PDF '{path}' konnte nicht gelesen werden: {e}")]
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user