agentic-flow 3.0.0 โ†’ 3.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.
Files changed (58) hide show
  1. package/.claude/skills/agentic-flow-quickstart/skill.md +6 -6
  2. package/.claude/skills/hooks-automation/skill.md +11 -11
  3. package/.claude/skills/memory-patterns/skill.md +7 -7
  4. package/.claude/skills/sparc-methodology/skill.md +13 -13
  5. package/.claude/skills/swarm-coordination/skill.md +5 -5
  6. package/.claude/skills/worker-benchmarks/skill.md +5 -5
  7. package/.claude/skills/worker-integration/skill.md +5 -5
  8. package/.claude/statusline.mjs +22 -5
  9. package/CHANGELOG.md +23 -0
  10. package/README.md +68 -71
  11. package/dist/.tsbuildinfo +1 -1
  12. package/dist/cli/commands/hooks.d.ts.map +1 -1
  13. package/dist/cli/commands/hooks.js +17 -17
  14. package/dist/cli/commands/hooks.js.map +1 -1
  15. package/dist/cli/commands/init.d.ts +2 -5
  16. package/dist/cli/commands/init.d.ts.map +1 -1
  17. package/dist/cli/commands/init.js +2 -15
  18. package/dist/cli/commands/init.js.map +1 -1
  19. package/dist/cli/commands/swarm.d.ts.map +1 -1
  20. package/dist/cli/commands/swarm.js +3 -2
  21. package/dist/cli/commands/swarm.js.map +1 -1
  22. package/dist/proxy/anthropic-to-gemini.d.ts.map +1 -1
  23. package/dist/proxy/anthropic-to-gemini.js +10 -14
  24. package/dist/proxy/anthropic-to-gemini.js.map +1 -1
  25. package/dist/proxy/anthropic-to-openrouter.d.ts.map +1 -1
  26. package/dist/proxy/anthropic-to-openrouter.js +6 -25
  27. package/dist/proxy/anthropic-to-openrouter.js.map +1 -1
  28. package/dist/proxy/anthropic-to-requesty.d.ts.map +1 -1
  29. package/dist/proxy/anthropic-to-requesty.js +8 -10
  30. package/dist/proxy/anthropic-to-requesty.js.map +1 -1
  31. package/dist/proxy/sse-lines.d.ts +9 -0
  32. package/dist/proxy/sse-lines.d.ts.map +1 -0
  33. package/dist/proxy/sse-lines.js +37 -0
  34. package/dist/proxy/sse-lines.js.map +1 -0
  35. package/dist/reasoningbank/index.d.ts +2 -1
  36. package/dist/reasoningbank/index.d.ts.map +1 -1
  37. package/dist/reasoningbank/index.js +1 -1
  38. package/dist/reasoningbank/index.js.map +1 -1
  39. package/dist/reasoningbank/utils/embeddings.d.ts +17 -0
  40. package/dist/reasoningbank/utils/embeddings.d.ts.map +1 -1
  41. package/dist/reasoningbank/utils/embeddings.js +48 -17
  42. package/dist/reasoningbank/utils/embeddings.js.map +1 -1
  43. package/dist/utils/package-version.d.ts +9 -0
  44. package/dist/utils/package-version.d.ts.map +1 -0
  45. package/dist/utils/package-version.js +39 -0
  46. package/dist/utils/package-version.js.map +1 -0
  47. package/docs/docker-tests/TEST-V1.7.8.Dockerfile +2 -2
  48. package/docs/docker-tests/TEST-V1.7.9-NODE20.Dockerfile +2 -2
  49. package/docs/docker-tests/TEST-V1.7.9.Dockerfile +2 -2
  50. package/docs/guides/CLAUDE-CODE-INTEGRATION.md +25 -8
  51. package/docs/guides/PROXY-ARCHITECTURE-AND-EXTENSION.md +22 -9
  52. package/docs/guides/STANDALONE_PROXY_GUIDE.md +16 -6
  53. package/docs/integrations/FASTMCP_CLI_INTEGRATION.md +1 -1
  54. package/docs/plans/requesty/02-architecture.md +5 -6
  55. package/docs/plans/requesty/03-implementation-phases.md +3 -4
  56. package/docs/plans/requesty/05-migration-guide.md +2 -2
  57. package/package.json +1 -1
  58. package/scripts/validate-providers.sh +7 -4
