@lov3kaizen/agentsea-evaluate 0.5.1

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.
Files changed (42) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +339 -0
  3. package/dist/annotation/index.d.mts +3 -0
  4. package/dist/annotation/index.d.ts +3 -0
  5. package/dist/annotation/index.js +630 -0
  6. package/dist/annotation/index.mjs +22 -0
  7. package/dist/chunk-5JRYKRSE.mjs +2791 -0
  8. package/dist/chunk-EUXXIZK3.mjs +676 -0
  9. package/dist/chunk-NBMUSATK.mjs +596 -0
  10. package/dist/chunk-PAQ2TTJJ.mjs +1105 -0
  11. package/dist/chunk-TUMNJN2S.mjs +416 -0
  12. package/dist/continuous/index.d.mts +2 -0
  13. package/dist/continuous/index.d.ts +2 -0
  14. package/dist/continuous/index.js +707 -0
  15. package/dist/continuous/index.mjs +16 -0
  16. package/dist/datasets/index.d.mts +1 -0
  17. package/dist/datasets/index.d.ts +1 -0
  18. package/dist/datasets/index.js +456 -0
  19. package/dist/datasets/index.mjs +14 -0
  20. package/dist/evaluation/index.d.mts +1 -0
  21. package/dist/evaluation/index.d.ts +1 -0
  22. package/dist/evaluation/index.js +2853 -0
  23. package/dist/evaluation/index.mjs +78 -0
  24. package/dist/feedback/index.d.mts +2 -0
  25. package/dist/feedback/index.d.ts +2 -0
  26. package/dist/feedback/index.js +1158 -0
  27. package/dist/feedback/index.mjs +40 -0
  28. package/dist/index-6Pbiq7ny.d.mts +234 -0
  29. package/dist/index-6Pbiq7ny.d.ts +234 -0
  30. package/dist/index-BNTycFEA.d.mts +479 -0
  31. package/dist/index-BNTycFEA.d.ts +479 -0
  32. package/dist/index-CTYCfWfH.d.mts +543 -0
  33. package/dist/index-CTYCfWfH.d.ts +543 -0
  34. package/dist/index-Cq5LwG_3.d.mts +322 -0
  35. package/dist/index-Cq5LwG_3.d.ts +322 -0
  36. package/dist/index-bPghFsfP.d.mts +315 -0
  37. package/dist/index-bPghFsfP.d.ts +315 -0
  38. package/dist/index.d.mts +81 -0
  39. package/dist/index.d.ts +81 -0
  40. package/dist/index.js +5962 -0
  41. package/dist/index.mjs +429 -0
  42. package/package.json +102 -0
