fix(audit): P0-P3 audit fixes — 838 ruff errors → 0, 30 F821 bugs fixed, 118 files changed

- P0: hooks.py 3-tuple fix, trigger_dispatcher Contract, contacts/plugin unregister_actions_by_owner
- P0: 5 test files — check_permission mocks removed, hardcoded DB credential → env var
- P1: attachment_service DmsFile via Contract helper, restore_registry/history_hooks dedup
- P1: mail/plugin restore unregister, mcp_client datetime.now(UTC), saved_views/filters patterns
- P1: ProtectedRoute fail-closed, 13 test assertion fixes (bcrypt, DB-URLs, SECRET_KEYs)
- P2: deprecated notifications → post_system_message (3 files), forgejo Base, report_generator lazy import
- P2: webhooks permissions, deps.py/roles.py plugin perms removed, import_export default
- P2: address/tags/entity_links patterns removed, worker.py Contract-Umgehungen fixed
- P2: 28 frontend TODOs (hardcoded constants, deprecated notification API)
- P3: dead code, duplicates, deprecated imports, private attr, __import__ inline
- P3: 8 frontend TODOs (LucideIcons, inline styles, XSS, i18n)
- ruff: 838 → 0 (612 auto-fix + 246 manual + 27 F821 regression fix)
- F821: 30 → 0 (AutomationDefinition, DmsFile, user_id, Path, Any, String)
- Contract-Umgehungen: 2 neue gefunden (worker.py:169, worker.py:280) und gefixt
This commit is contained in:
Agent Zero
2026-08-16 01:17:18 +02:00
parent 3d9b76cea4
commit abbe7a18fc
306 changed files with 5912 additions and 1827 deletions
+34 -8
View File
@@ -176,6 +176,18 @@ class AutomationPlugin(BasePlugin):
self._contributed_cron_jobs: dict[str, list[str]] = {} # plugin_name -> [cron_job_name, ...]
self._contributed_heartbeats: dict[str, list[str]] = {} # plugin_name -> [agent_name, ...]
def get_entity_models(self) -> dict[str, type]:
from app.plugins.builtins.automation.models import AgentDefinition, AutomationDefinition
return {"agent_definition": AgentDefinition, "automation_definition": AutomationDefinition}
def get_job_modules(self) -> list[str]:
return [
"app.plugins.builtins.automation.scheduler",
"app.plugins.builtins.automation.workflow_timeout",
"app.plugins.builtins.automation.agent_runner",
"app.plugins.builtins.automation.execution_engine",
]
async def on_activate(self, db, service_container, event_bus) -> None:
"""Register event listeners on activation."""
await super().on_activate(db, service_container, event_bus)
@@ -187,7 +199,9 @@ class AutomationPlugin(BasePlugin):
logger.exception("Failed to register agent communication tool")
# Register agent coordinator tools
try:
from app.plugins.builtins.automation.agent_coordinator import register_agent_coordinator_tools
from app.plugins.builtins.automation.agent_coordinator import (
register_agent_coordinator_tools,
)
register_agent_coordinator_tools()
except Exception:
logger.exception("Failed to register agent coordinator tools")
@@ -230,7 +244,9 @@ class AutomationPlugin(BasePlugin):
logger.exception("Failed to unregister agent communication tool")
# Unregister agent coordinator tools
try:
from app.plugins.builtins.automation.agent_coordinator import unregister_agent_coordinator_tools
from app.plugins.builtins.automation.agent_coordinator import (
unregister_agent_coordinator_tools,
)
unregister_agent_coordinator_tools()
except Exception:
logger.exception("Failed to unregister agent coordinator tools")
@@ -249,12 +265,16 @@ class AutomationPlugin(BasePlugin):
async def register_plugin_contributions(self, db, plugin_name: str, manifest) -> None:
"""Register agent definitions, automation templates, cron jobs, and heartbeat configs
from another plugin's manifest. Uses plugin name prefixing for conflict resolution."""
from app.plugins.builtins.automation.services import AgentService, AutomationService, CronJobService
from app.plugins.builtins.automation.models import AutomationCronJob
from sqlalchemy import select
# Get default tenant_id from the first tenant in the DB
from app.models.tenant import Tenant
from app.plugins.builtins.automation.models import AutomationCronJob
from app.plugins.builtins.automation.services import (
AgentService,
AutomationService,
CronJobService,
)
tenant_result = await db.execute(select(Tenant).limit(1))
tenant = tenant_result.scalar_one_or_none()
default_tenant_id = tenant.id if tenant else None
@@ -356,7 +376,11 @@ class AutomationPlugin(BasePlugin):
async def unregister_plugin_contributions(self, db, plugin_name: str) -> None:
"""Remove all contributed definitions from a plugin that is being deactivated."""
from app.plugins.builtins.automation.services import AgentService, AutomationService, CronJobService
from app.plugins.builtins.automation.services import (
AgentService,
AutomationService,
CronJobService,
)
# Remove contributed agents
agent_names = self._contributed_agents.pop(plugin_name, [])
@@ -384,8 +408,9 @@ class AutomationPlugin(BasePlugin):
cron_job_names = self._contributed_cron_jobs.pop(plugin_name, [])
for cron_name in cron_job_names:
try:
from app.plugins.builtins.automation.models import AutomationCronJob
from sqlalchemy import select
from app.plugins.builtins.automation.models import AutomationCronJob
result = await db.execute(
select(AutomationCronJob).where(AutomationCronJob.name == cron_name).limit(1)
)
@@ -411,9 +436,10 @@ class AutomationPlugin(BasePlugin):
async def ensure_ai_proactive_heartbeat(self, db) -> None:
"""Migrate the hardcoded ai_proactive heartbeat to a configurable cron job."""
from sqlalchemy import select
from app.plugins.builtins.automation.models import AutomationCronJob
from app.plugins.builtins.automation.services import CronJobService
from sqlalchemy import select
# Check if ai_proactive heartbeat cron job already exists
result = await db.execute(
@@ -456,4 +482,4 @@ class AutomationPlugin(BasePlugin):
async def on_workflow_timeout(self, payload: dict[str, Any]) -> None:
"""Handle workflow.timeout event — trigger matching automations."""
logger.debug("workflow.timeout event received: %s", payload)
logger.debug("workflow.timeout event received: %s", payload)