@careob/llm-gateway 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/dist/gateway.d.ts +36 -0
- package/dist/gateway.d.ts.map +1 -0
- package/dist/gateway.js +256 -0
- package/dist/gateway.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/key-pool.d.ts +23 -0
- package/dist/key-pool.d.ts.map +1 -0
- package/dist/key-pool.js +83 -0
- package/dist/key-pool.js.map +1 -0
- package/dist/middleware.d.ts +21 -0
- package/dist/middleware.d.ts.map +1 -0
- package/dist/middleware.js +83 -0
- package/dist/middleware.js.map +1 -0
- package/dist/registry.d.ts +39 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +413 -0
- package/dist/registry.js.map +1 -0
- package/dist/types.d.ts +112 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +34 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { GatewayConfig, ChatRequest, ChatResponse, StreamChunk } from './types.js';
|
|
2
|
+
export declare class LLMGateway {
|
|
3
|
+
private pool;
|
|
4
|
+
private config;
|
|
5
|
+
private providersByKey;
|
|
6
|
+
constructor(config: GatewayConfig);
|
|
7
|
+
/**
|
|
8
|
+
* Auto-discover keys from environment variables.
|
|
9
|
+
* Scans for OPENAI_API_KEY, ANTHROPIC_KEY, GEMINI_API_KEY_1, DEEPSEEK_KEY, etc.
|
|
10
|
+
*/
|
|
11
|
+
static fromEnv(overrides?: Omit<GatewayConfig, 'keys'>, env?: Record<string, string | undefined>): LLMGateway;
|
|
12
|
+
chat(request: ChatRequest): Promise<ChatResponse>;
|
|
13
|
+
chatStream(request: ChatRequest): AsyncGenerator<StreamChunk, void, unknown>;
|
|
14
|
+
/** Get health/stats for all registered keys */
|
|
15
|
+
getStats(): {
|
|
16
|
+
provider: string;
|
|
17
|
+
label: string;
|
|
18
|
+
healthy: boolean;
|
|
19
|
+
requestsThisMinute: number;
|
|
20
|
+
totalRequests: number;
|
|
21
|
+
totalErrors: number;
|
|
22
|
+
cooldownUntil: number;
|
|
23
|
+
}[];
|
|
24
|
+
/** List all registered providers */
|
|
25
|
+
getProviders(): string[];
|
|
26
|
+
private registerKeys;
|
|
27
|
+
private resolveProviders;
|
|
28
|
+
private logUsage;
|
|
29
|
+
}
|
|
30
|
+
export type GatewayErrorCode = 'CONFIG_ERROR' | 'PROVIDER_ERROR' | 'NETWORK_ERROR' | 'TIMEOUT' | 'ALL_EXHAUSTED' | 'UNSUPPORTED';
|
|
31
|
+
export declare class GatewayError extends Error {
|
|
32
|
+
code: GatewayErrorCode;
|
|
33
|
+
statusCode?: number | undefined;
|
|
34
|
+
constructor(message: string, code: GatewayErrorCode, statusCode?: number | undefined);
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=gateway.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../src/gateway.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,aAAa,EAEb,WAAW,EACX,YAAY,EACZ,WAAW,EAIZ,MAAM,YAAY,CAAC;AAEpB,qBAAa,UAAU;IACrB,OAAO,CAAC,IAAI,CAAU;IACtB,OAAO,CAAC,MAAM,CAAgF;IAC9F,OAAO,CAAC,cAAc,CAAkC;gBAE5C,MAAM,EAAE,aAAa;IAWjC;;;OAGG;IACH,MAAM,CAAC,OAAO,CACZ,SAAS,GAAE,IAAI,CAAC,aAAa,EAAE,MAAM,CAAM,EAC3C,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GACvC,UAAU;IAWP,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAwEhD,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,cAAc,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,CAAC;IAwFnF,+CAA+C;IAC/C,QAAQ;;;;;;;;;IAIR,oCAAoC;IACpC,YAAY;IAMZ,OAAO,CAAC,YAAY;IA8BpB,OAAO,CAAC,gBAAgB;IAqBxB,OAAO,CAAC,QAAQ;CAoCjB;AAED,MAAM,MAAM,gBAAgB,GACxB,cAAc,GACd,gBAAgB,GAChB,eAAe,GACf,SAAS,GACT,eAAe,GACf,aAAa,CAAC;AAElB,qBAAa,YAAa,SAAQ,KAAK;IAG5B,IAAI,EAAE,gBAAgB;IACtB,UAAU,CAAC,EAAE,MAAM;gBAF1B,OAAO,EAAE,MAAM,EACR,IAAI,EAAE,gBAAgB,EACtB,UAAU,CAAC,EAAE,MAAM,YAAA;CAK7B"}
|
package/dist/gateway.js
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { KeyPool } from './key-pool.js';
|
|
2
|
+
import { PROVIDERS, detectProvider, discoverKeysFromEnv, findProviderForModel, buildRequest, parseResponse, parseStreamChunk, estimateCost, } from './registry.js';
|
|
3
|
+
export class LLMGateway {
|
|
4
|
+
pool;
|
|
5
|
+
config;
|
|
6
|
+
providersByKey = new Map();
|
|
7
|
+
constructor(config) {
|
|
8
|
+
this.config = {
|
|
9
|
+
...config,
|
|
10
|
+
maxRetries: config.maxRetries ?? 3,
|
|
11
|
+
cooldownMs: config.cooldownMs ?? 60_000,
|
|
12
|
+
timeoutMs: config.timeoutMs ?? 30_000,
|
|
13
|
+
};
|
|
14
|
+
this.pool = new KeyPool(this.config.cooldownMs);
|
|
15
|
+
this.registerKeys(config.keys);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Auto-discover keys from environment variables.
|
|
19
|
+
* Scans for OPENAI_API_KEY, ANTHROPIC_KEY, GEMINI_API_KEY_1, DEEPSEEK_KEY, etc.
|
|
20
|
+
*/
|
|
21
|
+
static fromEnv(overrides = {}, env) {
|
|
22
|
+
const discovered = discoverKeysFromEnv(env);
|
|
23
|
+
if (discovered.length === 0) {
|
|
24
|
+
throw new GatewayError('No API keys found in environment. Expected vars like OPENAI_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY, etc.', 'CONFIG_ERROR');
|
|
25
|
+
}
|
|
26
|
+
return new LLMGateway({
|
|
27
|
+
...overrides,
|
|
28
|
+
keys: discovered.map((d) => ({ key: d.key, provider: d.provider, label: d.label })),
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
async chat(request) {
|
|
32
|
+
const model = request.model ?? this.config.defaultModel;
|
|
33
|
+
if (!model)
|
|
34
|
+
throw new GatewayError('No model specified and no defaultModel configured', 'CONFIG_ERROR');
|
|
35
|
+
const fullRequest = { ...request, model, stream: false };
|
|
36
|
+
const providers = this.resolveProviders(fullRequest);
|
|
37
|
+
let lastError = null;
|
|
38
|
+
let attempt = 0;
|
|
39
|
+
for (const providerDef of providers) {
|
|
40
|
+
for (let retry = 0; retry < this.config.maxRetries; retry++) {
|
|
41
|
+
const key = this.pool.getNextKey(providerDef.id);
|
|
42
|
+
if (!key)
|
|
43
|
+
break;
|
|
44
|
+
attempt++;
|
|
45
|
+
const requestId = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
46
|
+
const start = Date.now();
|
|
47
|
+
try {
|
|
48
|
+
const { url, init } = buildRequest(providerDef, fullRequest, key.key);
|
|
49
|
+
const controller = new AbortController();
|
|
50
|
+
const timeout = setTimeout(() => controller.abort(), this.config.timeoutMs);
|
|
51
|
+
init.signal = controller.signal;
|
|
52
|
+
const res = await fetch(url, init);
|
|
53
|
+
clearTimeout(timeout);
|
|
54
|
+
if (res.status === 429) {
|
|
55
|
+
this.pool.recordRateLimit(key);
|
|
56
|
+
this.logUsage(requestId, providerDef.id, key, model, start, 'rate_limited', undefined, 'Rate limited');
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
if (!res.ok) {
|
|
60
|
+
const errorText = await res.text().catch(() => `HTTP ${res.status}`);
|
|
61
|
+
this.pool.recordError(key);
|
|
62
|
+
lastError = new GatewayError(`${providerDef.label}: ${errorText}`, 'PROVIDER_ERROR', res.status);
|
|
63
|
+
this.logUsage(requestId, providerDef.id, key, model, start, 'error', undefined, errorText);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const data = await res.json();
|
|
67
|
+
const parsed = parseResponse(providerDef, data);
|
|
68
|
+
parsed._gateway = {
|
|
69
|
+
provider: providerDef.id,
|
|
70
|
+
keyLabel: key.label,
|
|
71
|
+
latencyMs: Date.now() - start,
|
|
72
|
+
attempt,
|
|
73
|
+
};
|
|
74
|
+
this.pool.recordSuccess(key, parsed.usage.total_tokens);
|
|
75
|
+
this.logUsage(requestId, providerDef.id, key, model, start, 'success', parsed.usage, undefined, request.metadata);
|
|
76
|
+
return parsed;
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
80
|
+
this.pool.recordError(key);
|
|
81
|
+
if (msg.includes('abort')) {
|
|
82
|
+
lastError = new GatewayError(`${providerDef.label}: timeout`, 'TIMEOUT');
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
lastError = err instanceof GatewayError ? err : new GatewayError(`${providerDef.label}: ${msg}`, 'NETWORK_ERROR');
|
|
86
|
+
}
|
|
87
|
+
this.logUsage(requestId, providerDef.id, key, model, start, 'error', undefined, msg);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
this.config.onAllKeysExhausted?.(providerDef.id);
|
|
91
|
+
}
|
|
92
|
+
throw lastError ?? new GatewayError('All providers and keys exhausted', 'ALL_EXHAUSTED');
|
|
93
|
+
}
|
|
94
|
+
async *chatStream(request) {
|
|
95
|
+
const model = request.model ?? this.config.defaultModel;
|
|
96
|
+
if (!model)
|
|
97
|
+
throw new GatewayError('No model specified and no defaultModel configured', 'CONFIG_ERROR');
|
|
98
|
+
const fullRequest = { ...request, model, stream: true };
|
|
99
|
+
const providers = this.resolveProviders(fullRequest);
|
|
100
|
+
let lastError = null;
|
|
101
|
+
for (const providerDef of providers) {
|
|
102
|
+
if (providerDef.format !== 'openai') {
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
for (let retry = 0; retry < this.config.maxRetries; retry++) {
|
|
106
|
+
const key = this.pool.getNextKey(providerDef.id);
|
|
107
|
+
if (!key)
|
|
108
|
+
break;
|
|
109
|
+
const requestId = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
110
|
+
const start = Date.now();
|
|
111
|
+
try {
|
|
112
|
+
const { url, init } = buildRequest(providerDef, fullRequest, key.key);
|
|
113
|
+
const controller = new AbortController();
|
|
114
|
+
const timeout = setTimeout(() => controller.abort(), this.config.timeoutMs * 3);
|
|
115
|
+
init.signal = controller.signal;
|
|
116
|
+
const res = await fetch(url, init);
|
|
117
|
+
clearTimeout(timeout);
|
|
118
|
+
if (res.status === 429) {
|
|
119
|
+
this.pool.recordRateLimit(key);
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
if (!res.ok) {
|
|
123
|
+
this.pool.recordError(key);
|
|
124
|
+
lastError = new GatewayError(`${providerDef.label}: HTTP ${res.status}`, 'PROVIDER_ERROR', res.status);
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if (!res.body)
|
|
128
|
+
throw new GatewayError('No response body for stream', 'PROVIDER_ERROR');
|
|
129
|
+
const reader = res.body.getReader();
|
|
130
|
+
const decoder = new TextDecoder();
|
|
131
|
+
let buffer = '';
|
|
132
|
+
let totalTokens = 0;
|
|
133
|
+
try {
|
|
134
|
+
while (true) {
|
|
135
|
+
const { done, value } = await reader.read();
|
|
136
|
+
if (done)
|
|
137
|
+
break;
|
|
138
|
+
buffer += decoder.decode(value, { stream: true });
|
|
139
|
+
const lines = buffer.split('\n');
|
|
140
|
+
buffer = lines.pop() ?? '';
|
|
141
|
+
for (const line of lines) {
|
|
142
|
+
const chunk = parseStreamChunk(line);
|
|
143
|
+
if (chunk) {
|
|
144
|
+
if (chunk.usage)
|
|
145
|
+
totalTokens = chunk.usage.total_tokens;
|
|
146
|
+
yield chunk;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
finally {
|
|
152
|
+
reader.releaseLock();
|
|
153
|
+
}
|
|
154
|
+
this.pool.recordSuccess(key, totalTokens);
|
|
155
|
+
this.logUsage(requestId, providerDef.id, key, model, start, 'success', {
|
|
156
|
+
prompt_tokens: 0, completion_tokens: 0, total_tokens: totalTokens,
|
|
157
|
+
}, undefined, request.metadata);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
catch (err) {
|
|
161
|
+
if (err instanceof GatewayError)
|
|
162
|
+
throw err;
|
|
163
|
+
this.pool.recordError(key);
|
|
164
|
+
lastError = new GatewayError(`${providerDef.label}: ${err instanceof Error ? err.message : String(err)}`, 'NETWORK_ERROR');
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
throw lastError ?? new GatewayError('All providers exhausted for streaming', 'ALL_EXHAUSTED');
|
|
169
|
+
}
|
|
170
|
+
/** Get health/stats for all registered keys */
|
|
171
|
+
getStats() {
|
|
172
|
+
return this.pool.getStats();
|
|
173
|
+
}
|
|
174
|
+
/** List all registered providers */
|
|
175
|
+
getProviders() {
|
|
176
|
+
return this.pool.getProviders();
|
|
177
|
+
}
|
|
178
|
+
// ── Private ──────────────────────────────────────────────────
|
|
179
|
+
registerKeys(keys) {
|
|
180
|
+
let autoIndex = 0;
|
|
181
|
+
for (const input of keys) {
|
|
182
|
+
const normalized = typeof input === 'string' ? { key: input } : input;
|
|
183
|
+
const providerId = normalized.provider ?? detectProvider(normalized.key);
|
|
184
|
+
if (!providerId) {
|
|
185
|
+
throw new GatewayError(`Cannot auto-detect provider for key "${normalized.key.slice(0, 4)}****". ` +
|
|
186
|
+
`Pass { key, provider: "deepseek" } explicitly.`, 'CONFIG_ERROR');
|
|
187
|
+
}
|
|
188
|
+
const providerDef = PROVIDERS[providerId];
|
|
189
|
+
if (!providerDef) {
|
|
190
|
+
throw new GatewayError(`Unknown provider "${providerId}". Known: ${Object.keys(PROVIDERS).join(', ')}`, 'CONFIG_ERROR');
|
|
191
|
+
}
|
|
192
|
+
autoIndex++;
|
|
193
|
+
const label = normalized.label ?? `${providerId}-${autoIndex}`;
|
|
194
|
+
const rpm = normalized.rpm ?? providerDef.defaultRpm;
|
|
195
|
+
const tpm = normalized.tpm ?? 0;
|
|
196
|
+
this.pool.addKey(normalized.key, providerId, label, rpm, tpm);
|
|
197
|
+
this.providersByKey.set(normalized.key, providerDef);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
resolveProviders(request) {
|
|
201
|
+
if (request.provider) {
|
|
202
|
+
const def = PROVIDERS[request.provider];
|
|
203
|
+
if (!def)
|
|
204
|
+
throw new GatewayError(`Provider "${request.provider}" not found`, 'CONFIG_ERROR');
|
|
205
|
+
return [def];
|
|
206
|
+
}
|
|
207
|
+
const registeredProviders = this.pool.getProviders();
|
|
208
|
+
const modelProvider = findProviderForModel(request.model);
|
|
209
|
+
if (modelProvider && registeredProviders.includes(modelProvider.id)) {
|
|
210
|
+
const others = registeredProviders
|
|
211
|
+
.filter((id) => id !== modelProvider.id)
|
|
212
|
+
.map((id) => PROVIDERS[id])
|
|
213
|
+
.filter(Boolean);
|
|
214
|
+
return [modelProvider, ...others];
|
|
215
|
+
}
|
|
216
|
+
return registeredProviders.map((id) => PROVIDERS[id]).filter(Boolean);
|
|
217
|
+
}
|
|
218
|
+
logUsage(requestId, provider, key, model, startMs, status, usage, error, metadata) {
|
|
219
|
+
if (!this.config.onUsage)
|
|
220
|
+
return;
|
|
221
|
+
const log = {
|
|
222
|
+
requestId,
|
|
223
|
+
provider,
|
|
224
|
+
keyLabel: key.label,
|
|
225
|
+
model,
|
|
226
|
+
promptTokens: usage?.prompt_tokens ?? 0,
|
|
227
|
+
completionTokens: usage?.completion_tokens ?? 0,
|
|
228
|
+
totalTokens: usage?.total_tokens ?? 0,
|
|
229
|
+
estimatedCostUsd: usage ? estimateCost(model, usage.prompt_tokens, usage.completion_tokens) : 0,
|
|
230
|
+
latencyMs: Date.now() - startMs,
|
|
231
|
+
status,
|
|
232
|
+
error,
|
|
233
|
+
metadata,
|
|
234
|
+
timestamp: new Date(),
|
|
235
|
+
};
|
|
236
|
+
try {
|
|
237
|
+
const result = this.config.onUsage(log);
|
|
238
|
+
if (result instanceof Promise)
|
|
239
|
+
result.catch(() => { });
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
// spend tracking should never crash the gateway
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
export class GatewayError extends Error {
|
|
247
|
+
code;
|
|
248
|
+
statusCode;
|
|
249
|
+
constructor(message, code, statusCode) {
|
|
250
|
+
super(message);
|
|
251
|
+
this.code = code;
|
|
252
|
+
this.statusCode = statusCode;
|
|
253
|
+
this.name = 'GatewayError';
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
//# sourceMappingURL=gateway.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gateway.js","sourceRoot":"","sources":["../src/gateway.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { LLMGateway, GatewayError } from './gateway.js';
|
|
2
|
+
export type { GatewayErrorCode } from './gateway.js';
|
|
3
|
+
export { KeyPool } from './key-pool.js';
|
|
4
|
+
export { createExpressProxy } from './middleware.js';
|
|
5
|
+
export type { ProxyOptions } from './middleware.js';
|
|
6
|
+
export { PROVIDERS, detectProvider, discoverKeysFromEnv, findProviderForModel, estimateCost, } from './registry.js';
|
|
7
|
+
export type { ProviderDef, ApiFormat, AuthStyle } from './registry.js';
|
|
8
|
+
export type { KeyInput, GatewayConfig, ChatMessage, ChatRequest, ChatResponse, StreamChunk, TokenUsage, UsageLog, KeyState, } from './types.js';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACxD,YAAY,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EACL,SAAS,EACT,cAAc,EACd,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,GACb,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACvE,YAAY,EACV,QAAQ,EACR,aAAa,EACb,WAAW,EACX,WAAW,EACX,YAAY,EACZ,WAAW,EACX,UAAU,EACV,QAAQ,EACR,QAAQ,GACT,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { LLMGateway, GatewayError } from './gateway.js';
|
|
2
|
+
export { KeyPool } from './key-pool.js';
|
|
3
|
+
export { createExpressProxy } from './middleware.js';
|
|
4
|
+
export { PROVIDERS, detectProvider, discoverKeysFromEnv, findProviderForModel, estimateCost, } from './registry.js';
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAExD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErD,OAAO,EACL,SAAS,EACT,cAAc,EACd,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,GACb,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { KeyState } from './types.js';
|
|
2
|
+
export declare class KeyPool {
|
|
3
|
+
private cooldownMs;
|
|
4
|
+
private keys;
|
|
5
|
+
private roundRobinIndex;
|
|
6
|
+
constructor(cooldownMs: number);
|
|
7
|
+
addKey(key: string, provider: string, label: string, rpm: number, tpm: number): void;
|
|
8
|
+
getNextKey(provider: string): KeyState | null;
|
|
9
|
+
recordSuccess(key: KeyState, tokens: number): void;
|
|
10
|
+
recordRateLimit(key: KeyState): void;
|
|
11
|
+
recordError(key: KeyState): void;
|
|
12
|
+
getProviders(): string[];
|
|
13
|
+
getStats(): {
|
|
14
|
+
provider: string;
|
|
15
|
+
label: string;
|
|
16
|
+
healthy: boolean;
|
|
17
|
+
requestsThisMinute: number;
|
|
18
|
+
totalRequests: number;
|
|
19
|
+
totalErrors: number;
|
|
20
|
+
cooldownUntil: number;
|
|
21
|
+
}[];
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=key-pool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key-pool.d.ts","sourceRoot":"","sources":["../src/key-pool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,qBAAa,OAAO;IAIN,OAAO,CAAC,UAAU;IAH9B,OAAO,CAAC,IAAI,CAAkB;IAC9B,OAAO,CAAC,eAAe,CAAK;gBAER,UAAU,EAAE,MAAM;IAEtC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAiBpF,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;IAgC7C,aAAa,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAMlD,eAAe,CAAC,GAAG,EAAE,QAAQ,GAAG,IAAI;IAMpC,WAAW,CAAC,GAAG,EAAE,QAAQ,GAAG,IAAI;IAIhC,YAAY,IAAI,MAAM,EAAE;IAIxB,QAAQ;;;;;;;;;CAWT"}
|
package/dist/key-pool.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
export class KeyPool {
|
|
2
|
+
cooldownMs;
|
|
3
|
+
keys = [];
|
|
4
|
+
roundRobinIndex = 0;
|
|
5
|
+
constructor(cooldownMs) {
|
|
6
|
+
this.cooldownMs = cooldownMs;
|
|
7
|
+
}
|
|
8
|
+
addKey(key, provider, label, rpm, tpm) {
|
|
9
|
+
this.keys.push({
|
|
10
|
+
key,
|
|
11
|
+
provider,
|
|
12
|
+
label,
|
|
13
|
+
rpm,
|
|
14
|
+
tpm,
|
|
15
|
+
requestsThisMinute: 0,
|
|
16
|
+
tokensThisMinute: 0,
|
|
17
|
+
minuteStart: Date.now(),
|
|
18
|
+
cooldownUntil: 0,
|
|
19
|
+
totalRequests: 0,
|
|
20
|
+
totalErrors: 0,
|
|
21
|
+
healthy: true,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
getNextKey(provider) {
|
|
25
|
+
const candidates = this.keys.filter((k) => k.provider === provider);
|
|
26
|
+
if (candidates.length === 0)
|
|
27
|
+
return null;
|
|
28
|
+
const now = Date.now();
|
|
29
|
+
const startIdx = this.roundRobinIndex % candidates.length;
|
|
30
|
+
for (let i = 0; i < candidates.length; i++) {
|
|
31
|
+
const idx = (startIdx + i) % candidates.length;
|
|
32
|
+
const key = candidates[idx];
|
|
33
|
+
if (now - key.minuteStart > 60_000) {
|
|
34
|
+
key.requestsThisMinute = 0;
|
|
35
|
+
key.tokensThisMinute = 0;
|
|
36
|
+
key.minuteStart = now;
|
|
37
|
+
}
|
|
38
|
+
if (key.cooldownUntil > now)
|
|
39
|
+
continue;
|
|
40
|
+
if (!key.healthy) {
|
|
41
|
+
if (key.cooldownUntil <= now)
|
|
42
|
+
key.healthy = true;
|
|
43
|
+
else
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (key.requestsThisMinute >= key.rpm)
|
|
47
|
+
continue;
|
|
48
|
+
if (key.tpm > 0 && key.tokensThisMinute >= key.tpm)
|
|
49
|
+
continue;
|
|
50
|
+
this.roundRobinIndex = idx + 1;
|
|
51
|
+
return key;
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
recordSuccess(key, tokens) {
|
|
56
|
+
key.requestsThisMinute++;
|
|
57
|
+
key.tokensThisMinute += tokens;
|
|
58
|
+
key.totalRequests++;
|
|
59
|
+
}
|
|
60
|
+
recordRateLimit(key) {
|
|
61
|
+
key.cooldownUntil = Date.now() + this.cooldownMs;
|
|
62
|
+
key.healthy = false;
|
|
63
|
+
key.totalErrors++;
|
|
64
|
+
}
|
|
65
|
+
recordError(key) {
|
|
66
|
+
key.totalErrors++;
|
|
67
|
+
}
|
|
68
|
+
getProviders() {
|
|
69
|
+
return [...new Set(this.keys.map((k) => k.provider))];
|
|
70
|
+
}
|
|
71
|
+
getStats() {
|
|
72
|
+
return this.keys.map((k) => ({
|
|
73
|
+
provider: k.provider,
|
|
74
|
+
label: k.label,
|
|
75
|
+
healthy: k.healthy && k.cooldownUntil <= Date.now(),
|
|
76
|
+
requestsThisMinute: k.requestsThisMinute,
|
|
77
|
+
totalRequests: k.totalRequests,
|
|
78
|
+
totalErrors: k.totalErrors,
|
|
79
|
+
cooldownUntil: k.cooldownUntil,
|
|
80
|
+
}));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=key-pool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key-pool.js","sourceRoot":"","sources":["../src/key-pool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Request, Response } from 'express';
|
|
2
|
+
import { LLMGateway } from './gateway.js';
|
|
3
|
+
export interface ProxyOptions {
|
|
4
|
+
/** Optional auth check before proxying. Return true to allow. */
|
|
5
|
+
authorize?: (req: Request) => boolean | Promise<boolean>;
|
|
6
|
+
/** Extract metadata from request for spend tracking */
|
|
7
|
+
extractMetadata?: (req: Request) => Record<string, string>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Returns Express route handlers you can mount on any route.
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* const proxy = createExpressProxy(gateway);
|
|
14
|
+
* app.post('/llm/v1/chat/completions', proxy.chatCompletions);
|
|
15
|
+
* app.get('/llm/v1/health', proxy.health);
|
|
16
|
+
*/
|
|
17
|
+
export declare function createExpressProxy(gateway: LLMGateway, options?: ProxyOptions): {
|
|
18
|
+
chatCompletions: (req: Request, res: Response) => Promise<void>;
|
|
19
|
+
health: (_req: Request, res: Response) => void;
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,EAAE,UAAU,EAAgB,MAAM,cAAc,CAAC;AAGxD,MAAM,WAAW,YAAY;IAC3B,iEAAiE;IACjE,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACzD,uDAAuD;IACvD,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC5D;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,GAAE,YAAiB;2BAC5C,OAAO,OAAO,QAAQ;mBAiEpC,OAAO,OAAO,QAAQ;EAU7C"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { GatewayError } from './gateway.js';
|
|
2
|
+
/**
|
|
3
|
+
* Returns Express route handlers you can mount on any route.
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* const proxy = createExpressProxy(gateway);
|
|
7
|
+
* app.post('/llm/v1/chat/completions', proxy.chatCompletions);
|
|
8
|
+
* app.get('/llm/v1/health', proxy.health);
|
|
9
|
+
*/
|
|
10
|
+
export function createExpressProxy(gateway, options = {}) {
|
|
11
|
+
const chatCompletions = async (req, res) => {
|
|
12
|
+
const body = req.body;
|
|
13
|
+
if (!body?.messages) {
|
|
14
|
+
res.status(400).json({ error: 'messages is required' });
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (options.authorize) {
|
|
18
|
+
try {
|
|
19
|
+
const allowed = await options.authorize(req);
|
|
20
|
+
if (!allowed) {
|
|
21
|
+
res.status(401).json({ error: 'Unauthorized' });
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
res.status(401).json({ error: 'Authorization failed' });
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const metadata = options.extractMetadata?.(req);
|
|
31
|
+
const request = {
|
|
32
|
+
model: body.model,
|
|
33
|
+
messages: body.messages,
|
|
34
|
+
temperature: body.temperature,
|
|
35
|
+
max_tokens: body.max_tokens,
|
|
36
|
+
top_p: body.top_p,
|
|
37
|
+
stream: body.stream,
|
|
38
|
+
tools: body.tools,
|
|
39
|
+
tool_choice: body.tool_choice,
|
|
40
|
+
response_format: body.response_format,
|
|
41
|
+
provider: body.provider,
|
|
42
|
+
metadata,
|
|
43
|
+
};
|
|
44
|
+
if (body.stream) {
|
|
45
|
+
res.setHeader('Content-Type', 'text/event-stream');
|
|
46
|
+
res.setHeader('Cache-Control', 'no-cache');
|
|
47
|
+
res.setHeader('Connection', 'keep-alive');
|
|
48
|
+
try {
|
|
49
|
+
for await (const chunk of gateway.chatStream(request)) {
|
|
50
|
+
res.write(`data: ${JSON.stringify(chunk)}\n\n`);
|
|
51
|
+
}
|
|
52
|
+
res.write('data: [DONE]\n\n');
|
|
53
|
+
res.end();
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
const ge = err instanceof GatewayError ? err : new GatewayError(String(err), 'PROVIDER_ERROR');
|
|
57
|
+
res.write(`data: ${JSON.stringify({ error: ge.message, code: ge.code })}\n\n`);
|
|
58
|
+
res.end();
|
|
59
|
+
}
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
const response = await gateway.chat(request);
|
|
64
|
+
res.json(response);
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
const ge = err instanceof GatewayError ? err : new GatewayError(String(err), 'PROVIDER_ERROR');
|
|
68
|
+
res.status(ge.statusCode ?? 502).json({
|
|
69
|
+
error: { message: ge.message, code: ge.code },
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
const health = (_req, res) => {
|
|
74
|
+
const stats = gateway.getStats();
|
|
75
|
+
const healthy = stats.some((s) => s.healthy);
|
|
76
|
+
res.status(healthy ? 200 : 503).json({
|
|
77
|
+
status: healthy ? 'healthy' : 'degraded',
|
|
78
|
+
keys: stats,
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
return { chatCompletions, health };
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { ChatRequest, ChatResponse, TokenUsage } from './types.js';
|
|
2
|
+
export type ApiFormat = 'openai' | 'anthropic' | 'gemini';
|
|
3
|
+
export type AuthStyle = 'bearer' | 'x-api-key' | 'query';
|
|
4
|
+
export interface ProviderDef {
|
|
5
|
+
id: string;
|
|
6
|
+
label: string;
|
|
7
|
+
baseUrl: string;
|
|
8
|
+
format: ApiFormat;
|
|
9
|
+
authStyle: AuthStyle;
|
|
10
|
+
extraHeaders?: Record<string, string>;
|
|
11
|
+
keyPatterns: RegExp[];
|
|
12
|
+
envPrefixes: string[];
|
|
13
|
+
models: string[];
|
|
14
|
+
defaultRpm: number;
|
|
15
|
+
costs: Record<string, {
|
|
16
|
+
prompt: number;
|
|
17
|
+
completion: number;
|
|
18
|
+
}>;
|
|
19
|
+
}
|
|
20
|
+
export declare const PROVIDERS: Record<string, ProviderDef>;
|
|
21
|
+
export declare function detectProvider(key: string): string | null;
|
|
22
|
+
export declare function discoverKeysFromEnv(env?: Record<string, string | undefined>): Array<{
|
|
23
|
+
key: string;
|
|
24
|
+
provider: string;
|
|
25
|
+
label: string;
|
|
26
|
+
}>;
|
|
27
|
+
export declare function buildRequest(provider: ProviderDef, request: ChatRequest, apiKey: string): {
|
|
28
|
+
url: string;
|
|
29
|
+
init: RequestInit;
|
|
30
|
+
};
|
|
31
|
+
export declare function parseResponse(provider: ProviderDef, data: unknown): ChatResponse;
|
|
32
|
+
export declare function parseStreamChunk(line: string): StreamChunkResult | null;
|
|
33
|
+
type StreamChunkResult = import('./types.js').StreamChunk & {
|
|
34
|
+
usage?: TokenUsage;
|
|
35
|
+
};
|
|
36
|
+
export declare function estimateCost(model: string, promptTokens: number, completionTokens: number): number;
|
|
37
|
+
export declare function findProviderForModel(model: string): ProviderDef | null;
|
|
38
|
+
export {};
|
|
39
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAMrF,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,WAAW,GAAG,QAAQ,CAAC;AAC1D,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,WAAW,GAAG,OAAO,CAAC;AAIzD,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,SAAS,CAAC;IAClB,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC/D;AAKD,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAuMjD,CAAC;AAIF,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQzD;AAED,wBAAgB,mBAAmB,CACjC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAqD,GAC1F,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAuBzD;AAKD,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,WAAW,EACrB,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,MAAM,GACb;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,WAAW,CAAA;CAAE,CAyBpC;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,GAAG,YAAY,CAOhF;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAUvE;AAED,KAAK,iBAAiB,GAAG,OAAO,YAAY,EAAE,WAAW,GAAG;IAAE,KAAK,CAAC,EAAE,UAAU,CAAA;CAAE,CAAC;AAInF,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,MAAM,CASlG;AAID,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAKtE"}
|
package/dist/registry.js
ADDED
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
// ─── Provider Registry ────────────────────────────────────────
|
|
2
|
+
// To add a new provider: add one object here. That's it.
|
|
3
|
+
export const PROVIDERS = {
|
|
4
|
+
openai: {
|
|
5
|
+
id: 'openai',
|
|
6
|
+
label: 'OpenAI',
|
|
7
|
+
baseUrl: 'https://api.openai.com/v1',
|
|
8
|
+
format: 'openai',
|
|
9
|
+
authStyle: 'bearer',
|
|
10
|
+
keyPatterns: [/^sk-proj-/],
|
|
11
|
+
envPrefixes: ['OPENAI'],
|
|
12
|
+
models: ['gpt-4o', 'gpt-4o-mini', 'gpt-4-turbo', 'gpt-4', 'gpt-3.5-turbo', 'o1', 'o1-mini', 'o3-mini', 'o4-mini'],
|
|
13
|
+
defaultRpm: 500,
|
|
14
|
+
costs: {
|
|
15
|
+
'gpt-4o': { prompt: 2.5, completion: 10 },
|
|
16
|
+
'gpt-4o-mini': { prompt: 0.15, completion: 0.6 },
|
|
17
|
+
'gpt-4-turbo': { prompt: 10, completion: 30 },
|
|
18
|
+
'gpt-4': { prompt: 30, completion: 60 },
|
|
19
|
+
'gpt-3.5-turbo': { prompt: 0.5, completion: 1.5 },
|
|
20
|
+
'o1': { prompt: 15, completion: 60 },
|
|
21
|
+
'o1-mini': { prompt: 3, completion: 12 },
|
|
22
|
+
'o3-mini': { prompt: 1.1, completion: 4.4 },
|
|
23
|
+
'o4-mini': { prompt: 1.1, completion: 4.4 },
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
anthropic: {
|
|
27
|
+
id: 'anthropic',
|
|
28
|
+
label: 'Anthropic',
|
|
29
|
+
baseUrl: 'https://api.anthropic.com/v1',
|
|
30
|
+
format: 'anthropic',
|
|
31
|
+
authStyle: 'x-api-key',
|
|
32
|
+
extraHeaders: { 'anthropic-version': '2023-06-01' },
|
|
33
|
+
keyPatterns: [/^sk-ant-/],
|
|
34
|
+
envPrefixes: ['ANTHROPIC', 'CLAUDE'],
|
|
35
|
+
models: ['claude-opus-4-20250514', 'claude-sonnet-4-20250514', 'claude-haiku-3-5-20241022'],
|
|
36
|
+
defaultRpm: 300,
|
|
37
|
+
costs: {
|
|
38
|
+
'claude-opus-4-20250514': { prompt: 15, completion: 75 },
|
|
39
|
+
'claude-sonnet-4-20250514': { prompt: 3, completion: 15 },
|
|
40
|
+
'claude-haiku-3-5-20241022': { prompt: 0.8, completion: 4 },
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
gemini: {
|
|
44
|
+
id: 'gemini',
|
|
45
|
+
label: 'Google Gemini',
|
|
46
|
+
baseUrl: 'https://generativelanguage.googleapis.com/v1beta',
|
|
47
|
+
format: 'gemini',
|
|
48
|
+
authStyle: 'query',
|
|
49
|
+
keyPatterns: [/^AIza/],
|
|
50
|
+
envPrefixes: ['GEMINI', 'GOOGLE_AI'],
|
|
51
|
+
models: ['gemini-2.5-pro', 'gemini-2.5-flash', 'gemini-2.0-flash', 'gemini-1.5-pro', 'gemini-1.5-flash'],
|
|
52
|
+
defaultRpm: 360,
|
|
53
|
+
costs: {
|
|
54
|
+
'gemini-2.5-pro': { prompt: 1.25, completion: 10 },
|
|
55
|
+
'gemini-2.5-flash': { prompt: 0.15, completion: 0.6 },
|
|
56
|
+
'gemini-2.0-flash': { prompt: 0.1, completion: 0.4 },
|
|
57
|
+
'gemini-1.5-pro': { prompt: 1.25, completion: 5 },
|
|
58
|
+
'gemini-1.5-flash': { prompt: 0.075, completion: 0.3 },
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
deepseek: {
|
|
62
|
+
id: 'deepseek',
|
|
63
|
+
label: 'DeepSeek',
|
|
64
|
+
baseUrl: 'https://api.deepseek.com/v1',
|
|
65
|
+
format: 'openai',
|
|
66
|
+
authStyle: 'bearer',
|
|
67
|
+
keyPatterns: [/^sk-[a-f0-9]{48}$/],
|
|
68
|
+
envPrefixes: ['DEEPSEEK'],
|
|
69
|
+
models: ['deepseek-chat', 'deepseek-coder', 'deepseek-reasoner'],
|
|
70
|
+
defaultRpm: 300,
|
|
71
|
+
costs: {
|
|
72
|
+
'deepseek-chat': { prompt: 0.14, completion: 0.28 },
|
|
73
|
+
'deepseek-coder': { prompt: 0.14, completion: 0.28 },
|
|
74
|
+
'deepseek-reasoner': { prompt: 0.55, completion: 2.19 },
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
qwen: {
|
|
78
|
+
id: 'qwen',
|
|
79
|
+
label: 'Alibaba Qwen',
|
|
80
|
+
baseUrl: 'https://dashscope.aliyuncs.com/compatible-mode/v1',
|
|
81
|
+
format: 'openai',
|
|
82
|
+
authStyle: 'bearer',
|
|
83
|
+
keyPatterns: [],
|
|
84
|
+
envPrefixes: ['QWEN', 'DASHSCOPE', 'ALIBABA'],
|
|
85
|
+
models: ['qwen-turbo', 'qwen-plus', 'qwen-max', 'qwen-long', 'qwen-vl-plus', 'qwen-coder-turbo'],
|
|
86
|
+
defaultRpm: 300,
|
|
87
|
+
costs: {
|
|
88
|
+
'qwen-turbo': { prompt: 0.08, completion: 0.16 },
|
|
89
|
+
'qwen-plus': { prompt: 0.4, completion: 0.8 },
|
|
90
|
+
'qwen-max': { prompt: 1.6, completion: 3.2 },
|
|
91
|
+
'qwen-long': { prompt: 0.04, completion: 0.08 },
|
|
92
|
+
'qwen-coder-turbo': { prompt: 0.15, completion: 0.3 },
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
zhipu: {
|
|
96
|
+
id: 'zhipu',
|
|
97
|
+
label: 'Zhipu GLM',
|
|
98
|
+
baseUrl: 'https://open.bigmodel.cn/api/paas/v4',
|
|
99
|
+
format: 'openai',
|
|
100
|
+
authStyle: 'bearer',
|
|
101
|
+
keyPatterns: [],
|
|
102
|
+
envPrefixes: ['ZHIPU', 'GLM', 'CHATGLM'],
|
|
103
|
+
models: ['glm-4', 'glm-4-flash', 'glm-4-plus', 'glm-4-long', 'glm-4v'],
|
|
104
|
+
defaultRpm: 300,
|
|
105
|
+
costs: {
|
|
106
|
+
'glm-4': { prompt: 1.4, completion: 1.4 },
|
|
107
|
+
'glm-4-flash': { prompt: 0.01, completion: 0.01 },
|
|
108
|
+
'glm-4-plus': { prompt: 0.7, completion: 0.7 },
|
|
109
|
+
'glm-4-long': { prompt: 0.14, completion: 0.14 },
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
moonshot: {
|
|
113
|
+
id: 'moonshot',
|
|
114
|
+
label: 'Moonshot Kimi',
|
|
115
|
+
baseUrl: 'https://api.moonshot.cn/v1',
|
|
116
|
+
format: 'openai',
|
|
117
|
+
authStyle: 'bearer',
|
|
118
|
+
keyPatterns: [],
|
|
119
|
+
envPrefixes: ['MOONSHOT', 'KIMI'],
|
|
120
|
+
models: ['moonshot-v1-8k', 'moonshot-v1-32k', 'moonshot-v1-128k'],
|
|
121
|
+
defaultRpm: 300,
|
|
122
|
+
costs: {
|
|
123
|
+
'moonshot-v1-8k': { prompt: 0.15, completion: 0.15 },
|
|
124
|
+
'moonshot-v1-32k': { prompt: 0.35, completion: 0.35 },
|
|
125
|
+
'moonshot-v1-128k': { prompt: 0.85, completion: 0.85 },
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
yi: {
|
|
129
|
+
id: 'yi',
|
|
130
|
+
label: '01.AI Yi',
|
|
131
|
+
baseUrl: 'https://api.01.ai/v1',
|
|
132
|
+
format: 'openai',
|
|
133
|
+
authStyle: 'bearer',
|
|
134
|
+
keyPatterns: [],
|
|
135
|
+
envPrefixes: ['YI', 'LINGYIWANWU'],
|
|
136
|
+
models: ['yi-large', 'yi-medium', 'yi-spark', 'yi-large-turbo'],
|
|
137
|
+
defaultRpm: 300,
|
|
138
|
+
costs: {
|
|
139
|
+
'yi-large': { prompt: 2.5, completion: 2.5 },
|
|
140
|
+
'yi-medium': { prompt: 0.36, completion: 0.36 },
|
|
141
|
+
'yi-spark': { prompt: 0.12, completion: 0.12 },
|
|
142
|
+
'yi-large-turbo': { prompt: 1.7, completion: 1.7 },
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
groq: {
|
|
146
|
+
id: 'groq',
|
|
147
|
+
label: 'Groq',
|
|
148
|
+
baseUrl: 'https://api.groq.com/openai/v1',
|
|
149
|
+
format: 'openai',
|
|
150
|
+
authStyle: 'bearer',
|
|
151
|
+
keyPatterns: [/^gsk_/],
|
|
152
|
+
envPrefixes: ['GROQ'],
|
|
153
|
+
models: ['llama-3.3-70b-versatile', 'llama-3.1-8b-instant', 'mixtral-8x7b-32768', 'gemma2-9b-it'],
|
|
154
|
+
defaultRpm: 30,
|
|
155
|
+
costs: {
|
|
156
|
+
'llama-3.3-70b-versatile': { prompt: 0.59, completion: 0.79 },
|
|
157
|
+
'llama-3.1-8b-instant': { prompt: 0.05, completion: 0.08 },
|
|
158
|
+
'mixtral-8x7b-32768': { prompt: 0.24, completion: 0.24 },
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
together: {
|
|
162
|
+
id: 'together',
|
|
163
|
+
label: 'Together AI',
|
|
164
|
+
baseUrl: 'https://api.together.xyz/v1',
|
|
165
|
+
format: 'openai',
|
|
166
|
+
authStyle: 'bearer',
|
|
167
|
+
keyPatterns: [],
|
|
168
|
+
envPrefixes: ['TOGETHER'],
|
|
169
|
+
models: ['meta-llama/Llama-3.3-70B-Instruct-Turbo', 'Qwen/Qwen2.5-72B-Instruct-Turbo', 'deepseek-ai/DeepSeek-R1'],
|
|
170
|
+
defaultRpm: 300,
|
|
171
|
+
costs: {
|
|
172
|
+
'meta-llama/Llama-3.3-70B-Instruct-Turbo': { prompt: 0.88, completion: 0.88 },
|
|
173
|
+
'deepseek-ai/DeepSeek-R1': { prompt: 3.0, completion: 7.0 },
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
mistral: {
|
|
177
|
+
id: 'mistral',
|
|
178
|
+
label: 'Mistral AI',
|
|
179
|
+
baseUrl: 'https://api.mistral.ai/v1',
|
|
180
|
+
format: 'openai',
|
|
181
|
+
authStyle: 'bearer',
|
|
182
|
+
keyPatterns: [],
|
|
183
|
+
envPrefixes: ['MISTRAL'],
|
|
184
|
+
models: ['mistral-large-latest', 'mistral-small-latest', 'codestral-latest', 'open-mistral-nemo'],
|
|
185
|
+
defaultRpm: 300,
|
|
186
|
+
costs: {
|
|
187
|
+
'mistral-large-latest': { prompt: 2, completion: 6 },
|
|
188
|
+
'mistral-small-latest': { prompt: 0.1, completion: 0.3 },
|
|
189
|
+
'codestral-latest': { prompt: 0.3, completion: 0.9 },
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
};
|
|
193
|
+
// ─── Auto-Detection ────────────────────────────────────────────
|
|
194
|
+
export function detectProvider(key) {
|
|
195
|
+
for (const [id, def] of Object.entries(PROVIDERS)) {
|
|
196
|
+
for (const pattern of def.keyPatterns) {
|
|
197
|
+
if (pattern.test(key))
|
|
198
|
+
return id;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (/^sk-/.test(key))
|
|
202
|
+
return 'openai';
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
export function discoverKeysFromEnv(env = process.env) {
|
|
206
|
+
const found = [];
|
|
207
|
+
for (const [envName, value] of Object.entries(env)) {
|
|
208
|
+
if (!value || value.length < 8)
|
|
209
|
+
continue;
|
|
210
|
+
for (const [providerId, def] of Object.entries(PROVIDERS)) {
|
|
211
|
+
for (const prefix of def.envPrefixes) {
|
|
212
|
+
const pattern = new RegExp(`^${prefix}_(?:API_)?KEY(?:_(\\d+))?$`, 'i');
|
|
213
|
+
const match = envName.match(pattern);
|
|
214
|
+
if (match) {
|
|
215
|
+
const suffix = match[1] ? `-${match[1]}` : '';
|
|
216
|
+
found.push({
|
|
217
|
+
key: value,
|
|
218
|
+
provider: providerId,
|
|
219
|
+
label: `${providerId}${suffix}`,
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return found;
|
|
226
|
+
}
|
|
227
|
+
// ─── Request Building (Dynamic) ────────────────────────────────
|
|
228
|
+
// 3 format functions handle all 11+ providers.
|
|
229
|
+
export function buildRequest(provider, request, apiKey) {
|
|
230
|
+
const headers = buildAuthHeaders(provider, apiKey);
|
|
231
|
+
const FORMATS = {
|
|
232
|
+
openai: () => ({
|
|
233
|
+
url: `${provider.baseUrl}/chat/completions`,
|
|
234
|
+
body: buildOpenAIBody(request),
|
|
235
|
+
}),
|
|
236
|
+
anthropic: () => ({
|
|
237
|
+
url: `${provider.baseUrl}/messages`,
|
|
238
|
+
body: buildAnthropicBody(request),
|
|
239
|
+
}),
|
|
240
|
+
gemini: () => {
|
|
241
|
+
const endpoint = request.stream ? 'streamGenerateContent' : 'generateContent';
|
|
242
|
+
return {
|
|
243
|
+
url: `${provider.baseUrl}/models/${request.model}:${endpoint}?key=${apiKey}`,
|
|
244
|
+
body: buildGeminiBody(request),
|
|
245
|
+
};
|
|
246
|
+
},
|
|
247
|
+
};
|
|
248
|
+
const { url, body } = FORMATS[provider.format]();
|
|
249
|
+
return {
|
|
250
|
+
url,
|
|
251
|
+
init: { method: 'POST', headers, body: JSON.stringify(body) },
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
export function parseResponse(provider, data) {
|
|
255
|
+
const PARSERS = {
|
|
256
|
+
openai: parseOpenAIFormat,
|
|
257
|
+
anthropic: parseAnthropicFormat,
|
|
258
|
+
gemini: parseGeminiFormat,
|
|
259
|
+
};
|
|
260
|
+
return PARSERS[provider.format](data);
|
|
261
|
+
}
|
|
262
|
+
export function parseStreamChunk(line) {
|
|
263
|
+
const trimmed = line.trim();
|
|
264
|
+
if (!trimmed.startsWith('data: '))
|
|
265
|
+
return null;
|
|
266
|
+
const payload = trimmed.slice(6);
|
|
267
|
+
if (payload === '[DONE]')
|
|
268
|
+
return null;
|
|
269
|
+
try {
|
|
270
|
+
return JSON.parse(payload);
|
|
271
|
+
}
|
|
272
|
+
catch {
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
// ─── Cost Estimation ──────────────────────────────────────────
|
|
277
|
+
export function estimateCost(model, promptTokens, completionTokens) {
|
|
278
|
+
for (const def of Object.values(PROVIDERS)) {
|
|
279
|
+
const costs = def.costs[model];
|
|
280
|
+
if (costs) {
|
|
281
|
+
return (promptTokens / 1_000_000) * costs.prompt
|
|
282
|
+
+ (completionTokens / 1_000_000) * costs.completion;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return 0;
|
|
286
|
+
}
|
|
287
|
+
// ─── Resolve model → provider ─────────────────────────────────
|
|
288
|
+
export function findProviderForModel(model) {
|
|
289
|
+
for (const def of Object.values(PROVIDERS)) {
|
|
290
|
+
if (def.models.includes(model))
|
|
291
|
+
return def;
|
|
292
|
+
}
|
|
293
|
+
return null;
|
|
294
|
+
}
|
|
295
|
+
// ─── Shared Internals ─────────────────────────────────────────
|
|
296
|
+
function buildAuthHeaders(provider, apiKey) {
|
|
297
|
+
const headers = { 'Content-Type': 'application/json' };
|
|
298
|
+
const AUTH = {
|
|
299
|
+
bearer: () => { headers['Authorization'] = `Bearer ${apiKey}`; },
|
|
300
|
+
'x-api-key': () => { headers['x-api-key'] = apiKey; },
|
|
301
|
+
query: () => { },
|
|
302
|
+
};
|
|
303
|
+
AUTH[provider.authStyle]();
|
|
304
|
+
if (provider.extraHeaders)
|
|
305
|
+
Object.assign(headers, provider.extraHeaders);
|
|
306
|
+
return headers;
|
|
307
|
+
}
|
|
308
|
+
function splitSystemMessages(messages) {
|
|
309
|
+
let system;
|
|
310
|
+
const rest = [];
|
|
311
|
+
for (const msg of messages) {
|
|
312
|
+
if (msg.role === 'system')
|
|
313
|
+
system = (system ? system + '\n' : '') + msg.content;
|
|
314
|
+
else
|
|
315
|
+
rest.push({ role: msg.role, content: msg.content });
|
|
316
|
+
}
|
|
317
|
+
return { system, rest };
|
|
318
|
+
}
|
|
319
|
+
function buildOpenAIBody(req) {
|
|
320
|
+
const body = { model: req.model, messages: req.messages };
|
|
321
|
+
if (req.temperature !== undefined)
|
|
322
|
+
body.temperature = req.temperature;
|
|
323
|
+
if (req.max_tokens !== undefined)
|
|
324
|
+
body.max_tokens = req.max_tokens;
|
|
325
|
+
if (req.top_p !== undefined)
|
|
326
|
+
body.top_p = req.top_p;
|
|
327
|
+
if (req.stream !== undefined)
|
|
328
|
+
body.stream = req.stream;
|
|
329
|
+
if (req.tools)
|
|
330
|
+
body.tools = req.tools;
|
|
331
|
+
if (req.tool_choice !== undefined)
|
|
332
|
+
body.tool_choice = req.tool_choice;
|
|
333
|
+
if (req.response_format)
|
|
334
|
+
body.response_format = req.response_format;
|
|
335
|
+
if (req.stream)
|
|
336
|
+
body.stream_options = { include_usage: true };
|
|
337
|
+
return body;
|
|
338
|
+
}
|
|
339
|
+
function buildAnthropicBody(req) {
|
|
340
|
+
const { system, rest } = splitSystemMessages(req.messages);
|
|
341
|
+
const body = { model: req.model, messages: rest, max_tokens: req.max_tokens ?? 4096 };
|
|
342
|
+
if (system)
|
|
343
|
+
body.system = system;
|
|
344
|
+
if (req.temperature !== undefined)
|
|
345
|
+
body.temperature = req.temperature;
|
|
346
|
+
if (req.top_p !== undefined)
|
|
347
|
+
body.top_p = req.top_p;
|
|
348
|
+
if (req.stream !== undefined)
|
|
349
|
+
body.stream = req.stream;
|
|
350
|
+
return body;
|
|
351
|
+
}
|
|
352
|
+
function buildGeminiBody(req) {
|
|
353
|
+
const contents = [];
|
|
354
|
+
let systemText;
|
|
355
|
+
for (const msg of req.messages) {
|
|
356
|
+
if (msg.role === 'system')
|
|
357
|
+
systemText = (systemText ? systemText + '\n' : '') + msg.content;
|
|
358
|
+
else
|
|
359
|
+
contents.push({ role: msg.role === 'assistant' ? 'model' : 'user', parts: [{ text: msg.content }] });
|
|
360
|
+
}
|
|
361
|
+
const body = { contents };
|
|
362
|
+
if (systemText)
|
|
363
|
+
body.systemInstruction = { parts: [{ text: systemText }] };
|
|
364
|
+
const genConfig = {};
|
|
365
|
+
if (req.temperature !== undefined)
|
|
366
|
+
genConfig.temperature = req.temperature;
|
|
367
|
+
if (req.max_tokens !== undefined)
|
|
368
|
+
genConfig.maxOutputTokens = req.max_tokens;
|
|
369
|
+
if (req.top_p !== undefined)
|
|
370
|
+
genConfig.topP = req.top_p;
|
|
371
|
+
if (Object.keys(genConfig).length > 0)
|
|
372
|
+
body.generationConfig = genConfig;
|
|
373
|
+
return body;
|
|
374
|
+
}
|
|
375
|
+
function parseOpenAIFormat(data) {
|
|
376
|
+
const raw = data;
|
|
377
|
+
const usage = (raw.usage ?? { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 });
|
|
378
|
+
return {
|
|
379
|
+
id: raw.id ?? `gen-${Date.now()}`,
|
|
380
|
+
object: raw.object ?? 'chat.completion',
|
|
381
|
+
model: raw.model,
|
|
382
|
+
choices: raw.choices,
|
|
383
|
+
usage,
|
|
384
|
+
_gateway: { provider: '', keyLabel: '', latencyMs: 0, attempt: 0 },
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
function parseAnthropicFormat(data) {
|
|
388
|
+
const raw = data;
|
|
389
|
+
const text = raw.content.filter((c) => c.type === 'text').map((c) => c.text).join('');
|
|
390
|
+
return {
|
|
391
|
+
id: raw.id,
|
|
392
|
+
object: 'chat.completion',
|
|
393
|
+
model: raw.model,
|
|
394
|
+
choices: [{ index: 0, message: { role: 'assistant', content: text }, finish_reason: raw.stop_reason === 'end_turn' ? 'stop' : raw.stop_reason }],
|
|
395
|
+
usage: { prompt_tokens: raw.usage.input_tokens, completion_tokens: raw.usage.output_tokens, total_tokens: raw.usage.input_tokens + raw.usage.output_tokens },
|
|
396
|
+
_gateway: { provider: '', keyLabel: '', latencyMs: 0, attempt: 0 },
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
function parseGeminiFormat(data) {
|
|
400
|
+
const raw = data;
|
|
401
|
+
const candidate = raw.candidates?.[0];
|
|
402
|
+
const text = candidate?.content?.parts?.map((p) => p.text).join('') ?? '';
|
|
403
|
+
const meta = raw.usageMetadata;
|
|
404
|
+
return {
|
|
405
|
+
id: `gemini-${Date.now()}`,
|
|
406
|
+
object: 'chat.completion',
|
|
407
|
+
model: 'gemini',
|
|
408
|
+
choices: [{ index: 0, message: { role: 'assistant', content: text }, finish_reason: candidate?.finishReason === 'STOP' ? 'stop' : (candidate?.finishReason ?? 'stop') }],
|
|
409
|
+
usage: { prompt_tokens: meta?.promptTokenCount ?? 0, completion_tokens: meta?.candidatesTokenCount ?? 0, total_tokens: meta?.totalTokenCount ?? 0 },
|
|
410
|
+
_gateway: { provider: '', keyLabel: '', latencyMs: 0, attempt: 0 },
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
export interface KeyInput {
|
|
2
|
+
key: string;
|
|
3
|
+
/** Provider name — auto-detected from key prefix if omitted */
|
|
4
|
+
provider?: string;
|
|
5
|
+
/** Requests per minute limit. Default: from provider registry */
|
|
6
|
+
rpm?: number;
|
|
7
|
+
/** Tokens per minute limit. Optional */
|
|
8
|
+
tpm?: number;
|
|
9
|
+
/** Human label (e.g. "prod-key-1"). Auto-generated if omitted */
|
|
10
|
+
label?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface GatewayConfig {
|
|
13
|
+
/** API keys — strings auto-detect provider; objects allow explicit control */
|
|
14
|
+
keys: Array<string | KeyInput>;
|
|
15
|
+
/** Default model to use when not specified in request */
|
|
16
|
+
defaultModel?: string;
|
|
17
|
+
/** Retries across keys before failing. Default: 3 */
|
|
18
|
+
maxRetries?: number;
|
|
19
|
+
/** Cooldown ms for a rate-limited key. Default: 60000 */
|
|
20
|
+
cooldownMs?: number;
|
|
21
|
+
/** Request timeout ms. Default: 30000 */
|
|
22
|
+
timeoutMs?: number;
|
|
23
|
+
/** Called after every LLM request for logging/tracking */
|
|
24
|
+
onUsage?: (log: UsageLog) => void | Promise<void>;
|
|
25
|
+
/** Called when all keys for a provider are exhausted */
|
|
26
|
+
onAllKeysExhausted?: (provider: string) => void;
|
|
27
|
+
}
|
|
28
|
+
export interface ChatMessage {
|
|
29
|
+
role: 'system' | 'user' | 'assistant' | 'tool';
|
|
30
|
+
content: string;
|
|
31
|
+
name?: string;
|
|
32
|
+
tool_call_id?: string;
|
|
33
|
+
tool_calls?: unknown[];
|
|
34
|
+
}
|
|
35
|
+
export interface ChatRequest {
|
|
36
|
+
model?: string;
|
|
37
|
+
messages: ChatMessage[];
|
|
38
|
+
temperature?: number;
|
|
39
|
+
max_tokens?: number;
|
|
40
|
+
top_p?: number;
|
|
41
|
+
stream?: boolean;
|
|
42
|
+
tools?: unknown[];
|
|
43
|
+
tool_choice?: unknown;
|
|
44
|
+
response_format?: unknown;
|
|
45
|
+
/** Force a specific provider by name */
|
|
46
|
+
provider?: string;
|
|
47
|
+
/** Metadata for spend tracking */
|
|
48
|
+
metadata?: Record<string, string>;
|
|
49
|
+
}
|
|
50
|
+
export interface ChatChoice {
|
|
51
|
+
index: number;
|
|
52
|
+
message: ChatMessage;
|
|
53
|
+
finish_reason: string | null;
|
|
54
|
+
}
|
|
55
|
+
export interface TokenUsage {
|
|
56
|
+
prompt_tokens: number;
|
|
57
|
+
completion_tokens: number;
|
|
58
|
+
total_tokens: number;
|
|
59
|
+
}
|
|
60
|
+
export interface ChatResponse {
|
|
61
|
+
id: string;
|
|
62
|
+
object: string;
|
|
63
|
+
model: string;
|
|
64
|
+
choices: ChatChoice[];
|
|
65
|
+
usage: TokenUsage;
|
|
66
|
+
_gateway: {
|
|
67
|
+
provider: string;
|
|
68
|
+
keyLabel: string;
|
|
69
|
+
latencyMs: number;
|
|
70
|
+
attempt: number;
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
export interface StreamChunk {
|
|
74
|
+
id: string;
|
|
75
|
+
object: string;
|
|
76
|
+
model: string;
|
|
77
|
+
choices: Array<{
|
|
78
|
+
index: number;
|
|
79
|
+
delta: Partial<ChatMessage>;
|
|
80
|
+
finish_reason: string | null;
|
|
81
|
+
}>;
|
|
82
|
+
}
|
|
83
|
+
export interface UsageLog {
|
|
84
|
+
requestId: string;
|
|
85
|
+
provider: string;
|
|
86
|
+
keyLabel: string;
|
|
87
|
+
model: string;
|
|
88
|
+
promptTokens: number;
|
|
89
|
+
completionTokens: number;
|
|
90
|
+
totalTokens: number;
|
|
91
|
+
estimatedCostUsd: number;
|
|
92
|
+
latencyMs: number;
|
|
93
|
+
status: 'success' | 'rate_limited' | 'error';
|
|
94
|
+
error?: string;
|
|
95
|
+
metadata?: Record<string, string>;
|
|
96
|
+
timestamp: Date;
|
|
97
|
+
}
|
|
98
|
+
export interface KeyState {
|
|
99
|
+
key: string;
|
|
100
|
+
provider: string;
|
|
101
|
+
label: string;
|
|
102
|
+
rpm: number;
|
|
103
|
+
tpm: number;
|
|
104
|
+
requestsThisMinute: number;
|
|
105
|
+
tokensThisMinute: number;
|
|
106
|
+
minuteStart: number;
|
|
107
|
+
cooldownUntil: number;
|
|
108
|
+
totalRequests: number;
|
|
109
|
+
totalErrors: number;
|
|
110
|
+
healthy: boolean;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,kEAAkE"}
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@careob/llm-gateway",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Lightweight LLM gateway with multi-key rotation, rate-limit handling, provider failover, and spend tracking for Node.js/Express apps",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"typecheck": "tsc --noEmit",
|
|
17
|
+
"dev": "tsc --watch"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {},
|
|
20
|
+
"peerDependencies": {
|
|
21
|
+
"express": "^4.18.0 || ^5.0.0"
|
|
22
|
+
},
|
|
23
|
+
"peerDependenciesMeta": {
|
|
24
|
+
"express": { "optional": true }
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/express": "^4.17.21",
|
|
28
|
+
"@types/node": "^20.14.9",
|
|
29
|
+
"typescript": "^5.5.3"
|
|
30
|
+
},
|
|
31
|
+
"files": ["dist", "README.md"],
|
|
32
|
+
"keywords": ["llm", "gateway", "openai", "anthropic", "key-rotation", "rate-limit", "express"],
|
|
33
|
+
"license": "MIT"
|
|
34
|
+
}
|