zen-ai-pentest 2.0.0__py3-none-any.whl
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.
- agents/__init__.py +28 -0
- agents/agent_base.py +239 -0
- agents/agent_orchestrator.py +346 -0
- agents/analysis_agent.py +225 -0
- agents/cli.py +258 -0
- agents/exploit_agent.py +224 -0
- agents/integration.py +211 -0
- agents/post_scan_agent.py +937 -0
- agents/react_agent.py +384 -0
- agents/react_agent_enhanced.py +616 -0
- agents/react_agent_vm.py +298 -0
- agents/research_agent.py +176 -0
- api/__init__.py +11 -0
- api/auth.py +123 -0
- api/main.py +1027 -0
- api/schemas.py +357 -0
- api/websocket.py +97 -0
- autonomous/__init__.py +122 -0
- autonomous/agent.py +253 -0
- autonomous/agent_loop.py +1370 -0
- autonomous/exploit_validator.py +1537 -0
- autonomous/memory.py +448 -0
- autonomous/react.py +339 -0
- autonomous/tool_executor.py +488 -0
- backends/__init__.py +16 -0
- backends/chatgpt_direct.py +133 -0
- backends/claude_direct.py +130 -0
- backends/duckduckgo.py +138 -0
- backends/openrouter.py +120 -0
- benchmarks/__init__.py +149 -0
- benchmarks/benchmark_engine.py +904 -0
- benchmarks/ci_benchmark.py +785 -0
- benchmarks/comparison.py +729 -0
- benchmarks/metrics.py +553 -0
- benchmarks/run_benchmarks.py +809 -0
- ci_cd/__init__.py +2 -0
- core/__init__.py +17 -0
- core/async_pool.py +282 -0
- core/asyncio_fix.py +222 -0
- core/cache.py +472 -0
- core/container.py +277 -0
- core/database.py +114 -0
- core/input_validator.py +353 -0
- core/models.py +288 -0
- core/orchestrator.py +611 -0
- core/plugin_manager.py +571 -0
- core/rate_limiter.py +405 -0
- core/secure_config.py +328 -0
- core/shield_integration.py +296 -0
- modules/__init__.py +46 -0
- modules/cve_database.py +362 -0
- modules/exploit_assist.py +330 -0
- modules/nuclei_integration.py +480 -0
- modules/osint.py +604 -0
- modules/protonvpn.py +554 -0
- modules/recon.py +165 -0
- modules/sql_injection_db.py +826 -0
- modules/tool_orchestrator.py +498 -0
- modules/vuln_scanner.py +292 -0
- modules/wordlist_generator.py +566 -0
- risk_engine/__init__.py +99 -0
- risk_engine/business_impact.py +267 -0
- risk_engine/business_impact_calculator.py +563 -0
- risk_engine/cvss.py +156 -0
- risk_engine/epss.py +190 -0
- risk_engine/example_usage.py +294 -0
- risk_engine/false_positive_engine.py +1073 -0
- risk_engine/scorer.py +304 -0
- web_ui/backend/main.py +471 -0
- zen_ai_pentest-2.0.0.dist-info/METADATA +795 -0
- zen_ai_pentest-2.0.0.dist-info/RECORD +75 -0
- zen_ai_pentest-2.0.0.dist-info/WHEEL +5 -0
- zen_ai_pentest-2.0.0.dist-info/entry_points.txt +2 -0
- zen_ai_pentest-2.0.0.dist-info/licenses/LICENSE +21 -0
- zen_ai_pentest-2.0.0.dist-info/top_level.txt +10 -0
agents/analysis_agent.py
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Analysis Agent - Specializes in analyzing data and finding patterns
|
|
4
|
+
Part of the Multi-Agent Collaboration System
|
|
5
|
+
Author: SHAdd0WTAka
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import asyncio
|
|
9
|
+
import logging
|
|
10
|
+
from typing import Any, Dict, List
|
|
11
|
+
|
|
12
|
+
from .agent_base import AgentMessage, AgentRole, BaseAgent
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger("ZenAI.Agents")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class AnalysisAgent(BaseAgent):
|
|
18
|
+
"""
|
|
19
|
+
Analysis Agent - Analyzes findings, identifies patterns
|
|
20
|
+
Correlates data from multiple sources to identify attack paths
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def __init__(self, name: str, orchestrator=None, zen_orchestrator=None):
|
|
24
|
+
super().__init__(name, AgentRole.ANALYST, orchestrator)
|
|
25
|
+
self.zen_orchestrator = zen_orchestrator
|
|
26
|
+
self.analysis_cache = {}
|
|
27
|
+
|
|
28
|
+
# Register handlers
|
|
29
|
+
self.register_handler("findings", self._handle_findings)
|
|
30
|
+
self.register_handler("analysis_request", self._handle_analysis_request)
|
|
31
|
+
|
|
32
|
+
async def _handle_findings(self, msg: AgentMessage):
|
|
33
|
+
"""Process findings from other agents"""
|
|
34
|
+
findings = msg.context.get("findings", [])
|
|
35
|
+
source = msg.sender
|
|
36
|
+
|
|
37
|
+
logger.info(
|
|
38
|
+
f"[AnalysisAgent:{self.name}] Analyzing {len(findings)} findings from {source}"
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
# Perform analysis
|
|
42
|
+
analysis = await self._analyze_findings(findings)
|
|
43
|
+
|
|
44
|
+
# If critical patterns found, alert all agents
|
|
45
|
+
if analysis.get("critical_patterns"):
|
|
46
|
+
await self.send_message(
|
|
47
|
+
content=f"⚠️ Critical patterns detected! Risk level: {analysis['risk_level']}",
|
|
48
|
+
recipient="all",
|
|
49
|
+
msg_type="alert",
|
|
50
|
+
priority=4, # Critical
|
|
51
|
+
context={
|
|
52
|
+
"patterns": analysis["critical_patterns"],
|
|
53
|
+
"recommendations": analysis["recommendations"],
|
|
54
|
+
},
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
# Send detailed analysis to requesting agent
|
|
58
|
+
await self.send_message(
|
|
59
|
+
content=f"Analysis complete: {analysis['summary']}",
|
|
60
|
+
recipient=msg.sender,
|
|
61
|
+
msg_type="analysis_result",
|
|
62
|
+
context={"analysis": analysis},
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
# Update shared context
|
|
66
|
+
self.update_context(f"analysis_{msg.id}", analysis, share=True)
|
|
67
|
+
|
|
68
|
+
async def _handle_analysis_request(self, msg: AgentMessage):
|
|
69
|
+
"""Handle explicit analysis requests"""
|
|
70
|
+
data = msg.context.get("data", [])
|
|
71
|
+
analysis_type = msg.context.get("analysis_type", "general")
|
|
72
|
+
|
|
73
|
+
result = await self._analyze_data(data, analysis_type)
|
|
74
|
+
|
|
75
|
+
await self.send_message(
|
|
76
|
+
content=f"Analysis of {analysis_type} complete",
|
|
77
|
+
recipient=msg.sender,
|
|
78
|
+
msg_type="response",
|
|
79
|
+
context={"analysis": result},
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
async def _analyze_findings(self, findings: List[Dict]) -> Dict:
|
|
83
|
+
"""Analyze findings and identify patterns"""
|
|
84
|
+
analysis = {
|
|
85
|
+
"total_findings": len(findings),
|
|
86
|
+
"by_type": {},
|
|
87
|
+
"critical_patterns": [],
|
|
88
|
+
"risk_level": "low",
|
|
89
|
+
"recommendations": [],
|
|
90
|
+
"summary": "",
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
# Categorize by type
|
|
94
|
+
for finding in findings:
|
|
95
|
+
f_type = finding.get("type", "unknown")
|
|
96
|
+
if f_type not in analysis["by_type"]:
|
|
97
|
+
analysis["by_type"][f_type] = []
|
|
98
|
+
analysis["by_type"][f_type].append(finding)
|
|
99
|
+
|
|
100
|
+
# Look for critical patterns
|
|
101
|
+
cves = [f for f in findings if f.get("type") == "cve"]
|
|
102
|
+
ransomware = [f for f in findings if f.get("type") == "ransomware"]
|
|
103
|
+
|
|
104
|
+
# Pattern 1: CVE associated with ransomware
|
|
105
|
+
for cve in cves:
|
|
106
|
+
cve_data = cve.get("data", {})
|
|
107
|
+
if hasattr(cve_data, "ransomware_used_by") and cve_data.ransomware_used_by:
|
|
108
|
+
analysis["critical_patterns"].append(
|
|
109
|
+
{
|
|
110
|
+
"type": "ransomware_cve",
|
|
111
|
+
"description": f"{cve_data.cve_id} is used by ransomware",
|
|
112
|
+
"affected": cve_data.ransomware_used_by,
|
|
113
|
+
}
|
|
114
|
+
)
|
|
115
|
+
analysis["risk_level"] = "critical"
|
|
116
|
+
|
|
117
|
+
# Pattern 2: Multiple high-severity CVEs
|
|
118
|
+
high_cves = [c for c in cves if c.get("data", {}).get("severity") == "Critical"]
|
|
119
|
+
if len(high_cves) >= 3:
|
|
120
|
+
analysis["critical_patterns"].append(
|
|
121
|
+
{
|
|
122
|
+
"type": "multiple_critical_cves",
|
|
123
|
+
"description": f"Found {len(high_cves)} critical CVEs",
|
|
124
|
+
"count": len(high_cves),
|
|
125
|
+
}
|
|
126
|
+
)
|
|
127
|
+
analysis["risk_level"] = "high"
|
|
128
|
+
|
|
129
|
+
# Generate recommendations using LLM
|
|
130
|
+
if self.zen_orchestrator and analysis["critical_patterns"]:
|
|
131
|
+
prompt = f"""
|
|
132
|
+
Analyze these security patterns and provide recommendations:
|
|
133
|
+
{analysis["critical_patterns"]}
|
|
134
|
+
|
|
135
|
+
Provide:
|
|
136
|
+
1. Priority order for remediation
|
|
137
|
+
2. Immediate actions
|
|
138
|
+
3. Long-term security improvements
|
|
139
|
+
"""
|
|
140
|
+
|
|
141
|
+
response = await self.zen_orchestrator.process(prompt)
|
|
142
|
+
analysis["recommendations"] = response.content.split("\n")
|
|
143
|
+
|
|
144
|
+
analysis["summary"] = (
|
|
145
|
+
f"Found {len(analysis['critical_patterns'])} critical patterns across {len(findings)} findings"
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
return analysis
|
|
149
|
+
|
|
150
|
+
async def _analyze_data(self, data: List, analysis_type: str) -> Dict:
|
|
151
|
+
"""Generic data analysis"""
|
|
152
|
+
if analysis_type == "attack_path":
|
|
153
|
+
return await self._analyze_attack_paths(data)
|
|
154
|
+
elif analysis_type == "correlation":
|
|
155
|
+
return await self._correlate_data(data)
|
|
156
|
+
else:
|
|
157
|
+
return {"status": "unknown_analysis_type"}
|
|
158
|
+
|
|
159
|
+
async def _analyze_attack_paths(self, data: List) -> Dict:
|
|
160
|
+
"""Analyze potential attack paths through the system"""
|
|
161
|
+
# This would use the LLM to chain together vulnerabilities
|
|
162
|
+
if self.zen_orchestrator:
|
|
163
|
+
prompt = f"""
|
|
164
|
+
Analyze these vulnerabilities and identify potential attack paths:
|
|
165
|
+
{data}
|
|
166
|
+
|
|
167
|
+
Map out:
|
|
168
|
+
1. Entry points
|
|
169
|
+
2. Lateral movement possibilities
|
|
170
|
+
3. Critical asset exposure
|
|
171
|
+
4. Kill chain stages
|
|
172
|
+
"""
|
|
173
|
+
|
|
174
|
+
response = await self.zen_orchestrator.process(prompt)
|
|
175
|
+
|
|
176
|
+
return {
|
|
177
|
+
"type": "attack_path_analysis",
|
|
178
|
+
"paths": response.content,
|
|
179
|
+
"agent": self.name,
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return {"type": "attack_path_analysis", "paths": [], "agent": self.name}
|
|
183
|
+
|
|
184
|
+
async def _correlate_data(self, data: List) -> Dict:
|
|
185
|
+
"""Find correlations between different data points"""
|
|
186
|
+
correlations = []
|
|
187
|
+
|
|
188
|
+
# Simple correlation: shared CVEs between findings
|
|
189
|
+
cve_sets = []
|
|
190
|
+
for item in data:
|
|
191
|
+
if "cves" in item:
|
|
192
|
+
cve_sets.append(set(item["cves"]))
|
|
193
|
+
|
|
194
|
+
# Find common CVEs
|
|
195
|
+
if len(cve_sets) >= 2:
|
|
196
|
+
common = cve_sets[0].intersection(*cve_sets[1:])
|
|
197
|
+
if common:
|
|
198
|
+
correlations.append(
|
|
199
|
+
{
|
|
200
|
+
"type": "shared_cves",
|
|
201
|
+
"cves": list(common),
|
|
202
|
+
"significance": "high",
|
|
203
|
+
}
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
return {
|
|
207
|
+
"type": "correlation_analysis",
|
|
208
|
+
"correlations": correlations,
|
|
209
|
+
"agent": self.name,
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
async def execute_task(self, task: Dict) -> Dict:
|
|
213
|
+
"""Execute analysis task"""
|
|
214
|
+
task_type = task.get("type", "")
|
|
215
|
+
context = task.get("context", {})
|
|
216
|
+
|
|
217
|
+
logger.info(f"[AnalysisAgent:{self.name}] Executing task: {task_type}")
|
|
218
|
+
|
|
219
|
+
if task_type == "vulnerability_analysis":
|
|
220
|
+
findings = context.get("findings", [])
|
|
221
|
+
analysis = await self._analyze_findings(findings)
|
|
222
|
+
|
|
223
|
+
return {"status": "complete", "analysis": analysis, "agent": self.name}
|
|
224
|
+
|
|
225
|
+
return {"status": "unknown_task"}
|
agents/cli.py
ADDED
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
CLI Interface for Multi-Agent System
|
|
4
|
+
Interactive commands for managing agents
|
|
5
|
+
Author: SHAdd0WTAka
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import asyncio
|
|
9
|
+
import sys
|
|
10
|
+
from typing import Dict
|
|
11
|
+
|
|
12
|
+
from backends.duckduckgo import DuckDuckGoBackend
|
|
13
|
+
from core.orchestrator import ZenOrchestrator
|
|
14
|
+
from utils.helpers import colorize
|
|
15
|
+
|
|
16
|
+
from .integration import AgentSystemIntegration
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class AgentCLI:
|
|
20
|
+
"""Command-line interface for the agent system"""
|
|
21
|
+
|
|
22
|
+
def __init__(self):
|
|
23
|
+
self.integration = None
|
|
24
|
+
self.zen_orchestrator = None
|
|
25
|
+
|
|
26
|
+
async def initialize(self):
|
|
27
|
+
"""Initialize the system"""
|
|
28
|
+
print(colorize("[*] Initializing Zen AI Agent System...", "cyan"))
|
|
29
|
+
|
|
30
|
+
# Setup LLM orchestrator
|
|
31
|
+
self.zen_orchestrator = ZenOrchestrator()
|
|
32
|
+
async with DuckDuckGoBackend() as ddg:
|
|
33
|
+
self.zen_orchestrator.add_backend(ddg)
|
|
34
|
+
|
|
35
|
+
# Setup agent integration
|
|
36
|
+
self.integration = AgentSystemIntegration(self.zen_orchestrator)
|
|
37
|
+
await self.integration.initialize()
|
|
38
|
+
|
|
39
|
+
print(colorize("[+] Agent system ready!", "green"))
|
|
40
|
+
print()
|
|
41
|
+
|
|
42
|
+
def print_banner(self):
|
|
43
|
+
"""Print agent system banner"""
|
|
44
|
+
print(
|
|
45
|
+
colorize(
|
|
46
|
+
"""
|
|
47
|
+
╔══════════════════════════════════════════════════════════════╗
|
|
48
|
+
║ 🤖 Zen AI Multi-Agent System 🤖 ║
|
|
49
|
+
║ (Inspired by Clawed/Moltbot) ║
|
|
50
|
+
╠══════════════════════════════════════════════════════════════╣
|
|
51
|
+
║ Agents: Research • Analysis • Exploit ║
|
|
52
|
+
║ Features: Collaborative Research • Context Sharing ║
|
|
53
|
+
╚══════════════════════════════════════════════════════════════╝
|
|
54
|
+
""",
|
|
55
|
+
"bold",
|
|
56
|
+
)
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
def print_help(self):
|
|
60
|
+
"""Print help message"""
|
|
61
|
+
help_text = """
|
|
62
|
+
Available Commands:
|
|
63
|
+
research <topic> - Start collaborative research on topic
|
|
64
|
+
analyze <target> - Have agents analyze a target
|
|
65
|
+
discuss <topic> - Facilitate agent discussion
|
|
66
|
+
status - Show agent system status
|
|
67
|
+
agents - List all active agents
|
|
68
|
+
context <key> <value> - Share context with agents
|
|
69
|
+
chat <message> - Send message to all agents
|
|
70
|
+
stop - Shutdown agent system
|
|
71
|
+
help - Show this help
|
|
72
|
+
quit/exit - Exit
|
|
73
|
+
|
|
74
|
+
Examples:
|
|
75
|
+
research WordPress CVEs
|
|
76
|
+
analyze example.com
|
|
77
|
+
discuss Attack vectors for CVE-2017-0144
|
|
78
|
+
context target example.com
|
|
79
|
+
"""
|
|
80
|
+
print(help_text)
|
|
81
|
+
|
|
82
|
+
async def run(self):
|
|
83
|
+
"""Main CLI loop"""
|
|
84
|
+
self.print_banner()
|
|
85
|
+
await self.initialize()
|
|
86
|
+
self.print_help()
|
|
87
|
+
|
|
88
|
+
while True:
|
|
89
|
+
try:
|
|
90
|
+
cmd = input(colorize("agents> ", "bold")).strip()
|
|
91
|
+
|
|
92
|
+
if not cmd:
|
|
93
|
+
continue
|
|
94
|
+
|
|
95
|
+
parts = cmd.split(maxsplit=1)
|
|
96
|
+
command = parts[0].lower()
|
|
97
|
+
args = parts[1] if len(parts) > 1 else ""
|
|
98
|
+
|
|
99
|
+
if command in ("quit", "exit"):
|
|
100
|
+
print(colorize("[*] Shutting down agent system...", "yellow"))
|
|
101
|
+
await self.integration.shutdown()
|
|
102
|
+
print(colorize("[+] Goodbye!", "green"))
|
|
103
|
+
break
|
|
104
|
+
|
|
105
|
+
elif command == "help":
|
|
106
|
+
self.print_help()
|
|
107
|
+
|
|
108
|
+
elif command == "research":
|
|
109
|
+
if not args:
|
|
110
|
+
print(colorize("[!] Usage: research <topic>", "red"))
|
|
111
|
+
continue
|
|
112
|
+
print(colorize(f"[*] Starting research on: {args}", "cyan"))
|
|
113
|
+
thread_id = await self.integration.conduct_research(
|
|
114
|
+
topic=args,
|
|
115
|
+
pentest_context={
|
|
116
|
+
"target_type": "unknown",
|
|
117
|
+
"initiated_by": "user",
|
|
118
|
+
},
|
|
119
|
+
)
|
|
120
|
+
print(
|
|
121
|
+
colorize(f"[+] Research thread started: {thread_id}", "green")
|
|
122
|
+
)
|
|
123
|
+
print(
|
|
124
|
+
colorize(
|
|
125
|
+
"[*] Agents are working... Check status for updates",
|
|
126
|
+
"yellow",
|
|
127
|
+
)
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
elif command == "analyze":
|
|
131
|
+
if not args:
|
|
132
|
+
print(colorize("[!] Usage: analyze <target>", "red"))
|
|
133
|
+
continue
|
|
134
|
+
print(colorize(f"[*] Analyzing target: {args}", "cyan"))
|
|
135
|
+
results = await self.integration.analyze_target(
|
|
136
|
+
target=args, findings=[]
|
|
137
|
+
)
|
|
138
|
+
print(colorize(f"[+] Analysis complete!", "green"))
|
|
139
|
+
print(
|
|
140
|
+
colorize(
|
|
141
|
+
f"[*] Agent responses: {len(results.get('agent_responses', {}))}",
|
|
142
|
+
"cyan",
|
|
143
|
+
)
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
elif command == "discuss":
|
|
147
|
+
if not args:
|
|
148
|
+
print(colorize("[!] Usage: discuss <topic>", "red"))
|
|
149
|
+
continue
|
|
150
|
+
print(
|
|
151
|
+
colorize(
|
|
152
|
+
f"[*] Facilitating agent discussion on: {args}", "cyan"
|
|
153
|
+
)
|
|
154
|
+
)
|
|
155
|
+
messages = await self.integration.facilitate_discussion(
|
|
156
|
+
topic=args, rounds=2
|
|
157
|
+
)
|
|
158
|
+
print(colorize("[+] Discussion complete:", "green"))
|
|
159
|
+
for i, msg in enumerate(messages, 1):
|
|
160
|
+
print(f" {i}. {msg[:100]}...")
|
|
161
|
+
|
|
162
|
+
elif command == "status":
|
|
163
|
+
status = self.integration.get_system_status()
|
|
164
|
+
print(colorize("[*] Agent System Status:", "cyan"))
|
|
165
|
+
print(f" Active agents: {len(status.get('agents', {}))}")
|
|
166
|
+
print(f" Message count: {status.get('message_count', 0)}")
|
|
167
|
+
print(
|
|
168
|
+
f" Shared context keys: {len(status.get('shared_context_keys', []))}"
|
|
169
|
+
)
|
|
170
|
+
print(f" Role distribution: {status.get('role_distribution', {})}")
|
|
171
|
+
|
|
172
|
+
elif command == "agents":
|
|
173
|
+
status = self.integration.get_system_status()
|
|
174
|
+
print(colorize("[*] Active Agents:", "cyan"))
|
|
175
|
+
for agent_id, agent_status in status.get("agents", {}).items():
|
|
176
|
+
role = agent_status.get("role", "unknown")
|
|
177
|
+
running = "✓" if agent_status.get("running") else "✗"
|
|
178
|
+
print(
|
|
179
|
+
f" {running} {agent_status['name']} ({role}) [{agent_id}]"
|
|
180
|
+
)
|
|
181
|
+
print(
|
|
182
|
+
f" Queue: {agent_status.get('queue_size', 0)} | Inbox: {agent_status.get('inbox_count', 0)}"
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
elif command == "context":
|
|
186
|
+
if not args or len(args.split()) < 2:
|
|
187
|
+
print(colorize("[!] Usage: context <key> <value>", "red"))
|
|
188
|
+
continue
|
|
189
|
+
key_val = args.split(maxsplit=1)
|
|
190
|
+
key, value = key_val[0], key_val[1]
|
|
191
|
+
await self.integration.share_context(key, value)
|
|
192
|
+
print(colorize(f"[+] Shared context: {key} = {value}", "green"))
|
|
193
|
+
|
|
194
|
+
elif command == "chat":
|
|
195
|
+
if not args:
|
|
196
|
+
print(colorize("[!] Usage: chat <message>", "red"))
|
|
197
|
+
continue
|
|
198
|
+
# Send to all agents
|
|
199
|
+
from .agent_base import AgentMessage
|
|
200
|
+
|
|
201
|
+
for (
|
|
202
|
+
agent_id,
|
|
203
|
+
agent,
|
|
204
|
+
) in self.integration.agent_orchestrator.agents.items():
|
|
205
|
+
await agent.receive_message(
|
|
206
|
+
AgentMessage(
|
|
207
|
+
sender="user",
|
|
208
|
+
recipient=f"{agent.name}[{agent.id}]",
|
|
209
|
+
msg_type="chat",
|
|
210
|
+
content=args,
|
|
211
|
+
)
|
|
212
|
+
)
|
|
213
|
+
print(colorize(f"[+] Message sent to all agents", "green"))
|
|
214
|
+
|
|
215
|
+
elif command == "stop":
|
|
216
|
+
await self.integration.shutdown()
|
|
217
|
+
print(colorize("[+] Agent system stopped", "green"))
|
|
218
|
+
|
|
219
|
+
else:
|
|
220
|
+
print(colorize(f"[!] Unknown command: {command}", "red"))
|
|
221
|
+
|
|
222
|
+
except KeyboardInterrupt:
|
|
223
|
+
print(colorize("\n[*] Use 'quit' to exit", "yellow"))
|
|
224
|
+
except Exception as e:
|
|
225
|
+
print(colorize(f"[!] Error: {e}", "red"))
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
async def main():
|
|
229
|
+
"""Entry point for agent CLI"""
|
|
230
|
+
cli = AgentCLI()
|
|
231
|
+
try:
|
|
232
|
+
await cli.run()
|
|
233
|
+
except Exception as e:
|
|
234
|
+
print(colorize(f"[!] Fatal error: {e}", "red"))
|
|
235
|
+
sys.exit(1)
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
if __name__ == "__main__":
|
|
239
|
+
# Handle Windows Python 3.13+ compatibility
|
|
240
|
+
import sys
|
|
241
|
+
|
|
242
|
+
if sys.platform == "win32" and sys.version_info >= (3, 13):
|
|
243
|
+
from utils.async_fixes import apply_windows_async_fixes
|
|
244
|
+
|
|
245
|
+
apply_windows_async_fixes()
|
|
246
|
+
|
|
247
|
+
loop = asyncio.SelectorEventLoop()
|
|
248
|
+
asyncio.set_event_loop(loop)
|
|
249
|
+
try:
|
|
250
|
+
loop.run_until_complete(main())
|
|
251
|
+
finally:
|
|
252
|
+
try:
|
|
253
|
+
loop.run_until_complete(asyncio.sleep(0.25))
|
|
254
|
+
except:
|
|
255
|
+
pass
|
|
256
|
+
loop.close()
|
|
257
|
+
else:
|
|
258
|
+
asyncio.run(main())
|