docling-serve-client 0.4.0 → 0.5.0
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/README.md +270 -29
- package/dist/capabilities.d.ts +10 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/core/input.d.ts +1 -1
- package/dist/core/pdf.d.ts +2 -2
- package/dist/core/validate.d.ts +2 -2
- package/dist/core/validate.d.ts.map +1 -1
- package/dist/images.d.ts +6 -3
- package/dist/images.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +146 -52
- package/dist/index.js.map +11 -10
- package/dist/options.d.ts +15 -5
- package/dist/options.d.ts.map +1 -1
- package/dist/types.d.ts +123 -9
- package/dist/types.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/capabilities.ts +109 -0
- package/src/client.ts +132 -65
- package/src/core/input.ts +3 -3
- package/src/core/pdf.ts +2 -2
- package/src/core/validate.ts +2 -2
- package/src/images.ts +4 -4
- package/src/index.ts +8 -0
- package/src/options.ts +23 -7
- package/src/response.ts +1 -1
- package/src/types.ts +136 -10
package/dist/index.js
CHANGED
|
@@ -250,6 +250,70 @@ function fail(error) {
|
|
|
250
250
|
return { ok: false, error };
|
|
251
251
|
}
|
|
252
252
|
|
|
253
|
+
// src/capabilities.ts
|
|
254
|
+
function readCapabilities(body) {
|
|
255
|
+
if (!isPlainObject(body)) {
|
|
256
|
+
return fail(ERR.INVALID_RESPONSE("Capabilities response is not a JSON object"));
|
|
257
|
+
}
|
|
258
|
+
const targets = objectOf(body.targets);
|
|
259
|
+
const features = objectOf(body.features);
|
|
260
|
+
return ok({
|
|
261
|
+
versions: Object.fromEntries(Object.entries(objectOf(body.versions)).filter((entry) => typeof entry[1] === "string")),
|
|
262
|
+
stages: Object.fromEntries(Object.entries(objectOf(body.stages)).map(([name, stage]) => [name, readStage(objectOf(stage))])),
|
|
263
|
+
sources: stringsOf(body.sources),
|
|
264
|
+
targets: { allowed: stringsOf(targets.allowed), default: stringOf(targets.default) },
|
|
265
|
+
outputFormats: stringsOf(body.output_formats),
|
|
266
|
+
imageExportModes: stringsOf(body.image_export_modes),
|
|
267
|
+
limits: readLimits(objectOf(body.limits)),
|
|
268
|
+
features: {
|
|
269
|
+
apiKeyRequired: features.api_key_required === true,
|
|
270
|
+
artifactStorage: features.artifact_storage === true,
|
|
271
|
+
websocket: features.websocket === true
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
function readStage(stage) {
|
|
276
|
+
const presets = [];
|
|
277
|
+
for (const item of Array.isArray(stage.presets) ? stage.presets : []) {
|
|
278
|
+
const preset = objectOf(item);
|
|
279
|
+
if (typeof preset.id === "string") {
|
|
280
|
+
presets.push({
|
|
281
|
+
id: preset.id,
|
|
282
|
+
name: stringOf(preset.name),
|
|
283
|
+
description: typeof preset.description === "string" ? preset.description : null,
|
|
284
|
+
source: stringOf(preset.source)
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return {
|
|
289
|
+
option: stringOf(stage.option),
|
|
290
|
+
customConfigOption: typeof stage.custom_config_option === "string" ? stage.custom_config_option : null,
|
|
291
|
+
default: stringOf(stage.default),
|
|
292
|
+
presets
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
function readLimits(limits) {
|
|
296
|
+
return {
|
|
297
|
+
maxDocumentTimeout: numberOf(limits.max_document_timeout),
|
|
298
|
+
maxImagesScale: numberOf(limits.max_images_scale),
|
|
299
|
+
maxSourcesPerRequest: numberOf(limits.max_sources_per_request),
|
|
300
|
+
maxNumPages: numberOf(limits.max_num_pages),
|
|
301
|
+
maxFileSize: numberOf(limits.max_file_size)
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
function objectOf(value) {
|
|
305
|
+
return isPlainObject(value) ? value : {};
|
|
306
|
+
}
|
|
307
|
+
function stringsOf(value) {
|
|
308
|
+
return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
|
|
309
|
+
}
|
|
310
|
+
function stringOf(value) {
|
|
311
|
+
return typeof value === "string" ? value : "";
|
|
312
|
+
}
|
|
313
|
+
function numberOf(value) {
|
|
314
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
315
|
+
}
|
|
316
|
+
|
|
253
317
|
// src/core/http.ts
|
|
254
318
|
var STRING_TOO_LONG = "ERR_STRING_TOO_LONG";
|
|
255
319
|
var MATCH_OUT_OF_MEMORY = /out of memory/i;
|
|
@@ -368,7 +432,8 @@ var DEFAULT_OPTIONS = Object.freeze({
|
|
|
368
432
|
pipeline: "standard",
|
|
369
433
|
pdfBackend: "docling_parse",
|
|
370
434
|
ocr: true,
|
|
371
|
-
forceOcr: false
|
|
435
|
+
forceOcr: false,
|
|
436
|
+
ocrEngine: "auto"
|
|
372
437
|
});
|
|
373
438
|
var CALL_OPTION_RULES = {
|
|
374
439
|
headingHierarchy: isBoolean,
|
|
@@ -378,7 +443,8 @@ var CALL_OPTION_RULES = {
|
|
|
378
443
|
pipeline: (value) => isOneOf(value, PIPELINES),
|
|
379
444
|
pdfBackend: (value) => isOneOf(value, PDF_BACKENDS),
|
|
380
445
|
ocr: isBoolean,
|
|
381
|
-
forceOcr: isBoolean
|
|
446
|
+
forceOcr: isBoolean,
|
|
447
|
+
ocrEngine: (value) => typeof value === "string" && value !== ""
|
|
382
448
|
};
|
|
383
449
|
var CLIENT_OPTION_RULES = {
|
|
384
450
|
...CALL_OPTION_RULES,
|
|
@@ -635,10 +701,11 @@ function isPageNumber(value) {
|
|
|
635
701
|
}
|
|
636
702
|
|
|
637
703
|
// src/client.ts
|
|
638
|
-
var
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
704
|
+
var TABLE_STRUCTURE_PRESET = "tableformer_v1_accurate";
|
|
705
|
+
var VLM_PIPELINE_PRESET = "granite_docling";
|
|
706
|
+
var CHART_EXTRACTION_PRESET = "granite_vision_v4";
|
|
707
|
+
var CODE_FORMULA_PRESET = "codeformulav2";
|
|
708
|
+
var MATCH_UPPER_CASE = /[A-Z]/g;
|
|
642
709
|
var INVALID_INPUT = "Expected a non-empty PDF, PNG, JPEG, TIFF or WebP as Uint8Array";
|
|
643
710
|
var SERVER_ANSWERED = new Set([
|
|
644
711
|
"http",
|
|
@@ -657,13 +724,18 @@ function createDoclingClient(config) {
|
|
|
657
724
|
convertDocument,
|
|
658
725
|
submitMarkdown,
|
|
659
726
|
submitDocument,
|
|
660
|
-
check
|
|
727
|
+
check,
|
|
728
|
+
capabilities
|
|
661
729
|
};
|
|
662
730
|
async function convertMarkdown(input, options) {
|
|
663
731
|
const call = resolveMarkdownCall(defaults, options);
|
|
664
732
|
const fields = { format: "md", embedImages: call.output.images === "extract", pageImages: false };
|
|
665
733
|
const res = await post("/v1/convert/file", input, call.options, fields, call.signal);
|
|
666
|
-
|
|
734
|
+
if (!res.ok) {
|
|
735
|
+
return res;
|
|
736
|
+
}
|
|
737
|
+
const converted = await withVersions(readMarkdown(res.data.body, call.output));
|
|
738
|
+
return converted.ok ? ok({ ...converted.data, settings: res.data.settings }) : converted;
|
|
667
739
|
}
|
|
668
740
|
async function convertDocument(input, options) {
|
|
669
741
|
const call = resolveDocumentCall(defaults, options);
|
|
@@ -673,13 +745,17 @@ function createDoclingClient(config) {
|
|
|
673
745
|
pageImages: call.pageImages
|
|
674
746
|
};
|
|
675
747
|
const res = await post("/v1/convert/file", input, call.options, fields, call.signal);
|
|
676
|
-
|
|
748
|
+
if (!res.ok) {
|
|
749
|
+
return res;
|
|
750
|
+
}
|
|
751
|
+
const converted = await withVersions(readDocument(res.data.body));
|
|
752
|
+
return converted.ok ? ok({ ...converted.data, settings: res.data.settings }) : converted;
|
|
677
753
|
}
|
|
678
754
|
async function submitMarkdown(input, options) {
|
|
679
755
|
const call = resolveMarkdownCall(defaults, options);
|
|
680
756
|
const fields = { format: "md", embedImages: call.output.images === "extract", pageImages: false };
|
|
681
|
-
const
|
|
682
|
-
return
|
|
757
|
+
const task = await submit(input, call.options, fields, call.signal);
|
|
758
|
+
return task.ok ? ok({ kind: "markdown", id: task.data.id, output: call.output, settings: task.data.settings }) : task;
|
|
683
759
|
}
|
|
684
760
|
async function submitDocument(input, options) {
|
|
685
761
|
const call = resolveDocumentCall(defaults, options);
|
|
@@ -688,8 +764,8 @@ function createDoclingClient(config) {
|
|
|
688
764
|
embedImages: call.images === "embedded",
|
|
689
765
|
pageImages: call.pageImages
|
|
690
766
|
};
|
|
691
|
-
const
|
|
692
|
-
return
|
|
767
|
+
const task = await submit(input, call.options, fields, call.signal);
|
|
768
|
+
return task.ok ? ok({ kind: "document", id: task.data.id, settings: task.data.settings }) : task;
|
|
693
769
|
}
|
|
694
770
|
async function check(job, options) {
|
|
695
771
|
const { signal } = resolveCheckOptions(options);
|
|
@@ -733,12 +809,21 @@ function createDoclingClient(config) {
|
|
|
733
809
|
return failWithVersions(ERR.INVALID_RESPONSE(`Unexpected task status: ${String(task.task_status)}`));
|
|
734
810
|
}
|
|
735
811
|
}
|
|
812
|
+
async function capabilities(options) {
|
|
813
|
+
const { signal } = resolveCheckOptions(options);
|
|
814
|
+
const res = await get("/v1/capabilities", signal);
|
|
815
|
+
if (!res.ok) {
|
|
816
|
+
return failWithVersions(res.error);
|
|
817
|
+
}
|
|
818
|
+
const read = readCapabilities(res.data);
|
|
819
|
+
return read.ok ? read : failWithVersions(read.error);
|
|
820
|
+
}
|
|
736
821
|
async function submit(input, options, fields, signal) {
|
|
737
822
|
const res = await post("/v1/convert/file/async", input, options, fields, signal);
|
|
738
823
|
if (!res.ok) {
|
|
739
824
|
return res;
|
|
740
825
|
}
|
|
741
|
-
const id = res.data?.task_id;
|
|
826
|
+
const id = res.data.body?.task_id;
|
|
742
827
|
if (readText(id) === undefined) {
|
|
743
828
|
return failWithVersions(ERR.INVALID_RESPONSE("Response has no task_id"));
|
|
744
829
|
}
|
|
@@ -746,16 +831,17 @@ function createDoclingClient(config) {
|
|
|
746
831
|
const shown = JSON.stringify(id).slice(0, MAX_SHOWN_ID_LENGTH);
|
|
747
832
|
return failWithVersions(ERR.INVALID_RESPONSE(`Response has an unusable task_id: ${shown}`));
|
|
748
833
|
}
|
|
749
|
-
return ok(id);
|
|
834
|
+
return ok({ id, settings: res.data.settings });
|
|
750
835
|
}
|
|
751
836
|
async function post(route, input, options, fields, signal) {
|
|
752
837
|
const format = readInputFormat(input);
|
|
753
838
|
if (!format.ok) {
|
|
754
839
|
return format;
|
|
755
840
|
}
|
|
841
|
+
const settings = buildSettings(format.data, options, fields);
|
|
756
842
|
let body;
|
|
757
843
|
try {
|
|
758
|
-
body = buildFormData(input, format.data,
|
|
844
|
+
body = buildFormData(input, format.data, settings);
|
|
759
845
|
} catch (error) {
|
|
760
846
|
return fail(ERR.INVALID_INPUT(`Input could not be prepared for upload: ${errorMessage(error)}`));
|
|
761
847
|
}
|
|
@@ -766,7 +852,7 @@ function createDoclingClient(config) {
|
|
|
766
852
|
body,
|
|
767
853
|
...limited === undefined ? {} : { signal: limited }
|
|
768
854
|
});
|
|
769
|
-
return res.ok ? res : failWithVersions(res.error);
|
|
855
|
+
return res.ok ? ok({ body: res.data, settings }) : failWithVersions(res.error);
|
|
770
856
|
}
|
|
771
857
|
function get(route, signal, limit = true) {
|
|
772
858
|
const limited = limit ? withTimeout(signal, timeoutMs) : signal;
|
|
@@ -822,43 +908,51 @@ function readInputFormat(input) {
|
|
|
822
908
|
const offset = format.fromFormat === "pdf" ? findTruncatedXref(bytes) : undefined;
|
|
823
909
|
return offset === undefined ? ok(format) : fail(ERR.INVALID_INPUT(`PDF is truncated: cross-reference offset ${offset} lies past the end of the file (${bytes.length} bytes)`));
|
|
824
910
|
}
|
|
825
|
-
function
|
|
911
|
+
function buildSettings({ fromFormat }, options, { format, embedImages, pageImages }) {
|
|
912
|
+
const isImage = fromFormat === "image";
|
|
913
|
+
const isMarkdown = format === "md";
|
|
914
|
+
return {
|
|
915
|
+
fromFormats: fromFormat,
|
|
916
|
+
toFormats: format,
|
|
917
|
+
imageExportMode: embedImages || pageImages ? "embedded" : "placeholder",
|
|
918
|
+
includeImages: embedImages,
|
|
919
|
+
includePageImages: pageImages,
|
|
920
|
+
imagesScale: PAGE_IMAGE_SCALE,
|
|
921
|
+
mdCompactTables: isMarkdown ? true : null,
|
|
922
|
+
mdPageBreakPlaceholder: isMarkdown ? "" : null,
|
|
923
|
+
doOcr: isImage || options.ocr,
|
|
924
|
+
forceOcr: !isImage && options.forceOcr,
|
|
925
|
+
ocrPreset: options.ocrEngine,
|
|
926
|
+
ocrLang: [...options.ocrLang ?? []],
|
|
927
|
+
pdfBackend: options.pdfBackend,
|
|
928
|
+
pipeline: options.pipeline,
|
|
929
|
+
vlmPipelinePreset: options.pipeline === "vlm" ? VLM_PIPELINE_PRESET : null,
|
|
930
|
+
doTableStructure: true,
|
|
931
|
+
tableMode: "accurate",
|
|
932
|
+
tableStructurePreset: TABLE_STRUCTURE_PRESET,
|
|
933
|
+
tableCellMatching: true,
|
|
934
|
+
doPdfHeadingHierarchy: options.headingHierarchy,
|
|
935
|
+
doFormulaEnrichment: options.formulaEnrichment,
|
|
936
|
+
doCodeEnrichment: options.codeEnrichment,
|
|
937
|
+
codeFormulaPreset: options.formulaEnrichment || options.codeEnrichment ? CODE_FORMULA_PRESET : null,
|
|
938
|
+
doChartExtraction: options.chartExtraction,
|
|
939
|
+
chartExtractionPreset: options.chartExtraction ? CHART_EXTRACTION_PRESET : null,
|
|
940
|
+
doPictureClassification: false,
|
|
941
|
+
doPictureDescription: false,
|
|
942
|
+
pageRange: options.pageRange === undefined ? null : [options.pageRange[0], options.pageRange[1]],
|
|
943
|
+
documentTimeout: options.documentTimeout ?? null,
|
|
944
|
+
abortOnError: false
|
|
945
|
+
};
|
|
946
|
+
}
|
|
947
|
+
function buildFormData(input, { mimeType, fileName }, settings) {
|
|
826
948
|
const form = new FormData;
|
|
827
949
|
const bytes = input.buffer instanceof ArrayBuffer ? input : new Uint8Array(input);
|
|
828
950
|
form.append("files", new Blob([bytes], { type: mimeType }), fileName);
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
if (format === "md") {
|
|
835
|
-
form.append("md_compact_tables", "true");
|
|
836
|
-
}
|
|
837
|
-
form.append("include_images", String(embedImages));
|
|
838
|
-
form.append("include_page_images", String(pageImages));
|
|
839
|
-
form.append("image_export_mode", embedImages || pageImages ? "embedded" : "placeholder");
|
|
840
|
-
form.append("images_scale", String(PAGE_IMAGE_SCALE));
|
|
841
|
-
form.append("do_pdf_heading_hierarchy", String(options.headingHierarchy));
|
|
842
|
-
form.append("do_formula_enrichment", String(options.formulaEnrichment));
|
|
843
|
-
form.append("do_code_enrichment", String(options.codeEnrichment));
|
|
844
|
-
if (options.formulaEnrichment || options.codeEnrichment) {
|
|
845
|
-
form.append("code_formula_preset", "codeformulav2");
|
|
846
|
-
}
|
|
847
|
-
form.append("do_chart_extraction", String(options.chartExtraction));
|
|
848
|
-
form.append("pipeline", options.pipeline);
|
|
849
|
-
form.append("pdf_backend", options.pdfBackend);
|
|
850
|
-
const isImage = fromFormat === "image";
|
|
851
|
-
form.append("do_ocr", String(isImage || options.ocr));
|
|
852
|
-
form.append("force_ocr", String(!isImage && options.forceOcr));
|
|
853
|
-
for (const lang of options.ocrLang ?? []) {
|
|
854
|
-
form.append("ocr_lang", lang);
|
|
855
|
-
}
|
|
856
|
-
if (options.pageRange !== undefined) {
|
|
857
|
-
form.append("page_range", String(options.pageRange[0]));
|
|
858
|
-
form.append("page_range", String(options.pageRange[1]));
|
|
859
|
-
}
|
|
860
|
-
if (options.documentTimeout !== undefined) {
|
|
861
|
-
form.append("document_timeout", String(options.documentTimeout));
|
|
951
|
+
for (const [key, value] of Object.entries(settings)) {
|
|
952
|
+
const name = key.replace(MATCH_UPPER_CASE, (letter) => `_${letter.toLowerCase()}`);
|
|
953
|
+
for (const item of value === null ? [] : Array.isArray(value) ? value : [value]) {
|
|
954
|
+
form.append(name, String(item));
|
|
955
|
+
}
|
|
862
956
|
}
|
|
863
957
|
return form;
|
|
864
958
|
}
|
|
@@ -870,5 +964,5 @@ export {
|
|
|
870
964
|
toPageImageBox
|
|
871
965
|
};
|
|
872
966
|
|
|
873
|
-
//# debugId=
|
|
967
|
+
//# debugId=A74469BA02A838B164756E2164756E21
|
|
874
968
|
//# sourceMappingURL=index.js.map
|