Coverage for src/alprina_cli/main_agent.py: 0%

249 statements  

« prev     ^ index     » next       coverage.py v7.11.3, created at 2025-11-14 11:27 +0100

1""" 

2Main Alprina Agent - The orchestrator that users interact with. 

3 

4The Main Agent is aware of all specialized security agents and routes tasks accordingly. 

5Users talk to the Main Agent via CLI, which then coordinates with specialized agents. 

6 

7Architecture: 

8User → CLI → Main Alprina Agent → Security Agents (CodeAgent, Web Scanner, etc.) 

9""" 

10 

11from typing import Dict, Any, List, Optional 

12from loguru import logger 

13from datetime import datetime 

14 

15from .llm_provider import get_llm_client 

16from .security_engine import ( 

17 run_agent, 

18 run_local_scan, 

19 run_remote_scan, 

20 AGENTS_AVAILABLE 

21) 

22from .report_generator import generate_security_reports 

23from .workflows import ( 

24 AlprinaWorkflow, 

25 WorkflowType, 

26 evaluate_scan_quality, 

27 evaluate_comprehensive_scan 

28) 

29from .agent_coordinator import ( 

30 AgentCoordinator, 

31 ChainType, 

32 VulnerabilityState, 

33 get_coordinator 

34) 

35import asyncio 

36 

37 

38class MainAlprinaAgent: 

39 """ 

40 Main Alprina Agent - The orchestrator that coordinates all security operations. 

41 

42 This is the primary agent users interact with. It has knowledge of all specialized 

43 security agents and routes tasks to the appropriate agent. 

44 """ 

45 

46 # Registry of all available security agents 

