agentic-flow 1.0.4 → 1.0.6
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 +60 -5
- package/dist/agents/directApiAgent.js +46 -10
- package/dist/cli/config-wizard.js +359 -0
- package/dist/cli-proxy.js +16 -0
- package/dist/mcp/standalone-stdio.js +8 -11
- package/dist/utils/cli.js +5 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -40,7 +40,7 @@ Traditional AI frameworks require persistent infrastructure and complex orchestr
|
|
|
40
40
|
|
|
41
41
|
## 🚀 Quick Start
|
|
42
42
|
|
|
43
|
-
###
|
|
43
|
+
### Installation
|
|
44
44
|
|
|
45
45
|
```bash
|
|
46
46
|
# Global installation
|
|
@@ -48,11 +48,29 @@ npm install -g agentic-flow
|
|
|
48
48
|
|
|
49
49
|
# Or use directly with npx (no installation)
|
|
50
50
|
npx agentic-flow --help
|
|
51
|
+
```
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
### Configuration Wizard (Interactive Setup)
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# Launch interactive configuration wizard
|
|
57
|
+
npx agentic-flow config
|
|
58
|
+
|
|
59
|
+
# Or use direct commands
|
|
60
|
+
npx agentic-flow config set ANTHROPIC_API_KEY sk-ant-xxxxx
|
|
61
|
+
npx agentic-flow config set PROVIDER anthropic
|
|
62
|
+
npx agentic-flow config list
|
|
54
63
|
```
|
|
55
64
|
|
|
65
|
+
The wizard helps you configure:
|
|
66
|
+
- **API Keys** - Anthropic, OpenRouter with validation
|
|
67
|
+
- **Provider Settings** - Choose default provider (anthropic/openrouter/onnx)
|
|
68
|
+
- **Model Selection** - Set default models
|
|
69
|
+
- **Custom Paths** - Configure agents directory
|
|
70
|
+
- **Advanced Options** - Proxy port, feature flags
|
|
71
|
+
|
|
72
|
+
All configuration is saved to `.env` with helpful comments.
|
|
73
|
+
|
|
56
74
|
### Your First Agent (Local Execution)
|
|
57
75
|
|
|
58
76
|
```bash
|
|
@@ -429,6 +447,40 @@ Docker: Infrastructure costs (AWS/GCP/Azure) + Claude API costs.*
|
|
|
429
447
|
|
|
430
448
|
## 📋 Commands
|
|
431
449
|
|
|
450
|
+
### Configuration Management
|
|
451
|
+
|
|
452
|
+
```bash
|
|
453
|
+
# Interactive configuration wizard
|
|
454
|
+
npx agentic-flow config
|
|
455
|
+
|
|
456
|
+
# Direct configuration commands
|
|
457
|
+
npx agentic-flow config set ANTHROPIC_API_KEY sk-ant-xxxxx
|
|
458
|
+
npx agentic-flow config set OPENROUTER_API_KEY sk-or-v1-xxxxx
|
|
459
|
+
npx agentic-flow config set PROVIDER openrouter
|
|
460
|
+
npx agentic-flow config set COMPLETION_MODEL meta-llama/llama-3.1-8b-instruct
|
|
461
|
+
|
|
462
|
+
# View configuration
|
|
463
|
+
npx agentic-flow config list
|
|
464
|
+
npx agentic-flow config get PROVIDER
|
|
465
|
+
|
|
466
|
+
# Manage configuration
|
|
467
|
+
npx agentic-flow config delete OPENROUTER_API_KEY
|
|
468
|
+
npx agentic-flow config reset
|
|
469
|
+
|
|
470
|
+
# Get help
|
|
471
|
+
npx agentic-flow config help
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
**Available Configuration Keys:**
|
|
475
|
+
- `ANTHROPIC_API_KEY` - Anthropic API key (validated: must start with `sk-ant-`)
|
|
476
|
+
- `OPENROUTER_API_KEY` - OpenRouter API key (validated: must start with `sk-or-`)
|
|
477
|
+
- `COMPLETION_MODEL` - Default model name
|
|
478
|
+
- `PROVIDER` - Default provider (anthropic, openrouter, onnx)
|
|
479
|
+
- `AGENTS_DIR` - Custom agents directory path
|
|
480
|
+
- `PROXY_PORT` - Proxy server port (default: 3000)
|
|
481
|
+
- `USE_OPENROUTER` - Force OpenRouter usage (true/false)
|
|
482
|
+
- `USE_ONNX` - Use ONNX local inference (true/false)
|
|
483
|
+
|
|
432
484
|
### Basic Operations (Works Locally, Docker, Cloud)
|
|
433
485
|
|
|
434
486
|
```bash
|
|
@@ -445,12 +497,15 @@ npx agentic-flow --agent coder --task "Build API" --stream
|
|
|
445
497
|
npx agentic-flow # Requires TOPIC, DIFF, DATASET env vars
|
|
446
498
|
```
|
|
447
499
|
|
|
448
|
-
### Environment Configuration
|
|
500
|
+
### Environment Configuration (Alternative to Config Wizard)
|
|
449
501
|
|
|
450
502
|
```bash
|
|
451
|
-
# Required
|
|
503
|
+
# Required (use config wizard instead for better UX)
|
|
452
504
|
export ANTHROPIC_API_KEY=sk-ant-...
|
|
453
505
|
|
|
506
|
+
# Or use OpenRouter
|
|
507
|
+
export OPENROUTER_API_KEY=sk-or-v1-...
|
|
508
|
+
|
|
454
509
|
# Agent mode (optional)
|
|
455
510
|
export AGENT=researcher
|
|
456
511
|
export TASK="Your task description"
|
|
@@ -3,9 +3,24 @@ import Anthropic from '@anthropic-ai/sdk';
|
|
|
3
3
|
import { logger } from '../utils/logger.js';
|
|
4
4
|
import { withRetry } from '../utils/retry.js';
|
|
5
5
|
import { execSync } from 'child_process';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
// Lazy initialize Anthropic client to allow runtime API key validation
|
|
7
|
+
let anthropic = null;
|
|
8
|
+
function getAnthropicClient() {
|
|
9
|
+
if (!anthropic) {
|
|
10
|
+
const apiKey = process.env.ANTHROPIC_API_KEY;
|
|
11
|
+
// Validate API key format
|
|
12
|
+
if (!apiKey) {
|
|
13
|
+
throw new Error('ANTHROPIC_API_KEY is required but not set');
|
|
14
|
+
}
|
|
15
|
+
if (!apiKey.startsWith('sk-ant-')) {
|
|
16
|
+
throw new Error(`Invalid ANTHROPIC_API_KEY format. Expected format: sk-ant-...\n` +
|
|
17
|
+
`Got: ${apiKey.substring(0, 10)}...\n\n` +
|
|
18
|
+
`Please check your API key at: https://console.anthropic.com/settings/keys`);
|
|
19
|
+
}
|
|
20
|
+
anthropic = new Anthropic({ apiKey });
|
|
21
|
+
}
|
|
22
|
+
return anthropic;
|
|
23
|
+
}
|
|
9
24
|
// Define claude-flow tools as native Anthropic tool definitions
|
|
10
25
|
const claudeFlowTools = [
|
|
11
26
|
{
|
|
@@ -179,13 +194,34 @@ export async function directApiAgent(agent, input, onStream) {
|
|
|
179
194
|
// Agentic loop: keep calling API until no more tool uses
|
|
180
195
|
while (toolUseCount < maxToolUses) {
|
|
181
196
|
logger.debug('API call iteration', { toolUseCount, messagesLength: messages.length });
|
|
182
|
-
const
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
197
|
+
const client = getAnthropicClient();
|
|
198
|
+
let response;
|
|
199
|
+
try {
|
|
200
|
+
response = await client.messages.create({
|
|
201
|
+
model: 'claude-sonnet-4-5-20250929',
|
|
202
|
+
max_tokens: 8192,
|
|
203
|
+
system: agent.systemPrompt || 'You are a helpful AI assistant.',
|
|
204
|
+
messages,
|
|
205
|
+
tools: claudeFlowTools
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
// Enhance authentication errors with helpful guidance
|
|
210
|
+
if (error?.status === 401) {
|
|
211
|
+
const apiKey = process.env.ANTHROPIC_API_KEY;
|
|
212
|
+
throw new Error(`❌ Anthropic API authentication failed (401)\n\n` +
|
|
213
|
+
`Your API key is invalid, expired, or lacks permissions.\n` +
|
|
214
|
+
`Current key: ${apiKey?.substring(0, 15)}...\n\n` +
|
|
215
|
+
`Please:\n` +
|
|
216
|
+
` 1. Check your key at: https://console.anthropic.com/settings/keys\n` +
|
|
217
|
+
` 2. Verify it's not expired\n` +
|
|
218
|
+
` 3. Ensure it has proper permissions\n` +
|
|
219
|
+
` 4. Update your .env file with: ANTHROPIC_API_KEY=sk-ant-...\n\n` +
|
|
220
|
+
`Alternative: Use OpenRouter instead (--model "meta-llama/llama-3.1-8b-instruct")\n` +
|
|
221
|
+
`Or use local ONNX (--provider onnx)`);
|
|
222
|
+
}
|
|
223
|
+
throw error;
|
|
224
|
+
}
|
|
189
225
|
logger.debug('API response', {
|
|
190
226
|
stopReason: response.stop_reason,
|
|
191
227
|
contentBlocks: response.content.length
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Interactive CLI wizard for agentic-flow configuration
|
|
4
|
+
* Supports both interactive mode and direct CLI arguments
|
|
5
|
+
*/
|
|
6
|
+
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
|
7
|
+
import { resolve } from 'path';
|
|
8
|
+
import { createInterface } from 'readline';
|
|
9
|
+
const CONFIG_DEFINITIONS = [
|
|
10
|
+
{
|
|
11
|
+
key: 'ANTHROPIC_API_KEY',
|
|
12
|
+
value: '',
|
|
13
|
+
description: 'Anthropic API key for Claude models (sk-ant-...)',
|
|
14
|
+
required: false,
|
|
15
|
+
validation: (val) => val.startsWith('sk-ant-') || 'Must start with sk-ant-'
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
key: 'OPENROUTER_API_KEY',
|
|
19
|
+
value: '',
|
|
20
|
+
description: 'OpenRouter API key for alternative models (sk-or-v1-...)',
|
|
21
|
+
required: false,
|
|
22
|
+
validation: (val) => val.startsWith('sk-or-') || 'Must start with sk-or-'
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
key: 'COMPLETION_MODEL',
|
|
26
|
+
value: 'claude-sonnet-4-5-20250929',
|
|
27
|
+
description: 'Default model for completions',
|
|
28
|
+
required: false
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
key: 'PROVIDER',
|
|
32
|
+
value: 'anthropic',
|
|
33
|
+
description: 'Default provider (anthropic, openrouter, onnx)',
|
|
34
|
+
required: false,
|
|
35
|
+
validation: (val) => ['anthropic', 'openrouter', 'onnx'].includes(val) || 'Must be anthropic, openrouter, or onnx'
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
key: 'AGENTS_DIR',
|
|
39
|
+
value: '',
|
|
40
|
+
description: 'Custom agents directory path (optional)',
|
|
41
|
+
required: false
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
key: 'PROXY_PORT',
|
|
45
|
+
value: '3000',
|
|
46
|
+
description: 'Proxy server port for OpenRouter',
|
|
47
|
+
required: false,
|
|
48
|
+
validation: (val) => !isNaN(parseInt(val)) || 'Must be a number'
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
key: 'USE_OPENROUTER',
|
|
52
|
+
value: 'false',
|
|
53
|
+
description: 'Force OpenRouter usage (true/false)',
|
|
54
|
+
required: false,
|
|
55
|
+
validation: (val) => ['true', 'false'].includes(val) || 'Must be true or false'
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
key: 'USE_ONNX',
|
|
59
|
+
value: 'false',
|
|
60
|
+
description: 'Use ONNX local inference (true/false)',
|
|
61
|
+
required: false,
|
|
62
|
+
validation: (val) => ['true', 'false'].includes(val) || 'Must be true or false'
|
|
63
|
+
}
|
|
64
|
+
];
|
|
65
|
+
export class ConfigWizard {
|
|
66
|
+
envPath;
|
|
67
|
+
currentConfig = new Map();
|
|
68
|
+
constructor(envPath) {
|
|
69
|
+
this.envPath = envPath || resolve(process.cwd(), '.env');
|
|
70
|
+
this.loadExistingConfig();
|
|
71
|
+
}
|
|
72
|
+
loadExistingConfig() {
|
|
73
|
+
if (existsSync(this.envPath)) {
|
|
74
|
+
const content = readFileSync(this.envPath, 'utf-8');
|
|
75
|
+
content.split('\n').forEach(line => {
|
|
76
|
+
const trimmed = line.trim();
|
|
77
|
+
if (trimmed && !trimmed.startsWith('#')) {
|
|
78
|
+
const [key, ...valueParts] = trimmed.split('=');
|
|
79
|
+
const value = valueParts.join('=');
|
|
80
|
+
if (key && value) {
|
|
81
|
+
this.currentConfig.set(key, value);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
saveConfig() {
|
|
88
|
+
const lines = [
|
|
89
|
+
'# Agentic Flow Configuration',
|
|
90
|
+
'# Generated by agentic-flow config wizard',
|
|
91
|
+
`# Created: ${new Date().toISOString()}`,
|
|
92
|
+
''
|
|
93
|
+
];
|
|
94
|
+
CONFIG_DEFINITIONS.forEach(def => {
|
|
95
|
+
const value = this.currentConfig.get(def.key) || def.value;
|
|
96
|
+
if (value) {
|
|
97
|
+
lines.push(`# ${def.description}`);
|
|
98
|
+
lines.push(`${def.key}=${value}`);
|
|
99
|
+
lines.push('');
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
// Preserve other env vars not in CONFIG_DEFINITIONS
|
|
103
|
+
this.currentConfig.forEach((value, key) => {
|
|
104
|
+
if (!CONFIG_DEFINITIONS.find(d => d.key === key)) {
|
|
105
|
+
lines.push(`${key}=${value}`);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
writeFileSync(this.envPath, lines.join('\n'), 'utf-8');
|
|
109
|
+
}
|
|
110
|
+
// Interactive wizard mode
|
|
111
|
+
async runInteractive() {
|
|
112
|
+
console.log('\n🤖 Agentic Flow Configuration Wizard\n');
|
|
113
|
+
console.log('Configure your environment variables for agentic-flow.');
|
|
114
|
+
console.log('Press Enter to keep current value, or type new value.\n');
|
|
115
|
+
const rl = createInterface({
|
|
116
|
+
input: process.stdin,
|
|
117
|
+
output: process.stdout
|
|
118
|
+
});
|
|
119
|
+
const question = (prompt) => {
|
|
120
|
+
return new Promise((resolve) => {
|
|
121
|
+
rl.question(prompt, resolve);
|
|
122
|
+
});
|
|
123
|
+
};
|
|
124
|
+
try {
|
|
125
|
+
for (const def of CONFIG_DEFINITIONS) {
|
|
126
|
+
const currentValue = this.currentConfig.get(def.key) || def.value;
|
|
127
|
+
const displayValue = currentValue
|
|
128
|
+
? (def.key.includes('KEY') ? `${currentValue.substring(0, 15)}...` : currentValue)
|
|
129
|
+
: '(not set)';
|
|
130
|
+
console.log(`\n📝 ${def.key}`);
|
|
131
|
+
console.log(` ${def.description}`);
|
|
132
|
+
let input;
|
|
133
|
+
let isValid = false;
|
|
134
|
+
while (!isValid) {
|
|
135
|
+
input = await question(` Current: ${displayValue}\n New value: `);
|
|
136
|
+
// Keep current if empty
|
|
137
|
+
if (!input.trim()) {
|
|
138
|
+
input = currentValue;
|
|
139
|
+
}
|
|
140
|
+
// Validate if validator exists
|
|
141
|
+
if (input && def.validation) {
|
|
142
|
+
const validationResult = def.validation(input);
|
|
143
|
+
if (validationResult === true) {
|
|
144
|
+
isValid = true;
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
console.log(` ❌ Invalid: ${validationResult}`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
isValid = true;
|
|
152
|
+
}
|
|
153
|
+
if (isValid && input) {
|
|
154
|
+
this.currentConfig.set(def.key, input);
|
|
155
|
+
}
|
|
156
|
+
else if (isValid && !input) {
|
|
157
|
+
// Remove if empty
|
|
158
|
+
this.currentConfig.delete(def.key);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
console.log('\n💾 Saving configuration...');
|
|
163
|
+
this.saveConfig();
|
|
164
|
+
console.log(`✅ Configuration saved to: ${this.envPath}\n`);
|
|
165
|
+
// Show summary
|
|
166
|
+
this.showSummary();
|
|
167
|
+
}
|
|
168
|
+
finally {
|
|
169
|
+
rl.close();
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
// Direct CLI mode - set single value
|
|
173
|
+
set(key, value) {
|
|
174
|
+
const def = CONFIG_DEFINITIONS.find(d => d.key === key);
|
|
175
|
+
if (!def) {
|
|
176
|
+
throw new Error(`Unknown configuration key: ${key}\nAvailable keys: ${CONFIG_DEFINITIONS.map(d => d.key).join(', ')}`);
|
|
177
|
+
}
|
|
178
|
+
// Validate
|
|
179
|
+
if (def.validation) {
|
|
180
|
+
const result = def.validation(value);
|
|
181
|
+
if (result !== true) {
|
|
182
|
+
throw new Error(`Invalid value for ${key}: ${result}`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
this.currentConfig.set(key, value);
|
|
186
|
+
this.saveConfig();
|
|
187
|
+
console.log(`✅ Set ${key}=${value.substring(0, 20)}${value.length > 20 ? '...' : ''}`);
|
|
188
|
+
}
|
|
189
|
+
// Get single value
|
|
190
|
+
get(key) {
|
|
191
|
+
const value = this.currentConfig.get(key);
|
|
192
|
+
if (value) {
|
|
193
|
+
// Mask API keys
|
|
194
|
+
if (key.includes('KEY')) {
|
|
195
|
+
console.log(`${key}=${value.substring(0, 15)}...`);
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
console.log(`${key}=${value}`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
console.log(`${key} is not set`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
// Delete value
|
|
206
|
+
delete(key) {
|
|
207
|
+
if (this.currentConfig.has(key)) {
|
|
208
|
+
this.currentConfig.delete(key);
|
|
209
|
+
this.saveConfig();
|
|
210
|
+
console.log(`✅ Deleted ${key}`);
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
console.log(`❌ ${key} is not set`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
// List all values
|
|
217
|
+
list() {
|
|
218
|
+
console.log('\n📋 Current Configuration:\n');
|
|
219
|
+
CONFIG_DEFINITIONS.forEach(def => {
|
|
220
|
+
const value = this.currentConfig.get(def.key);
|
|
221
|
+
const displayValue = value
|
|
222
|
+
? (def.key.includes('KEY') ? `${value.substring(0, 15)}...` : value)
|
|
223
|
+
: '(not set)';
|
|
224
|
+
console.log(`${def.key.padEnd(25)} = ${displayValue}`);
|
|
225
|
+
console.log(` ${def.description}`);
|
|
226
|
+
console.log('');
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
// Show configuration summary
|
|
230
|
+
showSummary() {
|
|
231
|
+
console.log('📊 Configuration Summary:\n');
|
|
232
|
+
const hasAnthropic = this.currentConfig.has('ANTHROPIC_API_KEY');
|
|
233
|
+
const hasOpenRouter = this.currentConfig.has('OPENROUTER_API_KEY');
|
|
234
|
+
const provider = this.currentConfig.get('PROVIDER') || 'anthropic';
|
|
235
|
+
console.log('Providers configured:');
|
|
236
|
+
console.log(` ${hasAnthropic ? '✅' : '❌'} Anthropic (Claude)`);
|
|
237
|
+
console.log(` ${hasOpenRouter ? '✅' : '❌'} OpenRouter (Alternative models)`);
|
|
238
|
+
console.log(` ⚙️ ONNX (Local inference) - always available`);
|
|
239
|
+
console.log('');
|
|
240
|
+
console.log(`Default provider: ${provider}`);
|
|
241
|
+
console.log('');
|
|
242
|
+
if (!hasAnthropic && !hasOpenRouter) {
|
|
243
|
+
console.log('⚠️ Warning: No API keys configured!');
|
|
244
|
+
console.log(' You can use ONNX local inference, but quality may be limited.');
|
|
245
|
+
console.log(' Run with --provider onnx to use local inference.\n');
|
|
246
|
+
}
|
|
247
|
+
console.log('Next steps:');
|
|
248
|
+
console.log(' npx agentic-flow --list # List available agents');
|
|
249
|
+
console.log(' npx agentic-flow --agent coder --task "Your task" # Run agent');
|
|
250
|
+
console.log('');
|
|
251
|
+
}
|
|
252
|
+
// Reset to defaults
|
|
253
|
+
reset() {
|
|
254
|
+
console.log('⚠️ Resetting configuration to defaults...');
|
|
255
|
+
this.currentConfig.clear();
|
|
256
|
+
CONFIG_DEFINITIONS.forEach(def => {
|
|
257
|
+
if (def.value) {
|
|
258
|
+
this.currentConfig.set(def.key, def.value);
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
this.saveConfig();
|
|
262
|
+
console.log('✅ Configuration reset to defaults');
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
// CLI handler
|
|
266
|
+
export async function handleConfigCommand(args) {
|
|
267
|
+
const command = args[0];
|
|
268
|
+
const wizard = new ConfigWizard();
|
|
269
|
+
switch (command) {
|
|
270
|
+
case undefined:
|
|
271
|
+
case 'wizard':
|
|
272
|
+
case 'interactive':
|
|
273
|
+
await wizard.runInteractive();
|
|
274
|
+
break;
|
|
275
|
+
case 'set':
|
|
276
|
+
if (args.length < 3) {
|
|
277
|
+
console.error('Usage: config set <KEY> <VALUE>');
|
|
278
|
+
process.exit(1);
|
|
279
|
+
}
|
|
280
|
+
wizard.set(args[1], args[2]);
|
|
281
|
+
break;
|
|
282
|
+
case 'get':
|
|
283
|
+
if (args.length < 2) {
|
|
284
|
+
console.error('Usage: config get <KEY>');
|
|
285
|
+
process.exit(1);
|
|
286
|
+
}
|
|
287
|
+
wizard.get(args[1]);
|
|
288
|
+
break;
|
|
289
|
+
case 'delete':
|
|
290
|
+
case 'remove':
|
|
291
|
+
if (args.length < 2) {
|
|
292
|
+
console.error('Usage: config delete <KEY>');
|
|
293
|
+
process.exit(1);
|
|
294
|
+
}
|
|
295
|
+
wizard.delete(args[1]);
|
|
296
|
+
break;
|
|
297
|
+
case 'list':
|
|
298
|
+
wizard.list();
|
|
299
|
+
break;
|
|
300
|
+
case 'reset':
|
|
301
|
+
wizard.reset();
|
|
302
|
+
break;
|
|
303
|
+
case 'help':
|
|
304
|
+
printConfigHelp();
|
|
305
|
+
break;
|
|
306
|
+
default:
|
|
307
|
+
console.error(`Unknown config command: ${command}`);
|
|
308
|
+
printConfigHelp();
|
|
309
|
+
process.exit(1);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
function printConfigHelp() {
|
|
313
|
+
console.log(`
|
|
314
|
+
🤖 Agentic Flow Configuration Manager
|
|
315
|
+
|
|
316
|
+
USAGE:
|
|
317
|
+
npx agentic-flow config [COMMAND] [OPTIONS]
|
|
318
|
+
|
|
319
|
+
COMMANDS:
|
|
320
|
+
(none), wizard, interactive Launch interactive configuration wizard
|
|
321
|
+
set <KEY> <VALUE> Set a configuration value
|
|
322
|
+
get <KEY> Get a configuration value
|
|
323
|
+
delete <KEY> Delete a configuration value
|
|
324
|
+
list List all configuration values
|
|
325
|
+
reset Reset to default configuration
|
|
326
|
+
help Show this help message
|
|
327
|
+
|
|
328
|
+
EXAMPLES:
|
|
329
|
+
# Interactive wizard
|
|
330
|
+
npx agentic-flow config
|
|
331
|
+
|
|
332
|
+
# Direct commands
|
|
333
|
+
npx agentic-flow config set ANTHROPIC_API_KEY sk-ant-xxxxx
|
|
334
|
+
npx agentic-flow config set PROVIDER openrouter
|
|
335
|
+
npx agentic-flow config get PROVIDER
|
|
336
|
+
npx agentic-flow config list
|
|
337
|
+
npx agentic-flow config delete OPENROUTER_API_KEY
|
|
338
|
+
|
|
339
|
+
AVAILABLE CONFIGURATION KEYS:
|
|
340
|
+
ANTHROPIC_API_KEY - Anthropic API key (sk-ant-...)
|
|
341
|
+
OPENROUTER_API_KEY - OpenRouter API key (sk-or-v1-...)
|
|
342
|
+
COMPLETION_MODEL - Default model name
|
|
343
|
+
PROVIDER - Default provider (anthropic, openrouter, onnx)
|
|
344
|
+
AGENTS_DIR - Custom agents directory
|
|
345
|
+
PROXY_PORT - Proxy server port (default: 3000)
|
|
346
|
+
USE_OPENROUTER - Force OpenRouter (true/false)
|
|
347
|
+
USE_ONNX - Use ONNX local inference (true/false)
|
|
348
|
+
|
|
349
|
+
For more information: https://github.com/ruvnet/agentic-flow
|
|
350
|
+
`);
|
|
351
|
+
}
|
|
352
|
+
// If run directly
|
|
353
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
354
|
+
const args = process.argv.slice(2);
|
|
355
|
+
handleConfigCommand(args).catch(err => {
|
|
356
|
+
console.error(err.message);
|
|
357
|
+
process.exit(1);
|
|
358
|
+
});
|
|
359
|
+
}
|
package/dist/cli-proxy.js
CHANGED
|
@@ -9,6 +9,7 @@ import { logger } from "./utils/logger.js";
|
|
|
9
9
|
import { parseArgs } from "./utils/cli.js";
|
|
10
10
|
import { getAgent, listAgents } from "./utils/agentLoader.js";
|
|
11
11
|
import { directApiAgent } from "./agents/directApiAgent.js";
|
|
12
|
+
import { handleConfigCommand } from "./cli/config-wizard.js";
|
|
12
13
|
import { readFileSync } from 'fs';
|
|
13
14
|
import { resolve, dirname } from 'path';
|
|
14
15
|
import { fileURLToPath } from 'url';
|
|
@@ -29,6 +30,12 @@ class AgenticFlowCLI {
|
|
|
29
30
|
this.listAgents();
|
|
30
31
|
process.exit(0);
|
|
31
32
|
}
|
|
33
|
+
if (options.mode === 'config') {
|
|
34
|
+
// Handle config wizard
|
|
35
|
+
const configArgs = process.argv.slice(3); // Skip 'node', 'cli-proxy.js', 'config'
|
|
36
|
+
await handleConfigCommand(configArgs);
|
|
37
|
+
process.exit(0);
|
|
38
|
+
}
|
|
32
39
|
if (options.mode === 'mcp') {
|
|
33
40
|
// Run standalone MCP server directly
|
|
34
41
|
const { spawn } = await import('child_process');
|
|
@@ -226,10 +233,19 @@ USAGE:
|
|
|
226
233
|
npx agentic-flow [COMMAND] [OPTIONS]
|
|
227
234
|
|
|
228
235
|
COMMANDS:
|
|
236
|
+
config [subcommand] Manage environment configuration (interactive wizard)
|
|
229
237
|
mcp <command> [server] Manage MCP servers (start, stop, status, list)
|
|
230
238
|
--list, -l List all available agents
|
|
231
239
|
--agent, -a <name> Run specific agent mode
|
|
232
240
|
|
|
241
|
+
CONFIG COMMANDS:
|
|
242
|
+
npx agentic-flow config # Interactive wizard
|
|
243
|
+
npx agentic-flow config set KEY VAL # Set configuration value
|
|
244
|
+
npx agentic-flow config get KEY # Get configuration value
|
|
245
|
+
npx agentic-flow config list # List all configuration
|
|
246
|
+
npx agentic-flow config delete KEY # Delete configuration value
|
|
247
|
+
npx agentic-flow config reset # Reset to defaults
|
|
248
|
+
|
|
233
249
|
MCP COMMANDS:
|
|
234
250
|
npx agentic-flow mcp start [server] Start MCP server(s)
|
|
235
251
|
npx agentic-flow mcp stop [server] Stop MCP server(s)
|
|
@@ -3,10 +3,6 @@
|
|
|
3
3
|
import { FastMCP } from 'fastmcp';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
import { execSync } from 'child_process';
|
|
6
|
-
import { resolve, dirname } from 'path';
|
|
7
|
-
import { fileURLToPath } from 'url';
|
|
8
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
-
const __dirname = dirname(__filename);
|
|
10
6
|
// Suppress FastMCP internal warnings for cleaner output
|
|
11
7
|
const originalConsoleWarn = console.warn;
|
|
12
8
|
console.warn = (...args) => {
|
|
@@ -23,7 +19,7 @@ console.error('🚀 Starting Agentic-Flow MCP Server (stdio)...');
|
|
|
23
19
|
console.error('📦 Local agentic-flow tools available');
|
|
24
20
|
const server = new FastMCP({
|
|
25
21
|
name: 'agentic-flow',
|
|
26
|
-
version: '1.0.
|
|
22
|
+
version: '1.0.6'
|
|
27
23
|
});
|
|
28
24
|
// Tool: Run agentic-flow agent
|
|
29
25
|
server.addTool({
|
|
@@ -36,12 +32,12 @@ server.addTool({
|
|
|
36
32
|
}),
|
|
37
33
|
execute: async ({ agent, task, stream }) => {
|
|
38
34
|
try {
|
|
39
|
-
|
|
40
|
-
const cmd = `
|
|
35
|
+
// Use npx to run agentic-flow from npm registry
|
|
36
|
+
const cmd = `npx --yes agentic-flow --agent "${agent}" --task "${task}"${stream ? ' --stream' : ''}`;
|
|
41
37
|
const result = execSync(cmd, {
|
|
42
38
|
encoding: 'utf-8',
|
|
43
39
|
maxBuffer: 10 * 1024 * 1024,
|
|
44
|
-
|
|
40
|
+
timeout: 300000 // 5 minute timeout
|
|
45
41
|
});
|
|
46
42
|
return JSON.stringify({
|
|
47
43
|
success: true,
|
|
@@ -62,11 +58,12 @@ server.addTool({
|
|
|
62
58
|
parameters: z.object({}),
|
|
63
59
|
execute: async () => {
|
|
64
60
|
try {
|
|
65
|
-
|
|
66
|
-
const cmd = `
|
|
61
|
+
// Use npx to run agentic-flow from npm registry
|
|
62
|
+
const cmd = `npx --yes agentic-flow --list`;
|
|
67
63
|
const result = execSync(cmd, {
|
|
68
64
|
encoding: 'utf-8',
|
|
69
|
-
|
|
65
|
+
maxBuffer: 5 * 1024 * 1024,
|
|
66
|
+
timeout: 30000
|
|
70
67
|
});
|
|
71
68
|
return JSON.stringify({
|
|
72
69
|
success: true,
|
package/dist/utils/cli.js
CHANGED
|
@@ -11,6 +11,11 @@ export function parseArgs() {
|
|
|
11
11
|
options.mcpServer = args[2] || 'all'; // default to all servers
|
|
12
12
|
return options;
|
|
13
13
|
}
|
|
14
|
+
// Check for config command
|
|
15
|
+
if (args[0] === 'config') {
|
|
16
|
+
options.mode = 'config';
|
|
17
|
+
return options;
|
|
18
|
+
}
|
|
14
19
|
for (let i = 0; i < args.length; i++) {
|
|
15
20
|
const arg = args[i];
|
|
16
21
|
switch (arg) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentic-flow",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "Production-ready AI agent orchestration platform with 66 specialized agents, 111 MCP tools, and autonomous multi-agent swarms. Built by @ruvnet with Claude Agent SDK, neural networks, memory persistence, GitHub integration, and distributed consensus protocols.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|