aiptx 2.0.7__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.
Files changed (187) hide show
  1. aipt_v2/__init__.py +110 -0
  2. aipt_v2/__main__.py +24 -0
  3. aipt_v2/agents/AIPTxAgent/__init__.py +10 -0
  4. aipt_v2/agents/AIPTxAgent/aiptx_agent.py +211 -0
  5. aipt_v2/agents/__init__.py +46 -0
  6. aipt_v2/agents/base.py +520 -0
  7. aipt_v2/agents/exploit_agent.py +688 -0
  8. aipt_v2/agents/ptt.py +406 -0
  9. aipt_v2/agents/state.py +168 -0
  10. aipt_v2/app.py +957 -0
  11. aipt_v2/browser/__init__.py +31 -0
  12. aipt_v2/browser/automation.py +458 -0
  13. aipt_v2/browser/crawler.py +453 -0
  14. aipt_v2/cli.py +2933 -0
  15. aipt_v2/compliance/__init__.py +71 -0
  16. aipt_v2/compliance/compliance_report.py +449 -0
  17. aipt_v2/compliance/framework_mapper.py +424 -0
  18. aipt_v2/compliance/nist_mapping.py +345 -0
  19. aipt_v2/compliance/owasp_mapping.py +330 -0
  20. aipt_v2/compliance/pci_mapping.py +297 -0
  21. aipt_v2/config.py +341 -0
  22. aipt_v2/core/__init__.py +43 -0
  23. aipt_v2/core/agent.py +630 -0
  24. aipt_v2/core/llm.py +395 -0
  25. aipt_v2/core/memory.py +305 -0
  26. aipt_v2/core/ptt.py +329 -0
  27. aipt_v2/database/__init__.py +14 -0
  28. aipt_v2/database/models.py +232 -0
  29. aipt_v2/database/repository.py +384 -0
  30. aipt_v2/docker/__init__.py +23 -0
  31. aipt_v2/docker/builder.py +260 -0
  32. aipt_v2/docker/manager.py +222 -0
  33. aipt_v2/docker/sandbox.py +371 -0
  34. aipt_v2/evasion/__init__.py +58 -0
  35. aipt_v2/evasion/request_obfuscator.py +272 -0
  36. aipt_v2/evasion/tls_fingerprint.py +285 -0
  37. aipt_v2/evasion/ua_rotator.py +301 -0
  38. aipt_v2/evasion/waf_bypass.py +439 -0
  39. aipt_v2/execution/__init__.py +23 -0
  40. aipt_v2/execution/executor.py +302 -0
  41. aipt_v2/execution/parser.py +544 -0
  42. aipt_v2/execution/terminal.py +337 -0
  43. aipt_v2/health.py +437 -0
  44. aipt_v2/intelligence/__init__.py +194 -0
  45. aipt_v2/intelligence/adaptation.py +474 -0
  46. aipt_v2/intelligence/auth.py +520 -0
  47. aipt_v2/intelligence/chaining.py +775 -0
  48. aipt_v2/intelligence/correlation.py +536 -0
  49. aipt_v2/intelligence/cve_aipt.py +334 -0
  50. aipt_v2/intelligence/cve_info.py +1111 -0
  51. aipt_v2/intelligence/knowledge_graph.py +590 -0
  52. aipt_v2/intelligence/learning.py +626 -0
  53. aipt_v2/intelligence/llm_analyzer.py +502 -0
  54. aipt_v2/intelligence/llm_tool_selector.py +518 -0
  55. aipt_v2/intelligence/payload_generator.py +562 -0
  56. aipt_v2/intelligence/rag.py +239 -0
  57. aipt_v2/intelligence/scope.py +442 -0
  58. aipt_v2/intelligence/searchers/__init__.py +5 -0
  59. aipt_v2/intelligence/searchers/exploitdb_searcher.py +523 -0
  60. aipt_v2/intelligence/searchers/github_searcher.py +467 -0
  61. aipt_v2/intelligence/searchers/google_searcher.py +281 -0
  62. aipt_v2/intelligence/tools.json +443 -0
  63. aipt_v2/intelligence/triage.py +670 -0
  64. aipt_v2/interactive_shell.py +559 -0
  65. aipt_v2/interface/__init__.py +5 -0
  66. aipt_v2/interface/cli.py +230 -0
  67. aipt_v2/interface/main.py +501 -0
  68. aipt_v2/interface/tui.py +1276 -0
  69. aipt_v2/interface/utils.py +583 -0
  70. aipt_v2/llm/__init__.py +39 -0
  71. aipt_v2/llm/config.py +26 -0
  72. aipt_v2/llm/llm.py +514 -0
  73. aipt_v2/llm/memory.py +214 -0
  74. aipt_v2/llm/request_queue.py +89 -0
  75. aipt_v2/llm/utils.py +89 -0
  76. aipt_v2/local_tool_installer.py +1467 -0
  77. aipt_v2/models/__init__.py +15 -0
  78. aipt_v2/models/findings.py +295 -0
  79. aipt_v2/models/phase_result.py +224 -0
  80. aipt_v2/models/scan_config.py +207 -0
  81. aipt_v2/monitoring/grafana/dashboards/aipt-dashboard.json +355 -0
  82. aipt_v2/monitoring/grafana/dashboards/default.yml +17 -0
  83. aipt_v2/monitoring/grafana/datasources/prometheus.yml +17 -0
  84. aipt_v2/monitoring/prometheus.yml +60 -0
  85. aipt_v2/orchestration/__init__.py +52 -0
  86. aipt_v2/orchestration/pipeline.py +398 -0
  87. aipt_v2/orchestration/progress.py +300 -0
  88. aipt_v2/orchestration/scheduler.py +296 -0
  89. aipt_v2/orchestrator.py +2427 -0
  90. aipt_v2/payloads/__init__.py +27 -0
  91. aipt_v2/payloads/cmdi.py +150 -0
  92. aipt_v2/payloads/sqli.py +263 -0
  93. aipt_v2/payloads/ssrf.py +204 -0
  94. aipt_v2/payloads/templates.py +222 -0
  95. aipt_v2/payloads/traversal.py +166 -0
  96. aipt_v2/payloads/xss.py +204 -0
  97. aipt_v2/prompts/__init__.py +60 -0
  98. aipt_v2/proxy/__init__.py +29 -0
  99. aipt_v2/proxy/history.py +352 -0
  100. aipt_v2/proxy/interceptor.py +452 -0
  101. aipt_v2/recon/__init__.py +44 -0
  102. aipt_v2/recon/dns.py +241 -0
  103. aipt_v2/recon/osint.py +367 -0
  104. aipt_v2/recon/subdomain.py +372 -0
  105. aipt_v2/recon/tech_detect.py +311 -0
  106. aipt_v2/reports/__init__.py +17 -0
  107. aipt_v2/reports/generator.py +313 -0
  108. aipt_v2/reports/html_report.py +378 -0
  109. aipt_v2/runtime/__init__.py +53 -0
  110. aipt_v2/runtime/base.py +30 -0
  111. aipt_v2/runtime/docker.py +401 -0
  112. aipt_v2/runtime/local.py +346 -0
  113. aipt_v2/runtime/tool_server.py +205 -0
  114. aipt_v2/runtime/vps.py +830 -0
  115. aipt_v2/scanners/__init__.py +28 -0
  116. aipt_v2/scanners/base.py +273 -0
  117. aipt_v2/scanners/nikto.py +244 -0
  118. aipt_v2/scanners/nmap.py +402 -0
  119. aipt_v2/scanners/nuclei.py +273 -0
  120. aipt_v2/scanners/web.py +454 -0
  121. aipt_v2/scripts/security_audit.py +366 -0
  122. aipt_v2/setup_wizard.py +941 -0
  123. aipt_v2/skills/__init__.py +80 -0
  124. aipt_v2/skills/agents/__init__.py +14 -0
  125. aipt_v2/skills/agents/api_tester.py +706 -0
  126. aipt_v2/skills/agents/base.py +477 -0
  127. aipt_v2/skills/agents/code_review.py +459 -0
  128. aipt_v2/skills/agents/security_agent.py +336 -0
  129. aipt_v2/skills/agents/web_pentest.py +818 -0
  130. aipt_v2/skills/prompts/__init__.py +647 -0
  131. aipt_v2/system_detector.py +539 -0
  132. aipt_v2/telemetry/__init__.py +7 -0
  133. aipt_v2/telemetry/tracer.py +347 -0
  134. aipt_v2/terminal/__init__.py +28 -0
  135. aipt_v2/terminal/executor.py +400 -0
  136. aipt_v2/terminal/sandbox.py +350 -0
  137. aipt_v2/tools/__init__.py +44 -0
  138. aipt_v2/tools/active_directory/__init__.py +78 -0
  139. aipt_v2/tools/active_directory/ad_config.py +238 -0
  140. aipt_v2/tools/active_directory/bloodhound_wrapper.py +447 -0
  141. aipt_v2/tools/active_directory/kerberos_attacks.py +430 -0
  142. aipt_v2/tools/active_directory/ldap_enum.py +533 -0
  143. aipt_v2/tools/active_directory/smb_attacks.py +505 -0
  144. aipt_v2/tools/agents_graph/__init__.py +19 -0
  145. aipt_v2/tools/agents_graph/agents_graph_actions.py +69 -0
  146. aipt_v2/tools/api_security/__init__.py +76 -0
  147. aipt_v2/tools/api_security/api_discovery.py +608 -0
  148. aipt_v2/tools/api_security/graphql_scanner.py +622 -0
  149. aipt_v2/tools/api_security/jwt_analyzer.py +577 -0
  150. aipt_v2/tools/api_security/openapi_fuzzer.py +761 -0
  151. aipt_v2/tools/browser/__init__.py +5 -0
  152. aipt_v2/tools/browser/browser_actions.py +238 -0
  153. aipt_v2/tools/browser/browser_instance.py +535 -0
  154. aipt_v2/tools/browser/tab_manager.py +344 -0
  155. aipt_v2/tools/cloud/__init__.py +70 -0
  156. aipt_v2/tools/cloud/cloud_config.py +273 -0
  157. aipt_v2/tools/cloud/cloud_scanner.py +639 -0
  158. aipt_v2/tools/cloud/prowler_tool.py +571 -0
  159. aipt_v2/tools/cloud/scoutsuite_tool.py +359 -0
  160. aipt_v2/tools/executor.py +307 -0
  161. aipt_v2/tools/parser.py +408 -0
  162. aipt_v2/tools/proxy/__init__.py +5 -0
  163. aipt_v2/tools/proxy/proxy_actions.py +103 -0
  164. aipt_v2/tools/proxy/proxy_manager.py +789 -0
  165. aipt_v2/tools/registry.py +196 -0
  166. aipt_v2/tools/scanners/__init__.py +343 -0
  167. aipt_v2/tools/scanners/acunetix_tool.py +712 -0
  168. aipt_v2/tools/scanners/burp_tool.py +631 -0
  169. aipt_v2/tools/scanners/config.py +156 -0
  170. aipt_v2/tools/scanners/nessus_tool.py +588 -0
  171. aipt_v2/tools/scanners/zap_tool.py +612 -0
  172. aipt_v2/tools/terminal/__init__.py +5 -0
  173. aipt_v2/tools/terminal/terminal_actions.py +37 -0
  174. aipt_v2/tools/terminal/terminal_manager.py +153 -0
  175. aipt_v2/tools/terminal/terminal_session.py +449 -0
  176. aipt_v2/tools/tool_processing.py +108 -0
  177. aipt_v2/utils/__init__.py +17 -0
  178. aipt_v2/utils/logging.py +202 -0
  179. aipt_v2/utils/model_manager.py +187 -0
  180. aipt_v2/utils/searchers/__init__.py +269 -0
  181. aipt_v2/verify_install.py +793 -0
  182. aiptx-2.0.7.dist-info/METADATA +345 -0
  183. aiptx-2.0.7.dist-info/RECORD +187 -0
  184. aiptx-2.0.7.dist-info/WHEEL +5 -0
  185. aiptx-2.0.7.dist-info/entry_points.txt +7 -0
  186. aiptx-2.0.7.dist-info/licenses/LICENSE +21 -0
  187. aiptx-2.0.7.dist-info/top_level.txt +1 -0