47 SECURITY_AGENTS = { 

48 "codeagent": { 

49 "name": "CodeAgent", 

50 "task_type": "code-audit", 

51 "description": "Static Application Security Testing (SAST)", 

52 "capabilities": [ 

53 "SQL injection detection", 

54 "XSS (Cross-Site Scripting) detection", 

55 "CSRF vulnerability detection", 

56 "Authentication and authorization flaws", 

57 "Hardcoded secrets and credentials", 

58 "Insecure cryptography", 

59 "Input validation issues", 

60 "Dependency vulnerability scanning" 

61 ], 

62 "languages": ["Python", "JavaScript", "TypeScript", "Java", "Go", "PHP", "Ruby", "Rust", "C/C++", "C#"], 

63 "use_cases": [ 

64 "Scan source code files", 

65 "Find hardcoded secrets", 

66 "Detect code vulnerabilities", 

67 "Audit dependencies" 

68 ] 

69 }, 

70 "web_scanner": { 

71 "name": "Web Scanner Agent", 

72 "task_type": "web-recon", 

73 "description": "Web application and API security testing", 

74 "capabilities": [ 

75 "API endpoint security testing", 

76 "Authentication bypass detection", 

77 "Rate limiting analysis", 

78 "CORS misconfiguration detection", 

79 "Session management vulnerabilities", 

80 "HTTP security headers validation", 

81 "SSL/TLS configuration testing" 

82 ], 

83 "use_cases": [ 

84 "Scan web applications", 

85 "Test API endpoints", 

86 "Analyze authentication flows", 

87 "Check security headers" 

88 ] 

89 }, 

90 "bug_bounty": { 

91 "name": "Bug Bounty Agent", 

92 "task_type": "vuln-scan", 

93 "description": "OWASP Top 10 and business logic vulnerability detection", 

94 "capabilities": [ 

95 "OWASP Top 10 vulnerability detection", 

96 "Business logic flaws", 

97 "Authorization issues", 

98 "Information disclosure", 

99 "Server misconfigurations", 

100 "Insecure deserialization", 

101 "XXE (XML External Entities)", 

102 "Path traversal" 

103 ], 

104 "use_cases": [ 

105 "Comprehensive vulnerability scanning", 

106 "Business logic testing", 

107 "Authorization testing", 

108 "OWASP compliance checks" 

109 ] 

110 }, 

111 "secret_detection": { 

112 "name": "Secret Detection Agent", 

113 "task_type": "secret-detection", 

114 "description": "Credential and secret scanning", 

115 "capabilities": [ 

116 "API keys detection", 

117 "Passwords and tokens", 

118 "AWS/Cloud credentials", 

119 "Database connection strings", 

120 "Private keys and certificates", 

121 "OAuth tokens", 

122 "GitHub/GitLab tokens", 

123 "Slack tokens", 

124 "Entropy-based analysis" 

125 ], 

126 "use_cases": [ 

127 "Find hardcoded secrets", 

128 "Scan for exposed credentials", 

129 "Detect API keys in code", 

130 "Check for password leaks" 

131 ] 

132 }, 

133 "config_audit": { 

134 "name": "Config Audit Agent", 

135 "task_type": "config-audit", 

136 "description": "Infrastructure and configuration security", 

137 "capabilities": [ 

138 "Docker security configuration", 

139 "Kubernetes manifest auditing", 

140 "CI/CD pipeline security", 

141 "Environment variable exposure", 

142 "Cloud infrastructure misconfigurations", 

143 "Terraform/IaC security", 

144 "Container security" 

145 ], 

146 "use_cases": [ 

147 "Audit Docker configurations", 

148 "Scan Kubernetes manifests", 

149 "Check CI/CD security", 

150 "Review infrastructure as code" 

151 ] 

152 }, 

153 # Priority 1: High-Value Security Agents 

154 "red_teamer": { 

155 "name": "Red Team Agent", 

156 "task_type": "offensive-security", 

157 "description": "Offensive security testing and attack simulation", 

158 "capabilities": [ 

159 "Attack simulation", 

160 "Exploitation techniques", 

161 "Penetration testing", 

162 "Security bypass detection", 

163 "Attack vector identification", 

164 "Offensive reconnaissance" 

165 ], 

166 "use_cases": [ 

167 "Simulate attacks on applications", 

168 "Test defensive measures", 

169 "Identify attack vectors", 

170 "Validate security controls" 

171 ] 

172 }, 

173 "blue_teamer": { 

174 "name": "Blue Team Agent", 

175 "task_type": "defensive-security", 

176 "description": "Defensive security posture assessment", 

177 "capabilities": [ 

178 "Security monitoring", 

179 "Defense validation", 

180 "Threat detection", 

181 "Incident response", 

182 "Security control assessment", 

183 "Gap analysis" 

184 ], 

185 "use_cases": [ 

186 "Assess defensive security posture", 

187 "Validate security controls", 

188 "Identify defense gaps", 

189 "Monitor for threats" 

190 ] 

191 }, 

192 "network_analyzer": { 

193 "name": "Network Traffic Analyzer", 

194 "task_type": "network-analysis", 

195 "description": "Network packet and traffic pattern analysis", 

196 "capabilities": [ 

197 "Packet inspection", 

198 "Traffic pattern analysis", 

199 "Protocol security analysis", 

200 "Network anomaly detection", 

201 "Unencrypted traffic detection", 

202 "Suspicious connection identification" 

203 ], 

204 "use_cases": [ 

205 "Analyze network traffic", 

206 "Inspect API communications", 

207 "Detect suspicious connections", 

208 "Validate encryption usage" 

209 ] 

210 }, 

211 "reverse_engineer": { 

212 "name": "Reverse Engineering Agent", 

213 "task_type": "binary-analysis", 

214 "description": "Binary analysis and reverse engineering", 

215 "capabilities": [ 

216 "Binary decompilation", 

217 "Malware analysis", 

218 "Executable security analysis", 

219 "Code obfuscation detection", 

220 "Backdoor detection", 

221 "Suspicious function analysis" 

222 ], 

223 "use_cases": [ 

224 "Analyze binary executables", 

225 "Reverse engineer compiled code", 

226 "Detect malware and backdoors", 

227 "Examine obfuscated code" 

228 ] 

229 }, 

230 "dfir": { 

231 "name": "DFIR Agent", 

232 "task_type": "forensics", 

233 "description": "Digital forensics and incident response", 

234 "capabilities": [ 

235 "Forensic analysis", 

236 "Incident investigation", 

237 "Evidence collection", 

238 "Timeline reconstruction", 

239 "Post-breach analysis", 

240 "Log analysis" 

241 ], 

242 "use_cases": [ 

243 "Investigate security incidents", 

244 "Perform forensic analysis", 

245 "Collect incident evidence", 

246 "Reconstruct attack timelines" 

247 ] 

248 }, 

249 # Priority 2: Specialized Security Agents 

250 "android_sast": { 

251 "name": "Android SAST Agent", 

252 "task_type": "android-scan", 

253 "description": "Android application security testing", 

254 "capabilities": [ 

255 "Android permission analysis", 

256 "Mobile app vulnerability scanning", 

257 "Intent security analysis", 

258 "Data storage security", 

259 "Network security in mobile apps" 

260 ], 

261 "use_cases": [ 

262 "Scan Android applications", 

263 "Audit mobile app security", 

264 "Check Android permissions", 

265 "Analyze mobile data storage" 

266 ] 

267 }, 

268 "memory_analysis": { 

269 "name": "Memory Analysis Agent", 

270 "task_type": "memory-forensics", 

271 "description": "Memory forensics and analysis", 

272 "capabilities": [ 

273 "Memory dump analysis", 

274 "Process memory inspection", 

275 "Memory anomaly detection", 

276 "Malware memory artifacts", 

277 "Credential extraction from memory" 

278 ], 

279 "use_cases": [ 

280 "Analyze memory dumps", 

281 "Investigate memory-based attacks", 

282 "Extract forensic evidence", 

283 "Detect memory anomalies" 

284 ] 

285 }, 

286 "wifi_security": { 

287 "name": "WiFi Security Tester", 

288 "task_type": "wifi-test", 

289 "description": "Wireless network security testing", 

290 "capabilities": [ 

291 "WiFi encryption analysis", 

292 "Wireless network scanning", 

293 "Access point security assessment", 

294 "Rogue AP detection", 

295 "Weak encryption identification" 

296 ], 

297 "use_cases": [ 

298 "Test WiFi security", 

299 "Audit wireless networks", 

300 "Detect weak encryption", 

301 "Identify rogue access points" 

302 ] 

303 }, 

304 "replay_attack": { 

305 "name": "Replay Attack Agent", 

306 "task_type": "replay-check", 

307 "description": "Replay attack detection and prevention", 

308 "capabilities": [ 

309 "Session token analysis", 

310 "Timestamp validation checking", 

311 "Nonce implementation review", 

312 "Replay vulnerability detection", 

313 "Authentication token security" 

314 ], 

315 "use_cases": [ 

316 "Check for replay vulnerabilities", 

317 "Validate session security", 

318 "Audit token mechanisms", 

319 "Test authentication flows" 

320 ] 

321 }, 

322 "subghz_sdr": { 

323 "name": "Sub-GHz SDR Agent", 

324 "task_type": "radio-security", 

325 "description": "Software Defined Radio security testing", 

326 "capabilities": [ 

327 "RF signal analysis", 

328 "Radio frequency security", 

329 "Wireless protocol analysis", 

330 "Unencrypted transmission detection", 

331 "IoT radio security" 

332 ], 

333 "use_cases": [ 

334 "Analyze radio frequency security", 

335 "Test IoT device communications", 

336 "Audit wireless protocols", 

337 "Detect unencrypted RF transmissions" 

338 ] 

339 }, 

340 # Priority 3: Utility & Support Agents 

341 "retester": { 

342 "name": "Retester Agent", 

343 "task_type": "retest", 

344 "description": "Re-testing previously found vulnerabilities", 

345 "capabilities": [ 

346 "Vulnerability retesting", 

347 "Fix validation", 

348 "Regression testing", 

349 "Historical vulnerability tracking", 

350 "Remediation verification" 

351 ], 

352 "use_cases": [ 

353 "Retest fixed vulnerabilities", 

354 "Validate security patches", 

355 "Verify remediation efforts", 

356 "Track vulnerability lifecycle" 

357 ] 

358 }, 

359 "mail": { 

360 "name": "Mail Agent", 

361 "task_type": "email-report", 

362 "description": "Email notifications for security findings", 

363 "capabilities": [ 

364 "Email report generation", 

365 "Team notifications", 

366 "Alert distribution", 

367 "Scheduled report delivery", 

368 "Custom email templates" 

369 ], 

370 "use_cases": [ 

371 "Email security reports", 

372 "Send alert notifications", 

373 "Distribute findings to team", 

374 "Schedule automated reports" 

375 ] 

376 }, 

377 "guardrails": { 

378 "name": "Guardrails Agent", 

379 "task_type": "safety-check", 

380 "description": "Safety validation before executing scans", 

381 "capabilities": [ 

382 "Pre-scan safety checks", 

383 "Destructive operation detection", 

384 "Resource usage validation", 

385 "Permission verification", 

386 "Risk assessment" 

387 ], 

388 "use_cases": [ 

389 "Validate scan safety", 

390 "Prevent destructive operations", 

391 "Check resource limits", 

392 "Assess operation risks" 

393 ] 

394 } 

395 } 

