@probeo/anymodel 0.3.0 → 0.4.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 +5 -8
- package/dist/cli.cjs +1016 -110
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.d.ts +0 -2
- package/dist/cli.js +2972 -30
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +1037 -112
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +106 -22
- package/dist/index.d.ts +632 -14
- package/dist/index.js +2969 -15
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/batch/index.d.ts +0 -4
- package/dist/batch/index.d.ts.map +0 -1
- package/dist/batch/index.js +0 -3
- package/dist/batch/index.js.map +0 -1
- package/dist/batch/manager.d.ts +0 -72
- package/dist/batch/manager.d.ts.map +0 -1
- package/dist/batch/manager.js +0 -328
- package/dist/batch/manager.js.map +0 -1
- package/dist/batch/store.d.ts +0 -54
- package/dist/batch/store.d.ts.map +0 -1
- package/dist/batch/store.js +0 -109
- package/dist/batch/store.js.map +0 -1
- package/dist/cli.d.ts.map +0 -1
- package/dist/client.d.ts +0 -42
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js +0 -181
- package/dist/client.js.map +0 -1
- package/dist/config.d.ts +0 -6
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -120
- package/dist/config.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/providers/adapter.d.ts +0 -33
- package/dist/providers/adapter.d.ts.map +0 -1
- package/dist/providers/adapter.js +0 -2
- package/dist/providers/adapter.js.map +0 -1
- package/dist/providers/anthropic-batch.d.ts +0 -3
- package/dist/providers/anthropic-batch.d.ts.map +0 -1
- package/dist/providers/anthropic-batch.js +0 -228
- package/dist/providers/anthropic-batch.js.map +0 -1
- package/dist/providers/anthropic.d.ts +0 -3
- package/dist/providers/anthropic.d.ts.map +0 -1
- package/dist/providers/anthropic.js +0 -358
- package/dist/providers/anthropic.js.map +0 -1
- package/dist/providers/custom.d.ts +0 -8
- package/dist/providers/custom.d.ts.map +0 -1
- package/dist/providers/custom.js +0 -61
- package/dist/providers/custom.js.map +0 -1
- package/dist/providers/google.d.ts +0 -3
- package/dist/providers/google.d.ts.map +0 -1
- package/dist/providers/google.js +0 -331
- package/dist/providers/google.js.map +0 -1
- package/dist/providers/index.d.ts +0 -6
- package/dist/providers/index.d.ts.map +0 -1
- package/dist/providers/index.js +0 -5
- package/dist/providers/index.js.map +0 -1
- package/dist/providers/openai-batch.d.ts +0 -3
- package/dist/providers/openai-batch.d.ts.map +0 -1
- package/dist/providers/openai-batch.js +0 -208
- package/dist/providers/openai-batch.js.map +0 -1
- package/dist/providers/openai.d.ts +0 -3
- package/dist/providers/openai.d.ts.map +0 -1
- package/dist/providers/openai.js +0 -221
- package/dist/providers/openai.js.map +0 -1
- package/dist/providers/registry.d.ts +0 -10
- package/dist/providers/registry.d.ts.map +0 -1
- package/dist/providers/registry.js +0 -27
- package/dist/providers/registry.js.map +0 -1
- package/dist/router.d.ts +0 -29
- package/dist/router.d.ts.map +0 -1
- package/dist/router.js +0 -212
- package/dist/router.js.map +0 -1
- package/dist/server.d.ts +0 -10
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js +0 -149
- package/dist/server.js.map +0 -1
- package/dist/types.d.ts +0 -283
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -21
- package/dist/types.js.map +0 -1
- package/dist/utils/fs-io.d.ts +0 -40
- package/dist/utils/fs-io.d.ts.map +0 -1
- package/dist/utils/fs-io.js +0 -203
- package/dist/utils/fs-io.js.map +0 -1
- package/dist/utils/generation-stats.d.ts +0 -25
- package/dist/utils/generation-stats.d.ts.map +0 -1
- package/dist/utils/generation-stats.js +0 -46
- package/dist/utils/generation-stats.js.map +0 -1
- package/dist/utils/id.d.ts +0 -2
- package/dist/utils/id.d.ts.map +0 -1
- package/dist/utils/id.js +0 -6
- package/dist/utils/id.js.map +0 -1
- package/dist/utils/model-parser.d.ts +0 -6
- package/dist/utils/model-parser.d.ts.map +0 -1
- package/dist/utils/model-parser.js +0 -21
- package/dist/utils/model-parser.js.map +0 -1
- package/dist/utils/rate-limiter.d.ts +0 -36
- package/dist/utils/rate-limiter.d.ts.map +0 -1
- package/dist/utils/rate-limiter.js +0 -80
- package/dist/utils/rate-limiter.js.map +0 -1
- package/dist/utils/retry.d.ts +0 -7
- package/dist/utils/retry.d.ts.map +0 -1
- package/dist/utils/retry.js +0 -54
- package/dist/utils/retry.js.map +0 -1
- package/dist/utils/transforms.d.ts +0 -7
- package/dist/utils/transforms.d.ts.map +0 -1
- package/dist/utils/transforms.js +0 -66
- package/dist/utils/transforms.js.map +0 -1
- package/dist/utils/validate.d.ts +0 -3
- package/dist/utils/validate.d.ts.map +0 -1
- package/dist/utils/validate.js +0 -31
- package/dist/utils/validate.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/index.ts
|
|
@@ -25,9 +35,20 @@ __export(src_exports, {
|
|
|
25
35
|
BatchManager: () => BatchManager,
|
|
26
36
|
BatchStore: () => BatchStore,
|
|
27
37
|
GenerationStatsStore: () => GenerationStatsStore,
|
|
38
|
+
appendFileQueued: () => appendFileQueued,
|
|
39
|
+
configureFsIO: () => configureFsIO,
|
|
40
|
+
createAnthropicBatchAdapter: () => createAnthropicBatchAdapter,
|
|
28
41
|
createAnyModelServer: () => createAnyModelServer,
|
|
42
|
+
createOpenAIBatchAdapter: () => createOpenAIBatchAdapter,
|
|
43
|
+
ensureDir: () => ensureDir,
|
|
44
|
+
getFsQueueStatus: () => getFsQueueStatus,
|
|
45
|
+
joinPath: () => joinPath,
|
|
46
|
+
readFileQueued: () => readFileQueued,
|
|
29
47
|
resolveConfig: () => resolveConfig,
|
|
30
|
-
startServer: () => startServer
|
|
48
|
+
startServer: () => startServer,
|
|
49
|
+
waitForFsQueuesIdle: () => waitForFsQueuesIdle,
|
|
50
|
+
writeFileFlushedQueued: () => writeFileFlushedQueued,
|
|
51
|
+
writeFileQueued: () => writeFileQueued
|
|
31
52
|
});
|
|
32
53
|
module.exports = __toCommonJS(src_exports);
|
|
33
54
|
|
|
@@ -175,7 +196,7 @@ async function withRetry(fn, options = {}) {
|
|
|
175
196
|
throw error;
|
|
176
197
|
}
|
|
177
198
|
const delay = computeDelay(attempt, opts, error);
|
|
178
|
-
await new Promise((
|
|
199
|
+
await new Promise((resolve2) => setTimeout(resolve2, delay));
|
|
179
200
|
}
|
|
180
201
|
}
|
|
181
202
|
throw lastError;
|
|
@@ -534,8 +555,8 @@ var SUPPORTED_PARAMS = /* @__PURE__ */ new Set([
|
|
|
534
555
|
]);
|
|
535
556
|
function createOpenAIAdapter(apiKey, baseURL) {
|
|
536
557
|
const base = baseURL || OPENAI_API_BASE;
|
|
537
|
-
async function makeRequest(
|
|
538
|
-
const res = await fetch(`${base}${
|
|
558
|
+
async function makeRequest(path2, body, method = "POST") {
|
|
559
|
+
const res = await fetch(`${base}${path2}`, {
|
|
539
560
|
method,
|
|
540
561
|
headers: {
|
|
541
562
|
"Content-Type": "application/json",
|
|
@@ -650,7 +671,19 @@ function createOpenAIAdapter(apiKey, baseURL) {
|
|
|
650
671
|
async listModels() {
|
|
651
672
|
const res = await makeRequest("/models", void 0, "GET");
|
|
652
673
|
const data = await res.json();
|
|
653
|
-
return (data.data || []).filter((m) =>
|
|
674
|
+
return (data.data || []).filter((m) => {
|
|
675
|
+
const id = m.id;
|
|
676
|
+
if (id.includes("embedding")) return false;
|
|
677
|
+
if (id.includes("whisper")) return false;
|
|
678
|
+
if (id.includes("tts")) return false;
|
|
679
|
+
if (id.includes("dall-e")) return false;
|
|
680
|
+
if (id.includes("davinci")) return false;
|
|
681
|
+
if (id.includes("babbage")) return false;
|
|
682
|
+
if (id.includes("moderation")) return false;
|
|
683
|
+
if (id.includes("realtime")) return false;
|
|
684
|
+
if (id.startsWith("ft:")) return false;
|
|
685
|
+
return id.startsWith("gpt-") || id.startsWith("o1") || id.startsWith("o3") || id.startsWith("o4") || id.startsWith("chatgpt-");
|
|
686
|
+
}).map((m) => ({
|
|
654
687
|
id: `openai/${m.id}`,
|
|
655
688
|
name: m.id,
|
|
656
689
|
created: m.created,
|
|
@@ -674,6 +707,9 @@ function createOpenAIAdapter(apiKey, baseURL) {
|
|
|
674
707
|
supportsParameter(param) {
|
|
675
708
|
return SUPPORTED_PARAMS.has(param);
|
|
676
709
|
},
|
|
710
|
+
supportsBatch() {
|
|
711
|
+
return true;
|
|
712
|
+
},
|
|
677
713
|
async sendRequest(request) {
|
|
678
714
|
const body = buildRequestBody(request);
|
|
679
715
|
const res = await makeRequest("/chat/completions", body);
|
|
@@ -717,14 +753,19 @@ var SUPPORTED_PARAMS2 = /* @__PURE__ */ new Set([
|
|
|
717
753
|
"response_format"
|
|
718
754
|
]);
|
|
719
755
|
var FALLBACK_MODELS = [
|
|
720
|
-
|
|
756
|
+
// Claude 4.6
|
|
757
|
+
{ id: "anthropic/claude-opus-4-6", name: "Claude Opus 4.6", created: 0, description: "Most capable model", context_length: 2e5, pricing: { prompt: "0.000015", completion: "0.000075" }, architecture: { modality: "text+image->text", input_modalities: ["text", "image"], output_modalities: ["text"], tokenizer: "claude" }, top_provider: { context_length: 2e5, max_completion_tokens: 32768, is_moderated: false }, supported_parameters: Array.from(SUPPORTED_PARAMS2) },
|
|
721
758
|
{ id: "anthropic/claude-sonnet-4-6", name: "Claude Sonnet 4.6", created: 0, description: "Best balance of speed and capability", context_length: 2e5, pricing: { prompt: "0.000003", completion: "0.000015" }, architecture: { modality: "text+image->text", input_modalities: ["text", "image"], output_modalities: ["text"], tokenizer: "claude" }, top_provider: { context_length: 2e5, max_completion_tokens: 16384, is_moderated: false }, supported_parameters: Array.from(SUPPORTED_PARAMS2) },
|
|
759
|
+
// Claude 4.5
|
|
722
760
|
{ id: "anthropic/claude-sonnet-4-5-20251022", name: "Claude Sonnet 4.5", created: 0, description: "Previous generation balanced model", context_length: 2e5, pricing: { prompt: "0.000003", completion: "0.000015" }, architecture: { modality: "text+image->text", input_modalities: ["text", "image"], output_modalities: ["text"], tokenizer: "claude" }, top_provider: { context_length: 2e5, max_completion_tokens: 16384, is_moderated: false }, supported_parameters: Array.from(SUPPORTED_PARAMS2) },
|
|
723
|
-
{ id: "anthropic/claude-haiku-4-5", name: "Claude Haiku 4.5", created: 0, description: "
|
|
761
|
+
{ id: "anthropic/claude-haiku-4-5", name: "Claude Haiku 4.5", created: 0, description: "Fast and compact", context_length: 2e5, pricing: { prompt: "0.000001", completion: "0.000005" }, architecture: { modality: "text+image->text", input_modalities: ["text", "image"], output_modalities: ["text"], tokenizer: "claude" }, top_provider: { context_length: 2e5, max_completion_tokens: 8192, is_moderated: false }, supported_parameters: Array.from(SUPPORTED_PARAMS2) },
|
|
762
|
+
// Claude 3.5
|
|
763
|
+
{ id: "anthropic/claude-3-5-sonnet-20241022", name: "Claude 3.5 Sonnet", created: 0, description: "Legacy balanced model", context_length: 2e5, pricing: { prompt: "0.000003", completion: "0.000015" }, architecture: { modality: "text+image->text", input_modalities: ["text", "image"], output_modalities: ["text"], tokenizer: "claude" }, top_provider: { context_length: 2e5, max_completion_tokens: 8192, is_moderated: false }, supported_parameters: Array.from(SUPPORTED_PARAMS2) },
|
|
764
|
+
{ id: "anthropic/claude-3-5-haiku-20241022", name: "Claude 3.5 Haiku", created: 0, description: "Legacy fast model", context_length: 2e5, pricing: { prompt: "0.0000008", completion: "0.000004" }, architecture: { modality: "text+image->text", input_modalities: ["text", "image"], output_modalities: ["text"], tokenizer: "claude" }, top_provider: { context_length: 2e5, max_completion_tokens: 8192, is_moderated: false }, supported_parameters: Array.from(SUPPORTED_PARAMS2) }
|
|
724
765
|
];
|
|
725
766
|
function createAnthropicAdapter(apiKey) {
|
|
726
|
-
async function makeRequest(
|
|
727
|
-
const res = await fetch(`${ANTHROPIC_API_BASE}${
|
|
767
|
+
async function makeRequest(path2, body, stream = false) {
|
|
768
|
+
const res = await fetch(`${ANTHROPIC_API_BASE}${path2}`, {
|
|
728
769
|
method: "POST",
|
|
729
770
|
headers: {
|
|
730
771
|
"Content-Type": "application/json",
|
|
@@ -1018,6 +1059,9 @@ ${body.system}` : jsonInstruction;
|
|
|
1018
1059
|
supportsParameter(param) {
|
|
1019
1060
|
return SUPPORTED_PARAMS2.has(param);
|
|
1020
1061
|
},
|
|
1062
|
+
supportsBatch() {
|
|
1063
|
+
return true;
|
|
1064
|
+
},
|
|
1021
1065
|
async sendRequest(request) {
|
|
1022
1066
|
const body = translateRequest(request);
|
|
1023
1067
|
const res = await makeRequest("/messages", body);
|
|
@@ -1052,8 +1096,15 @@ var SUPPORTED_PARAMS3 = /* @__PURE__ */ new Set([
|
|
|
1052
1096
|
"response_format"
|
|
1053
1097
|
]);
|
|
1054
1098
|
var FALLBACK_MODELS2 = [
|
|
1099
|
+
// Gemini 2.5
|
|
1055
1100
|
{ id: "google/gemini-2.5-pro", name: "Gemini 2.5 Pro", created: 0, description: "Most capable Gemini model", context_length: 1048576, pricing: { prompt: "0.00000125", completion: "0.000005" }, architecture: { modality: "text+image->text", input_modalities: ["text", "image", "video", "audio"], output_modalities: ["text"], tokenizer: "gemini" }, top_provider: { context_length: 1048576, max_completion_tokens: 65536, is_moderated: false }, supported_parameters: Array.from(SUPPORTED_PARAMS3) },
|
|
1056
|
-
{ id: "google/gemini-2.5-flash", name: "Gemini 2.5 Flash", created: 0, description: "Fast and efficient", context_length: 1048576, pricing: { prompt: "0.00000015", completion: "0.0000006" }, architecture: { modality: "text+image->text", input_modalities: ["text", "image", "video", "audio"], output_modalities: ["text"], tokenizer: "gemini" }, top_provider: { context_length: 1048576, max_completion_tokens: 65536, is_moderated: false }, supported_parameters: Array.from(SUPPORTED_PARAMS3) }
|
|
1101
|
+
{ id: "google/gemini-2.5-flash", name: "Gemini 2.5 Flash", created: 0, description: "Fast and efficient", context_length: 1048576, pricing: { prompt: "0.00000015", completion: "0.0000006" }, architecture: { modality: "text+image->text", input_modalities: ["text", "image", "video", "audio"], output_modalities: ["text"], tokenizer: "gemini" }, top_provider: { context_length: 1048576, max_completion_tokens: 65536, is_moderated: false }, supported_parameters: Array.from(SUPPORTED_PARAMS3) },
|
|
1102
|
+
// Gemini 2.0
|
|
1103
|
+
{ id: "google/gemini-2.0-flash", name: "Gemini 2.0 Flash", created: 0, description: "Fast multimodal model", context_length: 1048576, pricing: { prompt: "0.0000001", completion: "0.0000004" }, architecture: { modality: "text+image->text", input_modalities: ["text", "image", "video", "audio"], output_modalities: ["text"], tokenizer: "gemini" }, top_provider: { context_length: 1048576, max_completion_tokens: 65536, is_moderated: false }, supported_parameters: Array.from(SUPPORTED_PARAMS3) },
|
|
1104
|
+
{ id: "google/gemini-2.0-flash-lite", name: "Gemini 2.0 Flash Lite", created: 0, description: "Lightweight and fast", context_length: 1048576, pricing: { prompt: "0.00000005", completion: "0.0000002" }, architecture: { modality: "text+image->text", input_modalities: ["text", "image", "video", "audio"], output_modalities: ["text"], tokenizer: "gemini" }, top_provider: { context_length: 1048576, max_completion_tokens: 65536, is_moderated: false }, supported_parameters: Array.from(SUPPORTED_PARAMS3) },
|
|
1105
|
+
// Gemini 1.5
|
|
1106
|
+
{ id: "google/gemini-1.5-pro", name: "Gemini 1.5 Pro", created: 0, description: "Previous generation pro model", context_length: 2097152, pricing: { prompt: "0.00000125", completion: "0.000005" }, architecture: { modality: "text+image->text", input_modalities: ["text", "image", "video", "audio"], output_modalities: ["text"], tokenizer: "gemini" }, top_provider: { context_length: 2097152, max_completion_tokens: 8192, is_moderated: false }, supported_parameters: Array.from(SUPPORTED_PARAMS3) },
|
|
1107
|
+
{ id: "google/gemini-1.5-flash", name: "Gemini 1.5 Flash", created: 0, description: "Previous generation flash model", context_length: 1048576, pricing: { prompt: "0.000000075", completion: "0.0000003" }, architecture: { modality: "text+image->text", input_modalities: ["text", "image", "video", "audio"], output_modalities: ["text"], tokenizer: "gemini" }, top_provider: { context_length: 1048576, max_completion_tokens: 8192, is_moderated: false }, supported_parameters: Array.from(SUPPORTED_PARAMS3) }
|
|
1057
1108
|
];
|
|
1058
1109
|
function createGoogleAdapter(apiKey) {
|
|
1059
1110
|
function getModelEndpoint(model, stream) {
|
|
@@ -1290,6 +1341,9 @@ function createGoogleAdapter(apiKey) {
|
|
|
1290
1341
|
supportsParameter(param) {
|
|
1291
1342
|
return SUPPORTED_PARAMS3.has(param);
|
|
1292
1343
|
},
|
|
1344
|
+
supportsBatch() {
|
|
1345
|
+
return false;
|
|
1346
|
+
},
|
|
1293
1347
|
async sendRequest(request) {
|
|
1294
1348
|
const body = translateRequest(request);
|
|
1295
1349
|
const url = getModelEndpoint(request.model, false);
|
|
@@ -1342,12 +1396,199 @@ function createGoogleAdapter(apiKey) {
|
|
|
1342
1396
|
return adapter;
|
|
1343
1397
|
}
|
|
1344
1398
|
|
|
1399
|
+
// src/providers/perplexity.ts
|
|
1400
|
+
var PERPLEXITY_API_BASE = "https://api.perplexity.ai";
|
|
1401
|
+
var SUPPORTED_PARAMS4 = /* @__PURE__ */ new Set([
|
|
1402
|
+
"temperature",
|
|
1403
|
+
"max_tokens",
|
|
1404
|
+
"top_p",
|
|
1405
|
+
"frequency_penalty",
|
|
1406
|
+
"presence_penalty",
|
|
1407
|
+
"stream",
|
|
1408
|
+
"stop",
|
|
1409
|
+
"response_format",
|
|
1410
|
+
"tools",
|
|
1411
|
+
"tool_choice"
|
|
1412
|
+
]);
|
|
1413
|
+
var MODELS = [
|
|
1414
|
+
{ id: "sonar", name: "Sonar", context: 128e3, maxOutput: 4096, modality: "text->text", inputModalities: ["text"] },
|
|
1415
|
+
{ id: "sonar-pro", name: "Sonar Pro", context: 2e5, maxOutput: 8192, modality: "text->text", inputModalities: ["text"] },
|
|
1416
|
+
{ id: "sonar-reasoning", name: "Sonar Reasoning", context: 128e3, maxOutput: 8192, modality: "text->text", inputModalities: ["text"] },
|
|
1417
|
+
{ id: "sonar-reasoning-pro", name: "Sonar Reasoning Pro", context: 128e3, maxOutput: 16384, modality: "text->text", inputModalities: ["text"] },
|
|
1418
|
+
{ id: "sonar-deep-research", name: "Sonar Deep Research", context: 128e3, maxOutput: 16384, modality: "text->text", inputModalities: ["text"] },
|
|
1419
|
+
{ id: "r1-1776", name: "R1 1776", context: 128e3, maxOutput: 16384, modality: "text->text", inputModalities: ["text"] }
|
|
1420
|
+
];
|
|
1421
|
+
function createPerplexityAdapter(apiKey) {
|
|
1422
|
+
async function makeRequest(path2, body, method = "POST") {
|
|
1423
|
+
const res = await fetch(`${PERPLEXITY_API_BASE}${path2}`, {
|
|
1424
|
+
method,
|
|
1425
|
+
headers: {
|
|
1426
|
+
"Content-Type": "application/json",
|
|
1427
|
+
"Authorization": `Bearer ${apiKey}`
|
|
1428
|
+
},
|
|
1429
|
+
body: body ? JSON.stringify(body) : void 0
|
|
1430
|
+
});
|
|
1431
|
+
if (!res.ok) {
|
|
1432
|
+
let errorBody;
|
|
1433
|
+
try {
|
|
1434
|
+
errorBody = await res.json();
|
|
1435
|
+
} catch {
|
|
1436
|
+
errorBody = { message: res.statusText };
|
|
1437
|
+
}
|
|
1438
|
+
const msg = errorBody?.error?.message || errorBody?.message || res.statusText;
|
|
1439
|
+
throw new AnyModelError(mapErrorCode(res.status), msg, {
|
|
1440
|
+
provider_name: "perplexity",
|
|
1441
|
+
raw: errorBody
|
|
1442
|
+
});
|
|
1443
|
+
}
|
|
1444
|
+
return res;
|
|
1445
|
+
}
|
|
1446
|
+
function mapErrorCode(status) {
|
|
1447
|
+
if (status === 401 || status === 403) return 401;
|
|
1448
|
+
if (status === 429) return 429;
|
|
1449
|
+
if (status === 400 || status === 422) return 400;
|
|
1450
|
+
if (status >= 500) return 502;
|
|
1451
|
+
return status;
|
|
1452
|
+
}
|
|
1453
|
+
function rePrefixId(id) {
|
|
1454
|
+
if (id && id.startsWith("chatcmpl-")) {
|
|
1455
|
+
return `gen-${id.substring(9)}`;
|
|
1456
|
+
}
|
|
1457
|
+
return id.startsWith("gen-") ? id : `gen-${id}`;
|
|
1458
|
+
}
|
|
1459
|
+
function buildRequestBody(request) {
|
|
1460
|
+
const body = {
|
|
1461
|
+
model: request.model,
|
|
1462
|
+
messages: request.messages
|
|
1463
|
+
};
|
|
1464
|
+
if (request.temperature !== void 0) body.temperature = request.temperature;
|
|
1465
|
+
if (request.max_tokens !== void 0) body.max_tokens = request.max_tokens;
|
|
1466
|
+
if (request.top_p !== void 0) body.top_p = request.top_p;
|
|
1467
|
+
if (request.frequency_penalty !== void 0) body.frequency_penalty = request.frequency_penalty;
|
|
1468
|
+
if (request.presence_penalty !== void 0) body.presence_penalty = request.presence_penalty;
|
|
1469
|
+
if (request.stop !== void 0) body.stop = request.stop;
|
|
1470
|
+
if (request.stream !== void 0) body.stream = request.stream;
|
|
1471
|
+
if (request.response_format !== void 0) body.response_format = request.response_format;
|
|
1472
|
+
if (request.tools !== void 0) body.tools = request.tools;
|
|
1473
|
+
if (request.tool_choice !== void 0) body.tool_choice = request.tool_choice;
|
|
1474
|
+
return body;
|
|
1475
|
+
}
|
|
1476
|
+
const adapter = {
|
|
1477
|
+
name: "perplexity",
|
|
1478
|
+
translateRequest(request) {
|
|
1479
|
+
return buildRequestBody(request);
|
|
1480
|
+
},
|
|
1481
|
+
translateResponse(response) {
|
|
1482
|
+
const r = response;
|
|
1483
|
+
const result = {
|
|
1484
|
+
id: rePrefixId(r.id),
|
|
1485
|
+
object: "chat.completion",
|
|
1486
|
+
created: r.created,
|
|
1487
|
+
model: `perplexity/${r.model}`,
|
|
1488
|
+
choices: r.choices,
|
|
1489
|
+
usage: r.usage
|
|
1490
|
+
};
|
|
1491
|
+
if (r.citations && result.choices?.[0]?.message) {
|
|
1492
|
+
result.citations = r.citations;
|
|
1493
|
+
}
|
|
1494
|
+
return result;
|
|
1495
|
+
},
|
|
1496
|
+
async *translateStream(stream) {
|
|
1497
|
+
const reader = stream.getReader();
|
|
1498
|
+
const decoder = new TextDecoder();
|
|
1499
|
+
let buffer = "";
|
|
1500
|
+
try {
|
|
1501
|
+
while (true) {
|
|
1502
|
+
const { done, value } = await reader.read();
|
|
1503
|
+
if (done) break;
|
|
1504
|
+
buffer += decoder.decode(value, { stream: true });
|
|
1505
|
+
const lines = buffer.split("\n");
|
|
1506
|
+
buffer = lines.pop() || "";
|
|
1507
|
+
for (const line of lines) {
|
|
1508
|
+
const trimmed = line.trim();
|
|
1509
|
+
if (!trimmed || trimmed.startsWith(":")) continue;
|
|
1510
|
+
if (trimmed === "data: [DONE]") return;
|
|
1511
|
+
if (trimmed.startsWith("data: ")) {
|
|
1512
|
+
const json = JSON.parse(trimmed.substring(6));
|
|
1513
|
+
json.id = rePrefixId(json.id);
|
|
1514
|
+
json.model = `perplexity/${json.model}`;
|
|
1515
|
+
yield json;
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1519
|
+
} finally {
|
|
1520
|
+
reader.releaseLock();
|
|
1521
|
+
}
|
|
1522
|
+
},
|
|
1523
|
+
translateError(error) {
|
|
1524
|
+
if (error instanceof AnyModelError) {
|
|
1525
|
+
return { code: error.code, message: error.message, metadata: error.metadata };
|
|
1526
|
+
}
|
|
1527
|
+
const err = error;
|
|
1528
|
+
const status = err?.status || err?.code || 500;
|
|
1529
|
+
return {
|
|
1530
|
+
code: mapErrorCode(status),
|
|
1531
|
+
message: err?.message || "Unknown Perplexity error",
|
|
1532
|
+
metadata: { provider_name: "perplexity", raw: error }
|
|
1533
|
+
};
|
|
1534
|
+
},
|
|
1535
|
+
async listModels() {
|
|
1536
|
+
return MODELS.map((m) => ({
|
|
1537
|
+
id: `perplexity/${m.id}`,
|
|
1538
|
+
name: m.name,
|
|
1539
|
+
created: 0,
|
|
1540
|
+
description: "",
|
|
1541
|
+
context_length: m.context,
|
|
1542
|
+
pricing: { prompt: "0", completion: "0" },
|
|
1543
|
+
architecture: {
|
|
1544
|
+
modality: m.modality,
|
|
1545
|
+
input_modalities: m.inputModalities,
|
|
1546
|
+
output_modalities: ["text"],
|
|
1547
|
+
tokenizer: "unknown"
|
|
1548
|
+
},
|
|
1549
|
+
top_provider: {
|
|
1550
|
+
context_length: m.context,
|
|
1551
|
+
max_completion_tokens: m.maxOutput,
|
|
1552
|
+
is_moderated: false
|
|
1553
|
+
},
|
|
1554
|
+
supported_parameters: Array.from(SUPPORTED_PARAMS4)
|
|
1555
|
+
}));
|
|
1556
|
+
},
|
|
1557
|
+
supportsParameter(param) {
|
|
1558
|
+
return SUPPORTED_PARAMS4.has(param);
|
|
1559
|
+
},
|
|
1560
|
+
supportsBatch() {
|
|
1561
|
+
return false;
|
|
1562
|
+
},
|
|
1563
|
+
async sendRequest(request) {
|
|
1564
|
+
const body = buildRequestBody(request);
|
|
1565
|
+
const res = await makeRequest("/chat/completions", body);
|
|
1566
|
+
const json = await res.json();
|
|
1567
|
+
return adapter.translateResponse(json);
|
|
1568
|
+
},
|
|
1569
|
+
async sendStreamingRequest(request) {
|
|
1570
|
+
const body = buildRequestBody({ ...request, stream: true });
|
|
1571
|
+
const res = await makeRequest("/chat/completions", body);
|
|
1572
|
+
if (!res.body) {
|
|
1573
|
+
throw new AnyModelError(502, "No response body for streaming request", {
|
|
1574
|
+
provider_name: "perplexity"
|
|
1575
|
+
});
|
|
1576
|
+
}
|
|
1577
|
+
return adapter.translateStream(res.body);
|
|
1578
|
+
}
|
|
1579
|
+
};
|
|
1580
|
+
return adapter;
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1345
1583
|
// src/providers/custom.ts
|
|
1346
1584
|
function createCustomAdapter(name, config) {
|
|
1347
1585
|
const openaiAdapter = createOpenAIAdapter(config.apiKey || "", config.baseURL);
|
|
1348
1586
|
return {
|
|
1349
1587
|
...openaiAdapter,
|
|
1350
1588
|
name,
|
|
1589
|
+
supportsBatch() {
|
|
1590
|
+
return false;
|
|
1591
|
+
},
|
|
1351
1592
|
async listModels() {
|
|
1352
1593
|
if (config.models && config.models.length > 0) {
|
|
1353
1594
|
return config.models.map((modelId) => ({
|
|
@@ -1413,10 +1654,10 @@ function interpolateDeep(obj) {
|
|
|
1413
1654
|
}
|
|
1414
1655
|
return obj;
|
|
1415
1656
|
}
|
|
1416
|
-
function loadJsonFile(
|
|
1417
|
-
if (!(0, import_node_fs.existsSync)(
|
|
1657
|
+
function loadJsonFile(path2) {
|
|
1658
|
+
if (!(0, import_node_fs.existsSync)(path2)) return null;
|
|
1418
1659
|
try {
|
|
1419
|
-
const raw = (0, import_node_fs.readFileSync)(
|
|
1660
|
+
const raw = (0, import_node_fs.readFileSync)(path2, "utf-8");
|
|
1420
1661
|
const parsed = JSON.parse(raw);
|
|
1421
1662
|
return interpolateDeep(parsed);
|
|
1422
1663
|
} catch {
|
|
@@ -1517,93 +1758,237 @@ var GenerationStatsStore = class {
|
|
|
1517
1758
|
}
|
|
1518
1759
|
};
|
|
1519
1760
|
|
|
1520
|
-
// src/
|
|
1761
|
+
// src/utils/fs-io.ts
|
|
1762
|
+
var import_promises = require("fs/promises");
|
|
1521
1763
|
var import_node_fs2 = require("fs");
|
|
1522
|
-
var import_node_path2 = require("path");
|
|
1523
|
-
var
|
|
1524
|
-
var
|
|
1764
|
+
var import_node_path2 = __toESM(require("path"), 1);
|
|
1765
|
+
var import_p_queue = __toESM(require("p-queue"), 1);
|
|
1766
|
+
var writeQueue = new import_p_queue.default({ concurrency: 10 });
|
|
1767
|
+
var readQueue = new import_p_queue.default({ concurrency: 20 });
|
|
1768
|
+
function configureFsIO(options) {
|
|
1769
|
+
if (options.readConcurrency !== void 0) {
|
|
1770
|
+
readQueue.concurrency = options.readConcurrency;
|
|
1771
|
+
}
|
|
1772
|
+
if (options.writeConcurrency !== void 0) {
|
|
1773
|
+
writeQueue.concurrency = options.writeConcurrency;
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1776
|
+
var ensuredDirs = /* @__PURE__ */ new Set();
|
|
1777
|
+
var joinPathCache = /* @__PURE__ */ new Map();
|
|
1778
|
+
var dirnameCache = /* @__PURE__ */ new Map();
|
|
1779
|
+
var resolvePathCache = /* @__PURE__ */ new Map();
|
|
1780
|
+
async function ensureDir(dir) {
|
|
1781
|
+
if (!dir) return;
|
|
1782
|
+
if (ensuredDirs.has(dir)) return;
|
|
1783
|
+
await (0, import_promises.mkdir)(dir, { recursive: true });
|
|
1784
|
+
ensuredDirs.add(dir);
|
|
1785
|
+
}
|
|
1786
|
+
async function readFileQueued(filePath, encoding = "utf8") {
|
|
1787
|
+
return readQueue.add(async () => {
|
|
1788
|
+
return (0, import_promises.readFile)(filePath, encoding);
|
|
1789
|
+
});
|
|
1790
|
+
}
|
|
1791
|
+
async function readJsonQueued(filePath) {
|
|
1792
|
+
const raw = await readFileQueued(filePath, "utf8");
|
|
1793
|
+
return JSON.parse(raw);
|
|
1794
|
+
}
|
|
1795
|
+
async function readDirQueued(dirPath) {
|
|
1796
|
+
return readQueue.add(async () => {
|
|
1797
|
+
return (0, import_promises.readdir)(dirPath, { withFileTypes: true });
|
|
1798
|
+
});
|
|
1799
|
+
}
|
|
1800
|
+
async function pathExistsQueued(p) {
|
|
1801
|
+
return readQueue.add(async () => {
|
|
1802
|
+
try {
|
|
1803
|
+
await (0, import_promises.stat)(p);
|
|
1804
|
+
return true;
|
|
1805
|
+
} catch {
|
|
1806
|
+
return false;
|
|
1807
|
+
}
|
|
1808
|
+
});
|
|
1809
|
+
}
|
|
1810
|
+
async function fileExistsQueued(filePath) {
|
|
1811
|
+
return readQueue.add(async () => {
|
|
1812
|
+
try {
|
|
1813
|
+
const s = await (0, import_promises.stat)(filePath);
|
|
1814
|
+
return s.isFile();
|
|
1815
|
+
} catch {
|
|
1816
|
+
return false;
|
|
1817
|
+
}
|
|
1818
|
+
});
|
|
1819
|
+
}
|
|
1820
|
+
async function writeFileQueued(filePath, data) {
|
|
1821
|
+
await writeQueue.add(async () => {
|
|
1822
|
+
const dir = dirnameOf(filePath);
|
|
1823
|
+
await ensureDir(dir);
|
|
1824
|
+
await (0, import_promises.writeFile)(filePath, data);
|
|
1825
|
+
});
|
|
1826
|
+
}
|
|
1827
|
+
async function appendFileQueued(filePath, data) {
|
|
1828
|
+
await writeQueue.add(async () => {
|
|
1829
|
+
const dir = dirnameOf(filePath);
|
|
1830
|
+
await ensureDir(dir);
|
|
1831
|
+
await (0, import_promises.writeFile)(filePath, data, { flag: "a" });
|
|
1832
|
+
});
|
|
1833
|
+
}
|
|
1834
|
+
async function writeFileFlushedQueued(filePath, data) {
|
|
1835
|
+
await writeQueue.add(async () => {
|
|
1836
|
+
const dir = dirnameOf(filePath);
|
|
1837
|
+
await ensureDir(dir);
|
|
1838
|
+
const tmpPath = joinPath(
|
|
1839
|
+
dir,
|
|
1840
|
+
`.${import_node_path2.default.basename(filePath)}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`
|
|
1841
|
+
);
|
|
1842
|
+
const fh = await (0, import_promises.open)(tmpPath, "w");
|
|
1843
|
+
try {
|
|
1844
|
+
await fh.writeFile(data);
|
|
1845
|
+
await fh.sync();
|
|
1846
|
+
} finally {
|
|
1847
|
+
await fh.close();
|
|
1848
|
+
}
|
|
1849
|
+
await (0, import_promises.rename)(tmpPath, filePath);
|
|
1850
|
+
try {
|
|
1851
|
+
const dh = await (0, import_promises.open)(dir, "r");
|
|
1852
|
+
try {
|
|
1853
|
+
await dh.sync();
|
|
1854
|
+
} finally {
|
|
1855
|
+
await dh.close();
|
|
1856
|
+
}
|
|
1857
|
+
} catch {
|
|
1858
|
+
}
|
|
1859
|
+
});
|
|
1860
|
+
}
|
|
1861
|
+
function joinPath(...segments) {
|
|
1862
|
+
const key = segments.join("\0");
|
|
1863
|
+
const cached = joinPathCache.get(key);
|
|
1864
|
+
if (cached !== void 0) return cached;
|
|
1865
|
+
const out = import_node_path2.default.join(...segments);
|
|
1866
|
+
joinPathCache.set(key, out);
|
|
1867
|
+
return out;
|
|
1868
|
+
}
|
|
1869
|
+
function dirnameOf(p) {
|
|
1870
|
+
const cached = dirnameCache.get(p);
|
|
1871
|
+
if (cached !== void 0) return cached;
|
|
1872
|
+
const out = import_node_path2.default.dirname(p);
|
|
1873
|
+
dirnameCache.set(p, out);
|
|
1874
|
+
return out;
|
|
1875
|
+
}
|
|
1876
|
+
function resolvePath(...segments) {
|
|
1877
|
+
const key = segments.join("\0");
|
|
1878
|
+
const cached = resolvePathCache.get(key);
|
|
1879
|
+
if (cached !== void 0) return cached;
|
|
1880
|
+
const out = import_node_path2.default.resolve(...segments);
|
|
1881
|
+
resolvePathCache.set(key, out);
|
|
1882
|
+
return out;
|
|
1883
|
+
}
|
|
1884
|
+
function getFsQueueStatus() {
|
|
1885
|
+
return {
|
|
1886
|
+
read: { size: readQueue.size, pending: readQueue.pending },
|
|
1887
|
+
write: { size: writeQueue.size, pending: writeQueue.pending }
|
|
1888
|
+
};
|
|
1889
|
+
}
|
|
1890
|
+
async function waitForFsQueuesIdle() {
|
|
1891
|
+
await Promise.all([writeQueue.onIdle(), readQueue.onIdle()]);
|
|
1892
|
+
}
|
|
1893
|
+
|
|
1894
|
+
// src/batch/store.ts
|
|
1895
|
+
var DEFAULT_BATCH_DIR = joinPath(process.cwd(), ".anymodel", "batches");
|
|
1525
1896
|
var BatchStore = class {
|
|
1526
1897
|
dir;
|
|
1898
|
+
initialized = false;
|
|
1527
1899
|
constructor(dir) {
|
|
1528
|
-
this.dir = (
|
|
1529
|
-
|
|
1900
|
+
this.dir = resolvePath(dir || DEFAULT_BATCH_DIR);
|
|
1901
|
+
}
|
|
1902
|
+
async init() {
|
|
1903
|
+
if (this.initialized) return;
|
|
1904
|
+
await ensureDir(this.dir);
|
|
1905
|
+
this.initialized = true;
|
|
1530
1906
|
}
|
|
1531
1907
|
batchDir(id) {
|
|
1532
|
-
return (
|
|
1908
|
+
return joinPath(this.dir, id);
|
|
1533
1909
|
}
|
|
1534
1910
|
/**
|
|
1535
1911
|
* Create a new batch directory and save initial metadata.
|
|
1536
1912
|
*/
|
|
1537
|
-
create(batch) {
|
|
1913
|
+
async create(batch) {
|
|
1914
|
+
await this.init();
|
|
1538
1915
|
const dir = this.batchDir(batch.id);
|
|
1539
|
-
|
|
1540
|
-
|
|
1916
|
+
await ensureDir(dir);
|
|
1917
|
+
await writeFileFlushedQueued(joinPath(dir, "meta.json"), JSON.stringify(batch, null, 2));
|
|
1541
1918
|
}
|
|
1542
1919
|
/**
|
|
1543
|
-
* Update batch metadata.
|
|
1920
|
+
* Update batch metadata (atomic write).
|
|
1544
1921
|
*/
|
|
1545
|
-
updateMeta(batch) {
|
|
1546
|
-
|
|
1547
|
-
|
|
1922
|
+
async updateMeta(batch) {
|
|
1923
|
+
await writeFileFlushedQueued(
|
|
1924
|
+
joinPath(this.batchDir(batch.id), "meta.json"),
|
|
1925
|
+
JSON.stringify(batch, null, 2)
|
|
1926
|
+
);
|
|
1548
1927
|
}
|
|
1549
1928
|
/**
|
|
1550
1929
|
* Save requests as JSONL.
|
|
1551
1930
|
*/
|
|
1552
|
-
saveRequests(id, requests) {
|
|
1553
|
-
const dir = this.batchDir(id);
|
|
1931
|
+
async saveRequests(id, requests) {
|
|
1554
1932
|
const lines = requests.map((r) => JSON.stringify(r)).join("\n") + "\n";
|
|
1555
|
-
|
|
1933
|
+
await writeFileQueued(joinPath(this.batchDir(id), "requests.jsonl"), lines);
|
|
1556
1934
|
}
|
|
1557
1935
|
/**
|
|
1558
1936
|
* Append a result to results.jsonl.
|
|
1559
1937
|
*/
|
|
1560
|
-
appendResult(id, result) {
|
|
1561
|
-
|
|
1562
|
-
|
|
1938
|
+
async appendResult(id, result) {
|
|
1939
|
+
await appendFileQueued(
|
|
1940
|
+
joinPath(this.batchDir(id), "results.jsonl"),
|
|
1941
|
+
JSON.stringify(result) + "\n"
|
|
1942
|
+
);
|
|
1563
1943
|
}
|
|
1564
1944
|
/**
|
|
1565
1945
|
* Save provider-specific state (e.g., provider batch ID).
|
|
1566
1946
|
*/
|
|
1567
|
-
saveProviderState(id, state) {
|
|
1568
|
-
|
|
1569
|
-
|
|
1947
|
+
async saveProviderState(id, state) {
|
|
1948
|
+
await writeFileFlushedQueued(
|
|
1949
|
+
joinPath(this.batchDir(id), "provider.json"),
|
|
1950
|
+
JSON.stringify(state, null, 2)
|
|
1951
|
+
);
|
|
1570
1952
|
}
|
|
1571
1953
|
/**
|
|
1572
1954
|
* Load provider state.
|
|
1573
1955
|
*/
|
|
1574
|
-
loadProviderState(id) {
|
|
1575
|
-
const
|
|
1576
|
-
if (!
|
|
1577
|
-
return
|
|
1956
|
+
async loadProviderState(id) {
|
|
1957
|
+
const p = joinPath(this.batchDir(id), "provider.json");
|
|
1958
|
+
if (!await fileExistsQueued(p)) return null;
|
|
1959
|
+
return readJsonQueued(p);
|
|
1578
1960
|
}
|
|
1579
1961
|
/**
|
|
1580
1962
|
* Get batch metadata.
|
|
1581
1963
|
*/
|
|
1582
|
-
getMeta(id) {
|
|
1583
|
-
const
|
|
1584
|
-
if (!
|
|
1585
|
-
return
|
|
1964
|
+
async getMeta(id) {
|
|
1965
|
+
const p = joinPath(this.batchDir(id), "meta.json");
|
|
1966
|
+
if (!await fileExistsQueued(p)) return null;
|
|
1967
|
+
return readJsonQueued(p);
|
|
1586
1968
|
}
|
|
1587
1969
|
/**
|
|
1588
1970
|
* Get all results for a batch.
|
|
1589
1971
|
*/
|
|
1590
|
-
getResults(id) {
|
|
1591
|
-
const
|
|
1592
|
-
if (!
|
|
1593
|
-
|
|
1972
|
+
async getResults(id) {
|
|
1973
|
+
const p = joinPath(this.batchDir(id), "results.jsonl");
|
|
1974
|
+
if (!await fileExistsQueued(p)) return [];
|
|
1975
|
+
const raw = await readFileQueued(p, "utf8");
|
|
1976
|
+
return raw.trim().split("\n").filter(Boolean).map((line) => JSON.parse(line));
|
|
1594
1977
|
}
|
|
1595
1978
|
/**
|
|
1596
1979
|
* List all batch IDs.
|
|
1597
1980
|
*/
|
|
1598
|
-
listBatches() {
|
|
1599
|
-
|
|
1600
|
-
|
|
1981
|
+
async listBatches() {
|
|
1982
|
+
await this.init();
|
|
1983
|
+
if (!await pathExistsQueued(this.dir)) return [];
|
|
1984
|
+
const entries = await readDirQueued(this.dir);
|
|
1985
|
+
return entries.filter((d) => d.isDirectory()).map((d) => d.name).sort();
|
|
1601
1986
|
}
|
|
1602
1987
|
/**
|
|
1603
1988
|
* Check if a batch exists.
|
|
1604
1989
|
*/
|
|
1605
|
-
exists(id) {
|
|
1606
|
-
return (
|
|
1990
|
+
async exists(id) {
|
|
1991
|
+
return fileExistsQueued(joinPath(this.batchDir(id), "meta.json"));
|
|
1607
1992
|
}
|
|
1608
1993
|
};
|
|
1609
1994
|
|
|
@@ -1612,10 +1997,27 @@ var BatchManager = class {
|
|
|
1612
1997
|
store;
|
|
1613
1998
|
router;
|
|
1614
1999
|
concurrencyLimit;
|
|
2000
|
+
defaultPollInterval;
|
|
2001
|
+
batchAdapters = /* @__PURE__ */ new Map();
|
|
1615
2002
|
constructor(router, options) {
|
|
1616
2003
|
this.store = new BatchStore(options?.dir);
|
|
1617
2004
|
this.router = router;
|
|
1618
2005
|
this.concurrencyLimit = options?.concurrency ?? 5;
|
|
2006
|
+
this.defaultPollInterval = options?.pollInterval ?? 5e3;
|
|
2007
|
+
}
|
|
2008
|
+
/**
|
|
2009
|
+
* Register a native batch adapter for a provider.
|
|
2010
|
+
*/
|
|
2011
|
+
registerBatchAdapter(providerName, adapter) {
|
|
2012
|
+
this.batchAdapters.set(providerName, adapter);
|
|
2013
|
+
}
|
|
2014
|
+
/**
|
|
2015
|
+
* Check if a provider has native batch support.
|
|
2016
|
+
*/
|
|
2017
|
+
getNativeBatchAdapter(model) {
|
|
2018
|
+
const providerName = model.split("/")[0];
|
|
2019
|
+
const adapter = this.batchAdapters.get(providerName);
|
|
2020
|
+
return adapter ? { adapter, providerName } : null;
|
|
1619
2021
|
}
|
|
1620
2022
|
/**
|
|
1621
2023
|
* Create a batch and return immediately (no polling).
|
|
@@ -1623,13 +2025,16 @@ var BatchManager = class {
|
|
|
1623
2025
|
async create(request) {
|
|
1624
2026
|
const id = generateId("batch");
|
|
1625
2027
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2028
|
+
const providerName = request.model.split("/")[0] || "unknown";
|
|
2029
|
+
const native = this.getNativeBatchAdapter(request.model);
|
|
2030
|
+
const batchMode = native ? "native" : "concurrent";
|
|
1626
2031
|
const batch = {
|
|
1627
2032
|
id,
|
|
1628
2033
|
object: "batch",
|
|
1629
2034
|
status: "pending",
|
|
1630
2035
|
model: request.model,
|
|
1631
|
-
provider_name:
|
|
1632
|
-
batch_mode:
|
|
2036
|
+
provider_name: providerName,
|
|
2037
|
+
batch_mode: batchMode,
|
|
1633
2038
|
total: request.requests.length,
|
|
1634
2039
|
completed: 0,
|
|
1635
2040
|
failed: 0,
|
|
@@ -1637,10 +2042,15 @@ var BatchManager = class {
|
|
|
1637
2042
|
completed_at: null,
|
|
1638
2043
|
expires_at: null
|
|
1639
2044
|
};
|
|
1640
|
-
this.store.create(batch);
|
|
1641
|
-
this.store.saveRequests(id, request.requests);
|
|
1642
|
-
|
|
1643
|
-
|
|
2045
|
+
await this.store.create(batch);
|
|
2046
|
+
await this.store.saveRequests(id, request.requests);
|
|
2047
|
+
if (native) {
|
|
2048
|
+
this.processNativeBatch(id, request, native.adapter).catch(() => {
|
|
2049
|
+
});
|
|
2050
|
+
} else {
|
|
2051
|
+
this.processConcurrentBatch(id, request).catch(() => {
|
|
2052
|
+
});
|
|
2053
|
+
}
|
|
1644
2054
|
return batch;
|
|
1645
2055
|
}
|
|
1646
2056
|
/**
|
|
@@ -1654,14 +2064,19 @@ var BatchManager = class {
|
|
|
1654
2064
|
* Poll an existing batch until completion.
|
|
1655
2065
|
*/
|
|
1656
2066
|
async poll(id, options = {}) {
|
|
1657
|
-
const interval = options.interval ??
|
|
2067
|
+
const interval = options.interval ?? this.defaultPollInterval;
|
|
1658
2068
|
const timeout = options.timeout ?? 0;
|
|
1659
2069
|
const startTime = Date.now();
|
|
1660
2070
|
while (true) {
|
|
1661
|
-
|
|
2071
|
+
let batch = await this.store.getMeta(id);
|
|
1662
2072
|
if (!batch) {
|
|
1663
2073
|
throw new AnyModelError(404, `Batch ${id} not found`);
|
|
1664
2074
|
}
|
|
2075
|
+
if (batch.batch_mode === "native" && batch.status === "processing") {
|
|
2076
|
+
await this.syncNativeBatchStatus(id);
|
|
2077
|
+
batch = await this.store.getMeta(id);
|
|
2078
|
+
if (!batch) throw new AnyModelError(404, `Batch ${id} not found`);
|
|
2079
|
+
}
|
|
1665
2080
|
if (options.onProgress) {
|
|
1666
2081
|
options.onProgress(batch);
|
|
1667
2082
|
}
|
|
@@ -1671,24 +2086,24 @@ var BatchManager = class {
|
|
|
1671
2086
|
if (timeout > 0 && Date.now() - startTime > timeout) {
|
|
1672
2087
|
throw new AnyModelError(408, `Batch ${id} timed out after ${timeout}ms`);
|
|
1673
2088
|
}
|
|
1674
|
-
await new Promise((
|
|
2089
|
+
await new Promise((resolve2) => setTimeout(resolve2, interval));
|
|
1675
2090
|
}
|
|
1676
2091
|
}
|
|
1677
2092
|
/**
|
|
1678
2093
|
* Get the current status of a batch.
|
|
1679
2094
|
*/
|
|
1680
|
-
get(id) {
|
|
2095
|
+
async get(id) {
|
|
1681
2096
|
return this.store.getMeta(id);
|
|
1682
2097
|
}
|
|
1683
2098
|
/**
|
|
1684
2099
|
* Get results for a completed batch.
|
|
1685
2100
|
*/
|
|
1686
|
-
getResults(id) {
|
|
1687
|
-
const batch = this.store.getMeta(id);
|
|
2101
|
+
async getResults(id) {
|
|
2102
|
+
const batch = await this.store.getMeta(id);
|
|
1688
2103
|
if (!batch) {
|
|
1689
2104
|
throw new AnyModelError(404, `Batch ${id} not found`);
|
|
1690
2105
|
}
|
|
1691
|
-
const results = this.store.getResults(id);
|
|
2106
|
+
const results = await this.store.getResults(id);
|
|
1692
2107
|
const usage = {
|
|
1693
2108
|
total_prompt_tokens: 0,
|
|
1694
2109
|
total_completion_tokens: 0,
|
|
@@ -1710,37 +2125,119 @@ var BatchManager = class {
|
|
|
1710
2125
|
/**
|
|
1711
2126
|
* List all batches.
|
|
1712
2127
|
*/
|
|
1713
|
-
list() {
|
|
1714
|
-
|
|
2128
|
+
async list() {
|
|
2129
|
+
const ids = await this.store.listBatches();
|
|
2130
|
+
const batches = [];
|
|
2131
|
+
for (const id of ids) {
|
|
2132
|
+
const meta = await this.store.getMeta(id);
|
|
2133
|
+
if (meta) batches.push(meta);
|
|
2134
|
+
}
|
|
2135
|
+
return batches;
|
|
1715
2136
|
}
|
|
1716
2137
|
/**
|
|
1717
2138
|
* Cancel a batch.
|
|
1718
2139
|
*/
|
|
1719
|
-
cancel(id) {
|
|
1720
|
-
const batch = this.store.getMeta(id);
|
|
2140
|
+
async cancel(id) {
|
|
2141
|
+
const batch = await this.store.getMeta(id);
|
|
1721
2142
|
if (!batch) {
|
|
1722
2143
|
throw new AnyModelError(404, `Batch ${id} not found`);
|
|
1723
2144
|
}
|
|
1724
2145
|
if (batch.status === "completed" || batch.status === "cancelled") {
|
|
1725
2146
|
return batch;
|
|
1726
2147
|
}
|
|
2148
|
+
if (batch.batch_mode === "native") {
|
|
2149
|
+
const providerState = await this.store.loadProviderState(id);
|
|
2150
|
+
const adapter = this.batchAdapters.get(batch.provider_name);
|
|
2151
|
+
if (adapter && providerState?.providerBatchId) {
|
|
2152
|
+
try {
|
|
2153
|
+
await adapter.cancelBatch(providerState.providerBatchId);
|
|
2154
|
+
} catch {
|
|
2155
|
+
}
|
|
2156
|
+
}
|
|
2157
|
+
}
|
|
1727
2158
|
batch.status = "cancelled";
|
|
1728
2159
|
batch.completed_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
1729
|
-
this.store.updateMeta(batch);
|
|
2160
|
+
await this.store.updateMeta(batch);
|
|
1730
2161
|
return batch;
|
|
1731
2162
|
}
|
|
1732
2163
|
/**
|
|
1733
|
-
* Process batch
|
|
2164
|
+
* Process batch via native provider batch API.
|
|
2165
|
+
*/
|
|
2166
|
+
async processNativeBatch(batchId, request, adapter) {
|
|
2167
|
+
const batch = await this.store.getMeta(batchId);
|
|
2168
|
+
if (!batch) return;
|
|
2169
|
+
try {
|
|
2170
|
+
const model = request.model.includes("/") ? request.model.split("/").slice(1).join("/") : request.model;
|
|
2171
|
+
const { providerBatchId, metadata } = await adapter.createBatch(
|
|
2172
|
+
model,
|
|
2173
|
+
request.requests,
|
|
2174
|
+
request.options
|
|
2175
|
+
);
|
|
2176
|
+
await this.store.saveProviderState(batchId, {
|
|
2177
|
+
providerBatchId,
|
|
2178
|
+
providerName: batch.provider_name,
|
|
2179
|
+
...metadata
|
|
2180
|
+
});
|
|
2181
|
+
batch.status = "processing";
|
|
2182
|
+
await this.store.updateMeta(batch);
|
|
2183
|
+
} catch (err) {
|
|
2184
|
+
batch.status = "failed";
|
|
2185
|
+
batch.completed_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
2186
|
+
await this.store.updateMeta(batch);
|
|
2187
|
+
throw err;
|
|
2188
|
+
}
|
|
2189
|
+
}
|
|
2190
|
+
/**
|
|
2191
|
+
* Sync native batch status from provider.
|
|
2192
|
+
*/
|
|
2193
|
+
async syncNativeBatchStatus(batchId) {
|
|
2194
|
+
const batch = await this.store.getMeta(batchId);
|
|
2195
|
+
if (!batch) return;
|
|
2196
|
+
const providerState = await this.store.loadProviderState(batchId);
|
|
2197
|
+
if (!providerState?.providerBatchId) return;
|
|
2198
|
+
const adapter = this.batchAdapters.get(batch.provider_name);
|
|
2199
|
+
if (!adapter) return;
|
|
2200
|
+
try {
|
|
2201
|
+
const status = await adapter.pollBatch(providerState.providerBatchId);
|
|
2202
|
+
batch.total = status.total || batch.total;
|
|
2203
|
+
batch.completed = status.completed;
|
|
2204
|
+
batch.failed = status.failed;
|
|
2205
|
+
if (status.status === "completed" || status.status === "failed" || status.status === "cancelled") {
|
|
2206
|
+
batch.status = status.status;
|
|
2207
|
+
batch.completed_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
2208
|
+
if (status.status === "completed" || status.status === "failed") {
|
|
2209
|
+
try {
|
|
2210
|
+
const results = await adapter.getBatchResults(providerState.providerBatchId);
|
|
2211
|
+
for (const result of results) {
|
|
2212
|
+
await this.store.appendResult(batchId, result);
|
|
2213
|
+
}
|
|
2214
|
+
batch.completed = results.filter((r) => r.status === "success").length;
|
|
2215
|
+
batch.failed = results.filter((r) => r.status === "error").length;
|
|
2216
|
+
} catch {
|
|
2217
|
+
if (batch.status !== "failed") {
|
|
2218
|
+
batch.status = "failed";
|
|
2219
|
+
}
|
|
2220
|
+
}
|
|
2221
|
+
}
|
|
2222
|
+
} else {
|
|
2223
|
+
batch.status = "processing";
|
|
2224
|
+
}
|
|
2225
|
+
await this.store.updateMeta(batch);
|
|
2226
|
+
} catch {
|
|
2227
|
+
}
|
|
2228
|
+
}
|
|
2229
|
+
/**
|
|
2230
|
+
* Process batch requests concurrently (fallback path).
|
|
1734
2231
|
*/
|
|
1735
|
-
async
|
|
1736
|
-
const batch = this.store.getMeta(batchId);
|
|
2232
|
+
async processConcurrentBatch(batchId, request) {
|
|
2233
|
+
const batch = await this.store.getMeta(batchId);
|
|
2234
|
+
if (!batch) return;
|
|
1737
2235
|
batch.status = "processing";
|
|
1738
|
-
this.store.updateMeta(batch);
|
|
2236
|
+
await this.store.updateMeta(batch);
|
|
1739
2237
|
const items = request.requests;
|
|
1740
|
-
const queue = [...items];
|
|
1741
2238
|
const active = /* @__PURE__ */ new Set();
|
|
1742
2239
|
const processItem = async (item) => {
|
|
1743
|
-
const current = this.store.getMeta(batchId);
|
|
2240
|
+
const current = await this.store.getMeta(batchId);
|
|
1744
2241
|
if (current?.status === "cancelled") return;
|
|
1745
2242
|
const chatRequest = {
|
|
1746
2243
|
model: request.model,
|
|
@@ -1772,17 +2269,19 @@ var BatchManager = class {
|
|
|
1772
2269
|
error: { code: error.code, message: error.message }
|
|
1773
2270
|
};
|
|
1774
2271
|
}
|
|
1775
|
-
this.store.appendResult(batchId, result);
|
|
1776
|
-
const meta = this.store.getMeta(batchId);
|
|
1777
|
-
if (
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
2272
|
+
await this.store.appendResult(batchId, result);
|
|
2273
|
+
const meta = await this.store.getMeta(batchId);
|
|
2274
|
+
if (meta) {
|
|
2275
|
+
if (result.status === "success") {
|
|
2276
|
+
meta.completed++;
|
|
2277
|
+
} else {
|
|
2278
|
+
meta.failed++;
|
|
2279
|
+
}
|
|
2280
|
+
await this.store.updateMeta(meta);
|
|
1781
2281
|
}
|
|
1782
|
-
this.store.updateMeta(meta);
|
|
1783
2282
|
};
|
|
1784
|
-
for (const item of
|
|
1785
|
-
const current = this.store.getMeta(batchId);
|
|
2283
|
+
for (const item of items) {
|
|
2284
|
+
const current = await this.store.getMeta(batchId);
|
|
1786
2285
|
if (current?.status === "cancelled") break;
|
|
1787
2286
|
if (active.size >= this.concurrencyLimit) {
|
|
1788
2287
|
await Promise.race(active);
|
|
@@ -1793,15 +2292,411 @@ var BatchManager = class {
|
|
|
1793
2292
|
active.add(promise);
|
|
1794
2293
|
}
|
|
1795
2294
|
await Promise.all(active);
|
|
1796
|
-
const finalMeta = this.store.getMeta(batchId);
|
|
1797
|
-
if (finalMeta.status !== "cancelled") {
|
|
2295
|
+
const finalMeta = await this.store.getMeta(batchId);
|
|
2296
|
+
if (finalMeta && finalMeta.status !== "cancelled") {
|
|
1798
2297
|
finalMeta.status = finalMeta.failed === finalMeta.total ? "failed" : "completed";
|
|
1799
2298
|
finalMeta.completed_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
1800
|
-
this.store.updateMeta(finalMeta);
|
|
2299
|
+
await this.store.updateMeta(finalMeta);
|
|
1801
2300
|
}
|
|
1802
2301
|
}
|
|
1803
2302
|
};
|
|
1804
2303
|
|
|
2304
|
+
// src/providers/openai-batch.ts
|
|
2305
|
+
var OPENAI_API_BASE2 = "https://api.openai.com/v1";
|
|
2306
|
+
function createOpenAIBatchAdapter(apiKey) {
|
|
2307
|
+
async function apiRequest(path2, options = {}) {
|
|
2308
|
+
const headers = {
|
|
2309
|
+
"Authorization": `Bearer ${apiKey}`
|
|
2310
|
+
};
|
|
2311
|
+
let fetchBody;
|
|
2312
|
+
if (options.formData) {
|
|
2313
|
+
fetchBody = options.formData;
|
|
2314
|
+
} else if (options.body) {
|
|
2315
|
+
headers["Content-Type"] = "application/json";
|
|
2316
|
+
fetchBody = JSON.stringify(options.body);
|
|
2317
|
+
}
|
|
2318
|
+
const res = await fetch(`${OPENAI_API_BASE2}${path2}`, {
|
|
2319
|
+
method: options.method || "GET",
|
|
2320
|
+
headers,
|
|
2321
|
+
body: fetchBody
|
|
2322
|
+
});
|
|
2323
|
+
if (!res.ok) {
|
|
2324
|
+
let errorBody;
|
|
2325
|
+
try {
|
|
2326
|
+
errorBody = await res.json();
|
|
2327
|
+
} catch {
|
|
2328
|
+
errorBody = { message: res.statusText };
|
|
2329
|
+
}
|
|
2330
|
+
const msg = errorBody?.error?.message || errorBody?.message || res.statusText;
|
|
2331
|
+
throw new AnyModelError(res.status >= 500 ? 502 : res.status, msg, {
|
|
2332
|
+
provider_name: "openai",
|
|
2333
|
+
raw: errorBody
|
|
2334
|
+
});
|
|
2335
|
+
}
|
|
2336
|
+
return res;
|
|
2337
|
+
}
|
|
2338
|
+
function buildJSONL(model, requests) {
|
|
2339
|
+
return requests.map((req) => {
|
|
2340
|
+
const body = {
|
|
2341
|
+
model,
|
|
2342
|
+
messages: req.messages
|
|
2343
|
+
};
|
|
2344
|
+
if (req.max_tokens !== void 0) body.max_tokens = req.max_tokens;
|
|
2345
|
+
if (req.temperature !== void 0) body.temperature = req.temperature;
|
|
2346
|
+
if (req.top_p !== void 0) body.top_p = req.top_p;
|
|
2347
|
+
if (req.stop !== void 0) body.stop = req.stop;
|
|
2348
|
+
if (req.response_format !== void 0) body.response_format = req.response_format;
|
|
2349
|
+
if (req.tools !== void 0) body.tools = req.tools;
|
|
2350
|
+
if (req.tool_choice !== void 0) body.tool_choice = req.tool_choice;
|
|
2351
|
+
return JSON.stringify({
|
|
2352
|
+
custom_id: req.custom_id,
|
|
2353
|
+
method: "POST",
|
|
2354
|
+
url: "/v1/chat/completions",
|
|
2355
|
+
body
|
|
2356
|
+
});
|
|
2357
|
+
}).join("\n");
|
|
2358
|
+
}
|
|
2359
|
+
function rePrefixId(id) {
|
|
2360
|
+
if (id && id.startsWith("chatcmpl-")) {
|
|
2361
|
+
return `gen-${id.substring(9)}`;
|
|
2362
|
+
}
|
|
2363
|
+
return id.startsWith("gen-") ? id : `gen-${id}`;
|
|
2364
|
+
}
|
|
2365
|
+
function translateOpenAIResponse(body) {
|
|
2366
|
+
return {
|
|
2367
|
+
id: rePrefixId(body.id || generateId()),
|
|
2368
|
+
object: "chat.completion",
|
|
2369
|
+
created: body.created || Math.floor(Date.now() / 1e3),
|
|
2370
|
+
model: `openai/${body.model}`,
|
|
2371
|
+
choices: body.choices,
|
|
2372
|
+
usage: body.usage
|
|
2373
|
+
};
|
|
2374
|
+
}
|
|
2375
|
+
function mapStatus(openaiStatus) {
|
|
2376
|
+
switch (openaiStatus) {
|
|
2377
|
+
case "validating":
|
|
2378
|
+
case "finalizing":
|
|
2379
|
+
return "processing";
|
|
2380
|
+
case "in_progress":
|
|
2381
|
+
return "processing";
|
|
2382
|
+
case "completed":
|
|
2383
|
+
return "completed";
|
|
2384
|
+
case "failed":
|
|
2385
|
+
return "failed";
|
|
2386
|
+
case "expired":
|
|
2387
|
+
return "failed";
|
|
2388
|
+
case "cancelled":
|
|
2389
|
+
case "cancelling":
|
|
2390
|
+
return "cancelled";
|
|
2391
|
+
default:
|
|
2392
|
+
return "pending";
|
|
2393
|
+
}
|
|
2394
|
+
}
|
|
2395
|
+
return {
|
|
2396
|
+
async createBatch(model, requests, options) {
|
|
2397
|
+
const jsonlContent = buildJSONL(model, requests);
|
|
2398
|
+
const blob = new Blob([jsonlContent], { type: "application/jsonl" });
|
|
2399
|
+
const formData = new FormData();
|
|
2400
|
+
formData.append("purpose", "batch");
|
|
2401
|
+
formData.append("file", blob, "batch_input.jsonl");
|
|
2402
|
+
const uploadRes = await apiRequest("/files", { method: "POST", formData });
|
|
2403
|
+
const fileData = await uploadRes.json();
|
|
2404
|
+
const inputFileId = fileData.id;
|
|
2405
|
+
const batchRes = await apiRequest("/batches", {
|
|
2406
|
+
method: "POST",
|
|
2407
|
+
body: {
|
|
2408
|
+
input_file_id: inputFileId,
|
|
2409
|
+
endpoint: "/v1/chat/completions",
|
|
2410
|
+
completion_window: "24h",
|
|
2411
|
+
metadata: options?.metadata
|
|
2412
|
+
}
|
|
2413
|
+
});
|
|
2414
|
+
const batchData = await batchRes.json();
|
|
2415
|
+
return {
|
|
2416
|
+
providerBatchId: batchData.id,
|
|
2417
|
+
metadata: {
|
|
2418
|
+
input_file_id: inputFileId,
|
|
2419
|
+
openai_status: batchData.status
|
|
2420
|
+
}
|
|
2421
|
+
};
|
|
2422
|
+
},
|
|
2423
|
+
async pollBatch(providerBatchId) {
|
|
2424
|
+
const res = await apiRequest(`/batches/${providerBatchId}`);
|
|
2425
|
+
const data = await res.json();
|
|
2426
|
+
const requestCounts = data.request_counts || {};
|
|
2427
|
+
return {
|
|
2428
|
+
status: mapStatus(data.status),
|
|
2429
|
+
total: requestCounts.total || 0,
|
|
2430
|
+
completed: requestCounts.completed || 0,
|
|
2431
|
+
failed: requestCounts.failed || 0
|
|
2432
|
+
};
|
|
2433
|
+
},
|
|
2434
|
+
async getBatchResults(providerBatchId) {
|
|
2435
|
+
const batchRes = await apiRequest(`/batches/${providerBatchId}`);
|
|
2436
|
+
const batchData = await batchRes.json();
|
|
2437
|
+
const results = [];
|
|
2438
|
+
if (batchData.output_file_id) {
|
|
2439
|
+
const outputRes = await apiRequest(`/files/${batchData.output_file_id}/content`);
|
|
2440
|
+
const outputText = await outputRes.text();
|
|
2441
|
+
for (const line of outputText.trim().split("\n")) {
|
|
2442
|
+
if (!line) continue;
|
|
2443
|
+
const item = JSON.parse(line);
|
|
2444
|
+
if (item.response?.status_code === 200) {
|
|
2445
|
+
results.push({
|
|
2446
|
+
custom_id: item.custom_id,
|
|
2447
|
+
status: "success",
|
|
2448
|
+
response: translateOpenAIResponse(item.response.body),
|
|
2449
|
+
error: null
|
|
2450
|
+
});
|
|
2451
|
+
} else {
|
|
2452
|
+
results.push({
|
|
2453
|
+
custom_id: item.custom_id,
|
|
2454
|
+
status: "error",
|
|
2455
|
+
response: null,
|
|
2456
|
+
error: {
|
|
2457
|
+
code: item.response?.status_code || 500,
|
|
2458
|
+
message: item.error?.message || item.response?.body?.error?.message || "Unknown error"
|
|
2459
|
+
}
|
|
2460
|
+
});
|
|
2461
|
+
}
|
|
2462
|
+
}
|
|
2463
|
+
}
|
|
2464
|
+
if (batchData.error_file_id) {
|
|
2465
|
+
const errorRes = await apiRequest(`/files/${batchData.error_file_id}/content`);
|
|
2466
|
+
const errorText = await errorRes.text();
|
|
2467
|
+
for (const line of errorText.trim().split("\n")) {
|
|
2468
|
+
if (!line) continue;
|
|
2469
|
+
const item = JSON.parse(line);
|
|
2470
|
+
const existing = results.find((r) => r.custom_id === item.custom_id);
|
|
2471
|
+
if (!existing) {
|
|
2472
|
+
results.push({
|
|
2473
|
+
custom_id: item.custom_id,
|
|
2474
|
+
status: "error",
|
|
2475
|
+
response: null,
|
|
2476
|
+
error: {
|
|
2477
|
+
code: item.response?.status_code || 500,
|
|
2478
|
+
message: item.error?.message || "Batch item error"
|
|
2479
|
+
}
|
|
2480
|
+
});
|
|
2481
|
+
}
|
|
2482
|
+
}
|
|
2483
|
+
}
|
|
2484
|
+
return results;
|
|
2485
|
+
},
|
|
2486
|
+
async cancelBatch(providerBatchId) {
|
|
2487
|
+
await apiRequest(`/batches/${providerBatchId}/cancel`, { method: "POST" });
|
|
2488
|
+
}
|
|
2489
|
+
};
|
|
2490
|
+
}
|
|
2491
|
+
|
|
2492
|
+
// src/providers/anthropic-batch.ts
|
|
2493
|
+
var ANTHROPIC_API_BASE2 = "https://api.anthropic.com/v1";
|
|
2494
|
+
var ANTHROPIC_VERSION2 = "2023-06-01";
|
|
2495
|
+
var DEFAULT_MAX_TOKENS2 = 4096;
|
|
2496
|
+
function createAnthropicBatchAdapter(apiKey) {
|
|
2497
|
+
async function apiRequest(path2, options = {}) {
|
|
2498
|
+
const headers = {
|
|
2499
|
+
"x-api-key": apiKey,
|
|
2500
|
+
"anthropic-version": ANTHROPIC_VERSION2,
|
|
2501
|
+
"Content-Type": "application/json"
|
|
2502
|
+
};
|
|
2503
|
+
const res = await fetch(`${ANTHROPIC_API_BASE2}${path2}`, {
|
|
2504
|
+
method: options.method || "GET",
|
|
2505
|
+
headers,
|
|
2506
|
+
body: options.body ? JSON.stringify(options.body) : void 0
|
|
2507
|
+
});
|
|
2508
|
+
if (!res.ok) {
|
|
2509
|
+
let errorBody;
|
|
2510
|
+
try {
|
|
2511
|
+
errorBody = await res.json();
|
|
2512
|
+
} catch {
|
|
2513
|
+
errorBody = { message: res.statusText };
|
|
2514
|
+
}
|
|
2515
|
+
const msg = errorBody?.error?.message || errorBody?.message || res.statusText;
|
|
2516
|
+
throw new AnyModelError(res.status >= 500 ? 502 : res.status, msg, {
|
|
2517
|
+
provider_name: "anthropic",
|
|
2518
|
+
raw: errorBody
|
|
2519
|
+
});
|
|
2520
|
+
}
|
|
2521
|
+
return res;
|
|
2522
|
+
}
|
|
2523
|
+
function translateToAnthropicParams(model, req) {
|
|
2524
|
+
const params = {
|
|
2525
|
+
model,
|
|
2526
|
+
max_tokens: req.max_tokens || DEFAULT_MAX_TOKENS2
|
|
2527
|
+
};
|
|
2528
|
+
const systemMessages = req.messages.filter((m) => m.role === "system");
|
|
2529
|
+
const nonSystemMessages = req.messages.filter((m) => m.role !== "system");
|
|
2530
|
+
if (systemMessages.length > 0) {
|
|
2531
|
+
params.system = systemMessages.map((m) => typeof m.content === "string" ? m.content : "").join("\n");
|
|
2532
|
+
}
|
|
2533
|
+
params.messages = nonSystemMessages.map((m) => ({
|
|
2534
|
+
role: m.role === "tool" ? "user" : m.role,
|
|
2535
|
+
content: m.tool_call_id ? [{ type: "tool_result", tool_use_id: m.tool_call_id, content: typeof m.content === "string" ? m.content : "" }] : m.content
|
|
2536
|
+
}));
|
|
2537
|
+
if (req.temperature !== void 0) params.temperature = req.temperature;
|
|
2538
|
+
if (req.top_p !== void 0) params.top_p = req.top_p;
|
|
2539
|
+
if (req.top_k !== void 0) params.top_k = req.top_k;
|
|
2540
|
+
if (req.stop !== void 0) params.stop_sequences = Array.isArray(req.stop) ? req.stop : [req.stop];
|
|
2541
|
+
if (req.tools && req.tools.length > 0) {
|
|
2542
|
+
params.tools = req.tools.map((t) => ({
|
|
2543
|
+
name: t.function.name,
|
|
2544
|
+
description: t.function.description || "",
|
|
2545
|
+
input_schema: t.function.parameters || { type: "object", properties: {} }
|
|
2546
|
+
}));
|
|
2547
|
+
if (req.tool_choice) {
|
|
2548
|
+
if (req.tool_choice === "auto") {
|
|
2549
|
+
params.tool_choice = { type: "auto" };
|
|
2550
|
+
} else if (req.tool_choice === "required") {
|
|
2551
|
+
params.tool_choice = { type: "any" };
|
|
2552
|
+
} else if (req.tool_choice === "none") {
|
|
2553
|
+
delete params.tools;
|
|
2554
|
+
} else if (typeof req.tool_choice === "object") {
|
|
2555
|
+
params.tool_choice = { type: "tool", name: req.tool_choice.function.name };
|
|
2556
|
+
}
|
|
2557
|
+
}
|
|
2558
|
+
}
|
|
2559
|
+
if (req.response_format) {
|
|
2560
|
+
if (req.response_format.type === "json_object" || req.response_format.type === "json_schema") {
|
|
2561
|
+
const jsonInstruction = "Respond with valid JSON only. Do not include any text outside the JSON object.";
|
|
2562
|
+
params.system = params.system ? `${jsonInstruction}
|
|
2563
|
+
|
|
2564
|
+
${params.system}` : jsonInstruction;
|
|
2565
|
+
}
|
|
2566
|
+
}
|
|
2567
|
+
return params;
|
|
2568
|
+
}
|
|
2569
|
+
function mapStopReason(reason) {
|
|
2570
|
+
switch (reason) {
|
|
2571
|
+
case "end_turn":
|
|
2572
|
+
return "stop";
|
|
2573
|
+
case "max_tokens":
|
|
2574
|
+
return "length";
|
|
2575
|
+
case "tool_use":
|
|
2576
|
+
return "tool_calls";
|
|
2577
|
+
case "stop_sequence":
|
|
2578
|
+
return "stop";
|
|
2579
|
+
default:
|
|
2580
|
+
return "stop";
|
|
2581
|
+
}
|
|
2582
|
+
}
|
|
2583
|
+
function translateAnthropicMessage(msg) {
|
|
2584
|
+
let content = "";
|
|
2585
|
+
const toolCalls = [];
|
|
2586
|
+
for (const block of msg.content || []) {
|
|
2587
|
+
if (block.type === "text") {
|
|
2588
|
+
content += block.text;
|
|
2589
|
+
} else if (block.type === "tool_use") {
|
|
2590
|
+
toolCalls.push({
|
|
2591
|
+
id: block.id,
|
|
2592
|
+
type: "function",
|
|
2593
|
+
function: {
|
|
2594
|
+
name: block.name,
|
|
2595
|
+
arguments: JSON.stringify(block.input)
|
|
2596
|
+
}
|
|
2597
|
+
});
|
|
2598
|
+
}
|
|
2599
|
+
}
|
|
2600
|
+
const message = { role: "assistant", content };
|
|
2601
|
+
if (toolCalls.length > 0) {
|
|
2602
|
+
message.tool_calls = toolCalls;
|
|
2603
|
+
}
|
|
2604
|
+
return {
|
|
2605
|
+
id: generateId(),
|
|
2606
|
+
object: "chat.completion",
|
|
2607
|
+
created: Math.floor(Date.now() / 1e3),
|
|
2608
|
+
model: `anthropic/${msg.model}`,
|
|
2609
|
+
choices: [{
|
|
2610
|
+
index: 0,
|
|
2611
|
+
message,
|
|
2612
|
+
finish_reason: mapStopReason(msg.stop_reason)
|
|
2613
|
+
}],
|
|
2614
|
+
usage: {
|
|
2615
|
+
prompt_tokens: msg.usage?.input_tokens || 0,
|
|
2616
|
+
completion_tokens: msg.usage?.output_tokens || 0,
|
|
2617
|
+
total_tokens: (msg.usage?.input_tokens || 0) + (msg.usage?.output_tokens || 0)
|
|
2618
|
+
}
|
|
2619
|
+
};
|
|
2620
|
+
}
|
|
2621
|
+
return {
|
|
2622
|
+
async createBatch(model, requests, _options) {
|
|
2623
|
+
const batchRequests = requests.map((req) => ({
|
|
2624
|
+
custom_id: req.custom_id,
|
|
2625
|
+
params: translateToAnthropicParams(model, req)
|
|
2626
|
+
}));
|
|
2627
|
+
const res = await apiRequest("/messages/batches", {
|
|
2628
|
+
method: "POST",
|
|
2629
|
+
body: { requests: batchRequests }
|
|
2630
|
+
});
|
|
2631
|
+
const data = await res.json();
|
|
2632
|
+
return {
|
|
2633
|
+
providerBatchId: data.id,
|
|
2634
|
+
metadata: {
|
|
2635
|
+
anthropic_type: data.type,
|
|
2636
|
+
created_at: data.created_at
|
|
2637
|
+
}
|
|
2638
|
+
};
|
|
2639
|
+
},
|
|
2640
|
+
async pollBatch(providerBatchId) {
|
|
2641
|
+
const res = await apiRequest(`/messages/batches/${providerBatchId}`);
|
|
2642
|
+
const data = await res.json();
|
|
2643
|
+
const counts = data.request_counts || {};
|
|
2644
|
+
const total = (counts.processing || 0) + (counts.succeeded || 0) + (counts.errored || 0) + (counts.canceled || 0) + (counts.expired || 0);
|
|
2645
|
+
let status;
|
|
2646
|
+
if (data.processing_status === "ended") {
|
|
2647
|
+
if (counts.succeeded === 0 && (counts.errored > 0 || counts.expired > 0 || counts.canceled > 0)) {
|
|
2648
|
+
status = "failed";
|
|
2649
|
+
} else if (data.cancel_initiated_at) {
|
|
2650
|
+
status = "cancelled";
|
|
2651
|
+
} else {
|
|
2652
|
+
status = "completed";
|
|
2653
|
+
}
|
|
2654
|
+
} else {
|
|
2655
|
+
status = "processing";
|
|
2656
|
+
}
|
|
2657
|
+
return {
|
|
2658
|
+
status,
|
|
2659
|
+
total,
|
|
2660
|
+
completed: counts.succeeded || 0,
|
|
2661
|
+
failed: (counts.errored || 0) + (counts.expired || 0) + (counts.canceled || 0)
|
|
2662
|
+
};
|
|
2663
|
+
},
|
|
2664
|
+
async getBatchResults(providerBatchId) {
|
|
2665
|
+
const res = await apiRequest(`/messages/batches/${providerBatchId}/results`);
|
|
2666
|
+
const text = await res.text();
|
|
2667
|
+
const results = [];
|
|
2668
|
+
for (const line of text.trim().split("\n")) {
|
|
2669
|
+
if (!line) continue;
|
|
2670
|
+
const item = JSON.parse(line);
|
|
2671
|
+
if (item.result?.type === "succeeded") {
|
|
2672
|
+
results.push({
|
|
2673
|
+
custom_id: item.custom_id,
|
|
2674
|
+
status: "success",
|
|
2675
|
+
response: translateAnthropicMessage(item.result.message),
|
|
2676
|
+
error: null
|
|
2677
|
+
});
|
|
2678
|
+
} else {
|
|
2679
|
+
const errorType = item.result?.type || "unknown";
|
|
2680
|
+
const errorMsg = item.result?.error?.message || `Batch item ${errorType}`;
|
|
2681
|
+
results.push({
|
|
2682
|
+
custom_id: item.custom_id,
|
|
2683
|
+
status: "error",
|
|
2684
|
+
response: null,
|
|
2685
|
+
error: {
|
|
2686
|
+
code: errorType === "expired" ? 408 : 500,
|
|
2687
|
+
message: errorMsg
|
|
2688
|
+
}
|
|
2689
|
+
});
|
|
2690
|
+
}
|
|
2691
|
+
}
|
|
2692
|
+
return results;
|
|
2693
|
+
},
|
|
2694
|
+
async cancelBatch(providerBatchId) {
|
|
2695
|
+
await apiRequest(`/messages/batches/${providerBatchId}/cancel`, { method: "POST" });
|
|
2696
|
+
}
|
|
2697
|
+
};
|
|
2698
|
+
}
|
|
2699
|
+
|
|
1805
2700
|
// src/client.ts
|
|
1806
2701
|
var AnyModel = class {
|
|
1807
2702
|
registry;
|
|
@@ -1817,6 +2712,9 @@ var AnyModel = class {
|
|
|
1817
2712
|
constructor(config = {}) {
|
|
1818
2713
|
this.config = resolveConfig(config);
|
|
1819
2714
|
this.registry = new ProviderRegistry();
|
|
2715
|
+
if (this.config.io) {
|
|
2716
|
+
configureFsIO(this.config.io);
|
|
2717
|
+
}
|
|
1820
2718
|
this.registerProviders();
|
|
1821
2719
|
this.router = new Router(this.registry, this.config.aliases, this.config);
|
|
1822
2720
|
this.chat = {
|
|
@@ -1866,8 +2764,10 @@ var AnyModel = class {
|
|
|
1866
2764
|
};
|
|
1867
2765
|
this.batchManager = new BatchManager(this.router, {
|
|
1868
2766
|
dir: this.config.batch?.dir,
|
|
1869
|
-
concurrency: this.config.batch?.concurrencyFallback
|
|
2767
|
+
concurrency: this.config.batch?.concurrencyFallback,
|
|
2768
|
+
pollInterval: this.config.batch?.pollInterval
|
|
1870
2769
|
});
|
|
2770
|
+
this.registerBatchAdapters();
|
|
1871
2771
|
this.batches = {
|
|
1872
2772
|
create: (request) => this.batchManager.create(request),
|
|
1873
2773
|
createAndPoll: (request, options) => this.batchManager.createAndPoll(request, options),
|
|
@@ -1892,14 +2792,17 @@ var AnyModel = class {
|
|
|
1892
2792
|
if (googleKey) {
|
|
1893
2793
|
this.registry.register("google", createGoogleAdapter(googleKey));
|
|
1894
2794
|
}
|
|
2795
|
+
const perplexityKey = config.perplexity?.apiKey || process.env.PERPLEXITY_API_KEY;
|
|
2796
|
+
if (perplexityKey) {
|
|
2797
|
+
this.registry.register("perplexity", createPerplexityAdapter(perplexityKey));
|
|
2798
|
+
}
|
|
1895
2799
|
const builtinProviders = [
|
|
1896
2800
|
{ name: "mistral", baseURL: "https://api.mistral.ai/v1", configKey: "mistral", envVar: "MISTRAL_API_KEY" },
|
|
1897
2801
|
{ name: "groq", baseURL: "https://api.groq.com/openai/v1", configKey: "groq", envVar: "GROQ_API_KEY" },
|
|
1898
2802
|
{ name: "deepseek", baseURL: "https://api.deepseek.com", configKey: "deepseek", envVar: "DEEPSEEK_API_KEY" },
|
|
1899
2803
|
{ name: "xai", baseURL: "https://api.x.ai/v1", configKey: "xai", envVar: "XAI_API_KEY" },
|
|
1900
2804
|
{ name: "together", baseURL: "https://api.together.xyz/v1", configKey: "together", envVar: "TOGETHER_API_KEY" },
|
|
1901
|
-
{ name: "fireworks", baseURL: "https://api.fireworks.ai/inference/v1", configKey: "fireworks", envVar: "FIREWORKS_API_KEY" }
|
|
1902
|
-
{ name: "perplexity", baseURL: "https://api.perplexity.ai", configKey: "perplexity", envVar: "PERPLEXITY_API_KEY" }
|
|
2805
|
+
{ name: "fireworks", baseURL: "https://api.fireworks.ai/inference/v1", configKey: "fireworks", envVar: "FIREWORKS_API_KEY" }
|
|
1903
2806
|
];
|
|
1904
2807
|
for (const { name, baseURL, configKey, envVar } of builtinProviders) {
|
|
1905
2808
|
const providerConfig = config[configKey];
|
|
@@ -1919,6 +2822,17 @@ var AnyModel = class {
|
|
|
1919
2822
|
}
|
|
1920
2823
|
}
|
|
1921
2824
|
}
|
|
2825
|
+
registerBatchAdapters() {
|
|
2826
|
+
const config = this.config;
|
|
2827
|
+
const openaiKey = config.openai?.apiKey || process.env.OPENAI_API_KEY;
|
|
2828
|
+
if (openaiKey) {
|
|
2829
|
+
this.batchManager.registerBatchAdapter("openai", createOpenAIBatchAdapter(openaiKey));
|
|
2830
|
+
}
|
|
2831
|
+
const anthropicKey = config.anthropic?.apiKey || process.env.ANTHROPIC_API_KEY;
|
|
2832
|
+
if (anthropicKey) {
|
|
2833
|
+
this.batchManager.registerBatchAdapter("anthropic", createAnthropicBatchAdapter(anthropicKey));
|
|
2834
|
+
}
|
|
2835
|
+
}
|
|
1922
2836
|
applyDefaults(request) {
|
|
1923
2837
|
const defaults = this.config.defaults;
|
|
1924
2838
|
if (!defaults) return request;
|
|
@@ -1947,10 +2861,10 @@ var AnyModel = class {
|
|
|
1947
2861
|
// src/server.ts
|
|
1948
2862
|
var import_node_http = require("http");
|
|
1949
2863
|
function parseBody(req) {
|
|
1950
|
-
return new Promise((
|
|
2864
|
+
return new Promise((resolve2, reject) => {
|
|
1951
2865
|
const chunks = [];
|
|
1952
2866
|
req.on("data", (chunk) => chunks.push(chunk));
|
|
1953
|
-
req.on("end", () =>
|
|
2867
|
+
req.on("end", () => resolve2(Buffer.concat(chunks).toString()));
|
|
1954
2868
|
req.on("error", reject);
|
|
1955
2869
|
});
|
|
1956
2870
|
}
|
|
@@ -1980,7 +2894,7 @@ function createAnyModelServer(options = {}) {
|
|
|
1980
2894
|
const basePath = "/api/v1";
|
|
1981
2895
|
const server = (0, import_node_http.createServer)(async (req, res) => {
|
|
1982
2896
|
const url = new URL(req.url || "/", `http://${req.headers.host}`);
|
|
1983
|
-
const
|
|
2897
|
+
const path2 = url.pathname;
|
|
1984
2898
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
1985
2899
|
res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
1986
2900
|
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
|
|
@@ -1990,11 +2904,11 @@ function createAnyModelServer(options = {}) {
|
|
|
1990
2904
|
return;
|
|
1991
2905
|
}
|
|
1992
2906
|
try {
|
|
1993
|
-
if (
|
|
2907
|
+
if (path2 === "/health" && req.method === "GET") {
|
|
1994
2908
|
sendJSON(res, 200, { status: "ok" });
|
|
1995
2909
|
return;
|
|
1996
2910
|
}
|
|
1997
|
-
if (
|
|
2911
|
+
if (path2 === `${basePath}/chat/completions` && req.method === "POST") {
|
|
1998
2912
|
const body = JSON.parse(await parseBody(req));
|
|
1999
2913
|
if (body.stream) {
|
|
2000
2914
|
const stream = await client.chat.completions.create(body);
|
|
@@ -2005,14 +2919,14 @@ function createAnyModelServer(options = {}) {
|
|
|
2005
2919
|
}
|
|
2006
2920
|
return;
|
|
2007
2921
|
}
|
|
2008
|
-
if (
|
|
2922
|
+
if (path2 === `${basePath}/models` && req.method === "GET") {
|
|
2009
2923
|
const provider = url.searchParams.get("provider") || void 0;
|
|
2010
2924
|
const models = await client.models.list({ provider });
|
|
2011
2925
|
sendJSON(res, 200, { object: "list", data: models });
|
|
2012
2926
|
return;
|
|
2013
2927
|
}
|
|
2014
|
-
if (
|
|
2015
|
-
const id =
|
|
2928
|
+
if (path2.startsWith(`${basePath}/generation/`) && req.method === "GET") {
|
|
2929
|
+
const id = path2.substring(`${basePath}/generation/`.length);
|
|
2016
2930
|
const stats = client.generation.get(id);
|
|
2017
2931
|
if (!stats) {
|
|
2018
2932
|
sendError(res, 404, `Generation ${id} not found`);
|
|
@@ -2021,26 +2935,26 @@ function createAnyModelServer(options = {}) {
|
|
|
2021
2935
|
sendJSON(res, 200, stats);
|
|
2022
2936
|
return;
|
|
2023
2937
|
}
|
|
2024
|
-
if (
|
|
2938
|
+
if (path2 === `${basePath}/batches` && req.method === "POST") {
|
|
2025
2939
|
const body = JSON.parse(await parseBody(req));
|
|
2026
2940
|
const batch = await client.batches.create(body);
|
|
2027
2941
|
sendJSON(res, 201, batch);
|
|
2028
2942
|
return;
|
|
2029
2943
|
}
|
|
2030
|
-
if (
|
|
2031
|
-
const batches = client.batches.list();
|
|
2944
|
+
if (path2 === `${basePath}/batches` && req.method === "GET") {
|
|
2945
|
+
const batches = await client.batches.list();
|
|
2032
2946
|
sendJSON(res, 200, { object: "list", data: batches });
|
|
2033
2947
|
return;
|
|
2034
2948
|
}
|
|
2035
|
-
if (
|
|
2036
|
-
const parts =
|
|
2949
|
+
if (path2.startsWith(`${basePath}/batches/`) && req.method === "GET") {
|
|
2950
|
+
const parts = path2.substring(`${basePath}/batches/`.length).split("/");
|
|
2037
2951
|
const id = parts[0];
|
|
2038
2952
|
if (parts[1] === "results") {
|
|
2039
|
-
const results = client.batches.results(id);
|
|
2953
|
+
const results = await client.batches.results(id);
|
|
2040
2954
|
sendJSON(res, 200, results);
|
|
2041
2955
|
return;
|
|
2042
2956
|
}
|
|
2043
|
-
const batch = client.batches.get(id);
|
|
2957
|
+
const batch = await client.batches.get(id);
|
|
2044
2958
|
if (!batch) {
|
|
2045
2959
|
sendError(res, 404, `Batch ${id} not found`);
|
|
2046
2960
|
return;
|
|
@@ -2048,16 +2962,16 @@ function createAnyModelServer(options = {}) {
|
|
|
2048
2962
|
sendJSON(res, 200, batch);
|
|
2049
2963
|
return;
|
|
2050
2964
|
}
|
|
2051
|
-
if (
|
|
2052
|
-
const parts =
|
|
2965
|
+
if (path2.startsWith(`${basePath}/batches/`) && req.method === "POST") {
|
|
2966
|
+
const parts = path2.substring(`${basePath}/batches/`.length).split("/");
|
|
2053
2967
|
const id = parts[0];
|
|
2054
2968
|
if (parts[1] === "cancel") {
|
|
2055
|
-
const batch = client.batches.cancel(id);
|
|
2969
|
+
const batch = await client.batches.cancel(id);
|
|
2056
2970
|
sendJSON(res, 200, batch);
|
|
2057
2971
|
return;
|
|
2058
2972
|
}
|
|
2059
2973
|
}
|
|
2060
|
-
sendError(res, 404, `Not found: ${
|
|
2974
|
+
sendError(res, 404, `Not found: ${path2}`);
|
|
2061
2975
|
} catch (err) {
|
|
2062
2976
|
const code = err?.code || 500;
|
|
2063
2977
|
const message = err?.message || "Internal server error";
|
|
@@ -2093,8 +3007,19 @@ function startServer(options = {}) {
|
|
|
2093
3007
|
BatchManager,
|
|
2094
3008
|
BatchStore,
|
|
2095
3009
|
GenerationStatsStore,
|
|
3010
|
+
appendFileQueued,
|
|
3011
|
+
configureFsIO,
|
|
3012
|
+
createAnthropicBatchAdapter,
|
|
2096
3013
|
createAnyModelServer,
|
|
3014
|
+
createOpenAIBatchAdapter,
|
|
3015
|
+
ensureDir,
|
|
3016
|
+
getFsQueueStatus,
|
|
3017
|
+
joinPath,
|
|
3018
|
+
readFileQueued,
|
|
2097
3019
|
resolveConfig,
|
|
2098
|
-
startServer
|
|
3020
|
+
startServer,
|
|
3021
|
+
waitForFsQueuesIdle,
|
|
3022
|
+
writeFileFlushedQueued,
|
|
3023
|
+
writeFileQueued
|
|
2099
3024
|
});
|
|
2100
3025
|
//# sourceMappingURL=index.cjs.map
|