@heripo/pdf-parser 0.1.32 → 0.1.34
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 +118 -107
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +118 -107
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.d.cts
CHANGED
|
@@ -9,10 +9,20 @@ type ReviewAssistanceTaskId = 'text_ocr_hanja' | 'text_integrity' | 'text_role_f
|
|
|
9
9
|
|
|
10
10
|
interface PDFCorrectionModelOptions {
|
|
11
11
|
textCorrection: LanguageModel;
|
|
12
|
+
/** textCorrection 실패(예: lmstudio 400) 시 LLMCaller fallback. */
|
|
13
|
+
textCorrectionFallback?: LanguageModel;
|
|
12
14
|
pageGate: LanguageModel;
|
|
15
|
+
/** pageGate(page-eligibility) 실패 시 fallback. */
|
|
16
|
+
pageGateFallback?: LanguageModel;
|
|
13
17
|
reviewAssistance: LanguageModel;
|
|
18
|
+
/** review-assistance 공통 fallback (task별 미지정 시 사용). */
|
|
19
|
+
reviewAssistanceFallback?: LanguageModel;
|
|
14
20
|
reviewAssistanceTasks?: Partial<Record<ReviewAssistanceTaskId, LanguageModel>>;
|
|
21
|
+
/** review-assistance task별 fallback. */
|
|
22
|
+
reviewAssistanceTasksFallback?: Partial<Record<ReviewAssistanceTaskId, LanguageModel>>;
|
|
15
23
|
tableCorrection?: LanguageModel;
|
|
24
|
+
/** tableCorrection 실패 시 fallback. */
|
|
25
|
+
tableCorrectionFallback?: LanguageModel;
|
|
16
26
|
}
|
|
17
27
|
interface PDFCorrectionConcurrencyOptions {
|
|
18
28
|
pages?: number;
|
|
@@ -93,6 +103,8 @@ type PDFConvertOptions = Omit<ConversionOptions, 'to_formats' | 'image_export_mo
|
|
|
93
103
|
chunkMaxRetries?: number;
|
|
94
104
|
/** Vision model for document language detection when the PDF text layer is insufficient */
|
|
95
105
|
languageDetectionModel?: LanguageModel;
|
|
106
|
+
/** languageDetectionModel 실패 시 fallback. */
|
|
107
|
+
languageDetectionFallbackModel?: LanguageModel;
|
|
96
108
|
/** LLM model for document type validation (opt-in: skipped when not set) */
|
|
97
109
|
documentValidationModel?: LanguageModel;
|
|
98
110
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -9,10 +9,20 @@ type ReviewAssistanceTaskId = 'text_ocr_hanja' | 'text_integrity' | 'text_role_f
|
|
|
9
9
|
|
|
10
10
|
interface PDFCorrectionModelOptions {
|
|
11
11
|
textCorrection: LanguageModel;
|
|
12
|
+
/** textCorrection 실패(예: lmstudio 400) 시 LLMCaller fallback. */
|
|
13
|
+
textCorrectionFallback?: LanguageModel;
|
|
12
14
|
pageGate: LanguageModel;
|
|
15
|
+
/** pageGate(page-eligibility) 실패 시 fallback. */
|
|
16
|
+
pageGateFallback?: LanguageModel;
|
|
13
17
|
reviewAssistance: LanguageModel;
|
|
18
|
+
/** review-assistance 공통 fallback (task별 미지정 시 사용). */
|
|
19
|
+
reviewAssistanceFallback?: LanguageModel;
|
|
14
20
|
reviewAssistanceTasks?: Partial<Record<ReviewAssistanceTaskId, LanguageModel>>;
|
|
21
|
+
/** review-assistance task별 fallback. */
|
|
22
|
+
reviewAssistanceTasksFallback?: Partial<Record<ReviewAssistanceTaskId, LanguageModel>>;
|
|
15
23
|
tableCorrection?: LanguageModel;
|
|
24
|
+
/** tableCorrection 실패 시 fallback. */
|
|
25
|
+
tableCorrectionFallback?: LanguageModel;
|
|
16
26
|
}
|
|
17
27
|
interface PDFCorrectionConcurrencyOptions {
|
|
18
28
|
pages?: number;
|
|
@@ -93,6 +103,8 @@ type PDFConvertOptions = Omit<ConversionOptions, 'to_formats' | 'image_export_mo
|
|
|
93
103
|
chunkMaxRetries?: number;
|
|
94
104
|
/** Vision model for document language detection when the PDF text layer is insufficient */
|
|
95
105
|
languageDetectionModel?: LanguageModel;
|
|
106
|
+
/** languageDetectionModel 실패 시 fallback. */
|
|
107
|
+
languageDetectionFallbackModel?: LanguageModel;
|
|
96
108
|
/** LLM model for document type validation (opt-in: skipped when not set) */
|
|
97
109
|
documentValidationModel?: LanguageModel;
|
|
98
110
|
};
|
package/dist/index.js
CHANGED
|
@@ -138,6 +138,8 @@ function detectProvider(model) {
|
|
|
138
138
|
if (providerId.includes("google")) return "google";
|
|
139
139
|
if (providerId.includes("anthropic")) return "anthropic";
|
|
140
140
|
if (providerId.includes("together")) return "togetherai";
|
|
141
|
+
if (providerId.includes("ollama")) return "ollama";
|
|
142
|
+
if (providerId.includes("lmstudio")) return "lmstudio";
|
|
141
143
|
return "unknown";
|
|
142
144
|
}
|
|
143
145
|
var LLMCaller = class {
|
|
@@ -225,14 +227,18 @@ var LLMCaller = class {
|
|
|
225
227
|
*
|
|
226
228
|
* Strategy per provider:
|
|
227
229
|
* - OpenAI / Anthropic / Google Gemini: `Output.object()` with schema retry
|
|
228
|
-
* - Together AI / unknown: forced tool call pattern
|
|
230
|
+
* - Together AI / Ollama / unknown: forced tool call pattern
|
|
231
|
+
*
|
|
232
|
+
* Ollama uses tool-call because MLX backends ignore the `format` grammar
|
|
233
|
+
* that `Output.object()` relies on, and gguf's grammar is unstable once
|
|
234
|
+
* thinking is disabled. Applies to both text and vision paths.
|
|
229
235
|
*
|
|
230
236
|
* Retries up to MAX_STRUCTURED_OUTPUT_RETRIES times on NoObjectGeneratedError
|
|
231
237
|
* (schema mismatch), re-throwing the last error if all attempts fail.
|
|
232
238
|
*/
|
|
233
239
|
static async generateStructuredOutput(model, schema, promptParams) {
|
|
234
240
|
const providerType = detectProvider(model);
|
|
235
|
-
if (providerType === "togetherai" || providerType === "unknown") {
|
|
241
|
+
if (providerType === "togetherai" || providerType === "ollama" || providerType === "unknown") {
|
|
236
242
|
return this.generateViaToolCall(model, schema, promptParams);
|
|
237
243
|
}
|
|
238
244
|
let lastError;
|
|
@@ -337,6 +343,29 @@ var LLMCaller = class {
|
|
|
337
343
|
function formatTokens(usage) {
|
|
338
344
|
return `${usage.inputTokens} input, ${usage.outputTokens} output, ${usage.totalTokens} total`;
|
|
339
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
|
+
}
|
|
340
369
|
var LLMTokenUsageAggregator = class {
|
|
341
370
|
usage = {};
|
|
342
371
|
/**
|
|
@@ -349,21 +378,15 @@ var LLMTokenUsageAggregator = class {
|
|
|
349
378
|
this.usage[usage.component] = {
|
|
350
379
|
component: usage.component,
|
|
351
380
|
phases: {},
|
|
352
|
-
total:
|
|
353
|
-
inputTokens: 0,
|
|
354
|
-
outputTokens: 0,
|
|
355
|
-
totalTokens: 0
|
|
356
|
-
}
|
|
381
|
+
total: emptyUsage()
|
|
357
382
|
};
|
|
358
383
|
}
|
|
359
384
|
const component = this.usage[usage.component];
|
|
360
385
|
if (!component.phases[usage.phase]) {
|
|
361
386
|
component.phases[usage.phase] = {
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
totalTokens: 0
|
|
366
|
-
},
|
|
387
|
+
primary: /* @__PURE__ */ new Map(),
|
|
388
|
+
fallback: /* @__PURE__ */ new Map(),
|
|
389
|
+
total: emptyUsage(),
|
|
367
390
|
metadata: []
|
|
368
391
|
};
|
|
369
392
|
}
|
|
@@ -372,41 +395,17 @@ var LLMTokenUsageAggregator = class {
|
|
|
372
395
|
phase.metadata.push(usage.metadata);
|
|
373
396
|
}
|
|
374
397
|
if (usage.model === "primary") {
|
|
375
|
-
|
|
376
|
-
phase.primary = {
|
|
377
|
-
modelName: usage.modelName,
|
|
378
|
-
inputTokens: 0,
|
|
379
|
-
outputTokens: 0,
|
|
380
|
-
totalTokens: 0
|
|
381
|
-
};
|
|
382
|
-
}
|
|
383
|
-
phase.primary.inputTokens += usage.inputTokens;
|
|
384
|
-
phase.primary.outputTokens += usage.outputTokens;
|
|
385
|
-
phase.primary.totalTokens += usage.totalTokens;
|
|
398
|
+
accumulateModel(phase.primary, usage.modelName, usage);
|
|
386
399
|
} else if (usage.model === "fallback") {
|
|
387
|
-
|
|
388
|
-
phase.fallback = {
|
|
389
|
-
modelName: usage.modelName,
|
|
390
|
-
inputTokens: 0,
|
|
391
|
-
outputTokens: 0,
|
|
392
|
-
totalTokens: 0
|
|
393
|
-
};
|
|
394
|
-
}
|
|
395
|
-
phase.fallback.inputTokens += usage.inputTokens;
|
|
396
|
-
phase.fallback.outputTokens += usage.outputTokens;
|
|
397
|
-
phase.fallback.totalTokens += usage.totalTokens;
|
|
400
|
+
accumulateModel(phase.fallback, usage.modelName, usage);
|
|
398
401
|
}
|
|
399
|
-
phase.total
|
|
400
|
-
|
|
401
|
-
phase.total.totalTokens += usage.totalTokens;
|
|
402
|
-
component.total.inputTokens += usage.inputTokens;
|
|
403
|
-
component.total.outputTokens += usage.outputTokens;
|
|
404
|
-
component.total.totalTokens += usage.totalTokens;
|
|
402
|
+
addInto(phase.total, usage);
|
|
403
|
+
addInto(component.total, usage);
|
|
405
404
|
}
|
|
406
405
|
/**
|
|
407
406
|
* Get aggregated usage grouped by component
|
|
408
407
|
*
|
|
409
|
-
* @returns Array of component aggregates with phase breakdown
|
|
408
|
+
* @returns Array of component aggregates with per-model phase breakdown
|
|
410
409
|
*/
|
|
411
410
|
getByComponent() {
|
|
412
411
|
return Object.values(this.usage);
|
|
@@ -415,8 +414,16 @@ var LLMTokenUsageAggregator = class {
|
|
|
415
414
|
* Get token usage report in structured JSON format
|
|
416
415
|
*
|
|
417
416
|
* Converts internal usage data to external TokenUsageReport format suitable
|
|
418
|
-
* for serialization and reporting.
|
|
419
|
-
*
|
|
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.
|
|
420
427
|
*
|
|
421
428
|
* @returns Structured token usage report with components and total
|
|
422
429
|
*/
|
|
@@ -425,34 +432,41 @@ var LLMTokenUsageAggregator = class {
|
|
|
425
432
|
for (const component of Object.values(this.usage)) {
|
|
426
433
|
const phases = [];
|
|
427
434
|
for (const [phaseName, phaseData] of Object.entries(component.phases)) {
|
|
428
|
-
const
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
}
|
|
439
|
-
if (phaseData.primary) {
|
|
440
|
-
phaseReport.primary = {
|
|
441
|
-
modelName: phaseData.primary.modelName,
|
|
442
|
-
inputTokens: phaseData.primary.inputTokens,
|
|
443
|
-
outputTokens: phaseData.primary.outputTokens,
|
|
444
|
-
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 }
|
|
445
445
|
};
|
|
446
|
+
if (phaseData.metadata.length > 0) {
|
|
447
|
+
phaseReport.metadata = [...phaseData.metadata];
|
|
448
|
+
}
|
|
449
|
+
phases.push(phaseReport);
|
|
450
|
+
continue;
|
|
446
451
|
}
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
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])
|
|
453
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);
|
|
454
469
|
}
|
|
455
|
-
phases.push(phaseReport);
|
|
456
470
|
}
|
|
457
471
|
components.push({
|
|
458
472
|
component: component.component,
|
|
@@ -497,8 +511,8 @@ var LLMTokenUsageAggregator = class {
|
|
|
497
511
|
/**
|
|
498
512
|
* Log comprehensive token usage summary
|
|
499
513
|
*
|
|
500
|
-
* Outputs usage grouped by component, with phase and model breakdown.
|
|
501
|
-
* 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.
|
|
502
516
|
* Call this once at the end of document processing.
|
|
503
517
|
*
|
|
504
518
|
* @param logger - Logger instance for output
|
|
@@ -514,31 +528,23 @@ var LLMTokenUsageAggregator = class {
|
|
|
514
528
|
let grandInputTokens = 0;
|
|
515
529
|
let grandOutputTokens = 0;
|
|
516
530
|
let grandTotalTokens = 0;
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
let grandPrimaryTotalTokens = 0;
|
|
520
|
-
let grandFallbackInputTokens = 0;
|
|
521
|
-
let grandFallbackOutputTokens = 0;
|
|
522
|
-
let grandFallbackTotalTokens = 0;
|
|
531
|
+
const grandPrimary = emptyUsage();
|
|
532
|
+
const grandFallback = emptyUsage();
|
|
523
533
|
for (const component of components) {
|
|
524
534
|
logger.info(`${component.component}:`);
|
|
525
|
-
for (const [
|
|
526
|
-
logger.info(` - ${
|
|
527
|
-
|
|
535
|
+
for (const [phaseName, phaseData] of Object.entries(component.phases)) {
|
|
536
|
+
logger.info(` - ${phaseName}:`);
|
|
537
|
+
for (const [modelName, modelUsage] of phaseData.primary) {
|
|
528
538
|
logger.info(
|
|
529
|
-
` primary (${
|
|
539
|
+
` primary (${modelName}): ${formatTokens(modelUsage)}`
|
|
530
540
|
);
|
|
531
|
-
|
|
532
|
-
grandPrimaryOutputTokens += phaseData.primary.outputTokens;
|
|
533
|
-
grandPrimaryTotalTokens += phaseData.primary.totalTokens;
|
|
541
|
+
addInto(grandPrimary, modelUsage);
|
|
534
542
|
}
|
|
535
|
-
|
|
543
|
+
for (const [modelName, modelUsage] of phaseData.fallback) {
|
|
536
544
|
logger.info(
|
|
537
|
-
` fallback (${
|
|
545
|
+
` fallback (${modelName}): ${formatTokens(modelUsage)}`
|
|
538
546
|
);
|
|
539
|
-
|
|
540
|
-
grandFallbackOutputTokens += phaseData.fallback.outputTokens;
|
|
541
|
-
grandFallbackTotalTokens += phaseData.fallback.totalTokens;
|
|
547
|
+
addInto(grandFallback, modelUsage);
|
|
542
548
|
}
|
|
543
549
|
logger.info(` subtotal: ${formatTokens(phaseData.total)}`);
|
|
544
550
|
}
|
|
@@ -551,23 +557,11 @@ var LLMTokenUsageAggregator = class {
|
|
|
551
557
|
grandTotalTokens += component.total.totalTokens;
|
|
552
558
|
}
|
|
553
559
|
logger.info("--- Summary ---");
|
|
554
|
-
if (
|
|
555
|
-
logger.info(
|
|
556
|
-
`Primary total: ${formatTokens({
|
|
557
|
-
inputTokens: grandPrimaryInputTokens,
|
|
558
|
-
outputTokens: grandPrimaryOutputTokens,
|
|
559
|
-
totalTokens: grandPrimaryTotalTokens
|
|
560
|
-
})}`
|
|
561
|
-
);
|
|
560
|
+
if (grandPrimary.totalTokens > 0) {
|
|
561
|
+
logger.info(`Primary total: ${formatTokens(grandPrimary)}`);
|
|
562
562
|
}
|
|
563
|
-
if (
|
|
564
|
-
logger.info(
|
|
565
|
-
`Fallback total: ${formatTokens({
|
|
566
|
-
inputTokens: grandFallbackInputTokens,
|
|
567
|
-
outputTokens: grandFallbackOutputTokens,
|
|
568
|
-
totalTokens: grandFallbackTotalTokens
|
|
569
|
-
})}`
|
|
570
|
-
);
|
|
563
|
+
if (grandFallback.totalTokens > 0) {
|
|
564
|
+
logger.info(`Fallback total: ${formatTokens(grandFallback)}`);
|
|
571
565
|
}
|
|
572
566
|
logger.info(
|
|
573
567
|
`Grand total: ${formatTokens({
|
|
@@ -1334,6 +1328,7 @@ var PdfLanguageDetector = class {
|
|
|
1334
1328
|
}
|
|
1335
1329
|
],
|
|
1336
1330
|
primaryModel: options.model,
|
|
1331
|
+
fallbackModel: options.fallbackModel,
|
|
1337
1332
|
maxRetries: options.maxRetries ?? DEFAULT_MAX_RETRIES,
|
|
1338
1333
|
temperature: options.temperature ?? 0,
|
|
1339
1334
|
abortSignal: options.abortSignal,
|
|
@@ -3302,6 +3297,7 @@ var ReviewAssistancePageGate = class {
|
|
|
3302
3297
|
}
|
|
3303
3298
|
],
|
|
3304
3299
|
primaryModel: model,
|
|
3300
|
+
fallbackModel: options.fallbackModel,
|
|
3305
3301
|
maxRetries: options.maxRetries ?? REVIEW_ASSISTANCE_PAGE_GATE_MAX_RETRIES,
|
|
3306
3302
|
temperature: options.temperature ?? REVIEW_ASSISTANCE_PAGE_GATE_TEMPERATURE,
|
|
3307
3303
|
abortSignal: options.abortSignal,
|
|
@@ -3573,6 +3569,7 @@ var PostDoclingPageProcessor = class {
|
|
|
3573
3569
|
}
|
|
3574
3570
|
],
|
|
3575
3571
|
primaryModel: model,
|
|
3572
|
+
fallbackModel: options?.fallbackModel,
|
|
3576
3573
|
maxRetries: options?.maxRetries ?? DEFAULT_MAX_RETRIES2,
|
|
3577
3574
|
temperature: options?.temperature ?? DEFAULT_TEMPERATURE,
|
|
3578
3575
|
abortSignal: options?.abortSignal,
|
|
@@ -3618,6 +3615,7 @@ var PostDoclingPageProcessor = class {
|
|
|
3618
3615
|
image,
|
|
3619
3616
|
gateOptions.model,
|
|
3620
3617
|
{
|
|
3618
|
+
fallbackModel: gateOptions.fallback,
|
|
3621
3619
|
maxRetries: gateOptions.maxRetries,
|
|
3622
3620
|
temperature: gateOptions.temperature,
|
|
3623
3621
|
abortSignal: options?.abortSignal,
|
|
@@ -8863,6 +8861,7 @@ var ReviewAssistanceRunner = class {
|
|
|
8863
8861
|
image,
|
|
8864
8862
|
options.pageGateModel,
|
|
8865
8863
|
{
|
|
8864
|
+
fallbackModel: options.pageGateFallback,
|
|
8866
8865
|
maxRetries: options.pageGateMaxRetries,
|
|
8867
8866
|
temperature: options.pageGateTemperature,
|
|
8868
8867
|
abortSignal: options.abortSignal,
|
|
@@ -9141,7 +9140,7 @@ var ReviewAssistanceRunner = class {
|
|
|
9141
9140
|
async reviewWorkItem(context, workItem, image, pageCount, modelResolver, options) {
|
|
9142
9141
|
const startedAtMs = Date.now();
|
|
9143
9142
|
const startedAt = new Date(startedAtMs).toISOString();
|
|
9144
|
-
const model = modelResolver(workItem.task);
|
|
9143
|
+
const { model, fallback } = modelResolver(workItem.task);
|
|
9145
9144
|
const modelId = this.getModelId(model);
|
|
9146
9145
|
let attempts = 0;
|
|
9147
9146
|
let validationFeedback = [];
|
|
@@ -9182,6 +9181,7 @@ var ReviewAssistanceRunner = class {
|
|
|
9182
9181
|
}
|
|
9183
9182
|
],
|
|
9184
9183
|
primaryModel: model,
|
|
9184
|
+
fallbackModel: fallback,
|
|
9185
9185
|
maxRetries: this.getTaskMaxRetries(workItem.task, options),
|
|
9186
9186
|
temperature: options.temperature,
|
|
9187
9187
|
abortSignal: options.abortSignal,
|
|
@@ -9968,7 +9968,7 @@ var ReviewAssistanceRunner = class {
|
|
|
9968
9968
|
*/
|
|
9969
9969
|
async callMergeArbiter(candidates, context, image, modelResolver, options) {
|
|
9970
9970
|
const arbiterTask = this.resolveMergeTaskDefinition(candidates);
|
|
9971
|
-
const model = modelResolver(arbiterTask);
|
|
9971
|
+
const { model, fallback } = modelResolver(arbiterTask);
|
|
9972
9972
|
const conflictRefs = [
|
|
9973
9973
|
...new Set(
|
|
9974
9974
|
candidates.flatMap(
|
|
@@ -10007,6 +10007,7 @@ var ReviewAssistanceRunner = class {
|
|
|
10007
10007
|
}
|
|
10008
10008
|
],
|
|
10009
10009
|
primaryModel: model,
|
|
10010
|
+
fallbackModel: fallback,
|
|
10010
10011
|
maxRetries: REVIEW_ASSISTANCE_MERGE_MAX_RETRIES,
|
|
10011
10012
|
temperature: options.temperature,
|
|
10012
10013
|
abortSignal: options.abortSignal,
|
|
@@ -10559,6 +10560,7 @@ var PostDoclingCorrectionPipeline = class {
|
|
|
10559
10560
|
outputDir,
|
|
10560
10561
|
correction.models.textCorrection,
|
|
10561
10562
|
{
|
|
10563
|
+
fallbackModel: correction.models.textCorrectionFallback,
|
|
10562
10564
|
concurrency: correction.concurrency.pages,
|
|
10563
10565
|
maxRetries: correction.maxRetries.textCorrection,
|
|
10564
10566
|
temperature: correction.temperature,
|
|
@@ -10569,6 +10571,7 @@ var PostDoclingCorrectionPipeline = class {
|
|
|
10569
10571
|
pageTexts,
|
|
10570
10572
|
reviewAssistanceGate: {
|
|
10571
10573
|
model: correction.models.pageGate,
|
|
10574
|
+
fallback: correction.models.pageGateFallback,
|
|
10572
10575
|
maxRetries: correction.maxRetries.pageGate,
|
|
10573
10576
|
temperature: correction.temperature,
|
|
10574
10577
|
outputLanguage: correction.outputLanguage
|
|
@@ -10584,6 +10587,7 @@ var PostDoclingCorrectionPipeline = class {
|
|
|
10584
10587
|
pdfPath,
|
|
10585
10588
|
pageTexts,
|
|
10586
10589
|
pageGateModel: correction.models.pageGate,
|
|
10590
|
+
pageGateFallback: correction.models.pageGateFallback,
|
|
10587
10591
|
pageGateMaxRetries: correction.maxRetries.pageGate,
|
|
10588
10592
|
pageGateTemperature: correction.temperature,
|
|
10589
10593
|
pageConcurrency: correction.concurrency.pages,
|
|
@@ -10609,9 +10613,15 @@ var PostDoclingCorrectionPipeline = class {
|
|
|
10609
10613
|
buildReviewAssistanceModelResolver(correction) {
|
|
10610
10614
|
return (task) => {
|
|
10611
10615
|
if (task.id === "tables") {
|
|
10612
|
-
return
|
|
10616
|
+
return {
|
|
10617
|
+
model: correction.models.tableCorrection ?? correction.models.reviewAssistanceTasks?.tables ?? correction.models.reviewAssistance,
|
|
10618
|
+
fallback: correction.models.tableCorrectionFallback ?? correction.models.reviewAssistanceTasksFallback?.tables ?? correction.models.reviewAssistanceFallback
|
|
10619
|
+
};
|
|
10613
10620
|
}
|
|
10614
|
-
return
|
|
10621
|
+
return {
|
|
10622
|
+
model: correction.models.reviewAssistanceTasks?.[task.id] ?? correction.models.reviewAssistance,
|
|
10623
|
+
fallback: correction.models.reviewAssistanceTasksFallback?.[task.id] ?? correction.models.reviewAssistanceFallback
|
|
10624
|
+
};
|
|
10615
10625
|
};
|
|
10616
10626
|
}
|
|
10617
10627
|
async extractPageTexts(pdfPath, outputDir) {
|
|
@@ -10759,6 +10769,7 @@ var PDFConverter = class {
|
|
|
10759
10769
|
try {
|
|
10760
10770
|
const result = await detector.detect(pdfPath, languageDetectionDir, {
|
|
10761
10771
|
model: options.languageDetectionModel,
|
|
10772
|
+
fallbackModel: options.languageDetectionFallbackModel,
|
|
10762
10773
|
aggregator: options.aggregator,
|
|
10763
10774
|
abortSignal
|
|
10764
10775
|
});
|