396 

397 def __init__(self, model: str = "claude-3-5-sonnet-20241022"): 

398 """ 

399 Initialize the Main Alprina Agent. 

400 

401 Args: 

402 model: LLM model to use for natural language understanding 

403 """ 

404 self.model = model 

405 self.llm = get_llm_client(model=model) 

406 self.conversation_history = [] 

407 

408 logger.info("Main Alprina Agent initialized with FULL CAI agent coverage") 

409 logger.info(f"Available security agents: {len(self.SECURITY_AGENTS)} (5 core + 13 specialized)") 

410 

411 def process_user_request(self, user_message: str, context: Optional[Dict] = None) -> Dict[str, Any]: 

412 """ 

413 Process user request and route to appropriate security agents. 

414 

415 This is the main entry point. The Main Agent: 

416 1. Understands user's natural language request 

417 2. Determines which security agent(s) to use 

418 3. Coordinates execution with specialized agents (using workflows) 

419 4. Aggregates and returns results 

420 

421 Args: 

422 user_message: Natural language request from user 

423 context: Optional context (scan results, previous findings, etc.) 

424 

425 Returns: 

426 Dictionary with response and any actions taken 

427 """ 

428 logger.info(f"Main Agent processing: {user_message[:100]}...") 

429 

430 # Add to conversation history 

431 self.conversation_history.append({ 

432 "role": "user", 

433 "content": user_message, 

434 "timestamp": datetime.now().isoformat() 

435 }) 

436 

437 # Analyze user intent 

438 intent = self._analyze_intent(user_message, context) 

439 

440 # Route to appropriate handler 

441 if intent["type"] == "scan_request": 

442 # Use async workflow for scan requests 

443 response = asyncio.run(self._handle_scan_request_async(intent, user_message)) 

444 elif intent["type"] == "explain_vulnerability": 

445 response = self._handle_explanation_request(intent, user_message) 

446 elif intent["type"] == "get_remediation": 

447 response = self._handle_remediation_request(intent, user_message) 

448 elif intent["type"] == "general_question": 

449 response = self._handle_general_question(intent, user_message) 

450 elif intent["type"] == "list_capabilities": 

451 response = self._handle_capabilities_request() 

452 else: 

453 response = self._handle_general_question(intent, user_message) 

454 

455 # Add response to history 

