batchwork 1.4.0 → 1.5.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.
Files changed (61) hide show
  1. package/dist/body.d.ts +2 -2
  2. package/dist/body.d.ts.map +1 -1
  3. package/dist/chunk-6jgvqdpc.js +52 -0
  4. package/dist/chunk-6jgvqdpc.js.map +11 -0
  5. package/dist/{chunk-vy4w8mpb.js → chunk-7y95mhvm.js} +119 -151
  6. package/dist/chunk-7y95mhvm.js.map +27 -0
  7. package/dist/{chunk-ka9d4t6v.js → chunk-k7n7k3et.js} +66 -152
  8. package/dist/chunk-k7n7k3et.js.map +13 -0
  9. package/dist/{chunk-2ea62n95.js → chunk-zss8h417.js} +213 -200
  10. package/dist/chunk-zss8h417.js.map +12 -0
  11. package/dist/guards.d.ts +5 -0
  12. package/dist/guards.d.ts.map +1 -0
  13. package/dist/http.d.ts +3 -2
  14. package/dist/http.d.ts.map +1 -1
  15. package/dist/index.d.ts +1 -1
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +27 -28
  18. package/dist/index.js.map +1 -1
  19. package/dist/jsonl.d.ts +3 -2
  20. package/dist/jsonl.d.ts.map +1 -1
  21. package/dist/limits.d.ts +0 -1
  22. package/dist/limits.d.ts.map +1 -1
  23. package/dist/model.d.ts +48 -1
  24. package/dist/model.d.ts.map +1 -1
  25. package/dist/next/index.d.ts +1 -1
  26. package/dist/next/index.d.ts.map +1 -1
  27. package/dist/next/index.js +14 -20
  28. package/dist/next/index.js.map +3 -3
  29. package/dist/postgres/batch-store.d.ts.map +1 -1
  30. package/dist/postgres/index.js +22 -15
  31. package/dist/postgres/index.js.map +4 -4
  32. package/dist/postgres/types.d.ts +1 -1
  33. package/dist/postgres/types.d.ts.map +1 -1
  34. package/dist/providers/anthropic.d.ts.map +1 -1
  35. package/dist/providers/azure.d.ts.map +1 -1
  36. package/dist/providers/google.d.ts.map +1 -1
  37. package/dist/providers/mistral.d.ts.map +1 -1
  38. package/dist/providers/openai-compatible.d.ts +2 -2
  39. package/dist/providers/openai-compatible.d.ts.map +1 -1
  40. package/dist/providers/shared.d.ts +8 -8
  41. package/dist/providers/shared.d.ts.map +1 -1
  42. package/dist/providers/xai.d.ts.map +1 -1
  43. package/dist/redis/index.js +40 -6
  44. package/dist/redis/index.js.map +4 -4
  45. package/dist/redis/types.d.ts +18 -5
  46. package/dist/redis/types.d.ts.map +1 -1
  47. package/dist/server/index.js +13 -14
  48. package/dist/server/index.js.map +1 -1
  49. package/dist/server/poller.d.ts +6 -4
  50. package/dist/server/poller.d.ts.map +1 -1
  51. package/dist/server/signing.d.ts.map +1 -1
  52. package/dist/types.d.ts +16 -2
  53. package/dist/types.d.ts.map +1 -1
  54. package/dist/util.d.ts +18 -7
  55. package/dist/util.d.ts.map +1 -1
  56. package/package.json +20 -17
  57. package/dist/chunk-2ea62n95.js.map +0 -12
  58. package/dist/chunk-ka9d4t6v.js.map +0 -13
  59. package/dist/chunk-v0bahtg2.js +0 -7
  60. package/dist/chunk-v0bahtg2.js.map +0 -9
  61. package/dist/chunk-vy4w8mpb.js.map +0 -28
@@ -1,16 +1,18 @@
1
1
  import {
2
- BatchJob,
3
- BatchworkError,
4
- MissingDependencyError,
5
- UnsupportedProviderError,
2
+ BatchworkError2,
3
+ UnsupportedProviderError2,
4
+ MissingDependencyError2,
5
+ resolveBatchLimits,
6
6
  assertByteLength,
7
- getAdapter,
8
- mapWithConcurrency,
9
- resolveBatchLimits
10
- } from "./chunk-vy4w8mpb.js";
7
+ BatchJob2,
8
+ getAdapter
9
+ } from "./chunk-7y95mhvm.js";
11
10
  import {
12
- __require
13
- } from "./chunk-v0bahtg2.js";
11
+ isString,
12
+ trimTrailingSlashes,
13
+ isJsonObject,
14
+ parseJson
15
+ } from "./chunk-6jgvqdpc.js";
14
16
 
15
17
  // src/model.ts
16
18
  var CAPTURE_API_KEY = "batchwork-capture";
