@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,543 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* V3 OpenAI Provider
|
|
4
|
+
*
|
|
5
|
+
* Supports GPT-4o, GPT-4, o1, and other OpenAI models.
|
|
6
|
+
*
|
|
7
|
+
* @module @sparkleideas/providers/openai-provider
|
|
8
|
+
*/
|
|
9
|
+
var __extends = (this && this.__extends) || (function () {
|
|
10
|
+
var extendStatics = function (d, b) {
|
|
11
|
+
extendStatics = Object.setPrototypeOf ||
|
|
12
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
13
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
14
|
+
return extendStatics(d, b);
|
|
15
|
+
};
|
|
16
|
+
return function (d, b) {
|
|
17
|
+
if (typeof b !== "function" && b !== null)
|
|
18
|
+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
19
|
+
extendStatics(d, b);
|
|
20
|
+
function __() { this.constructor = d; }
|
|
21
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
var __assign = (this && this.__assign) || function () {
|
|
25
|
+
__assign = Object.assign || function(t) {
|
|
26
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
27
|
+
s = arguments[i];
|
|
28
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
29
|
+
t[p] = s[p];
|
|
30
|
+
}
|
|
31
|
+
return t;
|
|
32
|
+
};
|
|
33
|
+
return __assign.apply(this, arguments);
|
|
34
|
+
};
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
45
|
+
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);
|
|
46
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
47
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
48
|
+
function step(op) {
|
|
49
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
50
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
51
|
+
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;
|
|
52
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
53
|
+
switch (op[0]) {
|
|
54
|
+
case 0: case 1: t = op; break;
|
|
55
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
56
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
57
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
58
|
+
default:
|
|
59
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
60
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
61
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
62
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
63
|
+
if (t[2]) _.ops.pop();
|
|
64
|
+
_.trys.pop(); continue;
|
|
65
|
+
}
|
|
66
|
+
op = body.call(thisArg, _);
|
|
67
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
68
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
|
|
72
|
+
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
|
|
73
|
+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
74
|
+
var g = generator.apply(thisArg, _arguments || []), i, q = [];
|
|
75
|
+
return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
|
|
76
|
+
function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }
|
|
77
|
+
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]); } }
|
|
78
|
+
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
|
|
79
|
+
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
|
|
80
|
+
function fulfill(value) { resume("next", value); }
|
|
81
|
+
function reject(value) { resume("throw", value); }
|
|
82
|
+
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
|
|
83
|
+
};
|
|
84
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
85
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
86
|
+
if (ar || !(i in from)) {
|
|
87
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
88
|
+
ar[i] = from[i];
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
92
|
+
};
|
|
93
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
94
|
+
exports.OpenAIProvider = void 0;
|
|
95
|
+
var base_provider_js_1 = require("./base-provider.js");
|
|
96
|
+
var types_js_1 = require("./types.js");
|
|
97
|
+
var OpenAIProvider = /** @class */ (function (_super) {
|
|
98
|
+
__extends(OpenAIProvider, _super);
|
|
99
|
+
function OpenAIProvider(options) {
|
|
100
|
+
var _this = _super.call(this, options) || this;
|
|
101
|
+
_this.name = 'openai';
|
|
102
|
+
_this.capabilities = {
|
|
103
|
+
supportedModels: [
|
|
104
|
+
'gpt-4o',
|
|
105
|
+
'gpt-4o-mini',
|
|
106
|
+
'gpt-4-turbo',
|
|
107
|
+
'gpt-4',
|
|
108
|
+
'gpt-3.5-turbo',
|
|
109
|
+
'o1-preview',
|
|
110
|
+
'o1-mini',
|
|
111
|
+
'o3-mini',
|
|
112
|
+
],
|
|
113
|
+
maxContextLength: {
|
|
114
|
+
'gpt-4o': 128000,
|
|
115
|
+
'gpt-4o-mini': 128000,
|
|
116
|
+
'gpt-4-turbo': 128000,
|
|
117
|
+
'gpt-4': 8192,
|
|
118
|
+
'gpt-3.5-turbo': 16384,
|
|
119
|
+
'o1-preview': 128000,
|
|
120
|
+
'o1-mini': 128000,
|
|
121
|
+
'o3-mini': 200000,
|
|
122
|
+
},
|
|
123
|
+
maxOutputTokens: {
|
|
124
|
+
'gpt-4o': 16384,
|
|
125
|
+
'gpt-4o-mini': 16384,
|
|
126
|
+
'gpt-4-turbo': 4096,
|
|
127
|
+
'gpt-4': 8192,
|
|
128
|
+
'gpt-3.5-turbo': 4096,
|
|
129
|
+
'o1-preview': 32768,
|
|
130
|
+
'o1-mini': 65536,
|
|
131
|
+
'o3-mini': 100000,
|
|
132
|
+
},
|
|
133
|
+
supportsStreaming: true,
|
|
134
|
+
supportsToolCalling: true,
|
|
135
|
+
supportsSystemMessages: true,
|
|
136
|
+
supportsVision: true,
|
|
137
|
+
supportsAudio: true,
|
|
138
|
+
supportsFineTuning: true,
|
|
139
|
+
supportsEmbeddings: true,
|
|
140
|
+
supportsBatching: true,
|
|
141
|
+
rateLimit: {
|
|
142
|
+
requestsPerMinute: 10000,
|
|
143
|
+
tokensPerMinute: 2000000,
|
|
144
|
+
concurrentRequests: 500,
|
|
145
|
+
},
|
|
146
|
+
pricing: {
|
|
147
|
+
'gpt-4o': {
|
|
148
|
+
promptCostPer1k: 0.0025,
|
|
149
|
+
completionCostPer1k: 0.01,
|
|
150
|
+
currency: 'USD',
|
|
151
|
+
},
|
|
152
|
+
'gpt-4o-mini': {
|
|
153
|
+
promptCostPer1k: 0.00015,
|
|
154
|
+
completionCostPer1k: 0.0006,
|
|
155
|
+
currency: 'USD',
|
|
156
|
+
},
|
|
157
|
+
'gpt-4-turbo': {
|
|
158
|
+
promptCostPer1k: 0.01,
|
|
159
|
+
completionCostPer1k: 0.03,
|
|
160
|
+
currency: 'USD',
|
|
161
|
+
},
|
|
162
|
+
'gpt-4': {
|
|
163
|
+
promptCostPer1k: 0.03,
|
|
164
|
+
completionCostPer1k: 0.06,
|
|
165
|
+
currency: 'USD',
|
|
166
|
+
},
|
|
167
|
+
'gpt-3.5-turbo': {
|
|
168
|
+
promptCostPer1k: 0.0005,
|
|
169
|
+
completionCostPer1k: 0.0015,
|
|
170
|
+
currency: 'USD',
|
|
171
|
+
},
|
|
172
|
+
'o1-preview': {
|
|
173
|
+
promptCostPer1k: 0.015,
|
|
174
|
+
completionCostPer1k: 0.06,
|
|
175
|
+
currency: 'USD',
|
|
176
|
+
},
|
|
177
|
+
'o1-mini': {
|
|
178
|
+
promptCostPer1k: 0.003,
|
|
179
|
+
completionCostPer1k: 0.012,
|
|
180
|
+
currency: 'USD',
|
|
181
|
+
},
|
|
182
|
+
'o3-mini': {
|
|
183
|
+
promptCostPer1k: 0.0011,
|
|
184
|
+
completionCostPer1k: 0.0044,
|
|
185
|
+
currency: 'USD',
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
};
|
|
189
|
+
_this.baseUrl = 'https://api.openai.com/v1';
|
|
190
|
+
_this.headers = {};
|
|
191
|
+
return _this;
|
|
192
|
+
}
|
|
193
|
+
OpenAIProvider.prototype.doInitialize = function () {
|
|
194
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
195
|
+
var _a;
|
|
196
|
+
return __generator(this, function (_b) {
|
|
197
|
+
if (!this.config.apiKey) {
|
|
198
|
+
throw new types_js_1.AuthenticationError('OpenAI API key is required', 'openai');
|
|
199
|
+
}
|
|
200
|
+
this.baseUrl = this.config.apiUrl || 'https://api.openai.com/v1';
|
|
201
|
+
this.headers = {
|
|
202
|
+
Authorization: "Bearer ".concat(this.config.apiKey),
|
|
203
|
+
'Content-Type': 'application/json',
|
|
204
|
+
};
|
|
205
|
+
if ((_a = this.config.providerOptions) === null || _a === void 0 ? void 0 : _a.organization) {
|
|
206
|
+
this.headers['OpenAI-Organization'] = this.config.providerOptions.organization;
|
|
207
|
+
}
|
|
208
|
+
return [2 /*return*/];
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
};
|
|
212
|
+
OpenAIProvider.prototype.doComplete = function (request) {
|
|
213
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
214
|
+
var openAIRequest, controller, timeout, response, data, error_1;
|
|
215
|
+
return __generator(this, function (_a) {
|
|
216
|
+
switch (_a.label) {
|
|
217
|
+
case 0:
|
|
218
|
+
openAIRequest = this.buildRequest(request);
|
|
219
|
+
controller = new AbortController();
|
|
220
|
+
timeout = setTimeout(function () { return controller.abort(); }, this.config.timeout || 60000);
|
|
221
|
+
_a.label = 1;
|
|
222
|
+
case 1:
|
|
223
|
+
_a.trys.push([1, 6, , 7]);
|
|
224
|
+
return [4 /*yield*/, fetch("".concat(this.baseUrl, "/chat/completions"), {
|
|
225
|
+
method: 'POST',
|
|
226
|
+
headers: this.headers,
|
|
227
|
+
body: JSON.stringify(openAIRequest),
|
|
228
|
+
signal: controller.signal,
|
|
229
|
+
})];
|
|
230
|
+
case 2:
|
|
231
|
+
response = _a.sent();
|
|
232
|
+
clearTimeout(timeout);
|
|
233
|
+
if (!!response.ok) return [3 /*break*/, 4];
|
|
234
|
+
return [4 /*yield*/, this.handleErrorResponse(response)];
|
|
235
|
+
case 3:
|
|
236
|
+
_a.sent();
|
|
237
|
+
_a.label = 4;
|
|
238
|
+
case 4: return [4 /*yield*/, response.json()];
|
|
239
|
+
case 5:
|
|
240
|
+
data = _a.sent();
|
|
241
|
+
return [2 /*return*/, this.transformResponse(data, request)];
|
|
242
|
+
case 6:
|
|
243
|
+
error_1 = _a.sent();
|
|
244
|
+
clearTimeout(timeout);
|
|
245
|
+
throw this.transformError(error_1);
|
|
246
|
+
case 7: return [2 /*return*/];
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
};
|
|
251
|
+
OpenAIProvider.prototype.doStreamComplete = function (request) {
|
|
252
|
+
return __asyncGenerator(this, arguments, function doStreamComplete_1() {
|
|
253
|
+
var openAIRequest, controller, timeout, response, reader, decoder, buffer, _a, done, value, lines, _i, lines_1, line, data, promptTokens, model, baseModel, pricing, promptCostPer1k, completionCostPer1k, chunk, delta, _b, _c, toolCall, _d, error_2;
|
|
254
|
+
var _e, _f, _g, _h;
|
|
255
|
+
return __generator(this, function (_j) {
|
|
256
|
+
switch (_j.label) {
|
|
257
|
+
case 0:
|
|
258
|
+
openAIRequest = this.buildRequest(request, true);
|
|
259
|
+
controller = new AbortController();
|
|
260
|
+
timeout = setTimeout(function () { return controller.abort(); }, (this.config.timeout || 60000) * 2);
|
|
261
|
+
_j.label = 1;
|
|
262
|
+
case 1:
|
|
263
|
+
_j.trys.push([1, 23, 24, 25]);
|
|
264
|
+
return [4 /*yield*/, __await(fetch("".concat(this.baseUrl, "/chat/completions"), {
|
|
265
|
+
method: 'POST',
|
|
266
|
+
headers: this.headers,
|
|
267
|
+
body: JSON.stringify(openAIRequest),
|
|
268
|
+
signal: controller.signal,
|
|
269
|
+
}))];
|
|
270
|
+
case 2:
|
|
271
|
+
response = _j.sent();
|
|
272
|
+
if (!!response.ok) return [3 /*break*/, 4];
|
|
273
|
+
return [4 /*yield*/, __await(this.handleErrorResponse(response))];
|
|
274
|
+
case 3:
|
|
275
|
+
_j.sent();
|
|
276
|
+
_j.label = 4;
|
|
277
|
+
case 4:
|
|
278
|
+
reader = response.body.getReader();
|
|
279
|
+
decoder = new TextDecoder();
|
|
280
|
+
buffer = '';
|
|
281
|
+
_j.label = 5;
|
|
282
|
+
case 5:
|
|
283
|
+
if (!true) return [3 /*break*/, 22];
|
|
284
|
+
return [4 /*yield*/, __await(reader.read())];
|
|
285
|
+
case 6:
|
|
286
|
+
_a = _j.sent(), done = _a.done, value = _a.value;
|
|
287
|
+
if (done)
|
|
288
|
+
return [3 /*break*/, 22];
|
|
289
|
+
buffer += decoder.decode(value, { stream: true });
|
|
290
|
+
lines = buffer.split('\n');
|
|
291
|
+
buffer = lines.pop() || '';
|
|
292
|
+
_i = 0, lines_1 = lines;
|
|
293
|
+
_j.label = 7;
|
|
294
|
+
case 7:
|
|
295
|
+
if (!(_i < lines_1.length)) return [3 /*break*/, 21];
|
|
296
|
+
line = lines_1[_i];
|
|
297
|
+
if (!line.startsWith('data: ')) return [3 /*break*/, 20];
|
|
298
|
+
data = line.slice(6);
|
|
299
|
+
if (!(data === '[DONE]')) return [3 /*break*/, 10];
|
|
300
|
+
promptTokens = this.estimateTokens(JSON.stringify(request.messages));
|
|
301
|
+
model = request.model || this.config.model;
|
|
302
|
+
baseModel = model.includes('/') ? model.split('/').pop() : model;
|
|
303
|
+
pricing = this.capabilities.pricing[model] || this.capabilities.pricing[baseModel];
|
|
304
|
+
promptCostPer1k = (_e = pricing === null || pricing === void 0 ? void 0 : pricing.promptCostPer1k) !== null && _e !== void 0 ? _e : 0;
|
|
305
|
+
completionCostPer1k = (_f = pricing === null || pricing === void 0 ? void 0 : pricing.completionCostPer1k) !== null && _f !== void 0 ? _f : 0;
|
|
306
|
+
return [4 /*yield*/, __await({
|
|
307
|
+
type: 'done',
|
|
308
|
+
usage: {
|
|
309
|
+
promptTokens: promptTokens,
|
|
310
|
+
completionTokens: 100, // Estimate
|
|
311
|
+
totalTokens: promptTokens + 100,
|
|
312
|
+
},
|
|
313
|
+
cost: {
|
|
314
|
+
promptCost: (promptTokens / 1000) * promptCostPer1k,
|
|
315
|
+
completionCost: (100 / 1000) * completionCostPer1k,
|
|
316
|
+
totalCost: (promptTokens / 1000) * promptCostPer1k +
|
|
317
|
+
(100 / 1000) * completionCostPer1k,
|
|
318
|
+
currency: 'USD',
|
|
319
|
+
},
|
|
320
|
+
})];
|
|
321
|
+
case 8: return [4 /*yield*/, _j.sent()];
|
|
322
|
+
case 9:
|
|
323
|
+
_j.sent();
|
|
324
|
+
return [3 /*break*/, 20];
|
|
325
|
+
case 10:
|
|
326
|
+
_j.trys.push([10, 19, , 20]);
|
|
327
|
+
chunk = JSON.parse(data);
|
|
328
|
+
delta = (_h = (_g = chunk.choices) === null || _g === void 0 ? void 0 : _g[0]) === null || _h === void 0 ? void 0 : _h.delta;
|
|
329
|
+
if (!(delta === null || delta === void 0 ? void 0 : delta.content)) return [3 /*break*/, 13];
|
|
330
|
+
return [4 /*yield*/, __await({
|
|
331
|
+
type: 'content',
|
|
332
|
+
delta: { content: delta.content },
|
|
333
|
+
})];
|
|
334
|
+
case 11: return [4 /*yield*/, _j.sent()];
|
|
335
|
+
case 12:
|
|
336
|
+
_j.sent();
|
|
337
|
+
_j.label = 13;
|
|
338
|
+
case 13:
|
|
339
|
+
if (!(delta === null || delta === void 0 ? void 0 : delta.tool_calls)) return [3 /*break*/, 18];
|
|
340
|
+
_b = 0, _c = delta.tool_calls;
|
|
341
|
+
_j.label = 14;
|
|
342
|
+
case 14:
|
|
343
|
+
if (!(_b < _c.length)) return [3 /*break*/, 18];
|
|
344
|
+
toolCall = _c[_b];
|
|
345
|
+
return [4 /*yield*/, __await({
|
|
346
|
+
type: 'tool_call',
|
|
347
|
+
delta: {
|
|
348
|
+
toolCall: {
|
|
349
|
+
id: toolCall.id,
|
|
350
|
+
type: 'function',
|
|
351
|
+
function: toolCall.function,
|
|
352
|
+
},
|
|
353
|
+
},
|
|
354
|
+
})];
|
|
355
|
+
case 15: return [4 /*yield*/, _j.sent()];
|
|
356
|
+
case 16:
|
|
357
|
+
_j.sent();
|
|
358
|
+
_j.label = 17;
|
|
359
|
+
case 17:
|
|
360
|
+
_b++;
|
|
361
|
+
return [3 /*break*/, 14];
|
|
362
|
+
case 18: return [3 /*break*/, 20];
|
|
363
|
+
case 19:
|
|
364
|
+
_d = _j.sent();
|
|
365
|
+
return [3 /*break*/, 20];
|
|
366
|
+
case 20:
|
|
367
|
+
_i++;
|
|
368
|
+
return [3 /*break*/, 7];
|
|
369
|
+
case 21: return [3 /*break*/, 5];
|
|
370
|
+
case 22: return [3 /*break*/, 25];
|
|
371
|
+
case 23:
|
|
372
|
+
error_2 = _j.sent();
|
|
373
|
+
clearTimeout(timeout);
|
|
374
|
+
throw this.transformError(error_2);
|
|
375
|
+
case 24:
|
|
376
|
+
clearTimeout(timeout);
|
|
377
|
+
return [7 /*endfinally*/];
|
|
378
|
+
case 25: return [2 /*return*/];
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
});
|
|
382
|
+
};
|
|
383
|
+
OpenAIProvider.prototype.listModels = function () {
|
|
384
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
385
|
+
return __generator(this, function (_a) {
|
|
386
|
+
return [2 /*return*/, this.capabilities.supportedModels];
|
|
387
|
+
});
|
|
388
|
+
});
|
|
389
|
+
};
|
|
390
|
+
OpenAIProvider.prototype.getModelInfo = function (model) {
|
|
391
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
392
|
+
var descriptions;
|
|
393
|
+
return __generator(this, function (_a) {
|
|
394
|
+
descriptions = {
|
|
395
|
+
'gpt-4o': 'Most capable GPT-4 model with vision and audio',
|
|
396
|
+
'gpt-4o-mini': 'Affordable and intelligent small model',
|
|
397
|
+
'gpt-4-turbo': 'GPT-4 Turbo with vision',
|
|
398
|
+
'gpt-4': 'High capability model',
|
|
399
|
+
'gpt-3.5-turbo': 'Fast and efficient model',
|
|
400
|
+
'o1-preview': 'Reasoning model for complex tasks',
|
|
401
|
+
'o1-mini': 'Fast reasoning model',
|
|
402
|
+
'o3-mini': 'Latest reasoning model',
|
|
403
|
+
};
|
|
404
|
+
return [2 /*return*/, {
|
|
405
|
+
model: model,
|
|
406
|
+
name: model,
|
|
407
|
+
description: descriptions[model] || 'OpenAI language model',
|
|
408
|
+
contextLength: this.capabilities.maxContextLength[model] || 8192,
|
|
409
|
+
maxOutputTokens: this.capabilities.maxOutputTokens[model] || 4096,
|
|
410
|
+
supportedFeatures: __spreadArray([
|
|
411
|
+
'chat',
|
|
412
|
+
'completion',
|
|
413
|
+
'tool_calling'
|
|
414
|
+
], (model.includes('gpt-4') ? ['vision'] : []), true),
|
|
415
|
+
pricing: this.capabilities.pricing[model],
|
|
416
|
+
}];
|
|
417
|
+
});
|
|
418
|
+
});
|
|
419
|
+
};
|
|
420
|
+
OpenAIProvider.prototype.doHealthCheck = function () {
|
|
421
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
422
|
+
var response, error_3;
|
|
423
|
+
return __generator(this, function (_a) {
|
|
424
|
+
switch (_a.label) {
|
|
425
|
+
case 0:
|
|
426
|
+
_a.trys.push([0, 2, , 3]);
|
|
427
|
+
return [4 /*yield*/, fetch("".concat(this.baseUrl, "/models"), {
|
|
428
|
+
headers: this.headers,
|
|
429
|
+
})];
|
|
430
|
+
case 1:
|
|
431
|
+
response = _a.sent();
|
|
432
|
+
return [2 /*return*/, __assign({ healthy: response.ok, timestamp: new Date() }, (response.ok ? {} : { error: "HTTP ".concat(response.status) }))];
|
|
433
|
+
case 2:
|
|
434
|
+
error_3 = _a.sent();
|
|
435
|
+
return [2 /*return*/, {
|
|
436
|
+
healthy: false,
|
|
437
|
+
error: error_3 instanceof Error ? error_3.message : 'Unknown error',
|
|
438
|
+
timestamp: new Date(),
|
|
439
|
+
}];
|
|
440
|
+
case 3: return [2 /*return*/];
|
|
441
|
+
}
|
|
442
|
+
});
|
|
443
|
+
});
|
|
444
|
+
};
|
|
445
|
+
OpenAIProvider.prototype.buildRequest = function (request, stream) {
|
|
446
|
+
var _a, _b, _c, _d;
|
|
447
|
+
if (stream === void 0) { stream = false; }
|
|
448
|
+
var openAIRequest = {
|
|
449
|
+
model: request.model || this.config.model,
|
|
450
|
+
messages: request.messages.map(function (msg) { return (__assign(__assign(__assign({ role: msg.role, content: typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content) }, (msg.name && { name: msg.name })), (msg.toolCallId && { tool_call_id: msg.toolCallId })), (msg.toolCalls && { tool_calls: msg.toolCalls }))); }),
|
|
451
|
+
stream: stream,
|
|
452
|
+
};
|
|
453
|
+
if (request.temperature !== undefined || this.config.temperature !== undefined) {
|
|
454
|
+
openAIRequest.temperature = (_a = request.temperature) !== null && _a !== void 0 ? _a : this.config.temperature;
|
|
455
|
+
}
|
|
456
|
+
if (request.maxTokens || this.config.maxTokens) {
|
|
457
|
+
openAIRequest.max_tokens = request.maxTokens || this.config.maxTokens;
|
|
458
|
+
}
|
|
459
|
+
if (request.topP !== undefined || this.config.topP !== undefined) {
|
|
460
|
+
openAIRequest.top_p = (_b = request.topP) !== null && _b !== void 0 ? _b : this.config.topP;
|
|
461
|
+
}
|
|
462
|
+
if (request.frequencyPenalty !== undefined || this.config.frequencyPenalty !== undefined) {
|
|
463
|
+
openAIRequest.frequency_penalty = (_c = request.frequencyPenalty) !== null && _c !== void 0 ? _c : this.config.frequencyPenalty;
|
|
464
|
+
}
|
|
465
|
+
if (request.presencePenalty !== undefined || this.config.presencePenalty !== undefined) {
|
|
466
|
+
openAIRequest.presence_penalty = (_d = request.presencePenalty) !== null && _d !== void 0 ? _d : this.config.presencePenalty;
|
|
467
|
+
}
|
|
468
|
+
if (request.stopSequences || this.config.stopSequences) {
|
|
469
|
+
openAIRequest.stop = request.stopSequences || this.config.stopSequences;
|
|
470
|
+
}
|
|
471
|
+
if (request.tools) {
|
|
472
|
+
openAIRequest.tools = request.tools;
|
|
473
|
+
openAIRequest.tool_choice = request.toolChoice;
|
|
474
|
+
}
|
|
475
|
+
return openAIRequest;
|
|
476
|
+
};
|
|
477
|
+
OpenAIProvider.prototype.transformResponse = function (data, request) {
|
|
478
|
+
var _a, _b;
|
|
479
|
+
var choice = data.choices[0];
|
|
480
|
+
var model = request.model || this.config.model;
|
|
481
|
+
// Handle OpenRouter and other compatible APIs with different model naming
|
|
482
|
+
var baseModel = model.includes('/') ? model.split('/').pop() : model;
|
|
483
|
+
var pricing = this.capabilities.pricing[model] || this.capabilities.pricing[baseModel];
|
|
484
|
+
// Default pricing if model not found
|
|
485
|
+
var promptCostPer1k = (_a = pricing === null || pricing === void 0 ? void 0 : pricing.promptCostPer1k) !== null && _a !== void 0 ? _a : 0;
|
|
486
|
+
var completionCostPer1k = (_b = pricing === null || pricing === void 0 ? void 0 : pricing.completionCostPer1k) !== null && _b !== void 0 ? _b : 0;
|
|
487
|
+
var promptCost = (data.usage.prompt_tokens / 1000) * promptCostPer1k;
|
|
488
|
+
var completionCost = (data.usage.completion_tokens / 1000) * completionCostPer1k;
|
|
489
|
+
return {
|
|
490
|
+
id: data.id,
|
|
491
|
+
model: model,
|
|
492
|
+
provider: 'openai',
|
|
493
|
+
content: choice.message.content || '',
|
|
494
|
+
toolCalls: choice.message.tool_calls,
|
|
495
|
+
usage: {
|
|
496
|
+
promptTokens: data.usage.prompt_tokens,
|
|
497
|
+
completionTokens: data.usage.completion_tokens,
|
|
498
|
+
totalTokens: data.usage.total_tokens,
|
|
499
|
+
},
|
|
500
|
+
cost: {
|
|
501
|
+
promptCost: promptCost,
|
|
502
|
+
completionCost: completionCost,
|
|
503
|
+
totalCost: promptCost + completionCost,
|
|
504
|
+
currency: 'USD',
|
|
505
|
+
},
|
|
506
|
+
finishReason: choice.finish_reason,
|
|
507
|
+
};
|
|
508
|
+
};
|
|
509
|
+
OpenAIProvider.prototype.handleErrorResponse = function (response) {
|
|
510
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
511
|
+
var errorText, errorData, message, retryAfter;
|
|
512
|
+
var _a;
|
|
513
|
+
return __generator(this, function (_b) {
|
|
514
|
+
switch (_b.label) {
|
|
515
|
+
case 0: return [4 /*yield*/, response.text()];
|
|
516
|
+
case 1:
|
|
517
|
+
errorText = _b.sent();
|
|
518
|
+
try {
|
|
519
|
+
errorData = JSON.parse(errorText);
|
|
520
|
+
}
|
|
521
|
+
catch (_c) {
|
|
522
|
+
errorData = { error: { message: errorText } };
|
|
523
|
+
}
|
|
524
|
+
message = ((_a = errorData.error) === null || _a === void 0 ? void 0 : _a.message) || 'Unknown error';
|
|
525
|
+
switch (response.status) {
|
|
526
|
+
case 401:
|
|
527
|
+
throw new types_js_1.AuthenticationError(message, 'openai', errorData);
|
|
528
|
+
case 429:
|
|
529
|
+
retryAfter = response.headers.get('retry-after');
|
|
530
|
+
throw new types_js_1.RateLimitError(message, 'openai', retryAfter ? parseInt(retryAfter) : undefined, errorData);
|
|
531
|
+
case 404:
|
|
532
|
+
throw new types_js_1.ModelNotFoundError(this.config.model, 'openai', errorData);
|
|
533
|
+
default:
|
|
534
|
+
throw new types_js_1.LLMProviderError(message, "OPENAI_".concat(response.status), 'openai', response.status, response.status >= 500, errorData);
|
|
535
|
+
}
|
|
536
|
+
return [2 /*return*/];
|
|
537
|
+
}
|
|
538
|
+
});
|
|
539
|
+
});
|
|
540
|
+
};
|
|
541
|
+
return OpenAIProvider;
|
|
542
|
+
}(base_provider_js_1.BaseProvider));
|
|
543
|
+
exports.OpenAIProvider = OpenAIProvider;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* V3 Provider Manager
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates multiple LLM providers with:
|
|
5
|
+
* - Load balancing (round-robin, latency-based, cost-based)
|
|
6
|
+
* - Automatic failover
|
|
7
|
+
* - Request caching
|
|
8
|
+
* - Cost optimization
|
|
9
|
+
*
|
|
10
|
+
* @module @sparkleideas/providers/provider-manager
|
|
11
|
+
*/
|
|
12
|
+
import { EventEmitter } from 'events';
|
|
13
|
+
import { ILLMProvider, LLMProvider, LLMRequest, LLMResponse, LLMStreamEvent, ProviderManagerConfig, HealthCheckResult, CostEstimate, UsageStats, UsagePeriod } from './types.js';
|
|
14
|
+
import { ILogger } from './base-provider.js';
|
|
15
|
+
/**
|
|
16
|
+
* Provider metrics for load balancing
|
|
17
|
+
*/
|
|
18
|
+
interface ProviderMetrics {
|
|
19
|
+
latency: number;
|
|
20
|
+
errorRate: number;
|
|
21
|
+
cost: number;
|
|
22
|
+
lastUsed: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Provider Manager - Orchestrates multiple LLM providers
|
|
26
|
+
*/
|
|
27
|
+
export declare class ProviderManager extends EventEmitter {
|
|
28
|
+
private config;
|
|
29
|
+
private providers;
|
|
30
|
+
private cache;
|
|
31
|
+
private metrics;
|
|
32
|
+
private roundRobinIndex;
|
|
33
|
+
private logger;
|
|
34
|
+
constructor(config: ProviderManagerConfig, logger?: ILogger);
|
|
35
|
+
/**
|
|
36
|
+
* Initialize all configured providers
|
|
37
|
+
*/
|
|
38
|
+
initialize(): Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* Create a provider instance
|
|
41
|
+
*/
|
|
42
|
+
private createProvider;
|
|
43
|
+
/**
|
|
44
|
+
* Complete a request with automatic provider selection
|
|
45
|
+
*/
|
|
46
|
+
complete(request: LLMRequest, preferredProvider?: LLMProvider): Promise<LLMResponse>;
|
|
47
|
+
/**
|
|
48
|
+
* Stream complete with automatic provider selection
|
|
49
|
+
*/
|
|
50
|
+
streamComplete(request: LLMRequest, preferredProvider?: LLMProvider): AsyncIterable<LLMStreamEvent>;
|
|
51
|
+
/**
|
|
52
|
+
* Select provider based on load balancing strategy
|
|
53
|
+
*/
|
|
54
|
+
private selectProvider;
|
|
55
|
+
private selectRoundRobin;
|
|
56
|
+
private selectLeastLoaded;
|
|
57
|
+
private selectByLatency;
|
|
58
|
+
private selectByCost;
|
|
59
|
+
/**
|
|
60
|
+
* Complete with fallback on failure
|
|
61
|
+
*/
|
|
62
|
+
private completWithFallback;
|
|
63
|
+
/**
|
|
64
|
+
* Update provider metrics
|
|
65
|
+
*/
|
|
66
|
+
private updateMetrics;
|
|
67
|
+
/**
|
|
68
|
+
* Get cached response
|
|
69
|
+
*/
|
|
70
|
+
private getCached;
|
|
71
|
+
/**
|
|
72
|
+
* Set cached response
|
|
73
|
+
*/
|
|
74
|
+
private setCached;
|
|
75
|
+
/**
|
|
76
|
+
* Generate cache key
|
|
77
|
+
*/
|
|
78
|
+
private getCacheKey;
|
|
79
|
+
/**
|
|
80
|
+
* Get a specific provider
|
|
81
|
+
*/
|
|
82
|
+
getProvider(name: LLMProvider): ILLMProvider | undefined;
|
|
83
|
+
/**
|
|
84
|
+
* List all available providers
|
|
85
|
+
*/
|
|
86
|
+
listProviders(): LLMProvider[];
|
|
87
|
+
/**
|
|
88
|
+
* Health check all providers
|
|
89
|
+
*/
|
|
90
|
+
healthCheck(): Promise<Map<LLMProvider, HealthCheckResult>>;
|
|
91
|
+
/**
|
|
92
|
+
* Estimate cost across providers
|
|
93
|
+
*/
|
|
94
|
+
estimateCost(request: LLMRequest): Promise<Map<LLMProvider, CostEstimate>>;
|
|
95
|
+
/**
|
|
96
|
+
* Get aggregated usage statistics
|
|
97
|
+
*/
|
|
98
|
+
getUsage(period?: UsagePeriod): Promise<UsageStats>;
|
|
99
|
+
/**
|
|
100
|
+
* Get provider metrics
|
|
101
|
+
*/
|
|
102
|
+
getMetrics(): Map<LLMProvider, ProviderMetrics>;
|
|
103
|
+
/**
|
|
104
|
+
* Clear cache
|
|
105
|
+
*/
|
|
106
|
+
clearCache(): void;
|
|
107
|
+
/**
|
|
108
|
+
* Destroy all providers
|
|
109
|
+
*/
|
|
110
|
+
destroy(): void;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Create and initialize a provider manager
|
|
114
|
+
*/
|
|
115
|
+
export declare function createProviderManager(config: ProviderManagerConfig, logger?: ILogger): Promise<ProviderManager>;
|
|
116
|
+
export {};
|
|
117
|
+
//# sourceMappingURL=provider-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-manager.d.ts","sourceRoot":"","sources":["../src/provider-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EACL,YAAY,EACZ,WAAW,EAEX,UAAU,EACV,WAAW,EACX,cAAc,EAEd,qBAAqB,EAErB,iBAAiB,EACjB,YAAY,EACZ,UAAU,EACV,WAAW,EAGZ,MAAM,YAAY,CAAC;AACpB,OAAO,EAAuB,OAAO,EAAiB,MAAM,oBAAoB,CAAC;AAiBjF;;GAEG;AACH,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,qBAAa,eAAgB,SAAQ,YAAY;IAQ7C,OAAO,CAAC,MAAM;IAPhB,OAAO,CAAC,SAAS,CAA6C;IAC9D,OAAO,CAAC,KAAK,CAAsC;IACnD,OAAO,CAAC,OAAO,CAAgD;IAC/D,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,MAAM,CAAU;gBAGd,MAAM,EAAE,qBAAqB,EACrC,MAAM,CAAC,EAAE,OAAO;IAMlB;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IA6BjC;;OAEG;IACH,OAAO,CAAC,cAAc;IAwBtB;;OAEG;IACG,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,iBAAiB,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IA4C1F;;OAEG;IACI,cAAc,CACnB,OAAO,EAAE,UAAU,EACnB,iBAAiB,CAAC,EAAE,WAAW,GAC9B,aAAa,CAAC,cAAc,CAAC;IAuBhC;;OAEG;YACW,cAAc;IA0B5B,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,eAAe;YAUT,YAAY;IAgB1B;;OAEG;YACW,mBAAmB;IA6CjC;;OAEG;IACH,OAAO,CAAC,aAAa;IA6BrB;;OAEG;IACH,OAAO,CAAC,SAAS;IAgBjB;;OAEG;IACH,OAAO,CAAC,SAAS;IAoBjB;;OAEG;IACH,OAAO,CAAC,WAAW;IASnB;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,WAAW,GAAG,YAAY,GAAG,SAAS;IAIxD;;OAEG;IACH,aAAa,IAAI,WAAW,EAAE;IAI9B;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;IAajE;;OAEG;IACG,YAAY,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAahF;;OAEG;IACG,QAAQ,CAAC,MAAM,GAAE,WAAmB,GAAG,OAAO,CAAC,UAAU,CAAC;IAqChE;;OAEG;IACH,UAAU,IAAI,GAAG,CAAC,WAAW,EAAE,eAAe,CAAC;IAI/C;;OAEG;IACH,UAAU,IAAI,IAAI;IAKlB;;OAEG;IACH,OAAO,IAAI,IAAI;CAUhB;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,qBAAqB,EAC7B,MAAM,CAAC,EAAE,OAAO,GACf,OAAO,CAAC,eAAe,CAAC,CAI1B"}
|