okrapdf 0.12.1 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -4
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +1 -1
- package/dist/{chunk-YVUL6ZLA.js → chunk-7BAEYVWG.js} +2 -2
- package/dist/{chunk-XOHPZW3V.js → chunk-ETARIBOV.js} +405 -39
- package/dist/chunk-ETARIBOV.js.map +1 -0
- package/dist/{chunk-QKII53VN.js → chunk-HPTXRSWK.js} +2 -2
- package/dist/chunk-HPTXRSWK.js.map +1 -0
- package/dist/chunk-MSZQPLMQ.js +497 -0
- package/dist/chunk-MSZQPLMQ.js.map +1 -0
- package/dist/{chunk-2HJPTW6S.js → chunk-YGIBZV5J.js} +200 -82
- package/dist/chunk-YGIBZV5J.js.map +1 -0
- package/dist/cli/bin.d.ts +39 -0
- package/dist/cli/bin.js +581 -42
- package/dist/cli/bin.js.map +1 -1
- package/dist/cli/index.d.ts +2 -2
- package/dist/cli/index.js +2 -1
- package/dist/{client-p82YcAs3.d.ts → client-D4A0dQ4h.d.ts} +5 -1
- package/dist/index.d.ts +146 -4
- package/dist/index.js +19 -3
- package/dist/index.js.map +1 -1
- package/dist/react/index.d.ts +3 -3
- package/dist/react/index.js +2 -2
- package/dist/{types-DDm2eEL0.d.ts → types-SYOi8k1l.d.ts} +38 -4
- package/dist/url.d.ts +1 -1
- package/dist/url.js +1 -1
- package/package.json +4 -2
- package/dist/chunk-2HJPTW6S.js.map +0 -1
- package/dist/chunk-QKII53VN.js.map +0 -1
- package/dist/chunk-XOHPZW3V.js.map +0 -1
- /package/dist/{chunk-YVUL6ZLA.js.map → chunk-7BAEYVWG.js.map} +0 -0
|
@@ -37,6 +37,16 @@ function makeDocId() {
|
|
|
37
37
|
const rand = Math.random().toString(36).slice(2, 22);
|
|
38
38
|
return `doc-${rand}`;
|
|
39
39
|
}
|
|
40
|
+
function normalizeDocumentStatus(status) {
|
|
41
|
+
const totalPages = typeof status.pagesTotal === "number" ? status.pagesTotal : typeof status.totalPages === "number" ? status.totalPages : void 0;
|
|
42
|
+
if (typeof totalPages !== "number" || totalPages === status.pagesTotal) {
|
|
43
|
+
return status;
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
...status,
|
|
47
|
+
pagesTotal: totalPages
|
|
48
|
+
};
|
|
49
|
+
}
|
|
40
50
|
function toUint8Array(input) {
|
|
41
51
|
if (input instanceof Uint8Array) return input;
|
|
42
52
|
return new Uint8Array(input);
|
|
@@ -124,6 +134,10 @@ function normalizeSchema(schema) {
|
|
|
124
134
|
function isStructuredCode(code) {
|
|
125
135
|
return !!code && STRUCTURED_CODES.has(code);
|
|
126
136
|
}
|
|
137
|
+
function getErrorMessage(value) {
|
|
138
|
+
if (typeof value === "string" && value.trim() !== "") return value;
|
|
139
|
+
return void 0;
|
|
140
|
+
}
|
|
127
141
|
var OkraSessionHandle = class {
|
|
128
142
|
id;
|
|
129
143
|
modelEndpoint;
|
|
@@ -148,7 +162,11 @@ var OkraSessionHandle = class {
|
|
|
148
162
|
async setModel(model) {
|
|
149
163
|
const normalized = model.trim();
|
|
150
164
|
if (!normalized) {
|
|
151
|
-
throw new OkraRuntimeError(
|
|
165
|
+
throw new OkraRuntimeError(
|
|
166
|
+
"INVALID_REQUEST",
|
|
167
|
+
"session.setModel requires a non-empty model",
|
|
168
|
+
400
|
|
169
|
+
);
|
|
152
170
|
}
|
|
153
171
|
this.#model = normalized;
|
|
154
172
|
}
|
|
@@ -209,6 +227,7 @@ var OkraClient = class {
|
|
|
209
227
|
apiKey;
|
|
210
228
|
sharedSecret;
|
|
211
229
|
fetchImpl;
|
|
230
|
+
documentStatusRoute = "v1";
|
|
212
231
|
sessions;
|
|
213
232
|
collections;
|
|
214
233
|
constructor(options) {
|
|
@@ -252,11 +271,7 @@ var OkraClient = class {
|
|
|
252
271
|
400
|
|
253
272
|
);
|
|
254
273
|
}
|
|
255
|
-
return new OkraSessionHandle(
|
|
256
|
-
this,
|
|
257
|
-
normalized,
|
|
258
|
-
sessionOptions.model?.trim() || void 0
|
|
259
|
-
);
|
|
274
|
+
return new OkraSessionHandle(this, normalized, sessionOptions.model?.trim() || void 0);
|
|
260
275
|
}
|
|
261
276
|
};
|
|
262
277
|
this.collections = {
|
|
@@ -268,17 +283,17 @@ var OkraClient = class {
|
|
|
268
283
|
}
|
|
269
284
|
// ─── Collections ────────────────────────────────────────────────────────
|
|
270
285
|
async collectionList(signal) {
|
|
271
|
-
const res = await this.requestJson(
|
|
272
|
-
"
|
|
273
|
-
|
|
274
|
-
);
|
|
286
|
+
const res = await this.requestJson("/v1/collections", {
|
|
287
|
+
method: "GET",
|
|
288
|
+
signal
|
|
289
|
+
});
|
|
275
290
|
return res.collections;
|
|
276
291
|
}
|
|
277
292
|
async collectionGet(collectionId, signal) {
|
|
278
|
-
return this.requestJson(
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
);
|
|
293
|
+
return this.requestJson(`/v1/collections/${encodeURIComponent(collectionId)}`, {
|
|
294
|
+
method: "GET",
|
|
295
|
+
signal
|
|
296
|
+
});
|
|
282
297
|
}
|
|
283
298
|
collectionQuery(collectionId, prompt, options) {
|
|
284
299
|
const ac = new AbortController();
|
|
@@ -309,10 +324,18 @@ var OkraClient = class {
|
|
|
309
324
|
const response = await responsePromise;
|
|
310
325
|
if (!response.ok) {
|
|
311
326
|
const text = await response.text();
|
|
312
|
-
throw new OkraRuntimeError(
|
|
327
|
+
throw new OkraRuntimeError(
|
|
328
|
+
"HTTP_ERROR",
|
|
329
|
+
`Collection query failed: ${text}`,
|
|
330
|
+
response.status
|
|
331
|
+
);
|
|
313
332
|
}
|
|
314
333
|
if (!response.body) {
|
|
315
|
-
throw new OkraRuntimeError(
|
|
334
|
+
throw new OkraRuntimeError(
|
|
335
|
+
"INVALID_RESPONSE",
|
|
336
|
+
"No response body for collection query",
|
|
337
|
+
500
|
|
338
|
+
);
|
|
316
339
|
}
|
|
317
340
|
const reader = response.body.getReader();
|
|
318
341
|
const decoder = new TextDecoder();
|
|
@@ -429,13 +452,17 @@ var OkraClient = class {
|
|
|
429
452
|
format = options.format ?? "markdown";
|
|
430
453
|
signal = options.signal;
|
|
431
454
|
}
|
|
432
|
-
const response = await this.rawRequest(
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
);
|
|
455
|
+
const response = await this.rawRequest(this.collectionExportPath(collectionId, format), {
|
|
456
|
+
method: "GET",
|
|
457
|
+
signal
|
|
458
|
+
});
|
|
436
459
|
if (!response.ok) {
|
|
437
460
|
const text = await response.text();
|
|
438
|
-
throw new OkraRuntimeError(
|
|
461
|
+
throw new OkraRuntimeError(
|
|
462
|
+
"HTTP_ERROR",
|
|
463
|
+
`Collection export failed: ${text}`,
|
|
464
|
+
response.status
|
|
465
|
+
);
|
|
439
466
|
}
|
|
440
467
|
if (format === "zip") {
|
|
441
468
|
const body = await response.arrayBuffer();
|
|
@@ -526,7 +553,8 @@ var OkraClient = class {
|
|
|
526
553
|
url: input,
|
|
527
554
|
capabilities: options.capabilities,
|
|
528
555
|
visibility,
|
|
529
|
-
redact: options.redact
|
|
556
|
+
redact: options.redact,
|
|
557
|
+
...options.vendorOptions ? { vendor_options: options.vendorOptions } : {}
|
|
530
558
|
})
|
|
531
559
|
});
|
|
532
560
|
return this.sessions.from(documentId);
|
|
@@ -555,6 +583,9 @@ var OkraClient = class {
|
|
|
555
583
|
if (options.vendorKeys) {
|
|
556
584
|
headers["X-Vendor-Keys"] = JSON.stringify(options.vendorKeys);
|
|
557
585
|
}
|
|
586
|
+
if (options.vendorOptions) {
|
|
587
|
+
headers["X-Vendor-Options"] = JSON.stringify(options.vendorOptions);
|
|
588
|
+
}
|
|
558
589
|
if (options.redact) {
|
|
559
590
|
headers["X-Redact"] = JSON.stringify(options.redact);
|
|
560
591
|
}
|
|
@@ -571,10 +602,14 @@ var OkraClient = class {
|
|
|
571
602
|
// ─── Workflow Config / Reparse ───────────────────────────────────────────
|
|
572
603
|
async updateConfig(documentId, update, signal) {
|
|
573
604
|
if (!documentId.trim()) {
|
|
574
|
-
throw new OkraRuntimeError(
|
|
605
|
+
throw new OkraRuntimeError(
|
|
606
|
+
"INVALID_REQUEST",
|
|
607
|
+
"updateConfig requires a non-empty documentId",
|
|
608
|
+
400
|
|
609
|
+
);
|
|
575
610
|
}
|
|
576
611
|
return this.requestJson(
|
|
577
|
-
`/
|
|
612
|
+
`/document/${encodeURIComponent(documentId)}/config`,
|
|
578
613
|
{
|
|
579
614
|
method: "PUT",
|
|
580
615
|
headers: { "Content-Type": "application/json" },
|
|
@@ -589,7 +624,7 @@ var OkraClient = class {
|
|
|
589
624
|
}
|
|
590
625
|
const strategy = options.strategy && options.strategy !== "auto" ? `?strategy=${encodeURIComponent(options.strategy)}` : "";
|
|
591
626
|
return this.requestJson(
|
|
592
|
-
`/
|
|
627
|
+
`/document/${encodeURIComponent(documentId)}/reparse${strategy}`,
|
|
593
628
|
{ method: "POST", signal: options.signal }
|
|
594
629
|
);
|
|
595
630
|
}
|
|
@@ -612,28 +647,47 @@ var OkraClient = class {
|
|
|
612
647
|
return { config, reparse };
|
|
613
648
|
}
|
|
614
649
|
async getKeyWorkflow(signal) {
|
|
615
|
-
return this.requestJson(
|
|
616
|
-
"
|
|
617
|
-
|
|
618
|
-
);
|
|
650
|
+
return this.requestJson("/v1/key-workflow", {
|
|
651
|
+
method: "GET",
|
|
652
|
+
signal
|
|
653
|
+
});
|
|
619
654
|
}
|
|
620
655
|
async setKeyWorkflow(defaultCapabilities, signal) {
|
|
621
|
-
return this.requestJson(
|
|
622
|
-
"
|
|
623
|
-
{
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
signal
|
|
628
|
-
}
|
|
629
|
-
);
|
|
656
|
+
return this.requestJson("/v1/key-workflow", {
|
|
657
|
+
method: "PUT",
|
|
658
|
+
headers: { "Content-Type": "application/json" },
|
|
659
|
+
body: JSON.stringify({ default_capabilities: defaultCapabilities }),
|
|
660
|
+
signal
|
|
661
|
+
});
|
|
630
662
|
}
|
|
631
663
|
// ─── Status / Wait ───────────────────────────────────────────────────────
|
|
632
664
|
async status(documentId, signal) {
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
665
|
+
const encodedId = encodeURIComponent(documentId);
|
|
666
|
+
const legacyPath = `/document/${encodedId}/status`;
|
|
667
|
+
if (this.documentStatusRoute === "document") {
|
|
668
|
+
const status = await this.requestJson(legacyPath, {
|
|
669
|
+
method: "GET",
|
|
670
|
+
signal
|
|
671
|
+
});
|
|
672
|
+
return normalizeDocumentStatus(status);
|
|
673
|
+
}
|
|
674
|
+
try {
|
|
675
|
+
const status = await this.requestJson(`/document/${encodedId}/status`, {
|
|
676
|
+
method: "GET",
|
|
677
|
+
signal
|
|
678
|
+
});
|
|
679
|
+
return normalizeDocumentStatus(status);
|
|
680
|
+
} catch (error) {
|
|
681
|
+
if (!(error instanceof OkraRuntimeError) || error.status !== 404) {
|
|
682
|
+
throw error;
|
|
683
|
+
}
|
|
684
|
+
this.documentStatusRoute = "document";
|
|
685
|
+
const status = await this.requestJson(legacyPath, {
|
|
686
|
+
method: "GET",
|
|
687
|
+
signal
|
|
688
|
+
});
|
|
689
|
+
return normalizeDocumentStatus(status);
|
|
690
|
+
}
|
|
637
691
|
}
|
|
638
692
|
async wait(documentId, options = {}) {
|
|
639
693
|
const startedAt = Date.now();
|
|
@@ -670,10 +724,10 @@ var OkraClient = class {
|
|
|
670
724
|
// ─── Pages ───────────────────────────────────────────────────────────────
|
|
671
725
|
async pages(documentId, options) {
|
|
672
726
|
const params = options?.range ? `?range=${encodeURIComponent(options.range)}` : "";
|
|
673
|
-
return this.requestJson(
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
);
|
|
727
|
+
return this.requestJson(`/document/${encodeURIComponent(documentId)}/pages${params}`, {
|
|
728
|
+
method: "GET",
|
|
729
|
+
signal: options?.signal
|
|
730
|
+
});
|
|
677
731
|
}
|
|
678
732
|
async page(documentId, pageNumber, signal) {
|
|
679
733
|
return this.requestJson(
|
|
@@ -777,52 +831,75 @@ var OkraClient = class {
|
|
|
777
831
|
if (options?.schema) {
|
|
778
832
|
return this.generateStructured(documentId, query, options);
|
|
779
833
|
}
|
|
780
|
-
const result = await this.requestJson(
|
|
781
|
-
|
|
782
|
-
{
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
signal: options?.signal
|
|
790
|
-
}
|
|
791
|
-
);
|
|
834
|
+
const result = await this.requestJson(`/document/${encodeURIComponent(documentId)}/chat/completions`, {
|
|
835
|
+
method: "POST",
|
|
836
|
+
headers: { "Content-Type": "application/json" },
|
|
837
|
+
body: JSON.stringify({
|
|
838
|
+
messages: [{ role: "user", content: query }],
|
|
839
|
+
...options?.model ? { model: options.model } : {}
|
|
840
|
+
}),
|
|
841
|
+
signal: options?.signal
|
|
842
|
+
});
|
|
792
843
|
return {
|
|
793
844
|
answer: result.choices?.[0]?.message?.content || ""
|
|
794
845
|
};
|
|
795
846
|
}
|
|
796
847
|
async generateStructured(documentId, query, options) {
|
|
797
848
|
if (!query || query.trim() === "") {
|
|
798
|
-
throw new OkraRuntimeError(
|
|
849
|
+
throw new OkraRuntimeError(
|
|
850
|
+
"INVALID_REQUEST",
|
|
851
|
+
"generate with schema requires a non-empty query",
|
|
852
|
+
400
|
|
853
|
+
);
|
|
799
854
|
}
|
|
800
855
|
const normalized = normalizeSchema(options.schema);
|
|
801
|
-
const
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
856
|
+
const path = `/document/${encodeURIComponent(documentId)}/chat/completions`;
|
|
857
|
+
const init = {
|
|
858
|
+
method: "POST",
|
|
859
|
+
headers: { "Content-Type": "application/json" },
|
|
860
|
+
body: JSON.stringify({
|
|
861
|
+
messages: [{ role: "user", content: query }],
|
|
862
|
+
response_format: {
|
|
863
|
+
type: "json_schema",
|
|
864
|
+
json_schema: { name: "result", schema: normalized.jsonSchema }
|
|
865
|
+
},
|
|
866
|
+
...options.model ? { model: options.model } : {}
|
|
867
|
+
}),
|
|
868
|
+
signal: options.signal
|
|
869
|
+
};
|
|
870
|
+
let result;
|
|
871
|
+
const maxAttempts = 3;
|
|
872
|
+
let attempt = 0;
|
|
873
|
+
while (true) {
|
|
874
|
+
attempt += 1;
|
|
875
|
+
try {
|
|
876
|
+
result = await this.requestJson(path, init);
|
|
877
|
+
break;
|
|
878
|
+
} catch (error) {
|
|
879
|
+
const isRetriableTimeout = error instanceof OkraRuntimeError && error.status === 504 && (typeof error.details === "object" && error.details !== null && "timeoutMs" in error.details || error.message.toLowerCase().includes("timed out"));
|
|
880
|
+
if (!isRetriableTimeout || attempt >= maxAttempts) {
|
|
881
|
+
throw error;
|
|
882
|
+
}
|
|
883
|
+
await new Promise((resolve) => setTimeout(resolve, 350 * attempt));
|
|
815
884
|
}
|
|
816
|
-
|
|
885
|
+
}
|
|
817
886
|
const raw = result.choices?.[0]?.message?.content;
|
|
818
887
|
if (!raw) {
|
|
819
|
-
throw new OkraRuntimeError(
|
|
888
|
+
throw new OkraRuntimeError(
|
|
889
|
+
"INVALID_RESPONSE",
|
|
890
|
+
"No content in structured output response",
|
|
891
|
+
500
|
|
892
|
+
);
|
|
820
893
|
}
|
|
821
894
|
let parsed;
|
|
822
895
|
try {
|
|
823
896
|
parsed = JSON.parse(raw);
|
|
824
897
|
} catch {
|
|
825
|
-
throw new OkraRuntimeError(
|
|
898
|
+
throw new OkraRuntimeError(
|
|
899
|
+
"INVALID_RESPONSE",
|
|
900
|
+
"Structured output response is not valid JSON",
|
|
901
|
+
500
|
|
902
|
+
);
|
|
826
903
|
}
|
|
827
904
|
let data;
|
|
828
905
|
if (normalized.parser) {
|
|
@@ -844,9 +921,49 @@ var OkraClient = class {
|
|
|
844
921
|
data
|
|
845
922
|
};
|
|
846
923
|
}
|
|
924
|
+
// ─── List Documents ─────────────────────────────────────────────────────
|
|
925
|
+
async listDocuments(signal) {
|
|
926
|
+
const res = await this.requestJson("/v1/documents", {
|
|
927
|
+
method: "GET",
|
|
928
|
+
signal
|
|
929
|
+
});
|
|
930
|
+
return res.documents;
|
|
931
|
+
}
|
|
932
|
+
// ─── Delete Document ──────────────────────────────────────────────────
|
|
933
|
+
async deleteDocument(documentId, signal) {
|
|
934
|
+
if (!documentId.trim()) {
|
|
935
|
+
throw new OkraRuntimeError(
|
|
936
|
+
"INVALID_REQUEST",
|
|
937
|
+
"deleteDocument requires a non-empty documentId",
|
|
938
|
+
400
|
|
939
|
+
);
|
|
940
|
+
}
|
|
941
|
+
await this.requestJson(`/document/${encodeURIComponent(documentId)}`, {
|
|
942
|
+
method: "DELETE",
|
|
943
|
+
signal
|
|
944
|
+
});
|
|
945
|
+
return { deleted: true, documentId };
|
|
946
|
+
}
|
|
947
|
+
// ─── Read Document (full markdown) ────────────────────────────────────
|
|
948
|
+
async read(documentId, options) {
|
|
949
|
+
if (!documentId.trim()) {
|
|
950
|
+
throw new OkraRuntimeError("INVALID_REQUEST", "read requires a non-empty documentId", 400);
|
|
951
|
+
}
|
|
952
|
+
const params = options?.pages ? `?pages=${encodeURIComponent(options.pages)}` : "";
|
|
953
|
+
const response = await this.rawRequest(
|
|
954
|
+
`/document/${encodeURIComponent(documentId)}/full.md${params}`,
|
|
955
|
+
{ method: "GET", signal: options?.signal }
|
|
956
|
+
);
|
|
957
|
+
if (!response.ok) {
|
|
958
|
+
const text = await response.text();
|
|
959
|
+
throw new OkraRuntimeError("HTTP_ERROR", `Read failed: ${text}`, response.status);
|
|
960
|
+
}
|
|
961
|
+
const markdown = await response.text();
|
|
962
|
+
return { documentId, markdown };
|
|
963
|
+
}
|
|
847
964
|
// ─── Model Endpoint ──────────────────────────────────────────────────────
|
|
848
965
|
modelEndpoint(documentId) {
|
|
849
|
-
return `${this.baseUrl}/
|
|
966
|
+
return `${this.baseUrl}/document/${encodeURIComponent(documentId)}`;
|
|
850
967
|
}
|
|
851
968
|
// ─── Publish / Share ────────────────────────────────────────────────────
|
|
852
969
|
async publish(documentId, signal) {
|
|
@@ -856,7 +973,7 @@ var OkraClient = class {
|
|
|
856
973
|
);
|
|
857
974
|
return {
|
|
858
975
|
...result,
|
|
859
|
-
url: `${this.baseUrl}/
|
|
976
|
+
url: `${this.baseUrl}/document/${encodeURIComponent(documentId)}`
|
|
860
977
|
};
|
|
861
978
|
}
|
|
862
979
|
async shareLink(documentId, options) {
|
|
@@ -909,9 +1026,10 @@ var OkraClient = class {
|
|
|
909
1026
|
const parsed = this.parseBody(text);
|
|
910
1027
|
if (!response.ok) {
|
|
911
1028
|
const envelope = parsed;
|
|
912
|
-
const
|
|
913
|
-
const
|
|
914
|
-
const
|
|
1029
|
+
const nestedError = typeof envelope?.error === "object" && envelope.error !== null ? envelope.error : void 0;
|
|
1030
|
+
const code = envelope?.code || nestedError?.code;
|
|
1031
|
+
const message = getErrorMessage(envelope?.message) || getErrorMessage(typeof envelope?.error === "string" ? envelope.error : void 0) || getErrorMessage(nestedError?.message) || `Request failed with status ${response.status}`;
|
|
1032
|
+
const details = envelope?.details ?? nestedError?.details ?? parsed ?? text;
|
|
915
1033
|
if (isStructuredCode(code)) {
|
|
916
1034
|
throw new StructuredOutputError(code, message, response.status, details);
|
|
917
1035
|
}
|
|
@@ -942,4 +1060,4 @@ var OkraClient = class {
|
|
|
942
1060
|
export {
|
|
943
1061
|
OkraClient
|
|
944
1062
|
};
|
|
945
|
-
//# sourceMappingURL=chunk-
|
|
1063
|
+
//# sourceMappingURL=chunk-YGIBZV5J.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts"],"sourcesContent":["import { z, type ZodType } from 'zod';\nimport { OkraRuntimeError, StructuredOutputError } from './errors';\nimport type {\n OkraClientOptions,\n Collection,\n CollectionExportFormat,\n CollectionExportOptions,\n CollectionExportEvent,\n CollectionMarkdownExport,\n CollectionQueryEvent,\n CollectionQueryOptions,\n CollectionQueryResult,\n CollectionQueryStream,\n CollectionSummary,\n CompletionEvent,\n CompletionOptions,\n DeleteDocumentResult,\n DocumentAnswer,\n DocumentConfigResult,\n DocumentConfigUpdate,\n DocumentListItem,\n DocumentListResponse,\n DocumentMarkdownExport,\n DocumentStatus,\n EntitiesResponse,\n GenerateOptions,\n GenerateResult,\n JsonSchema,\n LogEntry,\n LogsOptions,\n MarkdownPage,\n Page,\n PublishResult,\n QueryResult,\n ReadDocumentOptions,\n ReadDocumentResult,\n ReparseOptions,\n ReparseResult,\n RuntimeErrorCode,\n ShareLinkOptions,\n ShareLinkResult,\n SessionAttachOptions,\n SessionCreateOptions,\n SessionState,\n OkraSession,\n StructuredOutputErrorCode,\n StructuredSchema,\n ApiKeyWorkflowConfigResponse,\n ApplyWorkflowOptions,\n ApplyWorkflowResult,\n UploadInput,\n UploadOptions,\n WaitOptions,\n} from './types';\n\nconst DEFAULT_BASE_URL = 'https://api.okrapdf.com';\nconst DEFAULT_WAIT_TIMEOUT_MS = 5 * 60_000;\nconst DEFAULT_WAIT_POLL_MS = 1_500;\nconst COMPLETE_PHASES = new Set(['complete', 'awaiting_review']);\nconst TERMINAL_ERROR_PHASES = new Set(['error']);\nconst STRUCTURED_CODES = new Set<StructuredOutputErrorCode>([\n 'SCHEMA_VALIDATION_FAILED',\n 'EXTRACTION_FAILED',\n 'TIMEOUT',\n 'DOCUMENT_NOT_FOUND',\n]);\nconst NODE_FS_PROMISES_SPECIFIER = `node:${'fs/promises'}`;\nconst NODE_PATH_SPECIFIER = `node:${'path'}`;\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction isHttpUrl(value: string): boolean {\n return /^https?:\\/\\//i.test(value);\n}\n\nfunction isDocumentId(value: string): boolean {\n return /^(?:ocr|doc)-[A-Za-z0-9_-]+$/.test(value);\n}\n\nfunction normalizeBaseUrl(baseUrl: string): string {\n return baseUrl.replace(/\\/+$/, '');\n}\n\nfunction makeDocId(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return `doc-${crypto.randomUUID().replace(/-/g, '').slice(0, 20)}`;\n }\n const rand = Math.random().toString(36).slice(2, 22);\n return `doc-${rand}`;\n}\n\nfunction normalizeDocumentStatus(status: DocumentStatus): DocumentStatus {\n const totalPages =\n typeof status.pagesTotal === 'number'\n ? status.pagesTotal\n : typeof status.totalPages === 'number'\n ? status.totalPages\n : undefined;\n\n if (typeof totalPages !== 'number' || totalPages === status.pagesTotal) {\n return status;\n }\n\n return {\n ...status,\n pagesTotal: totalPages,\n };\n}\n\nfunction toUint8Array(input: ArrayBuffer | Uint8Array): Uint8Array {\n if (input instanceof Uint8Array) return input;\n return new Uint8Array(input);\n}\n\ninterface NodeFsModule {\n readFile(path: string): Promise<ArrayBuffer | Uint8Array>;\n}\n\ninterface NodePathModule {\n basename(path: string): string;\n}\n\ninterface NamedBlob extends Blob {\n name?: string;\n}\n\nfunction isBlobLike(input: unknown): input is Blob {\n if (typeof Blob !== 'undefined' && input instanceof Blob) return true;\n return (\n !!input &&\n typeof input === 'object' &&\n typeof (input as { arrayBuffer?: unknown }).arrayBuffer === 'function'\n );\n}\n\nfunction inferBlobName(input: Blob, fallback: string): string {\n const named = input as NamedBlob;\n if (typeof named.name === 'string' && named.name.trim() !== '') {\n return named.name;\n }\n return fallback;\n}\n\nfunction toHeaderSafeFileName(fileName: string): string {\n const leaf = fileName.split(/[\\\\/]/).pop() || fileName;\n const cleaned = leaf.replace(/[\\r\\n]/g, ' ').trim();\n\n if (/^[\\x20-\\x7E]+$/.test(cleaned)) {\n return cleaned;\n }\n\n const extMatch = cleaned.match(/(\\.[A-Za-z0-9]{1,10})$/);\n const extension = extMatch?.[1].toLowerCase() ?? '';\n const base = extension ? cleaned.slice(0, -extension.length) : cleaned;\n\n const asciiBase = base\n .normalize('NFKD')\n .replace(/[^\\x20-\\x7E]/g, '')\n .replace(/[^A-Za-z0-9._ -]/g, '_')\n .replace(/\\s+/g, '_')\n .replace(/_+/g, '_')\n .replace(/^[._-]+|[._-]+$/g, '');\n\n return `${asciiBase || 'document'}${extension || '.pdf'}`;\n}\n\nasync function readLocalFileFromNode(\n inputPath: string,\n): Promise<{ bytes: Uint8Array; fileName: string }> {\n try {\n const [fsModule, pathModule] = await Promise.all([\n import(NODE_FS_PROMISES_SPECIFIER) as Promise<NodeFsModule>,\n import(NODE_PATH_SPECIFIER) as Promise<NodePathModule>,\n ]);\n const raw = await fsModule.readFile(inputPath);\n return {\n bytes: toUint8Array(raw),\n fileName: pathModule.basename(inputPath),\n };\n } catch (error) {\n const code =\n typeof error === 'object' && error && 'code' in error\n ? String((error as { code?: unknown }).code)\n : undefined;\n const msg = error instanceof Error ? error.message : String(error);\n\n if (code === 'ENOENT') {\n throw new OkraRuntimeError(\n 'INVALID_REQUEST',\n `Local file not found: ${inputPath}`,\n 400,\n error,\n );\n }\n\n if (code === 'EACCES' || code === 'EPERM') {\n throw new OkraRuntimeError(\n 'INVALID_REQUEST',\n `Cannot read local file (${code}): ${inputPath}`,\n 400,\n error,\n );\n }\n\n if (code === 'ERR_MODULE_NOT_FOUND' || code === 'ERR_UNKNOWN_BUILTIN_MODULE') {\n throw new OkraRuntimeError(\n 'INVALID_REQUEST',\n 'Local file path uploads are only supported in Node.js. In browser runtimes, pass File/Blob, ArrayBuffer, Uint8Array, or URL.',\n 400,\n error,\n );\n }\n\n throw new OkraRuntimeError(\n 'INVALID_REQUEST',\n `Failed to read local file \"${inputPath}\": ${msg}`,\n 400,\n error,\n );\n }\n}\n\ninterface StructuredErrorEnvelope {\n code?: string;\n message?: string;\n details?: unknown;\n error?: string | { message?: string; code?: string; details?: unknown; type?: string };\n}\n\ninterface NormalizedSchema<T> {\n jsonSchema: JsonSchema;\n parser?: ZodType<T>;\n}\n\nfunction normalizeSchema<T>(schema: StructuredSchema<T>): NormalizedSchema<T> {\n const maybeZod = schema as ZodType<T>;\n const hasSafeParse = typeof (maybeZod as { safeParse?: unknown }).safeParse === 'function';\n if (hasSafeParse) {\n return {\n jsonSchema: z.toJSONSchema(maybeZod, { target: 'draft-2020-12' }) as JsonSchema,\n parser: maybeZod,\n };\n }\n return { jsonSchema: schema as JsonSchema };\n}\n\nfunction isStructuredCode(code: string | undefined): code is StructuredOutputErrorCode {\n return !!code && STRUCTURED_CODES.has(code as StructuredOutputErrorCode);\n}\n\nfunction getErrorMessage(value: unknown): string | undefined {\n if (typeof value === 'string' && value.trim() !== '') return value;\n return undefined;\n}\n\n// ─── Session Handle ──────────────────────────────────────────────────────────\n\nclass OkraSessionHandle implements OkraSession {\n readonly id: string;\n readonly modelEndpoint: string;\n #model?: string;\n #client: OkraClient;\n\n constructor(client: OkraClient, documentId: string, model?: string) {\n this.#client = client;\n this.id = documentId;\n this.modelEndpoint = client.modelEndpoint(documentId);\n this.#model = model;\n }\n\n get model(): string | undefined {\n return this.#model;\n }\n\n state(): SessionState {\n return {\n id: this.id,\n model: this.#model,\n modelEndpoint: this.modelEndpoint,\n };\n }\n\n async setModel(model: string): Promise<void> {\n const normalized = model.trim();\n if (!normalized) {\n throw new OkraRuntimeError(\n 'INVALID_REQUEST',\n 'session.setModel requires a non-empty model',\n 400,\n );\n }\n this.#model = normalized;\n }\n\n status(signal?: AbortSignal): Promise<DocumentStatus> {\n return this.#client.status(this.id, signal);\n }\n\n wait(options?: WaitOptions): Promise<DocumentStatus> {\n return this.#client.wait(this.id, options);\n }\n\n pages(options?: { range?: string; signal?: AbortSignal }): Promise<Page[]> {\n return this.#client.pages(this.id, options);\n }\n\n page(pageNumber: number, signal?: AbortSignal): Promise<Page> {\n return this.#client.page(this.id, pageNumber, signal);\n }\n\n entities(options?: {\n type?: string;\n limit?: number;\n offset?: number;\n signal?: AbortSignal;\n }): Promise<EntitiesResponse> {\n return this.#client.entities(this.id, options);\n }\n\n downloadUrl(): string {\n return this.#client.downloadUrl(this.id);\n }\n\n query(sql: string, signal?: AbortSignal): Promise<QueryResult> {\n return this.#client.query(this.id, sql, signal);\n }\n\n logs(options?: LogsOptions): Promise<LogEntry[]> {\n return this.#client.logs(this.id, options);\n }\n\n publish(signal?: AbortSignal): Promise<PublishResult> {\n return this.#client.publish(this.id, signal);\n }\n\n shareLink(options?: ShareLinkOptions): Promise<ShareLinkResult> {\n return this.#client.shareLink(this.id, options);\n }\n\n prompt(\n query: string,\n options?: GenerateOptions & { schema?: undefined },\n ): Promise<GenerateResult>;\n prompt<T>(\n query: string,\n options: GenerateOptions & { schema: StructuredSchema<T> },\n ): Promise<GenerateResult<T>>;\n prompt<T = undefined>(query: string, options?: GenerateOptions): Promise<GenerateResult<T>> {\n const model = options?.model ?? this.#model;\n const merged = model ? { ...options, model } : options;\n if (merged?.schema !== undefined) {\n return this.#client.generate(\n this.id,\n query,\n merged as GenerateOptions & { schema: StructuredSchema<unknown> },\n ) as Promise<GenerateResult<T>>;\n }\n return this.#client.generate(\n this.id,\n query,\n merged as GenerateOptions & { schema?: undefined },\n ) as Promise<GenerateResult<T>>;\n }\n\n stream(query: string, options?: CompletionOptions): AsyncGenerator<CompletionEvent> {\n const model = options?.model ?? this.#model;\n const merged = model ? { ...options, model } : options;\n return this.#client.stream(this.id, query, merged);\n }\n}\n\n// ─── Client ──────────────────────────────────────────────────────────────────\n\nexport class OkraClient {\n private readonly baseUrl: string;\n private readonly apiKey?: string;\n private readonly sharedSecret?: string;\n private readonly fetchImpl: typeof globalThis.fetch;\n private documentStatusRoute: 'v1' | 'document' = 'v1';\n readonly sessions: {\n create: (sourceOrDocId: UploadInput, options?: SessionCreateOptions) => Promise<OkraSession>;\n from: (documentId: string, options?: SessionAttachOptions) => OkraSession;\n };\n readonly collections: {\n list: (signal?: AbortSignal) => Promise<CollectionSummary[]>;\n get: (collectionId: string, signal?: AbortSignal) => Promise<Collection>;\n query: <T = undefined>(\n collectionId: string,\n prompt: string,\n options?: CollectionQueryOptions<T>,\n ) => CollectionQueryStream<T>;\n exportMarkdown: (\n collectionId: string,\n options?: AbortSignal | CollectionExportOptions,\n ) => Promise<CollectionMarkdownExport | Uint8Array>;\n };\n constructor(options: OkraClientOptions) {\n this.baseUrl = normalizeBaseUrl(options.baseUrl || DEFAULT_BASE_URL);\n this.apiKey = options.apiKey;\n this.sharedSecret = options.sharedSecret;\n this.fetchImpl = options.fetch || globalThis.fetch.bind(globalThis);\n\n if (!this.apiKey && !this.sharedSecret) {\n throw new OkraRuntimeError(\n 'UNAUTHORIZED',\n 'OkraClient requires either apiKey or sharedSecret',\n 401,\n );\n }\n\n if (\n typeof globalThis !== 'undefined' &&\n 'window' in globalThis &&\n this.apiKey &&\n !this.apiKey.startsWith('okra_pk_')\n ) {\n console.warn(\n '[OkraPDF] Secret API key detected in browser. Use a publishable key (okra_pk_...) for client-side usage. ' +\n 'See https://docs.okrapdf.com/api-keys#publishable-keys',\n );\n }\n\n this.sessions = {\n create: async (sourceOrDocId, sessionOptions = {}) => {\n let documentId: string;\n if (typeof sourceOrDocId === 'string' && isDocumentId(sourceOrDocId.trim())) {\n documentId = sourceOrDocId.trim();\n } else {\n const session = await this.upload(sourceOrDocId, sessionOptions.upload);\n documentId = session.id;\n }\n\n const session = this.sessions.from(documentId, { model: sessionOptions.model });\n if (sessionOptions.wait ?? true) {\n await session.wait(sessionOptions.waitOptions);\n }\n return session;\n },\n from: (documentId, sessionOptions = {}) => {\n const normalized = documentId.trim();\n if (!normalized) {\n throw new OkraRuntimeError(\n 'INVALID_REQUEST',\n 'sessions.from requires a non-empty documentId',\n 400,\n );\n }\n\n return new OkraSessionHandle(this, normalized, sessionOptions.model?.trim() || undefined);\n },\n };\n\n this.collections = {\n list: (signal) => this.collectionList(signal),\n get: (collectionId, signal) => this.collectionGet(collectionId, signal),\n query: <T = undefined>(\n collectionId: string,\n prompt: string,\n options?: CollectionQueryOptions<T>,\n ) => this.collectionQuery<T>(collectionId, prompt, options),\n exportMarkdown: (collectionId, options?) =>\n this.collectionExportMarkdown(collectionId, options),\n };\n }\n\n // ─── Collections ────────────────────────────────────────────────────────\n\n private async collectionList(signal?: AbortSignal): Promise<CollectionSummary[]> {\n const res = await this.requestJson<{ collections: CollectionSummary[] }>('/v1/collections', {\n method: 'GET',\n signal,\n });\n return res.collections;\n }\n\n private async collectionGet(collectionId: string, signal?: AbortSignal): Promise<Collection> {\n return this.requestJson<Collection>(`/v1/collections/${encodeURIComponent(collectionId)}`, {\n method: 'GET',\n signal,\n });\n }\n\n private collectionQuery<T = undefined>(\n collectionId: string,\n prompt: string,\n options?: CollectionQueryOptions<T>,\n ): CollectionQueryStream<T> {\n const ac = new AbortController();\n if (options?.signal) {\n options.signal.addEventListener('abort', () => ac.abort(), { once: true });\n }\n\n const body: Record<string, unknown> = { prompt, stream: true };\n if (options?.schema) {\n const normalized = normalizeSchema(options.schema);\n body.response_format = {\n type: 'json_schema',\n json_schema: { name: 'result', schema: normalized.jsonSchema },\n };\n }\n if (options?.docIds) {\n body.doc_ids = options.docIds;\n }\n\n const responsePromise = this.rawRequest(\n `/v1/collections/${encodeURIComponent(collectionId)}/query`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n signal: ac.signal,\n },\n );\n\n async function* iterateNdjson(): AsyncGenerator<CollectionQueryEvent> {\n const response = await responsePromise;\n if (!response.ok) {\n const text = await response.text();\n throw new OkraRuntimeError(\n 'HTTP_ERROR',\n `Collection query failed: ${text}`,\n response.status,\n );\n }\n if (!response.body) {\n throw new OkraRuntimeError(\n 'INVALID_RESPONSE',\n 'No response body for collection query',\n 500,\n );\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n try {\n yield JSON.parse(trimmed) as CollectionQueryEvent;\n } catch {\n // skip malformed lines\n }\n }\n }\n\n // flush remaining buffer\n const remaining = buffer.trim();\n if (remaining) {\n try {\n yield JSON.parse(remaining) as CollectionQueryEvent;\n } catch {\n // skip\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n // Tee the generator so gather() and iteration don't conflict\n let iteratorInstance: AsyncGenerator<CollectionQueryEvent> | null = null;\n function getIterator(): AsyncGenerator<CollectionQueryEvent> {\n if (!iteratorInstance) iteratorInstance = iterateNdjson();\n return iteratorInstance;\n }\n\n const stream: CollectionQueryStream<T> = {\n [Symbol.asyncIterator]() {\n return getIterator();\n },\n\n async gather(): Promise<CollectionQueryResult<T>> {\n const startTime = Date.now();\n const answers = new Map<string, DocumentAnswer<T>>();\n let queryId = '';\n let queryPrompt = prompt;\n let totalCostUsd = 0;\n let completed = 0;\n let failed = 0;\n\n for await (const event of getIterator()) {\n if (event.type === 'start') {\n queryId = event.query_id;\n queryPrompt = event.prompt;\n } else if (event.type === 'result') {\n answers.set(event.doc_id, {\n docId: event.doc_id,\n status: event.status,\n answer: event.answer,\n data: event.data as T | undefined,\n costUsd: event.usage?.cost_usd ?? 0,\n durationMs: event.duration_ms,\n error: event.error,\n });\n } else if (event.type === 'done') {\n totalCostUsd = event.total_cost_usd;\n completed = event.completed;\n failed = event.failed;\n } else if (event.type === 'error') {\n throw new OkraRuntimeError('HTTP_ERROR', event.error, 500);\n }\n }\n\n return {\n queryId,\n prompt: queryPrompt,\n answers,\n totalCostUsd,\n durationMs: Date.now() - startTime,\n completed,\n failed,\n };\n },\n\n abort() {\n ac.abort();\n },\n\n toReadableStream(): ReadableStream<Uint8Array> {\n // Return raw body — lazy, only fetched if called before iteration\n const encoder = new TextEncoder();\n const iter = getIterator();\n return new ReadableStream({\n async pull(controller) {\n const { done, value } = await iter.next();\n if (done) {\n controller.close();\n } else {\n controller.enqueue(encoder.encode(JSON.stringify(value) + '\\n'));\n }\n },\n cancel() {\n ac.abort();\n },\n });\n },\n };\n\n return stream;\n }\n\n // ─── Collection Export (markdown from R2) ────────────────────────────────\n\n private collectionExportPath(collectionId: string, format: CollectionExportFormat): string {\n return `/v1/collections/${encodeURIComponent(collectionId)}/export?format=${encodeURIComponent(format)}`;\n }\n\n private async collectionExportMarkdown(\n collectionId: string,\n options?: AbortSignal | CollectionExportOptions,\n ): Promise<CollectionMarkdownExport | Uint8Array> {\n let format: CollectionExportFormat = 'markdown';\n let signal: AbortSignal | undefined;\n\n if (options && typeof options === 'object' && 'aborted' in options) {\n signal = options as AbortSignal;\n } else if (options) {\n format = options.format ?? 'markdown';\n signal = options.signal;\n }\n\n const response = await this.rawRequest(this.collectionExportPath(collectionId, format), {\n method: 'GET',\n signal,\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new OkraRuntimeError(\n 'HTTP_ERROR',\n `Collection export failed: ${text}`,\n response.status,\n );\n }\n\n if (format === 'zip') {\n const body = await response.arrayBuffer();\n return new Uint8Array(body);\n }\n\n if (!response.body) {\n throw new OkraRuntimeError('INVALID_RESPONSE', 'No response body for collection export', 500);\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n const documents: DocumentMarkdownExport[] = [];\n let totalPages = 0;\n let collectionName = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n try {\n const event = JSON.parse(trimmed) as CollectionExportEvent;\n if (event.type === 'result') {\n documents.push({\n docId: event.doc_id,\n fileName: event.file_name,\n pageCount: event.page_count,\n pages: event.pages,\n });\n totalPages += event.page_count;\n }\n } catch {\n // skip malformed lines\n }\n }\n }\n\n // flush remaining buffer\n const remaining = buffer.trim();\n if (remaining) {\n try {\n const event = JSON.parse(remaining) as CollectionExportEvent;\n if (event.type === 'result') {\n documents.push({\n docId: event.doc_id,\n fileName: event.file_name,\n pageCount: event.page_count,\n pages: event.pages,\n });\n totalPages += event.page_count;\n }\n } catch {\n // skip\n }\n }\n } finally {\n reader.releaseLock();\n }\n\n // Try to get collection name from metadata\n try {\n const col = await this.collectionGet(collectionId);\n collectionName = col.name;\n } catch {\n collectionName = collectionId;\n }\n\n return {\n collectionId,\n collectionName,\n documents,\n totalDocuments: documents.length,\n totalPages,\n exportedAt: new Date().toISOString(),\n };\n }\n\n // ─── Upload ──────────────────────────────────────────────────────────────\n\n async upload(input: UploadInput, options: UploadOptions = {}): Promise<OkraSession> {\n const documentId = options.documentId || makeDocId();\n const path = `/document/${encodeURIComponent(documentId)}`;\n const visibility = options.visibility || 'private';\n\n if (typeof input === 'string' && isHttpUrl(input)) {\n const urlHeaders: Record<string, string> = { 'Content-Type': 'application/json' };\n if (options.vendorKeys) {\n urlHeaders['X-Vendor-Keys'] = JSON.stringify(options.vendorKeys);\n }\n await this.requestJson<{ phase?: string }>(`${path}/upload-url`, {\n method: 'POST',\n headers: urlHeaders,\n body: JSON.stringify({\n url: input,\n capabilities: options.capabilities,\n visibility,\n redact: options.redact,\n ...(options.vendorOptions ? { vendor_options: options.vendorOptions } : {}),\n }),\n });\n return this.sessions.from(documentId);\n }\n\n let bytes: Uint8Array;\n let fileName = options.fileName || 'document.pdf';\n if (typeof input === 'string') {\n const local = await readLocalFileFromNode(input);\n bytes = local.bytes;\n if (!options.fileName) fileName = local.fileName;\n } else if (isBlobLike(input)) {\n bytes = toUint8Array(await input.arrayBuffer());\n if (!options.fileName) {\n fileName = inferBlobName(input, fileName);\n }\n } else {\n bytes = toUint8Array(input);\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/pdf',\n 'X-File-Name': toHeaderSafeFileName(fileName),\n };\n if (options.capabilities) {\n headers['X-Capabilities'] = JSON.stringify(options.capabilities);\n }\n if (options.vendorKeys) {\n headers['X-Vendor-Keys'] = JSON.stringify(options.vendorKeys);\n }\n if (options.vendorOptions) {\n headers['X-Vendor-Options'] = JSON.stringify(options.vendorOptions);\n }\n if (options.redact) {\n headers['X-Redact'] = JSON.stringify(options.redact);\n }\n if (visibility === 'public') {\n headers['X-Visibility'] = 'public';\n }\n\n await this.requestJson<{ phase?: string }>(`${path}/upload`, {\n method: 'POST',\n headers,\n body: bytes as unknown as BodyInit,\n });\n\n return this.sessions.from(documentId);\n }\n\n // ─── Workflow Config / Reparse ───────────────────────────────────────────\n\n async updateConfig(\n documentId: string,\n update: DocumentConfigUpdate,\n signal?: AbortSignal,\n ): Promise<DocumentConfigResult> {\n if (!documentId.trim()) {\n throw new OkraRuntimeError(\n 'INVALID_REQUEST',\n 'updateConfig requires a non-empty documentId',\n 400,\n );\n }\n return this.requestJson<DocumentConfigResult>(\n `/document/${encodeURIComponent(documentId)}/config`,\n {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(update),\n signal,\n },\n );\n }\n\n async reparse(documentId: string, options: ReparseOptions = {}): Promise<ReparseResult> {\n if (!documentId.trim()) {\n throw new OkraRuntimeError('INVALID_REQUEST', 'reparse requires a non-empty documentId', 400);\n }\n const strategy =\n options.strategy && options.strategy !== 'auto'\n ? `?strategy=${encodeURIComponent(options.strategy)}`\n : '';\n return this.requestJson<ReparseResult>(\n `/document/${encodeURIComponent(documentId)}/reparse${strategy}`,\n { method: 'POST', signal: options.signal },\n );\n }\n\n async applyWorkflow(\n documentId: string,\n options: ApplyWorkflowOptions,\n ): Promise<ApplyWorkflowResult> {\n if (!options?.capabilities) {\n throw new OkraRuntimeError('INVALID_REQUEST', 'applyWorkflow requires capabilities', 400);\n }\n\n const config = await this.updateConfig(\n documentId,\n { capabilities: options.capabilities },\n options.signal,\n );\n\n if (options.reparse === false) {\n return { config };\n }\n\n const reparse = await this.reparse(documentId, {\n strategy: options.strategy,\n signal: options.signal,\n });\n return { config, reparse };\n }\n\n async getKeyWorkflow(signal?: AbortSignal): Promise<ApiKeyWorkflowConfigResponse> {\n return this.requestJson<ApiKeyWorkflowConfigResponse>('/v1/key-workflow', {\n method: 'GET',\n signal,\n });\n }\n\n async setKeyWorkflow(\n defaultCapabilities: ApiKeyWorkflowConfigResponse['default_capabilities'],\n signal?: AbortSignal,\n ): Promise<ApiKeyWorkflowConfigResponse> {\n return this.requestJson<ApiKeyWorkflowConfigResponse>('/v1/key-workflow', {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ default_capabilities: defaultCapabilities }),\n signal,\n });\n }\n\n // ─── Status / Wait ───────────────────────────────────────────────────────\n\n async status(documentId: string, signal?: AbortSignal): Promise<DocumentStatus> {\n const encodedId = encodeURIComponent(documentId);\n const legacyPath = `/document/${encodedId}/status`;\n\n if (this.documentStatusRoute === 'document') {\n const status = await this.requestJson<DocumentStatus>(legacyPath, {\n method: 'GET',\n signal,\n });\n return normalizeDocumentStatus(status);\n }\n\n try {\n const status = await this.requestJson<DocumentStatus>(`/document/${encodedId}/status`, {\n method: 'GET',\n signal,\n });\n return normalizeDocumentStatus(status);\n } catch (error) {\n if (!(error instanceof OkraRuntimeError) || error.status !== 404) {\n throw error;\n }\n\n this.documentStatusRoute = 'document';\n const status = await this.requestJson<DocumentStatus>(legacyPath, {\n method: 'GET',\n signal,\n });\n return normalizeDocumentStatus(status);\n }\n }\n\n async wait(documentId: string, options: WaitOptions = {}): Promise<DocumentStatus> {\n const startedAt = Date.now();\n const timeoutMs = options.timeoutMs ?? DEFAULT_WAIT_TIMEOUT_MS;\n const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_WAIT_POLL_MS;\n\n while (true) {\n if (options.signal?.aborted) {\n throw new OkraRuntimeError('TIMEOUT', 'Wait aborted', 499);\n }\n\n const current = await this.status(documentId, options.signal);\n if (COMPLETE_PHASES.has(current.phase)) {\n return current;\n }\n if (TERMINAL_ERROR_PHASES.has(current.phase)) {\n throw new OkraRuntimeError(\n 'EXTRACTION_FAILED',\n `Document entered terminal error phase (${current.phase})`,\n 500,\n current,\n );\n }\n\n const elapsed = Date.now() - startedAt;\n if (elapsed >= timeoutMs) {\n throw new OkraRuntimeError(\n 'TIMEOUT',\n `Timed out waiting for document ${documentId} after ${timeoutMs}ms`,\n 504,\n current,\n );\n }\n\n await sleep(pollIntervalMs);\n }\n }\n\n // ─── Pages ───────────────────────────────────────────────────────────────\n\n async pages(\n documentId: string,\n options?: { range?: string; signal?: AbortSignal },\n ): Promise<Page[]> {\n const params = options?.range ? `?range=${encodeURIComponent(options.range)}` : '';\n return this.requestJson<Page[]>(`/document/${encodeURIComponent(documentId)}/pages${params}`, {\n method: 'GET',\n signal: options?.signal,\n });\n }\n\n async page(documentId: string, pageNumber: number, signal?: AbortSignal): Promise<Page> {\n return this.requestJson<Page>(\n `/document/${encodeURIComponent(documentId)}/page/${pageNumber}`,\n { method: 'GET', signal },\n );\n }\n\n // ─── Download ──────────────────────────────────────────────────────────\n\n downloadUrl(documentId: string): string {\n return `${this.baseUrl}/document/${encodeURIComponent(documentId)}/download`;\n }\n\n // ─── Entities ────────────────────────────────────────────────────────────\n\n async entities(\n documentId: string,\n options?: { type?: string; limit?: number; offset?: number; signal?: AbortSignal },\n ): Promise<EntitiesResponse> {\n const params = new URLSearchParams();\n if (options?.type) params.set('type', options.type);\n if (options?.limit) params.set('limit', String(options.limit));\n if (options?.offset) params.set('offset', String(options.offset));\n const qs = params.toString();\n return this.requestJson<EntitiesResponse>(\n `/document/${encodeURIComponent(documentId)}/nodes${qs ? `?${qs}` : ''}`,\n { method: 'GET', signal: options?.signal },\n );\n }\n\n // ─── Query (SQL) ─────────────────────────────────────────────────────────\n\n async query(documentId: string, sql: string, signal?: AbortSignal): Promise<QueryResult> {\n return this.requestJson<QueryResult>(\n `/document/${encodeURIComponent(documentId)}/query?select=${encodeURIComponent(sql)}`,\n { method: 'GET', signal },\n );\n }\n\n // ─── Logs ───────────────────────────────────────────────────────────────\n\n async logs(documentId: string, options?: LogsOptions): Promise<LogEntry[]> {\n const limit = options?.limit ?? 100;\n const res = await this.requestJson<{ entries: LogEntry[] }>(\n `/document/${encodeURIComponent(documentId)}/log?limit=${limit}`,\n { method: 'GET', signal: options?.signal },\n );\n return res.entries;\n }\n\n // ─── Stream (streaming completion via OpenAI SSE) ────────────────────────\n\n async *stream(\n documentId: string,\n query: string,\n options?: CompletionOptions,\n ): AsyncGenerator<CompletionEvent> {\n const response = await this.rawRequest(\n `/document/${encodeURIComponent(documentId)}/chat/completions`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n messages: [{ role: 'user', content: query }],\n stream: options?.stream !== false,\n ...(options?.model ? { model: options.model } : {}),\n }),\n signal: options?.signal,\n },\n );\n\n if (!response.ok) {\n const text = await response.text();\n throw new OkraRuntimeError('HTTP_ERROR', `Completion failed: ${text}`, response.status);\n }\n\n if (!response.body) {\n throw new OkraRuntimeError('INVALID_RESPONSE', 'No response body for completion stream', 500);\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n let fullText = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed === 'data: [DONE]') continue;\n if (!trimmed.startsWith('data: ')) continue;\n const json = trimmed.slice(6);\n try {\n const chunk = JSON.parse(json) as {\n choices?: Array<{ delta?: { content?: string }; finish_reason?: string | null }>;\n usage?: { prompt_tokens?: number; completion_tokens?: number; total_tokens?: number };\n error?: { message?: string };\n };\n\n if (chunk.error) {\n yield { type: 'error', message: chunk.error.message || 'Stream error' };\n continue;\n }\n\n const delta = chunk.choices?.[0]?.delta?.content;\n if (delta) {\n fullText += delta;\n yield { type: 'text_delta', text: delta };\n }\n\n if (chunk.choices?.[0]?.finish_reason === 'stop') {\n yield { type: 'done', answer: fullText };\n }\n } catch {\n // skip malformed lines\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n // ─── Generate (non-streaming AI) ─────────────────────────────────────────\n\n async generate(\n documentId: string,\n query: string,\n options?: GenerateOptions & { schema?: undefined },\n ): Promise<GenerateResult>;\n async generate<T>(\n documentId: string,\n query: string,\n options: GenerateOptions & { schema: StructuredSchema<T> },\n ): Promise<GenerateResult<T>>;\n async generate<T = undefined>(\n documentId: string,\n query: string,\n options?: GenerateOptions,\n ): Promise<GenerateResult<T>> {\n if (options?.schema) {\n return this.generateStructured<T>(documentId, query, options);\n }\n\n const result = await this.requestJson<{\n id: string;\n choices: Array<{ message: { content: string } }>;\n usage?: { prompt_tokens?: number; completion_tokens?: number; total_tokens?: number };\n }>(`/document/${encodeURIComponent(documentId)}/chat/completions`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n messages: [{ role: 'user', content: query }],\n ...(options?.model ? { model: options.model } : {}),\n }),\n signal: options?.signal,\n });\n\n return {\n answer: result.choices?.[0]?.message?.content || '',\n };\n }\n\n private async generateStructured<T>(\n documentId: string,\n query: string,\n options: GenerateOptions,\n ): Promise<GenerateResult<T>> {\n if (!query || query.trim() === '') {\n throw new OkraRuntimeError(\n 'INVALID_REQUEST',\n 'generate with schema requires a non-empty query',\n 400,\n );\n }\n\n const normalized = normalizeSchema(options.schema as StructuredSchema<T>);\n const path = `/document/${encodeURIComponent(documentId)}/chat/completions`;\n const init: RequestInit = {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n messages: [{ role: 'user', content: query }],\n response_format: {\n type: 'json_schema',\n json_schema: { name: 'result', schema: normalized.jsonSchema },\n },\n ...(options.model ? { model: options.model } : {}),\n }),\n signal: options.signal,\n };\n\n let result: {\n id: string;\n choices: Array<{ message: { content: string } }>;\n usage?: { prompt_tokens?: number; completion_tokens?: number; total_tokens?: number };\n };\n\n const maxAttempts = 3;\n let attempt = 0;\n while (true) {\n attempt += 1;\n try {\n result = await this.requestJson(path, init);\n break;\n } catch (error) {\n const isRetriableTimeout =\n error instanceof OkraRuntimeError &&\n error.status === 504 &&\n ((typeof error.details === 'object' &&\n error.details !== null &&\n 'timeoutMs' in error.details) ||\n error.message.toLowerCase().includes('timed out'));\n\n if (!isRetriableTimeout || attempt >= maxAttempts) {\n throw error;\n }\n\n await new Promise((resolve) => setTimeout(resolve, 350 * attempt));\n }\n }\n\n const raw = result.choices?.[0]?.message?.content;\n if (!raw) {\n throw new OkraRuntimeError(\n 'INVALID_RESPONSE',\n 'No content in structured output response',\n 500,\n );\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n throw new OkraRuntimeError(\n 'INVALID_RESPONSE',\n 'Structured output response is not valid JSON',\n 500,\n );\n }\n\n let data: T;\n if (normalized.parser) {\n const zodResult = normalized.parser.safeParse(parsed);\n if (!zodResult.success) {\n throw new StructuredOutputError(\n 'SCHEMA_VALIDATION_FAILED',\n 'Client-side schema validation failed for structured output response',\n 422,\n zodResult.error.issues,\n );\n }\n data = zodResult.data;\n } else {\n data = parsed as T;\n }\n\n return {\n answer: '',\n data,\n };\n }\n\n // ─── List Documents ─────────────────────────────────────────────────────\n\n async listDocuments(signal?: AbortSignal): Promise<DocumentListItem[]> {\n const res = await this.requestJson<DocumentListResponse>('/v1/documents', {\n method: 'GET',\n signal,\n });\n return res.documents;\n }\n\n // ─── Delete Document ──────────────────────────────────────────────────\n\n async deleteDocument(documentId: string, signal?: AbortSignal): Promise<DeleteDocumentResult> {\n if (!documentId.trim()) {\n throw new OkraRuntimeError(\n 'INVALID_REQUEST',\n 'deleteDocument requires a non-empty documentId',\n 400,\n );\n }\n await this.requestJson<{ ok: boolean }>(`/document/${encodeURIComponent(documentId)}`, {\n method: 'DELETE',\n signal,\n });\n return { deleted: true, documentId };\n }\n\n // ─── Read Document (full markdown) ────────────────────────────────────\n\n async read(documentId: string, options?: ReadDocumentOptions): Promise<ReadDocumentResult> {\n if (!documentId.trim()) {\n throw new OkraRuntimeError('INVALID_REQUEST', 'read requires a non-empty documentId', 400);\n }\n const params = options?.pages ? `?pages=${encodeURIComponent(options.pages)}` : '';\n const response = await this.rawRequest(\n `/document/${encodeURIComponent(documentId)}/full.md${params}`,\n { method: 'GET', signal: options?.signal },\n );\n if (!response.ok) {\n const text = await response.text();\n throw new OkraRuntimeError('HTTP_ERROR', `Read failed: ${text}`, response.status);\n }\n const markdown = await response.text();\n return { documentId, markdown };\n }\n\n // ─── Model Endpoint ──────────────────────────────────────────────────────\n\n modelEndpoint(documentId: string): string {\n return `${this.baseUrl}/document/${encodeURIComponent(documentId)}`;\n }\n\n // ─── Publish / Share ────────────────────────────────────────────────────\n\n async publish(documentId: string, signal?: AbortSignal): Promise<PublishResult> {\n const result = await this.requestJson<Omit<PublishResult, 'url'>>(\n `/document/${encodeURIComponent(documentId)}/publish`,\n { method: 'POST', signal },\n );\n return {\n ...result,\n url: `${this.baseUrl}/document/${encodeURIComponent(documentId)}`,\n };\n }\n\n async shareLink(documentId: string, options?: ShareLinkOptions): Promise<ShareLinkResult> {\n return this.requestJson<ShareLinkResult>(\n `/document/${encodeURIComponent(documentId)}/share-link`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n role: options?.role,\n label: options?.label,\n expiresInMs: options?.expiresInMs,\n maxViews: options?.maxViews,\n }),\n signal: options?.signal,\n },\n );\n }\n\n // ─── Public HTTP ─────────────────────────────────────────────────────────\n\n async request<T>(path: string, init: RequestInit = {}): Promise<T> {\n return this.requestJson<T>(path, init);\n }\n\n get url(): string {\n return this.baseUrl;\n }\n\n // ─── Internal HTTP ───────────────────────────────────────────────────────\n\n private authHeaders(): Record<string, string> {\n if (this.apiKey) return { Authorization: `Bearer ${this.apiKey}` };\n if (this.sharedSecret) return { 'x-document-agent-secret': this.sharedSecret };\n return {};\n }\n\n private async rawRequest(path: string, init: RequestInit): Promise<Response> {\n const headers = new Headers(init.headers);\n for (const [key, value] of Object.entries(this.authHeaders())) {\n if (!headers.has(key)) headers.set(key, value);\n }\n\n try {\n return await this.fetchImpl(`${this.baseUrl}${path}`, { ...init, headers });\n } catch (err) {\n throw new OkraRuntimeError(\n 'HTTP_ERROR',\n err instanceof Error ? err.message : String(err),\n 502,\n );\n }\n }\n\n private async requestJson<T>(path: string, init: RequestInit): Promise<T> {\n const response = await this.rawRequest(path, init);\n const text = await response.text();\n const parsed = this.parseBody(text);\n\n if (!response.ok) {\n const envelope = parsed as StructuredErrorEnvelope | null;\n const nestedError =\n typeof envelope?.error === 'object' && envelope.error !== null ? envelope.error : undefined;\n const code = envelope?.code || nestedError?.code;\n const message =\n getErrorMessage(envelope?.message) ||\n getErrorMessage(typeof envelope?.error === 'string' ? envelope.error : undefined) ||\n getErrorMessage(nestedError?.message) ||\n `Request failed with status ${response.status}`;\n const details = envelope?.details ?? nestedError?.details ?? parsed ?? text;\n if (isStructuredCode(code)) {\n throw new StructuredOutputError(code, message, response.status, details);\n }\n const runtimeCode: RuntimeErrorCode = response.status === 401 ? 'UNAUTHORIZED' : 'HTTP_ERROR';\n throw new OkraRuntimeError(runtimeCode, message, response.status, details);\n }\n\n if (parsed === null) {\n throw new OkraRuntimeError(\n 'INVALID_RESPONSE',\n `Expected JSON response for ${path}`,\n response.status,\n text,\n );\n }\n\n return parsed as T;\n }\n\n private parseBody(text: string): unknown | null {\n const trimmed = text.trim();\n if (!trimmed) return null;\n try {\n return JSON.parse(trimmed);\n } catch {\n return null;\n }\n }\n}\n"],"mappings":"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","names":["session","options"]}
|
package/dist/cli/bin.d.ts
CHANGED
|
@@ -1 +1,40 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* okra CLI — Agent-friendly PDF extraction and collection queries.
|
|
6
|
+
*
|
|
7
|
+
* Global flags:
|
|
8
|
+
* -j, --json Structured JSON output
|
|
9
|
+
* -q, --quiet Suppress progress (just data to stdout)
|
|
10
|
+
* -o, --output Write output to file (CSV/JSON/ZIP)
|
|
11
|
+
*
|
|
12
|
+
* Action commands (agent-grade):
|
|
13
|
+
* okra upload <source> # Upload + wait
|
|
14
|
+
* okra extract <source> --schema schema.json # Upload + structured extract
|
|
15
|
+
* okra extract <docId> --schema schema.json # Extract from existing doc
|
|
16
|
+
* okra list # List documents
|
|
17
|
+
* okra read <id> [--pages 1-5] # Full markdown
|
|
18
|
+
* okra delete <id> # Delete document
|
|
19
|
+
* okra chat "<question>" --doc <id> # Ask a question
|
|
20
|
+
* okra collection list # List collections
|
|
21
|
+
* okra collection query <name> "<question>" # Fan-out → CSV
|
|
22
|
+
* okra collection extract <name> --schema s.json # Experimental structured extract → CSV
|
|
23
|
+
*
|
|
24
|
+
* Review commands:
|
|
25
|
+
* okra tree / find / page / search / tables / history / toc
|
|
26
|
+
*
|
|
27
|
+
* Exit codes: 0=success, 1=client error, 2=server error
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
declare const CLI_VERSION: string;
|
|
31
|
+
declare const PRIMARY_COMMANDS: readonly ["auth", "upload", "extract", "chat", "list", "read", "delete", "collection"];
|
|
32
|
+
declare const ADVANCED_COMMANDS: readonly ["status", "tree", "find", "page", "search", "tables", "history", "toc", "local"];
|
|
33
|
+
declare const PRIMARY_COLLECTION_SUBCOMMANDS: readonly ["list", "query"];
|
|
34
|
+
declare const ADVANCED_COLLECTION_SUBCOMMANDS: readonly ["create", "show", "delete", "add", "remove", "publish", "unpublish", "export"];
|
|
35
|
+
declare const ROOT_HELP_FOOTER: string;
|
|
36
|
+
declare const COLLECTION_HELP_FOOTER: string;
|
|
37
|
+
declare const program: Command;
|
|
38
|
+
declare function getMissingApiKeyMessage(): string;
|
|
39
|
+
|
|
40
|
+
export { ADVANCED_COLLECTION_SUBCOMMANDS, ADVANCED_COMMANDS, CLI_VERSION, COLLECTION_HELP_FOOTER, PRIMARY_COLLECTION_SUBCOMMANDS, PRIMARY_COMMANDS, ROOT_HELP_FOOTER, getMissingApiKeyMessage, program };
|