Skip to content

Commit 328ac25

Browse files
authored
Merge pull request #28 from VRIG-RITSEC/Agents
Initialized Agents
2 parents eb7bdd7 + 797296a commit 328ac25

File tree

4 files changed

+482
-0
lines changed

4 files changed

+482
-0
lines changed
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
#!/usr/bin/env python3
2+
3+
import threading
4+
import time
5+
from abc import ABC, abstractmethod
6+
from pathlib import Path
7+
8+
from smolagents import LiteLLMModel, ToolCallingAgent
9+
10+
11+
class Agent(ABC):
12+
"""Base class for AI agents."""
13+
14+
def __init__(self, model: LiteLLMModel, api_key: str = None, anthropic_api_key: str = None):
15+
self.model = model
16+
self.api_key = api_key
17+
self.anthropic_api_key = anthropic_api_key
18+
self.agents = {}
19+
self.setup_agents()
20+
21+
# Rate limiting configuration
22+
self.min_request_interval = 1.0 # Minimum seconds between requests
23+
self.last_request_time = None
24+
self.request_lock = threading.Lock()
25+
26+
def wait_for_rate_limit(self):
27+
"""Ensure minimum time between requests."""
28+
with self.request_lock:
29+
if self.last_request_time:
30+
elapsed = time.time() - self.last_request_time
31+
if elapsed < self.min_request_interval:
32+
sleep_time = self.min_request_interval - elapsed
33+
print(f"Rate limiting: waiting {sleep_time:.2f} seconds...")
34+
time.sleep(sleep_time)
35+
self.last_request_time = time.time()
36+
37+
def get_prompt(self, prompt_name: str) -> str:
38+
"""Load prompt template from file."""
39+
prompt_path = Path(__file__).parent / "prompts" / prompt_name
40+
if prompt_path.exists():
41+
with open(prompt_path, 'r') as f:
42+
return f.read()
43+
return ""
44+
45+
@abstractmethod
46+
def setup_agents(self):
47+
"""Setup agents specific to this agent."""
48+
pass
49+
50+
def get_manager_agent(self) -> ToolCallingAgent:
51+
"""Get the main manager agent for this system."""
52+
# Try to find father_of_george first
53+
if 'father_of_george' in self.agents:
54+
return self.agents['father_of_george']
55+
56+
# Look for agents with 'Manager' in their description or name
57+
for key, agent in self.agents.items():
58+
if hasattr(agent, 'description') and 'Manager' in agent.description:
59+
return agent
60+
if hasattr(agent, 'name') and 'Manager' in agent.name:
61+
return agent
62+
63+
# Fallback: return the first agent if no manager found
64+
if self.agents:
65+
return list(self.agents.values())[0]
66+
67+
return None
68+
69+
def get_all_agents(self) -> list:
70+
"""Get all agents in this system."""
71+
return list(self.agents.values())
72+
73+
def run_task(self, task_description: str, context: dict = None) -> dict:
74+
"""Run a task using this system's agents."""
75+
results = {
76+
"task_description": task_description,
77+
"completed": False,
78+
"output": None,
79+
"error": None,
80+
}
81+
82+
try:
83+
self.wait_for_rate_limit()
84+
85+
# Get the manager agent
86+
manager_agent = self.get_manager_agent()
87+
if not manager_agent:
88+
results["error"] = "No manager agent found for this system"
89+
return results
90+
91+
# Create task prompt
92+
prompt = self._create_task_prompt(task_description, context)
93+
94+
print(f"Using {manager_agent.name} for task: {task_description}")
95+
96+
# Run the agent
97+
agent_output = manager_agent.run(prompt)
98+
results["output"] = str(agent_output)
99+
results["completed"] = True
100+
101+
except Exception as e:
102+
results["error"] = str(e)
103+
print(f"Error running task: {e}")
104+
105+
return results
106+
107+
def _create_task_prompt(self, task_description: str, context: dict = None) -> str:
108+
"""Create a prompt for the given task."""
109+
prompt = f"Task: {task_description}\n\n"
110+
111+
if context:
112+
prompt += "Context:\n"
113+
for key, value in context.items():
114+
prompt += f"- {key}: {value}\n"
115+
prompt += "\n"
116+
117+
return prompt
118+
119+
120+
# Tool definitions for different agent types
121+
def get_manager_tools():
122+
"""Tools available to manager agents."""
123+
return [
124+
# TODO: Add manager-specific tools
125+
# - orchestrate_subagents
126+
# - collect_results
127+
# - make_decisions
128+
# - validate_outputs
129+
]
130+
131+
def get_code_analysis_tools():
132+
"""Tools available to code analysis agents."""
133+
return [
134+
# TODO: Add code analysis tools
135+
# - analyze_syntax
136+
# - analyze_semantics
137+
# - extract_patterns
138+
# - identify_vulnerabilities
139+
]
140+
141+
def get_retrieval_tools():
142+
"""Tools available to retrieval agents."""
143+
return [
144+
# TODO: Add retrieval tools
145+
# - query_rag_db
146+
# - search_vector_db
147+
# - retrieve_context
148+
# - validate_information
149+
]
150+
151+
def get_v8_search_tools():
152+
"""Tools available to V8 search agents."""
153+
return [
154+
# TODO: Add V8 search tools
155+
# - fuzzy_find
156+
# - regex_search
157+
# - compile_with_clang
158+
# - test_with_python
159+
# - view_call_graph
160+
# - web_search
161+
]
162+
163+
def get_program_builder_tools():
164+
"""Tools available to program builder agents."""
165+
return [
166+
# TODO: Add program builder tools
167+
# - query_postgres_db
168+
# - generate_seed_program
169+
# - combine_contexts
170+
# - validate_syntax
171+
]
172+
173+
def get_corpus_generation_tools():
174+
"""Tools available to corpus generation agents."""
175+
return [
176+
# TODO: Add corpus generation tools
177+
# - validate_syntax
178+
# - validate_semantics
179+
# - test_program
180+
# - evaluate_interestingness
181+
]
182+
183+
def get_runtime_analysis_tools():
184+
"""Tools available to runtime analysis agents."""
185+
return [
186+
# TODO: Add runtime analysis tools
187+
# - analyze_execution_state
188+
# - check_coverage
189+
# - evaluate_flags
190+
# - determine_seed_quality
191+
]
192+
193+
def get_validation_tools():
194+
"""Tools available to validation agents."""
195+
return [
196+
# TODO: Add validation tools
197+
# - validate_corpus
198+
# - check_db_integrity
199+
# - verify_results
200+
# - quality_assurance
201+
]