@@ -110,6 +110,7 @@ private convertOpenAIStreamToAnthropic(chunk: string): string {
110
110
  ```typescript
111
111
  import express, { Request, Response } from 'express';
112
112
  import { logger } from '../utils/logger.js';
113
+ import { createProxyAuthMiddleware, resolveProxyHost, resolveProxyToken } from './proxy-auth.js';
113
114
 
114
115
  interface MistralMessage {
115
116
  role: 'system' | 'user' | 'assistant';
@@ -124,18 +125,23 @@ interface MistralRequest {
124
125
  stream?: boolean;
125
126
  }
126
127
 
128
+ // Every proxy that holds an upstream key must bind loopback and require a
129
+ // token (3.0.0+). proxy-auth.ts gives you both.
127
130
  export class AnthropicToMistralProxy {
128
131
  private app: express.Application;
129
132
  private mistralApiKey: string;
130
133
  private mistralBaseUrl: string;
131
134
  private defaultModel: string;
135
+ private authToken: string;
132
136
 
133
137
  constructor(config: {
134
138
  mistralApiKey: string;
135
139
  mistralBaseUrl?: string;
136
140
  defaultModel?: string;
141
+ authToken?: string; // default: AGENTIC_FLOW_PROXY_TOKEN or a random token
137
142
  }) {
138
143
  this.app = express();
144
+ this.authToken = config.authToken || resolveProxyToken();
139
145
  this.mistralApiKey = config.mistralApiKey;
140
146
  this.mistralBaseUrl = config.mistralBaseUrl || 'https://api.mistral.ai/v1';
141
147
  this.defaultModel = config.defaultModel || 'mistral-large-latest';
@@ -144,7 +150,13 @@ export class AnthropicToMistralProxy {
144
150
  this.setupRoutes();
145
151
  }
146
152
 
153
+ public getAuthToken(): string {
154
+ return this.authToken;
155
+ }
156
+
147
157
  private setupMiddleware(): void {
158
+ // Reject callers without the token before parsing their body. /health stays open.
159
+ this.app.use(createProxyAuthMiddleware(this.authToken));
148
160
  this.app.use(express.json({ limit: '50mb' }));
149
161
  }
150
162
 
@@ -246,10 +258,11 @@ export class AnthropicToMistralProxy {
246
258
  };
247
259
  }
248
260
 
249
- public start(port: number): void {
250
- this.app.listen(port, () => {
251
- logger.info('Mistral proxy started', { port });
252
- console.log(`\nโœ… Mistral Proxy running at http://localhost:${port}\n`);
261
+ public start(port: number, host: string = resolveProxyHost()): void {
262
+ this.app.listen(port, host, () => {
263
+ logger.info('Mistral proxy started', { port, host });
264
+ console.log(`\nโœ… Mistral Proxy running at http://${host}:${port}`);
265
+ console.log(` export ANTHROPIC_API_KEY=${this.authToken}\n`);
253
266
  });
254
267
  }
255
268
  }
@@ -283,7 +296,7 @@ node dist/proxy/anthropic-to-mistral.js
283
296
 
284
297
  # Terminal 2: Use with Claude Code
285
298
  export ANTHROPIC_BASE_URL=http://localhost:3000
286
- export ANTHROPIC_API_KEY=dummy-key
299
+ export ANTHROPIC_API_KEY='<token printed by the proxy>'
287
300
  npx agentic-flow --agent coder --task "Write hello world"
288
301
  ```
289
302
 
@@ -440,7 +453,7 @@ node dist/proxy/anthropic-to-ollama.js
440
453
 
441
454
  # Terminal 2: Use with agents
442
455
  export ANTHROPIC_BASE_URL=http://localhost:3000
443
- export ANTHROPIC_API_KEY=dummy-key
456
+ export ANTHROPIC_API_KEY='<token printed by the proxy>'
444
457
  npx agentic-flow --agent coder --task "Write hello world"
445
458
  ```
446
459
 
