feat(kreuzberg): add multi-file processing and PaddleOCR backend

- Add extract_files() for processing multiple files one by one
- Support comma-separated and JSON array input
- Switch OCR backend from Tesseract to PaddleOCR (better accuracy)
- Update tool description
This commit is contained in:
Folzo
2026-04-11 00:42:32 +02:00
parent 3355fd4f28
commit f85ee6c122
+78 -7
View File
@@ -4,7 +4,7 @@
1. **Admin Panel** → **Tools** → **Create Tool** 1. **Admin Panel** → **Tools** → **Create Tool**
2. **Name**: `Kreuzberg OCR` 2. **Name**: `Kreuzberg OCR`
3. **Description**: `Extract text from documents (PDF, images, scanned pages) using Kreuzberg OCR. Call `extract_file("filename")` on attached files.` 3. **Description**: `Extract text from documents using Kreuzberg OCR (PaddleOCR backend). Single: extract_file("file") or Multiple: extract_files("file1,file2")`
4. **Coller le code ci-dessous** 4. **Coller le code ci-dessous**
5. **Save and Activate** 5. **Save and Activate**
@@ -44,7 +44,7 @@ class Tools:
def extract_file(self, filename: str) -> str: def extract_file(self, filename: str) -> str:
""" """
Extract text from a file using Kreuzberg OCR. Extract text from a single file using Kreuzberg OCR.
Args: Args:
filename: The filename shown in the chat (e.g., "document.pdf", "image.jpg") filename: The filename shown in the chat (e.g., "document.pdf", "image.jpg")
@@ -53,6 +53,58 @@ class Tools:
Returns: Returns:
Extracted text content with markdown formatting Extracted text content with markdown formatting
""" """
return self._extract_single_file(filename)
def extract_files(self, filenames: str) -> str:
"""
Extract text from multiple files, one at a time.
Args:
filenames: Comma-separated list of filenames (e.g., "doc1.pdf,doc2.jpg")
or JSON array string (e.g., '["doc1.pdf","doc2.jpg"]')
Returns:
Combined extracted text from all files, processed sequentially
"""
import json
filenames = filenames.strip()
if not filenames:
return "❌ No filenames provided. Usage: extract_files(\"file1.pdf,file2.jpg\")"
if filenames.startswith('['):
try:
file_list = json.loads(filenames)
except json.JSONDecodeError:
return f"❌ Invalid JSON array: {filenames}"
else:
file_list = [f.strip() for f in filenames.split(',')]
if not file_list:
return "❌ No files to process"
if len(file_list) == 1:
return self._extract_single_file(file_list[0])
results = []
total = len(file_list)
for i, filename in enumerate(file_list, 1):
filename = filename.strip()
if not filename:
continue
if total > 1:
results.append(f"--- Document {i}/{total}: `{filename}` ---")
result = self._extract_single_file(filename)
results.append(result)
return "\n\n".join(results)
def _extract_single_file(self, filename: str) -> str:
"""Internal method to extract text from a single file"""
try: try:
file_path = self._find_file(filename) file_path = self._find_file(filename)
@@ -89,6 +141,7 @@ class Tools:
files=files, files=files,
data=data, data=data,
timeout=300 timeout=300
)
if response.status_code == 200: if response.status_code == 200:
result = response.json() result = response.json()
@@ -96,10 +149,8 @@ class Tools:
if 'document' in result: if 'document' in result:
content = result['document'].get('md_content', '') content = result['document'].get('md_content', '')
if content and len(content.strip()) > 10: if content and len(content.strip()) > 10:
# Clean up the content
content = self._clean_content(content) content = self._clean_content(content)
# Truncate if too long (LLM context limit)
if len(content) > 15000: if len(content) > 15000:
content = content[:15000] + "\n\n... (document truncated - too long for context)" content = content[:15000] + "\n\n... (document truncated - too long for context)"
@@ -290,7 +341,7 @@ class Tools:
# OpenWebUI Tool Functions # OpenWebUI Tool Functions
def extract_file(filename: str) -> str: def extract_file(filename: str) -> str:
""" """
Extract text from a file using Kreuzberg OCR. Extract text from a single file using Kreuzberg OCR.
Args: Args:
filename: The filename or UUID from the chat (e.g., "document.pdf", "abc123_document.pdf") filename: The filename or UUID from the chat (e.g., "document.pdf", "abc123_document.pdf")
@@ -301,6 +352,20 @@ def extract_file(filename: str) -> str:
tools = Tools() tools = Tools()
return tools.extract_file(filename) return tools.extract_file(filename)
def extract_files(filenames: str) -> str:
"""
Extract text from multiple files, one at a time.
Args:
filenames: Comma-separated list (e.g., "doc1.pdf,doc2.jpg")
or JSON array (e.g., '["doc1.pdf","doc2.jpg"]')
Returns:
Combined extracted text from all files
"""
tools = Tools()
return tools.extract_files(filenames)
def list_recent_files(count: int = 10) -> str: def list_recent_files(count: int = 10) -> str:
"""List recent uploaded files""" """List recent uploaded files"""
tools = Tools() tools = Tools()
@@ -316,13 +381,19 @@ def search_files(pattern: str) -> str:
After installing and activating the tool: After installing and activating the tool:
### Extract text from a file: ### Extract text from a single file:
``` ```
extract_file("document.pdf") extract_file("document.pdf")
extract_file("9af3d665-998b-4577-b893-340cb1c28385_document.pdf") extract_file("9af3d665-998b-4577-b893-340cb1c28385_document.pdf")
extract_file("image.jpg") extract_file("image.jpg")
``` ```
### Extract from multiple files (processed one by one):
```
extract_files("doc1.pdf,doc2.jpg")
extract_files('["page1.jpg","page2.jpg","page3.jpg"]')
```
### List recent files: ### List recent files:
``` ```
list_recent_files() list_recent_files()
@@ -337,4 +408,4 @@ search_files("polz")
--- ---
*Updated 11 April 2026 - Added image preprocessing (grayscale + contrast) for better OCR quality* *Updated 11 April 2026 - Added PaddleOCR backend + multi-file processing*