From 9100e91652786866dc3233755f1de9f506c3825d Mon Sep 17 00:00:00 2001 From: Arnav Naval Date: Wed, 6 May 2026 18:30:34 -0500 Subject: [PATCH] [arnav] clean up unused imports and dead local variables Auto-fixed 52 ruff F401 findings (unused imports) across 22 files in backend/ and backend/tests/. Manually resolved 8 F841 unused locals that ruff flagged as unsafe-fix: - agent_manager.resume_session: drop dead hours_since_closed block. - main.py mcp-meta + outputs-meta activate handlers: drop dead reason = body.get("reason") binding (server ignores the field). - dashboards.seed_demo, tools_lib.m365_device_login: keep _load(...) call for its 404 side-effect, drop unused binding, add intent comment. - outputs.auto_run_output: keep `import anthropic` as availability probe, mark with `# noqa: F401` and explanation. - dead_code_scan._extract_ws_event_branches: drop vestigial ws_handler_lines set (never written or read). - test_browser_agent_unit.test_hash_tool_call_falls_back_to_repr: drop the unused _Boom class+instance (the actual self-referential bait is bad_input/bad_result; _Boom was never passed to the function under test). Result: 1184/1184 backend tests pass (1 deselected: pre-existing sandbox-only git test). ruff --select F401,F811,F841 backend/ now clean (was 60 findings). Co-authored-by: Cursor --- backend/apps/agents/agent_manager.py | 9 --------- backend/apps/agents/agents.py | 5 +---- backend/apps/agents/browser_agent.py | 1 - backend/apps/agents/tools/web.py | 1 - backend/apps/dashboards/dashboards.py | 5 +---- backend/apps/health/health.py | 2 +- backend/apps/nine_router.py | 1 - backend/apps/outputs/outputs.py | 4 ++-- backend/apps/service/buffer.py | 2 +- backend/apps/skills/skills.py | 1 - backend/apps/subscription/router.py | 4 +--- backend/apps/tools_lib/tools_lib.py | 4 +--- backend/auth.py | 2 +- backend/main.py | 3 --- backend/scripts/dead_code_scan.py | 1 - backend/tests/conftest.py | 4 +--- backend/tests/test_agent_manager_unit.py | 4 +--- backend/tests/test_agents_lifespan_integration.py | 2 -- backend/tests/test_api_outputs.py | 1 - backend/tests/test_browser_agent_integration.py | 3 +-- backend/tests/test_browser_agent_unit.py | 6 ------ backend/tests/test_disconnect_resilience.py | 2 -- backend/tests/test_mcp_preflight.py | 3 +-- backend/tests/test_phase1_stress.py | 3 +-- backend/tests/test_service_legacy.py | 4 +--- backend/tests/test_v2_invariants.py | 4 +--- backend/tests/test_v2_label_logic.py | 1 - 27 files changed, 16 insertions(+), 66 deletions(-) diff --git a/backend/apps/agents/agent_manager.py b/backend/apps/agents/agent_manager.py index 470954f1..4e716638 100644 --- a/backend/apps/agents/agent_manager.py +++ b/backend/apps/agents/agent_manager.py @@ -801,7 +801,6 @@ class AgentManager: ) self.sessions[session_id] = session - from backend.apps.service.service import APP_VERSION await ws_manager.send_to_session(session_id, "agent:status", { "session_id": session_id, @@ -4101,14 +4100,6 @@ class AgentManager: session = AgentSession(**data) - hours_since_closed = 0 - if data.get("closed_at"): - try: - closed = datetime.fromisoformat(data["closed_at"][:19]) - hours_since_closed = round((datetime.now() - closed).total_seconds() / 3600, 1) - except Exception: - pass - session.closed_at = None self.sessions[session_id] = session diff --git a/backend/apps/agents/agents.py b/backend/apps/agents/agents.py index de5ec34d..2a5d99b4 100644 --- a/backend/apps/agents/agents.py +++ b/backend/apps/agents/agents.py @@ -1,11 +1,8 @@ from backend.config.Apps import SubApp from backend.apps.agents.agent_manager import agent_manager -from backend.apps.agents.ws_manager import ws_manager from backend.apps.agents.models import AgentConfig, ApprovalResponse from contextlib import asynccontextmanager -from fastapi import WebSocket, WebSocketDisconnect, HTTPException -from fastapi.responses import JSONResponse -import json +from fastapi import HTTPException import logging logger = logging.getLogger(__name__) diff --git a/backend/apps/agents/browser_agent.py b/backend/apps/agents/browser_agent.py index 0346e7a5..97591d39 100644 --- a/backend/apps/agents/browser_agent.py +++ b/backend/apps/agents/browser_agent.py @@ -13,7 +13,6 @@ import time from datetime import datetime from uuid import uuid4 -import anthropic from backend.apps.agents.models import AgentSession, ApprovalRequest, Message from backend.apps.agents.ws_manager import ws_manager diff --git a/backend/apps/agents/tools/web.py b/backend/apps/agents/tools/web.py index c358f47c..0609e3b2 100644 --- a/backend/apps/agents/tools/web.py +++ b/backend/apps/agents/tools/web.py @@ -4,7 +4,6 @@ from __future__ import annotations import html import re -from typing import Any import httpx diff --git a/backend/apps/dashboards/dashboards.py b/backend/apps/dashboards/dashboards.py index ba502dd1..fd532204 100644 --- a/backend/apps/dashboards/dashboards.py +++ b/backend/apps/dashboards/dashboards.py @@ -11,9 +11,6 @@ from backend.apps.dashboards.models import ( DashboardCreate, DashboardUpdate, DashboardLayout, - CardPosition, - ViewCardPosition, - BrowserCardPosition, ) from fastapi import HTTPException @@ -131,7 +128,7 @@ async def create_dashboard(body: DashboardCreate): @dashboards.router.post("/{dashboard_id}/seed-demo") async def seed_demo(dashboard_id: str): """Create a pre-populated demo session for onboarding.""" - dashboard = _load(dashboard_id) + _load(dashboard_id) # 404s if the dashboard doesn't exist session_id = uuid4().hex now = datetime.now() diff --git a/backend/apps/health/health.py b/backend/apps/health/health.py index 1ffbddfd..f80be804 100644 --- a/backend/apps/health/health.py +++ b/backend/apps/health/health.py @@ -3,7 +3,7 @@ from contextlib import asynccontextmanager from fastapi.responses import PlainTextResponse from typeguard import typechecked import debug -from fastapi import status, HTTPException +from fastapi import status @asynccontextmanager async def health_lifespan(): diff --git a/backend/apps/nine_router.py b/backend/apps/nine_router.py index a8a3cc52..6534b135 100644 --- a/backend/apps/nine_router.py +++ b/backend/apps/nine_router.py @@ -70,7 +70,6 @@ def _find_9router_dir() -> str | None: if _is_packaged: # Packaged Electron app — router is in extraResources - import sys # In packaged mode, backend is at /backend/ # So router is at /router/ _resources = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) diff --git a/backend/apps/outputs/outputs.py b/backend/apps/outputs/outputs.py index 24876f77..1c8ef4f9 100644 --- a/backend/apps/outputs/outputs.py +++ b/backend/apps/outputs/outputs.py @@ -6,7 +6,7 @@ import mimetypes import base64 from datetime import datetime from contextlib import asynccontextmanager -from fastapi import HTTPException, Query +from fastapi import HTTPException from fastapi.responses import Response from backend.auth import get_auth_token from jsonschema import validate as schema_validate, ValidationError as SchemaValidationError @@ -410,7 +410,7 @@ Every required field must be present. Use realistic, meaningful data.\ async def auto_run_output(body: AutoRunRequest): """Use an LLM to generate input data matching the schema, then optionally execute backend code.""" try: - import anthropic + import anthropic # noqa: F401 -- availability probe; client built below via helper except ImportError: return {"error": "anthropic SDK not installed", "input_data": None, "backend_result": None} diff --git a/backend/apps/service/buffer.py b/backend/apps/service/buffer.py index 964c36b6..42ddd060 100644 --- a/backend/apps/service/buffer.py +++ b/backend/apps/service/buffer.py @@ -19,7 +19,7 @@ import os import sqlite3 import threading from contextlib import contextmanager -from typing import Iterator, Optional +from typing import Iterator logger = logging.getLogger(__name__) diff --git a/backend/apps/skills/skills.py b/backend/apps/skills/skills.py index c9393d2d..0bfa0526 100644 --- a/backend/apps/skills/skills.py +++ b/backend/apps/skills/skills.py @@ -2,7 +2,6 @@ import os import json import logging import re -from pathlib import Path from contextlib import asynccontextmanager from fastapi import HTTPException from backend.config.Apps import SubApp diff --git a/backend/apps/subscription/router.py b/backend/apps/subscription/router.py index 7c91e77c..a82adca5 100644 --- a/backend/apps/subscription/router.py +++ b/backend/apps/subscription/router.py @@ -2,9 +2,7 @@ from __future__ import annotations -import json import logging -import os from contextlib import asynccontextmanager from typing import Optional @@ -14,7 +12,7 @@ from pydantic import BaseModel from backend.config.Apps import SubApp from backend.apps.settings.credentials import OPENSWARM_DEFAULT_PROXY_URL -from backend.apps.settings.settings import SETTINGS_FILE, load_settings, save_settings_async +from backend.apps.settings.settings import load_settings, save_settings_async logger = logging.getLogger(__name__) diff --git a/backend/apps/tools_lib/tools_lib.py b/backend/apps/tools_lib/tools_lib.py index ba0cfd52..28d8b0d2 100644 --- a/backend/apps/tools_lib/tools_lib.py +++ b/backend/apps/tools_lib/tools_lib.py @@ -1,5 +1,4 @@ import asyncio -import hashlib import json import os import re @@ -16,7 +15,6 @@ import httpx from dotenv import load_dotenv from fastapi import HTTPException, Query from fastapi.responses import HTMLResponse -from pydantic import BaseModel from backend.config.Apps import SubApp from backend.apps.tools_lib.models import ToolDefinition, ToolCreate, ToolUpdate, BUILTIN_TOOLS @@ -937,7 +935,7 @@ async def m365_device_login(tool_id: str): """ import subprocess - tool = _load(tool_id) + _load(tool_id) # 404s if the tool doesn't exist script = _m365_server_script() if not os.path.isfile(script): raise HTTPException(status_code=500, detail="M365 MCP server not installed") diff --git a/backend/auth.py b/backend/auth.py index f93a0925..1e3eb558 100644 --- a/backend/auth.py +++ b/backend/auth.py @@ -29,7 +29,7 @@ import logging import os import secrets -from backend.config.paths import AUTH_TOKEN_FILE, DATA_ROOT +from backend.config.paths import AUTH_TOKEN_FILE logger = logging.getLogger(__name__) diff --git a/backend/main.py b/backend/main.py index 7532374e..38b1097e 100644 --- a/backend/main.py +++ b/backend/main.py @@ -345,7 +345,6 @@ async def subscriptions_callback(request: Request): async def browser_agent_run(request: Request): """Run one or more browser sub-agents in parallel. Called by the browser_agent_mcp_server stdio subprocess.""" - from backend.apps.settings.settings import load_settings from backend.apps.agents.browser_agent import run_browser_agents body = await request.json() @@ -482,7 +481,6 @@ async def mcp_meta(action: str, request: Request): if action == "activate": server_name = (body.get("server_name") or "").strip() - reason = body.get("reason") or "" if not server_name: return JSONResponse({"error": "server_name is required"}, status_code=400) if not parent_session_id: @@ -663,7 +661,6 @@ async def outputs_meta(action: str, request: Request): if action == "activate": output_id = (body.get("output_id") or "").strip() - reason = body.get("reason") or "" if not output_id: return JSONResponse({"error": "output_id is required"}, status_code=400) if not parent_session_id: diff --git a/backend/scripts/dead_code_scan.py b/backend/scripts/dead_code_scan.py index db00e5f4..d100ff00 100644 --- a/backend/scripts/dead_code_scan.py +++ b/backend/scripts/dead_code_scan.py @@ -539,7 +539,6 @@ def _extract_ws_event_branches(tree: ast.Module) -> list[tuple[str, str]]: listenable events. """ out: list[tuple[str, str]] = [] - ws_handler_lines: set[int] = set() def _has_ws_decorator(fn: ast.FunctionDef | ast.AsyncFunctionDef) -> bool: for dec in fn.decorator_list: diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 4cea8fce..7914e38b 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -28,13 +28,11 @@ What's done here: from __future__ import annotations -import asyncio import os import shutil -import sys import tempfile from typing import Iterator -from unittest.mock import MagicMock, patch +from unittest.mock import MagicMock import pytest diff --git a/backend/tests/test_agent_manager_unit.py b/backend/tests/test_agent_manager_unit.py index 24121c07..c3e63b87 100644 --- a/backend/tests/test_agent_manager_unit.py +++ b/backend/tests/test_agent_manager_unit.py @@ -29,10 +29,8 @@ can write directly to a `tmp_path` without leaking into siblings. from __future__ import annotations import asyncio -import json import os -from datetime import datetime, timedelta -from unittest.mock import AsyncMock, MagicMock, patch +from unittest.mock import MagicMock import pytest diff --git a/backend/tests/test_agents_lifespan_integration.py b/backend/tests/test_agents_lifespan_integration.py index 3c11c7b8..f3ad723f 100644 --- a/backend/tests/test_agents_lifespan_integration.py +++ b/backend/tests/test_agents_lifespan_integration.py @@ -24,10 +24,8 @@ endpoint. This file fills in branches that those don't: from __future__ import annotations import asyncio -import os from unittest.mock import AsyncMock, MagicMock, patch -import pytest from backend.apps.agents import agents as agents_mod from backend.apps.agents.agent_manager import ( diff --git a/backend/tests/test_api_outputs.py b/backend/tests/test_api_outputs.py index 3eefce82..66997160 100644 --- a/backend/tests/test_api_outputs.py +++ b/backend/tests/test_api_outputs.py @@ -25,7 +25,6 @@ import json import os import sys -import pytest # --------------------------------------------------------------------------- diff --git a/backend/tests/test_browser_agent_integration.py b/backend/tests/test_browser_agent_integration.py index 08711e0f..6fc6f194 100644 --- a/backend/tests/test_browser_agent_integration.py +++ b/backend/tests/test_browser_agent_integration.py @@ -32,10 +32,9 @@ All tests: from __future__ import annotations -import asyncio from types import SimpleNamespace from typing import Any -from unittest.mock import AsyncMock, MagicMock, patch +from unittest.mock import AsyncMock, MagicMock import pytest diff --git a/backend/tests/test_browser_agent_unit.py b/backend/tests/test_browser_agent_unit.py index f8195a3e..2f0e7ef2 100644 --- a/backend/tests/test_browser_agent_unit.py +++ b/backend/tests/test_browser_agent_unit.py @@ -126,12 +126,6 @@ def test_hash_tool_call_falls_back_to_repr_on_serialization_failure(): """Self-referential dicts trip json.dumps even with default=str. The except branch must still return a (str, str, str) tuple.""" - class _Boom: - def __repr__(self) -> str: - return "" - - boom = _Boom() - # Self-referential dict — json.dumps raises ValueError with default=str bad_input: dict = {"x": 1} bad_input["self"] = bad_input diff --git a/backend/tests/test_disconnect_resilience.py b/backend/tests/test_disconnect_resilience.py index 38a567f3..7b65ea99 100644 --- a/backend/tests/test_disconnect_resilience.py +++ b/backend/tests/test_disconnect_resilience.py @@ -31,9 +31,7 @@ import asyncio import json import os import random -import sys import tempfile -from typing import Any from unittest.mock import patch import pytest diff --git a/backend/tests/test_mcp_preflight.py b/backend/tests/test_mcp_preflight.py index 90bb7133..62b8fd1d 100644 --- a/backend/tests/test_mcp_preflight.py +++ b/backend/tests/test_mcp_preflight.py @@ -24,9 +24,8 @@ Coverage targets: from __future__ import annotations import asyncio -import json from types import SimpleNamespace -from unittest.mock import AsyncMock, MagicMock, patch +from unittest.mock import AsyncMock, patch import pytest diff --git a/backend/tests/test_phase1_stress.py b/backend/tests/test_phase1_stress.py index efbb341c..46aff6a3 100644 --- a/backend/tests/test_phase1_stress.py +++ b/backend/tests/test_phase1_stress.py @@ -13,8 +13,7 @@ import os import random import string import tempfile -from typing import Any -from unittest.mock import patch, AsyncMock +from unittest.mock import patch import pytest diff --git a/backend/tests/test_service_legacy.py b/backend/tests/test_service_legacy.py index 1187f809..21803451 100644 --- a/backend/tests/test_service_legacy.py +++ b/backend/tests/test_service_legacy.py @@ -13,8 +13,6 @@ Run with: import json import os import tempfile -from unittest.mock import AsyncMock, MagicMock, patch -from uuid import uuid4 import pytest @@ -136,7 +134,7 @@ def last_sync(kind: str) -> dict: # Import application modules (after fixtures are wired). from backend.apps.service.client import record -from backend.apps.agents.models import AgentConfig, AgentSession, Message, ApprovalRequest +from backend.apps.agents.models import AgentConfig, Message from backend.apps.agents.agent_manager import AgentManager diff --git a/backend/tests/test_v2_invariants.py b/backend/tests/test_v2_invariants.py index 49a93b90..304ff1d0 100644 --- a/backend/tests/test_v2_invariants.py +++ b/backend/tests/test_v2_invariants.py @@ -24,10 +24,8 @@ import asyncio import json import os import random -import string import tempfile -from typing import Any -from unittest.mock import patch, AsyncMock, MagicMock +from unittest.mock import patch, AsyncMock import pytest diff --git a/backend/tests/test_v2_label_logic.py b/backend/tests/test_v2_label_logic.py index 6e7759ad..1e0a0913 100644 --- a/backend/tests/test_v2_label_logic.py +++ b/backend/tests/test_v2_label_logic.py @@ -16,7 +16,6 @@ from __future__ import annotations import random import re -import pytest # ===========================================================================