batchwork 1.0.1 → 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.
Files changed (45) hide show
  1. package/README.md +25 -0
  2. package/dist/batch.d.ts +18 -1
  3. package/dist/batch.d.ts.map +1 -1
  4. package/dist/body.d.ts +8 -1
  5. package/dist/body.d.ts.map +1 -1
  6. package/dist/{chunk-e6qn48qa.js → chunk-d0g9wsxq.js} +89 -15
  7. package/dist/chunk-d0g9wsxq.js.map +13 -0
  8. package/dist/{chunk-g481f961.js → chunk-xtk2ycy6.js} +145 -38
  9. package/dist/chunk-xtk2ycy6.js.map +27 -0
  10. package/dist/{chunk-m4n610nm.js → chunk-yzjd83s9.js} +108 -22
  11. package/dist/chunk-yzjd83s9.js.map +12 -0
  12. package/dist/errors.d.ts +1 -1
  13. package/dist/errors.d.ts.map +1 -1
  14. package/dist/index.d.ts +2 -2
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +5 -3
  17. package/dist/index.js.map +1 -1
  18. package/dist/job.d.ts.map +1 -1
  19. package/dist/jsonl.d.ts +5 -1
  20. package/dist/jsonl.d.ts.map +1 -1
  21. package/dist/limits.d.ts +1 -0
  22. package/dist/limits.d.ts.map +1 -1
  23. package/dist/model.d.ts +16 -2
  24. package/dist/model.d.ts.map +1 -1
  25. package/dist/next/index.js +3 -3
  26. package/dist/payload.d.ts +10 -0
  27. package/dist/payload.d.ts.map +1 -0
  28. package/dist/providers/anthropic.d.ts.map +1 -1
  29. package/dist/providers/google.d.ts.map +1 -1
  30. package/dist/providers/shared.d.ts +2 -0
  31. package/dist/providers/shared.d.ts.map +1 -1
  32. package/dist/providers/together.d.ts.map +1 -1
  33. package/dist/providers/xai.d.ts.map +1 -1
  34. package/dist/server/index.js +2 -2
  35. package/dist/server/poller.d.ts.map +1 -1
  36. package/dist/server/signing.d.ts +1 -0
  37. package/dist/server/signing.d.ts.map +1 -1
  38. package/dist/types.d.ts +24 -1
  39. package/dist/types.d.ts.map +1 -1
  40. package/dist/util.d.ts +2 -0
  41. package/dist/util.d.ts.map +1 -1
  42. package/package.json +1 -1
  43. package/dist/chunk-e6qn48qa.js.map +0 -13
  44. package/dist/chunk-g481f961.js.map +0 -26
  45. package/dist/chunk-m4n610nm.js.map +0 -12
