@defai.digital/automatosx 12.5.0 → 12.5.2

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.0 | MCP Hybrid Framing & Multi-Protocol Support
15
+ **Status**: ✅ **Production Ready** | v12.5.2 | MCP Hybrid Framing & Multi-Protocol Support
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
@@ -9431,7 +9431,7 @@ var PRECOMPILED_CONFIG = {
9431
9431
  "enableFreeTierPrioritization": true,
9432
9432
  "enableWorkloadAwareRouting": true
9433
9433
  },
9434
- "version": "12.5.0"
9434
+ "version": "12.5.2"
9435
9435
  };
9436
9436
 
9437
9437
  // src/core/config/schemas.ts
@@ -26006,6 +26006,232 @@ ${context.task}`;
26006
26006
  }
26007
26007
  };
26008
26008
 
26009
+ // src/agents/agent-selector.ts
26010
+ init_esm_shims();
26011
+ init_logger();
26012
+ function scoreAgent(task, profile) {
26013
+ let score = 0;
26014
+ const taskLower = task.toLowerCase();
26015
+ if (profile.selectionMetadata?.primaryIntents) {
26016
+ for (const intent of profile.selectionMetadata.primaryIntents) {
26017
+ const intentKeywords = intent.toLowerCase().split(/\s+/);
26018
+ const matchedKeywords = intentKeywords.filter(
26019
+ (keyword) => taskLower.includes(keyword) && keyword.length > 3
26020
+ );
26021
+ if (matchedKeywords.length >= 2) {
26022
+ score += 10;
26023
+ } else if (matchedKeywords.length === 1) {
26024
+ score += 5;
26025
+ }
26026
+ }
26027
+ }
26028
+ if (profile.selectionMetadata?.secondarySignals) {
26029
+ for (const signal of profile.selectionMetadata.secondarySignals) {
26030
+ if (taskLower.includes(signal.toLowerCase())) {
26031
+ score += 5;
26032
+ }
26033
+ }
26034
+ }
26035
+ if (profile.selectionMetadata?.negativeIntents) {
26036
+ for (const negative of profile.selectionMetadata.negativeIntents) {
26037
+ const keywords = negative.split("(")[0]?.toLowerCase() || "";
26038
+ const negativeKeywords = keywords.split(/\s+/).filter((k) => k.length > 3);
26039
+ const matchedNegative = negativeKeywords.filter(
26040
+ (keyword) => taskLower.includes(keyword)
26041
+ );
26042
+ if (matchedNegative.length >= 2) {
26043
+ score -= 20;
26044
+ }
26045
+ }
26046
+ }
26047
+ if (profile.selectionMetadata?.redirectWhen) {
26048
+ for (const rule of profile.selectionMetadata.redirectWhen) {
26049
+ try {
26050
+ const regex = new RegExp(rule.phrase, "i");
26051
+ if (regex.test(task)) {
26052
+ score -= 15;
26053
+ }
26054
+ } catch (error) {
26055
+ logger.debug("Invalid regex pattern in redirectWhen rule", {
26056
+ pattern: rule.phrase,
26057
+ error: error instanceof Error ? error.message : String(error)
26058
+ });
26059
+ }
26060
+ }
26061
+ }
26062
+ if (profile.abilitySelection?.taskBased) {
26063
+ for (const keyword of Object.keys(profile.abilitySelection.taskBased)) {
26064
+ if (taskLower.includes(keyword.toLowerCase())) {
26065
+ score += 3;
26066
+ }
26067
+ }
26068
+ }
26069
+ return Math.max(0, score);
26070
+ }
26071
+ function buildRationale(task, profile) {
26072
+ const rationale = [];
26073
+ const taskLower = task.toLowerCase();
26074
+ if (profile.selectionMetadata?.primaryIntents) {
26075
+ const matchedIntents = profile.selectionMetadata.primaryIntents.filter((intent) => {
26076
+ const keywords = intent.toLowerCase().split(/\s+/);
26077
+ return keywords.some((k) => taskLower.includes(k) && k.length > 3);
26078
+ });
26079
+ if (matchedIntents.length > 0) {
26080
+ rationale.push(`Matches: ${matchedIntents.slice(0, 2).join(", ")}`);
26081
+ }
26082
+ }
26083
+ if (profile.selectionMetadata?.secondarySignals) {
26084
+ const matchedSignals = profile.selectionMetadata.secondarySignals.filter(
26085
+ (signal) => taskLower.includes(signal.toLowerCase())
26086
+ );
26087
+ if (matchedSignals.length > 0) {
26088
+ rationale.push(`Keywords: ${matchedSignals.slice(0, 3).join(", ")}`);
26089
+ }
26090
+ }
26091
+ if (profile.abilitySelection?.taskBased) {
26092
+ const matchedAbilities = Object.keys(profile.abilitySelection.taskBased).filter(
26093
+ (keyword) => taskLower.includes(keyword.toLowerCase())
26094
+ );
26095
+ if (matchedAbilities.length > 0) {
26096
+ rationale.push(`Abilities: ${matchedAbilities.slice(0, 2).join(", ")}`);
26097
+ }
26098
+ }
26099
+ if (rationale.length === 0) {
26100
+ rationale.push("General capability match");
26101
+ }
26102
+ return rationale;
26103
+ }
26104
+ function getConfidence(score) {
26105
+ if (score >= 30) return "high";
26106
+ if (score >= 15) return "medium";
26107
+ return "low";
26108
+ }
26109
+ var MIN_SELECTION_SCORE = 5;
26110
+ var FALLBACK_AGENT = "standard";
26111
+ var AgentSelector = class {
26112
+ profileLoader;
26113
+ constructor(profileLoader) {
26114
+ this.profileLoader = profileLoader;
26115
+ }
26116
+ /**
26117
+ * Select the best agent for a task
26118
+ *
26119
+ * @param task - Task description
26120
+ * @returns Selection result with agent, score, confidence, and rationale
26121
+ */
26122
+ async selectAgent(task) {
26123
+ logger.debug("[AgentSelector] Selecting agent for task", {
26124
+ taskPreview: task.substring(0, 100)
26125
+ });
26126
+ const agentNames = await this.profileLoader.listProfiles();
26127
+ if (agentNames.length === 0) {
26128
+ logger.warn("[AgentSelector] No agents found, using fallback");
26129
+ return this.createFallbackResult(task);
26130
+ }
26131
+ const profileResults = await Promise.all(
26132
+ agentNames.map(async (name) => {
26133
+ try {
26134
+ const profile = await this.profileLoader.loadProfile(name);
26135
+ return { name, profile, score: scoreAgent(task, profile) };
26136
+ } catch (error) {
26137
+ logger.debug(`[AgentSelector] Failed to load profile: ${name}`, { error });
26138
+ return null;
26139
+ }
26140
+ })
26141
+ );
26142
+ const scoredAgents = profileResults.filter(
26143
+ (result) => result !== null
26144
+ );
26145
+ if (scoredAgents.length === 0) {
26146
+ logger.warn("[AgentSelector] Failed to load any profiles, using fallback");
26147
+ return this.createFallbackResult(task);
26148
+ }
26149
+ scoredAgents.sort((a, b) => b.score - a.score);
26150
+ const best = scoredAgents[0];
26151
+ const alternatives = scoredAgents.slice(1, 4).map((a) => ({
26152
+ agent: a.name,
26153
+ score: a.score
26154
+ }));
26155
+ if (best.score < MIN_SELECTION_SCORE) {
26156
+ logger.info("[AgentSelector] Best score below threshold, using fallback", {
26157
+ bestAgent: best.name,
26158
+ bestScore: best.score,
26159
+ threshold: MIN_SELECTION_SCORE
26160
+ });
26161
+ const standardAgent = scoredAgents.find((a) => a.name === FALLBACK_AGENT);
26162
+ if (standardAgent) {
26163
+ return {
26164
+ agent: standardAgent.name,
26165
+ displayName: standardAgent.profile.displayName || standardAgent.name,
26166
+ role: standardAgent.profile.role,
26167
+ score: standardAgent.score,
26168
+ confidence: "low",
26169
+ rationale: ["No strong match found, using general-purpose agent"],
26170
+ alternatives: scoredAgents.filter((a) => a.name !== FALLBACK_AGENT).slice(0, 3).map((a) => ({ agent: a.name, score: a.score })),
26171
+ usedFallback: true
26172
+ };
26173
+ }
26174
+ return {
26175
+ agent: best.name,
26176
+ displayName: best.profile.displayName || best.name,
26177
+ role: best.profile.role,
26178
+ score: best.score,
26179
+ confidence: "low",
26180
+ rationale: ["Low confidence match - consider specifying agent explicitly"],
26181
+ alternatives,
26182
+ usedFallback: false
26183
+ };
26184
+ }
26185
+ const rationale = buildRationale(task, best.profile);
26186
+ const confidence = getConfidence(best.score);
26187
+ logger.info("[AgentSelector] Agent selected", {
26188
+ agent: best.name,
26189
+ score: best.score,
26190
+ confidence,
26191
+ rationale
26192
+ });
26193
+ return {
26194
+ agent: best.name,
26195
+ displayName: best.profile.displayName || best.name,
26196
+ role: best.profile.role,
26197
+ score: best.score,
26198
+ confidence,
26199
+ rationale,
26200
+ alternatives,
26201
+ usedFallback: false
26202
+ };
26203
+ }
26204
+ /**
26205
+ * Create a fallback result when no agents are available
26206
+ */
26207
+ async createFallbackResult(_task) {
26208
+ try {
26209
+ const profile = await this.profileLoader.loadProfile(FALLBACK_AGENT);
26210
+ return {
26211
+ agent: FALLBACK_AGENT,
26212
+ displayName: profile.displayName || FALLBACK_AGENT,
26213
+ role: profile.role,
26214
+ score: 0,
26215
+ confidence: "low",
26216
+ rationale: ["No agents available, using fallback"],
26217
+ alternatives: [],
26218
+ usedFallback: true
26219
+ };
26220
+ } catch {
26221
+ return {
26222
+ agent: FALLBACK_AGENT,
26223
+ displayName: "Standard",
26224
+ role: "General-purpose agent",
26225
+ score: 0,
26226
+ confidence: "low",
26227
+ rationale: ["No agents available"],
26228
+ alternatives: [],
26229
+ usedFallback: true
26230
+ };
26231
+ }
26232
+ }
26233
+ };
26234
+
26009
26235
  // src/mcp/tools/run-agent.ts
26010
26236
  init_logger();
26011
26237
 
@@ -26305,22 +26531,41 @@ async function buildAgentContext(agentName, task, deps, callerProvider, bestProv
26305
26531
  }
26306
26532
  function createRunAgentHandler(deps) {
26307
26533
  return async (input, context) => {
26308
- const { agent, task, provider, no_memory, mode = "auto" } = input;
26534
+ const { task, provider, no_memory, mode = "auto" } = input;
26535
+ let { agent } = input;
26309
26536
  if (context?.signal?.aborted) {
26310
26537
  throw new Error("Request was cancelled");
26311
26538
  }
26312
- validateAgentName(agent);
26313
26539
  validateStringParameter(task, "task", {
26314
26540
  required: true,
26315
26541
  minLength: 1,
26316
26542
  maxLength: 1e4
26317
26543
  });
26544
+ let autoSelected = false;
26545
+ if (!agent && deps.profileLoader) {
26546
+ const selector = new AgentSelector(deps.profileLoader);
26547
+ const selection = await selector.selectAgent(task);
26548
+ agent = selection.agent;
26549
+ autoSelected = true;
26550
+ logger.info("[MCP] run_agent auto-selected agent", {
26551
+ task: task.substring(0, 100),
26552
+ selectedAgent: agent,
26553
+ confidence: selection.confidence,
26554
+ score: selection.score,
26555
+ rationale: selection.rationale
26556
+ });
26557
+ }
26558
+ if (!agent) {
26559
+ throw new Error("Agent name is required when profileLoader is not available");
26560
+ }
26561
+ validateAgentName(agent);
26318
26562
  const actualProvider = mapMcpProviderToActual(provider);
26319
26563
  const session = deps.getSession?.() || null;
26320
26564
  const callerProvider = session?.normalizedProvider || "unknown";
26321
26565
  const callerActual = mapNormalizedCallerToActual(callerProvider);
26322
26566
  logger.info("[MCP] run_agent called (Smart Routing v10.5.0)", {
26323
26567
  agent,
26568
+ autoSelected,
26324
26569
  task: task.substring(0, 100),
26325
26570
  mcpProvider: provider,
26326
26571
  actualProvider,
@@ -27133,20 +27378,35 @@ init_logger();
27133
27378
  function createGetAgentContextHandler(deps) {
27134
27379
  return async (input) => {
27135
27380
  const {
27136
- agent,
27137
27381
  task,
27138
27382
  includeMemory = true,
27139
27383
  maxMemoryResults = 5
27140
27384
  } = input;
27385
+ let { agent } = input;
27141
27386
  const startTime = Date.now();
27142
- validateAgentName(agent);
27143
27387
  validateStringParameter(task, "task", {
27144
27388
  required: true,
27145
27389
  minLength: 1,
27146
27390
  maxLength: 1e4
27147
27391
  });
27392
+ let autoSelected = false;
27393
+ if (!agent) {
27394
+ const selector = new AgentSelector(deps.profileLoader);
27395
+ const selection = await selector.selectAgent(task);
27396
+ agent = selection.agent;
27397
+ autoSelected = true;
27398
+ logger.info("[MCP] get_agent_context auto-selected agent", {
27399
+ task: task.substring(0, 100),
27400
+ selectedAgent: agent,
27401
+ confidence: selection.confidence,
27402
+ score: selection.score,
27403
+ rationale: selection.rationale
27404
+ });
27405
+ }
27406
+ validateAgentName(agent);
27148
27407
  logger.info("[MCP] get_agent_context called", {
27149
27408
  agent,
27409
+ autoSelected,
27150
27410
  task: task.substring(0, 100),
27151
27411
  includeMemory,
27152
27412
  maxMemoryResults
@@ -31561,7 +31821,12 @@ async function resolveResourceTemplate(uri, variables, profileLoader, workspaceM
31561
31821
  profile.role ? `**Role:** ${profile.role}` : "",
31562
31822
  profile.abilities?.length ? `**Abilities:** ${profile.abilities.join(", ")}` : "",
31563
31823
  "",
31564
- profile.systemPrompt || "No system prompt defined."
31824
+ profile.systemPrompt || "No system prompt defined.",
31825
+ "",
31826
+ "## Profile JSON",
31827
+ "```json",
31828
+ JSON.stringify(profile, null, 2),
31829
+ "```"
31565
31830
  ].filter(Boolean).join("\n");
