@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.cjs CHANGED
@@ -172,6 +172,8 @@ function detectProvider(model) {
172
172
  if (providerId.includes("google")) return "google";
173
173
  if (providerId.includes("anthropic")) return "anthropic";
174
174
  if (providerId.includes("together")) return "togetherai";
175
+ if (providerId.includes("ollama")) return "ollama";
176
+ if (providerId.includes("lmstudio")) return "lmstudio";
175
177
  return "unknown";
176
178
  }
177
179
  var LLMCaller = class {
@@ -259,14 +261,18 @@ var LLMCaller = class {
259
261
  *
260
262
  * Strategy per provider:
261
263
  * - OpenAI / Anthropic / Google Gemini: `Output.object()` with schema retry
262
- * - Together AI / unknown: forced tool call pattern
264
+ * - Together AI / Ollama / unknown: forced tool call pattern
265
+ *
266
+ * Ollama uses tool-call because MLX backends ignore the `format` grammar
267
+ * that `Output.object()` relies on, and gguf's grammar is unstable once
268
+ * thinking is disabled. Applies to both text and vision paths.
263
269
  *
264
270
  * Retries up to MAX_STRUCTURED_OUTPUT_RETRIES times on NoObjectGeneratedError
265
271
  * (schema mismatch), re-throwing the last error if all attempts fail.
266
272
  */
267
273
  static async generateStructuredOutput(model, schema, promptParams) {
268
274
  const providerType = detectProvider(model);
269
- if (providerType === "togetherai" || providerType === "unknown") {
275
+ if (providerType === "togetherai" || providerType === "ollama" || providerType === "unknown") {
270
276
  return this.generateViaToolCall(model, schema, promptParams);
271
277
  }
272
278
  let lastError;
@@ -1368,6 +1374,7 @@ var PdfLanguageDetector = class {
1368
1374
  }
1369
1375
  ],
1370
1376
  primaryModel: options.model,
1377
+ fallbackModel: options.fallbackModel,
1371
1378
  maxRetries: options.maxRetries ?? DEFAULT_MAX_RETRIES,
1372
1379
  temperature: options.temperature ?? 0,
1373
1380
  abortSignal: options.abortSignal,
@@ -3320,6 +3327,7 @@ var ReviewAssistancePageGate = class {
3320
3327
  }
3321
3328
  ],
3322
3329
  primaryModel: model,
3330
+ fallbackModel: options.fallbackModel,
3323
3331
  maxRetries: options.maxRetries ?? REVIEW_ASSISTANCE_PAGE_GATE_MAX_RETRIES,
3324
3332
  temperature: options.temperature ?? REVIEW_ASSISTANCE_PAGE_GATE_TEMPERATURE,
3325
3333
  abortSignal: options.abortSignal,
@@ -3591,6 +3599,7 @@ var PostDoclingPageProcessor = class {
3591
3599
  }
3592
3600
  ],
3593
3601
  primaryModel: model,
3602
+ fallbackModel: options?.fallbackModel,
3594
3603
  maxRetries: options?.maxRetries ?? DEFAULT_MAX_RETRIES2,
3595
3604
  temperature: options?.temperature ?? DEFAULT_TEMPERATURE,
3596
3605
  abortSignal: options?.abortSignal,
@@ -3636,6 +3645,7 @@ var PostDoclingPageProcessor = class {
3636
3645
  image,
3637
3646
  gateOptions.model,
3638
3647
  {
3648
+ fallbackModel: gateOptions.fallback,
3639
3649
  maxRetries: gateOptions.maxRetries,
3640
3650
  temperature: gateOptions.temperature,
3641
3651
  abortSignal: options?.abortSignal,
@@ -8881,6 +8891,7 @@ var ReviewAssistanceRunner = class {
8881
8891
  image,
8882
8892
  options.pageGateModel,
8883
8893
  {
8894
+ fallbackModel: options.pageGateFallback,
8884
8895
  maxRetries: options.pageGateMaxRetries,
8885
8896
  temperature: options.pageGateTemperature,
8886
8897
  abortSignal: options.abortSignal,
@@ -9159,7 +9170,7 @@ var ReviewAssistanceRunner = class {
9159
9170
  async reviewWorkItem(context, workItem, image, pageCount, modelResolver, options) {
9160
9171
  const startedAtMs = Date.now();
9161
9172
  const startedAt = new Date(startedAtMs).toISOString();
9162
- const model = modelResolver(workItem.task);
9173
+ const { model, fallback } = modelResolver(workItem.task);
9163
9174
  const modelId = this.getModelId(model);
9164
9175
  let attempts = 0;
9165
9176
  let validationFeedback = [];
@@ -9200,6 +9211,7 @@ var ReviewAssistanceRunner = class {
9200
9211
  }
9201
9212
  ],
9202
9213
  primaryModel: model,
9214
+ fallbackModel: fallback,
9203
9215
  maxRetries: this.getTaskMaxRetries(workItem.task, options),
9204
9216
  temperature: options.temperature,
9205
9217
  abortSignal: options.abortSignal,
@@ -9986,7 +9998,7 @@ var ReviewAssistanceRunner = class {
9986
9998
  */
9987
9999
  async callMergeArbiter(candidates, context, image, modelResolver, options) {
9988
10000
  const arbiterTask = this.resolveMergeTaskDefinition(candidates);
9989
- const model = modelResolver(arbiterTask);
10001
+ const { model, fallback } = modelResolver(arbiterTask);
9990
10002
  const conflictRefs = [
9991
10003
  ...new Set(
9992
10004
  candidates.flatMap(
@@ -10025,6 +10037,7 @@ var ReviewAssistanceRunner = class {
10025
10037
  }
10026
10038
  ],
10027
10039
  primaryModel: model,
10040
+ fallbackModel: fallback,
10028
10041
  maxRetries: REVIEW_ASSISTANCE_MERGE_MAX_RETRIES,
10029
10042
  temperature: options.temperature,
10030
10043
  abortSignal: options.abortSignal,
@@ -10577,6 +10590,7 @@ var PostDoclingCorrectionPipeline = class {
10577
10590
  outputDir,
10578
10591
  correction.models.textCorrection,
10579
10592
  {
10593
+ fallbackModel: correction.models.textCorrectionFallback,
10580
10594
  concurrency: correction.concurrency.pages,
10581
10595
  maxRetries: correction.maxRetries.textCorrection,
10582
10596
  temperature: correction.temperature,
@@ -10587,6 +10601,7 @@ var PostDoclingCorrectionPipeline = class {
10587
10601
  pageTexts,
10588
10602
  reviewAssistanceGate: {
10589
10603
  model: correction.models.pageGate,
10604
+ fallback: correction.models.pageGateFallback,
10590
10605
  maxRetries: correction.maxRetries.pageGate,
10591
10606
  temperature: correction.temperature,
10592
10607
  outputLanguage: correction.outputLanguage
@@ -10602,6 +10617,7 @@ var PostDoclingCorrectionPipeline = class {
10602
10617
  pdfPath,
10603
10618
  pageTexts,
10604
10619
  pageGateModel: correction.models.pageGate,
10620
+ pageGateFallback: correction.models.pageGateFallback,
10605
10621
  pageGateMaxRetries: correction.maxRetries.pageGate,
10606
10622
  pageGateTemperature: correction.temperature,
10607
10623
  pageConcurrency: correction.concurrency.pages,
@@ -10627,9 +10643,15 @@ var PostDoclingCorrectionPipeline = class {
10627
10643
  buildReviewAssistanceModelResolver(correction) {
10628
10644
  return (task) => {
10629
10645
  if (task.id === "tables") {
10630
- return correction.models.tableCorrection ?? correction.models.reviewAssistanceTasks?.tables ?? correction.models.reviewAssistance;
10646
+ return {
10647
+ model: correction.models.tableCorrection ?? correction.models.reviewAssistanceTasks?.tables ?? correction.models.reviewAssistance,
10648
+ fallback: correction.models.tableCorrectionFallback ?? correction.models.reviewAssistanceTasksFallback?.tables ?? correction.models.reviewAssistanceFallback
10649
+ };
10631
10650
  }
10632
- return correction.models.reviewAssistanceTasks?.[task.id] ?? correction.models.reviewAssistance;
10651
+ return {
10652
+ model: correction.models.reviewAssistanceTasks?.[task.id] ?? correction.models.reviewAssistance,
10653
+ fallback: correction.models.reviewAssistanceTasksFallback?.[task.id] ?? correction.models.reviewAssistanceFallback
10654
+ };
10633
10655
  };
10634
10656
  }
10635
10657
  async extractPageTexts(pdfPath, outputDir) {
@@ -10777,6 +10799,7 @@ var PDFConverter = class {
10777
10799
  try {
10778
10800
  const result = await detector.detect(pdfPath, languageDetectionDir, {
10779
10801
  model: options.languageDetectionModel,
10802
+ fallbackModel: options.languageDetectionFallbackModel,
10780
10803
  aggregator: options.aggregator,
10781
10804
  abortSignal
10782
10805
  });