@@ -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
- const timer = setTimeout(resolve, ms);
40
- signal?.addEventListener("abort", () => {
39
+ let timer;
40
+ const onAbort = () => {
41
41
  clearTimeout(timer);
42
42
  reject(new BatchworkError("batchwork: wait aborted."));
43
- }, { once: true });
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 {
@@ -124,12 +129,14 @@ var resolveBatchLimits = (limits) => ({
124
129
  maxUploadBytes: positiveInteger("maxUploadBytes", limits?.maxUploadBytes ?? DEFAULT_LIMITS.maxUploadBytes)
125
130
  });
126
131
  var byteLength = (value) => encoder.encode(value).length;
127
- var assertByteLength = (label, value, maxBytes) => {
128
- const bytes = byteLength(value);
132
+ var assertByteCount = (label, bytes, maxBytes) => {
129
133
  if (bytes > maxBytes) {
130
134
  throw new BatchworkError(`batchwork: ${label} is ${bytes} bytes, exceeding the ${maxBytes} byte limit.`);
131
135
  }
132
136
  };
137
+ var assertByteLength = (label, value, maxBytes) => {
138
+ assertByteCount(label, byteLength(value), maxBytes);
139
+ };
133
140
  var mapWithConcurrency = async (items, concurrency, mapper) => {
134
141
  const results = [];
135
142
  results.length = items.length;
@@ -172,6 +179,7 @@ var requestStream = async (url, init) => {
172
179
  var NEWLINE = `
173
180
  `;
174
181
  var DEFAULT_MAX_JSONL_LINE_BYTES = 20 * 1024 * 1024;
182
+ var NEWLINE_BYTES = byteLength(NEWLINE);
175
183
  var resolveMaxLineBytes = (options) => {
176
184
  const maxLineBytes = options?.maxLineBytes ?? DEFAULT_MAX_JSONL_LINE_BYTES;
177
185
  if (!(Number.isInteger(maxLineBytes) && maxLineBytes > 0)) {
@@ -197,12 +205,33 @@ var parseLine = (line, lineNumber, maxLineBytes) => {
197
205
  throw new BatchworkError(`batchwork: invalid JSONL at line ${lineNumber}.`, { cause: error });
198
206
  }
199
207
  };
200
- var encodeJsonl = (items) => {
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) => {
201
216
  if (items.length === 0) {
202
217
  return "";
203
218
  }
204
- const body = items.map((item) => JSON.stringify(item)).join(NEWLINE);
205
- return `${body}${NEWLINE}`;
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}`;
206
235
  };
207
236
  var isReadableStream = (source) => ("getReader" in source) && typeof source.getReader === "function";
208
237
  async function* toByteIterable(source) {
@@ -250,6 +279,32 @@ async function* streamJsonl(source, options) {
250
279
  }
251
280
  }
252
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
+
253
308
  // src/util.ts
254
309
  var asRecord = (value) => {
255
310
  if (typeof value === "object" && value !== null) {
@@ -260,6 +315,13 @@ var asRecord = (value) => {
260
315
  var asString = (value) => typeof value === "string" ? value : undefined;
261
316
  var asNumber = (value) => typeof value === "number" ? value : undefined;
262
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
+ };
263
325
  var omit = (obj, key) => {
264
326
  const result = {};
265
327
  for (const [k, v] of Object.entries(obj)) {
@@ -269,12 +331,13 @@ var omit = (obj, key) => {
269
331
  }
270
332
  return result;
271
333
  };
334
+ var validDate = (date) => Number.isNaN(date.getTime()) ? undefined : date;
272
335
  var toDate = (value) => {
273
336
  if (typeof value === "string") {
274
- return new Date(value);
337
+ return validDate(new Date(value));
275
338
  }
276
339
  if (typeof value === "number") {
277
- return new Date(value * 1000);
340
+ return validDate(new Date(value * 1000));
278
341
  }
279
342
  };
280
343
 
@@ -421,8 +484,13 @@ var submit = async (input) => {
421
484
  custom_id: item.customId,
422
485
  params: omit(item.body, "stream")
423
486
  }));
424
- const body = JSON.stringify({ requests });
425
- assertByteLength("batch upload payload", body, limits.maxUploadBytes);
487
+ const body = encodeJsonArrayPayload({
488
+ items: requests,
489
+ label: "batch upload payload",
490
+ maxBytes: limits.maxUploadBytes,
491
+ prefix: '{"requests":[',
492
+ suffix: "]}"
493
+ });
426
494
  const raw = await requestJson(`${baseUrl(input.credentials)}/v1/messages/batches`, {
427
495
  body,
428
496
  headers: headers(input.credentials),
@@ -442,7 +510,8 @@ async function* results(id, credentials) {
442
510
  throw new BatchworkError(`batchwork: results are not ready for batch "${id}" (status: ${snapshot.status}).`);
443
511
  }
444
512
  const stream = await requestStream(validateResultsUrl(resultsUrl, credentials), {
445
- headers: headers(credentials)
513
+ headers: headers(credentials),
514
+ redirect: "manual"
446
515
  });
447
516
  for await (const line of streamJsonl(stream)) {
448
517
  yield normalizeResult(line);
@@ -541,6 +610,7 @@ var textFromResponse = (response) => {
541
610
  const text = asArray(asRecord(candidate.content).parts).map((part) => asString(asRecord(part).text) ?? "").join("");
542
611
  return text.length > 0 ? text : undefined;
543
612
  };
613
+ var embeddingFromResponse = (response) => asNumberArray(asRecord(asRecord(response).embedding).values);
544
614
  var usageFromResponse = (response) => {
545
615
  const usage = asRecord(asRecord(response).usageMetadata);
546
616
  const inputTokens = asNumber(usage.promptTokenCount);
@@ -573,26 +643,52 @@ var normalizeResult2 = (item) => {
573
643
  }
574
644
  return {
575
645
  customId,
646
+ embedding: embeddingFromResponse(obj.response),
576
647
  response: obj.response,
577
648
  status: "succeeded",
578
649
  text: textFromResponse(obj.response),
579
650
  usage: usageFromResponse(obj.response)
580
651
  };
581
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
+ };
582
673
  var submit2 = async (input) => {
583
674
  const limits = resolveBatchLimits(input.limits);
584
- const requests = input.built.map((item) => ({
585
- metadata: { key: item.customId },
586
- request: omit(item.body, "stream")
587
- }));
588
- const body = JSON.stringify({
589
- batch: {
590
- display_name: "batchwork",
591
- input_config: { requests: { requests } }
592
- }
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: "]}}}}"
593
690
  });
594
- assertByteLength("batch upload payload", body, limits.maxUploadBytes);
595
- const raw = await requestJson(`${baseUrl2(input.credentials)}/models/${input.modelId}:batchGenerateContent`, {
691
+ const raw = await requestJson(`${baseUrl2(input.credentials)}/models/${input.modelId}:${method}`, {
596
692
  body,
597
693
  headers: headers2(input.credentials),
598
694
  method: "POST"
@@ -659,6 +755,13 @@ var textFromBody = (body) => {
659
755
  }
660
756
  return asString(obj.output_text);
661
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
+ };
662
765
  var usageFromBody = (body) => {
663
766
  const usage = asRecord(asRecord(body).usage);
664
767
  const inputTokens = asNumber(usage.prompt_tokens) ?? asNumber(usage.input_tokens);
@@ -699,6 +802,7 @@ var normalizeOpenAIResult = (line) => {
699
802
  if (statusCode >= HTTP_OK_MIN && statusCode < HTTP_OK_MAX) {
700
803
  return {
701
804
  customId,
805
+ embedding: embeddingFromBody(response.body),
702
806
  response: response.body,
703
807
  status: "succeeded",
704
808
  text: textFromBody(response.body),
@@ -722,13 +826,15 @@ var uploadInputFile = async (jsonl, baseUrl3, headers3, options = {}) => {
722
826
  const raw = await requestJson(`${baseUrl3}/files`, {
723
827
  body: form,
724
828
  headers: headers3,
725
- method: "POST"
829
+ method: "POST",
830
+ redirect: "manual"
726
831
  });
727
832
  return raw.id;
728
833
  };
729
834
  async function* streamResultFile(fileId, baseUrl3, headers3) {
730
835
  const stream = await requestStream(`${baseUrl3}/files/${fileId}/content`, {
731
- headers: headers3
836
+ headers: headers3,
837
+ redirect: "manual"
732
838
  });
733
839
  for await (const line of streamJsonl(stream)) {
734
840
  yield normalizeOpenAIResult(line);
@@ -797,8 +903,7 @@ var createOpenAICompatibleAdapter = (config) => {
797
903
  method: "POST",
798
904
  url: endpoint
799
905
  };
800
- }));
801
- assertByteLength("batch upload JSONL", jsonl, limits.maxUploadBytes);
906
+ }), { label: "batch upload JSONL", maxBytes: limits.maxUploadBytes });
802
907
  const headers3 = authHeaders(input.credentials);
803
908
  const url = baseUrl3(input.credentials);
804
909
  const purpose = config.filePurpose ?? "batch";
@@ -915,8 +1020,7 @@ var submit3 = async (input) => {
915
1020
  const jsonl = encodeJsonl(input.built.map((item) => ({
916
1021
  body: omit(omit(item.body, "stream"), "model"),
917
1022
  custom_id: item.customId
918
- })));
919
- assertByteLength("batch upload JSONL", jsonl, limits.maxUploadBytes);
1023
+ })), { label: "batch upload JSONL", maxBytes: limits.maxUploadBytes });
920
1024
  const inputFileId = await uploadInputFile(jsonl, baseUrl3(input.credentials), authHeaders(input.credentials));
921
1025
  const raw = await requestJson(`${baseUrl3(input.credentials)}/batch/jobs`, {
922
1026
  body: JSON.stringify({
@@ -997,6 +1101,9 @@ var isPrivateIpv4 = (parts) => {
997
1101
  };
998
1102
  var isPrivateIpv6 = (host) => {
999
1103
  const normalized = host.replace(/^\[/u, "").replace(/\]$/u, "").toLowerCase();
1104
+ if (!normalized.includes(":")) {
1105
+ return false;
1106
+ }
1000
1107
  return normalized === "::" || normalized === "::1" || normalized.startsWith("fc") || normalized.startsWith("fd") || normalized.startsWith("fe80:");
1001
1108
  };
1002
1109
  var validateUploadLocation = (location) => {
@@ -1038,7 +1145,8 @@ var uploadTogetherFile = async (args) => {
1038
1145
  const uploadLocation = validateUploadLocation(location);
1039
1146
  const upload = await fetch(uploadLocation, {
1040
1147
  body: args.jsonl,
1041
- method: "PUT"
1148
+ method: "PUT",
1149
+ redirect: "manual"
1042
1150
  });
1043
1151
  if (!upload.ok) {
1044
1152
  throw new BatchworkError(`batchwork: Together file upload failed (${upload.status}).`);
@@ -1092,7 +1200,7 @@ var normalizeSnapshot5 = (raw) => {
1092
1200
  const state = asRecord(obj.state);
1093
1201
  const id = asString(obj.batch_id) ?? asString(obj.id) ?? "";
1094
1202
  return {
1095
- completedAt: toDate(obj.cancel_time),
1203
+ completedAt: toDate(obj.finish_time ?? obj.completed_at),
1096
1204
  createdAt: toDate(obj.create_time),
1097
1205
  expiresAt: toDate(obj.expire_time ?? obj.expires_at),
1098
1206
  id: id ? assertSimpleProviderId("xAI batch id", id) : "",
@@ -1142,8 +1250,7 @@ var submit4 = async (input) => {
1142
1250
  custom_id: item.customId,
1143
1251
  method: "POST",
1144
1252
  url: input.endpoint
1145
- })));
1146
- assertByteLength("batch upload JSONL", jsonl, limits.maxUploadBytes);
1253
+ })), { label: "batch upload JSONL", maxBytes: limits.maxUploadBytes });
1147
1254
  const inputFileId = await uploadInputFile(jsonl, baseUrl4(input.credentials), authHeaders2(input.credentials), { purpose: null });
1148
1255
  const raw = await requestJson(`${baseUrl4(input.credentials)}/batches`, {
1149
1256
  body: JSON.stringify({ input_file_id: inputFileId, name: "batchwork" }),
@@ -1208,5 +1315,5 @@ var getAdapter = (provider) => adapters[provider];
1208
1315
 
1209
1316
  export { BatchworkError, UnsupportedProviderError, MissingDependencyError, resolveBatchLimits, assertByteLength, mapWithConcurrency, isTerminalStatus, BatchJob, getAdapter };
1210
1317
 
1211
- //# debugId=A38719FEA6433ECA64756E2164756E21
1212
- //# sourceMappingURL=chunk-g481f961.js.map
1318
+ //# debugId=A771CB719D6F2AEA64756E2164756E21
1319
+ //# sourceMappingURL=chunk-xtk2ycy6.js.map
@@ -0,0 +1,27 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/errors.ts", "../src/job.ts", "../src/limits.ts", "../src/http.ts", "../src/jsonl.ts", "../src/payload.ts", "../src/util.ts", "../src/providers/ids.ts", "../src/providers/anthropic.ts", "../src/providers/google.ts", "../src/providers/shared.ts", "../src/providers/openai-compatible.ts", "../src/providers/groq.ts", "../src/providers/mistral.ts", "../src/providers/openai.ts", "../src/providers/together.ts", "../src/providers/xai.ts", "../src/providers/index.ts"],
4
+ "sourcesContent": [
5
+ "// oxlint-disable max-classes-per-file -- the error hierarchy is co-located by design.\n\n/** Base error for all batchwork failures. */\nexport class BatchworkError extends Error {\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = \"BatchworkError\";\n }\n}\n\n/** Thrown when a model resolves to a provider without a batch adapter. */\nexport class UnsupportedProviderError extends BatchworkError {\n readonly provider: string;\n\n constructor(provider: string, detail?: string) {\n super(\n detail ??\n `batchwork: provider \"${provider}\" is not supported yet. Supported providers: openai, anthropic, google, groq, mistral, together, xai.`\n );\n this.name = \"UnsupportedProviderError\";\n this.provider = provider;\n }\n}\n\n/** Thrown when an optional provider package is not installed. */\nexport class MissingDependencyError extends BatchworkError {\n constructor(pkg: string, provider: string) {\n super(\n `batchwork: install \\`${pkg}\\` to batch ${provider} models (\\`npm install ${pkg}\\`).`\n );\n this.name = \"MissingDependencyError\";\n }\n}\n",
6
+ "import { BatchworkError } from \"./errors\";\nimport type { BatchAdapter } from \"./providers/adapter\";\nimport type {\n BatchProvider,\n BatchRequestCounts,\n BatchResult,\n BatchSnapshot,\n BatchStatus,\n ProviderCredentials,\n WaitOptions,\n} from \"./types\";\n\nconst DEFAULT_POLL_INTERVAL_MS = 15_000;\n\nconst TERMINAL_STATUSES: ReadonlySet<BatchStatus> = new Set<BatchStatus>([\n \"completed\",\n \"failed\",\n \"expired\",\n \"cancelled\",\n]);\n\n/** Whether a status means the batch has finished processing. */\nexport const isTerminalStatus = (status: BatchStatus): boolean =>\n TERMINAL_STATUSES.has(status);\n\nconst delay = (ms: number, signal?: AbortSignal): Promise<void> =>\n // oxlint-disable-next-line promise/avoid-new -- wrapping the callback-based setTimeout.\n new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(new BatchworkError(\"batchwork: wait aborted.\"));\n return;\n }\n // oxlint-disable-next-line prefer-const -- assigned below, after `onAbort` closes over it.\n let timer: ReturnType<typeof setTimeout>;\n const onAbort = (): void => {\n clearTimeout(timer);\n reject(new BatchworkError(\"batchwork: wait aborted.\"));\n };\n timer = setTimeout(() => {\n // Detach so a reused signal (one per poll across a long wait) doesn't\n // accumulate listeners that only fire on abort.\n signal?.removeEventListener(\"abort\", onAbort);\n resolve();\n }, ms);\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n\n/**\n * A handle to a submitted batch. Returned by `batch()` and `getBatch()`. Use it\n * to poll status, wait for completion, stream results, or cancel.\n */\nexport class BatchJob {\n readonly provider: BatchProvider;\n readonly id: string;\n\n readonly #adapter: BatchAdapter;\n readonly #credentials: ProviderCredentials;\n #snapshot: BatchSnapshot;\n\n constructor(\n adapter: BatchAdapter,\n credentials: ProviderCredentials,\n snapshot: BatchSnapshot\n ) {\n this.#adapter = adapter;\n this.#credentials = credentials;\n this.#snapshot = snapshot;\n this.id = snapshot.id;\n this.provider = snapshot.provider;\n }\n\n /** The most recently observed status. */\n get status(): BatchStatus {\n return this.#snapshot.status;\n }\n\n /** The most recently observed per-request tallies. */\n get requestCounts(): BatchRequestCounts {\n return this.#snapshot.requestCounts;\n }\n\n /** The most recently observed snapshot. */\n get snapshot(): BatchSnapshot {\n return this.#snapshot;\n }\n\n /** Refresh the status from the provider and return the new snapshot. */\n async poll(): Promise<BatchSnapshot> {\n this.#snapshot = await this.#adapter.retrieve(this.id, this.#credentials);\n return this.#snapshot;\n }\n\n /** Poll until the batch reaches a terminal status, then return the snapshot. */\n async wait(options: WaitOptions = {}): Promise<BatchSnapshot> {\n const interval = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;\n const deadline = options.timeoutMs\n ? Date.now() + options.timeoutMs\n : undefined;\n\n let snapshot = await this.poll();\n options.onPoll?.(snapshot);\n\n while (!isTerminalStatus(snapshot.status)) {\n if (options.signal?.aborted) {\n throw new BatchworkError(\"batchwork: wait aborted.\");\n }\n if (deadline !== undefined && Date.now() > deadline) {\n throw new BatchworkError(\n `batchwork: timed out waiting for batch \"${this.id}\".`\n );\n }\n // oxlint-disable-next-line no-await-in-loop -- polling is inherently sequential.\n await delay(interval, options.signal);\n // oxlint-disable-next-line no-await-in-loop -- polling is inherently sequential.\n snapshot = await this.poll();\n options.onPoll?.(snapshot);\n }\n\n return snapshot;\n }\n\n /** Stream normalized results as they are read. Order is not guaranteed. */\n results(): AsyncGenerator<BatchResult> {\n return this.#adapter.results(this.id, this.#credentials);\n }\n\n /** Collect all results into an array, keyed by `customId`. */\n async collect(): Promise<BatchResult[]> {\n const out: BatchResult[] = [];\n for await (const result of this.results()) {\n out.push(result);\n }\n return out;\n }\n\n /** Request cancellation, then refresh status. */\n async cancel(): Promise<BatchSnapshot> {\n await this.#adapter.cancel(this.id, this.#credentials);\n return await this.poll();\n }\n}\n",
7
+ "import { BatchworkError } from \"./errors\";\nimport type { BatchLimits } from \"./types\";\n\nexport interface ResolvedBatchLimits {\n captureConcurrency: number;\n maxRequests: number;\n maxRequestBytes: number;\n maxUploadBytes: number;\n}\n\nconst DEFAULT_LIMITS: ResolvedBatchLimits = {\n captureConcurrency: 16,\n maxRequestBytes: 20 * 1024 * 1024,\n maxRequests: 50_000,\n maxUploadBytes: 200 * 1024 * 1024,\n};\n\nconst encoder = new TextEncoder();\n\nconst positiveInteger = (name: string, value: number): number => {\n if (!(Number.isInteger(value) && value > 0)) {\n throw new BatchworkError(\n `batchwork: limits.${name} must be a positive integer.`\n );\n }\n return value;\n};\n\nexport const resolveBatchLimits = (\n limits: BatchLimits | undefined\n): ResolvedBatchLimits => ({\n captureConcurrency: positiveInteger(\n \"captureConcurrency\",\n limits?.captureConcurrency ?? DEFAULT_LIMITS.captureConcurrency\n ),\n maxRequestBytes: positiveInteger(\n \"maxRequestBytes\",\n limits?.maxRequestBytes ?? DEFAULT_LIMITS.maxRequestBytes\n ),\n maxRequests: positiveInteger(\n \"maxRequests\",\n limits?.maxRequests ?? DEFAULT_LIMITS.maxRequests\n ),\n maxUploadBytes: positiveInteger(\n \"maxUploadBytes\",\n limits?.maxUploadBytes ?? DEFAULT_LIMITS.maxUploadBytes\n ),\n});\n\nexport const byteLength = (value: string): number =>\n encoder.encode(value).length;\n\nexport const assertByteCount = (\n label: string,\n bytes: number,\n maxBytes: number\n): void => {\n if (bytes > maxBytes) {\n throw new BatchworkError(\n `batchwork: ${label} is ${bytes} bytes, exceeding the ${maxBytes} byte limit.`\n );\n }\n};\n\nexport const assertByteLength = (\n label: string,\n value: string,\n maxBytes: number\n): void => {\n assertByteCount(label, byteLength(value), maxBytes);\n};\n\nexport const mapWithConcurrency = async <Input, Output>(\n items: readonly Input[],\n concurrency: number,\n mapper: (item: Input) => Promise<Output>\n): Promise<Output[]> => {\n const results = [] as Output[];\n results.length = items.length;\n let nextIndex = 0;\n const workerCount = Math.min(concurrency, items.length);\n\n const runNext = async (): Promise<void> => {\n const index = nextIndex;\n nextIndex += 1;\n if (index >= items.length) {\n return;\n }\n results[index] = await mapper(items[index] as Input);\n await runNext();\n };\n\n await Promise.all(Array.from({ length: workerCount }, () => runNext()));\n return results;\n};\n",
8
+ "import { BatchworkError } from \"./errors\";\n\nconst assertOk = (url: string, init: RequestInit, response: Response) => {\n if (!response.ok) {\n throw new BatchworkError(\n `batchwork: ${init.method ?? \"GET\"} ${url} failed with ${response.status}.`\n );\n }\n};\n\n/** Make a request and parse a JSON response, throwing on non-2xx. */\nexport const requestJson = async <T>(\n url: string,\n init: RequestInit\n): Promise<T> => {\n const response = await fetch(url, init);\n assertOk(url, init, response);\n return (await response.json()) as T;\n};\n\n/** Make a request and return the raw body stream, throwing on non-2xx. */\nexport const requestStream = async (\n url: string,\n init: RequestInit\n): Promise<ReadableStream<Uint8Array>> => {\n const response = await fetch(url, init);\n assertOk(url, init, response);\n if (!response.body) {\n throw new BatchworkError(`batchwork: ${url} returned an empty body.`);\n }\n return response.body;\n};\n",
9
+ "import { BatchworkError } from \"./errors\";\nimport { assertByteCount, byteLength } from \"./limits\";\n\nconst NEWLINE = \"\\n\";\nconst DEFAULT_MAX_JSONL_LINE_BYTES = 20 * 1024 * 1024;\n\nexport interface JsonlParseOptions {\n maxLineBytes?: number;\n}\n\nexport interface JsonlEncodeOptions {\n label?: string;\n maxBytes?: number;\n}\n\nconst NEWLINE_BYTES = byteLength(NEWLINE);\n\nconst resolveMaxLineBytes = (options?: JsonlParseOptions): number => {\n const maxLineBytes = options?.maxLineBytes ?? DEFAULT_MAX_JSONL_LINE_BYTES;\n if (!(Number.isInteger(maxLineBytes) && maxLineBytes > 0)) {\n throw new BatchworkError(\n \"batchwork: JSONL maxLineBytes must be a positive integer.\"\n );\n }\n return maxLineBytes;\n};\n\nconst assertLineSize = (\n line: string,\n lineNumber: number,\n maxLineBytes: number\n): void => {\n const bytes = byteLength(line);\n if (bytes > maxLineBytes) {\n throw new BatchworkError(\n `batchwork: JSONL line ${lineNumber} is ${bytes} bytes, exceeding the ${maxLineBytes} byte limit.`\n );\n }\n};\n\nconst parseLine = <T>(\n line: string,\n lineNumber: number,\n maxLineBytes: number\n): T | undefined => {\n assertLineSize(line, lineNumber, maxLineBytes);\n const trimmed = line.trim();\n if (trimmed.length === 0) {\n return;\n }\n try {\n return JSON.parse(trimmed) as T;\n } catch (error) {\n throw new BatchworkError(\n `batchwork: invalid JSONL at line ${lineNumber}.`,\n { cause: error }\n );\n }\n};\n\nconst resolveMaxBytes = (options?: JsonlEncodeOptions): number | undefined => {\n const maxBytes = options?.maxBytes;\n if (maxBytes !== undefined && !(Number.isInteger(maxBytes) && maxBytes > 0)) {\n throw new BatchworkError(\n \"batchwork: JSONL maxBytes must be a positive integer.\"\n );\n }\n return maxBytes;\n};\n\nexport const encodeJsonl = (\n items: readonly unknown[],\n options?: JsonlEncodeOptions\n): string => {\n if (items.length === 0) {\n return \"\";\n }\n const lines: string[] = [];\n const maxBytes = resolveMaxBytes(options);\n const label = options?.label ?? \"JSONL\";\n let bytes = 0;\n for (const item of items) {\n const line = JSON.stringify(item);\n if (line === undefined) {\n throw new BatchworkError(\n `batchwork: ${label} contains a value that cannot be JSON encoded.`\n );\n }\n bytes += byteLength(line) + NEWLINE_BYTES;\n if (maxBytes !== undefined) {\n assertByteCount(label, bytes, maxBytes);\n }\n lines.push(line);\n }\n return `${lines.join(NEWLINE)}${NEWLINE}`;\n};\n\nexport const parseJsonl = <T = unknown>(\n text: string,\n options?: JsonlParseOptions\n): T[] => {\n const maxLineBytes = resolveMaxLineBytes(options);\n const results: T[] = [];\n const lines = text.split(NEWLINE);\n for (const [index, line] of lines.entries()) {\n const parsed = parseLine<T>(line, index + 1, maxLineBytes);\n if (parsed !== undefined) {\n results.push(parsed);\n }\n }\n return results;\n};\n\nconst isReadableStream = (\n source: ReadableStream<Uint8Array> | AsyncIterable<Uint8Array>\n): source is ReadableStream<Uint8Array> =>\n \"getReader\" in source &&\n typeof (source as ReadableStream<Uint8Array>).getReader === \"function\";\n\n// oxlint-disable-next-line func-style -- generators cannot be arrow functions.\nasync function* toByteIterable(\n source: ReadableStream<Uint8Array> | AsyncIterable<Uint8Array>\n): AsyncGenerator<Uint8Array> {\n // Prefer an explicit reader: a web `ReadableStream` (e.g. `fetch` response\n // bodies) is not reliably async-iterable at runtime across platforms.\n if (isReadableStream(source)) {\n const reader = source.getReader();\n try {\n let chunk = await reader.read();\n while (!chunk.done) {\n if (chunk.value) {\n yield chunk.value;\n }\n // oxlint-disable-next-line no-await-in-loop -- a stream is read sequentially.\n chunk = await reader.read();\n }\n } finally {\n reader.releaseLock();\n }\n return;\n }\n\n yield* source;\n}\n\n// oxlint-disable-next-line func-style -- generators cannot be arrow functions.\nexport async function* streamJsonl<T = unknown>(\n source: ReadableStream<Uint8Array> | AsyncIterable<Uint8Array>,\n options?: JsonlParseOptions\n): AsyncGenerator<T> {\n const decoder = new TextDecoder();\n const maxLineBytes = resolveMaxLineBytes(options);\n let buffer = \"\";\n let lineNumber = 1;\n\n for await (const chunk of toByteIterable(source)) {\n buffer += decoder.decode(chunk, { stream: true });\n let newlineIndex = buffer.indexOf(NEWLINE);\n while (newlineIndex !== -1) {\n const line = buffer.slice(0, newlineIndex);\n buffer = buffer.slice(newlineIndex + 1);\n const parsed = parseLine<T>(line, lineNumber, maxLineBytes);\n if (parsed !== undefined) {\n yield parsed;\n }\n lineNumber += 1;\n newlineIndex = buffer.indexOf(NEWLINE);\n }\n assertLineSize(buffer, lineNumber, maxLineBytes);\n }\n\n buffer += decoder.decode();\n const parsed = parseLine<T>(buffer, lineNumber, maxLineBytes);\n if (parsed !== undefined) {\n yield parsed;\n }\n}\n",
10
+ "import { BatchworkError } from \"./errors\";\nimport { assertByteCount, byteLength } from \"./limits\";\n\ninterface JsonArrayPayloadOptions {\n items: readonly unknown[];\n label: string;\n maxBytes: number;\n prefix: string;\n suffix: string;\n}\n\nexport const encodeJsonArrayPayload = ({\n items,\n label,\n maxBytes,\n prefix,\n suffix,\n}: JsonArrayPayloadOptions): string => {\n const encodedItems: string[] = [];\n let bytes = byteLength(prefix) + byteLength(suffix);\n assertByteCount(label, bytes, maxBytes);\n\n for (const [index, item] of items.entries()) {\n const encoded = JSON.stringify(item);\n if (encoded === undefined) {\n throw new BatchworkError(\n `batchwork: ${label} contains a value that cannot be JSON encoded.`\n );\n }\n bytes += byteLength(encoded);\n if (index > 0) {\n bytes += 1;\n }\n assertByteCount(label, bytes, maxBytes);\n encodedItems.push(encoded);\n }\n\n return `${prefix}${encodedItems.join(\",\")}${suffix}`;\n};\n",
11
+ "/** Small, defensive helpers for reading loosely-typed provider JSON. */\n\nexport const asRecord = (value: unknown): Record<string, unknown> => {\n if (typeof value === \"object\" && value !== null) {\n return value as Record<string, unknown>;\n }\n return {};\n};\n\nexport const asString = (value: unknown): string | undefined =>\n typeof value === \"string\" ? value : undefined;\n\nexport const asNumber = (value: unknown): number | undefined =>\n typeof value === \"number\" ? value : undefined;\n\nexport const asArray = (value: unknown): unknown[] =>\n Array.isArray(value) ? value : [];\n\n/** Read a non-empty array of numbers (e.g. an embedding vector), else undefined. */\nexport const asNumberArray = (value: unknown): number[] | undefined => {\n if (!Array.isArray(value) || value.length === 0) {\n return;\n }\n const numbers = value.filter(\n (item): item is number => typeof item === \"number\"\n );\n return numbers.length === value.length ? numbers : undefined;\n};\n\n/** Return a shallow copy of `obj` without `key`. */\nexport const omit = (\n obj: Record<string, unknown>,\n key: string\n): Record<string, unknown> => {\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) {\n if (k !== key) {\n result[k] = v;\n }\n }\n return result;\n};\n\n// An empty or malformed timestamp yields an `Invalid Date`, which later throws\n// `RangeError` from `.toISOString()` (e.g. when serializing a webhook event).\n// Normalize those to `undefined` so a bad provider value is simply omitted.\nconst validDate = (date: Date): Date | undefined =>\n Number.isNaN(date.getTime()) ? undefined : date;\n\n/** Coerce a provider timestamp (ISO string or unix seconds) to a `Date`. */\nexport const toDate = (value: unknown): Date | undefined => {\n if (typeof value === \"string\") {\n return validDate(new Date(value));\n }\n if (typeof value === \"number\") {\n return validDate(new Date(value * 1000));\n }\n};\n",
12
+ "import { BatchworkError } from \"../errors\";\n\nconst SIMPLE_PROVIDER_ID = /^[A-Za-z0-9_-]+$/u;\n\nexport const assertSimpleProviderId = (label: string, id: string): string => {\n if (!SIMPLE_PROVIDER_ID.test(id)) {\n throw new BatchworkError(`batchwork: invalid ${label}.`);\n }\n return id;\n};\n\nexport const assertPrefixedProviderId = (\n label: string,\n id: string,\n prefix: string\n): string => {\n const [actualPrefix, value, ...rest] = id.split(\"/\");\n if (\n rest.length > 0 ||\n actualPrefix !== prefix ||\n !value ||\n !SIMPLE_PROVIDER_ID.test(value)\n ) {\n throw new BatchworkError(`batchwork: invalid ${label}.`);\n }\n return id;\n};\n",
13
+ "import { BatchworkError } from \"../errors\";\nimport { requestJson, requestStream } from \"../http\";\nimport { streamJsonl } from \"../jsonl\";\nimport { resolveBatchLimits } from \"../limits\";\nimport { encodeJsonArrayPayload } from \"../payload\";\nimport type {\n BatchResult,\n BatchSnapshot,\n BatchStatus,\n BatchUsage,\n ProviderCredentials,\n} from \"../types\";\nimport { asArray, asNumber, asRecord, asString, omit, toDate } from \"../util\";\nimport type { BatchAdapter, SubmitInput } from \"./adapter\";\nimport { assertSimpleProviderId } from \"./ids\";\n\nconst ANTHROPIC_BASE = \"https://api.anthropic.com\";\nconst ANTHROPIC_VERSION = \"2023-06-01\";\n\nconst apiKey = (credentials: ProviderCredentials): string => {\n const key = credentials.apiKey ?? process.env.ANTHROPIC_API_KEY;\n if (!key) {\n throw new BatchworkError(\n \"batchwork: missing Anthropic API key. Set ANTHROPIC_API_KEY or pass `apiKey`.\"\n );\n }\n return key;\n};\n\nconst baseUrl = (credentials: ProviderCredentials): string =>\n credentials.baseURL ?? ANTHROPIC_BASE;\n\nconst validateResultsUrl = (\n rawUrl: string,\n credentials: ProviderCredentials\n): string => {\n let resultsUrl: URL;\n let expectedBase: URL;\n try {\n resultsUrl = new URL(rawUrl);\n expectedBase = new URL(baseUrl(credentials));\n } catch (error) {\n throw new BatchworkError(\"batchwork: invalid Anthropic results_url.\", {\n cause: error,\n });\n }\n if (resultsUrl.origin !== expectedBase.origin) {\n throw new BatchworkError(\n \"batchwork: Anthropic results_url must match the configured API origin.\"\n );\n }\n if (resultsUrl.username || resultsUrl.password) {\n throw new BatchworkError(\n \"batchwork: Anthropic results_url must not include credentials.\"\n );\n }\n return resultsUrl.toString();\n};\n\nconst headers = (credentials: ProviderCredentials): Record<string, string> => ({\n \"anthropic-version\": ANTHROPIC_VERSION,\n \"content-type\": \"application/json\",\n \"x-api-key\": apiKey(credentials),\n ...credentials.headers,\n});\n\nconst mapStatus = (status: string | undefined): BatchStatus => {\n if (status === \"ended\") {\n return \"completed\";\n }\n if (status === \"canceling\") {\n return \"cancelling\";\n }\n return \"in_progress\";\n};\n\nconst normalizeSnapshot = (raw: unknown): BatchSnapshot => {\n const obj = asRecord(raw);\n const counts = asRecord(obj.request_counts);\n const succeeded = asNumber(counts.succeeded) ?? 0;\n const errored = asNumber(counts.errored) ?? 0;\n const processing = asNumber(counts.processing) ?? 0;\n const canceled = asNumber(counts.canceled) ?? 0;\n const expired = asNumber(counts.expired) ?? 0;\n\n return {\n completedAt: toDate(obj.ended_at),\n createdAt: toDate(obj.created_at),\n expiresAt: toDate(obj.expires_at),\n id: asString(obj.id) ?? \"\",\n provider: \"anthropic\",\n raw,\n requestCounts: {\n canceled,\n completed: succeeded,\n expired,\n failed: errored,\n processing,\n total: succeeded + errored + processing + canceled + expired,\n },\n status: mapStatus(asString(obj.processing_status)),\n };\n};\n\nconst textFromMessage = (message: unknown): string | undefined => {\n const text = asArray(asRecord(message).content)\n .map((block) => asRecord(block))\n .filter((block) => block.type === \"text\")\n .map((block) => asString(block.text) ?? \"\")\n .join(\"\");\n return text.length > 0 ? text : undefined;\n};\n\nconst usageFromMessage = (message: unknown): BatchUsage | undefined => {\n const usage = asRecord(asRecord(message).usage);\n const inputTokens = asNumber(usage.input_tokens);\n const outputTokens = asNumber(usage.output_tokens);\n if (inputTokens === undefined && outputTokens === undefined) {\n return;\n }\n return {\n inputTokens,\n outputTokens,\n totalTokens: (inputTokens ?? 0) + (outputTokens ?? 0),\n };\n};\n\nconst normalizeResult = (line: unknown): BatchResult => {\n const obj = asRecord(line);\n const customId = asString(obj.custom_id) ?? \"\";\n const result = asRecord(obj.result);\n const type = asString(result.type);\n\n if (type === \"succeeded\") {\n return {\n customId,\n response: result.message,\n status: \"succeeded\",\n text: textFromMessage(result.message),\n usage: usageFromMessage(result.message),\n };\n }\n if (type === \"errored\") {\n const error = asRecord(result.error);\n const nested = asRecord(error.error);\n const source = Object.keys(nested).length > 0 ? nested : error;\n return {\n customId,\n error: {\n message: asString(source.message) ?? \"Request errored.\",\n type: asString(source.type),\n },\n response: result.error,\n status: \"errored\",\n };\n }\n if (type === \"expired\") {\n return { customId, status: \"expired\" };\n }\n return { customId, status: \"canceled\" };\n};\n\nconst submit = async (input: SubmitInput): Promise<BatchSnapshot> => {\n const limits = resolveBatchLimits(input.limits);\n const requests = input.built.map((item) => ({\n custom_id: item.customId,\n params: omit(item.body, \"stream\"),\n }));\n const body = encodeJsonArrayPayload({\n items: requests,\n label: \"batch upload payload\",\n maxBytes: limits.maxUploadBytes,\n prefix: '{\"requests\":[',\n suffix: \"]}\",\n });\n const raw = await requestJson(\n `${baseUrl(input.credentials)}/v1/messages/batches`,\n {\n body,\n headers: headers(input.credentials),\n method: \"POST\",\n }\n );\n return normalizeSnapshot(raw);\n};\n\nconst retrieve = async (\n id: string,\n credentials: ProviderCredentials\n): Promise<BatchSnapshot> => {\n const batchId = assertSimpleProviderId(\"Anthropic batch id\", id);\n const raw = await requestJson(\n `${baseUrl(credentials)}/v1/messages/batches/${batchId}`,\n { headers: headers(credentials) }\n );\n return normalizeSnapshot(raw);\n};\n\n// oxlint-disable-next-line func-style -- generators cannot be arrow functions.\nasync function* results(\n id: string,\n credentials: ProviderCredentials\n): AsyncGenerator<BatchResult> {\n const snapshot = await retrieve(id, credentials);\n const resultsUrl = asString(asRecord(snapshot.raw).results_url);\n if (!resultsUrl) {\n throw new BatchworkError(\n `batchwork: results are not ready for batch \"${id}\" (status: ${snapshot.status}).`\n );\n }\n const stream = await requestStream(\n validateResultsUrl(resultsUrl, credentials),\n {\n headers: headers(credentials),\n redirect: \"manual\",\n }\n );\n for await (const line of streamJsonl(stream)) {\n yield normalizeResult(line);\n }\n}\n\nconst cancel = async (\n id: string,\n credentials: ProviderCredentials\n): Promise<void> => {\n const batchId = assertSimpleProviderId(\"Anthropic batch id\", id);\n await requestJson(\n `${baseUrl(credentials)}/v1/messages/batches/${batchId}/cancel`,\n {\n headers: headers(credentials),\n method: \"POST\",\n }\n );\n};\n\nexport const anthropicAdapter: BatchAdapter = {\n cancel,\n id: \"anthropic\",\n results,\n retrieve,\n submit,\n};\n",
14
+ "import { BatchworkError } from \"../errors\";\nimport { requestJson } from \"../http\";\nimport { resolveBatchLimits } from \"../limits\";\nimport { encodeJsonArrayPayload } from \"../payload\";\nimport type {\n BatchResult,\n BatchSnapshot,\n BatchStatus,\n BatchUsage,\n ProviderCredentials,\n} from \"../types\";\nimport {\n asArray,\n asNumber,\n asNumberArray,\n asRecord,\n asString,\n omit,\n} from \"../util\";\nimport type { BatchAdapter, SubmitInput } from \"./adapter\";\nimport { assertPrefixedProviderId } from \"./ids\";\n\nconst GOOGLE_BASE = \"https://generativelanguage.googleapis.com/v1beta\";\nconst GOOGLE_BATCH_PREFIX = \"batches\";\n\nconst apiKey = (credentials: ProviderCredentials): string => {\n const key =\n credentials.apiKey ??\n process.env.GOOGLE_GENERATIVE_AI_API_KEY ??\n process.env.GEMINI_API_KEY;\n if (!key) {\n throw new BatchworkError(\n \"batchwork: missing Google Gemini API key. Set GOOGLE_GENERATIVE_AI_API_KEY (or GEMINI_API_KEY) or pass `apiKey`.\"\n );\n }\n return key;\n};\n\nconst baseUrl = (credentials: ProviderCredentials): string =>\n credentials.baseURL ?? GOOGLE_BASE;\n\nconst headers = (credentials: ProviderCredentials): Record<string, string> => ({\n \"content-type\": \"application/json\",\n \"x-goog-api-key\": apiKey(credentials),\n ...credentials.headers,\n});\n\n/** Gemini operation state. Live ops use `JOB_STATE_*`; match on the suffix. */\nconst mapState = (state: string | undefined, done: boolean): BatchStatus => {\n if (state) {\n if (state.endsWith(\"SUCCEEDED\")) {\n return \"completed\";\n }\n if (state.endsWith(\"FAILED\")) {\n return \"failed\";\n }\n if (state.endsWith(\"CANCELLED\")) {\n return \"cancelled\";\n }\n if (state.endsWith(\"EXPIRED\")) {\n return \"expired\";\n }\n if (state.endsWith(\"PENDING\")) {\n return \"validating\";\n }\n if (state.endsWith(\"RUNNING\")) {\n return \"in_progress\";\n }\n }\n return done ? \"completed\" : \"in_progress\";\n};\n\nconst inlinedResponses = (raw: unknown): unknown[] => {\n const obj = asRecord(raw);\n const response = asRecord(obj.response);\n const dest = asRecord(obj.dest);\n const responseInline =\n response.inlinedResponses ?? response.inlined_responses;\n const destInline = dest.inlinedResponses ?? dest.inlined_responses;\n const nestedResponseInline = asRecord(responseInline);\n const nestedDestInline = asRecord(destInline);\n return [\n ...asArray(responseInline),\n ...asArray(nestedResponseInline.inlinedResponses),\n ...asArray(nestedResponseInline.inlined_responses),\n ...asArray(destInline),\n ...asArray(nestedDestInline.inlinedResponses),\n ...asArray(nestedDestInline.inlined_responses),\n ];\n};\n\nconst normalizeSnapshot = (raw: unknown): BatchSnapshot => {\n const obj = asRecord(raw);\n const items = inlinedResponses(raw);\n const failed = items.filter((item) => asRecord(item).error).length;\n const id = asString(obj.name) ?? \"\";\n return {\n id: id\n ? assertPrefixedProviderId(\"Google operation id\", id, GOOGLE_BATCH_PREFIX)\n : \"\",\n provider: \"google\",\n raw,\n requestCounts: {\n completed: items.length - failed,\n failed,\n total: items.length,\n },\n status: mapState(\n asString(obj.state) ??\n asString(asRecord(obj.state).name) ??\n asString(asRecord(obj.metadata).state),\n obj.done === true\n ),\n };\n};\n\nconst textFromResponse = (response: unknown): string | undefined => {\n const candidate = asRecord(asArray(asRecord(response).candidates)[0]);\n const text = asArray(asRecord(candidate.content).parts)\n .map((part) => asString(asRecord(part).text) ?? \"\")\n .join(\"\");\n return text.length > 0 ? text : undefined;\n};\n\nconst embeddingFromResponse = (response: unknown): number[] | undefined =>\n asNumberArray(asRecord(asRecord(response).embedding).values);\n\nconst usageFromResponse = (response: unknown): BatchUsage | undefined => {\n const usage = asRecord(asRecord(response).usageMetadata);\n const inputTokens = asNumber(usage.promptTokenCount);\n const outputTokens = asNumber(usage.candidatesTokenCount);\n const totalTokens = asNumber(usage.totalTokenCount);\n if (\n inputTokens === undefined &&\n outputTokens === undefined &&\n totalTokens === undefined\n ) {\n return;\n }\n return {\n inputTokens,\n outputTokens,\n totalTokens: totalTokens ?? (inputTokens ?? 0) + (outputTokens ?? 0),\n };\n};\n\nconst normalizeResult = (item: unknown): BatchResult => {\n const obj = asRecord(item);\n const customId =\n asString(asRecord(obj.metadata).key) ??\n asString(obj.key) ??\n asString(obj.custom_id) ??\n \"\";\n if (obj.error) {\n const error = asRecord(obj.error);\n return {\n customId,\n error: {\n code: asNumber(error.code) ?? asString(error.code),\n message: asString(error.message) ?? \"Request errored.\",\n type: asString(error.status),\n },\n response: obj.error,\n status: \"errored\",\n };\n }\n return {\n customId,\n embedding: embeddingFromResponse(obj.response),\n response: obj.response,\n status: \"succeeded\",\n text: textFromResponse(obj.response),\n usage: usageFromResponse(obj.response),\n };\n};\n\n// Fields the single-value embedding capture emits flat, but the async batch\n// embedding API expects nested under `embedContentConfig`.\nconst EMBED_CONFIG_KEYS = new Set([\n \"outputDimensionality\",\n \"taskType\",\n \"title\",\n]);\n\n/** Reshape a captured `:embedContent` body into an async-batch `request`. */\nconst toEmbedRequest = (\n body: Record<string, unknown>\n): Record<string, unknown> => {\n const request: Record<string, unknown> = {};\n const config: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(body)) {\n if (EMBED_CONFIG_KEYS.has(key)) {\n config[key] = value;\n } else {\n request[key] = value;\n }\n }\n if (Object.keys(config).length > 0) {\n request.embedContentConfig = config;\n }\n return request;\n};\n\nconst submit = async (input: SubmitInput): Promise<BatchSnapshot> => {\n const limits = resolveBatchLimits(input.limits);\n // Embeddings capture targets `:embedContent`; route to the async batch\n // embedding method and reshape each request, otherwise generate content.\n const isEmbedding = input.endpoint.toLowerCase().includes(\"embedcontent\");\n const method = isEmbedding\n ? \"asyncBatchEmbedContent\"\n : \"batchGenerateContent\";\n const requests = input.built.map((item) => {\n const payload = omit(item.body, \"stream\");\n return {\n metadata: { key: item.customId },\n request: isEmbedding ? toEmbedRequest(payload) : payload,\n };\n });\n const body = encodeJsonArrayPayload({\n items: requests,\n label: \"batch upload payload\",\n maxBytes: limits.maxUploadBytes,\n prefix:\n '{\"batch\":{\"display_name\":\"batchwork\",\"input_config\":{\"requests\":{\"requests\":[',\n suffix: \"]}}}}\",\n });\n const raw = await requestJson(\n `${baseUrl(input.credentials)}/models/${input.modelId}:${method}`,\n {\n body,\n headers: headers(input.credentials),\n method: \"POST\",\n }\n );\n return normalizeSnapshot(raw);\n};\n\nconst retrieve = async (\n id: string,\n credentials: ProviderCredentials\n): Promise<BatchSnapshot> => {\n const operationId = assertPrefixedProviderId(\n \"Google operation id\",\n id,\n GOOGLE_BATCH_PREFIX\n );\n const raw = await requestJson(`${baseUrl(credentials)}/${operationId}`, {\n headers: headers(credentials),\n });\n return normalizeSnapshot(raw);\n};\n\n// oxlint-disable-next-line func-style -- generators cannot be arrow functions.\nasync function* results(\n id: string,\n credentials: ProviderCredentials\n): AsyncGenerator<BatchResult> {\n const snapshot = await retrieve(id, credentials);\n const raw = asRecord(snapshot.raw);\n const response = asRecord(raw.response);\n const dest = asRecord(raw.dest);\n const responsesFile =\n asString(asRecord(response.responsesFile).name) ??\n asString(response.responsesFile) ??\n asString(asRecord(response.responses_file).name) ??\n asString(response.responses_file) ??\n asString(dest.fileName) ??\n asString(dest.file_name);\n if (responsesFile) {\n throw new BatchworkError(\n `batchwork: batch \"${id}\" returned file-mode results, which are not supported yet.`\n );\n }\n const items = inlinedResponses(raw);\n if (items.length === 0) {\n throw new BatchworkError(\n `batchwork: results are not ready for batch \"${id}\" (status: ${snapshot.status}).`\n );\n }\n for (const item of items) {\n yield normalizeResult(item);\n }\n}\n\nconst cancel = async (\n id: string,\n credentials: ProviderCredentials\n): Promise<void> => {\n const operationId = assertPrefixedProviderId(\n \"Google operation id\",\n id,\n GOOGLE_BATCH_PREFIX\n );\n await requestJson(`${baseUrl(credentials)}/${operationId}:cancel`, {\n headers: headers(credentials),\n method: \"POST\",\n });\n};\n\n/**\n * Google Gemini (Developer API) batch adapter: submits inline requests via\n * `:batchGenerateContent`, polls the returned long-running operation, then reads\n * the inline responses keyed by each request's `metadata.key`.\n */\nexport const googleAdapter: BatchAdapter = {\n cancel,\n id: \"google\",\n results,\n retrieve,\n submit,\n};\n",
15
+ "/**\n * Helpers shared across the OpenAI-shaped adapters (OpenAI, Groq, Together,\n * Mistral). These providers all upload JSONL via a Files API, return results as\n * JSONL keyed by `custom_id`, and shape each result line like OpenAI's\n * (`{ custom_id, response: { status_code, body }, error }`).\n */\n\nimport { BatchworkError } from \"../errors\";\nimport { requestJson, requestStream } from \"../http\";\nimport { streamJsonl } from \"../jsonl\";\nimport type {\n BatchResult,\n BatchResultError,\n BatchUsage,\n ProviderCredentials,\n} from \"../types\";\nimport { asArray, asNumber, asNumberArray, asRecord, asString } from \"../util\";\n\nconst HTTP_OK_MIN = 200;\nconst HTTP_OK_MAX = 300;\n\n/** Resolve an API key from credentials or the provider's env var, or throw. */\nexport const resolveApiKey = (\n credentials: ProviderCredentials,\n envVar: string,\n label: string\n): string => {\n const key = credentials.apiKey ?? process.env[envVar];\n if (!key) {\n throw new BatchworkError(\n `batchwork: missing ${label} API key. Set ${envVar} or pass \\`apiKey\\`.`\n );\n }\n return key;\n};\n\nexport const textFromBody = (body: unknown): string | undefined => {\n const obj = asRecord(body);\n const choices = asArray(obj.choices);\n if (choices.length > 0) {\n const content = asString(asRecord(asRecord(choices[0]).message).content);\n if (content) {\n return content;\n }\n }\n return asString(obj.output_text);\n};\n\n/** Read the embedding vector from an OpenAI-shaped embeddings response body. */\nexport const embeddingFromBody = (body: unknown): number[] | undefined => {\n const data = asArray(asRecord(body).data);\n if (data.length === 0) {\n return;\n }\n return asNumberArray(asRecord(data[0]).embedding);\n};\n\nexport const usageFromBody = (body: unknown): BatchUsage | undefined => {\n const usage = asRecord(asRecord(body).usage);\n const inputTokens =\n asNumber(usage.prompt_tokens) ?? asNumber(usage.input_tokens);\n const outputTokens =\n asNumber(usage.completion_tokens) ?? asNumber(usage.output_tokens);\n const totalTokens = asNumber(usage.total_tokens);\n if (\n inputTokens === undefined &&\n outputTokens === undefined &&\n totalTokens === undefined\n ) {\n return;\n }\n return {\n inputTokens,\n outputTokens,\n totalTokens: totalTokens ?? (inputTokens ?? 0) + (outputTokens ?? 0),\n };\n};\n\nconst errorFromValue = (value: unknown, fallback: string): BatchResultError => {\n const obj = asRecord(value);\n const nested = asRecord(obj.error);\n const source = nested.message ? nested : obj;\n return {\n code: asNumber(source.code) ?? asString(source.code),\n message: asString(source.message) ?? fallback,\n type: asString(source.type),\n };\n};\n\n/** Normalize an OpenAI-shaped result line into a {@link BatchResult}. */\nexport const normalizeOpenAIResult = (line: unknown): BatchResult => {\n const obj = asRecord(line);\n const customId = asString(obj.custom_id) ?? \"\";\n\n if (obj.error) {\n return {\n customId,\n error: errorFromValue(obj.error, \"Request errored.\"),\n response: obj.error,\n status: \"errored\",\n };\n }\n\n const response = asRecord(obj.response);\n const statusCode = asNumber(response.status_code) ?? 0;\n if (statusCode >= HTTP_OK_MIN && statusCode < HTTP_OK_MAX) {\n return {\n customId,\n embedding: embeddingFromBody(response.body),\n response: response.body,\n status: \"succeeded\",\n text: textFromBody(response.body),\n usage: usageFromBody(response.body),\n };\n }\n\n return {\n customId,\n error: errorFromValue(\n response.body,\n `Request failed with status ${statusCode}.`\n ),\n response: response.body,\n status: \"errored\",\n };\n};\n\n// Upload a JSONL batch input file and return its id. Purpose defaults to `batch`.\nexport const uploadInputFile = async (\n jsonl: string,\n baseUrl: string,\n headers: Record<string, string>,\n options: { purpose?: string | null } = {}\n): Promise<string> => {\n const form = new FormData();\n const purpose = options.purpose === undefined ? \"batch\" : options.purpose;\n if (purpose !== null) {\n form.append(\"purpose\", purpose);\n }\n form.append(\n \"file\",\n new Blob([jsonl], { type: \"application/jsonl\" }),\n \"batchwork.jsonl\"\n );\n const raw = await requestJson<{ id: string }>(`${baseUrl}/files`, {\n body: form,\n headers,\n method: \"POST\",\n redirect: \"manual\",\n });\n return raw.id;\n};\n\n/**\n * Stream a JSONL result file's content as normalized OpenAI-shaped results.\n *\n * @yields {BatchResult} the normalized result for each line.\n */\n// oxlint-disable-next-line func-style -- generators cannot be arrow functions.\nexport async function* streamResultFile(\n fileId: string,\n baseUrl: string,\n headers: Record<string, string>\n): AsyncGenerator<BatchResult> {\n const stream = await requestStream(`${baseUrl}/files/${fileId}/content`, {\n headers,\n redirect: \"manual\",\n });\n for await (const line of streamJsonl(stream)) {\n yield normalizeOpenAIResult(line);\n }\n}\n",
16
+ "/**\n * Factory for OpenAI-compatible batch adapters. OpenAI, Groq, and Together AI\n * all share the same lifecycle — upload JSONL via the Files API, create a batch\n * referencing the file, poll a `status` field, then download output/error files\n * — differing only in base URL, credentials, and minor request-line shape.\n */\n\nimport { BatchworkError } from \"../errors\";\nimport { requestJson } from \"../http\";\nimport { encodeJsonl } from \"../jsonl\";\nimport { resolveBatchLimits } from \"../limits\";\nimport type {\n BatchProvider,\n BatchResult,\n BatchSnapshot,\n BatchStatus,\n ProviderCredentials,\n} from \"../types\";\nimport { asNumber, asRecord, asString, omit, toDate } from \"../util\";\nimport type { BatchAdapter, SubmitInput } from \"./adapter\";\nimport { assertSimpleProviderId } from \"./ids\";\nimport { resolveApiKey, streamResultFile, uploadInputFile } from \"./shared\";\n\n// How a batch input line is shaped.\nexport type BatchLineFormat = \"body-only\" | \"method-url\";\n\nexport interface OpenAICompatibleConfig {\n apiKeyEnv: string;\n apiKeyLabel: string;\n baseUrl: string;\n // How long the provider may take to finish (OpenAI/Groq/Together).\n completionWindow?: string;\n // Files API purpose value for uploaded JSONL batch inputs.\n filePurpose?: string;\n id: BatchProvider;\n /**\n * Override the JSONL upload. Defaults to a direct multipart POST to the Files\n * API (OpenAI, Groq); Together replaces it with its presigned-URL flow.\n * Returns the uploaded file id.\n */\n uploadFile?: (args: {\n baseUrl: string;\n headers: Record<string, string>;\n jsonl: string;\n purpose: string;\n }) => Promise<string>;\n /**\n * Input-line shape. `method-url` writes `{ custom_id, method, url, body }`\n * (OpenAI, Groq); `body-only` writes `{ custom_id, body }` (Together).\n */\n lineFormat?: BatchLineFormat;\n /**\n * Map the captured endpoint path to the value the provider expects in the\n * batch `url`/`endpoint` field (e.g. Groq serves under `/openai/v1` but its\n * batch `url` must be `/v1/chat/completions`).\n */\n normalizeEndpoint?: (endpoint: string) => string;\n}\n\nconst DEFAULT_COMPLETION_WINDOW = \"24h\";\n\nconst mapStatus = (status: string | undefined): BatchStatus => {\n const normalized = status?.toLowerCase();\n switch (normalized) {\n case \"validating\":\n case \"in_progress\":\n case \"finalizing\":\n case \"completed\":\n case \"failed\":\n case \"expired\":\n case \"cancelling\":\n case \"cancelled\": {\n return normalized;\n }\n default: {\n return \"in_progress\";\n }\n }\n};\n\nconst normalizeSnapshot = (\n raw: unknown,\n provider: BatchProvider\n): BatchSnapshot => {\n const outer = asRecord(raw);\n const obj = asRecord(outer.job);\n const source = Object.keys(obj).length > 0 ? obj : outer;\n const counts = asRecord(source.request_counts);\n return {\n completedAt: toDate(source.completed_at),\n createdAt: toDate(source.created_at),\n expiresAt: toDate(source.expires_at),\n id: asString(source.id) ?? \"\",\n provider,\n raw: source,\n requestCounts: {\n completed: asNumber(counts.completed) ?? 0,\n failed: asNumber(counts.failed) ?? 0,\n total: asNumber(counts.total) ?? 0,\n },\n status: mapStatus(asString(source.status)),\n };\n};\n\n// Build an OpenAI-compatible adapter from a provider config.\nexport const createOpenAICompatibleAdapter = (\n config: OpenAICompatibleConfig\n): BatchAdapter => {\n const completionWindow = config.completionWindow ?? DEFAULT_COMPLETION_WINDOW;\n const lineFormat = config.lineFormat ?? \"method-url\";\n\n const baseUrl = (credentials: ProviderCredentials): string =>\n credentials.baseURL ?? config.baseUrl;\n\n const authHeaders = (\n credentials: ProviderCredentials\n ): Record<string, string> => ({\n Authorization: `Bearer ${resolveApiKey(credentials, config.apiKeyEnv, config.apiKeyLabel)}`,\n ...credentials.headers,\n });\n\n const submit = async (input: SubmitInput): Promise<BatchSnapshot> => {\n const limits = resolveBatchLimits(input.limits);\n const endpoint = config.normalizeEndpoint\n ? config.normalizeEndpoint(input.endpoint)\n : input.endpoint;\n const jsonl = encodeJsonl(\n input.built.map((item) => {\n const body = omit(item.body, \"stream\");\n if (lineFormat === \"body-only\") {\n return { body, custom_id: item.customId };\n }\n return {\n body,\n custom_id: item.customId,\n method: \"POST\",\n url: endpoint,\n };\n }),\n { label: \"batch upload JSONL\", maxBytes: limits.maxUploadBytes }\n );\n const headers = authHeaders(input.credentials);\n const url = baseUrl(input.credentials);\n const purpose = config.filePurpose ?? \"batch\";\n const inputFileId = await (config.uploadFile\n ? config.uploadFile({ baseUrl: url, headers, jsonl, purpose })\n : uploadInputFile(jsonl, url, headers, { purpose }));\n const raw = await requestJson(`${url}/batches`, {\n body: JSON.stringify({\n completion_window: completionWindow,\n endpoint,\n input_file_id: inputFileId,\n metadata: input.metadata,\n }),\n headers: { ...headers, \"content-type\": \"application/json\" },\n method: \"POST\",\n });\n return normalizeSnapshot(raw, config.id);\n };\n\n const retrieve = async (\n id: string,\n credentials: ProviderCredentials\n ): Promise<BatchSnapshot> => {\n const batchId = assertSimpleProviderId(`${config.id} batch id`, id);\n const raw = await requestJson(\n `${baseUrl(credentials)}/batches/${batchId}`,\n {\n headers: authHeaders(credentials),\n }\n );\n return normalizeSnapshot(raw, config.id);\n };\n\n // oxlint-disable-next-line func-style -- generators cannot be arrow functions.\n async function* results(\n id: string,\n credentials: ProviderCredentials\n ): AsyncGenerator<BatchResult> {\n const snapshot = await retrieve(id, credentials);\n const raw = asRecord(snapshot.raw);\n const outputFileId = asString(raw.output_file_id);\n const errorFileId = asString(raw.error_file_id);\n\n if (!(outputFileId || errorFileId)) {\n throw new BatchworkError(\n `batchwork: results are not ready for batch \"${id}\" (status: ${snapshot.status}).`\n );\n }\n const headers = authHeaders(credentials);\n if (outputFileId) {\n yield* streamResultFile(\n assertSimpleProviderId(`${config.id} output file id`, outputFileId),\n baseUrl(credentials),\n headers\n );\n }\n if (errorFileId) {\n yield* streamResultFile(\n assertSimpleProviderId(`${config.id} error file id`, errorFileId),\n baseUrl(credentials),\n headers\n );\n }\n }\n\n const cancel = async (\n id: string,\n credentials: ProviderCredentials\n ): Promise<void> => {\n const batchId = assertSimpleProviderId(`${config.id} batch id`, id);\n await requestJson(`${baseUrl(credentials)}/batches/${batchId}/cancel`, {\n headers: authHeaders(credentials),\n method: \"POST\",\n });\n };\n\n return { cancel, id: config.id, results, retrieve, submit };\n};\n",
17
+ "import { createOpenAICompatibleAdapter } from \"./openai-compatible\";\n\n/**\n * Groq batch adapter. Groq's batch API is OpenAI-compatible (Files API +\n * `/batches`), so it reuses the OpenAI-compatible flow. Groq is served under\n * `/openai/v1`, but its batch `url` must be `/v1/chat/completions`, so the\n * captured endpoint's `/openai` prefix is stripped.\n */\nexport const groqAdapter = createOpenAICompatibleAdapter({\n apiKeyEnv: \"GROQ_API_KEY\",\n apiKeyLabel: \"Groq\",\n baseUrl: \"https://api.groq.com/openai/v1\",\n id: \"groq\",\n lineFormat: \"method-url\",\n normalizeEndpoint: (endpoint) => endpoint.replace(/^\\/openai/u, \"\"),\n});\n",
18
+ "import { BatchworkError } from \"../errors\";\nimport { requestJson } from \"../http\";\nimport { encodeJsonl } from \"../jsonl\";\nimport { resolveBatchLimits } from \"../limits\";\nimport type {\n BatchResult,\n BatchSnapshot,\n BatchStatus,\n ProviderCredentials,\n} from \"../types\";\nimport { asNumber, asRecord, asString, omit, toDate } from \"../util\";\nimport type { BatchAdapter, SubmitInput } from \"./adapter\";\nimport { assertSimpleProviderId } from \"./ids\";\nimport { resolveApiKey, streamResultFile, uploadInputFile } from \"./shared\";\n\nconst MISTRAL_BASE = \"https://api.mistral.ai/v1\";\n\nconst apiKey = (credentials: ProviderCredentials): string =>\n resolveApiKey(credentials, \"MISTRAL_API_KEY\", \"Mistral\");\n\nconst baseUrl = (credentials: ProviderCredentials): string =>\n credentials.baseURL ?? MISTRAL_BASE;\n\nconst authHeaders = (\n credentials: ProviderCredentials\n): Record<string, string> => ({\n Authorization: `Bearer ${apiKey(credentials)}`,\n ...credentials.headers,\n});\n\nconst mapStatus = (status: string | undefined): BatchStatus => {\n switch (status) {\n case \"QUEUED\": {\n return \"validating\";\n }\n case \"SUCCESS\": {\n return \"completed\";\n }\n case \"FAILED\": {\n return \"failed\";\n }\n case \"TIMEOUT_EXCEEDED\": {\n return \"expired\";\n }\n case \"CANCELLATION_REQUESTED\": {\n return \"cancelling\";\n }\n case \"CANCELLED\": {\n return \"cancelled\";\n }\n default: {\n return \"in_progress\";\n }\n }\n};\n\nconst normalizeSnapshot = (raw: unknown): BatchSnapshot => {\n const obj = asRecord(raw);\n const succeeded = asNumber(obj.succeeded_requests) ?? 0;\n const failed = asNumber(obj.failed_requests) ?? 0;\n const id = asString(obj.id) ?? \"\";\n return {\n completedAt: toDate(obj.completed_at),\n createdAt: toDate(obj.created_at),\n id: id ? assertSimpleProviderId(\"Mistral job id\", id) : \"\",\n provider: \"mistral\",\n raw,\n requestCounts: {\n completed: succeeded,\n failed,\n total: asNumber(obj.total_requests) ?? succeeded + failed,\n },\n status: mapStatus(asString(obj.status)),\n };\n};\n\nconst submit = async (input: SubmitInput): Promise<BatchSnapshot> => {\n const limits = resolveBatchLimits(input.limits);\n // Mistral sets the model on the job, so strip it (and `stream`) from each line.\n const jsonl = encodeJsonl(\n input.built.map((item) => ({\n body: omit(omit(item.body, \"stream\"), \"model\"),\n custom_id: item.customId,\n })),\n { label: \"batch upload JSONL\", maxBytes: limits.maxUploadBytes }\n );\n const inputFileId = await uploadInputFile(\n jsonl,\n baseUrl(input.credentials),\n authHeaders(input.credentials)\n );\n const raw = await requestJson(`${baseUrl(input.credentials)}/batch/jobs`, {\n body: JSON.stringify({\n endpoint: input.endpoint,\n input_files: [inputFileId],\n metadata: input.metadata,\n model: input.modelId,\n }),\n headers: {\n ...authHeaders(input.credentials),\n \"content-type\": \"application/json\",\n },\n method: \"POST\",\n });\n return normalizeSnapshot(raw);\n};\n\nconst retrieve = async (\n id: string,\n credentials: ProviderCredentials\n): Promise<BatchSnapshot> => {\n const jobId = assertSimpleProviderId(\"Mistral job id\", id);\n const raw = await requestJson(`${baseUrl(credentials)}/batch/jobs/${jobId}`, {\n headers: authHeaders(credentials),\n });\n return normalizeSnapshot(raw);\n};\n\n// oxlint-disable-next-line func-style -- generators cannot be arrow functions.\nasync function* results(\n id: string,\n credentials: ProviderCredentials\n): AsyncGenerator<BatchResult> {\n const snapshot = await retrieve(id, credentials);\n const raw = asRecord(snapshot.raw);\n const outputFileId = asString(raw.output_file);\n const errorFileId = asString(raw.error_file);\n const headers = authHeaders(credentials);\n if (outputFileId) {\n yield* streamResultFile(\n assertSimpleProviderId(\"Mistral output file id\", outputFileId),\n baseUrl(credentials),\n headers\n );\n }\n if (errorFileId) {\n yield* streamResultFile(\n assertSimpleProviderId(\"Mistral error file id\", errorFileId),\n baseUrl(credentials),\n headers\n );\n }\n if (!(outputFileId || errorFileId)) {\n throw new BatchworkError(\n `batchwork: results are not ready for batch \"${id}\" (status: ${snapshot.status}).`\n );\n }\n}\n\nconst cancel = async (\n id: string,\n credentials: ProviderCredentials\n): Promise<void> => {\n const jobId = assertSimpleProviderId(\"Mistral job id\", id);\n await requestJson(`${baseUrl(credentials)}/batch/jobs/${jobId}/cancel`, {\n headers: authHeaders(credentials),\n method: \"POST\",\n });\n};\n\n/**\n * Mistral batch adapter: uploads JSONL (`purpose=batch`), creates a job with the\n * model/endpoint set on the job, polls `status`, then downloads the OpenAI-shaped\n * output/error files.\n */\nexport const mistralAdapter: BatchAdapter = {\n cancel,\n id: \"mistral\",\n results,\n retrieve,\n submit,\n};\n",
19
+ "import { createOpenAICompatibleAdapter } from \"./openai-compatible\";\n\n/**\n * OpenAI batch adapter: builds JSONL, uploads it via the Files API\n * (`purpose=batch`), creates the batch, polls `status`, then downloads and\n * parses the output and error files.\n */\nexport const openaiAdapter = createOpenAICompatibleAdapter({\n apiKeyEnv: \"OPENAI_API_KEY\",\n apiKeyLabel: \"OpenAI\",\n baseUrl: \"https://api.openai.com/v1\",\n id: \"openai\",\n lineFormat: \"method-url\",\n});\n",
20
+ "import { BatchworkError } from \"../errors\";\nimport { requestJson } from \"../http\";\nimport { assertSimpleProviderId } from \"./ids\";\nimport { createOpenAICompatibleAdapter } from \"./openai-compatible\";\n\nconst INPUT_FILE_NAME = \"batchwork.jsonl\";\nconst HTTP_FOUND = 302;\n\nconst parseIpv4 = (host: string): number[] | undefined => {\n if (!/^\\d{1,3}(?:\\.\\d{1,3}){3}$/u.test(host)) {\n return;\n }\n const parts = host.split(\".\").map(Number);\n const valid = parts.every(\n (part) => Number.isInteger(part) && part >= 0 && part <= 255\n );\n return valid ? parts : undefined;\n};\n\nconst isPrivateIpv4 = (parts: number[]): boolean => {\n const [a = 0, b = 0] = parts;\n return (\n a === 0 ||\n a === 10 ||\n a === 127 ||\n (a === 100 && b >= 64 && b <= 127) ||\n (a === 169 && b === 254) ||\n (a === 172 && b >= 16 && b <= 31) ||\n (a === 192 && b === 168) ||\n (a === 198 && (b === 18 || b === 19)) ||\n a >= 224\n );\n};\n\nconst isPrivateIpv6 = (host: string): boolean => {\n const normalized = host.replace(/^\\[/u, \"\").replace(/\\]$/u, \"\").toLowerCase();\n // Only an IPv6 literal can be a private address, and one always contains a\n // colon — guard so a bare DNS name like `fc2.com` is not mistaken for `fc00::/7`.\n if (!normalized.includes(\":\")) {\n return false;\n }\n return (\n normalized === \"::\" ||\n normalized === \"::1\" ||\n normalized.startsWith(\"fc\") ||\n normalized.startsWith(\"fd\") ||\n normalized.startsWith(\"fe80:\")\n );\n};\n\nconst validateUploadLocation = (location: string): string => {\n let url: URL;\n try {\n url = new URL(location);\n } catch (error) {\n throw new BatchworkError(\n \"batchwork: Together upload Location must be a valid URL.\",\n { cause: error }\n );\n }\n if (url.protocol !== \"https:\") {\n throw new BatchworkError(\n \"batchwork: Together upload Location must use https.\"\n );\n }\n if (url.username || url.password) {\n throw new BatchworkError(\n \"batchwork: Together upload Location must not include credentials.\"\n );\n }\n const host = url.hostname.toLowerCase();\n const ipv4 = parseIpv4(host);\n if (\n host === \"localhost\" ||\n host.endsWith(\".localhost\") ||\n host.endsWith(\".local\") ||\n (ipv4 && isPrivateIpv4(ipv4)) ||\n isPrivateIpv6(host)\n ) {\n throw new BatchworkError(\n \"batchwork: Together upload Location must not target localhost or private networks.\"\n );\n }\n return url.toString();\n};\n\n/**\n * Together uploads files via a presigned URL rather than a direct multipart\n * upload of the bytes. The flow is three steps:\n *\n * 1. `POST /files` with multipart *metadata only* (`purpose`, `file_name`,\n * `file_type` — no file part) responds `302` with a `Location` (the\n * presigned storage URL) and an `X-Together-File-Id` header.\n * 2. `PUT` the raw bytes to that `Location` (no auth — the URL is signed).\n * 3. `POST /files/{id}/preprocess` to finalize the upload.\n */\nconst uploadTogetherFile = async (args: {\n baseUrl: string;\n headers: Record<string, string>;\n jsonl: string;\n purpose: string;\n}): Promise<string> => {\n const metadata = new FormData();\n metadata.append(\"purpose\", args.purpose);\n metadata.append(\"file_name\", INPUT_FILE_NAME);\n metadata.append(\"file_type\", \"jsonl\");\n const init = await fetch(`${args.baseUrl}/files`, {\n body: metadata,\n // Let fetch set the multipart content-type/boundary; only auth is needed.\n headers: args.headers,\n method: \"POST\",\n // Together signals the presigned URL via a redirect we must read, not follow.\n redirect: \"manual\",\n });\n const location = init.headers.get(\"location\");\n const fileId = init.headers.get(\"x-together-file-id\");\n if (init.status !== HTTP_FOUND || !(location && fileId)) {\n throw new BatchworkError(\n `batchwork: Together upload could not be initiated (${init.status}).`\n );\n }\n\n // The presigned URL carries its own auth; sending Together's would break it.\n const uploadLocation = validateUploadLocation(location);\n const upload = await fetch(uploadLocation, {\n body: args.jsonl,\n method: \"PUT\",\n redirect: \"manual\",\n });\n if (!upload.ok) {\n throw new BatchworkError(\n `batchwork: Together file upload failed (${upload.status}).`\n );\n }\n\n const safeFileId = assertSimpleProviderId(\"Together file id\", fileId);\n await requestJson(`${args.baseUrl}/files/${safeFileId}/preprocess`, {\n headers: args.headers,\n method: \"POST\",\n });\n return safeFileId;\n};\n\n/**\n * Together AI batch adapter. Together's batch API mirrors OpenAI's (Files API +\n * `/batches`) but uses the leaner `{ custom_id, body }` input-line shape, with\n * the endpoint declared on the batch rather than per line, and a presigned-URL\n * file upload in place of OpenAI's direct multipart POST.\n */\nexport const togetherAdapter = createOpenAICompatibleAdapter({\n apiKeyEnv: \"TOGETHER_API_KEY\",\n apiKeyLabel: \"Together AI\",\n baseUrl: \"https://api.together.xyz/v1\",\n filePurpose: \"batch-api\",\n id: \"together\",\n lineFormat: \"body-only\",\n uploadFile: uploadTogetherFile,\n});\n",
21
+ "import { requestJson } from \"../http\";\nimport { encodeJsonl } from \"../jsonl\";\nimport { resolveBatchLimits } from \"../limits\";\nimport type {\n BatchResult,\n BatchSnapshot,\n BatchStatus,\n ProviderCredentials,\n} from \"../types\";\nimport { asNumber, asRecord, asString, omit, toDate } from \"../util\";\nimport type { BatchAdapter, SubmitInput } from \"./adapter\";\nimport { assertSimpleProviderId } from \"./ids\";\nimport {\n resolveApiKey,\n textFromBody,\n uploadInputFile,\n usageFromBody,\n} from \"./shared\";\n\nconst XAI_BASE = \"https://api.x.ai/v1\";\nconst RESULTS_PAGE_SIZE = 100;\n\nconst apiKey = (credentials: ProviderCredentials): string =>\n resolveApiKey(credentials, \"XAI_API_KEY\", \"xAI\");\n\nconst baseUrl = (credentials: ProviderCredentials): string =>\n credentials.baseURL ?? XAI_BASE;\n\nconst authHeaders = (\n credentials: ProviderCredentials\n): Record<string, string> => ({\n Authorization: `Bearer ${apiKey(credentials)}`,\n ...credentials.headers,\n});\n\nconst deriveStatus = (state: Record<string, unknown>): BatchStatus => {\n const pending = asNumber(state.num_pending);\n // No counts yet (e.g. immediately after creation): still processing.\n if (pending === undefined) {\n return \"in_progress\";\n }\n const total = asNumber(state.num_requests) ?? 0;\n const cancelled = asNumber(state.num_cancelled) ?? 0;\n if (total === 0) {\n return \"in_progress\";\n }\n if (pending > 0) {\n return \"in_progress\";\n }\n if (cancelled > 0 && cancelled === total) {\n return \"cancelled\";\n }\n return \"completed\";\n};\n\nconst normalizeSnapshot = (raw: unknown): BatchSnapshot => {\n const obj = asRecord(raw);\n const state = asRecord(obj.state);\n const id = asString(obj.batch_id) ?? asString(obj.id) ?? \"\";\n return {\n // xAI reports the completion time on `finish_time`; `cancel_time` is only\n // set when a batch is cancelled, so it must not stand in for completedAt.\n completedAt: toDate(obj.finish_time ?? obj.completed_at),\n createdAt: toDate(obj.create_time),\n expiresAt: toDate(obj.expire_time ?? obj.expires_at),\n id: id ? assertSimpleProviderId(\"xAI batch id\", id) : \"\",\n provider: \"xai\",\n raw,\n requestCounts: {\n canceled: asNumber(state.num_cancelled) ?? 0,\n completed: asNumber(state.num_success) ?? 0,\n failed: asNumber(state.num_error) ?? 0,\n processing: asNumber(state.num_pending) ?? 0,\n total: asNumber(state.num_requests) ?? 0,\n },\n status: deriveStatus(state),\n };\n};\n\nconst normalizeResult = (item: unknown): BatchResult => {\n const obj = asRecord(item);\n const customId = asString(obj.batch_request_id) ?? \"\";\n const batchResult = asRecord(obj.batch_result);\n const resultError = batchResult.error;\n const errorMessage =\n asString(obj.error_message) ??\n asString(resultError) ??\n asString(asRecord(resultError).message);\n if (errorMessage) {\n return {\n customId,\n error: {\n message: errorMessage,\n type: asString(asRecord(resultError).type),\n },\n response: obj,\n status: \"errored\",\n };\n }\n // `batch_result.response` is keyed by operation type; chat lives under\n // `chat_get_completion`. Fall back to the first value for other op types.\n const response = asRecord(batchResult.response);\n const completion = response.chat_get_completion ?? Object.values(response)[0];\n return {\n customId,\n response: completion,\n status: \"succeeded\",\n text: textFromBody(completion),\n usage: usageFromBody(completion),\n };\n};\n\nconst submit = async (input: SubmitInput): Promise<BatchSnapshot> => {\n const limits = resolveBatchLimits(input.limits);\n const jsonl = encodeJsonl(\n input.built.map((item) => ({\n body: omit(item.body, \"stream\"),\n custom_id: item.customId,\n method: \"POST\",\n url: input.endpoint,\n })),\n { label: \"batch upload JSONL\", maxBytes: limits.maxUploadBytes }\n );\n const inputFileId = await uploadInputFile(\n jsonl,\n baseUrl(input.credentials),\n authHeaders(input.credentials),\n { purpose: null }\n );\n const raw = await requestJson(`${baseUrl(input.credentials)}/batches`, {\n body: JSON.stringify({ input_file_id: inputFileId, name: \"batchwork\" }),\n headers: {\n ...authHeaders(input.credentials),\n \"content-type\": \"application/json\",\n },\n method: \"POST\",\n });\n return normalizeSnapshot(raw);\n};\n\nconst retrieve = async (\n id: string,\n credentials: ProviderCredentials\n): Promise<BatchSnapshot> => {\n const batchId = assertSimpleProviderId(\"xAI batch id\", id);\n const raw = await requestJson(`${baseUrl(credentials)}/batches/${batchId}`, {\n headers: authHeaders(credentials),\n });\n return normalizeSnapshot(raw);\n};\n\n// oxlint-disable-next-line func-style -- generators cannot be arrow functions.\nasync function* results(\n id: string,\n credentials: ProviderCredentials\n): AsyncGenerator<BatchResult> {\n const batchId = assertSimpleProviderId(\"xAI batch id\", id);\n const headers = authHeaders(credentials);\n let token: string | undefined;\n do {\n const query = new URLSearchParams({ limit: String(RESULTS_PAGE_SIZE) });\n if (token) {\n query.set(\"pagination_token\", token);\n }\n // oxlint-disable-next-line no-await-in-loop -- pages are read sequentially.\n const raw = await requestJson<Record<string, unknown>>(\n `${baseUrl(credentials)}/batches/${batchId}/results?${query.toString()}`,\n { headers }\n );\n const page = asRecord(raw);\n for (const item of Array.isArray(page.results) ? page.results : []) {\n yield normalizeResult(item);\n }\n token = asString(page.pagination_token);\n } while (token);\n}\n\nconst cancel = async (\n id: string,\n credentials: ProviderCredentials\n): Promise<void> => {\n const batchId = assertSimpleProviderId(\"xAI batch id\", id);\n await requestJson(`${baseUrl(credentials)}/batches/${batchId}:cancel`, {\n headers: authHeaders(credentials),\n method: \"POST\",\n });\n};\n\n/**\n * xAI (Grok) batch adapter. Uses xAI's OpenAI-compatible file-upload path\n * (`/v1/files` + `/v1/batches` with `input_file_id`), but its status, paginated\n * `/results`, and `:cancel` shapes are proprietary.\n */\nexport const xaiAdapter: BatchAdapter = {\n cancel,\n id: \"xai\",\n results,\n retrieve,\n submit,\n};\n",
22
+ "import type { BatchProvider } from \"../types\";\nimport type { BatchAdapter } from \"./adapter\";\nimport { anthropicAdapter } from \"./anthropic\";\nimport { googleAdapter } from \"./google\";\nimport { groqAdapter } from \"./groq\";\nimport { mistralAdapter } from \"./mistral\";\nimport { openaiAdapter } from \"./openai\";\nimport { togetherAdapter } from \"./together\";\nimport { xaiAdapter } from \"./xai\";\n\nconst adapters: Record<BatchProvider, BatchAdapter> = {\n anthropic: anthropicAdapter,\n google: googleAdapter,\n groq: groqAdapter,\n mistral: mistralAdapter,\n openai: openaiAdapter,\n together: togetherAdapter,\n xai: xaiAdapter,\n};\n\nexport const getAdapter = (provider: BatchProvider): BatchAdapter =>\n adapters[provider];\n\nexport type { BatchAdapter, SubmitInput } from \"./adapter\";\n"
23
+ ],
24
+ "mappings": "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",
25
+ "debugId": "A771CB719D6F2AEA64756E2164756E21",
26
+ "names": []
27
+ }