@anyformat/sdk 0.2.0 → 0.2.2
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 +9 -0
- package/dist/index.cjs +142 -49
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +99 -29
- package/dist/index.d.ts +99 -29
- package/dist/index.js +140 -49
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -24,6 +24,15 @@ const result = await af
|
|
|
24
24
|
result.field("vendor")?.value; // -> "Acme Corp"
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
+
## Managing workflows
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
const workflows = await af.listWorkflows({ pageSize: 50 }); // -> Workflow[]
|
|
31
|
+
for (const wf of workflows) console.log(wf.id, wf.name);
|
|
32
|
+
|
|
33
|
+
await af.deleteWorkflow(workflows[0].id); // -> the deleted id
|
|
34
|
+
```
|
|
35
|
+
|
|
27
36
|
## How it's built
|
|
28
37
|
|
|
29
38
|
The wire types and the low-level HTTP client are **generated** from the API's
|
package/dist/index.cjs
CHANGED
|
@@ -26,6 +26,7 @@ __export(index_exports, {
|
|
|
26
26
|
BadRequest: () => BadRequest,
|
|
27
27
|
Forbidden: () => Forbidden,
|
|
28
28
|
NotFound: () => NotFound,
|
|
29
|
+
ParseView: () => ParseView,
|
|
29
30
|
RateLimited: () => RateLimited,
|
|
30
31
|
Result: () => Result,
|
|
31
32
|
Run: () => Run,
|
|
@@ -33,6 +34,7 @@ __export(index_exports, {
|
|
|
33
34
|
Schema: () => Schema,
|
|
34
35
|
ServerError: () => ServerError,
|
|
35
36
|
Unauthorized: () => Unauthorized,
|
|
37
|
+
Workflow: () => Workflow,
|
|
36
38
|
WorkflowBuilder: () => WorkflowBuilder,
|
|
37
39
|
WorkflowBuilderError: () => WorkflowBuilderError
|
|
38
40
|
});
|
|
@@ -42,18 +44,62 @@ module.exports = __toCommonJS(index_exports);
|
|
|
42
44
|
var import_node_fs = require("fs");
|
|
43
45
|
var import_node_path = require("path");
|
|
44
46
|
|
|
47
|
+
// src/parse-view.ts
|
|
48
|
+
var ParseView = class {
|
|
49
|
+
/** @internal */
|
|
50
|
+
constructor(parse) {
|
|
51
|
+
this.parse = parse;
|
|
52
|
+
}
|
|
53
|
+
parse;
|
|
54
|
+
get markdown() {
|
|
55
|
+
return this.parse.markdown ?? null;
|
|
56
|
+
}
|
|
57
|
+
get text() {
|
|
58
|
+
return this.parse.text ?? null;
|
|
59
|
+
}
|
|
60
|
+
get blocks() {
|
|
61
|
+
return this.parse.blocks ?? [];
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Document-level confidence (0-100) in the parsed content. May be `null` for
|
|
65
|
+
* some parse modes — fall back to `layoutConfidence`.
|
|
66
|
+
*/
|
|
67
|
+
get parseConfidence() {
|
|
68
|
+
return this.parse.parse_confidence ?? null;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Document-level confidence (0-100) in the page layout (block positions).
|
|
72
|
+
* `null` when not available.
|
|
73
|
+
*/
|
|
74
|
+
get layoutConfidence() {
|
|
75
|
+
return this.parse.layout_confidence ?? null;
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
45
79
|
// src/result.ts
|
|
46
80
|
var Result = class {
|
|
47
81
|
constructor(raw) {
|
|
48
82
|
this.raw = raw;
|
|
49
83
|
}
|
|
50
84
|
raw;
|
|
85
|
+
_parse;
|
|
51
86
|
get collectionId() {
|
|
52
87
|
return this.raw.collection_id;
|
|
53
88
|
}
|
|
54
89
|
get extractions() {
|
|
55
90
|
return this.raw.extractions ?? [];
|
|
56
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Typed view over the parse node's output, or `null` when the workflow has
|
|
94
|
+
* no parse node. Cached so repeated access doesn't re-wrap.
|
|
95
|
+
*/
|
|
96
|
+
get parse() {
|
|
97
|
+
if (this._parse === void 0) {
|
|
98
|
+
const raw = this.raw.parse;
|
|
99
|
+
this._parse = raw ? new ParseView(raw) : null;
|
|
100
|
+
}
|
|
101
|
+
return this._parse;
|
|
102
|
+
}
|
|
57
103
|
/**
|
|
58
104
|
* Convenience accessor for a top-level scalar field on the first
|
|
59
105
|
* extraction (linear workflows). Returns `undefined` for missing fields
|
|
@@ -926,6 +972,11 @@ var createClient = (config = {}) => {
|
|
|
926
972
|
var client = createClient(createConfig({ baseUrl: "https://api-dev.anyformat.ai" }));
|
|
927
973
|
|
|
928
974
|
// src/sdk/sdk.gen.ts
|
|
975
|
+
var v2ListWorkflows = (options) => (options?.client ?? client).get({
|
|
976
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
977
|
+
url: "/v2/workflows/",
|
|
978
|
+
...options
|
|
979
|
+
});
|
|
929
980
|
var v2CreateWorkflow = (options) => (options.client ?? client).post({
|
|
930
981
|
security: [{ scheme: "bearer", type: "http" }],
|
|
931
982
|
url: "/v2/workflows/",
|
|
@@ -935,6 +986,20 @@ var v2CreateWorkflow = (options) => (options.client ?? client).post({
|
|
|
935
986
|
...options.headers
|
|
936
987
|
}
|
|
937
988
|
});
|
|
989
|
+
var v2DeleteWorkflow = (options) => (options.client ?? client).delete({
|
|
990
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
991
|
+
url: "/v2/workflows/{workflow_id}/",
|
|
992
|
+
...options
|
|
993
|
+
});
|
|
994
|
+
var v2UpdateWorkflow = (options) => (options.client ?? client).put({
|
|
995
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
996
|
+
url: "/v2/workflows/{workflow_id}/",
|
|
997
|
+
...options,
|
|
998
|
+
headers: {
|
|
999
|
+
"Content-Type": "application/json",
|
|
1000
|
+
...options.headers
|
|
1001
|
+
}
|
|
1002
|
+
});
|
|
938
1003
|
var v2GetFileResults = (options) => (options.client ?? client).get({
|
|
939
1004
|
security: [{ scheme: "bearer", type: "http" }],
|
|
940
1005
|
url: "/v2/workflows/{workflow_id}/files/{collection_id}/results/",
|
|
@@ -953,45 +1018,23 @@ var v2RunWorkflow = (options) => (options.client ?? client).post({
|
|
|
953
1018
|
|
|
954
1019
|
// src/run.ts
|
|
955
1020
|
var Run = class {
|
|
956
|
-
|
|
1021
|
+
/** @internal */
|
|
1022
|
+
constructor(client2, workflowId, id) {
|
|
957
1023
|
this.client = client2;
|
|
958
|
-
this.
|
|
959
|
-
this.
|
|
960
|
-
this.text = text;
|
|
1024
|
+
this.workflowId = workflowId;
|
|
1025
|
+
this.id = id;
|
|
961
1026
|
}
|
|
962
1027
|
client;
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
text;
|
|
966
|
-
workflowId = null;
|
|
967
|
-
collectionId = null;
|
|
968
|
-
/**
|
|
969
|
-
* Create the workflow and submit the document — exactly once per `Run`.
|
|
970
|
-
* Memoized so that retrying `wait()` after an `SDKTimeout` resumes polling
|
|
971
|
-
* the in-flight run instead of creating a duplicate workflow + submission.
|
|
972
|
-
*/
|
|
973
|
-
async submit() {
|
|
974
|
-
if (this.collectionId !== null) return;
|
|
975
|
-
const created = await v2CreateWorkflow({ client: this.client, body: this.request });
|
|
976
|
-
if (created.error) throw toApiError(created.response?.status ?? 500, created.error);
|
|
977
|
-
this.workflowId = created.data.id;
|
|
978
|
-
const submitted = await v2RunWorkflow({
|
|
979
|
-
client: this.client,
|
|
980
|
-
path: { workflow_id: this.workflowId },
|
|
981
|
-
body: { file: this.file, text: this.text }
|
|
982
|
-
});
|
|
983
|
-
if (submitted.error) throw toApiError(submitted.response?.status ?? 500, submitted.error);
|
|
984
|
-
this.collectionId = submitted.data.id;
|
|
985
|
-
}
|
|
1028
|
+
workflowId;
|
|
1029
|
+
id;
|
|
986
1030
|
async wait(opts = {}) {
|
|
987
|
-
const timeoutMs = opts.timeoutMs ??
|
|
988
|
-
const pollMs = opts.pollMs ??
|
|
989
|
-
await this.submit();
|
|
1031
|
+
const timeoutMs = opts.timeoutMs ?? 3e5;
|
|
1032
|
+
const pollMs = opts.pollMs ?? 3e3;
|
|
990
1033
|
const deadline = Date.now() + timeoutMs;
|
|
991
1034
|
while (Date.now() < deadline) {
|
|
992
1035
|
const results = await v2GetFileResults({
|
|
993
1036
|
client: this.client,
|
|
994
|
-
path: { workflow_id: this.workflowId, collection_id: this.
|
|
1037
|
+
path: { workflow_id: this.workflowId, collection_id: this.id }
|
|
995
1038
|
});
|
|
996
1039
|
if (!results.error) return new Result(results.data);
|
|
997
1040
|
if (results.response?.status !== 412) {
|
|
@@ -1003,6 +1046,43 @@ var Run = class {
|
|
|
1003
1046
|
}
|
|
1004
1047
|
};
|
|
1005
1048
|
|
|
1049
|
+
// src/workflow.ts
|
|
1050
|
+
var Workflow = class {
|
|
1051
|
+
/** @internal */
|
|
1052
|
+
constructor(client2, id, name) {
|
|
1053
|
+
this.client = client2;
|
|
1054
|
+
this.id = id;
|
|
1055
|
+
this.name = name;
|
|
1056
|
+
}
|
|
1057
|
+
client;
|
|
1058
|
+
id;
|
|
1059
|
+
name;
|
|
1060
|
+
/** Submit a document against this workflow and return a pending `Run`. */
|
|
1061
|
+
async run(file = null, opts = {}) {
|
|
1062
|
+
if (file === null && !opts.text) {
|
|
1063
|
+
throw new WorkflowBuilderError("run() requires a document \u2014 pass a file or non-empty opts.text");
|
|
1064
|
+
}
|
|
1065
|
+
if (file !== null && opts.text !== void 0) {
|
|
1066
|
+
throw new WorkflowBuilderError("run() accepts either a file or text, not both");
|
|
1067
|
+
}
|
|
1068
|
+
if (file !== null) {
|
|
1069
|
+
const filename = file.name;
|
|
1070
|
+
if (typeof filename !== "string" || filename.length === 0) {
|
|
1071
|
+
throw new WorkflowBuilderError(
|
|
1072
|
+
'run() needs a named file so the server can detect its type \u2014 pass a File, e.g. new File([bytes], "invoice.pdf"), not a bare Blob'
|
|
1073
|
+
);
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
const submitted = await v2RunWorkflow({
|
|
1077
|
+
client: this.client,
|
|
1078
|
+
path: { workflow_id: this.id },
|
|
1079
|
+
body: { file, text: opts.text ?? null }
|
|
1080
|
+
});
|
|
1081
|
+
if (submitted.error) throw toApiError(submitted.response?.status ?? 500, submitted.error);
|
|
1082
|
+
return new Run(this.client, this.id, submitted.data.id);
|
|
1083
|
+
}
|
|
1084
|
+
};
|
|
1085
|
+
|
|
1006
1086
|
// src/builder.ts
|
|
1007
1087
|
var WorkflowBuilder = class {
|
|
1008
1088
|
constructor(client2, name, description) {
|
|
@@ -1034,7 +1114,8 @@ var WorkflowBuilder = class {
|
|
|
1034
1114
|
id: opts.id ?? this.nextId("parse"),
|
|
1035
1115
|
mode: opts.mode ?? "standard",
|
|
1036
1116
|
...opts.promptHint !== void 0 ? { prompt_hint: opts.promptHint } : {},
|
|
1037
|
-
figure_enhancement: opts.figureEnhancement ?? false
|
|
1117
|
+
figure_enhancement: opts.figureEnhancement ?? false,
|
|
1118
|
+
cache: opts.cache ?? true
|
|
1038
1119
|
};
|
|
1039
1120
|
return this;
|
|
1040
1121
|
}
|
|
@@ -1165,26 +1246,17 @@ var WorkflowBuilder = class {
|
|
|
1165
1246
|
}
|
|
1166
1247
|
return { name: this.name, description: this.description, nodes, edges };
|
|
1167
1248
|
}
|
|
1168
|
-
/** Persist the workflow and return
|
|
1249
|
+
/** Persist the workflow and return a handle you can `.run(file)` on. */
|
|
1169
1250
|
async create() {
|
|
1170
1251
|
const res = await v2CreateWorkflow({ client: this.client, body: this.build() });
|
|
1171
1252
|
if (res.error) throw toApiError(res.response?.status ?? 500, res.error);
|
|
1172
|
-
return res.data.id;
|
|
1253
|
+
return new Workflow(this.client, res.data.id, res.data.name);
|
|
1173
1254
|
}
|
|
1174
|
-
/**
|
|
1175
|
-
|
|
1176
|
-
this.
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
);
|
|
1180
|
-
if (file !== null) {
|
|
1181
|
-
const filename = file.name;
|
|
1182
|
-
this.require(
|
|
1183
|
-
typeof filename === "string" && filename.length > 0,
|
|
1184
|
-
'run() needs a named file so the server can detect its type \u2014 pass a File, e.g. new File([bytes], "invoice.pdf"), not a bare Blob'
|
|
1185
|
-
);
|
|
1186
|
-
}
|
|
1187
|
-
return new Run(this.client, this.build(), file, opts.text ?? null);
|
|
1255
|
+
/** Replace an existing workflow's definition and return a handle you can `.run(file)` on. */
|
|
1256
|
+
async update(workflowId) {
|
|
1257
|
+
const res = await v2UpdateWorkflow({ client: this.client, path: { workflow_id: workflowId }, body: this.build() });
|
|
1258
|
+
if (res.error) throw toApiError(res.response?.status ?? 500, res.error);
|
|
1259
|
+
return new Workflow(this.client, res.data.id, res.data.name);
|
|
1188
1260
|
}
|
|
1189
1261
|
};
|
|
1190
1262
|
|
|
@@ -1196,13 +1268,32 @@ var Anyformat = class {
|
|
|
1196
1268
|
this._client = createClient(
|
|
1197
1269
|
createConfig({
|
|
1198
1270
|
baseUrl: opts.baseUrl ?? "https://api.anyformat.ai",
|
|
1199
|
-
auth: opts.apiKey
|
|
1271
|
+
auth: opts.apiKey,
|
|
1272
|
+
// Identifies the caller in our logs (Datadog facet). Plain HTTP callers
|
|
1273
|
+
// send no such header and are logged as origin "api".
|
|
1274
|
+
headers: { "x-anyformat-origin": "js-sdk" }
|
|
1200
1275
|
})
|
|
1201
1276
|
);
|
|
1202
1277
|
}
|
|
1203
1278
|
workflow(name, description) {
|
|
1204
1279
|
return new WorkflowBuilder(this._client, name, description);
|
|
1205
1280
|
}
|
|
1281
|
+
async listWorkflows(opts) {
|
|
1282
|
+
const res = await v2ListWorkflows({
|
|
1283
|
+
client: this._client,
|
|
1284
|
+
query: { page: opts?.page, page_size: opts?.pageSize, status: opts?.status }
|
|
1285
|
+
});
|
|
1286
|
+
if (res.error) throw toApiError(res.response?.status ?? 500, res.error);
|
|
1287
|
+
return res.data.results.map((r) => new Workflow(this._client, r.id, r.name ?? ""));
|
|
1288
|
+
}
|
|
1289
|
+
async deleteWorkflow(workflowId) {
|
|
1290
|
+
const res = await v2DeleteWorkflow({
|
|
1291
|
+
client: this._client,
|
|
1292
|
+
path: { workflow_id: workflowId }
|
|
1293
|
+
});
|
|
1294
|
+
if (res.error) throw toApiError(res.response?.status ?? 500, res.error);
|
|
1295
|
+
return workflowId;
|
|
1296
|
+
}
|
|
1206
1297
|
};
|
|
1207
1298
|
|
|
1208
1299
|
// src/schema.ts
|
|
@@ -1230,6 +1321,7 @@ var Schema = {
|
|
|
1230
1321
|
BadRequest,
|
|
1231
1322
|
Forbidden,
|
|
1232
1323
|
NotFound,
|
|
1324
|
+
ParseView,
|
|
1233
1325
|
RateLimited,
|
|
1234
1326
|
Result,
|
|
1235
1327
|
Run,
|
|
@@ -1237,6 +1329,7 @@ var Schema = {
|
|
|
1237
1329
|
Schema,
|
|
1238
1330
|
ServerError,
|
|
1239
1331
|
Unauthorized,
|
|
1332
|
+
Workflow,
|
|
1240
1333
|
WorkflowBuilder,
|
|
1241
1334
|
WorkflowBuilderError
|
|
1242
1335
|
});
|