31566
31831
  return {
31567
31832
  uri: `agent/${agent}`,
@@ -31569,8 +31834,7 @@ async function resolveResourceTemplate(uri, variables, profileLoader, workspaceM
31569
31834
  description: `AutomatosX agent profile for ${agent}`,
31570
31835
  mimeType: "text/markdown",
31571
31836
  contents: [
31572
- { type: "text", text: summary },
31573
- { type: "application/json", json: profile }
31837
+ { type: "text", text: summary }
31574
31838
  ]
31575
31839
  };
31576
31840
  }
@@ -31588,8 +31852,7 @@ async function resolveResourceTemplate(uri, variables, profileLoader, workspaceM
31588
31852
  description: `Workspace ${isPrd ? "PRD" : "tmp"} file`,
31589
31853
  mimeType: "text/markdown",
31590
31854
  contents: [
31591
- { type: "text", text: content },
31592
- { type: "application/json", json: { path: path7, content, workspace: isPrd ? "PRD" : "tmp" } }
31855
+ { type: "text", text: content }
31593
31856
  ]
31594
31857
  };
31595
31858
  }
@@ -31697,17 +31960,24 @@ var McpServer = class _McpServer {
31697
31960
  return [
31698
31961
  {
31699
31962
  name: "run_agent",
31700
- description: "Execute an AutomatosX agent with a specific task. Uses Smart Routing: returns context for same-provider calls, spawns cross-provider execution.",
31963
+ description: `Execute an AutomatosX agent with a specific task.
31964
+
31965
+ v12.5.1: Agent auto-selection - if agent is omitted, system automatically selects the best agent based on task keywords.
31966
+ Uses Smart Routing: returns context for same-provider calls, spawns cross-provider execution.
31967
+
31968
+ Examples:
31969
+ - With agent: run_agent({ agent: "backend", task: "implement API" })
31970
+ - Auto-select: run_agent({ task: "fix bugs in the codebase" }) \u2192 selects "quality" agent`,
31701
31971
  inputSchema: {
31702
31972
  type: "object",
31703
31973
  properties: {
31704
- agent: { type: "string", description: "The name of the agent to run (e.g., backend, Paris, Bob)" },
31974
+ agent: { type: "string", description: "Optional: Agent name (e.g., backend, quality). If omitted, best agent is auto-selected based on task." },
31705
31975
  task: { type: "string", description: "The task for the agent to perform" },
31706
31976
  provider: { type: "string", description: "Optional: Override the AI provider", enum: ["claude", "gemini", "openai"] },
31707
31977
  no_memory: { type: "boolean", description: "Optional: Skip memory injection", default: false },
31708
31978
  mode: { type: "string", description: "Optional: Execution mode - auto (default), context (always return context), execute (always spawn)", enum: ["auto", "context", "execute"], default: "auto" }
31709
31979
  },
31710
- required: ["agent", "task"]
31980
+ required: ["task"]
31711
31981
  }
31712
31982
  },
31713
31983
  {
@@ -31819,16 +32089,18 @@ Use this tool first to understand what AutomatosX offers.`,
31819
32089
  // v10.5.0: Smart Routing - Explicit context retrieval
31820
32090
  {
31821
32091
  name: "get_agent_context",
31822
- description: "Get agent context without executing. Returns profile, relevant memory, and enhanced prompt for AI assistant to execute directly.",
32092
+ description: `Get agent context without executing. Returns profile, relevant memory, and enhanced prompt for AI assistant to execute directly.
32093
+
32094
+ v12.5.1: Agent auto-selection - if agent is omitted, system automatically selects the best agent based on task keywords.`,
31823
32095
  inputSchema: {
31824
32096
  type: "object",
31825
32097
  properties: {
31826
- agent: { type: "string", description: "The name of the agent (e.g., backend, Paris, Bob)" },
32098
+ agent: { type: "string", description: "Optional: Agent name (e.g., backend, quality). If omitted, best agent is auto-selected based on task." },
31827
32099
  task: { type: "string", description: "The task description for context building" },
31828
32100
  includeMemory: { type: "boolean", description: "Include relevant memory entries (default: true)", default: true },
31829
32101
  maxMemoryResults: { type: "number", description: "Maximum memory entries to return (default: 5)", default: 5 }
31830
32102
  },
31831
- required: ["agent", "task"]
32103
+ required: ["task"]
31832
32104
  }
31833
32105
  },
31834
32106
  // v11.3.5: Task Engine tools
@@ -32226,8 +32498,10 @@ Use this tool first to understand what AutomatosX offers.`,
32226
32498
  const profile = await this.profileLoader.loadProfile(agent);
32227
32499
  const content = [
32228
32500
  { type: "text", text: `System prompt for ${agent}:
32229
- ${profile.systemPrompt || "No system prompt defined."}` },
32230
- { type: "application/json", json: profile }
32501
+ ${profile.systemPrompt || "No system prompt defined."}
32502
+
32503
+ Profile:
32504
+ ${JSON.stringify(profile, null, 2)}` }
32231
32505
  ];
32232
32506
  return { jsonrpc: "2.0", id, result: { prompt: { name, description: "Agent context", arguments: [{ name: "agent", required: true }] }, content } };
32233
32507
  } catch (error) {
@@ -32244,8 +32518,10 @@ ${profile.systemPrompt || "No system prompt defined."}` },
32244
32518
  { type: "text", text: `AutomatosX MCP status:
32245
32519
  Version: ${summary.version}
32246
32520
  Providers: ${summary.providerCount}
32247
- Streaming: ${summary.streamingNotifications}` },
32248
- { type: "application/json", json: summary }
32521
+ Streaming: ${summary.streamingNotifications}
32522
+
32523
+ Details:
32524
+ ${JSON.stringify(summary, null, 2)}` }
32249
32525
  ];
32250
32526
  return { jsonrpc: "2.0", id, result: { prompt: { name, description: "AutomatosX status" }, content } };
32251
32527
  }
@@ -32270,11 +32546,15 @@ Streaming: ${summary.streamingNotifications}` },
32270
32546
  profile.role ? `**Role:** ${profile.role}` : "",
32271
32547
  profile.abilities?.length ? `**Abilities:** ${profile.abilities.join(", ")}` : "",
32272
32548
  "",
32273
- profile.systemPrompt || "No system prompt defined."
32549
+ profile.systemPrompt || "No system prompt defined.",
32550
+ "",
32551
+ "## Profile JSON",
32552
+ "```json",
32553
+ JSON.stringify(profile, null, 2),
32554
+ "```"
32274
32555
  ].filter(Boolean).join("\n");
32275
32556
  const contents = [
32276
- { type: "text", text: summary },
32277
- { type: "application/json", json: profile }
32557
+ { type: "text", text: summary }
32278
32558
  ];
32279
32559
  return { jsonrpc: "2.0", id, result: { uri, mimeType: "text/markdown", contents } };
32280
32560
  } catch (error) {
@@ -32317,15 +32597,8 @@ Streaming: ${summary.streamingNotifications}` },
32317
32597
  }
32318
32598
  /** Create MCP tool response wrapper */
32319
32599
  createToolResponse(id, result, isError = false) {
32320
- let content;
32321
- if (typeof result === "string") {
32322
- content = [{ type: "text", text: result }];
32323
- } else {
32324
- content = [
32325
- { type: "application/json", json: result },
32326
- { type: "text", text: JSON.stringify(result, null, 2) }
32327
- ];
32328
- }
32600
+ const text = typeof result === "string" ? result : JSON.stringify(result, null, 2);
32601
+ const content = [{ type: "text", text }];
32329
32602
  const response = { content, ...isError && { isError } };
32330
32603
  return { jsonrpc: "2.0", id, result: response };
32331
32604
  }
@@ -35189,232 +35462,6 @@ var memoryCommand = {
35189
35462
  // src/cli/commands/run.ts
35190
35463
  init_esm_shims();
35191
35464
 
35192
- // src/agents/agent-selector.ts
35193
- init_esm_shims();
35194
- init_logger();
35195
- function scoreAgent(task, profile) {
35196
- let score = 0;
35197
- const taskLower = task.toLowerCase();
35198
- if (profile.selectionMetadata?.primaryIntents) {
35199
- for (const intent of profile.selectionMetadata.primaryIntents) {
35200
- const intentKeywords = intent.toLowerCase().split(/\s+/);
35201
- const matchedKeywords = intentKeywords.filter(
35202
- (keyword) => taskLower.includes(keyword) && keyword.length > 3
35203
- );
35204
- if (matchedKeywords.length >= 2) {
35205
- score += 10;
35206
- } else if (matchedKeywords.length === 1) {
35207
- score += 5;
35208
- }
35209
- }
35210
- }
35211
- if (profile.selectionMetadata?.secondarySignals) {
35212
- for (const signal of profile.selectionMetadata.secondarySignals) {
35213
- if (taskLower.includes(signal.toLowerCase())) {
35214
- score += 5;
35215
- }
35216
- }
35217
- }
35218
- if (profile.selectionMetadata?.negativeIntents) {
35219
- for (const negative of profile.selectionMetadata.negativeIntents) {
35220
- const keywords = negative.split("(")[0]?.toLowerCase() || "";
35221
- const negativeKeywords = keywords.split(/\s+/).filter((k) => k.length > 3);
35222
- const matchedNegative = negativeKeywords.filter(
35223
- (keyword) => taskLower.includes(keyword)
35224
- );
35225
- if (matchedNegative.length >= 2) {
35226
- score -= 20;
35227
- }
35228
- }
35229
- }
35230
- if (profile.selectionMetadata?.redirectWhen) {
35231
- for (const rule of profile.selectionMetadata.redirectWhen) {
35232
- try {
35233
- const regex = new RegExp(rule.phrase, "i");
35234
- if (regex.test(task)) {
35235
- score -= 15;
35236
- }
35237
- } catch (error) {
35238
- logger.debug("Invalid regex pattern in redirectWhen rule", {
35239
- pattern: rule.phrase,
35240
- error: error instanceof Error ? error.message : String(error)
35241
- });
35242
- }
35243
- }
35244
- }
35245
- if (profile.abilitySelection?.taskBased) {
35246
- for (const keyword of Object.keys(profile.abilitySelection.taskBased)) {
35247
- if (taskLower.includes(keyword.toLowerCase())) {
35248
- score += 3;
35249
- }
35250
- }
35251
- }
35252
- return Math.max(0, score);
35253
- }
35254
- function buildRationale(task, profile) {
35255
- const rationale = [];
35256
- const taskLower = task.toLowerCase();
35257
- if (profile.selectionMetadata?.primaryIntents) {
35258
- const matchedIntents = profile.selectionMetadata.primaryIntents.filter((intent) => {
35259
- const keywords = intent.toLowerCase().split(/\s+/);
35260
- return keywords.some((k) => taskLower.includes(k) && k.length > 3);
35261
- });
35262
- if (matchedIntents.length > 0) {
35263
- rationale.push(`Matches: ${matchedIntents.slice(0, 2).join(", ")}`);
35264
- }
35265
- }
35266
- if (profile.selectionMetadata?.secondarySignals) {
35267
- const matchedSignals = profile.selectionMetadata.secondarySignals.filter(
35268
- (signal) => taskLower.includes(signal.toLowerCase())
35269
- );
35270
- if (matchedSignals.length > 0) {
35271
- rationale.push(`Keywords: ${matchedSignals.slice(0, 3).join(", ")}`);
35272
- }
35273
- }
35274
- if (profile.abilitySelection?.taskBased) {
35275
- const matchedAbilities = Object.keys(profile.abilitySelection.taskBased).filter(
35276
- (keyword) => taskLower.includes(keyword.toLowerCase())
35277
- );
35278
- if (matchedAbilities.length > 0) {
35279
- rationale.push(`Abilities: ${matchedAbilities.slice(0, 2).join(", ")}`);
35280
- }
35281
- }
35282
- if (rationale.length === 0) {
35283
- rationale.push("General capability match");
35284
- }
35285
- return rationale;
35286
- }
35287
- function getConfidence(score) {
35288
- if (score >= 30) return "high";
35289
- if (score >= 15) return "medium";
35290
- return "low";
35291
- }
35292
- var MIN_SELECTION_SCORE = 5;
35293
- var FALLBACK_AGENT = "standard";
35294
- var AgentSelector = class {
35295
- profileLoader;
35296
- constructor(profileLoader) {
35297
- this.profileLoader = profileLoader;
35298
- }
35299
- /**
35300
- * Select the best agent for a task
35301
- *
35302
- * @param task - Task description
35303
- * @returns Selection result with agent, score, confidence, and rationale
35304
- */
35305
- async selectAgent(task) {
35306
- logger.debug("[AgentSelector] Selecting agent for task", {
35307
- taskPreview: task.substring(0, 100)
35308
- });
35309
- const agentNames = await this.profileLoader.listProfiles();
35310
- if (agentNames.length === 0) {
35311
- logger.warn("[AgentSelector] No agents found, using fallback");
35312
- return this.createFallbackResult(task);
35313
- }
35314
- const profileResults = await Promise.all(
35315
- agentNames.map(async (name) => {
35316
- try {
35317
- const profile = await this.profileLoader.loadProfile(name);
35318
- return { name, profile, score: scoreAgent(task, profile) };
35319
- } catch (error) {
35320
- logger.debug(`[AgentSelector] Failed to load profile: ${name}`, { error });
35321
- return null;
35322
- }
35323
- })
35324
- );
35325
- const scoredAgents = profileResults.filter(
35326
- (result) => result !== null
35327
- );
35328
- if (scoredAgents.length === 0) {
35329
- logger.warn("[AgentSelector] Failed to load any profiles, using fallback");
35330
- return this.createFallbackResult(task);
35331
- }
35332
- scoredAgents.sort((a, b) => b.score - a.score);
35333
- const best = scoredAgents[0];
35334
- const alternatives = scoredAgents.slice(1, 4).map((a) => ({
35335
- agent: a.name,
35336
- score: a.score
35337
- }));
35338
- if (best.score < MIN_SELECTION_SCORE) {
35339
- logger.info("[AgentSelector] Best score below threshold, using fallback", {
35340
- bestAgent: best.name,
35341
- bestScore: best.score,
35342
- threshold: MIN_SELECTION_SCORE
35343
- });
35344
- const standardAgent = scoredAgents.find((a) => a.name === FALLBACK_AGENT);
35345
- if (standardAgent) {
35346
- return {
35347
- agent: standardAgent.name,
35348
- displayName: standardAgent.profile.displayName || standardAgent.name,
35349
- role: standardAgent.profile.role,
35350
- score: standardAgent.score,
35351
- confidence: "low",
35352
- rationale: ["No strong match found, using general-purpose agent"],
35353
- alternatives: scoredAgents.filter((a) => a.name !== FALLBACK_AGENT).slice(0, 3).map((a) => ({ agent: a.name, score: a.score })),
35354
- usedFallback: true
35355
- };
35356
- }
35357
- return {
35358
- agent: best.name,
35359
- displayName: best.profile.displayName || best.name,
35360
- role: best.profile.role,
35361
- score: best.score,
35362
- confidence: "low",
35363
- rationale: ["Low confidence match - consider specifying agent explicitly"],
35364
- alternatives,
35365
- usedFallback: false
35366
- };
35367
- }
35368
- const rationale = buildRationale(task, best.profile);
35369
- const confidence = getConfidence(best.score);
35370
- logger.info("[AgentSelector] Agent selected", {
35371
- agent: best.name,
35372
- score: best.score,
35373
- confidence,
35374
- rationale
35375
- });
35376
- return {
35377
- agent: best.name,
35378
- displayName: best.profile.displayName || best.name,
35379
- role: best.profile.role,
35380
- score: best.score,
35381
- confidence,
35382
- rationale,
35383
- alternatives,
35384
- usedFallback: false
35385
- };
35386
- }
35387
- /**
35388
- * Create a fallback result when no agents are available
35389
- */
35390
- async createFallbackResult(_task) {
35391
- try {
35392
- const profile = await this.profileLoader.loadProfile(FALLBACK_AGENT);
35393
- return {
35394
- agent: FALLBACK_AGENT,
35395
- displayName: profile.displayName || FALLBACK_AGENT,
35396
- role: profile.role,
35397
- score: 0,
35398
- confidence: "low",
35399
- rationale: ["No agents available, using fallback"],
35400
- alternatives: [],
35401
- usedFallback: true
35402
- };
35403
- } catch {
35404
- return {
35405
- agent: FALLBACK_AGENT,
35406
- displayName: "Standard",
35407
- role: "General-purpose agent",
35408
- score: 0,
35409
- confidence: "low",
35410
- rationale: ["No agents available"],
35411
- alternatives: [],
35412
- usedFallback: true
35413
- };
35414
- }
35415
- }
35416
- };
35417
-
35418
35465
  // src/core/stage-execution-controller.ts
35419
35466
  init_esm_shims();
35420
35467
 
package/dist/mcp/index.js CHANGED
@@ -8727,7 +8727,7 @@ var PRECOMPILED_CONFIG = {
8727
8727
  "enableFreeTierPrioritization": true,
8728
8728
  "enableWorkloadAwareRouting": true
8729
8729
  },
8730
- "version": "12.5.0"
8730
+ "version": "12.5.2"
8731
8731
  };
8732
8732
 
8733
8733
  // src/core/config/schemas.ts
@@ -20348,6 +20348,232 @@ ${context.task}`;
20348
20348
  }
