batchwork 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/batch.d.ts.map +1 -1
  2. package/dist/body.d.ts +3 -2
  3. package/dist/body.d.ts.map +1 -1
  4. package/dist/{chunk-zp2cxkyb.js → chunk-e6qn48qa.js} +88 -13
  5. package/dist/chunk-e6qn48qa.js.map +13 -0
  6. package/dist/{chunk-kv3847wy.js → chunk-g481f961.js} +220 -56
  7. package/dist/chunk-g481f961.js.map +26 -0
  8. package/dist/{chunk-ab2d71gk.js → chunk-m4n610nm.js} +20 -7
  9. package/dist/chunk-m4n610nm.js.map +12 -0
  10. package/dist/http.d.ts.map +1 -1
  11. package/dist/index.d.ts +1 -1
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +2 -2
  14. package/dist/jsonl.d.ts +5 -15
  15. package/dist/jsonl.d.ts.map +1 -1
  16. package/dist/limits.d.ts +12 -0
  17. package/dist/limits.d.ts.map +1 -0
  18. package/dist/next/index.d.ts +3 -1
  19. package/dist/next/index.d.ts.map +1 -1
  20. package/dist/next/index.js +7 -4
  21. package/dist/next/index.js.map +3 -3
  22. package/dist/providers/adapter.d.ts +2 -1
  23. package/dist/providers/adapter.d.ts.map +1 -1
  24. package/dist/providers/anthropic.d.ts.map +1 -1
  25. package/dist/providers/google.d.ts.map +1 -1
  26. package/dist/providers/ids.d.ts +3 -0
  27. package/dist/providers/ids.d.ts.map +1 -0
  28. package/dist/providers/mistral.d.ts.map +1 -1
  29. package/dist/providers/openai-compatible.d.ts.map +1 -1
  30. package/dist/providers/together.d.ts.map +1 -1
  31. package/dist/providers/xai.d.ts.map +1 -1
  32. package/dist/server/index.d.ts +2 -2
  33. package/dist/server/index.d.ts.map +1 -1
  34. package/dist/server/index.js +2 -2
  35. package/dist/server/poller.d.ts +3 -0
  36. package/dist/server/poller.d.ts.map +1 -1
  37. package/dist/server/signing.d.ts +9 -2
  38. package/dist/server/signing.d.ts.map +1 -1
  39. package/dist/types.d.ts +7 -0
  40. package/dist/types.d.ts.map +1 -1
  41. package/package.json +1 -1
  42. package/dist/chunk-ab2d71gk.js.map +0 -12
  43. package/dist/chunk-kv3847wy.js.map +0 -24
  44. package/dist/chunk-zp2cxkyb.js.map +0 -13
@@ -0,0 +1,26 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/errors.ts", "../src/job.ts", "../src/limits.ts", "../src/http.ts", "../src/jsonl.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) {\n super(\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 const timer = setTimeout(resolve, ms);\n signal?.addEventListener(\n \"abort\",\n () => {\n clearTimeout(timer);\n reject(new BatchworkError(\"batchwork: wait aborted.\"));\n },\n { once: true }\n );\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 assertByteLength = (\n label: string,\n value: string,\n maxBytes: number\n): void => {\n const bytes = byteLength(value);\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 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 { 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\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\nexport const encodeJsonl = (items: readonly unknown[]): string => {\n if (items.length === 0) {\n return \"\";\n }\n const body = items.map((item) => JSON.stringify(item)).join(NEWLINE);\n return `${body}${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
+ "/** 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/** 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/** 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 new Date(value);\n }\n if (typeof value === \"number\") {\n return new Date(value * 1000);\n }\n};\n",
11
+ "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",
12
+ "import { BatchworkError } from \"../errors\";\nimport { requestJson, requestStream } from \"../http\";\nimport { streamJsonl } from \"../jsonl\";\nimport { assertByteLength, resolveBatchLimits } from \"../limits\";\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 = JSON.stringify({ requests });\n assertByteLength(\"batch upload payload\", body, limits.maxUploadBytes);\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 }\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",
13
+ "import { BatchworkError } from \"../errors\";\nimport { requestJson } from \"../http\";\nimport { assertByteLength, resolveBatchLimits } from \"../limits\";\nimport type {\n BatchResult,\n BatchSnapshot,\n BatchStatus,\n BatchUsage,\n ProviderCredentials,\n} from \"../types\";\nimport { asArray, asNumber, asRecord, asString, omit } 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 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 response: obj.response,\n status: \"succeeded\",\n text: textFromResponse(obj.response),\n usage: usageFromResponse(obj.response),\n };\n};\n\nconst submit = async (input: SubmitInput): Promise<BatchSnapshot> => {\n const limits = resolveBatchLimits(input.limits);\n const requests = input.built.map((item) => ({\n metadata: { key: item.customId },\n request: omit(item.body, \"stream\"),\n }));\n const body = JSON.stringify({\n batch: {\n display_name: \"batchwork\",\n input_config: { requests: { requests } },\n },\n });\n assertByteLength(\"batch upload payload\", body, limits.maxUploadBytes);\n const raw = await requestJson(\n `${baseUrl(input.credentials)}/models/${input.modelId}:batchGenerateContent`,\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",
14
+ "/**\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, 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\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 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 });\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 });\n for await (const line of streamJsonl(stream)) {\n yield normalizeOpenAIResult(line);\n }\n}\n",
15
+ "/**\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 { assertByteLength, 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 );\n assertByteLength(\"batch upload JSONL\", jsonl, limits.maxUploadBytes);\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",
16
+ "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",
17
+ "import { BatchworkError } from \"../errors\";\nimport { requestJson } from \"../http\";\nimport { encodeJsonl } from \"../jsonl\";\nimport { assertByteLength, 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 );\n assertByteLength(\"batch upload JSONL\", jsonl, limits.maxUploadBytes);\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",
18
+ "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",
19
+ "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 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 });\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",
20
+ "import { requestJson } from \"../http\";\nimport { encodeJsonl } from \"../jsonl\";\nimport { assertByteLength, 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 completedAt: toDate(obj.cancel_time),\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 );\n assertByteLength(\"batch upload JSONL\", jsonl, limits.maxUploadBytes);\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",
21
+ "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"
22
+ ],
23
+ "mappings": "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",
24
+ "debugId": "A38719FEA6433ECA64756E2164756E21",
25
+ "names": []
26
+ }
@@ -3,8 +3,11 @@ import {
3
3
  BatchworkError,
4
4
  MissingDependencyError,
5
5
  UnsupportedProviderError,
6
- getAdapter
7
- } from "./chunk-kv3847wy.js";
6
+ assertByteLength,
7
+ getAdapter,
8
+ mapWithConcurrency,
9
+ resolveBatchLimits
10
+ } from "./chunk-g481f961.js";
8
11
  import {
9
12
  __require
10
13
  } from "./chunk-v0bahtg2.js";
@@ -258,7 +261,11 @@ var captureOne = async (model, request, customId) => {
258
261
  }
259
262
  throw new BatchworkError("batchwork: the request was not intercepted while building the batch body.");
260
263
  };
