@botpress/cognitive 0.1.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/index.mjs ADDED
@@ -0,0 +1,979 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __commonJS = (cb, mod) => function __require() {
8
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
19
+ // If the importer is in node compatibility mode or this is not an ESM
20
+ // file that has been converted to a CommonJS file using a Babel-
21
+ // compatible transform (i.e. "__esModule" has not been set), then set
22
+ // "default" to the CommonJS "module.exports" for node compatibility.
23
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
24
+ mod
25
+ ));
26
+
27
+ // ../../node_modules/.pnpm/exponential-backoff@3.1.1/node_modules/exponential-backoff/dist/options.js
28
+ var require_options = __commonJS({
29
+ "../../node_modules/.pnpm/exponential-backoff@3.1.1/node_modules/exponential-backoff/dist/options.js"(exports) {
30
+ "use strict";
31
+ var __assign = exports && exports.__assign || function() {
32
+ __assign = Object.assign || function(t) {
33
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
34
+ s = arguments[i];
35
+ for (var p in s)
36
+ if (Object.prototype.hasOwnProperty.call(s, p))
37
+ t[p] = s[p];
38
+ }
39
+ return t;
40
+ };
41
+ return __assign.apply(this, arguments);
42
+ };
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ var defaultOptions = {
45
+ delayFirstAttempt: false,
46
+ jitter: "none",
47
+ maxDelay: Infinity,
48
+ numOfAttempts: 10,
49
+ retry: function() {
50
+ return true;
51
+ },
52
+ startingDelay: 100,
53
+ timeMultiple: 2
54
+ };
55
+ function getSanitizedOptions(options) {
56
+ var sanitized = __assign(__assign({}, defaultOptions), options);
57
+ if (sanitized.numOfAttempts < 1) {
58
+ sanitized.numOfAttempts = 1;
59
+ }
60
+ return sanitized;
61
+ }
62
+ exports.getSanitizedOptions = getSanitizedOptions;
63
+ }
64
+ });
65
+
66
+ // ../../node_modules/.pnpm/exponential-backoff@3.1.1/node_modules/exponential-backoff/dist/jitter/full/full.jitter.js
67
+ var require_full_jitter = __commonJS({
68
+ "../../node_modules/.pnpm/exponential-backoff@3.1.1/node_modules/exponential-backoff/dist/jitter/full/full.jitter.js"(exports) {
69
+ "use strict";
70
+ Object.defineProperty(exports, "__esModule", { value: true });
71
+ function fullJitter(delay) {
72
+ var jitteredDelay = Math.random() * delay;
73
+ return Math.round(jitteredDelay);
74
+ }
75
+ exports.fullJitter = fullJitter;
76
+ }
77
+ });
78
+
79
+ // ../../node_modules/.pnpm/exponential-backoff@3.1.1/node_modules/exponential-backoff/dist/jitter/no/no.jitter.js
80
+ var require_no_jitter = __commonJS({
81
+ "../../node_modules/.pnpm/exponential-backoff@3.1.1/node_modules/exponential-backoff/dist/jitter/no/no.jitter.js"(exports) {
82
+ "use strict";
83
+ Object.defineProperty(exports, "__esModule", { value: true });
84
+ function noJitter(delay) {
85
+ return delay;
86
+ }
87
+ exports.noJitter = noJitter;
88
+ }
89
+ });
90
+
91
+ // ../../node_modules/.pnpm/exponential-backoff@3.1.1/node_modules/exponential-backoff/dist/jitter/jitter.factory.js
92
+ var require_jitter_factory = __commonJS({
93
+ "../../node_modules/.pnpm/exponential-backoff@3.1.1/node_modules/exponential-backoff/dist/jitter/jitter.factory.js"(exports) {
94
+ "use strict";
95
+ Object.defineProperty(exports, "__esModule", { value: true });
96
+ var full_jitter_1 = require_full_jitter();
97
+ var no_jitter_1 = require_no_jitter();
98
+ function JitterFactory(options) {
99
+ switch (options.jitter) {
100
+ case "full":
101
+ return full_jitter_1.fullJitter;
102
+ case "none":
103
+ default:
104
+ return no_jitter_1.noJitter;
105
+ }
106
+ }
107
+ exports.JitterFactory = JitterFactory;
108
+ }
109
+ });
110
+
111
+ // ../../node_modules/.pnpm/exponential-backoff@3.1.1/node_modules/exponential-backoff/dist/delay/delay.base.js
112
+ var require_delay_base = __commonJS({
113
+ "../../node_modules/.pnpm/exponential-backoff@3.1.1/node_modules/exponential-backoff/dist/delay/delay.base.js"(exports) {
114
+ "use strict";
115
+ Object.defineProperty(exports, "__esModule", { value: true });
116
+ var jitter_factory_1 = require_jitter_factory();
117
+ var Delay = (
118
+ /** @class */
119
+ function() {
120
+ function Delay2(options) {
121
+ this.options = options;
122
+ this.attempt = 0;
123
+ }
124
+ Delay2.prototype.apply = function() {
125
+ var _this = this;
126
+ return new Promise(function(resolve) {
127
+ return setTimeout(resolve, _this.jitteredDelay);
128
+ });
129
+ };
130
+ Delay2.prototype.setAttemptNumber = function(attempt) {
131
+ this.attempt = attempt;
132
+ };
133
+ Object.defineProperty(Delay2.prototype, "jitteredDelay", {
134
+ get: function() {
135
+ var jitter = jitter_factory_1.JitterFactory(this.options);
136
+ return jitter(this.delay);
137
+ },
138
+ enumerable: true,
139
+ configurable: true
140
+ });
141
+ Object.defineProperty(Delay2.prototype, "delay", {
142
+ get: function() {
143
+ var constant = this.options.startingDelay;
144
+ var base = this.options.timeMultiple;
145
+ var power = this.numOfDelayedAttempts;
146
+ var delay = constant * Math.pow(base, power);
147
+ return Math.min(delay, this.options.maxDelay);
148
+ },
149
+ enumerable: true,
150
+ configurable: true
151
+ });
152
+ Object.defineProperty(Delay2.prototype, "numOfDelayedAttempts", {
153
+ get: function() {
154
+ return this.attempt;
155
+ },
156
+ enumerable: true,
157
+ configurable: true
158
+ });
159
+ return Delay2;
160
+ }()
161
+ );
162
+ exports.Delay = Delay;
163
+ }
164
+ });
165
+
166
+ // ../../node_modules/.pnpm/exponential-backoff@3.1.1/node_modules/exponential-backoff/dist/delay/skip-first/skip-first.delay.js
167
+ var require_skip_first_delay = __commonJS({
168
+ "../../node_modules/.pnpm/exponential-backoff@3.1.1/node_modules/exponential-backoff/dist/delay/skip-first/skip-first.delay.js"(exports) {
169
+ "use strict";
170
+ var __extends = exports && exports.__extends || function() {
171
+ var extendStatics = function(d, b) {
172
+ extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) {
173
+ d2.__proto__ = b2;
174
+ } || function(d2, b2) {
175
+ for (var p in b2)
176
+ if (b2.hasOwnProperty(p))
177
+ d2[p] = b2[p];
178
+ };
179
+ return extendStatics(d, b);
180
+ };
181
+ return function(d, b) {
182
+ extendStatics(d, b);
183
+ function __() {
184
+ this.constructor = d;
185
+ }
186
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
187
+ };
188
+ }();
189
+ var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
190
+ function adopt(value) {
191
+ return value instanceof P ? value : new P(function(resolve) {
192
+ resolve(value);
193
+ });
194
+ }
195
+ return new (P || (P = Promise))(function(resolve, reject) {
196
+ function fulfilled(value) {
197
+ try {
198
+ step(generator.next(value));
199
+ } catch (e) {
200
+ reject(e);
201
+ }
202
+ }
203
+ function rejected(value) {
204
+ try {
205
+ step(generator["throw"](value));
206
+ } catch (e) {
207
+ reject(e);
208
+ }
209
+ }
210
+ function step(result) {
211
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
212
+ }
213
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
214
+ });
215
+ };
216
+ var __generator = exports && exports.__generator || function(thisArg, body) {
217
+ var _ = { label: 0, sent: function() {
218
+ if (t[0] & 1)
219
+ throw t[1];
220
+ return t[1];
221
+ }, trys: [], ops: [] }, f, y, t, g;
222
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() {
223
+ return this;
224
+ }), g;
225
+ function verb(n) {
226
+ return function(v) {
227
+ return step([n, v]);
228
+ };
229
+ }
230
+ function step(op) {
231
+ if (f)
232
+ throw new TypeError("Generator is already executing.");
233
+ while (_)
234
+ try {
235
+ 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)
236
+ return t;
237
+ if (y = 0, t)
238
+ op = [op[0] & 2, t.value];
239
+ switch (op[0]) {
240
+ case 0:
241
+ case 1:
242
+ t = op;
243
+ break;
244
+ case 4:
245
+ _.label++;
246
+ return { value: op[1], done: false };
247
+ case 5:
248
+ _.label++;
249
+ y = op[1];
250
+ op = [0];
251
+ continue;
252
+ case 7:
253
+ op = _.ops.pop();
254
+ _.trys.pop();
255
+ continue;
256
+ default:
257
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
258
+ _ = 0;
259
+ continue;
260
+ }
261
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
262
+ _.label = op[1];
263
+ break;
264
+ }
265
+ if (op[0] === 6 && _.label < t[1]) {
266
+ _.label = t[1];
267
+ t = op;
268
+ break;
269
+ }
270
+ if (t && _.label < t[2]) {
271
+ _.label = t[2];
272
+ _.ops.push(op);
273
+ break;
274
+ }
275
+ if (t[2])
276
+ _.ops.pop();
277
+ _.trys.pop();
278
+ continue;
279
+ }
280
+ op = body.call(thisArg, _);
281
+ } catch (e) {
282
+ op = [6, e];
283
+ y = 0;
284
+ } finally {
285
+ f = t = 0;
286
+ }
287
+ if (op[0] & 5)
288
+ throw op[1];
289
+ return { value: op[0] ? op[1] : void 0, done: true };
290
+ }
291
+ };
292
+ Object.defineProperty(exports, "__esModule", { value: true });
293
+ var delay_base_1 = require_delay_base();
294
+ var SkipFirstDelay = (
295
+ /** @class */
296
+ function(_super) {
297
+ __extends(SkipFirstDelay2, _super);
298
+ function SkipFirstDelay2() {
299
+ return _super !== null && _super.apply(this, arguments) || this;
300
+ }
301
+ SkipFirstDelay2.prototype.apply = function() {
302
+ return __awaiter(this, void 0, void 0, function() {
303
+ return __generator(this, function(_a) {
304
+ return [2, this.isFirstAttempt ? true : _super.prototype.apply.call(this)];
305
+ });
306
+ });
307
+ };
308
+ Object.defineProperty(SkipFirstDelay2.prototype, "isFirstAttempt", {
309
+ get: function() {
310
+ return this.attempt === 0;
311
+ },
312
+ enumerable: true,
313
+ configurable: true
314
+ });
315
+ Object.defineProperty(SkipFirstDelay2.prototype, "numOfDelayedAttempts", {
316
+ get: function() {
317
+ return this.attempt - 1;
318
+ },
319
+ enumerable: true,
320
+ configurable: true
321
+ });
322
+ return SkipFirstDelay2;
323
+ }(delay_base_1.Delay)
324
+ );
325
+ exports.SkipFirstDelay = SkipFirstDelay;
326
+ }
327
+ });
328
+
329
+ // ../../node_modules/.pnpm/exponential-backoff@3.1.1/node_modules/exponential-backoff/dist/delay/always/always.delay.js
330
+ var require_always_delay = __commonJS({
331
+ "../../node_modules/.pnpm/exponential-backoff@3.1.1/node_modules/exponential-backoff/dist/delay/always/always.delay.js"(exports) {
332
+ "use strict";
333
+ var __extends = exports && exports.__extends || function() {
334
+ var extendStatics = function(d, b) {
335
+ extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) {
336
+ d2.__proto__ = b2;
337
+ } || function(d2, b2) {
338
+ for (var p in b2)
339
+ if (b2.hasOwnProperty(p))
340
+ d2[p] = b2[p];
341
+ };
342
+ return extendStatics(d, b);
343
+ };
344
+ return function(d, b) {
345
+ extendStatics(d, b);
346
+ function __() {
347
+ this.constructor = d;
348
+ }
349
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
350
+ };
351
+ }();
352
+ Object.defineProperty(exports, "__esModule", { value: true });
353
+ var delay_base_1 = require_delay_base();
354
+ var AlwaysDelay = (
355
+ /** @class */
356
+ function(_super) {
357
+ __extends(AlwaysDelay2, _super);
358
+ function AlwaysDelay2() {
359
+ return _super !== null && _super.apply(this, arguments) || this;
360
+ }
361
+ return AlwaysDelay2;
362
+ }(delay_base_1.Delay)
363
+ );
364
+ exports.AlwaysDelay = AlwaysDelay;
365
+ }
366
+ });
367
+
368
+ // ../../node_modules/.pnpm/exponential-backoff@3.1.1/node_modules/exponential-backoff/dist/delay/delay.factory.js
369
+ var require_delay_factory = __commonJS({
370
+ "../../node_modules/.pnpm/exponential-backoff@3.1.1/node_modules/exponential-backoff/dist/delay/delay.factory.js"(exports) {
371
+ "use strict";
372
+ Object.defineProperty(exports, "__esModule", { value: true });
373
+ var skip_first_delay_1 = require_skip_first_delay();
374
+ var always_delay_1 = require_always_delay();
375
+ function DelayFactory(options, attempt) {
376
+ var delay = initDelayClass(options);
377
+ delay.setAttemptNumber(attempt);
378
+ return delay;
379
+ }
380
+ exports.DelayFactory = DelayFactory;
381
+ function initDelayClass(options) {
382
+ if (!options.delayFirstAttempt) {
383
+ return new skip_first_delay_1.SkipFirstDelay(options);
384
+ }
385
+ return new always_delay_1.AlwaysDelay(options);
386
+ }
387
+ }
388
+ });
389
+
390
+ // ../../node_modules/.pnpm/exponential-backoff@3.1.1/node_modules/exponential-backoff/dist/backoff.js
391
+ var require_backoff = __commonJS({
392
+ "../../node_modules/.pnpm/exponential-backoff@3.1.1/node_modules/exponential-backoff/dist/backoff.js"(exports) {
393
+ "use strict";
394
+ var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
395
+ function adopt(value) {
396
+ return value instanceof P ? value : new P(function(resolve) {
397
+ resolve(value);
398
+ });
399
+ }
400
+ return new (P || (P = Promise))(function(resolve, reject) {
401
+ function fulfilled(value) {
402
+ try {
403
+ step(generator.next(value));
404
+ } catch (e) {
405
+ reject(e);
406
+ }
407
+ }
408
+ function rejected(value) {
409
+ try {
410
+ step(generator["throw"](value));
411
+ } catch (e) {
412
+ reject(e);
413
+ }
414
+ }
415
+ function step(result) {
416
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
417
+ }
418
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
419
+ });
420
+ };
421
+ var __generator = exports && exports.__generator || function(thisArg, body) {
422
+ var _ = { label: 0, sent: function() {
423
+ if (t[0] & 1)
424
+ throw t[1];
425
+ return t[1];
426
+ }, trys: [], ops: [] }, f, y, t, g;
427
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() {
428
+ return this;
429
+ }), g;
430
+ function verb(n) {
431
+ return function(v) {
432
+ return step([n, v]);
433
+ };
434
+ }
435
+ function step(op) {
436
+ if (f)
437
+ throw new TypeError("Generator is already executing.");
438
+ while (_)
439
+ try {
440
+ 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)
441
+ return t;
442
+ if (y = 0, t)
443
+ op = [op[0] & 2, t.value];
444
+ switch (op[0]) {
445
+ case 0:
446
+ case 1:
447
+ t = op;
448
+ break;
449
+ case 4:
450
+ _.label++;
451
+ return { value: op[1], done: false };
452
+ case 5:
453
+ _.label++;
454
+ y = op[1];
455
+ op = [0];
456
+ continue;
457
+ case 7:
458
+ op = _.ops.pop();
459
+ _.trys.pop();
460
+ continue;
461
+ default:
462
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
463
+ _ = 0;
464
+ continue;
465
+ }
466
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
467
+ _.label = op[1];
468
+ break;
469
+ }
470
+ if (op[0] === 6 && _.label < t[1]) {
471
+ _.label = t[1];
472
+ t = op;
473
+ break;
474
+ }
475
+ if (t && _.label < t[2]) {
476
+ _.label = t[2];
477
+ _.ops.push(op);
478
+ break;
479
+ }
480
+ if (t[2])
481
+ _.ops.pop();
482
+ _.trys.pop();
483
+ continue;
484
+ }
485
+ op = body.call(thisArg, _);
486
+ } catch (e) {
487
+ op = [6, e];
488
+ y = 0;
489
+ } finally {
490
+ f = t = 0;
491
+ }
492
+ if (op[0] & 5)
493
+ throw op[1];
494
+ return { value: op[0] ? op[1] : void 0, done: true };
495
+ }
496
+ };
497
+ Object.defineProperty(exports, "__esModule", { value: true });
498
+ var options_1 = require_options();
499
+ var delay_factory_1 = require_delay_factory();
500
+ function backOff2(request, options) {
501
+ if (options === void 0) {
502
+ options = {};
503
+ }
504
+ return __awaiter(this, void 0, void 0, function() {
505
+ var sanitizedOptions, backOff3;
506
+ return __generator(this, function(_a) {
507
+ switch (_a.label) {
508
+ case 0:
509
+ sanitizedOptions = options_1.getSanitizedOptions(options);
510
+ backOff3 = new BackOff(request, sanitizedOptions);
511
+ return [4, backOff3.execute()];
512
+ case 1:
513
+ return [2, _a.sent()];
514
+ }
515
+ });
516
+ });
517
+ }
518
+ exports.backOff = backOff2;
519
+ var BackOff = (
520
+ /** @class */
521
+ function() {
522
+ function BackOff2(request, options) {
523
+ this.request = request;
524
+ this.options = options;
525
+ this.attemptNumber = 0;
526
+ }
527
+ BackOff2.prototype.execute = function() {
528
+ return __awaiter(this, void 0, void 0, function() {
529
+ var e_1, shouldRetry;
530
+ return __generator(this, function(_a) {
531
+ switch (_a.label) {
532
+ case 0:
533
+ if (!!this.attemptLimitReached)
534
+ return [3, 7];
535
+ _a.label = 1;
536
+ case 1:
537
+ _a.trys.push([1, 4, , 6]);
538
+ return [4, this.applyDelay()];
539
+ case 2:
540
+ _a.sent();
541
+ return [4, this.request()];
542
+ case 3:
543
+ return [2, _a.sent()];
544
+ case 4:
545
+ e_1 = _a.sent();
546
+ this.attemptNumber++;
547
+ return [4, this.options.retry(e_1, this.attemptNumber)];
548
+ case 5:
549
+ shouldRetry = _a.sent();
550
+ if (!shouldRetry || this.attemptLimitReached) {
551
+ throw e_1;
552
+ }
553
+ return [3, 6];
554
+ case 6:
555
+ return [3, 0];
556
+ case 7:
557
+ throw new Error("Something went wrong.");
558
+ }
559
+ });
560
+ });
561
+ };
562
+ Object.defineProperty(BackOff2.prototype, "attemptLimitReached", {
563
+ get: function() {
564
+ return this.attemptNumber >= this.options.numOfAttempts;
565
+ },
566
+ enumerable: true,
567
+ configurable: true
568
+ });
569
+ BackOff2.prototype.applyDelay = function() {
570
+ return __awaiter(this, void 0, void 0, function() {
571
+ var delay;
572
+ return __generator(this, function(_a) {
573
+ switch (_a.label) {
574
+ case 0:
575
+ delay = delay_factory_1.DelayFactory(this.options, this.attemptNumber);
576
+ return [4, delay.apply()];
577
+ case 1:
578
+ _a.sent();
579
+ return [
580
+ 2
581
+ /*return*/
582
+ ];
583
+ }
584
+ });
585
+ });
586
+ };
587
+ return BackOff2;
588
+ }()
589
+ );
590
+ }
591
+ });
592
+
593
+ // src/client.ts
594
+ var import_exponential_backoff = __toESM(require_backoff());
595
+
596
+ // ../../node_modules/.pnpm/nanoevents@9.1.0/node_modules/nanoevents/index.js
597
+ var createNanoEvents = () => ({
598
+ emit(event, ...args) {
599
+ for (let callbacks = this.events[event] || [], i = 0, length = callbacks.length; i < length; i++) {
600
+ callbacks[i](...args);
601
+ }
602
+ },
603
+ events: {},
604
+ on(event, cb) {
605
+ ;
606
+ (this.events[event] ||= []).push(cb);
607
+ return () => {
608
+ this.events[event] = this.events[event]?.filter((i) => cb !== i);
609
+ };
610
+ }
611
+ });
612
+
613
+ // src/bp-client.ts
614
+ var getExtendedClient = (client) => {
615
+ if (typeof client.constructor !== "function" || typeof client.callAction !== "function" || !client.config || typeof client.config !== "object" || !client.config.headers) {
616
+ throw new Error("Client must be a valid instance of a Botpress client (@botpress/client)");
617
+ }
618
+ const botId = client.config.headers["x-bot-id"];
619
+ if (!botId?.length) {
620
+ throw new Error("Client must be instanciated with Bot ID");
621
+ }
622
+ const clone = () => {
623
+ const c = client;
624
+ if (c.clone && typeof c.clone === "function") {
625
+ return getExtendedClient(c.clone());
626
+ }
627
+ return getExtendedClient(new c.constructor(c.config));
628
+ };
629
+ return {
630
+ ...client,
631
+ botId,
632
+ axios: client.axiosInstance,
633
+ clone,
634
+ abortable: (signal) => {
635
+ const abortable = clone();
636
+ const instance = abortable.axios;
637
+ instance.defaults.signal = signal;
638
+ return abortable;
639
+ }
640
+ };
641
+ };
642
+
643
+ // src/errors.ts
644
+ var getActionFromError = (error) => {
645
+ if (!isBotpressError(error)) {
646
+ return "retry";
647
+ }
648
+ if (error.type === "InvalidDataFormat") {
649
+ if (error.message?.includes("data/model/id")) {
650
+ return "fallback";
651
+ }
652
+ return "abort";
653
+ }
654
+ if (error.type === "Internal" || error.subtype === "UPSTREAM_PROVIDER_FAILED") {
655
+ return "fallback";
656
+ }
657
+ return "abort";
658
+ };
659
+ var isBotpressError = (error) => typeof error === "object" && error !== null && "isApiError" in error && "code" in error && "type" in error && "id" in error;
660
+
661
+ // src/interceptors.ts
662
+ var InterceptorManager = class {
663
+ _interceptors = [];
664
+ use(interceptor) {
665
+ this._interceptors.push(interceptor);
666
+ return () => this.remove(interceptor);
667
+ }
668
+ remove(interceptor) {
669
+ this._interceptors = this._interceptors.filter((i) => i !== interceptor);
670
+ }
671
+ async run(value, signal) {
672
+ let error = null;
673
+ let result = value;
674
+ let done = false;
675
+ for (const interceptor of this._interceptors) {
676
+ if (done) {
677
+ break;
678
+ }
679
+ if (signal.aborted) {
680
+ throw signal.reason;
681
+ }
682
+ await new Promise((resolve) => {
683
+ void interceptor(
684
+ error,
685
+ result,
686
+ (err, val) => {
687
+ error = err;
688
+ result = val;
689
+ resolve();
690
+ },
691
+ (err, val) => {
692
+ error = err;
693
+ result = val;
694
+ done = true;
695
+ resolve();
696
+ }
697
+ );
698
+ });
699
+ }
700
+ if (error) {
701
+ throw error;
702
+ }
703
+ return result;
704
+ }
705
+ };
706
+
707
+ // src/models.ts
708
+ import { ResourceNotFoundError } from "@botpress/client";
709
+ var PreferencesFile = "models.config.json";
710
+ var VendorPreferences = ["google-ai", "anthropic", "openai"];
711
+ var BestModelPreferences = ["4o", "3-5-sonnet", "gemini-1.5-pro"];
712
+ var FastModelPreferences = ["gemini-1.5-flash", "4o-mini", "flash", "haiku"];
713
+ var InputPricePenalty = 3;
714
+ var OutputPricePenalty = 10;
715
+ var LowTokensPenalty = 128e3;
716
+ var isRecommended = (model) => model.tags.includes("recommended");
717
+ var isDeprecated = (model) => model.tags.includes("deprecated");
718
+ var isLowCost = (model) => model.tags.includes("low-cost");
719
+ var hasVisionSupport = (model) => model.tags.includes("vision");
720
+ var isGeneralPurpose = (model) => model.tags.includes("general-purpose");
721
+ var scoreModel = (model, type, boosts = {}) => {
722
+ let score = 0;
723
+ const scores = [
724
+ ["input price penalty", model.input.costPer1MTokens > InputPricePenalty, -1],
725
+ ["output price penalty", model.output.costPer1MTokens > OutputPricePenalty, -1],
726
+ ["low tokens penalty", (model.input.maxTokens ?? 0 + model.output.maxTokens ?? 0) < LowTokensPenalty, -1],
727
+ ["recommended", isRecommended(model), 2],
728
+ ["deprecated", isDeprecated(model), -2],
729
+ ["vision support", hasVisionSupport(model), 1],
730
+ ["general purpose", isGeneralPurpose(model), 1],
731
+ ["vendor preference", VendorPreferences.includes(model.integration), 1],
732
+ ["best model preference", type === "best" && BestModelPreferences.some((x) => model.id.includes(x)), 1],
733
+ ["fast model preference penalty", type === "best" && FastModelPreferences.some((x) => model.id.includes(x)), -2],
734
+ ["fast model preference", type === "fast" && FastModelPreferences.some((x) => model.id.includes(x)), 2],
735
+ ["low cost", type === "fast" && isLowCost(model), 1]
736
+ ];
737
+ for (const rule in boosts) {
738
+ if (model.ref.includes(rule)) {
739
+ scores.push([`boost (${rule})`, true, Number(boosts[rule]) ?? 0]);
740
+ }
741
+ }
742
+ for (const [, condition, value] of scores) {
743
+ if (condition) {
744
+ score += value;
745
+ }
746
+ }
747
+ return score;
748
+ };
749
+ var getBestModels = (models, boosts = {}) => models.sort((a, b) => scoreModel(b, "best", boosts) - scoreModel(a, "best", boosts));
750
+ var getFastModels = (models, boosts = {}) => models.sort((a, b) => scoreModel(b, "fast", boosts) - scoreModel(a, "fast", boosts));
751
+ var pickModel = (models, downtimes = []) => {
752
+ const copy = [...models];
753
+ const elasped = (date) => new Date().getTime() - new Date(date).getTime();
754
+ const DOWNTIME_THRESHOLD = 1e3 * 60 * 5;
755
+ if (!copy.length) {
756
+ throw new Error("At least one model is required");
757
+ }
758
+ while (copy.length) {
759
+ const ref = copy.shift();
760
+ const downtime = downtimes.find((o) => o.ref === ref && elasped(o.startedAt) < DOWNTIME_THRESHOLD);
761
+ if (downtime) {
762
+ continue;
763
+ } else {
764
+ return ref;
765
+ }
766
+ }
767
+ throw new Error(`All models are down: ${models.join(", ")}`);
768
+ };
769
+ var ModelProvider = class {
770
+ };
771
+ var RemoteModelProvider = class extends ModelProvider {
772
+ _client;
773
+ constructor(client) {
774
+ super();
775
+ this._client = getExtendedClient(client);
776
+ }
777
+ async fetchInstalledModels() {
778
+ const { bot } = await this._client.getBot({ id: this._client.botId });
779
+ const models = [];
780
+ const registered = Object.values(bot.integrations).filter((x) => x.status === "registered");
781
+ await Promise.allSettled(
782
+ registered.map(async (integration) => {
783
+ const { output } = await this._client.callAction({
784
+ type: `${integration.name}:listLanguageModels`,
785
+ input: {}
786
+ });
787
+ if (!output?.models?.length) {
788
+ return;
789
+ }
790
+ for (const model of output.models) {
791
+ if (model.name && model.id && model.input && model.tags) {
792
+ models.push({
793
+ ref: `${integration.name}:${model.id}`,
794
+ integration: integration.name,
795
+ id: model.id,
796
+ name: model.name,
797
+ description: model.description,
798
+ input: model.input,
799
+ output: model.output,
800
+ tags: model.tags
801
+ });
802
+ }
803
+ }
804
+ })
805
+ );
806
+ return models;
807
+ }
808
+ async fetchModelPreferences() {
809
+ try {
810
+ const { file } = await this._client.getFile({ id: PreferencesFile });
811
+ const { data } = await this._client.axios.get(file.url, {
812
+ // we piggy-back axios to avoid adding a new dependency
813
+ // unset all headers to avoid S3 pre-signed signature mismatch
814
+ headers: Object.keys(this._client.config.headers).reduce(
815
+ (acc, key) => {
816
+ acc[key] = void 0;
817
+ return acc;
818
+ },
819
+ {}
820
+ )
821
+ });
822
+ return data;
823
+ } catch (err) {
824
+ if (err instanceof ResourceNotFoundError) {
825
+ return null;
826
+ }
827
+ throw err;
828
+ }
829
+ }
830
+ async saveModelPreferences(preferences) {
831
+ await this._client.uploadFile({
832
+ key: PreferencesFile,
833
+ content: JSON.stringify(preferences, null, 2),
834
+ index: false,
835
+ tags: {
836
+ system: "true",
837
+ purpose: "config"
838
+ }
839
+ });
840
+ }
841
+ async deleteModelPreferences() {
842
+ await this._client.deleteFile({ id: PreferencesFile }).catch(() => {
843
+ });
844
+ }
845
+ };
846
+
847
+ // src/client.ts
848
+ var Cognitive = class {
849
+ interceptors = {
850
+ request: new InterceptorManager(),
851
+ response: new InterceptorManager()
852
+ };
853
+ _client;
854
+ _preferences = null;
855
+ _provider;
856
+ _events = createNanoEvents();
857
+ _downtimes = [];
858
+ constructor(props) {
859
+ this._client = getExtendedClient(props.client);
860
+ this._provider = props.provider ?? new RemoteModelProvider(props.client);
861
+ }
862
+ on(event, cb) {
863
+ return this._events.on(event, cb);
864
+ }
865
+ async fetchPreferences() {
866
+ if (this._preferences) {
867
+ return this._preferences;
868
+ }
869
+ this._preferences = await this._provider.fetchModelPreferences();
870
+ if (this._preferences) {
871
+ return this._preferences;
872
+ }
873
+ const models = await this._provider.fetchInstalledModels();
874
+ this._preferences = {
875
+ best: getBestModels(models).map((m) => m.ref),
876
+ fast: getFastModels(models).map((m) => m.ref),
877
+ downtimes: []
878
+ };
879
+ await this._provider.saveModelPreferences(this._preferences);
880
+ return this._preferences;
881
+ }
882
+ async setPreferences(preferences, save = false) {
883
+ this._preferences = preferences;
884
+ if (save) {
885
+ await this._provider.saveModelPreferences(preferences);
886
+ }
887
+ }
888
+ async _selectModel(ref) {
889
+ const parseRef = (ref2) => {
890
+ const parts = ref2.split(":");
891
+ return { integration: parts[0], model: parts.slice(1).join(":") };
892
+ };
893
+ const preferences = await this.fetchPreferences();
894
+ preferences.best ??= [];
895
+ preferences.fast ??= [];
896
+ preferences.downtimes ??= [];
897
+ const downtimes = [...preferences.downtimes, ...this._downtimes ?? []];
898
+ if (ref === "best") {
899
+ return parseRef(pickModel(preferences.best, downtimes));
900
+ }
901
+ if (ref === "fast") {
902
+ return parseRef(pickModel(preferences.fast, downtimes));
903
+ }
904
+ return parseRef(pickModel([ref, ...preferences.best, ...preferences.fast], downtimes));
905
+ }
906
+ async generateContent(input) {
907
+ const start = Date.now();
908
+ const signal = input.signal ?? AbortSignal.timeout(3e4);
909
+ const client = this._client.abortable(signal);
910
+ let props = { input };
911
+ let integration;
912
+ let model;
913
+ const { output, meta } = await (0, import_exponential_backoff.backOff)(
914
+ async () => {
915
+ const selection = await this._selectModel(input.model ?? "best");
916
+ integration = selection.integration;
917
+ model = selection.model;
918
+ props = await this.interceptors.request.run({ input }, signal);
919
+ return client.callAction({
920
+ type: `${integration}:generateContent`,
921
+ input: {
922
+ ...props.input,
923
+ model: { id: model }
924
+ }
925
+ });
926
+ },
927
+ {
928
+ retry: async (err, _attempt) => {
929
+ if (signal?.aborted) {
930
+ this._events.emit("aborted", props, err);
931
+ return false;
932
+ }
933
+ if (_attempt > 3) {
934
+ this._events.emit("error", props, err);
935
+ return false;
936
+ }
937
+ const action = getActionFromError(err);
938
+ if (action === "abort") {
939
+ this._events.emit("error", props, err);
940
+ return false;
941
+ }
942
+ if (action === "fallback") {
943
+ this._downtimes.push({
944
+ ref: `${integration}:${model}`,
945
+ startedAt: new Date().toISOString(),
946
+ reason: "Model is down"
947
+ });
948
+ await this._provider.saveModelPreferences({
949
+ ...this._preferences ?? { best: [], downtimes: [], fast: [] },
950
+ downtimes: [...this._preferences.downtimes ?? [], ...this._downtimes ?? []]
951
+ });
952
+ this._events.emit("fallback", props, err);
953
+ return true;
954
+ }
955
+ this._events.emit("retry", props, err);
956
+ return true;
957
+ }
958
+ }
959
+ );
960
+ const response = {
961
+ output,
962
+ meta: {
963
+ cached: meta.cached ?? false,
964
+ model: { integration, model },
965
+ latency: Date.now() - start,
966
+ cost: { input: output.usage.inputCost, output: output.usage.outputCost },
967
+ tokens: { input: output.usage.inputTokens, output: output.usage.outputTokens }
968
+ }
969
+ };
970
+ this._events.emit("response", props, response);
971
+ return this.interceptors.response.run(response, signal);
972
+ }
973
+ };
974
+ export {
975
+ Cognitive,
976
+ ModelProvider,
977
+ RemoteModelProvider
978
+ };
979
+ //# sourceMappingURL=index.mjs.map