456 self.conversation_history.append({ 

457 "role": "assistant", 

458 "content": response.get("message", ""), 

459 "timestamp": datetime.now().isoformat() 

460 }) 

461 

462 return response 

463 

464 def _analyze_intent(self, user_message: str, context: Optional[Dict]) -> Dict[str, Any]: 

465 """ 

466 Analyze user's intent using LLM to determine which agent(s) to call. 

467 

468 Args: 

469 user_message: User's natural language request 

470 context: Optional context 

471 

472 Returns: 

473 Intent analysis with agent routing information 

474 """ 

475 # Build intent analysis prompt 

476 prompt = f"""Analyze this user request and determine the intent: 

477 

478User: "{user_message}" 

479 

480Available Alprina Security Agents: 

481{self._format_agents_for_llm()} 

482 

483Classify the intent as one of: 

4841. "scan_request" - User wants to scan code/web/API 

4852. "explain_vulnerability" - User wants explanation of a vulnerability 

4863. "get_remediation" - User wants fix instructions 

4874. "list_capabilities" - User asks what you can do / help 

4885. "general_question" - Security question or advice 

489 

490For scan_request, identify: 

491- Target (file path, directory, URL, or IP) 

492- Which agent(s) to use (codeagent, web_scanner, bug_bounty, secret_detection, config_audit) 

493- Scan type (code-audit, web-recon, vuln-scan, secret-detection, config-audit) 

494 

495Return JSON format: 

496{{ 

497 "type": "scan_request|explain_vulnerability|get_remediation|list_capabilities|general_question", 

498 "agent": "codeagent|web_scanner|bug_bounty|secret_detection|config_audit", 

499 "target": "path/url if applicable", 

500 "confidence": 0.0-1.0 

501}}""" 

502 

503 try: 

504 # Use LLM to analyze intent 

505 response = self.llm.chat( 

506 messages=[{"role": "user", "content": prompt}], 

507 system_prompt="You are an intent classifier for Alprina security platform. Return only JSON.", 

508 max_tokens=500, 

509 temperature=0.3 

510 ) 

511 

512 # Parse LLM response 

513 import json 

514 intent = json.loads(response.strip().strip("```json").strip("```")) 

515 return intent 

516 

517 except Exception as e: 

518 logger.warning(f"Intent analysis failed: {e}, using fallback") 

519 return self._fallback_intent_analysis(user_message) 

520 

521 def _fallback_intent_analysis(self, user_message: str) -> Dict[str, Any]: 

522 """Fallback intent analysis using keyword matching.""" 

523 message_lower = user_message.lower() 

524 

525 # Scan request keywords 

526 if any(word in message_lower for word in ["scan", "check", "analyze", "audit", "test"]): 

527 # Determine target and agent 

528 if any(word in message_lower for word in ["code", "file", "python", "javascript", ".py", ".js"]): 

529 return {"type": "scan_request", "agent": "codeagent", "target": None, "confidence": 0.8} 

530 elif any(word in message_lower for word in ["web", "api", "http", "url", "domain"]): 

531 return {"type": "scan_request", "agent": "web_scanner", "target": None, "confidence": 0.8} 

532 elif any(word in message_lower for word in ["secret", "key", "password", "token", "credential"]): 

533 return {"type": "scan_request", "agent": "secret_detection", "target": None, "confidence": 0.8} 

534 elif any(word in message_lower for word in ["docker", "kubernetes", "config", "k8s", "container"]): 

535 return {"type": "scan_request", "agent": "config_audit", "target": None, "confidence": 0.8} 

536 else: 

537 return {"type": "scan_request", "agent": "codeagent", "target": None, "confidence": 0.6} 

538 

539 # Help/capabilities request 

540 if any(word in message_lower for word in ["help", "what can you", "capabilities", "what do you"]): 

541 return {"type": "list_capabilities", "confidence": 0.9} 

542 

543 # Explanation request 

544 if any(word in message_lower for word in ["explain", "what is", "tell me about"]): 

545 return {"type": "explain_vulnerability", "confidence": 0.7} 

546 

547 # Remediation request 

548 if any(word in message_lower for word in ["fix", "remediate", "solve", "how to fix"]): 

549 return {"type": "get_remediation", "confidence": 0.7} 

550 

551 # Default to general question 

552 return {"type": "general_question", "confidence": 0.5} 

553 

554 async def _handle_scan_request_async(self, intent: Dict, user_message: str) -> Dict[str, Any]: 

555 """ 

556 Handle scan requests using AI SDK workflow patterns. 

557 

558 Uses orchestrator-worker pattern with parallel execution and quality control. 

559 

560 Args: 

561 intent: Intent analysis 

562 user_message: Original user message 

563 

564 Returns: 

565 Scan results and response 

566 """ 

567 agent_id = intent.get("agent", "codeagent") 

568 target = intent.get("target") 

569 

570 # Extract target from message if not in intent 

571 if not target: 

572 target = self._extract_target_from_message(user_message) 

573 

574 if not target: 

575 return { 

576 "message": "I'd be happy to run a scan! Could you tell me what you'd like to scan? For example:\n\n- `scan ./src` - Scan a directory\n- `scan app.py` - Scan a file\n- `scan https://api.example.com` - Scan a web endpoint\n- `find secrets in ./` - Search for hardcoded credentials", 

577 "type": "clarification_needed" 

578 } 

