Skip to content

Commit 0df081b

Browse files
committed
fix(types): resolve all 63 mypy strict mode errors across 19 files
- Fixed callable -> Callable[..., Any] in core/registry.py - Added type arguments to all generic types (dict, list, Callable) - Fixed Liskov violation: BasePlanner returns AssessmentPlan not list[dict] - Made AgentContext ai_client/repository optional to match actual usage - Fixed RulePlanner kwarg passing bug (repository passed as ai_client) - Fixed knowledge_graph graph.py return types (int cast) - Added proper type annotations to CLI commands.py - Fixed TUI App typing with Generic type parameter - Cleaned up all agent list/dict type annotations - Removed continue-on-error from CI mypy job
1 parent b74775d commit 0df081b

22 files changed

Lines changed: 126 additions & 95 deletions

File tree

.github/workflows/ci.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ jobs:
3939
run: uv sync --all-extras
4040
- name: Run mypy
4141
run: uv run mypy bugfinder/ --ignore-missing-imports
42-
continue-on-error: true
4342

4443
test:
4544
name: Test (Python ${{ matrix.python-version }})

bugfinder/agents/api/discover.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
from typing import Any
34
from urllib.parse import urljoin, urlparse
45

56
import httpx
@@ -45,10 +46,12 @@ async def execute(self) -> AgentResult:
4546
base_url = base_url.rstrip("/")
4647

4748
headers = {"User-Agent": "BugFinder/0.1.0", "Accept": "application/json"}
48-
findings = []
49-
assets = []
49+
findings: list[dict[str, Any]] = []
50+
assets: list[dict[str, Any]] = []
5051

51-
async with httpx.AsyncClient(timeout=settings.request_timeout, follow_redirects=True, verify=settings.ssl_verify) as client:
52+
async with httpx.AsyncClient(
53+
timeout=settings.request_timeout, follow_redirects=True, verify=settings.ssl_verify
54+
) as client:
5255
for path in API_PATTERNS:
5356
url = urljoin(base_url, path)
5457
parsed = urlparse(url)

bugfinder/agents/base.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ class AgentContext:
1515
target_type: str
1616
scan_id: str
1717
knowledge_graph: KnowledgeGraph
18-
ai_client: NVIDIAClient
19-
repository: Repository
18+
ai_client: NVIDIAClient | None = None
19+
repository: Repository | None = None
2020
config: dict[str, Any] = field(default_factory=dict)
2121

2222

bugfinder/agents/recon/dns.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ async def execute(self) -> AgentResult:
4747
def _resolve(self, hostname: str, rtype: str) -> list[str]:
4848
try:
4949
if rtype == "A":
50-
return [r[4][0] for r in socket.getaddrinfo(hostname, 0, socket.AF_INET)]
50+
return [str(r[4][0]) for r in socket.getaddrinfo(hostname, 0, socket.AF_INET)]
5151
if rtype == "AAAA":
52-
return [r[4][0] for r in socket.getaddrinfo(hostname, 0, socket.AF_INET6)]
52+
return [str(r[4][0]) for r in socket.getaddrinfo(hostname, 0, socket.AF_INET6)]
5353
return []
5454
except socket.gaierror:
5555
return []

bugfinder/agents/recon/tech.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from __future__ import annotations
22

3+
from typing import Any
4+
35
import httpx
46

57
from bugfinder.agents.base import AgentResult, BaseAgent
@@ -36,11 +38,13 @@ async def execute(self) -> AgentResult:
3638
url = f"https://{url}"
3739

3840
headers = {"User-Agent": "BugFinder/0.1.0"}
39-
technologies = []
40-
findings = []
41+
technologies: list[dict[str, Any]] = []
42+
findings: list[dict[str, Any]] = []
4143

4244
try:
43-
async with httpx.AsyncClient(timeout=settings.request_timeout, follow_redirects=True, verify=settings.ssl_verify) as client:
45+
async with httpx.AsyncClient(
46+
timeout=settings.request_timeout, follow_redirects=True, verify=settings.ssl_verify
47+
) as client:
4448
response = await client.get(url, headers=headers)
4549
body = response.text.lower()
4650
raw_headers = dict(response.headers)

bugfinder/agents/secrets/scan.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
import re
4+
from typing import Any
45

56
import httpx
67

@@ -32,11 +33,13 @@ async def execute(self) -> AgentResult:
3233
base_url = f"https://{base_url}"
3334

3435
headers = {"User-Agent": "BugFinder/0.1.0"}
35-
findings = []
36+
findings: list[dict[str, Any]] = []
3637

