docground 0.1.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/LICENSE +21 -0
- package/README.md +217 -0
- package/dist/src/compiler/zod-compiler.d.ts +31 -0
- package/dist/src/compiler/zod-compiler.d.ts.map +1 -0
- package/dist/src/compiler/zod-compiler.js +150 -0
- package/dist/src/compiler/zod-compiler.js.map +1 -0
- package/dist/src/core/extractor.d.ts +17 -0
- package/dist/src/core/extractor.d.ts.map +1 -0
- package/dist/src/core/extractor.js +268 -0
- package/dist/src/core/extractor.js.map +1 -0
- package/dist/src/core/types.d.ts +102 -0
- package/dist/src/core/types.d.ts.map +1 -0
- package/dist/src/core/types.js +2 -0
- package/dist/src/core/types.js.map +1 -0
- package/dist/src/grounding/bbox.d.ts +40 -0
- package/dist/src/grounding/bbox.d.ts.map +1 -0
- package/dist/src/grounding/bbox.js +98 -0
- package/dist/src/grounding/bbox.js.map +1 -0
- package/dist/src/index.d.ts +16 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +16 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/normalizers/currency.d.ts +14 -0
- package/dist/src/normalizers/currency.d.ts.map +1 -0
- package/dist/src/normalizers/currency.js +96 -0
- package/dist/src/normalizers/currency.js.map +1 -0
- package/dist/src/normalizers/tabular.d.ts +16 -0
- package/dist/src/normalizers/tabular.d.ts.map +1 -0
- package/dist/src/normalizers/tabular.js +81 -0
- package/dist/src/normalizers/tabular.js.map +1 -0
- package/dist/src/providers/anthropic-provider.d.ts +13 -0
- package/dist/src/providers/anthropic-provider.d.ts.map +1 -0
- package/dist/src/providers/anthropic-provider.js +62 -0
- package/dist/src/providers/anthropic-provider.js.map +1 -0
- package/dist/src/providers/factory.d.ts +11 -0
- package/dist/src/providers/factory.d.ts.map +1 -0
- package/dist/src/providers/factory.js +32 -0
- package/dist/src/providers/factory.js.map +1 -0
- package/dist/src/providers/gemini-provider.d.ts +13 -0
- package/dist/src/providers/gemini-provider.d.ts.map +1 -0
- package/dist/src/providers/gemini-provider.js +48 -0
- package/dist/src/providers/gemini-provider.js.map +1 -0
- package/dist/src/providers/openai-provider.d.ts +14 -0
- package/dist/src/providers/openai-provider.d.ts.map +1 -0
- package/dist/src/providers/openai-provider.js +48 -0
- package/dist/src/providers/openai-provider.js.map +1 -0
- package/dist/src/providers/types.d.ts +45 -0
- package/dist/src/providers/types.d.ts.map +1 -0
- package/dist/src/providers/types.js +2 -0
- package/dist/src/providers/types.js.map +1 -0
- package/dist/src/stitcher/table-stitcher.d.ts +19 -0
- package/dist/src/stitcher/table-stitcher.d.ts.map +1 -0
- package/dist/src/stitcher/table-stitcher.js +129 -0
- package/dist/src/stitcher/table-stitcher.js.map +1 -0
- package/dist/src/tiling/cutter.d.ts +14 -0
- package/dist/src/tiling/cutter.d.ts.map +1 -0
- package/dist/src/tiling/cutter.js +46 -0
- package/dist/src/tiling/cutter.js.map +1 -0
- package/dist/src/tiling/tiler.d.ts +41 -0
- package/dist/src/tiling/tiler.d.ts.map +1 -0
- package/dist/src/tiling/tiler.js +82 -0
- package/dist/src/tiling/tiler.js.map +1 -0
- package/dist/src/validators/invariants.d.ts +30 -0
- package/dist/src/validators/invariants.d.ts.map +1 -0
- package/dist/src/validators/invariants.js +164 -0
- package/dist/src/validators/invariants.js.map +1 -0
- package/dist/tests/compiler.test.d.ts +2 -0
- package/dist/tests/compiler.test.d.ts.map +1 -0
- package/dist/tests/compiler.test.js +110 -0
- package/dist/tests/compiler.test.js.map +1 -0
- package/dist/tests/extractor.test.d.ts +2 -0
- package/dist/tests/extractor.test.d.ts.map +1 -0
- package/dist/tests/extractor.test.js +195 -0
- package/dist/tests/extractor.test.js.map +1 -0
- package/dist/tests/fixtures.d.ts +9 -0
- package/dist/tests/fixtures.d.ts.map +1 -0
- package/dist/tests/fixtures.js +20 -0
- package/dist/tests/fixtures.js.map +1 -0
- package/dist/tests/grounding.test.d.ts +2 -0
- package/dist/tests/grounding.test.d.ts.map +1 -0
- package/dist/tests/grounding.test.js +82 -0
- package/dist/tests/grounding.test.js.map +1 -0
- package/dist/tests/multi-domain.test.d.ts +2 -0
- package/dist/tests/multi-domain.test.d.ts.map +1 -0
- package/dist/tests/multi-domain.test.js +135 -0
- package/dist/tests/multi-domain.test.js.map +1 -0
- package/dist/tests/normalizer.test.d.ts +2 -0
- package/dist/tests/normalizer.test.d.ts.map +1 -0
- package/dist/tests/normalizer.test.js +70 -0
- package/dist/tests/normalizer.test.js.map +1 -0
- package/dist/tests/providers.test.d.ts +2 -0
- package/dist/tests/providers.test.d.ts.map +1 -0
- package/dist/tests/providers.test.js +110 -0
- package/dist/tests/providers.test.js.map +1 -0
- package/dist/tests/stitcher.test.d.ts +2 -0
- package/dist/tests/stitcher.test.d.ts.map +1 -0
- package/dist/tests/stitcher.test.js +85 -0
- package/dist/tests/stitcher.test.js.map +1 -0
- package/dist/tests/tiling.test.d.ts +2 -0
- package/dist/tests/tiling.test.d.ts.map +1 -0
- package/dist/tests/tiling.test.js +85 -0
- package/dist/tests/tiling.test.js.map +1 -0
- package/dist/tests/validators.test.d.ts +2 -0
- package/dist/tests/validators.test.d.ts.map +1 -0
- package/dist/tests/validators.test.js +125 -0
- package/dist/tests/validators.test.js.map +1 -0
- package/dist/vitest.config.d.ts +3 -0
- package/dist/vitest.config.d.ts.map +1 -0
- package/dist/vitest.config.js +13 -0
- package/dist/vitest.config.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse an accounting number in multi-region formats and return a plain number.
|
|
3
|
+
*
|
|
4
|
+
* Supported inputs:
|
|
5
|
+
* - `$1,250.50` => 1250.5
|
|
6
|
+
* - `1.250,50 €` => 1250.5
|
|
7
|
+
* - `1,250` => 1250
|
|
8
|
+
* - `(450.00)` => -450
|
|
9
|
+
* - `-1.250,50` => -1250.5
|
|
10
|
+
*
|
|
11
|
+
* Returns `null` if the value cannot be parsed.
|
|
12
|
+
*/
|
|
13
|
+
export function parseAccountingNumber(val) {
|
|
14
|
+
if (typeof val === "number") {
|
|
15
|
+
return Number.isFinite(val) ? val : null;
|
|
16
|
+
}
|
|
17
|
+
if (typeof val !== "string") {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
let input = val.trim();
|
|
21
|
+
if (input === "")
|
|
22
|
+
return null;
|
|
23
|
+
let negative = false;
|
|
24
|
+
// Accounting parenthesis notation: (450.00) or (450,00)
|
|
25
|
+
if (input.startsWith("(") && input.endsWith(")")) {
|
|
26
|
+
negative = true;
|
|
27
|
+
input = input.slice(1, -1);
|
|
28
|
+
}
|
|
29
|
+
// Strip common currency symbols and any surrounding whitespace/letters.
|
|
30
|
+
input = input
|
|
31
|
+
.replace(/[\$€£¥¢]/g, "")
|
|
32
|
+
.replace(/[A-Za-z]/g, "")
|
|
33
|
+
.replace(/\s+/g, "");
|
|
34
|
+
// Detect explicit minus signs.
|
|
35
|
+
if (input.startsWith("-") || input.endsWith("-")) {
|
|
36
|
+
negative = true;
|
|
37
|
+
input = input.replace(/^-|-$/g, "");
|
|
38
|
+
}
|
|
39
|
+
// If both . and , exist, the rightmost one with 1-2 trailing digits is the decimal separator.
|
|
40
|
+
if (input.includes(".") && input.includes(",")) {
|
|
41
|
+
const lastDot = input.lastIndexOf(".");
|
|
42
|
+
const lastComma = input.lastIndexOf(",");
|
|
43
|
+
if (lastComma > lastDot) {
|
|
44
|
+
// e.g. 1.250,50 -> remove dots, comma is decimal
|
|
45
|
+
input = input.replace(/\./g, "").replace(",", ".");
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
// e.g. 1,250.50 -> remove commas, dot is decimal
|
|
49
|
+
input = input.replace(/,/g, "");
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else if (input.includes(",")) {
|
|
53
|
+
// Decide whether the comma is a decimal or thousands separator.
|
|
54
|
+
const parts = input.split(",");
|
|
55
|
+
const afterLast = parts[parts.length - 1];
|
|
56
|
+
if (parts.length === 2 && (afterLast.length === 1 || afterLast.length === 2)) {
|
|
57
|
+
// Most likely decimal (1,50 or 1,5)
|
|
58
|
+
input = input.replace(",", ".");
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
// Thousands separator(s); drop all commas.
|
|
62
|
+
input = input.replace(/,/g, "");
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else if (input.includes(".")) {
|
|
66
|
+
// Decide whether the dot is a decimal or thousands separator.
|
|
67
|
+
const parts = input.split(".");
|
|
68
|
+
if (parts.length > 2) {
|
|
69
|
+
// Multiple dots: the last one is decimal if it has 1-2 trailing digits.
|
|
70
|
+
const afterLast = parts[parts.length - 1];
|
|
71
|
+
if (afterLast.length === 1 || afterLast.length === 2) {
|
|
72
|
+
input = parts.slice(0, -1).join("").replace(/\./g, "") + "." + afterLast;
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
input = input.replace(/\./g, "");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
const before = parts[0];
|
|
80
|
+
const after = parts[1];
|
|
81
|
+
// Single dot with exactly 3 trailing digits and a short integer part
|
|
82
|
+
// is usually a thousands separator (e.g. 1.000).
|
|
83
|
+
if (after.length === 3 && before.length <= 3 && !before.startsWith("0")) {
|
|
84
|
+
input = input.replace(/\./g, "");
|
|
85
|
+
}
|
|
86
|
+
// Otherwise keep dot as decimal.
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (input === "")
|
|
90
|
+
return null;
|
|
91
|
+
const n = Number(input);
|
|
92
|
+
if (!Number.isFinite(n))
|
|
93
|
+
return null;
|
|
94
|
+
return negative ? -n : n;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=currency.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"currency.js","sourceRoot":"","sources":["../../../src/normalizers/currency.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse an ambiguous international date string into ISO-8601 `YYYY-MM-DD`.
|
|
3
|
+
*
|
|
4
|
+
* Supported formats:
|
|
5
|
+
* - `2024-03-15`, `2024/03/15`, `2024.03.15`
|
|
6
|
+
* - `15/03/2024`, `15-03-2024`, `15.03.2024`
|
|
7
|
+
* - `03/15/2024` (US)
|
|
8
|
+
*
|
|
9
|
+
* When the day and month are both <= 12 and ambiguous, the `locale` parameter decides:
|
|
10
|
+
* - `"international"` (default) assumes DD/MM/YYYY.
|
|
11
|
+
* - `"us"` assumes MM/DD/YYYY.
|
|
12
|
+
*
|
|
13
|
+
* Returns `null` if the string cannot be parsed or is invalid.
|
|
14
|
+
*/
|
|
15
|
+
export declare function parseISODate(dateStr: string, locale?: "international" | "us"): string | null;
|
|
16
|
+
//# sourceMappingURL=tabular.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tabular.d.ts","sourceRoot":"","sources":["../../../src/normalizers/tabular.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,eAAe,GAAG,IAAsB,GAC/C,MAAM,GAAG,IAAI,CA6Df"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
function pad2(n) {
|
|
2
|
+
return n.toString().padStart(2, "0");
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* Parse an ambiguous international date string into ISO-8601 `YYYY-MM-DD`.
|
|
6
|
+
*
|
|
7
|
+
* Supported formats:
|
|
8
|
+
* - `2024-03-15`, `2024/03/15`, `2024.03.15`
|
|
9
|
+
* - `15/03/2024`, `15-03-2024`, `15.03.2024`
|
|
10
|
+
* - `03/15/2024` (US)
|
|
11
|
+
*
|
|
12
|
+
* When the day and month are both <= 12 and ambiguous, the `locale` parameter decides:
|
|
13
|
+
* - `"international"` (default) assumes DD/MM/YYYY.
|
|
14
|
+
* - `"us"` assumes MM/DD/YYYY.
|
|
15
|
+
*
|
|
16
|
+
* Returns `null` if the string cannot be parsed or is invalid.
|
|
17
|
+
*/
|
|
18
|
+
export function parseISODate(dateStr, locale = "international") {
|
|
19
|
+
const s = dateStr.trim();
|
|
20
|
+
if (!s)
|
|
21
|
+
return null;
|
|
22
|
+
// Already ISO-8601; validate that the values are a real date.
|
|
23
|
+
const iso = s.match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
|
24
|
+
if (iso) {
|
|
25
|
+
const month = Number(iso[2]);
|
|
26
|
+
const day = Number(iso[3]);
|
|
27
|
+
if (month < 1 || month > 12 || day < 1 || day > 31)
|
|
28
|
+
return null;
|
|
29
|
+
// Catch impossible days like 2024-02-30.
|
|
30
|
+
const date = new Date(`${iso[1]}-${iso[2]}-${iso[3]}T00:00:00Z`);
|
|
31
|
+
if (date.getUTCMonth() + 1 !== month || date.getUTCDate() !== day)
|
|
32
|
+
return null;
|
|
33
|
+
return s;
|
|
34
|
+
}
|
|
35
|
+
// Year-first formats.
|
|
36
|
+
const yearFirst = s.match(/^(\d{4})[\/\-.](\d{1,2})[\/\-.](\d{1,2})$/);
|
|
37
|
+
if (yearFirst) {
|
|
38
|
+
const [, y, m, d] = yearFirst;
|
|
39
|
+
const month = Number(m);
|
|
40
|
+
const day = Number(d);
|
|
41
|
+
if (month < 1 || month > 12 || day < 1 || day > 31)
|
|
42
|
+
return null;
|
|
43
|
+
return `${y}-${pad2(month)}-${pad2(day)}`;
|
|
44
|
+
}
|
|
45
|
+
// Day/month/year or month/day/year formats.
|
|
46
|
+
const dmy = s.match(/^(\d{1,2})[\/\-.](\d{1,2})[\/\-.](\d{4})$/);
|
|
47
|
+
if (!dmy)
|
|
48
|
+
return null;
|
|
49
|
+
const first = Number(dmy[1]);
|
|
50
|
+
const second = Number(dmy[2]);
|
|
51
|
+
const year = dmy[3];
|
|
52
|
+
if (first < 1 || first > 31 || second < 1 || second > 31)
|
|
53
|
+
return null;
|
|
54
|
+
let day;
|
|
55
|
+
let month;
|
|
56
|
+
if (first > 12) {
|
|
57
|
+
// First token is unambiguously the day.
|
|
58
|
+
day = first;
|
|
59
|
+
month = second;
|
|
60
|
+
}
|
|
61
|
+
else if (second > 12) {
|
|
62
|
+
// Second token is unambiguously the day.
|
|
63
|
+
month = first;
|
|
64
|
+
day = second;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
// Ambiguous: both could be day or month.
|
|
68
|
+
if (locale === "us") {
|
|
69
|
+
month = first;
|
|
70
|
+
day = second;
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
day = first;
|
|
74
|
+
month = second;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (day < 1 || day > 31 || month < 1 || month > 12)
|
|
78
|
+
return null;
|
|
79
|
+
return `${year}-${pad2(month)}-${pad2(day)}`;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=tabular.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tabular.js","sourceRoot":"","sources":["../../../src/normalizers/tabular.ts"],"names":[],"mappings":"AAAA,SAAS,IAAI,CAAC,CAAS;IACrB,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACvC,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,YAAY,CAC1B,OAAe,EACf,SAAiC,eAAe;IAEhD,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IACzB,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAEpB,8DAA8D;IAC9D,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;IACjD,IAAI,GAAG,EAAE,CAAC;QACR,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7B,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3B,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,EAAE,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,GAAG,EAAE;YAAE,OAAO,IAAI,CAAC;QAChE,yCAAyC;QACzC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;QACjE,IAAI,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,UAAU,EAAE,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC;QAC/E,OAAO,CAAC,CAAC;IACX,CAAC;IAED,sBAAsB;IACtB,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;IACvE,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAAC;QAC9B,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACxB,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,EAAE,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,GAAG,EAAE;YAAE,OAAO,IAAI,CAAC;QAChE,OAAO,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;IAC5C,CAAC;IAED,4CAA4C;IAC5C,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;IACjE,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IAEtB,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7B,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9B,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;IAEpB,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,EAAE,IAAI,MAAM,GAAG,CAAC,IAAI,MAAM,GAAG,EAAE;QAAE,OAAO,IAAI,CAAC;IAEtE,IAAI,GAAW,CAAC;IAChB,IAAI,KAAa,CAAC;IAElB,IAAI,KAAK,GAAG,EAAE,EAAE,CAAC;QACf,wCAAwC;QACxC,GAAG,GAAG,KAAK,CAAC;QACZ,KAAK,GAAG,MAAM,CAAC;IACjB,CAAC;SAAM,IAAI,MAAM,GAAG,EAAE,EAAE,CAAC;QACvB,yCAAyC;QACzC,KAAK,GAAG,KAAK,CAAC;QACd,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;SAAM,CAAC;QACN,yCAAyC;QACzC,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,KAAK,GAAG,KAAK,CAAC;YACd,GAAG,GAAG,MAAM,CAAC;QACf,CAAC;aAAM,CAAC;YACN,GAAG,GAAG,KAAK,CAAC;YACZ,KAAK,GAAG,MAAM,CAAC;QACjB,CAAC;IACH,CAAC;IAED,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,GAAG,EAAE,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,EAAE;QAAE,OAAO,IAAI,CAAC;IAEhE,OAAO,GAAG,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ExtractionParams, RawVLMResponse, VLMProvider } from "./types.js";
|
|
2
|
+
export interface AnthropicProviderConfig {
|
|
3
|
+
apiKey?: string;
|
|
4
|
+
model?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class AnthropicProvider implements VLMProvider {
|
|
7
|
+
readonly name = "anthropic";
|
|
8
|
+
private client;
|
|
9
|
+
private model;
|
|
10
|
+
constructor(config?: AnthropicProviderConfig);
|
|
11
|
+
extract(params: ExtractionParams): Promise<RawVLMResponse>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=anthropic-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic-provider.d.ts","sourceRoot":"","sources":["../../../src/providers/anthropic-provider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEhF,MAAM,WAAW,uBAAuB;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID,qBAAa,iBAAkB,YAAW,WAAW;IACnD,QAAQ,CAAC,IAAI,eAAe;IAC5B,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,KAAK,CAAS;gBAEV,MAAM,GAAE,uBAA4B;IAS1C,OAAO,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,cAAc,CAAC;CAqDjE"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import Anthropic from "@anthropic-ai/sdk";
|
|
2
|
+
const TOOL_NAME = "extract_document";
|
|
3
|
+
export class AnthropicProvider {
|
|
4
|
+
name = "anthropic";
|
|
5
|
+
client;
|
|
6
|
+
model;
|
|
7
|
+
constructor(config = {}) {
|
|
8
|
+
const apiKey = config.apiKey ?? process.env.ANTHROPIC_API_KEY;
|
|
9
|
+
if (!apiKey) {
|
|
10
|
+
throw new Error("AnthropicProvider requires an apiKey or ANTHROPIC_API_KEY env variable.");
|
|
11
|
+
}
|
|
12
|
+
this.client = new Anthropic({ apiKey });
|
|
13
|
+
this.model = config.model ?? process.env.ANTHROPIC_MODEL ?? "claude-opus-5";
|
|
14
|
+
}
|
|
15
|
+
async extract(params) {
|
|
16
|
+
const content = [{ type: "text", text: params.prompt }];
|
|
17
|
+
for (const img of params.images) {
|
|
18
|
+
if (img.mimeType === "application/pdf") {
|
|
19
|
+
const documentBlock = {
|
|
20
|
+
type: "document",
|
|
21
|
+
source: {
|
|
22
|
+
type: "base64",
|
|
23
|
+
media_type: "application/pdf",
|
|
24
|
+
data: img.base64,
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
content.push(documentBlock);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
content.push({
|
|
31
|
+
type: "image",
|
|
32
|
+
source: {
|
|
33
|
+
type: "base64",
|
|
34
|
+
media_type: img.mimeType,
|
|
35
|
+
data: img.base64,
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const tools = params.schema
|
|
41
|
+
? [
|
|
42
|
+
{
|
|
43
|
+
name: TOOL_NAME,
|
|
44
|
+
description: "Extract structured information from the provided document.",
|
|
45
|
+
input_schema: params.schema,
|
|
46
|
+
},
|
|
47
|
+
]
|
|
48
|
+
: [];
|
|
49
|
+
const message = await this.client.messages.create({
|
|
50
|
+
model: this.model,
|
|
51
|
+
max_tokens: params.maxTokens ?? 4096,
|
|
52
|
+
temperature: params.temperature ?? 0,
|
|
53
|
+
messages: [{ role: "user", content }],
|
|
54
|
+
tools,
|
|
55
|
+
tool_choice: { type: "tool", name: TOOL_NAME },
|
|
56
|
+
});
|
|
57
|
+
const toolUse = message.content.find((block) => block.type === "tool_use");
|
|
58
|
+
const text = toolUse ? JSON.stringify(toolUse.input) : "";
|
|
59
|
+
return { text, raw: message };
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=anthropic-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic-provider.js","sourceRoot":"","sources":["../../../src/providers/anthropic-provider.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAQ1C,MAAM,SAAS,GAAG,kBAAkB,CAAC;AAErC,MAAM,OAAO,iBAAiB;IACnB,IAAI,GAAG,WAAW,CAAC;IACpB,MAAM,CAAY;IAClB,KAAK,CAAS;IAEtB,YAAY,SAAkC,EAAE;QAC9C,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;QAC9D,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,yEAAyE,CAAC,CAAC;QAC7F,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QACxC,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,eAAe,CAAC;IAC9E,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,MAAwB;QACpC,MAAM,OAAO,GAAkC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QAEvF,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAChC,IAAI,GAAG,CAAC,QAAQ,KAAK,iBAAiB,EAAE,CAAC;gBACvC,MAAM,aAAa,GAAG;oBACpB,IAAI,EAAE,UAAmB;oBACzB,MAAM,EAAE;wBACN,IAAI,EAAE,QAAiB;wBACvB,UAAU,EAAE,iBAA0B;wBACtC,IAAI,EAAE,GAAG,CAAC,MAAM;qBACjB;iBACF,CAAC;gBACF,OAAO,CAAC,IAAI,CAAC,aAAuD,CAAC,CAAC;YACxE,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC;oBACX,IAAI,EAAE,OAAO;oBACb,MAAM,EAAE;wBACN,IAAI,EAAE,QAAQ;wBACd,UAAU,EAAE,GAAG,CAAC,QAAmE;wBACnF,IAAI,EAAE,GAAG,CAAC,MAAM;qBACjB;iBACF,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,MAAM,KAAK,GAAqB,MAAM,CAAC,MAAM;YAC3C,CAAC,CAAC;gBACE;oBACE,IAAI,EAAE,SAAS;oBACf,WAAW,EAAE,4DAA4D;oBACzE,YAAY,EAAE,MAAM,CAAC,MAAoC;iBAC1D;aACF;YACH,CAAC,CAAC,EAAE,CAAC;QAEP,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;YAChD,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,UAAU,EAAE,MAAM,CAAC,SAAS,IAAI,IAAI;YACpC,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,CAAC;YACpC,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;YACrC,KAAK;YACL,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE;SAC/C,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAClC,CAAC,KAAK,EAAmC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,UAAU,CACtE,CAAC;QAEF,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAE1D,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;IAChC,CAAC;CACF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { VLMProvider } from "./types.js";
|
|
2
|
+
export interface ProviderFactoryConfig {
|
|
3
|
+
provider?: "gemini" | "openai" | "anthropic" | "custom";
|
|
4
|
+
apiKey?: string;
|
|
5
|
+
model?: string;
|
|
6
|
+
baseUrl?: string;
|
|
7
|
+
/** Inject a custom VLM provider. */
|
|
8
|
+
customVLM?: VLMProvider;
|
|
9
|
+
}
|
|
10
|
+
export declare function resolveProvider(config?: ProviderFactoryConfig): VLMProvider;
|
|
11
|
+
//# sourceMappingURL=factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/providers/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAK9C,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAAG,QAAQ,CAAC;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oCAAoC;IACpC,SAAS,CAAC,EAAE,WAAW,CAAC;CACzB;AAWD,wBAAgB,eAAe,CAAC,MAAM,GAAE,qBAA0B,GAAG,WAAW,CAkB/E"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { GeminiProvider } from "./gemini-provider.js";
|
|
2
|
+
import { OpenAIProvider } from "./openai-provider.js";
|
|
3
|
+
import { AnthropicProvider } from "./anthropic-provider.js";
|
|
4
|
+
function detectProvider() {
|
|
5
|
+
if (process.env.GEMINI_API_KEY)
|
|
6
|
+
return "gemini";
|
|
7
|
+
if (process.env.OPENAI_API_KEY)
|
|
8
|
+
return "openai";
|
|
9
|
+
if (process.env.ANTHROPIC_API_KEY)
|
|
10
|
+
return "anthropic";
|
|
11
|
+
throw new Error("No provider configured. Set GEMINI_API_KEY, OPENAI_API_KEY, ANTHROPIC_API_KEY or pass a customVLM.");
|
|
12
|
+
}
|
|
13
|
+
export function resolveProvider(config = {}) {
|
|
14
|
+
if (config.customVLM)
|
|
15
|
+
return config.customVLM;
|
|
16
|
+
const provider = config.provider ?? detectProvider();
|
|
17
|
+
switch (provider) {
|
|
18
|
+
case "gemini":
|
|
19
|
+
return new GeminiProvider({ apiKey: config.apiKey, model: config.model });
|
|
20
|
+
case "openai":
|
|
21
|
+
return new OpenAIProvider({
|
|
22
|
+
apiKey: config.apiKey,
|
|
23
|
+
model: config.model,
|
|
24
|
+
baseUrl: config.baseUrl,
|
|
25
|
+
});
|
|
26
|
+
case "anthropic":
|
|
27
|
+
return new AnthropicProvider({ apiKey: config.apiKey, model: config.model });
|
|
28
|
+
default:
|
|
29
|
+
throw new Error(`Unsupported provider: ${provider}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../../src/providers/factory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAW5D,SAAS,cAAc;IACrB,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc;QAAE,OAAO,QAAQ,CAAC;IAChD,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc;QAAE,OAAO,QAAQ,CAAC;IAChD,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB;QAAE,OAAO,WAAW,CAAC;IACtD,MAAM,IAAI,KAAK,CACb,oGAAoG,CACrG,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,SAAgC,EAAE;IAChE,IAAI,MAAM,CAAC,SAAS;QAAE,OAAO,MAAM,CAAC,SAAS,CAAC;IAE9C,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,cAAc,EAAE,CAAC;IACrD,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,QAAQ;YACX,OAAO,IAAI,cAAc,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;QAC5E,KAAK,QAAQ;YACX,OAAO,IAAI,cAAc,CAAC;gBACxB,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,OAAO,EAAE,MAAM,CAAC,OAAO;aACxB,CAAC,CAAC;QACL,KAAK,WAAW;YACd,OAAO,IAAI,iBAAiB,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;QAC/E;YACE,MAAM,IAAI,KAAK,CAAC,yBAAyB,QAAQ,EAAE,CAAC,CAAC;IACzD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ExtractionParams, RawVLMResponse, VLMProvider } from "./types.js";
|
|
2
|
+
export interface GeminiProviderConfig {
|
|
3
|
+
apiKey?: string;
|
|
4
|
+
model?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class GeminiProvider implements VLMProvider {
|
|
7
|
+
readonly name = "gemini";
|
|
8
|
+
private client;
|
|
9
|
+
private model;
|
|
10
|
+
constructor(config?: GeminiProviderConfig);
|
|
11
|
+
extract(params: ExtractionParams): Promise<RawVLMResponse>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=gemini-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini-provider.d.ts","sourceRoot":"","sources":["../../../src/providers/gemini-provider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAa,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG3F,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAWD,qBAAa,cAAe,YAAW,WAAW;IAChD,QAAQ,CAAC,IAAI,YAAY;IACzB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,KAAK,CAAS;gBAEV,MAAM,GAAE,oBAAyB;IASvC,OAAO,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,cAAc,CAAC;CA8BjE"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { GoogleGenAI } from "@google/genai";
|
|
2
|
+
import { toGeminiSDKSchema } from "../compiler/zod-compiler.js";
|
|
3
|
+
function toGeminiPart(img) {
|
|
4
|
+
return {
|
|
5
|
+
inlineData: {
|
|
6
|
+
mimeType: img.mimeType,
|
|
7
|
+
data: img.base64,
|
|
8
|
+
},
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export class GeminiProvider {
|
|
12
|
+
name = "gemini";
|
|
13
|
+
client;
|
|
14
|
+
model;
|
|
15
|
+
constructor(config = {}) {
|
|
16
|
+
const apiKey = config.apiKey ?? process.env.GEMINI_API_KEY;
|
|
17
|
+
if (!apiKey) {
|
|
18
|
+
throw new Error("GeminiProvider requires an apiKey or GEMINI_API_KEY env variable.");
|
|
19
|
+
}
|
|
20
|
+
this.client = new GoogleGenAI({ apiKey });
|
|
21
|
+
this.model = config.model ?? process.env.GEMINI_MODEL ?? "gemini-3.7-flash";
|
|
22
|
+
}
|
|
23
|
+
async extract(params) {
|
|
24
|
+
const parts = [{ text: params.prompt }];
|
|
25
|
+
for (const img of params.images) {
|
|
26
|
+
parts.push(toGeminiPart(img));
|
|
27
|
+
}
|
|
28
|
+
const config = {
|
|
29
|
+
responseMimeType: params.responseMimeType ?? "application/json",
|
|
30
|
+
maxOutputTokens: params.maxTokens,
|
|
31
|
+
temperature: params.temperature,
|
|
32
|
+
seed: params.seed,
|
|
33
|
+
};
|
|
34
|
+
if (params.schema) {
|
|
35
|
+
config.responseSchema = toGeminiSDKSchema(params.schema);
|
|
36
|
+
}
|
|
37
|
+
const response = await this.client.models.generateContent({
|
|
38
|
+
model: this.model,
|
|
39
|
+
contents: [{ role: "user", parts }],
|
|
40
|
+
config,
|
|
41
|
+
});
|
|
42
|
+
const text = response.text ??
|
|
43
|
+
response.candidates?.[0]?.content?.parts?.map((p) => p.text).join("") ??
|
|
44
|
+
"";
|
|
45
|
+
return { text, raw: response };
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=gemini-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini-provider.js","sourceRoot":"","sources":["../../../src/providers/gemini-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAA2C,MAAM,eAAe,CAAC;AAErF,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAOhE,SAAS,YAAY,CAAC,GAAc;IAClC,OAAO;QACL,UAAU,EAAE;YACV,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,IAAI,EAAE,GAAG,CAAC,MAAM;SACjB;KACF,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,cAAc;IAChB,IAAI,GAAG,QAAQ,CAAC;IACjB,MAAM,CAAc;IACpB,KAAK,CAAS;IAEtB,YAAY,SAA+B,EAAE;QAC3C,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;QAC3D,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAC;QACvF,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,IAAI,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QAC1C,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,kBAAkB,CAAC;IAC9E,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,MAAwB;QACpC,MAAM,KAAK,GAA8B,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QACnE,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAChC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;QAChC,CAAC;QAED,MAAM,MAAM,GAA0B;YACpC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB,IAAI,kBAAkB;YAC/D,eAAe,EAAE,MAAM,CAAC,SAAS;YACjC,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,IAAI,EAAE,MAAM,CAAC,IAAI;SAClB,CAAC;QAEF,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClB,MAAM,CAAC,cAAc,GAAG,iBAAiB,CAAC,MAAM,CAAC,MAAM,CAAsB,CAAC;QAChF,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC;YACxD,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;YACnC,MAAM;SACP,CAAC,CAAC;QAEH,MAAM,IAAI,GACP,QAA8B,CAAC,IAAI;YACpC,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAE,CAAuB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5F,EAAE,CAAC;QAEL,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC;IACjC,CAAC;CACF"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ExtractionParams, RawVLMResponse, VLMProvider } from "./types.js";
|
|
2
|
+
export interface OpenAIProviderConfig {
|
|
3
|
+
apiKey?: string;
|
|
4
|
+
model?: string;
|
|
5
|
+
baseUrl?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare class OpenAIProvider implements VLMProvider {
|
|
8
|
+
readonly name = "openai";
|
|
9
|
+
private client;
|
|
10
|
+
private model;
|
|
11
|
+
constructor(config?: OpenAIProviderConfig);
|
|
12
|
+
extract(params: ExtractionParams): Promise<RawVLMResponse>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=openai-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-provider.d.ts","sourceRoot":"","sources":["../../../src/providers/openai-provider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEhF,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,cAAe,YAAW,WAAW;IAChD,QAAQ,CAAC,IAAI,YAAY;IACzB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;gBAEV,MAAM,GAAE,oBAAyB;IASvC,OAAO,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,cAAc,CAAC;CAsCjE"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import OpenAI from "openai";
|
|
2
|
+
export class OpenAIProvider {
|
|
3
|
+
name = "openai";
|
|
4
|
+
client;
|
|
5
|
+
model;
|
|
6
|
+
constructor(config = {}) {
|
|
7
|
+
const apiKey = config.apiKey ?? process.env.OPENAI_API_KEY;
|
|
8
|
+
if (!apiKey) {
|
|
9
|
+
throw new Error("OpenAIProvider requires an apiKey or OPENAI_API_KEY env variable.");
|
|
10
|
+
}
|
|
11
|
+
this.client = new OpenAI({ apiKey, baseURL: config.baseUrl });
|
|
12
|
+
this.model = config.model ?? process.env.OPENAI_MODEL ?? "gpt-5.6-luna";
|
|
13
|
+
}
|
|
14
|
+
async extract(params) {
|
|
15
|
+
const content = [
|
|
16
|
+
{ type: "text", text: params.prompt },
|
|
17
|
+
];
|
|
18
|
+
for (const img of params.images) {
|
|
19
|
+
content.push({
|
|
20
|
+
type: "image_url",
|
|
21
|
+
image_url: {
|
|
22
|
+
url: `data:${img.mimeType};base64,${img.base64}`,
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
const body = {
|
|
27
|
+
model: this.model,
|
|
28
|
+
messages: [{ role: "user", content }],
|
|
29
|
+
max_tokens: params.maxTokens ?? 4096,
|
|
30
|
+
temperature: params.temperature ?? 0,
|
|
31
|
+
seed: params.seed,
|
|
32
|
+
};
|
|
33
|
+
if (params.schema) {
|
|
34
|
+
body.response_format = {
|
|
35
|
+
type: "json_schema",
|
|
36
|
+
json_schema: {
|
|
37
|
+
name: "extraction",
|
|
38
|
+
strict: true,
|
|
39
|
+
schema: params.schema,
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
const completion = await this.client.chat.completions.create(body);
|
|
44
|
+
const text = completion.choices[0]?.message?.content ?? "";
|
|
45
|
+
return { text, raw: completion };
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=openai-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-provider.js","sourceRoot":"","sources":["../../../src/providers/openai-provider.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAS5B,MAAM,OAAO,cAAc;IAChB,IAAI,GAAG,QAAQ,CAAC;IACjB,MAAM,CAAS;IACf,KAAK,CAAS;IAEtB,YAAY,SAA+B,EAAE;QAC3C,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;QAC3D,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAC;QACvF,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9D,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,cAAc,CAAC;IAC1E,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,MAAwB;QACpC,MAAM,OAAO,GAAwD;YACnE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE;SACtC,CAAC;QAEF,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAChC,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,WAAW;gBACjB,SAAS,EAAE;oBACT,GAAG,EAAE,QAAQ,GAAG,CAAC,QAAQ,WAAW,GAAG,CAAC,MAAM,EAAE;iBACjD;aACF,CAAC,CAAC;QACL,CAAC;QAED,MAAM,IAAI,GAAuD;YAC/D,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;YACrC,UAAU,EAAE,MAAM,CAAC,SAAS,IAAI,IAAI;YACpC,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,CAAC;YACpC,IAAI,EAAE,MAAM,CAAC,IAAI;SAClB,CAAC;QAEF,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClB,IAAI,CAAC,eAAe,GAAG;gBACrB,IAAI,EAAE,aAAa;gBACnB,WAAW,EAAE;oBACX,IAAI,EAAE,YAAY;oBAClB,MAAM,EAAE,IAAI;oBACZ,MAAM,EAAE,MAAM,CAAC,MAAM;iBACtB;aACF,CAAC;QACJ,CAAC;QAED,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACnE,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE,CAAC;QAE3D,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC;IACnC,CAAC;CACF"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { NormalizedBBox } from "../grounding/bbox.js";
|
|
2
|
+
export interface PageImage {
|
|
3
|
+
/** MIME type such as `image/png` or `image/jpeg`. */
|
|
4
|
+
mimeType: string;
|
|
5
|
+
/** Base64-encoded image bytes (without data URI prefix). */
|
|
6
|
+
base64: string;
|
|
7
|
+
/** Page width in pixels, used to normalize bboxes. */
|
|
8
|
+
width: number;
|
|
9
|
+
/** Page height in pixels. */
|
|
10
|
+
height: number;
|
|
11
|
+
}
|
|
12
|
+
export interface ExtractionParams {
|
|
13
|
+
/** Pages/images to send to the model. */
|
|
14
|
+
images: PageImage[];
|
|
15
|
+
/** System / user prompt describing the extraction task. */
|
|
16
|
+
prompt: string;
|
|
17
|
+
/** JSON Schema (or provider-specific native schema) the model must follow. */
|
|
18
|
+
schema?: Record<string, unknown>;
|
|
19
|
+
/** Desired MIME type of the response. Defaults to `application/json`. */
|
|
20
|
+
responseMimeType?: string;
|
|
21
|
+
/** Optional maximum output tokens. */
|
|
22
|
+
maxTokens?: number;
|
|
23
|
+
/** Temperature / creativity. */
|
|
24
|
+
temperature?: number;
|
|
25
|
+
/** Seed for deterministic sampling. */
|
|
26
|
+
seed?: number;
|
|
27
|
+
}
|
|
28
|
+
export interface RawVLMResponse {
|
|
29
|
+
/** Parsed raw JSON or text returned by the model. */
|
|
30
|
+
text: string;
|
|
31
|
+
/** Optional full provider-specific response object. */
|
|
32
|
+
raw: unknown;
|
|
33
|
+
}
|
|
34
|
+
export interface VLMProvider {
|
|
35
|
+
readonly name: string;
|
|
36
|
+
extract(params: ExtractionParams): Promise<RawVLMResponse>;
|
|
37
|
+
}
|
|
38
|
+
export interface GroundedField {
|
|
39
|
+
field: string;
|
|
40
|
+
value: unknown;
|
|
41
|
+
pageIndex: number;
|
|
42
|
+
bbox: NormalizedBBox;
|
|
43
|
+
confidence?: number;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/providers/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,MAAM,WAAW,SAAS;IACxB,qDAAqD;IACrD,QAAQ,EAAE,MAAM,CAAC;IACjB,4DAA4D;IAC5D,MAAM,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,KAAK,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,yCAAyC;IACzC,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gCAAgC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uCAAuC;IACvC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,GAAG,EAAE,OAAO,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CAC5D;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,cAAc,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/providers/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ExtractedTable } from "../core/types.js";
|
|
2
|
+
export interface TableStitcherOptions {
|
|
3
|
+
/** Max column count difference accepted between adjacent tables. */
|
|
4
|
+
columnCountTolerance?: number;
|
|
5
|
+
/** Minimum Jaccard index for header sets to consider a continuation. */
|
|
6
|
+
headerSimilarityThreshold?: number;
|
|
7
|
+
/** Minimum horizontal overlap ratio of the tables. */
|
|
8
|
+
horizontalOverlapThreshold?: number;
|
|
9
|
+
/** If true, drop repeated header rows that appear at page boundaries. */
|
|
10
|
+
skipRepeatedHeaders?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare class TableStitcher {
|
|
13
|
+
private opts;
|
|
14
|
+
constructor(options?: TableStitcherOptions);
|
|
15
|
+
canMerge(prev: ExtractedTable, next: ExtractedTable): boolean;
|
|
16
|
+
stitch(tables: ExtractedTable[]): ExtractedTable[];
|
|
17
|
+
private mergeGroup;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=table-stitcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table-stitcher.d.ts","sourceRoot":"","sources":["../../../src/stitcher/table-stitcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGvD,MAAM,WAAW,oBAAoB;IACnC,oEAAoE;IACpE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,wEAAwE;IACxE,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,sDAAsD;IACtD,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,yEAAyE;IACzE,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAoDD,qBAAa,aAAa;IACxB,OAAO,CAAC,IAAI,CAAiC;gBAEjC,OAAO,GAAE,oBAAyB;IAS9C,QAAQ,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO;IAuB7D,MAAM,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE;IAsBlD,OAAO,CAAC,UAAU;CAwCnB"}
|