@stackbilt/llm-providers 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +261 -0
- package/dist/errors.d.ts +79 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +183 -0
- package/dist/errors.js.map +1 -0
- package/dist/factory.d.ts +95 -0
- package/dist/factory.d.ts.map +1 -0
- package/dist/factory.js +418 -0
- package/dist/factory.js.map +1 -0
- package/dist/index.d.ts +137 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +263 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/anthropic.d.ts +38 -0
- package/dist/providers/anthropic.d.ts.map +1 -0
- package/dist/providers/anthropic.js +378 -0
- package/dist/providers/anthropic.js.map +1 -0
- package/dist/providers/base.d.ts +107 -0
- package/dist/providers/base.d.ts.map +1 -0
- package/dist/providers/base.js +230 -0
- package/dist/providers/base.js.map +1 -0
- package/dist/providers/cerebras.d.ts +30 -0
- package/dist/providers/cerebras.d.ts.map +1 -0
- package/dist/providers/cerebras.js +292 -0
- package/dist/providers/cerebras.js.map +1 -0
- package/dist/providers/cloudflare.d.ts +47 -0
- package/dist/providers/cloudflare.d.ts.map +1 -0
- package/dist/providers/cloudflare.js +544 -0
- package/dist/providers/cloudflare.js.map +1 -0
- package/dist/providers/groq.d.ts +30 -0
- package/dist/providers/groq.d.ts.map +1 -0
- package/dist/providers/groq.js +222 -0
- package/dist/providers/groq.js.map +1 -0
- package/dist/providers/openai.d.ts +36 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/openai.js +331 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/types.d.ts +238 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/circuit-breaker.d.ts +111 -0
- package/dist/utils/circuit-breaker.d.ts.map +1 -0
- package/dist/utils/circuit-breaker.js +365 -0
- package/dist/utils/circuit-breaker.js.map +1 -0
- package/dist/utils/cost-tracker.d.ts +130 -0
- package/dist/utils/cost-tracker.d.ts.map +1 -0
- package/dist/utils/cost-tracker.js +272 -0
- package/dist/utils/cost-tracker.js.map +1 -0
- package/dist/utils/credit-ledger.d.ts +161 -0
- package/dist/utils/credit-ledger.d.ts.map +1 -0
- package/dist/utils/credit-ledger.js +463 -0
- package/dist/utils/credit-ledger.js.map +1 -0
- package/dist/utils/retry.d.ts +46 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +125 -0
- package/dist/utils/retry.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graduated Circuit Breaker
|
|
3
|
+
* Routes traffic away from failing providers with confidence-weighted degradation.
|
|
4
|
+
*/
|
|
5
|
+
import { CircuitBreakerOpenError } from '../errors';
|
|
6
|
+
const DEFAULT_DEGRADATION_CURVE = [1.0, 0.9, 0.7, 0.4, 0.1];
|
|
7
|
+
const DEFAULT_CONFIG = {
|
|
8
|
+
failureThreshold: DEFAULT_DEGRADATION_CURVE.length,
|
|
9
|
+
resetTimeout: 60_000,
|
|
10
|
+
monitoringPeriod: 300_000,
|
|
11
|
+
minRequests: 3,
|
|
12
|
+
degradationCurve: DEFAULT_DEGRADATION_CURVE
|
|
13
|
+
};
|
|
14
|
+
function clampTrafficPct(value) {
|
|
15
|
+
if (Number.isNaN(value))
|
|
16
|
+
return 0;
|
|
17
|
+
return Math.min(1, Math.max(0, value));
|
|
18
|
+
}
|
|
19
|
+
function normalizeConfig(config) {
|
|
20
|
+
const degradationCurve = (config.degradationCurve?.length
|
|
21
|
+
? config.degradationCurve
|
|
22
|
+
: DEFAULT_DEGRADATION_CURVE).map(clampTrafficPct);
|
|
23
|
+
return {
|
|
24
|
+
failureThreshold: Math.max(1, config.failureThreshold ?? DEFAULT_CONFIG.failureThreshold),
|
|
25
|
+
resetTimeout: config.resetTimeout ?? DEFAULT_CONFIG.resetTimeout,
|
|
26
|
+
monitoringPeriod: config.monitoringPeriod ?? DEFAULT_CONFIG.monitoringPeriod,
|
|
27
|
+
minRequests: config.minRequests ?? DEFAULT_CONFIG.minRequests,
|
|
28
|
+
degradationCurve
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export class CircuitBreaker {
|
|
32
|
+
name;
|
|
33
|
+
config;
|
|
34
|
+
consecutiveFailures = 0;
|
|
35
|
+
totalFailures = 0;
|
|
36
|
+
totalSuccesses = 0;
|
|
37
|
+
totalRequests = 0;
|
|
38
|
+
lastFailureAt;
|
|
39
|
+
lastSuccessAt;
|
|
40
|
+
lastRequestAt;
|
|
41
|
+
lastDecayAt = 0;
|
|
42
|
+
windowStart = Date.now();
|
|
43
|
+
constructor(name, config = {}) {
|
|
44
|
+
this.name = name;
|
|
45
|
+
this.config = normalizeConfig(config);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Backwards-compatible execute alias.
|
|
49
|
+
*/
|
|
50
|
+
async execute(fn) {
|
|
51
|
+
return this.exec(fn);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Execute the primary operation if the breaker allows traffic through.
|
|
55
|
+
* Rejected requests throw CircuitBreakerOpenError so callers can route elsewhere.
|
|
56
|
+
*/
|
|
57
|
+
async exec(fn) {
|
|
58
|
+
const now = Date.now();
|
|
59
|
+
this.syncState(now);
|
|
60
|
+
this.markTraffic(now);
|
|
61
|
+
const primaryPct = this.currentPrimaryTrafficPct();
|
|
62
|
+
if (primaryPct <= 0) {
|
|
63
|
+
throw this.buildOpenError(now);
|
|
64
|
+
}
|
|
65
|
+
if (primaryPct < 1 && Math.random() > primaryPct) {
|
|
66
|
+
console.log(`[CircuitBreaker] ${this.name}: degraded (${(primaryPct * 100).toFixed(0)}% primary), rejecting request for fallback`);
|
|
67
|
+
throw new CircuitBreakerOpenError(this.name, 0, this.consecutiveFailures);
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
const result = await fn();
|
|
71
|
+
this.onSuccess();
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
this.onFailure();
|
|
76
|
+
throw error;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Execute with graduated fallback. Degraded traffic is routed to the fallback
|
|
81
|
+
* probabilistically, and primary failures immediately fail over.
|
|
82
|
+
*/
|
|
83
|
+
async execWithFallback(primary, fallback) {
|
|
84
|
+
const now = Date.now();
|
|
85
|
+
this.syncState(now);
|
|
86
|
+
this.markTraffic(now);
|
|
87
|
+
const primaryPct = this.currentPrimaryTrafficPct();
|
|
88
|
+
if (primaryPct <= 0) {
|
|
89
|
+
console.log(`[CircuitBreaker] ${this.name}: fully degraded (${this.consecutiveFailures} failures), using fallback`);
|
|
90
|
+
return fallback();
|
|
91
|
+
}
|
|
92
|
+
if (primaryPct < 1 && Math.random() > primaryPct) {
|
|
93
|
+
console.log(`[CircuitBreaker] ${this.name}: degraded (${(primaryPct * 100).toFixed(0)}% primary), routing to fallback`);
|
|
94
|
+
return fallback();
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
const result = await primary();
|
|
98
|
+
this.onSuccess();
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
this.onFailure();
|
|
103
|
+
console.warn(`[CircuitBreaker] ${this.name}: primary failed (${this.consecutiveFailures} consecutive), trying fallback`);
|
|
104
|
+
return fallback();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Current percentage of traffic that should be routed to the primary provider.
|
|
109
|
+
*/
|
|
110
|
+
primaryTrafficPct() {
|
|
111
|
+
this.syncState(Date.now());
|
|
112
|
+
return this.currentPrimaryTrafficPct();
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Get current state and breaker statistics.
|
|
116
|
+
*/
|
|
117
|
+
getState() {
|
|
118
|
+
this.syncState(Date.now());
|
|
119
|
+
return this.snapshot();
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Alias for stats-oriented call sites.
|
|
123
|
+
*/
|
|
124
|
+
getStats() {
|
|
125
|
+
return this.getState();
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Get current configuration.
|
|
129
|
+
*/
|
|
130
|
+
getConfig() {
|
|
131
|
+
return {
|
|
132
|
+
...this.config,
|
|
133
|
+
degradationCurve: [...this.config.degradationCurve]
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Manual reset for testing and operator intervention.
|
|
138
|
+
*/
|
|
139
|
+
reset() {
|
|
140
|
+
this.consecutiveFailures = 0;
|
|
141
|
+
this.totalFailures = 0;
|
|
142
|
+
this.totalSuccesses = 0;
|
|
143
|
+
this.totalRequests = 0;
|
|
144
|
+
this.lastFailureAt = undefined;
|
|
145
|
+
this.lastSuccessAt = undefined;
|
|
146
|
+
this.lastRequestAt = undefined;
|
|
147
|
+
this.lastDecayAt = 0;
|
|
148
|
+
this.windowStart = Date.now();
|
|
149
|
+
console.log(`[CircuitBreaker] ${this.name}: circuit breaker reset`);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Force the breaker into the fully open state.
|
|
153
|
+
*/
|
|
154
|
+
forceOpen() {
|
|
155
|
+
const now = Date.now();
|
|
156
|
+
this.consecutiveFailures = this.config.failureThreshold;
|
|
157
|
+
this.lastFailureAt = now;
|
|
158
|
+
this.lastRequestAt = now;
|
|
159
|
+
this.lastDecayAt = now;
|
|
160
|
+
console.log(`[CircuitBreaker] ${this.name}: circuit breaker force opened`);
|
|
161
|
+
}
|
|
162
|
+
isOpen() {
|
|
163
|
+
return this.getState().state === 'OPEN';
|
|
164
|
+
}
|
|
165
|
+
isClosed() {
|
|
166
|
+
return this.getState().state === 'CLOSED';
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Deprecated alias retained for compatibility with the prior state machine.
|
|
170
|
+
*/
|
|
171
|
+
isHalfOpen() {
|
|
172
|
+
return this.isRecovering();
|
|
173
|
+
}
|
|
174
|
+
isDegraded() {
|
|
175
|
+
return this.getState().state === 'DEGRADED';
|
|
176
|
+
}
|
|
177
|
+
isRecovering() {
|
|
178
|
+
return this.getState().state === 'RECOVERING';
|
|
179
|
+
}
|
|
180
|
+
getHealth() {
|
|
181
|
+
const state = this.getState();
|
|
182
|
+
return {
|
|
183
|
+
state: state.state,
|
|
184
|
+
failures: state.failures,
|
|
185
|
+
consecutiveFailures: state.consecutiveFailures,
|
|
186
|
+
failureThreshold: this.config.failureThreshold,
|
|
187
|
+
primaryTrafficPct: state.primaryTrafficPct,
|
|
188
|
+
healthy: state.state === 'CLOSED',
|
|
189
|
+
lastFailure: state.lastFailure,
|
|
190
|
+
lastSuccess: state.lastSuccess,
|
|
191
|
+
nextAttempt: state.nextAttempt,
|
|
192
|
+
totalFailures: state.totalFailures,
|
|
193
|
+
totalSuccesses: state.totalSuccesses,
|
|
194
|
+
totalRequests: state.totalRequests
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
snapshot(now = Date.now()) {
|
|
198
|
+
return {
|
|
199
|
+
state: this.currentState(),
|
|
200
|
+
failures: this.consecutiveFailures,
|
|
201
|
+
consecutiveFailures: this.consecutiveFailures,
|
|
202
|
+
primaryTrafficPct: this.currentPrimaryTrafficPct(),
|
|
203
|
+
totalFailures: this.totalFailures,
|
|
204
|
+
totalSuccesses: this.totalSuccesses,
|
|
205
|
+
totalRequests: this.totalRequests,
|
|
206
|
+
lastFailure: this.lastFailureAt,
|
|
207
|
+
lastSuccess: this.lastSuccessAt,
|
|
208
|
+
lastRequest: this.lastRequestAt,
|
|
209
|
+
nextAttempt: this.retryAt(now)
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
currentState() {
|
|
213
|
+
const primaryPct = this.currentPrimaryTrafficPct();
|
|
214
|
+
if (primaryPct >= 1)
|
|
215
|
+
return 'CLOSED';
|
|
216
|
+
if (primaryPct <= 0)
|
|
217
|
+
return 'OPEN';
|
|
218
|
+
if ((this.lastSuccessAt ?? 0) > (this.lastFailureAt ?? 0))
|
|
219
|
+
return 'RECOVERING';
|
|
220
|
+
return 'DEGRADED';
|
|
221
|
+
}
|
|
222
|
+
currentPrimaryTrafficPct() {
|
|
223
|
+
if (this.consecutiveFailures >= this.config.failureThreshold) {
|
|
224
|
+
return 0;
|
|
225
|
+
}
|
|
226
|
+
if (this.consecutiveFailures < this.config.degradationCurve.length) {
|
|
227
|
+
return this.config.degradationCurve[this.consecutiveFailures];
|
|
228
|
+
}
|
|
229
|
+
if (this.config.degradationCurve.length === 0) {
|
|
230
|
+
return this.consecutiveFailures === 0 ? 1 : 0;
|
|
231
|
+
}
|
|
232
|
+
return this.config.degradationCurve[this.config.degradationCurve.length - 1];
|
|
233
|
+
}
|
|
234
|
+
buildOpenError(now) {
|
|
235
|
+
return new CircuitBreakerOpenError(this.name, this.retryAfterSec(now), this.consecutiveFailures);
|
|
236
|
+
}
|
|
237
|
+
retryAfterSec(now) {
|
|
238
|
+
if (this.consecutiveFailures === 0 || this.lastDecayAt === 0) {
|
|
239
|
+
return 0;
|
|
240
|
+
}
|
|
241
|
+
return Math.max(0, Math.ceil((this.config.resetTimeout - (now - this.lastDecayAt)) / 1000));
|
|
242
|
+
}
|
|
243
|
+
retryAt(now) {
|
|
244
|
+
if (this.consecutiveFailures === 0 || this.lastDecayAt === 0) {
|
|
245
|
+
return undefined;
|
|
246
|
+
}
|
|
247
|
+
return Math.max(now, this.lastDecayAt + this.config.resetTimeout);
|
|
248
|
+
}
|
|
249
|
+
syncState(now) {
|
|
250
|
+
this.maybeDecayFailures(now);
|
|
251
|
+
this.maybeRotateWindow(now);
|
|
252
|
+
}
|
|
253
|
+
markTraffic(now) {
|
|
254
|
+
this.lastRequestAt = now;
|
|
255
|
+
this.lastDecayAt = now;
|
|
256
|
+
}
|
|
257
|
+
onSuccess() {
|
|
258
|
+
this.totalRequests++;
|
|
259
|
+
this.totalSuccesses++;
|
|
260
|
+
this.lastSuccessAt = Date.now();
|
|
261
|
+
if (this.consecutiveFailures > 0) {
|
|
262
|
+
this.consecutiveFailures--;
|
|
263
|
+
console.log(`[CircuitBreaker] ${this.name}: success -> recovering (${this.consecutiveFailures} failures, ${(this.currentPrimaryTrafficPct() * 100).toFixed(0)}% primary)`);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
onFailure() {
|
|
267
|
+
this.totalRequests++;
|
|
268
|
+
this.totalFailures++;
|
|
269
|
+
this.consecutiveFailures++;
|
|
270
|
+
this.lastFailureAt = Date.now();
|
|
271
|
+
const primaryPct = this.currentPrimaryTrafficPct();
|
|
272
|
+
if (primaryPct <= 0) {
|
|
273
|
+
console.log(`[CircuitBreaker] ${this.name}: OPEN (${this.consecutiveFailures} consecutive failures)`);
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
if (primaryPct < 1) {
|
|
277
|
+
console.log(`[CircuitBreaker] ${this.name}: degraded -> ${(primaryPct * 100).toFixed(0)}% primary (${this.consecutiveFailures} failures)`);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
maybeDecayFailures(now) {
|
|
281
|
+
if (this.consecutiveFailures === 0 || this.lastDecayAt === 0) {
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
const elapsed = now - this.lastDecayAt;
|
|
285
|
+
if (elapsed < this.config.resetTimeout) {
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
const steps = Math.floor(elapsed / this.config.resetTimeout);
|
|
289
|
+
const before = this.consecutiveFailures;
|
|
290
|
+
this.consecutiveFailures = Math.max(0, this.consecutiveFailures - steps);
|
|
291
|
+
this.lastDecayAt += steps * this.config.resetTimeout;
|
|
292
|
+
if (before !== this.consecutiveFailures) {
|
|
293
|
+
console.log(`[CircuitBreaker] ${this.name}: time-decay ${before} -> ${this.consecutiveFailures} failures (${(this.currentPrimaryTrafficPct() * 100).toFixed(0)}% primary)`);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
maybeRotateWindow(now) {
|
|
297
|
+
if (now - this.windowStart >= this.config.monitoringPeriod) {
|
|
298
|
+
this.windowStart = now;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Circuit breaker manager for multiple providers.
|
|
304
|
+
*/
|
|
305
|
+
export class CircuitBreakerManager {
|
|
306
|
+
breakers = new Map();
|
|
307
|
+
defaultConfig;
|
|
308
|
+
constructor(defaultConfig) {
|
|
309
|
+
this.defaultConfig = {
|
|
310
|
+
failureThreshold: defaultConfig?.failureThreshold ?? DEFAULT_CONFIG.failureThreshold,
|
|
311
|
+
resetTimeout: defaultConfig?.resetTimeout ?? DEFAULT_CONFIG.resetTimeout,
|
|
312
|
+
monitoringPeriod: defaultConfig?.monitoringPeriod ?? DEFAULT_CONFIG.monitoringPeriod,
|
|
313
|
+
minRequests: defaultConfig?.minRequests ?? DEFAULT_CONFIG.minRequests,
|
|
314
|
+
degradationCurve: defaultConfig?.degradationCurve
|
|
315
|
+
? [...defaultConfig.degradationCurve]
|
|
316
|
+
: [...DEFAULT_DEGRADATION_CURVE]
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
getBreaker(name, config) {
|
|
320
|
+
if (!this.breakers.has(name)) {
|
|
321
|
+
const breakerConfig = {
|
|
322
|
+
...this.defaultConfig,
|
|
323
|
+
...config,
|
|
324
|
+
degradationCurve: config?.degradationCurve
|
|
325
|
+
? [...config.degradationCurve]
|
|
326
|
+
: [...(this.defaultConfig.degradationCurve ?? DEFAULT_DEGRADATION_CURVE)]
|
|
327
|
+
};
|
|
328
|
+
this.breakers.set(name, new CircuitBreaker(name, breakerConfig));
|
|
329
|
+
}
|
|
330
|
+
return this.breakers.get(name);
|
|
331
|
+
}
|
|
332
|
+
async execute(name, fn, config) {
|
|
333
|
+
return this.getBreaker(name, config).execute(fn);
|
|
334
|
+
}
|
|
335
|
+
async execWithFallback(name, primary, fallback, config) {
|
|
336
|
+
return this.getBreaker(name, config).execWithFallback(primary, fallback);
|
|
337
|
+
}
|
|
338
|
+
getAllStates() {
|
|
339
|
+
const states = {};
|
|
340
|
+
for (const [name, breaker] of this.breakers) {
|
|
341
|
+
states[name] = breaker.getState();
|
|
342
|
+
}
|
|
343
|
+
return states;
|
|
344
|
+
}
|
|
345
|
+
getHealthStatus() {
|
|
346
|
+
const health = {};
|
|
347
|
+
for (const [name, breaker] of this.breakers) {
|
|
348
|
+
health[name] = breaker.getHealth();
|
|
349
|
+
}
|
|
350
|
+
return health;
|
|
351
|
+
}
|
|
352
|
+
resetAll() {
|
|
353
|
+
for (const breaker of this.breakers.values()) {
|
|
354
|
+
breaker.reset();
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
reset(name) {
|
|
358
|
+
this.breakers.get(name)?.reset();
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Default circuit breaker manager instance.
|
|
363
|
+
*/
|
|
364
|
+
export const defaultCircuitBreakerManager = new CircuitBreakerManager();
|
|
365
|
+
//# sourceMappingURL=circuit-breaker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circuit-breaker.js","sourceRoot":"","sources":["../../src/utils/circuit-breaker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cost Tracker
|
|
3
|
+
* Tracks and optimizes LLM usage costs across providers
|
|
4
|
+
*/
|
|
5
|
+
import type { LLMRequest, LLMResponse, CostConfig, ModelCapabilities } from '../types';
|
|
6
|
+
import type { CreditLedger } from './credit-ledger';
|
|
7
|
+
export interface ProviderCostEntry {
|
|
8
|
+
totalCost: number;
|
|
9
|
+
requestCount: number;
|
|
10
|
+
inputTokens: number;
|
|
11
|
+
outputTokens: number;
|
|
12
|
+
lastRecordedAt: number;
|
|
13
|
+
}
|
|
14
|
+
export interface ProviderCostBreakdownEntry extends ProviderCostEntry {
|
|
15
|
+
cost: number;
|
|
16
|
+
requests: number;
|
|
17
|
+
tokens: {
|
|
18
|
+
input: number;
|
|
19
|
+
output: number;
|
|
20
|
+
};
|
|
21
|
+
averageCostPerRequest: number;
|
|
22
|
+
}
|
|
23
|
+
export declare class CostTracker {
|
|
24
|
+
private providers;
|
|
25
|
+
private config;
|
|
26
|
+
private ledger?;
|
|
27
|
+
constructor(config?: Partial<CostConfig>, ledger?: CreditLedger);
|
|
28
|
+
/**
|
|
29
|
+
* Calculate cost for a request
|
|
30
|
+
*/
|
|
31
|
+
calculateRequestCost(request: LLMRequest, capabilities: ModelCapabilities): number;
|
|
32
|
+
/**
|
|
33
|
+
* Track actual cost from response
|
|
34
|
+
*/
|
|
35
|
+
trackCost(provider: string, response: LLMResponse): void;
|
|
36
|
+
/**
|
|
37
|
+
* Get the attached CreditLedger (if any)
|
|
38
|
+
*/
|
|
39
|
+
getLedger(): CreditLedger | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* Get total cost across all providers
|
|
42
|
+
*/
|
|
43
|
+
getTotalCost(): number;
|
|
44
|
+
/**
|
|
45
|
+
* Get cost for specific provider
|
|
46
|
+
*/
|
|
47
|
+
getProviderCost(provider: string): number;
|
|
48
|
+
/**
|
|
49
|
+
* Get cost breakdown by provider
|
|
50
|
+
*/
|
|
51
|
+
getCostBreakdown(): Record<string, ProviderCostBreakdownEntry>;
|
|
52
|
+
/**
|
|
53
|
+
* Get a provider snapshot aligned with Workers usage reporting.
|
|
54
|
+
*/
|
|
55
|
+
breakdown(): Record<string, ProviderCostEntry>;
|
|
56
|
+
/**
|
|
57
|
+
* Get total cost across all providers.
|
|
58
|
+
*/
|
|
59
|
+
total(): number;
|
|
60
|
+
/**
|
|
61
|
+
* Get most cost-effective provider for a request
|
|
62
|
+
*/
|
|
63
|
+
getMostCostEffectiveProvider(providers: Record<string, ModelCapabilities>, request: LLMRequest): string;
|
|
64
|
+
/**
|
|
65
|
+
* Check if we're approaching cost limits
|
|
66
|
+
*/
|
|
67
|
+
shouldRouteBasedOnCost(provider: string): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Reset cost tracking (e.g., monthly reset)
|
|
70
|
+
*/
|
|
71
|
+
reset(): void;
|
|
72
|
+
/**
|
|
73
|
+
* Reset tracking for specific provider
|
|
74
|
+
*/
|
|
75
|
+
resetProvider(provider: string): void;
|
|
76
|
+
/**
|
|
77
|
+
* Drain and reset provider tracking for periodic reporting.
|
|
78
|
+
*/
|
|
79
|
+
drain(): Record<string, ProviderCostEntry>;
|
|
80
|
+
/**
|
|
81
|
+
* Export cost data for analytics
|
|
82
|
+
*/
|
|
83
|
+
exportData(): {
|
|
84
|
+
totalCost: number;
|
|
85
|
+
breakdown: Record<string, ProviderCostBreakdownEntry>;
|
|
86
|
+
period: {
|
|
87
|
+
start: number;
|
|
88
|
+
end: number;
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* Estimate input tokens from request
|
|
93
|
+
*/
|
|
94
|
+
private estimateInputTokens;
|
|
95
|
+
/**
|
|
96
|
+
* Check for cost alerts
|
|
97
|
+
*/
|
|
98
|
+
private checkCostAlerts;
|
|
99
|
+
/**
|
|
100
|
+
* Update cost configuration
|
|
101
|
+
*/
|
|
102
|
+
updateConfig(config: Partial<CostConfig>): void;
|
|
103
|
+
/**
|
|
104
|
+
* Get current configuration
|
|
105
|
+
*/
|
|
106
|
+
getConfig(): CostConfig;
|
|
107
|
+
private createProviderEntry;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Default cost tracker instance
|
|
111
|
+
*/
|
|
112
|
+
export declare const defaultCostTracker: CostTracker;
|
|
113
|
+
/**
|
|
114
|
+
* Cost optimization utilities
|
|
115
|
+
*/
|
|
116
|
+
export declare class CostOptimizer {
|
|
117
|
+
/**
|
|
118
|
+
* Choose optimal provider based on cost and performance
|
|
119
|
+
*/
|
|
120
|
+
static chooseOptimalProvider(providers: Record<string, ModelCapabilities>, request: LLMRequest, costTracker: CostTracker, performanceWeights?: {
|
|
121
|
+
cost: number;
|
|
122
|
+
latency: number;
|
|
123
|
+
quality: number;
|
|
124
|
+
}): string;
|
|
125
|
+
/**
|
|
126
|
+
* Suggest cost reduction strategies
|
|
127
|
+
*/
|
|
128
|
+
static suggestOptimizations(costBreakdown: Record<string, any>): string[];
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=cost-tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost-tracker.d.ts","sourceRoot":"","sources":["../../src/utils/cost-tracker.ts"],"names":[],"mappings":"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"}
|