579 

580 # Get agent info 

581 agent_info = self._get_agent_info(agent_id) 

582 

583 logger.info(f"Routing scan to {agent_info['name']} for target: {target} using WORKFLOW orchestration") 

584 

585 # Determine if local or remote scan 

586 from pathlib import Path 

587 is_local = Path(target).exists() 

588 

589 try: 

590 # Check if this is a comprehensive scan (use multiple agents) 

591 is_comprehensive = any(word in user_message.lower() for word in ["comprehensive", "full", "complete", "all agents"]) 

592 

593 # Check if this is a deep analysis (use sequential workflow) 

594 is_deep_analysis = any(word in user_message.lower() for word in ["deep", "thorough", "detailed", "in-depth", "sequential"]) 

595 

596 # Check if this is a coordinated agent chain 

597 is_chain = any(word in user_message.lower() for word in ["chain", "coordinate", "lifecycle", "attack defense", "investigation"]) 

598 

599 if is_chain: 

600 # Use agent coordinator for sophisticated multi-agent chains 

601 logger.info("Using AGENT COORDINATOR for chain execution") 

602 

603 coordinator = get_coordinator() 

604 

605 # Detect chain type from keywords 

606 if "attack" in user_message.lower() and "defense" in user_message.lower(): 

607 chain_type = ChainType.ATTACK_DEFENSE 

608 elif "lifecycle" in user_message.lower() or "full" in user_message.lower(): 

609 chain_type = ChainType.FULL_LIFECYCLE 

610 elif "investigation" in user_message.lower() or "forensic" in user_message.lower(): 

611 chain_type = ChainType.INVESTIGATION 

612 elif "validation" in user_message.lower() or "retest" in user_message.lower(): 

613 chain_type = ChainType.VALIDATION 

614 elif "continuous" in user_message.lower() or "monitor" in user_message.lower(): 

615 chain_type = ChainType.CONTINUOUS 

616 else: 

617 # Default to attack/defense 

618 chain_type = ChainType.ATTACK_DEFENSE 

619 

620 # Execute coordinated chain 

621 chain_results = await coordinator.execute_chain( 

622 chain_type=chain_type, 

623 target=target, 

624 safe_only=True 

625 ) 

626 

627 results = { 

628 "findings": chain_results.get("vulnerabilities", []), 

629 "chain_type": chain_results.get("chain_type"), 

630 "steps": chain_results.get("steps", []), 

631 "total_steps": len(chain_results.get("steps", [])) 

632 } 

633 

634 agents_used = [step["agent"] for step in chain_results.get("steps", [])] 

635 

636 elif is_deep_analysis: 

637 # Use sequential workflow for deep analysis with context passing 

638 logger.info("Using SEQUENTIAL WORKFLOW for deep analysis") 

639 

640 workflow = AlprinaWorkflow(WorkflowType.SEQUENTIAL) 

641 

642 # Define sequential steps with context passing 

643 steps = [ 

644 { 

645 "agent": "codeagent", 

646 "task": "code-audit", 

647 "params": {"target": target, "safe_only": True} 

648 }, 

649 { 

650 "agent": "secret_detection", 

651 "task": "secret-detection", 

652 "params": {"target": target, "safe_only": True} 

653 }, 

654 { 

655 "agent": "main_alprina_agent", 

656 "task": "aggregate_results", 

657 "params": {"target": target} 

658 } 

659 ] 

660 

661 # Add web scanner if target is URL, otherwise config audit 

662 if not is_local: 

663 steps.insert(1, { 

664 "agent": "web_scanner", 

665 "task": "web-recon", 

666 "params": {"target": target, "safe_only": True} 

667 }) 

668 else: 

669 steps.insert(1, { 

670 "agent": "config_audit", 

671 "task": "config-audit", 

672 "params": {"target": target, "safe_only": True} 

673 }) 

674 

675 # Execute sequential workflow 

676 workflow_result = await workflow.execute_sequential(steps) 

677 

678 # Extract results from sequential execution 

679 all_findings = [] 

680 for step in workflow_result.steps: 

681 step_findings = step.get("output", {}).get("findings", []) 

682 all_findings.extend(step_findings) 

683 

684 results = { 

685 "findings": all_findings, 

686 "workflow_type": "sequential", 

687 "steps_completed": len(workflow_result.steps) 

688 } 

689 

690 agents_used = [step["agent"] for step in steps] 

691 

692 elif is_comprehensive: 

693 # Use parallel workflow for comprehensive scans (2-3x faster!) 

694 logger.info("Using PARALLEL WORKFLOW for comprehensive scan") 

695 

696 workflow = AlprinaWorkflow(WorkflowType.PARALLEL) 

697 

698 # Define tasks for all relevant agents 

699 tasks = [ 

700 {"agent": "codeagent", "task": "code-audit", "params": {"target": target, "safe_only": True}}, 

701 {"agent": "secret_detection", "task": "secret-detection", "params": {"target": target, "safe_only": True}}, 

702 ] 

703 

704 # Add web scanner if target is URL 

705 if not is_local: 