261
- var buildRequestBodies = async (resolved, requests, defaults, credentials) => {
264
+ var buildRequestBodies = async (resolved, requests, defaults, credentials, rawLimits) => {
265
+ const limits = resolveBatchLimits(rawLimits);
266
+ if (requests.length > limits.maxRequests) {
267
+ throw new BatchworkError(`batchwork: requests length ${requests.length} exceeds the ${limits.maxRequests} request limit.`);
268
+ }
262
269
  const model = await createCaptureModel(resolved, credentials, captureFetch);
263
270
  const seen = new Set;
264
271
  const items = requests.map((request, index) => {
@@ -269,7 +276,11 @@ var buildRequestBodies = async (resolved, requests, defaults, credentials) => {
269
276
  seen.add(customId);
270
277
  return { customId, request };
271
278
  });
272
- return await Promise.all(items.map((item) => captureOne(model, mergeDefaults(item.request, defaults), item.customId)));
279
+ return await mapWithConcurrency(items, limits.captureConcurrency, async (item) => {
280
+ const built = await captureOne(model, mergeDefaults(item.request, defaults), item.customId);
281
+ assertByteLength(`request "${item.customId}"`, JSON.stringify(built.body), limits.maxRequestBytes);
282
+ return built;
283
+ });
273
284
  };
274
285
 
275
286
  // src/batch.ts
@@ -293,12 +304,14 @@ var batch = async (options) => {
293
304
  }
294
305
  const resolved = resolveModel(options.model);
295
306
  const credentials = pickCredentials(options);
307
+ const limits = resolveBatchLimits(options.limits);
296
308
  const adapter = getAdapter(resolved.provider);
297
- const built = await buildRequestBodies(resolved, options.requests, options.defaults, credentials);
309
+ const built = await buildRequestBodies(resolved, options.requests, options.defaults, credentials, limits);
298
310
  const snapshot = await adapter.submit({
299
311
  built,
300
312
  credentials,
301
313
  endpoint: built[0]?.endpoint ?? "",
314
+ limits,
302
315
  metadata: options.metadata,
303
316
  modelId: resolved.modelId
304
317
  });
@@ -321,5 +334,5 @@ var cancelBatch = async (ref) => {
321
334
 
322
335
  export { resolveModel, batch, getBatch, getBatchResults, cancelBatch };
323
336
 
324
- //# debugId=A3005BE7078C61CE64756E2164756E21
325
- //# sourceMappingURL=chunk-ab2d71gk.js.map
337
+ //# debugId=C7BCC311BBAF05B464756E2164756E21
338
+ //# sourceMappingURL=chunk-m4n610nm.js.map
@@ -0,0 +1,12 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/model.ts", "../src/body.ts", "../src/batch.ts"],
4
+ "sourcesContent": [
5
+ "import type * as AnthropicModule from \"@ai-sdk/anthropic\";\nimport type * as GoogleModule from \"@ai-sdk/google\";\nimport type * as GroqModule from \"@ai-sdk/groq\";\nimport type * as MistralModule from \"@ai-sdk/mistral\";\nimport type * as OpenAIModule from \"@ai-sdk/openai\";\nimport type * as TogetherModule from \"@ai-sdk/togetherai\";\nimport type * as XaiModule from \"@ai-sdk/xai\";\nimport type { LanguageModel } from \"ai\";\n\nimport { MissingDependencyError, UnsupportedProviderError } from \"./errors\";\nimport type { BatchProvider, ProviderCredentials } from \"./types\";\n\n/** A fetch implementation compatible with the AI SDK provider `fetch` option. */\nexport type CapturingFetch = typeof globalThis.fetch;\n\n/** OpenAI exposes several request shapes; we mirror the one the model implies. */\nexport type OpenAIModelKind = \"chat\" | \"responses\" | \"completion\";\n\nexport interface ResolvedModel {\n /** Relevant for OpenAI; other providers always use a single chat endpoint. */\n kind: OpenAIModelKind;\n modelId: string;\n provider: BatchProvider;\n}\n\n/**\n * Placeholder API key used only when building request bodies. Body building\n * intercepts the request before it is sent, so no real credential is needed —\n * but the provider refuses to construct a model without one.\n */\nconst CAPTURE_API_KEY = \"batchwork-capture\";\n\n/** The optional `@ai-sdk/*` package backing each provider. */\nconst PACKAGE_BY_PROVIDER: Record<\n BatchProvider,\n { label: string; specifier: string }\n> = {\n anthropic: { label: \"Anthropic\", specifier: \"@ai-sdk/anthropic\" },\n google: { label: \"Google Gemini\", specifier: \"@ai-sdk/google\" },\n groq: { label: \"Groq\", specifier: \"@ai-sdk/groq\" },\n mistral: { label: \"Mistral\", specifier: \"@ai-sdk/mistral\" },\n openai: { label: \"OpenAI\", specifier: \"@ai-sdk/openai\" },\n together: { label: \"Together AI\", specifier: \"@ai-sdk/togetherai\" },\n xai: { label: \"xAI\", specifier: \"@ai-sdk/xai\" },\n};\n\n/**\n * AI SDK provider id prefixes (the part before the first `.` in `model.provider`)\n * mapped to batch providers.\n */\nconst PROVIDER_BY_FAMILY: Record<string, BatchProvider> = {\n anthropic: \"anthropic\",\n google: \"google\",\n groq: \"groq\",\n mistral: \"mistral\",\n openai: \"openai\",\n together: \"together\",\n togetherai: \"together\",\n xai: \"xai\",\n};\n\n/** Aliases accepted in the `\"provider/model\"` string form. */\nconst PROVIDER_BY_ALIAS: Record<string, BatchProvider> = {\n ...PROVIDER_BY_FAMILY,\n gemini: \"google\",\n};\n\nconst splitOnce = (value: string, separator: string): [string, string] => {\n const index = value.indexOf(separator);\n if (index === -1) {\n return [value, \"\"];\n }\n return [value.slice(0, index), value.slice(index + separator.length)];\n};\n\nconst openaiKind = (suffix: string): OpenAIModelKind => {\n if (suffix === \"responses\") {\n return \"responses\";\n }\n if (suffix === \"completion\") {\n return \"completion\";\n }\n // Default to chat completions: the most widely supported batch endpoint.\n return \"chat\";\n};\n\n/** Resolve a `\"provider/model\"` string into a provider + model id. */\nconst resolveModelString = (value: string): ResolvedModel => {\n const [providerId, modelId] = splitOnce(value, \"/\");\n if (modelId === \"\") {\n throw new UnsupportedProviderError(value);\n }\n const provider = PROVIDER_BY_ALIAS[providerId];\n if (!provider) {\n throw new UnsupportedProviderError(providerId);\n }\n return { kind: \"chat\", modelId, provider };\n};\n\n/**\n * Resolve any AI SDK `model` (a `\"provider/model\"` string or a provider model\n * object such as `openai(\"gpt-5.5\")`) to a provider + model id + request\n * shape. Gateway/registry model objects whose `modelId` is itself\n * `\"provider/model\"` are also handled.\n */\nexport const resolveModel = (model: LanguageModel): ResolvedModel => {\n if (typeof model === \"string\") {\n return resolveModelString(model);\n }\n\n const [family, suffix] = splitOnce(model.provider, \".\");\n const provider = PROVIDER_BY_FAMILY[family];\n if (provider === \"openai\") {\n return { kind: openaiKind(suffix), modelId: model.modelId, provider };\n }\n if (provider) {\n return { kind: \"chat\", modelId: model.modelId, provider };\n }\n // Gateway/registry providers carry the real target in the model id.\n if (model.modelId.includes(\"/\")) {\n return resolveModelString(model.modelId);\n }\n throw new UnsupportedProviderError(model.provider);\n};\n\nconst importProvider = (provider: BatchProvider): Promise<unknown> => {\n switch (provider) {\n case \"anthropic\": {\n return import(\"@ai-sdk/anthropic\");\n }\n case \"google\": {\n return import(\"@ai-sdk/google\");\n }\n case \"groq\": {\n return import(\"@ai-sdk/groq\");\n }\n case \"mistral\": {\n return import(\"@ai-sdk/mistral\");\n }\n case \"openai\": {\n return import(\"@ai-sdk/openai\");\n }\n case \"together\": {\n return import(\"@ai-sdk/togetherai\");\n }\n case \"xai\": {\n return import(\"@ai-sdk/xai\");\n }\n default: {\n return Promise.reject(new UnsupportedProviderError(provider));\n }\n }\n};\n\n/**\n * Import the `@ai-sdk/*` package for a provider, translating a missing optional\n * dependency into a `MissingDependencyError`. The importer is injectable (like\n * the capturing `fetch`) so tests can drive the failure paths without\n * uninstalling a package. Exported for testing; not part of the public API.\n */\nexport const loadProvider = async <T>(\n provider: BatchProvider,\n load: (target: BatchProvider) => Promise<unknown> = importProvider\n): Promise<T> => {\n try {\n return (await load(provider)) as T;\n } catch (error) {\n if (error instanceof UnsupportedProviderError) {\n throw error;\n }\n const { specifier, label } = PACKAGE_BY_PROVIDER[provider];\n throw new MissingDependencyError(specifier, label);\n }\n};\n\n/**\n * Construct an AI SDK model wired to a capturing `fetch`, used to derive the\n * provider request body for each batch item without making a network call.\n */\nexport const createCaptureModel = async (\n resolved: ResolvedModel,\n credentials: ProviderCredentials,\n fetchImpl: CapturingFetch\n): Promise<LanguageModel> => {\n const settings = {\n apiKey: credentials.apiKey ?? CAPTURE_API_KEY,\n baseURL: credentials.baseURL,\n fetch: fetchImpl,\n headers: credentials.headers,\n };\n\n switch (resolved.provider) {\n case \"openai\": {\n const { createOpenAI } =\n await loadProvider<typeof OpenAIModule>(\"openai\");\n const provider = createOpenAI(settings);\n if (resolved.kind === \"responses\") {\n return provider.responses(resolved.modelId);\n }\n if (resolved.kind === \"completion\") {\n return provider.completion(resolved.modelId);\n }\n return provider.chat(resolved.modelId);\n }\n case \"anthropic\": {\n const { createAnthropic } =\n await loadProvider<typeof AnthropicModule>(\"anthropic\");\n return createAnthropic(settings).messages(resolved.modelId);\n }\n case \"groq\": {\n const { createGroq } = await loadProvider<typeof GroqModule>(\"groq\");\n return createGroq(settings).languageModel(resolved.modelId);\n }\n case \"mistral\": {\n const { createMistral } =\n await loadProvider<typeof MistralModule>(\"mistral\");\n return createMistral(settings).languageModel(resolved.modelId);\n }\n case \"google\": {\n const { createGoogleGenerativeAI } =\n await loadProvider<typeof GoogleModule>(\"google\");\n return createGoogleGenerativeAI(settings).languageModel(resolved.modelId);\n }\n case \"xai\": {\n const { createXai } = await loadProvider<typeof XaiModule>(\"xai\");\n return createXai(settings).languageModel(resolved.modelId);\n }\n case \"together\": {\n const { createTogetherAI } =\n await loadProvider<typeof TogetherModule>(\"together\");\n return createTogetherAI(settings).languageModel(resolved.modelId);\n }\n default: {\n throw new UnsupportedProviderError(resolved.provider);\n }\n }\n};\n",
6
+ "import { generateText } from \"ai\";\nimport type { LanguageModel } from \"ai\";\n\nimport { BatchworkError } from \"./errors\";\nimport {\n assertByteLength,\n mapWithConcurrency,\n resolveBatchLimits,\n} from \"./limits\";\nimport type { ResolvedBatchLimits } from \"./limits\";\nimport { createCaptureModel } from \"./model\";\nimport type { CapturingFetch, ResolvedModel } from \"./model\";\nimport type {\n BatchDefaults,\n BatchLimits,\n BatchRequest,\n ProviderCredentials,\n} from \"./types\";\n\ntype GenerateTextInput = Parameters<typeof generateText>[0];\n\n/** A provider request body derived from a single batch item. */\nexport interface BuiltRequest {\n /** The serialized provider request body (becomes the batch line). */\n body: Record<string, unknown>;\n customId: string;\n /** API endpoint path the model targets, e.g. `/v1/chat/completions`. */\n endpoint: string;\n}\n\nconst MAX_CAUSE_DEPTH = 10;\n\n/**\n * Thrown by the capturing `fetch` to abort the request after its body has been\n * serialized. The body travels inside the error (not shared state), so capture\n * is correct even under concurrency.\n */\nclass CaptureSignalError extends Error {\n readonly url: string;\n readonly rawBody: string;\n\n constructor(url: string, rawBody: string) {\n super(\"batchwork:capture\");\n this.name = \"CaptureSignalError\";\n this.url = url;\n this.rawBody = rawBody;\n }\n}\n\nconst resolveUrl = (input: string | URL | Request): string => {\n if (typeof input === \"string\") {\n return input;\n }\n if (input instanceof URL) {\n return input.toString();\n }\n return input.url;\n};\n\nconst extractBody = (init?: RequestInit): string => {\n const body = init?.body;\n if (typeof body === \"string\") {\n return body;\n }\n if (body instanceof Uint8Array) {\n return new TextDecoder().decode(body);\n }\n throw new BatchworkError(\n \"batchwork: unable to read the provider request body during capture.\"\n );\n};\n\n// `CapturingFetch` is `typeof fetch`, whose shape varies by runtime types (e.g.\n// Bun adds a required `preconnect` method). We only ever call it as a plain\n// fetch, so cast the bare implementation rather than stub the extra members.\nconst captureFetch = ((input: string | URL | Request, init?: RequestInit) =>\n Promise.reject(\n new CaptureSignalError(resolveUrl(input), extractBody(init))\n )) as unknown as CapturingFetch;\n\nconst findCapture = (error: unknown): CaptureSignalError | undefined => {\n let current: unknown = error;\n let depth = 0;\n while (current && depth < MAX_CAUSE_DEPTH) {\n if (current instanceof CaptureSignalError) {\n return current;\n }\n current = (current as { cause?: unknown }).cause;\n depth += 1;\n }\n};\n\nconst endpointFromUrl = (url: string): string => {\n try {\n return new URL(url).pathname;\n } catch {\n return url;\n }\n};\n\nconst mergeDefaults = (\n request: BatchRequest,\n defaults: BatchDefaults | undefined\n): BatchRequest => {\n if (!defaults) {\n return request;\n }\n return { ...defaults, ...request };\n};\n\n/**\n * Map a batch request to AI SDK `generateText` input. Fields are listed\n * explicitly so `customId` never leaks into the provider request.\n */\nconst toGenerateInput = (\n model: LanguageModel,\n request: BatchRequest\n): GenerateTextInput =>\n // `prompt`/`messages` form a discriminated union in the AI SDK types; we\n // pass both keys and let `generateText` validate the XOR at runtime.\n ({\n frequencyPenalty: request.frequencyPenalty,\n maxOutputTokens: request.maxOutputTokens,\n maxRetries: 0,\n messages: request.messages,\n model,\n presencePenalty: request.presencePenalty,\n prompt: request.prompt,\n providerOptions: request.providerOptions,\n seed: request.seed,\n stopSequences: request.stopSequences,\n system: request.system,\n temperature: request.temperature,\n toolChoice: request.toolChoice,\n tools: request.tools,\n topK: request.topK,\n topP: request.topP,\n }) as GenerateTextInput;\n\nconst captureOne = async (\n model: LanguageModel,\n request: BatchRequest,\n customId: string\n): Promise<BuiltRequest> => {\n try {\n await generateText(toGenerateInput(model, request));\n } catch (error) {\n const capture = findCapture(error);\n if (capture) {\n return {\n body: JSON.parse(capture.rawBody) as Record<string, unknown>,\n customId,\n endpoint: endpointFromUrl(capture.url),\n };\n }\n // A genuine failure (e.g. invalid prompt) — surface it to the caller.\n throw error;\n }\n throw new BatchworkError(\n \"batchwork: the request was not intercepted while building the batch body.\"\n );\n};\n\n/**\n * Derive provider request bodies for every batch item by running each through\n * the AI SDK with a capturing `fetch`. This reuses the AI SDK's full message,\n * tool, and multimodal conversion, so the body matches what `generateText`\n * would send — minus the network call.\n */\nexport const buildRequestBodies = async (\n resolved: ResolvedModel,\n requests: readonly BatchRequest[],\n defaults: BatchDefaults | undefined,\n credentials: ProviderCredentials,\n rawLimits?: BatchLimits | ResolvedBatchLimits\n): Promise<BuiltRequest[]> => {\n const limits = resolveBatchLimits(rawLimits);\n if (requests.length > limits.maxRequests) {\n throw new BatchworkError(\n `batchwork: requests length ${requests.length} exceeds the ${limits.maxRequests} request limit.`\n );\n }\n const model = await createCaptureModel(resolved, credentials, captureFetch);\n const seen = new Set<string>();\n\n // Assign and validate customIds up front (sequentially, so duplicates are\n // reported deterministically) before capturing bodies in parallel.\n const items = requests.map((request, index) => {\n const customId = request.customId ?? `request-${index}`;\n if (seen.has(customId)) {\n throw new BatchworkError(\n `batchwork: duplicate customId \"${customId}\". customId values must be unique within a batch.`\n );\n }\n seen.add(customId);\n return { customId, request };\n });\n\n return await mapWithConcurrency(\n items,\n limits.captureConcurrency,\n async (item) => {\n const built = await captureOne(\n model,\n mergeDefaults(item.request, defaults),\n item.customId\n );\n assertByteLength(\n `request \"${item.customId}\"`,\n JSON.stringify(built.body),\n limits.maxRequestBytes\n );\n return built;\n }\n );\n};\n",
7
+ "import { buildRequestBodies } from \"./body\";\nimport { BatchworkError } from \"./errors\";\nimport { BatchJob } from \"./job\";\nimport { resolveBatchLimits } from \"./limits\";\nimport { resolveModel } from \"./model\";\nimport { getAdapter } from \"./providers\";\nimport type {\n BatchOptions,\n BatchProvider,\n BatchRef,\n BatchResult,\n ProviderCredentials,\n} from \"./types\";\n\nconst pickCredentials = (source: ProviderCredentials): ProviderCredentials => ({\n apiKey: source.apiKey,\n baseURL: source.baseURL,\n headers: source.headers,\n});\n\nconst providerFromRef = (ref: BatchRef): BatchProvider => {\n if (ref.provider) {\n return ref.provider;\n }\n if (ref.model !== undefined) {\n return resolveModel(ref.model).provider;\n }\n throw new BatchworkError(\n \"batchwork: provide `provider` or `model` to identify the batch.\"\n );\n};\n\n/**\n * Submit a batch of requests to the model's provider and return a handle.\n *\n * Resolves immediately once the batch is accepted — it does not wait for\n * processing. Use the returned {@link BatchJob} to poll, wait, or stream\n * results.\n *\n * @example\n * const job = await batch({\n * model: openai(\"gpt-5.5\"),\n * requests: [{ customId: \"a\", prompt: \"Say hi\" }],\n * });\n * const results = await job.wait().then(() => job.collect());\n */\nexport const batch = async (options: BatchOptions): Promise<BatchJob> => {\n if (options.requests.length === 0) {\n throw new BatchworkError(\"batchwork: `requests` must not be empty.\");\n }\n\n const resolved = resolveModel(options.model);\n const credentials = pickCredentials(options);\n const limits = resolveBatchLimits(options.limits);\n const adapter = getAdapter(resolved.provider);\n\n const built = await buildRequestBodies(\n resolved,\n options.requests,\n options.defaults,\n credentials,\n limits\n );\n const snapshot = await adapter.submit({\n built,\n credentials,\n endpoint: built[0]?.endpoint ?? \"\",\n limits,\n metadata: options.metadata,\n modelId: resolved.modelId,\n });\n\n return new BatchJob(adapter, credentials, snapshot);\n};\n\n/**\n * Rehydrate a {@link BatchJob} for an existing batch id (e.g. one persisted\n * after submission). Identify the provider with `provider` or `model`.\n */\nexport const getBatch = async (ref: BatchRef): Promise<BatchJob> => {\n const adapter = getAdapter(providerFromRef(ref));\n const credentials = pickCredentials(ref);\n const snapshot = await adapter.retrieve(ref.id, credentials);\n return new BatchJob(adapter, credentials, snapshot);\n};\n\n/** Stream the results of an existing batch by id, without a handle. */\nexport const getBatchResults = (ref: BatchRef): AsyncGenerator<BatchResult> => {\n const adapter = getAdapter(providerFromRef(ref));\n return adapter.results(ref.id, pickCredentials(ref));\n};\n\n/** Request cancellation of an existing batch by id. */\nexport const cancelBatch = async (ref: BatchRef): Promise<void> => {\n const adapter = getAdapter(providerFromRef(ref));\n await adapter.cancel(ref.id, pickCredentials(ref));\n};\n"
8
+ ],
9
+ "mappings": "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",
10
+ "debugId": "C7BCC311BBAF05B464756E2164756E21",
11
+ "names": []
12
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAmBA,qEAAqE;AACrE,eAAO,MAAM,WAAW,GAAU,CAAC,OAC5B,MAAM,QACL,WAAW,KAChB,OAAO,CAAC,CAAC,CAIX,CAAC;AAEF,0EAA0E;AAC1E,eAAO,MAAM,aAAa,QACnB,MAAM,QACL,WAAW,KAChB,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAOpC,CAAC"}
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAUA,qEAAqE;AACrE,eAAO,MAAM,WAAW,GAAU,CAAC,OAC5B,MAAM,QACL,WAAW,KAChB,OAAO,CAAC,CAAC,CAIX,CAAC;AAEF,0EAA0E;AAC1E,eAAO,MAAM,aAAa,QACnB,MAAM,QACL,WAAW,KAChB,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAOpC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -2,5 +2,5 @@ export { batch, cancelBatch, getBatch, getBatchResults } from "./batch";
2
2
  export { BatchworkError, MissingDependencyError, UnsupportedProviderError, } from "./errors";
3
3
  export { BatchJob, isTerminalStatus } from "./job";
4
4
  export { resolveModel } from "./model";
5
- export type { BatchDefaults, BatchOptions, BatchProvider, BatchRef, BatchRequest, BatchRequestCounts, BatchRequestSettings, BatchResult, BatchResultError, BatchResultStatus, BatchSnapshot, BatchStatus, BatchUsage, ProviderCredentials, ProviderOptions, WaitOptions, } from "./types";
5
+ export type { BatchDefaults, BatchLimits, BatchOptions, BatchProvider, BatchRef, BatchRequest, BatchRequestCounts, BatchRequestSettings, BatchResult, BatchResultError, BatchResultStatus, BatchSnapshot, BatchStatus, BatchUsage, ProviderCredentials, ProviderOptions, WaitOptions, } from "./types";
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AACxE,OAAO,EACL,cAAc,EACd,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,YAAY,EACV,aAAa,EACb,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,YAAY,EACZ,kBAAkB,EAClB,oBAAoB,EACpB,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,UAAU,EACV,mBAAmB,EACnB,eAAe,EACf,WAAW,GACZ,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AACxE,OAAO,EACL,cAAc,EACd,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,YAAY,EACV,aAAa,EACb,WAAW,EACX,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,YAAY,EACZ,kBAAkB,EAClB,oBAAoB,EACpB,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,UAAU,EACV,mBAAmB,EACnB,eAAe,EACf,WAAW,GACZ,MAAM,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -4,14 +4,14 @@ import {
4
4
  getBatch,
5
5
  getBatchResults,
6
6
  resolveModel
7
- } from "./chunk-ab2d71gk.js";
7
+ } from "./chunk-m4n610nm.js";
8
8
  import {
9
9
  BatchJob,
10
10
  BatchworkError,
11
11
  MissingDependencyError,
12
12
  UnsupportedProviderError,
13
13
  isTerminalStatus
14
- } from "./chunk-kv3847wy.js";
14
+ } from "./chunk-g481f961.js";
15
15
  import"./chunk-v0bahtg2.js";
16
16
  export {
17
17
  resolveModel,
package/dist/jsonl.d.ts CHANGED
@@ -1,17 +1,7 @@
1
- /**
2
- * JSONL (newline-delimited JSON) helpers. OpenAI batch input/output and
3
- * Anthropic batch results are all JSONL, so batchwork builds and parses it for
4
- * the user.
5
- */
6
- /** Serialize an array of values to a JSONL string (trailing newline included). */
1
+ export interface JsonlParseOptions {
2
+ maxLineBytes?: number;
3
+ }
7
4
  export declare const encodeJsonl: (items: readonly unknown[]) => string;
8
- /** Parse a complete JSONL string into an array, skipping blank lines. */
9
- export declare const parseJsonl: <T = unknown>(text: string) => T[];
10
- /**
11
- * Stream-parse JSONL from a byte stream, yielding one parsed value per line as
12
- * it arrives. Memory-efficient for large result files.
13
- *
14
- * @yields {T} the parsed value for each non-empty line.
15
- */
16
- export declare function streamJsonl<T = unknown>(source: ReadableStream<Uint8Array> | AsyncIterable<Uint8Array>): AsyncGenerator<T>;
5
+ export declare const parseJsonl: <T = unknown>(text: string, options?: JsonlParseOptions) => T[];
6
+ export declare function streamJsonl<T = unknown>(source: ReadableStream<Uint8Array> | AsyncIterable<Uint8Array>, options?: JsonlParseOptions): AsyncGenerator<T>;
17
7
  //# sourceMappingURL=jsonl.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"jsonl.d.ts","sourceRoot":"","sources":["../src/jsonl.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,kFAAkF;AAClF,eAAO,MAAM,WAAW,UAAW,SAAS,OAAO,EAAE,KAAG,MAMvD,CAAC;AAEF,yEAAyE;AACzE,eAAO,MAAM,UAAU,GAAI,CAAC,GAAG,OAAO,QAAQ,MAAM,KAAG,CAAC,EASvD,CAAC;AAkCF;;;;;GAKG;AAEH,wBAAuB,WAAW,CAAC,CAAC,GAAG,OAAO,EAC5C,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,GAAG,aAAa,CAAC,UAAU,CAAC,GAC7D,cAAc,CAAC,CAAC,CAAC,CAsBnB"}
1
+ {"version":3,"file":"jsonl.d.ts","sourceRoot":"","sources":["../src/jsonl.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,iBAAiB;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AA6CD,eAAO,MAAM,WAAW,UAAW,SAAS,OAAO,EAAE,KAAG,MAMvD,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,CAAC,GAAG,OAAO,QAC9B,MAAM,YACF,iBAAiB,KAC1B,CAAC,EAWH,CAAC;AAmCF,wBAAuB,WAAW,CAAC,CAAC,GAAG,OAAO,EAC5C,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,GAAG,aAAa,CAAC,UAAU,CAAC,EAC9D,OAAO,CAAC,EAAE,iBAAiB,GAC1B,cAAc,CAAC,CAAC,CAAC,CA2BnB"}
@@ -0,0 +1,12 @@
1
+ import type { BatchLimits } from "./types";
2
+ export interface ResolvedBatchLimits {
3
+ captureConcurrency: number;
4
+ maxRequests: number;
5
+ maxRequestBytes: number;
6
+ maxUploadBytes: number;
7
+ }
8
+ export declare const resolveBatchLimits: (limits: BatchLimits | undefined) => ResolvedBatchLimits;
9
+ export declare const byteLength: (value: string) => number;
10
+ export declare const assertByteLength: (label: string, value: string, maxBytes: number) => void;
11
+ export declare const mapWithConcurrency: <Input, Output>(items: readonly Input[], concurrency: number, mapper: (item: Input) => Promise<Output>) => Promise<Output[]>;
12
+ //# sourceMappingURL=limits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../src/limits.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C,MAAM,WAAW,mBAAmB;IAClC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;CACxB;AAoBD,eAAO,MAAM,kBAAkB,WACrB,WAAW,GAAG,SAAS,KAC9B,mBAiBD,CAAC;AAEH,eAAO,MAAM,UAAU,UAAW,MAAM,KAAG,MACb,CAAC;AAE/B,eAAO,MAAM,gBAAgB,UACpB,MAAM,SACN,MAAM,YACH,MAAM,KACf,IAOF,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAU,KAAK,EAAE,MAAM,SAC7C,SAAS,KAAK,EAAE,eACV,MAAM,UACX,CAAC,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC,MAAM,CAAC,KACvC,OAAO,CAAC,MAAM,EAAE,CAkBlB,CAAC"}
@@ -21,8 +21,10 @@ export interface BatchRoutesOptions {
21
21
  onComplete: OnBatchComplete;
22
22
  /** Falls back to provider env vars (e.g. `OPENAI_API_KEY`) when omitted. */
23
23
  credentials?: CredentialResolver;
24
- /** When set, the cron `GET` requires `Authorization: Bearer <cronSecret>`. */
24
+ /** Requires `Authorization: Bearer <cronSecret>` on the cron `GET`. */
25
25
  cronSecret?: string;
26
+ /** Allow unauthenticated cron ticks. Intended only for private/local routes. */
27
+ allowUnauthenticatedCron?: boolean;
26
28
  /** When set, mounts an OpenAI native-webhook handler on `POST`. */
27
29
  openaiSigningSecret?: string;
28
30
  /** Observe per-batch processing errors during a tick; the tick continues. */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/next/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAEV,kBAAkB,EAClB,WAAW,EACZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EACV,UAAU,EACV,iBAAiB,EACjB,YAAY,EACb,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAiB,WAAW,EAAuB,MAAM,UAAU,CAAC;AAEhF,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAC7B,YAAY,EACV,UAAU,EACV,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,WAAW,GACZ,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,MAAM,eAAe,GAAG,CAC5B,KAAK,EAAE,iBAAiB,EACxB,OAAO,EAAE,aAAa,CAAC,WAAW,CAAC,KAChC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,UAAU,CAAC;IAClB,6DAA6D;IAC7D,UAAU,EAAE,eAAe,CAAC;IAC5B,4EAA4E;IAC5E,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,8EAA8E;IAC9E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,6EAA6E;IAC7E,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CAC1D;AAED,MAAM,WAAW,WAAW;IAC1B,wEAAwE;IACxE,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC7C,8EAA8E;IAC9E,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC/C,4EAA4E;IAC5E,KAAK,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;CACvD;AASD;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,iBAAiB,YAAa,kBAAkB,KAAG,WAoD/D,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/next/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAEV,kBAAkB,EAClB,WAAW,EACZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EACV,UAAU,EACV,iBAAiB,EACjB,YAAY,EACb,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAiB,WAAW,EAAuB,MAAM,UAAU,CAAC;AAEhF,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAC7B,YAAY,EACV,UAAU,EACV,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,WAAW,GACZ,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,MAAM,eAAe,GAAG,CAC5B,KAAK,EAAE,iBAAiB,EACxB,OAAO,EAAE,aAAa,CAAC,WAAW,CAAC,KAChC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,UAAU,CAAC;IAClB,6DAA6D;IAC7D,UAAU,EAAE,eAAe,CAAC;IAC5B,4EAA4E;IAC5E,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gFAAgF;IAChF,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,mEAAmE;IACnE,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,6EAA6E;IAC7E,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CAC1D;AAED,MAAM,WAAW,WAAW;IAC1B,wEAAwE;IACxE,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC7C,8EAA8E;IAC9E,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC/C,4EAA4E;IAC5E,KAAK,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;CACvD;AASD;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,iBAAiB,YAAa,kBAAkB,KAAG,WAuD/D,CAAC"}
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  getBatchResults
3
- } from "../chunk-ab2d71gk.js";
3
+ } from "../chunk-m4n610nm.js";
4
4
  import {
5
5
  createBatchPoller,
6
6
  createMemoryStore,
7
7
  toEvent
8
- } from "../chunk-zp2cxkyb.js";
9
- import"../chunk-kv3847wy.js";
8
+ } from "../chunk-e6qn48qa.js";
9
+ import"../chunk-g481f961.js";
10
10
  import"../chunk-v0bahtg2.js";
11
11
 
12
12
  // src/next/index.ts
@@ -38,6 +38,9 @@ var createBatchRoutes = (options) => {
38
38
  store: options.store
39
39
  });
