batchwork 1.0.0 → 1.1.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 +25 -0
- package/dist/batch.d.ts +18 -1
- package/dist/batch.d.ts.map +1 -1
- package/dist/body.d.ts +10 -2
- package/dist/body.d.ts.map +1 -1
- package/dist/{chunk-zp2cxkyb.js → chunk-d0g9wsxq.js} +162 -13
- package/dist/chunk-d0g9wsxq.js.map +13 -0
- package/dist/{chunk-kv3847wy.js → chunk-xtk2ycy6.js} +349 -78
- package/dist/chunk-xtk2ycy6.js.map +27 -0
- package/dist/{chunk-ab2d71gk.js → chunk-yzjd83s9.js} +120 -21
- package/dist/chunk-yzjd83s9.js.map +12 -0
- package/dist/errors.d.ts +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/http.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/job.d.ts.map +1 -1
- package/dist/jsonl.d.ts +10 -16
- package/dist/jsonl.d.ts.map +1 -1
- package/dist/limits.d.ts +13 -0
- package/dist/limits.d.ts.map +1 -0
- package/dist/model.d.ts +16 -2
- package/dist/model.d.ts.map +1 -1
- package/dist/next/index.d.ts +3 -1
- package/dist/next/index.d.ts.map +1 -1
- package/dist/next/index.js +7 -4
- package/dist/next/index.js.map +3 -3
- package/dist/payload.d.ts +10 -0
- package/dist/payload.d.ts.map +1 -0
- package/dist/providers/adapter.d.ts +2 -1
- package/dist/providers/adapter.d.ts.map +1 -1
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/google.d.ts.map +1 -1
- package/dist/providers/ids.d.ts +3 -0
- package/dist/providers/ids.d.ts.map +1 -0
- package/dist/providers/mistral.d.ts.map +1 -1
- package/dist/providers/openai-compatible.d.ts.map +1 -1
- package/dist/providers/shared.d.ts +2 -0
- 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.d.ts +2 -2
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +2 -2
- package/dist/server/poller.d.ts +3 -0
- package/dist/server/poller.d.ts.map +1 -1
- package/dist/server/signing.d.ts +10 -2
- package/dist/server/signing.d.ts.map +1 -1
- package/dist/types.d.ts +31 -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 +1 -1
- package/dist/chunk-ab2d71gk.js.map +0 -12
- package/dist/chunk-kv3847wy.js.map +0 -24
- package/dist/chunk-zp2cxkyb.js.map +0 -13
|
@@ -8,8 +8,8 @@ class BatchworkError extends Error {
|
|
|
8
8
|
|
|
9
9
|
class UnsupportedProviderError extends BatchworkError {
|
|
10
10
|
provider;
|
|
11
|
-
constructor(provider) {
|
|
12
|
-
super(`batchwork: provider "${provider}" is not supported yet. Supported providers: openai, anthropic, google, groq, mistral, together, xai.`);
|
|
11
|
+
constructor(provider, detail) {
|
|
12
|
+
super(detail ?? `batchwork: provider "${provider}" is not supported yet. Supported providers: openai, anthropic, google, groq, mistral, together, xai.`);
|
|
13
13
|
this.name = "UnsupportedProviderError";
|
|
14
14
|
this.provider = provider;
|
|
15
15
|
}
|
|
@@ -36,11 +36,16 @@ var delay = (ms, signal) => new Promise((resolve, reject) => {
|
|
|
36
36
|
reject(new BatchworkError("batchwork: wait aborted."));
|
|
37
37
|
return;
|
|
38
38
|
}
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
let timer;
|
|
40
|
+
const onAbort = () => {
|
|
41
41
|
clearTimeout(timer);
|
|
42
42
|
reject(new BatchworkError("batchwork: wait aborted."));
|
|
43
|
-
}
|
|
43
|
+
};
|
|
44
|
+
timer = setTimeout(() => {
|
|
45
|
+
signal?.removeEventListener("abort", onAbort);
|
|
46
|
+
resolve();
|
|
47
|
+
}, ms);
|
|
48
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
44
49
|
});
|
|
45
50
|
|
|
46
51
|
class BatchJob {
|
|
@@ -103,28 +108,67 @@ class BatchJob {
|
|
|
103
108
|
}
|
|
104
109
|
}
|
|
105
110
|
|
|
106
|
-
// src/
|
|
107
|
-
var
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
111
|
+
// src/limits.ts
|
|
112
|
+
var DEFAULT_LIMITS = {
|
|
113
|
+
captureConcurrency: 16,
|
|
114
|
+
maxRequestBytes: 20 * 1024 * 1024,
|
|
115
|
+
maxRequests: 50000,
|
|
116
|
+
maxUploadBytes: 200 * 1024 * 1024
|
|
117
|
+
};
|
|
118
|
+
var encoder = new TextEncoder;
|
|
119
|
+
var positiveInteger = (name, value) => {
|
|
120
|
+
if (!(Number.isInteger(value) && value > 0)) {
|
|
121
|
+
throw new BatchworkError(`batchwork: limits.${name} must be a positive integer.`);
|
|
112
122
|
}
|
|
123
|
+
return value;
|
|
124
|
+
};
|
|
125
|
+
var resolveBatchLimits = (limits) => ({
|
|
126
|
+
captureConcurrency: positiveInteger("captureConcurrency", limits?.captureConcurrency ?? DEFAULT_LIMITS.captureConcurrency),
|
|
127
|
+
maxRequestBytes: positiveInteger("maxRequestBytes", limits?.maxRequestBytes ?? DEFAULT_LIMITS.maxRequestBytes),
|
|
128
|
+
maxRequests: positiveInteger("maxRequests", limits?.maxRequests ?? DEFAULT_LIMITS.maxRequests),
|
|
129
|
+
maxUploadBytes: positiveInteger("maxUploadBytes", limits?.maxUploadBytes ?? DEFAULT_LIMITS.maxUploadBytes)
|
|
130
|
+
});
|
|
131
|
+
var byteLength = (value) => encoder.encode(value).length;
|
|
132
|
+
var assertByteCount = (label, bytes, maxBytes) => {
|
|
133
|
+
if (bytes > maxBytes) {
|
|
134
|
+
throw new BatchworkError(`batchwork: ${label} is ${bytes} bytes, exceeding the ${maxBytes} byte limit.`);
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
var assertByteLength = (label, value, maxBytes) => {
|
|
138
|
+
assertByteCount(label, byteLength(value), maxBytes);
|
|
139
|
+
};
|
|
140
|
+
var mapWithConcurrency = async (items, concurrency, mapper) => {
|
|
141
|
+
const results = [];
|
|
142
|
+
results.length = items.length;
|
|
143
|
+
let nextIndex = 0;
|
|
144
|
+
const workerCount = Math.min(concurrency, items.length);
|
|
145
|
+
const runNext = async () => {
|
|
146
|
+
const index = nextIndex;
|
|
147
|
+
nextIndex += 1;
|
|
148
|
+
if (index >= items.length) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
results[index] = await mapper(items[index]);
|
|
152
|
+
await runNext();
|
|
153
|
+
};
|
|
154
|
+
await Promise.all(Array.from({ length: workerCount }, () => runNext()));
|
|
155
|
+
return results;
|
|
113
156
|
};
|
|
114
|
-
|
|
157
|
+
|
|
158
|
+
// src/http.ts
|
|
159
|
+
var assertOk = (url, init, response) => {
|
|
115
160
|
if (!response.ok) {
|
|
116
|
-
|
|
117
|
-
throw new BatchworkError(`batchwork: ${init.method ?? "GET"} ${url} failed with ${response.status}: ${detail}`);
|
|
161
|
+
throw new BatchworkError(`batchwork: ${init.method ?? "GET"} ${url} failed with ${response.status}.`);
|
|
118
162
|
}
|
|
119
163
|
};
|
|
120
164
|
var requestJson = async (url, init) => {
|
|
121
165
|
const response = await fetch(url, init);
|
|
122
|
-
|
|
166
|
+
assertOk(url, init, response);
|
|
123
167
|
return await response.json();
|
|
124
168
|
};
|
|
125
169
|
var requestStream = async (url, init) => {
|
|
126
170
|
const response = await fetch(url, init);
|
|
127
|
-
|
|
171
|
+
assertOk(url, init, response);
|
|
128
172
|
if (!response.body) {
|
|
129
173
|
throw new BatchworkError(`batchwork: ${url} returned an empty body.`);
|
|
130
174
|
}
|
|
@@ -134,12 +178,60 @@ var requestStream = async (url, init) => {
|
|
|
134
178
|
// src/jsonl.ts
|
|
135
179
|
var NEWLINE = `
|
|
136
180
|
`;
|
|
137
|
-
var
|
|
181
|
+
var DEFAULT_MAX_JSONL_LINE_BYTES = 20 * 1024 * 1024;
|
|
182
|
+
var NEWLINE_BYTES = byteLength(NEWLINE);
|
|
183
|
+
var resolveMaxLineBytes = (options) => {
|
|
184
|
+
const maxLineBytes = options?.maxLineBytes ?? DEFAULT_MAX_JSONL_LINE_BYTES;
|
|
185
|
+
if (!(Number.isInteger(maxLineBytes) && maxLineBytes > 0)) {
|
|
186
|
+
throw new BatchworkError("batchwork: JSONL maxLineBytes must be a positive integer.");
|
|
187
|
+
}
|
|
188
|
+
return maxLineBytes;
|
|
189
|
+
};
|
|
190
|
+
var assertLineSize = (line, lineNumber, maxLineBytes) => {
|
|
191
|
+
const bytes = byteLength(line);
|
|
192
|
+
if (bytes > maxLineBytes) {
|
|
193
|
+
throw new BatchworkError(`batchwork: JSONL line ${lineNumber} is ${bytes} bytes, exceeding the ${maxLineBytes} byte limit.`);
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
var parseLine = (line, lineNumber, maxLineBytes) => {
|
|
197
|
+
assertLineSize(line, lineNumber, maxLineBytes);
|
|
198
|
+
const trimmed = line.trim();
|
|
199
|
+
if (trimmed.length === 0) {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
try {
|
|
203
|
+
return JSON.parse(trimmed);
|
|
204
|
+
} catch (error) {
|
|
205
|
+
throw new BatchworkError(`batchwork: invalid JSONL at line ${lineNumber}.`, { cause: error });
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
var resolveMaxBytes = (options) => {
|
|
209
|
+
const maxBytes = options?.maxBytes;
|
|
210
|
+
if (maxBytes !== undefined && !(Number.isInteger(maxBytes) && maxBytes > 0)) {
|
|
211
|
+
throw new BatchworkError("batchwork: JSONL maxBytes must be a positive integer.");
|
|
212
|
+
}
|
|
213
|
+
return maxBytes;
|
|
214
|
+
};
|
|
215
|
+
var encodeJsonl = (items, options) => {
|
|
138
216
|
if (items.length === 0) {
|
|
139
217
|
return "";
|
|
140
218
|
}
|
|
141
|
-
const
|
|
142
|
-
|
|
219
|
+
const lines = [];
|
|
220
|
+
const maxBytes = resolveMaxBytes(options);
|
|
221
|
+
const label = options?.label ?? "JSONL";
|
|
222
|
+
let bytes = 0;
|
|
223
|
+
for (const item of items) {
|
|
224
|
+
const line = JSON.stringify(item);
|
|
225
|
+
if (line === undefined) {
|
|
226
|
+
throw new BatchworkError(`batchwork: ${label} contains a value that cannot be JSON encoded.`);
|
|
227
|
+
}
|
|
228
|
+
bytes += byteLength(line) + NEWLINE_BYTES;
|
|
229
|
+
if (maxBytes !== undefined) {
|
|
230
|
+
assertByteCount(label, bytes, maxBytes);
|
|
231
|
+
}
|
|
232
|
+
lines.push(line);
|
|
233
|
+
}
|
|
234
|
+
return `${lines.join(NEWLINE)}${NEWLINE}`;
|
|
143
235
|
};
|
|
144
236
|
var isReadableStream = (source) => ("getReader" in source) && typeof source.getReader === "function";
|
|
145
237
|
async function* toByteIterable(source) {
|
|
@@ -160,28 +252,59 @@ async function* toByteIterable(source) {
|
|
|
160
252
|
}
|
|
161
253
|
yield* source;
|
|
162
254
|
}
|
|
163
|
-
async function* streamJsonl(source) {
|
|
255
|
+
async function* streamJsonl(source, options) {
|
|
164
256
|
const decoder = new TextDecoder;
|
|
257
|
+
const maxLineBytes = resolveMaxLineBytes(options);
|
|
165
258
|
let buffer = "";
|
|
259
|
+
let lineNumber = 1;
|
|
166
260
|
for await (const chunk of toByteIterable(source)) {
|
|
167
261
|
buffer += decoder.decode(chunk, { stream: true });
|
|
168
262
|
let newlineIndex = buffer.indexOf(NEWLINE);
|
|
169
263
|
while (newlineIndex !== -1) {
|
|
170
|
-
const line = buffer.slice(0, newlineIndex)
|
|
264
|
+
const line = buffer.slice(0, newlineIndex);
|
|
171
265
|
buffer = buffer.slice(newlineIndex + 1);
|
|
172
|
-
|
|
173
|
-
|
|
266
|
+
const parsed2 = parseLine(line, lineNumber, maxLineBytes);
|
|
267
|
+
if (parsed2 !== undefined) {
|
|
268
|
+
yield parsed2;
|
|
174
269
|
}
|
|
270
|
+
lineNumber += 1;
|
|
175
271
|
newlineIndex = buffer.indexOf(NEWLINE);
|
|
176
272
|
}
|
|
273
|
+
assertLineSize(buffer, lineNumber, maxLineBytes);
|
|
177
274
|
}
|
|
178
275
|
buffer += decoder.decode();
|
|
179
|
-
const
|
|
180
|
-
if (
|
|
181
|
-
yield
|
|
276
|
+
const parsed = parseLine(buffer, lineNumber, maxLineBytes);
|
|
277
|
+
if (parsed !== undefined) {
|
|
278
|
+
yield parsed;
|
|
182
279
|
}
|
|
183
280
|
}
|
|
184
281
|
|
|
282
|
+
// src/payload.ts
|
|
283
|
+
var encodeJsonArrayPayload = ({
|
|
284
|
+
items,
|
|
285
|
+
label,
|
|
286
|
+
maxBytes,
|
|
287
|
+
prefix,
|
|
288
|
+
suffix
|
|
289
|
+
}) => {
|
|
290
|
+
const encodedItems = [];
|
|
291
|
+
let bytes = byteLength(prefix) + byteLength(suffix);
|
|
292
|
+
assertByteCount(label, bytes, maxBytes);
|
|
293
|
+
for (const [index, item] of items.entries()) {
|
|
294
|
+
const encoded = JSON.stringify(item);
|
|
295
|
+
if (encoded === undefined) {
|
|
296
|
+
throw new BatchworkError(`batchwork: ${label} contains a value that cannot be JSON encoded.`);
|
|
297
|
+
}
|
|
298
|
+
bytes += byteLength(encoded);
|
|
299
|
+
if (index > 0) {
|
|
300
|
+
bytes += 1;
|
|
301
|
+
}
|
|
302
|
+
assertByteCount(label, bytes, maxBytes);
|
|
303
|
+
encodedItems.push(encoded);
|
|
304
|
+
}
|
|
305
|
+
return `${prefix}${encodedItems.join(",")}${suffix}`;
|
|
306
|
+
};
|
|
307
|
+
|
|
185
308
|
// src/util.ts
|
|
186
309
|
var asRecord = (value) => {
|
|
187
310
|
if (typeof value === "object" && value !== null) {
|
|
@@ -192,6 +315,13 @@ var asRecord = (value) => {
|
|
|
192
315
|
var asString = (value) => typeof value === "string" ? value : undefined;
|
|
193
316
|
var asNumber = (value) => typeof value === "number" ? value : undefined;
|
|
194
317
|
var asArray = (value) => Array.isArray(value) ? value : [];
|
|
318
|
+
var asNumberArray = (value) => {
|
|
319
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
const numbers = value.filter((item) => typeof item === "number");
|
|
323
|
+
return numbers.length === value.length ? numbers : undefined;
|
|
324
|
+
};
|
|
195
325
|
var omit = (obj, key) => {
|
|
196
326
|
const result = {};
|
|
197
327
|
for (const [k, v] of Object.entries(obj)) {
|
|
@@ -201,13 +331,30 @@ var omit = (obj, key) => {
|
|
|
201
331
|
}
|
|
202
332
|
return result;
|
|
203
333
|
};
|
|
334
|
+
var validDate = (date) => Number.isNaN(date.getTime()) ? undefined : date;
|
|
204
335
|
var toDate = (value) => {
|
|
205
336
|
if (typeof value === "string") {
|
|
206
|
-
return new Date(value);
|
|
337
|
+
return validDate(new Date(value));
|
|
207
338
|
}
|
|
208
339
|
if (typeof value === "number") {
|
|
209
|
-
return new Date(value * 1000);
|
|
340
|
+
return validDate(new Date(value * 1000));
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
// src/providers/ids.ts
|
|
345
|
+
var SIMPLE_PROVIDER_ID = /^[A-Za-z0-9_-]+$/u;
|
|
346
|
+
var assertSimpleProviderId = (label, id) => {
|
|
347
|
+
if (!SIMPLE_PROVIDER_ID.test(id)) {
|
|
348
|
+
throw new BatchworkError(`batchwork: invalid ${label}.`);
|
|
210
349
|
}
|
|
350
|
+
return id;
|
|
351
|
+
};
|
|
352
|
+
var assertPrefixedProviderId = (label, id, prefix) => {
|
|
353
|
+
const [actualPrefix, value, ...rest] = id.split("/");
|
|
354
|
+
if (rest.length > 0 || actualPrefix !== prefix || !value || !SIMPLE_PROVIDER_ID.test(value)) {
|
|
355
|
+
throw new BatchworkError(`batchwork: invalid ${label}.`);
|
|
356
|
+
}
|
|
357
|
+
return id;
|
|
211
358
|
};
|
|
212
359
|
|
|
213
360
|
// src/providers/anthropic.ts
|
|
@@ -221,6 +368,25 @@ var apiKey = (credentials) => {
|
|
|
221
368
|
return key;
|
|
222
369
|
};
|
|
223
370
|
var baseUrl = (credentials) => credentials.baseURL ?? ANTHROPIC_BASE;
|
|
371
|
+
var validateResultsUrl = (rawUrl, credentials) => {
|
|
372
|
+
let resultsUrl;
|
|
373
|
+
let expectedBase;
|
|
374
|
+
try {
|
|
375
|
+
resultsUrl = new URL(rawUrl);
|
|
376
|
+
expectedBase = new URL(baseUrl(credentials));
|
|
377
|
+
} catch (error) {
|
|
378
|
+
throw new BatchworkError("batchwork: invalid Anthropic results_url.", {
|
|
379
|
+
cause: error
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
if (resultsUrl.origin !== expectedBase.origin) {
|
|
383
|
+
throw new BatchworkError("batchwork: Anthropic results_url must match the configured API origin.");
|
|
384
|
+
}
|
|
385
|
+
if (resultsUrl.username || resultsUrl.password) {
|
|
386
|
+
throw new BatchworkError("batchwork: Anthropic results_url must not include credentials.");
|
|
387
|
+
}
|
|
388
|
+
return resultsUrl.toString();
|
|
389
|
+
};
|
|
224
390
|
var headers = (credentials) => ({
|
|
225
391
|
"anthropic-version": ANTHROPIC_VERSION,
|
|
226
392
|
"content-type": "application/json",
|
|
@@ -313,19 +479,28 @@ var normalizeResult = (line) => {
|
|
|
313
479
|
return { customId, status: "canceled" };
|
|
314
480
|
};
|
|
315
481
|
var submit = async (input) => {
|
|
482
|
+
const limits = resolveBatchLimits(input.limits);
|
|
316
483
|
const requests = input.built.map((item) => ({
|
|
317
484
|
custom_id: item.customId,
|
|
318
485
|
params: omit(item.body, "stream")
|
|
319
486
|
}));
|
|
487
|
+
const body = encodeJsonArrayPayload({
|
|
488
|
+
items: requests,
|
|
489
|
+
label: "batch upload payload",
|
|
490
|
+
maxBytes: limits.maxUploadBytes,
|
|
491
|
+
prefix: '{"requests":[',
|
|
492
|
+
suffix: "]}"
|
|
493
|
+
});
|
|
320
494
|
const raw = await requestJson(`${baseUrl(input.credentials)}/v1/messages/batches`, {
|
|
321
|
-
body
|
|
495
|
+
body,
|
|
322
496
|
headers: headers(input.credentials),
|
|
323
497
|
method: "POST"
|
|
324
498
|
});
|
|
325
499
|
return normalizeSnapshot(raw);
|
|
326
500
|
};
|
|
327
501
|
var retrieve = async (id, credentials) => {
|
|
328
|
-
const
|
|
502
|
+
const batchId = assertSimpleProviderId("Anthropic batch id", id);
|
|
503
|
+
const raw = await requestJson(`${baseUrl(credentials)}/v1/messages/batches/${batchId}`, { headers: headers(credentials) });
|
|
329
504
|
return normalizeSnapshot(raw);
|
|
330
505
|
};
|
|
331
506
|
async function* results(id, credentials) {
|
|
@@ -334,15 +509,17 @@ async function* results(id, credentials) {
|
|
|
334
509
|
if (!resultsUrl) {
|
|
335
510
|
throw new BatchworkError(`batchwork: results are not ready for batch "${id}" (status: ${snapshot.status}).`);
|
|
336
511
|
}
|
|
337
|
-
const stream = await requestStream(resultsUrl, {
|
|
338
|
-
headers: headers(credentials)
|
|
512
|
+
const stream = await requestStream(validateResultsUrl(resultsUrl, credentials), {
|
|
513
|
+
headers: headers(credentials),
|
|
514
|
+
redirect: "manual"
|
|
339
515
|
});
|
|
340
516
|
for await (const line of streamJsonl(stream)) {
|
|
341
517
|
yield normalizeResult(line);
|
|
342
518
|
}
|
|
343
519
|
}
|
|
344
520
|
var cancel = async (id, credentials) => {
|
|
345
|
-
|
|
521
|
+
const batchId = assertSimpleProviderId("Anthropic batch id", id);
|
|
522
|
+
await requestJson(`${baseUrl(credentials)}/v1/messages/batches/${batchId}/cancel`, {
|
|
346
523
|
headers: headers(credentials),
|
|
347
524
|
method: "POST"
|
|
348
525
|
});
|
|
@@ -357,6 +534,7 @@ var anthropicAdapter = {
|
|
|
357
534
|
|
|
358
535
|
// src/providers/google.ts
|
|
359
536
|
var GOOGLE_BASE = "https://generativelanguage.googleapis.com/v1beta";
|
|
537
|
+
var GOOGLE_BATCH_PREFIX = "batches";
|
|
360
538
|
var apiKey2 = (credentials) => {
|
|
361
539
|
const key = credentials.apiKey ?? process.env.GOOGLE_GENERATIVE_AI_API_KEY ?? process.env.GEMINI_API_KEY;
|
|
362
540
|
if (!key) {
|
|
@@ -414,8 +592,9 @@ var normalizeSnapshot2 = (raw) => {
|
|
|
414
592
|
const obj = asRecord(raw);
|
|
415
593
|
const items = inlinedResponses(raw);
|
|
416
594
|
const failed = items.filter((item) => asRecord(item).error).length;
|
|
595
|
+
const id = asString(obj.name) ?? "";
|
|
417
596
|
return {
|
|
418
|
-
id:
|
|
597
|
+
id: id ? assertPrefixedProviderId("Google operation id", id, GOOGLE_BATCH_PREFIX) : "",
|
|
419
598
|
provider: "google",
|
|
420
599
|
raw,
|
|
421
600
|
requestCounts: {
|
|
@@ -431,6 +610,7 @@ var textFromResponse = (response) => {
|
|
|
431
610
|
const text = asArray(asRecord(candidate.content).parts).map((part) => asString(asRecord(part).text) ?? "").join("");
|
|
432
611
|
return text.length > 0 ? text : undefined;
|
|
433
612
|
};
|
|
613
|
+
var embeddingFromResponse = (response) => asNumberArray(asRecord(asRecord(response).embedding).values);
|
|
434
614
|
var usageFromResponse = (response) => {
|
|
435
615
|
const usage = asRecord(asRecord(response).usageMetadata);
|
|
436
616
|
const inputTokens = asNumber(usage.promptTokenCount);
|
|
@@ -463,31 +643,61 @@ var normalizeResult2 = (item) => {
|
|
|
463
643
|
}
|
|
464
644
|
return {
|
|
465
645
|
customId,
|
|
646
|
+
embedding: embeddingFromResponse(obj.response),
|
|
466
647
|
response: obj.response,
|
|
467
648
|
status: "succeeded",
|
|
468
649
|
text: textFromResponse(obj.response),
|
|
469
650
|
usage: usageFromResponse(obj.response)
|
|
470
651
|
};
|
|
471
652
|
};
|
|
653
|
+
var EMBED_CONFIG_KEYS = new Set([
|
|
654
|
+
"outputDimensionality",
|
|
655
|
+
"taskType",
|
|
656
|
+
"title"
|
|
657
|
+
]);
|
|
658
|
+
var toEmbedRequest = (body) => {
|
|
659
|
+
const request = {};
|
|
660
|
+
const config = {};
|
|
661
|
+
for (const [key, value] of Object.entries(body)) {
|
|
662
|
+
if (EMBED_CONFIG_KEYS.has(key)) {
|
|
663
|
+
config[key] = value;
|
|
664
|
+
} else {
|
|
665
|
+
request[key] = value;
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
if (Object.keys(config).length > 0) {
|
|
669
|
+
request.embedContentConfig = config;
|
|
670
|
+
}
|
|
671
|
+
return request;
|
|
672
|
+
};
|
|
472
673
|
var submit2 = async (input) => {
|
|
473
|
-
const
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
674
|
+
const limits = resolveBatchLimits(input.limits);
|
|
675
|
+
const isEmbedding = input.endpoint.toLowerCase().includes("embedcontent");
|
|
676
|
+
const method = isEmbedding ? "asyncBatchEmbedContent" : "batchGenerateContent";
|
|
677
|
+
const requests = input.built.map((item) => {
|
|
678
|
+
const payload = omit(item.body, "stream");
|
|
679
|
+
return {
|
|
680
|
+
metadata: { key: item.customId },
|
|
681
|
+
request: isEmbedding ? toEmbedRequest(payload) : payload
|
|
682
|
+
};
|
|
683
|
+
});
|
|
684
|
+
const body = encodeJsonArrayPayload({
|
|
685
|
+
items: requests,
|
|
686
|
+
label: "batch upload payload",
|
|
687
|
+
maxBytes: limits.maxUploadBytes,
|
|
688
|
+
prefix: '{"batch":{"display_name":"batchwork","input_config":{"requests":{"requests":[',
|
|
689
|
+
suffix: "]}}}}"
|
|
690
|
+
});
|
|
691
|
+
const raw = await requestJson(`${baseUrl2(input.credentials)}/models/${input.modelId}:${method}`, {
|
|
692
|
+
body,
|
|
484
693
|
headers: headers2(input.credentials),
|
|
485
694
|
method: "POST"
|
|
486
695
|
});
|
|
487
696
|
return normalizeSnapshot2(raw);
|
|
488
697
|
};
|
|
489
698
|
var retrieve2 = async (id, credentials) => {
|
|
490
|
-
const
|
|
699
|
+
const operationId = assertPrefixedProviderId("Google operation id", id, GOOGLE_BATCH_PREFIX);
|
|
700
|
+
const raw = await requestJson(`${baseUrl2(credentials)}/${operationId}`, {
|
|
491
701
|
headers: headers2(credentials)
|
|
492
702
|
});
|
|
493
703
|
return normalizeSnapshot2(raw);
|
|
@@ -510,7 +720,8 @@ async function* results2(id, credentials) {
|
|
|
510
720
|
}
|
|
511
721
|
}
|
|
512
722
|
var cancel2 = async (id, credentials) => {
|
|
513
|
-
|
|
723
|
+
const operationId = assertPrefixedProviderId("Google operation id", id, GOOGLE_BATCH_PREFIX);
|
|
724
|
+
await requestJson(`${baseUrl2(credentials)}/${operationId}:cancel`, {
|
|
514
725
|
headers: headers2(credentials),
|
|
515
726
|
method: "POST"
|
|
516
727
|
});
|
|
@@ -544,6 +755,13 @@ var textFromBody = (body) => {
|
|
|
544
755
|
}
|
|
545
756
|
return asString(obj.output_text);
|
|
546
757
|
};
|
|
758
|
+
var embeddingFromBody = (body) => {
|
|
759
|
+
const data = asArray(asRecord(body).data);
|
|
760
|
+
if (data.length === 0) {
|
|
761
|
+
return;
|
|
762
|
+
}
|
|
763
|
+
return asNumberArray(asRecord(data[0]).embedding);
|
|
764
|
+
};
|
|
547
765
|
var usageFromBody = (body) => {
|
|
548
766
|
const usage = asRecord(asRecord(body).usage);
|
|
549
767
|
const inputTokens = asNumber(usage.prompt_tokens) ?? asNumber(usage.input_tokens);
|
|
@@ -584,6 +802,7 @@ var normalizeOpenAIResult = (line) => {
|
|
|
584
802
|
if (statusCode >= HTTP_OK_MIN && statusCode < HTTP_OK_MAX) {
|
|
585
803
|
return {
|
|
586
804
|
customId,
|
|
805
|
+
embedding: embeddingFromBody(response.body),
|
|
587
806
|
response: response.body,
|
|
588
807
|
status: "succeeded",
|
|
589
808
|
text: textFromBody(response.body),
|
|
@@ -607,13 +826,15 @@ var uploadInputFile = async (jsonl, baseUrl3, headers3, options = {}) => {
|
|
|
607
826
|
const raw = await requestJson(`${baseUrl3}/files`, {
|
|
608
827
|
body: form,
|
|
609
828
|
headers: headers3,
|
|
610
|
-
method: "POST"
|
|
829
|
+
method: "POST",
|
|
830
|
+
redirect: "manual"
|
|
611
831
|
});
|
|
612
832
|
return raw.id;
|
|
613
833
|
};
|
|
614
834
|
async function* streamResultFile(fileId, baseUrl3, headers3) {
|
|
615
835
|
const stream = await requestStream(`${baseUrl3}/files/${fileId}/content`, {
|
|
616
|
-
headers: headers3
|
|
836
|
+
headers: headers3,
|
|
837
|
+
redirect: "manual"
|
|
617
838
|
});
|
|
618
839
|
for await (const line of streamJsonl(stream)) {
|
|
619
840
|
yield normalizeOpenAIResult(line);
|
|
@@ -669,6 +890,7 @@ var createOpenAICompatibleAdapter = (config) => {
|
|
|
669
890
|
...credentials.headers
|
|
670
891
|
});
|
|
671
892
|
const submit3 = async (input) => {
|
|
893
|
+
const limits = resolveBatchLimits(input.limits);
|
|
672
894
|
const endpoint = config.normalizeEndpoint ? config.normalizeEndpoint(input.endpoint) : input.endpoint;
|
|
673
895
|
const jsonl = encodeJsonl(input.built.map((item) => {
|
|
674
896
|
const body = omit(item.body, "stream");
|
|
@@ -681,7 +903,7 @@ var createOpenAICompatibleAdapter = (config) => {
|
|
|
681
903
|
method: "POST",
|
|
682
904
|
url: endpoint
|
|
683
905
|
};
|
|
684
|
-
}));
|
|
906
|
+
}), { label: "batch upload JSONL", maxBytes: limits.maxUploadBytes });
|
|
685
907
|
const headers3 = authHeaders(input.credentials);
|
|
686
908
|
const url = baseUrl3(input.credentials);
|
|
687
909
|
const purpose = config.filePurpose ?? "batch";
|
|
@@ -699,7 +921,8 @@ var createOpenAICompatibleAdapter = (config) => {
|
|
|
699
921
|
return normalizeSnapshot3(raw, config.id);
|
|
700
922
|
};
|
|
701
923
|
const retrieve3 = async (id, credentials) => {
|
|
702
|
-
const
|
|
924
|
+
const batchId = assertSimpleProviderId(`${config.id} batch id`, id);
|
|
925
|
+
const raw = await requestJson(`${baseUrl3(credentials)}/batches/${batchId}`, {
|
|
703
926
|
headers: authHeaders(credentials)
|
|
704
927
|
});
|
|
705
928
|
return normalizeSnapshot3(raw, config.id);
|
|
@@ -714,14 +937,15 @@ var createOpenAICompatibleAdapter = (config) => {
|
|
|
714
937
|
}
|
|
715
938
|
const headers3 = authHeaders(credentials);
|
|
716
939
|
if (outputFileId) {
|
|
717
|
-
yield* streamResultFile(outputFileId, baseUrl3(credentials), headers3);
|
|
940
|
+
yield* streamResultFile(assertSimpleProviderId(`${config.id} output file id`, outputFileId), baseUrl3(credentials), headers3);
|
|
718
941
|
}
|
|
719
942
|
if (errorFileId) {
|
|
720
|
-
yield* streamResultFile(errorFileId, baseUrl3(credentials), headers3);
|
|
943
|
+
yield* streamResultFile(assertSimpleProviderId(`${config.id} error file id`, errorFileId), baseUrl3(credentials), headers3);
|
|
721
944
|
}
|
|
722
945
|
}
|
|
723
946
|
const cancel3 = async (id, credentials) => {
|
|
724
|
-
|
|
947
|
+
const batchId = assertSimpleProviderId(`${config.id} batch id`, id);
|
|
948
|
+
await requestJson(`${baseUrl3(credentials)}/batches/${batchId}/cancel`, {
|
|
725
949
|
headers: authHeaders(credentials),
|
|
726
950
|
method: "POST"
|
|
727
951
|
});
|
|
@@ -776,10 +1000,11 @@ var normalizeSnapshot4 = (raw) => {
|
|
|
776
1000
|
const obj = asRecord(raw);
|
|
777
1001
|
const succeeded = asNumber(obj.succeeded_requests) ?? 0;
|
|
778
1002
|
const failed = asNumber(obj.failed_requests) ?? 0;
|
|
1003
|
+
const id = asString(obj.id) ?? "";
|
|
779
1004
|
return {
|
|
780
1005
|
completedAt: toDate(obj.completed_at),
|
|
781
1006
|
createdAt: toDate(obj.created_at),
|
|
782
|
-
id:
|
|
1007
|
+
id: id ? assertSimpleProviderId("Mistral job id", id) : "",
|
|
783
1008
|
provider: "mistral",
|
|
784
1009
|
raw,
|
|
785
1010
|
requestCounts: {
|
|
@@ -791,10 +1016,11 @@ var normalizeSnapshot4 = (raw) => {
|
|
|
791
1016
|
};
|
|
792
1017
|
};
|
|
793
1018
|
var submit3 = async (input) => {
|
|
1019
|
+
const limits = resolveBatchLimits(input.limits);
|
|
794
1020
|
const jsonl = encodeJsonl(input.built.map((item) => ({
|
|
795
1021
|
body: omit(omit(item.body, "stream"), "model"),
|
|
796
1022
|
custom_id: item.customId
|
|
797
|
-
})));
|
|
1023
|
+
})), { label: "batch upload JSONL", maxBytes: limits.maxUploadBytes });
|
|
798
1024
|
const inputFileId = await uploadInputFile(jsonl, baseUrl3(input.credentials), authHeaders(input.credentials));
|
|
799
1025
|
const raw = await requestJson(`${baseUrl3(input.credentials)}/batch/jobs`, {
|
|
800
1026
|
body: JSON.stringify({
|
|
@@ -812,7 +1038,8 @@ var submit3 = async (input) => {
|
|
|
812
1038
|
return normalizeSnapshot4(raw);
|
|
813
1039
|
};
|
|
814
1040
|
var retrieve3 = async (id, credentials) => {
|
|
815
|
-
const
|
|
1041
|
+
const jobId = assertSimpleProviderId("Mistral job id", id);
|
|
1042
|
+
const raw = await requestJson(`${baseUrl3(credentials)}/batch/jobs/${jobId}`, {
|
|
816
1043
|
headers: authHeaders(credentials)
|
|
817
1044
|
});
|
|
818
1045
|
return normalizeSnapshot4(raw);
|
|
@@ -824,17 +1051,18 @@ async function* results3(id, credentials) {
|
|
|
824
1051
|
const errorFileId = asString(raw.error_file);
|
|
825
1052
|
const headers3 = authHeaders(credentials);
|
|
826
1053
|
if (outputFileId) {
|
|
827
|
-
yield* streamResultFile(outputFileId, baseUrl3(credentials), headers3);
|
|
1054
|
+
yield* streamResultFile(assertSimpleProviderId("Mistral output file id", outputFileId), baseUrl3(credentials), headers3);
|
|
828
1055
|
}
|
|
829
1056
|
if (errorFileId) {
|
|
830
|
-
yield* streamResultFile(errorFileId, baseUrl3(credentials), headers3);
|
|
1057
|
+
yield* streamResultFile(assertSimpleProviderId("Mistral error file id", errorFileId), baseUrl3(credentials), headers3);
|
|
831
1058
|
}
|
|
832
1059
|
if (!(outputFileId || errorFileId)) {
|
|
833
1060
|
throw new BatchworkError(`batchwork: results are not ready for batch "${id}" (status: ${snapshot.status}).`);
|
|
834
1061
|
}
|
|
835
1062
|
}
|
|
836
1063
|
var cancel3 = async (id, credentials) => {
|
|
837
|
-
|
|
1064
|
+
const jobId = assertSimpleProviderId("Mistral job id", id);
|
|
1065
|
+
await requestJson(`${baseUrl3(credentials)}/batch/jobs/${jobId}/cancel`, {
|
|
838
1066
|
headers: authHeaders(credentials),
|
|
839
1067
|
method: "POST"
|
|
840
1068
|
});
|
|
@@ -859,12 +1087,44 @@ var openaiAdapter = createOpenAICompatibleAdapter({
|
|
|
859
1087
|
// src/providers/together.ts
|
|
860
1088
|
var INPUT_FILE_NAME = "batchwork.jsonl";
|
|
861
1089
|
var HTTP_FOUND = 302;
|
|
862
|
-
var
|
|
1090
|
+
var parseIpv4 = (host) => {
|
|
1091
|
+
if (!/^\d{1,3}(?:\.\d{1,3}){3}$/u.test(host)) {
|
|
1092
|
+
return;
|
|
1093
|
+
}
|
|
1094
|
+
const parts = host.split(".").map(Number);
|
|
1095
|
+
const valid = parts.every((part) => Number.isInteger(part) && part >= 0 && part <= 255);
|
|
1096
|
+
return valid ? parts : undefined;
|
|
1097
|
+
};
|
|
1098
|
+
var isPrivateIpv4 = (parts) => {
|
|
1099
|
+
const [a = 0, b = 0] = parts;
|
|
1100
|
+
return a === 0 || a === 10 || a === 127 || a === 100 && b >= 64 && b <= 127 || a === 169 && b === 254 || a === 172 && b >= 16 && b <= 31 || a === 192 && b === 168 || a === 198 && (b === 18 || b === 19) || a >= 224;
|
|
1101
|
+
};
|
|
1102
|
+
var isPrivateIpv6 = (host) => {
|
|
1103
|
+
const normalized = host.replace(/^\[/u, "").replace(/\]$/u, "").toLowerCase();
|
|
1104
|
+
if (!normalized.includes(":")) {
|
|
1105
|
+
return false;
|
|
1106
|
+
}
|
|
1107
|
+
return normalized === "::" || normalized === "::1" || normalized.startsWith("fc") || normalized.startsWith("fd") || normalized.startsWith("fe80:");
|
|
1108
|
+
};
|
|
1109
|
+
var validateUploadLocation = (location) => {
|
|
1110
|
+
let url;
|
|
863
1111
|
try {
|
|
864
|
-
|
|
865
|
-
} catch {
|
|
866
|
-
|
|
1112
|
+
url = new URL(location);
|
|
1113
|
+
} catch (error) {
|
|
1114
|
+
throw new BatchworkError("batchwork: Together upload Location must be a valid URL.", { cause: error });
|
|
867
1115
|
}
|
|
1116
|
+
if (url.protocol !== "https:") {
|
|
1117
|
+
throw new BatchworkError("batchwork: Together upload Location must use https.");
|
|
1118
|
+
}
|
|
1119
|
+
if (url.username || url.password) {
|
|
1120
|
+
throw new BatchworkError("batchwork: Together upload Location must not include credentials.");
|
|
1121
|
+
}
|
|
1122
|
+
const host = url.hostname.toLowerCase();
|
|
1123
|
+
const ipv4 = parseIpv4(host);
|
|
1124
|
+
if (host === "localhost" || host.endsWith(".localhost") || host.endsWith(".local") || ipv4 && isPrivateIpv4(ipv4) || isPrivateIpv6(host)) {
|
|
1125
|
+
throw new BatchworkError("batchwork: Together upload Location must not target localhost or private networks.");
|
|
1126
|
+
}
|
|
1127
|
+
return url.toString();
|
|
868
1128
|
};
|
|
869
1129
|
var uploadTogetherFile = async (args) => {
|
|
870
1130
|
const metadata = new FormData;
|
|
@@ -880,17 +1140,23 @@ var uploadTogetherFile = async (args) => {
|
|
|
880
1140
|
const location = init.headers.get("location");
|
|
881
1141
|
const fileId = init.headers.get("x-together-file-id");
|
|
882
1142
|
if (init.status !== HTTP_FOUND || !(location && fileId)) {
|
|
883
|
-
throw new BatchworkError(`batchwork: Together upload could not be initiated (${init.status})
|
|
1143
|
+
throw new BatchworkError(`batchwork: Together upload could not be initiated (${init.status}).`);
|
|
884
1144
|
}
|
|
885
|
-
const
|
|
1145
|
+
const uploadLocation = validateUploadLocation(location);
|
|
1146
|
+
const upload = await fetch(uploadLocation, {
|
|
1147
|
+
body: args.jsonl,
|
|
1148
|
+
method: "PUT",
|
|
1149
|
+
redirect: "manual"
|
|
1150
|
+
});
|
|
886
1151
|
if (!upload.ok) {
|
|
887
|
-
throw new BatchworkError(`batchwork: Together file upload failed (${upload.status})
|
|
1152
|
+
throw new BatchworkError(`batchwork: Together file upload failed (${upload.status}).`);
|
|
888
1153
|
}
|
|
889
|
-
|
|
1154
|
+
const safeFileId = assertSimpleProviderId("Together file id", fileId);
|
|
1155
|
+
await requestJson(`${args.baseUrl}/files/${safeFileId}/preprocess`, {
|
|
890
1156
|
headers: args.headers,
|
|
891
1157
|
method: "POST"
|
|
892
1158
|
});
|
|
893
|
-
return
|
|
1159
|
+
return safeFileId;
|
|
894
1160
|
};
|
|
895
1161
|
var togetherAdapter = createOpenAICompatibleAdapter({
|
|
896
1162
|
apiKeyEnv: "TOGETHER_API_KEY",
|
|
@@ -932,11 +1198,12 @@ var deriveStatus = (state) => {
|
|
|
932
1198
|
var normalizeSnapshot5 = (raw) => {
|
|
933
1199
|
const obj = asRecord(raw);
|
|
934
1200
|
const state = asRecord(obj.state);
|
|
1201
|
+
const id = asString(obj.batch_id) ?? asString(obj.id) ?? "";
|
|
935
1202
|
return {
|
|
936
|
-
completedAt: toDate(obj.
|
|
1203
|
+
completedAt: toDate(obj.finish_time ?? obj.completed_at),
|
|
937
1204
|
createdAt: toDate(obj.create_time),
|
|
938
1205
|
expiresAt: toDate(obj.expire_time ?? obj.expires_at),
|
|
939
|
-
id:
|
|
1206
|
+
id: id ? assertSimpleProviderId("xAI batch id", id) : "",
|
|
940
1207
|
provider: "xai",
|
|
941
1208
|
raw,
|
|
942
1209
|
requestCounts: {
|
|
@@ -977,12 +1244,13 @@ var normalizeResult3 = (item) => {
|
|
|
977
1244
|
};
|
|
978
1245
|
};
|
|
979
1246
|
var submit4 = async (input) => {
|
|
1247
|
+
const limits = resolveBatchLimits(input.limits);
|
|
980
1248
|
const jsonl = encodeJsonl(input.built.map((item) => ({
|
|
981
1249
|
body: omit(item.body, "stream"),
|
|
982
1250
|
custom_id: item.customId,
|
|
983
1251
|
method: "POST",
|
|
984
1252
|
url: input.endpoint
|
|
985
|
-
})));
|
|
1253
|
+
})), { label: "batch upload JSONL", maxBytes: limits.maxUploadBytes });
|
|
986
1254
|
const inputFileId = await uploadInputFile(jsonl, baseUrl4(input.credentials), authHeaders2(input.credentials), { purpose: null });
|
|
987
1255
|
const raw = await requestJson(`${baseUrl4(input.credentials)}/batches`, {
|
|
988
1256
|
body: JSON.stringify({ input_file_id: inputFileId, name: "batchwork" }),
|
|
@@ -995,12 +1263,14 @@ var submit4 = async (input) => {
|
|
|
995
1263
|
return normalizeSnapshot5(raw);
|
|
996
1264
|
};
|
|
997
1265
|
var retrieve4 = async (id, credentials) => {
|
|
998
|
-
const
|
|
1266
|
+
const batchId = assertSimpleProviderId("xAI batch id", id);
|
|
1267
|
+
const raw = await requestJson(`${baseUrl4(credentials)}/batches/${batchId}`, {
|
|
999
1268
|
headers: authHeaders2(credentials)
|
|
1000
1269
|
});
|
|
1001
1270
|
return normalizeSnapshot5(raw);
|
|
1002
1271
|
};
|
|
1003
1272
|
async function* results4(id, credentials) {
|
|
1273
|
+
const batchId = assertSimpleProviderId("xAI batch id", id);
|
|
1004
1274
|
const headers3 = authHeaders2(credentials);
|
|
1005
1275
|
let token;
|
|
1006
1276
|
do {
|
|
@@ -1008,7 +1278,7 @@ async function* results4(id, credentials) {
|
|
|
1008
1278
|
if (token) {
|
|
1009
1279
|
query.set("pagination_token", token);
|
|
1010
1280
|
}
|
|
1011
|
-
const raw = await requestJson(`${baseUrl4(credentials)}/batches/${
|
|
1281
|
+
const raw = await requestJson(`${baseUrl4(credentials)}/batches/${batchId}/results?${query.toString()}`, { headers: headers3 });
|
|
1012
1282
|
const page = asRecord(raw);
|
|
1013
1283
|
for (const item of Array.isArray(page.results) ? page.results : []) {
|
|
1014
1284
|
yield normalizeResult3(item);
|
|
@@ -1017,7 +1287,8 @@ async function* results4(id, credentials) {
|
|
|
1017
1287
|
} while (token);
|
|
1018
1288
|
}
|
|
1019
1289
|
var cancel4 = async (id, credentials) => {
|
|
1020
|
-
|
|
1290
|
+
const batchId = assertSimpleProviderId("xAI batch id", id);
|
|
1291
|
+
await requestJson(`${baseUrl4(credentials)}/batches/${batchId}:cancel`, {
|
|
1021
1292
|
headers: authHeaders2(credentials),
|
|
1022
1293
|
method: "POST"
|
|
1023
1294
|
});
|
|
@@ -1042,7 +1313,7 @@ var adapters = {
|
|
|
1042
1313
|
};
|
|
1043
1314
|
var getAdapter = (provider) => adapters[provider];
|
|
1044
1315
|
|
|
1045
|
-
export { BatchworkError, UnsupportedProviderError, MissingDependencyError, isTerminalStatus, BatchJob, getAdapter };
|
|
1316
|
+
export { BatchworkError, UnsupportedProviderError, MissingDependencyError, resolveBatchLimits, assertByteLength, mapWithConcurrency, isTerminalStatus, BatchJob, getAdapter };
|
|
1046
1317
|
|
|
1047
|
-
//# debugId=
|
|
1048
|
-
//# sourceMappingURL=chunk-
|
|
1318
|
+
//# debugId=A771CB719D6F2AEA64756E2164756E21
|
|
1319
|
+
//# sourceMappingURL=chunk-xtk2ycy6.js.map
|