@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/dist/index.js CHANGED
@@ -2,18 +2,62 @@
2
2
  import { readFileSync } from "fs";
3
3
  import { basename } from "path";
4
4
 
5
+ // src/parse-view.ts
6
+ var ParseView = class {
7
+ /** @internal */
8
+ constructor(parse) {
9
+ this.parse = parse;
10
+ }
11
+ parse;
12
+ get markdown() {
13
+ return this.parse.markdown ?? null;
14
+ }
15
+ get text() {
16
+ return this.parse.text ?? null;
17
+ }
18
+ get blocks() {
19
+ return this.parse.blocks ?? [];
20
+ }
21
+ /**
22
+ * Document-level confidence (0-100) in the parsed content. May be `null` for
23
+ * some parse modes — fall back to `layoutConfidence`.
24
+ */
25
+ get parseConfidence() {
26
+ return this.parse.parse_confidence ?? null;
27
+ }
28
+ /**
29
+ * Document-level confidence (0-100) in the page layout (block positions).
30
+ * `null` when not available.
31
+ */
32
+ get layoutConfidence() {
33
+ return this.parse.layout_confidence ?? null;
34
+ }
35
+ };
36
+
5
37
  // src/result.ts
6
38
  var Result = class {
7
39
  constructor(raw) {
8
40
  this.raw = raw;
9
41
  }
10
42
  raw;
43
+ _parse;
11
44
  get collectionId() {
12
45
  return this.raw.collection_id;
13
46
  }
14
47
  get extractions() {
15
48
  return this.raw.extractions ?? [];
16
49
  }
50
+ /**
51
+ * Typed view over the parse node's output, or `null` when the workflow has
52
+ * no parse node. Cached so repeated access doesn't re-wrap.
53
+ */
54
+ get parse() {
55
+ if (this._parse === void 0) {
56
+ const raw = this.raw.parse;
57
+ this._parse = raw ? new ParseView(raw) : null;
58
+ }
59
+ return this._parse;
60
+ }
17
61
  /**
18
62
  * Convenience accessor for a top-level scalar field on the first
19
63
  * extraction (linear workflows). Returns `undefined` for missing fields
@@ -886,6 +930,11 @@ var createClient = (config = {}) => {
886
930
  var client = createClient(createConfig({ baseUrl: "https://api-dev.anyformat.ai" }));
887
931
 
888
932
  // src/sdk/sdk.gen.ts
933
+ var v2ListWorkflows = (options) => (options?.client ?? client).get({
934
+ security: [{ scheme: "bearer", type: "http" }],
935
+ url: "/v2/workflows/",
936
+ ...options
937
+ });
889
938
  var v2CreateWorkflow = (options) => (options.client ?? client).post({
890
939
  security: [{ scheme: "bearer", type: "http" }],
891
940
  url: "/v2/workflows/",
@@ -895,6 +944,20 @@ var v2CreateWorkflow = (options) => (options.client ?? client).post({
895
944
  ...options.headers
896
945
  }
897
946
  });
947
+ var v2DeleteWorkflow = (options) => (options.client ?? client).delete({
948
+ security: [{ scheme: "bearer", type: "http" }],
949
+ url: "/v2/workflows/{workflow_id}/",
950
+ ...options
951
+ });
952
+ var v2UpdateWorkflow = (options) => (options.client ?? client).put({
953
+ security: [{ scheme: "bearer", type: "http" }],
954
+ url: "/v2/workflows/{workflow_id}/",
955
+ ...options,
956
+ headers: {
957
+ "Content-Type": "application/json",
958
+ ...options.headers
959
+ }
960
+ });
898
961
  var v2GetFileResults = (options) => (options.client ?? client).get({
899
962
  security: [{ scheme: "bearer", type: "http" }],
900
963
  url: "/v2/workflows/{workflow_id}/files/{collection_id}/results/",
@@ -913,45 +976,23 @@ var v2RunWorkflow = (options) => (options.client ?? client).post({
913
976
 
914
977
  // src/run.ts
915
978
  var Run = class {
916
- constructor(client2, request, file, text) {
979
+ /** @internal */
980
+ constructor(client2, workflowId, id) {
917
981
  this.client = client2;
918
- this.request = request;
919
- this.file = file;
920
- this.text = text;
982
+ this.workflowId = workflowId;
983
+ this.id = id;
921
984
  }
922
985
  client;
923
- request;
924
- file;
925
- text;
926
- workflowId = null;
927
- collectionId = null;
928
- /**
929
- * Create the workflow and submit the document — exactly once per `Run`.
930
- * Memoized so that retrying `wait()` after an `SDKTimeout` resumes polling
931
- * the in-flight run instead of creating a duplicate workflow + submission.
932
- */
933
- async submit() {
934
- if (this.collectionId !== null) return;
935
- const created = await v2CreateWorkflow({ client: this.client, body: this.request });
936
- if (created.error) throw toApiError(created.response?.status ?? 500, created.error);
937
- this.workflowId = created.data.id;
938
- const submitted = await v2RunWorkflow({
939
- client: this.client,
940
- path: { workflow_id: this.workflowId },
941
- body: { file: this.file, text: this.text }
942
- });
943
- if (submitted.error) throw toApiError(submitted.response?.status ?? 500, submitted.error);
944
- this.collectionId = submitted.data.id;
945
- }
986
+ workflowId;
987
+ id;
946
988
  async wait(opts = {}) {
947
- const timeoutMs = opts.timeoutMs ?? 12e4;
948
- const pollMs = opts.pollMs ?? 2e3;
949
- await this.submit();
989
+ const timeoutMs = opts.timeoutMs ?? 3e5;
990
+ const pollMs = opts.pollMs ?? 3e3;
950
991
  const deadline = Date.now() + timeoutMs;
951
992
  while (Date.now() < deadline) {
952
993
  const results = await v2GetFileResults({
953
994
  client: this.client,
954
- path: { workflow_id: this.workflowId, collection_id: this.collectionId }
995
+ path: { workflow_id: this.workflowId, collection_id: this.id }
955
996
  });
956
997
  if (!results.error) return new Result(results.data);
957
998
  if (results.response?.status !== 412) {
@@ -963,6 +1004,43 @@ var Run = class {
963
1004
  }
964
1005
  };
965
1006
 
1007
+ // src/workflow.ts
1008
+ var Workflow = class {
1009
+ /** @internal */
1010
+ constructor(client2, id, name) {
1011
+ this.client = client2;
1012
+ this.id = id;
1013
+ this.name = name;
1014
+ }
1015
+ client;
1016
+ id;
1017
+ name;
1018
+ /** Submit a document against this workflow and return a pending `Run`. */
1019
+ async run(file = null, opts = {}) {
1020
+ if (file === null && !opts.text) {
1021
+ throw new WorkflowBuilderError("run() requires a document \u2014 pass a file or non-empty opts.text");
1022
+ }
1023
+ if (file !== null && opts.text !== void 0) {
1024
+ throw new WorkflowBuilderError("run() accepts either a file or text, not both");
1025
+ }
1026
+ if (file !== null) {
1027
+ const filename = file.name;
1028
+ if (typeof filename !== "string" || filename.length === 0) {
1029
+ throw new WorkflowBuilderError(
1030
+ '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'
1031
+ );
1032
+ }
1033
+ }
1034
+ const submitted = await v2RunWorkflow({
1035
+ client: this.client,
1036
+ path: { workflow_id: this.id },
1037
+ body: { file, text: opts.text ?? null }
1038
+ });
1039
+ if (submitted.error) throw toApiError(submitted.response?.status ?? 500, submitted.error);
1040
+ return new Run(this.client, this.id, submitted.data.id);
1041
+ }
1042
+ };
1043
+
966
1044
  // src/builder.ts
967
1045
  var WorkflowBuilder = class {
968
1046
  constructor(client2, name, description) {
@@ -994,7 +1072,8 @@ var WorkflowBuilder = class {
994
1072
  id: opts.id ?? this.nextId("parse"),
995
1073
  mode: opts.mode ?? "standard",
996
1074
  ...opts.promptHint !== void 0 ? { prompt_hint: opts.promptHint } : {},
997
- figure_enhancement: opts.figureEnhancement ?? false
1075
+ figure_enhancement: opts.figureEnhancement ?? false,
1076
+ cache: opts.cache ?? true
998
1077
  };
999
1078
  return this;
1000
1079
  }
@@ -1125,26 +1204,17 @@ var WorkflowBuilder = class {
1125
1204
  }
1126
1205
  return { name: this.name, description: this.description, nodes, edges };
1127
1206
  }
1128
- /** Persist the workflow and return its id. */
1207
+ /** Persist the workflow and return a handle you can `.run(file)` on. */
1129
1208
  async create() {
1130
1209
  const res = await v2CreateWorkflow({ client: this.client, body: this.build() });
1131
1210
  if (res.error) throw toApiError(res.response?.status ?? 500, res.error);
1132
- return res.data.id;
1211
+ return new Workflow(this.client, res.data.id, res.data.name);
1133
1212
  }
1134
- /** Create the workflow, submit a document, and return a pending `Run`. */
1135
- run(file = null, opts = {}) {
1136
- this.require(
1137
- !(file === null && opts.text === void 0),
1138
- "run() requires a document \u2014 pass a file or opts.text"
1139
- );
1140
- if (file !== null) {
1141
- const filename = file.name;
1142
- this.require(
1143
- typeof filename === "string" && filename.length > 0,
1144
- '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'
1145
- );
1146
- }
1147
- return new Run(this.client, this.build(), file, opts.text ?? null);
1213
+ /** Replace an existing workflow's definition and return a handle you can `.run(file)` on. */
1214
+ async update(workflowId) {
1215
+ const res = await v2UpdateWorkflow({ client: this.client, path: { workflow_id: workflowId }, body: this.build() });
1216
+ if (res.error) throw toApiError(res.response?.status ?? 500, res.error);
1217
+ return new Workflow(this.client, res.data.id, res.data.name);
1148
1218
  }
1149
1219
  };
1150
1220
 
@@ -1156,13 +1226,32 @@ var Anyformat = class {
1156
1226
  this._client = createClient(
1157
1227
  createConfig({
1158
1228
  baseUrl: opts.baseUrl ?? "https://api.anyformat.ai",
1159
- auth: opts.apiKey
1229
+ auth: opts.apiKey,
1230
+ // Identifies the caller in our logs (Datadog facet). Plain HTTP callers
1231
+ // send no such header and are logged as origin "api".
1232
+ headers: { "x-anyformat-origin": "js-sdk" }
1160
1233
  })
1161
1234
  );
1162
1235
  }
1163
1236
  workflow(name, description) {
1164
1237
  return new WorkflowBuilder(this._client, name, description);
1165
1238
  }
1239
+ async listWorkflows(opts) {
1240
+ const res = await v2ListWorkflows({
1241
+ client: this._client,
1242
+ query: { page: opts?.page, page_size: opts?.pageSize, status: opts?.status }
1243
+ });
1244
+ if (res.error) throw toApiError(res.response?.status ?? 500, res.error);
1245
+ return res.data.results.map((r) => new Workflow(this._client, r.id, r.name ?? ""));
1246
+ }
1247
+ async deleteWorkflow(workflowId) {
1248
+ const res = await v2DeleteWorkflow({
1249
+ client: this._client,
1250
+ path: { workflow_id: workflowId }
1251
+ });
1252
+ if (res.error) throw toApiError(res.response?.status ?? 500, res.error);
1253
+ return workflowId;
1254
+ }
1166
1255
  };
1167
1256
 
1168
1257
  // src/schema.ts
@@ -1189,6 +1278,7 @@ export {
1189
1278
  BadRequest,
1190
1279
  Forbidden,
1191
1280
  NotFound,
1281
+ ParseView,
1192
1282
  RateLimited,
1193
1283
  Result,
1194
1284
  Run,
@@ -1196,6 +1286,7 @@ export {
1196
1286
  Schema,
1197
1287
  ServerError,
1198
1288
  Unauthorized,
1289
+ Workflow,
1199
1290
  WorkflowBuilder,
1200
1291
  WorkflowBuilderError
1201
1292
  };