exaai-agent 2.0.9__py3-none-any.whl → 2.2.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.
Files changed (34) hide show
  1. {exaai_agent-2.0.9.dist-info → exaai_agent-2.2.0.dist-info}/METADATA +72 -42
  2. {exaai_agent-2.0.9.dist-info → exaai_agent-2.2.0.dist-info}/RECORD +34 -22
  3. {exaai_agent-2.0.9.dist-info → exaai_agent-2.2.0.dist-info}/WHEEL +1 -1
  4. exaaiagnt/dashboard/server.py +99 -0
  5. exaaiagnt/dashboard/templates/index.html +232 -0
  6. exaaiagnt/interface/cli.py +62 -30
  7. exaaiagnt/interface/main.py +11 -1
  8. exaaiagnt/interface/tui.py +12 -8
  9. exaaiagnt/llm/llm.py +43 -8
  10. exaaiagnt/llm/llm_traffic_controller.py +5 -3
  11. exaaiagnt/prompts/README.md +3 -1
  12. exaaiagnt/prompts/auto_loader.py +31 -0
  13. exaaiagnt/prompts/cloud/azure_cloud_security.jinja +126 -0
  14. exaaiagnt/prompts/cloud/gcp_cloud_security.jinja +158 -0
  15. exaaiagnt/prompts/cloud/kubernetes_security.jinja +97 -0
  16. exaaiagnt/prompts/vulnerabilities/prompt_injection.jinja +276 -0
  17. exaaiagnt/runtime/tool_manager.py +12 -3
  18. exaaiagnt/telemetry/tracer.py +17 -1
  19. exaaiagnt/tools/__init__.py +24 -0
  20. exaaiagnt/tools/executor.py +16 -4
  21. exaaiagnt/tools/k8s_scanner/__init__.py +29 -0
  22. exaaiagnt/tools/k8s_scanner/k8s_actions.py +319 -0
  23. exaaiagnt/tools/k8s_scanner/k8s_actions_schema.xml +36 -0
  24. exaaiagnt/tools/prompt_injection/__init__.py +26 -0
  25. exaaiagnt/tools/prompt_injection/prompt_injection_actions.py +712 -0
  26. exaaiagnt/tools/prompt_injection/prompt_injection_actions_schema.xml +28 -0
  27. exaaiagnt/tools/python/python_instance.py +16 -1
  28. exaaiagnt/tools/reporting/reporting_actions.py +34 -5
  29. exaaiagnt/tools/response_analyzer.py +5 -3
  30. exaaiagnt/tools/smart_fuzzer.py +5 -3
  31. exaaiagnt/tools/vuln_validator.py +5 -3
  32. exaaiagnt/tools/web_search/web_search_actions.py +4 -2
  33. {exaai_agent-2.0.9.dist-info → exaai_agent-2.2.0.dist-info}/entry_points.txt +0 -0
  34. {exaai_agent-2.0.9.dist-info → exaai_agent-2.2.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: exaai-agent
3
- Version: 2.0.9
3
+ Version: 2.2.0
4
4
  Summary: ExaAi - Advanced AI Security Agent for Comprehensive Penetration Testing
5
5
  License: Apache-2.0
6
6
  License-File: LICENSE
@@ -53,57 +53,60 @@ Description-Content-Type: text/markdown
53
53
  [![Python](https://img.shields.io/pypi/pyversions/exaai-agent?color=3776AB)](https://pypi.org/project/exaai-agent/)
54
54
  [![PyPI](https://img.shields.io/pypi/v/exaai-agent?color=10b981)](https://pypi.org/project/exaai-agent/)
55
55
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
56
- [![Version](https://img.shields.io/badge/version-2.1.0-00d4ff.svg)]()
56
+ [![Version](https://img.shields.io/badge/version-2.1.2-00d4ff.svg)]()
57
57
 
58
58
  </div>
59
59
 
60
60
  <br>
61
61
 
62
62
  > [!TIP]
63
- > **🚀 v2.1.0 Released!** React2Shell Detection (CVE-2025-55182), Cloud Security Testing, Smart Fuzzing, and CLI improvements with `exaai` command!
63
+ > **🚀 v2.1.2 Released!** Now supports **AI Agent Integration (OpenClaw)**, Kubernetes Security, Azure/GCP modules, and Prompt Injection detection.
64
+ >
65
+ > 🤖 **Connect Your Agent:** You can now control ExaAiAgent via any AI agent (OpenClaw, etc).
66
+ > Just send this command to your agent:
67
+ > ```
68
+ > Read https://raw.githubusercontent.com/hleliofficiel/ExaAiAgent/main/SKILL.md and follow the instructions to join ExaAiAgent
69
+ > ```
64
70
 
65
71
  ---
66
72
 
67
- ## 🔥 What's New in v2.1.0
73
+ ## 🔥 What's New in v2.1.2
68
74
 
69
- ### 🚨 React2Shell Detection (CVE-2025-55182)
75
+ ### 🤖 AI Agent Integration (OpenClaw)
70
76
 
71
- New critical vulnerability scanner for **React Server Components**:
77
+ Seamlessly integrate ExaAiAgent with your AI workforce:
72
78
 
73
- - **CVSS 10.0** - Unauthenticated RCE via RSC Flight protocol
74
- - Auto-detects Next.js 15.x/16.x, React 19.x applications
75
- - Complete exploitation methodology and PoC generation
76
- - WAF bypass techniques included
79
+ - **Agent Control**: Control scans via OpenClaw or any agent framework
80
+ - **Auto-Discovery**: Agents can read `SKILL.md` to self-onboard
81
+ - **Output Optimization**: Tools now output cleaner data (no ANSI codes) for LLM consumption
77
82
 
78
- ### ☁️ AWS & Cloud Security
83
+ ### Kubernetes & Cloud Security (Updated)
79
84
 
80
- Comprehensive cloud infrastructure testing:
85
+ Expanded coverage for cloud-native infrastructure:
81
86
 
82
- - **AWS**: EC2 Metadata SSRF, S3 buckets, IAM escalation, Lambda
83
- - **Azure**: Blob storage, Managed Identity, Azure AD
84
- - **GCP**: Cloud Storage, Service Account abuse
85
- - **Kubernetes**: RBAC, Secrets, Pod escape
87
+ - **Kubernetes**: Deep RBAC auditing, Pod Security Standards (PSS), Network Policy checks
88
+ - **Azure**: Blob Storage, Entra ID (Azure AD), Key Vault auditing
89
+ - **GCP**: Cloud Storage, IAM, Service Account key leaks
90
+ - **Prompt Injection**: Dedicated scanner for AI/LLM applications
86
91
 
87
- ### Smart Security Tools
92
+ ### 🛡️ Smart Security Tools
88
93
 
89
94
  | Tool | Capability |
90
95
  |------|------------|
91
- | **Smart Fuzzer** | Context-aware payloads, parameter type detection |
96
+ | **Smart Fuzzer** | Thread-safe, context-aware fuzzing with rate limiting |
92
97
  | **Response Analyzer** | SQL errors, stack traces, sensitive data detection |
93
- | **Vuln Validator** | PoC generation, CVSS scoring, remediation advice |
94
- | **WAF Bypass** | Multi-layer bypass techniques |
98
+ | **Vuln Validator** | PoC generation with false positive reduction |
99
+ | **WAF Bypass** | Multi-layer bypass for Cloudflare, Akamai, AWS WAF |
95
100
 
96
- ### ⚡ CLI Improvements
101
+ ### ⚡ CLI & Stability
97
102
 
98
- ```bash
99
- # New command (shorter!)
100
- exaai --target https://example.com
101
-
102
- # Version check
103
- exaai --version
103
+ - **Thread-Safety**: Fixed race conditions in async scans
104
+ - **Resource Management**: Auto-shutdown and cleanup of background processes
105
+ - **Installation**: Robust `install.sh` for Linux/macOS (bash/zsh/fish)
104
106
 
105
- # TUI mode
106
- exaai tui
107
+ ```bash
108
+ # New install script
109
+ curl -sSL https://raw.githubusercontent.com/hleliofficiel/ExaAiAgent/main/install.sh | bash
107
110
  ```
108
111
 
109
112
  ---
@@ -146,6 +149,10 @@ ExaAiAgent is an elite AI-powered cybersecurity agent that acts like a real pene
146
149
 
147
150
  ```bash
148
151
  # Install ExaAiAgent
152
+
153
+ # Method 1: Automated Script (Recommended)
154
+ pip install exaai-agent
155
+ # Method 2: pipx
149
156
  pipx install exaai-agent
150
157
 
151
158
  # Configure your AI provider (choose one)
@@ -287,7 +294,7 @@ jobs:
287
294
  - uses: actions/checkout@v4
288
295
 
289
296
  - name: Install ExaAiAgent
290
- run: pipx install exaai-agent
297
+ run: curl -sSL https://raw.githubusercontent.com/hleliofficiel/ExaAiAgent/main/install.sh | bash
291
298
 
292
299
  - name: Run ExaAiAgent
293
300
  env:
@@ -339,26 +346,49 @@ export PERPLEXITY_API_KEY="key" # For search capabilities
339
346
  | `oauth_oidc` | OAuth2/OIDC flaws |
340
347
  | `waf_bypass` | WAF bypass techniques |
341
348
  | `subdomain_takeover` | Subdomain takeover |
349
+ | `prompt_injection` | AI/LLM prompt injection attacks |
350
+ | `kubernetes_security` | **NEW!** K8s RBAC & Pod Security auditing |
342
351
 
343
352
  ---
344
353
 
345
354
  ## 🆕 Changelog
346
355
 
347
- ### v2.0.0 (Latest)
356
+ ### v2.1.2 (Latest)
357
+ - **AI Agent Integration**: OpenClaw/Agent compatibility
358
+ - **Stability Fixes**: ToolManager thread-safety, Resource cleanup
359
+ - **DevEx**: New `install.sh` script, improved logging
360
+
361
+ ### v2.1.0
362
+ - **New Modules**: K8s, Azure, GCP, Prompt Injection
363
+ - **React2Shell**: CVE-2025-55182 detection
364
+ - **Auto-Discovery**: Improved target detection
365
+
366
+ ---
367
+
368
+ ## 🛠️ Troubleshooting
348
369
 
349
- - **Smart Auto-Module Loading** - Automatically detects target type
350
- - ⚡ **Token Optimization** - Lightweight mode & task scaling
351
- - 🛡️ **5 New Security Modules** - GraphQL, WebSocket, OAuth, WAF, Subdomain
352
- - 🎨 **New UI/Branding** - Fresh ExaAi logo with Cyan/Purple theme
353
- - 📊 **Improved Performance** - Reduced unnecessary LLM calls
370
+ ### 🔧 Troubleshooting
354
371
 
355
- ### v1.0.0
372
+ #### Problem: "LLM Connection Failed" or Model Not Found
373
+ Modern models (like `gemini-3-pro-preview`) require the latest version of `litellm` to be recognized correctly.
356
374
 
357
- - Multi-LLM Load Balancing
358
- - Enhanced Context Management
359
- - Specialized Agents
360
- - Advanced Prompts
361
- - Improved Reporting
375
+ **Solution: Update LiteLLM**
376
+ ```bash
377
+ pip install -U litellm
378
+ ```
379
+
380
+ **Linux/Debian Users (Externally Managed Environment):**
381
+ If you encounter permission errors or "externally-managed-environment", you may need to use a virtual environment (`venv`) or force a user install:
382
+
383
+ ```bash
384
+ # Option 1: Virtual Environment (Recommended for Servers)
385
+ python3 -m venv venv
386
+ source venv/bin/activate
387
+ pip install exaai-agent
388
+
389
+ # Option 2: Force User Install
390
+ pip install -U litellm --user --break-system-packages
391
+ ```
362
392
 
363
393
  ---
364
394
 
@@ -8,10 +8,12 @@ exaaiagnt/agents/base_agent.py,sha256=WzVJwjBM_gUo-P92zLHKq7C6wclDsVfAAO-bavLx5C
8
8
  exaaiagnt/agents/scan_modes.py,sha256=q2sSuTRCh_hOdVfikhHhOrEWl1GRCG9Uh6S6rALhLv0,8580
9
9
  exaaiagnt/agents/shared_memory.py,sha256=4Ps_kcUHIRVhpumlaF5ZGXmpoeAFi9JrJgEBK33qB84,10774
10
10
  exaaiagnt/agents/state.py,sha256=Tzjdegq3L4IS26XPlK9GQDcwqf6X-KKvih9_4LcXPYw,5881
11
+ exaaiagnt/dashboard/server.py,sha256=jmx6UwBm-Lpso5izf-W0pclqrTDoyBeF89B9l11eemY,3332
12
+ exaaiagnt/dashboard/templates/index.html,sha256=d5_Uwl2bNTm8Ynb_jlOoXftlrZ7F1KptzZBdxyDK3F0,11751
11
13
  exaaiagnt/interface/__init__.py,sha256=ww23sFOQhICEIrIo0MtwWv2qHW5qUprvPj8QVjv3SM0,44
12
14
  exaaiagnt/interface/assets/tui_styles.tcss,sha256=iwhx72f5bIiSg72168ifyR_Q0TKfL3Bf0lU6cyJw1Bg,12114
13
- exaaiagnt/interface/cli.py,sha256=MxcxxgFBj3DdYVRsQ2qFSzXhtrJVhU-7xyJk5b4vD-k,8451
14
- exaaiagnt/interface/main.py,sha256=Sn25MV1wmnSnmu2lB2onc7wXXdGzcdZ8zTPjlZJ2Ddw,19085
15
+ exaaiagnt/interface/cli.py,sha256=vTkeNELONfXwzQ_XgPhX3UcHVSbOBL_E6USnkRZtM74,9855
16
+ exaaiagnt/interface/main.py,sha256=PO62c4P26qT9v2nLWkfQSC_SWjaCncaxdZUT42U9Lu0,19483
15
17
  exaaiagnt/interface/tool_components/__init__.py,sha256=Dz5ci3VMzvhlPOwQ2x9Nd11cmFzx1OP7sdlpZPMTT4k,935
16
18
  exaaiagnt/interface/tool_components/agents_graph_renderer.py,sha256=eVFRqmJ-TxyxZ-hssLTweDAio4UvsZZgxo2dKky0N1U,4399
17
19
  exaaiagnt/interface/tool_components/base_renderer.py,sha256=P0zYeRnbkr2NYoE8KDQmj1TzrAGX6r7qLMb4Sw7AoTI,1905
@@ -28,22 +30,25 @@ exaaiagnt/interface/tool_components/terminal_renderer.py,sha256=-ORL2vBH5XImUZrI
28
30
  exaaiagnt/interface/tool_components/thinking_renderer.py,sha256=-MQLkKCgOJksrustULFf2jhAjJrP5bbfS2BQ6zgNKCc,927
29
31
  exaaiagnt/interface/tool_components/user_message_renderer.py,sha256=6gHJ1hG-pwcTsxLM7JuYZuaDu8cZ2MeOuUDF3LGy-4I,1432
30
32
  exaaiagnt/interface/tool_components/web_search_renderer.py,sha256=JnJa22ACIcRksfxxdenesUo8Th9cHSxo-fej9YcuYHs,911
31
- exaaiagnt/interface/tui.py,sha256=t3ZbYyiGfjEab0fd6Lk4hbpbWVKGxcLnifCKonTK61c,49777
33
+ exaaiagnt/interface/tui.py,sha256=bMuIJvrauCStAJkjvRWzDueLDraKnrHWtC5ZjyuDxOc,49970
32
34
  exaaiagnt/interface/utils.py,sha256=xp6eDOC8C0c3cjt791S_jBDs1B-xp_ydIb74QnMLEt8,20219
33
35
  exaaiagnt/llm/__init__.py,sha256=hUVixjSSIUtwIP2I5D_9e6Kdxhhunnajgxx_2DEYNww,1095
34
36
  exaaiagnt/llm/config.py,sha256=HQ0skwQxtHwiDLDWBCU1Fp4UoQ8tbrTNQw9s7JGVaiY,3303
35
37
  exaaiagnt/llm/fallback.py,sha256=oPS0PGRxEHnyyBgS4yP9zdwSf4JFJh4dYZ3g8OFwWEE,11413
36
- exaaiagnt/llm/llm.py,sha256=D9VnU73ffz7GhotGqQ5RZDufQ8xPKz8aouU23oW0kPY,18664
37
- exaaiagnt/llm/llm_traffic_controller.py,sha256=HkblT8OI3RcUdxT9kvyeNsUhowAGf1FZkhid_PdS998,12215
38
+ exaaiagnt/llm/llm.py,sha256=pMMRaHCnpD29iJR3ZTotqiONJ5JNI_Bc4Aem1ThZJl8,19858
39
+ exaaiagnt/llm/llm_traffic_controller.py,sha256=DIgJvjrT0MIOStb8g2wTAMoDXp9YLEBlFD5Bwt862K8,12304
38
40
  exaaiagnt/llm/memory_compressor.py,sha256=_At7e5QlDv2vrUDUJMEwm4CjNJ2uGYQsOBhiHiQvVr8,7054
39
41
  exaaiagnt/llm/output_processor.py,sha256=JC3TtzYj9DJhJRuKzz_VV3WIwAyYhUdZeY1N9c4SzVw,13568
40
42
  exaaiagnt/llm/request_queue.py,sha256=2H-jEcI1krY8U8oMoULu-1y6kEV84enI36QLUkTLKm0,9198
41
43
  exaaiagnt/llm/utils.py,sha256=0Z0r6qo9IfUSOJt5FJsq3X-veXrA8A09frc2VIy-aS4,2540
42
- exaaiagnt/prompts/README.md,sha256=Svgjx8pO1W0aVzC9z0Fxs88-NBA1whEqU8zrGBDqO0M,3813
44
+ exaaiagnt/prompts/README.md,sha256=PPeH0Up6_Ygk6zfYchcLVVZ-OqU5PhWIUwYx6KbhFaY,3975
43
45
  exaaiagnt/prompts/__init__.py,sha256=nUs1powNe_6sWmM5_KkAIxZj97t5IiMMgNrL39WwUjg,5042
44
- exaaiagnt/prompts/auto_loader.py,sha256=SNCewvdqfsIXydOcBNVcEE_x_w_j0Pl7ebOeOSNJ94E,12008
46
+ exaaiagnt/prompts/auto_loader.py,sha256=vVXBDLk8O08x3LglREvAReB2GqJqZKIsnhcwsQlKm4w,12994
45
47
  exaaiagnt/prompts/cloud/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
48
  exaaiagnt/prompts/cloud/aws_cloud_security.jinja,sha256=ObimikftsoqGzxhrvI6pQLVRQ4MmkJpjwexORS7P7uo,6768
49
+ exaaiagnt/prompts/cloud/azure_cloud_security.jinja,sha256=jKlQpWvPy6grYtU6S44cP1uKw5sLbCj6QmdUv9tu_PI,5225
50
+ exaaiagnt/prompts/cloud/gcp_cloud_security.jinja,sha256=n5GMgRufa0PBV8WbB6RfmmBAUeJZqEK_67b87MgjF7Y,6656
51
+ exaaiagnt/prompts/cloud/kubernetes_security.jinja,sha256=qmXHxMVg3wcj5aFzi176djJUhSp756obtk2Ff8PWGjo,4068
47
52
  exaaiagnt/prompts/coordination/root_agent.jinja,sha256=05VUZKnBX_7-FjEYilEq_OJG4u01_56bf4mzGNbFtJc,1996
48
53
  exaaiagnt/prompts/custom/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
49
54
  exaaiagnt/prompts/frameworks/fastapi.jinja,sha256=zXa08RDG9tVQu6MZetKCcOUPuDDKJJF1anTei7_2TZg,10200
@@ -74,6 +79,7 @@ exaaiagnt/prompts/vulnerabilities/open_redirect.jinja,sha256=Mbit385OO7fTSGRb0xF
74
79
  exaaiagnt/prompts/vulnerabilities/path_traversal_lfi_rfi.jinja,sha256=5Zfr424yM2LyFxt9A6q18RhbIjdq1MB6mpjWbG_FA7o,7916
75
80
  exaaiagnt/prompts/vulnerabilities/post_exploitation.jinja,sha256=YgGCIQu1FmrLq-KN930Pb-VqGWQV9BTbPIkcEFzkzac,8396
76
81
  exaaiagnt/prompts/vulnerabilities/privilege_escalation.jinja,sha256=XY0atQ4nEkGsmPiNoLtc0QwVTLV8r3w0ZvH4snmCgHE,6796
82
+ exaaiagnt/prompts/vulnerabilities/prompt_injection.jinja,sha256=7AsziV8IFMeQT1sUjFKppd76vlVfNSsiM9W523wew-E,9387
77
83
  exaaiagnt/prompts/vulnerabilities/prototype_pollution.jinja,sha256=g-I6ouqaZpxqoTa4MyGHaUKxwlM-gFrPo_F1T8r_ASI,6486
78
84
  exaaiagnt/prompts/vulnerabilities/race_conditions.jinja,sha256=ZHxdZc7v7yvhmUWJK3P3kIzOz3oaYRb2OJEzG1momcg,8372
79
85
  exaaiagnt/prompts/vulnerabilities/rce.jinja,sha256=tgmocWH3Y9FJ3fBeR9DTR7ViBcuH5salGis8vywJ2h8,8425
@@ -90,11 +96,11 @@ exaaiagnt/prompts/vulnerabilities/xxe.jinja,sha256=yyWl5i74YiFZIhQknMPWXLKL0C5gw
90
96
  exaaiagnt/runtime/__init__.py,sha256=MnuwXAMjvj2kQKJCOyzW-qQSpiipGzmESVWz436lqkQ,760
91
97
  exaaiagnt/runtime/docker_runtime.py,sha256=lb4cipUbCkwPw3_BxKyICFoIW8Su2zFs_sFW-r59Nfk,16185
92
98
  exaaiagnt/runtime/runtime.py,sha256=PRYByipRG9OhtIphIruGBSe4k-glVnYAXH68mikqt78,730
93
- exaaiagnt/runtime/tool_manager.py,sha256=CMUYlOC3Ez-9eqzz12tJO9tijdIBznFqCUwcT0hBnGA,14453
99
+ exaaiagnt/runtime/tool_manager.py,sha256=3PSUxTmGsFptNlKkZDnzXyyBA_AfbKvqhMPyRi6_fMU,14770
94
100
  exaaiagnt/runtime/tool_server.py,sha256=e23TJYL5w32gMqLS9UJ0xw3XZ4lM38ETBvHVHKk3APU,6835
95
101
  exaaiagnt/telemetry/__init__.py,sha256=8QLHMvrVNLlGKezWTf3mTSmTOLIvDS5xVciry1KVS1Y,130
96
- exaaiagnt/telemetry/tracer.py,sha256=DZuQ-xGdPWB2FKEn_rRPxP1RO2_acXQRkHzuhApAI88,12582
97
- exaaiagnt/tools/__init__.py,sha256=tFPqL3VKFumF1LgYMhvaecwTQ9b7vHxk0hRArPp3z2U,3402
102
+ exaaiagnt/telemetry/tracer.py,sha256=W7jWmsy41LZG_rvRCFRxa6Pxt6tAx8i5O3rW2dM6QUA,13299
103
+ exaaiagnt/tools/__init__.py,sha256=1Z4EECFThur9Bn_EkqVHJYx9Z3pM1cdh6qXc3rTcyPA,4000
98
104
  exaaiagnt/tools/agents_graph/__init__.py,sha256=FLJ2kGxXICY2pRKrC0sgIc3w3KhZo7VID7hbwYcgBfM,278
99
105
  exaaiagnt/tools/agents_graph/agents_graph_actions.py,sha256=ujBj3R3MpOmIVsN4T3nekVhreu60xA2EEg9rYXCdz2c,21103
100
106
  exaaiagnt/tools/agents_graph/agents_graph_actions_schema.xml,sha256=fczqDpNw2m58p2O_G0amBZso--EjEGZuK829lB-cXdE,12617
@@ -104,16 +110,22 @@ exaaiagnt/tools/browser/browser_actions.py,sha256=6p3drOznDLPVnqSo3CnJjq4qXXSvCh
104
110
  exaaiagnt/tools/browser/browser_actions_schema.xml,sha256=zZQD8sZWsNnxxnlY3QYDrfKHFu0x6i1vtfSOlIGyiho,9573
105
111
  exaaiagnt/tools/browser/browser_instance.py,sha256=vgb-dJP20SLaBOhFExn-uwfjdISBrHJpG7ewfiKQkYU,18605
106
112
  exaaiagnt/tools/browser/tab_manager.py,sha256=SMkDFOgEr3ADK2rP5Ko2uK-A24-8p0VsbjoxEj5eU-Y,13011
107
- exaaiagnt/tools/executor.py,sha256=-H-OuXI5UXGydqG9xH1lkmEKq--vTJMQiGbr5psbj1s,10854
113
+ exaaiagnt/tools/executor.py,sha256=nglkwrW_Tt0ZAkn9CQUheoOv6Ac5ZaKoRmwCGWY0uIU,11465
108
114
  exaaiagnt/tools/file_edit/__init__.py,sha256=8f6VlEoGP627hGtcdLkr63vdrTmdb8uyPIqB0qVgZd8,141
109
115
  exaaiagnt/tools/file_edit/file_edit_actions.py,sha256=w-rEB9MphijtXJUyypttQ4DLU4y9rwHd7Zpl21LTTis,3955
110
116
  exaaiagnt/tools/file_edit/file_edit_actions_schema.xml,sha256=tt0_QgSjOtTEy8ordsXUcEiVTePiybgn4aisZJ_qnbc,5477
111
117
  exaaiagnt/tools/finish/__init__.py,sha256=QIMaHYusly8YaFR3zjYsy_CFawwgtTZvOU7gsEumFrw,68
112
118
  exaaiagnt/tools/finish/finish_actions.py,sha256=ZLyOuYMjdTPHN9_6sQxyHwp3-BVSusk5dM2WHUn3WMI,5714
113
119
  exaaiagnt/tools/finish/finish_actions_schema.xml,sha256=CS6Vq3ByyNxv2spRWS4oJcmUzWQRB7jvUAOS8aiWd8o,2294
120
+ exaaiagnt/tools/k8s_scanner/__init__.py,sha256=MIo_Hl4p7Zzea9KSR_wVnxnlyyrB9eS8g3DlZxwSsHk,557
121
+ exaaiagnt/tools/k8s_scanner/k8s_actions.py,sha256=DdwnXm0Z86guNsAtuxsNhLeexIFk1y_Xza_GvACd2zM,13477
122
+ exaaiagnt/tools/k8s_scanner/k8s_actions_schema.xml,sha256=s-Qnq8FX6zjT6qIRHG81dq9zSToj6BbnntLGQ-vWzhM,1272
114
123
  exaaiagnt/tools/notes/__init__.py,sha256=DUpkZUWN21tb9AXCWfJLrKrgLz9YEBVU8KQy1J6cyxU,189
115
124
  exaaiagnt/tools/notes/notes_actions.py,sha256=8ewd1kCxZO_ujKP2oXuU03r9p8EZEYgoO7i_6GWw_VA,5775
116
125
  exaaiagnt/tools/notes/notes_actions_schema.xml,sha256=nzirWDyzbPRxaG3jdSjmSCjfY-ggDy1kH7oxAuj-osw,6264
126
+ exaaiagnt/tools/prompt_injection/__init__.py,sha256=YjzfqLYKdOuEeV8WgE_b9swnP2uhYtOlPbeRplKOTzc,645
127
+ exaaiagnt/tools/prompt_injection/prompt_injection_actions.py,sha256=yNJv7ESHBMvzFiNZGI8Jc8m0GwG73Z5yIngYEmZTOic,27903
128
+ exaaiagnt/tools/prompt_injection/prompt_injection_actions_schema.xml,sha256=wZHYpaS35tOEuzY8j1-4JkkLgDWvFhJwm7MzlRGpfyg,1381
117
129
  exaaiagnt/tools/proxy/__init__.py,sha256=K3BFmT6QWw9heB7l7DnmI-Yj-DOI3BAow6g0GLWsA0c,329
118
130
  exaaiagnt/tools/proxy/proxy_actions.py,sha256=HyfI6iUVkRSnzLR_xNRKWhr4roDEAatGyYTq4wij2Js,2549
119
131
  exaaiagnt/tools/proxy/proxy_actions_schema.xml,sha256=d87SUKD2J16KQCCFpI5w2y-Ax1NgwOuGO3crr1bFPDw,11567
@@ -121,14 +133,14 @@ exaaiagnt/tools/proxy/proxy_manager.py,sha256=rmy8c_7jcYl9WeeA3O2lcZBnN7hESpTYxo
121
133
  exaaiagnt/tools/python/__init__.py,sha256=l5mFWKbtis61S8lOQY-gFn-vIlc13lu1K-pqqRywOCk,72
122
134
  exaaiagnt/tools/python/python_actions.py,sha256=ggLFFLW7cQamY1fvgUxzz9beOy_deY1zdouK_K8iF50,1436
123
135
  exaaiagnt/tools/python/python_actions_schema.xml,sha256=XcIUjz5uEoI7J3VFcby0O-0ovm9r9cIoADfpqDGJXlU,7122
124
- exaaiagnt/tools/python/python_instance.py,sha256=G0wh9zwek-dM8DiKn4bR9qH5AYqDXeSUPSPkf4RtaYw,5551
136
+ exaaiagnt/tools/python/python_instance.py,sha256=pXF8MFVjxNeIUt6h_f2Oe5gjFEYJ-NM5Lqc6A3PUi40,6246
125
137
  exaaiagnt/tools/python/python_manager.py,sha256=C_k8C8uQ6ESpAgzhbf3km9jeFyI52SGd2m36mD1ErhM,4235
126
138
  exaaiagnt/tools/registry.py,sha256=iBRwtiWLQr3fo1vSAOehWbIlr6cqnNPLB1dluXtsf8s,6029
127
139
  exaaiagnt/tools/reporting/__init__.py,sha256=_cYxb3OP0vZtCwO_ExLBjhAn1ECaG-SH1Z4wfGDyT1Y,110
128
- exaaiagnt/tools/reporting/reporting_actions.py,sha256=aVEwfG5GgJ68bFJOicO_YD2yp5wCimxlnZzpXX3TJcQ,2200
140
+ exaaiagnt/tools/reporting/reporting_actions.py,sha256=CYAXz5ee_eN-zFxBdhJ-QsmtCECulnf9m44y2SrX4kk,3107
129
141
  exaaiagnt/tools/reporting/reporting_actions_schema.xml,sha256=y_g0iuyBuCh79fvA0ri8fOPlXY7uUd-P-mdzXLUyIJg,1629
130
- exaaiagnt/tools/response_analyzer.py,sha256=ZBOGwGkH2VM96UH4ZrYhPYI8S_YZp0SG8EDThO7bAX0,10566
131
- exaaiagnt/tools/smart_fuzzer.py,sha256=FQ3RQ8IYFRTEAsKzEtfephCpHbdmDRMm068AsEQ2B-k,12286
142
+ exaaiagnt/tools/response_analyzer.py,sha256=0B8LZ3pvBImH40t8QqCtLdxwc28Chq-2C8I23zi-XJM,10647
143
+ exaaiagnt/tools/smart_fuzzer.py,sha256=cN9TgJcLz3MzDuBIP8EVtEdoJL67LcrFBc2zo9j53cE,12367
132
144
  exaaiagnt/tools/terminal/__init__.py,sha256=xvflcrbLQ31o_K3cWFsIhTm7gxY5JF0nVnhOIadwFV0,80
133
145
  exaaiagnt/tools/terminal/terminal_actions.py,sha256=5z3OTF0YwZL0n_CVsx1yLmbSx7oUQg-xD0Wv8IXsIlw,892
134
146
  exaaiagnt/tools/terminal/terminal_actions_schema.xml,sha256=L7dzjvKNZpJA0qDGp1gCBuwXiY4mtjOq7T2tNDmUPA4,7257
@@ -138,13 +150,13 @@ exaaiagnt/tools/thinking/__init__.py,sha256=-v4fG4fyFkqsTSWspDtCT6IRlyRM8zeUwEM-
138
150
  exaaiagnt/tools/thinking/thinking_actions.py,sha256=Ynw1gBN4Z8iXGll0v9kObhkjQzc8-dEcHTWKeyFutAw,568
139
151
  exaaiagnt/tools/thinking/thinking_actions_schema.xml,sha256=otD4dOhQx4uyudLnjA_HIP6EmUS5NvKG4l3CVFrg8go,2756
140
152
  exaaiagnt/tools/tool_prompts.py,sha256=eQL7B8H8mo6d6mvtN_X9rmSfjwgz9Cuzfg7C7WH6TnU,5751
141
- exaaiagnt/tools/vuln_validator.py,sha256=jgfPOVogjfMSVaorlzXTUA56N1RgYrpF1QshKeHQBn8,13944
153
+ exaaiagnt/tools/vuln_validator.py,sha256=jViG2-3pVBwI3VXe5JsgCFsDBNk9nmT_s2vEe7cZjmA,14025
142
154
  exaaiagnt/tools/waf_bypass.py,sha256=71oPWnDHjn2EHi6I1SluZCKfqfXkA5j61oIkL5kNoSw,12047
143
155
  exaaiagnt/tools/web_search/__init__.py,sha256=m5PCHXqeNVraLRLNIbh54Z2N4Y_75d-ftqwyq3dbCd0,70
144
- exaaiagnt/tools/web_search/web_search_actions.py,sha256=jmlN2uIq8lRbhRnyaMQkC-44jhpfkLQZ_byYNlNNlOY,3111
156
+ exaaiagnt/tools/web_search/web_search_actions.py,sha256=k9zjzdqTVsNdh0pFtntIfwO77_ThQIedXSaUhJxPs2U,3295
145
157
  exaaiagnt/tools/web_search/web_search_actions_schema.xml,sha256=Ihc3Gv4LaPI_MzBbwZOt3y4pwg9xmtl8KfPNvFihEP4,4805
146
- exaai_agent-2.0.9.dist-info/METADATA,sha256=LCoSJoucmT-AzVO6DLNcH8PNZEZLP6k45QJaMNO-6fc,11959
147
- exaai_agent-2.0.9.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
148
- exaai_agent-2.0.9.dist-info/entry_points.txt,sha256=iLSTRDSjN8Zyc2Wo6WXmr4MtyEWkdqtZ1j_Hx73MiUs,137
149
- exaai_agent-2.0.9.dist-info/licenses/LICENSE,sha256=RV6IGl0sWdfbbtJmjPr1w_qwGyGt2jv02PXsAzN_kNs,11460
150
- exaai_agent-2.0.9.dist-info/RECORD,,
158
+ exaai_agent-2.2.0.dist-info/METADATA,sha256=92DfPaFHPXBZkhl09w4pWJ0CE_mKFs4mIOh3TMd3bZ8,13421
159
+ exaai_agent-2.2.0.dist-info/WHEEL,sha256=kJCRJT_g0adfAJzTx2GUMmS80rTJIVHRCfG0DQgLq3o,88
160
+ exaai_agent-2.2.0.dist-info/entry_points.txt,sha256=iLSTRDSjN8Zyc2Wo6WXmr4MtyEWkdqtZ1j_Hx73MiUs,137
161
+ exaai_agent-2.2.0.dist-info/licenses/LICENSE,sha256=RV6IGl0sWdfbbtJmjPr1w_qwGyGt2jv02PXsAzN_kNs,11460
162
+ exaai_agent-2.2.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.2.1
2
+ Generator: poetry-core 2.3.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -0,0 +1,99 @@
1
+ from fastapi import FastAPI, WebSocket, WebSocketDisconnect
2
+ from fastapi.staticfiles import StaticFiles
3
+ from fastapi.responses import HTMLResponse
4
+ import uvicorn
5
+ import json
6
+ import asyncio
7
+ import logging
8
+ from typing import List, Dict, Any
9
+ import os
10
+
11
+ from exaaiagnt.telemetry.tracer import get_global_tracer
12
+
13
+ app = FastAPI(title="ExaAi Live Dashboard")
14
+
15
+ # Serve static files
16
+ static_dir = os.path.join(os.path.dirname(__file__), "static")
17
+ app.mount("/static", StaticFiles(directory=static_dir), name="static")
18
+
19
+ class ConnectionManager:
20
+ def __init__(self):
21
+ self.active_connections: List[WebSocket] = []
22
+
23
+ async def connect(self, websocket: WebSocket):
24
+ await websocket.accept()
25
+ self.active_connections.append(websocket)
26
+
27
+ def disconnect(self, websocket: WebSocket):
28
+ self.active_connections.remove(websocket)
29
+
30
+ async def broadcast(self, message: str):
31
+ for connection in self.active_connections:
32
+ try:
33
+ await connection.send_text(message)
34
+ except Exception:
35
+ pass
36
+
37
+ manager = ConnectionManager()
38
+
39
+ @app.get("/")
40
+ async def get_dashboard():
41
+ html_path = os.path.join(os.path.dirname(__file__), "templates", "index.html")
42
+ with open(html_path, "r") as f:
43
+ return HTMLResponse(content=f.read())
44
+
45
+ @app.get("/api/stats")
46
+ async def get_stats():
47
+ tracer = get_global_tracer()
48
+ if not tracer:
49
+ return {"status": "Waiting for agent..."}
50
+
51
+ return {
52
+ "agents_count": len(tracer.agents),
53
+ "vulnerabilities": len(tracer.vulnerability_reports),
54
+ "tool_calls": len(tracer.tool_executions),
55
+ "start_time": tracer.start_time,
56
+ "run_name": tracer.run_name
57
+ }
58
+
59
+ @app.get("/api/vulnerabilities")
60
+ async def get_vulns():
61
+ tracer = get_global_tracer()
62
+ if not tracer:
63
+ return []
64
+ return tracer.vulnerability_reports
65
+
66
+ @app.websocket("/ws")
67
+ async def websocket_endpoint(websocket: WebSocket):
68
+ await manager.connect(websocket)
69
+ try:
70
+ while True:
71
+ # Send updates every second
72
+ tracer = get_global_tracer()
73
+ if tracer:
74
+ data = {
75
+ "agents": tracer.agents,
76
+ "stats": {
77
+ "active": sum(1 for a in tracer.agents.values() if a.get("status") == "running"),
78
+ "completed": sum(1 for a in tracer.agents.values() if a.get("status") == "completed"),
79
+ "failed": sum(1 for a in tracer.agents.values() if a.get("status") == "failed"),
80
+ },
81
+ "recent_logs": tracer.chat_messages[-10:] if tracer.chat_messages else []
82
+ }
83
+ await websocket.send_json(data)
84
+ await asyncio.sleep(1)
85
+ except WebSocketDisconnect:
86
+ manager.disconnect(websocket)
87
+ except Exception as e:
88
+ logging.error(f"WebSocket error: {e}")
89
+ manager.disconnect(websocket)
90
+
91
+ def start_dashboard(host="0.0.0.0", port=8000):
92
+ """Start the dashboard server in a background thread or process."""
93
+ config = uvicorn.Config(app, host=host, port=port, log_level="error")
94
+ server = uvicorn.Server(config)
95
+ # We'll run this in a thread from the main agent
96
+ import threading
97
+ t = threading.Thread(target=server.run, daemon=True)
98
+ t.start()
99
+ return t
@@ -0,0 +1,232 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>ExaAi Mission Control</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
9
+ <style>
10
+ body { background-color: #0f172a; color: #e2e8f0; font-family: 'Courier New', Courier, monospace; }
11
+ .neon-text { text-shadow: 0 0 5px #3b82f6, 0 0 10px #3b82f6; }
12
+ .neon-border { box-shadow: 0 0 5px #3b82f6; border-color: #3b82f6; }
13
+ .agent-card { transition: all 0.3s ease; }
14
+ .agent-card:hover { transform: translateY(-2px); box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); }
15
+ .vuln-critical { border-left: 4px solid #ef4444; background: rgba(239, 68, 68, 0.1); }
16
+ .vuln-high { border-left: 4px solid #f97316; background: rgba(249, 115, 22, 0.1); }
17
+ .vuln-medium { border-left: 4px solid #eab308; background: rgba(234, 179, 8, 0.1); }
18
+ ::-webkit-scrollbar { width: 8px; }
19
+ ::-webkit-scrollbar-track { background: #1e293b; }
20
+ ::-webkit-scrollbar-thumb { background: #475569; border-radius: 4px; }
21
+ ::-webkit-scrollbar-thumb:hover { background: #64748b; }
22
+ </style>
23
+ </head>
24
+ <body class="h-screen flex flex-col overflow-hidden">
25
+ <!-- Header -->
26
+ <header class="bg-slate-900 border-b border-slate-700 p-4 flex justify-between items-center shadow-lg z-10">
27
+ <div class="flex items-center gap-3">
28
+ <div class="w-3 h-3 rounded-full bg-green-500 animate-pulse"></div>
29
+ <h1 class="text-2xl font-bold tracking-wider text-blue-400 neon-text">EXAAI <span class="text-white">MISSION CONTROL</span></h1>
30
+ </div>
31
+ <div class="flex gap-6 text-sm">
32
+ <div class="flex flex-col items-end">
33
+ <span class="text-slate-400">STATUS</span>
34
+ <span class="text-green-400 font-bold">ONLINE</span>
35
+ </div>
36
+ <div class="flex flex-col items-end">
37
+ <span class="text-slate-400">AGENTS</span>
38
+ <span id="total-agents" class="text-blue-400 font-bold">0</span>
39
+ </div>
40
+ <div class="flex flex-col items-end">
41
+ <span class="text-slate-400">VULNERABILITIES</span>
42
+ <span id="total-vulns" class="text-red-500 font-bold neon-text">0</span>
43
+ </div>
44
+ </div>
45
+ </header>
46
+
47
+ <!-- Main Content -->
48
+ <main class="flex-1 flex overflow-hidden">
49
+ <!-- Sidebar: Agent Tree -->
50
+ <aside class="w-1/4 bg-slate-900 border-r border-slate-700 flex flex-col">
51
+ <div class="p-3 border-b border-slate-700 bg-slate-800">
52
+ <h2 class="font-bold text-slate-300 flex items-center gap-2">
53
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10"></path></svg>
54
+ Active Operations
55
+ </h2>
56
+ </div>
57
+ <div id="agent-list" class="flex-1 overflow-y-auto p-3 space-y-2">
58
+ <!-- Agents injected here -->
59
+ </div>
60
+ </aside>
61
+
62
+ <!-- Center: Live Feed & Stats -->
63
+ <section class="flex-1 flex flex-col bg-slate-900/50 relative">
64
+ <!-- Matrix Rain Background Effect (Optional/Subtle) -->
65
+ <div class="absolute inset-0 pointer-events-none opacity-5 bg-[url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0IiBoZWlnaHQ9IjQiPgo8cmVjdCB3aWR0aD0iNCIgaGVpZ2h0PSI0IiBmaWxsPSIjMWUyOTNiIi8+CjxyZWN0IHdpZHRoPSIxIiBoZWlnaHQ9IjEiIGZpbGw9IiMzMzQxNTUiLz4KPC9zdmc+')]"></div>
66
+
67
+ <div class="h-1/2 border-b border-slate-700 flex">
68
+ <!-- Live Terminal Log -->
69
+ <div class="w-2/3 border-r border-slate-700 flex flex-col">
70
+ <div class="p-2 bg-slate-800 border-b border-slate-700 flex justify-between">
71
+ <span class="text-xs font-mono text-slate-400">>_ SYSTEM LOGS</span>
72
+ <span class="text-xs text-green-500">● LIVE</span>
73
+ </div>
74
+ <div id="console-logs" class="flex-1 overflow-y-auto p-4 font-mono text-xs text-slate-300 space-y-1 bg-black/40">
75
+ <!-- Logs injected here -->
76
+ </div>
77
+ </div>
78
+
79
+ <!-- Quick Stats Chart -->
80
+ <div class="w-1/3 p-4 bg-slate-800/30 flex flex-col items-center justify-center">
81
+ <canvas id="statusChart"></canvas>
82
+ </div>
83
+ </div>
84
+
85
+ <!-- Vulnerabilities Panel -->
86
+ <div class="h-1/2 flex flex-col bg-slate-900">
87
+ <div class="p-3 border-b border-slate-700 bg-slate-800 flex justify-between items-center">
88
+ <h2 class="font-bold text-red-400 flex items-center gap-2">
89
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path></svg>
90
+ Detected Vulnerabilities
91
+ </h2>
92
+ <span class="text-xs text-slate-500">Auto-refreshing...</span>
93
+ </div>
94
+ <div id="vuln-list" class="flex-1 overflow-y-auto p-4 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
95
+ <!-- Vulns injected here -->
96
+ </div>
97
+ </div>
98
+ </section>
99
+ </main>
100
+
101
+ <script>
102
+ const wsProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
103
+ const socket = new WebSocket(`${wsProtocol}//${window.location.host}/ws`);
104
+
105
+ // Chart setup
106
+ const ctx = document.getElementById('statusChart').getContext('2d');
107
+ const statusChart = new Chart(ctx, {
108
+ type: 'doughnut',
109
+ data: {
110
+ labels: ['Active', 'Completed', 'Failed'],
111
+ datasets: [{
112
+ data: [0, 0, 0],
113
+ backgroundColor: ['#3b82f6', '#22c55e', '#ef4444'],
114
+ borderWidth: 0
115
+ }]
116
+ },
117
+ options: {
118
+ responsive: true,
119
+ plugins: {
120
+ legend: { position: 'bottom', labels: { color: '#94a3b8' } }
121
+ },
122
+ cutout: '70%'
123
+ }
124
+ });
125
+
126
+ socket.onmessage = function(event) {
127
+ const data = JSON.parse(event.data);
128
+ updateDashboard(data);
129
+ };
130
+
131
+ function updateDashboard(data) {
132
+ // Update Headers
133
+ document.getElementById('total-agents').textContent = Object.keys(data.agents).length;
134
+
135
+ // Update Agent List
136
+ const agentList = document.getElementById('agent-list');
137
+ agentList.innerHTML = '';
138
+
139
+ Object.values(data.agents).forEach(agent => {
140
+ const div = document.createElement('div');
141
+ div.className = `agent-card p-3 rounded bg-slate-800 border border-slate-700 ${agent.status === 'running' ? 'border-l-4 border-l-blue-500' : ''}`;
142
+ div.innerHTML = `
143
+ <div class="flex justify-between items-start mb-1">
144
+ <span class="font-bold text-xs text-slate-200 truncate" title="${agent.name}">${agent.name}</span>
145
+ <span class="text-[10px] px-1.5 py-0.5 rounded ${getStatusColor(agent.status)}">${agent.status}</span>
146
+ </div>
147
+ <div class="text-[10px] text-slate-500 truncate">${agent.id.substring(0, 8)}...</div>
148
+ <div class="text-[11px] text-slate-400 mt-1 line-clamp-2">${agent.task || 'No task description'}</div>
149
+ `;
150
+ agentList.appendChild(div);
151
+ });
152
+
153
+ // Update Logs
154
+ const logContainer = document.getElementById('console-logs');
155
+ logContainer.innerHTML = '';
156
+ data.recent_logs.forEach(log => {
157
+ const div = document.createElement('div');
158
+ const time = new Date(log.timestamp * 1000).toLocaleTimeString();
159
+ const color = log.role === 'assistant' ? 'text-blue-400' : 'text-slate-400';
160
+ div.innerHTML = `<span class="text-slate-600">[${time}]</span> <span class="${color}">${log.role.toUpperCase()}:</span> <span class="text-slate-300">${escapeHtml(log.content.substring(0, 150))}...</span>`;
161
+ logContainer.appendChild(div);
162
+ });
163
+
164
+ // Update Chart
165
+ statusChart.data.datasets[0].data = [
166
+ data.stats.active,
167
+ data.stats.completed,
168
+ data.stats.failed
169
+ ];
170
+ statusChart.update();
171
+
172
+ // Update Vulns (Fetching separately or from WS if included)
173
+ fetchVulns();
174
+ }
175
+
176
+ async function fetchVulns() {
177
+ try {
178
+ const response = await fetch('/api/vulnerabilities');
179
+ const vulns = await response.json();
180
+ document.getElementById('total-vulns').textContent = vulns.length;
181
+
182
+ const container = document.getElementById('vuln-list');
183
+ container.innerHTML = '';
184
+
185
+ if (vulns.length === 0) {
186
+ container.innerHTML = '<div class="col-span-full text-center text-slate-500 py-10">No vulnerabilities detected... yet.</div>';
187
+ return;
188
+ }
189
+
190
+ vulns.forEach(v => {
191
+ const div = document.createElement('div');
192
+ const severityClass = `vuln-${v.severity.toLowerCase()}`;
193
+ div.className = `p-4 rounded bg-slate-800 border border-slate-700 ${severityClass}`;
194
+ div.innerHTML = `
195
+ <div class="flex justify-between items-center mb-2">
196
+ <h3 class="font-bold text-sm text-white">${v.title}</h3>
197
+ <span class="text-[10px] font-bold uppercase tracking-wider px-2 py-1 bg-black/30 rounded text-white">${v.severity}</span>
198
+ </div>
199
+ <p class="text-xs text-slate-400 line-clamp-3 mb-2">${v.content}</p>
200
+ <div class="text-[10px] text-slate-500">ID: ${v.report_id}</div>
201
+ `;
202
+ container.appendChild(div);
203
+ });
204
+ } catch (e) {
205
+ console.error("Failed to fetch vulns", e);
206
+ }
207
+ }
208
+
209
+ function getStatusColor(status) {
210
+ switch(status) {
211
+ case 'running': return 'bg-blue-900 text-blue-300';
212
+ case 'completed': return 'bg-green-900 text-green-300';
213
+ case 'failed': return 'bg-red-900 text-red-300';
214
+ default: return 'bg-slate-700 text-slate-300';
215
+ }
216
+ }
217
+
218
+ function escapeHtml(text) {
219
+ if (!text) return "";
220
+ return text
221
+ .replace(/&/g, "&amp;")
222
+ .replace(/</g, "&lt;")
223
+ .replace(/>/g, "&gt;")
224
+ .replace(/"/g, "&quot;")
225
+ .replace(/'/g, "&#039;");
226
+ }
227
+
228
+ // Initial load
229
+ fetchVulns();
230
+ </script>
231
+ </body>
232
+ </html>