@heripo/pdf-parser 0.1.38 → 0.1.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts DELETED
@@ -1,365 +0,0 @@
1
- import { LoggerMethods } from '@heripo/logger';
2
- import { TokenUsageReport, ReviewAssistanceProgressEvent } from '@heripo/model';
3
- export { ReviewAssistanceProgressEvent, ReviewAssistanceProgressStatus, ReviewAssistanceProgressSubstage } from '@heripo/model';
4
- import { LanguageModel } from 'ai';
5
- import { ConversionOptions } from 'docling-sdk';
6
- import { LLMTokenUsageAggregator } from '@heripo/shared';
7
-
8
- type ReviewAssistanceTaskId = 'text_ocr_hanja' | 'text_integrity' | 'text_role_footnote' | 'tables' | 'pictures_captions' | 'layout_bbox_order';
9
-
10
- interface PDFCorrectionModelOptions {
11
- textCorrection: LanguageModel;
12
- /** textCorrection 실패(예: lmstudio 400) 시 LLMCaller fallback. */
13
- textCorrectionFallback?: LanguageModel;
14
- pageGate: LanguageModel;
15
- /** pageGate(page-eligibility) 실패 시 fallback. */
16
- pageGateFallback?: LanguageModel;
17
- reviewAssistance: LanguageModel;
18
- /** review-assistance 공통 fallback (task별 미지정 시 사용). */
19
- reviewAssistanceFallback?: LanguageModel;
20
- reviewAssistanceTasks?: Partial<Record<ReviewAssistanceTaskId, LanguageModel>>;
21
- /** review-assistance task별 fallback. */
22
- reviewAssistanceTasksFallback?: Partial<Record<ReviewAssistanceTaskId, LanguageModel>>;
23
- tableCorrection?: LanguageModel;
24
- /** tableCorrection 실패 시 fallback. */
25
- tableCorrectionFallback?: LanguageModel;
26
- }
27
- interface PDFCorrectionConcurrencyOptions {
28
- pages?: number;
29
- reviewTasks?: number;
30
- tables?: number;
31
- }
32
- interface PDFCorrectionMaxRetriesOptions {
33
- textCorrection?: number;
34
- pageGate?: number;
35
- reviewAssistance?: number;
36
- tableCorrection?: number;
37
- }
38
- interface PDFCorrectionPageGateOptions {
39
- structuralNoiseThreshold?: number;
40
- }
41
- interface PDFCorrectionOptions {
42
- models: PDFCorrectionModelOptions;
43
- concurrency?: PDFCorrectionConcurrencyOptions;
44
- maxRetries?: PDFCorrectionMaxRetriesOptions;
45
- modelConcurrency?: number;
46
- workItemTimeoutMs?: number;
47
- outputLanguage?: string;
48
- pageGate?: PDFCorrectionPageGateOptions;
49
- autoApplyThreshold?: number;
50
- proposalThreshold?: number;
51
- /**
52
- * When true, every valid review-assistance command auto-applies regardless of
53
- * confidence threshold or structural block reason (no manual-review routing).
54
- * Enabled by the engine demo; defaults to false everywhere else.
55
- */
56
- forceAutoApply?: boolean;
57
- /**
58
- * When false, the review-assistance stage (the per-page eligibility gate plus
59
- * the structural review-assistance runner) is skipped entirely and only the
60
- * text-correction stage runs. Defaults to true.
61
- */
62
- reviewAssistanceEnabled?: boolean;
63
- temperature?: number;
64
- }
65
- interface NormalizedPDFCorrectionOptions {
66
- models: PDFCorrectionModelOptions;
67
- concurrency: Required<PDFCorrectionConcurrencyOptions>;
68
- maxRetries: Required<PDFCorrectionMaxRetriesOptions>;
69
- modelConcurrency: number;
70
- workItemTimeoutMs: number;
71
- outputLanguage: string;
72
- pageGate: Required<PDFCorrectionPageGateOptions>;
73
- autoApplyThreshold: number;
74
- proposalThreshold: number;
75
- forceAutoApply: boolean;
76
- reviewAssistanceEnabled: boolean;
77
- temperature: number;
78
- }
79
- declare const PDF_CORRECTION_DEFAULTS: Omit<NormalizedPDFCorrectionOptions, 'models'>;
80
-
81
- /**
82
- * Callback function invoked after PDF conversion completes
83
- * @param outputPath Absolute path to the output directory containing result files
84
- */
85
- type ConversionCompleteCallback = (outputPath: string) => Promise<void> | void;
86
- /**
87
- * Extended options for PDF conversion.
88
- */
89
- type PDFConvertOptions = Omit<ConversionOptions, 'to_formats' | 'image_export_mode' | 'ocr_engine' | 'accelerator_options' | 'ocr_options' | 'generate_picture_images' | 'generate_page_images' | 'images_scale' | 'force_ocr' | 'pipeline' | 'vlm_pipeline_model_local' | 'vlm_pipeline_model_api'> & {
90
- correction: PDFCorrectionOptions;
91
- num_threads?: number;
92
- /**
93
- * Force pre-conversion to image-based PDF before processing.
94
- * Requires ImageMagick and Ghostscript.
95
- */
96
- forceImagePdf?: boolean;
97
- /** Token usage aggregator for tracking post-Docling correction calls */
98
- aggregator?: LLMTokenUsageAggregator;
99
- /** Callback fired after correction work completes, with cumulative token usage */
100
- onTokenUsage?: (report: TokenUsageReport) => void;
101
- /** Callback fired when Review Assistance advances through parser substages */
102
- onReviewAssistanceProgress?: (event: ReviewAssistanceProgressEvent) => void;
103
- /** Document processing timeout in seconds for the Docling server (default: server default) */
104
- document_timeout?: number;
105
- /** Enable chunked conversion for large PDFs (local files only) */
106
- chunkedConversion?: boolean;
107
- /** Pages per chunk (default: CHUNKED_CONVERSION.DEFAULT_CHUNK_SIZE) */
108
- chunkSize?: number;
109
- /** Max retry attempts per failed chunk (default: CHUNKED_CONVERSION.DEFAULT_MAX_RETRIES) */
110
- chunkMaxRetries?: number;
111
- /** Vision model for document language detection when the PDF text layer is insufficient */
112
- languageDetectionModel?: LanguageModel;
113
- /** languageDetectionModel 실패 시 fallback. */
114
- languageDetectionFallbackModel?: LanguageModel;
115
- /** LLM model for document type validation (opt-in: skipped when not set) */
116
- documentValidationModel?: LanguageModel;
117
- };
118
-
119
- type Options = {
120
- logger: LoggerMethods;
121
- timeout?: number;
122
- venvPath?: string;
123
- killExistingProcess?: boolean;
124
- /**
125
- * Enable fallback to image-based PDF when conversion fails.
126
- * Only works with local server mode (port option).
127
- * Requires ImageMagick and Ghostscript to be installed.
128
- */
129
- enableImagePdfFallback?: boolean;
130
- } & ({
131
- port?: number;
132
- } | {
133
- baseUrl: string;
134
- });
135
- /**
136
- * PDFParser - A PDF document parser using docling-serve
137
- *
138
- * ## System Requirements
139
- * Before using PDFParser, ensure your system meets these requirements:
140
- *
141
- * ### Operating System
142
- * - macOS 10.15 (Catalina) or later
143
- *
144
- * ### Required Software
145
- * - `python3` (version 3.9 - 3.12)
146
- * - Python 3.13+ is NOT compatible with docling-serve
147
- * - Recommended: Python 3.11 or 3.12
148
- * - Install specific version: `pyenv install 3.12.0 && pyenv global 3.12.0`
149
- * - `jq` - JSON processor
150
- * - Install: `brew install jq`
151
- * - `poppler` - PDF text extraction tools (pdftotext, pdfinfo)
152
- * - Install: `brew install poppler`
153
- * - `lsof` - List open files (usually pre-installed on macOS)
154
- *
155
- * ## Initialization Process
156
- * When `init()` is called, the following setup occurs automatically:
157
- *
158
- * ### If using external server (baseUrl provided):
159
- * 1. Connects to the provided baseUrl
160
- * 2. Waits for server health check (up to 120 seconds)
161
- *
162
- * ### If using local server (default):
163
- * 1. **Python Environment Setup**
164
- * - Verifies Python version compatibility (3.9-3.12)
165
- * - Creates Python virtual environment at `venvPath` (default: `.venv`)
166
- * - Verifies virtual environment Python version
167
- *
168
- * 2. **Dependency Installation**
169
- * - Upgrades pip to latest version
170
- * - Installs setuptools and wheel
171
- * - Installs pyarrow (binary-only to avoid compilation)
172
- * - Installs docling-serve package
173
- *
174
- * 3. **Server Management**
175
- * - Checks if specified port is already in use
176
- * - If `killExistingProcess` is true, kills any process using the port
177
- * - If port is in use and `killExistingProcess` is false, reuses existing server
178
- * - Otherwise, starts new docling-serve instance on specified port
179
- * - Waits for server to become ready (health check, up to 120 seconds)
180
- *
181
- * ## Notes
182
- * - First initialization may take several minutes due to Python package downloads
183
- * - Subsequent initializations are faster if virtual environment already exists
184
- * - The virtual environment and packages are reused across sessions
185
- * - Server process runs in background and needs to be managed separately if needed
186
- */
187
- declare class PDFParser {
188
- private readonly logger;
189
- private readonly port?;
190
- private readonly baseUrl?;
191
- private readonly timeout;
192
- private readonly venvPath;
193
- private readonly killExistingProcess;
194
- private readonly enableImagePdfFallback;
195
- private client;
196
- private environment?;
197
- private recoveryPromise;
198
- constructor(options: Options);
199
- init(): Promise<void>;
200
- /**
201
- * Check if an error is a connection refused error (ECONNREFUSED).
202
- * This typically indicates the Docling server has crashed.
203
- */
204
- private isConnectionRefusedError;
205
- private canRecoverLocalServer;
206
- /**
207
- * Restart the Docling server after it has crashed.
208
- * This kills any existing process on the port, starts a new server,
209
- * and waits for it to become ready.
210
- *
211
- * Note: This method is only called when canRecover is true,
212
- * which guarantees this.port is defined.
213
- */
214
- private restartServer;
215
- private recoverServer;
216
- isReady(): Promise<boolean>;
217
- ensureReady(): Promise<void>;
218
- private waitForServerReady;
219
- parse(url: string, reportId: string, onComplete: ConversionCompleteCallback, cleanupAfterCallback: boolean, options: PDFConvertOptions, abortSignal?: AbortSignal): Promise<TokenUsageReport | null>;
220
- /**
221
- * Execute a function with automatic server recovery on ECONNREFUSED errors.
222
- * Recovery is only attempted in local server mode (no baseUrl, port defined).
223
- */
224
- private executeWithRecovery;
225
- /**
226
- * Dispose the parser instance.
227
- * - Sets the internal client to null
228
- * - If a local docling server was started (no baseUrl), kills the process on the configured port
229
- */
230
- dispose(): Promise<void>;
231
- }
232
-
233
- /**
234
- * Error thrown when both original PDF conversion and image PDF fallback fail.
235
- * Contains both errors for debugging purposes.
236
- */
237
- declare class ImagePdfFallbackError extends Error {
238
- readonly originalError: Error;
239
- readonly fallbackError: Error;
240
- readonly name = "ImagePdfFallbackError";
241
- constructor(originalError: Error, fallbackError: Error);
242
- }
243
-
244
- /**
245
- * Error thrown when the uploaded PDF does not appear to be
246
- * an archaeological investigation report.
247
- */
248
- declare class InvalidDocumentTypeError extends Error {
249
- readonly reason: string;
250
- readonly name = "InvalidDocumentTypeError";
251
- readonly code = "INVALID_DOCUMENT_TYPE";
252
- constructor(reason: string);
253
- }
254
-
255
- /**
256
- * Intermediate format produced by VLM page-by-page processing.
257
- * Intentionally kept simple so VLM prompts stay short and accurate.
258
- * The DoclingDocumentAssembler converts these into a full DoclingDocument.
259
- */
260
- /** Allowed element types matching DoclingDocument text labels */
261
- declare const VLM_ELEMENT_TYPES: readonly ["text", "section_header", "caption", "footnote", "page_header", "page_footer", "list_item", "picture", "table"];
262
- type VlmElementType = (typeof VLM_ELEMENT_TYPES)[number];
263
- /**
264
- * Normalized bounding box with coordinates in the range 0.0 to 1.0,
265
- * using top-left origin (standard image coordinates).
266
- */
267
- interface VlmBBox {
268
- /** Left edge (0.0 = left boundary) */
269
- l: number;
270
- /** Top edge (0.0 = top boundary) */
271
- t: number;
272
- /** Right edge (1.0 = right boundary) */
273
- r: number;
274
- /** Bottom edge (1.0 = bottom boundary) */
275
- b: number;
276
- }
277
- /** A single content element detected on a page by VLM */
278
- interface VlmPageElement {
279
- /** Element type */
280
- type: VlmElementType;
281
- /** Text content (empty string for picture elements) */
282
- content: string;
283
- /** Heading depth for section_header (1 = top-level) */
284
- level?: number;
285
- /** List marker for list_item (e.g., "1)", "a.", "\u2022") */
286
- marker?: string;
287
- /** Reading order within the page (top-to-bottom, left-to-right) */
288
- order: number;
289
- /**
290
- * Bounding box in normalized coordinates (0.0-1.0, top-left origin).
291
- * - Text elements: optional (included in prov if present)
292
- * - Picture elements: **required** (used for image cropping)
293
- */
294
- bbox?: VlmBBox;
295
- }
296
- /** Types of quality issues detected in VLM responses */
297
- declare const VLM_QUALITY_ISSUE_TYPES: readonly ["placeholder_text", "script_anomaly", "meta_description", "repetitive_pattern"];
298
- type VlmQualityIssueType = (typeof VLM_QUALITY_ISSUE_TYPES)[number];
299
- /** Quality metadata for a processed page */
300
- interface VlmPageQuality {
301
- /** Whether the page passed quality validation (after possible retry) */
302
- isValid: boolean;
303
- /** Whether a quality retry was performed for this page */
304
- retried: boolean;
305
- /** Issue types detected (may persist even after retry) */
306
- issueTypes: VlmQualityIssueType[];
307
- }
308
-
309
- /** A single quality issue found during validation */
310
- interface VlmQualityIssue {
311
- /** Type of issue detected */
312
- type: VlmQualityIssueType;
313
- /** Human-readable description of the issue */
314
- message: string;
315
- /** Element reading-order indices that triggered the issue */
316
- affectedElements: number[];
317
- }
318
- /** Result of VLM response quality validation */
319
- interface VlmValidationResult {
320
- /** Whether the response passes quality validation */
321
- isValid: boolean;
322
- /** List of quality issues found (empty if valid) */
323
- issues: VlmQualityIssue[];
324
- }
325
- /**
326
- * Lightweight, stateless validator for VLM page extraction responses.
327
- *
328
- * Detects four categories of hallucination without any additional VLM calls:
329
- * 1. Placeholder text (Lorem ipsum and variants)
330
- * 2. Script anomaly (expected Korean but got Latin-only text)
331
- * 3. Meta description (VLM described the image instead of transcribing text)
332
- * 4. Repetitive pattern (repeated character patterns like `: : : : :`)
333
- */
334
- declare class VlmResponseValidator {
335
- /**
336
- * Validate VLM page result quality.
337
- *
338
- * @param elements - Extracted page elements to validate
339
- * @param documentLanguages - BCP 47 language tags (e.g., ['ko-KR', 'en-US'])
340
- * @returns Validation result with issues list
341
- */
342
- static validate(elements: VlmPageElement[], documentLanguages?: string[]): VlmValidationResult;
343
- /**
344
- * Detect known placeholder / filler text in elements.
345
- */
346
- private static detectPlaceholderText;
347
- /**
348
- * Detect script anomaly: expected Korean content but found mostly Latin text.
349
- * Counts Hangul + CJK characters and flags if the ratio is below threshold.
350
- */
351
- private static detectScriptAnomaly;
352
- /**
353
- * Detect meta description: VLM described the image/resolution instead
354
- * of transcribing actual text content.
355
- */
356
- private static detectMetaDescription;
357
- /**
358
- * Detect repetitive character patterns (e.g., `: : : : :` or `= = = = =`).
359
- * Flags when the same character repeats with spaces 5+ times and the
360
- * repetitive portion exceeds 30% of total content.
361
- */
362
- private static detectRepetitivePattern;
363
- }
364
-
365
- export { type ConversionCompleteCallback, ImagePdfFallbackError, InvalidDocumentTypeError, type NormalizedPDFCorrectionOptions, type PDFConvertOptions, type PDFCorrectionConcurrencyOptions, type PDFCorrectionMaxRetriesOptions, type PDFCorrectionModelOptions, type PDFCorrectionOptions, type PDFCorrectionPageGateOptions, PDFParser, PDF_CORRECTION_DEFAULTS, type ReviewAssistanceTaskId, type VlmPageQuality, type VlmQualityIssue, type VlmQualityIssueType, VlmResponseValidator, type VlmValidationResult };