claude-flow 2.5.0-alpha.141 → 2.7.0-alpha
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/.claude/agents/reasoning/README.md +171 -0
- package/.claude/agents/reasoning/agent.md +816 -0
- package/.claude/agents/reasoning/example-reasoning-agent-template.md +362 -0
- package/.claude/agents/reasoning/goal-planner.md +73 -0
- package/.claude/commands/coordination/README.md +9 -0
- package/.claude/commands/memory/README.md +9 -0
- package/.claude/settings.json +3 -3
- package/.claude/sparc-modes.json +108 -0
- package/README.md +1 -6
- package/bin/claude-flow +1 -1
- package/dist/src/cli/command-registry.js +70 -6
- package/dist/src/cli/command-registry.js.map +1 -1
- package/dist/src/cli/help-formatter.js +0 -3
- package/dist/src/cli/help-formatter.js.map +1 -1
- package/dist/src/cli/help-text.js +53 -5
- package/dist/src/cli/help-text.js.map +1 -1
- package/dist/src/cli/simple-cli.js +182 -172
- package/dist/src/cli/simple-cli.js.map +1 -1
- package/dist/src/cli/simple-commands/agent-booster.js +415 -0
- package/dist/src/cli/simple-commands/agent-booster.js.map +1 -0
- package/dist/src/cli/simple-commands/agent.js +856 -13
- package/dist/src/cli/simple-commands/agent.js.map +1 -1
- package/dist/src/cli/simple-commands/env-template.js +180 -0
- package/dist/src/cli/simple-commands/env-template.js.map +1 -0
- package/dist/src/cli/simple-commands/init/help.js +23 -0
- package/dist/src/cli/simple-commands/init/help.js.map +1 -1
- package/dist/src/cli/simple-commands/init/index.js +63 -0
- package/dist/src/cli/simple-commands/init/index.js.map +1 -1
- package/dist/src/cli/simple-commands/memory.js +307 -16
- package/dist/src/cli/simple-commands/memory.js.map +1 -1
- package/dist/src/cli/simple-commands/proxy.js +304 -0
- package/dist/src/cli/simple-commands/proxy.js.map +1 -0
- package/dist/src/cli/simple-commands/sparc.js +16 -19
- package/dist/src/cli/simple-commands/sparc.js.map +1 -1
- package/dist/src/cli/validation-helper.js.map +1 -1
- package/dist/src/core/version.js +1 -1
- package/dist/src/execution/agent-executor.js +181 -0
- package/dist/src/execution/agent-executor.js.map +1 -0
- package/dist/src/execution/index.js +12 -0
- package/dist/src/execution/index.js.map +1 -0
- package/dist/src/execution/provider-manager.js +110 -0
- package/dist/src/execution/provider-manager.js.map +1 -0
- package/dist/src/hooks/redaction-hook.js +89 -0
- package/dist/src/hooks/redaction-hook.js.map +1 -0
- package/dist/src/memory/swarm-memory.js +340 -421
- package/dist/src/memory/swarm-memory.js.map +1 -1
- package/dist/src/utils/key-redactor.js +108 -0
- package/dist/src/utils/key-redactor.js.map +1 -0
- package/dist/src/utils/metrics-reader.js +37 -39
- package/dist/src/utils/metrics-reader.js.map +1 -1
- package/docs/AGENT-BOOSTER-INTEGRATION.md +407 -0
- package/docs/AGENTIC-FLOW-INTEGRATION-GUIDE.md +753 -0
- package/docs/AGENTIC_FLOW_EXECUTION_FIX_REPORT.md +474 -0
- package/docs/AGENTIC_FLOW_INTEGRATION_STATUS.md +143 -0
- package/docs/AGENTIC_FLOW_MVP_COMPLETE.md +367 -0
- package/docs/AGENTIC_FLOW_SECURITY_TEST_REPORT.md +369 -0
- package/docs/COMMAND-VERIFICATION-REPORT.md +441 -0
- package/docs/COMMIT_SUMMARY.md +247 -0
- package/docs/DEEP_REVIEW_COMPREHENSIVE_REPORT.md +922 -0
- package/docs/DOCKER-VALIDATION-REPORT.md +281 -0
- package/docs/ENV-SETUP-GUIDE.md +270 -0
- package/docs/FINAL_PRE_PUBLISH_VALIDATION.md +823 -0
- package/docs/FINAL_VALIDATION_REPORT.md +165 -0
- package/docs/HOOKS-V2-MODIFICATION.md +146 -0
- package/docs/INDEX.md +568 -0
- package/docs/INTEGRATION_COMPLETE.md +414 -0
- package/docs/MEMORY_REDACTION_TEST_REPORT.md +300 -0
- package/docs/PERFORMANCE-SYSTEMS-STATUS.md +340 -0
- package/docs/PRE_RELEASE_FIXES_REPORT.md +435 -0
- package/docs/README.md +35 -0
- package/docs/REASONING-AGENTS.md +482 -0
- package/docs/REASONINGBANK-AGENT-CREATION-GUIDE.md +813 -0
- package/docs/REASONINGBANK-ANALYSIS-COMPLETE.md +479 -0
- package/docs/REASONINGBANK-BENCHMARK-RESULTS.md +166 -0
- package/docs/REASONINGBANK-BENCHMARK.md +396 -0
- package/docs/REASONINGBANK-CLI-INTEGRATION.md +455 -0
- package/docs/REASONINGBANK-CORE-INTEGRATION.md +658 -0
- package/docs/REASONINGBANK-COST-OPTIMIZATION.md +329 -0
- package/docs/REASONINGBANK-DEMO.md +419 -0
- package/docs/REASONINGBANK-INTEGRATION-COMPLETE.md +249 -0
- package/docs/REASONINGBANK-VALIDATION.md +532 -0
- package/docs/REASONINGBANK_ARCHITECTURE.md +475 -0
- package/docs/REASONINGBANK_INTEGRATION_COMPLETE.md +558 -0
- package/docs/REASONINGBANK_INTEGRATION_PLAN.md +1188 -0
- package/docs/REGRESSION-ANALYSIS-REPORT.md +500 -0
- package/docs/RELEASE_v2.6.0-alpha.2.md +658 -0
- package/docs/api/API_DOCUMENTATION.md +721 -0
- package/docs/architecture/ARCHITECTURE.md +1690 -0
- package/docs/ci-cd/README.md +368 -0
- package/docs/development/DEPLOYMENT.md +2348 -0
- package/docs/development/DEVELOPMENT_WORKFLOW.md +1333 -0
- package/docs/development/build-analysis-report.md +252 -0
- package/docs/development/pair-optimization.md +156 -0
- package/docs/development/token-tracking-status.md +103 -0
- package/docs/development/training-pipeline-demo.md +163 -0
- package/docs/development/training-pipeline-real-only.md +196 -0
- package/docs/epic-sdk-integration.md +1269 -0
- package/docs/experimental/RIEMANN_HYPOTHESIS_PROOF.md +124 -0
- package/docs/experimental/computational_verification.py +436 -0
- package/docs/experimental/novel_approaches.md +560 -0
- package/docs/experimental/riemann_hypothesis_analysis.md +263 -0
- package/docs/experimental/riemann_proof_attempt.md +124 -0
- package/docs/experimental/riemann_synthesis.md +277 -0
- package/docs/experimental/verification_results.json +12 -0
- package/docs/experimental/visualization_insights.md +720 -0
- package/docs/guides/USER_GUIDE.md +1138 -0
- package/docs/guides/token-tracking-guide.md +291 -0
- package/docs/reference/AGENTS.md +1011 -0
- package/docs/reference/MCP_TOOLS.md +2188 -0
- package/docs/reference/SPARC.md +717 -0
- package/docs/reference/SWARM.md +2000 -0
- package/docs/sdk/CLAUDE-CODE-SDK-DEEP-ANALYSIS.md +649 -0
- package/docs/sdk/CLAUDE-FLOW-SDK-INTEGRATION-ANALYSIS.md +242 -0
- package/docs/sdk/INTEGRATION-ROADMAP.md +420 -0
- package/docs/sdk/MCP-TOOLS-UPDATE.md +270 -0
- package/docs/sdk/SDK-ADVANCED-FEATURES-INTEGRATION.md +723 -0
- package/docs/sdk/SDK-ALL-FEATURES-INTEGRATION-MATRIX.md +612 -0
- package/docs/sdk/SDK-INTEGRATION-COMPLETE.md +358 -0
- package/docs/sdk/SDK-INTEGRATION-PHASES-V2.5.md +750 -0
- package/docs/sdk/SDK-LEVERAGE-REAL-FEATURES.md +676 -0
- package/docs/sdk/SDK-VALIDATION-RESULTS.md +400 -0
- package/docs/sdk/epic-sdk-integration.md +1269 -0
- package/docs/setup/remote-setup.md +93 -0
- package/docs/validation/final-validation-summary.md +220 -0
- package/docs/validation/verification-integration.md +190 -0
- package/docs/validation/verification-validation.md +349 -0
- package/docs/wiki/background-commands.md +1213 -0
- package/docs/wiki/session-persistence.md +342 -0
- package/docs/wiki/stream-chain-command.md +537 -0
- package/package.json +4 -2
- package/src/cli/command-registry.js +70 -5
- package/src/cli/help-text.js +26 -5
- package/src/cli/simple-cli.ts +18 -7
- package/src/cli/simple-commands/agent-booster.js +515 -0
- package/src/cli/simple-commands/agent.js +1001 -12
- package/src/cli/simple-commands/agent.ts +137 -0
- package/src/cli/simple-commands/config.ts +127 -0
- package/src/cli/simple-commands/env-template.js +190 -0
- package/src/cli/simple-commands/init/help.js +23 -0
- package/src/cli/simple-commands/init/index.js +84 -6
- package/src/cli/simple-commands/memory.js +363 -16
- package/src/cli/simple-commands/proxy.js +384 -0
- package/src/cli/simple-commands/sparc.js +16 -19
- package/src/execution/agent-executor.ts +306 -0
- package/src/execution/index.ts +19 -0
- package/src/execution/provider-manager.ts +187 -0
- package/src/hooks/redaction-hook.ts +115 -0
- package/src/utils/key-redactor.js +178 -0
- package/src/utils/key-redactor.ts +184 -0
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Executor - Wrapper around agentic-flow execution engine
|
|
3
|
+
* Integrates agentic-flow agents with claude-flow hooks and coordination
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { exec } from 'child_process';
|
|
7
|
+
import { promisify } from 'util';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import fs from 'fs-extra';
|
|
10
|
+
|
|
11
|
+
const execAsync = promisify(exec);
|
|
12
|
+
|
|
13
|
+
export interface AgentExecutionOptions {
|
|
14
|
+
agent: string;
|
|
15
|
+
task: string;
|
|
16
|
+
provider?: 'anthropic' | 'openrouter' | 'onnx' | 'gemini';
|
|
17
|
+
model?: string;
|
|
18
|
+
temperature?: number;
|
|
19
|
+
maxTokens?: number;
|
|
20
|
+
outputFormat?: 'text' | 'json' | 'markdown';
|
|
21
|
+
stream?: boolean;
|
|
22
|
+
verbose?: boolean;
|
|
23
|
+
retryOnError?: boolean;
|
|
24
|
+
timeout?: number;
|
|
25
|
+
|
|
26
|
+
// ReasoningBank memory options
|
|
27
|
+
enableMemory?: boolean; // Enable ReasoningBank learning
|
|
28
|
+
memoryDatabase?: string; // Path to .swarm/memory.db
|
|
29
|
+
memoryRetrievalK?: number; // Top-k memories to retrieve (default: 3)
|
|
30
|
+
memoryLearning?: boolean; // Enable post-task learning (default: true)
|
|
31
|
+
memoryDomain?: string; // Domain filter for memories
|
|
32
|
+
memoryMinConfidence?: number; // Minimum confidence threshold (default: 0.5)
|
|
33
|
+
memoryTaskId?: string; // Unique task ID for tracking
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface AgentExecutionResult {
|
|
37
|
+
success: boolean;
|
|
38
|
+
output: string;
|
|
39
|
+
error?: string;
|
|
40
|
+
provider: string;
|
|
41
|
+
model: string;
|
|
42
|
+
tokens?: number;
|
|
43
|
+
cost?: number;
|
|
44
|
+
duration: number;
|
|
45
|
+
agent: string;
|
|
46
|
+
task: string;
|
|
47
|
+
|
|
48
|
+
// ReasoningBank metrics
|
|
49
|
+
memoryEnabled?: boolean;
|
|
50
|
+
memoriesRetrieved?: number;
|
|
51
|
+
memoriesUsed?: string[]; // IDs of memories applied
|
|
52
|
+
memoryLearned?: boolean; // Whether new memories were created
|
|
53
|
+
memoryVerdict?: 'success' | 'failure';
|
|
54
|
+
memoryConfidence?: number;
|
|
55
|
+
newMemoryIds?: string[]; // IDs of newly created memories
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export class AgentExecutor {
|
|
59
|
+
private readonly agenticFlowPath: string;
|
|
60
|
+
private readonly hooksManager: any;
|
|
61
|
+
private memoryEnabled: boolean = false;
|
|
62
|
+
private memoryDatabase: string = '.swarm/memory.db';
|
|
63
|
+
|
|
64
|
+
constructor(hooksManager?: any) {
|
|
65
|
+
this.hooksManager = hooksManager;
|
|
66
|
+
// Agentic-flow is installed as npm dependency
|
|
67
|
+
this.agenticFlowPath = 'npx agentic-flow';
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Initialize ReasoningBank database
|
|
72
|
+
*/
|
|
73
|
+
async initializeMemory(dbPath?: string): Promise<void> {
|
|
74
|
+
const db = dbPath || this.memoryDatabase;
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
const { stdout } = await execAsync(
|
|
78
|
+
`${this.agenticFlowPath} reasoningbank init`
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
this.memoryEnabled = true;
|
|
82
|
+
this.memoryDatabase = db;
|
|
83
|
+
console.log('✅ ReasoningBank initialized:', db);
|
|
84
|
+
} catch (error: any) {
|
|
85
|
+
console.error('Failed to initialize ReasoningBank:', error.message);
|
|
86
|
+
throw error;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Get memory statistics
|
|
92
|
+
*/
|
|
93
|
+
async getMemoryStats(): Promise<any> {
|
|
94
|
+
if (!this.memoryEnabled) {
|
|
95
|
+
return { enabled: false, totalMemories: 0 };
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
try {
|
|
99
|
+
const { stdout } = await execAsync(
|
|
100
|
+
`${this.agenticFlowPath} reasoningbank status`
|
|
101
|
+
);
|
|
102
|
+
return { enabled: true, output: stdout };
|
|
103
|
+
} catch (error: any) {
|
|
104
|
+
return { enabled: true, error: error.message };
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Run memory consolidation (dedup + prune)
|
|
110
|
+
*/
|
|
111
|
+
async consolidateMemories(): Promise<void> {
|
|
112
|
+
if (!this.memoryEnabled) return;
|
|
113
|
+
|
|
114
|
+
try {
|
|
115
|
+
await execAsync(
|
|
116
|
+
`${this.agenticFlowPath} reasoningbank consolidate`
|
|
117
|
+
);
|
|
118
|
+
console.log('✅ Memory consolidation complete');
|
|
119
|
+
} catch (error: any) {
|
|
120
|
+
console.warn('Consolidation failed:', error.message);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Execute an agent with agentic-flow
|
|
126
|
+
*/
|
|
127
|
+
async execute(options: AgentExecutionOptions): Promise<AgentExecutionResult> {
|
|
128
|
+
const startTime = Date.now();
|
|
129
|
+
const taskId = options.memoryTaskId || `task-${Date.now()}`;
|
|
130
|
+
|
|
131
|
+
try {
|
|
132
|
+
// Initialize memory if requested
|
|
133
|
+
if (options.enableMemory && !this.memoryEnabled) {
|
|
134
|
+
try {
|
|
135
|
+
await this.initializeMemory(options.memoryDatabase);
|
|
136
|
+
} catch (error) {
|
|
137
|
+
console.warn('Memory initialization failed, continuing without memory');
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Trigger pre-execution hook
|
|
142
|
+
if (this.hooksManager) {
|
|
143
|
+
await this.hooksManager.trigger('pre-agent-execute', {
|
|
144
|
+
agent: options.agent,
|
|
145
|
+
task: options.task,
|
|
146
|
+
provider: options.provider || 'anthropic',
|
|
147
|
+
timestamp: Date.now(),
|
|
148
|
+
memoryEnabled: this.memoryEnabled || options.enableMemory,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Build agentic-flow command
|
|
153
|
+
const command = this.buildCommand(options);
|
|
154
|
+
|
|
155
|
+
// Execute command
|
|
156
|
+
const { stdout, stderr } = await execAsync(command, {
|
|
157
|
+
timeout: options.timeout || 300000, // 5 minutes default
|
|
158
|
+
maxBuffer: 10 * 1024 * 1024, // 10MB buffer,
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
const duration = Date.now() - startTime;
|
|
162
|
+
|
|
163
|
+
// Parse output
|
|
164
|
+
const result: AgentExecutionResult = {
|
|
165
|
+
success: true,
|
|
166
|
+
output: stdout,
|
|
167
|
+
provider: options.provider || 'anthropic',
|
|
168
|
+
model: options.model || 'default',
|
|
169
|
+
duration,
|
|
170
|
+
agent: options.agent,
|
|
171
|
+
task: options.task,
|
|
172
|
+
memoryEnabled: this.memoryEnabled || options.enableMemory || false,
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
// Trigger post-execution hook
|
|
176
|
+
if (this.hooksManager) {
|
|
177
|
+
await this.hooksManager.trigger('post-agent-execute', {
|
|
178
|
+
agent: options.agent,
|
|
179
|
+
task: options.task,
|
|
180
|
+
result,
|
|
181
|
+
success: true,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return result;
|
|
186
|
+
} catch (error: any) {
|
|
187
|
+
const duration = Date.now() - startTime;
|
|
188
|
+
|
|
189
|
+
const result: AgentExecutionResult = {
|
|
190
|
+
success: false,
|
|
191
|
+
output: '',
|
|
192
|
+
error: error.message,
|
|
193
|
+
provider: options.provider || 'anthropic',
|
|
194
|
+
model: options.model || 'default',
|
|
195
|
+
duration,
|
|
196
|
+
agent: options.agent,
|
|
197
|
+
task: options.task,
|
|
198
|
+
memoryEnabled: this.memoryEnabled || options.enableMemory || false,
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
// Trigger error hook
|
|
202
|
+
if (this.hooksManager) {
|
|
203
|
+
await this.hooksManager.trigger('agent-execute-error', {
|
|
204
|
+
agent: options.agent,
|
|
205
|
+
task: options.task,
|
|
206
|
+
error: error.message,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return result;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* List available agents from agentic-flow
|
|
216
|
+
*/
|
|
217
|
+
async listAgents(source?: 'all' | 'package' | 'local'): Promise<string[]> {
|
|
218
|
+
try {
|
|
219
|
+
// Agentic-flow uses 'agent list' command
|
|
220
|
+
const command = source
|
|
221
|
+
? `${this.agenticFlowPath} agent list --filter ${source}`
|
|
222
|
+
: `${this.agenticFlowPath} agent list`;
|
|
223
|
+
|
|
224
|
+
const { stdout } = await execAsync(command);
|
|
225
|
+
|
|
226
|
+
// Parse agent list from output
|
|
227
|
+
const agents = stdout
|
|
228
|
+
.split('\n')
|
|
229
|
+
.filter(line => line.trim())
|
|
230
|
+
.map(line => line.trim());
|
|
231
|
+
|
|
232
|
+
return agents;
|
|
233
|
+
} catch (error: any) {
|
|
234
|
+
console.error('Failed to list agents:', error.message);
|
|
235
|
+
return [];
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Get agent information
|
|
241
|
+
*/
|
|
242
|
+
async getAgentInfo(agentName: string): Promise<any> {
|
|
243
|
+
try {
|
|
244
|
+
// Agentic-flow uses 'agent info' command
|
|
245
|
+
const command = `${this.agenticFlowPath} agent info ${agentName}`;
|
|
246
|
+
const { stdout } = await execAsync(command);
|
|
247
|
+
|
|
248
|
+
// Try to parse as JSON if it looks like JSON
|
|
249
|
+
if (stdout.trim().startsWith('{')) {
|
|
250
|
+
return JSON.parse(stdout);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Otherwise return as plain text
|
|
254
|
+
return { name: agentName, description: stdout };
|
|
255
|
+
} catch (error: any) {
|
|
256
|
+
console.error('Failed to get agent info:', error.message);
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Build agentic-flow command from options
|
|
263
|
+
*/
|
|
264
|
+
private buildCommand(options: AgentExecutionOptions): string {
|
|
265
|
+
const parts = [this.agenticFlowPath];
|
|
266
|
+
|
|
267
|
+
// Agentic-flow uses --agent flag directly (no 'execute' subcommand)
|
|
268
|
+
parts.push('--agent', options.agent);
|
|
269
|
+
parts.push('--task', `"${options.task.replace(/"/g, '\\"')}"`);
|
|
270
|
+
|
|
271
|
+
if (options.provider) {
|
|
272
|
+
parts.push('--provider', options.provider);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (options.model) {
|
|
276
|
+
parts.push('--model', options.model);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (options.temperature !== undefined) {
|
|
280
|
+
parts.push('--temperature', options.temperature.toString());
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
if (options.maxTokens) {
|
|
284
|
+
parts.push('--max-tokens', options.maxTokens.toString());
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (options.outputFormat) {
|
|
288
|
+
parts.push('--output-format', options.outputFormat);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
if (options.stream) {
|
|
292
|
+
parts.push('--stream');
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
if (options.verbose) {
|
|
296
|
+
parts.push('--verbose');
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Note: agentic-flow doesn't have a --retry flag
|
|
300
|
+
// Retry logic should be handled by AgentExecutor if needed
|
|
301
|
+
|
|
302
|
+
return parts.join(' ');
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
export default AgentExecutor;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Execution Layer - Agentic-Flow Integration
|
|
3
|
+
* Entry point for multi-provider agent execution
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export { AgentExecutor, type AgentExecutionOptions, type AgentExecutionResult } from './agent-executor.js';
|
|
7
|
+
export { ProviderManager, type ProviderConfig, type ExecutionConfig } from './provider-manager.js';
|
|
8
|
+
|
|
9
|
+
// Convenience exports
|
|
10
|
+
import { AgentExecutor } from './agent-executor.js';
|
|
11
|
+
import { ProviderManager } from './provider-manager.js';
|
|
12
|
+
|
|
13
|
+
export function createExecutor(hooksManager?: any) {
|
|
14
|
+
return new AgentExecutor(hooksManager);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function createProviderManager() {
|
|
18
|
+
return new ProviderManager();
|
|
19
|
+
}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider Manager - Handles multi-provider configuration and selection
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import fs from 'fs-extra';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import os from 'os';
|
|
8
|
+
|
|
9
|
+
export interface ProviderConfig {
|
|
10
|
+
name: 'anthropic' | 'openrouter' | 'onnx' | 'gemini';
|
|
11
|
+
model?: string;
|
|
12
|
+
apiKey?: string;
|
|
13
|
+
enabled: boolean;
|
|
14
|
+
priority?: 'cost' | 'quality' | 'speed' | 'privacy';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface ExecutionConfig {
|
|
18
|
+
defaultProvider: string;
|
|
19
|
+
providers: Record<string, ProviderConfig>;
|
|
20
|
+
optimization?: {
|
|
21
|
+
strategy: 'balanced' | 'cost' | 'quality' | 'speed' | 'privacy';
|
|
22
|
+
maxCostPerTask?: number;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export class ProviderManager {
|
|
27
|
+
private config: ExecutionConfig;
|
|
28
|
+
private configPath: string;
|
|
29
|
+
|
|
30
|
+
constructor() {
|
|
31
|
+
this.configPath = path.join(os.homedir(), '.claude', 'settings.json');
|
|
32
|
+
this.config = this.loadConfig();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Get default provider
|
|
37
|
+
*/
|
|
38
|
+
getDefaultProvider(): string {
|
|
39
|
+
return this.config.defaultProvider || 'anthropic';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Get provider configuration
|
|
44
|
+
*/
|
|
45
|
+
getProviderConfig(provider: string): ProviderConfig | null {
|
|
46
|
+
return this.config.providers?.[provider] || null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Set default provider
|
|
51
|
+
*/
|
|
52
|
+
async setDefaultProvider(provider: string): Promise<void> {
|
|
53
|
+
this.config.defaultProvider = provider;
|
|
54
|
+
await this.saveConfig();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Configure a provider
|
|
59
|
+
*/
|
|
60
|
+
async configureProvider(
|
|
61
|
+
provider: string,
|
|
62
|
+
config: Partial<ProviderConfig>
|
|
63
|
+
): Promise<void> {
|
|
64
|
+
if (!this.config.providers) {
|
|
65
|
+
this.config.providers = {};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
this.config.providers[provider] = {
|
|
69
|
+
...this.config.providers[provider],
|
|
70
|
+
name: provider as any,
|
|
71
|
+
...config,
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
await this.saveConfig();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* List available providers
|
|
79
|
+
*/
|
|
80
|
+
listProviders(): ProviderConfig[] {
|
|
81
|
+
if (!this.config.providers) {
|
|
82
|
+
return this.getDefaultProviders();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return Object.values(this.config.providers);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Get optimization strategy
|
|
90
|
+
*/
|
|
91
|
+
getOptimizationStrategy(): string {
|
|
92
|
+
return this.config.optimization?.strategy || 'balanced';
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Load configuration from file
|
|
97
|
+
*/
|
|
98
|
+
private loadConfig(): ExecutionConfig {
|
|
99
|
+
try {
|
|
100
|
+
if (fs.existsSync(this.configPath)) {
|
|
101
|
+
const data = fs.readFileSync(this.configPath, 'utf-8');
|
|
102
|
+
const settings = JSON.parse(data);
|
|
103
|
+
return settings['claude-flow']?.execution || this.getDefaultConfig();
|
|
104
|
+
}
|
|
105
|
+
} catch (error) {
|
|
106
|
+
console.warn('Failed to load provider config, using defaults');
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return this.getDefaultConfig();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Save configuration to file
|
|
114
|
+
*/
|
|
115
|
+
private async saveConfig(): Promise<void> {
|
|
116
|
+
try {
|
|
117
|
+
await fs.ensureDir(path.dirname(this.configPath));
|
|
118
|
+
|
|
119
|
+
let settings: any = {};
|
|
120
|
+
if (await fs.pathExists(this.configPath)) {
|
|
121
|
+
const data = await fs.readFile(this.configPath, 'utf-8');
|
|
122
|
+
settings = JSON.parse(data);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (!settings['claude-flow']) {
|
|
126
|
+
settings['claude-flow'] = {};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
settings['claude-flow'].execution = this.config;
|
|
130
|
+
|
|
131
|
+
await fs.writeFile(
|
|
132
|
+
this.configPath,
|
|
133
|
+
JSON.stringify(settings, null, 2),
|
|
134
|
+
'utf-8'
|
|
135
|
+
);
|
|
136
|
+
} catch (error: any) {
|
|
137
|
+
console.error('Failed to save provider config:', error.message);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Get default configuration
|
|
143
|
+
*/
|
|
144
|
+
private getDefaultConfig(): ExecutionConfig {
|
|
145
|
+
return {
|
|
146
|
+
defaultProvider: 'anthropic',
|
|
147
|
+
providers: {
|
|
148
|
+
anthropic: {
|
|
149
|
+
name: 'anthropic',
|
|
150
|
+
model: 'claude-sonnet-4-5-20250929',
|
|
151
|
+
enabled: true,
|
|
152
|
+
priority: 'quality',
|
|
153
|
+
},
|
|
154
|
+
openrouter: {
|
|
155
|
+
name: 'openrouter',
|
|
156
|
+
model: 'meta-llama/llama-3.1-8b-instruct',
|
|
157
|
+
enabled: true,
|
|
158
|
+
priority: 'cost',
|
|
159
|
+
},
|
|
160
|
+
onnx: {
|
|
161
|
+
name: 'onnx',
|
|
162
|
+
model: 'Xenova/gpt2',
|
|
163
|
+
enabled: true,
|
|
164
|
+
priority: 'privacy',
|
|
165
|
+
},
|
|
166
|
+
gemini: {
|
|
167
|
+
name: 'gemini',
|
|
168
|
+
enabled: true,
|
|
169
|
+
priority: 'cost',
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
optimization: {
|
|
173
|
+
strategy: 'balanced',
|
|
174
|
+
maxCostPerTask: 0.5,
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Get default providers list
|
|
181
|
+
*/
|
|
182
|
+
private getDefaultProviders(): ProviderConfig[] {
|
|
183
|
+
return Object.values(this.getDefaultConfig().providers);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export default ProviderManager;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git Pre-commit Hook for API Key Redaction
|
|
3
|
+
* Prevents sensitive data from being committed
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { KeyRedactor } from '../utils/key-redactor.js';
|
|
7
|
+
import { readFileSync } from 'fs';
|
|
8
|
+
import { execSync } from 'child_process';
|
|
9
|
+
|
|
10
|
+
export async function validateNoSensitiveData(): Promise<{ safe: boolean; issues: string[] }> {
|
|
11
|
+
const issues: string[] = [];
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
// Get staged files
|
|
15
|
+
const stagedFiles = execSync('git diff --cached --name-only', { encoding: 'utf-8' })
|
|
16
|
+
.split('\n')
|
|
17
|
+
.filter(f => f.trim() && !f.includes('.env') && !f.includes('node_modules') && !f.endsWith('.map'));
|
|
18
|
+
|
|
19
|
+
// Common documentation placeholder patterns (these are safe)
|
|
20
|
+
const placeholderPatterns = [
|
|
21
|
+
/API_KEY=\(paste/i,
|
|
22
|
+
/API_KEY=\(your/i,
|
|
23
|
+
/API_KEY=\.\.\./i,
|
|
24
|
+
/API_KEY="\.\.\."/i,
|
|
25
|
+
/API_KEY="\(paste/i,
|
|
26
|
+
/API_KEY="\(your/i,
|
|
27
|
+
/API_KEY=sk-ant-\.\.\./i, // Truncated example keys
|
|
28
|
+
/API_KEY=sk-or-v1-\.\.\./i, // Truncated example keys
|
|
29
|
+
/API_KEY="sk-ant-\.\.\."/i, // Quoted truncated keys
|
|
30
|
+
/API_KEY="sk-or-v1-\.\.\."/i, // Quoted truncated keys
|
|
31
|
+
/API_KEY=sk-ant-xxxxx/i, // xxxxx format examples
|
|
32
|
+
/API_KEY=sk-or-v1-xxxxx/i, // xxxxx format examples
|
|
33
|
+
/TOKEN=\(paste/i,
|
|
34
|
+
/TOKEN=\(your/i,
|
|
35
|
+
/SECRET=\(paste/i,
|
|
36
|
+
/SECRET=\(your/i,
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
// Check each staged file
|
|
40
|
+
for (const file of stagedFiles) {
|
|
41
|
+
try {
|
|
42
|
+
// Skip documentation files with obvious placeholders
|
|
43
|
+
if (file.startsWith('docs/') || file.includes('/docs/')) {
|
|
44
|
+
const content = readFileSync(file, 'utf-8');
|
|
45
|
+
// Check if file only contains placeholder patterns
|
|
46
|
+
const hasOnlyPlaceholders = placeholderPatterns.some(pattern => pattern.test(content));
|
|
47
|
+
if (hasOnlyPlaceholders) {
|
|
48
|
+
continue; // Skip - these are documentation examples
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const content = readFileSync(file, 'utf-8');
|
|
53
|
+
|
|
54
|
+
// Check for placeholder patterns in the content
|
|
55
|
+
const hasPlaceholders = placeholderPatterns.some(pattern => pattern.test(content));
|
|
56
|
+
if (hasPlaceholders && (file.includes('example') || file.includes('template') || file.includes('/docs/'))) {
|
|
57
|
+
continue; // Skip - these are examples/templates with placeholders
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const validation = KeyRedactor.validate(content);
|
|
61
|
+
|
|
62
|
+
if (!validation.safe) {
|
|
63
|
+
// Double-check: if warnings are only about placeholder patterns, skip
|
|
64
|
+
const warningsText = validation.warnings.join(' ');
|
|
65
|
+
if (hasPlaceholders && !warningsText.includes('sk-ant-a') && !warningsText.includes('sk-or-v')) {
|
|
66
|
+
continue; // Likely a false positive from documentation
|
|
67
|
+
}
|
|
68
|
+
issues.push(`⚠️ ${file}: ${validation.warnings.join(', ')}`);
|
|
69
|
+
}
|
|
70
|
+
} catch (error) {
|
|
71
|
+
// File might be deleted or binary
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
safe: issues.length === 0,
|
|
78
|
+
issues,
|
|
79
|
+
};
|
|
80
|
+
} catch (error) {
|
|
81
|
+
console.error('Error validating sensitive data:', error);
|
|
82
|
+
return {
|
|
83
|
+
safe: false,
|
|
84
|
+
issues: ['Failed to validate files'],
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export async function runRedactionCheck(): Promise<number> {
|
|
90
|
+
console.log('🔒 Running API key redaction check...\n');
|
|
91
|
+
|
|
92
|
+
const result = await validateNoSensitiveData();
|
|
93
|
+
|
|
94
|
+
if (!result.safe) {
|
|
95
|
+
console.error('❌ COMMIT BLOCKED - Sensitive data detected:\n');
|
|
96
|
+
result.issues.forEach(issue => console.error(issue));
|
|
97
|
+
console.error('\n⚠️ Please remove sensitive data before committing.');
|
|
98
|
+
console.error('💡 Tip: Use environment variables instead of hardcoding keys.\n');
|
|
99
|
+
return 1;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
console.log('✅ No sensitive data detected - safe to commit\n');
|
|
103
|
+
return 0;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// CLI execution (ES module compatible)
|
|
107
|
+
const isMainModule = import.meta.url === `file://${process.argv[1]}`;
|
|
108
|
+
if (isMainModule) {
|
|
109
|
+
runRedactionCheck()
|
|
110
|
+
.then(code => process.exit(code))
|
|
111
|
+
.catch(error => {
|
|
112
|
+
console.error('Error:', error);
|
|
113
|
+
process.exit(1);
|
|
114
|
+
});
|
|
115
|
+
}
|