706 tasks.append({"agent": "web_scanner", "task": "web-recon", "params": {"target": target, "safe_only": True}}) 

707 else: 

708 # Add config audit for local scans 

709 tasks.append({"agent": "config_audit", "task": "config-audit", "params": {"target": target, "safe_only": True}}) 

710 

711 # Execute all agents in parallel 

712 workflow_result = await workflow.execute_parallel(tasks) 

713 

714 # Add quality control with evaluator-optimizer 

715 logger.info("Applying QUALITY CONTROL with evaluator-optimizer") 

716 quality_workflow = AlprinaWorkflow(WorkflowType.EVALUATOR_OPTIMIZER) 

717 

718 refined_result = await quality_workflow.execute_evaluator_optimizer( 

719 agent="main_alprina_agent", 

720 task="aggregate_results", 

721 params={"workflow_result": workflow_result.final_output}, 

722 evaluator_fn=evaluate_comprehensive_scan, 

723 max_iterations=2 

724 ) 

725 

726 # Aggregate results from all agents 

727 results = self._aggregate_parallel_results(workflow_result.final_output) 

728 agents_used = [task["agent"] for task in tasks] 

729 

730 else: 

731 # Single agent scan with quality control 

732 logger.info(f"Using SINGLE AGENT WORKFLOW with quality control: {agent_info['name']}") 

733 

734 # Use evaluator-optimizer workflow for quality 

735 workflow = AlprinaWorkflow(WorkflowType.EVALUATOR_OPTIMIZER) 

736 

737 workflow_result = await workflow.execute_evaluator_optimizer( 

738 agent=agent_id, 

739 task=agent_info["task_type"], 

740 params={"target": target, "safe_only": True}, 

741 evaluator_fn=evaluate_scan_quality, 

742 max_iterations=3 

743 ) 

744 

745 results = workflow_result.final_output 

746 agents_used = [agent_info["name"]] 

747 

748 # Generate markdown reports if local scan with findings 

749 report_path = None 

750 if is_local and results.get("findings"): 

751 try: 

752 report_path = generate_security_reports(results, target) 

753 except Exception as e: 

754 logger.warning(f"Report generation failed: {e}") 

755 

756 # Format response 

757 findings_count = len(results.get("findings", [])) 

758 

759 if is_chain: 

760 chain_name = results.get("chain_type", "agent chain").replace("_", " ").title() 

761 message = f"✓ **{chain_name} complete** using {len(agents_used)} coordinated agents!\n\n" 

762 message += f"**Workflow:** Agent Coordination Chain\n" 

763 message += f"**Chain Steps:** {results.get('total_steps', 0)}\n" 

764 elif is_deep_analysis: 

765 message = f"✓ **Deep analysis complete** using {len(agents_used)} agents sequentially with context passing!\n\n" 

766 message += f"**Workflow:** Sequential (each agent builds on previous results)\n" 

767 elif is_comprehensive: 

768 message = f"✓ **Comprehensive scan complete** using {len(agents_used)} agents in parallel!\n\n" 

769 else: 

770 message = f"✓ Scan complete using **{agent_info['name']}** with quality control!\n\n" 

771 

772 message += f"**Target:** `{target}`\n" 

773 message += f"**Findings:** {findings_count} security issues detected\n" 

774 

775 if findings_count > 0: 

776 # Summarize by severity 

777 severity_counts = {} 

778 for finding in results["findings"]: 

779 sev = finding.get("severity", "UNKNOWN") 

780 severity_counts[sev] = severity_counts.get(sev, 0) + 1 

781 

782 message += "\n**Severity Breakdown:**\n" 

783 for severity in ["CRITICAL", "HIGH", "MEDIUM", "LOW", "INFO"]: 

784 count = severity_counts.get(severity, 0) 

785 if count > 0: 

786 icons = {"CRITICAL": "🔴", "HIGH": "🟠", "MEDIUM": "🟡", "LOW": "🔵", "INFO": "⚪"} 

787 message += f" {icons.get(severity, '•')} {severity}: {count}\n" 

788 

789 if report_path: 

790 message += f"\n📁 **Security reports generated:** `{report_path}/`\n" 

791 message += " • SECURITY-REPORT.md\n" 

792 message += " • FINDINGS.md\n" 

793 message += " • REMEDIATION.md\n" 

794 message += " • EXECUTIVE-SUMMARY.md\n" 

795 else: 

796 message += "\n✅ No security issues found! Your code looks good.\n" 

797 

798 message += f"\nNeed help fixing issues? Just ask: *\"How do I fix finding #1?\"*" 

799 

800 return { 

801 "message": message, 

802 "type": "scan_complete", 

803 "results": results, 

804 "agent_used": ", ".join(agents_used), 

805 "report_path": report_path, 

806 "workflow_enabled": True 

807 } 

808 

809 except Exception as e: 

810 logger.error(f"Scan failed: {e}") 

811 return { 

812 "message": f"❌ Scan failed: {str(e)}\n\nPlease check the target path/URL and try again.", 

813 "type": "error", 

814 "error": str(e) 

815 } 

816 

817 def _handle_explanation_request(self, intent: Dict, user_message: str) -> Dict[str, Any]: 

818 """Handle vulnerability explanation requests.""" 

819 # Use LLM to generate explanation 

