src / documents / parsers / doclingRunner.ts
/**
* Shared low-level invocation of python/docling_parser.py.
* Used by PdfParser (as one link in its docling → pymupdf → pdf-parse fallback
* chain) and by DocxParser (as its only strategy — PyMuPDF/pdf-parse cannot
* read DOCX, so there is no fallback to chain for that format).
*/
import path from 'path';
import type { ParsedDocument, ParserOptions } from '../../types';
import { executePythonScript } from '../../utils/pythonRunner';
import { ragDebug } from '../../utils/ragLogger.js';
export async function parseWithDoclingScript(
filePath: string,
format: 'pdf' | 'docx',
logLabel: string,
options?: ParserOptions
): Promise<ParsedDocument> {
ragDebug(logLabel, 'Using docling for professional-grade parsing...');
const scriptPath = path.join(process.cwd(), 'python', 'docling_parser.py');
const extractTables = options?.extractTables !== false ? 'true' : 'false';
const args = [filePath, extractTables];
if (options?.imageOutputDir) args.push(options.imageOutputDir);
const result = await executePythonScript<{
success: boolean;
content: string;
metadata: {
format: string;
strategy: string;
title?: string;
page_count: number;
has_tables: boolean;
char_count: number;
image_count: number | null;
};
error?: string;
}>(scriptPath, args, {
timeout: 120000,
onStatus: options?.onStatus,
});
if (!result.success || !result.data?.success) {
throw new Error(result.error || result.data?.error || 'Docling parsing failed');
}
const data = result.data;
return {
content: data.content,
metadata: {
format,
strategy: 'docling',
title: data.metadata.title,
pageCount: data.metadata.page_count,
hasTables: data.metadata.has_tables,
imageCount: data.metadata.image_count ?? undefined,
},
};
}
src / documents / parsers / doclingRunner.ts
/**
* Shared low-level invocation of python/docling_parser.py.
* Used by PdfParser (as one link in its docling → pymupdf → pdf-parse fallback
* chain) and by DocxParser (as its only strategy — PyMuPDF/pdf-parse cannot
* read DOCX, so there is no fallback to chain for that format).
*/
import path from 'path';
import type { ParsedDocument, ParserOptions } from '../../types';
import { executePythonScript } from '../../utils/pythonRunner';
import { ragDebug } from '../../utils/ragLogger.js';
export async function parseWithDoclingScript(
filePath: string,
format: 'pdf' | 'docx',
logLabel: string,
options?: ParserOptions
): Promise<ParsedDocument> {
ragDebug(logLabel, 'Using docling for professional-grade parsing...');
const scriptPath = path.join(process.cwd(), 'python', 'docling_parser.py');
const extractTables = options?.extractTables !== false ? 'true' : 'false';
const args = [filePath, extractTables];
if (options?.imageOutputDir) args.push(options.imageOutputDir);
const result = await executePythonScript<{
success: boolean;
content: string;
metadata: {
format: string;
strategy: string;
title?: string;
page_count: number;
has_tables: boolean;
char_count: number;
image_count: number | null;
};
error?: string;
}>(scriptPath, args, {
timeout: 120000,
onStatus: options?.onStatus,
});
if (!result.success || !result.data?.success) {
throw new Error(result.error || result.data?.error || 'Docling parsing failed');
}
const data = result.data;
return {
content: data.content,
metadata: {
format,
strategy: 'docling',
title: data.metadata.title,
pageCount: data.metadata.page_count,
hasTables: data.metadata.has_tables,
imageCount: data.metadata.image_count ?? undefined,
},
};
}