@@ -0,0 +1,707 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
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 __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/continuous/index.ts
21
+ var continuous_exports = {};
22
+ __export(continuous_exports, {
23
+ ABTestRunner: () => ABTestRunner,
24
+ AlertManager: () => AlertManager,
25
+ ContinuousEval: () => ContinuousEval,
26
+ createABTestRunner: () => createABTestRunner,
27
+ createAlertManager: () => createAlertManager,
28
+ createContinuousEval: () => createContinuousEval
29
+ });
30
+ module.exports = __toCommonJS(continuous_exports);
31
+
32
+ // src/continuous/ContinuousEval.ts
33
+ var import_eventemitter32 = require("eventemitter3");
34
+
35
+ // src/continuous/ABTestRunner.ts
36
+ var import_eventemitter3 = require("eventemitter3");
37
+ var import_nanoid = require("nanoid");
38
+ var ABTestRunner = class extends import_eventemitter3.EventEmitter {
39
+ id;
40
+ name;
41
+ config;
42
+ status = "draft";
43
+ startedAt;
44
+ completedAt;
45
+ controlSamples = /* @__PURE__ */ new Map();
46
+ treatmentSamples = /* @__PURE__ */ new Map();
47
+ sampleCount = 0;
48
+ constructor(config) {
49
+ super();
50
+ this.id = (0, import_nanoid.nanoid)();
51
+ this.name = config.name;
52
+ this.config = config;
53
+ }
54
+ /**
55
+ * Start the A/B test
56
+ */
57
+ start() {
58
+ if (this.status !== "draft") {
59
+ throw new Error(`Cannot start test in ${this.status} status`);
60
+ }
61
+ this.status = "running";
62
+ this.startedAt = Date.now();
63
+ this.emit("test:started");
64
+ return Promise.resolve();
65
+ }
66
+ /**
67
+ * Stop the A/B test
68
+ */
69
+ stop() {
70
+ this.status = "completed";
71
+ this.completedAt = Date.now();
72
+ const results = this.getResults();
73
+ this.emit("test:completed", results);
74
+ return results;
75
+ }
76
+ /**
77
+ * Pause the test
78
+ */
79
+ pause() {
80
+ if (this.status === "running") {
81
+ this.status = "paused";
82
+ }
83
+ }
84
+ /**
85
+ * Resume the test
86
+ */
87
+ resume() {
88
+ if (this.status === "paused") {
89
+ this.status = "running";
90
+ }
91
+ }
92
+ /**
93
+ * Assign a sample to a variant
94
+ */
95
+ assignVariant() {
96
+ if (this.status !== "running") {
97
+ throw new Error("Test is not running");
98
+ }
99
+ const isControl = Math.random() >= this.config.trafficSplit;
100
+ const variant = isControl ? "control" : "treatment";
101
+ const assignment = {
102
+ variant,
103
+ testId: this.id,
104
+ assignedAt: Date.now()
105
+ };
106
+ this.emit("sample:assigned", assignment);
107
+ return variant;
108
+ }
109
+ /**
110
+ * Record sample result
111
+ */
112
+ recordSample(variant, sampleId, scores) {
113
+ if (this.status !== "running") {
114
+ throw new Error("Test is not running");
115
+ }
116
+ const samples = variant === "control" ? this.controlSamples : this.treatmentSamples;
117
+ samples.set(sampleId, scores);
118
+ this.sampleCount++;
119
+ if (this.sampleCount >= this.config.minSamples) {
120
+ this.checkSignificance();
121
+ }
122
+ if (this.config.maxDuration && this.startedAt && Date.now() - this.startedAt > this.config.maxDuration) {
123
+ this.stop();
124
+ }
125
+ }
126
+ /**
127
+ * Get current results
128
+ */
129
+ getResults() {
130
+ const metrics = {};
131
+ for (const metric of this.config.metrics) {
132
+ metrics[metric] = this.calculateMetricResult(metric);
133
+ }
134
+ let controlWins = 0;
135
+ let treatmentWins = 0;
136
+ for (const result of Object.values(metrics)) {
137
+ if (result.isSignificant) {
138
+ if (result.winner === "control") controlWins++;
139
+ else if (result.winner === "treatment") treatmentWins++;
140
+ }
141
+ }
142
+ let winner = "none";
143
+ if (controlWins > treatmentWins) winner = "control";
144
+ else if (treatmentWins > controlWins) winner = "treatment";
145
+ const isSignificant = Object.values(metrics).some((m) => m.isSignificant);
146
+ const confidence = isSignificant ? Math.max(...Object.values(metrics).map((m) => 1 - m.pValue)) : 0;
147
+ return {
148
+ controlSamples: this.controlSamples.size,
149
+ treatmentSamples: this.treatmentSamples.size,
150
+ metrics,
151
+ winner,
152
+ isSignificant,
153
+ confidence,
154
+ recommendation: this.generateRecommendation(
155
+ winner,
156
+ isSignificant,
157
+ metrics
158
+ )
159
+ };
160
+ }
161
+ /**
162
+ * Calculate result for a single metric
163
+ */
164
+ calculateMetricResult(metric) {
165
+ const controlScores = this.getScoresForMetric(this.controlSamples, metric);
166
+ const treatmentScores = this.getScoresForMetric(
167
+ this.treatmentSamples,
168
+ metric
169
+ );
170
+ const controlSummary = this.calculateSummary(controlScores);
171
+ const treatmentSummary = this.calculateSummary(treatmentScores);
172
+ const difference = treatmentSummary.mean - controlSummary.mean;
173
+ const differencePercent = controlSummary.mean !== 0 ? difference / controlSummary.mean * 100 : 0;
174
+ const pValue = this.calculatePValue(controlScores, treatmentScores);
175
+ const isSignificant = pValue < (this.config.significanceLevel ?? 0.05);
176
+ let winner = "none";
177
+ if (isSignificant) {
178
+ winner = difference > 0 ? "treatment" : "control";
179
+ }
180
+ return {
181
+ control: controlSummary,
182
+ treatment: treatmentSummary,
183
+ difference,
184
+ differencePercent,
185
+ pValue,
186
+ isSignificant,
187
+ winner
188
+ };
189
+ }
190
+ /**
191
+ * Get scores for a metric from samples
192
+ */
193
+ getScoresForMetric(samples, metric) {
194
+ const scores = [];
195
+ for (const sampleScores of samples.values()) {
196
+ if (metric in sampleScores) {
197
+ scores.push(sampleScores[metric]);
198
+ }
199
+ }
200
+ return scores;
201
+ }
202
+ /**
203
+ * Calculate summary statistics
204
+ */
205
+ calculateSummary(scores) {
206
+ if (scores.length === 0) {
207
+ return {
208
+ mean: 0,
209
+ std: 0,
210
+ sampleCount: 0,
211
+ confidenceInterval: [0, 0]
212
+ };
213
+ }
214
+ const mean = scores.reduce((a, b) => a + b, 0) / scores.length;
215
+ const variance = scores.reduce((sum, s) => sum + Math.pow(s - mean, 2), 0) / scores.length;
216
+ const std = Math.sqrt(variance);
217
+ const se = std / Math.sqrt(scores.length);
218
+ const margin = 1.96 * se;
219
+ return {
220
+ mean,
221
+ std,
222
+ sampleCount: scores.length,
223
+ confidenceInterval: [mean - margin, mean + margin]
224
+ };
225
+ }
226
+ /**
227
+ * Calculate p-value using Welch's t-test approximation
228
+ */
229
+ calculatePValue(control, treatment) {
230
+ if (control.length < 2 || treatment.length < 2) return 1;
231
+ const n1 = control.length;
232
+ const n2 = treatment.length;
233
+ const mean1 = control.reduce((a, b) => a + b, 0) / n1;
234
+ const mean2 = treatment.reduce((a, b) => a + b, 0) / n2;
235
+ const var1 = control.reduce((sum, x) => sum + Math.pow(x - mean1, 2), 0) / (n1 - 1);
236
+ const var2 = treatment.reduce((sum, x) => sum + Math.pow(x - mean2, 2), 0) / (n2 - 1);
237
+ const se = Math.sqrt(var1 / n1 + var2 / n2);
238
+ if (se === 0) return 1;
239
+ const t = Math.abs(mean1 - mean2) / se;
240
+ const pValue = 2 * (1 - this.normalCDF(t));
241
+ return Math.max(0, Math.min(1, pValue));
242
+ }
243
+ /**
244
+ * Normal CDF approximation
245
+ */
246
+ normalCDF(x) {
247
+ const a1 = 0.254829592;
248
+ const a2 = -0.284496736;
249
+ const a3 = 1.421413741;
250
+ const a4 = -1.453152027;
251
+ const a5 = 1.061405429;
252
+ const p = 0.3275911;
253
+ const sign = x < 0 ? -1 : 1;
254
+ x = Math.abs(x) / Math.sqrt(2);
255
+ const t = 1 / (1 + p * x);
256
+ const y = 1 - ((((a5 * t + a4) * t + a3) * t + a2) * t + a1) * t * Math.exp(-x * x);
257
+ return 0.5 * (1 + sign * y);
258
+ }
259
+ /**
260
+ * Check for statistical significance
261
+ */
262
+ checkSignificance() {
263
+ for (const metric of this.config.metrics) {
264
+ const result = this.calculateMetricResult(metric);
265
+ if (result.isSignificant && result.winner !== "none") {
266
+ this.emit("test:significant", metric, result.winner);
267
+ }
268
+ }
269
+ }
270
+ /**
271
+ * Generate recommendation
272
+ */
273
+ generateRecommendation(winner, isSignificant, metrics) {
274
+ if (!isSignificant) {
275
+ const totalSamples = this.controlSamples.size + this.treatmentSamples.size;
276
+ if (totalSamples < this.config.minSamples) {
277
+ return `Not enough samples yet. Need ${this.config.minSamples - totalSamples} more.`;
278
+ }
279
+ return "No significant difference detected. Consider running longer or adjusting variants.";
280
+ }
281
+ if (winner === "treatment") {
282
+ const improvements = Object.entries(metrics).filter(([, r]) => r.winner === "treatment").map(([m, r]) => `${m}: +${r.differencePercent.toFixed(1)}%`);
283
+ return `Treatment variant wins. Improvements: ${improvements.join(", ")}`;
284
+ }
285
+ if (winner === "control") {
286
+ return "Control variant performs better. Consider keeping current configuration.";
287
+ }
288
+ return "Mixed results. Review individual metrics for details.";
289
+ }
290
+ /**
291
+ * Get test status
292
+ */
293
+ getStatus() {
294
+ return this.status;
295
+ }
296
+ /**
297
+ * Get test configuration
298
+ */
299
+ getConfig() {
300
+ return { ...this.config };
301
+ }
302
+ /**
303
+ * Get test timestamps
304
+ */
305
+ getTimestamps() {
306
+ return {
307
+ startedAt: this.startedAt,
308
+ completedAt: this.completedAt
309
+ };
310
+ }
311
+ };
312
+ function createABTestRunner(config) {
313
+ return new ABTestRunner(config);
314
+ }
315
+
316
+ // src/continuous/ContinuousEval.ts
317
+ var ContinuousEval = class extends import_eventemitter32.EventEmitter {
318
+ pipeline;
319
+ sampleRate;
320
+ status = "stopped";
321
+ startedAt;
322
+ lastEvalAt;
323
+ totalEvaluations = 0;
324
+ passedCount = 0;
325
+ scoreHistory = {};
326
+ alertManager;
327
+ abTests = /* @__PURE__ */ new Map();
328
+ intervalId;
329
+ constructor(config) {
330
+ super();
331
+ this.pipeline = config.pipeline;
332
+ this.sampleRate = config.sampleRate;
333
+ }
334
+ /**
335
+ * Set alert manager
336
+ */
337
+ setAlerts(alertManager, rules) {
338
+ this.alertManager = alertManager;
339
+ for (const [metric, rule] of Object.entries(rules)) {
340
+ alertManager.addRule({
341
+ metric,
342
+ threshold: rule.threshold,
343
+ direction: rule.direction
344
+ });
345
+ }
346
+ }
347
+ /**
348
+ * Start monitoring
349
+ */
350
+ start() {
351
+ if (this.status === "running") return;
352
+ this.status = "running";
353
+ this.startedAt = Date.now();
354
+ this.emit("status:changed", this.status);
355
+ this.emit("eval:started");
356
+ }
357
+ /**
358
+ * Stop monitoring
359
+ */
360
+ stop() {
361
+ this.status = "stopped";
362
+ if (this.intervalId) {
363
+ clearInterval(this.intervalId);
364
+ this.intervalId = void 0;
365
+ }
366
+ this.emit("status:changed", this.status);
367
+ }
368
+ /**
369
+ * Pause monitoring
370
+ */
371
+ pause() {
372
+ if (this.status === "running") {
373
+ this.status = "paused";
374
+ this.emit("status:changed", this.status);
375
+ }
376
+ }
377
+ /**
378
+ * Resume monitoring
379
+ */
380
+ resume() {
381
+ if (this.status === "paused") {
382
+ this.status = "running";
383
+ this.emit("status:changed", this.status);
384
+ }
385
+ }
386
+ /**
387
+ * Evaluate a sample
388
+ */
389
+ async evaluate(input) {
390
+ if (Math.random() > this.sampleRate) {
391
+ return null;
392
+ }
393
+ if (this.status !== "running") {
394
+ return null;
395
+ }
396
+ try {
397
+ const result = await this.pipeline.evaluate(input);
398
+ this.totalEvaluations++;
399
+ this.lastEvalAt = Date.now();
400
+ if (result.passed) {
401
+ this.passedCount++;
402
+ }
403
+ for (const [metric, score] of Object.entries(result.scores)) {
404
+ if (!this.scoreHistory[metric]) {
405
+ this.scoreHistory[metric] = [];
406
+ }
407
+ this.scoreHistory[metric].push(score);
408
+ if (this.scoreHistory[metric].length > 1e3) {
409
+ this.scoreHistory[metric].shift();
410
+ }
411
+ if (this.alertManager) {
412
+ this.alertManager.check(metric, score);
413
+ }
414
+ }
415
+ this.emit("eval:completed", result);
416
+ return result;
417
+ } catch (error) {
418
+ this.status = "error";
419
+ this.emit("eval:error", error);
420
+ this.emit("status:changed", this.status);
421
+ return null;
422
+ }
423
+ }
424
+ /**
425
+ * Get statistics
426
+ */
427
+ getStats() {
428
+ const avgScores = {};
429
+ for (const [metric, scores] of Object.entries(this.scoreHistory)) {
430
+ if (scores.length > 0) {
431
+ avgScores[metric] = scores.reduce((a, b) => a + b, 0) / scores.length;
432
+ }
433
+ }
434
+ return {
435
+ status: this.status,
436
+ startedAt: this.startedAt,
437
+ lastEvalAt: this.lastEvalAt,
438
+ totalEvaluations: this.totalEvaluations,
439
+ passRate: this.totalEvaluations > 0 ? this.passedCount / this.totalEvaluations : 0,
440
+ avgScores,
441
+ alertsTriggered: this.alertManager?.getAlertCount() ?? 0
442
+ };
443
+ }
444
+ /**
445
+ * Create A/B test
446
+ */
447
+ createABTest(config) {
448
+ const test = new ABTestRunner(config);
449
+ this.abTests.set(test.id, test);
450
+ return test;
451
+ }
452
+ /**
453
+ * Get A/B test
454
+ */
455
+ getABTest(id) {
456
+ return this.abTests.get(id);
457
+ }
458
+ /**
459
+ * Get all A/B tests
460
+ */
461
+ getABTests() {
462
+ return Array.from(this.abTests.values());
463
+ }
464
+ /**
465
+ * Get score history for a metric
466
+ */
467
+ getScoreHistory(metric) {
468
+ return this.scoreHistory[metric] ?? [];
469
+ }
470
+ /**
471
+ * Reset statistics
472
+ */
473
+ reset() {
474
+ this.totalEvaluations = 0;
475
+ this.passedCount = 0;
476
+ this.scoreHistory = {};
477
+ this.lastEvalAt = void 0;
478
+ }
479
+ };
480
+ function createContinuousEval(config) {
481
+ return new ContinuousEval(config);
482
+ }
483
+
484
+ // src/continuous/AlertManager.ts
485
+ var import_eventemitter33 = require("eventemitter3");
486
+ var import_nanoid2 = require("nanoid");
487
+ var AlertManager = class extends import_eventemitter33.EventEmitter {
488
+ channels;
489
+ rules = /* @__PURE__ */ new Map();
490
+ activeAlerts = /* @__PURE__ */ new Map();
491
+ cooldownMs;
492
+ lastAlertTime = /* @__PURE__ */ new Map();
493
+ alertCount = 0;
494
+ constructor(config) {
495
+ super();
496
+ this.channels = config.channels;
497
+ this.cooldownMs = config.cooldownMs ?? 3e5;
498
+ if (config.rules) {
499
+ for (const [metric, rule] of Object.entries(config.rules)) {
500
+ this.rules.set(metric, rule);
501
+ }
502
+ }
503
+ }
504
+ /**
505
+ * Add an alert rule
506
+ */
507
+ addRule(rule) {
508
+ this.rules.set(rule.metric, rule);
509
+ }
510
+ /**
511
+ * Remove an alert rule
512
+ */
513
+ removeRule(metric) {
514
+ return this.rules.delete(metric);
515
+ }
516
+ /**
517
+ * Check value against rules
518
+ */
519
+ check(metric, value) {
520
+ const rule = this.rules.get(metric);
521
+ if (!rule) return null;
522
+ const shouldAlert = rule.direction === "above" && value > rule.threshold || rule.direction === "below" && value < rule.threshold;
523
+ if (shouldAlert) {
524
+ return this.triggerAlert(rule, metric, value);
525
+ } else {
526
+ const existingAlert = this.activeAlerts.get(metric);
527
+ if (existingAlert) {
528
+ this.resolveAlert(metric);
529
+ }
530
+ }
531
+ return null;
532
+ }
533
+ /**
534
+ * Trigger an alert
535
+ */
536
+ triggerAlert(rule, metric, value) {
537
+ const lastTime = this.lastAlertTime.get(metric);
538
+ if (lastTime && Date.now() - lastTime < this.cooldownMs) {
539
+ return null;
540
+ }
541
+ const alert = {
542
+ id: (0, import_nanoid2.nanoid)(),
543
+ rule,
544
+ metric,
545
+ currentValue: value,
546
+ threshold: rule.threshold,
547
+ severity: rule.severity ?? "warning",
548
+ message: this.formatMessage(rule, metric, value),
549
+ triggeredAt: Date.now()
550
+ };
551
+ this.activeAlerts.set(metric, alert);
552
+ this.lastAlertTime.set(metric, Date.now());
553
+ this.alertCount++;
554
+ this.emit("alert:triggered", alert);
555
+ void this.sendNotifications(alert);
556
+ return alert;
557
+ }
558
+ /**
559
+ * Resolve an alert
560
+ */
561
+ resolveAlert(metric) {
562
+ const alert = this.activeAlerts.get(metric);
563
+ if (alert) {
564
+ alert.resolvedAt = Date.now();
565
+ this.activeAlerts.delete(metric);
566
+ this.emit("alert:resolved", alert);
567
+ }
568
+ }
569
+ /**
570
+ * Acknowledge an alert
571
+ */
572
+ acknowledgeAlert(alertId) {
573
+ for (const alert of this.activeAlerts.values()) {
574
+ if (alert.id === alertId) {
575
+ alert.acknowledged = true;
576
+ return true;
577
+ }
578
+ }
579
+ return false;
580
+ }
581
+ /**
582
+ * Send notifications
583
+ */
584
+ async sendNotifications(alert) {
585
+ for (const channel of this.channels) {
586
+ try {
587
+ await this.sendToChannel(channel, alert);
588
+ const notification = {
589
+ alertId: alert.id,
590
+ channel: channel.type,
591
+ sentAt: Date.now(),
592
+ success: true
593
+ };
594
+ this.emit("notification:sent", notification);
595
+ } catch (error) {
596
+ const notification = {
597
+ alertId: alert.id,
598
+ channel: channel.type,
599
+ sentAt: Date.now(),
600
+ success: false,
601
+ error: error.message
602
+ };
603
+ this.emit("notification:sent", notification);
604
+ }
605
+ }
606
+ }
607
+ /**
608
+ * Send to a specific channel
609
+ */
610
+ async sendToChannel(channel, alert) {
611
+ switch (channel.type) {
612
+ case "webhook":
613
+ if (channel.webhook) {
614
+ await fetch(channel.webhook, {
615
+ method: "POST",
616
+ headers: { "Content-Type": "application/json" },
617
+ body: JSON.stringify({
618
+ alert: {
619
+ id: alert.id,
620
+ metric: alert.metric,
621
+ severity: alert.severity,
622
+ message: alert.message,
623
+ value: alert.currentValue,
624
+ threshold: alert.threshold,
625
+ triggeredAt: new Date(alert.triggeredAt).toISOString()
626
+ }
627
+ })
628
+ });
629
+ }
630
+ break;
631
+ case "slack":
632
+ if (channel.webhook) {
633
+ await fetch(channel.webhook, {
634
+ method: "POST",
635
+ headers: { "Content-Type": "application/json" },
636
+ body: JSON.stringify({
637
+ text: `\u{1F6A8} *${alert.severity.toUpperCase()}*: ${alert.message}`,
638
+ attachments: [
639
+ {
640
+ color: alert.severity === "critical" ? "danger" : "warning",
641
+ fields: [
642
+ { title: "Metric", value: alert.metric, short: true },
643
+ {
644
+ title: "Value",
645
+ value: alert.currentValue.toFixed(4),
646
+ short: true
647
+ },
648
+ {
649
+ title: "Threshold",
650
+ value: alert.threshold.toString(),
651
+ short: true
652
+ }
653
+ ]
654
+ }
655
+ ]
656
+ })
657
+ });
658
+ }
659
+ break;
660
+ case "email":
661
+ console.log(`[Email Alert] To: ${channel.to?.join(", ")}`);
662
+ console.log(`Subject: Alert: ${alert.metric} - ${alert.severity}`);
663
+ console.log(`Body: ${alert.message}`);
664
+ break;
665
+ case "pagerduty":
666
+ console.log(`[PagerDuty Alert] ${alert.severity}: ${alert.message}`);
667
+ break;
668
+ }
669
+ }
670
+ /**
671
+ * Format alert message
672
+ */
673
+ formatMessage(rule, metric, value) {
674
+ const direction = rule.direction === "above" ? "exceeded" : "dropped below";
675
+ return `${metric} ${direction} threshold: ${value.toFixed(4)} (threshold: ${rule.threshold})`;
676
+ }
677
+ /**
678
+ * Get active alerts
679
+ */
680
+ getActiveAlerts() {
681
+ return Array.from(this.activeAlerts.values());
682
+ }
683
+ /**
684
+ * Get alert count
685
+ */
686
+ getAlertCount() {
687
+ return this.alertCount;
688
+ }
689
+ /**
690
+ * Get rules
691
+ */
692
+ getRules() {
693
+ return Array.from(this.rules.values());
694
+ }
695
+ };
696
+ function createAlertManager(config) {
697
+ return new AlertManager(config);
698
+ }
699
+ // Annotate the CommonJS export names for ESM import in node:
700
+ 0 && (module.exports = {
701
+ ABTestRunner,
702
+ AlertManager,
703
+ ContinuousEval,
704
+ createABTestRunner,
705
+ createAlertManager,
706
+ createContinuousEval
707
+ });
@@ -0,0 +1,16 @@
1
+ import {
2
+ ABTestRunner,
3
+ AlertManager,
4
+ ContinuousEval,
5
+ createABTestRunner,
6
+ createAlertManager,
7
+ createContinuousEval
8
+ } from "../chunk-EUXXIZK3.mjs";
9
+ export {
10
+ ABTestRunner,
11
+ AlertManager,
12
+ ContinuousEval,
13
+ createABTestRunner,
14
+ createAlertManager,
15
+ createContinuousEval
16
+ };
@@ -0,0 +1 @@
1
+ export { v as DatasetExporter, s as PreferenceDataset, t as PreferenceDatasetBuilder, w as createDatasetExporter, u as createPreferenceDatasetBuilder } from '../index-6Pbiq7ny.mjs';