820 prompt = f"""User is asking about security concepts or vulnerabilities: "{user_message}" 

821 

822Provide a clear, concise explanation covering: 

8231. What it is (simple definition) 

8242. Why it matters (risk/impact) 

8253. Common examples 

8264. How to prevent it 

827 

828Keep it educational but practical. Use analogies if helpful.""" 

829 

830 try: 

831 explanation = self.llm.chat( 

832 messages=[{"role": "user", "content": prompt}], 

833 system_prompt=self._get_system_prompt(), 

834 max_tokens=1000, 

835 temperature=0.7 

836 ) 

837 

838 return { 

839 "message": explanation, 

840 "type": "explanation" 

841 } 

842 except Exception as e: 

843 logger.error(f"Explanation generation failed: {e}") 

844 return { 

845 "message": "I can explain security vulnerabilities! Try asking: 'What is SQL injection?' or 'Explain XSS attacks'", 

846 "type": "error" 

847 } 

848 

849 def _handle_remediation_request(self, intent: Dict, user_message: str) -> Dict[str, Any]: 

850 """Handle remediation/fix requests.""" 

851 prompt = f"""User needs help fixing a security issue: "{user_message}" 

852 

853Provide step-by-step remediation instructions with: 

8541. Code examples (vulnerable vs. secure) 

8552. Best practices 

8563. Testing/verification steps 

857 

858Be specific and actionable.""" 

859 

860 try: 

861 remediation = self.llm.chat( 

862 messages=[{"role": "user", "content": prompt}], 

863 system_prompt=self._get_system_prompt(), 

864 max_tokens=1500, 

865 temperature=0.7 

866 ) 

867 

868 return { 

869 "message": remediation, 

870 "type": "remediation" 

871 } 

872 except Exception as e: 

873 logger.error(f"Remediation generation failed: {e}") 

874 return { 

875 "message": "I can help you fix security issues! Check the REMEDIATION.md file in your .alprina/ folder for detailed fix instructions.", 

876 "type": "error" 

877 } 

878 

879 def _handle_general_question(self, intent: Dict, user_message: str) -> Dict[str, Any]: 

880 """Handle general security questions.""" 

881 try: 

882 response = self.llm.chat( 

883 messages=[{"role": "user", "content": user_message}], 

884 system_prompt=self._get_system_prompt(), 

885 max_tokens=1000, 

886 temperature=0.7 

887 ) 

888 

889 return { 

890 "message": response, 

891 "type": "general" 

892 } 

893 except Exception as e: 

894 logger.error(f"Question handling failed: {e}") 

895 return { 

896 "message": "I'm here to help with security! Ask me to scan code, explain vulnerabilities, or provide security advice.", 

897 "type": "error" 

898 } 

899 

900 def _handle_capabilities_request(self) -> Dict[str, Any]: 

901 """Handle 'What can you do?' requests.""" 

902 message = """# 👋 Hey! I'm Alprina, your AI security assistant. 

903 

904I coordinate with **5 specialized security agents** to help you find and fix vulnerabilities: 

905 

906## 🔍 What I Can Do: 

907 

908### 1️⃣ **Scan Your Code** 

909- "Scan ./src for vulnerabilities" 

910- "Check app.py for security issues" 

911- "Find hardcoded secrets in my project" 

912 

913**Agents:** CodeAgent, Secret Detection Agent 

914 

915### 2️⃣ **Test Web Applications & APIs** 

916- "Scan https://api.myapp.com" 

917- "Check my website for vulnerabilities" 

918- "Test my API endpoints" 

919 

920**Agent:** Web Scanner Agent 

921 

922### 3️⃣ **Comprehensive Security Audits** 

923- "Run full security scan on ./project" 

924- "Find OWASP Top 10 vulnerabilities" 

925- "Check for business logic flaws" 

926 

927**Agent:** Bug Bounty Agent 

928 

929### 4️⃣ **Audit Infrastructure** 

930- "Check my Dockerfile security" 

931- "Audit Kubernetes manifests" 

932- "Review CI/CD pipeline security" 

933 

934**Agent:** Config Audit Agent 

935 

936### 5️⃣ **Explain & Fix** 

937- "What is SQL injection?" 

938- "How do I fix XSS vulnerabilities?" 

939- "Explain finding #3" 

940 

941## 📁 Automatic Reports 

942 

943Every scan generates professional markdown reports in `.alprina/`: 

944- SECURITY-REPORT.md 

945- FINDINGS.md 

946- REMEDIATION.md 

947- EXECUTIVE-SUMMARY.md 

948 

949## 💬 Just Talk to Me! 

950 

951You don't need to memorize commands. Just tell me what you need: 

952- "I want to check my code for vulnerabilities" 

953- "Help me secure my API" 

954- "Find any exposed credentials" 

955 

956**Ready to get started?** Try: `scan ./src` 

957""" 

958 

959 return { 

960 "message": message, 

961 "type": "capabilities" 

962 } 

963 

964 def _aggregate_parallel_results(self, parallel_outputs: List[Any]) -> Dict[str, Any]: 

965 """ 

966 Aggregate results from multiple agents running in parallel. 

967 

968 Args: 

969 parallel_outputs: List of outputs from parallel workflow execution 

970 

971 Returns: 

972 Aggregated results dictionary 

973 """ 

