@agentforge/core 0.16.66 → 0.16.68

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.cjs CHANGED
@@ -1351,7 +1351,7 @@ function toError(error) {
1351
1351
  }
1352
1352
  return new Error(String(error));
1353
1353
  }
1354
- function resolveExecutionMethod(tool, logger7) {
1354
+ function resolveExecutionMethod(tool, logger6) {
1355
1355
  const executeFn = tool.invoke || tool.execute;
1356
1356
  if (!executeFn) {
1357
1357
  throw new Error(
@@ -1359,14 +1359,14 @@ function resolveExecutionMethod(tool, logger7) {
1359
1359
  );
1360
1360
  }
1361
1361
  if (!tool.invoke && tool.execute) {
1362
- logger7.warn(
1362
+ logger6.warn(
1363
1363
  `Tool "${tool.metadata?.name ?? tool.name ?? "unknown"}" only implements execute() which is deprecated. Please update to implement invoke() as the primary method. execute() will be removed in v1.0.0.`
1364
1364
  );
1365
1365
  }
1366
1366
  return executeFn;
1367
1367
  }
1368
- async function executeWithRetry(tool, input, policy, logger7) {
1369
- const executeFn = resolveExecutionMethod(tool, logger7);
1368
+ async function executeWithRetry(tool, input, policy, logger6) {
1369
+ const executeFn = resolveExecutionMethod(tool, logger6);
1370
1370
  if (!policy) {
1371
1371
  return await executeFn.call(tool, input);
1372
1372
  }
@@ -1645,7 +1645,7 @@ async function performManagedCleanup({
1645
1645
  function ensureManagedBeforeExitHandler({
1646
1646
  autoCleanup,
1647
1647
  cleanup,
1648
- logger: logger7,
1648
+ logger: logger6,
1649
1649
  name,
1650
1650
  state
1651
1651
  }) {
@@ -1654,7 +1654,7 @@ function ensureManagedBeforeExitHandler({
1654
1654
  }
1655
1655
  state.beforeExitHandler = () => {
1656
1656
  cleanup().catch(
1657
- (err) => logger7.error("Cleanup failed", {
1657
+ (err) => logger6.error("Cleanup failed", {
1658
1658
  toolName: name,
1659
1659
  error: getErrorMessage(err),
1660
1660
  ...err instanceof Error && err.stack ? { stack: err.stack } : {}
@@ -2625,14 +2625,14 @@ var withLogging = (options) => {
2625
2625
  onComplete,
2626
2626
  onError
2627
2627
  } = options;
2628
- const logger7 = providedLogger || createLogger(name, { level });
2628
+ const logger6 = providedLogger || createLogger(name, { level });
2629
2629
  return (node) => {
2630
2630
  return async (state) => {
2631
2631
  const startTime = Date.now();
2632
2632
  try {
2633
2633
  if (logInput) {
2634
2634
  const data = extractData ? extractData(state) : { state };
2635
- logger7.info("Node execution started", data);
2635
+ logger6.info("Node execution started", data);
2636
2636
  }
2637
2637
  if (onStart) {
2638
2638
  onStart(state);
@@ -2642,9 +2642,9 @@ var withLogging = (options) => {
2642
2642
  if (logOutput) {
2643
2643
  const data = extractData ? extractData(result) : { result };
2644
2644
  if (logDuration) {
2645
- logger7.info(`Node execution completed (${duration}ms)`, data);
2645
+ logger6.info(`Node execution completed (${duration}ms)`, data);
2646
2646
  } else {
2647
- logger7.info("Node execution completed", data);
2647
+ logger6.info("Node execution completed", data);
2648
2648
  }
2649
2649
  }
2650
2650
  if (onComplete) {
@@ -2655,7 +2655,7 @@ var withLogging = (options) => {
2655
2655
  const duration = Date.now() - startTime;
2656
2656
  const err = error instanceof Error ? error : new Error(String(error));
2657
2657
  if (logErrors) {
2658
- logger7.error(`Node execution failed (${duration}ms)`, {
2658
+ logger6.error(`Node execution failed (${duration}ms)`, {
2659
2659
  error: err.message,
2660
2660
  ...err.stack ? { stack: err.stack } : {}
2661
2661
  });
@@ -2777,7 +2777,7 @@ function withLogging2(options) {
2777
2777
  function production(node, options) {
2778
2778
  const {
2779
2779
  nodeName,
2780
- logger: logger7,
2780
+ logger: logger6,
2781
2781
  enableMetrics = true,
2782
2782
  enableTracing = true,
2783
2783
  enableRetry = true,
@@ -2785,7 +2785,7 @@ function production(node, options) {
2785
2785
  retryOptions = {},
2786
2786
  errorOptions = {}
2787
2787
  } = options;
2788
- const actualLogger = logger7 || createLogger(nodeName, { level: "info" /* INFO */ });
2788
+ const actualLogger = logger6 || createLogger(nodeName, { level: "info" /* INFO */ });
2789
2789
  const middleware = [
2790
2790
  withLogging2({
2791
2791
  logger: actualLogger,
@@ -2840,8 +2840,8 @@ function production(node, options) {
2840
2840
 
2841
2841
  // src/langgraph/middleware/preset-development.ts
2842
2842
  function development(node, options) {
2843
- const { nodeName, verbose = true, logger: logger7 } = options;
2844
- const actualLogger = logger7 || createLogger(nodeName, { level: "debug" /* DEBUG */ });
2843
+ const { nodeName, verbose = true, logger: logger6 } = options;
2844
+ const actualLogger = logger6 || createLogger(nodeName, { level: "debug" /* DEBUG */ });
2845
2845
  return withLogging2({
2846
2846
  logger: actualLogger,
2847
2847
  name: nodeName,
@@ -5351,8 +5351,8 @@ function createProfiler(options) {
5351
5351
  return new Profiler(options);
5352
5352
  }
5353
5353
 
5354
- // src/monitoring/alerts.ts
5355
- var logger6 = createLogger("agentforge:core:monitoring:alerts", { level: "info" /* INFO */ });
5354
+ // src/monitoring/alerts-shared.ts
5355
+ var alertLogger = createLogger("agentforge:core:monitoring:alerts", { level: "info" /* INFO */ });
5356
5356
  function toAlertSummary(alert) {
5357
5357
  return {
5358
5358
  name: alert.name,
@@ -5360,13 +5360,57 @@ function toAlertSummary(alert) {
5360
5360
  message: alert.message
5361
5361
  };
5362
5362
  }
5363
- function toRuleErrorPayload(ruleName, error) {
5363
+
5364
+ // src/monitoring/alerts-channels.ts
5365
+ async function sendAlertToChannel(channels, channelName, alert) {
5366
+ const channel = channels[channelName];
5367
+ if (!channel) {
5368
+ throw new Error(`Channel not found: ${channelName}`);
5369
+ }
5370
+ switch (channel.type) {
5371
+ case "email":
5372
+ alertLogger.info("Alert sent to email", {
5373
+ channel: channelName,
5374
+ to: channel.config.to,
5375
+ alert: toAlertSummary(alert)
5376
+ });
5377
+ return;
5378
+ case "slack":
5379
+ alertLogger.info("Alert sent to Slack", {
5380
+ channel: channelName,
5381
+ webhookUrl: channel.config.webhookUrl,
5382
+ alert: toAlertSummary(alert)
5383
+ });
5384
+ return;
5385
+ case "webhook":
5386
+ alertLogger.info("Alert sent to webhook", {
5387
+ channel: channelName,
5388
+ url: channel.config.url,
5389
+ alert: toAlertSummary(alert)
5390
+ });
5391
+ return;
5392
+ default:
5393
+ alertLogger.info("Alert sent", {
5394
+ channel: channelName,
5395
+ channelType: channel.type,
5396
+ alert: toAlertSummary(alert)
5397
+ });
5398
+ }
5399
+ }
5400
+
5401
+ // src/monitoring/alerts-errors.ts
5402
+ function toErrorDetails(error) {
5364
5403
  return {
5365
- ruleName,
5366
5404
  error: error instanceof Error ? error.message : String(error),
5367
5405
  ...error instanceof Error && error.stack ? { stack: error.stack } : {}
5368
5406
  };
5369
5407
  }
5408
+ function toRuleErrorPayload(ruleName, error) {
5409
+ return {
5410
+ ruleName,
5411
+ ...toErrorDetails(error)
5412
+ };
5413
+ }
5370
5414
  function toAlertDispatchErrorPayload(ruleName, error) {
5371
5415
  return {
5372
5416
  stage: "alert-dispatch",
@@ -5376,17 +5420,52 @@ function toAlertDispatchErrorPayload(ruleName, error) {
5376
5420
  function toAlertCallbackErrorPayload(error) {
5377
5421
  return {
5378
5422
  stage: "alert-callback",
5379
- error: error instanceof Error ? error.message : String(error),
5380
- ...error instanceof Error && error.stack ? { stack: error.stack } : {}
5423
+ ...toErrorDetails(error)
5381
5424
  };
5382
5425
  }
5383
5426
  function toMetricsProviderErrorPayload(error) {
5384
5427
  return {
5385
5428
  stage: "metrics-provider",
5386
- error: error instanceof Error ? error.message : String(error),
5387
- ...error instanceof Error && error.stack ? { stack: error.stack } : {}
5429
+ ...toErrorDetails(error)
5388
5430
  };
5389
5431
  }
5432
+
5433
+ // src/monitoring/alerts-rules.ts
5434
+ function checkAlertRules(rules, metrics, alert) {
5435
+ if (!rules) {
5436
+ return;
5437
+ }
5438
+ for (const rule of rules) {
5439
+ try {
5440
+ if (!rule.condition(metrics)) {
5441
+ continue;
5442
+ }
5443
+ void alert({
5444
+ name: rule.name,
5445
+ severity: rule.severity,
5446
+ message: rule.message || `Alert triggered: ${rule.name}`,
5447
+ data: { metrics }
5448
+ }).catch((error) => {
5449
+ alertLogger.error("Alert dispatch failed", toAlertDispatchErrorPayload(rule.name, error));
5450
+ });
5451
+ } catch (error) {
5452
+ alertLogger.error("Rule check failed", toRuleErrorPayload(rule.name, error));
5453
+ }
5454
+ }
5455
+ }
5456
+ function isAlertThrottled(rules, name, lastAlertTime, now) {
5457
+ const rule = rules?.find((candidate) => candidate.name === name);
5458
+ if (!rule?.throttle) {
5459
+ return false;
5460
+ }
5461
+ const lastTime = lastAlertTime.get(name);
5462
+ if (!lastTime) {
5463
+ return false;
5464
+ }
5465
+ return now - lastTime < rule.throttle;
5466
+ }
5467
+
5468
+ // src/monitoring/alerts-manager.ts
5390
5469
  var AlertManager = class {
5391
5470
  constructor(options) {
5392
5471
  this.options = options;
@@ -5401,10 +5480,9 @@ var AlertManager = class {
5401
5480
  this.running = true;
5402
5481
  this.monitorTimer = setInterval(() => {
5403
5482
  try {
5404
- const currentMetrics = metrics();
5405
- this.checkRules(currentMetrics);
5483
+ checkAlertRules(this.options.rules, metrics(), (alert) => this.alert(alert));
5406
5484
  } catch (error) {
5407
- logger6.error("Metrics collection failed", toMetricsProviderErrorPayload(error));
5485
+ alertLogger.error("Metrics collection failed", toMetricsProviderErrorPayload(error));
5408
5486
  }
5409
5487
  }, interval);
5410
5488
  }
@@ -5419,92 +5497,29 @@ var AlertManager = class {
5419
5497
  }
5420
5498
  }
5421
5499
  async alert(alert) {
5500
+ const now = Date.now();
5422
5501
  const fullAlert = {
5423
5502
  ...alert,
5424
- timestamp: alert.timestamp ?? Date.now()
5503
+ timestamp: alert.timestamp ?? now
5425
5504
  };
5426
- if (this.isThrottled(alert.name)) {
5505
+ if (isAlertThrottled(this.options.rules, alert.name, this.lastAlertTime, now)) {
5427
5506
  return;
5428
5507
  }
5429
- this.lastAlertTime.set(alert.name, Date.now());
5508
+ this.lastAlertTime.set(alert.name, now);
5430
5509
  try {
5431
5510
  await this.options.onAlert?.(fullAlert);
5432
5511
  } catch (error) {
5433
- logger6.error("Alert callback failed", toAlertCallbackErrorPayload(error));
5512
+ alertLogger.error("Alert callback failed", toAlertCallbackErrorPayload(error));
5434
5513
  }
5435
- logger6.warn("Alert triggered", {
5514
+ alertLogger.warn("Alert triggered", {
5436
5515
  name: alert.name,
5437
5516
  severity: alert.severity,
5438
5517
  message: alert.message,
5439
5518
  ...alert.data ? { data: alert.data } : {}
5440
5519
  });
5441
5520
  }
5442
- checkRules(metrics) {
5443
- if (!this.options.rules) {
5444
- return;
5445
- }
5446
- for (const rule of this.options.rules) {
5447
- try {
5448
- if (rule.condition(metrics)) {
5449
- void this.alert({
5450
- name: rule.name,
5451
- severity: rule.severity,
5452
- message: rule.message || `Alert triggered: ${rule.name}`,
5453
- data: { metrics }
5454
- }).catch((error) => {
5455
- logger6.error("Alert dispatch failed", toAlertDispatchErrorPayload(rule.name, error));
5456
- });
5457
- }
5458
- } catch (error) {
5459
- logger6.error("Rule check failed", toRuleErrorPayload(rule.name, error));
5460
- }
5461
- }
5462
- }
5463
- isThrottled(name) {
5464
- const rule = this.options.rules?.find((r) => r.name === name);
5465
- if (!rule?.throttle) {
5466
- return false;
5467
- }
5468
- const lastTime = this.lastAlertTime.get(name);
5469
- if (!lastTime) {
5470
- return false;
5471
- }
5472
- return Date.now() - lastTime < rule.throttle;
5473
- }
5474
5521
  async sendToChannel(channelName, alert) {
5475
- const channel = this.options.channels[channelName];
5476
- if (!channel) {
5477
- throw new Error(`Channel not found: ${channelName}`);
5478
- }
5479
- switch (channel.type) {
5480
- case "email":
5481
- logger6.info("Alert sent to email", {
5482
- channel: channelName,
5483
- to: channel.config.to,
5484
- alert: toAlertSummary(alert)
5485
- });
5486
- break;
5487
- case "slack":
5488
- logger6.info("Alert sent to Slack", {
5489
- channel: channelName,
5490
- webhookUrl: channel.config.webhookUrl,
5491
- alert: toAlertSummary(alert)
5492
- });
5493
- break;
5494
- case "webhook":
5495
- logger6.info("Alert sent to webhook", {
5496
- channel: channelName,
5497
- url: channel.config.url,
5498
- alert: toAlertSummary(alert)
5499
- });
5500
- break;
5501
- default:
5502
- logger6.info("Alert sent", {
5503
- channel: channelName,
5504
- channelType: channel.type,
5505
- alert: toAlertSummary(alert)
5506
- });
5507
- }
5522
+ await sendAlertToChannel(this.options.channels, channelName, alert);
5508
5523
  }
5509
5524
  getAlertHistory(_name, _limit = 100) {
5510
5525
  return [];
@@ -5512,9 +5527,9 @@ var AlertManager = class {
5512
5527
  clearAlertHistory(name) {
5513
5528
  if (name) {
5514
5529
  this.lastAlertTime.delete(name);
5515
- } else {
5516
- this.lastAlertTime.clear();
5530
+ return;
5517
5531
  }
5532
+ this.lastAlertTime.clear();
5518
5533
  }
5519
5534
  };
5520
5535
  function createAlertManager(options) {
package/dist/index.d.cts CHANGED
@@ -4440,10 +4440,6 @@ declare class Profiler {
4440
4440
  }
4441
4441
  declare function createProfiler(options?: ProfilerOptions): Profiler;
4442
4442
 
4443
- /**
4444
- * Alert system for production monitoring
4445
- */
4446
-
4447
4443
  type AlertSeverity = 'info' | 'warning' | 'error' | 'critical';
4448
4444
  interface Alert<TData extends JsonObject = JsonObject> {
4449
4445
  name: string;
@@ -4501,6 +4497,7 @@ interface AlertManagerOptions<TMetrics extends JsonObject = JsonObject, TChannel
4501
4497
  rules?: AlertRule<TMetrics, AlertChannelName<TChannels>>[];
4502
4498
  onAlert?: (alert: Alert<AlertCallbackData<TMetrics>>) => void | Promise<void>;
4503
4499
  }
4500
+
4504
4501
  declare class AlertManager<TMetrics extends JsonObject = JsonObject, TChannels extends AlertChannelMap = Record<string, GenericAlertChannel>> {
4505
4502
  private options;
4506
4503
  private lastAlertTime;
@@ -4510,8 +4507,6 @@ declare class AlertManager<TMetrics extends JsonObject = JsonObject, TChannels e
4510
4507
  start(metrics?: () => TMetrics, interval?: number): void;
4511
4508
  stop(): void;
4512
4509
  alert(alert: Alert<AlertCallbackData<TMetrics>>): Promise<void>;
4513
- private checkRules;
4514
- private isThrottled;
4515
4510
  sendToChannel(channelName: keyof TChannels & string, alert: Alert<AlertCallbackData<TMetrics>>): Promise<void>;
4516
4511
  getAlertHistory(_name?: string, _limit?: number): Alert<AlertCallbackData<TMetrics>>[];
4517
4512
  clearAlertHistory(name?: string): void;
package/dist/index.d.ts CHANGED
@@ -4440,10 +4440,6 @@ declare class Profiler {
4440
4440
  }
4441
4441
  declare function createProfiler(options?: ProfilerOptions): Profiler;
4442
4442
 
4443
- /**
4444
- * Alert system for production monitoring
4445
- */
4446
-
4447
4443
  type AlertSeverity = 'info' | 'warning' | 'error' | 'critical';
4448
4444
  interface Alert<TData extends JsonObject = JsonObject> {
4449
4445
  name: string;
@@ -4501,6 +4497,7 @@ interface AlertManagerOptions<TMetrics extends JsonObject = JsonObject, TChannel
4501
4497
  rules?: AlertRule<TMetrics, AlertChannelName<TChannels>>[];
4502
4498
  onAlert?: (alert: Alert<AlertCallbackData<TMetrics>>) => void | Promise<void>;
4503
4499
  }
4500
+
4504
4501
  declare class AlertManager<TMetrics extends JsonObject = JsonObject, TChannels extends AlertChannelMap = Record<string, GenericAlertChannel>> {
4505
4502
  private options;
4506
4503
  private lastAlertTime;
@@ -4510,8 +4507,6 @@ declare class AlertManager<TMetrics extends JsonObject = JsonObject, TChannels e
4510
4507
  start(metrics?: () => TMetrics, interval?: number): void;
4511
4508
  stop(): void;
4512
4509
  alert(alert: Alert<AlertCallbackData<TMetrics>>): Promise<void>;
4513
- private checkRules;
4514
- private isThrottled;
4515
4510
  sendToChannel(channelName: keyof TChannels & string, alert: Alert<AlertCallbackData<TMetrics>>): Promise<void>;
4516
4511
  getAlertHistory(_name?: string, _limit?: number): Alert<AlertCallbackData<TMetrics>>[];
4517
4512
  clearAlertHistory(name?: string): void;
package/dist/index.js CHANGED
@@ -1176,7 +1176,7 @@ function toError(error) {
1176
1176
  }
1177
1177
  return new Error(String(error));
1178
1178
  }
1179
- function resolveExecutionMethod(tool, logger7) {
1179
+ function resolveExecutionMethod(tool, logger6) {
1180
1180
  const executeFn = tool.invoke || tool.execute;
1181
1181
  if (!executeFn) {
1182
1182
  throw new Error(
@@ -1184,14 +1184,14 @@ function resolveExecutionMethod(tool, logger7) {
1184
1184
  );
1185
1185
  }
1186
1186
  if (!tool.invoke && tool.execute) {
1187
- logger7.warn(
1187
+ logger6.warn(
1188
1188
  `Tool "${tool.metadata?.name ?? tool.name ?? "unknown"}" only implements execute() which is deprecated. Please update to implement invoke() as the primary method. execute() will be removed in v1.0.0.`
1189
1189
  );
1190
1190
  }
1191
1191
  return executeFn;
1192
1192
  }
1193
- async function executeWithRetry(tool, input, policy, logger7) {
1194
- const executeFn = resolveExecutionMethod(tool, logger7);
1193
+ async function executeWithRetry(tool, input, policy, logger6) {
1194
+ const executeFn = resolveExecutionMethod(tool, logger6);
1195
1195
  if (!policy) {
1196
1196
  return await executeFn.call(tool, input);
1197
1197
  }
@@ -1470,7 +1470,7 @@ async function performManagedCleanup({
1470
1470
  function ensureManagedBeforeExitHandler({
1471
1471
  autoCleanup,
1472
1472
  cleanup,
1473
- logger: logger7,
1473
+ logger: logger6,
1474
1474
  name,
1475
1475
  state
1476
1476
  }) {
@@ -1479,7 +1479,7 @@ function ensureManagedBeforeExitHandler({
1479
1479
  }
1480
1480
  state.beforeExitHandler = () => {
1481
1481
  cleanup().catch(
1482
- (err) => logger7.error("Cleanup failed", {
1482
+ (err) => logger6.error("Cleanup failed", {
1483
1483
  toolName: name,
1484
1484
  error: getErrorMessage(err),
1485
1485
  ...err instanceof Error && err.stack ? { stack: err.stack } : {}
@@ -2450,14 +2450,14 @@ var withLogging = (options) => {
2450
2450
  onComplete,
2451
2451
  onError
2452
2452
  } = options;
2453
- const logger7 = providedLogger || createLogger(name, { level });
2453
+ const logger6 = providedLogger || createLogger(name, { level });
2454
2454
  return (node) => {
2455
2455
  return async (state) => {
2456
2456
  const startTime = Date.now();
2457
2457
  try {
2458
2458
  if (logInput) {
2459
2459
  const data = extractData ? extractData(state) : { state };
2460
- logger7.info("Node execution started", data);
2460
+ logger6.info("Node execution started", data);
2461
2461
  }
2462
2462
  if (onStart) {
2463
2463
  onStart(state);
@@ -2467,9 +2467,9 @@ var withLogging = (options) => {
2467
2467
  if (logOutput) {
2468
2468
  const data = extractData ? extractData(result) : { result };
2469
2469
  if (logDuration) {
2470
- logger7.info(`Node execution completed (${duration}ms)`, data);
2470
+ logger6.info(`Node execution completed (${duration}ms)`, data);
2471
2471
  } else {
2472
- logger7.info("Node execution completed", data);
2472
+ logger6.info("Node execution completed", data);
2473
2473
  }
2474
2474
  }
2475
2475
  if (onComplete) {
@@ -2480,7 +2480,7 @@ var withLogging = (options) => {
2480
2480
  const duration = Date.now() - startTime;
2481
2481
  const err = error instanceof Error ? error : new Error(String(error));
2482
2482
  if (logErrors) {
2483
- logger7.error(`Node execution failed (${duration}ms)`, {
2483
+ logger6.error(`Node execution failed (${duration}ms)`, {
2484
2484
  error: err.message,
2485
2485
  ...err.stack ? { stack: err.stack } : {}
2486
2486
  });
@@ -2602,7 +2602,7 @@ function withLogging2(options) {
2602
2602
  function production(node, options) {
2603
2603
  const {
2604
2604
  nodeName,
2605
- logger: logger7,
2605
+ logger: logger6,
2606
2606
  enableMetrics = true,
2607
2607
  enableTracing = true,
2608
2608
  enableRetry = true,
@@ -2610,7 +2610,7 @@ function production(node, options) {
2610
2610
  retryOptions = {},
2611
2611
  errorOptions = {}
2612
2612
  } = options;
2613
- const actualLogger = logger7 || createLogger(nodeName, { level: "info" /* INFO */ });
2613
+ const actualLogger = logger6 || createLogger(nodeName, { level: "info" /* INFO */ });
2614
2614
  const middleware = [
2615
2615
  withLogging2({
2616
2616
  logger: actualLogger,
@@ -2665,8 +2665,8 @@ function production(node, options) {
2665
2665
 
2666
2666
  // src/langgraph/middleware/preset-development.ts
2667
2667
  function development(node, options) {
2668
- const { nodeName, verbose = true, logger: logger7 } = options;
2669
- const actualLogger = logger7 || createLogger(nodeName, { level: "debug" /* DEBUG */ });
2668
+ const { nodeName, verbose = true, logger: logger6 } = options;
2669
+ const actualLogger = logger6 || createLogger(nodeName, { level: "debug" /* DEBUG */ });
2670
2670
  return withLogging2({
2671
2671
  logger: actualLogger,
2672
2672
  name: nodeName,
@@ -5176,8 +5176,8 @@ function createProfiler(options) {
5176
5176
  return new Profiler(options);
5177
5177
  }
5178
5178
 
5179
- // src/monitoring/alerts.ts
5180
- var logger6 = createLogger("agentforge:core:monitoring:alerts", { level: "info" /* INFO */ });
5179
+ // src/monitoring/alerts-shared.ts
5180
+ var alertLogger = createLogger("agentforge:core:monitoring:alerts", { level: "info" /* INFO */ });
5181
5181
  function toAlertSummary(alert) {
5182
5182
  return {
5183
5183
  name: alert.name,
@@ -5185,13 +5185,57 @@ function toAlertSummary(alert) {
5185
5185
  message: alert.message
5186
5186
  };
5187
5187
  }
5188
- function toRuleErrorPayload(ruleName, error) {
5188
+
5189
+ // src/monitoring/alerts-channels.ts
5190
+ async function sendAlertToChannel(channels, channelName, alert) {
5191
+ const channel = channels[channelName];
5192
+ if (!channel) {
5193
+ throw new Error(`Channel not found: ${channelName}`);
5194
+ }
5195
+ switch (channel.type) {
5196
+ case "email":
5197
+ alertLogger.info("Alert sent to email", {
5198
+ channel: channelName,
5199
+ to: channel.config.to,
5200
+ alert: toAlertSummary(alert)
5201
+ });
5202
+ return;
5203
+ case "slack":
5204
+ alertLogger.info("Alert sent to Slack", {
5205
+ channel: channelName,
5206
+ webhookUrl: channel.config.webhookUrl,
5207
+ alert: toAlertSummary(alert)
5208
+ });
5209
+ return;
5210
+ case "webhook":
5211
+ alertLogger.info("Alert sent to webhook", {
5212
+ channel: channelName,
5213
+ url: channel.config.url,
5214
+ alert: toAlertSummary(alert)
5215
+ });
5216
+ return;
5217
+ default:
5218
+ alertLogger.info("Alert sent", {
5219
+ channel: channelName,
5220
+ channelType: channel.type,
5221
+ alert: toAlertSummary(alert)
5222
+ });
5223
+ }
5224
+ }
5225
+
5226
+ // src/monitoring/alerts-errors.ts
5227
+ function toErrorDetails(error) {
5189
5228
  return {
5190
- ruleName,
5191
5229
  error: error instanceof Error ? error.message : String(error),
5192
5230
  ...error instanceof Error && error.stack ? { stack: error.stack } : {}
5193
5231
  };
5194
5232
  }
5233
+ function toRuleErrorPayload(ruleName, error) {
5234
+ return {
5235
+ ruleName,
5236
+ ...toErrorDetails(error)
5237
+ };
5238
+ }
5195
5239
  function toAlertDispatchErrorPayload(ruleName, error) {
5196
5240
  return {
5197
5241
  stage: "alert-dispatch",
@@ -5201,17 +5245,52 @@ function toAlertDispatchErrorPayload(ruleName, error) {
5201
5245
  function toAlertCallbackErrorPayload(error) {
5202
5246
  return {
5203
5247
  stage: "alert-callback",
5204
- error: error instanceof Error ? error.message : String(error),
5205
- ...error instanceof Error && error.stack ? { stack: error.stack } : {}
5248
+ ...toErrorDetails(error)
5206
5249
  };
5207
5250
  }
5208
5251
  function toMetricsProviderErrorPayload(error) {
5209
5252
  return {
5210
5253
  stage: "metrics-provider",
5211
- error: error instanceof Error ? error.message : String(error),
5212
- ...error instanceof Error && error.stack ? { stack: error.stack } : {}
5254
+ ...toErrorDetails(error)
5213
5255
  };
5214
5256
  }
5257
+
5258
+ // src/monitoring/alerts-rules.ts
5259
+ function checkAlertRules(rules, metrics, alert) {
5260
+ if (!rules) {
5261
+ return;
5262
+ }
5263
+ for (const rule of rules) {
5264
+ try {
5265
+ if (!rule.condition(metrics)) {
5266
+ continue;
5267
+ }
5268
+ void alert({
5269
+ name: rule.name,
5270
+ severity: rule.severity,
5271
+ message: rule.message || `Alert triggered: ${rule.name}`,
5272
+ data: { metrics }
5273
+ }).catch((error) => {
5274
+ alertLogger.error("Alert dispatch failed", toAlertDispatchErrorPayload(rule.name, error));
5275
+ });
5276
+ } catch (error) {
5277
+ alertLogger.error("Rule check failed", toRuleErrorPayload(rule.name, error));
5278
+ }
5279
+ }
5280
+ }
5281
+ function isAlertThrottled(rules, name, lastAlertTime, now) {
5282
+ const rule = rules?.find((candidate) => candidate.name === name);
5283
+ if (!rule?.throttle) {
5284
+ return false;
5285
+ }
5286
+ const lastTime = lastAlertTime.get(name);
5287
+ if (!lastTime) {
5288
+ return false;
5289
+ }
5290
+ return now - lastTime < rule.throttle;
5291
+ }
5292
+
5293
+ // src/monitoring/alerts-manager.ts
5215
5294
  var AlertManager = class {
5216
5295
  constructor(options) {
5217
5296
  this.options = options;
@@ -5226,10 +5305,9 @@ var AlertManager = class {
5226
5305
  this.running = true;
5227
5306
  this.monitorTimer = setInterval(() => {
5228
5307
  try {
5229
- const currentMetrics = metrics();
5230
- this.checkRules(currentMetrics);
5308
+ checkAlertRules(this.options.rules, metrics(), (alert) => this.alert(alert));
5231
5309
  } catch (error) {
5232
- logger6.error("Metrics collection failed", toMetricsProviderErrorPayload(error));
5310
+ alertLogger.error("Metrics collection failed", toMetricsProviderErrorPayload(error));
5233
5311
  }
5234
5312
  }, interval);
5235
5313
  }
@@ -5244,92 +5322,29 @@ var AlertManager = class {
5244
5322
  }
5245
5323
  }
5246
5324
  async alert(alert) {
5325
+ const now = Date.now();
5247
5326
  const fullAlert = {
5248
5327
  ...alert,
5249
- timestamp: alert.timestamp ?? Date.now()
5328
+ timestamp: alert.timestamp ?? now
5250
5329
  };
5251
- if (this.isThrottled(alert.name)) {
5330
+ if (isAlertThrottled(this.options.rules, alert.name, this.lastAlertTime, now)) {
5252
5331
  return;
5253
5332
  }
5254
- this.lastAlertTime.set(alert.name, Date.now());
5333
+ this.lastAlertTime.set(alert.name, now);
5255
5334
  try {
5256
5335
  await this.options.onAlert?.(fullAlert);
5257
5336
  } catch (error) {
5258
- logger6.error("Alert callback failed", toAlertCallbackErrorPayload(error));
5337
+ alertLogger.error("Alert callback failed", toAlertCallbackErrorPayload(error));
5259
5338
  }
5260
- logger6.warn("Alert triggered", {
5339
+ alertLogger.warn("Alert triggered", {
5261
5340
  name: alert.name,
5262
5341
  severity: alert.severity,
5263
5342
  message: alert.message,
5264
5343
  ...alert.data ? { data: alert.data } : {}
5265
5344
  });
5266
5345
  }
5267
- checkRules(metrics) {
5268
- if (!this.options.rules) {
5269
- return;
5270
- }
5271
- for (const rule of this.options.rules) {
5272
- try {
5273
- if (rule.condition(metrics)) {
5274
- void this.alert({
5275
- name: rule.name,
5276
- severity: rule.severity,
5277
- message: rule.message || `Alert triggered: ${rule.name}`,
5278
- data: { metrics }
5279
- }).catch((error) => {
5280
- logger6.error("Alert dispatch failed", toAlertDispatchErrorPayload(rule.name, error));
5281
- });
5282
- }
5283
- } catch (error) {
5284
- logger6.error("Rule check failed", toRuleErrorPayload(rule.name, error));
5285
- }
5286
- }
5287
- }
5288
- isThrottled(name) {
5289
- const rule = this.options.rules?.find((r) => r.name === name);
5290
- if (!rule?.throttle) {
5291
- return false;
5292
- }
5293
- const lastTime = this.lastAlertTime.get(name);
5294
- if (!lastTime) {
5295
- return false;
5296
- }
5297
- return Date.now() - lastTime < rule.throttle;
5298
- }
5299
5346
  async sendToChannel(channelName, alert) {
5300
- const channel = this.options.channels[channelName];
5301
- if (!channel) {
5302
- throw new Error(`Channel not found: ${channelName}`);
5303
- }
5304
- switch (channel.type) {
5305
- case "email":
5306
- logger6.info("Alert sent to email", {
5307
- channel: channelName,
5308
- to: channel.config.to,
5309
- alert: toAlertSummary(alert)
5310
- });
5311
- break;
5312
- case "slack":
5313
- logger6.info("Alert sent to Slack", {
5314
- channel: channelName,
5315
- webhookUrl: channel.config.webhookUrl,
5316
- alert: toAlertSummary(alert)
5317
- });
5318
- break;
5319
- case "webhook":
5320
- logger6.info("Alert sent to webhook", {
5321
- channel: channelName,
5322
- url: channel.config.url,
5323
- alert: toAlertSummary(alert)
5324
- });
5325
- break;
5326
- default:
5327
- logger6.info("Alert sent", {
5328
- channel: channelName,
5329
- channelType: channel.type,
5330
- alert: toAlertSummary(alert)
5331
- });
5332
- }
5347
+ await sendAlertToChannel(this.options.channels, channelName, alert);
5333
5348
  }
5334
5349
  getAlertHistory(_name, _limit = 100) {
5335
5350
  return [];
@@ -5337,9 +5352,9 @@ var AlertManager = class {
5337
5352
  clearAlertHistory(name) {
5338
5353
  if (name) {
5339
5354
  this.lastAlertTime.delete(name);
5340
- } else {
5341
- this.lastAlertTime.clear();
5355
+ return;
5342
5356
  }
5357
+ this.lastAlertTime.clear();
5343
5358
  }
5344
5359
  };
5345
5360
  function createAlertManager(options) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentforge/core",
3
- "version": "0.16.66",
3
+ "version": "0.16.68",
4
4
  "description": "Production-ready TypeScript agent framework built on LangGraph with orchestration, middleware, and typed abstractions.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -61,8 +61,8 @@
61
61
  "scripts": {
62
62
  "build": "tsup src/index.ts --format esm,cjs --dts --clean",
63
63
  "dev": "tsup src/index.ts --format esm,cjs --dts --watch",
64
- "test": "vitest",
65
- "test:coverage": "vitest --coverage",
64
+ "test": "vitest --config vitest.config.ts",
65
+ "test:coverage": "vitest --config vitest.config.ts --coverage",
66
66
  "typecheck": "tsc --noEmit",
67
67
  "lint": "eslint src",
68
68
  "lint:fix": "eslint src --fix",