agentic-flow 1.0.7 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,451 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Agent Management CLI - Create, list, and manage custom agents
4
+ * Supports both npm package agents and local .claude/agents
5
+ * Includes conflict detection and deduplication
6
+ */
7
+ import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, statSync } from 'fs';
8
+ import { join, dirname, relative, extname } from 'path';
9
+ import { fileURLToPath } from 'url';
10
+ import { createInterface } from 'readline';
11
+ // Get package root and default paths
12
+ const __filename = fileURLToPath(import.meta.url);
13
+ const __dirname = dirname(__filename);
14
+ const packageRoot = join(__dirname, '../..');
15
+ const packageAgentsDir = join(packageRoot, '.claude/agents');
16
+ const localAgentsDir = join(process.cwd(), '.claude/agents');
17
+ export class AgentManager {
18
+ /**
19
+ * Find all agent files from both package and local directories
20
+ * Deduplicates by preferring local over package
21
+ */
22
+ findAllAgents() {
23
+ const agents = new Map();
24
+ // Load package agents first
25
+ if (existsSync(packageAgentsDir)) {
26
+ this.scanAgentsDirectory(packageAgentsDir, 'package', agents);
27
+ }
28
+ // Load local agents (overrides package agents with same relative path)
29
+ if (existsSync(localAgentsDir)) {
30
+ this.scanAgentsDirectory(localAgentsDir, 'local', agents);
31
+ }
32
+ return agents;
33
+ }
34
+ /**
35
+ * Recursively scan directory for agent markdown files
36
+ */
37
+ scanAgentsDirectory(dir, source, agents) {
38
+ const baseDir = source === 'package' ? packageAgentsDir : localAgentsDir;
39
+ try {
40
+ const entries = readdirSync(dir);
41
+ for (const entry of entries) {
42
+ const fullPath = join(dir, entry);
43
+ const stat = statSync(fullPath);
44
+ if (stat.isDirectory()) {
45
+ this.scanAgentsDirectory(fullPath, source, agents);
46
+ }
47
+ else if (extname(entry) === '.md' && entry !== 'README.md') {
48
+ const relativePath = relative(baseDir, fullPath);
49
+ const agentInfo = this.parseAgentFile(fullPath, source, relativePath);
50
+ if (agentInfo) {
51
+ // Use relative path as key for deduplication
52
+ // Local agents override package agents
53
+ const existingAgent = agents.get(relativePath);
54
+ if (!existingAgent || source === 'local') {
55
+ agents.set(relativePath, agentInfo);
56
+ }
57
+ }
58
+ }
59
+ }
60
+ }
61
+ catch (error) {
62
+ console.error(`Error scanning directory ${dir}: ${error.message}`);
63
+ }
64
+ }
65
+ /**
66
+ * Parse agent markdown file and extract metadata
67
+ */
68
+ parseAgentFile(filePath, source, relativePath) {
69
+ try {
70
+ const content = readFileSync(filePath, 'utf-8');
71
+ // Try frontmatter format first
72
+ const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
73
+ if (frontmatterMatch) {
74
+ const [, frontmatter] = frontmatterMatch;
75
+ const meta = {};
76
+ frontmatter.split('\n').forEach(line => {
77
+ const match = line.match(/^(\w+):\s*(.+)$/);
78
+ if (match) {
79
+ const [, key, value] = match;
80
+ meta[key] = value.replace(/^["']|["']$/g, '');
81
+ }
82
+ });
83
+ if (meta.name && meta.description) {
84
+ return {
85
+ name: meta.name,
86
+ description: meta.description,
87
+ category: this.getCategoryFromPath(relativePath),
88
+ filePath,
89
+ source,
90
+ relativePath
91
+ };
92
+ }
93
+ }
94
+ // Fallback: extract from markdown headers
95
+ const nameMatch = content.match(/^#\s+(.+)$/m);
96
+ const descMatch = content.match(/^##\s+Description\s*\n\s*(.+)$/m);
97
+ if (nameMatch) {
98
+ return {
99
+ name: nameMatch[1].trim(),
100
+ description: descMatch ? descMatch[1].trim() : 'No description available',
101
+ category: this.getCategoryFromPath(relativePath),
102
+ filePath,
103
+ source,
104
+ relativePath
105
+ };
106
+ }
107
+ return null;
108
+ }
109
+ catch (error) {
110
+ return null;
111
+ }
112
+ }
113
+ /**
114
+ * Get category from file path
115
+ */
116
+ getCategoryFromPath(relativePath) {
117
+ const parts = relativePath.split('/');
118
+ return parts.length > 1 ? parts[0] : 'custom';
119
+ }
120
+ /**
121
+ * List all agents with deduplication
122
+ */
123
+ list(format = 'summary') {
124
+ const agents = this.findAllAgents();
125
+ if (format === 'json') {
126
+ const agentList = Array.from(agents.values()).map(a => ({
127
+ name: a.name,
128
+ description: a.description,
129
+ category: a.category,
130
+ source: a.source,
131
+ path: a.relativePath
132
+ }));
133
+ console.log(JSON.stringify(agentList, null, 2));
134
+ return;
135
+ }
136
+ // Group by category
137
+ const byCategory = new Map();
138
+ for (const agent of agents.values()) {
139
+ const category = agent.category;
140
+ if (!byCategory.has(category)) {
141
+ byCategory.set(category, []);
142
+ }
143
+ byCategory.get(category).push(agent);
144
+ }
145
+ // Sort categories
146
+ const sortedCategories = Array.from(byCategory.keys()).sort();
147
+ console.log('\n📦 Available Agents:');
148
+ console.log('═'.repeat(80));
149
+ for (const category of sortedCategories) {
150
+ const categoryAgents = byCategory.get(category).sort((a, b) => a.name.localeCompare(b.name));
151
+ console.log(`\n${category.toUpperCase()}:`);
152
+ for (const agent of categoryAgents) {
153
+ const sourceIcon = agent.source === 'local' ? '📝' : '📦';
154
+ if (format === 'detailed') {
155
+ console.log(` ${sourceIcon} ${agent.name}`);
156
+ console.log(` ${agent.description}`);
157
+ console.log(` Source: ${agent.source} (${agent.relativePath})`);
158
+ }
159
+ else {
160
+ console.log(` ${sourceIcon} ${agent.name.padEnd(30)} ${agent.description.substring(0, 45)}...`);
161
+ }
162
+ }
163
+ }
164
+ console.log(`\n📊 Total: ${agents.size} agents`);
165
+ console.log(` 📝 Local: ${Array.from(agents.values()).filter(a => a.source === 'local').length}`);
166
+ console.log(` 📦 Package: ${Array.from(agents.values()).filter(a => a.source === 'package').length}`);
167
+ console.log('');
168
+ }
169
+ /**
170
+ * Create a new agent
171
+ */
172
+ async create(options) {
173
+ let { name, description, category, systemPrompt, tools } = options;
174
+ // Interactive mode
175
+ if (options.interactive) {
176
+ const rl = createInterface({
177
+ input: process.stdin,
178
+ output: process.stdout
179
+ });
180
+ const question = (prompt) => {
181
+ return new Promise(resolve => rl.question(prompt, resolve));
182
+ };
183
+ console.log('\n🤖 Create New Agent');
184
+ console.log('═'.repeat(80));
185
+ name = await question('Agent name (e.g., my-custom-agent): ');
186
+ description = await question('Description: ');
187
+ category = await question('Category (default: custom): ') || 'custom';
188
+ systemPrompt = await question('System prompt: ');
189
+ const toolsInput = await question('Tools (comma-separated, optional): ');
190
+ tools = toolsInput ? toolsInput.split(',').map(t => t.trim()) : [];
191
+ rl.close();
192
+ }
193
+ // Validate required fields
194
+ if (!name || !description || !systemPrompt) {
195
+ throw new Error('Name, description, and system prompt are required');
196
+ }
197
+ // Normalize name to kebab-case
198
+ const kebabName = name.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, '');
199
+ // Check for conflicts
200
+ const agents = this.findAllAgents();
201
+ const conflictingAgent = Array.from(agents.values()).find(a => a.name.toLowerCase() === kebabName.toLowerCase());
202
+ if (conflictingAgent) {
203
+ console.log(`\n⚠️ Warning: Agent "${conflictingAgent.name}" already exists`);
204
+ console.log(` Source: ${conflictingAgent.source}`);
205
+ console.log(` Path: ${conflictingAgent.relativePath}`);
206
+ const rl = createInterface({
207
+ input: process.stdin,
208
+ output: process.stdout
209
+ });
210
+ const answer = await new Promise(resolve => {
211
+ rl.question('\nCreate in local .claude/agents anyway? (y/N): ', resolve);
212
+ });
213
+ rl.close();
214
+ if (answer.toLowerCase() !== 'y') {
215
+ console.log('Cancelled.');
216
+ return;
217
+ }
218
+ }
219
+ // Create directory structure
220
+ const targetCategory = category || 'custom';
221
+ const targetDir = join(localAgentsDir, targetCategory);
222
+ if (!existsSync(targetDir)) {
223
+ mkdirSync(targetDir, { recursive: true });
224
+ }
225
+ // Generate markdown content
226
+ const markdown = this.generateAgentMarkdown({
227
+ name: kebabName,
228
+ description: description,
229
+ category: targetCategory,
230
+ tools
231
+ }, systemPrompt);
232
+ const filePath = join(targetDir, `${kebabName}.md`);
233
+ if (existsSync(filePath)) {
234
+ throw new Error(`Agent file already exists at ${filePath}`);
235
+ }
236
+ writeFileSync(filePath, markdown, 'utf8');
237
+ console.log(`\n✅ Agent created successfully!`);
238
+ console.log(` Name: ${kebabName}`);
239
+ console.log(` Category: ${targetCategory}`);
240
+ console.log(` Path: ${filePath}`);
241
+ console.log(`\n📝 Usage:`);
242
+ console.log(` npx agentic-flow --agent ${kebabName} --task "Your task"`);
243
+ console.log('');
244
+ }
245
+ /**
246
+ * Generate agent markdown with frontmatter
247
+ */
248
+ generateAgentMarkdown(metadata, systemPrompt) {
249
+ const toolsLine = metadata.tools && metadata.tools.length > 0
250
+ ? `tools: ${metadata.tools.join(', ')}`
251
+ : '';
252
+ return `---
253
+ name: ${metadata.name}
254
+ description: ${metadata.description}
255
+ ${metadata.color ? `color: ${metadata.color}` : ''}
256
+ ${toolsLine}
257
+ ---
258
+
259
+ ${systemPrompt}
260
+
261
+ ## Usage
262
+
263
+ \`\`\`bash
264
+ npx agentic-flow --agent ${metadata.name} --task "Your task"
265
+ \`\`\`
266
+
267
+ ## Examples
268
+
269
+ ### Example 1
270
+ \`\`\`bash
271
+ npx agentic-flow --agent ${metadata.name} --task "Example task description"
272
+ \`\`\`
273
+
274
+ ---
275
+ *Created: ${new Date().toISOString()}*
276
+ *Source: local*
277
+ `;
278
+ }
279
+ /**
280
+ * Get information about a specific agent
281
+ */
282
+ info(name) {
283
+ const agents = this.findAllAgents();
284
+ const agent = Array.from(agents.values()).find(a => a.name.toLowerCase() === name.toLowerCase());
285
+ if (!agent) {
286
+ console.log(`\n❌ Agent "${name}" not found`);
287
+ console.log('\nUse "agentic-flow agent list" to see all available agents\n');
288
+ return;
289
+ }
290
+ console.log('\n📋 Agent Information');
291
+ console.log('═'.repeat(80));
292
+ console.log(`Name: ${agent.name}`);
293
+ console.log(`Description: ${agent.description}`);
294
+ console.log(`Category: ${agent.category}`);
295
+ console.log(`Source: ${agent.source === 'local' ? '📝 Local' : '📦 Package'}`);
296
+ console.log(`Path: ${agent.relativePath}`);
297
+ console.log(`Full Path: ${agent.filePath}`);
298
+ console.log('');
299
+ // Show content preview
300
+ try {
301
+ const content = readFileSync(agent.filePath, 'utf-8');
302
+ console.log('Preview:');
303
+ console.log('─'.repeat(80));
304
+ const lines = content.split('\n').slice(0, 20);
305
+ console.log(lines.join('\n'));
306
+ if (content.split('\n').length > 20) {
307
+ console.log('...');
308
+ }
309
+ console.log('');
310
+ }
311
+ catch (error) {
312
+ console.log('Could not read agent file\n');
313
+ }
314
+ }
315
+ /**
316
+ * Check for conflicts between package and local agents
317
+ */
318
+ checkConflicts() {
319
+ console.log('\n🔍 Checking for agent conflicts...');
320
+ console.log('═'.repeat(80));
321
+ const packageAgents = new Map();
322
+ const localAgents = new Map();
323
+ if (existsSync(packageAgentsDir)) {
324
+ this.scanAgentsDirectory(packageAgentsDir, 'package', packageAgents);
325
+ }
326
+ if (existsSync(localAgentsDir)) {
327
+ this.scanAgentsDirectory(localAgentsDir, 'local', localAgents);
328
+ }
329
+ // Find conflicts (same relative path in both)
330
+ const conflicts = [];
331
+ for (const [relativePath, localAgent] of localAgents) {
332
+ const packageAgent = packageAgents.get(relativePath);
333
+ if (packageAgent) {
334
+ conflicts.push({ path: relativePath, package: packageAgent, local: localAgent });
335
+ }
336
+ }
337
+ if (conflicts.length === 0) {
338
+ console.log('\n✅ No conflicts found!\n');
339
+ return;
340
+ }
341
+ console.log(`\n⚠️ Found ${conflicts.length} conflict(s):\n`);
342
+ for (const conflict of conflicts) {
343
+ console.log(`📁 ${conflict.path}`);
344
+ console.log(` 📦 Package: ${conflict.package.name}`);
345
+ console.log(` ${conflict.package.description}`);
346
+ console.log(` 📝 Local: ${conflict.local.name}`);
347
+ console.log(` ${conflict.local.description}`);
348
+ console.log(` ℹ️ Local version will be used\n`);
349
+ }
350
+ }
351
+ }
352
+ /**
353
+ * CLI command handler
354
+ */
355
+ export async function handleAgentCommand(args) {
356
+ const command = args[0];
357
+ const manager = new AgentManager();
358
+ switch (command) {
359
+ case undefined:
360
+ case 'help':
361
+ console.log(`
362
+ 🤖 Agent Management CLI
363
+
364
+ USAGE:
365
+ npx agentic-flow agent <command> [options]
366
+
367
+ COMMANDS:
368
+ list [format] List all available agents
369
+ format: summary (default), detailed, json
370
+
371
+ create Create a new agent interactively
372
+ create --name NAME Create agent with CLI arguments
373
+ --description DESC
374
+ --category CAT
375
+ --prompt PROMPT
376
+ [--tools TOOLS]
377
+
378
+ info <name> Show detailed information about an agent
379
+
380
+ conflicts Check for conflicts between package and local agents
381
+
382
+ help Show this help message
383
+
384
+ EXAMPLES:
385
+ # List all agents
386
+ npx agentic-flow agent list
387
+
388
+ # List with details
389
+ npx agentic-flow agent list detailed
390
+
391
+ # Create agent interactively
392
+ npx agentic-flow agent create
393
+
394
+ # Create agent with CLI
395
+ npx agentic-flow agent create --name my-agent --description "My custom agent" --prompt "You are a helpful assistant"
396
+
397
+ # Get agent info
398
+ npx agentic-flow agent info coder
399
+
400
+ # Check conflicts
401
+ npx agentic-flow agent conflicts
402
+
403
+ AGENT LOCATIONS:
404
+ 📦 Package: ${packageAgentsDir}
405
+ 📝 Local: ${localAgentsDir}
406
+
407
+ Note: Local agents override package agents with the same path.
408
+ `);
409
+ break;
410
+ case 'list':
411
+ const format = args[1] || 'summary';
412
+ manager.list(format);
413
+ break;
414
+ case 'create':
415
+ const nameIdx = args.indexOf('--name');
416
+ const descIdx = args.indexOf('--description');
417
+ const catIdx = args.indexOf('--category');
418
+ const promptIdx = args.indexOf('--prompt');
419
+ const toolsIdx = args.indexOf('--tools');
420
+ if (nameIdx === -1 || descIdx === -1 || promptIdx === -1) {
421
+ // Interactive mode
422
+ await manager.create({ interactive: true });
423
+ }
424
+ else {
425
+ // CLI mode
426
+ await manager.create({
427
+ name: args[nameIdx + 1],
428
+ description: args[descIdx + 1],
429
+ category: catIdx !== -1 ? args[catIdx + 1] : 'custom',
430
+ systemPrompt: args[promptIdx + 1],
431
+ tools: toolsIdx !== -1 ? args[toolsIdx + 1].split(',').map(t => t.trim()) : []
432
+ });
433
+ }
434
+ break;
435
+ case 'info':
436
+ if (!args[1]) {
437
+ console.log('\n❌ Please specify an agent name\n');
438
+ console.log('Usage: npx agentic-flow agent info <name>\n');
439
+ process.exit(1);
440
+ }
441
+ manager.info(args[1]);
442
+ break;
443
+ case 'conflicts':
444
+ manager.checkConflicts();
445
+ break;
446
+ default:
447
+ console.log(`\n❌ Unknown command: ${command}\n`);
448
+ console.log('Use "npx agentic-flow agent help" for usage information\n');
449
+ process.exit(1);
450
+ }
451
+ }
package/dist/cli-proxy.js CHANGED
@@ -10,6 +10,8 @@ import { parseArgs } from "./utils/cli.js";
10
10
  import { getAgent, listAgents } from "./utils/agentLoader.js";
11
11
  import { directApiAgent } from "./agents/directApiAgent.js";
12
12
  import { handleConfigCommand } from "./cli/config-wizard.js";
13
+ import { handleAgentCommand } from "./cli/agent-manager.js";
14
+ import { ModelOptimizer } from "./utils/modelOptimizer.js";
13
15
  import { readFileSync } from 'fs';
14
16
  import { resolve, dirname } from 'path';
15
17
  import { fileURLToPath } from 'url';
@@ -36,6 +38,12 @@ class AgenticFlowCLI {
36
38
  await handleConfigCommand(configArgs);
37
39
  process.exit(0);
38
40
  }
41
+ if (options.mode === 'agent-manager') {
42
+ // Handle agent management commands
43
+ const agentArgs = process.argv.slice(3); // Skip 'node', 'cli-proxy.js', 'agent'
44
+ await handleAgentCommand(agentArgs);
45
+ process.exit(0);
46
+ }
39
47
  if (options.mode === 'mcp') {
40
48
  // Run standalone MCP server directly
41
49
  const { spawn } = await import('child_process');
@@ -55,6 +63,25 @@ class AgenticFlowCLI {
55
63
  process.on('SIGTERM', () => proc.kill('SIGTERM'));
56
64
  return;
57
65
  }
66
+ // Apply model optimization if requested
67
+ if (options.optimize && options.agent && options.task) {
68
+ const recommendation = ModelOptimizer.optimize({
69
+ agent: options.agent,
70
+ task: options.task,
71
+ priority: options.optimizePriority || 'balanced',
72
+ maxCostPerTask: options.maxCost
73
+ });
74
+ // Display recommendation
75
+ ModelOptimizer.displayRecommendation(recommendation);
76
+ // Apply recommendation to options
77
+ if (!options.provider || options.optimize) {
78
+ options.provider = recommendation.provider;
79
+ }
80
+ if (!options.model || options.optimize) {
81
+ options.model = recommendation.model;
82
+ }
83
+ console.log(`✅ Using optimized model: ${recommendation.modelName}\n`);
84
+ }
58
85
  // Determine if we should use OpenRouter
59
86
  const useOpenRouter = this.shouldUseOpenRouter(options);
60
87
  try {
@@ -235,6 +262,7 @@ USAGE:
235
262
  COMMANDS:
236
263
  config [subcommand] Manage environment configuration (interactive wizard)
237
264
  mcp <command> [server] Manage MCP servers (start, stop, status, list)
265
+ agent <command> Agent management (list, create, info, conflicts)
238
266
  --list, -l List all available agents
239
267
  --agent, -a <name> Run specific agent mode
240
268
 
@@ -254,12 +282,51 @@ MCP COMMANDS:
254
282
 
255
283
  Available servers: claude-flow, flow-nexus, agentic-payments, all (default)
256
284
 
285
+ AGENT COMMANDS:
286
+ npx agentic-flow agent list [format] List all agents (summary/detailed/json)
287
+ npx agentic-flow agent create Create new custom agent (interactive)
288
+ npx agentic-flow agent info <name> Show detailed agent information
289
+ npx agentic-flow agent conflicts Check for package/local conflicts
290
+
257
291
  OPTIONS:
258
- --task, -t <task> Task description for agent mode
259
- --model, -m <model> Model to use (triggers OpenRouter if contains "/")
260
- --provider, -p <name> Provider to use (anthropic, openrouter, onnx)
261
- --stream, -s Enable real-time streaming output
262
- --help, -h Show this help message
292
+ --task, -t <task> Task description for agent mode
293
+ --model, -m <model> Model to use (triggers OpenRouter if contains "/")
294
+ --provider, -p <name> Provider to use (anthropic, openrouter, onnx)
295
+ --stream, -s Enable real-time streaming output
296
+ --help, -h Show this help message
297
+
298
+ API CONFIGURATION:
299
+ --anthropic-key <key> Override ANTHROPIC_API_KEY environment variable
300
+ --openrouter-key <key> Override OPENROUTER_API_KEY environment variable
301
+
302
+ AGENT BEHAVIOR:
303
+ --temperature <0.0-1.0> Sampling temperature (creativity control)
304
+ --max-tokens <number> Maximum tokens in response
305
+
306
+ DIRECTORY:
307
+ --agents-dir <path> Custom agents directory (default: .claude/agents)
308
+
309
+ OUTPUT:
310
+ --output <text|json|md> Output format (text/json/markdown)
311
+ --verbose Enable verbose logging for debugging
312
+
313
+ EXECUTION:
314
+ --timeout <ms> Execution timeout in milliseconds
315
+ --retry Auto-retry on transient errors
316
+
317
+ MODEL OPTIMIZATION (NEW!):
318
+ --optimize, -O Auto-select best model for agent/task based on priorities
319
+ --priority <type> Optimization priority:
320
+ • quality - Best results (Claude Sonnet 4.5, GPT-4o)
321
+ • balanced - Mix quality/cost (DeepSeek R1, Gemini 2.5 Flash) [default]
322
+ • cost - Cheapest (DeepSeek Chat V3, Llama 3.1 8B)
323
+ • speed - Fastest responses (Gemini 2.5 Flash)
324
+ • privacy - Local only (ONNX Phi-4, no cloud)
325
+ --max-cost <dollars> Maximum cost per task (e.g., 0.001 = $0.001/task budget cap)
326
+
327
+ Optimization analyzes agent type + task complexity to recommend best model.
328
+ Example savings: DeepSeek R1 costs 85% less than Claude Sonnet 4.5 with similar quality.
329
+ See docs/agentic-flow/benchmarks/MODEL_CAPABILITIES.md for full comparison.
263
330
 
264
331
  EXAMPLES:
265
332
  # MCP Server Management
@@ -274,6 +341,12 @@ EXAMPLES:
274
341
  npx agentic-flow --agent coder --task "Create REST API" --model "meta-llama/llama-3.1-8b-instruct"
275
342
  npx agentic-flow --agent coder --task "Create code" --provider onnx
276
343
 
344
+ # Model Optimization (Auto-select best model)
345
+ npx agentic-flow --agent coder --task "Build API" --optimize
346
+ npx agentic-flow --agent coder --task "Build API" --optimize --priority cost
347
+ npx agentic-flow --agent reviewer --task "Security audit" --optimize --priority quality
348
+ npx agentic-flow --agent coder --task "Simple function" --optimize --max-cost 0.001
349
+
277
350
  ENVIRONMENT VARIABLES:
278
351
  ANTHROPIC_API_KEY Anthropic API key (for Claude models)
279
352
  OPENROUTER_API_KEY OpenRouter API key (for alternative models)
@@ -288,11 +361,17 @@ OPENROUTER MODELS:
288
361
  - google/gemini-2.5-flash-preview (fastest)
289
362
  - See https://openrouter.ai/models for full list
290
363
 
291
- MCP TOOLS (203+ available):
292
- claude-flow-sdk: 6 in-process tools (memory, swarm coordination)
364
+ MCP TOOLS (213+ available):
365
+ agentic-flow: 7 tools (agent execution, creation, management, model optimization)
293
366
  • claude-flow: 101 tools (neural networks, GitHub, workflows, DAA)
294
367
  • flow-nexus: 96 cloud tools (sandboxes, distributed swarms, templates)
295
- • agentic-payments: Payment authorization and multi-agent consensus
368
+ • agentic-payments: 6 tools (payment authorization, multi-agent consensus)
369
+
370
+ OPTIMIZATION BENEFITS:
371
+ 💰 Cost Savings: 85-98% cheaper models for same quality tasks
372
+ 🎯 Smart Selection: Agent-aware (coder needs quality ≥85, researcher flexible)
373
+ 📊 10+ Models: Claude, GPT-4o, Gemini, DeepSeek, Llama, ONNX local
374
+ ⚡ Zero Overhead: <5ms decision time, no API calls during optimization
296
375
 
297
376
  For more information: https://github.com/ruvnet/agentic-flow
298
377
  `);