batchwork 1.2.1 → 1.4.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 +92 -5
- package/dist/batch.d.ts +123 -4
- package/dist/batch.d.ts.map +1 -1
- package/dist/body.d.ts +30 -1
- package/dist/body.d.ts.map +1 -1
- package/dist/{chunk-sw8dg4sm.js → chunk-2ea62n95.js} +367 -7
- package/dist/chunk-2ea62n95.js.map +12 -0
- package/dist/{chunk-c7hzcpdy.js → chunk-ka9d4t6v.js} +2 -2
- package/dist/{chunk-jvrfwjwq.js → chunk-vy4w8mpb.js} +418 -267
- package/dist/{chunk-jvrfwjwq.js.map → chunk-vy4w8mpb.js.map} +10 -9
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/model.d.ts +50 -3
- package/dist/model.d.ts.map +1 -1
- package/dist/next/index.js +3 -3
- package/dist/providers/azure.d.ts +8 -0
- package/dist/providers/azure.d.ts.map +1 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/openai-compatible.d.ts +23 -2
- package/dist/providers/openai-compatible.d.ts.map +1 -1
- package/dist/providers/shared.d.ts +16 -1
- package/dist/providers/shared.d.ts.map +1 -1
- package/dist/providers/together.d.ts.map +1 -1
- package/dist/providers/xai.d.ts.map +1 -1
- package/dist/server/index.js +2 -2
- package/dist/types.d.ts +210 -5
- package/dist/types.d.ts.map +1 -1
- package/package.json +8 -4
- package/dist/chunk-sw8dg4sm.js.map +0 -12
- /package/dist/{chunk-c7hzcpdy.js.map → chunk-ka9d4t6v.js.map} +0 -0
|
@@ -9,7 +9,7 @@ class BatchworkError extends Error {
|
|
|
9
9
|
class UnsupportedProviderError extends BatchworkError {
|
|
10
10
|
provider;
|
|
11
11
|
constructor(provider, detail) {
|
|
12
|
-
super(detail ?? `batchwork: provider "${provider}" is not supported yet. Supported providers: openai, anthropic, google, groq, mistral, together, xai.`);
|
|
12
|
+
super(detail ?? `batchwork: provider "${provider}" is not supported yet. Supported providers: openai, azure, anthropic, google, groq, mistral, together, xai.`);
|
|
13
13
|
this.name = "UnsupportedProviderError";
|
|
14
14
|
this.provider = provider;
|
|
15
15
|
}
|
|
@@ -539,6 +539,366 @@ var anthropicAdapter = {
|
|
|
539
539
|
submit
|
|
540
540
|
};
|
|
541
541
|
|
|
542
|
+
// src/providers/shared.ts
|
|
543
|
+
var HTTP_OK_MIN = 200;
|
|
544
|
+
var HTTP_OK_MAX = 300;
|
|
545
|
+
var resolveApiKey = (credentials, envVar, label) => {
|
|
546
|
+
const key = credentials.apiKey ?? process.env[envVar];
|
|
547
|
+
if (!key) {
|
|
548
|
+
throw new BatchworkError(`batchwork: missing ${label} API key. Set ${envVar} or pass \`apiKey\`.`);
|
|
549
|
+
}
|
|
550
|
+
return key;
|
|
551
|
+
};
|
|
552
|
+
var textFromBody = (body) => {
|
|
553
|
+
const obj = asRecord(body);
|
|
554
|
+
const choices = asArray(obj.choices);
|
|
555
|
+
if (choices.length > 0) {
|
|
556
|
+
const content = asString(asRecord(asRecord(choices[0]).message).content);
|
|
557
|
+
if (content) {
|
|
558
|
+
return content;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
const directText = asString(obj.output_text) ?? asString(obj.text);
|
|
562
|
+
if (directText !== undefined) {
|
|
563
|
+
return directText;
|
|
564
|
+
}
|
|
565
|
+
const parts = [];
|
|
566
|
+
for (const output of asArray(obj.output)) {
|
|
567
|
+
const item = asRecord(output);
|
|
568
|
+
if (item.type !== "message") {
|
|
569
|
+
continue;
|
|
570
|
+
}
|
|
571
|
+
for (const content of asArray(item.content)) {
|
|
572
|
+
const part = asRecord(content);
|
|
573
|
+
if (part.type !== "output_text") {
|
|
574
|
+
continue;
|
|
575
|
+
}
|
|
576
|
+
const text = asString(part.text);
|
|
577
|
+
if (text !== undefined) {
|
|
578
|
+
parts.push(text);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
if (parts.length > 0) {
|
|
583
|
+
return parts.join("");
|
|
584
|
+
}
|
|
585
|
+
};
|
|
586
|
+
var segmentsFromBody = (body) => {
|
|
587
|
+
const obj = asRecord(body);
|
|
588
|
+
if (asString(obj.text) === undefined) {
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
591
|
+
const segments = [];
|
|
592
|
+
for (const item of asArray(obj.segments)) {
|
|
593
|
+
const segment = asRecord(item);
|
|
594
|
+
const text = asString(segment.text);
|
|
595
|
+
if (text !== undefined) {
|
|
596
|
+
segments.push({
|
|
597
|
+
endSecond: asNumber(segment.end),
|
|
598
|
+
startSecond: asNumber(segment.start),
|
|
599
|
+
text
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
return segments.length > 0 ? segments : undefined;
|
|
604
|
+
};
|
|
605
|
+
var embeddingFromBody = (body) => {
|
|
606
|
+
const data = asArray(asRecord(body).data);
|
|
607
|
+
if (data.length === 0) {
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
return asNumberArray(asRecord(data[0]).embedding);
|
|
611
|
+
};
|
|
612
|
+
var imagesFromBody = (body) => {
|
|
613
|
+
const obj = asRecord(body);
|
|
614
|
+
const mediaType = `image/${asString(obj.output_format) ?? "png"}`;
|
|
615
|
+
const images = [];
|
|
616
|
+
for (const item of asArray(obj.data)) {
|
|
617
|
+
const b64 = asString(asRecord(item).b64_json);
|
|
618
|
+
if (b64) {
|
|
619
|
+
images.push({ data: b64, mediaType });
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
return images.length > 0 ? images : undefined;
|
|
623
|
+
};
|
|
624
|
+
var moderationFromBody = (body) => {
|
|
625
|
+
const results2 = asArray(asRecord(body).results);
|
|
626
|
+
if (results2.length === 0) {
|
|
627
|
+
return;
|
|
628
|
+
}
|
|
629
|
+
const first = asRecord(results2[0]);
|
|
630
|
+
const categories = {};
|
|
631
|
+
for (const [key, value] of Object.entries(asRecord(first.categories))) {
|
|
632
|
+
if (typeof value === "boolean") {
|
|
633
|
+
categories[key] = value;
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
if (Object.keys(categories).length === 0) {
|
|
637
|
+
return;
|
|
638
|
+
}
|
|
639
|
+
const categoryScores = {};
|
|
640
|
+
for (const [key, value] of Object.entries(asRecord(first.category_scores))) {
|
|
641
|
+
const score = asNumber(value);
|
|
642
|
+
if (score !== undefined) {
|
|
643
|
+
categoryScores[key] = score;
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
const flagged = typeof first.flagged === "boolean" ? first.flagged : Object.values(categories).some(Boolean);
|
|
647
|
+
return { categories, categoryScores, flagged };
|
|
648
|
+
};
|
|
649
|
+
var usageFromBody = (body) => {
|
|
650
|
+
const usage = asRecord(asRecord(body).usage);
|
|
651
|
+
const inputTokens = asNumber(usage.prompt_tokens) ?? asNumber(usage.input_tokens);
|
|
652
|
+
const outputTokens = asNumber(usage.completion_tokens) ?? asNumber(usage.output_tokens);
|
|
653
|
+
const totalTokens = asNumber(usage.total_tokens);
|
|
654
|
+
if (inputTokens === undefined && outputTokens === undefined && totalTokens === undefined) {
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
657
|
+
return {
|
|
658
|
+
inputTokens,
|
|
659
|
+
outputTokens,
|
|
660
|
+
totalTokens: totalTokens ?? (inputTokens ?? 0) + (outputTokens ?? 0)
|
|
661
|
+
};
|
|
662
|
+
};
|
|
663
|
+
var errorFromValue = (value, fallback) => {
|
|
664
|
+
const obj = asRecord(value);
|
|
665
|
+
const nested = asRecord(obj.error);
|
|
666
|
+
const source = nested.message ? nested : obj;
|
|
667
|
+
return {
|
|
668
|
+
code: asNumber(source.code) ?? asString(source.code),
|
|
669
|
+
message: asString(source.message) ?? fallback,
|
|
670
|
+
type: asString(source.type)
|
|
671
|
+
};
|
|
672
|
+
};
|
|
673
|
+
var normalizeOpenAIResult = (line) => {
|
|
674
|
+
const obj = asRecord(line);
|
|
675
|
+
const customId = asString(obj.custom_id) ?? "";
|
|
676
|
+
if (obj.error) {
|
|
677
|
+
return {
|
|
678
|
+
customId,
|
|
679
|
+
error: errorFromValue(obj.error, "Request errored."),
|
|
680
|
+
response: obj.error,
|
|
681
|
+
status: "errored"
|
|
682
|
+
};
|
|
683
|
+
}
|
|
684
|
+
const response = asRecord(obj.response);
|
|
685
|
+
const statusCode = asNumber(response.status_code) ?? 0;
|
|
686
|
+
if (statusCode >= HTTP_OK_MIN && statusCode < HTTP_OK_MAX) {
|
|
687
|
+
return {
|
|
688
|
+
customId,
|
|
689
|
+
embedding: embeddingFromBody(response.body),
|
|
690
|
+
images: imagesFromBody(response.body),
|
|
691
|
+
moderation: moderationFromBody(response.body),
|
|
692
|
+
response: response.body,
|
|
693
|
+
segments: segmentsFromBody(response.body),
|
|
694
|
+
status: "succeeded",
|
|
695
|
+
text: textFromBody(response.body),
|
|
696
|
+
usage: usageFromBody(response.body)
|
|
697
|
+
};
|
|
698
|
+
}
|
|
699
|
+
return {
|
|
700
|
+
customId,
|
|
701
|
+
error: errorFromValue(response.body, `Request failed with status ${statusCode}.`),
|
|
702
|
+
response: response.body,
|
|
703
|
+
status: "errored"
|
|
704
|
+
};
|
|
705
|
+
};
|
|
706
|
+
var uploadInputFile = async (jsonl, baseUrl2, headers2, options = {}) => {
|
|
707
|
+
const form = new FormData;
|
|
708
|
+
const purpose = options.purpose === undefined ? "batch" : options.purpose;
|
|
709
|
+
if (purpose !== null) {
|
|
710
|
+
form.append("purpose", purpose);
|
|
711
|
+
}
|
|
712
|
+
form.append("file", new Blob([jsonl], { type: "application/jsonl" }), "batchwork.jsonl");
|
|
713
|
+
const raw = await requestJson(`${baseUrl2}/files`, {
|
|
714
|
+
body: form,
|
|
715
|
+
headers: headers2,
|
|
716
|
+
method: "POST",
|
|
717
|
+
redirect: "manual"
|
|
718
|
+
});
|
|
719
|
+
return raw.id;
|
|
720
|
+
};
|
|
721
|
+
async function* streamResultFile(fileId, baseUrl2, headers2) {
|
|
722
|
+
const stream = await requestStream(`${baseUrl2}/files/${fileId}/content`, {
|
|
723
|
+
headers: headers2,
|
|
724
|
+
redirect: "manual"
|
|
725
|
+
});
|
|
726
|
+
for await (const line of streamJsonl(stream)) {
|
|
727
|
+
yield normalizeOpenAIResult(line);
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
// src/providers/openai-compatible.ts
|
|
732
|
+
var DEFAULT_COMPLETION_WINDOW = "24h";
|
|
733
|
+
var mapStatus2 = (status) => {
|
|
734
|
+
const normalized = status?.toLowerCase();
|
|
735
|
+
switch (normalized) {
|
|
736
|
+
case "validating":
|
|
737
|
+
case "in_progress":
|
|
738
|
+
case "finalizing":
|
|
739
|
+
case "completed":
|
|
740
|
+
case "failed":
|
|
741
|
+
case "expired":
|
|
742
|
+
case "cancelling":
|
|
743
|
+
case "cancelled": {
|
|
744
|
+
return normalized;
|
|
745
|
+
}
|
|
746
|
+
default: {
|
|
747
|
+
return "in_progress";
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
};
|
|
751
|
+
var normalizeSnapshot2 = (raw, provider) => {
|
|
752
|
+
const outer = asRecord(raw);
|
|
753
|
+
const obj = asRecord(outer.job);
|
|
754
|
+
const source = Object.keys(obj).length > 0 ? obj : outer;
|
|
755
|
+
const counts = asRecord(source.request_counts);
|
|
756
|
+
return {
|
|
757
|
+
completedAt: toDate(source.completed_at),
|
|
758
|
+
createdAt: toDate(source.created_at),
|
|
759
|
+
expiresAt: toDate(source.expires_at),
|
|
760
|
+
id: asString(source.id) ?? "",
|
|
761
|
+
provider,
|
|
762
|
+
raw: source,
|
|
763
|
+
requestCounts: {
|
|
764
|
+
completed: asNumber(counts.completed) ?? 0,
|
|
765
|
+
failed: asNumber(counts.failed) ?? 0,
|
|
766
|
+
total: asNumber(counts.total) ?? 0
|
|
767
|
+
},
|
|
768
|
+
status: mapStatus2(asString(source.status))
|
|
769
|
+
};
|
|
770
|
+
};
|
|
771
|
+
var createOpenAICompatibleAdapter = (config) => {
|
|
772
|
+
const completionWindow = config.completionWindow ?? DEFAULT_COMPLETION_WINDOW;
|
|
773
|
+
const lineFormat = config.lineFormat ?? "method-url";
|
|
774
|
+
const baseUrl2 = (credentials) => config.resolveBaseUrl?.(credentials) ?? credentials.baseURL ?? config.baseUrl ?? (() => {
|
|
775
|
+
throw new BatchworkError(`batchwork: missing ${config.apiKeyLabel} base URL. Pass \`baseURL\`.`);
|
|
776
|
+
})();
|
|
777
|
+
const authHeaders = (credentials) => ({
|
|
778
|
+
...config.authHeaders ? config.authHeaders(credentials) : {
|
|
779
|
+
Authorization: `Bearer ${resolveApiKey(credentials, config.apiKeyEnv, config.apiKeyLabel)}`
|
|
780
|
+
},
|
|
781
|
+
...credentials.headers
|
|
782
|
+
});
|
|
783
|
+
const submit2 = async (input) => {
|
|
784
|
+
const limits = resolveBatchLimits(input.limits);
|
|
785
|
+
const endpoint = config.normalizeEndpoint ? config.normalizeEndpoint(input.endpoint) : input.endpoint;
|
|
786
|
+
const batchEndpoint = config.batchEndpoint?.(endpoint) ?? endpoint;
|
|
787
|
+
const jsonl = encodeJsonl(input.built.map((item) => {
|
|
788
|
+
const body = omit(item.body, "stream");
|
|
789
|
+
if (lineFormat === "body-only") {
|
|
790
|
+
return {
|
|
791
|
+
body,
|
|
792
|
+
custom_id: item.customId,
|
|
793
|
+
...config.lineExtras?.(endpoint)
|
|
794
|
+
};
|
|
795
|
+
}
|
|
796
|
+
return {
|
|
797
|
+
body,
|
|
798
|
+
custom_id: item.customId,
|
|
799
|
+
method: "POST",
|
|
800
|
+
url: endpoint
|
|
801
|
+
};
|
|
802
|
+
}), { label: "batch upload JSONL", maxBytes: limits.maxUploadBytes });
|
|
803
|
+
const headers2 = authHeaders(input.credentials);
|
|
804
|
+
const url = baseUrl2(input.credentials);
|
|
805
|
+
const purpose = config.filePurpose ?? "batch";
|
|
806
|
+
const inputFileId = await (config.uploadFile ? config.uploadFile({ baseUrl: url, headers: headers2, jsonl, purpose }) : uploadInputFile(jsonl, url, headers2, { purpose }));
|
|
807
|
+
const raw = await requestJson(`${url}/batches`, {
|
|
808
|
+
body: JSON.stringify({
|
|
809
|
+
completion_window: completionWindow,
|
|
810
|
+
endpoint: batchEndpoint,
|
|
811
|
+
input_file_id: inputFileId,
|
|
812
|
+
metadata: input.metadata
|
|
813
|
+
}),
|
|
814
|
+
headers: { ...headers2, "content-type": "application/json" },
|
|
815
|
+
method: "POST"
|
|
816
|
+
});
|
|
817
|
+
return normalizeSnapshot2(raw, config.id);
|
|
818
|
+
};
|
|
819
|
+
const retrieve2 = async (id, credentials) => {
|
|
820
|
+
const batchId = assertSimpleProviderId(`${config.id} batch id`, id);
|
|
821
|
+
const raw = await requestJson(`${baseUrl2(credentials)}/batches/${batchId}`, {
|
|
822
|
+
headers: authHeaders(credentials)
|
|
823
|
+
});
|
|
824
|
+
return normalizeSnapshot2(raw, config.id);
|
|
825
|
+
};
|
|
826
|
+
async function* results2(id, credentials) {
|
|
827
|
+
const snapshot = await retrieve2(id, credentials);
|
|
828
|
+
const raw = asRecord(snapshot.raw);
|
|
829
|
+
const outputFileId = asString(raw.output_file_id);
|
|
830
|
+
const errorFileId = asString(raw.error_file_id);
|
|
831
|
+
if (!(outputFileId || errorFileId)) {
|
|
832
|
+
throw new BatchworkError(`batchwork: results are not ready for batch "${id}" (status: ${snapshot.status}).`);
|
|
833
|
+
}
|
|
834
|
+
const headers2 = authHeaders(credentials);
|
|
835
|
+
if (outputFileId) {
|
|
836
|
+
yield* streamResultFile(assertSimpleProviderId(`${config.id} output file id`, outputFileId), baseUrl2(credentials), headers2);
|
|
837
|
+
}
|
|
838
|
+
if (errorFileId) {
|
|
839
|
+
yield* streamResultFile(assertSimpleProviderId(`${config.id} error file id`, errorFileId), baseUrl2(credentials), headers2);
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
const cancel2 = async (id, credentials) => {
|
|
843
|
+
const batchId = assertSimpleProviderId(`${config.id} batch id`, id);
|
|
844
|
+
await requestJson(`${baseUrl2(credentials)}/batches/${batchId}/cancel`, {
|
|
845
|
+
headers: authHeaders(credentials),
|
|
846
|
+
method: "POST"
|
|
847
|
+
});
|
|
848
|
+
};
|
|
849
|
+
return { cancel: cancel2, id: config.id, results: results2, retrieve: retrieve2, submit: submit2 };
|
|
850
|
+
};
|
|
851
|
+
|
|
852
|
+
// src/providers/azure.ts
|
|
853
|
+
var withoutTrailingSlash = (value) => value.replace(/\/+$/u, "");
|
|
854
|
+
var isAzureOpenAIUrl = (value) => {
|
|
855
|
+
try {
|
|
856
|
+
return new URL(value).hostname.endsWith(".openai.azure.com");
|
|
857
|
+
} catch {
|
|
858
|
+
return false;
|
|
859
|
+
}
|
|
860
|
+
};
|
|
861
|
+
var baseUrl2 = (credentials) => {
|
|
862
|
+
const configured = credentials.baseURL ?? (process.env.AZURE_RESOURCE_NAME ? `https://${process.env.AZURE_RESOURCE_NAME}.openai.azure.com/openai` : undefined);
|
|
863
|
+
if (!configured) {
|
|
864
|
+
throw new BatchworkError("batchwork: missing Azure OpenAI resource. Set AZURE_RESOURCE_NAME or pass `baseURL`.");
|
|
865
|
+
}
|
|
866
|
+
const normalized = withoutTrailingSlash(configured);
|
|
867
|
+
if (!isAzureOpenAIUrl(normalized)) {
|
|
868
|
+
return normalized;
|
|
869
|
+
}
|
|
870
|
+
if (normalized.endsWith("/v1")) {
|
|
871
|
+
return normalized;
|
|
872
|
+
}
|
|
873
|
+
return normalized.endsWith("/openai") ? `${normalized}/v1` : `${normalized}/openai/v1`;
|
|
874
|
+
};
|
|
875
|
+
var hasCallerAuth = (headers2) => Object.keys(headers2 ?? {}).some((name) => {
|
|
876
|
+
const normalized = name.toLowerCase();
|
|
877
|
+
return normalized === "api-key" || normalized === "authorization";
|
|
878
|
+
});
|
|
879
|
+
var authHeaders = (credentials) => {
|
|
880
|
+
if (credentials.apiKey) {
|
|
881
|
+
return { "api-key": credentials.apiKey };
|
|
882
|
+
}
|
|
883
|
+
if (hasCallerAuth(credentials.headers)) {
|
|
884
|
+
return {};
|
|
885
|
+
}
|
|
886
|
+
const apiKey2 = process.env.AZURE_API_KEY ?? process.env.AZURE_OPENAI_API_KEY;
|
|
887
|
+
if (apiKey2) {
|
|
888
|
+
return { "api-key": apiKey2 };
|
|
889
|
+
}
|
|
890
|
+
throw new BatchworkError("batchwork: missing Azure OpenAI API key. Set AZURE_API_KEY or pass `apiKey`.");
|
|
891
|
+
};
|
|
892
|
+
var azureAdapter = createOpenAICompatibleAdapter({
|
|
893
|
+
apiKeyEnv: "AZURE_API_KEY",
|
|
894
|
+
apiKeyLabel: "Azure OpenAI",
|
|
895
|
+
authHeaders,
|
|
896
|
+
batchEndpoint: () => "/v1/chat/completions",
|
|
897
|
+
id: "azure",
|
|
898
|
+
normalizeEndpoint: (endpoint) => endpoint.replace(/^\/openai/u, ""),
|
|
899
|
+
resolveBaseUrl: baseUrl2
|
|
900
|
+
});
|
|
901
|
+
|
|
542
902
|
// src/providers/google.ts
|
|
543
903
|
var GOOGLE_BASE = "https://generativelanguage.googleapis.com/v1beta";
|
|
544
904
|
var OPERATION_ID_LABEL = "Google operation id";
|
|
@@ -550,7 +910,7 @@ var apiKey2 = (credentials) => {
|
|
|
550
910
|
}
|
|
551
911
|
return key;
|
|
552
912
|
};
|
|
553
|
-
var
|
|
913
|
+
var baseUrl3 = (credentials) => credentials.baseURL ?? GOOGLE_BASE;
|
|
554
914
|
var headers2 = (credentials) => ({
|
|
555
915
|
"content-type": "application/json",
|
|
556
916
|
"x-goog-api-key": apiKey2(credentials),
|
|
@@ -596,7 +956,7 @@ var inlinedResponses = (raw) => {
|
|
|
596
956
|
...asArray(nestedDestInline.inlined_responses)
|
|
597
957
|
];
|
|
598
958
|
};
|
|
599
|
-
var
|
|
959
|
+
var normalizeSnapshot3 = (raw) => {
|
|
600
960
|
const obj = asRecord(raw);
|
|
601
961
|
const items = inlinedResponses(raw);
|
|
602
962
|
const failed = items.filter((item) => asRecord(item).error).length;
|
|
@@ -711,19 +1071,19 @@ var submit2 = async (input) => {
|
|
|
711
1071
|
prefix: '{"batch":{"display_name":"batchwork","input_config":{"requests":{"requests":[',
|
|
712
1072
|
suffix: "]}}}}"
|
|
713
1073
|
});
|
|
714
|
-
const raw = await requestJson(`${
|
|
1074
|
+
const raw = await requestJson(`${baseUrl3(input.credentials)}/models/${input.modelId}:${method}`, {
|
|
715
1075
|
body,
|
|
716
1076
|
headers: headers2(input.credentials),
|
|
717
1077
|
method: "POST"
|
|
718
1078
|
});
|
|
719
|
-
return
|
|
1079
|
+
return normalizeSnapshot3(raw);
|
|
720
1080
|
};
|
|
721
1081
|
var retrieve2 = async (id, credentials) => {
|
|
722
1082
|
const operationId = assertPrefixedProviderId(OPERATION_ID_LABEL, id, GOOGLE_BATCH_PREFIX);
|
|
723
|
-
const raw = await requestJson(`${
|
|
1083
|
+
const raw = await requestJson(`${baseUrl3(credentials)}/${operationId}`, {
|
|
724
1084
|
headers: headers2(credentials)
|
|
725
1085
|
});
|
|
726
|
-
return
|
|
1086
|
+
return normalizeSnapshot3(raw);
|
|
727
1087
|
};
|
|
728
1088
|
var fileNameFrom = (value) => asString(asRecord(value).name) ?? asString(value);
|
|
729
1089
|
async function* results2(id, credentials) {
|
|
@@ -745,7 +1105,7 @@ async function* results2(id, credentials) {
|
|
|
745
1105
|
}
|
|
746
1106
|
var cancel2 = async (id, credentials) => {
|
|
747
1107
|
const operationId = assertPrefixedProviderId(OPERATION_ID_LABEL, id, GOOGLE_BATCH_PREFIX);
|
|
748
|
-
await requestJson(`${
|
|
1108
|
+
await requestJson(`${baseUrl3(credentials)}/${operationId}:cancel`, {
|
|
749
1109
|
headers: headers2(credentials),
|
|
750
1110
|
method: "POST"
|
|
751
1111
|
});
|
|
@@ -758,238 +1118,6 @@ var googleAdapter = {
|
|
|
758
1118
|
submit: submit2
|
|
759
1119
|
};
|
|
760
1120
|
|
|
761
|
-
// src/providers/shared.ts
|
|
762
|
-
var HTTP_OK_MIN = 200;
|
|
763
|
-
var HTTP_OK_MAX = 300;
|
|
764
|
-
var resolveApiKey = (credentials, envVar, label) => {
|
|
765
|
-
const key = credentials.apiKey ?? process.env[envVar];
|
|
766
|
-
if (!key) {
|
|
767
|
-
throw new BatchworkError(`batchwork: missing ${label} API key. Set ${envVar} or pass \`apiKey\`.`);
|
|
768
|
-
}
|
|
769
|
-
return key;
|
|
770
|
-
};
|
|
771
|
-
var textFromBody = (body) => {
|
|
772
|
-
const obj = asRecord(body);
|
|
773
|
-
const choices = asArray(obj.choices);
|
|
774
|
-
if (choices.length > 0) {
|
|
775
|
-
const content = asString(asRecord(asRecord(choices[0]).message).content);
|
|
776
|
-
if (content) {
|
|
777
|
-
return content;
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
return asString(obj.output_text);
|
|
781
|
-
};
|
|
782
|
-
var embeddingFromBody = (body) => {
|
|
783
|
-
const data = asArray(asRecord(body).data);
|
|
784
|
-
if (data.length === 0) {
|
|
785
|
-
return;
|
|
786
|
-
}
|
|
787
|
-
return asNumberArray(asRecord(data[0]).embedding);
|
|
788
|
-
};
|
|
789
|
-
var imagesFromBody = (body) => {
|
|
790
|
-
const obj = asRecord(body);
|
|
791
|
-
const mediaType = `image/${asString(obj.output_format) ?? "png"}`;
|
|
792
|
-
const images = [];
|
|
793
|
-
for (const item of asArray(obj.data)) {
|
|
794
|
-
const b64 = asString(asRecord(item).b64_json);
|
|
795
|
-
if (b64) {
|
|
796
|
-
images.push({ data: b64, mediaType });
|
|
797
|
-
}
|
|
798
|
-
}
|
|
799
|
-
return images.length > 0 ? images : undefined;
|
|
800
|
-
};
|
|
801
|
-
var usageFromBody = (body) => {
|
|
802
|
-
const usage = asRecord(asRecord(body).usage);
|
|
803
|
-
const inputTokens = asNumber(usage.prompt_tokens) ?? asNumber(usage.input_tokens);
|
|
804
|
-
const outputTokens = asNumber(usage.completion_tokens) ?? asNumber(usage.output_tokens);
|
|
805
|
-
const totalTokens = asNumber(usage.total_tokens);
|
|
806
|
-
if (inputTokens === undefined && outputTokens === undefined && totalTokens === undefined) {
|
|
807
|
-
return;
|
|
808
|
-
}
|
|
809
|
-
return {
|
|
810
|
-
inputTokens,
|
|
811
|
-
outputTokens,
|
|
812
|
-
totalTokens: totalTokens ?? (inputTokens ?? 0) + (outputTokens ?? 0)
|
|
813
|
-
};
|
|
814
|
-
};
|
|
815
|
-
var errorFromValue = (value, fallback) => {
|
|
816
|
-
const obj = asRecord(value);
|
|
817
|
-
const nested = asRecord(obj.error);
|
|
818
|
-
const source = nested.message ? nested : obj;
|
|
819
|
-
return {
|
|
820
|
-
code: asNumber(source.code) ?? asString(source.code),
|
|
821
|
-
message: asString(source.message) ?? fallback,
|
|
822
|
-
type: asString(source.type)
|
|
823
|
-
};
|
|
824
|
-
};
|
|
825
|
-
var normalizeOpenAIResult = (line) => {
|
|
826
|
-
const obj = asRecord(line);
|
|
827
|
-
const customId = asString(obj.custom_id) ?? "";
|
|
828
|
-
if (obj.error) {
|
|
829
|
-
return {
|
|
830
|
-
customId,
|
|
831
|
-
error: errorFromValue(obj.error, "Request errored."),
|
|
832
|
-
response: obj.error,
|
|
833
|
-
status: "errored"
|
|
834
|
-
};
|
|
835
|
-
}
|
|
836
|
-
const response = asRecord(obj.response);
|
|
837
|
-
const statusCode = asNumber(response.status_code) ?? 0;
|
|
838
|
-
if (statusCode >= HTTP_OK_MIN && statusCode < HTTP_OK_MAX) {
|
|
839
|
-
return {
|
|
840
|
-
customId,
|
|
841
|
-
embedding: embeddingFromBody(response.body),
|
|
842
|
-
images: imagesFromBody(response.body),
|
|
843
|
-
response: response.body,
|
|
844
|
-
status: "succeeded",
|
|
845
|
-
text: textFromBody(response.body),
|
|
846
|
-
usage: usageFromBody(response.body)
|
|
847
|
-
};
|
|
848
|
-
}
|
|
849
|
-
return {
|
|
850
|
-
customId,
|
|
851
|
-
error: errorFromValue(response.body, `Request failed with status ${statusCode}.`),
|
|
852
|
-
response: response.body,
|
|
853
|
-
status: "errored"
|
|
854
|
-
};
|
|
855
|
-
};
|
|
856
|
-
var uploadInputFile = async (jsonl, baseUrl3, headers3, options = {}) => {
|
|
857
|
-
const form = new FormData;
|
|
858
|
-
const purpose = options.purpose === undefined ? "batch" : options.purpose;
|
|
859
|
-
if (purpose !== null) {
|
|
860
|
-
form.append("purpose", purpose);
|
|
861
|
-
}
|
|
862
|
-
form.append("file", new Blob([jsonl], { type: "application/jsonl" }), "batchwork.jsonl");
|
|
863
|
-
const raw = await requestJson(`${baseUrl3}/files`, {
|
|
864
|
-
body: form,
|
|
865
|
-
headers: headers3,
|
|
866
|
-
method: "POST",
|
|
867
|
-
redirect: "manual"
|
|
868
|
-
});
|
|
869
|
-
return raw.id;
|
|
870
|
-
};
|
|
871
|
-
async function* streamResultFile(fileId, baseUrl3, headers3) {
|
|
872
|
-
const stream = await requestStream(`${baseUrl3}/files/${fileId}/content`, {
|
|
873
|
-
headers: headers3,
|
|
874
|
-
redirect: "manual"
|
|
875
|
-
});
|
|
876
|
-
for await (const line of streamJsonl(stream)) {
|
|
877
|
-
yield normalizeOpenAIResult(line);
|
|
878
|
-
}
|
|
879
|
-
}
|
|
880
|
-
|
|
881
|
-
// src/providers/openai-compatible.ts
|
|
882
|
-
var DEFAULT_COMPLETION_WINDOW = "24h";
|
|
883
|
-
var mapStatus2 = (status) => {
|
|
884
|
-
const normalized = status?.toLowerCase();
|
|
885
|
-
switch (normalized) {
|
|
886
|
-
case "validating":
|
|
887
|
-
case "in_progress":
|
|
888
|
-
case "finalizing":
|
|
889
|
-
case "completed":
|
|
890
|
-
case "failed":
|
|
891
|
-
case "expired":
|
|
892
|
-
case "cancelling":
|
|
893
|
-
case "cancelled": {
|
|
894
|
-
return normalized;
|
|
895
|
-
}
|
|
896
|
-
default: {
|
|
897
|
-
return "in_progress";
|
|
898
|
-
}
|
|
899
|
-
}
|
|
900
|
-
};
|
|
901
|
-
var normalizeSnapshot3 = (raw, provider) => {
|
|
902
|
-
const outer = asRecord(raw);
|
|
903
|
-
const obj = asRecord(outer.job);
|
|
904
|
-
const source = Object.keys(obj).length > 0 ? obj : outer;
|
|
905
|
-
const counts = asRecord(source.request_counts);
|
|
906
|
-
return {
|
|
907
|
-
completedAt: toDate(source.completed_at),
|
|
908
|
-
createdAt: toDate(source.created_at),
|
|
909
|
-
expiresAt: toDate(source.expires_at),
|
|
910
|
-
id: asString(source.id) ?? "",
|
|
911
|
-
provider,
|
|
912
|
-
raw: source,
|
|
913
|
-
requestCounts: {
|
|
914
|
-
completed: asNumber(counts.completed) ?? 0,
|
|
915
|
-
failed: asNumber(counts.failed) ?? 0,
|
|
916
|
-
total: asNumber(counts.total) ?? 0
|
|
917
|
-
},
|
|
918
|
-
status: mapStatus2(asString(source.status))
|
|
919
|
-
};
|
|
920
|
-
};
|
|
921
|
-
var createOpenAICompatibleAdapter = (config) => {
|
|
922
|
-
const completionWindow = config.completionWindow ?? DEFAULT_COMPLETION_WINDOW;
|
|
923
|
-
const lineFormat = config.lineFormat ?? "method-url";
|
|
924
|
-
const baseUrl3 = (credentials) => credentials.baseURL ?? config.baseUrl;
|
|
925
|
-
const authHeaders = (credentials) => ({
|
|
926
|
-
Authorization: `Bearer ${resolveApiKey(credentials, config.apiKeyEnv, config.apiKeyLabel)}`,
|
|
927
|
-
...credentials.headers
|
|
928
|
-
});
|
|
929
|
-
const submit3 = async (input) => {
|
|
930
|
-
const limits = resolveBatchLimits(input.limits);
|
|
931
|
-
const endpoint = config.normalizeEndpoint ? config.normalizeEndpoint(input.endpoint) : input.endpoint;
|
|
932
|
-
const jsonl = encodeJsonl(input.built.map((item) => {
|
|
933
|
-
const body = omit(item.body, "stream");
|
|
934
|
-
if (lineFormat === "body-only") {
|
|
935
|
-
return { body, custom_id: item.customId };
|
|
936
|
-
}
|
|
937
|
-
return {
|
|
938
|
-
body,
|
|
939
|
-
custom_id: item.customId,
|
|
940
|
-
method: "POST",
|
|
941
|
-
url: endpoint
|
|
942
|
-
};
|
|
943
|
-
}), { label: "batch upload JSONL", maxBytes: limits.maxUploadBytes });
|
|
944
|
-
const headers3 = authHeaders(input.credentials);
|
|
945
|
-
const url = baseUrl3(input.credentials);
|
|
946
|
-
const purpose = config.filePurpose ?? "batch";
|
|
947
|
-
const inputFileId = await (config.uploadFile ? config.uploadFile({ baseUrl: url, headers: headers3, jsonl, purpose }) : uploadInputFile(jsonl, url, headers3, { purpose }));
|
|
948
|
-
const raw = await requestJson(`${url}/batches`, {
|
|
949
|
-
body: JSON.stringify({
|
|
950
|
-
completion_window: completionWindow,
|
|
951
|
-
endpoint,
|
|
952
|
-
input_file_id: inputFileId,
|
|
953
|
-
metadata: input.metadata
|
|
954
|
-
}),
|
|
955
|
-
headers: { ...headers3, "content-type": "application/json" },
|
|
956
|
-
method: "POST"
|
|
957
|
-
});
|
|
958
|
-
return normalizeSnapshot3(raw, config.id);
|
|
959
|
-
};
|
|
960
|
-
const retrieve3 = async (id, credentials) => {
|
|
961
|
-
const batchId = assertSimpleProviderId(`${config.id} batch id`, id);
|
|
962
|
-
const raw = await requestJson(`${baseUrl3(credentials)}/batches/${batchId}`, {
|
|
963
|
-
headers: authHeaders(credentials)
|
|
964
|
-
});
|
|
965
|
-
return normalizeSnapshot3(raw, config.id);
|
|
966
|
-
};
|
|
967
|
-
async function* results3(id, credentials) {
|
|
968
|
-
const snapshot = await retrieve3(id, credentials);
|
|
969
|
-
const raw = asRecord(snapshot.raw);
|
|
970
|
-
const outputFileId = asString(raw.output_file_id);
|
|
971
|
-
const errorFileId = asString(raw.error_file_id);
|
|
972
|
-
if (!(outputFileId || errorFileId)) {
|
|
973
|
-
throw new BatchworkError(`batchwork: results are not ready for batch "${id}" (status: ${snapshot.status}).`);
|
|
974
|
-
}
|
|
975
|
-
const headers3 = authHeaders(credentials);
|
|
976
|
-
if (outputFileId) {
|
|
977
|
-
yield* streamResultFile(assertSimpleProviderId(`${config.id} output file id`, outputFileId), baseUrl3(credentials), headers3);
|
|
978
|
-
}
|
|
979
|
-
if (errorFileId) {
|
|
980
|
-
yield* streamResultFile(assertSimpleProviderId(`${config.id} error file id`, errorFileId), baseUrl3(credentials), headers3);
|
|
981
|
-
}
|
|
982
|
-
}
|
|
983
|
-
const cancel3 = async (id, credentials) => {
|
|
984
|
-
const batchId = assertSimpleProviderId(`${config.id} batch id`, id);
|
|
985
|
-
await requestJson(`${baseUrl3(credentials)}/batches/${batchId}/cancel`, {
|
|
986
|
-
headers: authHeaders(credentials),
|
|
987
|
-
method: "POST"
|
|
988
|
-
});
|
|
989
|
-
};
|
|
990
|
-
return { cancel: cancel3, id: config.id, results: results3, retrieve: retrieve3, submit: submit3 };
|
|
991
|
-
};
|
|
992
|
-
|
|
993
1121
|
// src/providers/groq.ts
|
|
994
1122
|
var groqAdapter = createOpenAICompatibleAdapter({
|
|
995
1123
|
apiKeyEnv: "GROQ_API_KEY",
|
|
@@ -1004,8 +1132,8 @@ var groqAdapter = createOpenAICompatibleAdapter({
|
|
|
1004
1132
|
var MISTRAL_BASE = "https://api.mistral.ai/v1";
|
|
1005
1133
|
var JOB_ID_LABEL = "Mistral job id";
|
|
1006
1134
|
var apiKey3 = (credentials) => resolveApiKey(credentials, "MISTRAL_API_KEY", "Mistral");
|
|
1007
|
-
var
|
|
1008
|
-
var
|
|
1135
|
+
var baseUrl4 = (credentials) => credentials.baseURL ?? MISTRAL_BASE;
|
|
1136
|
+
var authHeaders2 = (credentials) => ({
|
|
1009
1137
|
Authorization: `Bearer ${apiKey3(credentials)}`,
|
|
1010
1138
|
...credentials.headers
|
|
1011
1139
|
});
|
|
@@ -1059,8 +1187,8 @@ var submit3 = async (input) => {
|
|
|
1059
1187
|
body: omit(omit(item.body, "stream"), "model"),
|
|
1060
1188
|
custom_id: item.customId
|
|
1061
1189
|
})), { label: "batch upload JSONL", maxBytes: limits.maxUploadBytes });
|
|
1062
|
-
const inputFileId = await uploadInputFile(jsonl,
|
|
1063
|
-
const raw = await requestJson(`${
|
|
1190
|
+
const inputFileId = await uploadInputFile(jsonl, baseUrl4(input.credentials), authHeaders2(input.credentials));
|
|
1191
|
+
const raw = await requestJson(`${baseUrl4(input.credentials)}/batch/jobs`, {
|
|
1064
1192
|
body: JSON.stringify({
|
|
1065
1193
|
endpoint: input.endpoint,
|
|
1066
1194
|
input_files: [inputFileId],
|
|
@@ -1068,7 +1196,7 @@ var submit3 = async (input) => {
|
|
|
1068
1196
|
model: input.modelId
|
|
1069
1197
|
}),
|
|
1070
1198
|
headers: {
|
|
1071
|
-
...
|
|
1199
|
+
...authHeaders2(input.credentials),
|
|
1072
1200
|
"content-type": "application/json"
|
|
1073
1201
|
},
|
|
1074
1202
|
method: "POST"
|
|
@@ -1077,8 +1205,8 @@ var submit3 = async (input) => {
|
|
|
1077
1205
|
};
|
|
1078
1206
|
var retrieve3 = async (id, credentials) => {
|
|
1079
1207
|
const jobId = assertSimpleProviderId(JOB_ID_LABEL, id);
|
|
1080
|
-
const raw = await requestJson(`${
|
|
1081
|
-
headers:
|
|
1208
|
+
const raw = await requestJson(`${baseUrl4(credentials)}/batch/jobs/${jobId}`, {
|
|
1209
|
+
headers: authHeaders2(credentials)
|
|
1082
1210
|
});
|
|
1083
1211
|
return normalizeSnapshot4(raw);
|
|
1084
1212
|
};
|
|
@@ -1087,12 +1215,12 @@ async function* results3(id, credentials) {
|
|
|
1087
1215
|
const raw = asRecord(snapshot.raw);
|
|
1088
1216
|
const outputFileId = asString(raw.output_file);
|
|
1089
1217
|
const errorFileId = asString(raw.error_file);
|
|
1090
|
-
const headers3 =
|
|
1218
|
+
const headers3 = authHeaders2(credentials);
|
|
1091
1219
|
if (outputFileId) {
|
|
1092
|
-
yield* streamResultFile(assertSimpleProviderId("Mistral output file id", outputFileId),
|
|
1220
|
+
yield* streamResultFile(assertSimpleProviderId("Mistral output file id", outputFileId), baseUrl4(credentials), headers3);
|
|
1093
1221
|
}
|
|
1094
1222
|
if (errorFileId) {
|
|
1095
|
-
yield* streamResultFile(assertSimpleProviderId("Mistral error file id", errorFileId),
|
|
1223
|
+
yield* streamResultFile(assertSimpleProviderId("Mistral error file id", errorFileId), baseUrl4(credentials), headers3);
|
|
1096
1224
|
}
|
|
1097
1225
|
if (!(outputFileId || errorFileId)) {
|
|
1098
1226
|
throw new BatchworkError(`batchwork: results are not ready for batch "${id}" (status: ${snapshot.status}).`);
|
|
@@ -1100,8 +1228,8 @@ async function* results3(id, credentials) {
|
|
|
1100
1228
|
}
|
|
1101
1229
|
var cancel3 = async (id, credentials) => {
|
|
1102
1230
|
const jobId = assertSimpleProviderId(JOB_ID_LABEL, id);
|
|
1103
|
-
await requestJson(`${
|
|
1104
|
-
headers:
|
|
1231
|
+
await requestJson(`${baseUrl4(credentials)}/batch/jobs/${jobId}/cancel`, {
|
|
1232
|
+
headers: authHeaders2(credentials),
|
|
1105
1233
|
method: "POST"
|
|
1106
1234
|
});
|
|
1107
1235
|
};
|
|
@@ -1232,6 +1360,7 @@ var togetherAdapter = createOpenAICompatibleAdapter({
|
|
|
1232
1360
|
baseUrl: "https://api.together.xyz/v1",
|
|
1233
1361
|
filePurpose: "batch-api",
|
|
1234
1362
|
id: "together",
|
|
1363
|
+
lineExtras: (endpoint) => endpoint.startsWith("/v1/audio/") ? { method: "FILE" } : undefined,
|
|
1235
1364
|
lineFormat: "body-only",
|
|
1236
1365
|
uploadFile: uploadTogetherFile
|
|
1237
1366
|
});
|
|
@@ -1241,8 +1370,8 @@ var XAI_BASE = "https://api.x.ai/v1";
|
|
|
1241
1370
|
var BATCH_ID_LABEL = "xAI batch id";
|
|
1242
1371
|
var RESULTS_PAGE_SIZE = 100;
|
|
1243
1372
|
var apiKey4 = (credentials) => resolveApiKey(credentials, "XAI_API_KEY", "xAI");
|
|
1244
|
-
var
|
|
1245
|
-
var
|
|
1373
|
+
var baseUrl5 = (credentials) => credentials.baseURL ?? XAI_BASE;
|
|
1374
|
+
var authHeaders3 = (credentials) => ({
|
|
1246
1375
|
Authorization: `Bearer ${apiKey4(credentials)}`,
|
|
1247
1376
|
...credentials.headers
|
|
1248
1377
|
});
|
|
@@ -1303,6 +1432,25 @@ var imagesFromXaiCompletion = (completion) => {
|
|
|
1303
1432
|
}
|
|
1304
1433
|
return images.length > 0 ? images : undefined;
|
|
1305
1434
|
};
|
|
1435
|
+
var videosFromXaiCompletion = (completion) => {
|
|
1436
|
+
const obj = asRecord(completion);
|
|
1437
|
+
const entries = asArray(obj.data);
|
|
1438
|
+
const sources = entries.length > 0 ? entries : [obj];
|
|
1439
|
+
const videos = [];
|
|
1440
|
+
for (const source of sources) {
|
|
1441
|
+
const record = asRecord(source);
|
|
1442
|
+
const video = asRecord(record.video);
|
|
1443
|
+
const url = asString(video.url) ?? asString(record.url);
|
|
1444
|
+
if (url) {
|
|
1445
|
+
const duration = asNumber(video.duration) ?? asNumber(record.duration);
|
|
1446
|
+
videos.push({
|
|
1447
|
+
...duration === undefined ? {} : { durationSeconds: duration },
|
|
1448
|
+
url
|
|
1449
|
+
});
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
return videos.length > 0 ? videos : undefined;
|
|
1453
|
+
};
|
|
1306
1454
|
var normalizeResult3 = (item) => {
|
|
1307
1455
|
const obj = asRecord(item);
|
|
1308
1456
|
const customId = asString(obj.batch_request_id) ?? "";
|
|
@@ -1321,10 +1469,12 @@ var normalizeResult3 = (item) => {
|
|
|
1321
1469
|
};
|
|
1322
1470
|
}
|
|
1323
1471
|
const response = asRecord(batchResult.response);
|
|
1472
|
+
const [opKey] = Object.keys(response);
|
|
1324
1473
|
const completion = response.chat_get_completion ?? Object.values(response)[0];
|
|
1474
|
+
const isVideo = response.chat_get_completion === undefined && opKey !== undefined && opKey.includes("video");
|
|
1325
1475
|
return {
|
|
1326
1476
|
customId,
|
|
1327
|
-
images: imagesFromXaiCompletion(completion),
|
|
1477
|
+
...isVideo ? { videos: videosFromXaiCompletion(completion) } : { images: imagesFromXaiCompletion(completion) },
|
|
1328
1478
|
response: completion,
|
|
1329
1479
|
status: "succeeded",
|
|
1330
1480
|
text: textFromBody(completion),
|
|
@@ -1337,13 +1487,13 @@ var submit4 = async (input) => {
|
|
|
1337
1487
|
body: omit(item.body, "stream"),
|
|
1338
1488
|
custom_id: item.customId,
|
|
1339
1489
|
method: "POST",
|
|
1340
|
-
url: input.endpoint
|
|
1490
|
+
url: item.endpoint || input.endpoint
|
|
1341
1491
|
})), { label: "batch upload JSONL", maxBytes: limits.maxUploadBytes });
|
|
1342
|
-
const inputFileId = await uploadInputFile(jsonl,
|
|
1343
|
-
const raw = await requestJson(`${
|
|
1492
|
+
const inputFileId = await uploadInputFile(jsonl, baseUrl5(input.credentials), authHeaders3(input.credentials), { purpose: null });
|
|
1493
|
+
const raw = await requestJson(`${baseUrl5(input.credentials)}/batches`, {
|
|
1344
1494
|
body: JSON.stringify({ input_file_id: inputFileId, name: "batchwork" }),
|
|
1345
1495
|
headers: {
|
|
1346
|
-
...
|
|
1496
|
+
...authHeaders3(input.credentials),
|
|
1347
1497
|
"content-type": "application/json"
|
|
1348
1498
|
},
|
|
1349
1499
|
method: "POST"
|
|
@@ -1352,21 +1502,21 @@ var submit4 = async (input) => {
|
|
|
1352
1502
|
};
|
|
1353
1503
|
var retrieve4 = async (id, credentials) => {
|
|
1354
1504
|
const batchId = assertSimpleProviderId(BATCH_ID_LABEL, id);
|
|
1355
|
-
const raw = await requestJson(`${
|
|
1356
|
-
headers:
|
|
1505
|
+
const raw = await requestJson(`${baseUrl5(credentials)}/batches/${batchId}`, {
|
|
1506
|
+
headers: authHeaders3(credentials)
|
|
1357
1507
|
});
|
|
1358
1508
|
return normalizeSnapshot5(raw);
|
|
1359
1509
|
};
|
|
1360
1510
|
async function* results4(id, credentials) {
|
|
1361
1511
|
const batchId = assertSimpleProviderId(BATCH_ID_LABEL, id);
|
|
1362
|
-
const headers3 =
|
|
1512
|
+
const headers3 = authHeaders3(credentials);
|
|
1363
1513
|
let token;
|
|
1364
1514
|
do {
|
|
1365
1515
|
const query = new URLSearchParams({ limit: String(RESULTS_PAGE_SIZE) });
|
|
1366
1516
|
if (token) {
|
|
1367
1517
|
query.set("pagination_token", token);
|
|
1368
1518
|
}
|
|
1369
|
-
const raw = await requestJson(`${
|
|
1519
|
+
const raw = await requestJson(`${baseUrl5(credentials)}/batches/${batchId}/results?${query.toString()}`, { headers: headers3 });
|
|
1370
1520
|
const page = asRecord(raw);
|
|
1371
1521
|
for (const item of Array.isArray(page.results) ? page.results : []) {
|
|
1372
1522
|
yield normalizeResult3(item);
|
|
@@ -1376,8 +1526,8 @@ async function* results4(id, credentials) {
|
|
|
1376
1526
|
}
|
|
1377
1527
|
var cancel4 = async (id, credentials) => {
|
|
1378
1528
|
const batchId = assertSimpleProviderId(BATCH_ID_LABEL, id);
|
|
1379
|
-
await requestJson(`${
|
|
1380
|
-
headers:
|
|
1529
|
+
await requestJson(`${baseUrl5(credentials)}/batches/${batchId}:cancel`, {
|
|
1530
|
+
headers: authHeaders3(credentials),
|
|
1381
1531
|
method: "POST"
|
|
1382
1532
|
});
|
|
1383
1533
|
};
|
|
@@ -1392,6 +1542,7 @@ var xaiAdapter = {
|
|
|
1392
1542
|
// src/providers/index.ts
|
|
1393
1543
|
var adapters = {
|
|
1394
1544
|
anthropic: anthropicAdapter,
|
|
1545
|
+
azure: azureAdapter,
|
|
1395
1546
|
google: googleAdapter,
|
|
1396
1547
|
groq: groqAdapter,
|
|
1397
1548
|
mistral: mistralAdapter,
|
|
@@ -1403,5 +1554,5 @@ var getAdapter = (provider) => adapters[provider];
|
|
|
1403
1554
|
|
|
1404
1555
|
export { BatchworkError, UnsupportedProviderError, MissingDependencyError, resolveBatchLimits, assertByteLength, mapWithConcurrency, isTerminalStatus, BatchJob, getAdapter };
|
|
1405
1556
|
|
|
1406
|
-
//# debugId=
|
|
1407
|
-
//# sourceMappingURL=chunk-
|
|
1557
|
+
//# debugId=C9B199FFE835E11B64756E2164756E21
|
|
1558
|
+
//# sourceMappingURL=chunk-vy4w8mpb.js.map
|