@defai.digital/automatosx 12.5.2 → 12.5.3

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/README.md CHANGED
@@ -12,7 +12,7 @@
12
12
  [![Ubuntu](https://img.shields.io/badge/Ubuntu-24.04-blue.svg)](https://ubuntu.com)
13
13
  [![License](https://img.shields.io/badge/license-Apache--2.0-yellow.svg)](LICENSE)
14
14
 
15
- **Status**: ✅ **Production Ready** | v12.5.2 | MCP Hybrid Framing & Multi-Protocol Support
15
+ **Status**: ✅ **Production Ready** | v12.5.3 | Performance & Reliability Improvements
16
16
 
17
17
  > 🎯 **What AutomatosX Does**: Adds 20+ specialized agents, persistent memory, workflow automation, and 80% cost savings to Claude Code/Codex - **without changing how you work**.
18
18
 
package/dist/index.js CHANGED
@@ -401,7 +401,9 @@ var init_validation_limits = __esm({
401
401
  /** Quick CLI command timeout (3 seconds) */
402
402
  QUICK_COMMAND: 3e3,
403
403
  /** CLI version check timeout (10 seconds) */
404
- VERSION_CHECK: 1e4
404
+ VERSION_CHECK: 1e4,
405
+ /** MCP agent execution timeout (5 minutes) */
406
+ MCP_AGENT_EXECUTION: 3e5
405
407
  };
406
408
  DATABASE = {
407
409
  /** SQLite busy timeout in milliseconds */
@@ -4975,6 +4977,37 @@ var init_flags = __esm({
4975
4977
  }
4976
4978
  });
4977
4979
 
4980
+ // src/shared/errors/error-wrapper.ts
4981
+ function getErrorMessage(error) {
4982
+ if (error instanceof Error) {
4983
+ return error.message;
4984
+ }
4985
+ if (typeof error === "string") {
4986
+ return error;
4987
+ }
4988
+ if (error && typeof error === "object") {
4989
+ const obj = error;
4990
+ if (obj.error && typeof obj.error === "object") {
4991
+ const nested = obj.error;
4992
+ if (typeof nested.message === "string") {
4993
+ return nested.message;
4994
+ }
4995
+ }
4996
+ if (typeof obj.error === "string") {
4997
+ return obj.error;
4998
+ }
4999
+ if ("message" in obj) {
5000
+ return String(obj.message);
5001
+ }
5002
+ }
5003
+ return String(error);
5004
+ }
5005
+ var init_error_wrapper = __esm({
5006
+ "src/shared/errors/error-wrapper.ts"() {
5007
+ init_esm_shims();
5008
+ }
5009
+ });
5010
+
4978
5011
  // src/providers/fallback-decision.ts
4979
5012
  function decideFallback(error, providerName) {
4980
5013
  const errorMessage = getErrorMessage(error).toLowerCase();
@@ -5045,30 +5078,6 @@ function decideFallback(error, providerName) {
5045
5078
  severity: "error"
5046
5079
  };
5047
5080
  }
5048
- function getErrorMessage(error) {
5049
- if (error instanceof Error) {
5050
- return error.message;
5051
- }
5052
- if (typeof error === "string") {
5053
- return error;
5054
- }
5055
- if (error && typeof error === "object") {
5056
- const obj = error;
5057
- if (typeof obj.message === "string") {
5058
- return obj.message;
5059
- }
5060
- if (typeof obj.error === "string") {
5061
- return obj.error;
5062
- }
5063
- if (obj.error && typeof obj.error === "object") {
5064
- const innerError = obj.error;
5065
- if (typeof innerError.message === "string") {
5066
- return innerError.message;
5067
- }
5068
- }
5069
- }
5070
- return String(error);
5071
- }
5072
5081
  function getErrorCode(error) {
5073
5082
  if (error && typeof error === "object") {
5074
5083
  const obj = error;
@@ -5108,6 +5117,7 @@ var init_fallback_decision = __esm({
5108
5117
  init_esm_shims();
5109
5118
  init_logger();
5110
5119
  init_flags();
5120
+ init_error_wrapper();
5111
5121
  SDK_UNAVAILABLE_PATTERNS = [
5112
5122
  "module not found",
5113
5123
  "cannot find module",
@@ -9431,7 +9441,7 @@ var PRECOMPILED_CONFIG = {
9431
9441
  "enableFreeTierPrioritization": true,
9432
9442
  "enableWorkloadAwareRouting": true
9433
9443
  },
9434
- "version": "12.5.2"
9444
+ "version": "12.5.3"
9435
9445
  };
9436
9446
 
9437
9447
  // src/core/config/schemas.ts
@@ -12369,16 +12379,21 @@ var ProfileLoader = class {
12369
12379
  logger.debug("Building displayName mapping table");
12370
12380
  this.displayNameMap.clear();
12371
12381
  try {
12372
- const localProfiles = await this.listProfilesFromDir(this.profilesDir);
12382
+ const [localProfiles, fallbackProfiles] = await Promise.all([
12383
+ this.listProfilesFromDir(this.profilesDir),
12384
+ this.listProfilesFromDir(this.fallbackProfilesDir)
12385
+ ]);
12373
12386
  for (const name of localProfiles) {
12374
12387
  await this.addToDisplayNameMap(name, "local");
12375
12388
  }
12376
- const fallbackProfiles = await this.listProfilesFromDir(this.fallbackProfilesDir);
12377
- for (const name of fallbackProfiles) {
12389
+ const fallbacksToProcess = fallbackProfiles.filter((name) => {
12378
12390
  if (localProfiles.includes(name)) {
12379
12391
  logger.debug("Skipping fallback profile (local override)", { name });
12380
- continue;
12392
+ return false;
12381
12393
  }
12394
+ return true;
12395
+ });
12396
+ for (const name of fallbacksToProcess) {
12382
12397
  await this.addToDisplayNameMap(name, "fallback");
12383
12398
  }
12384
12399
  this.mapInitialized = true;
@@ -19172,6 +19187,7 @@ Run 'ax doctor' to diagnose provider setup.` : "";
19172
19187
  logger.error("Health check interval failed", { error: err.message });
19173
19188
  });
19174
19189
  }, intervalMs);
19190
+ if (this.healthCheckInterval.unref) this.healthCheckInterval.unref();
19175
19191
  logger.debug("Starting background health checks", {
19176
19192
  interval: intervalMs,
19177
19193
  providers: this.providers.map((p) => p.name)
@@ -26428,6 +26444,12 @@ function mapNormalizedCallerToActual(caller) {
26428
26444
  }
26429
26445
 
26430
26446
  // src/mcp/tools/run-agent.ts
26447
+ init_validation_limits();
26448
+ function checkAborted(signal) {
26449
+ if (signal?.aborted) {
26450
+ throw new Error("Request was cancelled");
26451
+ }
26452
+ }
26431
26453
  async function executeViaMcpPool(provider, agent, task, pool) {
26432
26454
  const startTime = Date.now();
26433
26455
  const client = await pool.acquire(provider);
@@ -26448,17 +26470,20 @@ async function executeViaMcpPool(provider, agent, task, pool) {
26448
26470
  pool.release(provider, client);
26449
26471
  }
26450
26472
  }
26451
- async function executeViaCli(agent, task, actualProvider, no_memory, deps, isFallback, signal) {
26473
+ var MCP_DEFAULT_AGENT_TIMEOUT_MS = TIMEOUTS.MCP_AGENT_EXECUTION;
26474
+ async function executeViaCli(agent, task, actualProvider, no_memory, deps, isFallback, signal, timeout) {
26452
26475
  const context = await deps.contextManager.createContext(agent, task, {
26453
26476
  provider: actualProvider,
26454
26477
  skipMemory: no_memory
26455
26478
  });
26456
26479
  const executor = new AgentExecutor(deps.executorConfig);
26457
26480
  const startTime = Date.now();
26481
+ const effectiveTimeout = timeout ?? MCP_DEFAULT_AGENT_TIMEOUT_MS;
26458
26482
  const result = await executor.execute(context, {
26459
26483
  showProgress: false,
26460
26484
  verbose: false,
26461
- signal
26485
+ signal,
26486
+ timeout: effectiveTimeout
26462
26487
  });
26463
26488
  const latencyMs = Date.now() - startTime;
26464
26489
  const executionMode = isFallback ? "cli_fallback" : "cli_spawn";
@@ -26533,9 +26558,7 @@ function createRunAgentHandler(deps) {
26533
26558
  return async (input, context) => {
26534
26559
  const { task, provider, no_memory, mode = "auto" } = input;
26535
26560
  let { agent } = input;
26536
- if (context?.signal?.aborted) {
26537
- throw new Error("Request was cancelled");
26538
- }
26561
+ checkAborted(context?.signal);
26539
26562
  validateStringParameter(task, "task", {
26540
26563
  required: true,
26541
26564
  minLength: 1,
@@ -26580,9 +26603,7 @@ function createRunAgentHandler(deps) {
26580
26603
  bestProvider = selectedProvider?.name || "claude-code";
26581
26604
  }
26582
26605
  const shouldReturnContext = mode === "context" || mode === "auto" && callerActual === bestProvider && callerProvider !== "unknown";
26583
- if (context?.signal?.aborted) {
26584
- throw new Error("Request was cancelled");
26585
- }
26606
+ checkAborted(context?.signal);
26586
26607
  logger.info("[Smart Routing] Decision", {
26587
26608
  mode,
26588
26609
  callerProvider,
@@ -26617,7 +26638,7 @@ function createRunAgentHandler(deps) {
26617
26638
  const shouldTryMcp = !!deps.mcpPool;
26618
26639
  if (shouldTryMcp && deps.mcpPool) {
26619
26640
  try {
26620
- if (context?.signal?.aborted) throw new Error("Request was cancelled");
26641
+ checkAborted(context?.signal);
26621
26642
  const result = await executeViaMcpPool(
26622
26643
  bestProvider,
26623
26644
  agent,
@@ -26647,10 +26668,8 @@ function createRunAgentHandler(deps) {
26647
26668
  }
26648
26669
  }
26649
26670
  try {
26650
- if (context?.signal?.aborted) {
26651
- throw new Error("Request was cancelled");
26652
- }
26653
- const result = await executeViaCli(agent, task, actualProvider, no_memory, deps, shouldTryMcp, context?.signal);
26671
+ checkAborted(context?.signal);
26672
+ const result = await executeViaCli(agent, task, actualProvider, no_memory, deps, shouldTryMcp, context?.signal, MCP_DEFAULT_AGENT_TIMEOUT_MS);
26654
26673
  logger.info("[MCP] run_agent completed (CLI spawn mode)", {
26655
26674
  agent,
26656
26675
  latencyMs: result.latencyMs,
@@ -26684,8 +26703,9 @@ function createListAgentsHandler(deps) {
26684
26703
  }
26685
26704
  })
26686
26705
  );
26706
+ const validProfiles = profiles.filter((profile) => profile !== null);
26687
26707
  const result = {
26688
- agents: profiles.filter((profile) => profile !== null).map((profile) => ({
26708
+ agents: validProfiles.map((profile) => ({
26689
26709
  name: profile.name,
26690
26710
  displayName: profile.displayName,
26691
26711
  role: profile.role,
@@ -27522,29 +27542,34 @@ function createGetCapabilitiesHandler(deps) {
27522
27542
  }
27523
27543
  providers.sort((a, b) => b.priority - a.priority);
27524
27544
  const agentNames = await deps.profileLoader.listProfiles();
27525
- const agents = [];
27526
- for (const agentName of agentNames) {
27527
- try {
27528
- const profile = await deps.profileLoader.loadProfile(agentName);
27529
- agents.push({
27530
- name: profile.name,
27531
- displayName: profile.displayName,
27532
- role: profile.role,
27533
- description: profile.systemPrompt?.substring(0, 200),
27534
- team: profile.team,
27535
- abilities: profile.abilities || []
27536
- });
27537
- } catch (error) {
27538
- logger.warn(`Failed to load profile for ${agentName}`, { error });
27539
- }
27540
- }
27545
+ const agentResults = await Promise.all(
27546
+ agentNames.map(async (agentName) => {
27547
+ try {
27548
+ const profile = await deps.profileLoader.loadProfile(agentName);
27549
+ return {
27550
+ name: profile.name,
27551
+ displayName: profile.displayName,
27552
+ role: profile.role,
27553
+ description: profile.systemPrompt?.substring(0, 200),
27554
+ team: profile.team,
27555
+ abilities: profile.abilities || []
27556
+ };
27557
+ } catch (error) {
27558
+ logger.warn(`Failed to load profile for ${agentName}`, { error });
27559
+ return null;
27560
+ }
27561
+ })
27562
+ );
27563
+ const agents = agentResults.filter((a) => a !== null);
27541
27564
  const tools = deps.toolSchemas.map((schema) => ({
27542
27565
  name: schema.name,
27543
27566
  description: schema.description,
27544
27567
  category: categorizeTools(schema.name)
27545
27568
  }));
27546
- const memoryStats = await deps.memoryManager.getStats();
27547
- const activeSessions = await deps.sessionManager.getActiveSessions();
27569
+ const [memoryStats, activeSessions] = await Promise.all([
27570
+ deps.memoryManager.getStats(),
27571
+ deps.sessionManager.getActiveSessions()
27572
+ ]);
27548
27573
  const result = {
27549
27574
  version,
27550
27575
  providers,
@@ -30196,17 +30221,18 @@ var ConnectionTimeoutError = class extends McpClientError {
30196
30221
  };
30197
30222
 
30198
30223
  // src/providers/mcp/pool-manager.ts
30224
+ init_validation_limits();
30199
30225
  var DEFAULT_CONFIG6 = {
30200
30226
  maxConnectionsPerProvider: 2,
30201
- idleTimeoutMs: 3e5,
30227
+ idleTimeoutMs: TIMEOUTS.IDLE_CONNECTION,
30202
30228
  // 5 minutes
30203
- healthCheckIntervalMs: 3e4,
30229
+ healthCheckIntervalMs: TIMEOUTS.MCP_HEALTH_CHECK,
30204
30230
  // 30 seconds
30205
- acquireTimeoutMs: 1e4,
30231
+ acquireTimeoutMs: TIMEOUTS.VERSION_CHECK,
30206
30232
  // 10 seconds
30207
30233
  fallbackToCli: true
30208
30234
  };
30209
- var IDLE_CLEANUP_INTERVAL_MS = 6e4;
30235
+ var IDLE_CLEANUP_INTERVAL_MS = TIMEOUTS.CONFIG_CACHE_TTL;
30210
30236
  var McpClientPool = class extends EventEmitter {
30211
30237
  config;
30212
30238
  pools = /* @__PURE__ */ new Map();
@@ -30535,6 +30561,7 @@ var McpClientPool = class extends EventEmitter {
30535
30561
  });
30536
30562
  }
30537
30563
  }, this.config.healthCheckIntervalMs);
30564
+ if (this.healthCheckTimer.unref) this.healthCheckTimer.unref();
30538
30565
  }
30539
30566
  startIdleCleanup() {
30540
30567
  this.idleCheckTimer = setInterval(() => {
@@ -30565,6 +30592,7 @@ var McpClientPool = class extends EventEmitter {
30565
30592
  }
30566
30593
  }
30567
30594
  }, IDLE_CLEANUP_INTERVAL_MS);
30595
+ if (this.idleCheckTimer.unref) this.idleCheckTimer.unref();
30568
30596
  }
30569
30597
  emitEvent(type, provider, details) {
30570
30598
  const event = {
@@ -33123,6 +33151,7 @@ var MetricsCollector = class {
33123
33151
  this.collectionInterval = setInterval(() => {
33124
33152
  this.cleanup();
33125
33153
  }, this.collectionIntervalMs);
33154
+ if (this.collectionInterval.unref) this.collectionInterval.unref();
33126
33155
  }
33127
33156
  /**
33128
33157
  * Stop metrics collection
@@ -33414,6 +33443,7 @@ var ResourceEnforcer = class {
33414
33443
  });
33415
33444
  }
33416
33445
  }, this.checkIntervalMs);
33446
+ if (this.checkInterval.unref) this.checkInterval.unref();
33417
33447
  }
33418
33448
  /**
33419
33449
  * Stop enforcing resource limits
@@ -33660,6 +33690,7 @@ function createResourceEnforcer(config) {
33660
33690
  }
33661
33691
 
33662
33692
  // src/mcp/unified-manager.ts
33693
+ init_validation_limits();
33663
33694
  var UnifiedMCPManager = class {
33664
33695
  constructor(config) {
33665
33696
  this.config = config;
@@ -33979,35 +34010,36 @@ var UnifiedMCPManager = class {
33979
34010
  }
33980
34011
  /**
33981
34012
  * Run health check on all servers
34013
+ * v12.5.3: Parallelized health checks for better performance
33982
34014
  *
33983
34015
  * @returns Array of health check results
33984
34016
  */
33985
34017
  async healthCheck() {
33986
34018
  logger.debug("UnifiedMCPManager: Running health checks");
33987
- const results = [];
33988
- for (const [serverName, serverProcess] of this.servers) {
33989
- const result = await this.healthCheckServer(serverName, serverProcess);
33990
- results.push(result);
33991
- }
34019
+ const serverEntries = Array.from(this.servers.entries());
34020
+ const results = await Promise.all(
34021
+ serverEntries.map(
34022
+ ([serverName, serverProcess]) => this.healthCheckServer(serverName, serverProcess)
34023
+ )
34024
+ );
33992
34025
  return results;
33993
34026
  }
33994
34027
  /**
33995
34028
  * Get metrics for all servers (Phase 4D)
34029
+ * v12.5.3: Parallelized metrics collection for better performance
33996
34030
  *
33997
34031
  * @returns Array of server metrics
33998
34032
  */
33999
34033
  async getMetrics() {
34000
- const metrics = [];
34001
- for (const [serverName, serverProcess] of this.servers) {
34002
- if (!serverProcess.running || !serverProcess.process.pid) {
34003
- continue;
34004
- }
34005
- const serverMetrics = await this.metricsCollector.collectServerMetrics(
34006
- serverName,
34007
- serverProcess.process.pid
34008
- );
34009
- metrics.push(serverMetrics);
34010
- }
34034
+ const runningServers = Array.from(this.servers.entries()).filter(([, serverProcess]) => serverProcess.running && serverProcess.process.pid);
34035
+ const metrics = await Promise.all(
34036
+ runningServers.map(
34037
+ ([serverName, serverProcess]) => this.metricsCollector.collectServerMetrics(
34038
+ serverName,
34039
+ serverProcess.process.pid
34040
+ )
34041
+ )
34042
+ );
34011
34043
  return metrics;
34012
34044
  }
34013
34045
  /**
@@ -34218,9 +34250,10 @@ var UnifiedMCPManager = class {
34218
34250
  }
34219
34251
  /**
34220
34252
  * Start periodic health checking
34253
+ * v12.5.3: Use centralized TIMEOUTS.CONFIG_CACHE_TTL for default
34221
34254
  */
34222
34255
  startHealthChecking() {
34223
- const intervalMs = this.config.healthCheck?.intervalMs || 6e4;
34256
+ const intervalMs = this.config.healthCheck?.intervalMs || TIMEOUTS.CONFIG_CACHE_TTL;
34224
34257
  logger.info("UnifiedMCPManager: Starting health checks", {
34225
34258
  intervalMs
34226
34259
  });
@@ -34240,6 +34273,7 @@ var UnifiedMCPManager = class {
34240
34273
  });
34241
34274
  }
34242
34275
  }, intervalMs);
34276
+ if (this.healthCheckInterval.unref) this.healthCheckInterval.unref();
34243
34277
  }
34244
34278
  /**
34245
34279
  * Discover and add servers from registry
@@ -41644,13 +41678,11 @@ function installExitHandler() {
41644
41678
  });
41645
41679
  process.on("exit", () => {
41646
41680
  });
41647
- process.on("SIGINT", async () => {
41648
- await flushAllSessions();
41649
- process.exit(130);
41681
+ process.on("SIGINT", () => {
41682
+ void flushAllSessions().catch((err) => logger.error("SIGINT flush failed", { error: err.message })).finally(() => process.exit(130));
41650
41683
  });
41651
- process.on("SIGTERM", async () => {
41652
- await flushAllSessions();
41653
- process.exit(143);
41684
+ process.on("SIGTERM", () => {
41685
+ void flushAllSessions().catch((err) => logger.error("SIGTERM flush failed", { error: err.message })).finally(() => process.exit(143));
41654
41686
  });
41655
41687
  exitHandlerInstalled = true;
41656
41688
  logger.debug("Session manager exit handler installed");
package/dist/mcp/index.js CHANGED
@@ -193,7 +193,9 @@ var init_validation_limits = __esm({
193
193
  /** Quick CLI command timeout (3 seconds) */
194
194
  QUICK_COMMAND: 3e3,
195
195
  /** CLI version check timeout (10 seconds) */
196
- VERSION_CHECK: 1e4
196
+ VERSION_CHECK: 1e4,
197
+ /** MCP agent execution timeout (5 minutes) */
198
+ MCP_AGENT_EXECUTION: 3e5
197
199
  };
198
200
  DATABASE = {
199
201
  /** SQLite busy timeout in milliseconds */
@@ -4719,6 +4721,37 @@ var init_flags = __esm({
4719
4721
  }
4720
4722
  });
4721
4723
 
4724
+ // src/shared/errors/error-wrapper.ts
4725
+ function getErrorMessage(error) {
4726
+ if (error instanceof Error) {
4727
+ return error.message;
4728
+ }
4729
+ if (typeof error === "string") {
4730
+ return error;
4731
+ }
4732
+ if (error && typeof error === "object") {
4733
+ const obj = error;
4734
+ if (obj.error && typeof obj.error === "object") {
4735
+ const nested = obj.error;
4736
+ if (typeof nested.message === "string") {
4737
+ return nested.message;
4738
+ }
4739
+ }
4740
+ if (typeof obj.error === "string") {
4741
+ return obj.error;
4742
+ }
4743
+ if ("message" in obj) {
4744
+ return String(obj.message);
4745
+ }
4746
+ }
4747
+ return String(error);
4748
+ }
4749
+ var init_error_wrapper = __esm({
4750
+ "src/shared/errors/error-wrapper.ts"() {
4751
+ init_esm_shims();
4752
+ }
4753
+ });
4754
+
4722
4755
  // src/providers/fallback-decision.ts
4723
4756
  function decideFallback(error, providerName) {
4724
4757
  const errorMessage = getErrorMessage(error).toLowerCase();
@@ -4789,30 +4822,6 @@ function decideFallback(error, providerName) {
4789
4822
  severity: "error"
4790
4823
  };
4791
4824
  }
4792
- function getErrorMessage(error) {
4793
- if (error instanceof Error) {
4794
- return error.message;
4795
- }
4796
- if (typeof error === "string") {
4797
- return error;
4798
- }
4799
- if (error && typeof error === "object") {
4800
- const obj = error;
4801
- if (typeof obj.message === "string") {
4802
- return obj.message;
4803
- }
4804
- if (typeof obj.error === "string") {
4805
- return obj.error;
4806
- }
4807
- if (obj.error && typeof obj.error === "object") {
4808
- const innerError = obj.error;
4809
- if (typeof innerError.message === "string") {
4810
- return innerError.message;
4811
- }
4812
- }
4813
- }
4814
- return String(error);
4815
- }
4816
4825
  function getErrorCode(error) {
4817
4826
  if (error && typeof error === "object") {
4818
4827
  const obj = error;
@@ -4852,6 +4861,7 @@ var init_fallback_decision = __esm({
4852
4861
  init_esm_shims();
4853
4862
  init_logger();
4854
4863
  init_flags();
4864
+ init_error_wrapper();
4855
4865
  SDK_UNAVAILABLE_PATTERNS = [
4856
4866
  "module not found",
4857
4867
  "cannot find module",
@@ -8727,7 +8737,7 @@ var PRECOMPILED_CONFIG = {
8727
8737
  "enableFreeTierPrioritization": true,
8728
8738
  "enableWorkloadAwareRouting": true
8729
8739
  },
8730
- "version": "12.5.2"
8740
+ "version": "12.5.3"
8731
8741
  };
8732
8742
 
8733
8743
  // src/core/config/schemas.ts
@@ -12425,6 +12435,7 @@ Run 'ax doctor' to diagnose provider setup.` : "";
12425
12435
  logger.error("Health check interval failed", { error: err.message });
12426
12436
  });
12427
12437
  }, intervalMs);
12438
+ if (this.healthCheckInterval.unref) this.healthCheckInterval.unref();
12428
12439
  logger.debug("Starting background health checks", {
12429
12440
  interval: intervalMs,
12430
12441
  providers: this.providers.map((p) => p.name)
@@ -16609,16 +16620,21 @@ var ProfileLoader = class {
16609
16620
  logger.debug("Building displayName mapping table");
16610
16621
  this.displayNameMap.clear();
16611
16622
  try {
16612
- const localProfiles = await this.listProfilesFromDir(this.profilesDir);
16623
+ const [localProfiles, fallbackProfiles] = await Promise.all([
16624
+ this.listProfilesFromDir(this.profilesDir),
16625
+ this.listProfilesFromDir(this.fallbackProfilesDir)
16626
+ ]);
16613
16627
  for (const name of localProfiles) {
16614
16628
  await this.addToDisplayNameMap(name, "local");
16615
16629
  }
16616
- const fallbackProfiles = await this.listProfilesFromDir(this.fallbackProfilesDir);
16617
- for (const name of fallbackProfiles) {
16630
+ const fallbacksToProcess = fallbackProfiles.filter((name) => {
16618
16631
  if (localProfiles.includes(name)) {
16619
16632
  logger.debug("Skipping fallback profile (local override)", { name });
16620
- continue;
16633
+ return false;
16621
16634
  }
16635
+ return true;
16636
+ });
16637
+ for (const name of fallbacksToProcess) {
16622
16638
  await this.addToDisplayNameMap(name, "fallback");
16623
16639
  }
16624
16640
  this.mapInitialized = true;
@@ -20770,6 +20786,12 @@ function mapNormalizedCallerToActual(caller) {
20770
20786
  }
20771
20787
 
20772
20788
  // src/mcp/tools/run-agent.ts
20789
+ init_validation_limits();
20790
+ function checkAborted(signal) {
20791
+ if (signal?.aborted) {
20792
+ throw new Error("Request was cancelled");
20793
+ }
20794
+ }
20773
20795
  async function executeViaMcpPool(provider, agent, task, pool) {
20774
20796
  const startTime = Date.now();
20775
20797
  const client = await pool.acquire(provider);
@@ -20790,17 +20812,20 @@ async function executeViaMcpPool(provider, agent, task, pool) {
20790
20812
  pool.release(provider, client);
20791
20813
  }
20792
20814
  }
20793
- async function executeViaCli(agent, task, actualProvider, no_memory, deps, isFallback, signal) {
20815
+ var MCP_DEFAULT_AGENT_TIMEOUT_MS = TIMEOUTS.MCP_AGENT_EXECUTION;
20816
+ async function executeViaCli(agent, task, actualProvider, no_memory, deps, isFallback, signal, timeout) {
20794
20817
  const context = await deps.contextManager.createContext(agent, task, {
20795
20818
  provider: actualProvider,
20796
20819
  skipMemory: no_memory
20797
20820
  });
20798
20821
  const executor = new AgentExecutor(deps.executorConfig);
20799
20822
  const startTime = Date.now();
20823
+ const effectiveTimeout = timeout ?? MCP_DEFAULT_AGENT_TIMEOUT_MS;
20800
20824
  const result = await executor.execute(context, {
20801
20825
  showProgress: false,
20802
20826
  verbose: false,
20803
- signal
20827
+ signal,
20828
+ timeout: effectiveTimeout
20804
20829
  });
20805
20830
  const latencyMs = Date.now() - startTime;
20806
20831
  const executionMode = isFallback ? "cli_fallback" : "cli_spawn";
@@ -20875,9 +20900,7 @@ function createRunAgentHandler(deps) {
20875
20900
  return async (input, context) => {
20876
20901
  const { task, provider, no_memory, mode = "auto" } = input;
20877
20902
  let { agent } = input;
20878
- if (context?.signal?.aborted) {
20879
- throw new Error("Request was cancelled");
20880
- }
20903
+ checkAborted(context?.signal);
20881
20904
  validateStringParameter(task, "task", {
20882
20905
  required: true,
20883
20906
  minLength: 1,
@@ -20922,9 +20945,7 @@ function createRunAgentHandler(deps) {
20922
20945
  bestProvider = selectedProvider?.name || "claude-code";
20923
20946
  }
20924
20947
  const shouldReturnContext = mode === "context" || mode === "auto" && callerActual === bestProvider && callerProvider !== "unknown";
20925
- if (context?.signal?.aborted) {
20926
- throw new Error("Request was cancelled");
20927
- }
20948
+ checkAborted(context?.signal);
20928
20949
  logger.info("[Smart Routing] Decision", {
20929
20950
  mode,
20930
20951
  callerProvider,
@@ -20959,7 +20980,7 @@ function createRunAgentHandler(deps) {
20959
20980
  const shouldTryMcp = !!deps.mcpPool;
20960
20981
  if (shouldTryMcp && deps.mcpPool) {
20961
20982
  try {
20962
- if (context?.signal?.aborted) throw new Error("Request was cancelled");
20983
+ checkAborted(context?.signal);
20963
20984
  const result = await executeViaMcpPool(
20964
20985
  bestProvider,
20965
20986
  agent,
@@ -20989,10 +21010,8 @@ function createRunAgentHandler(deps) {
20989
21010
  }
20990
21011
  }
20991
21012
  try {
20992
- if (context?.signal?.aborted) {
20993
- throw new Error("Request was cancelled");
20994
- }
20995
- const result = await executeViaCli(agent, task, actualProvider, no_memory, deps, shouldTryMcp, context?.signal);
21013
+ checkAborted(context?.signal);
21014
+ const result = await executeViaCli(agent, task, actualProvider, no_memory, deps, shouldTryMcp, context?.signal, MCP_DEFAULT_AGENT_TIMEOUT_MS);
20996
21015
  logger.info("[MCP] run_agent completed (CLI spawn mode)", {
20997
21016
  agent,
20998
21017
  latencyMs: result.latencyMs,
@@ -21026,8 +21045,9 @@ function createListAgentsHandler(deps) {
21026
21045
  }
21027
21046
  })
21028
21047
  );
21048
+ const validProfiles = profiles.filter((profile) => profile !== null);
21029
21049
  const result = {
21030
- agents: profiles.filter((profile) => profile !== null).map((profile) => ({
21050
+ agents: validProfiles.map((profile) => ({
21031
21051
  name: profile.name,
21032
21052
  displayName: profile.displayName,
21033
21053
  role: profile.role,
@@ -21864,29 +21884,34 @@ function createGetCapabilitiesHandler(deps) {
21864
21884
  }
21865
21885
  providers.sort((a, b) => b.priority - a.priority);
21866
21886
  const agentNames = await deps.profileLoader.listProfiles();
21867
- const agents = [];
21868
- for (const agentName of agentNames) {
21869
- try {
21870
- const profile = await deps.profileLoader.loadProfile(agentName);
21871
- agents.push({
21872
- name: profile.name,
21873
- displayName: profile.displayName,
21874
- role: profile.role,
21875
- description: profile.systemPrompt?.substring(0, 200),
21876
- team: profile.team,
21877
- abilities: profile.abilities || []
21878
- });
21879
- } catch (error) {
21880
- logger.warn(`Failed to load profile for ${agentName}`, { error });
21881
- }
21882
- }
21887
+ const agentResults = await Promise.all(
21888
+ agentNames.map(async (agentName) => {
21889
+ try {
21890
+ const profile = await deps.profileLoader.loadProfile(agentName);
21891
+ return {
21892
+ name: profile.name,
21893
+ displayName: profile.displayName,
21894
+ role: profile.role,
21895
+ description: profile.systemPrompt?.substring(0, 200),
21896
+ team: profile.team,
21897
+ abilities: profile.abilities || []
21898
+ };
21899
+ } catch (error) {
21900
+ logger.warn(`Failed to load profile for ${agentName}`, { error });
21901
+ return null;
21902
+ }
21903
+ })
21904
+ );
21905
+ const agents = agentResults.filter((a) => a !== null);
21883
21906
  const tools = deps.toolSchemas.map((schema) => ({
21884
21907
  name: schema.name,
21885
21908
  description: schema.description,
21886
21909
  category: categorizeTools(schema.name)
21887
21910
  }));
21888
- const memoryStats = await deps.memoryManager.getStats();
21889
- const activeSessions = await deps.sessionManager.getActiveSessions();
21911
+ const [memoryStats, activeSessions] = await Promise.all([
21912
+ deps.memoryManager.getStats(),
21913
+ deps.sessionManager.getActiveSessions()
21914
+ ]);
21890
21915
  const result = {
21891
21916
  version,
21892
21917
  providers,
@@ -24538,17 +24563,18 @@ var ConnectionTimeoutError = class extends McpClientError {
24538
24563
  };
24539
24564
 
24540
24565
  // src/providers/mcp/pool-manager.ts
24566
+ init_validation_limits();
24541
24567
  var DEFAULT_CONFIG6 = {
24542
24568
  maxConnectionsPerProvider: 2,
24543
- idleTimeoutMs: 3e5,
24569
+ idleTimeoutMs: TIMEOUTS.IDLE_CONNECTION,
24544
24570
  // 5 minutes
24545
- healthCheckIntervalMs: 3e4,
24571
+ healthCheckIntervalMs: TIMEOUTS.MCP_HEALTH_CHECK,
24546
24572
  // 30 seconds
24547
- acquireTimeoutMs: 1e4,
24573
+ acquireTimeoutMs: TIMEOUTS.VERSION_CHECK,
24548
24574
  // 10 seconds
24549
24575
  fallbackToCli: true
24550
24576
  };
24551
- var IDLE_CLEANUP_INTERVAL_MS = 6e4;
24577
+ var IDLE_CLEANUP_INTERVAL_MS = TIMEOUTS.CONFIG_CACHE_TTL;
24552
24578
  var McpClientPool = class extends EventEmitter {
24553
24579
  config;
24554
24580
  pools = /* @__PURE__ */ new Map();
@@ -24877,6 +24903,7 @@ var McpClientPool = class extends EventEmitter {
24877
24903
  });
24878
24904
  }
24879
24905
  }, this.config.healthCheckIntervalMs);
24906
+ if (this.healthCheckTimer.unref) this.healthCheckTimer.unref();
24880
24907
  }
24881
24908
  startIdleCleanup() {
24882
24909
  this.idleCheckTimer = setInterval(() => {
@@ -24907,6 +24934,7 @@ var McpClientPool = class extends EventEmitter {
24907
24934
  }
24908
24935
  }
24909
24936
  }, IDLE_CLEANUP_INTERVAL_MS);
24937
+ if (this.idleCheckTimer.unref) this.idleCheckTimer.unref();
24910
24938
  }
24911
24939
  emitEvent(type, provider, details) {
24912
24940
  const event = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defai.digital/automatosx",
3
- "version": "12.5.2",
3
+ "version": "12.5.3",
4
4
  "description": "Provider-agnostic AI orchestration platform with 20+ specialized agents, persistent memory, and multi-provider routing for Claude Code, Gemini CLI, Codex CLI, GLM, and Grok",
5
5
  "type": "module",
6
6
  "publishConfig": {