@@ -621,7 +634,7 @@ describe('Mistral Proxy', () => {
621
634
  it('should convert Anthropic request to Mistral format', async () => {
622
635
  const response = await fetch(`http://localhost:${port}/v1/messages`, {
623
636
  method: 'POST',
624
- headers: { 'Content-Type': 'application/json' },
637
+ headers: { 'Content-Type': 'application/json', 'x-api-key': proxy.getAuthToken() },
625
638
  body: JSON.stringify({
626
639
  model: 'claude-3-5-sonnet-20241022',
627
640
  messages: [{ role: 'user', content: 'Hello!' }],
@@ -672,9 +685,9 @@ if (options.provider === 'mistral' || process.env.USE_MISTRAL) {
672
685
  });
673
686
  proxy.start(3000);
674
687
 
675
- // Set environment for SDK
688
+ // Set environment for SDK; the proxy rejects requests without its token
676
689
  process.env.ANTHROPIC_BASE_URL = 'http://localhost:3000';
677
- process.env.ANTHROPIC_API_KEY = 'dummy-key';
690
+ process.env.ANTHROPIC_API_KEY = proxy.getAuthToken();
678
691
  }
679
692
  ```
680
693
 
@@ -52,7 +52,7 @@ npx agentic-flow proxy --provider openrouter
52
52
  ```bash
53
53
  # Point Claude Code to the proxy
54
54
  export ANTHROPIC_BASE_URL=http://localhost:3000
55
- export ANTHROPIC_API_KEY=sk-ant-proxy-dummy-key # Any value works
55
+ export ANTHROPIC_API_KEY='<token printed by the proxy>' # required; see below
56
56
 
57
57
  # Now use Claude Code normally
58
58
  claude
@@ -63,6 +63,14 @@ claude --agent coder --task "Create a REST API in Python"
63
63
 
64
64
  **That's it!** Claude Code will now route all requests through the proxy, using Gemini or OpenRouter instead of Anthropic.
65
65
 
66
+ **Authentication (3.0.0+).** The proxy binds `127.0.0.1` and rejects any
67
+ `/v1/messages` request without its token, so nobody else on your network can
68
+ spend your provider key. On start it prints a random per-run token; pass it as
69
+ `ANTHROPIC_API_KEY` (sent as `x-api-key`) or as `Authorization: Bearer`. To
70
+ keep the same token across restarts, set `AGENTIC_FLOW_PROXY_TOKEN` before
71
+ starting the proxy and use that value. `AGENTIC_FLOW_PROXY_HOST` changes the
72
+ bind address; only widen it on a network you trust. `/health` needs no token.
73
+
66
74
  ## Usage with Cursor IDE
67
75
 
68
76
  **Status:** Cursor does not currently support custom `ANTHROPIC_BASE_URL` for Anthropic models.
@@ -79,7 +87,7 @@ npx agentic-flow proxy
79
87
  # Configure Cursor
80
88
  Settings โ†’ API Keys
81
89
  Anthropic Base URL: http://localhost:3000
82
- Anthropic API Key: sk-ant-proxy-dummy-key
90
+ Anthropic API Key: <token printed by the proxy>
83
91
  ```
84
92
 
85
93
  ## Full Command Reference
@@ -106,6 +114,8 @@ npx agentic-flow proxy [OPTIONS]
106
114
  | `GOOGLE_GEMINI_API_KEY` | Gemini | Your Google Gemini API key |
107
115
  | `OPENROUTER_API_KEY` | OpenRouter | Your OpenRouter API key |
108
116
  | `COMPLETION_MODEL` | Optional | Override default model |
117
+ | `AGENTIC_FLOW_PROXY_TOKEN` | Optional | Token clients must send (default: random per run, printed on start) |
118
+ | `AGENTIC_FLOW_PROXY_HOST` | Optional | Bind address (default: `127.0.0.1`) |
109
119
 
110
120
  ## Examples
111
121
 
@@ -117,7 +127,7 @@ npx agentic-flow proxy --port 8080
117
127
 
118
128
  # In another terminal
119
129
  export ANTHROPIC_BASE_URL=http://localhost:8080
120
- export ANTHROPIC_API_KEY=sk-ant-proxy-dummy-key
130
+ export ANTHROPIC_API_KEY='<token printed by the proxy>'
121
131
  claude
122
132
  ```
123
133
 
@@ -129,7 +139,7 @@ npx agentic-flow proxy --provider openrouter --model "anthropic/claude-3.5-sonne
129
139
 
130
140
  # Use Claude Code
131
141
  export ANTHROPIC_BASE_URL=http://localhost:3000
132
- export ANTHROPIC_API_KEY=sk-ant-proxy-dummy-key
142
+ export ANTHROPIC_API_KEY='<token printed by the proxy>'
133
143
  claude --agent researcher --task "Analyze market trends"
134
144
  ```
135
145
 
@@ -141,7 +151,7 @@ npx agentic-flow proxy --provider openrouter --model "deepseek/deepseek-chat-v3.
141
151
 
142
152
  # 98% cost savings vs Claude Sonnet!
143
153
  export ANTHROPIC_BASE_URL=http://localhost:3000
144
- export ANTHROPIC_API_KEY=sk-ant-proxy-dummy-key
154
+ export ANTHROPIC_API_KEY='<token printed by the proxy>'
145
155
  claude --agent coder --task "Build a web scraper"
146
156
  ```
147
157
 
@@ -233,7 +243,7 @@ npx agentic-flow proxy
233
243
  # Enable MCP in Claude Code
234
244
  export ENABLE_CLAUDE_FLOW_SDK=true
235
245
  export ANTHROPIC_BASE_URL=http://localhost:3000
236
- export ANTHROPIC_API_KEY=sk-ant-proxy-dummy-key
246
+ export ANTHROPIC_API_KEY='<token printed by the proxy>'
237
247
 
238
248
  # MCP tools will be forwarded to Gemini/OpenRouter
239
249
  claude --agent coder --task "Use memory_store to save config"
@@ -367,7 +367,7 @@ npm run build
367
367
  npm publish
368
368
 
369
369
  # Users can then use:
370
- npx agentic-flow@latest mcp start
370
+ npx agentic-flow@3.1.0 mcp start
371
371
  ```
372
372
 
373
373
  ## ๐Ÿš€ Advanced Usage
@@ -133,9 +133,8 @@ private async startRequestyProxy(modelOverride?: string): Promise<void> {
133
133
 
134
134
  process.env.ANTHROPIC_BASE_URL = `http://localhost:${this.proxyPort}`;
135
135
 
136
- if (!process.env.ANTHROPIC_API_KEY) {
137
- process.env.ANTHROPIC_API_KEY = 'sk-ant-proxy-dummy-key';
138
- }
136
+ // The proxy rejects requests without its per-run token (3.0.0+)
137
+ process.env.ANTHROPIC_API_KEY = proxy.getAuthToken();
139
138
 
140
139
  console.log(`๐Ÿ”— Proxy Mode: Requesty`);
141
140
  console.log(`๐Ÿ”ง Proxy URL: http://localhost:${this.proxyPort}`);
@@ -478,7 +477,7 @@ User CLI Command
478
477
  โ”‚
479
478
  โ”œโ”€> Set Environment Variables
480
479
  โ”‚ โ”œโ”€ ANTHROPIC_BASE_URL = http://localhost:3000
481
- โ”‚ โ””โ”€ ANTHROPIC_API_KEY = sk-ant-proxy-dummy-key
480
+ โ”‚ โ””โ”€ ANTHROPIC_API_KEY = <proxy's per-run token>
482
481
  โ”‚
483
482
  โ””โ”€> Execute Agent (claudeAgent.ts)
484
483
  โ”‚
@@ -932,12 +931,12 @@ Support running Requesty proxy as standalone server:
932
931
 
933
932
  ```bash
934
933
  # Terminal 1 - Run proxy
934
+ export REQUESTY_API_KEY=requesty-xxxxx
935
935
  npx agentic-flow proxy --provider requesty --port 3000 --model "openai/gpt-4o-mini"
936
936
 
937
937
  # Terminal 2 - Use with Claude Code
938
938
  export ANTHROPIC_BASE_URL=http://localhost:3000
939
- export ANTHROPIC_API_KEY=sk-ant-proxy-dummy-key
940
- export REQUESTY_API_KEY=requesty-xxxxx
939
+ export ANTHROPIC_API_KEY='<token printed by the proxy>'
941
940
  claude
942
941
  ```
943
942
 
@@ -286,10 +286,9 @@ private async startRequestyProxy(modelOverride?: string): Promise<void> {
286
286
  // Set ANTHROPIC_BASE_URL to proxy
287
287
  process.env.ANTHROPIC_BASE_URL = `http://localhost:${this.proxyPort}`;
288
288
 
289
- // Set dummy ANTHROPIC_API_KEY for proxy (actual auth uses REQUESTY_API_KEY)
290
- if (!process.env.ANTHROPIC_API_KEY) {
291
- process.env.ANTHROPIC_API_KEY = 'sk-ant-proxy-dummy-key';
292
- }
289
+ // The proxy rejects requests without its per-run token (3.0.0+);
290
+ // the upstream call still uses REQUESTY_API_KEY
291
+ process.env.ANTHROPIC_API_KEY = proxy.getAuthToken();
293
292
 
294
293
  console.log(`๐Ÿ”— Proxy Mode: Requesty`);
295
294
  console.log(`๐Ÿ”ง Proxy URL: http://localhost:${this.proxyPort}`);
@@ -258,6 +258,7 @@ npx agentic-flow --agent coder \
258
258
  #### Terminal 1 - Start Proxy
259
259
 
260
260
  ```bash
261
+ export REQUESTY_API_KEY="requesty-xxxxx"
261
262
  npx agentic-flow proxy --provider requesty --port 3000
262
263
  ```
263
264
 
@@ -265,8 +266,7 @@ npx agentic-flow proxy --provider requesty --port 3000
265
266
 
266
267
  ```bash
267
268
  export ANTHROPIC_BASE_URL="http://localhost:3000"
268
- export ANTHROPIC_API_KEY="sk-ant-proxy-dummy-key"
269
- export REQUESTY_API_KEY="requesty-xxxxx"
269
+ export ANTHROPIC_API_KEY="<token printed by the proxy>" # the proxy rejects any other key (3.0.0+)
270
270
 
271
271
  claude
272
272
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentic-flow",
3
- "version": "3.0.0",
3
+ "version": "3.1.0",
4
4
  "description": "The agentic meta-harness โ€” freeze the model, evolve the harness. An open runtime that routes each query to the cost-optimal model, evolves its own harness (planner/context/reviewer/retry/tool/memory/score policy) and autonomously repairs code, then orchestrates 66 specialized agents, 213 MCP tools, ReasoningBank memory, and multi-agent swarms on top. Built by @ruvnet on the Claude Agent SDK.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -7,6 +7,9 @@ echo "๐Ÿงช Agentic Flow - Provider Validation Suite"
7
7
  echo "==========================================="
8
8
  echo ""
9
9
 
10
+ # Exactly this checkout's version (override with AGENTIC_FLOW_SPEC), never a dist-tag
11
+ AF_SPEC="${AGENTIC_FLOW_SPEC:-agentic-flow@$(node -p "require('$(cd "$(dirname "$0")/.." && pwd)/package.json').version")}"
12
+
10
13
  # Colors
11
14
  GREEN='\033[0;32m'
12
15
  BLUE='\033[0;34m'
@@ -15,7 +18,7 @@ NC='\033[0m' # No Color
15
18
  # Test 1: Anthropic Provider
16
19
  if [ -n "$ANTHROPIC_API_KEY" ]; then
17
20
  echo -e "${BLUE}1๏ธโƒฃ Testing Anthropic Provider...${NC}"
18
- npx agentic-flow@latest --agent coder --task "Write hello world" --provider anthropic 2>&1 | grep -q "Completed" && \
21
+ npx "$AF_SPEC" --agent coder --task "Write hello world" --provider anthropic 2>&1 | grep -q "Completed" && \
19
22
  echo -e "${GREEN}โœ… Anthropic provider works${NC}" || \
20
23
  echo "โŒ Anthropic provider failed"
21
24
  else
@@ -27,19 +30,19 @@ echo ""
27
30
  # Test 2: OpenRouter Provider - Meta Llama
28
31
  if [ -n "$OPENROUTER_API_KEY" ]; then
29
32
  echo -e "${BLUE}2๏ธโƒฃ Testing OpenRouter - Meta Llama 3.1...${NC}"
30
- npx agentic-flow@latest --agent coder --task "Write hello world" --model "meta-llama/llama-3.1-8b-instruct" 2>&1 | grep -q "Completed" && \
33
+ npx "$AF_SPEC" --agent coder --task "Write hello world" --model "meta-llama/llama-3.1-8b-instruct" 2>&1 | grep -q "Completed" && \
31
34
  echo -e "${GREEN}โœ… OpenRouter (Meta Llama) works${NC}" || \
32
35
  echo "โŒ OpenRouter (Meta Llama) failed"
33
36
 
34
37
  echo ""
35
38
  echo -e "${BLUE}3๏ธโƒฃ Testing OpenRouter - DeepSeek...${NC}"
36
- npx agentic-flow@latest --agent coder --task "Write hello world" --model "deepseek/deepseek-chat" 2>&1 | grep -q "Completed" && \
39
+ npx "$AF_SPEC" --agent coder --task "Write hello world" --model "deepseek/deepseek-chat" 2>&1 | grep -q "Completed" && \
37
40
  echo -e "${GREEN}โœ… OpenRouter (DeepSeek) works${NC}" || \
38
41
  echo "โŒ OpenRouter (DeepSeek) failed"
39
42
 
40
43
  echo ""
41
44
  echo -e "${BLUE}4๏ธโƒฃ Testing OpenRouter - Gemini Free...${NC}"
42
- npx agentic-flow@latest --agent coder --task "Write hello world" --model "google/gemini-2.0-flash-exp:free" 2>&1 | grep -q "Completed" && \
45
+ npx "$AF_SPEC" --agent coder --task "Write hello world" --model "google/gemini-2.0-flash-exp:free" 2>&1 | grep -q "Completed" && \
43
46
  echo -e "${GREEN}โœ… OpenRouter (Gemini) works${NC}" || \
44
47
  echo "โŒ OpenRouter (Gemini) failed"
45
48
  else