Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .bandit
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,19 @@ exclude_dirs:

skips:
- B101 # assert_used - common in tests
- B104 # hardcoded_bind_all_interfaces - test/dev servers bind 0.0.0.0 intentionally
- B105 # hardcoded_password_string - false positive on event/policy variable names
- B106 # hardcoded_password_funcarg - false positive on param names (token_type, password)
- B108 # hardcoded_tmp_directory - /tmp used for legitimate temp files
- B110 # try_except_pass - intentional exception suppression pattern
- B112 # try_except_continue - intentional exception-and-continue pattern
- B113 # request_without_timeout - all 21 instances in test files (not production)
- B311 # random - used for demo data variance, not cryptographic purposes
- B324 # hashlib weak hash - MD5 used for caching fingerprints, not security
- B404 # import_subprocess - subprocess use is intentional and reviewed
- B601 # paramiko_calls - intentional usage
- B603 # subprocess_without_shell_equals_true - we use shell=False
- B605 # start_process_with_a_shell - static commands for system info collection
- B607 # start_process_with_partial_path - tool names resolved via PATH intentionally
- B608 # hardcoded_sql_expressions - false positive in analysis tooling
- B615 # huggingface_unsafe_download - intentional model downloads from trusted sources
11 changes: 4 additions & 7 deletions .github/workflows/code-quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ jobs:
run: |
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install black isort flake8 autoflake bandit[toml]
# Pin versions to match .pre-commit-config.yaml (Issue #2128)
python -m pip install black==26.3.1 isort==8.0.1 flake8==7.3.0 autoflake==2.3.3 'bandit[toml]==1.9.4'

