@heripo/pdf-parser 0.1.32 → 0.1.33

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 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;
@@ -1334,6 +1340,7 @@ var PdfLanguageDetector = class {
1334
1340
  }
1335
1341
  ],
1336
1342
  primaryModel: options.model,
1343
+ fallbackModel: options.fallbackModel,
1337
1344
  maxRetries: options.maxRetries ?? DEFAULT_MAX_RETRIES,
1338
1345
  temperature: options.temperature ?? 0,
1339
1346
  abortSignal: options.abortSignal,
@@ -3302,6 +3309,7 @@ var ReviewAssistancePageGate = class {
3302
3309
  }
3303
3310
  ],
3304
3311
  primaryModel: model,
3312
+ fallbackModel: options.fallbackModel,
3305
3313
  maxRetries: options.maxRetries ?? REVIEW_ASSISTANCE_PAGE_GATE_MAX_RETRIES,
3306
3314
  temperature: options.temperature ?? REVIEW_ASSISTANCE_PAGE_GATE_TEMPERATURE,
3307
3315
  abortSignal: options.abortSignal,
@@ -3573,6 +3581,7 @@ var PostDoclingPageProcessor = class {
3573
3581
  }
3574
3582
  ],
3575
3583
  primaryModel: model,
3584
+ fallbackModel: options?.fallbackModel,
3576
3585
  maxRetries: options?.maxRetries ?? DEFAULT_MAX_RETRIES2,
3577
3586
  temperature: options?.temperature ?? DEFAULT_TEMPERATURE,
3578
3587
  abortSignal: options?.abortSignal,
@@ -3618,6 +3627,7 @@ var PostDoclingPageProcessor = class {
3618
3627
  image,
3619
3628
  gateOptions.model,
3620
3629
  {
3630
+ fallbackModel: gateOptions.fallback,
3621
3631
  maxRetries: gateOptions.maxRetries,
3622
3632
  temperature: gateOptions.temperature,
3623
3633
  abortSignal: options?.abortSignal,
@@ -8863,6 +8873,7 @@ var ReviewAssistanceRunner = class {
8863
8873
  image,
8864
8874
  options.pageGateModel,
8865
8875
  {
8876
+ fallbackModel: options.pageGateFallback,
8866
8877
  maxRetries: options.pageGateMaxRetries,
8867
8878
  temperature: options.pageGateTemperature,
8868
8879
  abortSignal: options.abortSignal,
@@ -9141,7 +9152,7 @@ var ReviewAssistanceRunner = class {
9141
9152
  async reviewWorkItem(context, workItem, image, pageCount, modelResolver, options) {
9142
9153
  const startedAtMs = Date.now();
9143
9154
  const startedAt = new Date(startedAtMs).toISOString();
9144
- const model = modelResolver(workItem.task);
9155
+ const { model, fallback } = modelResolver(workItem.task);
9145
9156
  const modelId = this.getModelId(model);
9146
9157
  let attempts = 0;
9147
9158
  let validationFeedback = [];
@@ -9182,6 +9193,7 @@ var ReviewAssistanceRunner = class {
9182
9193
  }
9183
9194
  ],
9184
9195
  primaryModel: model,
9196
+ fallbackModel: fallback,
9185
9197
  maxRetries: this.getTaskMaxRetries(workItem.task, options),
9186
9198
  temperature: options.temperature,
9187
9199
  abortSignal: options.abortSignal,
@@ -9968,7 +9980,7 @@ var ReviewAssistanceRunner = class {
9968
9980
  */
9969
9981
  async callMergeArbiter(candidates, context, image, modelResolver, options) {
9970
9982
  const arbiterTask = this.resolveMergeTaskDefinition(candidates);
9971
- const model = modelResolver(arbiterTask);
9983
+ const { model, fallback } = modelResolver(arbiterTask);
9972
9984
  const conflictRefs = [
9973
9985
  ...new Set(
9974
9986
  candidates.flatMap(
@@ -10007,6 +10019,7 @@ var ReviewAssistanceRunner = class {
10007
10019
  }
10008
10020
  ],
10009
10021
  primaryModel: model,
10022
+ fallbackModel: fallback,
10010
10023
  maxRetries: REVIEW_ASSISTANCE_MERGE_MAX_RETRIES,
10011
10024
  temperature: options.temperature,
10012
10025
  abortSignal: options.abortSignal,
@@ -10559,6 +10572,7 @@ var PostDoclingCorrectionPipeline = class {
10559
10572
  outputDir,
10560
10573
  correction.models.textCorrection,
10561
10574
  {
10575
+ fallbackModel: correction.models.textCorrectionFallback,
10562
10576
  concurrency: correction.concurrency.pages,
10563
10577
  maxRetries: correction.maxRetries.textCorrection,
10564
10578
  temperature: correction.temperature,
@@ -10569,6 +10583,7 @@ var PostDoclingCorrectionPipeline = class {
10569
10583
  pageTexts,
10570
10584
  reviewAssistanceGate: {
10571
10585
  model: correction.models.pageGate,
10586
+ fallback: correction.models.pageGateFallback,
10572
10587
  maxRetries: correction.maxRetries.pageGate,
10573
10588
  temperature: correction.temperature,
10574
10589
  outputLanguage: correction.outputLanguage
@@ -10584,6 +10599,7 @@ var PostDoclingCorrectionPipeline = class {
10584
10599
  pdfPath,
10585
10600
  pageTexts,
10586
10601
  pageGateModel: correction.models.pageGate,
10602
+ pageGateFallback: correction.models.pageGateFallback,
10587
10603
  pageGateMaxRetries: correction.maxRetries.pageGate,
10588
10604
  pageGateTemperature: correction.temperature,
10589
10605
  pageConcurrency: correction.concurrency.pages,
@@ -10609,9 +10625,15 @@ var PostDoclingCorrectionPipeline = class {
10609
10625
  buildReviewAssistanceModelResolver(correction) {
10610
10626
  return (task) => {
10611
10627
  if (task.id === "tables") {
10612
- return correction.models.tableCorrection ?? correction.models.reviewAssistanceTasks?.tables ?? correction.models.reviewAssistance;
10628
+ return {
10629
+ model: correction.models.tableCorrection ?? correction.models.reviewAssistanceTasks?.tables ?? correction.models.reviewAssistance,
10630
+ fallback: correction.models.tableCorrectionFallback ?? correction.models.reviewAssistanceTasksFallback?.tables ?? correction.models.reviewAssistanceFallback
10631
+ };
10613
10632
  }
10614
- return correction.models.reviewAssistanceTasks?.[task.id] ?? correction.models.reviewAssistance;
10633
+ return {
10634
+ model: correction.models.reviewAssistanceTasks?.[task.id] ?? correction.models.reviewAssistance,
10635
+ fallback: correction.models.reviewAssistanceTasksFallback?.[task.id] ?? correction.models.reviewAssistanceFallback
10636
+ };
10615
10637
  };
10616
10638
  }
10617
10639
  async extractPageTexts(pdfPath, outputDir) {
@@ -10759,6 +10781,7 @@ var PDFConverter = class {
10759
10781
  try {
10760
10782
  const result = await detector.detect(pdfPath, languageDetectionDir, {
10761
10783
  model: options.languageDetectionModel,
10784
+ fallbackModel: options.languageDetectionFallbackModel,
10762
10785
  aggregator: options.aggregator,
10763
10786
  abortSignal
10764
10787
  });