20349
20349
  };
20350
20350
 
20351
+ // src/agents/agent-selector.ts
20352
+ init_esm_shims();
20353
+ init_logger();
20354
+ function scoreAgent(task, profile) {
20355
+ let score = 0;
20356
+ const taskLower = task.toLowerCase();
20357
+ if (profile.selectionMetadata?.primaryIntents) {
20358
+ for (const intent of profile.selectionMetadata.primaryIntents) {
20359
+ const intentKeywords = intent.toLowerCase().split(/\s+/);
20360
+ const matchedKeywords = intentKeywords.filter(
20361
+ (keyword) => taskLower.includes(keyword) && keyword.length > 3
20362
+ );
20363
+ if (matchedKeywords.length >= 2) {
20364
+ score += 10;
20365
+ } else if (matchedKeywords.length === 1) {
20366
+ score += 5;
20367
+ }
20368
+ }
20369
+ }
20370
+ if (profile.selectionMetadata?.secondarySignals) {
20371
+ for (const signal of profile.selectionMetadata.secondarySignals) {
20372
+ if (taskLower.includes(signal.toLowerCase())) {
20373
+ score += 5;
20374
+ }
20375
+ }
20376
+ }
20377
+ if (profile.selectionMetadata?.negativeIntents) {
20378
+ for (const negative of profile.selectionMetadata.negativeIntents) {
20379
+ const keywords = negative.split("(")[0]?.toLowerCase() || "";
20380
+ const negativeKeywords = keywords.split(/\s+/).filter((k) => k.length > 3);
20381
+ const matchedNegative = negativeKeywords.filter(
20382
+ (keyword) => taskLower.includes(keyword)
20383
+ );
20384
+ if (matchedNegative.length >= 2) {
20385
+ score -= 20;
20386
+ }
20387
+ }
20388
+ }
20389
+ if (profile.selectionMetadata?.redirectWhen) {
20390
+ for (const rule of profile.selectionMetadata.redirectWhen) {
20391
+ try {
20392
+ const regex = new RegExp(rule.phrase, "i");
20393
+ if (regex.test(task)) {
20394
+ score -= 15;
20395
+ }
20396
+ } catch (error) {
20397
+ logger.debug("Invalid regex pattern in redirectWhen rule", {
20398
+ pattern: rule.phrase,
20399
+ error: error instanceof Error ? error.message : String(error)
20400
+ });
20401
+ }
20402
+ }
20403
+ }
20404
+ if (profile.abilitySelection?.taskBased) {
20405
+ for (const keyword of Object.keys(profile.abilitySelection.taskBased)) {
20406
+ if (taskLower.includes(keyword.toLowerCase())) {
20407
+ score += 3;
20408
+ }
20409
+ }
20410
+ }
20411
+ return Math.max(0, score);
20412
+ }
20413
+ function buildRationale(task, profile) {
20414
+ const rationale = [];
20415
+ const taskLower = task.toLowerCase();
20416
+ if (profile.selectionMetadata?.primaryIntents) {
20417
+ const matchedIntents = profile.selectionMetadata.primaryIntents.filter((intent) => {
20418
+ const keywords = intent.toLowerCase().split(/\s+/);
20419
+ return keywords.some((k) => taskLower.includes(k) && k.length > 3);
20420
+ });
20421
+ if (matchedIntents.length > 0) {
20422
+ rationale.push(`Matches: ${matchedIntents.slice(0, 2).join(", ")}`);
20423
+ }
20424
+ }
20425
+ if (profile.selectionMetadata?.secondarySignals) {
20426
+ const matchedSignals = profile.selectionMetadata.secondarySignals.filter(
20427
+ (signal) => taskLower.includes(signal.toLowerCase())
20428
+ );
20429
+ if (matchedSignals.length > 0) {
20430
+ rationale.push(`Keywords: ${matchedSignals.slice(0, 3).join(", ")}`);
20431
+ }
20432
+ }
20433
+ if (profile.abilitySelection?.taskBased) {
20434
+ const matchedAbilities = Object.keys(profile.abilitySelection.taskBased).filter(
20435
+ (keyword) => taskLower.includes(keyword.toLowerCase())
20436
+ );
20437
+ if (matchedAbilities.length > 0) {
20438
+ rationale.push(`Abilities: ${matchedAbilities.slice(0, 2).join(", ")}`);
20439
+ }
20440
+ }
20441
+ if (rationale.length === 0) {
20442
+ rationale.push("General capability match");
20443
+ }
20444
+ return rationale;
20445
+ }
20446
+ function getConfidence(score) {
20447
+ if (score >= 30) return "high";
20448
+ if (score >= 15) return "medium";
20449
+ return "low";
20450
+ }
20451
+ var MIN_SELECTION_SCORE = 5;
20452
+ var FALLBACK_AGENT = "standard";
20453
+ var AgentSelector = class {
20454
+ profileLoader;
20455
+ constructor(profileLoader) {
20456
+ this.profileLoader = profileLoader;
20457
+ }
20458
+ /**
20459
+ * Select the best agent for a task
20460
+ *
20461
+ * @param task - Task description
20462
+ * @returns Selection result with agent, score, confidence, and rationale
20463
+ */
20464
+ async selectAgent(task) {
20465
+ logger.debug("[AgentSelector] Selecting agent for task", {
20466
+ taskPreview: task.substring(0, 100)
20467
+ });
20468
+ const agentNames = await this.profileLoader.listProfiles();
20469
+ if (agentNames.length === 0) {
20470
+ logger.warn("[AgentSelector] No agents found, using fallback");
20471
+ return this.createFallbackResult(task);
20472
+ }
20473
+ const profileResults = await Promise.all(
20474
+ agentNames.map(async (name) => {
20475
+ try {
20476
+ const profile = await this.profileLoader.loadProfile(name);
20477
+ return { name, profile, score: scoreAgent(task, profile) };
20478
+ } catch (error) {
20479
+ logger.debug(`[AgentSelector] Failed to load profile: ${name}`, { error });
20480
+ return null;
20481
+ }
20482
+ })
20483
+ );
20484
+ const scoredAgents = profileResults.filter(
20485
+ (result) => result !== null
20486
+ );
20487
+ if (scoredAgents.length === 0) {
20488
+ logger.warn("[AgentSelector] Failed to load any profiles, using fallback");
20489
+ return this.createFallbackResult(task);
20490
+ }
20491
+ scoredAgents.sort((a, b) => b.score - a.score);
20492
+ const best = scoredAgents[0];
20493
+ const alternatives = scoredAgents.slice(1, 4).map((a) => ({
20494
+ agent: a.name,
20495
+ score: a.score
20496
+ }));
20497
+ if (best.score < MIN_SELECTION_SCORE) {
20498
+ logger.info("[AgentSelector] Best score below threshold, using fallback", {
20499
+ bestAgent: best.name,
20500
+ bestScore: best.score,
20501
+ threshold: MIN_SELECTION_SCORE
20502
+ });
20503
+ const standardAgent = scoredAgents.find((a) => a.name === FALLBACK_AGENT);
20504
+ if (standardAgent) {
20505
+ return {
20506
+ agent: standardAgent.name,
20507
+ displayName: standardAgent.profile.displayName || standardAgent.name,
20508
+ role: standardAgent.profile.role,
20509
+ score: standardAgent.score,
20510
+ confidence: "low",
20511
+ rationale: ["No strong match found, using general-purpose agent"],
20512
+ alternatives: scoredAgents.filter((a) => a.name !== FALLBACK_AGENT).slice(0, 3).map((a) => ({ agent: a.name, score: a.score })),
20513
+ usedFallback: true
20514
+ };
20515
+ }
20516
+ return {
20517
+ agent: best.name,
20518
+ displayName: best.profile.displayName || best.name,
20519
+ role: best.profile.role,
20520
+ score: best.score,
20521
+ confidence: "low",
20522
+ rationale: ["Low confidence match - consider specifying agent explicitly"],
20523
+ alternatives,
20524
+ usedFallback: false
20525
+ };
20526
+ }
20527
+ const rationale = buildRationale(task, best.profile);
20528
+ const confidence = getConfidence(best.score);
20529
+ logger.info("[AgentSelector] Agent selected", {
20530
+ agent: best.name,
20531
+ score: best.score,
20532
+ confidence,
20533
+ rationale
20534
+ });
20535
+ return {
20536
+ agent: best.name,
20537
+ displayName: best.profile.displayName || best.name,
20538
+ role: best.profile.role,
20539
+ score: best.score,
20540
+ confidence,
20541
+ rationale,
20542
+ alternatives,
20543
+ usedFallback: false
20544
+ };
20545
+ }
20546
+ /**
20547
+ * Create a fallback result when no agents are available
20548
+ */
20549
+ async createFallbackResult(_task) {
20550
+ try {
20551
+ const profile = await this.profileLoader.loadProfile(FALLBACK_AGENT);
20552
+ return {
20553
+ agent: FALLBACK_AGENT,
20554
+ displayName: profile.displayName || FALLBACK_AGENT,
20555
+ role: profile.role,
20556
+ score: 0,
20557
+ confidence: "low",
20558
+ rationale: ["No agents available, using fallback"],
20559
+ alternatives: [],
20560
+ usedFallback: true
20561
+ };
20562
+ } catch {
20563
+ return {
20564
+ agent: FALLBACK_AGENT,
20565
+ displayName: "Standard",
20566
+ role: "General-purpose agent",
20567
+ score: 0,
20568
+ confidence: "low",
20569
+ rationale: ["No agents available"],
20570
+ alternatives: [],
20571
+ usedFallback: true
20572
+ };
20573
+ }
20574
+ }
20575
+ };
20576
+
20351
20577
  // src/mcp/tools/run-agent.ts
