@heripo/document-processor 0.1.22 → 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/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, outputPath) {
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, outputPath),
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, outputPath) {
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: `${outputPath}/images/image_${index}.png`,
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 MAX_VALIDATION_RETRIES = 3;
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 MAX_VALIDATION_RETRIES times.
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 <= MAX_VALIDATION_RETRIES && validationError !== null; attempt++) {
2154
+ for (let attempt = 1; attempt <= this.maxValidationRetries && validationError !== null; attempt++) {
2153
2155
  this.log(
2154
2156
  "warn",
2155
- `Validation failed (attempt ${attempt}/${MAX_VALIDATION_RETRIES}), retrying with correction feedback`
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 ${MAX_VALIDATION_RETRIES} retries:
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
- outputPath;
2371
- constructor(logger, model, componentName, outputPath, options, fallbackModel, aggregator) {
2372
+ artifactDir;
2373
+ constructor(logger, model, componentName, artifactDir, options, fallbackModel, aggregator) {
2372
2374
  super(logger, model, componentName, options, fallbackModel, aggregator);
2373
- this.outputPath = outputPath;
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 outputPath or absolute)
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.outputPath, imagePath);
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, outputPath, options, fallbackModel, aggregator) {
2431
+ constructor(logger, model, artifactDir, options, fallbackModel, aggregator) {
2430
2432
  super(
2431
2433
  logger,
2432
2434
  model,
2433
2435
  "VisionTocExtractor",
2434
- outputPath,
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.outputPath,
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, outputPath, maxRetries = 3, fallbackModel, aggregator, abortSignal) {
2979
+ constructor(logger, model, artifactDir, maxRetries = 3, fallbackModel, aggregator, abortSignal) {
2978
2980
  super(
2979
2981
  logger,
2980
2982
  model,
2981
2983
  "PageRangeParser",
2982
- outputPath,
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.outputPath,
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 parse page ranges (parallel)
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 outputPath - Path containing images and pages subdirectories (images/image_0.png, pages/page_0.png, etc.)
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, outputPath) {
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, outputPath);
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 parsing took ${pageRangeTime}ms`
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
- doclingDoc,
4465
- filtered
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, outputPath);
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, outputPath) {
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
- outputPath,
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
- outputPath,
4575
+ artifactDir,
4563
4576
  { maxRetries: this.maxRetries, abortSignal: this.abortSignal },
4564
4577
  this.enableFallbackRetry ? this.fallbackModel : void 0,
4565
4578
  this.usageAggregator