@sparkleideas/providers 3.0.0-alpha.6-patch.26 → 3.0.0-alpha.6-patch.27
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/anthropic-provider.d.ts +26 -0
- package/dist/anthropic-provider.d.ts.map +1 -0
- package/dist/anthropic-provider.js +513 -0
- package/dist/base-provider.d.ts +174 -0
- package/dist/base-provider.d.ts.map +1 -0
- package/dist/base-provider.js +636 -0
- package/dist/cohere-provider.d.ts +26 -0
- package/dist/cohere-provider.d.ts.map +1 -0
- package/dist/cohere-provider.js +501 -0
- package/dist/google-provider.d.ts +25 -0
- package/dist/google-provider.d.ts.map +1 -0
- package/dist/google-provider.js +498 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +62 -0
- package/dist/ollama-provider.d.ts +26 -0
- package/dist/ollama-provider.d.ts.map +1 -0
- package/dist/ollama-provider.js +489 -0
- package/dist/openai-provider.d.ts +26 -0
- package/dist/openai-provider.d.ts.map +1 -0
- package/dist/openai-provider.js +543 -0
- package/dist/provider-manager.d.ts +117 -0
- package/dist/provider-manager.d.ts.map +1 -0
- package/dist/provider-manager.js +712 -0
- package/dist/ruvector-provider.d.ts +65 -0
- package/dist/ruvector-provider.d.ts.map +1 -0
- package/dist/ruvector-provider.js +813 -0
- package/dist/types.d.ts +280 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +108 -0
- package/package.json +1 -1
|
@@ -0,0 +1,636 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* V3 Abstract Base Provider
|
|
4
|
+
*
|
|
5
|
+
* Provides common functionality for all LLM providers:
|
|
6
|
+
* - Circuit breaker protection
|
|
7
|
+
* - Health monitoring
|
|
8
|
+
* - Cost tracking
|
|
9
|
+
* - Request metrics
|
|
10
|
+
*
|
|
11
|
+
* @module @sparkleideas/providers/base-provider
|
|
12
|
+
*/
|
|
13
|
+
var __extends = (this && this.__extends) || (function () {
|
|
14
|
+
var extendStatics = function (d, b) {
|
|
15
|
+
extendStatics = Object.setPrototypeOf ||
|
|
16
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
17
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
18
|
+
return extendStatics(d, b);
|
|
19
|
+
};
|
|
20
|
+
return function (d, b) {
|
|
21
|
+
if (typeof b !== "function" && b !== null)
|
|
22
|
+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
23
|
+
extendStatics(d, b);
|
|
24
|
+
function __() { this.constructor = d; }
|
|
25
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
26
|
+
};
|
|
27
|
+
})();
|
|
28
|
+
var __assign = (this && this.__assign) || function () {
|
|
29
|
+
__assign = Object.assign || function(t) {
|
|
30
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
31
|
+
s = arguments[i];
|
|
32
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
33
|
+
t[p] = s[p];
|
|
34
|
+
}
|
|
35
|
+
return t;
|
|
36
|
+
};
|
|
37
|
+
return __assign.apply(this, arguments);
|
|
38
|
+
};
|
|
39
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
40
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
41
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
42
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
43
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
44
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
45
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
49
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
50
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
51
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
52
|
+
function step(op) {
|
|
53
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
54
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
55
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
56
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
57
|
+
switch (op[0]) {
|
|
58
|
+
case 0: case 1: t = op; break;
|
|
59
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
60
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
61
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
62
|
+
default:
|
|
63
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
64
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
65
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
66
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
67
|
+
if (t[2]) _.ops.pop();
|
|
68
|
+
_.trys.pop(); continue;
|
|
69
|
+
}
|
|
70
|
+
op = body.call(thisArg, _);
|
|
71
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
72
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
|
|
76
|
+
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
77
|
+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
78
|
+
var m = o[Symbol.asyncIterator], i;
|
|
79
|
+
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
80
|
+
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
81
|
+
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
82
|
+
};
|
|
83
|
+
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
|
|
84
|
+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
85
|
+
var g = generator.apply(thisArg, _arguments || []), i, q = [];
|
|
86
|
+
return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
|
|
87
|
+
function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }
|
|
88
|
+
function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }
|
|
89
|
+
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
|
|
90
|
+
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
|
|
91
|
+
function fulfill(value) { resume("next", value); }
|
|
92
|
+
function reject(value) { resume("throw", value); }
|
|
93
|
+
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
|
|
94
|
+
};
|
|
95
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
96
|
+
exports.BaseProvider = exports.consoleLogger = void 0;
|
|
97
|
+
var events_1 = require("events");
|
|
98
|
+
var types_js_1 = require("./types.js");
|
|
99
|
+
/**
|
|
100
|
+
* Simple circuit breaker implementation
|
|
101
|
+
*/
|
|
102
|
+
var CircuitBreaker = /** @class */ (function () {
|
|
103
|
+
function CircuitBreaker(name, threshold, resetTimeout) {
|
|
104
|
+
if (threshold === void 0) { threshold = 5; }
|
|
105
|
+
if (resetTimeout === void 0) { resetTimeout = 60000; }
|
|
106
|
+
this.name = name;
|
|
107
|
+
this.threshold = threshold;
|
|
108
|
+
this.resetTimeout = resetTimeout;
|
|
109
|
+
this.failures = 0;
|
|
110
|
+
this.lastFailure = 0;
|
|
111
|
+
this.state = 'closed';
|
|
112
|
+
}
|
|
113
|
+
CircuitBreaker.prototype.execute = function (fn) {
|
|
114
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
115
|
+
var result, error_1;
|
|
116
|
+
return __generator(this, function (_a) {
|
|
117
|
+
switch (_a.label) {
|
|
118
|
+
case 0:
|
|
119
|
+
if (this.state === 'open') {
|
|
120
|
+
if (Date.now() - this.lastFailure > this.resetTimeout) {
|
|
121
|
+
this.state = 'half-open';
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
throw new Error("Circuit breaker ".concat(this.name, " is open"));
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
_a.label = 1;
|
|
128
|
+
case 1:
|
|
129
|
+
_a.trys.push([1, 3, , 4]);
|
|
130
|
+
return [4 /*yield*/, fn()];
|
|
131
|
+
case 2:
|
|
132
|
+
result = _a.sent();
|
|
133
|
+
this.onSuccess();
|
|
134
|
+
return [2 /*return*/, result];
|
|
135
|
+
case 3:
|
|
136
|
+
error_1 = _a.sent();
|
|
137
|
+
this.onFailure();
|
|
138
|
+
throw error_1;
|
|
139
|
+
case 4: return [2 /*return*/];
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
};
|
|
144
|
+
CircuitBreaker.prototype.onSuccess = function () {
|
|
145
|
+
this.failures = 0;
|
|
146
|
+
this.state = 'closed';
|
|
147
|
+
};
|
|
148
|
+
CircuitBreaker.prototype.onFailure = function () {
|
|
149
|
+
this.failures++;
|
|
150
|
+
this.lastFailure = Date.now();
|
|
151
|
+
if (this.failures >= this.threshold) {
|
|
152
|
+
this.state = 'open';
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
CircuitBreaker.prototype.getState = function () {
|
|
156
|
+
return this.state;
|
|
157
|
+
};
|
|
158
|
+
return CircuitBreaker;
|
|
159
|
+
}());
|
|
160
|
+
/**
|
|
161
|
+
* Console logger implementation
|
|
162
|
+
*/
|
|
163
|
+
exports.consoleLogger = {
|
|
164
|
+
info: function (msg, meta) { return console.log("[INFO] ".concat(msg), meta || ''); },
|
|
165
|
+
warn: function (msg, meta) { return console.warn("[WARN] ".concat(msg), meta || ''); },
|
|
166
|
+
error: function (msg, err) { return console.error("[ERROR] ".concat(msg), err || ''); },
|
|
167
|
+
debug: function (msg, meta) { return console.debug("[DEBUG] ".concat(msg), meta || ''); },
|
|
168
|
+
};
|
|
169
|
+
/**
|
|
170
|
+
* Abstract base class for LLM providers
|
|
171
|
+
*/
|
|
172
|
+
var BaseProvider = /** @class */ (function (_super) {
|
|
173
|
+
__extends(BaseProvider, _super);
|
|
174
|
+
function BaseProvider(options) {
|
|
175
|
+
var _a, _b;
|
|
176
|
+
var _this = _super.call(this) || this;
|
|
177
|
+
// Metrics
|
|
178
|
+
_this.requestCount = 0;
|
|
179
|
+
_this.errorCount = 0;
|
|
180
|
+
_this.totalTokens = 0;
|
|
181
|
+
_this.totalCost = 0;
|
|
182
|
+
_this.requestMetrics = new Map();
|
|
183
|
+
_this.logger = options.logger || exports.consoleLogger;
|
|
184
|
+
_this.config = options.config;
|
|
185
|
+
// Initialize circuit breaker
|
|
186
|
+
_this.circuitBreaker = new CircuitBreaker("llm-".concat(_this.config.provider), ((_a = options.circuitBreakerOptions) === null || _a === void 0 ? void 0 : _a.threshold) || 5, ((_b = options.circuitBreakerOptions) === null || _b === void 0 ? void 0 : _b.resetTimeout) || 60000);
|
|
187
|
+
return _this;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Initialize the provider
|
|
191
|
+
*/
|
|
192
|
+
BaseProvider.prototype.initialize = function () {
|
|
193
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
194
|
+
return __generator(this, function (_a) {
|
|
195
|
+
switch (_a.label) {
|
|
196
|
+
case 0:
|
|
197
|
+
this.logger.info("Initializing ".concat(this.name, " provider"), {
|
|
198
|
+
model: this.config.model,
|
|
199
|
+
temperature: this.config.temperature,
|
|
200
|
+
maxTokens: this.config.maxTokens,
|
|
201
|
+
});
|
|
202
|
+
// Validate configuration
|
|
203
|
+
this.validateConfig();
|
|
204
|
+
// Provider-specific initialization
|
|
205
|
+
return [4 /*yield*/, this.doInitialize()];
|
|
206
|
+
case 1:
|
|
207
|
+
// Provider-specific initialization
|
|
208
|
+
_a.sent();
|
|
209
|
+
// Start health checks if caching enabled
|
|
210
|
+
if (this.config.enableCaching) {
|
|
211
|
+
this.startHealthChecks();
|
|
212
|
+
}
|
|
213
|
+
// Initial health check
|
|
214
|
+
return [4 /*yield*/, this.healthCheck()];
|
|
215
|
+
case 2:
|
|
216
|
+
// Initial health check
|
|
217
|
+
_a.sent();
|
|
218
|
+
return [2 /*return*/];
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
};
|
|
223
|
+
/**
|
|
224
|
+
* Validate provider configuration
|
|
225
|
+
*/
|
|
226
|
+
BaseProvider.prototype.validateConfig = function () {
|
|
227
|
+
if (!this.config.model) {
|
|
228
|
+
throw new Error("Model is required for ".concat(this.name, " provider"));
|
|
229
|
+
}
|
|
230
|
+
if (!this.validateModel(this.config.model)) {
|
|
231
|
+
this.logger.warn("Model ".concat(this.config.model, " may not be supported by ").concat(this.name));
|
|
232
|
+
}
|
|
233
|
+
if (this.config.temperature !== undefined) {
|
|
234
|
+
if (this.config.temperature < 0 || this.config.temperature > 2) {
|
|
235
|
+
throw new Error('Temperature must be between 0 and 2');
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
/**
|
|
240
|
+
* Complete a request
|
|
241
|
+
*/
|
|
242
|
+
BaseProvider.prototype.complete = function (request) {
|
|
243
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
244
|
+
var startTime, response, latency, error_2, providerError;
|
|
245
|
+
var _this = this;
|
|
246
|
+
var _a;
|
|
247
|
+
return __generator(this, function (_b) {
|
|
248
|
+
switch (_b.label) {
|
|
249
|
+
case 0:
|
|
250
|
+
startTime = Date.now();
|
|
251
|
+
_b.label = 1;
|
|
252
|
+
case 1:
|
|
253
|
+
_b.trys.push([1, 3, , 4]);
|
|
254
|
+
return [4 /*yield*/, this.circuitBreaker.execute(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
255
|
+
return __generator(this, function (_a) {
|
|
256
|
+
switch (_a.label) {
|
|
257
|
+
case 0: return [4 /*yield*/, this.doComplete(request)];
|
|
258
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
}); })];
|
|
262
|
+
case 2:
|
|
263
|
+
response = _b.sent();
|
|
264
|
+
latency = Date.now() - startTime;
|
|
265
|
+
this.trackRequest(request, response, latency);
|
|
266
|
+
this.emit('response', {
|
|
267
|
+
provider: this.name,
|
|
268
|
+
model: response.model,
|
|
269
|
+
latency: latency,
|
|
270
|
+
tokens: response.usage.totalTokens,
|
|
271
|
+
cost: (_a = response.cost) === null || _a === void 0 ? void 0 : _a.totalCost,
|
|
272
|
+
});
|
|
273
|
+
return [2 /*return*/, response];
|
|
274
|
+
case 3:
|
|
275
|
+
error_2 = _b.sent();
|
|
276
|
+
this.errorCount++;
|
|
277
|
+
providerError = this.transformError(error_2);
|
|
278
|
+
this.emit('error', {
|
|
279
|
+
provider: this.name,
|
|
280
|
+
error: providerError,
|
|
281
|
+
request: request,
|
|
282
|
+
});
|
|
283
|
+
throw providerError;
|
|
284
|
+
case 4: return [2 /*return*/];
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
});
|
|
288
|
+
};
|
|
289
|
+
/**
|
|
290
|
+
* Stream complete a request
|
|
291
|
+
*/
|
|
292
|
+
BaseProvider.prototype.streamComplete = function (request) {
|
|
293
|
+
return __asyncGenerator(this, arguments, function streamComplete_1() {
|
|
294
|
+
var startTime, totalTokens, totalCost, stream, _a, stream_1, stream_1_1, event_1, e_1_1, latency, error_3, providerError;
|
|
295
|
+
var _this = this;
|
|
296
|
+
var _b, e_1, _c, _d;
|
|
297
|
+
return __generator(this, function (_e) {
|
|
298
|
+
switch (_e.label) {
|
|
299
|
+
case 0:
|
|
300
|
+
startTime = Date.now();
|
|
301
|
+
totalTokens = 0;
|
|
302
|
+
totalCost = 0;
|
|
303
|
+
_e.label = 1;
|
|
304
|
+
case 1:
|
|
305
|
+
_e.trys.push([1, 17, , 20]);
|
|
306
|
+
if (!this.capabilities.supportsStreaming) {
|
|
307
|
+
throw new types_js_1.LLMProviderError('Streaming not supported', 'STREAMING_NOT_SUPPORTED', this.name, undefined, false);
|
|
308
|
+
}
|
|
309
|
+
return [4 /*yield*/, __await(this.circuitBreaker.execute(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
310
|
+
return __generator(this, function (_a) {
|
|
311
|
+
return [2 /*return*/, this.doStreamComplete(request)];
|
|
312
|
+
});
|
|
313
|
+
}); }))];
|
|
314
|
+
case 2:
|
|
315
|
+
stream = _e.sent();
|
|
316
|
+
_e.label = 3;
|
|
317
|
+
case 3:
|
|
318
|
+
_e.trys.push([3, 10, 11, 16]);
|
|
319
|
+
_a = true, stream_1 = __asyncValues(stream);
|
|
320
|
+
_e.label = 4;
|
|
321
|
+
case 4: return [4 /*yield*/, __await(stream_1.next())];
|
|
322
|
+
case 5:
|
|
323
|
+
if (!(stream_1_1 = _e.sent(), _b = stream_1_1.done, !_b)) return [3 /*break*/, 9];
|
|
324
|
+
_d = stream_1_1.value;
|
|
325
|
+
_a = false;
|
|
326
|
+
event_1 = _d;
|
|
327
|
+
if (event_1.usage) {
|
|
328
|
+
totalTokens = event_1.usage.totalTokens;
|
|
329
|
+
}
|
|
330
|
+
if (event_1.cost) {
|
|
331
|
+
totalCost = event_1.cost.totalCost;
|
|
332
|
+
}
|
|
333
|
+
return [4 /*yield*/, __await(event_1)];
|
|
334
|
+
case 6: return [4 /*yield*/, _e.sent()];
|
|
335
|
+
case 7:
|
|
336
|
+
_e.sent();
|
|
337
|
+
_e.label = 8;
|
|
338
|
+
case 8:
|
|
339
|
+
_a = true;
|
|
340
|
+
return [3 /*break*/, 4];
|
|
341
|
+
case 9: return [3 /*break*/, 16];
|
|
342
|
+
case 10:
|
|
343
|
+
e_1_1 = _e.sent();
|
|
344
|
+
e_1 = { error: e_1_1 };
|
|
345
|
+
return [3 /*break*/, 16];
|
|
346
|
+
case 11:
|
|
347
|
+
_e.trys.push([11, , 14, 15]);
|
|
348
|
+
if (!(!_a && !_b && (_c = stream_1.return))) return [3 /*break*/, 13];
|
|
349
|
+
return [4 /*yield*/, __await(_c.call(stream_1))];
|
|
350
|
+
case 12:
|
|
351
|
+
_e.sent();
|
|
352
|
+
_e.label = 13;
|
|
353
|
+
case 13: return [3 /*break*/, 15];
|
|
354
|
+
case 14:
|
|
355
|
+
if (e_1) throw e_1.error;
|
|
356
|
+
return [7 /*endfinally*/];
|
|
357
|
+
case 15: return [7 /*endfinally*/];
|
|
358
|
+
case 16:
|
|
359
|
+
latency = Date.now() - startTime;
|
|
360
|
+
this.trackStreamRequest(request, totalTokens, totalCost, latency);
|
|
361
|
+
return [3 /*break*/, 20];
|
|
362
|
+
case 17:
|
|
363
|
+
error_3 = _e.sent();
|
|
364
|
+
this.errorCount++;
|
|
365
|
+
providerError = this.transformError(error_3);
|
|
366
|
+
return [4 /*yield*/, __await({ type: 'error', error: providerError })];
|
|
367
|
+
case 18: return [4 /*yield*/, _e.sent()];
|
|
368
|
+
case 19:
|
|
369
|
+
_e.sent();
|
|
370
|
+
throw providerError;
|
|
371
|
+
case 20: return [2 /*return*/];
|
|
372
|
+
}
|
|
373
|
+
});
|
|
374
|
+
});
|
|
375
|
+
};
|
|
376
|
+
/**
|
|
377
|
+
* Validate if a model is supported
|
|
378
|
+
*/
|
|
379
|
+
BaseProvider.prototype.validateModel = function (model) {
|
|
380
|
+
return this.capabilities.supportedModels.includes(model);
|
|
381
|
+
};
|
|
382
|
+
/**
|
|
383
|
+
* Perform health check
|
|
384
|
+
*/
|
|
385
|
+
BaseProvider.prototype.healthCheck = function () {
|
|
386
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
387
|
+
var startTime, result, error_4;
|
|
388
|
+
return __generator(this, function (_a) {
|
|
389
|
+
switch (_a.label) {
|
|
390
|
+
case 0:
|
|
391
|
+
startTime = Date.now();
|
|
392
|
+
_a.label = 1;
|
|
393
|
+
case 1:
|
|
394
|
+
_a.trys.push([1, 3, , 4]);
|
|
395
|
+
return [4 /*yield*/, this.doHealthCheck()];
|
|
396
|
+
case 2:
|
|
397
|
+
result = _a.sent();
|
|
398
|
+
this.lastHealthCheck = __assign(__assign({}, result), { latency: Date.now() - startTime, timestamp: new Date() });
|
|
399
|
+
this.emit('health_check', this.lastHealthCheck);
|
|
400
|
+
return [2 /*return*/, this.lastHealthCheck];
|
|
401
|
+
case 3:
|
|
402
|
+
error_4 = _a.sent();
|
|
403
|
+
this.lastHealthCheck = {
|
|
404
|
+
healthy: false,
|
|
405
|
+
error: error_4 instanceof Error ? error_4.message : 'Unknown error',
|
|
406
|
+
latency: Date.now() - startTime,
|
|
407
|
+
timestamp: new Date(),
|
|
408
|
+
};
|
|
409
|
+
this.emit('health_check', this.lastHealthCheck);
|
|
410
|
+
return [2 /*return*/, this.lastHealthCheck];
|
|
411
|
+
case 4: return [2 /*return*/];
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
});
|
|
415
|
+
};
|
|
416
|
+
/**
|
|
417
|
+
* Get provider status
|
|
418
|
+
*/
|
|
419
|
+
BaseProvider.prototype.getStatus = function () {
|
|
420
|
+
var _a, _b;
|
|
421
|
+
var queueLength = this.requestMetrics.size;
|
|
422
|
+
return {
|
|
423
|
+
available: (_b = (_a = this.lastHealthCheck) === null || _a === void 0 ? void 0 : _a.healthy) !== null && _b !== void 0 ? _b : false,
|
|
424
|
+
currentLoad: Math.min(queueLength / 100, 1),
|
|
425
|
+
queueLength: queueLength,
|
|
426
|
+
activeRequests: queueLength,
|
|
427
|
+
rateLimitRemaining: this.getRateLimitRemaining(),
|
|
428
|
+
rateLimitReset: this.getRateLimitReset(),
|
|
429
|
+
};
|
|
430
|
+
};
|
|
431
|
+
/**
|
|
432
|
+
* Get remaining rate limit (override in provider)
|
|
433
|
+
*/
|
|
434
|
+
BaseProvider.prototype.getRateLimitRemaining = function () {
|
|
435
|
+
return undefined;
|
|
436
|
+
};
|
|
437
|
+
/**
|
|
438
|
+
* Get rate limit reset time (override in provider)
|
|
439
|
+
*/
|
|
440
|
+
BaseProvider.prototype.getRateLimitReset = function () {
|
|
441
|
+
return undefined;
|
|
442
|
+
};
|
|
443
|
+
/**
|
|
444
|
+
* Estimate cost for a request
|
|
445
|
+
*/
|
|
446
|
+
BaseProvider.prototype.estimateCost = function (request) {
|
|
447
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
448
|
+
var model, pricing, promptTokens, completionTokens, promptCost, completionCost;
|
|
449
|
+
var _a;
|
|
450
|
+
return __generator(this, function (_b) {
|
|
451
|
+
model = request.model || this.config.model;
|
|
452
|
+
pricing = (_a = this.capabilities.pricing) === null || _a === void 0 ? void 0 : _a[model];
|
|
453
|
+
if (!pricing) {
|
|
454
|
+
return [2 /*return*/, {
|
|
455
|
+
estimatedPromptTokens: 0,
|
|
456
|
+
estimatedCompletionTokens: 0,
|
|
457
|
+
estimatedTotalTokens: 0,
|
|
458
|
+
estimatedCost: { prompt: 0, completion: 0, total: 0, currency: 'USD' },
|
|
459
|
+
confidence: 0,
|
|
460
|
+
}];
|
|
461
|
+
}
|
|
462
|
+
promptTokens = this.estimateTokens(JSON.stringify(request.messages));
|
|
463
|
+
completionTokens = request.maxTokens || this.config.maxTokens || 1000;
|
|
464
|
+
promptCost = (promptTokens / 1000) * pricing.promptCostPer1k;
|
|
465
|
+
completionCost = (completionTokens / 1000) * pricing.completionCostPer1k;
|
|
466
|
+
return [2 /*return*/, {
|
|
467
|
+
estimatedPromptTokens: promptTokens,
|
|
468
|
+
estimatedCompletionTokens: completionTokens,
|
|
469
|
+
estimatedTotalTokens: promptTokens + completionTokens,
|
|
470
|
+
estimatedCost: {
|
|
471
|
+
prompt: promptCost,
|
|
472
|
+
completion: completionCost,
|
|
473
|
+
total: promptCost + completionCost,
|
|
474
|
+
currency: pricing.currency,
|
|
475
|
+
},
|
|
476
|
+
confidence: 0.7,
|
|
477
|
+
}];
|
|
478
|
+
});
|
|
479
|
+
});
|
|
480
|
+
};
|
|
481
|
+
/**
|
|
482
|
+
* Simple token estimation (4 chars ≈ 1 token)
|
|
483
|
+
*/
|
|
484
|
+
BaseProvider.prototype.estimateTokens = function (text) {
|
|
485
|
+
return Math.ceil(text.length / 4);
|
|
486
|
+
};
|
|
487
|
+
/**
|
|
488
|
+
* Get usage statistics
|
|
489
|
+
*/
|
|
490
|
+
BaseProvider.prototype.getUsage = function () {
|
|
491
|
+
return __awaiter(this, arguments, void 0, function (period) {
|
|
492
|
+
var now, start;
|
|
493
|
+
if (period === void 0) { period = 'day'; }
|
|
494
|
+
return __generator(this, function (_a) {
|
|
495
|
+
now = new Date();
|
|
496
|
+
start = this.getStartDate(now, period);
|
|
497
|
+
return [2 /*return*/, {
|
|
498
|
+
period: { start: start, end: now },
|
|
499
|
+
requests: this.requestCount,
|
|
500
|
+
tokens: {
|
|
501
|
+
prompt: Math.floor(this.totalTokens * 0.7),
|
|
502
|
+
completion: Math.floor(this.totalTokens * 0.3),
|
|
503
|
+
total: this.totalTokens,
|
|
504
|
+
},
|
|
505
|
+
cost: {
|
|
506
|
+
prompt: this.totalCost * 0.7,
|
|
507
|
+
completion: this.totalCost * 0.3,
|
|
508
|
+
total: this.totalCost,
|
|
509
|
+
currency: 'USD',
|
|
510
|
+
},
|
|
511
|
+
errors: this.errorCount,
|
|
512
|
+
averageLatency: this.calculateAverageLatency(),
|
|
513
|
+
modelBreakdown: {},
|
|
514
|
+
}];
|
|
515
|
+
});
|
|
516
|
+
});
|
|
517
|
+
};
|
|
518
|
+
BaseProvider.prototype.getStartDate = function (end, period) {
|
|
519
|
+
var start = new Date(end);
|
|
520
|
+
switch (period) {
|
|
521
|
+
case 'hour':
|
|
522
|
+
start.setHours(start.getHours() - 1);
|
|
523
|
+
break;
|
|
524
|
+
case 'day':
|
|
525
|
+
start.setDate(start.getDate() - 1);
|
|
526
|
+
break;
|
|
527
|
+
case 'week':
|
|
528
|
+
start.setDate(start.getDate() - 7);
|
|
529
|
+
break;
|
|
530
|
+
case 'month':
|
|
531
|
+
start.setMonth(start.getMonth() - 1);
|
|
532
|
+
break;
|
|
533
|
+
case 'all':
|
|
534
|
+
start.setFullYear(2020);
|
|
535
|
+
break;
|
|
536
|
+
}
|
|
537
|
+
return start;
|
|
538
|
+
};
|
|
539
|
+
BaseProvider.prototype.calculateAverageLatency = function () {
|
|
540
|
+
if (this.requestMetrics.size === 0)
|
|
541
|
+
return 0;
|
|
542
|
+
var total = 0;
|
|
543
|
+
var count = 0;
|
|
544
|
+
this.requestMetrics.forEach(function (metrics) {
|
|
545
|
+
if (metrics.latency) {
|
|
546
|
+
total += metrics.latency;
|
|
547
|
+
count++;
|
|
548
|
+
}
|
|
549
|
+
});
|
|
550
|
+
return count > 0 ? total / count : 0;
|
|
551
|
+
};
|
|
552
|
+
/**
|
|
553
|
+
* Track successful request
|
|
554
|
+
*/
|
|
555
|
+
BaseProvider.prototype.trackRequest = function (request, response, latency) {
|
|
556
|
+
var _a;
|
|
557
|
+
this.requestCount++;
|
|
558
|
+
this.totalTokens += response.usage.totalTokens;
|
|
559
|
+
if (response.cost) {
|
|
560
|
+
this.totalCost += response.cost.totalCost;
|
|
561
|
+
}
|
|
562
|
+
this.requestMetrics.set(response.id, {
|
|
563
|
+
timestamp: new Date(),
|
|
564
|
+
model: response.model,
|
|
565
|
+
tokens: response.usage.totalTokens,
|
|
566
|
+
cost: (_a = response.cost) === null || _a === void 0 ? void 0 : _a.totalCost,
|
|
567
|
+
latency: latency,
|
|
568
|
+
});
|
|
569
|
+
// Keep last 1000 metrics
|
|
570
|
+
if (this.requestMetrics.size > 1000) {
|
|
571
|
+
var oldestKey = this.requestMetrics.keys().next().value;
|
|
572
|
+
if (oldestKey)
|
|
573
|
+
this.requestMetrics.delete(oldestKey);
|
|
574
|
+
}
|
|
575
|
+
};
|
|
576
|
+
/**
|
|
577
|
+
* Track streaming request
|
|
578
|
+
*/
|
|
579
|
+
BaseProvider.prototype.trackStreamRequest = function (request, totalTokens, totalCost, latency) {
|
|
580
|
+
this.requestCount++;
|
|
581
|
+
this.totalTokens += totalTokens;
|
|
582
|
+
this.totalCost += totalCost;
|
|
583
|
+
this.requestMetrics.set("stream-".concat(Date.now()), {
|
|
584
|
+
timestamp: new Date(),
|
|
585
|
+
model: request.model || this.config.model,
|
|
586
|
+
tokens: totalTokens,
|
|
587
|
+
cost: totalCost,
|
|
588
|
+
latency: latency,
|
|
589
|
+
});
|
|
590
|
+
};
|
|
591
|
+
/**
|
|
592
|
+
* Transform errors to provider errors
|
|
593
|
+
*/
|
|
594
|
+
BaseProvider.prototype.transformError = function (error) {
|
|
595
|
+
if (error instanceof types_js_1.LLMProviderError) {
|
|
596
|
+
return error;
|
|
597
|
+
}
|
|
598
|
+
if (error instanceof Error) {
|
|
599
|
+
if (error.message.includes('rate limit')) {
|
|
600
|
+
return new types_js_1.RateLimitError(error.message, this.name);
|
|
601
|
+
}
|
|
602
|
+
if (error.message.includes('timeout') || error.message.includes('ETIMEDOUT')) {
|
|
603
|
+
return new types_js_1.LLMProviderError('Request timed out', 'TIMEOUT', this.name, undefined, true);
|
|
604
|
+
}
|
|
605
|
+
if (error.message.includes('ECONNREFUSED') || error.message.includes('fetch failed')) {
|
|
606
|
+
return new types_js_1.ProviderUnavailableError(this.name, { originalError: error.message });
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
return new types_js_1.LLMProviderError(error instanceof Error ? error.message : String(error), 'UNKNOWN', this.name, undefined, true);
|
|
610
|
+
};
|
|
611
|
+
/**
|
|
612
|
+
* Start periodic health checks
|
|
613
|
+
*/
|
|
614
|
+
BaseProvider.prototype.startHealthChecks = function () {
|
|
615
|
+
var _this = this;
|
|
616
|
+
var interval = this.config.cacheTimeout || 300000;
|
|
617
|
+
this.healthCheckInterval = setInterval(function () {
|
|
618
|
+
_this.healthCheck().catch(function (error) {
|
|
619
|
+
_this.logger.error("Health check failed for ".concat(_this.name), error);
|
|
620
|
+
});
|
|
621
|
+
}, interval);
|
|
622
|
+
};
|
|
623
|
+
/**
|
|
624
|
+
* Clean up resources
|
|
625
|
+
*/
|
|
626
|
+
BaseProvider.prototype.destroy = function () {
|
|
627
|
+
if (this.healthCheckInterval) {
|
|
628
|
+
clearInterval(this.healthCheckInterval);
|
|
629
|
+
}
|
|
630
|
+
this.requestMetrics.clear();
|
|
631
|
+
this.removeAllListeners();
|
|
632
|
+
this.logger.info("".concat(this.name, " provider destroyed"));
|
|
633
|
+
};
|
|
634
|
+
return BaseProvider;
|
|
635
|
+
}(events_1.EventEmitter));
|
|
636
|
+
exports.BaseProvider = BaseProvider;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* V3 Cohere Provider
|
|
3
|
+
*
|
|
4
|
+
* Supports Command R+, Command R, and Command Light models.
|
|
5
|
+
*
|
|
6
|
+
* @module @sparkleideas/providers/cohere-provider
|
|
7
|
+
*/
|
|
8
|
+
import { BaseProvider, BaseProviderOptions } from './base-provider.js';
|
|
9
|
+
import { LLMProvider, LLMModel, LLMRequest, LLMResponse, LLMStreamEvent, ModelInfo, ProviderCapabilities, HealthCheckResult } from './types.js';
|
|
10
|
+
export declare class CohereProvider extends BaseProvider {
|
|
11
|
+
readonly name: LLMProvider;
|
|
12
|
+
readonly capabilities: ProviderCapabilities;
|
|
13
|
+
private baseUrl;
|
|
14
|
+
private headers;
|
|
15
|
+
constructor(options: BaseProviderOptions);
|
|
16
|
+
protected doInitialize(): Promise<void>;
|
|
17
|
+
protected doComplete(request: LLMRequest): Promise<LLMResponse>;
|
|
18
|
+
protected doStreamComplete(request: LLMRequest): AsyncIterable<LLMStreamEvent>;
|
|
19
|
+
listModels(): Promise<LLMModel[]>;
|
|
20
|
+
getModelInfo(model: LLMModel): Promise<ModelInfo>;
|
|
21
|
+
protected doHealthCheck(): Promise<HealthCheckResult>;
|
|
22
|
+
private buildRequest;
|
|
23
|
+
private transformResponse;
|
|
24
|
+
private handleErrorResponse;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=cohere-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cohere-provider.d.ts","sourceRoot":"","sources":["../src/cohere-provider.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EACL,WAAW,EACX,QAAQ,EACR,UAAU,EACV,WAAW,EACX,cAAc,EACd,SAAS,EACT,oBAAoB,EACpB,iBAAiB,EAIlB,MAAM,YAAY,CAAC;AA0CpB,qBAAa,cAAe,SAAQ,YAAY;IAC9C,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAY;IACtC,QAAQ,CAAC,YAAY,EAAE,oBAAoB,CAsDzC;IAEF,OAAO,CAAC,OAAO,CAAsC;IACrD,OAAO,CAAC,OAAO,CAA8B;gBAEjC,OAAO,EAAE,mBAAmB;cAIxB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;cAY7B,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;cA4BpD,gBAAgB,CAAC,OAAO,EAAE,UAAU,GAAG,aAAa,CAAC,cAAc,CAAC;IAkF/E,UAAU,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAIjC,YAAY,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC;cAmBvC,aAAa,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAqB3D,OAAO,CAAC,YAAY;IA4DpB,OAAO,CAAC,iBAAiB;YAwCX,mBAAmB;CA4BlC"}
|