974 aggregated = { 

975 "findings": [], 

976 "stats": { 

977 "total_agents": len(parallel_outputs), 

978 "total_findings": 0, 

979 "by_severity": {} 

980 } 

981 } 

982 

983 # Combine findings from all agents 

984 for output in parallel_outputs: 

985 if isinstance(output, dict) and "findings" in output: 

986 aggregated["findings"].extend(output["findings"]) 

987 

988 # Deduplicate findings based on file + line + type 

989 seen = set() 

990 unique_findings = [] 

991 for finding in aggregated["findings"]: 

992 key = ( 

993 finding.get("file", ""), 

994 finding.get("line", 0), 

995 finding.get("type", ""), 

996 finding.get("message", "") 

997 ) 

998 if key not in seen: 

999 seen.add(key) 

1000 unique_findings.append(finding) 

1001 

1002 aggregated["findings"] = unique_findings 

1003 aggregated["stats"]["total_findings"] = len(unique_findings) 

1004 

1005 # Count by severity 

1006 for finding in unique_findings: 

1007 severity = finding.get("severity", "UNKNOWN") 

1008 aggregated["stats"]["by_severity"][severity] = aggregated["stats"]["by_severity"].get(severity, 0) + 1 

1009 

1010 return aggregated 

1011 

1012 def _extract_target_from_message(self, message: str) -> Optional[str]: 

1013 """Extract scan target from natural language message.""" 

1014 import re 

1015 

1016 # Look for file paths 

1017 path_pattern = r'[./~][\w/.-]+' 

1018 paths = re.findall(path_pattern, message) 

1019 if paths: 

1020 return paths[0] 

1021 

1022 # Look for URLs 

1023 url_pattern = r'https?://[\w.-]+(?:/[\w.-]*)?' 

1024 urls = re.findall(url_pattern, message) 

1025 if urls: 

1026 return urls[0] 

1027 

1028 # Look for IP addresses 

1029 ip_pattern = r'\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b' 

1030 ips = re.findall(ip_pattern, message) 

1031 if ips: 

1032 return ips[0] 

1033 

1034 return None 

1035 

1036 def _get_agent_info(self, agent_id: str) -> Dict[str, Any]: 

1037 """Get information about a security agent.""" 

1038 # Map agent IDs to registry keys 

1039 agent_map = { 

1040 "codeagent": "codeagent", 

1041 "web_scanner": "web_scanner", 

1042 "bug_bounty": "bug_bounty", 

1043 "secret_detection": "secret_detection", 

1044 "config_audit": "config_audit" 

1045 } 

1046 

1047 registry_key = agent_map.get(agent_id, "codeagent") 

1048 return self.SECURITY_AGENTS[registry_key] 

1049 

1050 def _format_agents_for_llm(self) -> str: 

1051 """Format agent registry for LLM consumption.""" 

1052 output = "" 

1053 for agent_id, agent in self.SECURITY_AGENTS.items(): 

1054 output += f"\n**{agent['name']}** ({agent_id}):\n" 

1055 output += f" Task: {agent['task_type']}\n" 

1056 output += f" Use for: {', '.join(agent['use_cases'][:2])}\n" 

1057 return output 

1058 

1059 def _get_system_prompt(self) -> str: 

1060 """Get system prompt for the Main Alprina Agent.""" 

1061 return f"""You are the Main Alprina Agent - the primary AI security assistant that users interact with. 

1062 

1063You coordinate with {len(self.SECURITY_AGENTS)} specialized security agents: 

1064 

1065{self._format_agents_for_llm()} 

1066 

1067## Your Role: 

1068- Understand user requests in natural language 

1069- Route tasks to appropriate security agents 

1070- Provide security advice and education 

1071- Generate clear, actionable responses 

1072 

1073## Communication Style: 

1074- Friendly and conversational 

1075- Explain security concepts simply 

1076- Provide code examples when helpful 

1077- Always offer next steps 

1078 

1079## Remember: 

1080- Users talk to YOU (Main Agent) 

1081- YOU decide which specialized agent to use 

1082- YOU coordinate all security operations 

1083- YOU present results in user-friendly format 

1084 

1085Be helpful, educational, and proactive in making security accessible to all developers!""" 

1086 

1087 def get_agent_registry(self) -> Dict[str, Any]: 

1088 """ 

1089 Get the complete registry of all security agents. 

1090 

1091 Returns: 

1092 Dictionary of all available security agents 

1093 """ 

1094 return self.SECURITY_AGENTS 

1095 

1096 def list_agents(self) -> List[Dict[str, Any]]: 

1097 """ 

1098 Get a list of all available security agents. 

1099 

1100 Returns: 

1101 List of agent information dictionaries 

1102 """ 

1103 agents_list = [] 

1104 for agent_id, agent_info in self.SECURITY_AGENTS.items(): 

1105 agents_list.append({ 

1106 "id": agent_id, 

1107 "name": agent_info["name"], 

1108 "description": agent_info["description"], 

1109 "capabilities": agent_info["capabilities"], 

1110 "use_cases": agent_info["use_cases"] 

1111 }) 

1112 return agents_list