batchwork 1.2.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +89 -2
- package/dist/batch.d.ts +123 -4
- package/dist/batch.d.ts.map +1 -1
- package/dist/body.d.ts +30 -1
- package/dist/body.d.ts.map +1 -1
- package/dist/{chunk-c7hzcpdy.js → chunk-9cwfwzm4.js} +2 -2
- package/dist/{chunk-jvrfwjwq.js → chunk-gwa0dkhj.js} +78 -6
- package/dist/{chunk-jvrfwjwq.js.map → chunk-gwa0dkhj.js.map} +6 -6
- package/dist/{chunk-sw8dg4sm.js → chunk-qqz5h9v6.js} +334 -6
- package/dist/chunk-qqz5h9v6.js.map +12 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/model.d.ts +50 -3
- package/dist/model.d.ts.map +1 -1
- package/dist/next/index.js +3 -3
- package/dist/providers/openai-compatible.d.ts +5 -0
- package/dist/providers/openai-compatible.d.ts.map +1 -1
- package/dist/providers/shared.d.ts +16 -1
- package/dist/providers/shared.d.ts.map +1 -1
- package/dist/providers/together.d.ts.map +1 -1
- package/dist/providers/xai.d.ts.map +1 -1
- package/dist/server/index.js +2 -2
- package/dist/types.d.ts +209 -4
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -4
- package/dist/chunk-sw8dg4sm.js.map +0 -12
- /package/dist/{chunk-c7hzcpdy.js.map → chunk-9cwfwzm4.js.map} +0 -0
package/README.md
CHANGED
|
@@ -88,13 +88,100 @@ for (const r of results) {
|
|
|
88
88
|
}
|
|
89
89
|
```
|
|
90
90
|
|
|
91
|
-
Batch image generation is available for **OpenAI** (`/v1/images/generations`, e.g. `gpt-image-2`), **Google Gemini** image models (e.g. `gemini-
|
|
91
|
+
Batch image generation is available for **OpenAI** (`/v1/images/generations`, e.g. `gpt-image-2`), **Google Gemini** image models (e.g. `gemini-3.1-flash-image`), and **xAI** (`/v1/images/generations`, e.g. `grok-imagine-image-quality`); other providers throw a clear error. Google's Imagen models aren't batch-supported, and Together AI's batch API is chat/audio only. OpenAI and Google return inline base64 on `image.data`; xAI batch returns signed `image.url`s that **expire ~1h** after completion, so download them promptly.
|
|
92
|
+
|
|
93
|
+
Image **editing** works too, on OpenAI and xAI, via `batch.images.edit()` (`batch.images.create()` is an alias of `batch.images()`). Source images are passed as JSON references — uploaded `fileId`s (OpenAI) or hosted `imageUrl`s — with an optional `mask` on OpenAI:
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
const job = await batch.images.edit({
|
|
97
|
+
model: openai.image("gpt-image-2"),
|
|
98
|
+
requests: [
|
|
99
|
+
{
|
|
100
|
+
customId: "a",
|
|
101
|
+
prompt: "Make the bicycle blue.",
|
|
102
|
+
images: [{ imageUrl: "https://example.com/bicycle.png" }],
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
});
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Videos
|
|
109
|
+
|
|
110
|
+
Generate videos in bulk — pass a video model and `prompt`s, and get signed video URLs back on `result.videos`:
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
import { batch } from "batchwork";
|
|
114
|
+
import { xai } from "@ai-sdk/xai";
|
|
115
|
+
|
|
116
|
+
const job = await batch.videos({
|
|
117
|
+
model: xai.video("grok-imagine-video"),
|
|
118
|
+
requests: [
|
|
119
|
+
{ customId: "a", prompt: "A red bicycle rolling downhill.", duration: 5 },
|
|
120
|
+
],
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
const results = await job.wait().then(() => job.collect());
|
|
124
|
+
for (const r of results) {
|
|
125
|
+
console.log(r.customId, r.videos?.[0]?.url);
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Batch video generation is available for **xAI** (Grok Imagine via `/v1/videos/generations`, plus editing and extension through `providerOptions.xai`); other providers throw a clear error — OpenAI's Videos API (Sora) is deprecated (shutting down September 2026) and Google's Veo models aren't batch-supported. Results are signed URLs that **expire ~1h** after completion, so download them promptly.
|
|
130
|
+
|
|
131
|
+
## Transcriptions
|
|
132
|
+
|
|
133
|
+
Transcribe audio in bulk — pass a transcription model and hosted audio URLs, and get transcripts back on `result.text`:
|
|
134
|
+
|
|
135
|
+
```ts
|
|
136
|
+
import { batch } from "batchwork";
|
|
137
|
+
import { groq } from "@ai-sdk/groq";
|
|
138
|
+
|
|
139
|
+
const job = await batch.transcriptions({
|
|
140
|
+
model: groq.transcription("whisper-large-v3"),
|
|
141
|
+
requests: [
|
|
142
|
+
{ customId: "a", audioUrl: "https://example.com/interview.wav" },
|
|
143
|
+
{ customId: "b", audioUrl: "https://example.com/standup.mp3" },
|
|
144
|
+
],
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
const results = await job.wait().then(() => job.collect());
|
|
148
|
+
for (const r of results) {
|
|
149
|
+
console.log(r.customId, r.text);
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Batch transcription is available for **Groq** (`whisper-large-v3`, audio by `url`), **Mistral** (Voxtral models, e.g. `"mistral/voxtral-mini-latest"`, audio by `file_url`), and **Together AI** (Whisper models, e.g. `"together/openai/whisper-large-v3"`, audio by `file`); other providers throw a clear error — OpenAI's batch API doesn't accept its audio endpoints. Batch audio endpoints take **hosted URLs only** (no file uploads), so each `audioUrl` must stay reachable while the batch processes. Request `timestampGranularities: ["segment"]` to also get timestamped spans on `result.segments`.
|
|
154
|
+
|
|
155
|
+
`batch.translations()` runs Whisper's **translate** task instead — audio in any language, English text out — on **Groq** (`whisper-large-v3` only) and **Together AI**, with the same request shape minus `language`.
|
|
156
|
+
|
|
157
|
+
## Moderations
|
|
158
|
+
|
|
159
|
+
Moderate content in bulk — pass a moderation model and texts (or image URLs, OpenAI omni moderation only), and get verdicts back on `result.moderation`:
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
import { batch } from "batchwork";
|
|
163
|
+
|
|
164
|
+
const job = await batch.moderations({
|
|
165
|
+
model: "openai/omni-moderation-latest",
|
|
166
|
+
requests: [
|
|
167
|
+
{ customId: "a", value: "What a lovely day for a picnic." },
|
|
168
|
+
{ customId: "b", value: "…user-generated content…" },
|
|
169
|
+
],
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
const results = await job.wait().then(() => job.collect());
|
|
173
|
+
for (const r of results) {
|
|
174
|
+
console.log(r.customId, r.moderation?.flagged, r.moderation?.categories);
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Batch moderation is available for **OpenAI** (`omni-moderation-latest`, text + images) and **Mistral** (`mistral-moderation-latest`, text-only); other providers throw a clear error. Models are passed as `"provider/model"` strings (the AI SDK has no moderation model type). Category names are provider-native; `flagged` is the provider's own flag (OpenAI) or "any category flagged" (Mistral).
|
|
92
179
|
|
|
93
180
|
## Features
|
|
94
181
|
|
|
95
182
|
- **One API, many providers** — OpenAI, Anthropic, Google Gemini, Groq, Mistral, Together AI, and xAI.
|
|
96
183
|
- **AI SDK native** — author requests in the familiar `generateText` shape.
|
|
97
|
-
- **Chat, embeddings &
|
|
184
|
+
- **Chat, embeddings, images, video, audio & moderation** — `batch()` for completions, `batch.embeddings()` for vectors, `batch.images()` for image generation, `batch.videos()` for video generation, `batch.transcriptions()` for audio transcription, `batch.moderations()` for content moderation.
|
|
98
185
|
- **~50% cheaper** — every request runs against the provider's batch window.
|
|
99
186
|
- **Normalized results** — unified status, text, usage, and error types regardless of provider.
|
|
100
187
|
- **Server-ready** — optional layers for managed polling, unified webhooks, and Next.js route handlers.
|
package/dist/batch.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BatchJob } from "./job";
|
|
2
|
-
import type { BatchEmbeddingsOptions, BatchImageOptions, BatchOptions, BatchRef, BatchResult } from "./types";
|
|
2
|
+
import type { BatchEmbeddingsOptions, BatchImageEditOptions, BatchImageOptions, BatchModerationOptions, BatchOptions, BatchRef, BatchResult, BatchTranscriptionOptions, BatchTranslationOptions, BatchVideoOptions } from "./types";
|
|
3
3
|
/**
|
|
4
4
|
* Submit a batch of text/chat requests to the model's provider and return a
|
|
5
5
|
* handle. Reachable as both `batch()` (shorthand) and `batch.text()`.
|
|
@@ -50,6 +50,103 @@ declare const submitEmbeddings: (options: BatchEmbeddingsOptions) => Promise<Bat
|
|
|
50
50
|
* }
|
|
51
51
|
*/
|
|
52
52
|
declare const submitImages: (options: BatchImageOptions) => Promise<BatchJob>;
|
|
53
|
+
/**
|
|
54
|
+
* Submit a batch of image-edit requests to the model's provider and return a
|
|
55
|
+
* handle. Each request's `prompt` is applied to its source `images` (uploaded
|
|
56
|
+
* file ids or hosted URLs — batch bodies are JSON, so raw uploads aren't
|
|
57
|
+
* possible), producing edited images on `result.images`, correlated by
|
|
58
|
+
* `customId` via {@link BatchJob.results}. Supported for OpenAI and xAI; other
|
|
59
|
+
* providers throw {@link UnsupportedProviderError}.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* const job = await batch.images.edit({
|
|
63
|
+
* model: openai.image("gpt-image-2"),
|
|
64
|
+
* requests: [
|
|
65
|
+
* {
|
|
66
|
+
* customId: "a",
|
|
67
|
+
* prompt: "Make the bicycle blue.",
|
|
68
|
+
* images: [{ imageUrl: "https://example.com/bicycle.png" }],
|
|
69
|
+
* },
|
|
70
|
+
* ],
|
|
71
|
+
* });
|
|
72
|
+
* const results = await job.wait().then(() => job.collect());
|
|
73
|
+
*/
|
|
74
|
+
declare const submitImageEdits: (options: BatchImageEditOptions) => Promise<BatchJob>;
|
|
75
|
+
/**
|
|
76
|
+
* Submit a batch of moderation requests to the model's provider and return a
|
|
77
|
+
* handle. Each request's `value` (and/or `imageUrls`, OpenAI omni moderation
|
|
78
|
+
* only) produces one verdict on `result.moderation`, correlated by `customId`
|
|
79
|
+
* via {@link BatchJob.results}. Supported for OpenAI and Mistral; other
|
|
80
|
+
* providers throw {@link UnsupportedProviderError}. Pass the model as a
|
|
81
|
+
* `"provider/model"` string — the AI SDK has no moderation model type.
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* const job = await batch.moderations({
|
|
85
|
+
* model: "openai/omni-moderation-latest",
|
|
86
|
+
* requests: [{ customId: "a", value: "…user-generated content…" }],
|
|
87
|
+
* });
|
|
88
|
+
* const results = await job.wait().then(() => job.collect());
|
|
89
|
+
* for (const r of results) {
|
|
90
|
+
* console.log(r.customId, r.moderation?.flagged);
|
|
91
|
+
* }
|
|
92
|
+
*/
|
|
93
|
+
declare const submitModerations: (options: BatchModerationOptions) => Promise<BatchJob>;
|
|
94
|
+
/**
|
|
95
|
+
* Submit a batch of audio-transcription requests to the model's provider and
|
|
96
|
+
* return a handle. Each request's `audioUrl` (a hosted audio file — batch
|
|
97
|
+
* audio endpoints accept URLs, not file uploads) produces one transcript,
|
|
98
|
+
* correlated by `customId` via {@link BatchJob.results}. Supported for Groq
|
|
99
|
+
* and Mistral; other providers throw {@link UnsupportedProviderError}.
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* const job = await batch.transcriptions({
|
|
103
|
+
* model: groq.transcription("whisper-large-v3"),
|
|
104
|
+
* requests: [{ customId: "a", audioUrl: "https://example.com/call.wav" }],
|
|
105
|
+
* });
|
|
106
|
+
* const results = await job.wait().then(() => job.collect());
|
|
107
|
+
* for (const r of results) {
|
|
108
|
+
* console.log(r.customId, r.text);
|
|
109
|
+
* }
|
|
110
|
+
*/
|
|
111
|
+
declare const submitTranscriptions: (options: BatchTranscriptionOptions) => Promise<BatchJob>;
|
|
112
|
+
/**
|
|
113
|
+
* Submit a batch of video-generation requests to the model's provider and
|
|
114
|
+
* return a handle. Each request's `prompt` produces one video, correlated by
|
|
115
|
+
* `customId` via {@link BatchJob.results}. Supported for xAI (Grok Imagine);
|
|
116
|
+
* other providers throw {@link UnsupportedProviderError} — OpenAI's Videos API
|
|
117
|
+
* (Sora) is deprecated and Google's Veo models are not batch-compatible.
|
|
118
|
+
*
|
|
119
|
+
* Results come back as signed URLs on `result.videos` that **expire ~1h**
|
|
120
|
+
* after completion — download promptly.
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* const job = await batch.videos({
|
|
124
|
+
* model: xai.video("grok-imagine-video"),
|
|
125
|
+
* requests: [{ customId: "a", prompt: "A red bicycle rolling downhill." }],
|
|
126
|
+
* });
|
|
127
|
+
* const results = await job.wait().then(() => job.collect());
|
|
128
|
+
* for (const r of results) {
|
|
129
|
+
* console.log(r.customId, r.videos?.[0]?.url);
|
|
130
|
+
* }
|
|
131
|
+
*/
|
|
132
|
+
declare const submitVideos: (options: BatchVideoOptions) => Promise<BatchJob>;
|
|
133
|
+
/**
|
|
134
|
+
* Submit a batch of audio-translation requests (Whisper's translate task —
|
|
135
|
+
* audio in any language, English text out) and return a handle. Mirrors
|
|
136
|
+
* {@link batch.transcriptions} minus `language`: each request's `audioUrl`
|
|
137
|
+
* produces one English transcript on `result.text`, correlated by `customId`.
|
|
138
|
+
* Supported for Groq and Together; other providers throw
|
|
139
|
+
* {@link UnsupportedProviderError} — Mistral batches transcriptions but not
|
|
140
|
+
* translations.
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* const job = await batch.translations({
|
|
144
|
+
* model: groq.transcription("whisper-large-v3"),
|
|
145
|
+
* requests: [{ customId: "a", audioUrl: "https://example.com/french.wav" }],
|
|
146
|
+
* });
|
|
147
|
+
* const results = await job.wait().then(() => job.collect());
|
|
148
|
+
*/
|
|
149
|
+
declare const submitTranslations: (options: BatchTranslationOptions) => Promise<BatchJob>;
|
|
53
150
|
/**
|
|
54
151
|
* Submit a batch of requests and return a {@link BatchJob} handle.
|
|
55
152
|
*
|
|
@@ -58,7 +155,12 @@ declare const submitImages: (options: BatchImageOptions) => Promise<BatchJob>;
|
|
|
58
155
|
*
|
|
59
156
|
* - `batch()` / {@link batch.text} — text & chat completions
|
|
60
157
|
* - {@link batch.embeddings} — embedding vectors
|
|
61
|
-
* - {@link batch.images} — image generation
|
|
158
|
+
* - {@link batch.images} / {@link batch.images.create} — image generation
|
|
159
|
+
* - {@link batch.images.edit} — image editing
|
|
160
|
+
* - {@link batch.transcriptions} — audio transcription
|
|
161
|
+
* - {@link batch.translations} — audio translation to English
|
|
162
|
+
* - {@link batch.moderations} — content moderation
|
|
163
|
+
* - {@link batch.videos} — video generation
|
|
62
164
|
*
|
|
63
165
|
* @example
|
|
64
166
|
* const job = await batch({
|
|
@@ -69,10 +171,27 @@ declare const submitImages: (options: BatchImageOptions) => Promise<BatchJob>;
|
|
|
69
171
|
export declare const batch: typeof submitText & {
|
|
70
172
|
/** Submit a batch of embedding requests. */
|
|
71
173
|
embeddings: typeof submitEmbeddings;
|
|
72
|
-
/**
|
|
73
|
-
|
|
174
|
+
/**
|
|
175
|
+
* Submit a batch of image-generation requests. Also exposes
|
|
176
|
+
* {@link batch.images.create} (an alias of calling it directly) and
|
|
177
|
+
* {@link batch.images.edit} for editing existing images.
|
|
178
|
+
*/
|
|
179
|
+
images: typeof submitImages & {
|
|
180
|
+
/** Submit a batch of image-generation requests. Equivalent to `batch.images()`. */
|
|
181
|
+
create: typeof submitImages;
|
|
182
|
+
/** Submit a batch of image-edit requests. */
|
|
183
|
+
edit: typeof submitImageEdits;
|
|
184
|
+
};
|
|
185
|
+
/** Submit a batch of moderation requests. */
|
|
186
|
+
moderations: typeof submitModerations;
|
|
74
187
|
/** Submit a batch of text/chat requests. Equivalent to calling `batch()`. */
|
|
75
188
|
text: typeof submitText;
|
|
189
|
+
/** Submit a batch of audio-transcription requests. */
|
|
190
|
+
transcriptions: typeof submitTranscriptions;
|
|
191
|
+
/** Submit a batch of audio-translation (to English) requests. */
|
|
192
|
+
translations: typeof submitTranslations;
|
|
193
|
+
/** Submit a batch of video-generation requests. */
|
|
194
|
+
videos: typeof submitVideos;
|
|
76
195
|
};
|
|
77
196
|
/**
|
|
78
197
|
* @deprecated Use {@link batch.embeddings} instead. Kept as a standalone alias
|
package/dist/batch.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"batch.d.ts","sourceRoot":"","sources":["../src/batch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"batch.d.ts","sourceRoot":"","sources":["../src/batch.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAoBjC,OAAO,KAAK,EACV,sBAAsB,EACtB,qBAAqB,EACrB,iBAAiB,EACjB,sBAAsB,EACtB,YAAY,EAEZ,QAAQ,EACR,WAAW,EACX,yBAAyB,EACzB,uBAAuB,EACvB,iBAAiB,EAElB,MAAM,SAAS,CAAC;AAsBjB;;;;;;;;;;;;;;GAcG;AACH,QAAA,MAAM,UAAU,YAAmB,YAAY,KAAG,OAAO,CAAC,QAAQ,CA2BjE,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,QAAA,MAAM,gBAAgB,YACX,sBAAsB,KAC9B,OAAO,CAAC,QAAQ,CA6BlB,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,QAAA,MAAM,YAAY,YAAmB,iBAAiB,KAAG,OAAO,CAAC,QAAQ,CA8BxE,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,QAAA,MAAM,gBAAgB,YACX,qBAAqB,KAC7B,OAAO,CAAC,QAAQ,CA6BlB,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,QAAA,MAAM,iBAAiB,YACZ,sBAAsB,KAC9B,OAAO,CAAC,QAAQ,CAwBlB,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,QAAA,MAAM,oBAAoB,YACf,yBAAyB,KACjC,OAAO,CAAC,QAAQ,CA6BlB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,QAAA,MAAM,YAAY,YAAmB,iBAAiB,KAAG,OAAO,CAAC,QAAQ,CA8BxE,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,QAAA,MAAM,kBAAkB,YACb,uBAAuB,KAC/B,OAAO,CAAC,QAAQ,CA6BlB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,KAAK;IAChB,4CAA4C;;IAE5C;;;;OAIG;;QAED,mFAAmF;;QAEnF,6CAA6C;;;IAG/C,6CAA6C;;IAE7C,6EAA6E;;IAE7E,sDAAsD;;IAEtD,iEAAiE;;IAEjE,mDAAmD;;CAEnD,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,eAAe,yBAAmB,CAAC;AAEhD;;;GAGG;AACH,eAAO,MAAM,WAAW,qBAAe,CAAC;AAExC;;;GAGG;AACH,eAAO,MAAM,QAAQ,QAAe,QAAQ,KAAG,OAAO,CAAC,QAAQ,CAK9D,CAAC;AAEF,uEAAuE;AACvE,eAAO,MAAM,eAAe,QAAS,QAAQ,KAAG,cAAc,CAAC,WAAW,CAGzE,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,WAAW,QAAe,QAAQ,KAAG,OAAO,CAAC,IAAI,CAG7D,CAAC"}
|
package/dist/body.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ResolvedBatchLimits } from "./limits";
|
|
2
2
|
import type { ResolvedModel } from "./model";
|
|
3
|
-
import type { BatchDefaults, BatchEmbeddingRequest, BatchImageDefaults, BatchImageRequest, BatchLimits, BatchRequest, ProviderCredentials } from "./types";
|
|
3
|
+
import type { BatchDefaults, BatchEmbeddingRequest, BatchImageDefaults, BatchImageEditDefaults, BatchImageEditRequest, BatchImageRequest, BatchLimits, BatchModerationRequest, BatchRequest, BatchTranscriptionDefaults, BatchTranscriptionRequest, BatchTranslationDefaults, BatchTranslationRequest, BatchVideoDefaults, BatchVideoRequest, ProviderCredentials } from "./types";
|
|
4
4
|
/** A provider request body derived from a single batch item. */
|
|
5
5
|
export interface BuiltRequest {
|
|
6
6
|
/** The serialized provider request body (becomes the batch line). */
|
|
@@ -23,6 +23,23 @@ export declare const buildRequestBodies: (resolved: ResolvedModel, requests: rea
|
|
|
23
23
|
* single embedding (`input: [value]`), correlated by `customId`.
|
|
24
24
|
*/
|
|
25
25
|
export declare const buildEmbeddingBodies: (resolved: ResolvedModel, requests: readonly BatchEmbeddingRequest[], credentials: ProviderCredentials, rawLimits?: BatchLimits | ResolvedBatchLimits) => Promise<BuiltRequest[]>;
|
|
26
|
+
/**
|
|
27
|
+
* Build provider moderation request bodies for every batch item. Each item
|
|
28
|
+
* maps to a single moderation verdict, correlated by `customId`.
|
|
29
|
+
*/
|
|
30
|
+
export declare const buildModerationBodies: (resolved: ResolvedModel, requests: readonly BatchModerationRequest[], rawLimits?: BatchLimits | ResolvedBatchLimits) => BuiltRequest[];
|
|
31
|
+
/**
|
|
32
|
+
* Build provider transcription request bodies for every batch item. Each item
|
|
33
|
+
* maps to a single transcription of a hosted audio URL, correlated by
|
|
34
|
+
* `customId`.
|
|
35
|
+
*/
|
|
36
|
+
export declare const buildTranscriptionBodies: (resolved: ResolvedModel, requests: readonly BatchTranscriptionRequest[], defaults: BatchTranscriptionDefaults | undefined, rawLimits?: BatchLimits | ResolvedBatchLimits) => BuiltRequest[];
|
|
37
|
+
/**
|
|
38
|
+
* Build provider audio-translation request bodies for every batch item. The
|
|
39
|
+
* body shape is identical to transcription (minus `language` — the output is
|
|
40
|
+
* always English); only the endpoint differs.
|
|
41
|
+
*/
|
|
42
|
+
export declare const buildTranslationBodies: (resolved: ResolvedModel, requests: readonly BatchTranslationRequest[], defaults: BatchTranslationDefaults | undefined, rawLimits?: BatchLimits | ResolvedBatchLimits) => BuiltRequest[];
|
|
26
43
|
/**
|
|
27
44
|
* Derive provider image-generation request bodies for every batch item by
|
|
28
45
|
* running each through the AI SDK `generateImage` with a capturing `fetch`.
|
|
@@ -30,4 +47,16 @@ export declare const buildEmbeddingBodies: (resolved: ResolvedModel, requests: r
|
|
|
30
47
|
* single image-generation call, correlated by `customId`.
|
|
31
48
|
*/
|
|
32
49
|
export declare const buildImageBodies: (resolved: ResolvedModel, requests: readonly BatchImageRequest[], defaults: BatchImageDefaults | undefined, credentials: ProviderCredentials, rawLimits?: BatchLimits | ResolvedBatchLimits) => Promise<BuiltRequest[]>;
|
|
50
|
+
/**
|
|
51
|
+
* Build provider image-edit request bodies for every batch item. Each item
|
|
52
|
+
* maps to a single edit call, correlated by `customId`.
|
|
53
|
+
*/
|
|
54
|
+
export declare const buildImageEditBodies: (resolved: ResolvedModel, requests: readonly BatchImageEditRequest[], defaults: BatchImageEditDefaults | undefined, rawLimits?: BatchLimits | ResolvedBatchLimits) => BuiltRequest[];
|
|
55
|
+
/**
|
|
56
|
+
* Derive provider video-generation request bodies for every batch item by
|
|
57
|
+
* running each through the AI SDK `generateVideo` with a capturing `fetch`.
|
|
58
|
+
* Mirrors {@link buildRequestBodies} for the video endpoints; each item maps to
|
|
59
|
+
* a single video job, correlated by `customId`.
|
|
60
|
+
*/
|
|
61
|
+
export declare const buildVideoBodies: (resolved: ResolvedModel, requests: readonly BatchVideoRequest[], defaults: BatchVideoDefaults | undefined, credentials: ProviderCredentials, rawLimits?: BatchLimits | ResolvedBatchLimits) => Promise<BuiltRequest[]>;
|
|
33
62
|
//# sourceMappingURL=body.d.ts.map
|
package/dist/body.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"body.d.ts","sourceRoot":"","sources":["../src/body.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"body.d.ts","sourceRoot":"","sources":["../src/body.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAUpD,OAAO,KAAK,EAAkB,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,KAAK,EACV,aAAa,EACb,qBAAqB,EACrB,kBAAkB,EAClB,sBAAsB,EACtB,qBAAqB,EAErB,iBAAiB,EACjB,WAAW,EACX,sBAAsB,EACtB,YAAY,EACZ,0BAA0B,EAC1B,yBAAyB,EACzB,wBAAwB,EACxB,uBAAuB,EACvB,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EAEpB,MAAM,SAAS,CAAC;AAIjB,gEAAgE;AAChE,MAAM,WAAW,YAAY;IAC3B,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,QAAQ,EAAE,MAAM,CAAC;CAClB;AAgOD;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,aACnB,aAAa,YACb,SAAS,YAAY,EAAE,YACvB,aAAa,GAAG,SAAS,eACtB,mBAAmB,cACpB,WAAW,GAAG,mBAAmB,KAC5C,OAAO,CAAC,YAAY,EAAE,CA4BxB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,aACrB,aAAa,YACb,SAAS,qBAAqB,EAAE,eAC7B,mBAAmB,cACpB,WAAW,GAAG,mBAAmB,KAC5C,OAAO,CAAC,YAAY,EAAE,CAgCxB,CAAC;AAyDF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,aACtB,aAAa,YACb,SAAS,sBAAsB,EAAE,cAC/B,WAAW,GAAG,mBAAmB,KAC5C,YAAY,EAgBd,CAAC;AA0FF;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,aACzB,aAAa,YACb,SAAS,yBAAyB,EAAE,YACpC,0BAA0B,GAAG,SAAS,cACpC,WAAW,GAAG,mBAAmB,KAC5C,YAAY,EAOZ,CAAC;AAEJ;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,aACvB,aAAa,YACb,SAAS,uBAAuB,EAAE,YAClC,wBAAwB,GAAG,SAAS,cAClC,WAAW,GAAG,mBAAmB,KAC5C,YAAY,EAOZ,CAAC;AAEJ;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,aACjB,aAAa,YACb,SAAS,iBAAiB,EAAE,YAC5B,kBAAkB,GAAG,SAAS,eAC3B,mBAAmB,cACpB,WAAW,GAAG,mBAAmB,KAC5C,OAAO,CAAC,YAAY,EAAE,CAgCxB,CAAC;AAmEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,aACrB,aAAa,YACb,SAAS,qBAAqB,EAAE,YAChC,sBAAsB,GAAG,SAAS,cAChC,WAAW,GAAG,mBAAmB,KAC5C,YAAY,EAoBd,CAAC;AAiCF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,aACjB,aAAa,YACb,SAAS,iBAAiB,EAAE,YAC5B,kBAAkB,GAAG,SAAS,eAC3B,mBAAmB,cACpB,WAAW,GAAG,mBAAmB,KAC5C,OAAO,CAAC,YAAY,EAAE,CAgCxB,CAAC"}
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
BatchworkError,
|
|
3
3
|
getAdapter,
|
|
4
4
|
isTerminalStatus
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-gwa0dkhj.js";
|
|
6
6
|
|
|
7
7
|
// src/server/events.ts
|
|
8
8
|
var EVENT_BY_STATUS = {
|
|
@@ -402,4 +402,4 @@ var createMemoryStore = () => {
|
|
|
402
402
|
export { toEvent, signWebhook, verifyWebhook, verifyBatchWebhook, createBatchPoller, createMemoryStore };
|
|
403
403
|
|
|
404
404
|
//# debugId=F1B4BA11C9A6AE3364756E2164756E21
|
|
405
|
-
//# sourceMappingURL=chunk-
|
|
405
|
+
//# sourceMappingURL=chunk-9cwfwzm4.js.map
|
|
@@ -777,7 +777,26 @@ var textFromBody = (body) => {
|
|
|
777
777
|
return content;
|
|
778
778
|
}
|
|
779
779
|
}
|
|
780
|
-
return asString(obj.output_text);
|
|
780
|
+
return asString(obj.output_text) ?? asString(obj.text);
|
|
781
|
+
};
|
|
782
|
+
var segmentsFromBody = (body) => {
|
|
783
|
+
const obj = asRecord(body);
|
|
784
|
+
if (asString(obj.text) === undefined) {
|
|
785
|
+
return;
|
|
786
|
+
}
|
|
787
|
+
const segments = [];
|
|
788
|
+
for (const item of asArray(obj.segments)) {
|
|
789
|
+
const segment = asRecord(item);
|
|
790
|
+
const text = asString(segment.text);
|
|
791
|
+
if (text !== undefined) {
|
|
792
|
+
segments.push({
|
|
793
|
+
endSecond: asNumber(segment.end),
|
|
794
|
+
startSecond: asNumber(segment.start),
|
|
795
|
+
text
|
|
796
|
+
});
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
return segments.length > 0 ? segments : undefined;
|
|
781
800
|
};
|
|
782
801
|
var embeddingFromBody = (body) => {
|
|
783
802
|
const data = asArray(asRecord(body).data);
|
|
@@ -798,6 +817,31 @@ var imagesFromBody = (body) => {
|
|
|
798
817
|
}
|
|
799
818
|
return images.length > 0 ? images : undefined;
|
|
800
819
|
};
|
|
820
|
+
var moderationFromBody = (body) => {
|
|
821
|
+
const results3 = asArray(asRecord(body).results);
|
|
822
|
+
if (results3.length === 0) {
|
|
823
|
+
return;
|
|
824
|
+
}
|
|
825
|
+
const first = asRecord(results3[0]);
|
|
826
|
+
const categories = {};
|
|
827
|
+
for (const [key, value] of Object.entries(asRecord(first.categories))) {
|
|
828
|
+
if (typeof value === "boolean") {
|
|
829
|
+
categories[key] = value;
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
if (Object.keys(categories).length === 0) {
|
|
833
|
+
return;
|
|
834
|
+
}
|
|
835
|
+
const categoryScores = {};
|
|
836
|
+
for (const [key, value] of Object.entries(asRecord(first.category_scores))) {
|
|
837
|
+
const score = asNumber(value);
|
|
838
|
+
if (score !== undefined) {
|
|
839
|
+
categoryScores[key] = score;
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
const flagged = typeof first.flagged === "boolean" ? first.flagged : Object.values(categories).some(Boolean);
|
|
843
|
+
return { categories, categoryScores, flagged };
|
|
844
|
+
};
|
|
801
845
|
var usageFromBody = (body) => {
|
|
802
846
|
const usage = asRecord(asRecord(body).usage);
|
|
803
847
|
const inputTokens = asNumber(usage.prompt_tokens) ?? asNumber(usage.input_tokens);
|
|
@@ -840,7 +884,9 @@ var normalizeOpenAIResult = (line) => {
|
|
|
840
884
|
customId,
|
|
841
885
|
embedding: embeddingFromBody(response.body),
|
|
842
886
|
images: imagesFromBody(response.body),
|
|
887
|
+
moderation: moderationFromBody(response.body),
|
|
843
888
|
response: response.body,
|
|
889
|
+
segments: segmentsFromBody(response.body),
|
|
844
890
|
status: "succeeded",
|
|
845
891
|
text: textFromBody(response.body),
|
|
846
892
|
usage: usageFromBody(response.body)
|
|
@@ -932,7 +978,11 @@ var createOpenAICompatibleAdapter = (config) => {
|
|
|
932
978
|
const jsonl = encodeJsonl(input.built.map((item) => {
|
|
933
979
|
const body = omit(item.body, "stream");
|
|
934
980
|
if (lineFormat === "body-only") {
|
|
935
|
-
return {
|
|
981
|
+
return {
|
|
982
|
+
body,
|
|
983
|
+
custom_id: item.customId,
|
|
984
|
+
...config.lineExtras?.(endpoint)
|
|
985
|
+
};
|
|
936
986
|
}
|
|
937
987
|
return {
|
|
938
988
|
body,
|
|
@@ -1232,6 +1282,7 @@ var togetherAdapter = createOpenAICompatibleAdapter({
|
|
|
1232
1282
|
baseUrl: "https://api.together.xyz/v1",
|
|
1233
1283
|
filePurpose: "batch-api",
|
|
1234
1284
|
id: "together",
|
|
1285
|
+
lineExtras: (endpoint) => endpoint.startsWith("/v1/audio/") ? { method: "FILE" } : undefined,
|
|
1235
1286
|
lineFormat: "body-only",
|
|
1236
1287
|
uploadFile: uploadTogetherFile
|
|
1237
1288
|
});
|
|
@@ -1303,6 +1354,25 @@ var imagesFromXaiCompletion = (completion) => {
|
|
|
1303
1354
|
}
|
|
1304
1355
|
return images.length > 0 ? images : undefined;
|
|
1305
1356
|
};
|
|
1357
|
+
var videosFromXaiCompletion = (completion) => {
|
|
1358
|
+
const obj = asRecord(completion);
|
|
1359
|
+
const entries = asArray(obj.data);
|
|
1360
|
+
const sources = entries.length > 0 ? entries : [obj];
|
|
1361
|
+
const videos = [];
|
|
1362
|
+
for (const source of sources) {
|
|
1363
|
+
const record = asRecord(source);
|
|
1364
|
+
const video = asRecord(record.video);
|
|
1365
|
+
const url = asString(video.url) ?? asString(record.url);
|
|
1366
|
+
if (url) {
|
|
1367
|
+
const duration = asNumber(video.duration) ?? asNumber(record.duration);
|
|
1368
|
+
videos.push({
|
|
1369
|
+
...duration === undefined ? {} : { durationSeconds: duration },
|
|
1370
|
+
url
|
|
1371
|
+
});
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
return videos.length > 0 ? videos : undefined;
|
|
1375
|
+
};
|
|
1306
1376
|
var normalizeResult3 = (item) => {
|
|
1307
1377
|
const obj = asRecord(item);
|
|
1308
1378
|
const customId = asString(obj.batch_request_id) ?? "";
|
|
@@ -1321,10 +1391,12 @@ var normalizeResult3 = (item) => {
|
|
|
1321
1391
|
};
|
|
1322
1392
|
}
|
|
1323
1393
|
const response = asRecord(batchResult.response);
|
|
1394
|
+
const [opKey] = Object.keys(response);
|
|
1324
1395
|
const completion = response.chat_get_completion ?? Object.values(response)[0];
|
|
1396
|
+
const isVideo = response.chat_get_completion === undefined && opKey !== undefined && opKey.includes("video");
|
|
1325
1397
|
return {
|
|
1326
1398
|
customId,
|
|
1327
|
-
images: imagesFromXaiCompletion(completion),
|
|
1399
|
+
...isVideo ? { videos: videosFromXaiCompletion(completion) } : { images: imagesFromXaiCompletion(completion) },
|
|
1328
1400
|
response: completion,
|
|
1329
1401
|
status: "succeeded",
|
|
1330
1402
|
text: textFromBody(completion),
|
|
@@ -1337,7 +1409,7 @@ var submit4 = async (input) => {
|
|
|
1337
1409
|
body: omit(item.body, "stream"),
|
|
1338
1410
|
custom_id: item.customId,
|
|
1339
1411
|
method: "POST",
|
|
1340
|
-
url: input.endpoint
|
|
1412
|
+
url: item.endpoint || input.endpoint
|
|
1341
1413
|
})), { label: "batch upload JSONL", maxBytes: limits.maxUploadBytes });
|
|
1342
1414
|
const inputFileId = await uploadInputFile(jsonl, baseUrl4(input.credentials), authHeaders2(input.credentials), { purpose: null });
|
|
1343
1415
|
const raw = await requestJson(`${baseUrl4(input.credentials)}/batches`, {
|
|
@@ -1403,5 +1475,5 @@ var getAdapter = (provider) => adapters[provider];
|
|
|
1403
1475
|
|
|
1404
1476
|
export { BatchworkError, UnsupportedProviderError, MissingDependencyError, resolveBatchLimits, assertByteLength, mapWithConcurrency, isTerminalStatus, BatchJob, getAdapter };
|
|
1405
1477
|
|
|
1406
|
-
//# debugId=
|
|
1407
|
-
//# sourceMappingURL=chunk-
|
|
1478
|
+
//# debugId=4C939B96519322C164756E2164756E21
|
|
1479
|
+
//# sourceMappingURL=chunk-gwa0dkhj.js.map
|