Sources/FatherOfGeorge/FoG.py

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Father of George, and thus George the negative First.
4+
L0 Root Manager Agent - Orchestrates Code Analysis and Program Building
5+
"""
6+
7+
from smolagents import LiteLLMModel, ToolCallingAgent
8+
from BaseAgent import Agent, get_manager_tools, get_code_analysis_tools, get_program_builder_tools, get_retrieval_tools, get_v8_search_tools
9+
from GeorgeForeman import George
10+
11+
12+
class Father(Agent):
13+
"""Init code analysis and program builder."""
14+
15+
def setup_agents(self):
16+
# L2 Worker: George Foreman
17+
self.agents['george_foreman'] = George(
18+
model=self.model,
19+
api_key=self.api_key,
20+
anthropic_api_key=self.anthropic_api_key
21+
)
22+
23+
# L2 Worker: Retriever of Code (under CodeAnalyzer)
24+
self.agents['retriever_of_code'] = ToolCallingAgent(
25+
name="RetrieverOfCode",
26+
description="L2 Worker responsible for retrieving code from various sources using RAG database",
27+
tools=get_retrieval_tools(),
28+
model=LiteLLMModel(model_id="gpt-5", api_key=self.api_key),
29+
managed_agents=[
30+
self.agents['george_foreman']
31+
],
32+
max_steps=10,
33+
planning_interval=None,
34+
)
35+
36+
# L2 Worker: V8 Search (under CodeAnalyzer)
37+
self.agents['v8_search'] = ToolCallingAgent(
38+
name="V8Search",
39+
description="L2 Worker responsible for searching V8 source code using fuzzy find, regex, and compilation tools",
40+
tools=get_v8_search_tools(),
41+
model=LiteLLMModel(model_id="gpt-5", api_key=self.api_key),
42+
managed_agents=[],
43+
max_steps=10,
44+
planning_interval=None,
45+
)
46+
47+
# L1 Manager: Code Analysis Agent
48+
self.agents['code_analyzer'] = ToolCallingAgent(
49+
name="CodeAnalyzer",
50+
description="L1 Manager responsible for analyzing code and coordinating retrieval and V8 search operations",
51+
tools=get_code_analysis_tools(),
52+
model=LiteLLMModel(model_id="gpt-5", api_key=self.api_key),
53+
managed_agents=[
54+
self.agents['retriever_of_code'],
55+
self.agents['v8_search']
56+
],
57+
max_steps=15,
58+
planning_interval=None,
59+
)
60+
61+
# L1 Manager: Program Builder Agent
62+
self.agents['program_builder'] = ToolCallingAgent(
63+
name="ProgramBuilder",
64+
description="L1 Manager responsible for building program templates using corpus and context",
65+
tools=get_program_builder_tools(),
66+
model=LiteLLMModel(model_id="gpt-5", api_key=self.api_key),
67+
managed_agents=[
68+
self.agents['george_foreman']
69+
],
70+
max_steps=15,
71+
planning_interval=None,
72+
)
73+
74+
# L0 Root Manager Agent
75+
self.agents['father_of_george'] = ToolCallingAgent(
76+
name="FatherOfGeorge",
77+
description="L0 Root Manager responsible for orchestrating code analysis and program building operations",
78+
tools=get_manager_tools(),
79+
model=LiteLLMModel(model_id="gpt-5-mini", api_key=self.api_key),
80+
managed_agents=[
81+
self.agents['code_analyzer'],
82+
self.agents['program_builder']
83+
],
84+
max_steps=20,
85+
planning_interval=None,
86+
)
87+
88+
89+
def run_task(self, task_description: str, context: dict = None) -> dict:
90+
results = {
91+
"task_description": task_description,
92+
"completed": False,
93+
"output": None,
94+
"error": None,
95+
}
96+
return results
97+
98+
99+
def main():
100+
# Init model
101+
model = LiteLLMModel(
102+
model_id="gpt-5-mini",
103+
api_key="<key>"
104+
)
105+
106+
system = Father(model)
107+
108+
# run task
109+
result = system.run_task(
110+
task_description="Initialize corpus generation for V8 fuzzing",
111+
context={
112+
"CodeAnalyzer": "Analyze V8 source code for patterns. vulnerabilities. specifc components, etc...",
113+
"ProgramBuilder": "Build JavaScript programs using corpus and context"
114+
}
115+
)
116+
117+
print("Task Result:")
118+
print(f"Completed: {result['completed']}")
119+
print(f"Output: {result['output']}")
120+
if result['error']:
121+
print(f"Error: {result['error']}")
122+
123+
124+
if __name__ == "__main__":
125+
main()

0 commit comments

Comments
 (0)