@agentforge/core 0.11.8 → 0.12.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.cjs +504 -9
- package/dist/index.d.cts +218 -5
- package/dist/index.d.ts +218 -5
- package/dist/index.js +496 -9
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -31,10 +31,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
AgentError: () => AgentError,
|
|
34
|
+
AlertManager: () => AlertManager,
|
|
35
|
+
AuditLogger: () => AuditLogger,
|
|
34
36
|
BatchProcessor: () => BatchProcessor,
|
|
35
37
|
CircuitBreaker: () => CircuitBreaker,
|
|
36
38
|
ConnectionPool: () => ConnectionPool,
|
|
37
39
|
DatabasePool: () => DatabasePool,
|
|
40
|
+
HealthChecker: () => HealthChecker,
|
|
38
41
|
HttpPool: () => HttpPool,
|
|
39
42
|
LogLevel: () => LogLevel,
|
|
40
43
|
ManagedTool: () => ManagedTool,
|
|
@@ -42,6 +45,7 @@ __export(index_exports, {
|
|
|
42
45
|
MetricType: () => MetricType,
|
|
43
46
|
MiddlewareChain: () => MiddlewareChain,
|
|
44
47
|
MissingDescriptionError: () => MissingDescriptionError,
|
|
48
|
+
Profiler: () => Profiler,
|
|
45
49
|
RegistryEvent: () => RegistryEvent,
|
|
46
50
|
TimeoutError: () => TimeoutError,
|
|
47
51
|
ToolBuilder: () => ToolBuilder,
|
|
@@ -65,7 +69,9 @@ __export(index_exports, {
|
|
|
65
69
|
composeWithOptions: () => composeWithOptions,
|
|
66
70
|
conditional: () => conditional,
|
|
67
71
|
configureLangSmith: () => configureLangSmith,
|
|
72
|
+
createAlertManager: () => createAlertManager,
|
|
68
73
|
createApprovalRequiredInterrupt: () => createApprovalRequiredInterrupt,
|
|
74
|
+
createAuditLogger: () => createAuditLogger,
|
|
69
75
|
createBatchProcessor: () => createBatchProcessor,
|
|
70
76
|
createBinaryRouter: () => createBinaryRouter,
|
|
71
77
|
createCircuitBreaker: () => createCircuitBreaker,
|
|
@@ -75,6 +81,7 @@ __export(index_exports, {
|
|
|
75
81
|
createCustomInterrupt: () => createCustomInterrupt,
|
|
76
82
|
createDatabasePool: () => createDatabasePool,
|
|
77
83
|
createErrorReporter: () => createErrorReporter,
|
|
84
|
+
createHealthChecker: () => createHealthChecker,
|
|
78
85
|
createHeartbeat: () => createHeartbeat,
|
|
79
86
|
createHttpPool: () => createHttpPool,
|
|
80
87
|
createHumanRequestInterrupt: () => createHumanRequestInterrupt,
|
|
@@ -88,6 +95,7 @@ __export(index_exports, {
|
|
|
88
95
|
createMockTool: () => createMockTool,
|
|
89
96
|
createMultiRouter: () => createMultiRouter,
|
|
90
97
|
createParallelWorkflow: () => createParallelWorkflow,
|
|
98
|
+
createProfiler: () => createProfiler,
|
|
91
99
|
createProgressTracker: () => createProgressTracker,
|
|
92
100
|
createSSEFormatter: () => createSSEFormatter,
|
|
93
101
|
createSequentialWorkflow: () => createSequentialWorkflow,
|
|
@@ -2682,14 +2690,14 @@ var withLogging = (options) => {
|
|
|
2682
2690
|
onComplete,
|
|
2683
2691
|
onError
|
|
2684
2692
|
} = options;
|
|
2685
|
-
const
|
|
2693
|
+
const logger5 = providedLogger || createLogger(name, { level });
|
|
2686
2694
|
return (node) => {
|
|
2687
2695
|
return async (state) => {
|
|
2688
2696
|
const startTime = Date.now();
|
|
2689
2697
|
try {
|
|
2690
2698
|
if (logInput) {
|
|
2691
2699
|
const data = extractData ? extractData(state) : { state };
|
|
2692
|
-
|
|
2700
|
+
logger5.info("Node execution started", data);
|
|
2693
2701
|
}
|
|
2694
2702
|
if (onStart) {
|
|
2695
2703
|
onStart(state);
|
|
@@ -2699,9 +2707,9 @@ var withLogging = (options) => {
|
|
|
2699
2707
|
if (logOutput) {
|
|
2700
2708
|
const data = extractData ? extractData(result) : { result };
|
|
2701
2709
|
if (logDuration) {
|
|
2702
|
-
|
|
2710
|
+
logger5.info(`Node execution completed (${duration}ms)`, data);
|
|
2703
2711
|
} else {
|
|
2704
|
-
|
|
2712
|
+
logger5.info("Node execution completed", data);
|
|
2705
2713
|
}
|
|
2706
2714
|
}
|
|
2707
2715
|
if (onComplete) {
|
|
@@ -2712,7 +2720,7 @@ var withLogging = (options) => {
|
|
|
2712
2720
|
const duration = Date.now() - startTime;
|
|
2713
2721
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
2714
2722
|
if (logErrors) {
|
|
2715
|
-
|
|
2723
|
+
logger5.error(`Node execution failed (${duration}ms)`, {
|
|
2716
2724
|
error: err.message,
|
|
2717
2725
|
stack: err.stack
|
|
2718
2726
|
});
|
|
@@ -2748,7 +2756,7 @@ function withLogging2(options) {
|
|
|
2748
2756
|
function production(node, options) {
|
|
2749
2757
|
const {
|
|
2750
2758
|
nodeName,
|
|
2751
|
-
logger:
|
|
2759
|
+
logger: logger5,
|
|
2752
2760
|
enableMetrics = true,
|
|
2753
2761
|
enableTracing = true,
|
|
2754
2762
|
enableRetry = true,
|
|
@@ -2756,7 +2764,7 @@ function production(node, options) {
|
|
|
2756
2764
|
retryOptions = {},
|
|
2757
2765
|
errorOptions = {}
|
|
2758
2766
|
} = options;
|
|
2759
|
-
const actualLogger =
|
|
2767
|
+
const actualLogger = logger5 || createLogger(nodeName, { level: "info" /* INFO */ });
|
|
2760
2768
|
const middleware = [];
|
|
2761
2769
|
middleware.push(
|
|
2762
2770
|
withLogging2({
|
|
@@ -2820,9 +2828,9 @@ function development(node, options) {
|
|
|
2820
2828
|
const {
|
|
2821
2829
|
nodeName,
|
|
2822
2830
|
verbose = true,
|
|
2823
|
-
logger:
|
|
2831
|
+
logger: logger5
|
|
2824
2832
|
} = options;
|
|
2825
|
-
const actualLogger =
|
|
2833
|
+
const actualLogger = logger5 || createLogger(nodeName, { level: "debug" /* DEBUG */ });
|
|
2826
2834
|
return withLogging2({
|
|
2827
2835
|
logger: actualLogger,
|
|
2828
2836
|
name: nodeName,
|
|
@@ -4934,6 +4942,485 @@ function createCircuitBreaker(options) {
|
|
|
4934
4942
|
return new CircuitBreaker(options);
|
|
4935
4943
|
}
|
|
4936
4944
|
|
|
4945
|
+
// src/monitoring/health.ts
|
|
4946
|
+
var HealthChecker = class {
|
|
4947
|
+
constructor(options) {
|
|
4948
|
+
this.options = options;
|
|
4949
|
+
}
|
|
4950
|
+
checkTimer;
|
|
4951
|
+
lastReport;
|
|
4952
|
+
startTime = Date.now();
|
|
4953
|
+
running = false;
|
|
4954
|
+
start() {
|
|
4955
|
+
if (this.running) {
|
|
4956
|
+
return;
|
|
4957
|
+
}
|
|
4958
|
+
this.running = true;
|
|
4959
|
+
const interval = this.options.interval || 3e4;
|
|
4960
|
+
this.runChecks().catch((error) => {
|
|
4961
|
+
console.error("Initial health check failed:", error);
|
|
4962
|
+
});
|
|
4963
|
+
this.checkTimer = setInterval(() => {
|
|
4964
|
+
this.runChecks().catch((error) => {
|
|
4965
|
+
console.error("Health check failed:", error);
|
|
4966
|
+
});
|
|
4967
|
+
}, interval);
|
|
4968
|
+
}
|
|
4969
|
+
stop() {
|
|
4970
|
+
if (!this.running) {
|
|
4971
|
+
return;
|
|
4972
|
+
}
|
|
4973
|
+
this.running = false;
|
|
4974
|
+
if (this.checkTimer) {
|
|
4975
|
+
clearInterval(this.checkTimer);
|
|
4976
|
+
this.checkTimer = void 0;
|
|
4977
|
+
}
|
|
4978
|
+
}
|
|
4979
|
+
async getHealth() {
|
|
4980
|
+
if (!this.lastReport) {
|
|
4981
|
+
return this.runChecks();
|
|
4982
|
+
}
|
|
4983
|
+
return this.lastReport;
|
|
4984
|
+
}
|
|
4985
|
+
async getLiveness() {
|
|
4986
|
+
return {
|
|
4987
|
+
healthy: true,
|
|
4988
|
+
status: "healthy",
|
|
4989
|
+
message: "Application is running",
|
|
4990
|
+
timestamp: Date.now()
|
|
4991
|
+
};
|
|
4992
|
+
}
|
|
4993
|
+
async getReadiness() {
|
|
4994
|
+
return this.getHealth();
|
|
4995
|
+
}
|
|
4996
|
+
async runChecks() {
|
|
4997
|
+
const timeout2 = this.options.timeout || 5e3;
|
|
4998
|
+
const results = {};
|
|
4999
|
+
const checkPromises = Object.entries(this.options.checks).map(async ([name, check]) => {
|
|
5000
|
+
const startTime = Date.now();
|
|
5001
|
+
try {
|
|
5002
|
+
const result = await Promise.race([
|
|
5003
|
+
check(),
|
|
5004
|
+
new Promise(
|
|
5005
|
+
(_, reject) => setTimeout(() => reject(new Error("Health check timeout")), timeout2)
|
|
5006
|
+
)
|
|
5007
|
+
]);
|
|
5008
|
+
results[name] = {
|
|
5009
|
+
...result,
|
|
5010
|
+
timestamp: Date.now(),
|
|
5011
|
+
duration: Date.now() - startTime
|
|
5012
|
+
};
|
|
5013
|
+
} catch (error) {
|
|
5014
|
+
const errorMessage = error.message;
|
|
5015
|
+
results[name] = {
|
|
5016
|
+
healthy: false,
|
|
5017
|
+
status: "unhealthy",
|
|
5018
|
+
error: errorMessage,
|
|
5019
|
+
timestamp: Date.now(),
|
|
5020
|
+
duration: Date.now() - startTime
|
|
5021
|
+
};
|
|
5022
|
+
this.options.onCheckFail?.(name, error);
|
|
5023
|
+
}
|
|
5024
|
+
});
|
|
5025
|
+
await Promise.all(checkPromises);
|
|
5026
|
+
const allHealthy = Object.values(results).every((r) => r.healthy);
|
|
5027
|
+
const anyUnhealthy = Object.values(results).some((r) => r.status === "unhealthy");
|
|
5028
|
+
const status = allHealthy ? "healthy" : anyUnhealthy ? "unhealthy" : "degraded";
|
|
5029
|
+
const report = {
|
|
5030
|
+
healthy: allHealthy,
|
|
5031
|
+
status,
|
|
5032
|
+
timestamp: Date.now(),
|
|
5033
|
+
checks: results,
|
|
5034
|
+
uptime: Date.now() - this.startTime
|
|
5035
|
+
};
|
|
5036
|
+
if (this.lastReport && this.lastReport.healthy !== report.healthy) {
|
|
5037
|
+
this.options.onHealthChange?.(report);
|
|
5038
|
+
}
|
|
5039
|
+
this.lastReport = report;
|
|
5040
|
+
return report;
|
|
5041
|
+
}
|
|
5042
|
+
};
|
|
5043
|
+
function createHealthChecker(options) {
|
|
5044
|
+
return new HealthChecker(options);
|
|
5045
|
+
}
|
|
5046
|
+
|
|
5047
|
+
// src/monitoring/profiler.ts
|
|
5048
|
+
var Profiler = class {
|
|
5049
|
+
profiles = /* @__PURE__ */ new Map();
|
|
5050
|
+
enabled;
|
|
5051
|
+
sampleRate;
|
|
5052
|
+
includeMemory;
|
|
5053
|
+
includeStack;
|
|
5054
|
+
maxSamples;
|
|
5055
|
+
constructor(options = {}) {
|
|
5056
|
+
this.enabled = options.enabled ?? true;
|
|
5057
|
+
this.sampleRate = options.sampleRate ?? 1;
|
|
5058
|
+
this.includeMemory = options.includeMemory ?? false;
|
|
5059
|
+
this.includeStack = options.includeStack ?? false;
|
|
5060
|
+
this.maxSamples = options.maxSamples ?? 1e3;
|
|
5061
|
+
}
|
|
5062
|
+
profile(name, fn) {
|
|
5063
|
+
return async (...args) => {
|
|
5064
|
+
if (!this.enabled || Math.random() > this.sampleRate) {
|
|
5065
|
+
return fn(...args);
|
|
5066
|
+
}
|
|
5067
|
+
const startTime = Date.now();
|
|
5068
|
+
const startMemory = this.includeMemory ? process.memoryUsage() : void 0;
|
|
5069
|
+
const stack = this.includeStack ? new Error().stack : void 0;
|
|
5070
|
+
try {
|
|
5071
|
+
const result = await fn(...args);
|
|
5072
|
+
this.recordSample(name, startTime, startMemory, stack);
|
|
5073
|
+
return result;
|
|
5074
|
+
} catch (error) {
|
|
5075
|
+
this.recordSample(name, startTime, startMemory, stack);
|
|
5076
|
+
throw error;
|
|
5077
|
+
}
|
|
5078
|
+
};
|
|
5079
|
+
}
|
|
5080
|
+
wrap(name, promise) {
|
|
5081
|
+
if (!this.enabled || Math.random() > this.sampleRate) {
|
|
5082
|
+
return promise;
|
|
5083
|
+
}
|
|
5084
|
+
const startTime = Date.now();
|
|
5085
|
+
const startMemory = this.includeMemory ? process.memoryUsage() : void 0;
|
|
5086
|
+
const stack = this.includeStack ? new Error().stack : void 0;
|
|
5087
|
+
return promise.finally(() => {
|
|
5088
|
+
this.recordSample(name, startTime, startMemory, stack);
|
|
5089
|
+
});
|
|
5090
|
+
}
|
|
5091
|
+
recordSample(name, startTime, startMemory, stack) {
|
|
5092
|
+
const duration = Date.now() - startTime;
|
|
5093
|
+
const sample = {
|
|
5094
|
+
timestamp: startTime,
|
|
5095
|
+
duration
|
|
5096
|
+
};
|
|
5097
|
+
if (this.includeMemory && startMemory) {
|
|
5098
|
+
const currentMemory = process.memoryUsage();
|
|
5099
|
+
sample.memory = {
|
|
5100
|
+
heapUsed: currentMemory.heapUsed - startMemory.heapUsed,
|
|
5101
|
+
heapTotal: currentMemory.heapTotal,
|
|
5102
|
+
external: currentMemory.external
|
|
5103
|
+
};
|
|
5104
|
+
}
|
|
5105
|
+
if (this.includeStack && stack) {
|
|
5106
|
+
sample.stack = stack;
|
|
5107
|
+
}
|
|
5108
|
+
if (!this.profiles.has(name)) {
|
|
5109
|
+
this.profiles.set(name, []);
|
|
5110
|
+
}
|
|
5111
|
+
const samples = this.profiles.get(name);
|
|
5112
|
+
samples.push(sample);
|
|
5113
|
+
if (samples.length > this.maxSamples) {
|
|
5114
|
+
samples.shift();
|
|
5115
|
+
}
|
|
5116
|
+
}
|
|
5117
|
+
getReport() {
|
|
5118
|
+
const report = {};
|
|
5119
|
+
for (const [name, samples] of this.profiles.entries()) {
|
|
5120
|
+
if (samples.length === 0) {
|
|
5121
|
+
continue;
|
|
5122
|
+
}
|
|
5123
|
+
const durations = samples.map((s) => s.duration).sort((a, b) => a - b);
|
|
5124
|
+
const totalTime = durations.reduce((sum, d) => sum + d, 0);
|
|
5125
|
+
const stats = {
|
|
5126
|
+
calls: samples.length,
|
|
5127
|
+
totalTime,
|
|
5128
|
+
avgTime: totalTime / samples.length,
|
|
5129
|
+
minTime: durations[0],
|
|
5130
|
+
maxTime: durations[durations.length - 1],
|
|
5131
|
+
p50: this.percentile(durations, 0.5),
|
|
5132
|
+
p95: this.percentile(durations, 0.95),
|
|
5133
|
+
p99: this.percentile(durations, 0.99),
|
|
5134
|
+
samples
|
|
5135
|
+
};
|
|
5136
|
+
if (this.includeMemory) {
|
|
5137
|
+
const memorySamples = samples.filter((s) => s.memory).map((s) => s.memory.heapUsed);
|
|
5138
|
+
if (memorySamples.length > 0) {
|
|
5139
|
+
stats.memory = {
|
|
5140
|
+
avgHeapUsed: memorySamples.reduce((sum, m) => sum + m, 0) / memorySamples.length,
|
|
5141
|
+
maxHeapUsed: Math.max(...memorySamples),
|
|
5142
|
+
minHeapUsed: Math.min(...memorySamples)
|
|
5143
|
+
};
|
|
5144
|
+
}
|
|
5145
|
+
}
|
|
5146
|
+
report[name] = stats;
|
|
5147
|
+
}
|
|
5148
|
+
return report;
|
|
5149
|
+
}
|
|
5150
|
+
percentile(sorted, p) {
|
|
5151
|
+
const index = Math.ceil(sorted.length * p) - 1;
|
|
5152
|
+
return sorted[Math.max(0, index)];
|
|
5153
|
+
}
|
|
5154
|
+
reset(name) {
|
|
5155
|
+
if (name) {
|
|
5156
|
+
this.profiles.delete(name);
|
|
5157
|
+
} else {
|
|
5158
|
+
this.profiles.clear();
|
|
5159
|
+
}
|
|
5160
|
+
}
|
|
5161
|
+
export(path) {
|
|
5162
|
+
const report = this.getReport();
|
|
5163
|
+
console.log("Exporting profile report to:", path);
|
|
5164
|
+
console.log(JSON.stringify(report, null, 2));
|
|
5165
|
+
}
|
|
5166
|
+
};
|
|
5167
|
+
function createProfiler(options) {
|
|
5168
|
+
return new Profiler(options);
|
|
5169
|
+
}
|
|
5170
|
+
|
|
5171
|
+
// src/monitoring/alerts.ts
|
|
5172
|
+
var logger4 = createLogger("agentforge:core:monitoring:alerts", { level: "info" /* INFO */ });
|
|
5173
|
+
var AlertManager = class {
|
|
5174
|
+
constructor(options) {
|
|
5175
|
+
this.options = options;
|
|
5176
|
+
}
|
|
5177
|
+
lastAlertTime = /* @__PURE__ */ new Map();
|
|
5178
|
+
monitorTimer;
|
|
5179
|
+
running = false;
|
|
5180
|
+
start(metrics, interval = 6e4) {
|
|
5181
|
+
if (this.running || !metrics) {
|
|
5182
|
+
return;
|
|
5183
|
+
}
|
|
5184
|
+
this.running = true;
|
|
5185
|
+
this.monitorTimer = setInterval(() => {
|
|
5186
|
+
const currentMetrics = metrics();
|
|
5187
|
+
this.checkRules(currentMetrics);
|
|
5188
|
+
}, interval);
|
|
5189
|
+
}
|
|
5190
|
+
stop() {
|
|
5191
|
+
if (!this.running) {
|
|
5192
|
+
return;
|
|
5193
|
+
}
|
|
5194
|
+
this.running = false;
|
|
5195
|
+
if (this.monitorTimer) {
|
|
5196
|
+
clearInterval(this.monitorTimer);
|
|
5197
|
+
this.monitorTimer = void 0;
|
|
5198
|
+
}
|
|
5199
|
+
}
|
|
5200
|
+
async alert(alert) {
|
|
5201
|
+
const fullAlert = {
|
|
5202
|
+
...alert,
|
|
5203
|
+
timestamp: alert.timestamp || Date.now()
|
|
5204
|
+
};
|
|
5205
|
+
if (this.isThrottled(alert.name)) {
|
|
5206
|
+
return;
|
|
5207
|
+
}
|
|
5208
|
+
this.lastAlertTime.set(alert.name, Date.now());
|
|
5209
|
+
this.options.onAlert?.(fullAlert);
|
|
5210
|
+
logger4.warn("Alert triggered", {
|
|
5211
|
+
name: alert.name,
|
|
5212
|
+
severity: alert.severity,
|
|
5213
|
+
message: alert.message,
|
|
5214
|
+
data: alert.data
|
|
5215
|
+
});
|
|
5216
|
+
}
|
|
5217
|
+
checkRules(metrics) {
|
|
5218
|
+
if (!this.options.rules) {
|
|
5219
|
+
return;
|
|
5220
|
+
}
|
|
5221
|
+
for (const rule of this.options.rules) {
|
|
5222
|
+
try {
|
|
5223
|
+
if (rule.condition(metrics)) {
|
|
5224
|
+
this.alert({
|
|
5225
|
+
name: rule.name,
|
|
5226
|
+
severity: rule.severity,
|
|
5227
|
+
message: rule.message || `Alert triggered: ${rule.name}`,
|
|
5228
|
+
data: { metrics }
|
|
5229
|
+
});
|
|
5230
|
+
}
|
|
5231
|
+
} catch (error) {
|
|
5232
|
+
logger4.error("Rule check failed", {
|
|
5233
|
+
ruleName: rule.name,
|
|
5234
|
+
error: error instanceof Error ? error.message : String(error),
|
|
5235
|
+
stack: error instanceof Error ? error.stack : void 0
|
|
5236
|
+
});
|
|
5237
|
+
}
|
|
5238
|
+
}
|
|
5239
|
+
}
|
|
5240
|
+
isThrottled(name) {
|
|
5241
|
+
const rule = this.options.rules?.find((r) => r.name === name);
|
|
5242
|
+
if (!rule?.throttle) {
|
|
5243
|
+
return false;
|
|
5244
|
+
}
|
|
5245
|
+
const lastTime = this.lastAlertTime.get(name);
|
|
5246
|
+
if (!lastTime) {
|
|
5247
|
+
return false;
|
|
5248
|
+
}
|
|
5249
|
+
return Date.now() - lastTime < rule.throttle;
|
|
5250
|
+
}
|
|
5251
|
+
async sendToChannel(channelName, alert) {
|
|
5252
|
+
const channel = this.options.channels[channelName];
|
|
5253
|
+
if (!channel) {
|
|
5254
|
+
throw new Error(`Channel not found: ${channelName}`);
|
|
5255
|
+
}
|
|
5256
|
+
switch (channel.type) {
|
|
5257
|
+
case "email":
|
|
5258
|
+
logger4.info("Alert sent to email", {
|
|
5259
|
+
channel: channelName,
|
|
5260
|
+
to: channel.config.to,
|
|
5261
|
+
alert: { name: alert.name, severity: alert.severity, message: alert.message }
|
|
5262
|
+
});
|
|
5263
|
+
break;
|
|
5264
|
+
case "slack":
|
|
5265
|
+
logger4.info("Alert sent to Slack", {
|
|
5266
|
+
channel: channelName,
|
|
5267
|
+
webhookUrl: channel.config.webhookUrl,
|
|
5268
|
+
alert: { name: alert.name, severity: alert.severity, message: alert.message }
|
|
5269
|
+
});
|
|
5270
|
+
break;
|
|
5271
|
+
case "webhook":
|
|
5272
|
+
logger4.info("Alert sent to webhook", {
|
|
5273
|
+
channel: channelName,
|
|
5274
|
+
url: channel.config.url,
|
|
5275
|
+
alert: { name: alert.name, severity: alert.severity, message: alert.message }
|
|
5276
|
+
});
|
|
5277
|
+
break;
|
|
5278
|
+
default:
|
|
5279
|
+
logger4.info("Alert sent", {
|
|
5280
|
+
channel: channelName,
|
|
5281
|
+
channelType: channel.type,
|
|
5282
|
+
alert: { name: alert.name, severity: alert.severity, message: alert.message }
|
|
5283
|
+
});
|
|
5284
|
+
}
|
|
5285
|
+
}
|
|
5286
|
+
getAlertHistory(name, limit = 100) {
|
|
5287
|
+
return [];
|
|
5288
|
+
}
|
|
5289
|
+
clearAlertHistory(name) {
|
|
5290
|
+
if (name) {
|
|
5291
|
+
this.lastAlertTime.delete(name);
|
|
5292
|
+
} else {
|
|
5293
|
+
this.lastAlertTime.clear();
|
|
5294
|
+
}
|
|
5295
|
+
}
|
|
5296
|
+
};
|
|
5297
|
+
function createAlertManager(options) {
|
|
5298
|
+
return new AlertManager(options);
|
|
5299
|
+
}
|
|
5300
|
+
|
|
5301
|
+
// src/monitoring/audit.ts
|
|
5302
|
+
var AuditLogger = class {
|
|
5303
|
+
constructor(options = {}) {
|
|
5304
|
+
this.options = options;
|
|
5305
|
+
if (options.retention?.autoCleanup) {
|
|
5306
|
+
this.startCleanup();
|
|
5307
|
+
}
|
|
5308
|
+
}
|
|
5309
|
+
logs = [];
|
|
5310
|
+
cleanupTimer;
|
|
5311
|
+
async log(entry) {
|
|
5312
|
+
const fullEntry = {
|
|
5313
|
+
...entry,
|
|
5314
|
+
id: this.generateId(),
|
|
5315
|
+
timestamp: entry.timestamp || Date.now(),
|
|
5316
|
+
success: entry.success ?? true
|
|
5317
|
+
};
|
|
5318
|
+
const fields = this.options.fields || {};
|
|
5319
|
+
const filteredEntry = {
|
|
5320
|
+
id: fullEntry.id,
|
|
5321
|
+
userId: fields.userId !== false ? fullEntry.userId : "",
|
|
5322
|
+
action: fields.action !== false ? fullEntry.action : "",
|
|
5323
|
+
resource: fields.resource !== false ? fullEntry.resource : "",
|
|
5324
|
+
timestamp: fields.timestamp !== false ? fullEntry.timestamp : void 0
|
|
5325
|
+
};
|
|
5326
|
+
if (fields.input !== false && fullEntry.input) {
|
|
5327
|
+
filteredEntry.input = fullEntry.input;
|
|
5328
|
+
}
|
|
5329
|
+
if (fields.output !== false && fullEntry.output) {
|
|
5330
|
+
filteredEntry.output = fullEntry.output;
|
|
5331
|
+
}
|
|
5332
|
+
if (fullEntry.metadata) {
|
|
5333
|
+
filteredEntry.metadata = fullEntry.metadata;
|
|
5334
|
+
}
|
|
5335
|
+
if (fullEntry.error) {
|
|
5336
|
+
filteredEntry.error = fullEntry.error;
|
|
5337
|
+
filteredEntry.success = false;
|
|
5338
|
+
}
|
|
5339
|
+
this.logs.push(filteredEntry);
|
|
5340
|
+
this.options.onLog?.(filteredEntry);
|
|
5341
|
+
}
|
|
5342
|
+
async query(query = {}) {
|
|
5343
|
+
let results = [...this.logs];
|
|
5344
|
+
if (query.userId) {
|
|
5345
|
+
results = results.filter((log) => log.userId === query.userId);
|
|
5346
|
+
}
|
|
5347
|
+
if (query.action) {
|
|
5348
|
+
results = results.filter((log) => log.action === query.action);
|
|
5349
|
+
}
|
|
5350
|
+
if (query.resource) {
|
|
5351
|
+
results = results.filter((log) => log.resource === query.resource);
|
|
5352
|
+
}
|
|
5353
|
+
if (query.startDate) {
|
|
5354
|
+
const startTime = query.startDate.getTime();
|
|
5355
|
+
results = results.filter((log) => (log.timestamp || 0) >= startTime);
|
|
5356
|
+
}
|
|
5357
|
+
if (query.endDate) {
|
|
5358
|
+
const endTime = query.endDate.getTime();
|
|
5359
|
+
results = results.filter((log) => (log.timestamp || 0) <= endTime);
|
|
5360
|
+
}
|
|
5361
|
+
const offset = query.offset || 0;
|
|
5362
|
+
const limit = query.limit || 100;
|
|
5363
|
+
results = results.slice(offset, offset + limit);
|
|
5364
|
+
return results;
|
|
5365
|
+
}
|
|
5366
|
+
async export(path, options = {}) {
|
|
5367
|
+
const logs = await this.query({
|
|
5368
|
+
startDate: options.startDate,
|
|
5369
|
+
endDate: options.endDate
|
|
5370
|
+
});
|
|
5371
|
+
const format = options.format || "json";
|
|
5372
|
+
if (format === "json") {
|
|
5373
|
+
console.log(`Exporting ${logs.length} audit logs to ${path} (JSON)`);
|
|
5374
|
+
console.log(JSON.stringify(logs, null, 2));
|
|
5375
|
+
} else if (format === "csv") {
|
|
5376
|
+
console.log(`Exporting ${logs.length} audit logs to ${path} (CSV)`);
|
|
5377
|
+
const csv = this.convertToCSV(logs);
|
|
5378
|
+
console.log(csv);
|
|
5379
|
+
}
|
|
5380
|
+
}
|
|
5381
|
+
convertToCSV(logs) {
|
|
5382
|
+
if (logs.length === 0) {
|
|
5383
|
+
return "";
|
|
5384
|
+
}
|
|
5385
|
+
const headers = ["id", "userId", "action", "resource", "timestamp", "success"];
|
|
5386
|
+
const rows = logs.map((log) => [
|
|
5387
|
+
log.id,
|
|
5388
|
+
log.userId,
|
|
5389
|
+
log.action,
|
|
5390
|
+
log.resource,
|
|
5391
|
+
log.timestamp,
|
|
5392
|
+
log.success
|
|
5393
|
+
]);
|
|
5394
|
+
return [headers.join(","), ...rows.map((row) => row.join(","))].join("\n");
|
|
5395
|
+
}
|
|
5396
|
+
startCleanup() {
|
|
5397
|
+
const interval = 24 * 60 * 60 * 1e3;
|
|
5398
|
+
this.cleanupTimer = setInterval(() => {
|
|
5399
|
+
this.cleanup();
|
|
5400
|
+
}, interval);
|
|
5401
|
+
}
|
|
5402
|
+
cleanup() {
|
|
5403
|
+
if (!this.options.retention) {
|
|
5404
|
+
return;
|
|
5405
|
+
}
|
|
5406
|
+
const retentionMs = this.options.retention.days * 24 * 60 * 60 * 1e3;
|
|
5407
|
+
const cutoffTime = Date.now() - retentionMs;
|
|
5408
|
+
this.logs = this.logs.filter((log) => (log.timestamp || 0) >= cutoffTime);
|
|
5409
|
+
}
|
|
5410
|
+
generateId() {
|
|
5411
|
+
return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
5412
|
+
}
|
|
5413
|
+
stop() {
|
|
5414
|
+
if (this.cleanupTimer) {
|
|
5415
|
+
clearInterval(this.cleanupTimer);
|
|
5416
|
+
this.cleanupTimer = void 0;
|
|
5417
|
+
}
|
|
5418
|
+
}
|
|
5419
|
+
};
|
|
5420
|
+
function createAuditLogger(options) {
|
|
5421
|
+
return new AuditLogger(options);
|
|
5422
|
+
}
|
|
5423
|
+
|
|
4937
5424
|
// src/prompt-loader/index.ts
|
|
4938
5425
|
var import_fs = require("fs");
|
|
4939
5426
|
var import_path = require("path");
|
|
@@ -4998,10 +5485,13 @@ function loadPrompt(promptName, options = {}, promptsDir) {
|
|
|
4998
5485
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4999
5486
|
0 && (module.exports = {
|
|
5000
5487
|
AgentError,
|
|
5488
|
+
AlertManager,
|
|
5489
|
+
AuditLogger,
|
|
5001
5490
|
BatchProcessor,
|
|
5002
5491
|
CircuitBreaker,
|
|
5003
5492
|
ConnectionPool,
|
|
5004
5493
|
DatabasePool,
|
|
5494
|
+
HealthChecker,
|
|
5005
5495
|
HttpPool,
|
|
5006
5496
|
LogLevel,
|
|
5007
5497
|
ManagedTool,
|
|
@@ -5009,6 +5499,7 @@ function loadPrompt(promptName, options = {}, promptsDir) {
|
|
|
5009
5499
|
MetricType,
|
|
5010
5500
|
MiddlewareChain,
|
|
5011
5501
|
MissingDescriptionError,
|
|
5502
|
+
Profiler,
|
|
5012
5503
|
RegistryEvent,
|
|
5013
5504
|
TimeoutError,
|
|
5014
5505
|
ToolBuilder,
|
|
@@ -5032,7 +5523,9 @@ function loadPrompt(promptName, options = {}, promptsDir) {
|
|
|
5032
5523
|
composeWithOptions,
|
|
5033
5524
|
conditional,
|
|
5034
5525
|
configureLangSmith,
|
|
5526
|
+
createAlertManager,
|
|
5035
5527
|
createApprovalRequiredInterrupt,
|
|
5528
|
+
createAuditLogger,
|
|
5036
5529
|
createBatchProcessor,
|
|
5037
5530
|
createBinaryRouter,
|
|
5038
5531
|
createCircuitBreaker,
|
|
@@ -5042,6 +5535,7 @@ function loadPrompt(promptName, options = {}, promptsDir) {
|
|
|
5042
5535
|
createCustomInterrupt,
|
|
5043
5536
|
createDatabasePool,
|
|
5044
5537
|
createErrorReporter,
|
|
5538
|
+
createHealthChecker,
|
|
5045
5539
|
createHeartbeat,
|
|
5046
5540
|
createHttpPool,
|
|
5047
5541
|
createHumanRequestInterrupt,
|
|
@@ -5055,6 +5549,7 @@ function loadPrompt(promptName, options = {}, promptsDir) {
|
|
|
5055
5549
|
createMockTool,
|
|
5056
5550
|
createMultiRouter,
|
|
5057
5551
|
createParallelWorkflow,
|
|
5552
|
+
createProfiler,
|
|
5058
5553
|
createProgressTracker,
|
|
5059
5554
|
createSSEFormatter,
|
|
5060
5555
|
createSequentialWorkflow,
|