@agentforge/core 0.16.51 → 0.16.53
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 +360 -211
- package/dist/index.d.cts +21 -87
- package/dist/index.d.ts +21 -87
- package/dist/index.js +360 -211
- package/package.json +1 -1
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,
|
|
1179
|
+
function resolveExecutionMethod(tool, logger7) {
|
|
1180
1180
|
const executeFn = tool.invoke || tool.execute;
|
|
1181
1181
|
if (!executeFn) {
|
|
1182
1182
|
throw new Error(
|
|
@@ -1184,14 +1184,14 @@ function resolveExecutionMethod(tool, logger6) {
|
|
|
1184
1184
|
);
|
|
1185
1185
|
}
|
|
1186
1186
|
if (!tool.invoke && tool.execute) {
|
|
1187
|
-
|
|
1187
|
+
logger7.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,
|
|
1194
|
-
const executeFn = resolveExecutionMethod(tool,
|
|
1193
|
+
async function executeWithRetry(tool, input, policy, logger7) {
|
|
1194
|
+
const executeFn = resolveExecutionMethod(tool, logger7);
|
|
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:
|
|
1473
|
+
logger: logger7,
|
|
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) =>
|
|
1482
|
+
(err) => logger7.error("Cleanup failed", {
|
|
1483
1483
|
toolName: name,
|
|
1484
1484
|
error: getErrorMessage(err),
|
|
1485
1485
|
...err instanceof Error && err.stack ? { stack: err.stack } : {}
|
|
@@ -1932,8 +1932,10 @@ function createToolSimulator(config) {
|
|
|
1932
1932
|
};
|
|
1933
1933
|
}
|
|
1934
1934
|
|
|
1935
|
-
// src/langgraph/state.ts
|
|
1935
|
+
// src/langgraph/state-annotation.ts
|
|
1936
1936
|
import { Annotation } from "@langchain/langgraph";
|
|
1937
|
+
|
|
1938
|
+
// src/langgraph/state-shared.ts
|
|
1937
1939
|
function entriesOf(value) {
|
|
1938
1940
|
return Object.entries(value);
|
|
1939
1941
|
}
|
|
@@ -1952,6 +1954,8 @@ function setStateValue(target, key, value) {
|
|
|
1952
1954
|
function setStateDefinitionValue(target, key, value) {
|
|
1953
1955
|
target[key] = value;
|
|
1954
1956
|
}
|
|
1957
|
+
|
|
1958
|
+
// src/langgraph/state-annotation.ts
|
|
1955
1959
|
function createChannel(channelConfig) {
|
|
1956
1960
|
if (channelConfig.reducer) {
|
|
1957
1961
|
return Annotation({
|
|
@@ -1978,6 +1982,8 @@ function createStateAnnotation(config) {
|
|
|
1978
1982
|
}
|
|
1979
1983
|
return Annotation.Root(stateDefinition);
|
|
1980
1984
|
}
|
|
1985
|
+
|
|
1986
|
+
// src/langgraph/state-validation.ts
|
|
1981
1987
|
function validateState(state, config) {
|
|
1982
1988
|
const validated = {};
|
|
1983
1989
|
for (const [key, channelConfig] of entriesOf(config)) {
|
|
@@ -1995,6 +2001,8 @@ function validateState(state, config) {
|
|
|
1995
2001
|
}
|
|
1996
2002
|
return validated;
|
|
1997
2003
|
}
|
|
2004
|
+
|
|
2005
|
+
// src/langgraph/state-merge.ts
|
|
1998
2006
|
function mergeState(currentState, update, config) {
|
|
1999
2007
|
const merged = { ...currentState };
|
|
2000
2008
|
for (const key of keysOf(update)) {
|
|
@@ -2442,14 +2450,14 @@ var withLogging = (options) => {
|
|
|
2442
2450
|
onComplete,
|
|
2443
2451
|
onError
|
|
2444
2452
|
} = options;
|
|
2445
|
-
const
|
|
2453
|
+
const logger7 = providedLogger || createLogger(name, { level });
|
|
2446
2454
|
return (node) => {
|
|
2447
2455
|
return async (state) => {
|
|
2448
2456
|
const startTime = Date.now();
|
|
2449
2457
|
try {
|
|
2450
2458
|
if (logInput) {
|
|
2451
2459
|
const data = extractData ? extractData(state) : { state };
|
|
2452
|
-
|
|
2460
|
+
logger7.info("Node execution started", data);
|
|
2453
2461
|
}
|
|
2454
2462
|
if (onStart) {
|
|
2455
2463
|
onStart(state);
|
|
@@ -2459,9 +2467,9 @@ var withLogging = (options) => {
|
|
|
2459
2467
|
if (logOutput) {
|
|
2460
2468
|
const data = extractData ? extractData(result) : { result };
|
|
2461
2469
|
if (logDuration) {
|
|
2462
|
-
|
|
2470
|
+
logger7.info(`Node execution completed (${duration}ms)`, data);
|
|
2463
2471
|
} else {
|
|
2464
|
-
|
|
2472
|
+
logger7.info("Node execution completed", data);
|
|
2465
2473
|
}
|
|
2466
2474
|
}
|
|
2467
2475
|
if (onComplete) {
|
|
@@ -2472,7 +2480,7 @@ var withLogging = (options) => {
|
|
|
2472
2480
|
const duration = Date.now() - startTime;
|
|
2473
2481
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
2474
2482
|
if (logErrors) {
|
|
2475
|
-
|
|
2483
|
+
logger7.error(`Node execution failed (${duration}ms)`, {
|
|
2476
2484
|
error: err.message,
|
|
2477
2485
|
...err.stack ? { stack: err.stack } : {}
|
|
2478
2486
|
});
|
|
@@ -2594,7 +2602,7 @@ function withLogging2(options) {
|
|
|
2594
2602
|
function production(node, options) {
|
|
2595
2603
|
const {
|
|
2596
2604
|
nodeName,
|
|
2597
|
-
logger:
|
|
2605
|
+
logger: logger7,
|
|
2598
2606
|
enableMetrics = true,
|
|
2599
2607
|
enableTracing = true,
|
|
2600
2608
|
enableRetry = true,
|
|
@@ -2602,7 +2610,7 @@ function production(node, options) {
|
|
|
2602
2610
|
retryOptions = {},
|
|
2603
2611
|
errorOptions = {}
|
|
2604
2612
|
} = options;
|
|
2605
|
-
const actualLogger =
|
|
2613
|
+
const actualLogger = logger7 || createLogger(nodeName, { level: "info" /* INFO */ });
|
|
2606
2614
|
const middleware = [
|
|
2607
2615
|
withLogging2({
|
|
2608
2616
|
logger: actualLogger,
|
|
@@ -2657,8 +2665,8 @@ function production(node, options) {
|
|
|
2657
2665
|
|
|
2658
2666
|
// src/langgraph/middleware/preset-development.ts
|
|
2659
2667
|
function development(node, options) {
|
|
2660
|
-
const { nodeName, verbose = true, logger:
|
|
2661
|
-
const actualLogger =
|
|
2668
|
+
const { nodeName, verbose = true, logger: logger7 } = options;
|
|
2669
|
+
const actualLogger = logger7 || createLogger(nodeName, { level: "debug" /* DEBUG */ });
|
|
2662
2670
|
return withLogging2({
|
|
2663
2671
|
logger: actualLogger,
|
|
2664
2672
|
name: nodeName,
|
|
@@ -4065,37 +4073,9 @@ function createMessage(type, data, error) {
|
|
|
4065
4073
|
return { type, data, error };
|
|
4066
4074
|
}
|
|
4067
4075
|
|
|
4068
|
-
// src/resources/pool.ts
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
this.options = options;
|
|
4072
|
-
const poolConfig = options.pool || {};
|
|
4073
|
-
const min = poolConfig.min || 0;
|
|
4074
|
-
if (min > 0) {
|
|
4075
|
-
this.initialize(min).catch((error) => {
|
|
4076
|
-
console.error("Failed to initialize pool:", error);
|
|
4077
|
-
});
|
|
4078
|
-
}
|
|
4079
|
-
const evictionInterval = poolConfig.evictionInterval || 6e4;
|
|
4080
|
-
this.evictionTimer = setInterval(() => {
|
|
4081
|
-
this.evictIdleConnections().catch((error) => {
|
|
4082
|
-
console.error("Failed to evict idle connections:", error);
|
|
4083
|
-
});
|
|
4084
|
-
}, evictionInterval);
|
|
4085
|
-
const healthCheck = options.healthCheck || {};
|
|
4086
|
-
if (healthCheck.enabled) {
|
|
4087
|
-
const interval = healthCheck.interval || 3e4;
|
|
4088
|
-
this.healthCheckTimer = setInterval(() => {
|
|
4089
|
-
this.performHealthChecks().catch((error) => {
|
|
4090
|
-
console.error("Health check failed:", error);
|
|
4091
|
-
options.onHealthCheckFail?.(error);
|
|
4092
|
-
});
|
|
4093
|
-
}, interval);
|
|
4094
|
-
}
|
|
4095
|
-
}
|
|
4096
|
-
connections = [];
|
|
4097
|
-
pending = [];
|
|
4098
|
-
stats = {
|
|
4076
|
+
// src/resources/pool-runtime.ts
|
|
4077
|
+
function createInitialPoolStats() {
|
|
4078
|
+
return {
|
|
4099
4079
|
size: 0,
|
|
4100
4080
|
available: 0,
|
|
4101
4081
|
pending: 0,
|
|
@@ -4105,178 +4085,347 @@ var ConnectionPool = class {
|
|
|
4105
4085
|
healthChecksPassed: 0,
|
|
4106
4086
|
healthChecksFailed: 0
|
|
4107
4087
|
};
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
|
|
4111
|
-
async
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
|
|
4120
|
-
|
|
4121
|
-
|
|
4122
|
-
|
|
4123
|
-
|
|
4124
|
-
|
|
4125
|
-
this.stats.available++;
|
|
4126
|
-
return connection;
|
|
4127
|
-
}
|
|
4128
|
-
async destroyConnection(pooled) {
|
|
4129
|
-
const index = this.connections.indexOf(pooled);
|
|
4130
|
-
if (index !== -1) {
|
|
4131
|
-
this.connections.splice(index, 1);
|
|
4132
|
-
}
|
|
4133
|
-
if (this.options.destroyer) {
|
|
4134
|
-
await this.options.destroyer(pooled.connection);
|
|
4135
|
-
}
|
|
4136
|
-
this.options.onDestroy?.(pooled.connection);
|
|
4137
|
-
this.stats.destroyed++;
|
|
4138
|
-
this.stats.size--;
|
|
4139
|
-
if (!pooled.inUse) {
|
|
4140
|
-
this.stats.available--;
|
|
4088
|
+
}
|
|
4089
|
+
async function initializeConnections(runtime, count) {
|
|
4090
|
+
runtime.creating += count;
|
|
4091
|
+
const promises = Array.from({ length: count }, async () => {
|
|
4092
|
+
try {
|
|
4093
|
+
const connection = await createConnection(runtime);
|
|
4094
|
+
const pooled = runtime.connections.find((item) => item.connection === connection);
|
|
4095
|
+
if (!pooled) {
|
|
4096
|
+
throw new Error("Newly created connection not found in pool");
|
|
4097
|
+
}
|
|
4098
|
+
if (runtime.draining) {
|
|
4099
|
+
await destroyConnection(runtime, pooled);
|
|
4100
|
+
return;
|
|
4101
|
+
}
|
|
4102
|
+
assignConnectionToPendingAcquire(runtime, connection);
|
|
4103
|
+
} finally {
|
|
4104
|
+
runtime.creating--;
|
|
4141
4105
|
}
|
|
4106
|
+
});
|
|
4107
|
+
await Promise.all(promises);
|
|
4108
|
+
}
|
|
4109
|
+
function assignConnectionToPendingAcquire(runtime, connection) {
|
|
4110
|
+
const pending = runtime.pending.shift();
|
|
4111
|
+
if (!pending) {
|
|
4112
|
+
return;
|
|
4142
4113
|
}
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
4151
|
-
|
|
4152
|
-
|
|
4153
|
-
|
|
4154
|
-
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
|
|
4160
|
-
|
|
4114
|
+
const pooled = runtime.connections.find((item) => item.connection === connection);
|
|
4115
|
+
if (!pooled) {
|
|
4116
|
+
runtime.pending.unshift(pending);
|
|
4117
|
+
return;
|
|
4118
|
+
}
|
|
4119
|
+
clearTimeout(pending.timeout);
|
|
4120
|
+
runtime.stats.pending--;
|
|
4121
|
+
pooled.inUse = true;
|
|
4122
|
+
pooled.lastUsedAt = Date.now();
|
|
4123
|
+
runtime.stats.available--;
|
|
4124
|
+
runtime.stats.acquired++;
|
|
4125
|
+
runtime.options.onAcquire?.(connection);
|
|
4126
|
+
pending.resolve(connection);
|
|
4127
|
+
}
|
|
4128
|
+
async function createConnection(runtime) {
|
|
4129
|
+
const connection = await runtime.options.factory();
|
|
4130
|
+
const now = Date.now();
|
|
4131
|
+
runtime.connections.push({
|
|
4132
|
+
connection,
|
|
4133
|
+
createdAt: now,
|
|
4134
|
+
lastUsedAt: now,
|
|
4135
|
+
inUse: false
|
|
4136
|
+
});
|
|
4137
|
+
runtime.stats.created++;
|
|
4138
|
+
runtime.stats.size++;
|
|
4139
|
+
runtime.stats.available++;
|
|
4140
|
+
return connection;
|
|
4141
|
+
}
|
|
4142
|
+
async function destroyConnection(runtime, pooled) {
|
|
4143
|
+
const index = runtime.connections.indexOf(pooled);
|
|
4144
|
+
if (index !== -1) {
|
|
4145
|
+
runtime.connections.splice(index, 1);
|
|
4146
|
+
}
|
|
4147
|
+
if (runtime.options.destroyer) {
|
|
4148
|
+
await runtime.options.destroyer(pooled.connection);
|
|
4149
|
+
}
|
|
4150
|
+
runtime.options.onDestroy?.(pooled.connection);
|
|
4151
|
+
runtime.stats.destroyed++;
|
|
4152
|
+
runtime.stats.size--;
|
|
4153
|
+
if (pooled.inUse) {
|
|
4154
|
+
runtime.stats.acquired--;
|
|
4155
|
+
} else {
|
|
4156
|
+
runtime.stats.available--;
|
|
4157
|
+
}
|
|
4158
|
+
}
|
|
4159
|
+
function getPoolConfig(runtime) {
|
|
4160
|
+
return runtime.options.pool || {};
|
|
4161
|
+
}
|
|
4162
|
+
function getHealthCheckConfig(runtime) {
|
|
4163
|
+
return runtime.options.healthCheck || {};
|
|
4164
|
+
}
|
|
4165
|
+
function clonePoolStats(runtime) {
|
|
4166
|
+
return { ...runtime.stats };
|
|
4167
|
+
}
|
|
4168
|
+
|
|
4169
|
+
// src/resources/pool-acquisition.ts
|
|
4170
|
+
async function acquireConnection(runtime) {
|
|
4171
|
+
if (runtime.draining) {
|
|
4172
|
+
throw new Error("Pool is draining");
|
|
4173
|
+
}
|
|
4174
|
+
const available = runtime.connections.find((connection) => !connection.inUse);
|
|
4175
|
+
if (available) {
|
|
4176
|
+
available.inUse = true;
|
|
4177
|
+
available.lastUsedAt = Date.now();
|
|
4178
|
+
runtime.stats.available--;
|
|
4179
|
+
runtime.stats.acquired++;
|
|
4180
|
+
runtime.options.onAcquire?.(available.connection);
|
|
4181
|
+
return available.connection;
|
|
4182
|
+
}
|
|
4183
|
+
const poolConfig = getPoolConfig(runtime);
|
|
4184
|
+
const max = poolConfig.max || 10;
|
|
4185
|
+
if (runtime.connections.length + runtime.creating < max) {
|
|
4186
|
+
runtime.creating++;
|
|
4187
|
+
try {
|
|
4188
|
+
const connection = await createConnection(runtime);
|
|
4189
|
+
const pooled = runtime.connections.find((item) => item.connection === connection);
|
|
4190
|
+
if (!pooled) {
|
|
4191
|
+
throw new Error("Newly created connection not found in pool");
|
|
4192
|
+
}
|
|
4193
|
+
if (runtime.draining) {
|
|
4194
|
+
await destroyConnection(runtime, pooled);
|
|
4195
|
+
throw new Error("Pool is draining");
|
|
4196
|
+
}
|
|
4161
4197
|
pooled.inUse = true;
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4198
|
+
pooled.lastUsedAt = Date.now();
|
|
4199
|
+
runtime.stats.available--;
|
|
4200
|
+
runtime.stats.acquired++;
|
|
4201
|
+
runtime.options.onAcquire?.(connection);
|
|
4165
4202
|
return connection;
|
|
4203
|
+
} finally {
|
|
4204
|
+
runtime.creating--;
|
|
4166
4205
|
}
|
|
4167
|
-
return new Promise((resolve, reject) => {
|
|
4168
|
-
const timeout2 = poolConfig.acquireTimeout || 3e4;
|
|
4169
|
-
const timer = setTimeout(() => {
|
|
4170
|
-
const index = this.pending.findIndex((p) => p.resolve === resolve);
|
|
4171
|
-
if (index !== -1) {
|
|
4172
|
-
this.pending.splice(index, 1);
|
|
4173
|
-
this.stats.pending--;
|
|
4174
|
-
}
|
|
4175
|
-
reject(new Error("Acquire timeout"));
|
|
4176
|
-
}, timeout2);
|
|
4177
|
-
this.pending.push({ resolve, reject, timeout: timer });
|
|
4178
|
-
this.stats.pending++;
|
|
4179
|
-
});
|
|
4180
4206
|
}
|
|
4181
|
-
|
|
4182
|
-
const
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
|
|
4207
|
+
return new Promise((resolve, reject) => {
|
|
4208
|
+
const timeout2 = poolConfig.acquireTimeout || 3e4;
|
|
4209
|
+
const timer = setTimeout(() => {
|
|
4210
|
+
const index = runtime.pending.findIndex((pending) => pending.resolve === resolve);
|
|
4211
|
+
if (index !== -1) {
|
|
4212
|
+
runtime.pending.splice(index, 1);
|
|
4213
|
+
runtime.stats.pending--;
|
|
4214
|
+
}
|
|
4215
|
+
reject(new Error("Acquire timeout"));
|
|
4216
|
+
}, timeout2);
|
|
4217
|
+
runtime.pending.push({ resolve, reject, timeout: timer });
|
|
4218
|
+
runtime.stats.pending++;
|
|
4219
|
+
});
|
|
4220
|
+
}
|
|
4221
|
+
async function releaseConnection(runtime, connection) {
|
|
4222
|
+
const pooled = runtime.connections.find((item) => item.connection === connection);
|
|
4223
|
+
if (!pooled) {
|
|
4224
|
+
throw new Error("Connection not found in pool");
|
|
4225
|
+
}
|
|
4226
|
+
if (!pooled.inUse) {
|
|
4227
|
+
throw new Error("Connection is not in use");
|
|
4228
|
+
}
|
|
4229
|
+
pooled.inUse = false;
|
|
4230
|
+
pooled.lastUsedAt = Date.now();
|
|
4231
|
+
runtime.stats.available++;
|
|
4232
|
+
runtime.stats.acquired--;
|
|
4233
|
+
runtime.options.onRelease?.(connection);
|
|
4234
|
+
const pending = runtime.pending.shift();
|
|
4235
|
+
if (!pending) {
|
|
4236
|
+
return;
|
|
4237
|
+
}
|
|
4238
|
+
clearTimeout(pending.timeout);
|
|
4239
|
+
runtime.stats.pending--;
|
|
4240
|
+
pooled.inUse = true;
|
|
4241
|
+
pooled.lastUsedAt = Date.now();
|
|
4242
|
+
runtime.stats.available--;
|
|
4243
|
+
runtime.stats.acquired++;
|
|
4244
|
+
runtime.options.onAcquire?.(connection);
|
|
4245
|
+
pending.resolve(connection);
|
|
4246
|
+
}
|
|
4247
|
+
|
|
4248
|
+
// src/resources/pool-eviction.ts
|
|
4249
|
+
function selectIdleConnectionsForEviction(runtime, idleTimeout, min, now) {
|
|
4250
|
+
const idleConnections = runtime.connections.filter(
|
|
4251
|
+
(connection) => !connection.inUse && now - connection.lastUsedAt > idleTimeout
|
|
4252
|
+
);
|
|
4253
|
+
const evictableCount = Math.max(0, runtime.connections.length - min);
|
|
4254
|
+
return idleConnections.slice(0, evictableCount);
|
|
4255
|
+
}
|
|
4256
|
+
async function evictIdleConnections(runtime) {
|
|
4257
|
+
const poolConfig = getPoolConfig(runtime);
|
|
4258
|
+
const idleTimeout = poolConfig.idleTimeout || 6e4;
|
|
4259
|
+
const min = poolConfig.min || 0;
|
|
4260
|
+
const now = Date.now();
|
|
4261
|
+
const toEvict = selectIdleConnectionsForEviction(runtime, idleTimeout, min, now);
|
|
4262
|
+
for (const pooled of toEvict) {
|
|
4263
|
+
if (!runtime.connections.includes(pooled)) {
|
|
4264
|
+
continue;
|
|
4265
|
+
}
|
|
4266
|
+
if (pooled.inUse) {
|
|
4267
|
+
continue;
|
|
4268
|
+
}
|
|
4269
|
+
if (runtime.connections.length <= min) {
|
|
4270
|
+
break;
|
|
4271
|
+
}
|
|
4272
|
+
if (Date.now() - pooled.lastUsedAt <= idleTimeout) {
|
|
4273
|
+
continue;
|
|
4203
4274
|
}
|
|
4275
|
+
await destroyConnection(runtime, pooled);
|
|
4204
4276
|
}
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4277
|
+
}
|
|
4278
|
+
|
|
4279
|
+
// src/resources/pool-health.ts
|
|
4280
|
+
async function runHealthCheckWithTimeout(runtime, connection, timeout2) {
|
|
4281
|
+
let timer;
|
|
4282
|
+
try {
|
|
4283
|
+
return await Promise.race([
|
|
4284
|
+
runtime.options.validator(connection),
|
|
4285
|
+
new Promise((_, reject) => {
|
|
4286
|
+
timer = setTimeout(() => reject(new Error("Health check timeout")), timeout2);
|
|
4287
|
+
})
|
|
4288
|
+
]);
|
|
4289
|
+
} finally {
|
|
4290
|
+
if (timer) {
|
|
4291
|
+
clearTimeout(timer);
|
|
4215
4292
|
}
|
|
4216
4293
|
}
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4294
|
+
}
|
|
4295
|
+
async function performHealthChecks(runtime) {
|
|
4296
|
+
if (!runtime.options.validator) {
|
|
4297
|
+
return;
|
|
4298
|
+
}
|
|
4299
|
+
const healthCheck = getHealthCheckConfig(runtime);
|
|
4300
|
+
const timeout2 = healthCheck.timeout || 5e3;
|
|
4301
|
+
const retries = healthCheck.retries || 1;
|
|
4302
|
+
for (const pooled of [...runtime.connections]) {
|
|
4303
|
+
if (pooled.inUse) {
|
|
4304
|
+
continue;
|
|
4220
4305
|
}
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
let healthy = false;
|
|
4229
|
-
for (let i = 0; i < retries; i++) {
|
|
4230
|
-
try {
|
|
4231
|
-
const result = await Promise.race([
|
|
4232
|
-
this.options.validator(pooled.connection),
|
|
4233
|
-
new Promise(
|
|
4234
|
-
(_, reject) => setTimeout(() => reject(new Error("Health check timeout")), timeout2)
|
|
4235
|
-
)
|
|
4236
|
-
]);
|
|
4237
|
-
if (result) {
|
|
4238
|
-
healthy = true;
|
|
4239
|
-
break;
|
|
4240
|
-
}
|
|
4241
|
-
} catch (error) {
|
|
4306
|
+
let healthy = false;
|
|
4307
|
+
for (let attempt = 0; attempt < retries; attempt++) {
|
|
4308
|
+
try {
|
|
4309
|
+
const result = await runHealthCheckWithTimeout(runtime, pooled.connection, timeout2);
|
|
4310
|
+
if (result) {
|
|
4311
|
+
healthy = true;
|
|
4312
|
+
break;
|
|
4242
4313
|
}
|
|
4243
|
-
}
|
|
4244
|
-
if (healthy) {
|
|
4245
|
-
this.stats.healthChecksPassed++;
|
|
4246
|
-
} else {
|
|
4247
|
-
this.stats.healthChecksFailed++;
|
|
4248
|
-
await this.destroyConnection(pooled);
|
|
4314
|
+
} catch {
|
|
4249
4315
|
}
|
|
4250
4316
|
}
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
for (const pending of this.pending) {
|
|
4255
|
-
clearTimeout(pending.timeout);
|
|
4256
|
-
pending.reject(new Error("Pool is draining"));
|
|
4317
|
+
if (healthy) {
|
|
4318
|
+
runtime.stats.healthChecksPassed++;
|
|
4319
|
+
continue;
|
|
4257
4320
|
}
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
while (this.connections.some((c) => c.inUse)) {
|
|
4261
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
4321
|
+
if (!runtime.connections.includes(pooled) || pooled.inUse) {
|
|
4322
|
+
continue;
|
|
4262
4323
|
}
|
|
4324
|
+
runtime.stats.healthChecksFailed++;
|
|
4325
|
+
await destroyConnection(runtime, pooled);
|
|
4263
4326
|
}
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4327
|
+
}
|
|
4328
|
+
|
|
4329
|
+
// src/resources/pool-lifecycle.ts
|
|
4330
|
+
function rejectPendingAcquisitions(runtime, message) {
|
|
4331
|
+
for (const pending of runtime.pending) {
|
|
4332
|
+
clearTimeout(pending.timeout);
|
|
4333
|
+
pending.reject(new Error(message));
|
|
4334
|
+
}
|
|
4335
|
+
runtime.pending = [];
|
|
4336
|
+
runtime.stats.pending = 0;
|
|
4337
|
+
}
|
|
4338
|
+
async function drainPool(runtime) {
|
|
4339
|
+
runtime.draining = true;
|
|
4340
|
+
rejectPendingAcquisitions(runtime, "Pool is draining");
|
|
4341
|
+
while (runtime.connections.some((connection) => connection.inUse)) {
|
|
4342
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
4343
|
+
}
|
|
4344
|
+
}
|
|
4345
|
+
async function clearPool(runtime) {
|
|
4346
|
+
runtime.draining = true;
|
|
4347
|
+
rejectPendingAcquisitions(runtime, "Pool is draining");
|
|
4348
|
+
if (runtime.evictionTimer) {
|
|
4349
|
+
clearInterval(runtime.evictionTimer);
|
|
4350
|
+
runtime.evictionTimer = void 0;
|
|
4351
|
+
}
|
|
4352
|
+
if (runtime.healthCheckTimer) {
|
|
4353
|
+
clearInterval(runtime.healthCheckTimer);
|
|
4354
|
+
runtime.healthCheckTimer = void 0;
|
|
4355
|
+
}
|
|
4356
|
+
const connections = [...runtime.connections];
|
|
4357
|
+
for (const pooled of connections) {
|
|
4358
|
+
await destroyConnection(runtime, pooled);
|
|
4359
|
+
}
|
|
4360
|
+
}
|
|
4361
|
+
|
|
4362
|
+
// src/resources/pool.ts
|
|
4363
|
+
var logger4 = createLogger("agentforge:core:resources:pool");
|
|
4364
|
+
function toErrorPayload(error) {
|
|
4365
|
+
if (error instanceof Error) {
|
|
4366
|
+
return {
|
|
4367
|
+
error: error.message,
|
|
4368
|
+
stack: error.stack
|
|
4369
|
+
};
|
|
4370
|
+
}
|
|
4371
|
+
return { error: String(error) };
|
|
4372
|
+
}
|
|
4373
|
+
function toError3(error) {
|
|
4374
|
+
if (error instanceof Error) {
|
|
4375
|
+
return error;
|
|
4376
|
+
}
|
|
4377
|
+
return new Error(String(error));
|
|
4378
|
+
}
|
|
4379
|
+
var ConnectionPool = class {
|
|
4380
|
+
runtime;
|
|
4381
|
+
constructor(options) {
|
|
4382
|
+
this.runtime = {
|
|
4383
|
+
connections: [],
|
|
4384
|
+
pending: [],
|
|
4385
|
+
stats: createInitialPoolStats(),
|
|
4386
|
+
draining: false,
|
|
4387
|
+
creating: 0,
|
|
4388
|
+
options
|
|
4389
|
+
};
|
|
4390
|
+
const poolConfig = getPoolConfig(this.runtime);
|
|
4391
|
+
const min = poolConfig.min || 0;
|
|
4392
|
+
if (min > 0) {
|
|
4393
|
+
initializeConnections(this.runtime, min).catch((error) => {
|
|
4394
|
+
logger4.error("Failed to initialize pool", toErrorPayload(error));
|
|
4395
|
+
});
|
|
4272
4396
|
}
|
|
4273
|
-
const
|
|
4274
|
-
|
|
4275
|
-
|
|
4397
|
+
const evictionInterval = poolConfig.evictionInterval || 6e4;
|
|
4398
|
+
this.runtime.evictionTimer = setInterval(() => {
|
|
4399
|
+
evictIdleConnections(this.runtime).catch((error) => {
|
|
4400
|
+
logger4.error("Failed to evict idle connections", toErrorPayload(error));
|
|
4401
|
+
});
|
|
4402
|
+
}, evictionInterval);
|
|
4403
|
+
const healthCheck = getHealthCheckConfig(this.runtime);
|
|
4404
|
+
if (healthCheck.enabled) {
|
|
4405
|
+
const interval = healthCheck.interval || 3e4;
|
|
4406
|
+
this.runtime.healthCheckTimer = setInterval(() => {
|
|
4407
|
+
performHealthChecks(this.runtime).catch((error) => {
|
|
4408
|
+
const normalizedError = toError3(error);
|
|
4409
|
+
logger4.error("Health check failed", toErrorPayload(normalizedError));
|
|
4410
|
+
options.onHealthCheckFail?.(normalizedError);
|
|
4411
|
+
});
|
|
4412
|
+
}, interval);
|
|
4276
4413
|
}
|
|
4277
4414
|
}
|
|
4415
|
+
async acquire() {
|
|
4416
|
+
return acquireConnection(this.runtime);
|
|
4417
|
+
}
|
|
4418
|
+
async release(connection) {
|
|
4419
|
+
return releaseConnection(this.runtime, connection);
|
|
4420
|
+
}
|
|
4421
|
+
async drain() {
|
|
4422
|
+
return drainPool(this.runtime);
|
|
4423
|
+
}
|
|
4424
|
+
async clear() {
|
|
4425
|
+
return clearPool(this.runtime);
|
|
4426
|
+
}
|
|
4278
4427
|
getStats() {
|
|
4279
|
-
return
|
|
4428
|
+
return clonePoolStats(this.runtime);
|
|
4280
4429
|
}
|
|
4281
4430
|
};
|
|
4282
4431
|
function createConnectionPool(options) {
|
|
@@ -4809,7 +4958,7 @@ function createCircuitBreaker(options) {
|
|
|
4809
4958
|
}
|
|
4810
4959
|
|
|
4811
4960
|
// src/monitoring/health.ts
|
|
4812
|
-
var
|
|
4961
|
+
var logger5 = createLogger("agentforge:core:monitoring:health", { level: "info" /* INFO */ });
|
|
4813
4962
|
var HealthChecker = class {
|
|
4814
4963
|
constructor(options) {
|
|
4815
4964
|
this.options = options;
|
|
@@ -4825,14 +4974,14 @@ var HealthChecker = class {
|
|
|
4825
4974
|
this.running = true;
|
|
4826
4975
|
const interval = this.options.interval || 3e4;
|
|
4827
4976
|
this.runChecks().catch((error) => {
|
|
4828
|
-
|
|
4977
|
+
logger5.error("Initial health check failed", {
|
|
4829
4978
|
error: error instanceof Error ? error.message : String(error),
|
|
4830
4979
|
...error instanceof Error && error.stack ? { stack: error.stack } : {}
|
|
4831
4980
|
});
|
|
4832
4981
|
});
|
|
4833
4982
|
this.checkTimer = setInterval(() => {
|
|
4834
4983
|
this.runChecks().catch((error) => {
|
|
4835
|
-
|
|
4984
|
+
logger5.error("Health check failed", {
|
|
4836
4985
|
error: error instanceof Error ? error.message : String(error),
|
|
4837
4986
|
...error instanceof Error && error.stack ? { stack: error.stack } : {}
|
|
4838
4987
|
});
|
|
@@ -5042,7 +5191,7 @@ function createProfiler(options) {
|
|
|
5042
5191
|
}
|
|
5043
5192
|
|
|
5044
5193
|
// src/monitoring/alerts.ts
|
|
5045
|
-
var
|
|
5194
|
+
var logger6 = createLogger("agentforge:core:monitoring:alerts", { level: "info" /* INFO */ });
|
|
5046
5195
|
function toAlertSummary(alert) {
|
|
5047
5196
|
return {
|
|
5048
5197
|
name: alert.name,
|
|
@@ -5094,7 +5243,7 @@ var AlertManager = class {
|
|
|
5094
5243
|
const currentMetrics = metrics();
|
|
5095
5244
|
this.checkRules(currentMetrics);
|
|
5096
5245
|
} catch (error) {
|
|
5097
|
-
|
|
5246
|
+
logger6.error("Metrics collection failed", toMetricsProviderErrorPayload(error));
|
|
5098
5247
|
}
|
|
5099
5248
|
}, interval);
|
|
5100
5249
|
}
|
|
@@ -5120,9 +5269,9 @@ var AlertManager = class {
|
|
|
5120
5269
|
try {
|
|
5121
5270
|
await this.options.onAlert?.(fullAlert);
|
|
5122
5271
|
} catch (error) {
|
|
5123
|
-
|
|
5272
|
+
logger6.error("Alert callback failed", toAlertCallbackErrorPayload(error));
|
|
5124
5273
|
}
|
|
5125
|
-
|
|
5274
|
+
logger6.warn("Alert triggered", {
|
|
5126
5275
|
name: alert.name,
|
|
5127
5276
|
severity: alert.severity,
|
|
5128
5277
|
message: alert.message,
|
|
@@ -5142,11 +5291,11 @@ var AlertManager = class {
|
|
|
5142
5291
|
message: rule.message || `Alert triggered: ${rule.name}`,
|
|
5143
5292
|
data: { metrics }
|
|
5144
5293
|
}).catch((error) => {
|
|
5145
|
-
|
|
5294
|
+
logger6.error("Alert dispatch failed", toAlertDispatchErrorPayload(rule.name, error));
|
|
5146
5295
|
});
|
|
5147
5296
|
}
|
|
5148
5297
|
} catch (error) {
|
|
5149
|
-
|
|
5298
|
+
logger6.error("Rule check failed", toRuleErrorPayload(rule.name, error));
|
|
5150
5299
|
}
|
|
5151
5300
|
}
|
|
5152
5301
|
}
|
|
@@ -5168,28 +5317,28 @@ var AlertManager = class {
|
|
|
5168
5317
|
}
|
|
5169
5318
|
switch (channel.type) {
|
|
5170
5319
|
case "email":
|
|
5171
|
-
|
|
5320
|
+
logger6.info("Alert sent to email", {
|
|
5172
5321
|
channel: channelName,
|
|
5173
5322
|
to: channel.config.to,
|
|
5174
5323
|
alert: toAlertSummary(alert)
|
|
5175
5324
|
});
|
|
5176
5325
|
break;
|
|
5177
5326
|
case "slack":
|
|
5178
|
-
|
|
5327
|
+
logger6.info("Alert sent to Slack", {
|
|
5179
5328
|
channel: channelName,
|
|
5180
5329
|
webhookUrl: channel.config.webhookUrl,
|
|
5181
5330
|
alert: toAlertSummary(alert)
|
|
5182
5331
|
});
|
|
5183
5332
|
break;
|
|
5184
5333
|
case "webhook":
|
|
5185
|
-
|
|
5334
|
+
logger6.info("Alert sent to webhook", {
|
|
5186
5335
|
channel: channelName,
|
|
5187
5336
|
url: channel.config.url,
|
|
5188
5337
|
alert: toAlertSummary(alert)
|
|
5189
5338
|
});
|
|
5190
5339
|
break;
|
|
5191
5340
|
default:
|
|
5192
|
-
|
|
5341
|
+
logger6.info("Alert sent", {
|
|
5193
5342
|
channel: channelName,
|
|
5194
5343
|
channelType: channel.type,
|
|
5195
5344
|
alert: toAlertSummary(alert)
|