- name: Check code formatting with Black
run: |
Expand All @@ -69,12 +70,8 @@ jobs:
- name: Lint with flake8
run: |
source .venv/bin/activate
python3 -m flake8 autobot-backend/ autobot-slm-backend/ autobot-shared/ \
--max-line-length=100 \
--extend-ignore=E203,W503 \
--exclude=node_modules,.venv,venv,__pycache__,.git,temp,logs,reports,archive \
--statistics \
--count || {
# Uses .flake8 config for consistency with pre-commit (Issue #2128)
python3 -m flake8 --config=.flake8 autobot-backend/ autobot-slm-backend/ autobot-shared/ || {
echo "⚠️ flake8 linting issues found"
exit 1
}
Expand Down
10 changes: 5 additions & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ repos:

# Python code formatting with Black
- repo: https://github.com/psf/black
rev: 23.12.1
rev: 26.3.1
hooks:
- id: black
args: [--line-length=88]
Expand All @@ -27,7 +27,7 @@ repos:

# Python import sorting with isort
- repo: https://github.com/pycqa/isort
rev: 5.13.2
rev: 8.0.1
hooks:
- id: isort
args: [--profile=black, --line-length=88]
Expand All @@ -36,7 +36,7 @@ repos:
# Python linting with flake8
# Uses .flake8 config file for consistent settings across local dev and CI
- repo: https://github.com/pycqa/flake8
rev: 7.0.0
rev: 7.3.0
hooks:
- id: flake8
# Uses .flake8 config file in repo root via args
Expand All @@ -46,7 +46,7 @@ repos:

# Remove unused imports and variables with autoflake
- repo: https://github.com/PyCQA/autoflake
rev: v2.2.1
rev: v2.3.3
hooks:
- id: autoflake
args: [
Expand Down Expand Up @@ -89,7 +89,7 @@ repos:

# Security checks with bandit
- repo: https://github.com/PyCQA/bandit
rev: 1.7.6
rev: 1.9.4
hooks:
- id: bandit
args: [-c, .bandit]
Expand Down
12 changes: 4 additions & 8 deletions autobot-backend/agents/agent_optimizer_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,7 @@ def test_statistics_tracking(self):
# Create larger code blocks to ensure size reduction
large_code = "\n".join([f" line_{j} = {j}" for j in range(20)])
with open(test_file, "w", encoding="utf-8") as f:
f.write(
f"""---
f.write(f"""---
name: agent-{i}
---
Content for agent {i}.
Expand All @@ -276,8 +275,7 @@ def example_function_{i}():
return "result"
```

Additional text after code block."""
)
Additional text after code block.""")

# Optimize all
stats = self.optimizer.optimize_all()
Expand Down Expand Up @@ -450,11 +448,9 @@ def test_malformed_agent_file(self):
# Create malformed file (missing closing frontmatter)
test_file = self.source_dir / "malformed.md"
with open(test_file, "w", encoding="utf-8") as f:
f.write(
"""---
f.write("""---
name: malformed
This is malformed frontmatter without closing"""
)
This is malformed frontmatter without closing""")

# Should handle gracefully without crashing
result = optimizer.optimize_agent_file(test_file)
Expand Down
3 changes: 2 additions & 1 deletion autobot-backend/agents/interactive_terminal_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,8 @@ async def take_control(self):
"chat_id": self.chat_id,
"status": "user_control",
"message": (
"🎮 You now have control of the terminal. " "Type commands directly."
"🎮 You now have control of the terminal. "
"Type commands directly."
),
},
)
Expand Down
7 changes: 2 additions & 5 deletions autobot-backend/agents/kb_librarian/librarian.py
Original file line number Diff line number Diff line change
Expand Up @@ -477,14 +477,11 @@ async def _store_tool_research_results(
if not tools:
return

tool_summaries = [
f"""
tool_summaries = [f"""
{i}. {tool['name']}
Purpose: {tool.get('purpose', 'N/A')}
Installation: {tool.get('installation', 'N/A')[:200]}...
"""
for i, tool in enumerate(tools, 1)
]
""" for i, tool in enumerate(tools, 1)]

summary_content = f"""
Tool Research Results: {tool_type}
Expand Down
6 changes: 3 additions & 3 deletions autobot-backend/agents/knowledge_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,9 +426,9 @@ async def get_machine_info(self) -> Optional[Dict[str, Any]]:

# Access machine profile from MachineAwareSystemKnowledgeManager
if hasattr(self._system_manager, "current_machine_profile"):
profile: Optional[
MachineProfile
] = self._system_manager.current_machine_profile
profile: Optional[MachineProfile] = (
self._system_manager.current_machine_profile
)
if profile:
return profile.to_dict()

Expand Down
2 changes: 1 addition & 1 deletion autobot-backend/agents/librarian_assistant.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
from datetime import datetime
from typing import Any, Callable, Dict, List, Optional

from config import config
from knowledge_base import KnowledgeBase
from llm_interface import LLMInterface
from utils.service_registry import get_service_url

from autobot_shared.http_client import get_http_client
from config import config

logger = logging.getLogger(__name__)

Expand Down
4 changes: 3 additions & 1 deletion autobot-backend/ai_hardware_accelerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,9 @@ async def _handle_task_failure(
fallback_device = self._get_fallback_device(selected_device)

if fallback_device and fallback_device != selected_device:
logger.info("🔄 Retrying task %s on %s", task.task_id, fallback_device.value)
logger.info(
"🔄 Retrying task %s on %s", task.task_id, fallback_device.value
)
fallback_result = await _try_fallback_processing(
task, fallback_device, self._process_on_gpu, self._process_on_cpu
)
Expand Down
1 change: 1 addition & 0 deletions autobot-backend/api/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

Consolidated from agent.py and agent_enhanced.py per Issue #708.
"""

import asyncio
import json
import logging
Expand Down
4 changes: 1 addition & 3 deletions autobot-backend/api/analytics_cost.py
Original file line number Diff line number Diff line change
Expand Up @@ -551,9 +551,7 @@ def _calculate_alert_status(name: str, data: str, current_costs: dict) -> dict:
"status": (
"exceeded"
if percent_used >= 100
else "warning"
if percent_used >= 75
else "ok"
else "warning" if percent_used >= 75 else "ok"
),
"remaining_usd": max(threshold - current, 0),
}
Expand Down
8 changes: 2 additions & 6 deletions autobot-backend/api/analytics_debt.py
Original file line number Diff line number Diff line change
Expand Up @@ -341,9 +341,7 @@ def _process_complexity(complexity_data: Dict[str, Any]) -> List[DebtItem]:
severity = (
DebtSeverity.CRITICAL
if complexity > 20
else DebtSeverity.HIGH
if complexity > 15
else DebtSeverity.MEDIUM
else DebtSeverity.HIGH if complexity > 15 else DebtSeverity.MEDIUM
)
debt_items.append(
DebtItem(
Expand Down Expand Up @@ -698,9 +696,7 @@ def _calculate_trend_change(trend_data: List[Dict[str, Any]]) -> tuple:
direction = (
"improving"
if change["items"] < 0
else "worsening"
if change["items"] > 0
else "stable"
else "worsening" if change["items"] > 0 else "stable"
)
return change, direction

Expand Down
1 change: 1 addition & 0 deletions autobot-backend/api/chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

Consolidated from chat.py and chat_enhanced.py per Issue #708.
"""

import asyncio
import json
import logging
Expand Down
6 changes: 3 additions & 3 deletions autobot-backend/api/chat_sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1095,9 +1095,9 @@ def _process_kb_deletion_result(result: dict, kb_cleanup_result: dict) -> None:
kb_cleanup_result["facts_preserved"] = result.get("preserved_count", 0)

if result.get("errors"):
kb_cleanup_result[
"cleanup_error"
] = f"{len(result['errors'])} errors during cleanup"
kb_cleanup_result["cleanup_error"] = (
f"{len(result['errors'])} errors during cleanup"
)


def _log_kb_cleanup_result(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,9 +178,7 @@ def _dfs(start: str, node: str, path: List[str], depth: int):
severity = (
"high"
if len(path) <= 2
else "medium"
if len(path) <= 4
else "low"
else "medium" if len(path) <= 4 else "low"
)
cycle_path = path + [start]
cycles.append(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -423,8 +423,6 @@ async def cancel_indexing_job():
- task_id: The cancelled job's task ID
- message: Status message
"""
global _current_indexing_task_id

# All accesses to shared state under lock
async with _tasks_lock:
if _current_indexing_task_id is None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
Usage (internal — called by _run_indexing_subprocess):
python indexing_worker.py <task_id> <root_path> [source_id]
"""

import asyncio
import logging
import os
Expand Down
6 changes: 3 additions & 3 deletions autobot-backend/api/codebase_analytics/npu_embeddings.py
Original file line number Diff line number Diff line change
Expand Up @@ -417,9 +417,9 @@ async def warmup_npu_for_codebase() -> Dict[str, Any]:
result["npu_available"] = True
result["warmup_time_ms"] = warmup_time
result["embedding_dimensions"] = len(embeddings[0])
result[
"message"
] = f"NPU connection warmed up for codebase indexing in {warmup_time:.1f}ms"
result["message"] = (
f"NPU connection warmed up for codebase indexing in {warmup_time:.1f}ms"
)

# Get device info
if client:
Expand Down
6 changes: 5 additions & 1 deletion autobot-backend/api/codebase_analytics/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@
pattern_analysis,
)
from .endpoints import queue as queue_router
from .endpoints import report, sources, stats
from .endpoints import (
report,
sources,
stats,
)

# Create main router — prefix provided by analytics_routers.py registry (#1027)
router = APIRouter(
Expand Down
1 change: 1 addition & 0 deletions autobot-backend/api/data_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
- Conversation/transcript management
- Database file information
"""

import logging
import shutil
from datetime import datetime
Expand Down
16 changes: 4 additions & 12 deletions autobot-backend/api/knowledge.py
Original file line number Diff line number Diff line change
Expand Up @@ -1319,9 +1319,7 @@ async def get_machine_profile(
"cpu_count": psutil.cpu_count(logical=False),
"cpu_count_logical": psutil.cpu_count(logical=True),
"memory_total_gb": round(psutil.virtual_memory().total / (1024**3), 2),
"memory_available_gb": round(
psutil.virtual_memory().available / (1024**3), 2
),
"memory_available_gb": round(psutil.virtual_memory().available / (1024**3), 2),
"disk_total_gb": round(psutil.disk_usage("/").total / (1024**3), 2),
"disk_free_gb": round(psutil.disk_usage("/").free / (1024**3), 2),
}
Expand Down Expand Up @@ -1739,9 +1737,7 @@ def _process_fact_data(fact_data: dict, cat: str, fact_key: str) -> Optional[dic
content = (
content_raw.decode("utf-8")
if isinstance(content_raw, bytes)
else str(content_raw)
if content_raw
else ""
else str(content_raw) if content_raw else ""
)

fact_title = metadata.get("title", metadata.get("command", "Untitled"))
Expand Down Expand Up @@ -1993,9 +1989,7 @@ def _extract_fact_content(fact_data: dict) -> str:
return (
content_raw.decode("utf-8")
if isinstance(content_raw, bytes)
else str(content_raw)
if content_raw
else ""
else str(content_raw) if content_raw else ""
)


Expand All @@ -2016,9 +2010,7 @@ def _extract_fact_created_at(fact_data: dict) -> str:
return (
created_at_raw.decode("utf-8")
if isinstance(created_at_raw, bytes)
else str(created_at_raw)
if created_at_raw
else ""
else str(created_at_raw) if created_at_raw else ""
)


Expand Down
4 changes: 3 additions & 1 deletion autobot-backend/api/live_workflow.e2e_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,9 @@ async def monitor_workflow_progress(session, base_url, workflow_id):
break

else:
print(f" ❌ Status check failed: {response.status}") # noqa: print
print(
f" ❌ Status check failed: {response.status}"
) # noqa: print
break

except Exception as e:
Expand Down
6 changes: 2 additions & 4 deletions autobot-backend/api/merge_conflict_resolution_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,14 @@
@pytest.fixture
def conflict_file():
"""Create a temporary file with a merge conflict."""
conflict_content = textwrap.dedent(
"""
conflict_content = textwrap.dedent("""
def hello():
<<<<<<< HEAD
return "current"
=======
return "incoming"
>>>>>>> branch
"""
)
""")

with tempfile.NamedTemporaryFile(suffix=".py", delete=False, mode="w") as f:
f.write(conflict_content)
Expand Down
6 changes: 3 additions & 3 deletions autobot-backend/api/natural_language_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@
_ASYNC_FUNC_RE = re.compile(r"async\s+def\s+(\w+)")

# Issue #336: Keyword heuristics dispatch table for intent classification
KEYWORD_INTENT_FALLBACKS: Dict[
Tuple[str, ...], "QueryIntent"
] = {} # Populated after enum defined
KEYWORD_INTENT_FALLBACKS: Dict[Tuple[str, ...], "QueryIntent"] = (
{}
) # Populated after enum defined

router = APIRouter(prefix="/nl-search", tags=["natural-language-search", "code-search"])

Expand Down
Loading
Loading