mirror of
https://github.com/ruvnet/ruflo.git
synced 2026-10-23 03:47:00 +09:00
✅ Phase 2 Complete: Execution Layer API Alignment ## Overview Fixed critical API misalignment in agentic-flow integration that prevented agent execution. All 66+ agents now execute successfully with proper command structure and multi-provider support. ## Key Changes ### Execution Layer Fixes (src/execution/) - Fixed agent-executor.ts command building (removed non-existent 'execute' subcommand) - Corrected flag names (--format → --output-format) - Fixed agent listing (list-agents → agent list) - Fixed agent info (agent-info → agent info) - Added comprehensive error handling and logging ### CLI Integration (src/cli/simple-commands/) - Updated agent.js with correct command structure - Added agent.ts TypeScript implementation - Enhanced config.ts for provider management - Updated memory.js with API key redaction ### Security Features (src/utils/, src/hooks/) - Implemented KeyRedactor utility for sensitive data protection - Added redaction-hook for automatic API key detection - Support for Anthropic, OpenRouter, Gemini, Bearer tokens - Auto-validation warns when storing unredacted secrets ### Documentation (docs/) - AGENTIC_FLOW_EXECUTION_FIX_REPORT.md - Detailed fix analysis - AGENTIC_FLOW_INTEGRATION_STATUS.md - Integration tracking - AGENTIC_FLOW_MVP_COMPLETE.md - MVP completion details - RELEASE_v2.6.0-alpha.2.md - Release notes - FINAL_VALIDATION_REPORT.md - End-to-end test results - AGENTIC_FLOW_SECURITY_TEST_REPORT.md - Security validation - MEMORY_REDACTION_TEST_REPORT.md - Redaction feature tests ### Testing - test-agent-execution.sh - Automated validation script - All 4 test scenarios passing - End-to-end execution validated successfully ## API Corrections Before (Incorrect): npx agentic-flow execute --agent coder --task "Hello" npx agentic-flow list-agents After (Correct): npx agentic-flow --agent coder --task "Hello" npx agentic-flow agent list ## Test Results ✅ Agent Listing: PASS (66+ agents) ✅ Agent Info: PASS ✅ Agent Execution: PASS (end-to-end with Anthropic) ✅ TypeScript Build: PASS (582 files) ✅ Backwards Compatibility: PASS ✅ Security Features: PASS (API key redaction) ## Provider Support - Anthropic: ✅ Working (default, tested) - OpenRouter: ✅ Detected - Gemini: ✅ Detected - ONNX: ⚠️ Available (4.9GB model download required) ## Files Modified New Files: - src/execution/ (agent-executor.ts, provider-manager.ts, index.ts) - src/hooks/redaction-hook.ts - src/utils/key-redactor.ts - src/cli/simple-commands/agent.ts, config.ts - dist-cjs/src/execution/ (compiled) - docs/ (7 new documentation files) - test-agent-execution.sh - .githooks/pre-commit Modified Files: - src/cli/simple-commands/agent.js, memory.js - dist-cjs/ (compiled versions) ## Breaking Changes None - Full backwards compatibility maintained ## GitHub Issue Resolves #795 (Phase 2: Execution Layer API Alignment) ## Next Steps Ready for v2.6.0-alpha.2 release 🤖 Generated with Claude Code
127 lines
4.3 KiB
JavaScript
127 lines
4.3 KiB
JavaScript
import { exec } from 'child_process';
|
|
import { promisify } from 'util';
|
|
const execAsync = promisify(exec);
|
|
export class AgentExecutor {
|
|
agenticFlowPath;
|
|
hooksManager;
|
|
constructor(hooksManager){
|
|
this.hooksManager = hooksManager;
|
|
this.agenticFlowPath = 'npx agentic-flow';
|
|
}
|
|
async execute(options) {
|
|
const startTime = Date.now();
|
|
try {
|
|
if (this.hooksManager) {
|
|
await this.hooksManager.trigger('pre-agent-execute', {
|
|
agent: options.agent,
|
|
task: options.task,
|
|
provider: options.provider || 'anthropic',
|
|
timestamp: Date.now()
|
|
});
|
|
}
|
|
const command = this.buildCommand(options);
|
|
const { stdout, stderr } = await execAsync(command, {
|
|
timeout: options.timeout || 300000,
|
|
maxBuffer: 10 * 1024 * 1024
|
|
});
|
|
const duration = Date.now() - startTime;
|
|
const result = {
|
|
success: true,
|
|
output: stdout,
|
|
provider: options.provider || 'anthropic',
|
|
model: options.model || 'default',
|
|
duration,
|
|
agent: options.agent,
|
|
task: options.task
|
|
};
|
|
if (this.hooksManager) {
|
|
await this.hooksManager.trigger('post-agent-execute', {
|
|
agent: options.agent,
|
|
task: options.task,
|
|
result,
|
|
success: true
|
|
});
|
|
}
|
|
return result;
|
|
} catch (error) {
|
|
const duration = Date.now() - startTime;
|
|
const result = {
|
|
success: false,
|
|
output: '',
|
|
error: error.message,
|
|
provider: options.provider || 'anthropic',
|
|
model: options.model || 'default',
|
|
duration,
|
|
agent: options.agent,
|
|
task: options.task
|
|
};
|
|
if (this.hooksManager) {
|
|
await this.hooksManager.trigger('agent-execute-error', {
|
|
agent: options.agent,
|
|
task: options.task,
|
|
error: error.message
|
|
});
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
async listAgents(source) {
|
|
try {
|
|
const command = source ? `${this.agenticFlowPath} agent list --filter ${source}` : `${this.agenticFlowPath} agent list`;
|
|
const { stdout } = await execAsync(command);
|
|
const agents = stdout.split('\n').filter((line)=>line.trim()).map((line)=>line.trim());
|
|
return agents;
|
|
} catch (error) {
|
|
console.error('Failed to list agents:', error.message);
|
|
return [];
|
|
}
|
|
}
|
|
async getAgentInfo(agentName) {
|
|
try {
|
|
const command = `${this.agenticFlowPath} agent info ${agentName}`;
|
|
const { stdout } = await execAsync(command);
|
|
if (stdout.trim().startsWith('{')) {
|
|
return JSON.parse(stdout);
|
|
}
|
|
return {
|
|
name: agentName,
|
|
description: stdout
|
|
};
|
|
} catch (error) {
|
|
console.error('Failed to get agent info:', error.message);
|
|
return null;
|
|
}
|
|
}
|
|
buildCommand(options) {
|
|
const parts = [
|
|
this.agenticFlowPath
|
|
];
|
|
parts.push('--agent', options.agent);
|
|
parts.push('--task', `"${options.task.replace(/"/g, '\\"')}"`);
|
|
if (options.provider) {
|
|
parts.push('--provider', options.provider);
|
|
}
|
|
if (options.model) {
|
|
parts.push('--model', options.model);
|
|
}
|
|
if (options.temperature !== undefined) {
|
|
parts.push('--temperature', options.temperature.toString());
|
|
}
|
|
if (options.maxTokens) {
|
|
parts.push('--max-tokens', options.maxTokens.toString());
|
|
}
|
|
if (options.outputFormat) {
|
|
parts.push('--output-format', options.outputFormat);
|
|
}
|
|
if (options.stream) {
|
|
parts.push('--stream');
|
|
}
|
|
if (options.verbose) {
|
|
parts.push('--verbose');
|
|
}
|
|
return parts.join(' ');
|
|
}
|
|
}
|
|
export default AgentExecutor;
|
|
|
|
//# sourceMappingURL=agent-executor.js.map
|