3738
targets_to_scan = [base_url]
3839

39-
async with httpx.AsyncClient(timeout=settings.request_timeout, follow_redirects=True, verify=settings.ssl_verify) as client:
40+
async with httpx.AsyncClient(
41+
timeout=settings.request_timeout, follow_redirects=True, verify=settings.ssl_verify
42+
) as client:
4043
js_paths = ["/", "/static/js/", "/assets/", "/app.js", "/main.js"]
4144
for path in js_paths:
4245
from urllib.parse import urljoin

bugfinder/agents/web/crawler.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
from typing import Any
34
from urllib.parse import urljoin
45

56
import httpx
@@ -44,10 +45,12 @@ async def execute(self) -> AgentResult:
4445
base_url = base_url.rstrip("/")
4546

4647
headers = {"User-Agent": "BugFinder/0.1.0"}
47-
findings = []
48-
assets = []
48+
findings: list[dict[str, Any]] = []
49+
assets: list[dict[str, Any]] = []
4950

50-
async with httpx.AsyncClient(timeout=settings.request_timeout, follow_redirects=True, verify=settings.ssl_verify) as client:
51+
async with httpx.AsyncClient(
52+
timeout=settings.request_timeout, follow_redirects=True, verify=settings.ssl_verify
53+
) as client:
5154
try:
5255
resp = await client.get(base_url, headers=headers)
5356
assets.append(
@@ -76,7 +79,7 @@ async def execute(self) -> AgentResult:
7679
summary=f"Crawl failed: {e}",
7780
)
7881

79-
discovered_assets = []
82+
discovered_assets: list[dict[str, Any]] = []
8083
for path in COMMON_PATHS:
8184
url = urljoin(base_url, path)
8285
try:

bugfinder/agents/web/sqli.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ async def execute(self) -> AgentResult:
3535
findings = []
3636
headers = {"User-Agent": "BugFinder/0.1.0"}
3737

38-
async with httpx.AsyncClient(timeout=settings.request_timeout, follow_redirects=True, verify=settings.ssl_verify) as client:
38+
async with httpx.AsyncClient(
39+
timeout=settings.request_timeout, follow_redirects=True, verify=settings.ssl_verify
40+
) as client:
3941
try:
4042
resp = await client.get(base_url, headers=headers)
4143
except Exception:

bugfinder/agents/web/xss.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ async def execute(self) -> AgentResult:
2828
findings = []
2929
headers = {"User-Agent": "BugFinder/0.1.0"}
3030

31-
async with httpx.AsyncClient(timeout=settings.request_timeout, follow_redirects=True, verify=settings.ssl_verify) as client:
31+
async with httpx.AsyncClient(
32+
timeout=settings.request_timeout, follow_redirects=True, verify=settings.ssl_verify
33+
) as client:
3234
try:
3335
resp = await client.get(base_url, headers=headers)
3436
content = resp.text.lower()

bugfinder/ai/client.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ async def chat(
4848
messages: list[dict[str, str]],
4949
temperature: float | None = None,
5050
max_tokens: int | None = None,
51-
response_format: dict | None = None,
51+
response_format: dict[str, Any] | None = None,
5252
) -> dict[str, Any]:
5353
if not self.api_key:
5454
msg = "NVIDIA API key not configured. Set BF_NVIDIA_API_KEY or run `bf config nvidia.api_key YOUR_KEY`."
@@ -71,7 +71,8 @@ async def chat(
7171
try:
7272
response = await client.post("/chat/completions", json=payload)
7373
response.raise_for_status()
74-
return response.json()
74+
data: dict[str, Any] = response.json()
75+
return data
7576
except httpx.HTTPStatusError as e:
7677
raise NVIDIAError(f"API error: {e.response.status_code} - {e.response.text}") from e
7778
except httpx.RequestError as e:
@@ -91,7 +92,8 @@ async def chat_text(
9192
messages.append({"role": "system", "content": system_prompt})
9293
messages.append({"role": "user", "content": user_prompt})
9394
result = await self.chat(messages, **kwargs)
94-
return result["choices"][0]["message"]["content"]
95+
content: str = result["choices"][0]["message"]["content"]
96+
return content
9597

9698
async def chat_json(
9799
self,
@@ -106,7 +108,8 @@ async def chat_json(
106108
**kwargs,
107109
)
108110
try:
109-
return json.loads(text)
111+
data: dict[str, Any] = json.loads(text)
112+
return data
110113
except json.JSONDecodeError as e:
111114
raise NVIDIAError(f"Failed to parse JSON response: {e}") from e
112115

0 commit comments

Comments
 (0)