@heripo/pdf-parser 0.1.33 → 0.1.35
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.cjs +127 -132
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +127 -132
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/dist/index.d.cts
CHANGED
|
@@ -54,6 +54,12 @@ interface PDFCorrectionOptions {
|
|
|
54
54
|
* Enabled by the engine demo; defaults to false everywhere else.
|
|
55
55
|
*/
|
|
56
56
|
forceAutoApply?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* When false, the review-assistance stage (the per-page eligibility gate plus
|
|
59
|
+
* the structural review-assistance runner) is skipped entirely and only the
|
|
60
|
+
* text-correction stage runs. Defaults to true.
|
|
61
|
+
*/
|
|
62
|
+
reviewAssistanceEnabled?: boolean;
|
|
57
63
|
temperature?: number;
|
|
58
64
|
}
|
|
59
65
|
interface NormalizedPDFCorrectionOptions {
|
|
@@ -67,6 +73,7 @@ interface NormalizedPDFCorrectionOptions {
|
|
|
67
73
|
autoApplyThreshold: number;
|
|
68
74
|
proposalThreshold: number;
|
|
69
75
|
forceAutoApply: boolean;
|
|
76
|
+
reviewAssistanceEnabled: boolean;
|
|
70
77
|
temperature: number;
|
|
71
78
|
}
|
|
72
79
|
declare const PDF_CORRECTION_DEFAULTS: Omit<NormalizedPDFCorrectionOptions, 'models'>;
|
package/dist/index.d.ts
CHANGED
|
@@ -54,6 +54,12 @@ interface PDFCorrectionOptions {
|
|
|
54
54
|
* Enabled by the engine demo; defaults to false everywhere else.
|
|
55
55
|
*/
|
|
56
56
|
forceAutoApply?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* When false, the review-assistance stage (the per-page eligibility gate plus
|
|
59
|
+
* the structural review-assistance runner) is skipped entirely and only the
|
|
60
|
+
* text-correction stage runs. Defaults to true.
|
|
61
|
+
*/
|
|
62
|
+
reviewAssistanceEnabled?: boolean;
|
|
57
63
|
temperature?: number;
|
|
58
64
|
}
|
|
59
65
|
interface NormalizedPDFCorrectionOptions {
|
|
@@ -67,6 +73,7 @@ interface NormalizedPDFCorrectionOptions {
|
|
|
67
73
|
autoApplyThreshold: number;
|
|
68
74
|
proposalThreshold: number;
|
|
69
75
|
forceAutoApply: boolean;
|
|
76
|
+
reviewAssistanceEnabled: boolean;
|
|
70
77
|
temperature: number;
|
|
71
78
|
}
|
|
72
79
|
declare const PDF_CORRECTION_DEFAULTS: Omit<NormalizedPDFCorrectionOptions, 'models'>;
|
package/dist/index.js
CHANGED
|
@@ -343,6 +343,29 @@ var LLMCaller = class {
|
|
|
343
343
|
function formatTokens(usage) {
|
|
344
344
|
return `${usage.inputTokens} input, ${usage.outputTokens} output, ${usage.totalTokens} total`;
|
|
345
345
|
}
|
|
346
|
+
function emptyUsage() {
|
|
347
|
+
return { inputTokens: 0, outputTokens: 0, totalTokens: 0 };
|
|
348
|
+
}
|
|
349
|
+
function addInto(target, src) {
|
|
350
|
+
target.inputTokens += src.inputTokens;
|
|
351
|
+
target.outputTokens += src.outputTokens;
|
|
352
|
+
target.totalTokens += src.totalTokens;
|
|
353
|
+
}
|
|
354
|
+
function sumUsage(a, b) {
|
|
355
|
+
return {
|
|
356
|
+
inputTokens: (a?.inputTokens ?? 0) + (b?.inputTokens ?? 0),
|
|
357
|
+
outputTokens: (a?.outputTokens ?? 0) + (b?.outputTokens ?? 0),
|
|
358
|
+
totalTokens: (a?.totalTokens ?? 0) + (b?.totalTokens ?? 0)
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
function accumulateModel(bucket, modelName, usage) {
|
|
362
|
+
let entry = bucket.get(modelName);
|
|
363
|
+
if (!entry) {
|
|
364
|
+
entry = emptyUsage();
|
|
365
|
+
bucket.set(modelName, entry);
|
|
366
|
+
}
|
|
367
|
+
addInto(entry, usage);
|
|
368
|
+
}
|
|
346
369
|
var LLMTokenUsageAggregator = class {
|
|
347
370
|
usage = {};
|
|
348
371
|
/**
|
|
@@ -355,21 +378,15 @@ var LLMTokenUsageAggregator = class {
|
|
|
355
378
|
this.usage[usage.component] = {
|
|
356
379
|
component: usage.component,
|
|
357
380
|
phases: {},
|
|
358
|
-
total:
|
|
359
|
-
inputTokens: 0,
|
|
360
|
-
outputTokens: 0,
|
|
361
|
-
totalTokens: 0
|
|
362
|
-
}
|
|
381
|
+
total: emptyUsage()
|
|
363
382
|
};
|
|
364
383
|
}
|
|
365
384
|
const component = this.usage[usage.component];
|
|
366
385
|
if (!component.phases[usage.phase]) {
|
|
367
386
|
component.phases[usage.phase] = {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
totalTokens: 0
|
|
372
|
-
},
|
|
387
|
+
primary: /* @__PURE__ */ new Map(),
|
|
388
|
+
fallback: /* @__PURE__ */ new Map(),
|
|
389
|
+
total: emptyUsage(),
|
|
373
390
|
metadata: []
|
|
374
391
|
};
|
|
375
392
|
}
|
|
@@ -378,41 +395,17 @@ var LLMTokenUsageAggregator = class {
|
|
|
378
395
|
phase.metadata.push(usage.metadata);
|
|
379
396
|
}
|
|
380
397
|
if (usage.model === "primary") {
|
|
381
|
-
|
|
382
|
-
phase.primary = {
|
|
383
|
-
modelName: usage.modelName,
|
|
384
|
-
inputTokens: 0,
|
|
385
|
-
outputTokens: 0,
|
|
386
|
-
totalTokens: 0
|
|
387
|
-
};
|
|
388
|
-
}
|
|
389
|
-
phase.primary.inputTokens += usage.inputTokens;
|
|
390
|
-
phase.primary.outputTokens += usage.outputTokens;
|
|
391
|
-
phase.primary.totalTokens += usage.totalTokens;
|
|
398
|
+
accumulateModel(phase.primary, usage.modelName, usage);
|
|
392
399
|
} else if (usage.model === "fallback") {
|
|
393
|
-
|
|
394
|
-
phase.fallback = {
|
|
395
|
-
modelName: usage.modelName,
|
|
396
|
-
inputTokens: 0,
|
|
397
|
-
outputTokens: 0,
|
|
398
|
-
totalTokens: 0
|
|
399
|
-
};
|
|
400
|
-
}
|
|
401
|
-
phase.fallback.inputTokens += usage.inputTokens;
|
|
402
|
-
phase.fallback.outputTokens += usage.outputTokens;
|
|
403
|
-
phase.fallback.totalTokens += usage.totalTokens;
|
|
400
|
+
accumulateModel(phase.fallback, usage.modelName, usage);
|
|
404
401
|
}
|
|
405
|
-
phase.total
|
|
406
|
-
|
|
407
|
-
phase.total.totalTokens += usage.totalTokens;
|
|
408
|
-
component.total.inputTokens += usage.inputTokens;
|
|
409
|
-
component.total.outputTokens += usage.outputTokens;
|
|
410
|
-
component.total.totalTokens += usage.totalTokens;
|
|
402
|
+
addInto(phase.total, usage);
|
|
403
|
+
addInto(component.total, usage);
|
|
411
404
|
}
|
|
412
405
|
/**
|
|
413
406
|
* Get aggregated usage grouped by component
|
|
414
407
|
*
|
|
415
|
-
* @returns Array of component aggregates with phase breakdown
|
|
408
|
+
* @returns Array of component aggregates with per-model phase breakdown
|
|
416
409
|
*/
|
|
417
410
|
getByComponent() {
|
|
418
411
|
return Object.values(this.usage);
|
|
@@ -421,8 +414,16 @@ var LLMTokenUsageAggregator = class {
|
|
|
421
414
|
* Get token usage report in structured JSON format
|
|
422
415
|
*
|
|
423
416
|
* Converts internal usage data to external TokenUsageReport format suitable
|
|
424
|
-
* for serialization and reporting.
|
|
425
|
-
*
|
|
417
|
+
* for serialization and reporting.
|
|
418
|
+
*
|
|
419
|
+
* Each (phase, model) pair becomes its own PhaseUsageReport entry. A phase
|
|
420
|
+
* that used a single primary (and/or a single fallback) model yields exactly
|
|
421
|
+
* one entry — identical to the legacy shape — while a phase that mixed models
|
|
422
|
+
* yields one entry per model, all sharing the same `phase` name. Every
|
|
423
|
+
* (phase, tier, modelName) combination appears in exactly one entry, so
|
|
424
|
+
* consumers that key by `${component}|${phase}|${tier}|${modelName}`
|
|
425
|
+
* (heripo-web's token-usage emitter / ledger recorder) attribute each model's
|
|
426
|
+
* tokens — and cost — correctly without double counting.
|
|
426
427
|
*
|
|
427
428
|
* @returns Structured token usage report with components and total
|
|
428
429
|
*/
|
|
@@ -431,34 +432,41 @@ var LLMTokenUsageAggregator = class {
|
|
|
431
432
|
for (const component of Object.values(this.usage)) {
|
|
432
433
|
const phases = [];
|
|
433
434
|
for (const [phaseName, phaseData] of Object.entries(component.phases)) {
|
|
434
|
-
const
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
}
|
|
445
|
-
if (phaseData.primary) {
|
|
446
|
-
phaseReport.primary = {
|
|
447
|
-
modelName: phaseData.primary.modelName,
|
|
448
|
-
inputTokens: phaseData.primary.inputTokens,
|
|
449
|
-
outputTokens: phaseData.primary.outputTokens,
|
|
450
|
-
totalTokens: phaseData.primary.totalTokens
|
|
435
|
+
const primaryEntries = [...phaseData.primary.entries()];
|
|
436
|
+
const fallbackEntries = [...phaseData.fallback.entries()];
|
|
437
|
+
const entryCount = Math.max(
|
|
438
|
+
primaryEntries.length,
|
|
439
|
+
fallbackEntries.length
|
|
440
|
+
);
|
|
441
|
+
if (entryCount === 0) {
|
|
442
|
+
const phaseReport = {
|
|
443
|
+
phase: phaseName,
|
|
444
|
+
total: { ...phaseData.total }
|
|
451
445
|
};
|
|
446
|
+
if (phaseData.metadata.length > 0) {
|
|
447
|
+
phaseReport.metadata = [...phaseData.metadata];
|
|
448
|
+
}
|
|
449
|
+
phases.push(phaseReport);
|
|
450
|
+
continue;
|
|
452
451
|
}
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
452
|
+
for (let i = 0; i < entryCount; i++) {
|
|
453
|
+
const primary = primaryEntries[i];
|
|
454
|
+
const fallback = fallbackEntries[i];
|
|
455
|
+
const phaseReport = {
|
|
456
|
+
phase: phaseName,
|
|
457
|
+
total: sumUsage(primary?.[1], fallback?.[1])
|
|
459
458
|
};
|
|
459
|
+
if (primary) {
|
|
460
|
+
phaseReport.primary = { modelName: primary[0], ...primary[1] };
|
|
461
|
+
}
|
|
462
|
+
if (fallback) {
|
|
463
|
+
phaseReport.fallback = { modelName: fallback[0], ...fallback[1] };
|
|
464
|
+
}
|
|
465
|
+
if (i === 0 && phaseData.metadata.length > 0) {
|
|
466
|
+
phaseReport.metadata = [...phaseData.metadata];
|
|
467
|
+
}
|
|
468
|
+
phases.push(phaseReport);
|
|
460
469
|
}
|
|
461
|
-
phases.push(phaseReport);
|
|
462
470
|
}
|
|
463
471
|
components.push({
|
|
464
472
|
component: component.component,
|
|
@@ -503,8 +511,8 @@ var LLMTokenUsageAggregator = class {
|
|
|
503
511
|
/**
|
|
504
512
|
* Log comprehensive token usage summary
|
|
505
513
|
*
|
|
506
|
-
* Outputs usage grouped by component, with phase and model breakdown.
|
|
507
|
-
* Shows primary and fallback
|
|
514
|
+
* Outputs usage grouped by component, with phase and per-model breakdown.
|
|
515
|
+
* Shows each primary and fallback model on its own line for each phase.
|
|
508
516
|
* Call this once at the end of document processing.
|
|
509
517
|
*
|
|
510
518
|
* @param logger - Logger instance for output
|
|
@@ -520,31 +528,23 @@ var LLMTokenUsageAggregator = class {
|
|
|
520
528
|
let grandInputTokens = 0;
|
|
521
529
|
let grandOutputTokens = 0;
|
|
522
530
|
let grandTotalTokens = 0;
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
let grandPrimaryTotalTokens = 0;
|
|
526
|
-
let grandFallbackInputTokens = 0;
|
|
527
|
-
let grandFallbackOutputTokens = 0;
|
|
528
|
-
let grandFallbackTotalTokens = 0;
|
|
531
|
+
const grandPrimary = emptyUsage();
|
|
532
|
+
const grandFallback = emptyUsage();
|
|
529
533
|
for (const component of components) {
|
|
530
534
|
logger.info(`${component.component}:`);
|
|
531
|
-
for (const [
|
|
532
|
-
logger.info(` - ${
|
|
533
|
-
|
|
535
|
+
for (const [phaseName, phaseData] of Object.entries(component.phases)) {
|
|
536
|
+
logger.info(` - ${phaseName}:`);
|
|
537
|
+
for (const [modelName, modelUsage] of phaseData.primary) {
|
|
534
538
|
logger.info(
|
|
535
|
-
` primary (${
|
|
539
|
+
` primary (${modelName}): ${formatTokens(modelUsage)}`
|
|
536
540
|
);
|
|
537
|
-
|
|
538
|
-
grandPrimaryOutputTokens += phaseData.primary.outputTokens;
|
|
539
|
-
grandPrimaryTotalTokens += phaseData.primary.totalTokens;
|
|
541
|
+
addInto(grandPrimary, modelUsage);
|
|
540
542
|
}
|
|
541
|
-
|
|
543
|
+
for (const [modelName, modelUsage] of phaseData.fallback) {
|
|
542
544
|
logger.info(
|
|
543
|
-
` fallback (${
|
|
545
|
+
` fallback (${modelName}): ${formatTokens(modelUsage)}`
|
|
544
546
|
);
|
|
545
|
-
|
|
546
|
-
grandFallbackOutputTokens += phaseData.fallback.outputTokens;
|
|
547
|
-
grandFallbackTotalTokens += phaseData.fallback.totalTokens;
|
|
547
|
+
addInto(grandFallback, modelUsage);
|
|
548
548
|
}
|
|
549
549
|
logger.info(` subtotal: ${formatTokens(phaseData.total)}`);
|
|
550
550
|
}
|
|
@@ -557,23 +557,11 @@ var LLMTokenUsageAggregator = class {
|
|
|
557
557
|
grandTotalTokens += component.total.totalTokens;
|
|
558
558
|
}
|
|
559
559
|
logger.info("--- Summary ---");
|
|
560
|
-
if (
|
|
561
|
-
logger.info(
|
|
562
|
-
`Primary total: ${formatTokens({
|
|
563
|
-
inputTokens: grandPrimaryInputTokens,
|
|
564
|
-
outputTokens: grandPrimaryOutputTokens,
|
|
565
|
-
totalTokens: grandPrimaryTotalTokens
|
|
566
|
-
})}`
|
|
567
|
-
);
|
|
560
|
+
if (grandPrimary.totalTokens > 0) {
|
|
561
|
+
logger.info(`Primary total: ${formatTokens(grandPrimary)}`);
|
|
568
562
|
}
|
|
569
|
-
if (
|
|
570
|
-
logger.info(
|
|
571
|
-
`Fallback total: ${formatTokens({
|
|
572
|
-
inputTokens: grandFallbackInputTokens,
|
|
573
|
-
outputTokens: grandFallbackOutputTokens,
|
|
574
|
-
totalTokens: grandFallbackTotalTokens
|
|
575
|
-
})}`
|
|
576
|
-
);
|
|
563
|
+
if (grandFallback.totalTokens > 0) {
|
|
564
|
+
logger.info(`Fallback total: ${formatTokens(grandFallback)}`);
|
|
577
565
|
}
|
|
578
566
|
logger.info(
|
|
579
567
|
`Grand total: ${formatTokens({
|
|
@@ -10449,6 +10437,7 @@ var PDF_CORRECTION_DEFAULTS = {
|
|
|
10449
10437
|
autoApplyThreshold: 0.85,
|
|
10450
10438
|
proposalThreshold: 0.5,
|
|
10451
10439
|
forceAutoApply: false,
|
|
10440
|
+
reviewAssistanceEnabled: true,
|
|
10452
10441
|
temperature: 0
|
|
10453
10442
|
};
|
|
10454
10443
|
function normalizeNumber(value, fallback) {
|
|
@@ -10548,6 +10537,7 @@ function normalizePDFCorrectionOptions(value) {
|
|
|
10548
10537
|
autoApplyThreshold,
|
|
10549
10538
|
proposalThreshold,
|
|
10550
10539
|
forceAutoApply: value.forceAutoApply ?? PDF_CORRECTION_DEFAULTS.forceAutoApply,
|
|
10540
|
+
reviewAssistanceEnabled: value.reviewAssistanceEnabled ?? PDF_CORRECTION_DEFAULTS.reviewAssistanceEnabled,
|
|
10551
10541
|
temperature: normalizeTemperature(
|
|
10552
10542
|
value.temperature,
|
|
10553
10543
|
PDF_CORRECTION_DEFAULTS.temperature
|
|
@@ -10581,44 +10571,49 @@ var PostDoclingCorrectionPipeline = class {
|
|
|
10581
10571
|
onTokenUsage: options.onTokenUsage,
|
|
10582
10572
|
documentLanguages: options.ocr_lang,
|
|
10583
10573
|
pageTexts,
|
|
10584
|
-
|
|
10574
|
+
// When review assistance is disabled, omit the gate entirely so the
|
|
10575
|
+
// per-page eligibility checks (pageGate LLM calls + sidecar report)
|
|
10576
|
+
// never run — only text correction executes.
|
|
10577
|
+
reviewAssistanceGate: correction.reviewAssistanceEnabled ? {
|
|
10585
10578
|
model: correction.models.pageGate,
|
|
10586
10579
|
fallback: correction.models.pageGateFallback,
|
|
10587
10580
|
maxRetries: correction.maxRetries.pageGate,
|
|
10588
10581
|
temperature: correction.temperature,
|
|
10589
10582
|
outputLanguage: correction.outputLanguage
|
|
10590
|
-
}
|
|
10591
|
-
}
|
|
10592
|
-
);
|
|
10593
|
-
const runner = new ReviewAssistanceRunner(this.logger);
|
|
10594
|
-
await runner.analyzeAndSave(
|
|
10595
|
-
outputDir,
|
|
10596
|
-
reportId,
|
|
10597
|
-
this.buildReviewAssistanceModelResolver(correction),
|
|
10598
|
-
{
|
|
10599
|
-
pdfPath,
|
|
10600
|
-
pageTexts,
|
|
10601
|
-
pageGateModel: correction.models.pageGate,
|
|
10602
|
-
pageGateFallback: correction.models.pageGateFallback,
|
|
10603
|
-
pageGateMaxRetries: correction.maxRetries.pageGate,
|
|
10604
|
-
pageGateTemperature: correction.temperature,
|
|
10605
|
-
pageConcurrency: correction.concurrency.pages,
|
|
10606
|
-
taskConcurrency: correction.concurrency.reviewTasks,
|
|
10607
|
-
modelConcurrency: correction.modelConcurrency,
|
|
10608
|
-
workItemTimeoutMs: correction.workItemTimeoutMs,
|
|
10609
|
-
autoApplyThreshold: correction.autoApplyThreshold,
|
|
10610
|
-
proposalThreshold: correction.proposalThreshold,
|
|
10611
|
-
forceAutoApply: correction.forceAutoApply,
|
|
10612
|
-
maxRetries: correction.maxRetries.reviewAssistance,
|
|
10613
|
-
tableMaxRetries: correction.maxRetries.tableCorrection,
|
|
10614
|
-
temperature: correction.temperature,
|
|
10615
|
-
outputLanguage: correction.outputLanguage,
|
|
10616
|
-
aggregator: options.aggregator,
|
|
10617
|
-
abortSignal,
|
|
10618
|
-
onTokenUsage: options.onTokenUsage,
|
|
10619
|
-
onProgress: options.onReviewAssistanceProgress
|
|
10583
|
+
} : void 0
|
|
10620
10584
|
}
|
|
10621
10585
|
);
|
|
10586
|
+
if (correction.reviewAssistanceEnabled) {
|
|
10587
|
+
const runner = new ReviewAssistanceRunner(this.logger);
|
|
10588
|
+
await runner.analyzeAndSave(
|
|
10589
|
+
outputDir,
|
|
10590
|
+
reportId,
|
|
10591
|
+
this.buildReviewAssistanceModelResolver(correction),
|
|
10592
|
+
{
|
|
10593
|
+
pdfPath,
|
|
10594
|
+
pageTexts,
|
|
10595
|
+
pageGateModel: correction.models.pageGate,
|
|
10596
|
+
pageGateFallback: correction.models.pageGateFallback,
|
|
10597
|
+
pageGateMaxRetries: correction.maxRetries.pageGate,
|
|
10598
|
+
pageGateTemperature: correction.temperature,
|
|
10599
|
+
pageConcurrency: correction.concurrency.pages,
|
|
10600
|
+
taskConcurrency: correction.concurrency.reviewTasks,
|
|
10601
|
+
modelConcurrency: correction.modelConcurrency,
|
|
10602
|
+
workItemTimeoutMs: correction.workItemTimeoutMs,
|
|
10603
|
+
autoApplyThreshold: correction.autoApplyThreshold,
|
|
10604
|
+
proposalThreshold: correction.proposalThreshold,
|
|
10605
|
+
forceAutoApply: correction.forceAutoApply,
|
|
10606
|
+
maxRetries: correction.maxRetries.reviewAssistance,
|
|
10607
|
+
tableMaxRetries: correction.maxRetries.tableCorrection,
|
|
10608
|
+
temperature: correction.temperature,
|
|
10609
|
+
outputLanguage: correction.outputLanguage,
|
|
10610
|
+
aggregator: options.aggregator,
|
|
10611
|
+
abortSignal,
|
|
10612
|
+
onTokenUsage: options.onTokenUsage,
|
|
10613
|
+
onProgress: options.onReviewAssistanceProgress
|
|
10614
|
+
}
|
|
10615
|
+
);
|
|
10616
|
+
}
|
|
10622
10617
|
await originalCallback(outputDir);
|
|
10623
10618
|
};
|
|
10624
10619
|
}
|