@heripo/document-processor 0.1.21 → 0.1.23
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/README.ko.md +81 -4
- package/README.md +81 -4
- package/dist/index.cjs +48 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +96 -69
- package/dist/index.d.ts +96 -69
- package/dist/index.js +48 -35
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -1224,12 +1224,12 @@ var ResourceConverter = class {
|
|
|
1224
1224
|
*
|
|
1225
1225
|
* Runs image and table conversions in parallel, then footnotes synchronously.
|
|
1226
1226
|
*/
|
|
1227
|
-
async convertAll(doclingDoc,
|
|
1227
|
+
async convertAll(doclingDoc, artifactDir) {
|
|
1228
1228
|
this.logger.info(
|
|
1229
1229
|
"[ResourceConverter] Converting images, tables, and footnotes..."
|
|
1230
1230
|
);
|
|
1231
1231
|
const [images, tables] = await Promise.all([
|
|
1232
|
-
this.convertImages(doclingDoc,
|
|
1232
|
+
this.convertImages(doclingDoc, artifactDir),
|
|
1233
1233
|
this.convertTables(doclingDoc)
|
|
1234
1234
|
]);
|
|
1235
1235
|
const footnotes = this.convertFootnotes(doclingDoc);
|
|
@@ -1241,7 +1241,7 @@ var ResourceConverter = class {
|
|
|
1241
1241
|
/**
|
|
1242
1242
|
* Convert images from DoclingDocument to ProcessedImage[]
|
|
1243
1243
|
*/
|
|
1244
|
-
async convertImages(doclingDoc,
|
|
1244
|
+
async convertImages(doclingDoc, artifactDir) {
|
|
1245
1245
|
this.logger.info(
|
|
1246
1246
|
`[ResourceConverter] Converting ${doclingDoc.pictures.length} images...`
|
|
1247
1247
|
);
|
|
@@ -1251,7 +1251,7 @@ var ResourceConverter = class {
|
|
|
1251
1251
|
const images = doclingDoc.pictures.map(
|
|
1252
1252
|
(picture, index) => ({
|
|
1253
1253
|
id: this.idGenerator.generateImageId(),
|
|
1254
|
-
path: `${
|
|
1254
|
+
path: `${artifactDir}/images/image_${index}.png`,
|
|
1255
1255
|
pdfPageNo: picture.prov?.[0]?.page_no ?? 0
|
|
1256
1256
|
})
|
|
1257
1257
|
);
|
|
@@ -2072,7 +2072,7 @@ var TextLLMComponent = class extends BaseLLMComponent {
|
|
|
2072
2072
|
};
|
|
2073
2073
|
|
|
2074
2074
|
// src/extractors/toc-extractor.ts
|
|
2075
|
-
var
|
|
2075
|
+
var DEFAULT_MAX_VALIDATION_RETRIES = 3;
|
|
2076
2076
|
var VALIDATION_CODE_DESCRIPTIONS = {
|
|
2077
2077
|
V001: "Page numbers must be in non-decreasing order within the same level. A decrease usually means a hierarchy or page number error.",
|
|
2078
2078
|
V002: "Page number is out of valid range (must be >= 1 and <= total pages).",
|
|
@@ -2105,6 +2105,7 @@ var TocResponseSchema = z.object({
|
|
|
2105
2105
|
var TocExtractor = class extends TextLLMComponent {
|
|
2106
2106
|
validationOptions;
|
|
2107
2107
|
skipValidation;
|
|
2108
|
+
maxValidationRetries;
|
|
2108
2109
|
constructor(logger, model, options, fallbackModel, abortSignal) {
|
|
2109
2110
|
super(
|
|
2110
2111
|
logger,
|
|
@@ -2115,11 +2116,12 @@ var TocExtractor = class extends TextLLMComponent {
|
|
|
2115
2116
|
);
|
|
2116
2117
|
this.validationOptions = options?.validation;
|
|
2117
2118
|
this.skipValidation = options?.skipValidation ?? false;
|
|
2119
|
+
this.maxValidationRetries = options?.maxValidationRetries ?? DEFAULT_MAX_VALIDATION_RETRIES;
|
|
2118
2120
|
}
|
|
2119
2121
|
/**
|
|
2120
2122
|
* Extract TOC structure from Markdown
|
|
2121
2123
|
*
|
|
2122
|
-
* When validation fails, retries with correction feedback up to
|
|
2124
|
+
* When validation fails, retries with correction feedback up to maxValidationRetries times.
|
|
2123
2125
|
*
|
|
2124
2126
|
* @param markdown - Markdown representation of TOC area
|
|
2125
2127
|
* @param validationOverrides - Optional overrides for validation options (merged with constructor options)
|
|
@@ -2149,10 +2151,10 @@ var TocExtractor = class extends TextLLMComponent {
|
|
|
2149
2151
|
entries,
|
|
2150
2152
|
validationOverrides
|
|
2151
2153
|
);
|
|
2152
|
-
for (let attempt = 1; attempt <=
|
|
2154
|
+
for (let attempt = 1; attempt <= this.maxValidationRetries && validationError !== null; attempt++) {
|
|
2153
2155
|
this.log(
|
|
2154
2156
|
"warn",
|
|
2155
|
-
`Validation failed (attempt ${attempt}/${
|
|
2157
|
+
`Validation failed (attempt ${attempt}/${this.maxValidationRetries}), retrying with correction feedback`
|
|
2156
2158
|
);
|
|
2157
2159
|
const correctionPrompt = this.buildCorrectionPrompt(
|
|
2158
2160
|
markdown,
|
|
@@ -2175,7 +2177,7 @@ var TocExtractor = class extends TextLLMComponent {
|
|
|
2175
2177
|
if (validationError !== null) {
|
|
2176
2178
|
this.log(
|
|
2177
2179
|
"error",
|
|
2178
|
-
`Validation failed after ${
|
|
2180
|
+
`Validation failed after ${this.maxValidationRetries} retries:
|
|
2179
2181
|
${validationError.getSummary()}`
|
|
2180
2182
|
);
|
|
2181
2183
|
throw validationError;
|
|
@@ -2367,10 +2369,10 @@ import { z as z2 } from "zod";
|
|
|
2367
2369
|
import * as fs from "fs";
|
|
2368
2370
|
import * as path from "path";
|
|
2369
2371
|
var VisionLLMComponent = class extends BaseLLMComponent {
|
|
2370
|
-
|
|
2371
|
-
constructor(logger, model, componentName,
|
|
2372
|
+
artifactDir;
|
|
2373
|
+
constructor(logger, model, componentName, artifactDir, options, fallbackModel, aggregator) {
|
|
2372
2374
|
super(logger, model, componentName, options, fallbackModel, aggregator);
|
|
2373
|
-
this.
|
|
2375
|
+
this.artifactDir = artifactDir;
|
|
2374
2376
|
}
|
|
2375
2377
|
/**
|
|
2376
2378
|
* Call LLM with vision capabilities using LLMCaller.callVision()
|
|
@@ -2402,12 +2404,12 @@ var VisionLLMComponent = class extends BaseLLMComponent {
|
|
|
2402
2404
|
/**
|
|
2403
2405
|
* Build image content object for vision LLM messages
|
|
2404
2406
|
*
|
|
2405
|
-
* @param imagePath - Path to the image file (relative to
|
|
2407
|
+
* @param imagePath - Path to the image file (relative to artifactDir or absolute)
|
|
2406
2408
|
* @param mimeType - MIME type of the image (default: 'image/png')
|
|
2407
2409
|
* @returns ImageContent object for LLM message
|
|
2408
2410
|
*/
|
|
2409
2411
|
buildImageContent(imagePath, mimeType = "image/png") {
|
|
2410
|
-
const absolutePath = path.isAbsolute(imagePath) ? imagePath : path.resolve(this.
|
|
2412
|
+
const absolutePath = path.isAbsolute(imagePath) ? imagePath : path.resolve(this.artifactDir, imagePath);
|
|
2411
2413
|
const imageData = new Uint8Array(fs.readFileSync(absolutePath));
|
|
2412
2414
|
return {
|
|
2413
2415
|
type: "image",
|
|
@@ -2426,12 +2428,12 @@ var VisionTocExtractionSchema = z2.object({
|
|
|
2426
2428
|
var VisionTocExtractor = class extends VisionLLMComponent {
|
|
2427
2429
|
firstBatchSize;
|
|
2428
2430
|
secondBatchSize;
|
|
2429
|
-
constructor(logger, model,
|
|
2431
|
+
constructor(logger, model, artifactDir, options, fallbackModel, aggregator) {
|
|
2430
2432
|
super(
|
|
2431
2433
|
logger,
|
|
2432
2434
|
model,
|
|
2433
2435
|
"VisionTocExtractor",
|
|
2434
|
-
|
|
2436
|
+
artifactDir,
|
|
2435
2437
|
options,
|
|
2436
2438
|
fallbackModel,
|
|
2437
2439
|
aggregator ?? new LLMTokenUsageAggregator()
|
|
@@ -2564,7 +2566,7 @@ var VisionTocExtractor = class extends VisionLLMComponent {
|
|
|
2564
2566
|
const imageContents = [];
|
|
2565
2567
|
for (let pageNo = startPage; pageNo <= endPage; pageNo++) {
|
|
2566
2568
|
const imagePath = path2.resolve(
|
|
2567
|
-
this.
|
|
2569
|
+
this.artifactDir,
|
|
2568
2570
|
`pages/page_${pageNo - 1}.png`
|
|
2569
2571
|
);
|
|
2570
2572
|
const imageData = new Uint8Array(fs2.readFileSync(imagePath));
|
|
@@ -2974,12 +2976,12 @@ var PageRangeParser = class extends VisionLLMComponent {
|
|
|
2974
2976
|
SAMPLE_SIZE = 3;
|
|
2975
2977
|
MAX_PATTERN_RETRIES = 19;
|
|
2976
2978
|
SIZE_TOLERANCE = 5;
|
|
2977
|
-
constructor(logger, model,
|
|
2979
|
+
constructor(logger, model, artifactDir, maxRetries = 3, fallbackModel, aggregator, abortSignal) {
|
|
2978
2980
|
super(
|
|
2979
2981
|
logger,
|
|
2980
2982
|
model,
|
|
2981
2983
|
"PageRangeParser",
|
|
2982
|
-
|
|
2984
|
+
artifactDir,
|
|
2983
2985
|
{ maxRetries, abortSignal },
|
|
2984
2986
|
fallbackModel,
|
|
2985
2987
|
aggregator ?? new LLMTokenUsageAggregator()
|
|
@@ -3178,7 +3180,7 @@ var PageRangeParser = class extends VisionLLMComponent {
|
|
|
3178
3180
|
const imageContentsFromPages = pageNos.map((pageNo) => {
|
|
3179
3181
|
const page = pages[pageNo - 1];
|
|
3180
3182
|
const imagePath = path3.resolve(
|
|
3181
|
-
this.
|
|
3183
|
+
this.artifactDir,
|
|
3182
3184
|
`pages/page_${pageNo - 1}.png`
|
|
3183
3185
|
);
|
|
3184
3186
|
const imageData = new Uint8Array(fs3.readFileSync(imagePath));
|
|
@@ -4362,6 +4364,7 @@ var DocumentProcessor = class {
|
|
|
4362
4364
|
captionParserBatchSize;
|
|
4363
4365
|
captionValidatorBatchSize;
|
|
4364
4366
|
maxRetries;
|
|
4367
|
+
maxValidationRetries;
|
|
4365
4368
|
enableFallbackRetry;
|
|
4366
4369
|
abortSignal;
|
|
4367
4370
|
onTokenUsage;
|
|
@@ -4391,6 +4394,7 @@ var DocumentProcessor = class {
|
|
|
4391
4394
|
this.captionParserBatchSize = options.captionParserBatchSize;
|
|
4392
4395
|
this.captionValidatorBatchSize = options.captionValidatorBatchSize;
|
|
4393
4396
|
this.maxRetries = options.maxRetries ?? 3;
|
|
4397
|
+
this.maxValidationRetries = options.maxValidationRetries ?? 3;
|
|
4394
4398
|
this.enableFallbackRetry = options.enableFallbackRetry ?? false;
|
|
4395
4399
|
this.abortSignal = options.abortSignal;
|
|
4396
4400
|
this.onTokenUsage = options.onTokenUsage;
|
|
@@ -4422,7 +4426,7 @@ var DocumentProcessor = class {
|
|
|
4422
4426
|
* Conversion process:
|
|
4423
4427
|
* 1. Initialize processors and resolvers
|
|
4424
4428
|
* 2. Normalize and filter texts
|
|
4425
|
-
* 3. Clean texts and
|
|
4429
|
+
* 3. Clean texts and resolve page ranges
|
|
4426
4430
|
* 4. Extract table of contents
|
|
4427
4431
|
* 5. Convert images and tables (parallel)
|
|
4428
4432
|
* 6. Convert chapters and link resources
|
|
@@ -4431,19 +4435,20 @@ var DocumentProcessor = class {
|
|
|
4431
4435
|
*
|
|
4432
4436
|
* @param doclingDoc - Original document extracted from Docling SDK
|
|
4433
4437
|
* @param reportId - Report unique identifier
|
|
4434
|
-
* @param
|
|
4438
|
+
* @param artifactDir - Directory containing parser artifacts such as images/, pages/, and result.json
|
|
4439
|
+
* @param processOptions - Per-document processing inputs such as manually verified page range mappings and TOC entries
|
|
4435
4440
|
* @returns Document processing result with ProcessedDocument and token usage report
|
|
4436
4441
|
*
|
|
4437
4442
|
* @throws {TocExtractError} When TOC extraction fails
|
|
4438
4443
|
* @throws {PageRangeParseError} When page range parsing fails
|
|
4439
4444
|
* @throws {ConversionError} When error occurs during conversion
|
|
4440
4445
|
*/
|
|
4441
|
-
async process(doclingDoc, reportId,
|
|
4446
|
+
async process(doclingDoc, reportId, artifactDir, processOptions = {}) {
|
|
4442
4447
|
this.logger.info("[DocumentProcessor] Starting document processing...");
|
|
4443
4448
|
this.logger.info("[DocumentProcessor] Report ID:", reportId);
|
|
4444
4449
|
this.usageAggregator.reset();
|
|
4445
4450
|
this.checkAborted();
|
|
4446
|
-
this.initializeProcessors(doclingDoc,
|
|
4451
|
+
this.initializeProcessors(doclingDoc, artifactDir);
|
|
4447
4452
|
const startTimeFilter = Date.now();
|
|
4448
4453
|
const filtered = this.normalizeAndFilterTexts(doclingDoc);
|
|
4449
4454
|
const filteringTime = Date.now() - startTimeFilter;
|
|
@@ -4452,24 +4457,31 @@ var DocumentProcessor = class {
|
|
|
4452
4457
|
);
|
|
4453
4458
|
this.checkAborted();
|
|
4454
4459
|
const startTimePageRange = Date.now();
|
|
4455
|
-
const pageRangeMap = await this.parsePageRanges(doclingDoc);
|
|
4460
|
+
const pageRangeMap = processOptions.pageRangeMap !== void 0 ? processOptions.pageRangeMap : await this.parsePageRanges(doclingDoc);
|
|
4461
|
+
if (processOptions.pageRangeMap !== void 0) {
|
|
4462
|
+
this.logger.info(
|
|
4463
|
+
`[DocumentProcessor] Using injected page range map with ${Object.keys(pageRangeMap).length} entries`
|
|
4464
|
+
);
|
|
4465
|
+
}
|
|
4456
4466
|
const pageRangeTime = Date.now() - startTimePageRange;
|
|
4457
4467
|
this.logger.info(
|
|
4458
|
-
`[DocumentProcessor] Page range
|
|
4468
|
+
`[DocumentProcessor] Page range resolution took ${pageRangeTime}ms`
|
|
4459
4469
|
);
|
|
4460
4470
|
this.emitTokenUsage();
|
|
4461
4471
|
this.checkAborted();
|
|
4462
4472
|
const startTimeToc = Date.now();
|
|
4463
|
-
const tocEntries = await this.tocExtractionPipeline.extract(
|
|
4464
|
-
|
|
4465
|
-
|
|
4466
|
-
|
|
4473
|
+
const tocEntries = processOptions.tocEntries !== void 0 ? processOptions.tocEntries : await this.tocExtractionPipeline.extract(doclingDoc, filtered);
|
|
4474
|
+
if (processOptions.tocEntries !== void 0) {
|
|
4475
|
+
this.logger.info(
|
|
4476
|
+
`[DocumentProcessor] Using injected TOC entries with ${tocEntries.length} top-level entries`
|
|
4477
|
+
);
|
|
4478
|
+
}
|
|
4467
4479
|
const tocTime = Date.now() - startTimeToc;
|
|
4468
4480
|
this.logger.info(`[DocumentProcessor] TOC extraction took ${tocTime}ms`);
|
|
4469
4481
|
this.emitTokenUsage();
|
|
4470
4482
|
this.checkAborted();
|
|
4471
4483
|
const startTimeResources = Date.now();
|
|
4472
|
-
const { images, tables, footnotes } = await this.resourceConverter.convertAll(doclingDoc,
|
|
4484
|
+
const { images, tables, footnotes } = await this.resourceConverter.convertAll(doclingDoc, artifactDir);
|
|
4473
4485
|
const resourcesTime = Date.now() - startTimeResources;
|
|
4474
4486
|
this.logger.info(
|
|
4475
4487
|
`[DocumentProcessor] Resource conversion took ${resourcesTime}ms`
|
|
@@ -4513,7 +4525,7 @@ var DocumentProcessor = class {
|
|
|
4513
4525
|
*
|
|
4514
4526
|
* Sets up RefResolver, PageRangeParser, TocFinder, and TocExtractor
|
|
4515
4527
|
*/
|
|
4516
|
-
initializeProcessors(doclingDoc,
|
|
4528
|
+
initializeProcessors(doclingDoc, artifactDir) {
|
|
4517
4529
|
this.logger.info("[DocumentProcessor] Initializing processors...");
|
|
4518
4530
|
this.logger.info("[DocumentProcessor] - RefResolver");
|
|
4519
4531
|
this.refResolver = new RefResolver(this.logger, doclingDoc);
|
|
@@ -4521,7 +4533,7 @@ var DocumentProcessor = class {
|
|
|
4521
4533
|
this.pageRangeParser = new PageRangeParser(
|
|
4522
4534
|
this.logger,
|
|
4523
4535
|
this.pageRangeParserModel,
|
|
4524
|
-
|
|
4536
|
+
artifactDir,
|
|
4525
4537
|
this.maxRetries,
|
|
4526
4538
|
this.enableFallbackRetry ? this.fallbackModel : void 0,
|
|
4527
4539
|
this.usageAggregator,
|
|
@@ -4534,7 +4546,8 @@ var DocumentProcessor = class {
|
|
|
4534
4546
|
this.logger,
|
|
4535
4547
|
this.tocExtractorModel,
|
|
4536
4548
|
{
|
|
4537
|
-
maxRetries: this.maxRetries
|
|
4549
|
+
maxRetries: this.maxRetries,
|
|
4550
|
+
maxValidationRetries: this.maxValidationRetries
|
|
4538
4551
|
},
|
|
4539
4552
|
this.enableFallbackRetry ? this.fallbackModel : void 0,
|
|
4540
4553
|
this.abortSignal
|
|
@@ -4559,7 +4572,7 @@ var DocumentProcessor = class {
|
|
|
4559
4572
|
this.visionTocExtractor = new VisionTocExtractor(
|
|
4560
4573
|
this.logger,
|
|
4561
4574
|
this.visionTocExtractorModel,
|
|
4562
|
-
|
|
4575
|
+
artifactDir,
|
|
4563
4576
|
{ maxRetries: this.maxRetries, abortSignal: this.abortSignal },
|
|
4564
4577
|
this.enableFallbackRetry ? this.fallbackModel : void 0,
|
|
4565
4578
|
this.usageAggregator
|