Agent & Tools
VenomX doesn't just answer questions — it acts. A master-specialist multi-agent system orchestrates specialized agents, executes security tools, and reasons across a shared state graph toward a result, and does all that, autonomously. Give it a target. Walk away.
How the Agent Works
VenomX uses a master-specialist multi-agent architecture. A MasterAgent orchestrates eleven specialists, each confined to a distinct attack phase. Rather than talking to each other, they share state through a central FindingGraph, so every agent begins its task with full knowledge of what came before it.
Each dispatch cycle begins with MasterAgent feeding the LLM a current snapshot of the FindingGraph. The LLM reads the known hosts, open ports, services, credentials, and attack paths, then decides what gaps are worth filling next.
The LLM returns a TaskSpec, a structured JSON object that names the target specialist, the objective, and the context pulled from the graph. The master routes it to whichever of the seven specialists fits the current state. Not every specialist runs on every engagement. The SMB specialist only activates when ports 139 or 445 appear in the graph. SQL only runs when injectable web endpoints have been confirmed.
Each specialist runs its own internal Plan → Tool → Observe → Reason → Act loop against the assigned task. It calls its tools, parses output into structured objects, and reasons about what the results mean. Every successful tool call writes its findings into the shared FindingGraph on the spot, before the loop continues.
When the specialist finishes, it returns a plain-text summary of its findings to the master. The graph has already been updated throughout the run, so all new hosts, ports, services, credentials, and vulnerabilities are in place by the time the master reads back. The master appends the summary to its dispatch log and returns to step 1.
When the master determines the engagement is done, or the iteration limit is reached, it dispatches the report specialist. The report agent builds its sections directly from live graph data, covering discovered services, scored vulnerabilities, captured credentials, and attack paths. It makes a single LLM call for the executive summary and recommendations, then delivers the finished report to the UI as a .docx.
Tool Inventory
Each tool is wrapped in a Python interface that sanitizes input, manages execution, and structures output for the agent's observe step.
Architecture
MasterAgent owns the shared state and drives the engagement. At startup it instantiates all eleven specialists (osint, recon, web, auth, vuln, sql, smb, ad, exploit, post, report) and passes each of them shared references to the graph and credential store. Each dispatch cycle, the master asks the LLM what to do next given the current graph state, then routes a TaskSpec to the right specialist.
Specialists don't talk to each other directly. They all read from and write to a shared FindingGraph, a WAL-backed graph that persists each discovery the moment it happens. When the master dispatches a new specialist, it passes graph.summary_for_llm() as context, so each specialist arrives knowing every host, port, service, credential, and attack path that prior agents found.
Master Dispatch Loop
# Shared state — owned by master, passed by reference to all 11 specialists self.graph = FindingGraph(session_id, wal_path, json_path) self.credential_store = CredentialStore(session_id, persist_path) self._specialists = { "osint": OsintSpecialist(**shared), # subfinder "recon": ReconSpecialist(**shared), # masscan + nmap + netcat "web": WebSpecialist(**shared), # httpx + nikto + gobuster + nuclei + wpscan "auth": AuthSpecialist(**shared), # kerbrute (det.) + hydra "vuln": VulnSpecialist(**shared), # searchsploit + metasploit "sql": SqlSpecialist(**shared), # sqlmap "smb": SmbSpecialist(**shared), # enum4linux + netexec "ad": ADSpecialist(**shared), # getuserspns + getnpusers "exploit": ExploitSpecialist(**shared), # metasploit (Phase 2 only) "post": PostSpecialist(**shared), # netexec (post-exploitation) "report": ReportSpecialist(**shared), # reads graph, writes report } for _ in range(self.MAX_DISPATCHES): task = self._decide_next_task(user_input) # LLM reads graph, returns TaskSpec if task is DONE: break result = self._specialists[task.specialist].run(task) self._dispatch_log.append(result.summary) # graph already updated by specialist
Scope enforcement: Every tool wrapper validates targets against an authorized scope list before execution. The agent has no path to run tools outside the configured lab range. That enforcement lives at the tool layer, wired into the code, with no prompt-level override available.
Output & Safety
An agent that runs for a dozen tool calls across seven specialists has a lot of ways to go wrong. Output parsing, token budgeting, and hard-coded safety controls are what keep it on track.
Tool outputs are parsed into typed objects before touching the context window. Nmap XML becomes host and port dicts. SQLMap output becomes injection and database dicts. The LLM sees clean, structured data rather than hundreds of lines it has to interpret on its own.
Nemotron 30B runs a 32K token context window, eight times the budget of the 9B it replaced. Per-specialist caps hold tool output to 6000 chars and RAG threat intel to 3000 per turn. Each specialist starts fresh, so findings from one phase never pollute the reasoning of the next.
Safety controls are wired into the code, not whispered in a system prompt. Target scope is enforced at the tool wrapper level. Max iteration counts stop runaway loops. Subprocess timeouts kill stalled tools. The agent has no way to talk its way around any of this.