40
40
  const GET = (request) => {
41
+ if (!(options.cronSecret || options.allowUnauthenticatedCron)) {
42
+ return Promise.resolve(new Response("unauthorized", { status: 401 }));
43
+ }
41
44
  if (options.cronSecret && request.headers.get("authorization") !== `Bearer ${options.cronSecret}`) {
42
45
  return Promise.resolve(new Response("unauthorized", { status: 401 }));
43
46
  }
@@ -57,5 +60,5 @@ export {
57
60
  createBatchRoutes
58
61
  };
59
62
 
60
- //# debugId=2EB8C739158F3A9164756E2164756E21
63
+ //# debugId=5888D5A3C810FEE564756E2164756E21
61
64
  //# sourceMappingURL=index.js.map
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/next/index.ts"],
4
4
  "sourcesContent": [
5
- "import { getBatchResults } from \"../batch\";\nimport { toEvent } from \"../server/events\";\nimport { createBatchPoller } from \"../server/poller\";\nimport type {\n CompletionSink,\n CredentialResolver,\n TrackTarget,\n} from \"../server/poller\";\nimport { createMemoryStore } from \"../server/store\";\nimport type {\n BatchStore,\n BatchWebhookEvent,\n TrackedBatch,\n} from \"../server/types\";\nimport type { BatchProvider, BatchResult, ProviderCredentials } from \"../types\";\n\nexport { createMemoryStore };\nexport type {\n BatchStore,\n BatchWebhookEvent,\n BatchResult,\n TrackedBatch,\n TrackTarget,\n};\n\n/**\n * Invoked once per batch when it reaches a terminal status. Persist the results\n * to your database here. `results` streams the parsed result lines for a\n * completed batch and is empty for failure events (`batch.failed` /\n * `batch.expired` / `batch.cancelled`) — inspect `event.type`.\n *\n * May fire more than once for the same batch (a cron tick racing the OpenAI\n * native webhook, or a retry after a partial save), so make persistence\n * idempotent — upsert keyed by `(provider, batchId, customId)`.\n */\nexport type OnBatchComplete = (\n event: BatchWebhookEvent,\n results: AsyncIterable<BatchResult>\n) => void | Promise<void>;\n\nexport interface BatchRoutesOptions {\n store: BatchStore;\n /** Called when each batch finishes; persist results here. */\n onComplete: OnBatchComplete;\n /** Falls back to provider env vars (e.g. `OPENAI_API_KEY`) when omitted. */\n credentials?: CredentialResolver;\n /** When set, the cron `GET` requires `Authorization: Bearer <cronSecret>`. */\n cronSecret?: string;\n /** When set, mounts an OpenAI native-webhook handler on `POST`. */\n openaiSigningSecret?: string;\n /** Observe per-batch processing errors during a tick; the tick continues. */\n onError?: (record: TrackedBatch, error: unknown) => void;\n}\n\nexport interface BatchRoutes {\n /** Cron-triggered poll tick. Wire to Vercel Cron (or any scheduler). */\n GET: (request: Request) => Promise<Response>;\n /** OpenAI native-webhook handler. Present only with `openaiSigningSecret`. */\n POST?: (request: Request) => Promise<Response>;\n /** Register a submitted batch so the cron polls it (a `BatchJob` works). */\n track: (target: TrackTarget) => Promise<TrackedBatch>;\n}\n\n/** An already-exhausted async iterable, for non-completed events. */\nconst EMPTY_RESULTS: AsyncIterable<BatchResult> = {\n [Symbol.asyncIterator]: () => ({\n next: () => Promise.resolve({ done: true, value: undefined }),\n }),\n};\n\n/**\n * Build Next.js App Router route handlers that poll your in-flight batches on a\n * cron tick and invoke `onComplete` directly when each finishes — persist\n * results to your DB without round-tripping an HTTP webhook back to your app.\n *\n * @example\n * import { createBatchRoutes, createMemoryStore } from \"batchwork/next\";\n *\n * export const { GET, POST } = createBatchRoutes({\n * store: createMemoryStore(),\n * cronSecret: process.env.CRON_SECRET,\n * openaiSigningSecret: process.env.OPENAI_WEBHOOK_SECRET,\n * onComplete: async (event, results) => {\n * for await (const r of results) {\n * await db.insert({ id: r.customId, status: r.status, text: r.text });\n * }\n * },\n * });\n */\nexport const createBatchRoutes = (options: BatchRoutesOptions): BatchRoutes => {\n const resolveCredentials = (provider: BatchProvider): ProviderCredentials => {\n if (typeof options.credentials === \"function\") {\n return options.credentials(provider);\n }\n return options.credentials ?? {};\n };\n\n const sink: CompletionSink = async (record, snapshot) => {\n const event = toEvent(record.provider, snapshot);\n // Only completed batches have results to fetch — the adapter throws when a\n // terminal batch has no output/error file (failed/expired/cancelled).\n const results =\n event.type === \"batch.completed\"\n ? getBatchResults({\n id: record.id,\n provider: record.provider,\n ...resolveCredentials(record.provider),\n })\n : EMPTY_RESULTS;\n await options.onComplete(event, results);\n };\n\n const poller = createBatchPoller({\n credentials: options.credentials,\n onComplete: sink,\n // Always supply an `onError` so one failing batch can't abort the whole\n // tick; forward to the caller's handler when they provided one.\n onError: (record, error) => options.onError?.(record, error),\n store: options.store,\n });\n\n const GET = (request: Request): Promise<Response> => {\n if (\n options.cronSecret &&\n request.headers.get(\"authorization\") !== `Bearer ${options.cronSecret}`\n ) {\n return Promise.resolve(new Response(\"unauthorized\", { status: 401 }));\n }\n return poller.tick().then((result) => Response.json(result));\n };\n\n const track = (target: TrackTarget): Promise<TrackedBatch> =>\n poller.track(target, {});\n\n const routes: BatchRoutes = { GET, track };\n if (options.openaiSigningSecret) {\n routes.POST = poller.openaiWebhookHandler({\n signingSecret: options.openaiSigningSecret,\n });\n }\n return routes;\n};\n"
5
+ "import { getBatchResults } from \"../batch\";\nimport { toEvent } from \"../server/events\";\nimport { createBatchPoller } from \"../server/poller\";\nimport type {\n CompletionSink,\n CredentialResolver,\n TrackTarget,\n} from \"../server/poller\";\nimport { createMemoryStore } from \"../server/store\";\nimport type {\n BatchStore,\n BatchWebhookEvent,\n TrackedBatch,\n} from \"../server/types\";\nimport type { BatchProvider, BatchResult, ProviderCredentials } from \"../types\";\n\nexport { createMemoryStore };\nexport type {\n BatchStore,\n BatchWebhookEvent,\n BatchResult,\n TrackedBatch,\n TrackTarget,\n};\n\n/**\n * Invoked once per batch when it reaches a terminal status. Persist the results\n * to your database here. `results` streams the parsed result lines for a\n * completed batch and is empty for failure events (`batch.failed` /\n * `batch.expired` / `batch.cancelled`) — inspect `event.type`.\n *\n * May fire more than once for the same batch (a cron tick racing the OpenAI\n * native webhook, or a retry after a partial save), so make persistence\n * idempotent — upsert keyed by `(provider, batchId, customId)`.\n */\nexport type OnBatchComplete = (\n event: BatchWebhookEvent,\n results: AsyncIterable<BatchResult>\n) => void | Promise<void>;\n\nexport interface BatchRoutesOptions {\n store: BatchStore;\n /** Called when each batch finishes; persist results here. */\n onComplete: OnBatchComplete;\n /** Falls back to provider env vars (e.g. `OPENAI_API_KEY`) when omitted. */\n credentials?: CredentialResolver;\n /** Requires `Authorization: Bearer <cronSecret>` on the cron `GET`. */\n cronSecret?: string;\n /** Allow unauthenticated cron ticks. Intended only for private/local routes. */\n allowUnauthenticatedCron?: boolean;\n /** When set, mounts an OpenAI native-webhook handler on `POST`. */\n openaiSigningSecret?: string;\n /** Observe per-batch processing errors during a tick; the tick continues. */\n onError?: (record: TrackedBatch, error: unknown) => void;\n}\n\nexport interface BatchRoutes {\n /** Cron-triggered poll tick. Wire to Vercel Cron (or any scheduler). */\n GET: (request: Request) => Promise<Response>;\n /** OpenAI native-webhook handler. Present only with `openaiSigningSecret`. */\n POST?: (request: Request) => Promise<Response>;\n /** Register a submitted batch so the cron polls it (a `BatchJob` works). */\n track: (target: TrackTarget) => Promise<TrackedBatch>;\n}\n\n/** An already-exhausted async iterable, for non-completed events. */\nconst EMPTY_RESULTS: AsyncIterable<BatchResult> = {\n [Symbol.asyncIterator]: () => ({\n next: () => Promise.resolve({ done: true, value: undefined }),\n }),\n};\n\n/**\n * Build Next.js App Router route handlers that poll your in-flight batches on a\n * cron tick and invoke `onComplete` directly when each finishes — persist\n * results to your DB without round-tripping an HTTP webhook back to your app.\n *\n * @example\n * import { createBatchRoutes, createMemoryStore } from \"batchwork/next\";\n *\n * export const { GET, POST } = createBatchRoutes({\n * store: createMemoryStore(),\n * cronSecret: process.env.CRON_SECRET,\n * openaiSigningSecret: process.env.OPENAI_WEBHOOK_SECRET,\n * onComplete: async (event, results) => {\n * for await (const r of results) {\n * await db.insert({ id: r.customId, status: r.status, text: r.text });\n * }\n * },\n * });\n */\nexport const createBatchRoutes = (options: BatchRoutesOptions): BatchRoutes => {\n const resolveCredentials = (provider: BatchProvider): ProviderCredentials => {\n if (typeof options.credentials === \"function\") {\n return options.credentials(provider);\n }\n return options.credentials ?? {};\n };\n\n const sink: CompletionSink = async (record, snapshot) => {\n const event = toEvent(record.provider, snapshot);\n // Only completed batches have results to fetch — the adapter throws when a\n // terminal batch has no output/error file (failed/expired/cancelled).\n const results =\n event.type === \"batch.completed\"\n ? getBatchResults({\n id: record.id,\n provider: record.provider,\n ...resolveCredentials(record.provider),\n })\n : EMPTY_RESULTS;\n await options.onComplete(event, results);\n };\n\n const poller = createBatchPoller({\n credentials: options.credentials,\n onComplete: sink,\n // Always supply an `onError` so one failing batch can't abort the whole\n // tick; forward to the caller's handler when they provided one.\n onError: (record, error) => options.onError?.(record, error),\n store: options.store,\n });\n\n const GET = (request: Request): Promise<Response> => {\n if (!(options.cronSecret || options.allowUnauthenticatedCron)) {\n return Promise.resolve(new Response(\"unauthorized\", { status: 401 }));\n }\n if (\n options.cronSecret &&\n request.headers.get(\"authorization\") !== `Bearer ${options.cronSecret}`\n ) {\n return Promise.resolve(new Response(\"unauthorized\", { status: 401 }));\n }\n return poller.tick().then((result) => Response.json(result));\n };\n\n const track = (target: TrackTarget): Promise<TrackedBatch> =>\n poller.track(target, {});\n\n const routes: BatchRoutes = { GET, track };\n if (options.openaiSigningSecret) {\n routes.POST = poller.openaiWebhookHandler({\n signingSecret: options.openaiSigningSecret,\n });\n }\n return routes;\n};\n"
6
6
  ],
7
- "mappings": ";;;;;;;;;;;;AAgEA,IAAM,gBAA4C;AAAA,GAC/C,OAAO,gBAAgB,OAAO;AAAA,IAC7B,MAAM,MAAM,QAAQ,QAAQ,EAAE,MAAM,MAAM,OAAO,UAAU,CAAC;AAAA,EAC9D;AACF;AAqBO,IAAM,oBAAoB,CAAC,YAA6C;AAAA,EAC7E,MAAM,qBAAqB,CAAC,aAAiD;AAAA,IAC3E,IAAI,OAAO,QAAQ,gBAAgB,YAAY;AAAA,MAC7C,OAAO,QAAQ,YAAY,QAAQ;AAAA,IACrC;AAAA,IACA,OAAO,QAAQ,eAAe,CAAC;AAAA;AAAA,EAGjC,MAAM,OAAuB,OAAO,QAAQ,aAAa;AAAA,IACvD,MAAM,QAAQ,QAAQ,OAAO,UAAU,QAAQ;AAAA,IAG/C,MAAM,UACJ,MAAM,SAAS,oBACX,gBAAgB;AAAA,MACd,IAAI,OAAO;AAAA,MACX,UAAU,OAAO;AAAA,SACd,mBAAmB,OAAO,QAAQ;AAAA,IACvC,CAAC,IACD;AAAA,IACN,MAAM,QAAQ,WAAW,OAAO,OAAO;AAAA;AAAA,EAGzC,MAAM,SAAS,kBAAkB;AAAA,IAC/B,aAAa,QAAQ;AAAA,IACrB,YAAY;AAAA,IAGZ,SAAS,CAAC,QAAQ,UAAU,QAAQ,UAAU,QAAQ,KAAK;AAAA,IAC3D,OAAO,QAAQ;AAAA,EACjB,CAAC;AAAA,EAED,MAAM,MAAM,CAAC,YAAwC;AAAA,IACnD,IACE,QAAQ,cACR,QAAQ,QAAQ,IAAI,eAAe,MAAM,UAAU,QAAQ,cAC3D;AAAA,MACA,OAAO,QAAQ,QAAQ,IAAI,SAAS,gBAAgB,EAAE,QAAQ,IAAI,CAAC,CAAC;AAAA,IACtE;AAAA,IACA,OAAO,OAAO,KAAK,EAAE,KAAK,CAAC,WAAW,SAAS,KAAK,MAAM,CAAC;AAAA;AAAA,EAG7D,MAAM,QAAQ,CAAC,WACb,OAAO,MAAM,QAAQ,CAAC,CAAC;AAAA,EAEzB,MAAM,SAAsB,EAAE,KAAK,MAAM;AAAA,EACzC,IAAI,QAAQ,qBAAqB;AAAA,IAC/B,OAAO,OAAO,OAAO,qBAAqB;AAAA,MACxC,eAAe,QAAQ;AAAA,IACzB,CAAC;AAAA,EACH;AAAA,EACA,OAAO;AAAA;",
8
- "debugId": "2EB8C739158F3A9164756E2164756E21",
7
+ "mappings": ";;;;;;;;;;;;AAkEA,IAAM,gBAA4C;AAAA,GAC/C,OAAO,gBAAgB,OAAO;AAAA,IAC7B,MAAM,MAAM,QAAQ,QAAQ,EAAE,MAAM,MAAM,OAAO,UAAU,CAAC;AAAA,EAC9D;AACF;AAqBO,IAAM,oBAAoB,CAAC,YAA6C;AAAA,EAC7E,MAAM,qBAAqB,CAAC,aAAiD;AAAA,IAC3E,IAAI,OAAO,QAAQ,gBAAgB,YAAY;AAAA,MAC7C,OAAO,QAAQ,YAAY,QAAQ;AAAA,IACrC;AAAA,IACA,OAAO,QAAQ,eAAe,CAAC;AAAA;AAAA,EAGjC,MAAM,OAAuB,OAAO,QAAQ,aAAa;AAAA,IACvD,MAAM,QAAQ,QAAQ,OAAO,UAAU,QAAQ;AAAA,IAG/C,MAAM,UACJ,MAAM,SAAS,oBACX,gBAAgB;AAAA,MACd,IAAI,OAAO;AAAA,MACX,UAAU,OAAO;AAAA,SACd,mBAAmB,OAAO,QAAQ;AAAA,IACvC,CAAC,IACD;AAAA,IACN,MAAM,QAAQ,WAAW,OAAO,OAAO;AAAA;AAAA,EAGzC,MAAM,SAAS,kBAAkB;AAAA,IAC/B,aAAa,QAAQ;AAAA,IACrB,YAAY;AAAA,IAGZ,SAAS,CAAC,QAAQ,UAAU,QAAQ,UAAU,QAAQ,KAAK;AAAA,IAC3D,OAAO,QAAQ;AAAA,EACjB,CAAC;AAAA,EAED,MAAM,MAAM,CAAC,YAAwC;AAAA,IACnD,IAAI,EAAE,QAAQ,cAAc,QAAQ,2BAA2B;AAAA,MAC7D,OAAO,QAAQ,QAAQ,IAAI,SAAS,gBAAgB,EAAE,QAAQ,IAAI,CAAC,CAAC;AAAA,IACtE;AAAA,IACA,IACE,QAAQ,cACR,QAAQ,QAAQ,IAAI,eAAe,MAAM,UAAU,QAAQ,cAC3D;AAAA,MACA,OAAO,QAAQ,QAAQ,IAAI,SAAS,gBAAgB,EAAE,QAAQ,IAAI,CAAC,CAAC;AAAA,IACtE;AAAA,IACA,OAAO,OAAO,KAAK,EAAE,KAAK,CAAC,WAAW,SAAS,KAAK,MAAM,CAAC;AAAA;AAAA,EAG7D,MAAM,QAAQ,CAAC,WACb,OAAO,MAAM,QAAQ,CAAC,CAAC;AAAA,EAEzB,MAAM,SAAsB,EAAE,KAAK,MAAM;AAAA,EACzC,IAAI,QAAQ,qBAAqB;AAAA,IAC/B,OAAO,OAAO,OAAO,qBAAqB;AAAA,MACxC,eAAe,QAAQ;AAAA,IACzB,CAAC;AAAA,EACH;AAAA,EACA,OAAO;AAAA;",
8
+ "debugId": "5888D5A3C810FEE564756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -1,10 +1,11 @@
1
1
  import type { BuiltRequest } from "../body";
2
- import type { BatchProvider, BatchResult, BatchSnapshot, ProviderCredentials } from "../types";
2
+ import type { BatchLimits, BatchProvider, BatchResult, BatchSnapshot, ProviderCredentials } from "../types";
3
3
  export interface SubmitInput {
4
4
  built: BuiltRequest[];
5
5
  credentials: ProviderCredentials;
6
6
  /** Endpoint path the captured requests target (e.g. `/v1/chat/completions`). */
7
7
  endpoint: string;
8
+ limits?: BatchLimits;
8
9
  metadata?: Record<string, string>;
9
10
  /**
10
11
  * Resolved model id. Needed by providers that set the model on the batch/job
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/providers/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EACV,aAAa,EACb,WAAW,EACX,aAAa,EACb,mBAAmB,EACpB,MAAM,UAAU,CAAC;AAElB,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,WAAW,EAAE,mBAAmB,CAAC;IACjC,gFAAgF;IAChF,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,0EAA0E;AAC1E,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,mBAAmB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxE,QAAQ,CAAC,EAAE,EAAE,aAAa,CAAC;IAC3B,OAAO,EAAE,CACP,EAAE,EAAE,MAAM,EACV,WAAW,EAAE,mBAAmB,KAC7B,cAAc,CAAC,WAAW,CAAC,CAAC;IACjC,QAAQ,EAAE,CACR,EAAE,EAAE,MAAM,EACV,WAAW,EAAE,mBAAmB,KAC7B,OAAO,CAAC,aAAa,CAAC,CAAC;IAC5B,MAAM,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;CACxD"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/providers/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EACV,WAAW,EACX,aAAa,EACb,WAAW,EACX,aAAa,EACb,mBAAmB,EACpB,MAAM,UAAU,CAAC;AAElB,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,WAAW,EAAE,mBAAmB,CAAC;IACjC,gFAAgF;IAChF,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,0EAA0E;AAC1E,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,mBAAmB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxE,QAAQ,CAAC,EAAE,EAAE,aAAa,CAAC;IAC3B,OAAO,EAAE,CACP,EAAE,EAAE,MAAM,EACV,WAAW,EAAE,mBAAmB,KAC7B,cAAc,CAAC,WAAW,CAAC,CAAC;IACjC,QAAQ,EAAE,CACR,EAAE,EAAE,MAAM,EACV,WAAW,EAAE,mBAAmB,KAC7B,OAAO,CAAC,aAAa,CAAC,CAAC;IAC5B,MAAM,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;CACxD"}
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,YAAY,EAAe,MAAM,WAAW,CAAC;AAqL3D,eAAO,MAAM,gBAAgB,EAAE,YAM9B,CAAC"}
1
+ {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,YAAY,EAAe,MAAM,WAAW,CAAC;AAyN3D,eAAO,MAAM,gBAAgB,EAAE,YAM9B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"google.d.ts","sourceRoot":"","sources":["../../src/providers/google.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,YAAY,EAAe,MAAM,WAAW,CAAC;AA6N3D;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,YAM3B,CAAC"}
1
+ {"version":3,"file":"google.d.ts","sourceRoot":"","sources":["../../src/providers/google.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,YAAY,EAAe,MAAM,WAAW,CAAC;AA+O3D;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,YAM3B,CAAC"}