@@ -0,0 +1,347 @@
1
+ """
2
+ AIPT Telemetry Tracer - Agent execution tracking and monitoring
3
+
4
+ Provides comprehensive tracking of:
5
+ - Agent creation and status
6
+ - Tool executions
7
+ - Chat messages
8
+ - Vulnerability findings
9
+ - LLM usage statistics
10
+ """
11
+
12
+ import json
13
+ import logging
14
+ import os
15
+ from datetime import datetime
16
+ from pathlib import Path
17
+ from typing import Any, Callable, Optional
18
+ from dataclasses import dataclass, field
19
+
20
+
21
+ logger = logging.getLogger(__name__)
22
+
23
+
24
+ @dataclass
25
+ class ToolExecution:
26
+ """Record of a tool execution"""
27
+ execution_id: int
28
+ agent_id: str
29
+ tool_name: str
30
+ args: dict
31
+ status: str = "running"
32
+ result: Any = None
33
+ started_at: str = field(default_factory=lambda: datetime.now().isoformat())
34
+ completed_at: Optional[str] = None
35
+
36
+
37
+ @dataclass
38
+ class AgentRecord:
39
+ """Record of an agent"""
40
+ agent_id: str
41
+ name: str
42
+ task: str
43
+ parent_id: Optional[str] = None
44
+ status: str = "running"
45
+ created_at: str = field(default_factory=lambda: datetime.now().isoformat())
46
+
47
+
48
+ class Tracer:
49
+ """
50
+ Tracer for agent execution telemetry.
51
+
52
+ Tracks:
53
+ - Agent lifecycle events
54
+ - Tool executions
55
+ - Chat messages
56
+ - Vulnerability discoveries
57
+ - LLM token usage and costs
58
+ """
59
+
60
+ def __init__(self, scan_id: str = ""):
61
+ self.scan_id = scan_id
62
+ self.scan_config: dict = {}
63
+
64
+ # Agent tracking
65
+ self.agents: dict[str, AgentRecord] = {}
66
+
67
+ # Tool execution tracking
68
+ self._next_execution_id: int = 0
69
+ self.tool_executions: dict[int, ToolExecution] = {}
70
+
71
+ # Vulnerability tracking
72
+ self.vulnerability_reports: list[dict[str, Any]] = []
73
+ self.vulnerability_found_callback: Optional[Callable[[str, str, str, str], None]] = None
74
+
75
+ # Chat message tracking
76
+ self.chat_messages: list[dict[str, Any]] = []
77
+
78
+ # LLM usage tracking
79
+ self._llm_stats: dict[str, Any] = {
80
+ "total": {
81
+ "input_tokens": 0,
82
+ "output_tokens": 0,
83
+ "cached_tokens": 0,
84
+ "cache_creation_tokens": 0,
85
+ "cost": 0.0,
86
+ "requests": 0,
87
+ },
88
+ "by_agent": {},
89
+ }
90
+
91
+ # Final result storage
92
+ self.final_scan_result: Optional[str] = None
93
+
94
+ # Output directory
95
+ self.output_dir = Path(f"aipt_runs/{scan_id}") if scan_id else None
96
+ if self.output_dir:
97
+ self.output_dir.mkdir(parents=True, exist_ok=True)
98
+
99
+ def set_scan_config(self, config: dict) -> None:
100
+ """Set the scan configuration."""
101
+ self.scan_config = config
102
+ self.scan_id = config.get("scan_id", self.scan_id)
103
+
104
+ if self.scan_id and not self.output_dir:
105
+ self.output_dir = Path(f"aipt_runs/{self.scan_id}")
106
+ self.output_dir.mkdir(parents=True, exist_ok=True)
107
+
108
+ def log_agent_creation(
109
+ self,
110
+ agent_id: str,
111
+ name: str,
112
+ task: str,
113
+ parent_id: Optional[str] = None,
114
+ ) -> None:
115
+ """Log agent creation event."""
116
+ record = AgentRecord(
117
+ agent_id=agent_id,
118
+ name=name,
119
+ task=task,
120
+ parent_id=parent_id,
121
+ )
122
+ self.agents[agent_id] = record
123
+
124
+ logger.info(f"Agent created: {name} ({agent_id})")
125
+
126
+ def log_tool_execution_start(
127
+ self,
128
+ agent_id: str,
129
+ tool_name: str,
130
+ args: dict,
131
+ ) -> int:
132
+ """Log start of tool execution."""
133
+ self._next_execution_id += 1
134
+ execution_id = self._next_execution_id
135
+
136
+ execution = ToolExecution(
137
+ execution_id=execution_id,
138
+ agent_id=agent_id,
139
+ tool_name=tool_name,
140
+ args=args,
141
+ )
142
+ self.tool_executions[execution_id] = execution
143
+
144
+ logger.info(f"Tool execution started: {tool_name} (exec_id={execution_id})")
145
+
146
+ return execution_id
147
+
148
+ def update_tool_execution(
149
+ self,
150
+ execution_id: int,
151
+ status: str,
152
+ result: Any = None,
153
+ ) -> None:
154
+ """Update tool execution status."""
155
+ if execution_id in self.tool_executions:
156
+ execution = self.tool_executions[execution_id]
157
+ execution.status = status
158
+ execution.result = result
159
+ if status in ("completed", "failed"):
160
+ execution.completed_at = datetime.now().isoformat()
161
+
162
+ logger.info(f"Tool execution updated: exec_id={execution_id} status={status}")
163
+
164
+ def update_agent_status(
165
+ self,
166
+ agent_id: str,
167
+ status: str,
168
+ error: Optional[str] = None,
169
+ ) -> None:
170
+ """Update agent status."""
171
+ if agent_id in self.agents:
172
+ self.agents[agent_id].status = status
173
+
174
+ if error:
175
+ logger.warning(f"Agent {agent_id} error: {error}")
176
+ else:
177
+ logger.info(f"Agent {agent_id} status: {status}")
178
+
179
+ def log_chat_message(
180
+ self,
181
+ content: str,
182
+ role: str,
183
+ agent_id: str,
184
+ ) -> None:
185
+ """Log chat message."""
186
+ message = {
187
+ "agent_id": agent_id,
188
+ "role": role,
189
+ "content": content,
190
+ "timestamp": datetime.now().isoformat(),
191
+ }
192
+ self.chat_messages.append(message)
193
+
194
+ def report_vulnerability(
195
+ self,
196
+ report_id: str,
197
+ title: str,
198
+ content: str,
199
+ severity: str,
200
+ ) -> None:
201
+ """Report a discovered vulnerability."""
202
+ report = {
203
+ "report_id": report_id,
204
+ "title": title,
205
+ "content": content,
206
+ "severity": severity,
207
+ "timestamp": datetime.now().isoformat(),
208
+ }
209
+ self.vulnerability_reports.append(report)
210
+
211
+ logger.warning(f"Vulnerability found: [{severity.upper()}] {title}")
212
+
213
+ # Call the callback if registered
214
+ if self.vulnerability_found_callback:
215
+ try:
216
+ self.vulnerability_found_callback(report_id, title, content, severity)
217
+ except Exception as e:
218
+ logger.error(f"Vulnerability callback failed: {e}")
219
+
220
+ def update_llm_stats(
221
+ self,
222
+ agent_id: str,
223
+ input_tokens: int = 0,
224
+ output_tokens: int = 0,
225
+ cached_tokens: int = 0,
226
+ cache_creation_tokens: int = 0,
227
+ cost: float = 0.0,
228
+ ) -> None:
229
+ """Update LLM usage statistics."""
230
+ # Update total stats
231
+ self._llm_stats["total"]["input_tokens"] += input_tokens
232
+ self._llm_stats["total"]["output_tokens"] += output_tokens
233
+ self._llm_stats["total"]["cached_tokens"] += cached_tokens
234
+ self._llm_stats["total"]["cache_creation_tokens"] += cache_creation_tokens
235
+ self._llm_stats["total"]["cost"] += cost
236
+ self._llm_stats["total"]["requests"] += 1
237
+
238
+ # Update per-agent stats
239
+ if agent_id not in self._llm_stats["by_agent"]:
240
+ self._llm_stats["by_agent"][agent_id] = {
241
+ "input_tokens": 0,
242
+ "output_tokens": 0,
243
+ "cached_tokens": 0,
244
+ "cache_creation_tokens": 0,
245
+ "cost": 0.0,
246
+ "requests": 0,
247
+ }
248
+
249
+ agent_stats = self._llm_stats["by_agent"][agent_id]
250
+ agent_stats["input_tokens"] += input_tokens
251
+ agent_stats["output_tokens"] += output_tokens
252
+ agent_stats["cached_tokens"] += cached_tokens
253
+ agent_stats["cache_creation_tokens"] += cache_creation_tokens
254
+ agent_stats["cost"] += cost
255
+ agent_stats["requests"] += 1
256
+
257
+ def get_total_llm_stats(self) -> dict[str, Any]:
258
+ """Get total LLM usage statistics."""
259
+ return self._llm_stats
260
+
261
+ def get_real_tool_count(self) -> int:
262
+ """Get count of real tool executions (excluding internal tools)."""
263
+ internal_tools = {
264
+ "scan_start_info",
265
+ "subagent_start_info",
266
+ "llm_error_details",
267
+ }
268
+ count = 0
269
+ for execution in self.tool_executions.values():
270
+ if execution.tool_name not in internal_tools:
271
+ count += 1
272
+ return count
273
+
274
+ def set_final_result(self, result: str) -> None:
275
+ """Set the final scan result."""
276
+ self.final_scan_result = result
277
+
278
+ def cleanup(self) -> None:
279
+ """Cleanup tracer resources and save final state."""
280
+ if self.output_dir:
281
+ try:
282
+ # Save vulnerability reports
283
+ vuln_file = self.output_dir / "vulnerabilities.json"
284
+ with open(vuln_file, "w") as f:
285
+ json.dump(self.vulnerability_reports, f, indent=2)
286
+
287
+ # Save tool executions
288
+ tools_file = self.output_dir / "tool_executions.json"
289
+ tool_data = [
290
+ {
291
+ "execution_id": e.execution_id,
292
+ "agent_id": e.agent_id,
293
+ "tool_name": e.tool_name,
294
+ "args": e.args,
295
+ "status": e.status,
296
+ "started_at": e.started_at,
297
+ "completed_at": e.completed_at,
298
+ }
299
+ for e in self.tool_executions.values()
300
+ ]
301
+ with open(tools_file, "w") as f:
302
+ json.dump(tool_data, f, indent=2)
303
+
304
+ # Save LLM stats
305
+ stats_file = self.output_dir / "llm_stats.json"
306
+ with open(stats_file, "w") as f:
307
+ json.dump(self._llm_stats, f, indent=2)
308
+
309
+ # Save final result
310
+ if self.final_scan_result:
311
+ result_file = self.output_dir / "final_result.txt"
312
+ with open(result_file, "w") as f:
313
+ f.write(self.final_scan_result)
314
+
315
+ logger.info(f"Tracer data saved to {self.output_dir}")
316
+
317
+ except Exception as e:
318
+ logger.error(f"Failed to save tracer data: {e}")
319
+
320
+ def get_summary(self) -> dict[str, Any]:
321
+ """Get summary of the scan."""
322
+ return {
323
+ "scan_id": self.scan_id,
324
+ "agents_count": len(self.agents),
325
+ "tool_executions_count": self.get_real_tool_count(),
326
+ "vulnerabilities_count": len(self.vulnerability_reports),
327
+ "chat_messages_count": len(self.chat_messages),
328
+ "llm_stats": self._llm_stats["total"],
329
+ }
330
+
331
+
332
+ # Global tracer instance
333
+ _global_tracer: Optional[Tracer] = None
334
+
335
+
336
+ def get_global_tracer() -> Optional[Tracer]:
337
+ """Get the global tracer instance."""
338
+ return _global_tracer
339
+
340
+
341
+ def set_global_tracer(tracer: Tracer) -> None:
342
+ """Set the global tracer instance."""
343
+ global _global_tracer
344
+ _global_tracer = tracer
345
+
346
+
347
+ __all__ = ["Tracer", "get_global_tracer", "set_global_tracer"]
@@ -0,0 +1,28 @@
1
+ """
2
+ AIPT Terminal Module
3
+
4
+ Secure shell command execution with:
5
+ - Async subprocess management
6
+ - Output streaming
7
+ - Timeout handling
8
+ - Command sanitization
9
+ - Docker sandboxing support
10
+ """
11
+
12
+ from .executor import (
13
+ TerminalExecutor,
14
+ CommandResult,
15
+ ExecutionConfig,
16
+ )
17
+ from .sandbox import (
18
+ DockerSandbox,
19
+ SandboxConfig,
20
+ )
21
+
22
+ __all__ = [
23
+ "TerminalExecutor",
24
+ "CommandResult",
25
+ "ExecutionConfig",
26
+ "DockerSandbox",
27
+ "SandboxConfig",
28
+ ]