daqc commited on
Commit
eea2f4b
·
1 Parent(s): 2e82565

Add new configuration and tools

Browse files
.env.template ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # API Keys and Endpoints
2
+ NVD_API_KEY=""
3
+
4
+ # Model Configuration
5
+ MODEL_ID="Qwen/Qwen2.5-Coder-32B-Instruct"
6
+ MAX_TOKENS=2096
7
+ TEMPERATURE=0.3
8
+
9
+ # Application Configuration
10
+ ENV="development"
11
+ DEBUG=true
__pycache__/Gradio_UI.cpython-310.pyc ADDED
Binary file (6.81 kB). View file
 
agent.json CHANGED
@@ -1,9 +1,43 @@
1
  {
 
 
 
 
 
 
 
 
 
 
 
 
2
  "tools": [
3
- "web_search",
4
- "visit_webpage",
5
- "final_answer"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  ],
 
 
 
 
 
7
  "model": {
8
  "class": "HfApiModel",
9
  "data": {
 
1
  {
2
+ "agent_config": {
3
+ "name": "VulnerabilityIntelligenceAgent",
4
+ "description": "Agente especializado en análisis de vulnerabilidades y amenazas de ciberseguridad",
5
+ "model": {
6
+ "type": "HfApiModel",
7
+ "model_id": "Qwen/Qwen2.5-Coder-32B-Instruct",
8
+ "max_tokens": 2096,
9
+ "temperature": 0.3
10
+ },
11
+ "max_steps": 10,
12
+ "verbosity_level": 2
13
+ },
14
  "tools": [
15
+ {
16
+ "name": "final_answer",
17
+ "type": "FinalAnswerTool",
18
+ "description": "Proporciona una respuesta final al problema"
19
+ },
20
+ {
21
+ "name": "web_search",
22
+ "type": "DuckDuckGoSearchTool",
23
+ "description": "Realiza búsquedas web usando DuckDuckGo"
24
+ },
25
+ {
26
+ "name": "visit_webpage",
27
+ "type": "VisitWebpageTool",
28
+ "description": "Visita y extrae contenido de páginas web"
29
+ },
30
+ {
31
+ "name": "vuln_search",
32
+ "type": "VulnerabilitySearchTool",
33
+ "description": "Busca información sobre vulnerabilidades en múltiples fuentes"
34
+ }
35
  ],
36
+ "prompt_templates": {
37
+ "path": "prompts.yaml",
38
+ "default_system_prompt": "system_prompt",
39
+ "default_user_prompt": "user_prompt"
40
+ },
41
  "model": {
42
  "class": "HfApiModel",
43
  "data": {
app.py CHANGED
@@ -1,113 +1,115 @@
1
- #!/usr/bin/env python3
2
- """
3
- Gradio UI for the Vulnerability Intelligence Agent (VIA).
4
- This provides a chat interface to interact with the VIA using natural language.
5
- """
6
  import os
7
- import sys
8
- import argparse
9
- import logging
10
- from typing import Dict, List, Any, Optional
11
-
12
  import gradio as gr
13
- from smolagents import CodeAgent, HfApiModel, GradioUI
14
- from smolagents.tools import load_tool, tool
15
-
16
- # Asegurarse de que el directorio actual esté en sys.path para que los imports funcionen
17
- sys.path.append(os.path.dirname(os.path.abspath(__file__)))
 
18
 
19
- from agents.coordinator_agent import search_vulnerabilities_for_software, get_vulnerability_details
20
- from tools import utils
21
 
22
- # Configure logging
23
- logging.basicConfig(
24
- level=logging.INFO,
25
- format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
26
- )
27
- logger = utils.setup_logger("gradio_ui")
28
 
29
- # Cargar las herramientas básicas usando las que ya existen en smolagents
30
- final_answer = load_tool("smolagents/final_answer", trust_remote_code=True)
31
-
32
- def get_agent_description():
33
- """
34
- Get the description for the agent.
35
- """
36
- return """
37
- # 🔐 Vulnerability Intelligence Agent (VIA)
38
-
39
- I am an intelligent agent designed to help you find vulnerabilities in software and systems.
40
-
41
- ## What I can do:
42
- - Search for known vulnerabilities in software by name and version
43
- - Provide detailed information about specific vulnerabilities (CVE, CWE, etc.)
44
- - Generate reports about vulnerabilities
45
-
46
- ## How to use me:
47
- - Ask about vulnerabilities in specific software, e.g., "Find vulnerabilities in OpenSSL 1.1.1k"
48
- - Ask about a specific vulnerability, e.g., "Tell me about CVE-2021-44228"
49
- - Use natural language to describe what you're looking for
50
-
51
- ## Examples:
52
- - "What vulnerabilities exist in Apache 2.4.54?"
53
- - "Are there any critical vulnerabilities in log4j 2.14.1?"
54
- - "Give me details about CVE-2021-44228"
55
- - "What security issues should I be aware of in OpenSSL 1.1.1k?"
56
- """
57
 
58
- def create_parser():
59
- """Create command line argument parser."""
60
- parser = argparse.ArgumentParser(description="Vulnerability Intelligence Agent (VIA) UI")
61
- parser.add_argument("--port", type=int, default=7860, help="Port to run the Gradio app on")
62
- parser.add_argument("--host", type=str, default="127.0.0.1", help="Host to run the Gradio app on")
63
- parser.add_argument("--model", type=str, default="Qwen/Qwen2.5-Coder-32B-Instruct",
64
- help="HuggingFace model ID to use")
65
- parser.add_argument("--share", action="store_true", help="Create a public link")
66
- parser.add_argument("--verbose", action="store_true", help="Enable verbose logging")
67
-
68
- return parser
69
 
70
- def main():
71
- """Main entry point for the Gradio UI."""
72
- args = create_parser().parse_args()
 
73
 
74
- # Configure logging level
75
- log_level = logging.DEBUG if args.verbose else logging.INFO
76
- logging.basicConfig(level=log_level)
77
-
78
- # Initialize the model
79
  model = HfApiModel(
80
- max_tokens=2096,
81
- temperature=0.5,
82
- model_id=args.model,
83
- custom_role_conversions=None,
84
  )
85
 
86
- # Initialize the agent con las herramientas ya existentes y las que hemos creado
 
 
 
87
  agent = CodeAgent(
88
  model=model,
89
- tools=[search_vulnerabilities_for_software, get_vulnerability_details, final_answer],
90
- max_steps=10,
91
- verbosity_level=2 if args.verbose else 1,
92
  )
93
 
94
- # Create Gradio UI
95
- ui = GradioUI(agent)
 
 
 
96
 
97
- # Launch the UI
98
- ui.launch(
99
- share=args.share,
100
- server_name=args.host,
101
- server_port=args.port,
102
- show_api=False,
103
- favicon_path=None,
104
- allowed_paths=[],
105
- app_kwargs={
106
- "title": "🔐 Vulnerability Intelligence Agent (VIA)",
107
- "description": get_agent_description(),
108
- "theme": gr.themes.Base(),
109
- },
110
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
 
112
  if __name__ == "__main__":
113
- main()
 
 
 
 
 
 
 
1
  import os
2
+ import json
3
+ import yaml
4
+ from dotenv import load_dotenv
 
 
5
  import gradio as gr
6
+ from smolagents import CodeAgent
7
+ from smolagents.models import HfApiModel
8
+ from tools.final_answer import FinalAnswerTool
9
+ from tools.web_search import DuckDuckGoSearchTool
10
+ from tools.visit_webpage import VisitWebpageTool
11
+ from tools.vuln_search import VulnerabilitySearchTool
12
 
13
+ # Load environment variables
14
+ load_dotenv()
15
 
16
+ def load_agent_config():
17
+ """Load agent configuration from agent.json"""
18
+ with open('agent.json', 'r') as f:
19
+ return json.load(f)
 
 
20
 
21
+ def load_prompts():
22
+ """Load prompt templates from prompts.yaml"""
23
+ with open('prompts.yaml', 'r') as f:
24
+ return yaml.safe_load(f)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
+ def initialize_tools():
27
+ """Initialize agent tools"""
28
+ tools = {
29
+ 'final_answer': FinalAnswerTool(),
30
+ 'web_search': DuckDuckGoSearchTool(),
31
+ 'visit_webpage': VisitWebpageTool(),
32
+ 'vuln_search': VulnerabilitySearchTool()
33
+ }
34
+ return tools
 
 
35
 
36
+ def create_agent():
37
+ """Create and configure the vulnerability agent"""
38
+ config = load_agent_config()
39
+ prompts = load_prompts()
40
 
41
+ # Configure model
42
+ model_config = config['agent_config']['model']
 
 
 
43
  model = HfApiModel(
44
+ model_id=model_config['model_id'],
45
+ max_tokens=model_config['max_tokens'],
46
+ temperature=model_config['temperature']
 
47
  )
48
 
49
+ # Initialize tools
50
+ tools = initialize_tools()
51
+
52
+ # Create agent
53
  agent = CodeAgent(
54
  model=model,
55
+ tools=tools,
56
+ max_steps=config['agent_config']['max_steps'],
57
+ verbosity_level=config['agent_config']['verbosity_level']
58
  )
59
 
60
+ return agent, prompts
61
+
62
+ def process_query(query, analysis_type="general"):
63
+ """Process a user query"""
64
+ agent, prompts = create_agent()
65
 
66
+ # Select appropriate template
67
+ if analysis_type == "vulnerability":
68
+ template = prompts['vulnerability_analysis']
69
+ formatted_prompt = template.format(cve_id=query)
70
+ elif analysis_type == "threat":
71
+ template = prompts['threat_report']
72
+ formatted_prompt = template.format(target=query)
73
+ else:
74
+ template = prompts['user_prompt']
75
+ formatted_prompt = template.format(query=query)
76
+
77
+ # Execute agent
78
+ system_prompt = prompts['system_prompt']
79
+ result = agent.run(formatted_prompt, system_prompt=system_prompt)
80
+
81
+ return result
82
+
83
+ # Gradio Interface
84
+ def create_interface():
85
+ """Create the Gradio user interface"""
86
+ with gr.Blocks(title="Vulnerability Intelligence Agent") as interface:
87
+ gr.Markdown("# Vulnerability Intelligence Agent (VIA)")
88
+
89
+ with gr.Row():
90
+ with gr.Column():
91
+ query_input = gr.Textbox(
92
+ label="Query",
93
+ placeholder="Enter your security query..."
94
+ )
95
+ analysis_type = gr.Radio(
96
+ choices=["general", "vulnerability", "threat"],
97
+ label="Analysis Type",
98
+ value="general"
99
+ )
100
+ submit_btn = gr.Button("Analyze")
101
+
102
+ with gr.Column():
103
+ output = gr.Markdown(label="Result")
104
+
105
+ submit_btn.click(
106
+ fn=process_query,
107
+ inputs=[query_input, analysis_type],
108
+ outputs=output
109
+ )
110
+
111
+ return interface
112
 
113
  if __name__ == "__main__":
114
+ interface = create_interface()
115
+ interface.launch()
prompts.yaml CHANGED
@@ -186,7 +186,6 @@
186
  "planning":
187
  "initial_facts": |-
188
  Below I will present you a task.
189
-
190
  You will now build a comprehensive preparatory survey of which facts we have at our disposal and which ones we still need.
191
  To do so, you will have to read the task and identify things that must be discovered in order to successfully complete it.
192
  Don't make any assumptions. For each item, provide a thorough reasoning. Here is how you will structure this survey:
@@ -209,7 +208,6 @@
209
  Do not add anything else.
210
  "initial_plan": |-
211
  You are a world expert at making efficient plans to solve any task using a set of carefully crafted tools.
212
-
213
  Now for the given task, develop a step-by-step high-level plan taking into account the above inputs and list of facts.
214
  This plan should involve individual tasks based on the available tools, that if executed correctly will yield the correct answer.
215
  Do not skip steps, do not add any superfluous steps. Only write the high-level plan, DO NOT DETAIL INDIVIDUAL TOOL CALLS.
@@ -261,11 +259,9 @@
261
  ### 2. Facts that we have learned
262
  ### 3. Facts still to look up
263
  ### 4. Facts still to derive
264
-
265
  Now write your new list of facts below.
266
  "update_plan_pre_messages": |-
267
  You are a world expert at making efficient plans to solve any task using a set of carefully crafted tools.
268
-
269
  You have been given a task:
270
  ```
271
  {{task}}
@@ -279,7 +275,6 @@
279
  ```
280
  {{task}}
281
  ```
282
-
283
  You can leverage these tools:
284
  {%- for tool in tools.values() %}
285
  - {{ tool.name }}: {{ tool.description }}
@@ -319,7 +314,6 @@
319
  {{task}}
320
  ---
321
  You're helping your manager solve a wider task: so make sure to not provide a one-line answer, but give as much information as possible to give them a clear understanding of the answer.
322
-
323
  Your final_answer WILL HAVE to contain these parts:
324
  ### 1. Task outcome (short version):
325
  ### 2. Task outcome (extremely detailed version):
@@ -329,4 +323,4 @@
329
  And even if your task resolution is not successful, please return as much context as possible, so that your manager can act upon this feedback.
330
  "report": |-
331
  Here is the final answer from your managed agent '{{name}}':
332
- {{final_answer}}
 
186
  "planning":
187
  "initial_facts": |-
188
  Below I will present you a task.
 
189
  You will now build a comprehensive preparatory survey of which facts we have at our disposal and which ones we still need.
190
  To do so, you will have to read the task and identify things that must be discovered in order to successfully complete it.
191
  Don't make any assumptions. For each item, provide a thorough reasoning. Here is how you will structure this survey:
 
208
  Do not add anything else.
209
  "initial_plan": |-
210
  You are a world expert at making efficient plans to solve any task using a set of carefully crafted tools.
 
211
  Now for the given task, develop a step-by-step high-level plan taking into account the above inputs and list of facts.
212
  This plan should involve individual tasks based on the available tools, that if executed correctly will yield the correct answer.
213
  Do not skip steps, do not add any superfluous steps. Only write the high-level plan, DO NOT DETAIL INDIVIDUAL TOOL CALLS.
 
259
  ### 2. Facts that we have learned
260
  ### 3. Facts still to look up
261
  ### 4. Facts still to derive
 
262
  Now write your new list of facts below.
263
  "update_plan_pre_messages": |-
264
  You are a world expert at making efficient plans to solve any task using a set of carefully crafted tools.
 
265
  You have been given a task:
266
  ```
267
  {{task}}
 
275
  ```
276
  {{task}}
277
  ```
 
278
  You can leverage these tools:
279
  {%- for tool in tools.values() %}
280
  - {{ tool.name }}: {{ tool.description }}
 
314
  {{task}}
315
  ---
316
  You're helping your manager solve a wider task: so make sure to not provide a one-line answer, but give as much information as possible to give them a clear understanding of the answer.
 
317
  Your final_answer WILL HAVE to contain these parts:
318
  ### 1. Task outcome (short version):
319
  ### 2. Task outcome (extremely detailed version):
 
323
  And even if your task resolution is not successful, please return as much context as possible, so that your manager can act upon this feedback.
324
  "report": |-
325
  Here is the final answer from your managed agent '{{name}}':
326
+ {{final_answer}}
tools/__pycache__/final_answer.cpython-310.pyc ADDED
Binary file (898 Bytes). View file
 
tools/__pycache__/visit_webpage.cpython-310.pyc ADDED
Binary file (1.9 kB). View file
 
tools/__pycache__/vuln_search.cpython-310.pyc ADDED
Binary file (3.9 kB). View file
 
tools/__pycache__/web_search.cpython-310.pyc ADDED
Binary file (1.77 kB). View file
 
tools/final_answer.py CHANGED
@@ -11,4 +11,4 @@ class FinalAnswerTool(Tool):
11
  return answer
12
 
13
  def __init__(self, *args, **kwargs):
14
- self.is_initialized = False
 
11
  return answer
12
 
13
  def __init__(self, *args, **kwargs):
14
+ self.is_initialized = False
tools/visit_webpage.py CHANGED
@@ -3,6 +3,7 @@ from smolagents.tools import Tool
3
  import requests
4
  import markdownify
5
  import smolagents
 
6
 
7
  class VisitWebpageTool(Tool):
8
  name = "visit_webpage"
@@ -42,4 +43,4 @@ class VisitWebpageTool(Tool):
42
  return f"An unexpected error occurred: {str(e)}"
43
 
44
  def __init__(self, *args, **kwargs):
45
- self.is_initialized = False
 
3
  import requests
4
  import markdownify
5
  import smolagents
6
+ import re
7
 
8
  class VisitWebpageTool(Tool):
9
  name = "visit_webpage"
 
43
  return f"An unexpected error occurred: {str(e)}"
44
 
45
  def __init__(self, *args, **kwargs):
46
+ self.is_initialized = False
tools/vuln_search.py ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from typing import Dict, Any, Optional, List
3
+ import nvdlib
4
+ from smolagents.tools import Tool
5
+
6
+ class VulnerabilitySearchTool(Tool):
7
+ name = "vuln_search"
8
+ description = "Search for vulnerabilities in NVD (National Vulnerability Database)"
9
+ inputs = {
10
+ 'query': {'type': 'str', 'description': 'Search term or CVE ID'},
11
+ 'max_results': {'type': 'int', 'description': 'Maximum number of results', 'default': 5}
12
+ }
13
+ output_type = Dict[str, Any]
14
+
15
+ def __init__(self):
16
+ """Initialize NVD API connection"""
17
+ self.nvd_api_key = os.getenv('NVD_API_KEY')
18
+
19
+ # Configure NVD
20
+ if self.nvd_api_key:
21
+ nvdlib.set_api_key(self.nvd_api_key)
22
+
23
+ def search_nvd(self, query: str, max_results: int) -> List[Dict[str, Any]]:
24
+ """Search vulnerabilities in NVD"""
25
+ try:
26
+ # If query looks like a CVE-ID, search directly
27
+ if query.startswith('CVE-'):
28
+ results = nvdlib.get_cve(query)
29
+ return [{
30
+ 'id': results.id,
31
+ 'description': results.descriptions[0].value,
32
+ 'severity': results.metrics.cvssMetricV31[0].cvssData.baseScore if results.metrics else None,
33
+ 'published': results.published,
34
+ 'references': [ref.url for ref in results.references]
35
+ }]
36
+
37
+ # Otherwise, perform general search
38
+ results = nvdlib.searchCVE(
39
+ keyword=query,
40
+ limit=max_results
41
+ )
42
+
43
+ return [{
44
+ 'id': r.id,
45
+ 'description': r.descriptions[0].value,
46
+ 'severity': r.metrics.cvssMetricV31[0].cvssData.baseScore if r.metrics else None,
47
+ 'published': r.published,
48
+ 'references': [ref.url for ref in r.references]
49
+ } for r in results]
50
+
51
+ except Exception as e:
52
+ return [{'error': f"Error in NVD search: {str(e)}"}]
53
+
54
+ def forward(self, query: str, max_results: int = 5) -> Dict[str, Any]:
55
+ """Process search in NVD"""
56
+ results = self.search_nvd(query, max_results)
57
+
58
+ return {
59
+ 'query': query,
60
+ 'source': 'nvd',
61
+ 'results': results
62
+ }
tools/web_search.py CHANGED
@@ -24,4 +24,4 @@ class DuckDuckGoSearchTool(Tool):
24
  if len(results) == 0:
25
  raise Exception("No results found! Try a less restrictive/shorter query.")
26
  postprocessed_results = [f"[{result['title']}]({result['href']})\n{result['body']}" for result in results]
27
- return "## Search Results\n\n" + "\n\n".join(postprocessed_results)
 
24
  if len(results) == 0:
25
  raise Exception("No results found! Try a less restrictive/shorter query.")
26
  postprocessed_results = [f"[{result['title']}]({result['href']})\n{result['body']}" for result in results]
27
+ return "## Search Results\n\n" + "\n\n".join(postprocessed_results)