batchwork 1.3.0 → 1.4.1
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 +3 -3
- package/dist/body.d.ts.map +1 -1
- package/dist/{chunk-qqz5h9v6.js → chunk-14qcscwd.js} +47 -14
- package/dist/chunk-14qcscwd.js.map +12 -0
- package/dist/{chunk-9cwfwzm4.js → chunk-mathjpg6.js} +27 -118
- package/dist/chunk-mathjpg6.js.map +13 -0
- package/dist/{chunk-gwa0dkhj.js → chunk-n50t31ca.js} +405 -337
- package/dist/{chunk-gwa0dkhj.js.map → chunk-n50t31ca.js.map} +10 -9
- package/dist/index.js +2 -2
- package/dist/limits.d.ts +0 -1
- package/dist/limits.d.ts.map +1 -1
- 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 +18 -2
- package/dist/providers/openai-compatible.d.ts.map +1 -1
- package/dist/providers/shared.d.ts.map +1 -1
- package/dist/server/index.js +2 -2
- package/dist/server/poller.d.ts.map +1 -1
- package/dist/server/signing.d.ts.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/util.d.ts +2 -0
- package/dist/util.d.ts.map +1 -1
- package/package.json +10 -2
- package/dist/chunk-9cwfwzm4.js.map +0 -13
- package/dist/chunk-qqz5h9v6.js.map +0 -12
|
@@ -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
|
}
|
|
@@ -138,22 +138,48 @@ var assertByteCount = (label, bytes, maxBytes) => {
|
|
|
138
138
|
var assertByteLength = (label, value, maxBytes) => {
|
|
139
139
|
assertByteCount(label, byteLength(value), maxBytes);
|
|
140
140
|
};
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
let
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
141
|
+
|
|
142
|
+
// src/util.ts
|
|
143
|
+
var trimTrailingSlashes = (value) => {
|
|
144
|
+
let end = value.length;
|
|
145
|
+
while (end > 0 && value[end - 1] === "/") {
|
|
146
|
+
end -= 1;
|
|
147
|
+
}
|
|
148
|
+
return value.slice(0, end);
|
|
149
|
+
};
|
|
150
|
+
var asRecord = (value) => {
|
|
151
|
+
if (typeof value === "object" && value !== null) {
|
|
152
|
+
return value;
|
|
153
|
+
}
|
|
154
|
+
return {};
|
|
155
|
+
};
|
|
156
|
+
var asString = (value) => typeof value === "string" ? value : undefined;
|
|
157
|
+
var asNumber = (value) => typeof value === "number" ? value : undefined;
|
|
158
|
+
var asArray = (value) => Array.isArray(value) ? value : [];
|
|
159
|
+
var asNumberArray = (value) => {
|
|
160
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
const numbers = value.filter((item) => typeof item === "number");
|
|
164
|
+
return numbers.length === value.length ? numbers : undefined;
|
|
165
|
+
};
|
|
166
|
+
var omit = (obj, key) => {
|
|
167
|
+
const result = {};
|
|
168
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
169
|
+
if (k !== key) {
|
|
170
|
+
result[k] = v;
|
|
151
171
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
172
|
+
}
|
|
173
|
+
return result;
|
|
174
|
+
};
|
|
175
|
+
var validDate = (date) => Number.isNaN(date.getTime()) ? undefined : date;
|
|
176
|
+
var toDate = (value) => {
|
|
177
|
+
if (typeof value === "string") {
|
|
178
|
+
return validDate(new Date(value));
|
|
179
|
+
}
|
|
180
|
+
if (typeof value === "number") {
|
|
181
|
+
return validDate(new Date(value * 1000));
|
|
182
|
+
}
|
|
157
183
|
};
|
|
158
184
|
|
|
159
185
|
// src/http.ts
|
|
@@ -306,42 +332,6 @@ var encodeJsonArrayPayload = ({
|
|
|
306
332
|
return `${prefix}${encodedItems.join(",")}${suffix}`;
|
|
307
333
|
};
|
|
308
334
|
|
|
309
|
-
// src/util.ts
|
|
310
|
-
var asRecord = (value) => {
|
|
311
|
-
if (typeof value === "object" && value !== null) {
|
|
312
|
-
return value;
|
|
313
|
-
}
|
|
314
|
-
return {};
|
|
315
|
-
};
|
|
316
|
-
var asString = (value) => typeof value === "string" ? value : undefined;
|
|
317
|
-
var asNumber = (value) => typeof value === "number" ? value : undefined;
|
|
318
|
-
var asArray = (value) => Array.isArray(value) ? value : [];
|
|
319
|
-
var asNumberArray = (value) => {
|
|
320
|
-
if (!Array.isArray(value) || value.length === 0) {
|
|
321
|
-
return;
|
|
322
|
-
}
|
|
323
|
-
const numbers = value.filter((item) => typeof item === "number");
|
|
324
|
-
return numbers.length === value.length ? numbers : undefined;
|
|
325
|
-
};
|
|
326
|
-
var omit = (obj, key) => {
|
|
327
|
-
const result = {};
|
|
328
|
-
for (const [k, v] of Object.entries(obj)) {
|
|
329
|
-
if (k !== key) {
|
|
330
|
-
result[k] = v;
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
return result;
|
|
334
|
-
};
|
|
335
|
-
var validDate = (date) => Number.isNaN(date.getTime()) ? undefined : date;
|
|
336
|
-
var toDate = (value) => {
|
|
337
|
-
if (typeof value === "string") {
|
|
338
|
-
return validDate(new Date(value));
|
|
339
|
-
}
|
|
340
|
-
if (typeof value === "number") {
|
|
341
|
-
return validDate(new Date(value * 1000));
|
|
342
|
-
}
|
|
343
|
-
};
|
|
344
|
-
|
|
345
335
|
// src/providers/ids.ts
|
|
346
336
|
var SIMPLE_PROVIDER_ID = /^[A-Za-z0-9_-]+$/u;
|
|
347
337
|
var assertSimpleProviderId = (label, id) => {
|
|
@@ -525,237 +515,18 @@ async function* results(id, credentials) {
|
|
|
525
515
|
}
|
|
526
516
|
}
|
|
527
517
|
var cancel = async (id, credentials) => {
|
|
528
|
-
const batchId = assertSimpleProviderId("Anthropic batch id", id);
|
|
529
|
-
await requestJson(`${baseUrl(credentials)}/v1/messages/batches/${batchId}/cancel`, {
|
|
530
|
-
headers: headers(credentials),
|
|
531
|
-
method: "POST"
|
|
532
|
-
});
|
|
533
|
-
};
|
|
534
|
-
var anthropicAdapter = {
|
|
535
|
-
cancel,
|
|
536
|
-
id: "anthropic",
|
|
537
|
-
results,
|
|
538
|
-
retrieve,
|
|
539
|
-
submit
|
|
540
|
-
};
|
|
541
|
-
|
|
542
|
-
// src/providers/google.ts
|
|
543
|
-
var GOOGLE_BASE = "https://generativelanguage.googleapis.com/v1beta";
|
|
544
|
-
var OPERATION_ID_LABEL = "Google operation id";
|
|
545
|
-
var GOOGLE_BATCH_PREFIX = "batches";
|
|
546
|
-
var apiKey2 = (credentials) => {
|
|
547
|
-
const key = credentials.apiKey ?? process.env.GOOGLE_GENERATIVE_AI_API_KEY ?? process.env.GEMINI_API_KEY;
|
|
548
|
-
if (!key) {
|
|
549
|
-
throw new BatchworkError("batchwork: missing Google Gemini API key. Set GOOGLE_GENERATIVE_AI_API_KEY (or GEMINI_API_KEY) or pass `apiKey`.");
|
|
550
|
-
}
|
|
551
|
-
return key;
|
|
552
|
-
};
|
|
553
|
-
var baseUrl2 = (credentials) => credentials.baseURL ?? GOOGLE_BASE;
|
|
554
|
-
var headers2 = (credentials) => ({
|
|
555
|
-
"content-type": "application/json",
|
|
556
|
-
"x-goog-api-key": apiKey2(credentials),
|
|
557
|
-
...credentials.headers
|
|
558
|
-
});
|
|
559
|
-
var mapState = (state, done) => {
|
|
560
|
-
if (state) {
|
|
561
|
-
if (state.endsWith("SUCCEEDED")) {
|
|
562
|
-
return "completed";
|
|
563
|
-
}
|
|
564
|
-
if (state.endsWith("FAILED")) {
|
|
565
|
-
return "failed";
|
|
566
|
-
}
|
|
567
|
-
if (state.endsWith("CANCELLED")) {
|
|
568
|
-
return "cancelled";
|
|
569
|
-
}
|
|
570
|
-
if (state.endsWith("EXPIRED")) {
|
|
571
|
-
return "expired";
|
|
572
|
-
}
|
|
573
|
-
if (state.endsWith("PENDING")) {
|
|
574
|
-
return "validating";
|
|
575
|
-
}
|
|
576
|
-
if (state.endsWith("RUNNING")) {
|
|
577
|
-
return "in_progress";
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
return done ? "completed" : "in_progress";
|
|
581
|
-
};
|
|
582
|
-
var inlinedResponses = (raw) => {
|
|
583
|
-
const obj = asRecord(raw);
|
|
584
|
-
const response = asRecord(obj.response);
|
|
585
|
-
const dest = asRecord(obj.dest);
|
|
586
|
-
const responseInline = response.inlinedResponses ?? response.inlined_responses;
|
|
587
|
-
const destInline = dest.inlinedResponses ?? dest.inlined_responses;
|
|
588
|
-
const nestedResponseInline = asRecord(responseInline);
|
|
589
|
-
const nestedDestInline = asRecord(destInline);
|
|
590
|
-
return [
|
|
591
|
-
...asArray(responseInline),
|
|
592
|
-
...asArray(nestedResponseInline.inlinedResponses),
|
|
593
|
-
...asArray(nestedResponseInline.inlined_responses),
|
|
594
|
-
...asArray(destInline),
|
|
595
|
-
...asArray(nestedDestInline.inlinedResponses),
|
|
596
|
-
...asArray(nestedDestInline.inlined_responses)
|
|
597
|
-
];
|
|
598
|
-
};
|
|
599
|
-
var normalizeSnapshot2 = (raw) => {
|
|
600
|
-
const obj = asRecord(raw);
|
|
601
|
-
const items = inlinedResponses(raw);
|
|
602
|
-
const failed = items.filter((item) => asRecord(item).error).length;
|
|
603
|
-
const id = asString(obj.name) ?? "";
|
|
604
|
-
return {
|
|
605
|
-
id: id ? assertPrefixedProviderId(OPERATION_ID_LABEL, id, GOOGLE_BATCH_PREFIX) : "",
|
|
606
|
-
provider: "google",
|
|
607
|
-
raw,
|
|
608
|
-
requestCounts: {
|
|
609
|
-
completed: items.length - failed,
|
|
610
|
-
failed,
|
|
611
|
-
total: items.length
|
|
612
|
-
},
|
|
613
|
-
status: mapState(asString(obj.state) ?? asString(asRecord(obj.state).name) ?? asString(asRecord(obj.metadata).state), obj.done === true)
|
|
614
|
-
};
|
|
615
|
-
};
|
|
616
|
-
var textFromResponse = (response) => {
|
|
617
|
-
const candidate = asRecord(asArray(asRecord(response).candidates)[0]);
|
|
618
|
-
const text = asArray(asRecord(candidate.content).parts).map((part) => asString(asRecord(part).text) ?? "").join("");
|
|
619
|
-
return text.length > 0 ? text : undefined;
|
|
620
|
-
};
|
|
621
|
-
var embeddingFromResponse = (response) => asNumberArray(asRecord(asRecord(response).embedding).values);
|
|
622
|
-
var imagesFromResponse = (response) => {
|
|
623
|
-
const candidate = asRecord(asArray(asRecord(response).candidates)[0]);
|
|
624
|
-
const images = [];
|
|
625
|
-
for (const part of asArray(asRecord(candidate.content).parts)) {
|
|
626
|
-
const partObj = asRecord(part);
|
|
627
|
-
const inline = asRecord(partObj.inlineData ?? partObj.inline_data);
|
|
628
|
-
const data = asString(inline.data);
|
|
629
|
-
const mediaType = asString(inline.mimeType) ?? asString(inline.mime_type);
|
|
630
|
-
if (data && mediaType?.startsWith("image/")) {
|
|
631
|
-
images.push({ data, mediaType });
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
|
-
return images.length > 0 ? images : undefined;
|
|
635
|
-
};
|
|
636
|
-
var usageFromResponse = (response) => {
|
|
637
|
-
const usage = asRecord(asRecord(response).usageMetadata);
|
|
638
|
-
const inputTokens = asNumber(usage.promptTokenCount);
|
|
639
|
-
const outputTokens = asNumber(usage.candidatesTokenCount);
|
|
640
|
-
const totalTokens = asNumber(usage.totalTokenCount);
|
|
641
|
-
if (inputTokens === undefined && outputTokens === undefined && totalTokens === undefined) {
|
|
642
|
-
return;
|
|
643
|
-
}
|
|
644
|
-
return {
|
|
645
|
-
inputTokens,
|
|
646
|
-
outputTokens,
|
|
647
|
-
totalTokens: totalTokens ?? (inputTokens ?? 0) + (outputTokens ?? 0)
|
|
648
|
-
};
|
|
649
|
-
};
|
|
650
|
-
var normalizeResult2 = (item) => {
|
|
651
|
-
const obj = asRecord(item);
|
|
652
|
-
const customId = asString(asRecord(obj.metadata).key) ?? asString(obj.key) ?? asString(obj.custom_id) ?? "";
|
|
653
|
-
if (obj.error) {
|
|
654
|
-
const error = asRecord(obj.error);
|
|
655
|
-
return {
|
|
656
|
-
customId,
|
|
657
|
-
error: {
|
|
658
|
-
code: asNumber(error.code) ?? asString(error.code),
|
|
659
|
-
message: asString(error.message) ?? "Request errored.",
|
|
660
|
-
type: asString(error.status)
|
|
661
|
-
},
|
|
662
|
-
response: obj.error,
|
|
663
|
-
status: "errored"
|
|
664
|
-
};
|
|
665
|
-
}
|
|
666
|
-
return {
|
|
667
|
-
customId,
|
|
668
|
-
embedding: embeddingFromResponse(obj.response),
|
|
669
|
-
images: imagesFromResponse(obj.response),
|
|
670
|
-
response: obj.response,
|
|
671
|
-
status: "succeeded",
|
|
672
|
-
text: textFromResponse(obj.response),
|
|
673
|
-
usage: usageFromResponse(obj.response)
|
|
674
|
-
};
|
|
675
|
-
};
|
|
676
|
-
var EMBED_CONFIG_KEYS = new Set([
|
|
677
|
-
"outputDimensionality",
|
|
678
|
-
"taskType",
|
|
679
|
-
"title"
|
|
680
|
-
]);
|
|
681
|
-
var toEmbedRequest = (body) => {
|
|
682
|
-
const request = {};
|
|
683
|
-
const config = {};
|
|
684
|
-
for (const [key, value] of Object.entries(body)) {
|
|
685
|
-
if (EMBED_CONFIG_KEYS.has(key)) {
|
|
686
|
-
config[key] = value;
|
|
687
|
-
} else {
|
|
688
|
-
request[key] = value;
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
if (Object.keys(config).length > 0) {
|
|
692
|
-
request.embedContentConfig = config;
|
|
693
|
-
}
|
|
694
|
-
return request;
|
|
695
|
-
};
|
|
696
|
-
var submit2 = async (input) => {
|
|
697
|
-
const limits = resolveBatchLimits(input.limits);
|
|
698
|
-
const isEmbedding = input.endpoint.toLowerCase().includes("embedcontent");
|
|
699
|
-
const method = isEmbedding ? "asyncBatchEmbedContent" : "batchGenerateContent";
|
|
700
|
-
const requests = input.built.map((item) => {
|
|
701
|
-
const payload = omit(item.body, "stream");
|
|
702
|
-
return {
|
|
703
|
-
metadata: { key: item.customId },
|
|
704
|
-
request: isEmbedding ? toEmbedRequest(payload) : payload
|
|
705
|
-
};
|
|
706
|
-
});
|
|
707
|
-
const body = encodeJsonArrayPayload({
|
|
708
|
-
items: requests,
|
|
709
|
-
label: "batch upload payload",
|
|
710
|
-
maxBytes: limits.maxUploadBytes,
|
|
711
|
-
prefix: '{"batch":{"display_name":"batchwork","input_config":{"requests":{"requests":[',
|
|
712
|
-
suffix: "]}}}}"
|
|
713
|
-
});
|
|
714
|
-
const raw = await requestJson(`${baseUrl2(input.credentials)}/models/${input.modelId}:${method}`, {
|
|
715
|
-
body,
|
|
716
|
-
headers: headers2(input.credentials),
|
|
717
|
-
method: "POST"
|
|
718
|
-
});
|
|
719
|
-
return normalizeSnapshot2(raw);
|
|
720
|
-
};
|
|
721
|
-
var retrieve2 = async (id, credentials) => {
|
|
722
|
-
const operationId = assertPrefixedProviderId(OPERATION_ID_LABEL, id, GOOGLE_BATCH_PREFIX);
|
|
723
|
-
const raw = await requestJson(`${baseUrl2(credentials)}/${operationId}`, {
|
|
724
|
-
headers: headers2(credentials)
|
|
725
|
-
});
|
|
726
|
-
return normalizeSnapshot2(raw);
|
|
727
|
-
};
|
|
728
|
-
var fileNameFrom = (value) => asString(asRecord(value).name) ?? asString(value);
|
|
729
|
-
async function* results2(id, credentials) {
|
|
730
|
-
const snapshot = await retrieve2(id, credentials);
|
|
731
|
-
const raw = asRecord(snapshot.raw);
|
|
732
|
-
const response = asRecord(raw.response);
|
|
733
|
-
const dest = asRecord(raw.dest);
|
|
734
|
-
const responsesFile = fileNameFrom(response.responsesFile) ?? fileNameFrom(response.responses_file) ?? asString(dest.fileName) ?? asString(dest.file_name);
|
|
735
|
-
if (responsesFile) {
|
|
736
|
-
throw new BatchworkError(`batchwork: batch "${id}" returned file-mode results, which are not supported yet.`);
|
|
737
|
-
}
|
|
738
|
-
const items = inlinedResponses(raw);
|
|
739
|
-
if (items.length === 0) {
|
|
740
|
-
throw new BatchworkError(`batchwork: results are not ready for batch "${id}" (status: ${snapshot.status}).`);
|
|
741
|
-
}
|
|
742
|
-
for (const item of items) {
|
|
743
|
-
yield normalizeResult2(item);
|
|
744
|
-
}
|
|
745
|
-
}
|
|
746
|
-
var cancel2 = async (id, credentials) => {
|
|
747
|
-
const operationId = assertPrefixedProviderId(OPERATION_ID_LABEL, id, GOOGLE_BATCH_PREFIX);
|
|
748
|
-
await requestJson(`${baseUrl2(credentials)}/${operationId}:cancel`, {
|
|
749
|
-
headers: headers2(credentials),
|
|
518
|
+
const batchId = assertSimpleProviderId("Anthropic batch id", id);
|
|
519
|
+
await requestJson(`${baseUrl(credentials)}/v1/messages/batches/${batchId}/cancel`, {
|
|
520
|
+
headers: headers(credentials),
|
|
750
521
|
method: "POST"
|
|
751
522
|
});
|
|
752
523
|
};
|
|
753
|
-
var
|
|
754
|
-
cancel
|
|
755
|
-
id: "
|
|
756
|
-
results
|
|
757
|
-
retrieve
|
|
758
|
-
submit
|
|
524
|
+
var anthropicAdapter = {
|
|
525
|
+
cancel,
|
|
526
|
+
id: "anthropic",
|
|
527
|
+
results,
|
|
528
|
+
retrieve,
|
|
529
|
+
submit
|
|
759
530
|
};
|
|
760
531
|
|
|
761
532
|
// src/providers/shared.ts
|
|
@@ -777,7 +548,30 @@ var textFromBody = (body) => {
|
|
|
777
548
|
return content;
|
|
778
549
|
}
|
|
779
550
|
}
|
|
780
|
-
|
|
551
|
+
const directText = asString(obj.output_text) ?? asString(obj.text);
|
|
552
|
+
if (directText !== undefined) {
|
|
553
|
+
return directText;
|
|
554
|
+
}
|
|
555
|
+
const parts = [];
|
|
556
|
+
for (const output of asArray(obj.output)) {
|
|
557
|
+
const item = asRecord(output);
|
|
558
|
+
if (item.type !== "message") {
|
|
559
|
+
continue;
|
|
560
|
+
}
|
|
561
|
+
for (const content of asArray(item.content)) {
|
|
562
|
+
const part = asRecord(content);
|
|
563
|
+
if (part.type !== "output_text") {
|
|
564
|
+
continue;
|
|
565
|
+
}
|
|
566
|
+
const text = asString(part.text);
|
|
567
|
+
if (text !== undefined) {
|
|
568
|
+
parts.push(text);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
if (parts.length > 0) {
|
|
573
|
+
return parts.join("");
|
|
574
|
+
}
|
|
781
575
|
};
|
|
782
576
|
var segmentsFromBody = (body) => {
|
|
783
577
|
const obj = asRecord(body);
|
|
@@ -818,11 +612,11 @@ var imagesFromBody = (body) => {
|
|
|
818
612
|
return images.length > 0 ? images : undefined;
|
|
819
613
|
};
|
|
820
614
|
var moderationFromBody = (body) => {
|
|
821
|
-
const
|
|
822
|
-
if (
|
|
615
|
+
const results2 = asArray(asRecord(body).results);
|
|
616
|
+
if (results2.length === 0) {
|
|
823
617
|
return;
|
|
824
618
|
}
|
|
825
|
-
const first = asRecord(
|
|
619
|
+
const first = asRecord(results2[0]);
|
|
826
620
|
const categories = {};
|
|
827
621
|
for (const [key, value] of Object.entries(asRecord(first.categories))) {
|
|
828
622
|
if (typeof value === "boolean") {
|
|
@@ -899,24 +693,24 @@ var normalizeOpenAIResult = (line) => {
|
|
|
899
693
|
status: "errored"
|
|
900
694
|
};
|
|
901
695
|
};
|
|
902
|
-
var uploadInputFile = async (jsonl,
|
|
696
|
+
var uploadInputFile = async (jsonl, baseUrl2, headers2, options = {}) => {
|
|
903
697
|
const form = new FormData;
|
|
904
698
|
const purpose = options.purpose === undefined ? "batch" : options.purpose;
|
|
905
699
|
if (purpose !== null) {
|
|
906
700
|
form.append("purpose", purpose);
|
|
907
701
|
}
|
|
908
702
|
form.append("file", new Blob([jsonl], { type: "application/jsonl" }), "batchwork.jsonl");
|
|
909
|
-
const raw = await requestJson(`${
|
|
703
|
+
const raw = await requestJson(`${baseUrl2}/files`, {
|
|
910
704
|
body: form,
|
|
911
|
-
headers:
|
|
705
|
+
headers: headers2,
|
|
912
706
|
method: "POST",
|
|
913
707
|
redirect: "manual"
|
|
914
708
|
});
|
|
915
709
|
return raw.id;
|
|
916
710
|
};
|
|
917
|
-
async function* streamResultFile(fileId,
|
|
918
|
-
const stream = await requestStream(`${
|
|
919
|
-
headers:
|
|
711
|
+
async function* streamResultFile(fileId, baseUrl2, headers2) {
|
|
712
|
+
const stream = await requestStream(`${baseUrl2}/files/${fileId}/content`, {
|
|
713
|
+
headers: headers2,
|
|
920
714
|
redirect: "manual"
|
|
921
715
|
});
|
|
922
716
|
for await (const line of streamJsonl(stream)) {
|
|
@@ -944,7 +738,7 @@ var mapStatus2 = (status) => {
|
|
|
944
738
|
}
|
|
945
739
|
}
|
|
946
740
|
};
|
|
947
|
-
var
|
|
741
|
+
var normalizeSnapshot2 = (raw, provider) => {
|
|
948
742
|
const outer = asRecord(raw);
|
|
949
743
|
const obj = asRecord(outer.job);
|
|
950
744
|
const source = Object.keys(obj).length > 0 ? obj : outer;
|
|
@@ -967,14 +761,19 @@ var normalizeSnapshot3 = (raw, provider) => {
|
|
|
967
761
|
var createOpenAICompatibleAdapter = (config) => {
|
|
968
762
|
const completionWindow = config.completionWindow ?? DEFAULT_COMPLETION_WINDOW;
|
|
969
763
|
const lineFormat = config.lineFormat ?? "method-url";
|
|
970
|
-
const
|
|
764
|
+
const baseUrl2 = (credentials) => config.resolveBaseUrl?.(credentials) ?? credentials.baseURL ?? config.baseUrl ?? (() => {
|
|
765
|
+
throw new BatchworkError(`batchwork: missing ${config.apiKeyLabel} base URL. Pass \`baseURL\`.`);
|
|
766
|
+
})();
|
|
971
767
|
const authHeaders = (credentials) => ({
|
|
972
|
-
|
|
768
|
+
...config.authHeaders ? config.authHeaders(credentials) : {
|
|
769
|
+
Authorization: `Bearer ${resolveApiKey(credentials, config.apiKeyEnv, config.apiKeyLabel)}`
|
|
770
|
+
},
|
|
973
771
|
...credentials.headers
|
|
974
772
|
});
|
|
975
|
-
const
|
|
773
|
+
const submit2 = async (input) => {
|
|
976
774
|
const limits = resolveBatchLimits(input.limits);
|
|
977
775
|
const endpoint = config.normalizeEndpoint ? config.normalizeEndpoint(input.endpoint) : input.endpoint;
|
|
776
|
+
const batchEndpoint = config.batchEndpoint?.(endpoint) ?? endpoint;
|
|
978
777
|
const jsonl = encodeJsonl(input.built.map((item) => {
|
|
979
778
|
const body = omit(item.body, "stream");
|
|
980
779
|
if (lineFormat === "body-only") {
|
|
@@ -991,53 +790,321 @@ var createOpenAICompatibleAdapter = (config) => {
|
|
|
991
790
|
url: endpoint
|
|
992
791
|
};
|
|
993
792
|
}), { label: "batch upload JSONL", maxBytes: limits.maxUploadBytes });
|
|
994
|
-
const
|
|
995
|
-
const url =
|
|
793
|
+
const headers2 = authHeaders(input.credentials);
|
|
794
|
+
const url = baseUrl2(input.credentials);
|
|
996
795
|
const purpose = config.filePurpose ?? "batch";
|
|
997
|
-
const inputFileId = await (config.uploadFile ? config.uploadFile({ baseUrl: url, headers:
|
|
796
|
+
const inputFileId = await (config.uploadFile ? config.uploadFile({ baseUrl: url, headers: headers2, jsonl, purpose }) : uploadInputFile(jsonl, url, headers2, { purpose }));
|
|
998
797
|
const raw = await requestJson(`${url}/batches`, {
|
|
999
798
|
body: JSON.stringify({
|
|
1000
799
|
completion_window: completionWindow,
|
|
1001
|
-
endpoint,
|
|
800
|
+
endpoint: batchEndpoint,
|
|
1002
801
|
input_file_id: inputFileId,
|
|
1003
802
|
metadata: input.metadata
|
|
1004
803
|
}),
|
|
1005
|
-
headers: { ...
|
|
804
|
+
headers: { ...headers2, "content-type": "application/json" },
|
|
1006
805
|
method: "POST"
|
|
1007
806
|
});
|
|
1008
|
-
return
|
|
807
|
+
return normalizeSnapshot2(raw, config.id);
|
|
1009
808
|
};
|
|
1010
|
-
const
|
|
809
|
+
const retrieve2 = async (id, credentials) => {
|
|
1011
810
|
const batchId = assertSimpleProviderId(`${config.id} batch id`, id);
|
|
1012
|
-
const raw = await requestJson(`${
|
|
811
|
+
const raw = await requestJson(`${baseUrl2(credentials)}/batches/${batchId}`, {
|
|
1013
812
|
headers: authHeaders(credentials)
|
|
1014
813
|
});
|
|
1015
|
-
return
|
|
814
|
+
return normalizeSnapshot2(raw, config.id);
|
|
1016
815
|
};
|
|
1017
|
-
async function*
|
|
1018
|
-
const snapshot = await
|
|
816
|
+
async function* results2(id, credentials) {
|
|
817
|
+
const snapshot = await retrieve2(id, credentials);
|
|
1019
818
|
const raw = asRecord(snapshot.raw);
|
|
1020
819
|
const outputFileId = asString(raw.output_file_id);
|
|
1021
820
|
const errorFileId = asString(raw.error_file_id);
|
|
1022
821
|
if (!(outputFileId || errorFileId)) {
|
|
1023
822
|
throw new BatchworkError(`batchwork: results are not ready for batch "${id}" (status: ${snapshot.status}).`);
|
|
1024
823
|
}
|
|
1025
|
-
const
|
|
824
|
+
const headers2 = authHeaders(credentials);
|
|
1026
825
|
if (outputFileId) {
|
|
1027
|
-
yield* streamResultFile(assertSimpleProviderId(`${config.id} output file id`, outputFileId),
|
|
826
|
+
yield* streamResultFile(assertSimpleProviderId(`${config.id} output file id`, outputFileId), baseUrl2(credentials), headers2);
|
|
1028
827
|
}
|
|
1029
828
|
if (errorFileId) {
|
|
1030
|
-
yield* streamResultFile(assertSimpleProviderId(`${config.id} error file id`, errorFileId),
|
|
829
|
+
yield* streamResultFile(assertSimpleProviderId(`${config.id} error file id`, errorFileId), baseUrl2(credentials), headers2);
|
|
1031
830
|
}
|
|
1032
831
|
}
|
|
1033
|
-
const
|
|
832
|
+
const cancel2 = async (id, credentials) => {
|
|
1034
833
|
const batchId = assertSimpleProviderId(`${config.id} batch id`, id);
|
|
1035
|
-
await requestJson(`${
|
|
834
|
+
await requestJson(`${baseUrl2(credentials)}/batches/${batchId}/cancel`, {
|
|
1036
835
|
headers: authHeaders(credentials),
|
|
1037
836
|
method: "POST"
|
|
1038
837
|
});
|
|
1039
838
|
};
|
|
1040
|
-
return { cancel:
|
|
839
|
+
return { cancel: cancel2, id: config.id, results: results2, retrieve: retrieve2, submit: submit2 };
|
|
840
|
+
};
|
|
841
|
+
|
|
842
|
+
// src/providers/azure.ts
|
|
843
|
+
var isAzureOpenAIUrl = (value) => {
|
|
844
|
+
try {
|
|
845
|
+
return new URL(value).hostname.endsWith(".openai.azure.com");
|
|
846
|
+
} catch {
|
|
847
|
+
return false;
|
|
848
|
+
}
|
|
849
|
+
};
|
|
850
|
+
var baseUrl2 = (credentials) => {
|
|
851
|
+
const configured = credentials.baseURL ?? (process.env.AZURE_RESOURCE_NAME ? `https://${process.env.AZURE_RESOURCE_NAME}.openai.azure.com/openai` : undefined);
|
|
852
|
+
if (!configured) {
|
|
853
|
+
throw new BatchworkError("batchwork: missing Azure OpenAI resource. Set AZURE_RESOURCE_NAME or pass `baseURL`.");
|
|
854
|
+
}
|
|
855
|
+
const normalized = trimTrailingSlashes(configured);
|
|
856
|
+
if (!isAzureOpenAIUrl(normalized)) {
|
|
857
|
+
return normalized;
|
|
858
|
+
}
|
|
859
|
+
if (normalized.endsWith("/v1")) {
|
|
860
|
+
return normalized;
|
|
861
|
+
}
|
|
862
|
+
return normalized.endsWith("/openai") ? `${normalized}/v1` : `${normalized}/openai/v1`;
|
|
863
|
+
};
|
|
864
|
+
var hasCallerAuth = (headers2) => Object.keys(headers2 ?? {}).some((name) => {
|
|
865
|
+
const normalized = name.toLowerCase();
|
|
866
|
+
return normalized === "api-key" || normalized === "authorization";
|
|
867
|
+
});
|
|
868
|
+
var authHeaders = (credentials) => {
|
|
869
|
+
if (credentials.apiKey) {
|
|
870
|
+
return { "api-key": credentials.apiKey };
|
|
871
|
+
}
|
|
872
|
+
if (hasCallerAuth(credentials.headers)) {
|
|
873
|
+
return {};
|
|
874
|
+
}
|
|
875
|
+
const apiKey2 = process.env.AZURE_API_KEY ?? process.env.AZURE_OPENAI_API_KEY;
|
|
876
|
+
if (apiKey2) {
|
|
877
|
+
return { "api-key": apiKey2 };
|
|
878
|
+
}
|
|
879
|
+
throw new BatchworkError("batchwork: missing Azure OpenAI API key. Set AZURE_API_KEY or pass `apiKey`.");
|
|
880
|
+
};
|
|
881
|
+
var azureAdapter = createOpenAICompatibleAdapter({
|
|
882
|
+
apiKeyEnv: "AZURE_API_KEY",
|
|
883
|
+
apiKeyLabel: "Azure OpenAI",
|
|
884
|
+
authHeaders,
|
|
885
|
+
batchEndpoint: () => "/v1/chat/completions",
|
|
886
|
+
id: "azure",
|
|
887
|
+
normalizeEndpoint: (endpoint) => endpoint.replace(/^\/openai/u, ""),
|
|
888
|
+
resolveBaseUrl: baseUrl2
|
|
889
|
+
});
|
|
890
|
+
|
|
891
|
+
// src/providers/google.ts
|
|
892
|
+
var GOOGLE_BASE = "https://generativelanguage.googleapis.com/v1beta";
|
|
893
|
+
var OPERATION_ID_LABEL = "Google operation id";
|
|
894
|
+
var GOOGLE_BATCH_PREFIX = "batches";
|
|
895
|
+
var apiKey2 = (credentials) => {
|
|
896
|
+
const key = credentials.apiKey ?? process.env.GOOGLE_GENERATIVE_AI_API_KEY ?? process.env.GEMINI_API_KEY;
|
|
897
|
+
if (!key) {
|
|
898
|
+
throw new BatchworkError("batchwork: missing Google Gemini API key. Set GOOGLE_GENERATIVE_AI_API_KEY (or GEMINI_API_KEY) or pass `apiKey`.");
|
|
899
|
+
}
|
|
900
|
+
return key;
|
|
901
|
+
};
|
|
902
|
+
var baseUrl3 = (credentials) => credentials.baseURL ?? GOOGLE_BASE;
|
|
903
|
+
var headers2 = (credentials) => ({
|
|
904
|
+
"content-type": "application/json",
|
|
905
|
+
"x-goog-api-key": apiKey2(credentials),
|
|
906
|
+
...credentials.headers
|
|
907
|
+
});
|
|
908
|
+
var mapState = (state, done) => {
|
|
909
|
+
if (state) {
|
|
910
|
+
if (state.endsWith("SUCCEEDED")) {
|
|
911
|
+
return "completed";
|
|
912
|
+
}
|
|
913
|
+
if (state.endsWith("FAILED")) {
|
|
914
|
+
return "failed";
|
|
915
|
+
}
|
|
916
|
+
if (state.endsWith("CANCELLED")) {
|
|
917
|
+
return "cancelled";
|
|
918
|
+
}
|
|
919
|
+
if (state.endsWith("EXPIRED")) {
|
|
920
|
+
return "expired";
|
|
921
|
+
}
|
|
922
|
+
if (state.endsWith("PENDING")) {
|
|
923
|
+
return "validating";
|
|
924
|
+
}
|
|
925
|
+
if (state.endsWith("RUNNING")) {
|
|
926
|
+
return "in_progress";
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
return done ? "completed" : "in_progress";
|
|
930
|
+
};
|
|
931
|
+
var inlinedResponses = (raw) => {
|
|
932
|
+
const obj = asRecord(raw);
|
|
933
|
+
const response = asRecord(obj.response);
|
|
934
|
+
const dest = asRecord(obj.dest);
|
|
935
|
+
const responseInline = response.inlinedResponses ?? response.inlined_responses;
|
|
936
|
+
const destInline = dest.inlinedResponses ?? dest.inlined_responses;
|
|
937
|
+
const nestedResponseInline = asRecord(responseInline);
|
|
938
|
+
const nestedDestInline = asRecord(destInline);
|
|
939
|
+
return [
|
|
940
|
+
...asArray(responseInline),
|
|
941
|
+
...asArray(nestedResponseInline.inlinedResponses),
|
|
942
|
+
...asArray(nestedResponseInline.inlined_responses),
|
|
943
|
+
...asArray(destInline),
|
|
944
|
+
...asArray(nestedDestInline.inlinedResponses),
|
|
945
|
+
...asArray(nestedDestInline.inlined_responses)
|
|
946
|
+
];
|
|
947
|
+
};
|
|
948
|
+
var normalizeSnapshot3 = (raw) => {
|
|
949
|
+
const obj = asRecord(raw);
|
|
950
|
+
const items = inlinedResponses(raw);
|
|
951
|
+
const failed = items.filter((item) => asRecord(item).error).length;
|
|
952
|
+
const id = asString(obj.name) ?? "";
|
|
953
|
+
return {
|
|
954
|
+
id: id ? assertPrefixedProviderId(OPERATION_ID_LABEL, id, GOOGLE_BATCH_PREFIX) : "",
|
|
955
|
+
provider: "google",
|
|
956
|
+
raw,
|
|
957
|
+
requestCounts: {
|
|
958
|
+
completed: items.length - failed,
|
|
959
|
+
failed,
|
|
960
|
+
total: items.length
|
|
961
|
+
},
|
|
962
|
+
status: mapState(asString(obj.state) ?? asString(asRecord(obj.state).name) ?? asString(asRecord(obj.metadata).state), obj.done === true)
|
|
963
|
+
};
|
|
964
|
+
};
|
|
965
|
+
var textFromResponse = (response) => {
|
|
966
|
+
const candidate = asRecord(asArray(asRecord(response).candidates)[0]);
|
|
967
|
+
const text = asArray(asRecord(candidate.content).parts).map((part) => asString(asRecord(part).text) ?? "").join("");
|
|
968
|
+
return text.length > 0 ? text : undefined;
|
|
969
|
+
};
|
|
970
|
+
var embeddingFromResponse = (response) => asNumberArray(asRecord(asRecord(response).embedding).values);
|
|
971
|
+
var imagesFromResponse = (response) => {
|
|
972
|
+
const candidate = asRecord(asArray(asRecord(response).candidates)[0]);
|
|
973
|
+
const images = [];
|
|
974
|
+
for (const part of asArray(asRecord(candidate.content).parts)) {
|
|
975
|
+
const partObj = asRecord(part);
|
|
976
|
+
const inline = asRecord(partObj.inlineData ?? partObj.inline_data);
|
|
977
|
+
const data = asString(inline.data);
|
|
978
|
+
const mediaType = asString(inline.mimeType) ?? asString(inline.mime_type);
|
|
979
|
+
if (data && mediaType?.startsWith("image/")) {
|
|
980
|
+
images.push({ data, mediaType });
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
return images.length > 0 ? images : undefined;
|
|
984
|
+
};
|
|
985
|
+
var usageFromResponse = (response) => {
|
|
986
|
+
const usage = asRecord(asRecord(response).usageMetadata);
|
|
987
|
+
const inputTokens = asNumber(usage.promptTokenCount);
|
|
988
|
+
const outputTokens = asNumber(usage.candidatesTokenCount);
|
|
989
|
+
const totalTokens = asNumber(usage.totalTokenCount);
|
|
990
|
+
if (inputTokens === undefined && outputTokens === undefined && totalTokens === undefined) {
|
|
991
|
+
return;
|
|
992
|
+
}
|
|
993
|
+
return {
|
|
994
|
+
inputTokens,
|
|
995
|
+
outputTokens,
|
|
996
|
+
totalTokens: totalTokens ?? (inputTokens ?? 0) + (outputTokens ?? 0)
|
|
997
|
+
};
|
|
998
|
+
};
|
|
999
|
+
var normalizeResult2 = (item) => {
|
|
1000
|
+
const obj = asRecord(item);
|
|
1001
|
+
const customId = asString(asRecord(obj.metadata).key) ?? asString(obj.key) ?? asString(obj.custom_id) ?? "";
|
|
1002
|
+
if (obj.error) {
|
|
1003
|
+
const error = asRecord(obj.error);
|
|
1004
|
+
return {
|
|
1005
|
+
customId,
|
|
1006
|
+
error: {
|
|
1007
|
+
code: asNumber(error.code) ?? asString(error.code),
|
|
1008
|
+
message: asString(error.message) ?? "Request errored.",
|
|
1009
|
+
type: asString(error.status)
|
|
1010
|
+
},
|
|
1011
|
+
response: obj.error,
|
|
1012
|
+
status: "errored"
|
|
1013
|
+
};
|
|
1014
|
+
}
|
|
1015
|
+
return {
|
|
1016
|
+
customId,
|
|
1017
|
+
embedding: embeddingFromResponse(obj.response),
|
|
1018
|
+
images: imagesFromResponse(obj.response),
|
|
1019
|
+
response: obj.response,
|
|
1020
|
+
status: "succeeded",
|
|
1021
|
+
text: textFromResponse(obj.response),
|
|
1022
|
+
usage: usageFromResponse(obj.response)
|
|
1023
|
+
};
|
|
1024
|
+
};
|
|
1025
|
+
var EMBED_CONFIG_KEYS = new Set([
|
|
1026
|
+
"outputDimensionality",
|
|
1027
|
+
"taskType",
|
|
1028
|
+
"title"
|
|
1029
|
+
]);
|
|
1030
|
+
var toEmbedRequest = (body) => {
|
|
1031
|
+
const request = {};
|
|
1032
|
+
const config = {};
|
|
1033
|
+
for (const [key, value] of Object.entries(body)) {
|
|
1034
|
+
if (EMBED_CONFIG_KEYS.has(key)) {
|
|
1035
|
+
config[key] = value;
|
|
1036
|
+
} else {
|
|
1037
|
+
request[key] = value;
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
if (Object.keys(config).length > 0) {
|
|
1041
|
+
request.embedContentConfig = config;
|
|
1042
|
+
}
|
|
1043
|
+
return request;
|
|
1044
|
+
};
|
|
1045
|
+
var submit2 = async (input) => {
|
|
1046
|
+
const limits = resolveBatchLimits(input.limits);
|
|
1047
|
+
const isEmbedding = input.endpoint.toLowerCase().includes("embedcontent");
|
|
1048
|
+
const method = isEmbedding ? "asyncBatchEmbedContent" : "batchGenerateContent";
|
|
1049
|
+
const requests = input.built.map((item) => {
|
|
1050
|
+
const payload = omit(item.body, "stream");
|
|
1051
|
+
return {
|
|
1052
|
+
metadata: { key: item.customId },
|
|
1053
|
+
request: isEmbedding ? toEmbedRequest(payload) : payload
|
|
1054
|
+
};
|
|
1055
|
+
});
|
|
1056
|
+
const body = encodeJsonArrayPayload({
|
|
1057
|
+
items: requests,
|
|
1058
|
+
label: "batch upload payload",
|
|
1059
|
+
maxBytes: limits.maxUploadBytes,
|
|
1060
|
+
prefix: '{"batch":{"display_name":"batchwork","input_config":{"requests":{"requests":[',
|
|
1061
|
+
suffix: "]}}}}"
|
|
1062
|
+
});
|
|
1063
|
+
const raw = await requestJson(`${baseUrl3(input.credentials)}/models/${input.modelId}:${method}`, {
|
|
1064
|
+
body,
|
|
1065
|
+
headers: headers2(input.credentials),
|
|
1066
|
+
method: "POST"
|
|
1067
|
+
});
|
|
1068
|
+
return normalizeSnapshot3(raw);
|
|
1069
|
+
};
|
|
1070
|
+
var retrieve2 = async (id, credentials) => {
|
|
1071
|
+
const operationId = assertPrefixedProviderId(OPERATION_ID_LABEL, id, GOOGLE_BATCH_PREFIX);
|
|
1072
|
+
const raw = await requestJson(`${baseUrl3(credentials)}/${operationId}`, {
|
|
1073
|
+
headers: headers2(credentials)
|
|
1074
|
+
});
|
|
1075
|
+
return normalizeSnapshot3(raw);
|
|
1076
|
+
};
|
|
1077
|
+
var fileNameFrom = (value) => asString(asRecord(value).name) ?? asString(value);
|
|
1078
|
+
async function* results2(id, credentials) {
|
|
1079
|
+
const snapshot = await retrieve2(id, credentials);
|
|
1080
|
+
const raw = asRecord(snapshot.raw);
|
|
1081
|
+
const response = asRecord(raw.response);
|
|
1082
|
+
const dest = asRecord(raw.dest);
|
|
1083
|
+
const responsesFile = fileNameFrom(response.responsesFile) ?? fileNameFrom(response.responses_file) ?? asString(dest.fileName) ?? asString(dest.file_name);
|
|
1084
|
+
if (responsesFile) {
|
|
1085
|
+
throw new BatchworkError(`batchwork: batch "${id}" returned file-mode results, which are not supported yet.`);
|
|
1086
|
+
}
|
|
1087
|
+
const items = inlinedResponses(raw);
|
|
1088
|
+
if (items.length === 0) {
|
|
1089
|
+
throw new BatchworkError(`batchwork: results are not ready for batch "${id}" (status: ${snapshot.status}).`);
|
|
1090
|
+
}
|
|
1091
|
+
for (const item of items) {
|
|
1092
|
+
yield normalizeResult2(item);
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
var cancel2 = async (id, credentials) => {
|
|
1096
|
+
const operationId = assertPrefixedProviderId(OPERATION_ID_LABEL, id, GOOGLE_BATCH_PREFIX);
|
|
1097
|
+
await requestJson(`${baseUrl3(credentials)}/${operationId}:cancel`, {
|
|
1098
|
+
headers: headers2(credentials),
|
|
1099
|
+
method: "POST"
|
|
1100
|
+
});
|
|
1101
|
+
};
|
|
1102
|
+
var googleAdapter = {
|
|
1103
|
+
cancel: cancel2,
|
|
1104
|
+
id: "google",
|
|
1105
|
+
results: results2,
|
|
1106
|
+
retrieve: retrieve2,
|
|
1107
|
+
submit: submit2
|
|
1041
1108
|
};
|
|
1042
1109
|
|
|
1043
1110
|
// src/providers/groq.ts
|
|
@@ -1054,8 +1121,8 @@ var groqAdapter = createOpenAICompatibleAdapter({
|
|
|
1054
1121
|
var MISTRAL_BASE = "https://api.mistral.ai/v1";
|
|
1055
1122
|
var JOB_ID_LABEL = "Mistral job id";
|
|
1056
1123
|
var apiKey3 = (credentials) => resolveApiKey(credentials, "MISTRAL_API_KEY", "Mistral");
|
|
1057
|
-
var
|
|
1058
|
-
var
|
|
1124
|
+
var baseUrl4 = (credentials) => credentials.baseURL ?? MISTRAL_BASE;
|
|
1125
|
+
var authHeaders2 = (credentials) => ({
|
|
1059
1126
|
Authorization: `Bearer ${apiKey3(credentials)}`,
|
|
1060
1127
|
...credentials.headers
|
|
1061
1128
|
});
|
|
@@ -1109,8 +1176,8 @@ var submit3 = async (input) => {
|
|
|
1109
1176
|
body: omit(omit(item.body, "stream"), "model"),
|
|
1110
1177
|
custom_id: item.customId
|
|
1111
1178
|
})), { label: "batch upload JSONL", maxBytes: limits.maxUploadBytes });
|
|
1112
|
-
const inputFileId = await uploadInputFile(jsonl,
|
|
1113
|
-
const raw = await requestJson(`${
|
|
1179
|
+
const inputFileId = await uploadInputFile(jsonl, baseUrl4(input.credentials), authHeaders2(input.credentials));
|
|
1180
|
+
const raw = await requestJson(`${baseUrl4(input.credentials)}/batch/jobs`, {
|
|
1114
1181
|
body: JSON.stringify({
|
|
1115
1182
|
endpoint: input.endpoint,
|
|
1116
1183
|
input_files: [inputFileId],
|
|
@@ -1118,7 +1185,7 @@ var submit3 = async (input) => {
|
|
|
1118
1185
|
model: input.modelId
|
|
1119
1186
|
}),
|
|
1120
1187
|
headers: {
|
|
1121
|
-
...
|
|
1188
|
+
...authHeaders2(input.credentials),
|
|
1122
1189
|
"content-type": "application/json"
|
|
1123
1190
|
},
|
|
1124
1191
|
method: "POST"
|
|
@@ -1127,8 +1194,8 @@ var submit3 = async (input) => {
|
|
|
1127
1194
|
};
|
|
1128
1195
|
var retrieve3 = async (id, credentials) => {
|
|
1129
1196
|
const jobId = assertSimpleProviderId(JOB_ID_LABEL, id);
|
|
1130
|
-
const raw = await requestJson(`${
|
|
1131
|
-
headers:
|
|
1197
|
+
const raw = await requestJson(`${baseUrl4(credentials)}/batch/jobs/${jobId}`, {
|
|
1198
|
+
headers: authHeaders2(credentials)
|
|
1132
1199
|
});
|
|
1133
1200
|
return normalizeSnapshot4(raw);
|
|
1134
1201
|
};
|
|
@@ -1137,12 +1204,12 @@ async function* results3(id, credentials) {
|
|
|
1137
1204
|
const raw = asRecord(snapshot.raw);
|
|
1138
1205
|
const outputFileId = asString(raw.output_file);
|
|
1139
1206
|
const errorFileId = asString(raw.error_file);
|
|
1140
|
-
const headers3 =
|
|
1207
|
+
const headers3 = authHeaders2(credentials);
|
|
1141
1208
|
if (outputFileId) {
|
|
1142
|
-
yield* streamResultFile(assertSimpleProviderId("Mistral output file id", outputFileId),
|
|
1209
|
+
yield* streamResultFile(assertSimpleProviderId("Mistral output file id", outputFileId), baseUrl4(credentials), headers3);
|
|
1143
1210
|
}
|
|
1144
1211
|
if (errorFileId) {
|
|
1145
|
-
yield* streamResultFile(assertSimpleProviderId("Mistral error file id", errorFileId),
|
|
1212
|
+
yield* streamResultFile(assertSimpleProviderId("Mistral error file id", errorFileId), baseUrl4(credentials), headers3);
|
|
1146
1213
|
}
|
|
1147
1214
|
if (!(outputFileId || errorFileId)) {
|
|
1148
1215
|
throw new BatchworkError(`batchwork: results are not ready for batch "${id}" (status: ${snapshot.status}).`);
|
|
@@ -1150,8 +1217,8 @@ async function* results3(id, credentials) {
|
|
|
1150
1217
|
}
|
|
1151
1218
|
var cancel3 = async (id, credentials) => {
|
|
1152
1219
|
const jobId = assertSimpleProviderId(JOB_ID_LABEL, id);
|
|
1153
|
-
await requestJson(`${
|
|
1154
|
-
headers:
|
|
1220
|
+
await requestJson(`${baseUrl4(credentials)}/batch/jobs/${jobId}/cancel`, {
|
|
1221
|
+
headers: authHeaders2(credentials),
|
|
1155
1222
|
method: "POST"
|
|
1156
1223
|
});
|
|
1157
1224
|
};
|
|
@@ -1292,8 +1359,8 @@ var XAI_BASE = "https://api.x.ai/v1";
|
|
|
1292
1359
|
var BATCH_ID_LABEL = "xAI batch id";
|
|
1293
1360
|
var RESULTS_PAGE_SIZE = 100;
|
|
1294
1361
|
var apiKey4 = (credentials) => resolveApiKey(credentials, "XAI_API_KEY", "xAI");
|
|
1295
|
-
var
|
|
1296
|
-
var
|
|
1362
|
+
var baseUrl5 = (credentials) => credentials.baseURL ?? XAI_BASE;
|
|
1363
|
+
var authHeaders3 = (credentials) => ({
|
|
1297
1364
|
Authorization: `Bearer ${apiKey4(credentials)}`,
|
|
1298
1365
|
...credentials.headers
|
|
1299
1366
|
});
|
|
@@ -1411,11 +1478,11 @@ var submit4 = async (input) => {
|
|
|
1411
1478
|
method: "POST",
|
|
1412
1479
|
url: item.endpoint || input.endpoint
|
|
1413
1480
|
})), { label: "batch upload JSONL", maxBytes: limits.maxUploadBytes });
|
|
1414
|
-
const inputFileId = await uploadInputFile(jsonl,
|
|
1415
|
-
const raw = await requestJson(`${
|
|
1481
|
+
const inputFileId = await uploadInputFile(jsonl, baseUrl5(input.credentials), authHeaders3(input.credentials), { purpose: null });
|
|
1482
|
+
const raw = await requestJson(`${baseUrl5(input.credentials)}/batches`, {
|
|
1416
1483
|
body: JSON.stringify({ input_file_id: inputFileId, name: "batchwork" }),
|
|
1417
1484
|
headers: {
|
|
1418
|
-
...
|
|
1485
|
+
...authHeaders3(input.credentials),
|
|
1419
1486
|
"content-type": "application/json"
|
|
1420
1487
|
},
|
|
1421
1488
|
method: "POST"
|
|
@@ -1424,21 +1491,21 @@ var submit4 = async (input) => {
|
|
|
1424
1491
|
};
|
|
1425
1492
|
var retrieve4 = async (id, credentials) => {
|
|
1426
1493
|
const batchId = assertSimpleProviderId(BATCH_ID_LABEL, id);
|
|
1427
|
-
const raw = await requestJson(`${
|
|
1428
|
-
headers:
|
|
1494
|
+
const raw = await requestJson(`${baseUrl5(credentials)}/batches/${batchId}`, {
|
|
1495
|
+
headers: authHeaders3(credentials)
|
|
1429
1496
|
});
|
|
1430
1497
|
return normalizeSnapshot5(raw);
|
|
1431
1498
|
};
|
|
1432
1499
|
async function* results4(id, credentials) {
|
|
1433
1500
|
const batchId = assertSimpleProviderId(BATCH_ID_LABEL, id);
|
|
1434
|
-
const headers3 =
|
|
1501
|
+
const headers3 = authHeaders3(credentials);
|
|
1435
1502
|
let token;
|
|
1436
1503
|
do {
|
|
1437
1504
|
const query = new URLSearchParams({ limit: String(RESULTS_PAGE_SIZE) });
|
|
1438
1505
|
if (token) {
|
|
1439
1506
|
query.set("pagination_token", token);
|
|
1440
1507
|
}
|
|
1441
|
-
const raw = await requestJson(`${
|
|
1508
|
+
const raw = await requestJson(`${baseUrl5(credentials)}/batches/${batchId}/results?${query.toString()}`, { headers: headers3 });
|
|
1442
1509
|
const page = asRecord(raw);
|
|
1443
1510
|
for (const item of Array.isArray(page.results) ? page.results : []) {
|
|
1444
1511
|
yield normalizeResult3(item);
|
|
@@ -1448,8 +1515,8 @@ async function* results4(id, credentials) {
|
|
|
1448
1515
|
}
|
|
1449
1516
|
var cancel4 = async (id, credentials) => {
|
|
1450
1517
|
const batchId = assertSimpleProviderId(BATCH_ID_LABEL, id);
|
|
1451
|
-
await requestJson(`${
|
|
1452
|
-
headers:
|
|
1518
|
+
await requestJson(`${baseUrl5(credentials)}/batches/${batchId}:cancel`, {
|
|
1519
|
+
headers: authHeaders3(credentials),
|
|
1453
1520
|
method: "POST"
|
|
1454
1521
|
});
|
|
1455
1522
|
};
|
|
@@ -1464,6 +1531,7 @@ var xaiAdapter = {
|
|
|
1464
1531
|
// src/providers/index.ts
|
|
1465
1532
|
var adapters = {
|
|
1466
1533
|
anthropic: anthropicAdapter,
|
|
1534
|
+
azure: azureAdapter,
|
|
1467
1535
|
google: googleAdapter,
|
|
1468
1536
|
groq: groqAdapter,
|
|
1469
1537
|
mistral: mistralAdapter,
|
|
@@ -1473,7 +1541,7 @@ var adapters = {
|
|
|
1473
1541
|
};
|
|
1474
1542
|
var getAdapter = (provider) => adapters[provider];
|
|
1475
1543
|
|
|
1476
|
-
export { BatchworkError, UnsupportedProviderError, MissingDependencyError, resolveBatchLimits, assertByteLength,
|
|
1544
|
+
export { BatchworkError, UnsupportedProviderError, MissingDependencyError, resolveBatchLimits, assertByteLength, trimTrailingSlashes, isTerminalStatus, BatchJob, getAdapter };
|
|
1477
1545
|
|
|
1478
|
-
//# debugId=
|
|
1479
|
-
//# sourceMappingURL=chunk-
|
|
1546
|
+
//# debugId=C29D2DE3DBB0695664756E2164756E21
|
|
1547
|
+
//# sourceMappingURL=chunk-n50t31ca.js.map
|