@nodetool-ai/base-nodes 0.7.0-rc.11
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.ts +72 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +270 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/audio-wav.d.ts +66 -0
- package/dist/lib/audio-wav.d.ts.map +1 -0
- package/dist/lib/audio-wav.js +215 -0
- package/dist/lib/audio-wav.js.map +1 -0
- package/dist/nodes/agents.d.ts +253 -0
- package/dist/nodes/agents.d.ts.map +1 -0
- package/dist/nodes/agents.js +2784 -0
- package/dist/nodes/agents.js.map +1 -0
- package/dist/nodes/anthropic.d.ts +26 -0
- package/dist/nodes/anthropic.d.ts.map +1 -0
- package/dist/nodes/anthropic.js +133 -0
- package/dist/nodes/anthropic.js.map +1 -0
- package/dist/nodes/apify.d.ts +120 -0
- package/dist/nodes/apify.d.ts.map +1 -0
- package/dist/nodes/apify.js +618 -0
- package/dist/nodes/apify.js.map +1 -0
- package/dist/nodes/audio.d.ts +301 -0
- package/dist/nodes/audio.d.ts.map +1 -0
- package/dist/nodes/audio.js +1274 -0
- package/dist/nodes/audio.js.map +1 -0
- package/dist/nodes/code-node.d.ts +34 -0
- package/dist/nodes/code-node.d.ts.map +1 -0
- package/dist/nodes/code-node.js +343 -0
- package/dist/nodes/code-node.js.map +1 -0
- package/dist/nodes/code.d.ts +301 -0
- package/dist/nodes/code.d.ts.map +1 -0
- package/dist/nodes/code.js +850 -0
- package/dist/nodes/code.js.map +1 -0
- package/dist/nodes/compare.d.ts +18 -0
- package/dist/nodes/compare.d.ts.map +1 -0
- package/dist/nodes/compare.js +122 -0
- package/dist/nodes/compare.js.map +1 -0
- package/dist/nodes/constant.d.ts +315 -0
- package/dist/nodes/constant.d.ts.map +1 -0
- package/dist/nodes/constant.js +715 -0
- package/dist/nodes/constant.js.map +1 -0
- package/dist/nodes/control.d.ts +83 -0
- package/dist/nodes/control.d.ts.map +1 -0
- package/dist/nodes/control.js +212 -0
- package/dist/nodes/control.js.map +1 -0
- package/dist/nodes/data.d.ts +369 -0
- package/dist/nodes/data.d.ts.map +1 -0
- package/dist/nodes/data.js +1590 -0
- package/dist/nodes/data.js.map +1 -0
- package/dist/nodes/document.d.ts +134 -0
- package/dist/nodes/document.d.ts.map +1 -0
- package/dist/nodes/document.js +984 -0
- package/dist/nodes/document.js.map +1 -0
- package/dist/nodes/extended-placeholders.d.ts +6 -0
- package/dist/nodes/extended-placeholders.d.ts.map +1 -0
- package/dist/nodes/extended-placeholders.js +19 -0
- package/dist/nodes/extended-placeholders.js.map +1 -0
- package/dist/nodes/gemini.d.ts +109 -0
- package/dist/nodes/gemini.d.ts.map +1 -0
- package/dist/nodes/gemini.js +861 -0
- package/dist/nodes/gemini.js.map +1 -0
- package/dist/nodes/generators.d.ts +84 -0
- package/dist/nodes/generators.d.ts.map +1 -0
- package/dist/nodes/generators.js +937 -0
- package/dist/nodes/generators.js.map +1 -0
- package/dist/nodes/image.d.ts +232 -0
- package/dist/nodes/image.d.ts.map +1 -0
- package/dist/nodes/image.js +1395 -0
- package/dist/nodes/image.js.map +1 -0
- package/dist/nodes/input.d.ts +445 -0
- package/dist/nodes/input.d.ts.map +1 -0
- package/dist/nodes/input.js +1459 -0
- package/dist/nodes/input.js.map +1 -0
- package/dist/nodes/kie-dynamic.d.ts +31 -0
- package/dist/nodes/kie-dynamic.d.ts.map +1 -0
- package/dist/nodes/kie-dynamic.js +270 -0
- package/dist/nodes/kie-dynamic.js.map +1 -0
- package/dist/nodes/lib-audio-dsp.d.ts +85 -0
- package/dist/nodes/lib-audio-dsp.d.ts.map +1 -0
- package/dist/nodes/lib-audio-dsp.js +450 -0
- package/dist/nodes/lib-audio-dsp.js.map +1 -0
- package/dist/nodes/lib-audio-effects.d.ts +116 -0
- package/dist/nodes/lib-audio-effects.d.ts.map +1 -0
- package/dist/nodes/lib-audio-effects.js +905 -0
- package/dist/nodes/lib-audio-effects.js.map +1 -0
- package/dist/nodes/lib-browser.d.ts +99 -0
- package/dist/nodes/lib-browser.d.ts.map +1 -0
- package/dist/nodes/lib-browser.js +692 -0
- package/dist/nodes/lib-browser.js.map +1 -0
- package/dist/nodes/lib-charts.d.ts +20 -0
- package/dist/nodes/lib-charts.d.ts.map +1 -0
- package/dist/nodes/lib-charts.js +245 -0
- package/dist/nodes/lib-charts.js.map +1 -0
- package/dist/nodes/lib-datetime.d.ts +108 -0
- package/dist/nodes/lib-datetime.d.ts.map +1 -0
- package/dist/nodes/lib-datetime.js +421 -0
- package/dist/nodes/lib-datetime.js.map +1 -0
- package/dist/nodes/lib-doc-convert.d.ts +19 -0
- package/dist/nodes/lib-doc-convert.d.ts.map +1 -0
- package/dist/nodes/lib-doc-convert.js +257 -0
- package/dist/nodes/lib-doc-convert.js.map +1 -0
- package/dist/nodes/lib-doc-transform.d.ts +39 -0
- package/dist/nodes/lib-doc-transform.d.ts.map +1 -0
- package/dist/nodes/lib-doc-transform.js +335 -0
- package/dist/nodes/lib-doc-transform.js.map +1 -0
- package/dist/nodes/lib-docx.d.ts +106 -0
- package/dist/nodes/lib-docx.d.ts.map +1 -0
- package/dist/nodes/lib-docx.js +595 -0
- package/dist/nodes/lib-docx.js.map +1 -0
- package/dist/nodes/lib-epub.d.ts +55 -0
- package/dist/nodes/lib-epub.d.ts.map +1 -0
- package/dist/nodes/lib-epub.js +220 -0
- package/dist/nodes/lib-epub.js.map +1 -0
- package/dist/nodes/lib-excel.d.ts +74 -0
- package/dist/nodes/lib-excel.d.ts.map +1 -0
- package/dist/nodes/lib-excel.js +448 -0
- package/dist/nodes/lib-excel.js.map +1 -0
- package/dist/nodes/lib-graphql.d.ts +66 -0
- package/dist/nodes/lib-graphql.d.ts.map +1 -0
- package/dist/nodes/lib-graphql.js +333 -0
- package/dist/nodes/lib-graphql.js.map +1 -0
- package/dist/nodes/lib-grid.d.ts +27 -0
- package/dist/nodes/lib-grid.d.ts.map +1 -0
- package/dist/nodes/lib-grid.js +172 -0
- package/dist/nodes/lib-grid.js.map +1 -0
- package/dist/nodes/lib-html-parse.d.ts +108 -0
- package/dist/nodes/lib-html-parse.d.ts.map +1 -0
- package/dist/nodes/lib-html-parse.js +365 -0
- package/dist/nodes/lib-html-parse.js.map +1 -0
- package/dist/nodes/lib-http.d.ts +98 -0
- package/dist/nodes/lib-http.d.ts.map +1 -0
- package/dist/nodes/lib-http.js +267 -0
- package/dist/nodes/lib-http.js.map +1 -0
- package/dist/nodes/lib-image-color-grading.d.ts +3 -0
- package/dist/nodes/lib-image-color-grading.d.ts.map +1 -0
- package/dist/nodes/lib-image-color-grading.js +1386 -0
- package/dist/nodes/lib-image-color-grading.js.map +1 -0
- package/dist/nodes/lib-image-draw.d.ts +3 -0
- package/dist/nodes/lib-image-draw.d.ts.map +1 -0
- package/dist/nodes/lib-image-draw.js +470 -0
- package/dist/nodes/lib-image-draw.js.map +1 -0
- package/dist/nodes/lib-image-enhance.d.ts +3 -0
- package/dist/nodes/lib-image-enhance.d.ts.map +1 -0
- package/dist/nodes/lib-image-enhance.js +731 -0
- package/dist/nodes/lib-image-enhance.js.map +1 -0
- package/dist/nodes/lib-image-filter.d.ts +3 -0
- package/dist/nodes/lib-image-filter.d.ts.map +1 -0
- package/dist/nodes/lib-image-filter.js +684 -0
- package/dist/nodes/lib-image-filter.js.map +1 -0
- package/dist/nodes/lib-image-utils.d.ts +24 -0
- package/dist/nodes/lib-image-utils.d.ts.map +1 -0
- package/dist/nodes/lib-image-utils.js +150 -0
- package/dist/nodes/lib-image-utils.js.map +1 -0
- package/dist/nodes/lib-mail.d.ts +74 -0
- package/dist/nodes/lib-mail.d.ts.map +1 -0
- package/dist/nodes/lib-mail.js +452 -0
- package/dist/nodes/lib-mail.js.map +1 -0
- package/dist/nodes/lib-markdown.d.ts +70 -0
- package/dist/nodes/lib-markdown.d.ts.map +1 -0
- package/dist/nodes/lib-markdown.js +236 -0
- package/dist/nodes/lib-markdown.js.map +1 -0
- package/dist/nodes/lib-nlp.d.ts +98 -0
- package/dist/nodes/lib-nlp.d.ts.map +1 -0
- package/dist/nodes/lib-nlp.js +374 -0
- package/dist/nodes/lib-nlp.js.map +1 -0
- package/dist/nodes/lib-notion.d.ts +99 -0
- package/dist/nodes/lib-notion.d.ts.map +1 -0
- package/dist/nodes/lib-notion.js +601 -0
- package/dist/nodes/lib-notion.js.map +1 -0
- package/dist/nodes/lib-ocr.d.ts +31 -0
- package/dist/nodes/lib-ocr.d.ts.map +1 -0
- package/dist/nodes/lib-ocr.js +143 -0
- package/dist/nodes/lib-ocr.js.map +1 -0
- package/dist/nodes/lib-os.d.ts +312 -0
- package/dist/nodes/lib-os.d.ts.map +1 -0
- package/dist/nodes/lib-os.js +909 -0
- package/dist/nodes/lib-os.js.map +1 -0
- package/dist/nodes/lib-pdf.d.ts +142 -0
- package/dist/nodes/lib-pdf.d.ts.map +1 -0
- package/dist/nodes/lib-pdf.js +871 -0
- package/dist/nodes/lib-pdf.js.map +1 -0
- package/dist/nodes/lib-pptx.d.ts +29 -0
- package/dist/nodes/lib-pptx.d.ts.map +1 -0
- package/dist/nodes/lib-pptx.js +122 -0
- package/dist/nodes/lib-pptx.js.map +1 -0
- package/dist/nodes/lib-rss.d.ts +31 -0
- package/dist/nodes/lib-rss.d.ts.map +1 -0
- package/dist/nodes/lib-rss.js +163 -0
- package/dist/nodes/lib-rss.js.map +1 -0
- package/dist/nodes/lib-s3.d.ts +112 -0
- package/dist/nodes/lib-s3.d.ts.map +1 -0
- package/dist/nodes/lib-s3.js +521 -0
- package/dist/nodes/lib-s3.js.map +1 -0
- package/dist/nodes/lib-secret.d.ts +15 -0
- package/dist/nodes/lib-secret.d.ts.map +1 -0
- package/dist/nodes/lib-secret.js +42 -0
- package/dist/nodes/lib-secret.js.map +1 -0
- package/dist/nodes/lib-sqlite.d.ts +102 -0
- package/dist/nodes/lib-sqlite.d.ts.map +1 -0
- package/dist/nodes/lib-sqlite.js +532 -0
- package/dist/nodes/lib-sqlite.js.map +1 -0
- package/dist/nodes/lib-supabase.d.ts +86 -0
- package/dist/nodes/lib-supabase.d.ts.map +1 -0
- package/dist/nodes/lib-supabase.js +425 -0
- package/dist/nodes/lib-supabase.js.map +1 -0
- package/dist/nodes/lib-svg.d.ts +199 -0
- package/dist/nodes/lib-svg.d.ts.map +1 -0
- package/dist/nodes/lib-svg.js +1027 -0
- package/dist/nodes/lib-svg.js.map +1 -0
- package/dist/nodes/lib-tensorflow.d.ts +71 -0
- package/dist/nodes/lib-tensorflow.d.ts.map +1 -0
- package/dist/nodes/lib-tensorflow.js +351 -0
- package/dist/nodes/lib-tensorflow.js.map +1 -0
- package/dist/nodes/lib-twilio.d.ts +71 -0
- package/dist/nodes/lib-twilio.d.ts.map +1 -0
- package/dist/nodes/lib-twilio.js +469 -0
- package/dist/nodes/lib-twilio.js.map +1 -0
- package/dist/nodes/lib-validate.d.ts +84 -0
- package/dist/nodes/lib-validate.d.ts.map +1 -0
- package/dist/nodes/lib-validate.js +215 -0
- package/dist/nodes/lib-validate.js.map +1 -0
- package/dist/nodes/lib-video-download.d.ts +26 -0
- package/dist/nodes/lib-video-download.d.ts.map +1 -0
- package/dist/nodes/lib-video-download.js +299 -0
- package/dist/nodes/lib-video-download.js.map +1 -0
- package/dist/nodes/messaging.d.ts +88 -0
- package/dist/nodes/messaging.d.ts.map +1 -0
- package/dist/nodes/messaging.js +418 -0
- package/dist/nodes/messaging.js.map +1 -0
- package/dist/nodes/mistral.d.ts +83 -0
- package/dist/nodes/mistral.d.ts.map +1 -0
- package/dist/nodes/mistral.js +450 -0
- package/dist/nodes/mistral.js.map +1 -0
- package/dist/nodes/model3d/analysis.d.ts +13 -0
- package/dist/nodes/model3d/analysis.d.ts.map +1 -0
- package/dist/nodes/model3d/analysis.js +36 -0
- package/dist/nodes/model3d/analysis.js.map +1 -0
- package/dist/nodes/model3d/base.d.ts +11 -0
- package/dist/nodes/model3d/base.d.ts.map +1 -0
- package/dist/nodes/model3d/base.js +20 -0
- package/dist/nodes/model3d/base.js.map +1 -0
- package/dist/nodes/model3d/boolean-ops.d.ts +2 -0
- package/dist/nodes/model3d/boolean-ops.d.ts.map +1 -0
- package/dist/nodes/model3d/boolean-ops.js +172 -0
- package/dist/nodes/model3d/boolean-ops.js.map +1 -0
- package/dist/nodes/model3d/cleanup.d.ts +47 -0
- package/dist/nodes/model3d/cleanup.d.ts.map +1 -0
- package/dist/nodes/model3d/cleanup.js +136 -0
- package/dist/nodes/model3d/cleanup.js.map +1 -0
- package/dist/nodes/model3d/convert.d.ts +14 -0
- package/dist/nodes/model3d/convert.d.ts.map +1 -0
- package/dist/nodes/model3d/convert.js +64 -0
- package/dist/nodes/model3d/convert.js.map +1 -0
- package/dist/nodes/model3d/defaults.d.ts +34 -0
- package/dist/nodes/model3d/defaults.d.ts.map +1 -0
- package/dist/nodes/model3d/defaults.js +28 -0
- package/dist/nodes/model3d/defaults.js.map +1 -0
- package/dist/nodes/model3d/document-ops.d.ts +4 -0
- package/dist/nodes/model3d/document-ops.d.ts.map +1 -0
- package/dist/nodes/model3d/document-ops.js +40 -0
- package/dist/nodes/model3d/document-ops.js.map +1 -0
- package/dist/nodes/model3d/generation.d.ts +39 -0
- package/dist/nodes/model3d/generation.d.ts.map +1 -0
- package/dist/nodes/model3d/generation.js +179 -0
- package/dist/nodes/model3d/generation.js.map +1 -0
- package/dist/nodes/model3d/glb.d.ts +29 -0
- package/dist/nodes/model3d/glb.d.ts.map +1 -0
- package/dist/nodes/model3d/glb.js +255 -0
- package/dist/nodes/model3d/glb.js.map +1 -0
- package/dist/nodes/model3d/index.d.ts +20 -0
- package/dist/nodes/model3d/index.d.ts.map +1 -0
- package/dist/nodes/model3d/index.js +38 -0
- package/dist/nodes/model3d/index.js.map +1 -0
- package/dist/nodes/model3d/io.d.ts +38 -0
- package/dist/nodes/model3d/io.d.ts.map +1 -0
- package/dist/nodes/model3d/io.js +162 -0
- package/dist/nodes/model3d/io.js.map +1 -0
- package/dist/nodes/model3d/mesh-ops.d.ts +40 -0
- package/dist/nodes/model3d/mesh-ops.d.ts.map +1 -0
- package/dist/nodes/model3d/mesh-ops.js +775 -0
- package/dist/nodes/model3d/mesh-ops.js.map +1 -0
- package/dist/nodes/model3d/nodes.d.ts +2 -0
- package/dist/nodes/model3d/nodes.d.ts.map +1 -0
- package/dist/nodes/model3d/nodes.js +2 -0
- package/dist/nodes/model3d/nodes.js.map +1 -0
- package/dist/nodes/model3d/ops.d.ts +37 -0
- package/dist/nodes/model3d/ops.d.ts.map +1 -0
- package/dist/nodes/model3d/ops.js +137 -0
- package/dist/nodes/model3d/ops.js.map +1 -0
- package/dist/nodes/model3d/transforms.d.ts +49 -0
- package/dist/nodes/model3d/transforms.d.ts.map +1 -0
- package/dist/nodes/model3d/transforms.js +142 -0
- package/dist/nodes/model3d/transforms.js.map +1 -0
- package/dist/nodes/model3d/types.d.ts +81 -0
- package/dist/nodes/model3d/types.d.ts.map +1 -0
- package/dist/nodes/model3d/types.js +2 -0
- package/dist/nodes/model3d/types.js.map +1 -0
- package/dist/nodes/model3d/utils.d.ts +34 -0
- package/dist/nodes/model3d/utils.d.ts.map +1 -0
- package/dist/nodes/model3d/utils.js +185 -0
- package/dist/nodes/model3d/utils.js.map +1 -0
- package/dist/nodes/model3d.d.ts +2 -0
- package/dist/nodes/model3d.d.ts.map +1 -0
- package/dist/nodes/model3d.js +2 -0
- package/dist/nodes/model3d.js.map +1 -0
- package/dist/nodes/openai.d.ts +172 -0
- package/dist/nodes/openai.d.ts.map +1 -0
- package/dist/nodes/openai.js +1294 -0
- package/dist/nodes/openai.js.map +1 -0
- package/dist/nodes/output.d.ts +29 -0
- package/dist/nodes/output.d.ts.map +1 -0
- package/dist/nodes/output.js +87 -0
- package/dist/nodes/output.js.map +1 -0
- package/dist/nodes/sandbox.d.ts +67 -0
- package/dist/nodes/sandbox.d.ts.map +1 -0
- package/dist/nodes/sandbox.js +681 -0
- package/dist/nodes/sandbox.js.map +1 -0
- package/dist/nodes/search.d.ts +117 -0
- package/dist/nodes/search.d.ts.map +1 -0
- package/dist/nodes/search.js +607 -0
- package/dist/nodes/search.js.map +1 -0
- package/dist/nodes/team.d.ts +74 -0
- package/dist/nodes/team.d.ts.map +1 -0
- package/dist/nodes/team.js +304 -0
- package/dist/nodes/team.js.map +1 -0
- package/dist/nodes/text-extra.d.ts +633 -0
- package/dist/nodes/text-extra.d.ts.map +1 -0
- package/dist/nodes/text-extra.js +2226 -0
- package/dist/nodes/text-extra.js.map +1 -0
- package/dist/nodes/tool-agents.d.ts +334 -0
- package/dist/nodes/tool-agents.d.ts.map +1 -0
- package/dist/nodes/tool-agents.js +1861 -0
- package/dist/nodes/tool-agents.js.map +1 -0
- package/dist/nodes/triggers.d.ts +107 -0
- package/dist/nodes/triggers.d.ts.map +1 -0
- package/dist/nodes/triggers.js +706 -0
- package/dist/nodes/triggers.js.map +1 -0
- package/dist/nodes/vector.d.ts +168 -0
- package/dist/nodes/vector.d.ts.map +1 -0
- package/dist/nodes/vector.js +1121 -0
- package/dist/nodes/vector.js.map +1 -0
- package/dist/nodes/video.d.ts +387 -0
- package/dist/nodes/video.d.ts.map +1 -0
- package/dist/nodes/video.js +2361 -0
- package/dist/nodes/video.js.map +1 -0
- package/dist/nodes/workflow.d.ts +24 -0
- package/dist/nodes/workflow.d.ts.map +1 -0
- package/dist/nodes/workflow.js +146 -0
- package/dist/nodes/workflow.js.map +1 -0
- package/dist/nodes/workspace.d.ts +203 -0
- package/dist/nodes/workspace.d.ts.map +1 -0
- package/dist/nodes/workspace.js +795 -0
- package/dist/nodes/workspace.js.map +1 -0
- package/package.json +103 -0
|
@@ -0,0 +1,871 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* PDF processing nodes using @llamaindex/liteparse.
|
|
9
|
+
*
|
|
10
|
+
* Provides text extraction, markdown conversion, table detection,
|
|
11
|
+
* layout analysis, metadata reading, screenshots, text search,
|
|
12
|
+
* and OCR extraction from PDF documents.
|
|
13
|
+
*/
|
|
14
|
+
import { BaseNode, prop } from "@nodetool-ai/node-sdk";
|
|
15
|
+
function asBytes(data) {
|
|
16
|
+
if (!data)
|
|
17
|
+
return new Uint8Array();
|
|
18
|
+
if (data instanceof Uint8Array)
|
|
19
|
+
return data;
|
|
20
|
+
return Uint8Array.from(Buffer.from(data, "base64"));
|
|
21
|
+
}
|
|
22
|
+
async function resolvePdfBuffer(pdf, context) {
|
|
23
|
+
if (pdf.data) {
|
|
24
|
+
return Buffer.from(asBytes(pdf.data));
|
|
25
|
+
}
|
|
26
|
+
else if (pdf.uri) {
|
|
27
|
+
const uri = pdf.uri.startsWith("file://") ? pdf.uri.slice(7) : pdf.uri;
|
|
28
|
+
if (context?.storage) {
|
|
29
|
+
const stored = await context.storage.retrieve(pdf.uri);
|
|
30
|
+
if (stored !== null)
|
|
31
|
+
return Buffer.from(stored);
|
|
32
|
+
}
|
|
33
|
+
const { promises: fs } = await import("node:fs");
|
|
34
|
+
return fs.readFile(uri);
|
|
35
|
+
}
|
|
36
|
+
throw new Error("No PDF data or URI provided");
|
|
37
|
+
}
|
|
38
|
+
async function parsePdf(pdf, context) {
|
|
39
|
+
const { LiteParse } = await import("@llamaindex/liteparse");
|
|
40
|
+
const pdfBuffer = await resolvePdfBuffer(pdf, context);
|
|
41
|
+
const parser = new LiteParse({ ocrEnabled: false });
|
|
42
|
+
return parser.parse(pdfBuffer, true);
|
|
43
|
+
}
|
|
44
|
+
function resolvePageRange(startPage, endPage, totalPages) {
|
|
45
|
+
const start = Math.max(0, startPage);
|
|
46
|
+
const end = endPage === -1 ? totalPages - 1 : Math.min(endPage, totalPages - 1);
|
|
47
|
+
return [start, end];
|
|
48
|
+
}
|
|
49
|
+
/** Standard page-range props shared by most nodes. */
|
|
50
|
+
const PDF_INPUT = {
|
|
51
|
+
type: "document",
|
|
52
|
+
default: {
|
|
53
|
+
type: "document",
|
|
54
|
+
uri: "",
|
|
55
|
+
asset_id: null,
|
|
56
|
+
data: null,
|
|
57
|
+
metadata: null
|
|
58
|
+
},
|
|
59
|
+
title: "PDF",
|
|
60
|
+
description: "The PDF document to process"
|
|
61
|
+
};
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
// PageCount
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
export class PdfPageCountNode extends BaseNode {
|
|
66
|
+
static nodeType = "lib.pdf.PageCount";
|
|
67
|
+
static title = "PDF Page Count";
|
|
68
|
+
static description = "Get the total number of pages in a PDF document.\n pdf, pages, count, length";
|
|
69
|
+
static metadataOutputTypes = { output: "int" };
|
|
70
|
+
async process(context) {
|
|
71
|
+
const result = await parsePdf((this.pdf ?? {}), context);
|
|
72
|
+
return { output: result.pages.length };
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
__decorate([
|
|
76
|
+
prop(PDF_INPUT)
|
|
77
|
+
], PdfPageCountNode.prototype, "pdf", void 0);
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
// ExtractText
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
export class PdfExtractTextNode extends BaseNode {
|
|
82
|
+
static nodeType = "lib.pdf.ExtractText";
|
|
83
|
+
static title = "PDF Extract Text";
|
|
84
|
+
static description = "Extract plain text from a PDF, preserving line breaks based on layout position.\n pdf, text, extract, read, content";
|
|
85
|
+
static metadataOutputTypes = { output: "str" };
|
|
86
|
+
static exposeAsTool = true;
|
|
87
|
+
async process(context) {
|
|
88
|
+
const result = await parsePdf((this.pdf ?? {}), context);
|
|
89
|
+
const [start, end] = resolvePageRange(Number(this.start_page ?? 0), Number(this.end_page ?? -1), result.pages.length);
|
|
90
|
+
const parts = [];
|
|
91
|
+
for (let i = start; i <= end; i++) {
|
|
92
|
+
const page = result.pages[i];
|
|
93
|
+
if (page)
|
|
94
|
+
parts.push(page.text);
|
|
95
|
+
}
|
|
96
|
+
return { output: parts.join("\n\n").trim() };
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
__decorate([
|
|
100
|
+
prop(PDF_INPUT)
|
|
101
|
+
], PdfExtractTextNode.prototype, "pdf", void 0);
|
|
102
|
+
__decorate([
|
|
103
|
+
prop({
|
|
104
|
+
type: "int",
|
|
105
|
+
default: 0,
|
|
106
|
+
title: "Start Page",
|
|
107
|
+
description: "First page (0-based)"
|
|
108
|
+
})
|
|
109
|
+
], PdfExtractTextNode.prototype, "start_page", void 0);
|
|
110
|
+
__decorate([
|
|
111
|
+
prop({
|
|
112
|
+
type: "int",
|
|
113
|
+
default: -1,
|
|
114
|
+
title: "End Page",
|
|
115
|
+
description: "Last page (-1 for all)"
|
|
116
|
+
})
|
|
117
|
+
], PdfExtractTextNode.prototype, "end_page", void 0);
|
|
118
|
+
// ---------------------------------------------------------------------------
|
|
119
|
+
// ExtractMarkdown
|
|
120
|
+
// ---------------------------------------------------------------------------
|
|
121
|
+
export class PdfExtractMarkdownNode extends BaseNode {
|
|
122
|
+
static nodeType = "lib.pdf.ExtractMarkdown";
|
|
123
|
+
static title = "PDF to Markdown";
|
|
124
|
+
static description = "Convert PDF to Markdown, inferring headings from font size.\n pdf, markdown, convert, headings, structure";
|
|
125
|
+
static metadataOutputTypes = { output: "str" };
|
|
126
|
+
static exposeAsTool = true;
|
|
127
|
+
async process(context) {
|
|
128
|
+
const result = await parsePdf((this.pdf ?? {}), context);
|
|
129
|
+
const [start, end] = resolvePageRange(Number(this.start_page ?? 0), Number(this.end_page ?? -1), result.pages.length);
|
|
130
|
+
const bulletRe = /^[•‣◦⁃∙\-*]\s*/;
|
|
131
|
+
const numberedRe = /^(\d+)[.)]\s*/;
|
|
132
|
+
const mdParts = [];
|
|
133
|
+
for (let i = start; i <= end; i++) {
|
|
134
|
+
const page = result.pages[i];
|
|
135
|
+
if (!page)
|
|
136
|
+
continue;
|
|
137
|
+
const items = page.textItems
|
|
138
|
+
.filter((it) => it.str.trim())
|
|
139
|
+
.sort((a, b) => a.y - b.y || a.x - b.x);
|
|
140
|
+
if (items.length === 0)
|
|
141
|
+
continue;
|
|
142
|
+
// Compute average font size for heading thresholds
|
|
143
|
+
const sizes = items.map((it) => it.fontSize ?? it.height ?? 12);
|
|
144
|
+
const avgSize = sizes.reduce((a, b) => a + b, 0) / sizes.length;
|
|
145
|
+
// Detect left margin for indent detection
|
|
146
|
+
const leftMargin = Math.min(...items.map((it) => it.x));
|
|
147
|
+
const indentThreshold = 15;
|
|
148
|
+
const lineMap = new Map();
|
|
149
|
+
const yTol = 3;
|
|
150
|
+
for (const item of items) {
|
|
151
|
+
const ky = Math.round(item.y / yTol) * yTol;
|
|
152
|
+
const existing = lineMap.get(ky);
|
|
153
|
+
const size = item.fontSize ?? item.height ?? 12;
|
|
154
|
+
const isBold = /bold/i.test(item.fontName ?? "");
|
|
155
|
+
if (existing) {
|
|
156
|
+
existing.text += item.str;
|
|
157
|
+
existing.maxSize = Math.max(existing.maxSize, size);
|
|
158
|
+
if (isBold)
|
|
159
|
+
existing.isBold = true;
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
lineMap.set(ky, {
|
|
163
|
+
text: item.str,
|
|
164
|
+
maxSize: size,
|
|
165
|
+
isBold,
|
|
166
|
+
x: item.x,
|
|
167
|
+
y: item.y
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
const lineEntries = Array.from(lineMap.entries())
|
|
172
|
+
.sort((a, b) => a[0] - b[0])
|
|
173
|
+
.map(([, ld]) => ld);
|
|
174
|
+
// Detect table-like rows: groups with consistent multi-column layout
|
|
175
|
+
const tableYTol = 3;
|
|
176
|
+
const rowMap = new Map();
|
|
177
|
+
for (const item of items) {
|
|
178
|
+
const ky = Math.round(item.y / tableYTol) * tableYTol;
|
|
179
|
+
if (!rowMap.has(ky))
|
|
180
|
+
rowMap.set(ky, []);
|
|
181
|
+
rowMap.get(ky).push({ x: item.x, str: item.str.trim() });
|
|
182
|
+
}
|
|
183
|
+
const rowEntries = Array.from(rowMap.entries())
|
|
184
|
+
.sort((a, b) => a[0] - b[0])
|
|
185
|
+
.map(([y, cells]) => ({ y, cells: cells.sort((a, b) => a.x - b.x) }));
|
|
186
|
+
const tableYRanges = [];
|
|
187
|
+
let runStart = 0;
|
|
188
|
+
while (runStart < rowEntries.length) {
|
|
189
|
+
const colCount = rowEntries[runStart].cells.length;
|
|
190
|
+
if (colCount < 2) {
|
|
191
|
+
runStart++;
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
let runEnd = runStart + 1;
|
|
195
|
+
while (runEnd < rowEntries.length &&
|
|
196
|
+
rowEntries[runEnd].cells.length === colCount) {
|
|
197
|
+
runEnd++;
|
|
198
|
+
}
|
|
199
|
+
if (runEnd - runStart >= 2) {
|
|
200
|
+
tableYRanges.push({
|
|
201
|
+
startY: rowEntries[runStart].y,
|
|
202
|
+
endY: rowEntries[runEnd - 1].y,
|
|
203
|
+
rows: rowEntries.slice(runStart, runEnd).map((r) => r.cells.map((c) => c.str))
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
runStart = runEnd;
|
|
207
|
+
}
|
|
208
|
+
const isInTable = (y) => {
|
|
209
|
+
const ry = Math.round(y / tableYTol) * tableYTol;
|
|
210
|
+
for (const range of tableYRanges) {
|
|
211
|
+
if (ry >= range.startY - tableYTol && ry <= range.endY + tableYTol)
|
|
212
|
+
return range;
|
|
213
|
+
}
|
|
214
|
+
return null;
|
|
215
|
+
};
|
|
216
|
+
const emittedTables = new Set();
|
|
217
|
+
const lines = [];
|
|
218
|
+
for (let li = 0; li < lineEntries.length; li++) {
|
|
219
|
+
const ld = lineEntries[li];
|
|
220
|
+
const text = ld.text.trim();
|
|
221
|
+
if (!text)
|
|
222
|
+
continue;
|
|
223
|
+
// Paragraph break detection (large Y gap between lines)
|
|
224
|
+
if (li > 0) {
|
|
225
|
+
const prev = lineEntries[li - 1];
|
|
226
|
+
const gap = ld.y - prev.y;
|
|
227
|
+
if (gap > avgSize * 1.8)
|
|
228
|
+
lines.push("");
|
|
229
|
+
}
|
|
230
|
+
const table = isInTable(ld.y);
|
|
231
|
+
if (table && !emittedTables.has(table)) {
|
|
232
|
+
emittedTables.add(table);
|
|
233
|
+
const header = table.rows[0];
|
|
234
|
+
lines.push("| " + header.join(" | ") + " |");
|
|
235
|
+
lines.push("| " + header.map(() => "---").join(" | ") + " |");
|
|
236
|
+
for (let ri = 1; ri < table.rows.length; ri++) {
|
|
237
|
+
lines.push("| " + table.rows[ri].join(" | ") + " |");
|
|
238
|
+
}
|
|
239
|
+
lines.push("");
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
if (table)
|
|
243
|
+
continue;
|
|
244
|
+
const bulletMatch = text.match(bulletRe);
|
|
245
|
+
const numberedMatch = text.match(numberedRe);
|
|
246
|
+
if (bulletMatch) {
|
|
247
|
+
lines.push(`- ${text.replace(bulletRe, "")}`);
|
|
248
|
+
}
|
|
249
|
+
else if (numberedMatch) {
|
|
250
|
+
lines.push(`${numberedMatch[1]}. ${text.replace(numberedRe, "")}`);
|
|
251
|
+
}
|
|
252
|
+
else if (ld.maxSize > avgSize * 1.5) {
|
|
253
|
+
lines.push(`# ${text}`);
|
|
254
|
+
}
|
|
255
|
+
else if (ld.maxSize > avgSize * 1.2) {
|
|
256
|
+
lines.push(`## ${text}`);
|
|
257
|
+
}
|
|
258
|
+
else if (ld.isBold && ld.maxSize >= avgSize) {
|
|
259
|
+
lines.push(`### ${text}`);
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
const isIndented = ld.x - leftMargin > indentThreshold;
|
|
263
|
+
void isIndented;
|
|
264
|
+
lines.push(text);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
mdParts.push(lines.join("\n"));
|
|
268
|
+
}
|
|
269
|
+
return { output: mdParts.join("\n\n---\n\n") };
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
__decorate([
|
|
273
|
+
prop(PDF_INPUT)
|
|
274
|
+
], PdfExtractMarkdownNode.prototype, "pdf", void 0);
|
|
275
|
+
__decorate([
|
|
276
|
+
prop({
|
|
277
|
+
type: "int",
|
|
278
|
+
default: 0,
|
|
279
|
+
title: "Start Page",
|
|
280
|
+
description: "First page (0-based)"
|
|
281
|
+
})
|
|
282
|
+
], PdfExtractMarkdownNode.prototype, "start_page", void 0);
|
|
283
|
+
__decorate([
|
|
284
|
+
prop({
|
|
285
|
+
type: "int",
|
|
286
|
+
default: -1,
|
|
287
|
+
title: "End Page",
|
|
288
|
+
description: "Last page (-1 for all)"
|
|
289
|
+
})
|
|
290
|
+
], PdfExtractMarkdownNode.prototype, "end_page", void 0);
|
|
291
|
+
// ---------------------------------------------------------------------------
|
|
292
|
+
// ExtractTables
|
|
293
|
+
// ---------------------------------------------------------------------------
|
|
294
|
+
export class PdfExtractTablesNode extends BaseNode {
|
|
295
|
+
static nodeType = "lib.pdf.ExtractTables";
|
|
296
|
+
static title = "PDF Extract Tables";
|
|
297
|
+
static description = "Detect and extract tables from a PDF by analysing text layout.\n pdf, tables, extract, data, rows, columns";
|
|
298
|
+
static metadataOutputTypes = { output: "list[dict]" };
|
|
299
|
+
static exposeAsTool = true;
|
|
300
|
+
async process(context) {
|
|
301
|
+
const result = await parsePdf((this.pdf ?? {}), context);
|
|
302
|
+
const [start, end] = resolvePageRange(Number(this.start_page ?? 0), Number(this.end_page ?? -1), result.pages.length);
|
|
303
|
+
const yTolerance = Number(this.y_tolerance ?? 3);
|
|
304
|
+
const tables = [];
|
|
305
|
+
for (let pageIdx = start; pageIdx <= end; pageIdx++) {
|
|
306
|
+
const page = result.pages[pageIdx];
|
|
307
|
+
if (!page)
|
|
308
|
+
continue;
|
|
309
|
+
const items = [];
|
|
310
|
+
for (const item of page.textItems) {
|
|
311
|
+
if (!item.str.trim())
|
|
312
|
+
continue;
|
|
313
|
+
items.push({
|
|
314
|
+
x: item.x,
|
|
315
|
+
y: Math.round(item.y / yTolerance) * yTolerance,
|
|
316
|
+
w: item.width,
|
|
317
|
+
str: item.str.trim()
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
const rowMap = new Map();
|
|
321
|
+
for (const it of items) {
|
|
322
|
+
if (!rowMap.has(it.y))
|
|
323
|
+
rowMap.set(it.y, []);
|
|
324
|
+
rowMap.get(it.y).push({ x: it.x, w: it.w, str: it.str });
|
|
325
|
+
}
|
|
326
|
+
const sortedRowEntries = Array.from(rowMap.entries())
|
|
327
|
+
.sort((a, b) => a[0] - b[0])
|
|
328
|
+
.map(([, cells]) => cells.sort((a, b) => a.x - b.x));
|
|
329
|
+
if (sortedRowEntries.length < 2)
|
|
330
|
+
continue;
|
|
331
|
+
const freq = new Map();
|
|
332
|
+
for (const r of sortedRowEntries) {
|
|
333
|
+
freq.set(r.length, (freq.get(r.length) ?? 0) + 1);
|
|
334
|
+
}
|
|
335
|
+
let mostCommonCount = 0;
|
|
336
|
+
let maxFreq = 0;
|
|
337
|
+
for (const [cols, count] of freq) {
|
|
338
|
+
if (cols >= 2 && count > maxFreq) {
|
|
339
|
+
mostCommonCount = cols;
|
|
340
|
+
maxFreq = count;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
if (mostCommonCount < 2 || maxFreq < 2)
|
|
344
|
+
continue;
|
|
345
|
+
const candidateRows = sortedRowEntries.filter((r) => r.length === mostCommonCount);
|
|
346
|
+
const colXPositions = Array.from({ length: mostCommonCount }, () => []);
|
|
347
|
+
for (const row of candidateRows) {
|
|
348
|
+
for (let ci = 0; ci < row.length; ci++) {
|
|
349
|
+
colXPositions[ci].push(row[ci].x);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
const colCenters = colXPositions.map((xs) => {
|
|
353
|
+
const sorted = xs.slice().sort((a, b) => a - b);
|
|
354
|
+
return sorted[Math.floor(sorted.length / 2)];
|
|
355
|
+
});
|
|
356
|
+
const maxSpread = 15;
|
|
357
|
+
let aligned = true;
|
|
358
|
+
for (const xs of colXPositions) {
|
|
359
|
+
if (Math.max(...xs) - Math.min(...xs) > maxSpread) {
|
|
360
|
+
aligned = false;
|
|
361
|
+
break;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
if (!aligned)
|
|
365
|
+
continue;
|
|
366
|
+
const colBoundaries = [];
|
|
367
|
+
for (let ci = 0; ci < mostCommonCount - 1; ci++) {
|
|
368
|
+
colBoundaries.push((colCenters[ci] + colCenters[ci + 1]) / 2);
|
|
369
|
+
}
|
|
370
|
+
const assignColumn = (x) => {
|
|
371
|
+
for (let bi = 0; bi < colBoundaries.length; bi++) {
|
|
372
|
+
if (x < colBoundaries[bi])
|
|
373
|
+
return bi;
|
|
374
|
+
}
|
|
375
|
+
return colBoundaries.length;
|
|
376
|
+
};
|
|
377
|
+
const tableRows = [];
|
|
378
|
+
for (const row of candidateRows) {
|
|
379
|
+
const cells = Array.from({ length: mostCommonCount }, () => "");
|
|
380
|
+
for (const cell of row) {
|
|
381
|
+
const ci = assignColumn(cell.x);
|
|
382
|
+
cells[ci] = cells[ci] ? `${cells[ci]} ${cell.str}` : cell.str;
|
|
383
|
+
}
|
|
384
|
+
tableRows.push(cells);
|
|
385
|
+
}
|
|
386
|
+
if (tableRows.length < 2)
|
|
387
|
+
continue;
|
|
388
|
+
tables.push({
|
|
389
|
+
page: pageIdx,
|
|
390
|
+
header: tableRows[0],
|
|
391
|
+
rows: tableRows.slice(1),
|
|
392
|
+
columns: mostCommonCount,
|
|
393
|
+
total_rows: tableRows.length
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
return { output: tables };
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
__decorate([
|
|
400
|
+
prop(PDF_INPUT)
|
|
401
|
+
], PdfExtractTablesNode.prototype, "pdf", void 0);
|
|
402
|
+
__decorate([
|
|
403
|
+
prop({
|
|
404
|
+
type: "int",
|
|
405
|
+
default: 0,
|
|
406
|
+
title: "Start Page",
|
|
407
|
+
description: "First page (0-based)"
|
|
408
|
+
})
|
|
409
|
+
], PdfExtractTablesNode.prototype, "start_page", void 0);
|
|
410
|
+
__decorate([
|
|
411
|
+
prop({
|
|
412
|
+
type: "int",
|
|
413
|
+
default: -1,
|
|
414
|
+
title: "End Page",
|
|
415
|
+
description: "Last page (-1 for all)"
|
|
416
|
+
})
|
|
417
|
+
], PdfExtractTablesNode.prototype, "end_page", void 0);
|
|
418
|
+
__decorate([
|
|
419
|
+
prop({
|
|
420
|
+
type: "int",
|
|
421
|
+
default: 3,
|
|
422
|
+
title: "Y Tolerance",
|
|
423
|
+
description: "Pixel tolerance for grouping text into rows",
|
|
424
|
+
min: 1,
|
|
425
|
+
max: 20
|
|
426
|
+
})
|
|
427
|
+
], PdfExtractTablesNode.prototype, "y_tolerance", void 0);
|
|
428
|
+
// ---------------------------------------------------------------------------
|
|
429
|
+
// ExtractTextBlocks
|
|
430
|
+
// ---------------------------------------------------------------------------
|
|
431
|
+
export class PdfExtractTextBlocksNode extends BaseNode {
|
|
432
|
+
static nodeType = "lib.pdf.ExtractTextBlocks";
|
|
433
|
+
static title = "PDF Extract Text Blocks";
|
|
434
|
+
static description = "Extract text blocks with bounding boxes, useful for layout analysis.\n pdf, text, blocks, layout, bbox, position";
|
|
435
|
+
static metadataOutputTypes = { output: "list[dict]" };
|
|
436
|
+
static exposeAsTool = true;
|
|
437
|
+
async process(context) {
|
|
438
|
+
const result = await parsePdf((this.pdf ?? {}), context);
|
|
439
|
+
const [start, end] = resolvePageRange(Number(this.start_page ?? 0), Number(this.end_page ?? -1), result.pages.length);
|
|
440
|
+
const blocks = [];
|
|
441
|
+
for (let i = start; i <= end; i++) {
|
|
442
|
+
const page = result.pages[i];
|
|
443
|
+
if (!page)
|
|
444
|
+
continue;
|
|
445
|
+
const items = page.textItems.sort((a, b) => a.y - b.y || a.x - b.x);
|
|
446
|
+
let block = null;
|
|
447
|
+
let lastY = null;
|
|
448
|
+
const flushBlock = () => {
|
|
449
|
+
if (block?.text.trim()) {
|
|
450
|
+
blocks.push({
|
|
451
|
+
page: i,
|
|
452
|
+
text: block.text.trim(),
|
|
453
|
+
bbox: {
|
|
454
|
+
x0: block.x0,
|
|
455
|
+
y0: block.y0,
|
|
456
|
+
x1: block.x1,
|
|
457
|
+
y1: block.y1
|
|
458
|
+
}
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
block = null;
|
|
462
|
+
};
|
|
463
|
+
for (const item of items) {
|
|
464
|
+
const h = item.height ?? 12;
|
|
465
|
+
if (lastY !== null && Math.abs(item.y - lastY) > h * 1.5)
|
|
466
|
+
flushBlock();
|
|
467
|
+
if (!block) {
|
|
468
|
+
block = {
|
|
469
|
+
text: "",
|
|
470
|
+
x0: item.x,
|
|
471
|
+
y0: item.y,
|
|
472
|
+
x1: item.x + item.width,
|
|
473
|
+
y1: item.y + h
|
|
474
|
+
};
|
|
475
|
+
}
|
|
476
|
+
block.text += item.str;
|
|
477
|
+
block.x0 = Math.min(block.x0, item.x);
|
|
478
|
+
block.y0 = Math.min(block.y0, item.y);
|
|
479
|
+
block.x1 = Math.max(block.x1, item.x + item.width);
|
|
480
|
+
block.y1 = Math.max(block.y1, item.y + h);
|
|
481
|
+
lastY = item.y;
|
|
482
|
+
}
|
|
483
|
+
flushBlock();
|
|
484
|
+
}
|
|
485
|
+
return { output: blocks };
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
__decorate([
|
|
489
|
+
prop(PDF_INPUT)
|
|
490
|
+
], PdfExtractTextBlocksNode.prototype, "pdf", void 0);
|
|
491
|
+
__decorate([
|
|
492
|
+
prop({
|
|
493
|
+
type: "int",
|
|
494
|
+
default: 0,
|
|
495
|
+
title: "Start Page",
|
|
496
|
+
description: "First page (0-based)"
|
|
497
|
+
})
|
|
498
|
+
], PdfExtractTextBlocksNode.prototype, "start_page", void 0);
|
|
499
|
+
__decorate([
|
|
500
|
+
prop({
|
|
501
|
+
type: "int",
|
|
502
|
+
default: -1,
|
|
503
|
+
title: "End Page",
|
|
504
|
+
description: "Last page (-1 for all)"
|
|
505
|
+
})
|
|
506
|
+
], PdfExtractTextBlocksNode.prototype, "end_page", void 0);
|
|
507
|
+
// ---------------------------------------------------------------------------
|
|
508
|
+
// ExtractStyledText
|
|
509
|
+
// ---------------------------------------------------------------------------
|
|
510
|
+
export class PdfExtractStyledTextNode extends BaseNode {
|
|
511
|
+
static nodeType = "lib.pdf.ExtractStyledText";
|
|
512
|
+
static title = "PDF Extract Styled Text";
|
|
513
|
+
static description = "Extract text spans with font name, size, bounding box, and color (always null; liteparse does not expose per-span color).\n pdf, text, style, font, size, formatting, color";
|
|
514
|
+
static metadataOutputTypes = { output: "list[dict]" };
|
|
515
|
+
static exposeAsTool = true;
|
|
516
|
+
async process(context) {
|
|
517
|
+
const result = await parsePdf((this.pdf ?? {}), context);
|
|
518
|
+
const [start, end] = resolvePageRange(Number(this.start_page ?? 0), Number(this.end_page ?? -1), result.pages.length);
|
|
519
|
+
const spans = [];
|
|
520
|
+
for (let i = start; i <= end; i++) {
|
|
521
|
+
const page = result.pages[i];
|
|
522
|
+
if (!page)
|
|
523
|
+
continue;
|
|
524
|
+
for (const item of page.textItems) {
|
|
525
|
+
if (!item.str.trim())
|
|
526
|
+
continue;
|
|
527
|
+
const h = item.height ?? 12;
|
|
528
|
+
spans.push({
|
|
529
|
+
page: i,
|
|
530
|
+
text: item.str,
|
|
531
|
+
font: item.fontName ?? "unknown",
|
|
532
|
+
size: item.fontSize ?? h,
|
|
533
|
+
color: null,
|
|
534
|
+
bbox: {
|
|
535
|
+
x0: item.x,
|
|
536
|
+
y0: item.y,
|
|
537
|
+
x1: item.x + item.width,
|
|
538
|
+
y1: item.y + h
|
|
539
|
+
}
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
return { output: spans };
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
__decorate([
|
|
547
|
+
prop(PDF_INPUT)
|
|
548
|
+
], PdfExtractStyledTextNode.prototype, "pdf", void 0);
|
|
549
|
+
__decorate([
|
|
550
|
+
prop({
|
|
551
|
+
type: "int",
|
|
552
|
+
default: 0,
|
|
553
|
+
title: "Start Page",
|
|
554
|
+
description: "First page (0-based)"
|
|
555
|
+
})
|
|
556
|
+
], PdfExtractStyledTextNode.prototype, "start_page", void 0);
|
|
557
|
+
__decorate([
|
|
558
|
+
prop({
|
|
559
|
+
type: "int",
|
|
560
|
+
default: -1,
|
|
561
|
+
title: "End Page",
|
|
562
|
+
description: "Last page (-1 for all)"
|
|
563
|
+
})
|
|
564
|
+
], PdfExtractStyledTextNode.prototype, "end_page", void 0);
|
|
565
|
+
// ---------------------------------------------------------------------------
|
|
566
|
+
// PageMetadata
|
|
567
|
+
// ---------------------------------------------------------------------------
|
|
568
|
+
export class PdfPageMetadataNode extends BaseNode {
|
|
569
|
+
static nodeType = "lib.pdf.PageMetadata";
|
|
570
|
+
static title = "PDF Page Metadata";
|
|
571
|
+
static description = "Get dimensions and bounding box for each page.\n pdf, metadata, pages, size, dimensions";
|
|
572
|
+
static metadataOutputTypes = { output: "list[dict]" };
|
|
573
|
+
async process(context) {
|
|
574
|
+
const result = await parsePdf((this.pdf ?? {}), context);
|
|
575
|
+
const [start, end] = resolvePageRange(Number(this.start_page ?? 0), Number(this.end_page ?? -1), result.pages.length);
|
|
576
|
+
const metadata = [];
|
|
577
|
+
for (let i = start; i <= end; i++) {
|
|
578
|
+
const page = result.pages[i];
|
|
579
|
+
if (!page)
|
|
580
|
+
continue;
|
|
581
|
+
let x0 = Infinity;
|
|
582
|
+
let y0 = Infinity;
|
|
583
|
+
let x1 = -Infinity;
|
|
584
|
+
let y1 = -Infinity;
|
|
585
|
+
for (const item of page.textItems) {
|
|
586
|
+
if (!item.str.trim())
|
|
587
|
+
continue;
|
|
588
|
+
const h = item.height ?? 12;
|
|
589
|
+
x0 = Math.min(x0, item.x);
|
|
590
|
+
y0 = Math.min(y0, item.y);
|
|
591
|
+
x1 = Math.max(x1, item.x + item.width);
|
|
592
|
+
y1 = Math.max(y1, item.y + h);
|
|
593
|
+
}
|
|
594
|
+
const hasContent = x0 !== Infinity;
|
|
595
|
+
metadata.push({
|
|
596
|
+
page: i,
|
|
597
|
+
width: page.width,
|
|
598
|
+
height: page.height,
|
|
599
|
+
bbox: hasContent ? { x0, y0, x1, y1 } : null
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
return { output: metadata };
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
__decorate([
|
|
606
|
+
prop(PDF_INPUT)
|
|
607
|
+
], PdfPageMetadataNode.prototype, "pdf", void 0);
|
|
608
|
+
__decorate([
|
|
609
|
+
prop({
|
|
610
|
+
type: "int",
|
|
611
|
+
default: 0,
|
|
612
|
+
title: "Start Page",
|
|
613
|
+
description: "First page (0-based)"
|
|
614
|
+
})
|
|
615
|
+
], PdfPageMetadataNode.prototype, "start_page", void 0);
|
|
616
|
+
__decorate([
|
|
617
|
+
prop({
|
|
618
|
+
type: "int",
|
|
619
|
+
default: -1,
|
|
620
|
+
title: "End Page",
|
|
621
|
+
description: "Last page (-1 for all)"
|
|
622
|
+
})
|
|
623
|
+
], PdfPageMetadataNode.prototype, "end_page", void 0);
|
|
624
|
+
// ---------------------------------------------------------------------------
|
|
625
|
+
// Screenshot
|
|
626
|
+
// ---------------------------------------------------------------------------
|
|
627
|
+
export class PdfScreenshotNode extends BaseNode {
|
|
628
|
+
static nodeType = "lib.pdf.Screenshot";
|
|
629
|
+
static title = "PDF Page Screenshot";
|
|
630
|
+
static description = "Render PDF pages as PNG images.\n pdf, screenshot, render, image, pages, png";
|
|
631
|
+
static metadataOutputTypes = { output: "list[image]" };
|
|
632
|
+
async process(context) {
|
|
633
|
+
// Bypass liteparse's parser.screenshot(): it loads the same buffer into
|
|
634
|
+
// pdf.js *and* PDFium, but pdf.js detaches the underlying ArrayBuffer
|
|
635
|
+
// during its load, leaving PDFium with a detached buffer (→ "File not in
|
|
636
|
+
// PDF format or corrupted"). Render directly via PDFium + sharp.
|
|
637
|
+
const [{ PDFiumLibrary }, sharpModule] = await Promise.all([
|
|
638
|
+
import("@hyzyla/pdfium"),
|
|
639
|
+
import("sharp")
|
|
640
|
+
]);
|
|
641
|
+
const sharp = sharpModule.default;
|
|
642
|
+
const pdfBuffer = await resolvePdfBuffer((this.pdf ?? {}), context);
|
|
643
|
+
const dpi = Number(this.dpi ?? 150);
|
|
644
|
+
const scale = dpi / 72;
|
|
645
|
+
const lib = await PDFiumLibrary.init();
|
|
646
|
+
const images = [];
|
|
647
|
+
let doc = null;
|
|
648
|
+
try {
|
|
649
|
+
doc = await lib.loadDocument(Buffer.from(pdfBuffer));
|
|
650
|
+
const totalPages = doc.getPageCount();
|
|
651
|
+
const [start, end] = resolvePageRange(Number(this.start_page ?? 0), Number(this.end_page ?? -1), totalPages);
|
|
652
|
+
for (let i = start; i <= end; i++) {
|
|
653
|
+
const page = doc.getPage(i);
|
|
654
|
+
const image = await page.render({
|
|
655
|
+
scale,
|
|
656
|
+
render: async (options) => sharp(options.data, {
|
|
657
|
+
raw: {
|
|
658
|
+
width: options.width,
|
|
659
|
+
height: options.height,
|
|
660
|
+
channels: 4
|
|
661
|
+
}
|
|
662
|
+
})
|
|
663
|
+
.png({ compressionLevel: 6 })
|
|
664
|
+
.withMetadata({ density: dpi })
|
|
665
|
+
.toBuffer()
|
|
666
|
+
});
|
|
667
|
+
images.push({
|
|
668
|
+
type: "image",
|
|
669
|
+
data: Buffer.from(image.data).toString("base64")
|
|
670
|
+
});
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
finally {
|
|
674
|
+
if (doc)
|
|
675
|
+
doc.destroy();
|
|
676
|
+
lib.destroy();
|
|
677
|
+
}
|
|
678
|
+
return { output: images };
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
__decorate([
|
|
682
|
+
prop(PDF_INPUT)
|
|
683
|
+
], PdfScreenshotNode.prototype, "pdf", void 0);
|
|
684
|
+
__decorate([
|
|
685
|
+
prop({
|
|
686
|
+
type: "int",
|
|
687
|
+
default: 0,
|
|
688
|
+
title: "Start Page",
|
|
689
|
+
description: "First page to render (0-based)"
|
|
690
|
+
})
|
|
691
|
+
], PdfScreenshotNode.prototype, "start_page", void 0);
|
|
692
|
+
__decorate([
|
|
693
|
+
prop({
|
|
694
|
+
type: "int",
|
|
695
|
+
default: -1,
|
|
696
|
+
title: "End Page",
|
|
697
|
+
description: "Last page to render (-1 for all)"
|
|
698
|
+
})
|
|
699
|
+
], PdfScreenshotNode.prototype, "end_page", void 0);
|
|
700
|
+
__decorate([
|
|
701
|
+
prop({
|
|
702
|
+
type: "int",
|
|
703
|
+
default: 150,
|
|
704
|
+
title: "DPI",
|
|
705
|
+
description: "Rendering resolution in dots per inch",
|
|
706
|
+
min: 72,
|
|
707
|
+
max: 600
|
|
708
|
+
})
|
|
709
|
+
], PdfScreenshotNode.prototype, "dpi", void 0);
|
|
710
|
+
// ---------------------------------------------------------------------------
|
|
711
|
+
// SearchText
|
|
712
|
+
// ---------------------------------------------------------------------------
|
|
713
|
+
export class PdfSearchTextNode extends BaseNode {
|
|
714
|
+
static nodeType = "lib.pdf.SearchText";
|
|
715
|
+
static title = "PDF Search Text";
|
|
716
|
+
static description = "Search a PDF for a phrase and return each match with its page number and bounding box.\n pdf, search, find, phrase, text, location, bbox";
|
|
717
|
+
static metadataOutputTypes = { output: "list[dict]" };
|
|
718
|
+
static exposeAsTool = true;
|
|
719
|
+
async process(context) {
|
|
720
|
+
const { searchItems } = await import("@llamaindex/liteparse");
|
|
721
|
+
const result = await parsePdf((this.pdf ?? {}), context);
|
|
722
|
+
const [start, end] = resolvePageRange(Number(this.start_page ?? 0), Number(this.end_page ?? -1), result.pages.length);
|
|
723
|
+
const phrase = String(this.phrase ?? "");
|
|
724
|
+
const caseSensitive = Boolean(this.case_sensitive ?? false);
|
|
725
|
+
const matches = [];
|
|
726
|
+
for (let i = start; i <= end; i++) {
|
|
727
|
+
const page = result.pages[i];
|
|
728
|
+
if (!page)
|
|
729
|
+
continue;
|
|
730
|
+
// Convert TextItem (str) to JsonTextItem (text) shape for searchItems
|
|
731
|
+
const jsonItems = page.textItems.map((it) => ({
|
|
732
|
+
text: it.str,
|
|
733
|
+
x: it.x,
|
|
734
|
+
y: it.y,
|
|
735
|
+
width: it.width,
|
|
736
|
+
height: it.height,
|
|
737
|
+
fontName: it.fontName,
|
|
738
|
+
fontSize: it.fontSize,
|
|
739
|
+
confidence: it.confidence
|
|
740
|
+
}));
|
|
741
|
+
const found = searchItems(jsonItems, { phrase, caseSensitive });
|
|
742
|
+
for (const m of found) {
|
|
743
|
+
matches.push({
|
|
744
|
+
page: i,
|
|
745
|
+
text: m.text,
|
|
746
|
+
x: m.x,
|
|
747
|
+
y: m.y,
|
|
748
|
+
width: m.width,
|
|
749
|
+
height: m.height,
|
|
750
|
+
fontName: m.fontName ?? null,
|
|
751
|
+
fontSize: m.fontSize ?? null
|
|
752
|
+
});
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
return { output: matches };
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
__decorate([
|
|
759
|
+
prop(PDF_INPUT)
|
|
760
|
+
], PdfSearchTextNode.prototype, "pdf", void 0);
|
|
761
|
+
__decorate([
|
|
762
|
+
prop({
|
|
763
|
+
type: "str",
|
|
764
|
+
default: "",
|
|
765
|
+
title: "Phrase",
|
|
766
|
+
description: "Text phrase to search for"
|
|
767
|
+
})
|
|
768
|
+
], PdfSearchTextNode.prototype, "phrase", void 0);
|
|
769
|
+
__decorate([
|
|
770
|
+
prop({
|
|
771
|
+
type: "bool",
|
|
772
|
+
default: false,
|
|
773
|
+
title: "Case Sensitive",
|
|
774
|
+
description: "Whether the search is case-sensitive"
|
|
775
|
+
})
|
|
776
|
+
], PdfSearchTextNode.prototype, "case_sensitive", void 0);
|
|
777
|
+
__decorate([
|
|
778
|
+
prop({
|
|
779
|
+
type: "int",
|
|
780
|
+
default: 0,
|
|
781
|
+
title: "Start Page",
|
|
782
|
+
description: "First page to search (0-based)"
|
|
783
|
+
})
|
|
784
|
+
], PdfSearchTextNode.prototype, "start_page", void 0);
|
|
785
|
+
__decorate([
|
|
786
|
+
prop({
|
|
787
|
+
type: "int",
|
|
788
|
+
default: -1,
|
|
789
|
+
title: "End Page",
|
|
790
|
+
description: "Last page to search (-1 for all)"
|
|
791
|
+
})
|
|
792
|
+
], PdfSearchTextNode.prototype, "end_page", void 0);
|
|
793
|
+
// ---------------------------------------------------------------------------
|
|
794
|
+
// ExtractOcr
|
|
795
|
+
// ---------------------------------------------------------------------------
|
|
796
|
+
export class PdfExtractOcrNode extends BaseNode {
|
|
797
|
+
static nodeType = "lib.pdf.ExtractOcr";
|
|
798
|
+
static title = "PDF Extract Text (OCR)";
|
|
799
|
+
static description = "Extract text from a PDF using OCR, suitable for scanned documents and image-based PDFs.\n pdf, ocr, scan, text, extract, image-based";
|
|
800
|
+
static metadataOutputTypes = { output: "str" };
|
|
801
|
+
static exposeAsTool = true;
|
|
802
|
+
async process(context) {
|
|
803
|
+
const { LiteParse } = await import("@llamaindex/liteparse");
|
|
804
|
+
const pdfBuffer = await resolvePdfBuffer((this.pdf ?? {}), context);
|
|
805
|
+
const ocrLanguage = String(this.ocr_language ?? "en");
|
|
806
|
+
const dpi = Number(this.dpi ?? 150);
|
|
807
|
+
const parser = new LiteParse({ ocrEnabled: true, ocrLanguage, dpi });
|
|
808
|
+
const result = await parser.parse(pdfBuffer, true);
|
|
809
|
+
const [start, end] = resolvePageRange(Number(this.start_page ?? 0), Number(this.end_page ?? -1), result.pages.length);
|
|
810
|
+
const parts = [];
|
|
811
|
+
for (let i = start; i <= end; i++) {
|
|
812
|
+
const page = result.pages[i];
|
|
813
|
+
if (page)
|
|
814
|
+
parts.push(page.text);
|
|
815
|
+
}
|
|
816
|
+
return { output: parts.join("\n\n").trim() };
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
__decorate([
|
|
820
|
+
prop(PDF_INPUT)
|
|
821
|
+
], PdfExtractOcrNode.prototype, "pdf", void 0);
|
|
822
|
+
__decorate([
|
|
823
|
+
prop({
|
|
824
|
+
type: "int",
|
|
825
|
+
default: 0,
|
|
826
|
+
title: "Start Page",
|
|
827
|
+
description: "First page (0-based)"
|
|
828
|
+
})
|
|
829
|
+
], PdfExtractOcrNode.prototype, "start_page", void 0);
|
|
830
|
+
__decorate([
|
|
831
|
+
prop({
|
|
832
|
+
type: "int",
|
|
833
|
+
default: -1,
|
|
834
|
+
title: "End Page",
|
|
835
|
+
description: "Last page (-1 for all)"
|
|
836
|
+
})
|
|
837
|
+
], PdfExtractOcrNode.prototype, "end_page", void 0);
|
|
838
|
+
__decorate([
|
|
839
|
+
prop({
|
|
840
|
+
type: "str",
|
|
841
|
+
default: "en",
|
|
842
|
+
title: "OCR Language",
|
|
843
|
+
description: "ISO 639-1 language code for OCR (e.g. en, fr, de, es)"
|
|
844
|
+
})
|
|
845
|
+
], PdfExtractOcrNode.prototype, "ocr_language", void 0);
|
|
846
|
+
__decorate([
|
|
847
|
+
prop({
|
|
848
|
+
type: "int",
|
|
849
|
+
default: 150,
|
|
850
|
+
title: "DPI",
|
|
851
|
+
description: "Rendering DPI for OCR — higher values improve accuracy on small text",
|
|
852
|
+
min: 72,
|
|
853
|
+
max: 600
|
|
854
|
+
})
|
|
855
|
+
], PdfExtractOcrNode.prototype, "dpi", void 0);
|
|
856
|
+
// ---------------------------------------------------------------------------
|
|
857
|
+
// Export
|
|
858
|
+
// ---------------------------------------------------------------------------
|
|
859
|
+
export const LIB_PDF_NODES = [
|
|
860
|
+
PdfPageCountNode,
|
|
861
|
+
PdfExtractTextNode,
|
|
862
|
+
PdfExtractMarkdownNode,
|
|
863
|
+
PdfExtractTablesNode,
|
|
864
|
+
PdfExtractTextBlocksNode,
|
|
865
|
+
PdfExtractStyledTextNode,
|
|
866
|
+
PdfPageMetadataNode,
|
|
867
|
+
PdfScreenshotNode,
|
|
868
|
+
PdfSearchTextNode,
|
|
869
|
+
PdfExtractOcrNode
|
|
870
|
+
];
|
|
871
|
+
//# sourceMappingURL=lib-pdf.js.map
|