agentic-flow 1.3.1 → 1.4.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.
- package/README.md +69 -44
- package/dist/agents/claudeAgent.js +78 -67
- package/dist/cli/claude-code-wrapper.js +14 -1
- package/dist/cli-proxy.js +4 -20
- package/dist/mcp/standalone-stdio.js +251 -2
- package/dist/proxy/anthropic-to-requesty.js +116 -36
- package/dist/utils/cli.js +6 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
[](https://nodejs.org/)
|
|
7
7
|
[](https://github.com/ruvnet/)
|
|
8
8
|
|
|
9
|
-
**Production-ready AI agent orchestration with 66+ specialized agents,
|
|
9
|
+
**Production-ready AI agent orchestration with 66+ specialized agents, 216 MCP tools, Agent Booster (152x faster edits), and multi-model routing (Anthropic, OpenRouter, Gemini, ONNX).**
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
@@ -23,10 +23,11 @@ Extending agent capabilities is effortless. Add custom tools and integrations th
|
|
|
23
23
|
Define routing rules through flexible policy modes: Strict mode keeps sensitive data offline, Economy mode prefers free models (99% savings), Premium mode uses Anthropic for highest quality, or create custom cost/quality thresholds. The policy defines the rules; the swarm enforces them automatically. Runs local for development, Docker for CI/CD, or Flow Nexus cloud for production scale. Agentic Flow is the framework for autonomous efficiency—one unified runner for every Claude Code agent, self-tuning, self-routing, and built for real-world deployment.
|
|
24
24
|
|
|
25
25
|
**Key Capabilities:**
|
|
26
|
-
- ✅ **Claude Code Mode** - Run Claude Code with OpenRouter/
|
|
26
|
+
- ✅ **Claude Code Mode** - Run Claude Code with OpenRouter/Gemini/ONNX (85-99% savings)
|
|
27
|
+
- ✅ **Agent Booster** - 152x faster code edits with WASM (12ms vs 13s, $0 cost)
|
|
27
28
|
- ✅ **66 Specialized Agents** - Pre-built experts for coding, research, review, testing, DevOps
|
|
28
|
-
- ✅ **
|
|
29
|
-
- ✅ **Multi-Model Router** - Anthropic, OpenRouter (
|
|
29
|
+
- ✅ **216 MCP Tools** - Agent Booster (3), Memory, GitHub, neural networks, sandboxes, workflows, payments
|
|
30
|
+
- ✅ **Multi-Model Router** - Anthropic, OpenRouter (300+ models), Gemini, ONNX (free local)
|
|
30
31
|
- ✅ **Cost Optimization** - DeepSeek at $0.14/M tokens vs Claude at $15/M (99% savings)
|
|
31
32
|
|
|
32
33
|
**Built On:**
|
|
@@ -56,7 +57,7 @@ npx agentic-flow --agent coder --task "Build a REST API with authentication"
|
|
|
56
57
|
export OPENROUTER_API_KEY=sk-or-v1-...
|
|
57
58
|
npx agentic-flow --agent coder --task "Build REST API" --model "meta-llama/llama-3.1-8b-instruct"
|
|
58
59
|
|
|
59
|
-
# Run with
|
|
60
|
+
# Run with (300+ models, 95% cost savings)
|
|
60
61
|
export REQUESTY_API_KEY=sk-...
|
|
61
62
|
npx agentic-flow --agent coder --task "Build REST API" --provider requesty
|
|
62
63
|
|
|
@@ -85,7 +86,7 @@ npx agentic-flow --list
|
|
|
85
86
|
Access 213 MCP tools for memory, swarms, GitHub, neural networks, and cloud sandboxes:
|
|
86
87
|
|
|
87
88
|
```bash
|
|
88
|
-
# Start all MCP servers (
|
|
89
|
+
# Start all MCP servers (216 tools) - stdio transport
|
|
89
90
|
npx agentic-flow mcp start
|
|
90
91
|
|
|
91
92
|
# List all available tools
|
|
@@ -124,13 +125,17 @@ npm run mcp:stdio
|
|
|
124
125
|
|
|
125
126
|
---
|
|
126
127
|
|
|
127
|
-
### Option 3: Claude Code Mode (v1.
|
|
128
|
+
### Option 3: Claude Code Mode with Agent Booster (v1.3.1+)
|
|
128
129
|
|
|
129
|
-
**Run Claude Code with alternative AI providers
|
|
130
|
+
**Run Claude Code with alternative AI providers + 152x faster code edits!**
|
|
130
131
|
|
|
131
|
-
Automatically spawns Claude Code with proxy configuration
|
|
132
|
+
Automatically spawns Claude Code with proxy configuration and Agent Booster MCP tools:
|
|
132
133
|
|
|
133
134
|
```bash
|
|
135
|
+
# With Agent Booster (152x faster code edits, $0 cost)
|
|
136
|
+
npx agentic-flow claude-code --provider openrouter --agent-booster
|
|
137
|
+
npx agentic-flow claude-code --provider gemini --agent-booster
|
|
138
|
+
|
|
134
139
|
# Interactive mode - Opens Claude Code UI with proxy
|
|
135
140
|
npx agentic-flow claude-code --provider openrouter
|
|
136
141
|
npx agentic-flow claude-code --provider requesty
|
|
@@ -155,8 +160,8 @@ npx agentic-flow claude-code --provider onnx "Analyze this codebase"
|
|
|
155
160
|
| Provider | Model | Cost/M Tokens | Context | Best For |
|
|
156
161
|
|----------|-------|---------------|---------|----------|
|
|
157
162
|
| OpenRouter | `deepseek/deepseek-chat` (default) | $0.14 | 128k | General tasks, best value |
|
|
158
|
-
|
|
|
159
|
-
|
|
|
163
|
+
| | `deepseek/deepseek-chat` | $0.14 | 128k | 300+ models, unified API |
|
|
164
|
+
| | `openai/gpt-4o-mini` | $0.15 | 128k | OpenAI models via |
|
|
160
165
|
| OpenRouter | `anthropic/claude-3.5-sonnet` | $3.00 | 200k | Highest quality, complex reasoning |
|
|
161
166
|
| OpenRouter | `google/gemini-2.0-flash-exp:free` | FREE | 1M | Development, testing (rate limited) |
|
|
162
167
|
| Gemini | `gemini-2.0-flash-exp` | FREE | 1M | Fast responses, rate limited |
|
|
@@ -164,13 +169,24 @@ npx agentic-flow claude-code --provider onnx "Analyze this codebase"
|
|
|
164
169
|
|
|
165
170
|
⚠️ **Note:** Claude Code sends 35k+ tokens in tool definitions. Models with <128k context (like Mistral Small at 32k) will fail with "context length exceeded" errors.
|
|
166
171
|
|
|
172
|
+
**Agent Booster Performance:**
|
|
173
|
+
|
|
174
|
+
| Metric | Standard LLM | Agent Booster (WASM) | Improvement |
|
|
175
|
+
|--------|-------------|---------------------|-------------|
|
|
176
|
+
| **Latency** | 13,000ms (13s) | 85ms | **152x faster** |
|
|
177
|
+
| **Cost** | $0.001/edit | $0.000 | **100% savings** |
|
|
178
|
+
| **Quality** | 100% | 100% | Comparable |
|
|
179
|
+
|
|
180
|
+
Agent Booster uses Rust/WASM for ultra-fast code editing (152x faster than LLMs, zero cost). Enabled by default with `--agent-booster` flag.
|
|
181
|
+
|
|
167
182
|
**How it works:**
|
|
168
183
|
1. ✅ Auto-starts proxy server in background (OpenRouter/Gemini/ONNX)
|
|
169
184
|
2. ✅ Sets `ANTHROPIC_BASE_URL` to proxy endpoint
|
|
170
185
|
3. ✅ Configures provider-specific API keys transparently
|
|
171
|
-
4. ✅
|
|
172
|
-
5. ✅
|
|
173
|
-
6. ✅
|
|
186
|
+
4. ✅ Loads Agent Booster MCP tools (3 tools for ultra-fast edits)
|
|
187
|
+
5. ✅ Spawns Claude Code with environment configured
|
|
188
|
+
6. ✅ All Claude SDK features work (tools, memory, MCP, etc.)
|
|
189
|
+
7. ✅ Automatic cleanup on exit
|
|
174
190
|
|
|
175
191
|
**Environment Setup:**
|
|
176
192
|
|
|
@@ -178,7 +194,7 @@ npx agentic-flow claude-code --provider onnx "Analyze this codebase"
|
|
|
178
194
|
# OpenRouter (100+ models at 85-99% savings)
|
|
179
195
|
export OPENROUTER_API_KEY=sk-or-v1-...
|
|
180
196
|
|
|
181
|
-
#
|
|
197
|
+
# (300+ models, unified access)
|
|
182
198
|
export REQUESTY_API_KEY=sk-...
|
|
183
199
|
|
|
184
200
|
# Gemini (FREE tier available)
|
|
@@ -211,7 +227,7 @@ npx agentic-flow proxy --provider openrouter --model "openai/gpt-4o-mini"
|
|
|
211
227
|
```
|
|
212
228
|
|
|
213
229
|
**Features:**
|
|
214
|
-
- ✅ MCP tools work through proxy (all
|
|
230
|
+
- ✅ MCP tools work through proxy (all 216 tools)
|
|
215
231
|
- ✅ Compatible with Claude Code official CLI
|
|
216
232
|
- ✅ Context-aware instruction injection (v1.1.13)
|
|
217
233
|
- ✅ Model-specific max_tokens optimization
|
|
@@ -393,7 +409,7 @@ MCP (Model Context Protocol) tools extend agent capabilities beyond text generat
|
|
|
393
409
|
|
|
394
410
|
**stdio Transport (default for Claude Desktop):**
|
|
395
411
|
```bash
|
|
396
|
-
# Start all
|
|
412
|
+
# Start all 216 tools (4 servers)
|
|
397
413
|
npx agentic-flow mcp start
|
|
398
414
|
|
|
399
415
|
# Start specific server
|
|
@@ -1032,43 +1048,52 @@ ENABLE_CLAUDE_FLOW_SDK=true
|
|
|
1032
1048
|
COMPLETION_MODEL=deepseek/deepseek-chat-v3.1
|
|
1033
1049
|
```
|
|
1034
1050
|
|
|
1035
|
-
**
|
|
1051
|
+
** Configuration (v1.3.1+)** ⚠️
|
|
1036
1052
|
|
|
1037
|
-
|
|
1053
|
+
.ai provides unified access to 300+ AI models including OpenAI (GPT-4o, GPT-4o-mini), Anthropic, DeepSeek, Meta, Mistral, and more through a single API key.
|
|
1038
1054
|
|
|
1039
|
-
|
|
1040
|
-
# Get your API key from https://requesty.ai
|
|
1041
|
-
export REQUESTY_API_KEY=sk-...
|
|
1055
|
+
⚠️ **Current Status**: provider has integration challenges with Claude SDK agent initialization. **We recommend using OpenRouter instead** for agent-based tasks.
|
|
1042
1056
|
|
|
1043
|
-
|
|
1044
|
-
|
|
1057
|
+
**What Works:**
|
|
1058
|
+
- ✅ Simple API calls without agents
|
|
1059
|
+
- ✅ Basic arithmetic and simple tasks
|
|
1060
|
+
- ✅ Direct API integration via curl/fetch
|
|
1045
1061
|
|
|
1046
|
-
|
|
1047
|
-
|
|
1062
|
+
**Known Limitations:**
|
|
1063
|
+
- ❌ Hangs during Claude SDK agent initialization with MCP tools
|
|
1064
|
+
- ❌ Cannot handle full agent execution (coder, reviewer, etc.)
|
|
1065
|
+
- ⚠️ Tool limit reduced to 10 maximum (vs 213 available)
|
|
1066
|
+
|
|
1067
|
+
**Recommended Alternative:**
|
|
1068
|
+
Use **OpenRouter** for identical cost savings and full agent support:
|
|
1069
|
+
```bash
|
|
1070
|
+
# OpenRouter works perfectly with all agents and tools
|
|
1071
|
+
export OPENROUTER_API_KEY=sk-or-v1-...
|
|
1072
|
+
npx agentic-flow --agent coder --task "your task" --provider openrouter
|
|
1073
|
+
npx agentic-flow --agent coder --task "your task" --model "deepseek/deepseek-chat"
|
|
1074
|
+
```
|
|
1048
1075
|
|
|
1049
|
-
|
|
1050
|
-
|
|
1076
|
+
**If you still want to try :**
|
|
1077
|
+
```bash
|
|
1078
|
+
# Get your API key from https://requesty.ai
|
|
1079
|
+
export REQUESTY_API_KEY=sk-...
|
|
1051
1080
|
|
|
1052
|
-
#
|
|
1053
|
-
|
|
1054
|
-
npx agentic-flow --agent coder --task "your task"
|
|
1081
|
+
# Simple tasks only (no agent mode recommended)
|
|
1082
|
+
# Use OpenRouter for agent-based work instead
|
|
1055
1083
|
```
|
|
1056
1084
|
|
|
1057
|
-
**
|
|
1058
|
-
-
|
|
1059
|
-
-
|
|
1060
|
-
-
|
|
1061
|
-
-
|
|
1085
|
+
**Technical Details:**
|
|
1086
|
+
- Schema sanitization for array properties
|
|
1087
|
+
- 60-second timeout protection
|
|
1088
|
+
- Tool limiting (10 max) to prevent overload
|
|
1089
|
+
- OpenAI-compatible API format
|
|
1090
|
+
- Automatic max_tokens optimization (capped at 8192)
|
|
1091
|
+
|
|
1092
|
+
**Supported Models (when working):**
|
|
1093
|
+
- `deepseek/deepseek-chat` - $0.14/M tokens, 128k context
|
|
1094
|
+
- `openai/gpt-4o-mini` - $0.15/M tokens, 128k context
|
|
1062
1095
|
- 300+ other models available
|
|
1063
1096
|
|
|
1064
|
-
**Features:**
|
|
1065
|
-
- ✅ OpenAI-compatible API format
|
|
1066
|
-
- ✅ Native tool calling support for GPT-4o, DeepSeek
|
|
1067
|
-
- ✅ Automatic max_tokens optimization (capped at 8192)
|
|
1068
|
-
- ✅ 95% cost savings vs Anthropic direct API
|
|
1069
|
-
- ✅ Full MCP tool integration (all 213 tools)
|
|
1070
|
-
- ✅ Works with `--verbose` flag for debugging
|
|
1071
|
-
|
|
1072
1097
|
---
|
|
1073
1098
|
|
|
1074
1099
|
## 📚 Complete Agent List
|
|
@@ -121,77 +121,88 @@ export async function claudeAgent(agent, input, onStream, modelOverride) {
|
|
|
121
121
|
try {
|
|
122
122
|
// MCP server setup - enable in-SDK server and optional external servers
|
|
123
123
|
const mcpServers = {};
|
|
124
|
-
//
|
|
125
|
-
|
|
126
|
-
|
|
124
|
+
// CRITICAL FIX: Disable all MCP servers for Requesty provider
|
|
125
|
+
// The Claude SDK hangs when trying to initialize MCP servers with Requesty
|
|
126
|
+
// This is a fundamental incompatibility - SDK initialization fails before API call
|
|
127
|
+
if (provider === 'requesty') {
|
|
128
|
+
logger.info('⚠️ Requesty provider detected - disabling all MCP servers to prevent hang');
|
|
129
|
+
console.log('⚠️ Requesty: MCP tools disabled (SDK incompatibility)');
|
|
130
|
+
// Skip all MCP server initialization for Requesty
|
|
131
|
+
// Continue with empty mcpServers object
|
|
127
132
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
const
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
133
|
+
else {
|
|
134
|
+
// Enable in-SDK MCP server for custom tools (enabled by default)
|
|
135
|
+
if (process.env.ENABLE_CLAUDE_FLOW_SDK !== 'false') {
|
|
136
|
+
mcpServers['claude-flow-sdk'] = claudeFlowSdkServer;
|
|
137
|
+
}
|
|
138
|
+
// External MCP servers (enabled by default for full 213-tool access)
|
|
139
|
+
// Disable by setting ENABLE_CLAUDE_FLOW_MCP=false
|
|
140
|
+
if (process.env.ENABLE_CLAUDE_FLOW_MCP !== 'false') {
|
|
141
|
+
mcpServers['claude-flow'] = {
|
|
142
|
+
type: 'stdio',
|
|
143
|
+
command: 'npx',
|
|
144
|
+
args: ['claude-flow@alpha', 'mcp', 'start'],
|
|
145
|
+
env: {
|
|
146
|
+
...process.env,
|
|
147
|
+
MCP_AUTO_START: 'true',
|
|
148
|
+
PROVIDER: provider
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
if (process.env.ENABLE_FLOW_NEXUS_MCP !== 'false') {
|
|
153
|
+
mcpServers['flow-nexus'] = {
|
|
154
|
+
type: 'stdio',
|
|
155
|
+
command: 'npx',
|
|
156
|
+
args: ['flow-nexus@latest', 'mcp', 'start'],
|
|
157
|
+
env: {
|
|
158
|
+
...process.env,
|
|
159
|
+
FLOW_NEXUS_AUTO_START: 'true'
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
if (process.env.ENABLE_AGENTIC_PAYMENTS_MCP !== 'false') {
|
|
164
|
+
mcpServers['agentic-payments'] = {
|
|
165
|
+
type: 'stdio',
|
|
166
|
+
command: 'npx',
|
|
167
|
+
args: ['-y', 'agentic-payments', 'mcp'],
|
|
168
|
+
env: {
|
|
169
|
+
...process.env,
|
|
170
|
+
AGENTIC_PAYMENTS_AUTO_START: 'true'
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
// Load MCP servers from user config file (~/.agentic-flow/mcp-config.json)
|
|
175
|
+
try {
|
|
176
|
+
const fs = await import('fs');
|
|
177
|
+
const path = await import('path');
|
|
178
|
+
const os = await import('os');
|
|
179
|
+
const configPath = path.join(os.homedir(), '.agentic-flow', 'mcp-config.json');
|
|
180
|
+
if (fs.existsSync(configPath)) {
|
|
181
|
+
const configContent = fs.readFileSync(configPath, 'utf-8');
|
|
182
|
+
const config = JSON.parse(configContent);
|
|
183
|
+
// Add enabled user-configured servers
|
|
184
|
+
for (const [name, server] of Object.entries(config.servers || {})) {
|
|
185
|
+
const serverConfig = server;
|
|
186
|
+
if (serverConfig.enabled) {
|
|
187
|
+
mcpServers[name] = {
|
|
188
|
+
type: 'stdio',
|
|
189
|
+
command: serverConfig.command,
|
|
190
|
+
args: serverConfig.args || [],
|
|
191
|
+
env: {
|
|
192
|
+
...process.env,
|
|
193
|
+
...serverConfig.env
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
console.log(`[agentic-flow] Loaded MCP server: ${name}`);
|
|
197
|
+
}
|
|
187
198
|
}
|
|
188
199
|
}
|
|
189
200
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
// Silently fail if config doesn't exist or can't be read
|
|
203
|
+
console.log('[agentic-flow] No user MCP config found (this is normal)');
|
|
204
|
+
}
|
|
205
|
+
} // End of provider !== 'requesty' check
|
|
195
206
|
const queryOptions = {
|
|
196
207
|
systemPrompt: agent.systemPrompt,
|
|
197
208
|
model: finalModel, // Claude Agent SDK handles model selection
|
|
@@ -212,6 +212,9 @@ Examples:
|
|
|
212
212
|
$ agentic-flow claude-code --provider gemini # Uses Gemini 2.0 Flash
|
|
213
213
|
$ agentic-flow claude-code --provider onnx # Uses local ONNX models (free)
|
|
214
214
|
|
|
215
|
+
# With Agent Booster for 57x faster code edits
|
|
216
|
+
$ agentic-flow claude-code --provider openrouter --agent-booster
|
|
217
|
+
|
|
215
218
|
Recommended Models:
|
|
216
219
|
OpenRouter:
|
|
217
220
|
mistralai/mistral-small-3.1-24b-instruct (default, $0.02/M, 128k context, optimized for tools)
|
|
@@ -233,6 +236,7 @@ Documentation:
|
|
|
233
236
|
.option('--provider <provider>', 'AI provider (anthropic, openrouter, gemini, onnx)', 'anthropic')
|
|
234
237
|
.option('--port <port>', 'Proxy server port', '3000')
|
|
235
238
|
.option('--model <model>', 'Specific model to use (e.g., mistralai/mistral-small-3.1-24b-instruct)')
|
|
239
|
+
.option('--agent-booster', 'Enable Agent Booster MCP tools for 57x faster code edits (default: true)', true)
|
|
236
240
|
.option('--keep-proxy', 'Keep proxy running after Claude Code exits')
|
|
237
241
|
.option('--no-auto-start', 'Skip proxy startup (use existing proxy)')
|
|
238
242
|
.allowUnknownOption(true)
|
|
@@ -256,7 +260,7 @@ Documentation:
|
|
|
256
260
|
process.exit(1);
|
|
257
261
|
}
|
|
258
262
|
// Get Claude Code arguments (filter out wrapper-specific flags only)
|
|
259
|
-
const wrapperFlags = new Set(['--provider', '--port', '--model', '--keep-proxy', '--no-auto-start']);
|
|
263
|
+
const wrapperFlags = new Set(['--provider', '--port', '--model', '--agent-booster', '--keep-proxy', '--no-auto-start']);
|
|
260
264
|
const wrapperValues = new Set([options.provider, options.port, options.model]);
|
|
261
265
|
const claudeArgs = [];
|
|
262
266
|
let skipNext = false;
|
|
@@ -292,6 +296,15 @@ Documentation:
|
|
|
292
296
|
}
|
|
293
297
|
let proxyServer = null;
|
|
294
298
|
try {
|
|
299
|
+
// Info about Agent Booster MCP tools if enabled
|
|
300
|
+
if (options.agentBooster) {
|
|
301
|
+
logger.info('');
|
|
302
|
+
logger.info('⚡ Agent Booster enabled (57x faster code edits)');
|
|
303
|
+
logger.info(' Available tools: agent_booster_edit_file, agent_booster_batch_edit, agent_booster_parse_markdown');
|
|
304
|
+
logger.info(' Configure MCP: Add "agentic-flow" to Claude Desktop config');
|
|
305
|
+
logger.info(' Learn more: examples/mcp-integration.md');
|
|
306
|
+
logger.info('');
|
|
307
|
+
}
|
|
295
308
|
// Start proxy if needed and auto-start is enabled
|
|
296
309
|
if (options.autoStart) {
|
|
297
310
|
proxyServer = await startProxyServer(config);
|
package/dist/cli-proxy.js
CHANGED
|
@@ -155,7 +155,8 @@ class AgenticFlowCLI {
|
|
|
155
155
|
const useONNX = this.shouldUseONNX(options);
|
|
156
156
|
const useOpenRouter = this.shouldUseOpenRouter(options);
|
|
157
157
|
const useGemini = this.shouldUseGemini(options);
|
|
158
|
-
|
|
158
|
+
// Requesty temporarily disabled - keep proxy files for future use
|
|
159
|
+
const useRequesty = false; // this.shouldUseRequesty(options);
|
|
159
160
|
// Debug output for provider selection
|
|
160
161
|
if (options.verbose || process.env.VERBOSE === 'true') {
|
|
161
162
|
console.log('\n🔍 Provider Selection Debug:');
|
|
@@ -583,18 +584,6 @@ EXAMPLES:
|
|
|
583
584
|
console.error(' export ANTHROPIC_API_KEY=sk-ant-xxxxx\n');
|
|
584
585
|
console.error('Or use alternative providers:');
|
|
585
586
|
console.error(' --provider openrouter (requires OPENROUTER_API_KEY)');
|
|
586
|
-
console.error(' --provider requesty (requires REQUESTY_API_KEY)');
|
|
587
|
-
console.error(' --provider gemini (requires GOOGLE_GEMINI_API_KEY)');
|
|
588
|
-
console.error(' --provider onnx (free local inference)\n');
|
|
589
|
-
process.exit(1);
|
|
590
|
-
}
|
|
591
|
-
if (!isOnnx && useRequesty && !process.env.REQUESTY_API_KEY) {
|
|
592
|
-
console.error('\n❌ Error: REQUESTY_API_KEY is required for Requesty\n');
|
|
593
|
-
console.error('Please set your API key:');
|
|
594
|
-
console.error(' export REQUESTY_API_KEY=sk-xxxxx\n');
|
|
595
|
-
console.error('Or use alternative providers:');
|
|
596
|
-
console.error(' --provider anthropic (requires ANTHROPIC_API_KEY)');
|
|
597
|
-
console.error(' --provider openrouter (requires OPENROUTER_API_KEY)');
|
|
598
587
|
console.error(' --provider gemini (requires GOOGLE_GEMINI_API_KEY)');
|
|
599
588
|
console.error(' --provider onnx (free local inference)\n');
|
|
600
589
|
process.exit(1);
|
|
@@ -605,7 +594,6 @@ EXAMPLES:
|
|
|
605
594
|
console.error(' export OPENROUTER_API_KEY=sk-or-v1-xxxxx\n');
|
|
606
595
|
console.error('Or use alternative providers:');
|
|
607
596
|
console.error(' --provider anthropic (requires ANTHROPIC_API_KEY)');
|
|
608
|
-
console.error(' --provider requesty (requires REQUESTY_API_KEY)');
|
|
609
597
|
console.error(' --provider gemini (requires GOOGLE_GEMINI_API_KEY)');
|
|
610
598
|
console.error(' --provider onnx (free local inference)\n');
|
|
611
599
|
process.exit(1);
|
|
@@ -742,7 +730,7 @@ AGENT COMMANDS:
|
|
|
742
730
|
OPTIONS:
|
|
743
731
|
--task, -t <task> Task description for agent mode
|
|
744
732
|
--model, -m <model> Model to use (triggers OpenRouter if contains "/")
|
|
745
|
-
--provider, -p <name> Provider to use (anthropic, openrouter,
|
|
733
|
+
--provider, -p <name> Provider to use (anthropic, openrouter, gemini, onnx)
|
|
746
734
|
--stream, -s Enable real-time streaming output
|
|
747
735
|
--help, -h Show this help message
|
|
748
736
|
|
|
@@ -789,19 +777,17 @@ EXAMPLES:
|
|
|
789
777
|
|
|
790
778
|
# Proxy Server for Claude Code/Cursor
|
|
791
779
|
npx agentic-flow proxy --provider openrouter --port 3000
|
|
792
|
-
npx agentic-flow proxy --provider requesty --port 3000
|
|
793
780
|
npx agentic-flow proxy --provider gemini --port 3001
|
|
794
781
|
|
|
795
782
|
# Claude Code Integration (Auto-start proxy + spawn Claude Code)
|
|
796
783
|
npx agentic-flow claude-code --provider openrouter "Write a Python function"
|
|
797
|
-
npx agentic-flow claude-code --provider requesty "Write a Python function"
|
|
798
784
|
npx agentic-flow claude-code --provider gemini "Create a REST API"
|
|
799
785
|
npx agentic-flow claude-code --provider anthropic "Help me debug this code"
|
|
800
786
|
|
|
801
787
|
# Agent Execution
|
|
802
788
|
npx agentic-flow --list # List all 150+ agents
|
|
803
789
|
npx agentic-flow --agent coder --task "Create Python hello world"
|
|
804
|
-
npx agentic-flow --agent coder --task "Create REST API" --provider
|
|
790
|
+
npx agentic-flow --agent coder --task "Create REST API" --provider openrouter
|
|
805
791
|
npx agentic-flow --agent coder --task "Create REST API" --model "meta-llama/llama-3.1-8b-instruct"
|
|
806
792
|
npx agentic-flow --agent coder --task "Create code" --provider onnx
|
|
807
793
|
|
|
@@ -814,10 +800,8 @@ EXAMPLES:
|
|
|
814
800
|
ENVIRONMENT VARIABLES:
|
|
815
801
|
ANTHROPIC_API_KEY Anthropic API key (for Claude models)
|
|
816
802
|
OPENROUTER_API_KEY OpenRouter API key (for alternative models)
|
|
817
|
-
REQUESTY_API_KEY Requesty API key (for Requesty models - 300+ models)
|
|
818
803
|
GOOGLE_GEMINI_API_KEY Google Gemini API key (for Gemini models)
|
|
819
804
|
USE_OPENROUTER Set to 'true' to force OpenRouter usage
|
|
820
|
-
USE_REQUESTY Set to 'true' to force Requesty usage
|
|
821
805
|
USE_GEMINI Set to 'true' to force Gemini usage
|
|
822
806
|
COMPLETION_MODEL Default model for OpenRouter
|
|
823
807
|
AGENTS_DIR Path to agents directory
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { FastMCP } from 'fastmcp';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
import { execSync } from 'child_process';
|
|
6
|
+
import { resolve } from 'path';
|
|
6
7
|
// Suppress FastMCP internal warnings for cleaner output
|
|
7
8
|
const originalConsoleWarn = console.warn;
|
|
8
9
|
console.warn = (...args) => {
|
|
@@ -290,14 +291,262 @@ server.addTool({
|
|
|
290
291
|
}
|
|
291
292
|
}
|
|
292
293
|
});
|
|
293
|
-
|
|
294
|
+
// ========================================
|
|
295
|
+
// Agent Booster Tools (352x faster code editing)
|
|
296
|
+
// ========================================
|
|
297
|
+
// Tool: Apply code edit with Agent Booster
|
|
298
|
+
server.addTool({
|
|
299
|
+
name: 'agent_booster_edit_file',
|
|
300
|
+
description: 'Ultra-fast code editing (352x faster than cloud APIs, $0 cost). Apply precise code edits using Agent Booster\'s local WASM engine. Use "// ... existing code ..." markers for unchanged sections.',
|
|
301
|
+
parameters: z.object({
|
|
302
|
+
target_filepath: z.string().describe('Path of the file to modify'),
|
|
303
|
+
instructions: z.string().describe('First-person instruction (e.g., "I will add error handling")'),
|
|
304
|
+
code_edit: z.string().describe('Precise code lines to edit, using "// ... existing code ..." for unchanged sections'),
|
|
305
|
+
language: z.string().optional().describe('Programming language (auto-detected from file extension if not provided)')
|
|
306
|
+
}),
|
|
307
|
+
execute: async ({ target_filepath, instructions, code_edit, language }) => {
|
|
308
|
+
try {
|
|
309
|
+
const fs = await import('fs');
|
|
310
|
+
const path = await import('path');
|
|
311
|
+
// Read current file
|
|
312
|
+
if (!fs.existsSync(target_filepath)) {
|
|
313
|
+
throw new Error(`File not found: ${target_filepath}`);
|
|
314
|
+
}
|
|
315
|
+
const originalCode = fs.readFileSync(target_filepath, 'utf-8');
|
|
316
|
+
// Detect language if not provided
|
|
317
|
+
if (!language) {
|
|
318
|
+
const ext = path.extname(target_filepath).slice(1);
|
|
319
|
+
const langMap = {
|
|
320
|
+
'ts': 'typescript', 'js': 'javascript', 'py': 'python',
|
|
321
|
+
'rs': 'rust', 'go': 'go', 'java': 'java',
|
|
322
|
+
'c': 'c', 'cpp': 'cpp', 'h': 'c', 'hpp': 'cpp'
|
|
323
|
+
};
|
|
324
|
+
language = langMap[ext] || 'javascript';
|
|
325
|
+
}
|
|
326
|
+
// Apply edit using agent-booster CLI directly (local WASM, 0-1ms)
|
|
327
|
+
const agentBoosterCli = resolve(__dirname, '../../../agent-booster/dist/cli.js');
|
|
328
|
+
const cmd = `node ${agentBoosterCli} apply --language ${language}`;
|
|
329
|
+
const result = execSync(cmd, {
|
|
330
|
+
encoding: 'utf-8',
|
|
331
|
+
input: JSON.stringify({ code: originalCode, edit: code_edit }),
|
|
332
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
333
|
+
timeout: 5000,
|
|
334
|
+
cwd: resolve(__dirname, '../../../agent-booster')
|
|
335
|
+
});
|
|
336
|
+
const parsed = JSON.parse(result);
|
|
337
|
+
if (parsed.success && parsed.confidence >= 0.7) {
|
|
338
|
+
// High confidence - use Agent Booster result
|
|
339
|
+
fs.writeFileSync(target_filepath, parsed.output);
|
|
340
|
+
return JSON.stringify({
|
|
341
|
+
success: true,
|
|
342
|
+
method: 'agent_booster',
|
|
343
|
+
filepath: target_filepath,
|
|
344
|
+
instruction: instructions,
|
|
345
|
+
latency_ms: parsed.latency,
|
|
346
|
+
confidence: (parsed.confidence * 100).toFixed(1) + '%',
|
|
347
|
+
strategy: parsed.strategy,
|
|
348
|
+
message: `✅ Successfully edited ${target_filepath} (${parsed.latency}ms, ${(parsed.confidence * 100).toFixed(1)}% confidence)`
|
|
349
|
+
}, null, 2);
|
|
350
|
+
}
|
|
351
|
+
else {
|
|
352
|
+
// Low confidence - fall back to LLM for complex edits
|
|
353
|
+
const confidencePercent = (parsed.confidence * 100).toFixed(1);
|
|
354
|
+
return JSON.stringify({
|
|
355
|
+
success: false,
|
|
356
|
+
method: 'agent_booster_failed',
|
|
357
|
+
filepath: target_filepath,
|
|
358
|
+
confidence: confidencePercent + '%',
|
|
359
|
+
fallback_required: true,
|
|
360
|
+
message: `⚠️ Agent Booster confidence too low (${confidencePercent}%). Falling back to LLM for complex edit.`,
|
|
361
|
+
suggestion: `Use agentic_flow_agent with task: "Apply this edit to ${target_filepath}: ${instructions}. Original code: ${originalCode.substring(0, 500)}... Target edit: ${code_edit.substring(0, 500)}..."`,
|
|
362
|
+
llm_fallback: {
|
|
363
|
+
tool: 'agentic_flow_agent',
|
|
364
|
+
agent: 'coder',
|
|
365
|
+
task: `Apply code edit to ${target_filepath}:\n\nInstructions: ${instructions}\n\nOriginal code:\n${originalCode}\n\nTarget edit:\n${code_edit}`,
|
|
366
|
+
reason: `Agent Booster pattern matching failed (${confidencePercent}% confidence). This edit requires LLM reasoning for: structural changes, complex logic, or vague instructions.`
|
|
367
|
+
}
|
|
368
|
+
}, null, 2);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
catch (error) {
|
|
372
|
+
throw new Error(`Failed to edit file: ${error.message}`);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
// Tool: Batch apply multiple edits
|
|
377
|
+
server.addTool({
|
|
378
|
+
name: 'agent_booster_batch_edit',
|
|
379
|
+
description: 'Apply multiple code edits in a single operation (ultra-fast batch processing). Perfect for multi-file refactoring.',
|
|
380
|
+
parameters: z.object({
|
|
381
|
+
edits: z.array(z.object({
|
|
382
|
+
target_filepath: z.string().describe('File path'),
|
|
383
|
+
instructions: z.string().describe('First-person instruction'),
|
|
384
|
+
code_edit: z.string().describe('Code edit with markers'),
|
|
385
|
+
language: z.string().optional().describe('Programming language')
|
|
386
|
+
})).describe('Array of edit requests')
|
|
387
|
+
}),
|
|
388
|
+
execute: async ({ edits }) => {
|
|
389
|
+
try {
|
|
390
|
+
const fs = await import('fs');
|
|
391
|
+
const path = await import('path');
|
|
392
|
+
const results = [];
|
|
393
|
+
let totalLatency = 0;
|
|
394
|
+
for (const edit of edits) {
|
|
395
|
+
const originalCode = fs.existsSync(edit.target_filepath)
|
|
396
|
+
? fs.readFileSync(edit.target_filepath, 'utf-8')
|
|
397
|
+
: '';
|
|
398
|
+
// Detect language
|
|
399
|
+
let language = edit.language;
|
|
400
|
+
if (!language) {
|
|
401
|
+
const ext = path.extname(edit.target_filepath).slice(1);
|
|
402
|
+
const langMap = {
|
|
403
|
+
'ts': 'typescript', 'js': 'javascript', 'py': 'python',
|
|
404
|
+
'rs': 'rust', 'go': 'go', 'java': 'java',
|
|
405
|
+
'c': 'c', 'cpp': 'cpp', 'h': 'c', 'hpp': 'cpp'
|
|
406
|
+
};
|
|
407
|
+
language = langMap[ext] || 'javascript';
|
|
408
|
+
}
|
|
409
|
+
// Apply edit
|
|
410
|
+
const cmd = `npx --yes agent-booster apply --language ${language}`;
|
|
411
|
+
const result = execSync(cmd, {
|
|
412
|
+
encoding: 'utf-8',
|
|
413
|
+
input: JSON.stringify({ code: originalCode, edit: edit.code_edit }),
|
|
414
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
415
|
+
timeout: 5000
|
|
416
|
+
});
|
|
417
|
+
const parsed = JSON.parse(result);
|
|
418
|
+
totalLatency += parsed.latency;
|
|
419
|
+
if (parsed.success && parsed.confidence >= 0.7) {
|
|
420
|
+
fs.writeFileSync(edit.target_filepath, parsed.output);
|
|
421
|
+
results.push({
|
|
422
|
+
file: edit.target_filepath,
|
|
423
|
+
success: true,
|
|
424
|
+
latency_ms: parsed.latency,
|
|
425
|
+
confidence: (parsed.confidence * 100).toFixed(1) + '%'
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
else {
|
|
429
|
+
results.push({
|
|
430
|
+
file: edit.target_filepath,
|
|
431
|
+
success: false,
|
|
432
|
+
confidence: (parsed.confidence * 100).toFixed(1) + '%',
|
|
433
|
+
reason: 'Low confidence'
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
const successful = results.filter(r => r.success).length;
|
|
438
|
+
return JSON.stringify({
|
|
439
|
+
success: true,
|
|
440
|
+
total: edits.length,
|
|
441
|
+
successful,
|
|
442
|
+
failed: edits.length - successful,
|
|
443
|
+
total_latency_ms: totalLatency,
|
|
444
|
+
avg_latency_ms: (totalLatency / edits.length).toFixed(1),
|
|
445
|
+
results,
|
|
446
|
+
performance_note: `Agent Booster: ${totalLatency}ms total vs Morph LLM: ~${edits.length * 352}ms (${((edits.length * 352) / totalLatency).toFixed(1)}x faster)`
|
|
447
|
+
}, null, 2);
|
|
448
|
+
}
|
|
449
|
+
catch (error) {
|
|
450
|
+
throw new Error(`Batch edit failed: ${error.message}`);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
});
|
|
454
|
+
// Tool: Parse markdown code blocks and apply edits
|
|
455
|
+
server.addTool({
|
|
456
|
+
name: 'agent_booster_parse_markdown',
|
|
457
|
+
description: 'Parse markdown code blocks with filepath= and instruction= metadata, then apply all edits. Compatible with LLM-generated multi-file refactoring outputs.',
|
|
458
|
+
parameters: z.object({
|
|
459
|
+
markdown: z.string().describe('Markdown text containing code blocks with filepath= and instruction= metadata')
|
|
460
|
+
}),
|
|
461
|
+
execute: async ({ markdown }) => {
|
|
462
|
+
try {
|
|
463
|
+
const fs = await import('fs');
|
|
464
|
+
const path = await import('path');
|
|
465
|
+
// Parse markdown code blocks
|
|
466
|
+
const regex = /```(?:(\w+))?\s*filepath=([^\s]+)\s+instruction=([^\n]+)\n([\s\S]*?)```/g;
|
|
467
|
+
const edits = [];
|
|
468
|
+
let match;
|
|
469
|
+
while ((match = regex.exec(markdown)) !== null) {
|
|
470
|
+
const [_, language, filepath, instruction, code_edit] = match;
|
|
471
|
+
edits.push({
|
|
472
|
+
target_filepath: filepath.trim(),
|
|
473
|
+
instructions: instruction.trim(),
|
|
474
|
+
code_edit: code_edit.trim(),
|
|
475
|
+
language: language || undefined
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
if (edits.length === 0) {
|
|
479
|
+
throw new Error('No code blocks found in markdown. Expected format: ```language filepath=path instruction=description\\ncode\\n```');
|
|
480
|
+
}
|
|
481
|
+
// Apply all edits using batch tool
|
|
482
|
+
const results = [];
|
|
483
|
+
let totalLatency = 0;
|
|
484
|
+
for (const edit of edits) {
|
|
485
|
+
const originalCode = fs.existsSync(edit.target_filepath)
|
|
486
|
+
? fs.readFileSync(edit.target_filepath, 'utf-8')
|
|
487
|
+
: '';
|
|
488
|
+
let language = edit.language;
|
|
489
|
+
if (!language) {
|
|
490
|
+
const ext = path.extname(edit.target_filepath).slice(1);
|
|
491
|
+
const langMap = {
|
|
492
|
+
'ts': 'typescript', 'js': 'javascript', 'py': 'python',
|
|
493
|
+
'rs': 'rust', 'go': 'go', 'java': 'java',
|
|
494
|
+
'c': 'c', 'cpp': 'cpp', 'h': 'c', 'hpp': 'cpp'
|
|
495
|
+
};
|
|
496
|
+
language = langMap[ext] || 'javascript';
|
|
497
|
+
}
|
|
498
|
+
const cmd = `npx --yes agent-booster apply --language ${language}`;
|
|
499
|
+
const result = execSync(cmd, {
|
|
500
|
+
encoding: 'utf-8',
|
|
501
|
+
input: JSON.stringify({ code: originalCode, edit: edit.code_edit }),
|
|
502
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
503
|
+
timeout: 5000
|
|
504
|
+
});
|
|
505
|
+
const parsed = JSON.parse(result);
|
|
506
|
+
totalLatency += parsed.latency;
|
|
507
|
+
if (parsed.success && parsed.confidence >= 0.7) {
|
|
508
|
+
fs.writeFileSync(edit.target_filepath, parsed.output);
|
|
509
|
+
results.push({
|
|
510
|
+
file: edit.target_filepath,
|
|
511
|
+
instruction: edit.instructions,
|
|
512
|
+
success: true,
|
|
513
|
+
latency_ms: parsed.latency
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
else {
|
|
517
|
+
results.push({
|
|
518
|
+
file: edit.target_filepath,
|
|
519
|
+
success: false,
|
|
520
|
+
confidence: (parsed.confidence * 100).toFixed(1) + '%'
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
const successful = results.filter(r => r.success).length;
|
|
525
|
+
return JSON.stringify({
|
|
526
|
+
success: true,
|
|
527
|
+
parsed_edits: edits.length,
|
|
528
|
+
successful,
|
|
529
|
+
failed: edits.length - successful,
|
|
530
|
+
total_latency_ms: totalLatency,
|
|
531
|
+
results
|
|
532
|
+
}, null, 2);
|
|
533
|
+
}
|
|
534
|
+
catch (error) {
|
|
535
|
+
throw new Error(`Failed to parse and apply markdown edits: ${error.message}`);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
});
|
|
539
|
+
console.error('✅ Registered 10 tools (7 agentic-flow + 3 agent-booster):');
|
|
294
540
|
console.error(' • agentic_flow_agent (execute agent with 13 parameters)');
|
|
295
541
|
console.error(' • agentic_flow_list_agents (list 66+ agents)');
|
|
296
542
|
console.error(' • agentic_flow_create_agent (create custom agent)');
|
|
297
543
|
console.error(' • agentic_flow_list_all_agents (list with sources)');
|
|
298
544
|
console.error(' • agentic_flow_agent_info (get agent details)');
|
|
299
545
|
console.error(' • agentic_flow_check_conflicts (conflict detection)');
|
|
300
|
-
console.error(' • agentic_flow_optimize_model (auto-select best model)
|
|
546
|
+
console.error(' • agentic_flow_optimize_model (auto-select best model)');
|
|
547
|
+
console.error(' • agent_booster_edit_file (352x faster code editing) ⚡ NEW');
|
|
548
|
+
console.error(' • agent_booster_batch_edit (multi-file refactoring) ⚡ NEW');
|
|
549
|
+
console.error(' • agent_booster_parse_markdown (LLM output parsing) ⚡ NEW');
|
|
301
550
|
console.error('🔌 Starting stdio transport...');
|
|
302
551
|
server.start({ transportType: 'stdio' }).then(() => {
|
|
303
552
|
console.error('✅ Agentic-Flow MCP server running on stdio');
|
|
@@ -48,8 +48,11 @@ export class AnthropicToRequestyProxy {
|
|
|
48
48
|
});
|
|
49
49
|
// Anthropic Messages API → Requesty Chat Completions
|
|
50
50
|
this.app.post('/v1/messages', async (req, res) => {
|
|
51
|
+
console.log('🔵 REQUEST RECEIVED AT PROXY - /v1/messages');
|
|
52
|
+
logger.info('🔵 REQUEST RECEIVED AT PROXY - /v1/messages');
|
|
51
53
|
try {
|
|
52
54
|
const anthropicReq = req.body;
|
|
55
|
+
console.log('🔵 Request body parsed successfully');
|
|
53
56
|
// VERBOSE LOGGING: Log incoming Anthropic request
|
|
54
57
|
// Handle system prompt which can be string OR array of content blocks
|
|
55
58
|
const systemPreview = typeof anthropicReq.system === 'string'
|
|
@@ -256,21 +259,83 @@ export class AnthropicToRequestyProxy {
|
|
|
256
259
|
};
|
|
257
260
|
}
|
|
258
261
|
async callRequesty(openaiReq) {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
262
|
+
// Add timeout for Requesty API calls (60 seconds)
|
|
263
|
+
const controller = new AbortController();
|
|
264
|
+
const timeoutId = setTimeout(() => controller.abort(), 60000);
|
|
265
|
+
try {
|
|
266
|
+
const response = await fetch(`${this.requestyBaseUrl}/chat/completions`, {
|
|
267
|
+
method: 'POST',
|
|
268
|
+
headers: {
|
|
269
|
+
'Authorization': `Bearer ${this.requestyApiKey}`,
|
|
270
|
+
'Content-Type': 'application/json',
|
|
271
|
+
'HTTP-Referer': 'https://github.com/ruvnet/agentic-flow',
|
|
272
|
+
'X-Title': 'Agentic Flow'
|
|
273
|
+
},
|
|
274
|
+
body: JSON.stringify(openaiReq),
|
|
275
|
+
signal: controller.signal
|
|
276
|
+
});
|
|
277
|
+
clearTimeout(timeoutId);
|
|
278
|
+
if (!response.ok) {
|
|
279
|
+
const error = await response.text();
|
|
280
|
+
throw new Error(`Requesty API error: ${error}`);
|
|
281
|
+
}
|
|
282
|
+
return response.json();
|
|
283
|
+
}
|
|
284
|
+
catch (error) {
|
|
285
|
+
clearTimeout(timeoutId);
|
|
286
|
+
if (error.name === 'AbortError') {
|
|
287
|
+
throw new Error('Requesty API request timed out after 60 seconds');
|
|
288
|
+
}
|
|
289
|
+
throw error;
|
|
272
290
|
}
|
|
273
|
-
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Sanitize JSON Schema to be OpenAI-compatible
|
|
294
|
+
* Fixes array properties without items, removes unsupported keywords
|
|
295
|
+
*/
|
|
296
|
+
sanitizeJsonSchema(schema, path = 'root') {
|
|
297
|
+
if (!schema || typeof schema !== 'object') {
|
|
298
|
+
return schema;
|
|
299
|
+
}
|
|
300
|
+
// Create a shallow copy to avoid mutations
|
|
301
|
+
const sanitized = { ...schema };
|
|
302
|
+
// Fix array types without items
|
|
303
|
+
if (sanitized.type === 'array' && !sanitized.items) {
|
|
304
|
+
logger.warn(`Schema sanitization: Adding missing 'items' for array at ${path}`);
|
|
305
|
+
sanitized.items = { type: 'string' };
|
|
306
|
+
}
|
|
307
|
+
// Remove JSON Schema 2020-12 keywords not supported by OpenAI
|
|
308
|
+
const unsupportedKeywords = [
|
|
309
|
+
'$schema', '$id', '$ref', '$defs', 'definitions',
|
|
310
|
+
'if', 'then', 'else', 'dependentSchemas', 'dependentRequired',
|
|
311
|
+
'prefixItems', 'unevaluatedItems', 'unevaluatedProperties',
|
|
312
|
+
'minContains', 'maxContains', 'patternProperties',
|
|
313
|
+
'additionalItems', 'contains'
|
|
314
|
+
];
|
|
315
|
+
for (const keyword of unsupportedKeywords) {
|
|
316
|
+
if (keyword in sanitized) {
|
|
317
|
+
logger.warn(`Schema sanitization: Removing unsupported keyword '${keyword}' at ${path}`);
|
|
318
|
+
delete sanitized[keyword];
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
// Recursively sanitize nested properties
|
|
322
|
+
if (sanitized.properties && typeof sanitized.properties === 'object') {
|
|
323
|
+
sanitized.properties = {};
|
|
324
|
+
for (const [key, value] of Object.entries(schema.properties)) {
|
|
325
|
+
sanitized.properties[key] = this.sanitizeJsonSchema(value, `${path}.properties.${key}`);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
// Recursively sanitize array items
|
|
329
|
+
if (sanitized.items && typeof sanitized.items === 'object') {
|
|
330
|
+
sanitized.items = this.sanitizeJsonSchema(sanitized.items, `${path}.items`);
|
|
331
|
+
}
|
|
332
|
+
// Recursively sanitize allOf, anyOf, oneOf
|
|
333
|
+
for (const combinator of ['allOf', 'anyOf', 'oneOf']) {
|
|
334
|
+
if (Array.isArray(sanitized[combinator])) {
|
|
335
|
+
sanitized[combinator] = sanitized[combinator].map((subschema, index) => this.sanitizeJsonSchema(subschema, `${path}.${combinator}[${index}]`));
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
return sanitized;
|
|
274
339
|
}
|
|
275
340
|
convertAnthropicToOpenAI(anthropicReq) {
|
|
276
341
|
logger.info('=== STARTING ANTHROPIC TO OPENAI CONVERSION ===');
|
|
@@ -380,30 +445,45 @@ export class AnthropicToRequestyProxy {
|
|
|
380
445
|
};
|
|
381
446
|
// Convert MCP/Anthropic tools to OpenAI tools format
|
|
382
447
|
if (anthropicReq.tools && anthropicReq.tools.length > 0) {
|
|
383
|
-
logger.info('Converting MCP tools to OpenAI format...'
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
448
|
+
logger.info('Converting MCP tools to OpenAI format...', {
|
|
449
|
+
totalTools: anthropicReq.tools.length
|
|
450
|
+
});
|
|
451
|
+
// Requesty has strict limits - only send a subset of tools to avoid timeouts
|
|
452
|
+
// Requesty also rejects empty tools arrays, so we either send tools or omit the parameter
|
|
453
|
+
const MAX_TOOLS_FOR_REQUESTY = 10; // Very conservative limit - Requesty timeouts with more
|
|
454
|
+
const toolsToConvert = anthropicReq.tools.slice(0, MAX_TOOLS_FOR_REQUESTY);
|
|
455
|
+
if (anthropicReq.tools.length > MAX_TOOLS_FOR_REQUESTY) {
|
|
456
|
+
logger.warn(`Limiting tools to ${MAX_TOOLS_FOR_REQUESTY} for Requesty (${anthropicReq.tools.length} available)`);
|
|
457
|
+
}
|
|
458
|
+
// Only set tools if we have at least one (Requesty rejects empty arrays)
|
|
459
|
+
if (toolsToConvert.length > 0) {
|
|
460
|
+
openaiReq.tools = toolsToConvert.map(tool => {
|
|
461
|
+
// Sanitize the input schema to fix array properties without items
|
|
462
|
+
const rawSchema = tool.input_schema || {
|
|
463
|
+
type: 'object',
|
|
464
|
+
properties: {},
|
|
465
|
+
required: []
|
|
466
|
+
};
|
|
467
|
+
const sanitizedSchema = this.sanitizeJsonSchema(rawSchema, `tool.${tool.name}`);
|
|
468
|
+
const openaiTool = {
|
|
469
|
+
type: 'function',
|
|
470
|
+
function: {
|
|
471
|
+
name: tool.name,
|
|
472
|
+
description: tool.description || '',
|
|
473
|
+
parameters: sanitizedSchema
|
|
394
474
|
}
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
logger.info(`Converted tool: ${tool.name}`, {
|
|
398
|
-
hasDescription: !!tool.description,
|
|
399
|
-
hasInputSchema: !!tool.input_schema
|
|
475
|
+
};
|
|
476
|
+
return openaiTool;
|
|
400
477
|
});
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
478
|
+
logger.info('Forwarding MCP tools to Requesty', {
|
|
479
|
+
toolCount: openaiReq.tools.length,
|
|
480
|
+
toolNames: openaiReq.tools.map(t => t.function.name).slice(0, 5)
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
else {
|
|
484
|
+
logger.info('No tools to send (omitting tools parameter entirely for Requesty)');
|
|
485
|
+
// Don't set openaiReq.tools at all - Requesty rejects empty arrays
|
|
486
|
+
}
|
|
407
487
|
}
|
|
408
488
|
else {
|
|
409
489
|
logger.info('No MCP tools to convert');
|
package/dist/utils/cli.js
CHANGED
|
@@ -130,6 +130,7 @@ USAGE:
|
|
|
130
130
|
npx agentic-flow [COMMAND] [OPTIONS]
|
|
131
131
|
|
|
132
132
|
COMMANDS:
|
|
133
|
+
claude-code [options] Spawn Claude Code with proxy + Agent Booster (57x faster edits)
|
|
133
134
|
mcp <command> [server] Manage MCP servers (start, stop, status, list)
|
|
134
135
|
config [command] Configuration wizard (set, get, list, delete, reset)
|
|
135
136
|
agent <command> Agent management (list, create, info, conflicts)
|
|
@@ -178,6 +179,11 @@ OPTIONS:
|
|
|
178
179
|
--help, -h Show this help message
|
|
179
180
|
|
|
180
181
|
EXAMPLES:
|
|
182
|
+
# Claude Code with Agent Booster (57x faster code edits)
|
|
183
|
+
npx agentic-flow claude-code --provider openrouter --agent-booster
|
|
184
|
+
npx agentic-flow claude-code --provider gemini "Write a REST API"
|
|
185
|
+
npx agentic-flow claude-code --help # See all claude-code options
|
|
186
|
+
|
|
181
187
|
# Agent Management
|
|
182
188
|
npx agentic-flow agent list # List all agents with sources
|
|
183
189
|
npx agentic-flow agent create # Interactive agent creator
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentic-flow",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Production-ready AI agent orchestration platform with 66 specialized agents, 213 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",
|