@@ -18,7 +20,7 @@ var azureCaptureBaseUrl = (baseURL) => {
18
20
  if (!baseURL) {
19
21
  return;
20
22
  }
21
- const normalized = baseURL.replace(/\/+$/u, "");
23
+ const normalized = trimTrailingSlashes(baseURL);
22
24
  try {
23
25
  if (new URL(normalized).hostname.endsWith(".openai.azure.com")) {
24
26
  const root = normalized.replace(/\/v1$/u, "");
@@ -37,21 +39,21 @@ var PACKAGE_BY_PROVIDER = {
37
39
  together: { label: "Together AI", specifier: "@ai-sdk/togetherai" },
38
40
  xai: { label: "xAI", specifier: "@ai-sdk/xai" }
39
41
  };
40
- var PROVIDER_BY_FAMILY = {
41
- anthropic: "anthropic",
42
- azure: "azure",
43
- google: "google",
44
- groq: "groq",
45
- mistral: "mistral",
46
- openai: "openai",
47
- together: "together",
48
- togetherai: "together",
49
- xai: "xai"
50
- };
51
- var PROVIDER_BY_ALIAS = {
42
+ var PROVIDER_BY_FAMILY = new Map([
43
+ ["anthropic", "anthropic"],
44
+ ["azure", "azure"],
45
+ ["google", "google"],
46
+ ["groq", "groq"],
47
+ ["mistral", "mistral"],
48
+ ["openai", "openai"],
49
+ ["together", "together"],
50
+ ["togetherai", "together"],
51
+ ["xai", "xai"]
52
+ ]);
53
+ var PROVIDER_BY_ALIAS = new Map([
52
54
  ...PROVIDER_BY_FAMILY,
53
- gemini: "google"
54
- };
55
+ ["gemini", "google"]
56
+ ]);
55
57
  var splitOnce = (value, separator) => {
56
58
  const index = value.indexOf(separator);
57
59
  if (index === -1) {
@@ -71,20 +73,20 @@ var openaiKind = (suffix) => {
71
73
  var resolveModelString = (value) => {
72
74
  const [providerId, modelId] = splitOnce(value, "/");
73
75
  if (modelId === "") {
74
- throw new UnsupportedProviderError(value);
76
+ throw new UnsupportedProviderError2(value);
75
77
  }
76
- const provider = PROVIDER_BY_ALIAS[providerId];
78
+ const provider = PROVIDER_BY_ALIAS.get(providerId);
77
79
  if (!provider) {
78
- throw new UnsupportedProviderError(providerId);
80
+ throw new UnsupportedProviderError2(providerId);
79
81
  }
80
82
  return { kind: "chat", modelId, provider };
81
83
  };
82
- var resolveModel = (model) => {
83
- if (typeof model === "string") {
84
+ var resolveModel2 = (model) => {
85
+ if (isString(model)) {
84
86
  return resolveModelString(model);
85
87
  }
86
88
  const [family, suffix] = splitOnce(model.provider, ".");
87
- const provider = PROVIDER_BY_FAMILY[family];
89
+ const provider = PROVIDER_BY_FAMILY.get(family);
88
90
  if (provider === "openai" || provider === "azure") {
89
91
  return { kind: openaiKind(suffix), modelId: model.modelId, provider };
90
92
  }
@@ -94,48 +96,34 @@ var resolveModel = (model) => {
94
96
  if (model.modelId.includes("/")) {
95
97
  return resolveModelString(model.modelId);
96
98
  }
97
- throw new UnsupportedProviderError(model.provider);
99
+ throw new UnsupportedProviderError2(model.provider);
100
+ };
101
+ var importers = {
102
+ anthropic: () => import("@ai-sdk/anthropic"),
103
+ azure: () => import("@ai-sdk/azure"),
104
+ google: () => import("@ai-sdk/google"),
105
+ groq: () => import("@ai-sdk/groq"),
106
+ mistral: () => import("@ai-sdk/mistral"),
107
+ openai: () => import("@ai-sdk/openai"),
108
+ together: () => import("@ai-sdk/togetherai"),
109
+ xai: () => import("@ai-sdk/xai")
98
110
  };
99
111
  var importProvider = (provider) => {
100
- switch (provider) {
101
- case "anthropic": {
102
- return import("@ai-sdk/anthropic");
103
- }
104
- case "azure": {
105
- return import("@ai-sdk/azure");
106
- }
107
- case "google": {
108
- return import("@ai-sdk/google");
109
- }
110
- case "groq": {
111
- return import("@ai-sdk/groq");
112
- }
113
- case "mistral": {
114
- return import("@ai-sdk/mistral");
115
- }
116
- case "openai": {
117
- return import("@ai-sdk/openai");
118
- }
119
- case "together": {
120
- return import("@ai-sdk/togetherai");
121
- }
122
- case "xai": {
123
- return import("@ai-sdk/xai");
124
- }
125
- default: {
126
- return Promise.reject(new UnsupportedProviderError(provider));
127
- }
112
+ const importer = importers[provider];
113
+ if (importer === undefined) {
114
+ return Promise.reject(new UnsupportedProviderError2(provider));
128
115
  }
116
+ return importer();
129
117
  };
130
118
  var loadProvider = async (provider, load = importProvider) => {
131
119
  try {
132
120
  return await load(provider);
133
121
  } catch (error) {
134
- if (error instanceof UnsupportedProviderError) {
122
+ if (error instanceof UnsupportedProviderError2) {
135
123
  throw error;
136
124
  }
137
125
  const { specifier, label } = PACKAGE_BY_PROVIDER[provider];
138
- throw new MissingDependencyError(specifier, label);
126
+ throw new MissingDependencyError2(specifier, label);
139
127
  }
140
128
  };
141
129
  var createCaptureModel = async (resolved, credentials, fetchImpl) => {
@@ -196,7 +184,7 @@ var createCaptureModel = async (resolved, credentials, fetchImpl) => {
196
184
  return createTogetherAI(settings).languageModel(resolved.modelId);
197
185
  }
198
186
  default: {
199
- throw new UnsupportedProviderError(resolved.provider);
187
+ throw new UnsupportedProviderError2(resolved.provider);
200
188
  }
201
189
  }
202
190
  };
@@ -205,7 +193,7 @@ var EMBEDDING_PROVIDERS = new Set([
205
193
  "mistral",
206
194
  "openai"
207
195
  ]);
208
- var unsupportedEmbeddingProvider = (provider) => new UnsupportedProviderError(provider, `batchwork: provider "${provider}" does not offer batch embeddings. Embeddings are supported for: openai, mistral, google.`);
196
+ var unsupportedEmbeddingProvider = (provider) => new UnsupportedProviderError2(provider, `batchwork: provider "${provider}" does not offer batch embeddings. Embeddings are supported for: openai, mistral, google.`);
209
197
  var createCaptureEmbeddingModel = async (resolved, credentials, fetchImpl) => {
210
198
  const settings = {
211
199
  apiKey: credentials.apiKey ?? CAPTURE_API_KEY,
@@ -232,9 +220,9 @@ var createCaptureEmbeddingModel = async (resolved, credentials, fetchImpl) => {
232
220
  }
233
221
  };
234
222
  var IMAGE_EDIT_PROVIDERS = new Set(["openai", "xai"]);
235
- var unsupportedImageEditProvider = (provider) => new UnsupportedProviderError(provider, `batchwork: provider "${provider}" does not offer batch image editing. Image edits are supported for: openai, xai.`);
223
+ var unsupportedImageEditProvider = (provider) => new UnsupportedProviderError2(provider, `batchwork: provider "${provider}" does not offer batch image editing. Image edits are supported for: openai, xai.`);
236
224
  var VIDEO_PROVIDERS = new Set(["xai"]);
237
- var unsupportedVideoProvider = (provider) => new UnsupportedProviderError(provider, `batchwork: provider "${provider}" does not offer batch video generation. Videos are supported for: xai.`);
225
+ var unsupportedVideoProvider = (provider) => new UnsupportedProviderError2(provider, `batchwork: provider "${provider}" does not offer batch video generation. Videos are supported for: xai.`);
238
226
  var createCaptureVideoModel = async (resolved, credentials, fetchImpl) => {
239
227
  if (resolved.provider !== "xai") {
240
228
  throw unsupportedVideoProvider(resolved.provider);
@@ -251,24 +239,24 @@ var TRANSLATION_PROVIDERS = new Set([
251
239
  "groq",
252
240
  "together"
253
241
  ]);
254
- var unsupportedTranslationProvider = (provider) => new UnsupportedProviderError(provider, `batchwork: provider "${provider}" does not offer batch translation. Translations are supported for: groq, together.`);
242
+ var unsupportedTranslationProvider = (provider) => new UnsupportedProviderError2(provider, `batchwork: provider "${provider}" does not offer batch translation. Translations are supported for: groq, together.`);
255
243
  var MODERATION_PROVIDERS = new Set([
256
244
  "mistral",
257
245
  "openai"
258
246
  ]);
259
- var unsupportedModerationProvider = (provider) => new UnsupportedProviderError(provider, `batchwork: provider "${provider}" does not offer batch moderation. Moderations are supported for: openai, mistral.`);
247
+ var unsupportedModerationProvider = (provider) => new UnsupportedProviderError2(provider, `batchwork: provider "${provider}" does not offer batch moderation. Moderations are supported for: openai, mistral.`);
260
248
  var TRANSCRIPTION_PROVIDERS = new Set([
261
249
  "groq",
262
250
  "mistral",
263
251
  "together"
264
252
  ]);
265
- var unsupportedTranscriptionProvider = (provider) => new UnsupportedProviderError(provider, `batchwork: provider "${provider}" does not offer batch transcription. Transcriptions are supported for: groq, mistral, together.`);
253
+ var unsupportedTranscriptionProvider = (provider) => new UnsupportedProviderError2(provider, `batchwork: provider "${provider}" does not offer batch transcription. Transcriptions are supported for: groq, mistral, together.`);
266
254
  var IMAGE_PROVIDERS = new Set([
267
255
  "google",
268
256
  "openai",
269
257
  "xai"
270
258
  ]);
271
- var unsupportedImageProvider = (provider) => new UnsupportedProviderError(provider, `batchwork: provider "${provider}" does not offer batch image generation. Image batches are supported for: openai, google, xai.`);
259
+ var unsupportedImageProvider = (provider) => new UnsupportedProviderError2(provider, `batchwork: provider "${provider}" does not offer batch image generation. Image batches are supported for: openai, google, xai.`);
272
260
  var createCaptureImageModel = async (resolved, credentials, fetchImpl) => {
273
261
  const settings = {
274
262
  apiKey: credentials.apiKey ?? CAPTURE_API_KEY,
@@ -302,6 +290,7 @@ import {
302
290
  generateImage,
303
291
  generateText
304
292
  } from "ai";
293
+ import pMap from "p-map";
305
294
  var MAX_CAUSE_DEPTH = 10;
306
295
 
307
296
  class CaptureSignalError extends Error {
@@ -315,35 +304,36 @@ class CaptureSignalError extends Error {
315
304
  }
316
305
  }
317
306
  var resolveUrl = (input) => {
318
- if (typeof input === "string") {
319
- return input;
320
- }
321
307
  if (input instanceof URL) {
322
308
  return input.toString();
323
309
  }
324
- return input.url;
310
+ if (input instanceof Request) {
311
+ return input.url;
312
+ }
313
+ return input;
325
314
  };
326
315
  var extractBody = (init) => {
327
316
  const body = init?.body;
328
- if (typeof body === "string") {
317
+ if (isString(body)) {
329
318
  return body;
330
319
  }
331
320
  if (body instanceof Uint8Array) {
332
321
  return new TextDecoder().decode(body);
333
322
  }
334
- throw new BatchworkError("batchwork: unable to read the provider request body during capture.");
323
+ throw new BatchworkError2("batchwork: unable to read the provider request body during capture.");
335
324
  };
336
- var captureFetch = (input, init) => Promise.reject(new CaptureSignalError(resolveUrl(input), extractBody(init)));
337
- var findCapture = (error) => {
338
- let current = error;
339
- let depth = 0;
340
- while (current && depth < MAX_CAUSE_DEPTH) {
341
- if (current instanceof CaptureSignalError) {
342
- return current;
343
- }
344
- current = current.cause;
345
- depth += 1;
325
+ var captureFetch = Object.assign((input, init) => Promise.reject(new CaptureSignalError(resolveUrl(input), extractBody(init))), {
326
+ preconnect: () => {}
327
+ });
328
+ var hasCause = (value) => typeof value === "object" && value !== null && ("cause" in value);
329
+ var findCapture = (cause, depth = 0) => {
330
+ if (depth >= MAX_CAUSE_DEPTH) {
331
+ return;
332
+ }
333
+ if (cause instanceof CaptureSignalError) {
334
+ return cause;
346
335
  }
336
+ return hasCause(cause) ? findCapture(cause.cause, depth + 1) : undefined;
347
337
  };
348
338
  var endpointFromUrl = (url) => {
349
339
  try {
@@ -376,25 +366,25 @@ var toGenerateInput = (model, request) => ({
376
366
  topK: request.topK,
377
367
  topP: request.topP
378
368
  });
379
- var bodyFromCapture = (error, customId, maxRequestBytes) => {
380
- const capture = findCapture(error);
381
- if (capture) {
382
- assertByteLength(`request "${customId}"`, capture.rawBody, maxRequestBytes);
383
- return {
384
- body: JSON.parse(capture.rawBody),
385
- customId,
386
- endpoint: endpointFromUrl(capture.url)
387
- };
369
+ var bodyFromCapture = (capture, customId, maxRequestBytes) => {
370
+ assertByteLength(`request "${customId}"`, capture.rawBody, maxRequestBytes);
371
+ const body = parseJson(capture.rawBody);
372
+ if (!isJsonObject(body)) {
373
+ throw new BatchworkError2(`batchwork: the captured body for request "${customId}" is not a JSON object.`);
388
374
  }
389
- throw error;
375
+ return { body, customId, endpoint: endpointFromUrl(capture.url) };
390
376
  };
391
377
  var captureOne = async (model, request, customId, maxRequestBytes) => {
392
378
  try {
393
379
  await generateText(toGenerateInput(model, request));
394
380
  } catch (error) {
395
- return bodyFromCapture(error, customId, maxRequestBytes);
381
+ const capture = findCapture(error);
382
+ if (!capture) {
383
+ throw error;
384
+ }
385
+ return bodyFromCapture(capture, customId, maxRequestBytes);
396
386
  }
397
- throw new BatchworkError("batchwork: the request was not intercepted while building the batch body.");
387
+ throw new BatchworkError2("batchwork: the request was not intercepted while building the batch body.");
398
388
  };
399
389
  var captureEmbeddingOne = async (model, request, customId, maxRequestBytes) => {
400
390
  try {
@@ -405,9 +395,13 @@ var captureEmbeddingOne = async (model, request, customId, maxRequestBytes) => {
405
395
  value: request.value
406
396
  });
407
397
  } catch (error) {
408
- return bodyFromCapture(error, customId, maxRequestBytes);
398
+ const capture = findCapture(error);
399
+ if (!capture) {
400
+ throw error;
401
+ }
402
+ return bodyFromCapture(capture, customId, maxRequestBytes);
409
403
  }
410
- throw new BatchworkError("batchwork: the request was not intercepted while building the embedding body.");
404
+ throw new BatchworkError2("batchwork: the request was not intercepted while building the embedding body.");
411
405
  };
412
406
  var captureImageOne = async (model, request, customId, maxRequestBytes) => {
413
407
  try {
@@ -423,16 +417,20 @@ var captureImageOne = async (model, request, customId, maxRequestBytes) => {
423
417
  size: request.size
424
418
  });
425
419
  } catch (error) {
426
- return bodyFromCapture(error, customId, maxRequestBytes);
420
+ const capture = findCapture(error);
421
+ if (!capture) {
422
+ throw error;
423
+ }
424
+ return bodyFromCapture(capture, customId, maxRequestBytes);
427
425
  }
428
- throw new BatchworkError("batchwork: the request was not intercepted while building the image body.");
426
+ throw new BatchworkError2("batchwork: the request was not intercepted while building the image body.");
429
427
  };
430
428
  var assignCustomIds = (requests) => {
431
429
  const seen = new Set;
432
430
  return requests.map((request, index) => {
433
431
  const customId = request.customId ?? `request-${index}`;
434
432
  if (seen.has(customId)) {
435
- throw new BatchworkError(`batchwork: duplicate customId "${customId}". customId values must be unique within a batch.`);
433
+ throw new BatchworkError2(`batchwork: duplicate customId "${customId}". customId values must be unique within a batch.`);
436
434
  }
437
435
  seen.add(customId);
438
436
  return { customId, request };
@@ -441,64 +439,63 @@ var assignCustomIds = (requests) => {
441
439
  var buildRequestBodies = async (resolved, requests, defaults, credentials, rawLimits) => {
442
440
  const limits = resolveBatchLimits(rawLimits);
443
441
  if (requests.length > limits.maxRequests) {
444
- throw new BatchworkError(`batchwork: requests length ${requests.length} exceeds the ${limits.maxRequests} request limit.`);
442
+ throw new BatchworkError2(`batchwork: requests length ${requests.length} exceeds the ${limits.maxRequests} request limit.`);
445
443
  }
446
444
  const model = await createCaptureModel(resolved, credentials, captureFetch);
447
445
  const items = assignCustomIds(requests);
448
- return await mapWithConcurrency(items, limits.captureConcurrency, async (item) => {
446
+ return await pMap(items, async (item) => {
449
447
  const built = await captureOne(model, mergeDefaults(item.request, defaults), item.customId, limits.maxRequestBytes);
450
448
  assertByteLength(`request "${item.customId}"`, JSON.stringify(built.body), limits.maxRequestBytes);
451
449
  return built;
452
- });
450
+ }, { concurrency: limits.captureConcurrency });
453
451
  };
454
452
  var buildEmbeddingBodies = async (resolved, requests, credentials, rawLimits) => {
455
453
  const limits = resolveBatchLimits(rawLimits);
456
454
  if (requests.length > limits.maxRequests) {
457
- throw new BatchworkError(`batchwork: requests length ${requests.length} exceeds the ${limits.maxRequests} request limit.`);
455
+ throw new BatchworkError2(`batchwork: requests length ${requests.length} exceeds the ${limits.maxRequests} request limit.`);
458
456
  }
459
457
  const model = await createCaptureEmbeddingModel(resolved, credentials, captureFetch);
460
458
  const items = assignCustomIds(requests);
461
- return await mapWithConcurrency(items, limits.captureConcurrency, async (item) => {
459
+ return await pMap(items, async (item) => {
462
460
  const built = await captureEmbeddingOne(model, item.request, item.customId, limits.maxRequestBytes);
463
461
  assertByteLength(`request "${item.customId}"`, JSON.stringify(built.body), limits.maxRequestBytes);
464
462
  return built;
465
- });
463
+ }, { concurrency: limits.captureConcurrency });
466
464
  };
467
465
  var MODERATION_ENDPOINT = "/v1/moderations";
468
- var moderationInput = (request) => {
469
- const imageUrls = request.imageUrls ?? [];
470
- if (imageUrls.length === 0) {
471
- return request.value;
466
+ var moderationParts = (value, imageUrls) => {
467
+ const parts = [];
468
+ if (value !== undefined) {
469
+ parts.push({ text: value, type: "text" });
470
+ }
471
+ for (const url of imageUrls) {
472
+ parts.push({ image_url: { url }, type: "image_url" });
472
473
  }
473
- return [
474
- ...request.value === undefined ? [] : [{ text: request.value, type: "text" }],
475
- ...imageUrls.map((url) => ({ image_url: { url }, type: "image_url" }))
476
- ];
474
+ return parts;
477
475
  };
478
476
  var moderationBody = (resolved, request, customId) => {
479
- if (request.value === undefined && !request.imageUrls?.length) {
480
- throw new BatchworkError(`batchwork: moderation request "${customId}" needs \`value\` or \`imageUrls\`.`);
477
+ const { value } = request;
478
+ const imageUrls = request.imageUrls ?? [];
479
+ if (value === undefined && imageUrls.length === 0) {
480
+ throw new BatchworkError2(`batchwork: moderation request "${customId}" needs \`value\` or \`imageUrls\`.`);
481
481
  }
482
482
  const options = request.providerOptions?.[resolved.provider];
483
483
  if (resolved.provider === "openai") {
484
- return {
485
- input: moderationInput(request),
486
- model: resolved.modelId,
487
- ...options
488
- };
484
+ const input = imageUrls.length === 0 && value !== undefined ? value : moderationParts(value, imageUrls);
485
+ return { input, model: resolved.modelId, ...options };
489
486
  }
490
487
  if (resolved.provider === "mistral") {
491
- if (request.imageUrls?.length) {
492
- throw new BatchworkError(`batchwork: moderation request "${customId}" has \`imageUrls\`, but Mistral moderation is text-only.`);
488
+ if (imageUrls.length > 0) {
489
+ throw new BatchworkError2(`batchwork: moderation request "${customId}" has \`imageUrls\`, but Mistral moderation is text-only.`);
493
490
  }
494
- return { input: request.value, model: resolved.modelId, ...options };
491
+ return { input: value ?? "", model: resolved.modelId, ...options };
495
492
  }
496
493
  throw unsupportedModerationProvider(resolved.provider);
497
494
  };
498
495
  var buildModerationBodies = (resolved, requests, rawLimits) => {
499
496
  const limits = resolveBatchLimits(rawLimits);
500
497
  if (requests.length > limits.maxRequests) {
501
- throw new BatchworkError(`batchwork: requests length ${requests.length} exceeds the ${limits.maxRequests} request limit.`);
498
+ throw new BatchworkError2(`batchwork: requests length ${requests.length} exceeds the ${limits.maxRequests} request limit.`);
502
499
  }
503
500
  return assignCustomIds(requests).map((item) => {
504
501
  const body = moderationBody(resolved, item.request, item.customId);
@@ -507,17 +504,26 @@ var buildModerationBodies = (resolved, requests, rawLimits) => {
507
504
  });
508
505
  };
509
506
  var TRANSCRIPTION_ENDPOINT = "/v1/audio/transcriptions";
507
+ var audioOptions = (request, verboseTimestamps) => {
508
+ const fields = {};
509
+ if (request.language) {
510
+ fields.language = request.language;
511
+ }
512
+ if (request.timestampGranularities) {
513
+ if (verboseTimestamps) {
514
+ fields.response_format = "verbose_json";
515
+ }
516
+ fields.timestamp_granularities = request.timestampGranularities;
517
+ }
518
+ return fields;
519
+ };
510
520
  var transcriptionBody = (resolved, request) => {
511
521
  const options = request.providerOptions?.[resolved.provider];
512
522
  if (resolved.provider === "groq") {
513
523
  return {
514
524
  model: resolved.modelId,
515
525
  url: request.audioUrl,
516
- ...request.language ? { language: request.language } : {},
517
- ...request.timestampGranularities ? {
518
- response_format: "verbose_json",
519
- timestamp_granularities: request.timestampGranularities
520
- } : {},
526
+ ...audioOptions(request, true),
521
527
  ...options
522
528
  };
523
529
  }
@@ -525,8 +531,7 @@ var transcriptionBody = (resolved, request) => {
525
531
  return {
526
532
  file_url: request.audioUrl,
527
533
  model: resolved.modelId,
528
- ...request.language ? { language: request.language } : {},
529
- ...request.timestampGranularities ? { timestamp_granularities: request.timestampGranularities } : {},
534
+ ...audioOptions(request, false),
530
535
  ...options
531
536
  };
532
537
  }
@@ -534,11 +539,7 @@ var transcriptionBody = (resolved, request) => {
534
539
  return {
535
540
  file: request.audioUrl,
536
541
  model: resolved.modelId,
537
- ...request.language ? { language: request.language } : {},
538
- ...request.timestampGranularities ? {
539
- response_format: "verbose_json",
540
- timestamp_granularities: request.timestampGranularities
541
- } : {},
542
+ ...audioOptions(request, true),
542
543
  ...options
543
544
  };
544
545
  }
@@ -547,7 +548,7 @@ var transcriptionBody = (resolved, request) => {
547
548
  var buildAudioBodies = (resolved, requests, defaults, endpoint, rawLimits) => {
548
549
  const limits = resolveBatchLimits(rawLimits);
549
550
  if (requests.length > limits.maxRequests) {
550
- throw new BatchworkError(`batchwork: requests length ${requests.length} exceeds the ${limits.maxRequests} request limit.`);
551
+ throw new BatchworkError2(`batchwork: requests length ${requests.length} exceeds the ${limits.maxRequests} request limit.`);
551
552
  }
552
553
  return assignCustomIds(requests).map((item) => {
553
554
  const body = transcriptionBody(resolved, mergeDefaults(item.request, defaults));
@@ -560,61 +561,69 @@ var buildTranslationBodies = (resolved, requests, defaults, rawLimits) => buildA
560
561
  var buildImageBodies = async (resolved, requests, defaults, credentials, rawLimits) => {
561
562
  const limits = resolveBatchLimits(rawLimits);
562
563
  if (requests.length > limits.maxRequests) {
563
- throw new BatchworkError(`batchwork: requests length ${requests.length} exceeds the ${limits.maxRequests} request limit.`);
564
+ throw new BatchworkError2(`batchwork: requests length ${requests.length} exceeds the ${limits.maxRequests} request limit.`);
564
565
  }
565
566
  const model = await createCaptureImageModel(resolved, credentials, captureFetch);
566
567
  const items = assignCustomIds(requests);
567
- return await mapWithConcurrency(items, limits.captureConcurrency, async (item) => {
568
+ return await pMap(items, async (item) => {
568
569
  const built = await captureImageOne(model, mergeDefaults(item.request, defaults), item.customId, limits.maxRequestBytes);
569
570
  assertByteLength(`request "${item.customId}"`, JSON.stringify(built.body), limits.maxRequestBytes);
570
571
  return built;
571
- });
572
+ }, { concurrency: limits.captureConcurrency });
572
573
  };
573
574
  var IMAGE_EDIT_ENDPOINT = "/v1/images/edits";
574
575
  var openaiImageRef = (ref) => ("fileId" in ref) ? { file_id: ref.fileId } : { image_url: ref.imageUrl };
575
576
  var imageEditBody = (resolved, request, customId) => {
576
577
  if (request.images.length === 0) {
577
- throw new BatchworkError(`batchwork: image-edit request "${customId}" needs at least one entry in \`images\`.`);
578
+ throw new BatchworkError2(`batchwork: image-edit request "${customId}" needs at least one entry in \`images\`.`);
578
579
  }
579
580
  const options = request.providerOptions?.[resolved.provider];
580
581
  if (resolved.provider === "openai") {
581
- return {
582
+ const body = {
582
583
  images: request.images.map(openaiImageRef),
583
584
  model: resolved.modelId,
584
- prompt: request.prompt,
585
- ...request.mask ? { mask: openaiImageRef(request.mask) } : {},
586
- ...request.n === undefined ? {} : { n: request.n },
587
- ...request.size ? { size: request.size } : {},
588
- ...options
585
+ prompt: request.prompt
589
586
  };
587
+ if (request.mask) {
588
+ body.mask = openaiImageRef(request.mask);
589
+ }
590
+ if (request.n !== undefined) {
591
+ body.n = request.n;
592
+ }
593
+ if (request.size) {
594
+ body.size = request.size;
595
+ }
596
+ return { ...body, ...options };
590
597
  }
591
598
  if (resolved.provider === "xai") {
592
599
  if (request.mask) {
593
- throw new BatchworkError(`batchwork: image-edit request "${customId}" has a \`mask\`, but xAI image edits do not support masks.`);
600
+ throw new BatchworkError2(`batchwork: image-edit request "${customId}" has a \`mask\`, but xAI image edits do not support masks.`);
594
601
  }
595
602
  if (request.size) {
596
- throw new BatchworkError(`batchwork: image-edit request "${customId}" has \`size\`, but xAI image edits take \`providerOptions.xai.aspect_ratio\` instead.`);
603
+ throw new BatchworkError2(`batchwork: image-edit request "${customId}" has \`size\`, but xAI image edits take \`providerOptions.xai.aspect_ratio\` instead.`);
597
604
  }
598
605
  const urls = request.images.map((ref) => {
599
606
  if ("fileId" in ref) {
600
- throw new BatchworkError(`batchwork: image-edit request "${customId}" uses a \`fileId\` reference, but xAI image edits accept image URLs only.`);
607
+ throw new BatchworkError2(`batchwork: image-edit request "${customId}" uses a \`fileId\` reference, but xAI image edits accept image URLs only.`);
601
608
  }
602
609
  return ref.imageUrl;
603
610
  });
604
- return {
611
+ const body = {
605
612
  model: resolved.modelId,
606
613
  prompt: request.prompt,
607
- ...urls.length === 1 ? { image: { url: urls[0] } } : { images: urls.map((url) => ({ url })) },
608
- ...request.n === undefined ? {} : { n: request.n },
609
- ...options
614
+ ...urls.length === 1 ? { image: { url: urls[0] } } : { images: urls.map((url) => ({ url })) }
610
615
  };
616
+ if (request.n !== undefined) {
617
+ body.n = request.n;
618
+ }
619
+ return { ...body, ...options };
611
620
  }
612
621
  throw unsupportedImageEditProvider(resolved.provider);
613
622
  };
614
623
  var buildImageEditBodies = (resolved, requests, defaults, rawLimits) => {
615
624
  const limits = resolveBatchLimits(rawLimits);
616
625
  if (requests.length > limits.maxRequests) {
617
- throw new BatchworkError(`batchwork: requests length ${requests.length} exceeds the ${limits.maxRequests} request limit.`);
626
+ throw new BatchworkError2(`batchwork: requests length ${requests.length} exceeds the ${limits.maxRequests} request limit.`);
618
627
  }
619
628
  return assignCustomIds(requests).map((item) => {
620
629
  const body = imageEditBody(resolved, mergeDefaults(item.request, defaults), item.customId);
@@ -634,22 +643,26 @@ var captureVideoOne = async (model, request, customId, maxRequestBytes) => {
634
643
  resolution: request.resolution
635
644
  });
636
645
  } catch (error) {
637
- return bodyFromCapture(error, customId, maxRequestBytes);
646
+ const capture = findCapture(error);
647
+ if (!capture) {
648
+ throw error;
649
+ }
650
+ return bodyFromCapture(capture, customId, maxRequestBytes);
638
651
  }
639
- throw new BatchworkError("batchwork: the request was not intercepted while building the video body.");
652
+ throw new BatchworkError2("batchwork: the request was not intercepted while building the video body.");
640
653
  };
641
654
  var buildVideoBodies = async (resolved, requests, defaults, credentials, rawLimits) => {
642
655
  const limits = resolveBatchLimits(rawLimits);
643
656
  if (requests.length > limits.maxRequests) {
644
- throw new BatchworkError(`batchwork: requests length ${requests.length} exceeds the ${limits.maxRequests} request limit.`);
657
+ throw new BatchworkError2(`batchwork: requests length ${requests.length} exceeds the ${limits.maxRequests} request limit.`);
645
658
  }
646
659
  const model = await createCaptureVideoModel(resolved, credentials, captureFetch);
647
660
  const items = assignCustomIds(requests);
648
- return await mapWithConcurrency(items, limits.captureConcurrency, async (item) => {
661
+ return await pMap(items, async (item) => {
649
662
  const built = await captureVideoOne(model, mergeDefaults(item.request, defaults), item.customId, limits.maxRequestBytes);
650
663
  assertByteLength(`request "${item.customId}"`, JSON.stringify(built.body), limits.maxRequestBytes);
651
664
  return built;
652
- });
665
+ }, { concurrency: limits.captureConcurrency });
653
666
  };
654
667
 
655
668
  // src/batch.ts
@@ -664,15 +677,15 @@ var providerFromRef = (ref) => {
664
677
  return ref.provider;
665
678
  }
666
679
  if (ref.model !== undefined) {
667
- return resolveModel(ref.model).provider;
680
+ return resolveModel2(ref.model).provider;
668
681
  }
669
- throw new BatchworkError("batchwork: provide `provider` or `model` to identify the batch.");
682
+ throw new BatchworkError2("batchwork: provide `provider` or `model` to identify the batch.");
670
683
  };
671
684
  var submitText = async (options) => {
672
685
  if (options.requests.length === 0) {
673
- throw new BatchworkError(EMPTY_REQUESTS_MESSAGE);
686
+ throw new BatchworkError2(EMPTY_REQUESTS_MESSAGE);
674
687
  }
675
- const resolved = resolveModel(options.model);
688
+ const resolved = resolveModel2(options.model);
676
689
  const credentials = pickCredentials(options);
677
690
  const limits = resolveBatchLimits(options.limits);
678
691
  const adapter = getAdapter(resolved.provider);
@@ -685,13 +698,13 @@ var submitText = async (options) => {
685
698
  metadata: options.metadata,
686
699
  modelId: resolved.modelId
687
700
  });
688
- return new BatchJob(adapter, credentials, snapshot);
701
+ return new BatchJob2(adapter, credentials, snapshot);
689
702
  };
690
703
  var submitEmbeddings = async (options) => {
691
704
  if (options.requests.length === 0) {
692
- throw new BatchworkError(EMPTY_REQUESTS_MESSAGE);
705
+ throw new BatchworkError2(EMPTY_REQUESTS_MESSAGE);
693
706
  }
694
- const resolved = resolveModel(options.model);
707
+ const resolved = resolveModel2(options.model);
695
708
  if (!EMBEDDING_PROVIDERS.has(resolved.provider)) {
696
709
  throw unsupportedEmbeddingProvider(resolved.provider);
697
710
  }
@@ -707,13 +720,13 @@ var submitEmbeddings = async (options) => {
707
720
  metadata: options.metadata,
708
721
  modelId: resolved.modelId
709
722
  });
710
- return new BatchJob(adapter, credentials, snapshot);
723
+ return new BatchJob2(adapter, credentials, snapshot);
711
724
  };
712
725
  var submitImages = async (options) => {
713
726
  if (options.requests.length === 0) {
714
- throw new BatchworkError(EMPTY_REQUESTS_MESSAGE);
727
+ throw new BatchworkError2(EMPTY_REQUESTS_MESSAGE);
715
728
  }
716
- const resolved = resolveModel(options.model);
729
+ const resolved = resolveModel2(options.model);
717
730
  if (!IMAGE_PROVIDERS.has(resolved.provider)) {
718
731
  throw unsupportedImageProvider(resolved.provider);
719
732
  }
@@ -729,13 +742,13 @@ var submitImages = async (options) => {
729
742
  metadata: options.metadata,
730
743
  modelId: resolved.modelId
731
744
  });
732
- return new BatchJob(adapter, credentials, snapshot);
745
+ return new BatchJob2(adapter, credentials, snapshot);
733
746
  };
734
747
  var submitImageEdits = async (options) => {
735
748
  if (options.requests.length === 0) {
736
- throw new BatchworkError(EMPTY_REQUESTS_MESSAGE);
749
+ throw new BatchworkError2(EMPTY_REQUESTS_MESSAGE);
737
750
  }
738
- const resolved = resolveModel(options.model);
751
+ const resolved = resolveModel2(options.model);
739
752
  if (!IMAGE_EDIT_PROVIDERS.has(resolved.provider)) {
740
753
  throw unsupportedImageEditProvider(resolved.provider);
741
754
  }
@@ -751,13 +764,13 @@ var submitImageEdits = async (options) => {
751
764
  metadata: options.metadata,
752
765
  modelId: resolved.modelId
753
766
  });
754
- return new BatchJob(adapter, credentials, snapshot);
767
+ return new BatchJob2(adapter, credentials, snapshot);
755
768
  };
756
769
  var submitModerations = async (options) => {
757
770
  if (options.requests.length === 0) {
758
- throw new BatchworkError(EMPTY_REQUESTS_MESSAGE);
771
+ throw new BatchworkError2(EMPTY_REQUESTS_MESSAGE);
759
772
  }
760
- const resolved = resolveModel(options.model);
773
+ const resolved = resolveModel2(options.model);
761
774
  if (!MODERATION_PROVIDERS.has(resolved.provider)) {
762
775
  throw unsupportedModerationProvider(resolved.provider);
763
776
  }
@@ -773,13 +786,13 @@ var submitModerations = async (options) => {
773
786
  metadata: options.metadata,
774
787
  modelId: resolved.modelId
775
788
  });
776
- return new BatchJob(adapter, credentials, snapshot);
789
+ return new BatchJob2(adapter, credentials, snapshot);
777
790
  };
778
791
  var submitTranscriptions = async (options) => {
779
792
  if (options.requests.length === 0) {
780
- throw new BatchworkError(EMPTY_REQUESTS_MESSAGE);
793
+ throw new BatchworkError2(EMPTY_REQUESTS_MESSAGE);
781
794
  }
782
- const resolved = resolveModel(options.model);
795
+ const resolved = resolveModel2(options.model);
783
796
  if (!TRANSCRIPTION_PROVIDERS.has(resolved.provider)) {
784
797
  throw unsupportedTranscriptionProvider(resolved.provider);
785
798
  }
@@ -795,13 +808,13 @@ var submitTranscriptions = async (options) => {
795
808
  metadata: options.metadata,
796
809
  modelId: resolved.modelId
797
810
  });
798
- return new BatchJob(adapter, credentials, snapshot);
811
+ return new BatchJob2(adapter, credentials, snapshot);
799
812
  };
800
813
  var submitVideos = async (options) => {
801
814
  if (options.requests.length === 0) {
802
- throw new BatchworkError(EMPTY_REQUESTS_MESSAGE);
815
+ throw new BatchworkError2(EMPTY_REQUESTS_MESSAGE);
803
816
  }
804
- const resolved = resolveModel(options.model);
817
+ const resolved = resolveModel2(options.model);
805
818
  if (!VIDEO_PROVIDERS.has(resolved.provider)) {
806
819
  throw unsupportedVideoProvider(resolved.provider);
807
820
  }
@@ -817,13 +830,13 @@ var submitVideos = async (options) => {
817
830
  metadata: options.metadata,
818
831
  modelId: resolved.modelId
819
832
  });
820
- return new BatchJob(adapter, credentials, snapshot);
833
+ return new BatchJob2(adapter, credentials, snapshot);
821
834
  };
822
835
  var submitTranslations = async (options) => {
823
836
  if (options.requests.length === 0) {
824
- throw new BatchworkError(EMPTY_REQUESTS_MESSAGE);
837
+ throw new BatchworkError2(EMPTY_REQUESTS_MESSAGE);
825
838
  }
826
- const resolved = resolveModel(options.model);
839
+ const resolved = resolveModel2(options.model);
827
840
  if (!TRANSLATION_PROVIDERS.has(resolved.provider)) {
828
841
  throw unsupportedTranslationProvider(resolved.provider);
829
842
  }
@@ -839,9 +852,9 @@ var submitTranslations = async (options) => {
839
852
  metadata: options.metadata,
840
853
  modelId: resolved.modelId
841
854
  });
842
- return new BatchJob(adapter, credentials, snapshot);
855
+ return new BatchJob2(adapter, credentials, snapshot);
843
856
  };
844
- var batch = Object.assign(submitText, {
857
+ var batch2 = Object.assign(submitText, {
845
858
  embeddings: submitEmbeddings,
846
859
  images: Object.assign(submitImages, {
847
860
  create: submitImages,
@@ -853,24 +866,24 @@ var batch = Object.assign(submitText, {
853
866
  translations: submitTranslations,
854
867
  videos: submitVideos
855
868
  });
856
- var batchEmbeddings = submitEmbeddings;
857
- var batchImages = submitImages;
858
- var getBatch = async (ref) => {
869
+ var batchEmbeddings2 = submitEmbeddings;
870
+ var batchImages2 = submitImages;
871
+ var getBatch2 = async (ref) => {
859
872
  const adapter = getAdapter(providerFromRef(ref));
860
873
  const credentials = pickCredentials(ref);
861
874
  const snapshot = await adapter.retrieve(ref.id, credentials);
862
- return new BatchJob(adapter, credentials, snapshot);
875
+ return new BatchJob2(adapter, credentials, snapshot);
863
876
  };
864
- var getBatchResults = (ref) => {
877
+ var getBatchResults2 = (ref) => {
865
878
  const adapter = getAdapter(providerFromRef(ref));
866
879
  return adapter.results(ref.id, pickCredentials(ref));
867
880
  };
868
- var cancelBatch = async (ref) => {
881
+ var cancelBatch2 = async (ref) => {
869
882
  const adapter = getAdapter(providerFromRef(ref));
870
883
  await adapter.cancel(ref.id, pickCredentials(ref));
871
884
  };
872
885
 
873
- export { resolveModel, batch, batchEmbeddings, batchImages, getBatch, getBatchResults, cancelBatch };
886
+ export { resolveModel2, batch2, batchEmbeddings2, batchImages2, getBatch2, getBatchResults2, cancelBatch2 };
874
887
 
875
- //# debugId=1B451ACF41BE2A3C64756E2164756E21
876
- //# sourceMappingURL=chunk-2ea62n95.js.map
888
+ //# debugId=555DA8E4F0C86CA964756E2164756E21
889
+ //# sourceMappingURL=chunk-zss8h417.js.map