batchwork 0.0.0 → 1.0.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/LICENSE +21 -0
- package/README.md +57 -0
- package/dist/batch.d.ts +27 -0
- package/dist/batch.d.ts.map +1 -0
- package/dist/body.d.ts +18 -0
- package/dist/body.d.ts.map +1 -0
- package/dist/chunk-ab2d71gk.js +325 -0
- package/dist/chunk-ab2d71gk.js.map +12 -0
- package/dist/chunk-kv3847wy.js +1048 -0
- package/dist/chunk-kv3847wy.js.map +24 -0
- package/dist/chunk-v0bahtg2.js +7 -0
- package/dist/chunk-v0bahtg2.js.map +9 -0
- package/dist/chunk-zp2cxkyb.js +226 -0
- package/dist/chunk-zp2cxkyb.js.map +13 -0
- package/dist/errors.d.ts +16 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/http.d.ts +5 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +9 -0
- package/dist/job.d.ts +31 -0
- package/dist/job.d.ts.map +1 -0
- package/dist/jsonl.d.ts +17 -0
- package/dist/jsonl.d.ts.map +1 -0
- package/dist/model.d.ts +32 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/next/index.d.ts +59 -0
- package/dist/next/index.d.ts.map +1 -0
- package/dist/next/index.js +61 -0
- package/dist/next/index.js.map +10 -0
- package/dist/postgres/batch-store.d.ts +19 -0
- package/dist/postgres/batch-store.d.ts.map +1 -0
- package/dist/postgres/index.d.ts +6 -0
- package/dist/postgres/index.d.ts.map +1 -0
- package/dist/postgres/index.js +101 -0
- package/dist/postgres/index.js.map +12 -0
- package/dist/postgres/migrate.d.ts +15 -0
- package/dist/postgres/migrate.d.ts.map +1 -0
- package/dist/postgres/types.d.ts +26 -0
- package/dist/postgres/types.d.ts.map +1 -0
- package/dist/providers/adapter.d.ts +24 -0
- package/dist/providers/adapter.d.ts.map +1 -0
- package/dist/providers/anthropic.d.ts +3 -0
- package/dist/providers/anthropic.d.ts.map +1 -0
- package/dist/providers/google.d.ts +8 -0
- package/dist/providers/google.d.ts.map +1 -0
- package/dist/providers/groq.d.ts +8 -0
- package/dist/providers/groq.d.ts.map +1 -0
- package/dist/providers/index.d.ts +5 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/mistral.d.ts +8 -0
- package/dist/providers/mistral.d.ts.map +1 -0
- package/dist/providers/openai-compatible.d.ts +41 -0
- package/dist/providers/openai-compatible.d.ts.map +1 -0
- package/dist/providers/openai.d.ts +7 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/shared.d.ts +23 -0
- package/dist/providers/shared.d.ts.map +1 -0
- package/dist/providers/together.d.ts +8 -0
- package/dist/providers/together.d.ts.map +1 -0
- package/dist/providers/xai.d.ts +8 -0
- package/dist/providers/xai.d.ts.map +1 -0
- package/dist/redis/batch-store.d.ts +15 -0
- package/dist/redis/batch-store.d.ts.map +1 -0
- package/dist/redis/index.d.ts +4 -0
- package/dist/redis/index.d.ts.map +1 -0
- package/dist/redis/index.js +55 -0
- package/dist/redis/index.js.map +11 -0
- package/dist/redis/types.d.ts +19 -0
- package/dist/redis/types.d.ts.map +1 -0
- package/dist/server/events.d.ts +5 -0
- package/dist/server/events.d.ts.map +1 -0
- package/dist/server/index.d.ts +7 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +19 -0
- package/dist/server/index.js.map +9 -0
- package/dist/server/poller.d.ts +60 -0
- package/dist/server/poller.d.ts.map +1 -0
- package/dist/server/signing.d.ts +20 -0
- package/dist/server/signing.d.ts.map +1 -0
- package/dist/server/store.d.ts +4 -0
- package/dist/server/store.d.ts.map +1 -0
- package/dist/server/types.d.ts +37 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/types.d.ts +118 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/util.d.ts +10 -0
- package/dist/util.d.ts.map +1 -0
- package/package.json +119 -7
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Hayden Bleasel
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Batchwork
|
|
2
|
+
|
|
3
|
+
A unified **batch API** for AI providers. Submit thousands of LLM requests at roughly half the cost with a single call — `batchwork` handles JSONL, file uploads, inline submission, polling, and result parsing across every major provider.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/batchwork)
|
|
6
|
+
[](https://www.npmjs.com/package/batchwork)
|
|
7
|
+
[](#license)
|
|
8
|
+
[](https://socket.dev/npm/package/batchwork)
|
|
9
|
+
|
|
10
|
+
📖 **Full documentation: [batchwork.dev](https://batchwork.dev)**
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install batchwork
|
|
16
|
+
# plus the provider package(s) you use:
|
|
17
|
+
npm install @ai-sdk/openai @ai-sdk/anthropic
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
`batchwork` depends only on `ai`. The `@ai-sdk/*` provider packages are **optional peer dependencies** — install only the ones you batch with. Requires Node.js 20 or newer.
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
import { batch } from "batchwork";
|
|
26
|
+
import { openai } from "@ai-sdk/openai";
|
|
27
|
+
|
|
28
|
+
const job = await batch({
|
|
29
|
+
model: openai.chat("gpt-5.5"),
|
|
30
|
+
requests: [
|
|
31
|
+
{ customId: "a", prompt: "Summarize: …" },
|
|
32
|
+
{ customId: "b", messages: [{ role: "user", content: "Translate: …" }] },
|
|
33
|
+
],
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const results = await job.wait().then(() => job.collect());
|
|
37
|
+
for (const r of results) {
|
|
38
|
+
console.log(r.customId, r.status, r.text);
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Author requests in the same `generateText` shape you already use, pass the AI SDK models you already use, and get back one normalized result type correlated by `customId`.
|
|
43
|
+
|
|
44
|
+
## Features
|
|
45
|
+
|
|
46
|
+
- **One API, many providers** — OpenAI, Anthropic, Google Gemini, Groq, Mistral, Together AI, and xAI.
|
|
47
|
+
- **AI SDK native** — author requests in the familiar `generateText` shape.
|
|
48
|
+
- **~50% cheaper** — every request runs against the provider's batch window.
|
|
49
|
+
- **Normalized results** — unified status, text, usage, and error types regardless of provider.
|
|
50
|
+
- **Server-ready** — optional layers for managed polling, unified webhooks, and Next.js route handlers.
|
|
51
|
+
- **Durable stores** — drop-in Postgres (`batchwork/postgres`) and Upstash Redis (`batchwork/redis`) adapters for the poller, or bring your own.
|
|
52
|
+
|
|
53
|
+
Guides for models, the job handle, rehydration, the server layer, and Next.js handlers all live at **[batchwork.dev](https://batchwork.dev)**.
|
|
54
|
+
|
|
55
|
+
## License
|
|
56
|
+
|
|
57
|
+
[MIT](https://opensource.org/licenses/MIT) © [Hayden Bleasel](https://github.com/haydenbleasel)
|
package/dist/batch.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { BatchJob } from "./job";
|
|
2
|
+
import type { BatchOptions, BatchRef, BatchResult } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Submit a batch of requests to the model's provider and return a handle.
|
|
5
|
+
*
|
|
6
|
+
* Resolves immediately once the batch is accepted — it does not wait for
|
|
7
|
+
* processing. Use the returned {@link BatchJob} to poll, wait, or stream
|
|
8
|
+
* results.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* const job = await batch({
|
|
12
|
+
* model: openai("gpt-5.5"),
|
|
13
|
+
* requests: [{ customId: "a", prompt: "Say hi" }],
|
|
14
|
+
* });
|
|
15
|
+
* const results = await job.wait().then(() => job.collect());
|
|
16
|
+
*/
|
|
17
|
+
export declare const batch: (options: BatchOptions) => Promise<BatchJob>;
|
|
18
|
+
/**
|
|
19
|
+
* Rehydrate a {@link BatchJob} for an existing batch id (e.g. one persisted
|
|
20
|
+
* after submission). Identify the provider with `provider` or `model`.
|
|
21
|
+
*/
|
|
22
|
+
export declare const getBatch: (ref: BatchRef) => Promise<BatchJob>;
|
|
23
|
+
/** Stream the results of an existing batch by id, without a handle. */
|
|
24
|
+
export declare const getBatchResults: (ref: BatchRef) => AsyncGenerator<BatchResult>;
|
|
25
|
+
/** Request cancellation of an existing batch by id. */
|
|
26
|
+
export declare const cancelBatch: (ref: BatchRef) => Promise<void>;
|
|
27
|
+
//# sourceMappingURL=batch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch.d.ts","sourceRoot":"","sources":["../src/batch.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAGjC,OAAO,KAAK,EACV,YAAY,EAEZ,QAAQ,EACR,WAAW,EAEZ,MAAM,SAAS,CAAC;AAoBjB;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,KAAK,YAAmB,YAAY,KAAG,OAAO,CAAC,QAAQ,CAwBnE,CAAC;AAEF;;;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
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ResolvedModel } from "./model";
|
|
2
|
+
import type { BatchDefaults, BatchRequest, ProviderCredentials } from "./types";
|
|
3
|
+
/** A provider request body derived from a single batch item. */
|
|
4
|
+
export interface BuiltRequest {
|
|
5
|
+
/** The serialized provider request body (becomes the batch line). */
|
|
6
|
+
body: Record<string, unknown>;
|
|
7
|
+
customId: string;
|
|
8
|
+
/** API endpoint path the model targets, e.g. `/v1/chat/completions`. */
|
|
9
|
+
endpoint: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Derive provider request bodies for every batch item by running each through
|
|
13
|
+
* the AI SDK with a capturing `fetch`. This reuses the AI SDK's full message,
|
|
14
|
+
* tool, and multimodal conversion, so the body matches what `generateText`
|
|
15
|
+
* would send — minus the network call.
|
|
16
|
+
*/
|
|
17
|
+
export declare const buildRequestBodies: (resolved: ResolvedModel, requests: readonly BatchRequest[], defaults: BatchDefaults | undefined, credentials: ProviderCredentials) => Promise<BuiltRequest[]>;
|
|
18
|
+
//# sourceMappingURL=body.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"body.d.ts","sourceRoot":"","sources":["../src/body.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAkB,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAIhF,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;AAuID;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,aACnB,aAAa,YACb,SAAS,YAAY,EAAE,YACvB,aAAa,GAAG,SAAS,eACtB,mBAAmB,KAC/B,OAAO,CAAC,YAAY,EAAE,CAsBxB,CAAC"}
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BatchJob,
|
|
3
|
+
BatchworkError,
|
|
4
|
+
MissingDependencyError,
|
|
5
|
+
UnsupportedProviderError,
|
|
6
|
+
getAdapter
|
|
7
|
+
} from "./chunk-kv3847wy.js";
|
|
8
|
+
import {
|
|
9
|
+
__require
|
|
10
|
+
} from "./chunk-v0bahtg2.js";
|
|
11
|
+
|
|
12
|
+
// src/model.ts
|
|
13
|
+
var CAPTURE_API_KEY = "batchwork-capture";
|
|
14
|
+
var PACKAGE_BY_PROVIDER = {
|
|
15
|
+
anthropic: { label: "Anthropic", specifier: "@ai-sdk/anthropic" },
|
|
16
|
+
google: { label: "Google Gemini", specifier: "@ai-sdk/google" },
|
|
17
|
+
groq: { label: "Groq", specifier: "@ai-sdk/groq" },
|
|
18
|
+
mistral: { label: "Mistral", specifier: "@ai-sdk/mistral" },
|
|
19
|
+
openai: { label: "OpenAI", specifier: "@ai-sdk/openai" },
|
|
20
|
+
together: { label: "Together AI", specifier: "@ai-sdk/togetherai" },
|
|
21
|
+
xai: { label: "xAI", specifier: "@ai-sdk/xai" }
|
|
22
|
+
};
|
|
23
|
+
var PROVIDER_BY_FAMILY = {
|
|
24
|
+
anthropic: "anthropic",
|
|
25
|
+
google: "google",
|
|
26
|
+
groq: "groq",
|
|
27
|
+
mistral: "mistral",
|
|
28
|
+
openai: "openai",
|
|
29
|
+
together: "together",
|
|
30
|
+
togetherai: "together",
|
|
31
|
+
xai: "xai"
|
|
32
|
+
};
|
|
33
|
+
var PROVIDER_BY_ALIAS = {
|
|
34
|
+
...PROVIDER_BY_FAMILY,
|
|
35
|
+
gemini: "google"
|
|
36
|
+
};
|
|
37
|
+
var splitOnce = (value, separator) => {
|
|
38
|
+
const index = value.indexOf(separator);
|
|
39
|
+
if (index === -1) {
|
|
40
|
+
return [value, ""];
|
|
41
|
+
}
|
|
42
|
+
return [value.slice(0, index), value.slice(index + separator.length)];
|
|
43
|
+
};
|
|
44
|
+
var openaiKind = (suffix) => {
|
|
45
|
+
if (suffix === "responses") {
|
|
46
|
+
return "responses";
|
|
47
|
+
}
|
|
48
|
+
if (suffix === "completion") {
|
|
49
|
+
return "completion";
|
|
50
|
+
}
|
|
51
|
+
return "chat";
|
|
52
|
+
};
|
|
53
|
+
var resolveModelString = (value) => {
|
|
54
|
+
const [providerId, modelId] = splitOnce(value, "/");
|
|
55
|
+
if (modelId === "") {
|
|
56
|
+
throw new UnsupportedProviderError(value);
|
|
57
|
+
}
|
|
58
|
+
const provider = PROVIDER_BY_ALIAS[providerId];
|
|
59
|
+
if (!provider) {
|
|
60
|
+
throw new UnsupportedProviderError(providerId);
|
|
61
|
+
}
|
|
62
|
+
return { kind: "chat", modelId, provider };
|
|
63
|
+
};
|
|
64
|
+
var resolveModel = (model) => {
|
|
65
|
+
if (typeof model === "string") {
|
|
66
|
+
return resolveModelString(model);
|
|
67
|
+
}
|
|
68
|
+
const [family, suffix] = splitOnce(model.provider, ".");
|
|
69
|
+
const provider = PROVIDER_BY_FAMILY[family];
|
|
70
|
+
if (provider === "openai") {
|
|
71
|
+
return { kind: openaiKind(suffix), modelId: model.modelId, provider };
|
|
72
|
+
}
|
|
73
|
+
if (provider) {
|
|
74
|
+
return { kind: "chat", modelId: model.modelId, provider };
|
|
75
|
+
}
|
|
76
|
+
if (model.modelId.includes("/")) {
|
|
77
|
+
return resolveModelString(model.modelId);
|
|
78
|
+
}
|
|
79
|
+
throw new UnsupportedProviderError(model.provider);
|
|
80
|
+
};
|
|
81
|
+
var importProvider = (provider) => {
|
|
82
|
+
switch (provider) {
|
|
83
|
+
case "anthropic": {
|
|
84
|
+
return import("@ai-sdk/anthropic");
|
|
85
|
+
}
|
|
86
|
+
case "google": {
|
|
87
|
+
return import("@ai-sdk/google");
|
|
88
|
+
}
|
|
89
|
+
case "groq": {
|
|
90
|
+
return import("@ai-sdk/groq");
|
|
91
|
+
}
|
|
92
|
+
case "mistral": {
|
|
93
|
+
return import("@ai-sdk/mistral");
|
|
94
|
+
}
|
|
95
|
+
case "openai": {
|
|
96
|
+
return import("@ai-sdk/openai");
|
|
97
|
+
}
|
|
98
|
+
case "together": {
|
|
99
|
+
return import("@ai-sdk/togetherai");
|
|
100
|
+
}
|
|
101
|
+
case "xai": {
|
|
102
|
+
return import("@ai-sdk/xai");
|
|
103
|
+
}
|
|
104
|
+
default: {
|
|
105
|
+
return Promise.reject(new UnsupportedProviderError(provider));
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
var loadProvider = async (provider, load = importProvider) => {
|
|
110
|
+
try {
|
|
111
|
+
return await load(provider);
|
|
112
|
+
} catch (error) {
|
|
113
|
+
if (error instanceof UnsupportedProviderError) {
|
|
114
|
+
throw error;
|
|
115
|
+
}
|
|
116
|
+
const { specifier, label } = PACKAGE_BY_PROVIDER[provider];
|
|
117
|
+
throw new MissingDependencyError(specifier, label);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
var createCaptureModel = async (resolved, credentials, fetchImpl) => {
|
|
121
|
+
const settings = {
|
|
122
|
+
apiKey: credentials.apiKey ?? CAPTURE_API_KEY,
|
|
123
|
+
baseURL: credentials.baseURL,
|
|
124
|
+
fetch: fetchImpl,
|
|
125
|
+
headers: credentials.headers
|
|
126
|
+
};
|
|
127
|
+
switch (resolved.provider) {
|
|
128
|
+
case "openai": {
|
|
129
|
+
const { createOpenAI } = await loadProvider("openai");
|
|
130
|
+
const provider = createOpenAI(settings);
|
|
131
|
+
if (resolved.kind === "responses") {
|
|
132
|
+
return provider.responses(resolved.modelId);
|
|
133
|
+
}
|
|
134
|
+
if (resolved.kind === "completion") {
|
|
135
|
+
return provider.completion(resolved.modelId);
|
|
136
|
+
}
|
|
137
|
+
return provider.chat(resolved.modelId);
|
|
138
|
+
}
|
|
139
|
+
case "anthropic": {
|
|
140
|
+
const { createAnthropic } = await loadProvider("anthropic");
|
|
141
|
+
return createAnthropic(settings).messages(resolved.modelId);
|
|
142
|
+
}
|
|
143
|
+
case "groq": {
|
|
144
|
+
const { createGroq } = await loadProvider("groq");
|
|
145
|
+
return createGroq(settings).languageModel(resolved.modelId);
|
|
146
|
+
}
|
|
147
|
+
case "mistral": {
|
|
148
|
+
const { createMistral } = await loadProvider("mistral");
|
|
149
|
+
return createMistral(settings).languageModel(resolved.modelId);
|
|
150
|
+
}
|
|
151
|
+
case "google": {
|
|
152
|
+
const { createGoogleGenerativeAI } = await loadProvider("google");
|
|
153
|
+
return createGoogleGenerativeAI(settings).languageModel(resolved.modelId);
|
|
154
|
+
}
|
|
155
|
+
case "xai": {
|
|
156
|
+
const { createXai } = await loadProvider("xai");
|
|
157
|
+
return createXai(settings).languageModel(resolved.modelId);
|
|
158
|
+
}
|
|
159
|
+
case "together": {
|
|
160
|
+
const { createTogetherAI } = await loadProvider("together");
|
|
161
|
+
return createTogetherAI(settings).languageModel(resolved.modelId);
|
|
162
|
+
}
|
|
163
|
+
default: {
|
|
164
|
+
throw new UnsupportedProviderError(resolved.provider);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
// src/body.ts
|
|
170
|
+
import { generateText } from "ai";
|
|
171
|
+
var MAX_CAUSE_DEPTH = 10;
|
|
172
|
+
|
|
173
|
+
class CaptureSignalError extends Error {
|
|
174
|
+
url;
|
|
175
|
+
rawBody;
|
|
176
|
+
constructor(url, rawBody) {
|
|
177
|
+
super("batchwork:capture");
|
|
178
|
+
this.name = "CaptureSignalError";
|
|
179
|
+
this.url = url;
|
|
180
|
+
this.rawBody = rawBody;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
var resolveUrl = (input) => {
|
|
184
|
+
if (typeof input === "string") {
|
|
185
|
+
return input;
|
|
186
|
+
}
|
|
187
|
+
if (input instanceof URL) {
|
|
188
|
+
return input.toString();
|
|
189
|
+
}
|
|
190
|
+
return input.url;
|
|
191
|
+
};
|
|
192
|
+
var extractBody = (init) => {
|
|
193
|
+
const body = init?.body;
|
|
194
|
+
if (typeof body === "string") {
|
|
195
|
+
return body;
|
|
196
|
+
}
|
|
197
|
+
if (body instanceof Uint8Array) {
|
|
198
|
+
return new TextDecoder().decode(body);
|
|
199
|
+
}
|
|
200
|
+
throw new BatchworkError("batchwork: unable to read the provider request body during capture.");
|
|
201
|
+
};
|
|
202
|
+
var captureFetch = (input, init) => Promise.reject(new CaptureSignalError(resolveUrl(input), extractBody(init)));
|
|
203
|
+
var findCapture = (error) => {
|
|
204
|
+
let current = error;
|
|
205
|
+
let depth = 0;
|
|
206
|
+
while (current && depth < MAX_CAUSE_DEPTH) {
|
|
207
|
+
if (current instanceof CaptureSignalError) {
|
|
208
|
+
return current;
|
|
209
|
+
}
|
|
210
|
+
current = current.cause;
|
|
211
|
+
depth += 1;
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
var endpointFromUrl = (url) => {
|
|
215
|
+
try {
|
|
216
|
+
return new URL(url).pathname;
|
|
217
|
+
} catch {
|
|
218
|
+
return url;
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
var mergeDefaults = (request, defaults) => {
|
|
222
|
+
if (!defaults) {
|
|
223
|
+
return request;
|
|
224
|
+
}
|
|
225
|
+
return { ...defaults, ...request };
|
|
226
|
+
};
|
|
227
|
+
var toGenerateInput = (model, request) => ({
|
|
228
|
+
frequencyPenalty: request.frequencyPenalty,
|
|
229
|
+
maxOutputTokens: request.maxOutputTokens,
|
|
230
|
+
maxRetries: 0,
|
|
231
|
+
messages: request.messages,
|
|
232
|
+
model,
|
|
233
|
+
presencePenalty: request.presencePenalty,
|
|
234
|
+
prompt: request.prompt,
|
|
235
|
+
providerOptions: request.providerOptions,
|
|
236
|
+
seed: request.seed,
|
|
237
|
+
stopSequences: request.stopSequences,
|
|
238
|
+
system: request.system,
|
|
239
|
+
temperature: request.temperature,
|
|
240
|
+
toolChoice: request.toolChoice,
|
|
241
|
+
tools: request.tools,
|
|
242
|
+
topK: request.topK,
|
|
243
|
+
topP: request.topP
|
|
244
|
+
});
|
|
245
|
+
var captureOne = async (model, request, customId) => {
|
|
246
|
+
try {
|
|
247
|
+
await generateText(toGenerateInput(model, request));
|
|
248
|
+
} catch (error) {
|
|
249
|
+
const capture = findCapture(error);
|
|
250
|
+
if (capture) {
|
|
251
|
+
return {
|
|
252
|
+
body: JSON.parse(capture.rawBody),
|
|
253
|
+
customId,
|
|
254
|
+
endpoint: endpointFromUrl(capture.url)
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
throw error;
|
|
258
|
+
}
|
|
259
|
+
throw new BatchworkError("batchwork: the request was not intercepted while building the batch body.");
|
|
260
|
+
};
|
|
261
|
+
var buildRequestBodies = async (resolved, requests, defaults, credentials) => {
|
|
262
|
+
const model = await createCaptureModel(resolved, credentials, captureFetch);
|
|
263
|
+
const seen = new Set;
|
|
264
|
+
const items = requests.map((request, index) => {
|
|
265
|
+
const customId = request.customId ?? `request-${index}`;
|
|
266
|
+
if (seen.has(customId)) {
|
|
267
|
+
throw new BatchworkError(`batchwork: duplicate customId "${customId}". customId values must be unique within a batch.`);
|
|
268
|
+
}
|
|
269
|
+
seen.add(customId);
|
|
270
|
+
return { customId, request };
|
|
271
|
+
});
|
|
272
|
+
return await Promise.all(items.map((item) => captureOne(model, mergeDefaults(item.request, defaults), item.customId)));
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
// src/batch.ts
|
|
276
|
+
var pickCredentials = (source) => ({
|
|
277
|
+
apiKey: source.apiKey,
|
|
278
|
+
baseURL: source.baseURL,
|
|
279
|
+
headers: source.headers
|
|
280
|
+
});
|
|
281
|
+
var providerFromRef = (ref) => {
|
|
282
|
+
if (ref.provider) {
|
|
283
|
+
return ref.provider;
|
|
284
|
+
}
|
|
285
|
+
if (ref.model !== undefined) {
|
|
286
|
+
return resolveModel(ref.model).provider;
|
|
287
|
+
}
|
|
288
|
+
throw new BatchworkError("batchwork: provide `provider` or `model` to identify the batch.");
|
|
289
|
+
};
|
|
290
|
+
var batch = async (options) => {
|
|
291
|
+
if (options.requests.length === 0) {
|
|
292
|
+
throw new BatchworkError("batchwork: `requests` must not be empty.");
|
|
293
|
+
}
|
|
294
|
+
const resolved = resolveModel(options.model);
|
|
295
|
+
const credentials = pickCredentials(options);
|
|
296
|
+
const adapter = getAdapter(resolved.provider);
|
|
297
|
+
const built = await buildRequestBodies(resolved, options.requests, options.defaults, credentials);
|
|
298
|
+
const snapshot = await adapter.submit({
|
|
299
|
+
built,
|
|
300
|
+
credentials,
|
|
301
|
+
endpoint: built[0]?.endpoint ?? "",
|
|
302
|
+
metadata: options.metadata,
|
|
303
|
+
modelId: resolved.modelId
|
|
304
|
+
});
|
|
305
|
+
return new BatchJob(adapter, credentials, snapshot);
|
|
306
|
+
};
|
|
307
|
+
var getBatch = async (ref) => {
|
|
308
|
+
const adapter = getAdapter(providerFromRef(ref));
|
|
309
|
+
const credentials = pickCredentials(ref);
|
|
310
|
+
const snapshot = await adapter.retrieve(ref.id, credentials);
|
|
311
|
+
return new BatchJob(adapter, credentials, snapshot);
|
|
312
|
+
};
|
|
313
|
+
var getBatchResults = (ref) => {
|
|
314
|
+
const adapter = getAdapter(providerFromRef(ref));
|
|
315
|
+
return adapter.results(ref.id, pickCredentials(ref));
|
|
316
|
+
};
|
|
317
|
+
var cancelBatch = async (ref) => {
|
|
318
|
+
const adapter = getAdapter(providerFromRef(ref));
|
|
319
|
+
await adapter.cancel(ref.id, pickCredentials(ref));
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
export { resolveModel, batch, getBatch, getBatchResults, cancelBatch };
|
|
323
|
+
|
|
324
|
+
//# debugId=A3005BE7078C61CE64756E2164756E21
|
|
325
|
+
//# sourceMappingURL=chunk-ab2d71gk.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 { createCaptureModel } from \"./model\";\nimport type { CapturingFetch, ResolvedModel } from \"./model\";\nimport type { BatchDefaults, BatchRequest, ProviderCredentials } 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): Promise<BuiltRequest[]> => {\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 Promise.all(\n items.map((item) =>\n captureOne(model, mergeDefaults(item.request, defaults), item.customId)\n )\n );\n};\n",
|
|
7
|
+
"import { buildRequestBodies } from \"./body\";\nimport { BatchworkError } from \"./errors\";\nimport { BatchJob } from \"./job\";\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 adapter = getAdapter(resolved.provider);\n\n const built = await buildRequestBodies(\n resolved,\n options.requests,\n options.defaults,\n credentials\n );\n const snapshot = await adapter.submit({\n built,\n credentials,\n endpoint: built[0]?.endpoint ?? \"\",\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": "A3005BE7078C61CE64756E2164756E21",
|
|
11
|
+
"names": []
|
|
12
|
+
}
|