20352
20578
  init_logger();
20353
20579
 
@@ -20647,22 +20873,41 @@ async function buildAgentContext(agentName, task, deps, callerProvider, bestProv
20647
20873
  }
20648
20874
  function createRunAgentHandler(deps) {
20649
20875
  return async (input, context) => {
20650
- const { agent, task, provider, no_memory, mode = "auto" } = input;
20876
+ const { task, provider, no_memory, mode = "auto" } = input;
20877
+ let { agent } = input;
20651
20878
  if (context?.signal?.aborted) {
20652
20879
  throw new Error("Request was cancelled");
20653
20880
  }
20654
- validateAgentName(agent);
20655
20881
  validateStringParameter(task, "task", {
20656
20882
  required: true,
20657
20883
  minLength: 1,
20658
20884
  maxLength: 1e4
20659
20885
  });
20886
+ let autoSelected = false;
20887
+ if (!agent && deps.profileLoader) {
20888
+ const selector = new AgentSelector(deps.profileLoader);
20889
+ const selection = await selector.selectAgent(task);
20890
+ agent = selection.agent;
20891
+ autoSelected = true;
20892
+ logger.info("[MCP] run_agent auto-selected agent", {
20893
+ task: task.substring(0, 100),
20894
+ selectedAgent: agent,
20895
+ confidence: selection.confidence,
20896
+ score: selection.score,
20897
+ rationale: selection.rationale
20898
+ });
20899
+ }
20900
+ if (!agent) {
20901
+ throw new Error("Agent name is required when profileLoader is not available");
20902
+ }
20903
+ validateAgentName(agent);
20660
20904
  const actualProvider = mapMcpProviderToActual(provider);
20661
20905
  const session = deps.getSession?.() || null;
20662
20906
  const callerProvider = session?.normalizedProvider || "unknown";
20663
20907
  const callerActual = mapNormalizedCallerToActual(callerProvider);
20664
20908
  logger.info("[MCP] run_agent called (Smart Routing v10.5.0)", {
20665
20909
  agent,
20910
+ autoSelected,
20666
20911
  task: task.substring(0, 100),
20667
20912
  mcpProvider: provider,
20668
20913
  actualProvider,
@@ -21475,20 +21720,35 @@ init_logger();
21475
21720
  function createGetAgentContextHandler(deps) {
21476
21721
  return async (input) => {
21477
21722
  const {
21478
- agent,
21479
21723
  task,
21480
21724
  includeMemory = true,
21481
21725
  maxMemoryResults = 5
21482
21726
  } = input;
21727
+ let { agent } = input;
21483
21728
  const startTime = Date.now();
21484
- validateAgentName(agent);
21485
21729
  validateStringParameter(task, "task", {
21486
21730
  required: true,
21487
21731
  minLength: 1,
21488
21732
  maxLength: 1e4
21489
21733
  });
21734
+ let autoSelected = false;
21735
+ if (!agent) {
21736
+ const selector = new AgentSelector(deps.profileLoader);
21737
+ const selection = await selector.selectAgent(task);
21738
+ agent = selection.agent;
21739
+ autoSelected = true;
21740
+ logger.info("[MCP] get_agent_context auto-selected agent", {
21741
+ task: task.substring(0, 100),
21742
+ selectedAgent: agent,
21743
+ confidence: selection.confidence,
21744
+ score: selection.score,
21745
+ rationale: selection.rationale
21746
+ });
21747
+ }
21748
+ validateAgentName(agent);
21490
21749
  logger.info("[MCP] get_agent_context called", {
21491
21750
  agent,
21751
+ autoSelected,
21492
21752
  task: task.substring(0, 100),
21493
21753
  includeMemory,
21494
21754
  maxMemoryResults
@@ -25903,7 +26163,12 @@ async function resolveResourceTemplate(uri, variables, profileLoader, workspaceM
25903
26163
  profile.role ? `**Role:** ${profile.role}` : "",
25904
26164
  profile.abilities?.length ? `**Abilities:** ${profile.abilities.join(", ")}` : "",
25905
26165
  "",
25906
- profile.systemPrompt || "No system prompt defined."
26166
+ profile.systemPrompt || "No system prompt defined.",
26167
+ "",
26168
+ "## Profile JSON",
26169
+ "```json",
26170
+ JSON.stringify(profile, null, 2),
26171
+ "```"
25907
26172
  ].filter(Boolean).join("\n");
25908
26173
  return {
25909
26174
  uri: `agent/${agent}`,
@@ -25911,8 +26176,7 @@ async function resolveResourceTemplate(uri, variables, profileLoader, workspaceM
25911
26176
  description: `AutomatosX agent profile for ${agent}`,
25912
26177
  mimeType: "text/markdown",
25913
26178
  contents: [
25914
- { type: "text", text: summary },
25915
- { type: "application/json", json: profile }
26179
+ { type: "text", text: summary }
25916
26180
  ]
25917
26181
  };
25918
26182
  }
@@ -25930,8 +26194,7 @@ async function resolveResourceTemplate(uri, variables, profileLoader, workspaceM
25930
26194
  description: `Workspace ${isPrd ? "PRD" : "tmp"} file`,
25931
26195
  mimeType: "text/markdown",
25932
26196
  contents: [
25933
- { type: "text", text: content },
25934
- { type: "application/json", json: { path: path7, content, workspace: isPrd ? "PRD" : "tmp" } }
26197
+ { type: "text", text: content }
25935
26198
  ]
25936
26199
  };
25937
26200
  }
@@ -26039,17 +26302,24 @@ var McpServer = class _McpServer {
26039
26302
  return [
26040
26303
  {
26041
26304
  name: "run_agent",
26042
- description: "Execute an AutomatosX agent with a specific task. Uses Smart Routing: returns context for same-provider calls, spawns cross-provider execution.",
26305
+ description: `Execute an AutomatosX agent with a specific task.
26306
+
26307
+ v12.5.1: Agent auto-selection - if agent is omitted, system automatically selects the best agent based on task keywords.
26308
+ Uses Smart Routing: returns context for same-provider calls, spawns cross-provider execution.
26309
+
26310
+ Examples:
26311
+ - With agent: run_agent({ agent: "backend", task: "implement API" })
26312
+ - Auto-select: run_agent({ task: "fix bugs in the codebase" }) \u2192 selects "quality" agent`,
26043
26313
  inputSchema: {
26044
26314
  type: "object",
26045
26315
  properties: {
26046
- agent: { type: "string", description: "The name of the agent to run (e.g., backend, Paris, Bob)" },
26316
+ agent: { type: "string", description: "Optional: Agent name (e.g., backend, quality). If omitted, best agent is auto-selected based on task." },
26047
26317
  task: { type: "string", description: "The task for the agent to perform" },
26048
26318
  provider: { type: "string", description: "Optional: Override the AI provider", enum: ["claude", "gemini", "openai"] },
26049
26319
  no_memory: { type: "boolean", description: "Optional: Skip memory injection", default: false },
26050
26320
  mode: { type: "string", description: "Optional: Execution mode - auto (default), context (always return context), execute (always spawn)", enum: ["auto", "context", "execute"], default: "auto" }
26051
26321
  },
26052
- required: ["agent", "task"]
26322
+ required: ["task"]
26053
26323
  }
26054
26324
  },
26055
26325
  {
@@ -26161,16 +26431,18 @@ Use this tool first to understand what AutomatosX offers.`,
26161
26431
  // v10.5.0: Smart Routing - Explicit context retrieval
26162
26432
  {
26163
26433
  name: "get_agent_context",
26164
- description: "Get agent context without executing. Returns profile, relevant memory, and enhanced prompt for AI assistant to execute directly.",
26434
+ description: `Get agent context without executing. Returns profile, relevant memory, and enhanced prompt for AI assistant to execute directly.
26435
+
26436
+ v12.5.1: Agent auto-selection - if agent is omitted, system automatically selects the best agent based on task keywords.`,
26165
26437
  inputSchema: {
26166
26438
  type: "object",
26167
26439
  properties: {
26168
- agent: { type: "string", description: "The name of the agent (e.g., backend, Paris, Bob)" },
26440
+ agent: { type: "string", description: "Optional: Agent name (e.g., backend, quality). If omitted, best agent is auto-selected based on task." },
26169
26441
  task: { type: "string", description: "The task description for context building" },
26170
26442
  includeMemory: { type: "boolean", description: "Include relevant memory entries (default: true)", default: true },
26171
26443
  maxMemoryResults: { type: "number", description: "Maximum memory entries to return (default: 5)", default: 5 }
26172
26444
  },
26173
- required: ["agent", "task"]
26445
+ required: ["task"]
26174
26446
  }
26175
26447
  },
26176
26448
  // v11.3.5: Task Engine tools
@@ -26568,8 +26840,10 @@ Use this tool first to understand what AutomatosX offers.`,
26568
26840
  const profile = await this.profileLoader.loadProfile(agent);
26569
26841
  const content = [
26570
26842
  { type: "text", text: `System prompt for ${agent}:
26571
- ${profile.systemPrompt || "No system prompt defined."}` },
26572
- { type: "application/json", json: profile }
26843
+ ${profile.systemPrompt || "No system prompt defined."}
26844
+
26845
+ Profile:
26846
+ ${JSON.stringify(profile, null, 2)}` }
26573
26847
  ];
26574
26848
  return { jsonrpc: "2.0", id, result: { prompt: { name, description: "Agent context", arguments: [{ name: "agent", required: true }] }, content } };
26575
26849
  } catch (error) {
@@ -26586,8 +26860,10 @@ ${profile.systemPrompt || "No system prompt defined."}` },
26586
26860
  { type: "text", text: `AutomatosX MCP status:
26587
26861
  Version: ${summary.version}
26588
26862
  Providers: ${summary.providerCount}
26589
- Streaming: ${summary.streamingNotifications}` },
26590
- { type: "application/json", json: summary }
26863
+ Streaming: ${summary.streamingNotifications}
26864
+
26865
+ Details:
26866
+ ${JSON.stringify(summary, null, 2)}` }
26591
26867
  ];
26592
26868
  return { jsonrpc: "2.0", id, result: { prompt: { name, description: "AutomatosX status" }, content } };
26593
26869
  }
@@ -26612,11 +26888,15 @@ Streaming: ${summary.streamingNotifications}` },
26612
26888
  profile.role ? `**Role:** ${profile.role}` : "",
26613
26889
  profile.abilities?.length ? `**Abilities:** ${profile.abilities.join(", ")}` : "",
26614
26890
  "",
26615
- profile.systemPrompt || "No system prompt defined."
26891
+ profile.systemPrompt || "No system prompt defined.",
26892
+ "",
26893
+ "## Profile JSON",
26894
+ "```json",
26895
+ JSON.stringify(profile, null, 2),
26896
+ "```"
26616
26897
  ].filter(Boolean).join("\n");
26617
26898
  const contents = [
26618
- { type: "text", text: summary },
26619
- { type: "application/json", json: profile }
26899
+ { type: "text", text: summary }
26620
26900
  ];
26621
26901
  return { jsonrpc: "2.0", id, result: { uri, mimeType: "text/markdown", contents } };
26622
26902
  } catch (error) {
@@ -26659,15 +26939,8 @@ Streaming: ${summary.streamingNotifications}` },
26659
26939
  }
26660
26940
  /** Create MCP tool response wrapper */
26661
26941
  createToolResponse(id, result, isError = false) {
26662
- let content;
26663
- if (typeof result === "string") {
26664
- content = [{ type: "text", text: result }];
26665
- } else {
26666
- content = [
26667
- { type: "application/json", json: result },
26668
- { type: "text", text: JSON.stringify(result, null, 2) }
26669
- ];
26670
- }
26942
+ const text = typeof result === "string" ? result : JSON.stringify(result, null, 2);
26943
+ const content = [{ type: "text", text }];
26671
26944
  const response = { content, ...isError && { isError } };
26672
26945
  return { jsonrpc: "2.0", id, result: response };
26673
26946
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defai.digital/automatosx",
3
- "version": "12.5.0",
3
+ "version": "12.5.2",
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": {