@heripo/document-processor 0.1.39 → 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,1702 +0,0 @@
1
- import { LoggerMethods } from '@heripo/logger';
2
- import { TokenUsageReport, DoclingDocument, PageRange, ProcessedDocumentSource, DocumentProcessResult, Caption, DoclingTextItem, DoclingPictureItem, DoclingTableItem, DoclingGroupItem, ProcessedImage, ProcessedTable, ProcessedFootnote, Chapter, DoclingReference } from '@heripo/model';
3
- import { LanguageModel } from 'ai';
4
- import { LLMTokenUsageAggregator, ExtendedTokenUsage } from '@heripo/shared';
5
- import { z } from 'zod';
6
-
7
- /**
8
- * Table of Contents Entry
9
- *
10
- * Tree node representing the table of contents structure of a document.
11
- */
12
- interface TocEntry {
13
- /**
14
- * Chapter title
15
- */
16
- title: string;
17
- /**
18
- * Hierarchy depth (1, 2, 3...)
19
- */
20
- level: number;
21
- /**
22
- * Starting page number
23
- */
24
- pageNo: number;
25
- /**
26
- * Docling references for source nodes used to derive this TOC entry
27
- */
28
- sourceRefs?: string[];
29
- /**
30
- * Child TOC entries
31
- */
32
- children?: TocEntry[];
33
- }
34
- /**
35
- * TOC Area Search Result
36
- */
37
- interface TocAreaResult {
38
- /**
39
- * Group or table item references corresponding to the table of contents
40
- */
41
- itemRefs: string[];
42
- /**
43
- * TOC start page
44
- */
45
- startPage: number;
46
- /**
47
- * TOC end page
48
- */
49
- endPage: number;
50
- }
51
- /**
52
- * Page Size Information
53
- */
54
- interface PageSizeGroup {
55
- /**
56
- * Size identifier (width x height)
57
- */
58
- sizeKey: string;
59
- /**
60
- * PDF page numbers with this size specification
61
- */
62
- pageNos: number[];
63
- }
64
-
65
- declare const PROCESSED_DOCUMENT_SCHEMA_VERSION = "processed-document.v2";
66
- type SourceRefValidationMode = 'off' | 'warn' | 'error';
67
- /**
68
- * DocumentProcessor Options
69
- */
70
- interface DocumentProcessorOptions {
71
- /**
72
- * Logger instance
73
- */
74
- logger: LoggerMethods;
75
- /**
76
- * Fallback model - used as fallback when component-specific models are not provided or fail.
77
- * This is the only required model. Should be set to a frontier model (e.g., Claude Opus 4.6, GPT-5.2)
78
- * to ensure reliable fallback performance across all components.
79
- */
80
- fallbackModel: LanguageModel;
81
- /**
82
- * Model for PageRangeParser - extracts page numbers from page images.
83
- * Requires vision capabilities. Falls back to 'fallbackModel' if not provided.
84
- */
85
- pageRangeParserModel?: LanguageModel;
86
- /**
87
- * Model for TocExtractor - extracts structured TOC from Markdown representation.
88
- * Falls back to 'fallbackModel' if not provided.
89
- */
90
- tocExtractorModel?: LanguageModel;
91
- /**
92
- * Model for validators (TOC content validation, caption validation).
93
- * Falls back to 'fallbackModel' if not provided.
94
- */
95
- validatorModel?: LanguageModel;
96
- /**
97
- * Model for VisionTocExtractor - extracts TOC directly from page images.
98
- * Requires vision capabilities. Falls back to 'fallbackModel' if not provided.
99
- */
100
- visionTocExtractorModel?: LanguageModel;
101
- /**
102
- * Model for CaptionParser - extracts caption prefix and number from image/table captions.
103
- * Falls back to 'fallbackModel' if not provided.
104
- */
105
- captionParserModel?: LanguageModel;
106
- /**
107
- * Batch size for TextCleaner text normalization (synchronous processing)
108
- */
109
- textCleanerBatchSize: number;
110
- /**
111
- * Batch size for CaptionParser LLM parsing (async parallel processing)
112
- */
113
- captionParserBatchSize: number;
114
- /**
115
- * Batch size for CaptionValidator LLM validation (async parallel processing)
116
- */
117
- captionValidatorBatchSize: number;
118
- /**
119
- * Maximum retry count (default: 3)
120
- */
121
- maxRetries?: number;
122
- /**
123
- * Maximum retry count for TOC validation correction feedback (default: 3)
124
- */
125
- maxValidationRetries?: number;
126
- /**
127
- * Enable fallback retry mechanism - automatically retries with fallback model on failure (default: false)
128
- * Set to true to enable automatic fallback retry with fallback model on component-specific model errors
129
- */
130
- enableFallbackRetry?: boolean;
131
- /**
132
- * Abort signal for cancellation support.
133
- * When aborted, processing stops at the next checkpoint between stages.
134
- */
135
- abortSignal?: AbortSignal;
136
- /**
137
- * Callback fired after each major processing phase completes.
138
- * Receives the current cumulative token usage report.
139
- * Useful for real-time token usage monitoring during processing.
140
- */
141
- onTokenUsage?: (report: TokenUsageReport) => void;
142
- }
143
- /**
144
- * Per-document processing inputs.
145
- */
146
- interface DocumentProcessorProcessOptions {
147
- /**
148
- * Precomputed PDF page number to actual document page range mapping.
149
- * When provided, automatic PageRangeParser execution is skipped.
150
- */
151
- pageRangeMap?: Record<number, PageRange>;
152
- /**
153
- * Precomputed table of contents entries.
154
- * When provided, automatic TOC extraction pipeline execution is skipped.
155
- */
156
- tocEntries?: TocEntry[];
157
- /**
158
- * Caller-supplied source artifact metadata for the Docling input.
159
- */
160
- source?: ProcessedDocumentSource;
161
- /**
162
- * Validate generated source references against the input Docling document.
163
- *
164
- * When true, missing references are treated as errors unless
165
- * `sourceRefValidationMode` is provided.
166
- *
167
- * @experimental
168
- */
169
- validateSourceRefs?: boolean;
170
- /**
171
- * Controls how missing generated source references are handled.
172
- *
173
- * Explicit mode takes precedence over `validateSourceRefs`. Use `warn` for
174
- * rollout visibility without failing processing, and `error` for strict
175
- * provenance checks.
176
- *
177
- * @default 'off'
178
- * @experimental
179
- */
180
- sourceRefValidationMode?: SourceRefValidationMode;
181
- }
182
- /**
183
- * DocumentProcessor
184
- *
185
- * Main class that converts DoclingDocument to ProcessedDocument.
186
- *
187
- * ## Conversion Process
188
- *
189
- * 1. Initialize RefResolver - indexing for $ref resolution
190
- * 2. Initialize IdGenerator - unique ID generator
191
- * 3. Text filtering and PageRangeMap generation (visionModel)
192
- * 4. TOC extraction (model) - core step
193
- * 5. Parallel processing block:
194
- * - Images conversion (caption extraction)
195
- * - Tables conversion (excluding TOC tables)
196
- * 6. Chapters conversion (based on TOC)
197
- * 7. Assemble ProcessedDocument
198
- *
199
- * @example
200
- * ```typescript
201
- * import { openai } from '@ai-sdk/openai';
202
- * import { anthropic } from '@ai-sdk/anthropic';
203
- * import { DocumentProcessor } from '@heripo/document-processor';
204
- * import { getLogger } from '@heripo/logger';
205
- *
206
- * const logger = getLogger();
207
- *
208
- * // Basic usage - all components use the fallback model
209
- * const processor = new DocumentProcessor({
210
- * logger,
211
- * fallbackModel: anthropic('claude-opus-4-5-20251101'), // Frontier model for reliable fallback
212
- * });
213
- *
214
- * // Advanced usage - component-specific models with frontier fallback
215
- * const advancedProcessor = new DocumentProcessor({
216
- * logger,
217
- * fallbackModel: anthropic('claude-opus-4-5-20251101'), // Frontier model for fallback
218
- * pageRangeParserModel: openai('gpt-5.2'), // Vision-capable
219
- * tocExtractorModel: openai('gpt-5-mini'), // Structured output
220
- * validatorModel: openai('gpt-5.2'), // Validation (TOC + caption)
221
- * visionTocExtractorModel: openai('gpt-5.1'), // Vision-capable
222
- * captionParserModel: openai('gpt-5-mini'),
223
- * textCleanerBatchSize: 20, // Sync text processing
224
- * captionParserBatchSize: 10, // LLM caption parsing
225
- * captionValidatorBatchSize: 10, // LLM caption validation
226
- * maxRetries: 3,
227
- * maxValidationRetries: 3,
228
- * });
229
- *
230
- * const result = await processor.process(
231
- * doclingDoc,
232
- * 'report-001',
233
- * artifactDir
234
- * );
235
- * ```
236
- */
237
- declare class DocumentProcessor {
238
- private readonly logger;
239
- private readonly fallbackModel;
240
- private readonly pageRangeParserModel;
241
- private readonly tocExtractorModel;
242
- private readonly validatorModel;
243
- private readonly visionTocExtractorModel;
244
- private readonly captionParserModel;
245
- private readonly textCleanerBatchSize;
246
- private readonly captionParserBatchSize;
247
- private readonly captionValidatorBatchSize;
248
- private readonly maxRetries;
249
- private readonly maxValidationRetries;
250
- private readonly enableFallbackRetry;
251
- private readonly abortSignal?;
252
- private readonly onTokenUsage?;
253
- private idGenerator;
254
- private refResolver?;
255
- private pageRangeParser?;
256
- private tocFinder?;
257
- private tocExtractor?;
258
- private tocContentValidator?;
259
- private captionValidator?;
260
- private visionTocExtractor?;
261
- private captionParser?;
262
- private chapterConverter?;
263
- private resourceConverter?;
264
- private tocExtractionPipeline?;
265
- private captionProcessingPipeline?;
266
- private readonly usageAggregator;
267
- constructor(options: DocumentProcessorOptions);
268
- /**
269
- * Emit current token usage report via callback
270
- *
271
- * Calls the onTokenUsage callback with the current cumulative report
272
- * from the usage aggregator. Safe to call even if no callback is set.
273
- */
274
- private emitTokenUsage;
275
- /**
276
- * Check if abort has been requested and throw error if so
277
- *
278
- * @throws {Error} with name 'AbortError' if aborted
279
- */
280
- private checkAborted;
281
- /**
282
- * Converts DoclingDocument to ProcessedDocument with token usage tracking.
283
- *
284
- * Conversion process:
285
- * 1. Initialize processors and resolvers
286
- * 2. Normalize and filter texts
287
- * 3. Clean texts and resolve page ranges
288
- * 4. Extract table of contents
289
- * 5. Convert images and tables (parallel)
290
- * 6. Convert chapters and link resources
291
- * 7. Assemble final ProcessedDocument
292
- * 8. Collect and report token usage
293
- *
294
- * @param doclingDoc - Original document extracted from Docling SDK
295
- * @param reportId - Report unique identifier
296
- * @param artifactDir - Directory containing parser artifacts such as images/, pages/, and result.json
297
- * @param processOptions - Per-document processing inputs such as manually verified page range mappings and TOC entries
298
- * @returns Document processing result with ProcessedDocument and token usage report
299
- *
300
- * @throws {TocExtractError} When TOC extraction fails
301
- * @throws {PageRangeParseError} When page range parsing fails
302
- * @throws {ConversionError} When error occurs during conversion
303
- */
304
- process(doclingDoc: DoclingDocument, reportId: string, artifactDir: string, processOptions?: DocumentProcessorProcessOptions): Promise<DocumentProcessResult>;
305
- /**
306
- * Initialize all processors and resolvers
307
- *
308
- * Sets up RefResolver, PageRangeParser, TocFinder, and TocExtractor
309
- */
310
- private initializeProcessors;
311
- /**
312
- * Normalize and filter texts using TextCleaner
313
- *
314
- * Performs basic text normalization (unicode, whitespace, punctuation)
315
- * and filters out invalid texts (empty, numbers-only, etc.)
316
- */
317
- private normalizeAndFilterTexts;
318
- /**
319
- * Parse page ranges using Vision LLM
320
- *
321
- * Extracts actual page numbers from page images and creates mapping.
322
- * Token usage is automatically tracked by PageRangeParser into the shared aggregator.
323
- */
324
- private parsePageRanges;
325
- private resolveSourceRefValidationMode;
326
- private validateProcessedDocumentSourceRefs;
327
- private collectMissingSourceRefs;
328
- /**
329
- * Assemble the final ProcessedDocument
330
- *
331
- * Creates the ProcessedDocument structure with all converted components
332
- */
333
- private assembleProcessedDocument;
334
- /**
335
- * Convert chapters and link resources
336
- *
337
- * Generates chapters based on TOC and links images/tables/footnotes using ChapterConverter.
338
- * Throws TocNotFoundError if TOC entries are empty (defensive assertion).
339
- */
340
- private convertChapters;
341
- }
342
-
343
- /**
344
- * Base options for all LLM-based components
345
- */
346
- interface BaseLLMComponentOptions {
347
- /**
348
- * Maximum retry count for LLM API (default: 3)
349
- */
350
- maxRetries?: number;
351
- /**
352
- * Temperature for LLM generation (default: 0)
353
- */
354
- temperature?: number;
355
- /**
356
- * Abort signal for cancellation support
357
- */
358
- abortSignal?: AbortSignal;
359
- }
360
- /**
361
- * Abstract base class for all LLM-based components
362
- *
363
- * Provides common functionality:
364
- * - Consistent logging with component name prefix
365
- * - Token usage tracking via optional aggregator
366
- * - Standard configuration (model, fallback, retries, temperature)
367
- *
368
- * Subclasses must implement buildSystemPrompt() and buildUserPrompt().
369
- */
370
- declare abstract class BaseLLMComponent {
371
- protected readonly logger: LoggerMethods;
372
- protected readonly model: LanguageModel;
373
- protected readonly fallbackModel?: LanguageModel;
374
- protected readonly maxRetries: number;
375
- protected readonly temperature: number;
376
- protected readonly componentName: string;
377
- protected readonly aggregator?: LLMTokenUsageAggregator;
378
- protected readonly abortSignal?: AbortSignal;
379
- /**
380
- * Constructor for BaseLLMComponent
381
- *
382
- * @param logger - Logger instance for logging
383
- * @param model - Primary language model for LLM calls
384
- * @param componentName - Name of the component for logging (e.g., "TocExtractor")
385
- * @param options - Optional configuration (maxRetries, temperature)
386
- * @param fallbackModel - Optional fallback model for retry on failure
387
- * @param aggregator - Optional token usage aggregator for tracking LLM calls
388
- */
389
- constructor(logger: LoggerMethods, model: LanguageModel, componentName: string, options?: BaseLLMComponentOptions, fallbackModel?: LanguageModel, aggregator?: LLMTokenUsageAggregator);
390
- /**
391
- * Log a message with consistent component name prefix
392
- *
393
- * @param level - Log level ('info', 'warn', 'error')
394
- * @param message - Message to log (without prefix)
395
- * @param args - Additional arguments to pass to logger
396
- */
397
- protected log(level: 'info' | 'warn' | 'error', message: string, ...args: unknown[]): void;
398
- /**
399
- * Track token usage to aggregator if available
400
- *
401
- * @param usage - Token usage information to track
402
- */
403
- protected trackUsage(usage: ExtendedTokenUsage): void;
404
- /**
405
- * Create an empty usage record for edge cases (e.g., empty input)
406
- *
407
- * @param phase - Phase name for the usage record
408
- * @returns Empty ExtendedTokenUsage object
409
- */
410
- protected createEmptyUsage(phase: string): ExtendedTokenUsage;
411
- /**
412
- * Build system prompt for LLM call
413
- *
414
- * Subclasses must implement this to provide component-specific system prompts.
415
- */
416
- protected abstract buildSystemPrompt(...args: unknown[]): string;
417
- /**
418
- * Build user prompt for LLM call
419
- *
420
- * Subclasses must implement this to construct prompts from input data.
421
- */
422
- protected abstract buildUserPrompt(...args: unknown[]): string;
423
- }
424
-
425
- /**
426
- * Abstract base class for text-based LLM components
427
- *
428
- * Extends BaseLLMComponent with helper method for text-based LLM calls
429
- * using LLMCaller.call() (non-vision).
430
- *
431
- * Subclasses: TocExtractor, CaptionParser, BaseValidator
432
- */
433
- declare abstract class TextLLMComponent extends BaseLLMComponent {
434
- constructor(logger: LoggerMethods, model: LanguageModel, componentName: string, options?: BaseLLMComponentOptions, fallbackModel?: LanguageModel, aggregator?: LLMTokenUsageAggregator);
435
- /**
436
- * Call LLM with text-based prompts using LLMCaller.call()
437
- *
438
- * @template TSchema - Zod schema type for response validation
439
- * @param schema - Zod schema for response validation
440
- * @param systemPrompt - System prompt for LLM
441
- * @param userPrompt - User prompt for LLM
442
- * @param phase - Phase name for tracking (e.g., 'extraction', 'validation')
443
- * @returns Promise with parsed object and usage information
444
- */
445
- protected callTextLLM<TSchema extends z.ZodType>(schema: TSchema, systemPrompt: string, userPrompt: string, phase: string): Promise<{
446
- output: z.infer<TSchema>;
447
- usage: ExtendedTokenUsage;
448
- }>;
449
- }
450
-
451
- /**
452
- * Options for VisionLLMComponent
453
- */
454
- interface VisionLLMComponentOptions extends BaseLLMComponentOptions {
455
- }
456
- /**
457
- * Image content structure for vision LLM messages
458
- */
459
- interface ImageContent {
460
- type: 'image';
461
- image: Uint8Array;
462
- mediaType: string;
463
- }
464
- /**
465
- * Abstract base class for vision-based LLM components
466
- *
467
- * Extends BaseLLMComponent with helper methods for vision-based LLM calls
468
- * using LLMCaller.callVision().
469
- *
470
- * Subclasses: PageRangeParser, VisionTocExtractor
471
- */
472
- declare abstract class VisionLLMComponent extends BaseLLMComponent {
473
- protected readonly artifactDir: string;
474
- constructor(logger: LoggerMethods, model: LanguageModel, componentName: string, artifactDir: string, options?: VisionLLMComponentOptions, fallbackModel?: LanguageModel, aggregator?: LLMTokenUsageAggregator);
475
- /**
476
- * Call LLM with vision capabilities using LLMCaller.callVision()
477
- *
478
- * @template TSchema - Zod schema type for response validation
479
- * @param schema - Zod schema for response validation
480
- * @param messages - Messages array including image content
481
- * @param phase - Phase name for tracking (e.g., 'extraction', 'sampling')
482
- * @returns Promise with parsed object and usage information
483
- */
484
- protected callVisionLLM<TSchema extends z.ZodType>(schema: TSchema, messages: Array<{
485
- role: 'user' | 'assistant';
486
- content: unknown[] | string;
487
- }>, phase: string): Promise<{
488
- output: z.infer<TSchema>;
489
- usage: ExtendedTokenUsage;
490
- }>;
491
- /**
492
- * Build image content object for vision LLM messages
493
- *
494
- * @param imagePath - Path to the image file (relative to artifactDir or absolute)
495
- * @param mimeType - MIME type of the image (default: 'image/png')
496
- * @returns ImageContent object for LLM message
497
- */
498
- protected buildImageContent(imagePath: string, mimeType?: string): ImageContent;
499
- }
500
-
501
- /**
502
- * CaptionParser options
503
- */
504
- interface CaptionParserOptions extends BaseLLMComponentOptions {
505
- /**
506
- * Custom component name for token usage tracking.
507
- * Defaults to 'CaptionParser'.
508
- */
509
- componentName?: string;
510
- }
511
- /**
512
- * CaptionParser
513
- *
514
- * Extracts caption prefix and number from image/table captions using LLM.
515
- * Preserves original spacing from input text.
516
- * Extends TextLLMComponent for standardized LLM call handling.
517
- *
518
- * ## Algorithm
519
- *
520
- * 1. Collect caption texts
521
- * 2. Split into batches based on batchSize
522
- * 3. For each batch: call LLM to extract caption prefix + number
523
- * 4. Flatten results and return
524
- */
525
- declare class CaptionParser extends TextLLMComponent {
526
- constructor(logger: LoggerMethods, model: LanguageModel, options?: CaptionParserOptions, fallbackModel?: LanguageModel, aggregator?: LLMTokenUsageAggregator);
527
- /**
528
- * Parse batch of captions
529
- *
530
- * @param captions - Array of caption full texts
531
- * @param batchSize - Batch size for processing. Set to 0 for sequential processing without batching.
532
- * @param overrideModel - Optional model to use instead of the default model
533
- * @returns Array of Caption objects with num extracted (maintains original order)
534
- */
535
- parseBatch(captions: string[], batchSize: number, overrideModel?: LanguageModel): Promise<Caption[]>;
536
- /**
537
- * Internal: Parse batch of captions using LLM
538
- *
539
- * @param captions - Batch of caption texts with original indices
540
- * @param model - Effective model to use
541
- * @returns Array of Caption objects indexed correctly
542
- */
543
- private parseBatchInternal;
544
- /**
545
- * Extract and normalize caption number from full text
546
- *
547
- * Finds the extracted num pattern in the full text and extracts it
548
- * with original casing. Handles case-insensitive matching.
549
- *
550
- * @param fullText - The full caption text
551
- * @param extractedNum - The num extracted by LLM (may have different casing)
552
- * @returns Normalized num or undefined if no match
553
- */
554
- private extractNumFromFullText;
555
- /**
556
- * Build system prompt for caption parsing
557
- *
558
- * @param mode - 'batch' for multiple captions, 'single' for single caption
559
- */
560
- protected buildSystemPrompt(mode?: 'batch' | 'single'): string;
561
- /**
562
- * Build user prompt for caption parsing
563
- */
564
- protected buildUserPrompt(captions: Array<{
565
- index: number;
566
- text: string;
567
- }>): string;
568
- /**
569
- * Build user prompt for single caption parsing
570
- */
571
- private buildUserPromptSingle;
572
- }
573
- /**
574
- * Error thrown when caption parsing fails
575
- */
576
- declare class CaptionParseError extends Error {
577
- constructor(message: string, options?: ErrorOptions);
578
- }
579
-
580
- /**
581
- * PageRangeParseError
582
- *
583
- * Custom error thrown when page range parsing fails.
584
- */
585
- declare class PageRangeParseError extends Error {
586
- constructor(message: string, options?: ErrorOptions);
587
- /**
588
- * Extract error message from unknown error type
589
- */
590
- static getErrorMessage(error: unknown): string;
591
- /**
592
- * Create PageRangeParseError from unknown error with context
593
- */
594
- static fromError(context: string, error: unknown): PageRangeParseError;
595
- }
596
-
597
- /**
598
- * Pattern types for page number sequences
599
- */
600
- declare enum PagePattern {
601
- /** Simple increment: [1, 2, 3, 4, ...] */
602
- SIMPLE_INCREMENT = "simple_increment",
603
- /** Double-sided scan: [1-2, 3-4, 5-6, ...] */
604
- DOUBLE_SIDED = "double_sided",
605
- /** Offset pattern: PDF page != actual page (consistent offset) */
606
- OFFSET = "offset",
607
- /** No clear pattern detected */
608
- UNKNOWN = "unknown"
609
- }
610
- /**
611
- * PageRangeParser
612
- *
613
- * Extracts actual document page numbers from PDF page images using Vision LLM.
614
- * Uses random sampling + pattern detection to minimize LLM calls.
615
- * Extends VisionLLMComponent for standardized vision LLM call handling.
616
- *
617
- * ## Algorithm
618
- *
619
- * 1. Group pages by size (consecutive pages with same dimensions)
620
- * 2. For each group:
621
- * - If ≤3 pages: send all to LLM at once
622
- * - If >3 pages: random sample 3 pages, detect pattern, apply to all
623
- * 3. Post-process: handle drops, normalize negatives, backfill failed pages
624
- */
625
- declare class PageRangeParser extends VisionLLMComponent {
626
- private readonly SAMPLE_SIZE;
627
- private readonly MAX_PATTERN_RETRIES;
628
- private readonly SIZE_TOLERANCE;
629
- constructor(logger: LoggerMethods, model: LanguageModel, artifactDir: string, maxRetries?: number, fallbackModel?: LanguageModel, aggregator?: LLMTokenUsageAggregator, abortSignal?: AbortSignal);
630
- /**
631
- * Main parse method
632
- *
633
- * Extracts page range mapping from DoclingDocument using Vision LLM.
634
- * Automatically tracks token usage in the aggregator if one was provided.
635
- *
636
- * @param doclingDoc - DoclingDocument to extract page ranges from
637
- * @returns Object with page range mapping and token usage information
638
- */
639
- parse(doclingDoc: DoclingDocument): Promise<{
640
- pageRangeMap: Record<number, PageRange>;
641
- usage: ExtendedTokenUsage[];
642
- }>;
643
- /**
644
- * Extract pages array from DoclingDocument
645
- */
646
- private extractPages;
647
- /**
648
- * Analyze page sizes and group consecutive pages with same dimensions
649
- */
650
- private analyzeSizes;
651
- /**
652
- * Create size key with tolerance for floating point comparison
653
- */
654
- private createSizeKey;
655
- /**
656
- * Process a single size group
657
- */
658
- private processGroup;
659
- /**
660
- * Select random samples from page numbers
661
- */
662
- private selectRandomSamples;
663
- /**
664
- * Extract page numbers from multiple pages in a single LLM call
665
- */
666
- private extractMultiplePages;
667
- /**
668
- * Detect pattern from sample results
669
- */
670
- private detectPattern;
671
- /**
672
- * Apply detected pattern to generate page range map
673
- */
674
- private applyPattern;
675
- /**
676
- * Convert sample results to page range map (for small groups)
677
- */
678
- private samplesToMap;
679
- /**
680
- * Post-process the page range map
681
- */
682
- private postProcess;
683
- /**
684
- * Detect and handle outlier page numbers at the beginning of document
685
- *
686
- * When early PDF pages have abnormally high page numbers compared to
687
- * subsequent pages (e.g., PDF 1-9 = 75-83, but PDF 10+ = 2,3,4...),
688
- * the LLM likely misread figure/photo numbers as page numbers.
689
- *
690
- * Detection: If page numbers at the beginning are significantly higher
691
- * than subsequent pages (which follow a normal pattern), mark them as failed.
692
- */
693
- private detectAndHandleOutliers;
694
- /**
695
- * Find the start index of a "normal" sequence in the page range map
696
- *
697
- * A normal sequence is defined as at least 3 consecutive PDF pages where:
698
- * - Page numbers are increasing (for single-page) or increasing by 2 (for double-sided)
699
- * - The pattern is consistent
700
- *
701
- * Returns the index in pdfPages array, or null if not found.
702
- */
703
- private findNormalSequenceStart;
704
- /**
705
- * Check if a page range represents a double-sided scan
706
- */
707
- private isDoubleSidedRange;
708
- /**
709
- * Detect and handle page number drops
710
- *
711
- * When page numbers suddenly decrease (e.g., 8,9 -> 3,4),
712
- * recalculate previous pages based on the drop point.
713
- */
714
- private detectAndHandleDrops;
715
- /**
716
- * Normalize negative page numbers to 0
717
- */
718
- private normalizeNegatives;
719
- /**
720
- * Backfill pages marked with 0 using detected pattern
721
- */
722
- private backfillFailedPages;
723
- /**
724
- * Build system prompt for Vision LLM
725
- */
726
- protected buildSystemPrompt(): string;
727
- /**
728
- * Build user prompt for Vision LLM
729
- */
730
- protected buildUserPrompt(pageNos: number[]): string;
731
- }
732
-
733
- /**
734
- * Single validation issue detected during TOC validation
735
- */
736
- interface TocValidationIssue {
737
- /**
738
- * Issue code (V001, V002, etc.)
739
- */
740
- code: string;
741
- /**
742
- * Human-readable error message
743
- */
744
- message: string;
745
- /**
746
- * Path to the problematic entry (e.g., "[0].children[2]")
747
- */
748
- path: string;
749
- /**
750
- * The problematic entry
751
- */
752
- entry: TocEntry;
753
- }
754
- /**
755
- * TocExtractError
756
- *
757
- * Base error class for TOC extraction failures.
758
- */
759
- declare class TocExtractError extends Error {
760
- constructor(message: string, options?: ErrorOptions);
761
- /**
762
- * Extract error message from unknown error type
763
- */
764
- static getErrorMessage(error: unknown): string;
765
- /**
766
- * Create TocExtractError from unknown error with context
767
- */
768
- static fromError(context: string, error: unknown): TocExtractError;
769
- }
770
- /**
771
- * TocNotFoundError
772
- *
773
- * Error thrown when TOC area cannot be found in the document.
774
- */
775
- declare class TocNotFoundError extends TocExtractError {
776
- constructor(message?: string);
777
- }
778
- /**
779
- * TocParseError
780
- *
781
- * Error thrown when LLM fails to parse TOC structure.
782
- */
783
- declare class TocParseError extends TocExtractError {
784
- constructor(message: string, options?: ErrorOptions);
785
- }
786
-
787
- /**
788
- * Validation options for TocValidator
789
- */
790
- interface TocValidationOptions {
791
- /**
792
- * Total page count of the document (for range validation)
793
- * If not provided, page range upper bound validation is skipped
794
- */
795
- totalPages?: number;
796
- /**
797
- * Maximum allowed title length (default: 200)
798
- */
799
- maxTitleLength?: number;
800
- /**
801
- * Maximum ratio of the first entry's page to total pages (default: 0.3)
802
- * Used for V007 completeness check - if the first level-1 entry
803
- * starts beyond max(50, totalPages * ratio), the TOC may be incomplete.
804
- */
805
- maxFirstEntryPageRatio?: number;
806
- }
807
-
808
- /**
809
- * Resolves $ref references in DoclingDocument to actual objects.
810
- *
811
- * DoclingDocument uses JSON references (e.g., "#/texts/0") to link nodes.
812
- * This class builds an index for quick lookups of texts, pictures, tables, and groups.
813
- */
814
- declare class RefResolver {
815
- private readonly logger;
816
- private readonly textMap;
817
- private readonly pictureMap;
818
- private readonly tableMap;
819
- private readonly groupMap;
820
- constructor(logger: LoggerMethods, doc: DoclingDocument);
821
- /**
822
- * Build an index mapping self_ref to the actual item
823
- */
824
- private buildIndex;
825
- /**
826
- * Check whether a Docling self reference exists in the indexed document.
827
- */
828
- hasRef(ref: string): boolean;
829
- /**
830
- * Assert that a Docling self reference exists in the indexed document.
831
- */
832
- assertRef(ref: string, context: string): void;
833
- /**
834
- * Assert that every Docling self reference exists in the indexed document.
835
- */
836
- assertRefs(refs: string[], context: string): void;
837
- /**
838
- * Resolve a $ref string to the actual item
839
- * @param ref - Reference string (e.g., "#/texts/0")
840
- * @returns The resolved item, or null if not found
841
- */
842
- resolve(ref: string): DoclingTextItem | DoclingPictureItem | DoclingTableItem | DoclingGroupItem | null;
843
- /**
844
- * Resolve a text reference
845
- * @param ref - Reference string (e.g., "#/texts/0")
846
- * @returns The resolved text item, or null if not found
847
- */
848
- resolveText(ref: string): DoclingTextItem | null;
849
- /**
850
- * Resolve a picture reference
851
- * @param ref - Reference string (e.g., "#/pictures/0")
852
- * @returns The resolved picture item, or null if not found
853
- */
854
- resolvePicture(ref: string): DoclingPictureItem | null;
855
- /**
856
- * Resolve a table reference
857
- * @param ref - Reference string (e.g., "#/tables/0")
858
- * @returns The resolved table item, or null if not found
859
- */
860
- resolveTable(ref: string): DoclingTableItem | null;
861
- /**
862
- * Resolve a group reference
863
- * @param ref - Reference string (e.g., "#/groups/0")
864
- * @returns The resolved group item, or null if not found
865
- */
866
- resolveGroup(ref: string): DoclingGroupItem | null;
867
- /**
868
- * Resolve multiple references at once
869
- * @param refs - Array of reference objects with $ref property
870
- * @returns Array of resolved items (null for unresolved references)
871
- */
872
- resolveMany(refs: Array<{
873
- $ref: string;
874
- }>): Array<DoclingTextItem | DoclingPictureItem | DoclingTableItem | DoclingGroupItem | null>;
875
- }
876
-
877
- /**
878
- * Generates sequential IDs for different types of items.
879
- *
880
- * IDs are formatted as: `{prefix}-{number}` where number is zero-padded to 3 digits.
881
- * - Chapters: ch-001, ch-002, ...
882
- * - Images: img-001, img-002, ...
883
- * - Tables: tbl-001, tbl-002, ...
884
- * - Text blocks: txt-001, txt-002, ...
885
- *
886
- * Each type maintains its own independent counter.
887
- */
888
- declare class IdGenerator {
889
- private chapterCounter;
890
- private imageCounter;
891
- private tableCounter;
892
- private footnoteCounter;
893
- private textBlockCounter;
894
- /**
895
- * Generate a chapter ID
896
- * @returns A chapter ID in the format "ch-001"
897
- */
898
- generateChapterId(): string;
899
- /**
900
- * Generate an image ID
901
- * @returns An image ID in the format "img-001"
902
- */
903
- generateImageId(): string;
904
- /**
905
- * Generate a table ID
906
- * @returns A table ID in the format "tbl-001"
907
- */
908
- generateTableId(): string;
909
- /**
910
- * Generate a footnote ID
911
- * @returns A footnote ID in the format "ftn-001"
912
- */
913
- generateFootnoteId(): string;
914
- /**
915
- * Generate a text block ID
916
- * @returns A text block ID in the format "txt-001"
917
- */
918
- generateTextBlockId(): string;
919
- /**
920
- * Reset all counters to zero
921
- */
922
- reset(): void;
923
- /**
924
- * Get current counter values (for testing/debugging)
925
- */
926
- getCounters(): {
927
- chapter: number;
928
- image: number;
929
- table: number;
930
- footnote: number;
931
- textBlock: number;
932
- };
933
- /**
934
- * Pad a number to 3 digits with leading zeros
935
- */
936
- private padNumber;
937
- }
938
-
939
- /**
940
- * Extract the maximum page number from TOC markdown
941
- *
942
- * Parses page numbers from dot-leader patterns (e.g., "..... 175")
943
- * and table cell patterns (e.g., "| title | 175 |") to detect compiled
944
- * volume scenarios where TOC page numbers exceed the sub-document's page count.
945
- *
946
- * @param markdown - TOC markdown content
947
- * @returns Maximum page number found, or 0 if none found
948
- */
949
- declare function extractMaxPageNumber(markdown: string): number;
950
-
951
- /**
952
- * TOC keyword patterns for different languages
953
- * Korean: 목차, 차례, 목 차
954
- * Chinese: 目录, 目 录, 内容, 內容
955
- * Japanese: 目次, 目 次
956
- * English: Contents, Table of Contents, etc.
957
- */
958
- declare const TOC_KEYWORDS: readonly ["목차", "차례", "목 차", "目录", "目 录", "内容", "內容", "目次", "目 次", "Contents", "Table of Contents", "TABLE OF CONTENTS", "CONTENTS"];
959
- /**
960
- * Continuation marker patterns for multi-page TOC
961
- * Korean: 목차(계속), 목차 (계속), (계속)
962
- * Chinese: 目录(续), 目录 (续), (续), 续表
963
- * Japanese: 目次(続), 目次 (続), (続)
964
- * English: (continued), (Continued), etc.
965
- */
966
- declare const CONTINUATION_MARKERS: readonly ["목차(계속)", "목차 (계속)", "(계속)", "目录(续)", "目录 (续)", "(续)", "续表", "目次(続)", "目次 (続)", "(続)", "(continued)", "(Continued)", "(CONTINUED)", "continued"];
967
- /**
968
- * Page number pattern regex for detecting TOC-like structures
969
- * Matches patterns like "... 123", ".... 45", ending with numbers
970
- */
971
- declare const PAGE_NUMBER_PATTERN: RegExp;
972
- /**
973
- * TocFinder options
974
- */
975
- interface TocFinderOptions {
976
- /**
977
- * Maximum pages to search for TOC (default: 10)
978
- */
979
- maxSearchPages?: number;
980
- /**
981
- * Custom TOC keywords to add (optional)
982
- */
983
- additionalKeywords?: string[];
984
- }
985
- /**
986
- * TocFinder
987
- *
988
- * Finds TOC area in DoclingDocument using multi-stage search strategy:
989
- * 1. Keyword search in texts (section_header, list_item labels)
990
- * 2. Structure analysis for lists/tables with page number patterns
991
- * 3. Position heuristic (prioritize early pages)
992
- */
993
- declare class TocFinder {
994
- private readonly logger;
995
- private readonly refResolver;
996
- private readonly maxSearchPages;
997
- private readonly keywords;
998
- constructor(logger: LoggerMethods, refResolver: RefResolver, options?: TocFinderOptions);
999
- /**
1000
- * Find TOC area in the document
1001
- *
1002
- * @throws {TocNotFoundError} When no TOC area is found
1003
- */
1004
- find(doc: DoclingDocument): TocAreaResult;
1005
- /**
1006
- * Stage 1: Search by keywords in text items
1007
- */
1008
- private findByKeywords;
1009
- /**
1010
- * Stage 2: Search by structure (lists/tables with page numbers)
1011
- */
1012
- private findByStructure;
1013
- /**
1014
- * Find the TOC container (group or table) from a parent reference
1015
- */
1016
- private findTocContainer;
1017
- /**
1018
- * Find adjacent TOC item among body siblings following the keyword text.
1019
- * Used when findTocContainer returns null (e.g., parent is #/body).
1020
- */
1021
- private findSiblingTocItem;
1022
- /**
1023
- * Check if a group contains TOC-like structure
1024
- */
1025
- private isGroupTocLike;
1026
- /**
1027
- * Check if a table contains TOC-like structure
1028
- */
1029
- private isTableTocLike;
1030
- /**
1031
- * Check if a table is a resource index (drawing/photo/figure list)
1032
- * rather than a main TOC table
1033
- */
1034
- private isResourceIndexTable;
1035
- /**
1036
- * Expand TOC area to consecutive pages (both backward and forward)
1037
- */
1038
- private expandToConsecutivePages;
1039
- /**
1040
- * Find TOC continuation items on a specific page
1041
- */
1042
- private findContinuationOnPage;
1043
- /**
1044
- * Check if text contains TOC keyword
1045
- */
1046
- private containsTocKeyword;
1047
- /**
1048
- * Check for continuation markers
1049
- */
1050
- private hasContinuationMarker;
1051
- /**
1052
- * Get first page number of a group by checking its children
1053
- */
1054
- private getGroupFirstPage;
1055
- /**
1056
- * Calculate score for a group candidate
1057
- * Higher score = better match
1058
- */
1059
- private calculateScore;
1060
- /**
1061
- * Calculate score for a table candidate
1062
- */
1063
- private calculateTableScore;
1064
- }
1065
-
1066
- /**
1067
- * Zod schema for TocEntry structure with fixed 4-level depth
1068
- */
1069
- declare const TocEntrySchema: z.ZodType<TocEntry>;
1070
- /**
1071
- * Schema for LLM response
1072
- */
1073
- declare const TocResponseSchema: z.ZodObject<{
1074
- entries: z.ZodArray<z.ZodType<TocEntry, unknown, z.core.$ZodTypeInternals<TocEntry, unknown>>>;
1075
- }, z.core.$strip>;
1076
- type TocResponse = z.infer<typeof TocResponseSchema>;
1077
- /**
1078
- * TocExtractor options
1079
- */
1080
- interface TocExtractorOptions extends BaseLLMComponentOptions {
1081
- /**
1082
- * Validation options (optional)
1083
- * If not provided, validation is performed with default settings
1084
- */
1085
- validation?: TocValidationOptions;
1086
- /**
1087
- * Whether to skip validation entirely (default: false)
1088
- */
1089
- skipValidation?: boolean;
1090
- /**
1091
- * Maximum retry count for TOC validation correction feedback (default: 3)
1092
- */
1093
- maxValidationRetries?: number;
1094
- }
1095
- /**
1096
- * TocExtractor
1097
- *
1098
- * Uses high-performance LLM to extract structured TOC from Markdown representation.
1099
- * Extends TextLLMComponent for standardized LLM call handling.
1100
- *
1101
- * When validation fails, automatically retries with correction feedback
1102
- * up to maxValidationRetries times before throwing.
1103
- */
1104
- declare class TocExtractor extends TextLLMComponent {
1105
- private readonly validationOptions?;
1106
- private readonly skipValidation;
1107
- private readonly maxValidationRetries;
1108
- constructor(logger: LoggerMethods, model: LanguageModel, options?: TocExtractorOptions, fallbackModel?: LanguageModel, abortSignal?: AbortSignal);
1109
- /**
1110
- * Extract TOC structure from Markdown
1111
- *
1112
- * When validation fails, retries with correction feedback up to maxValidationRetries times.
1113
- *
1114
- * @param markdown - Markdown representation of TOC area
1115
- * @param validationOverrides - Optional overrides for validation options (merged with constructor options)
1116
- * @returns Object with entries array and token usage array (initial extraction + any corrections)
1117
- * @throws {TocParseError} When LLM fails to parse structure
1118
- * @throws {TocValidationError} When validation fails after all retries
1119
- */
1120
- extract(markdown: string, validationOverrides?: Partial<TocValidationOptions>): Promise<{
1121
- entries: TocEntry[];
1122
- usages: ExtendedTokenUsage[];
1123
- }>;
1124
- /**
1125
- * Validate extracted entries and return error or null
1126
- *
1127
- * Unlike validateOrThrow, this returns the error instead of throwing,
1128
- * allowing the retry loop to handle it.
1129
- *
1130
- * @returns TocValidationError if validation fails, null if valid
1131
- */
1132
- private tryValidateEntries;
1133
- /**
1134
- * Build correction prompt with validation error feedback
1135
- *
1136
- * Includes the original markdown, previous extraction result,
1137
- * validation errors, and guidance for fixing common mistakes.
1138
- */
1139
- protected buildCorrectionPrompt(markdown: string, previousEntries: TocEntry[], issues: TocValidationIssue[]): string;
1140
- /**
1141
- * Build system prompt for TOC extraction
1142
- */
1143
- protected buildSystemPrompt(): string;
1144
- /**
1145
- * Build user prompt with Markdown content
1146
- */
1147
- protected buildUserPrompt(markdown: string): string;
1148
- /**
1149
- * Normalize and validate extracted entries
1150
- */
1151
- private normalizeEntries;
1152
- /**
1153
- * Recursively ensure level consistency
1154
- *
1155
- * Children must have level = parent.level + 1
1156
- */
1157
- private normalizeLevel;
1158
- }
1159
-
1160
- /**
1161
- * Schema for vision-based TOC extraction response
1162
- */
1163
- declare const VisionTocExtractionSchema: z.ZodObject<{
1164
- hasToc: z.ZodBoolean;
1165
- tocMarkdown: z.ZodNullable<z.ZodString>;
1166
- continuesOnNextPage: z.ZodBoolean;
1167
- }, z.core.$strip>;
1168
- type VisionTocExtractionResult = z.infer<typeof VisionTocExtractionSchema>;
1169
- /**
1170
- * Options for VisionTocExtractor
1171
- */
1172
- interface VisionTocExtractorOptions extends VisionLLMComponentOptions {
1173
- /**
1174
- * Number of pages for first batch (default: 10)
1175
- */
1176
- firstBatchSize?: number;
1177
- /**
1178
- * Number of pages for second batch (default: 10)
1179
- */
1180
- secondBatchSize?: number;
1181
- }
1182
- /**
1183
- * VisionTocExtractor
1184
- *
1185
- * Uses vision LLM to find and extract TOC directly from page images.
1186
- * Fallback strategy when rule-based extraction fails or produces invalid content.
1187
- * Extends VisionLLMComponent for standardized vision LLM call handling.
1188
- *
1189
- * Output format matches MarkdownConverter.convert() for consistency.
1190
- */
1191
- declare class VisionTocExtractor extends VisionLLMComponent {
1192
- private readonly firstBatchSize;
1193
- private readonly secondBatchSize;
1194
- constructor(logger: LoggerMethods, model: LanguageModel, artifactDir: string, options?: VisionTocExtractorOptions, fallbackModel?: LanguageModel, aggregator?: LLMTokenUsageAggregator);
1195
- /**
1196
- * Extract TOC from page images
1197
- *
1198
- * Searches pages 1-10 first, then 11-20 if not found.
1199
- *
1200
- * @param totalPages - Total number of pages in the document
1201
- * @returns Extracted TOC markdown or null if not found
1202
- */
1203
- extract(totalPages: number): Promise<string | null>;
1204
- /**
1205
- * Extract TOC from a specific batch of pages
1206
- */
1207
- private extractFromBatch;
1208
- /**
1209
- * Load page images and build message content
1210
- */
1211
- private loadPageImages;
1212
- /**
1213
- * Merge markdown from multiple batches
1214
- */
1215
- private mergeMarkdown;
1216
- /**
1217
- * Build system prompt for vision LLM (not used, but required by abstract class)
1218
- */
1219
- protected buildSystemPrompt(): string;
1220
- /**
1221
- * Build user prompt with page range information
1222
- */
1223
- protected buildUserPrompt(startPage: number, endPage: number): string;
1224
- }
1225
-
1226
- /**
1227
- * Base options for all validators
1228
- *
1229
- * Re-exported from BaseLLMComponentOptions for backwards compatibility.
1230
- */
1231
- type BaseValidatorOptions = BaseLLMComponentOptions;
1232
- /**
1233
- * Abstract base class for LLM-based validators
1234
- *
1235
- * Extends TextLLMComponent to provide common functionality for validators
1236
- * that use LLM to validate/analyze content:
1237
- * - LLM API call wrapper with LLMCaller (via callLLM method)
1238
- * - Standard logging patterns (via log method from base class)
1239
- * - Retry and fallback configuration
1240
- *
1241
- * Token usage is tracked by LLMCaller and should be aggregated by DocumentProcessor.
1242
- *
1243
- * @template TSchema - Zod schema type for validation
1244
- * @template TResult - Result type after parsing with schema
1245
- */
1246
- declare abstract class BaseValidator<TSchema extends z.ZodType, TResult = z.infer<TSchema>> extends TextLLMComponent {
1247
- /**
1248
- * Validator name for logging (kept for backwards compatibility)
1249
- */
1250
- protected readonly validatorName: string;
1251
- /**
1252
- * Constructor for BaseValidator
1253
- *
1254
- * @param logger - Logger instance
1255
- * @param model - Language model to use for validation
1256
- * @param validatorName - Name of the validator for logging (e.g., "TocContentValidator")
1257
- * @param options - Optional configuration (maxRetries, temperature)
1258
- * @param fallbackModel - Optional fallback model for retry on failure
1259
- * @param aggregator - Optional token usage aggregator for tracking LLM calls
1260
- */
1261
- constructor(logger: LoggerMethods, model: LanguageModel, validatorName: string, options?: BaseValidatorOptions, fallbackModel?: LanguageModel, aggregator?: LLMTokenUsageAggregator);
1262
- /**
1263
- * Call LLM with LLMCaller
1264
- *
1265
- * This method provides backwards compatibility with existing validators.
1266
- * It wraps the parent callTextLLM method but allows passing a custom aggregator.
1267
- *
1268
- * @param schema - Zod schema for response validation
1269
- * @param systemPrompt - System prompt
1270
- * @param userPrompt - User prompt
1271
- * @param phase - Phase name for tracking (e.g., 'validation', 'batch-validation')
1272
- * @param aggregator - Optional token usage aggregator for tracking this call
1273
- * @returns Parsed and validated LLM response with usage information
1274
- */
1275
- protected callLLM(schema: TSchema, systemPrompt: string, userPrompt: string, phase: string, aggregator?: LLMTokenUsageAggregator): Promise<{
1276
- output: TResult;
1277
- usage: ExtendedTokenUsage;
1278
- }>;
1279
- }
1280
-
1281
- /**
1282
- * Content type for TOC validation
1283
- */
1284
- type TocContentType = 'pure_toc' | 'mixed' | 'resource_only' | 'invalid';
1285
- /**
1286
- * Schema for TOC content validation response
1287
- */
1288
- declare const TocContentValidationSchema: z.ZodObject<{
1289
- isValid: z.ZodBoolean;
1290
- confidence: z.ZodNumber;
1291
- contentType: z.ZodEnum<{
1292
- pure_toc: "pure_toc";
1293
- mixed: "mixed";
1294
- resource_only: "resource_only";
1295
- invalid: "invalid";
1296
- }>;
1297
- extractedTocMarkdown: z.ZodNullable<z.ZodString>;
1298
- reason: z.ZodString;
1299
- }, z.core.$strip>;
1300
- type TocContentValidationResult = z.infer<typeof TocContentValidationSchema>;
1301
- /**
1302
- * Output type for TOC validation with resolved markdown
1303
- */
1304
- interface TocValidationOutput {
1305
- isValid: boolean;
1306
- confidence: number;
1307
- contentType: TocContentType;
1308
- validTocMarkdown: string | null;
1309
- reason: string;
1310
- }
1311
- /**
1312
- * Options for TocContentValidator
1313
- */
1314
- interface TocContentValidatorOptions extends BaseValidatorOptions {
1315
- /**
1316
- * Minimum confidence to consider valid (default: 0.7)
1317
- */
1318
- confidenceThreshold?: number;
1319
- }
1320
- /**
1321
- * TocContentValidator
1322
- *
1323
- * Uses LLM to validate whether extracted markdown content is actually a TOC.
1324
- * This is a semantic validation, not structural validation.
1325
- * Supports mixed content extraction where main TOC is combined with resource indices.
1326
- */
1327
- declare class TocContentValidator extends BaseValidator<typeof TocContentValidationSchema, TocContentValidationResult> {
1328
- private readonly confidenceThreshold;
1329
- constructor(logger: LoggerMethods, model: LanguageModel, options?: TocContentValidatorOptions, fallbackModel?: LanguageModel, aggregator?: LLMTokenUsageAggregator);
1330
- /**
1331
- * Validate if the markdown content is a table of contents
1332
- *
1333
- * @param markdown - Markdown content to validate
1334
- * @returns Validation output with resolved markdown for valid TOC
1335
- */
1336
- validate(markdown: string): Promise<TocValidationOutput>;
1337
- /**
1338
- * Check if validation result passes threshold
1339
- *
1340
- * @param result - Validation output from validate()
1341
- * @returns true if content is valid TOC with sufficient confidence
1342
- */
1343
- isValid(result: TocValidationOutput): boolean;
1344
- /**
1345
- * Get the valid TOC markdown from validation result
1346
- *
1347
- * @param result - Validation output from validate()
1348
- * @returns Valid TOC markdown or null if invalid
1349
- */
1350
- getValidMarkdown(result: TocValidationOutput): string | null;
1351
- /**
1352
- * Build system prompt for TOC content validation
1353
- */
1354
- protected buildSystemPrompt(): string;
1355
- /**
1356
- * Build user prompt with markdown content
1357
- */
1358
- protected buildUserPrompt(markdown: string): string;
1359
- }
1360
-
1361
- /**
1362
- * Schema for batch caption validation response
1363
- */
1364
- declare const CaptionValidationBatchSchema: z.ZodObject<{
1365
- results: z.ZodArray<z.ZodObject<{
1366
- index: z.ZodNumber;
1367
- isValid: z.ZodBoolean;
1368
- reason: z.ZodNullable<z.ZodString>;
1369
- }, z.core.$strip>>;
1370
- }, z.core.$strip>;
1371
- type CaptionValidationBatch = z.infer<typeof CaptionValidationBatchSchema>;
1372
- /**
1373
- * Options for CaptionValidator
1374
- */
1375
- interface CaptionValidatorOptions extends BaseValidatorOptions {
1376
- }
1377
- /**
1378
- * CaptionValidator
1379
- *
1380
- * Validates parsed captions against original text using LLM.
1381
- * Processes captions in batches to optimize LLM API calls.
1382
- *
1383
- * ## Validation Rules
1384
- *
1385
- * Checks if the parsed "num" field correctly extracts the prefix + number from original text:
1386
- * 1. **Correctness**: The "num" must contain the actual prefix+number from the original text
1387
- * - Example: "도판 1 유적 전경" → num="도판 1" ✓
1388
- * - Example: "도판 1 유적 전경" → num="도판" ✗ (incomplete)
1389
- *
1390
- * 2. **Spacing**: The spacing in "num" must match the original text exactly
1391
- * - Example: "도판 1" → num="도판 1" ✓
1392
- * - Example: "도판1" → num="도판1" ✓
1393
- * - Example: "도판 1" → num="도판1" ✗ (spacing mismatch)
1394
- *
1395
- * 3. **Completeness**: The number part must be fully extracted
1396
- * - Example: "Figure 2-3" → num="Figure 2-3" ✓
1397
- * - Example: "Figure 2-3" → num="Figure 2" ✗ (incomplete number)
1398
- *
1399
- * 4. **Null handling**: If "num" is null, verify that the original text has no number prefix
1400
- * - Example: "유적 전경 사진" → num=null ✓
1401
- * - Example: "도판 1 전경" → num=null ✗ (should extract "도판 1")
1402
- */
1403
- declare class CaptionValidator extends BaseValidator<typeof CaptionValidationBatchSchema, CaptionValidationBatch> {
1404
- constructor(logger: LoggerMethods, model: LanguageModel, options?: CaptionValidatorOptions, fallbackModel?: LanguageModel, aggregator?: LLMTokenUsageAggregator);
1405
- /**
1406
- * Validate batch of parsed captions against original texts
1407
- *
1408
- * @param captions - Array of parsed Caption objects
1409
- * @param originalTexts - Array of original caption texts (same order as captions)
1410
- * @param batchSize - Batch size for processing. Set to 0 to skip validation (assume all valid).
1411
- * @returns Array of validation results (boolean) maintaining original order
1412
- */
1413
- validateBatch(captions: Caption[], originalTexts: string[], batchSize: number): Promise<boolean[]>;
1414
- /**
1415
- * Internal: Validate batch of captions using LLM
1416
- *
1417
- * @param items - Batch of caption items with original indices
1418
- * @param model - Effective model to use
1419
- * @returns Array of validation results indexed correctly
1420
- */
1421
- private validateBatchInternal;
1422
- protected buildSystemPrompt(): string;
1423
- protected buildUserPrompt(items: Array<{
1424
- index: number;
1425
- caption: Caption;
1426
- originalText: string;
1427
- }>): string;
1428
- }
1429
- /**
1430
- * Error thrown when caption validation fails
1431
- */
1432
- declare class CaptionValidationError extends Error {
1433
- constructor(message: string, options?: ErrorOptions);
1434
- }
1435
-
1436
- /**
1437
- * ChapterConverter
1438
- *
1439
- * Converts TocEntry[] to Chapter[] with text blocks, images, and tables.
1440
- *
1441
- * ## Conversion Process
1442
- *
1443
- * 1. Create Front Matter chapter (ch-000) for pre-TOC content
1444
- * 2. Build chapter tree from TocEntry[] (recursive)
1445
- * 3. Calculate page ranges for each chapter
1446
- * 4. Assign text blocks to chapters based on page ranges
1447
- * 5. Link images/tables to chapters based on page ranges
1448
- *
1449
- * ## Page Assignment Strategy
1450
- *
1451
- * Uses "start page first" strategy: resources are assigned to the chapter
1452
- * whose startPage is the largest value that is still <= the resource's page.
1453
- *
1454
- * ## Front Matter
1455
- *
1456
- * A special chapter (ch-000) is always created to hold content that appears
1457
- * before the first TOC entry (e.g., cover, preface, table of contents itself).
1458
- */
1459
- declare class ChapterConverter {
1460
- private static readonly FRONT_MATTER_ID;
1461
- private static readonly FRONT_MATTER_TITLE;
1462
- private readonly logger;
1463
- private readonly idGenerator;
1464
- constructor(logger: LoggerMethods, idGenerator: IdGenerator);
1465
- /**
1466
- * Convert TocEntry[] to Chapter[]
1467
- *
1468
- * @param tocEntries - Table of contents entries
1469
- * @param textItems - DoclingDocument.texts (with prov for page numbers)
1470
- * @param pageRangeMap - PDF page to actual page mapping
1471
- * @param images - Converted images
1472
- * @param tables - Converted tables
1473
- * @param footnotes - Converted footnotes
1474
- * @returns Converted chapters with text blocks and resource references
1475
- */
1476
- convert(tocEntries: TocEntry[], textItems: DoclingTextItem[], pageRangeMap: Record<number, PageRange>, images: ProcessedImage[], tables: ProcessedTable[], footnotes: ProcessedFootnote[]): Chapter[];
1477
- /**
1478
- * Create Front Matter chapter for pre-TOC content
1479
- */
1480
- private createFrontMatterChapter;
1481
- /**
1482
- * Build chapter tree from TocEntry[]
1483
- * Recursively processes children
1484
- */
1485
- private buildChapterTree;
1486
- /**
1487
- * Flatten chapter tree for page range calculation
1488
- * Preserves original TOC page numbers
1489
- */
1490
- private flattenChapters;
1491
- /**
1492
- * Calculate page range for each chapter
1493
- * Uses next chapter's start page as end boundary
1494
- *
1495
- * Front Matter (ch-000) gets special handling:
1496
- * - startPage: 1
1497
- * - endPage: first TOC entry's page - 1 (or 0 if TOC starts at page 1)
1498
- */
1499
- private calculatePageRanges;
1500
- /**
1501
- * Valid labels for text blocks
1502
- * Only these labels are included in chapter text blocks
1503
- */
1504
- private static readonly VALID_TEXT_LABELS;
1505
- /**
1506
- * Check if text item has a picture parent
1507
- * Items with parent.$ref starting with "#/pictures/" are excluded
1508
- */
1509
- private static hasPictureParent;
1510
- /**
1511
- * Convert text items to text blocks
1512
- * Filters by label (text, section_header, list_item), excludes picture children,
1513
- * and extracts page numbers from prov
1514
- */
1515
- private convertTextBlocks;
1516
- /**
1517
- * Convert PDF page number to actual document page number
1518
- * Falls back to pdfPageNo if mapping is missing
1519
- */
1520
- private pdfPageToActualPage;
1521
- /**
1522
- * Find chapter ID for a given actual page number
1523
- * Uses "start page first" strategy
1524
- */
1525
- private findChapterForPage;
1526
- /**
1527
- * Assign text blocks to chapters based on page ranges
1528
- */
1529
- private assignTextBlocks;
1530
- /**
1531
- * Link images, tables, and footnotes to chapters based on page ranges
1532
- */
1533
- private linkResources;
1534
- /**
1535
- * Build flat chapter map for O(1) lookup
1536
- */
1537
- private buildChapterMap;
1538
- }
1539
-
1540
- /**
1541
- * Dependencies required by CaptionProcessingPipeline
1542
- */
1543
- interface CaptionProcessingPipelineDeps {
1544
- logger: LoggerMethods;
1545
- captionParser: CaptionParser;
1546
- captionValidator: CaptionValidator;
1547
- refResolver?: RefResolver;
1548
- fallbackModel: LanguageModel;
1549
- enableFallbackRetry: boolean;
1550
- maxRetries: number;
1551
- captionParserBatchSize: number;
1552
- captionValidatorBatchSize: number;
1553
- usageAggregator: LLMTokenUsageAggregator;
1554
- abortSignal?: AbortSignal;
1555
- }
1556
- /**
1557
- * Caption text and source references extracted from Docling caption links.
1558
- *
1559
- * `text` is omitted when none of the captions resolved to non-empty text;
1560
- * `sourceRefs` is always present and contains every `$ref` caption in order
1561
- * (string captions contribute to `text` only).
1562
- */
1563
- interface CaptionSourceExtraction {
1564
- text?: string;
1565
- sourceRefs: string[];
1566
- }
1567
- /**
1568
- * CaptionProcessingPipeline
1569
- *
1570
- * Processes resource captions through a multi-step pipeline:
1571
- * 1. Parse captions in batch (CaptionParser)
1572
- * 2. Handle length mismatch recovery
1573
- * 3. Validate parsed captions (CaptionValidator)
1574
- * 4. Reparse failed captions with fallback model
1575
- */
1576
- declare class CaptionProcessingPipeline {
1577
- private static readonly CAPTION_JOIN_SEPARATOR;
1578
- private readonly logger;
1579
- private readonly captionParser;
1580
- private readonly captionValidator;
1581
- private readonly refResolver?;
1582
- private readonly fallbackModel;
1583
- private readonly enableFallbackRetry;
1584
- private readonly maxRetries;
1585
- private readonly captionParserBatchSize;
1586
- private readonly captionValidatorBatchSize;
1587
- private readonly usageAggregator;
1588
- private readonly abortSignal?;
1589
- constructor(deps: CaptionProcessingPipelineDeps);
1590
- /**
1591
- * Process resource captions (for images and tables)
1592
- *
1593
- * Common caption processing pipeline:
1594
- * 1. Parse captions in batch
1595
- * 2. Validate parsed captions
1596
- * 3. Reparse failed captions with fallback model
1597
- *
1598
- * @param captionTexts - Array of caption texts to process
1599
- * @param resourceType - Type of resource for logging (e.g., 'image', 'table')
1600
- * @returns Parsed captions with index mapping
1601
- */
1602
- processResourceCaptions(captionTexts: Array<string | undefined>, resourceType: string): Promise<Map<number, Caption>>;
1603
- /**
1604
- * Extract combined caption text from resource captions.
1605
- *
1606
- * Returns every caption joined with a single space; empty/whitespace-only
1607
- * entries are skipped. Returns `undefined` when nothing resolves to text.
1608
- *
1609
- * @deprecated Use {@link extractCaptionSource} to also receive the
1610
- * caption `$ref` list. This helper is retained as a thin wrapper for
1611
- * legacy callers.
1612
- */
1613
- extractCaptionText(captions: Array<string | DoclingReference> | undefined): string | undefined;
1614
- /**
1615
- * Extract caption text and source references from resource captions.
1616
- *
1617
- * Iterates captions in order. String captions contribute to text only;
1618
- * `$ref` captions also push the ref onto `sourceRefs` regardless of whether
1619
- * the resolver finds text. Resolved/raw text is trimmed, and empty parts
1620
- * are skipped before joining.
1621
- */
1622
- extractCaptionSource(captions: Array<string | DoclingReference> | undefined): CaptionSourceExtraction;
1623
- }
1624
-
1625
- /**
1626
- * Dependencies required by TocExtractionPipeline
1627
- */
1628
- interface TocExtractionPipelineDeps {
1629
- logger: LoggerMethods;
1630
- tocFinder: TocFinder;
1631
- tocExtractor: TocExtractor;
1632
- tocContentValidator: TocContentValidator;
1633
- visionTocExtractor: VisionTocExtractor;
1634
- refResolver: RefResolver;
1635
- usageAggregator: LLMTokenUsageAggregator;
1636
- }
1637
- /**
1638
- * TocExtractionPipeline
1639
- *
1640
- * Orchestrates the multi-stage TOC extraction process:
1641
- * 1. Rule-based extraction (TocFinder + MarkdownConverter)
1642
- * 2. Content validation (TocContentValidator)
1643
- * 3. Vision fallback (VisionTocExtractor)
1644
- * 4. Structured extraction with validation retry (TocExtractor)
1645
- * 5. Vision fallback retry when text-based extraction yields 0 entries
1646
- */
1647
- declare class TocExtractionPipeline {
1648
- private readonly logger;
1649
- private readonly tocFinder;
1650
- private readonly tocExtractor;
1651
- private readonly tocContentValidator;
1652
- private readonly visionTocExtractor;
1653
- private readonly refResolver;
1654
- private readonly usageAggregator;
1655
- constructor(deps: TocExtractionPipelineDeps);
1656
- /**
1657
- * Execute the TOC extraction pipeline
1658
- *
1659
- * @param doclingDoc - Document containing texts, pages, etc.
1660
- * @param _filteredTexts - Pre-filtered texts (reserved for future use)
1661
- * @returns Extracted TOC entries
1662
- * @throws {TocNotFoundError} When TOC cannot be found or extracted
1663
- */
1664
- extract(doclingDoc: DoclingDocument, _filteredTexts: string[]): Promise<TocEntry[]>;
1665
- }
1666
-
1667
- /**
1668
- * ResourceConverter
1669
- *
1670
- * Converts DoclingDocument resources (images, tables, footnotes) to processed format.
1671
- * Uses CaptionProcessingPipeline for caption extraction and validation.
1672
- */
1673
- declare class ResourceConverter {
1674
- private readonly logger;
1675
- private readonly idGenerator;
1676
- private readonly captionProcessingPipeline;
1677
- constructor(logger: LoggerMethods, idGenerator: IdGenerator, captionProcessingPipeline: CaptionProcessingPipeline);
1678
- /**
1679
- * Convert all resources (images, tables, footnotes)
1680
- *
1681
- * Runs image and table conversions in parallel, then footnotes synchronously.
1682
- */
1683
- convertAll(doclingDoc: DoclingDocument, artifactDir: string): Promise<{
1684
- images: ProcessedImage[];
1685
- tables: ProcessedTable[];
1686
- footnotes: ProcessedFootnote[];
1687
- }>;
1688
- /**
1689
- * Convert images from DoclingDocument to ProcessedImage[]
1690
- */
1691
- convertImages(doclingDoc: DoclingDocument, artifactDir: string): Promise<ProcessedImage[]>;
1692
- /**
1693
- * Convert tables from DoclingDocument to ProcessedTable[]
1694
- */
1695
- convertTables(doclingDoc: DoclingDocument): Promise<ProcessedTable[]>;
1696
- /**
1697
- * Convert footnotes from DoclingDocument text items
1698
- */
1699
- convertFootnotes(doclingDoc: DoclingDocument): ProcessedFootnote[];
1700
- }
1701
-
1702
- export { BaseLLMComponent, type BaseLLMComponentOptions, BaseValidator, type BaseValidatorOptions, CONTINUATION_MARKERS, CaptionParseError, CaptionParser, type CaptionParserOptions, CaptionProcessingPipeline, type CaptionProcessingPipelineDeps, type CaptionSourceExtraction, CaptionValidationError, CaptionValidator, type CaptionValidatorOptions, ChapterConverter, DocumentProcessor, type DocumentProcessorOptions, type DocumentProcessorProcessOptions, type ImageContent, PAGE_NUMBER_PATTERN, PROCESSED_DOCUMENT_SCHEMA_VERSION, PagePattern, PageRangeParseError, PageRangeParser, type PageSizeGroup, ResourceConverter, type SourceRefValidationMode, TOC_KEYWORDS, TextLLMComponent, type TocAreaResult, type TocContentValidationResult, TocContentValidationSchema, TocContentValidator, type TocContentValidatorOptions, type TocEntry, TocEntrySchema, TocExtractError, TocExtractionPipeline, type TocExtractionPipelineDeps, TocExtractor, type TocExtractorOptions, TocFinder, type TocFinderOptions, TocNotFoundError, TocParseError, type TocResponse, TocResponseSchema, VisionLLMComponent, type VisionLLMComponentOptions, type VisionTocExtractionResult, VisionTocExtractionSchema, VisionTocExtractor, type VisionTocExtractorOptions, extractMaxPageNumber };