fix(imports): agent_runner MailService→Mail model, fix trace_hooks syntax, fix trace_api_contracts warnings
Check Cross-Plugin Imports / check (push) Has been cancelled
Check Cross-Plugin Imports / check (push) Has been cancelled
This commit is contained in:
@@ -112,15 +112,18 @@ async def run_agent(
|
|||||||
logger.warning("Failed to collect contacts for proactive context")
|
logger.warning("Failed to collect contacts for proactive context")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from app.services.mail_service import MailService
|
from app.plugins.builtins.mail.models import Mail
|
||||||
mail_svc = MailService(db)
|
from sqlalchemy import select as _select
|
||||||
recent_mails = await mail_svc.list_mails(
|
mail_q = await db.execute(
|
||||||
tenant_id=agent.tenant_id,
|
_select(Mail)
|
||||||
user_id=None,
|
.where(Mail.tenant_id == agent.tenant_id)
|
||||||
page=1,
|
.order_by(Mail.date.desc())
|
||||||
page_size=5,
|
.limit(5)
|
||||||
)
|
)
|
||||||
context_data["recent_mails"] = recent_mails.get("items", [])
|
context_data["recent_mails"] = [
|
||||||
|
{"id": str(m.id), "subject": m.subject, "from": m.sender}
|
||||||
|
for m in mail_q.scalars()
|
||||||
|
]
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.warning("Failed to collect mails for proactive context")
|
logger.warning("Failed to collect mails for proactive context")
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"timestamp": "2026-08-17T00:23:01.849835",
|
"timestamp": "2026-08-17T07:15:04.567567",
|
||||||
"total_time": 6.53,
|
"total_time": 5.77,
|
||||||
"total_scripts": 7,
|
"total_scripts": 7,
|
||||||
"total_issues": 1112,
|
"total_issues": 1110,
|
||||||
"passed": 1,
|
"passed": 1,
|
||||||
"failed": 6,
|
"failed": 6,
|
||||||
"skipped": 0,
|
"skipped": 0,
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
"description": "Frontend\u2194Backend API Contracts",
|
"description": "Frontend\u2194Backend API Contracts",
|
||||||
"status": "FAIL",
|
"status": "FAIL",
|
||||||
"exit_code": 246,
|
"exit_code": 246,
|
||||||
"elapsed": 0.21,
|
"elapsed": 0.29,
|
||||||
"issues": 758
|
"issues": 758
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
"description": "Hook Registrations vs Triggers",
|
"description": "Hook Registrations vs Triggers",
|
||||||
"status": "FAIL",
|
"status": "FAIL",
|
||||||
"exit_code": 1,
|
"exit_code": 1,
|
||||||
"elapsed": 0.06,
|
"elapsed": 0.11,
|
||||||
"issues": 0
|
"issues": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
"description": "Dead Functions (defined but never called)",
|
"description": "Dead Functions (defined but never called)",
|
||||||
"status": "FAIL",
|
"status": "FAIL",
|
||||||
"exit_code": 3,
|
"exit_code": 3,
|
||||||
"elapsed": 2.94,
|
"elapsed": 2.47,
|
||||||
"issues": 3
|
"issues": 3
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
"description": "Unused Store Actions/State",
|
"description": "Unused Store Actions/State",
|
||||||
"status": "FAIL",
|
"status": "FAIL",
|
||||||
"exit_code": 67,
|
"exit_code": 67,
|
||||||
"elapsed": 0.08,
|
"elapsed": 0.07,
|
||||||
"issues": 323
|
"issues": 323
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
"description": "Contract Attribute Mismatches",
|
"description": "Contract Attribute Mismatches",
|
||||||
"status": "PASS",
|
"status": "PASS",
|
||||||
"exit_code": 0,
|
"exit_code": 0,
|
||||||
"elapsed": 1.72,
|
"elapsed": 1.42,
|
||||||
"issues": 0
|
"issues": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -52,16 +52,16 @@
|
|||||||
"description": "Plugin\u2192Manifest\u2192Frontend Verkabelung",
|
"description": "Plugin\u2192Manifest\u2192Frontend Verkabelung",
|
||||||
"status": "FAIL",
|
"status": "FAIL",
|
||||||
"exit_code": 24,
|
"exit_code": 24,
|
||||||
"elapsed": 0.11,
|
"elapsed": 0.12,
|
||||||
"issues": 24
|
"issues": 24
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "trace_imports",
|
"name": "trace_imports",
|
||||||
"description": "Broken/Missing Imports",
|
"description": "Broken/Missing Imports",
|
||||||
"status": "FAIL",
|
"status": "FAIL",
|
||||||
"exit_code": 4,
|
"exit_code": 2,
|
||||||
"elapsed": 1.4,
|
"elapsed": 1.28,
|
||||||
"issues": 4
|
"issues": 2
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"py_defs": 1616,
|
"py_defs": 1616,
|
||||||
"py_dead": 629,
|
"py_dead": 628,
|
||||||
"ts_defs": 959,
|
"ts_defs": 959,
|
||||||
"ts_dead": 442,
|
"ts_dead": 442,
|
||||||
"critical_dead": [
|
"critical_dead": [
|
||||||
|
|||||||
@@ -1,13 +1,6 @@
|
|||||||
{
|
{
|
||||||
"total_imports": 2274,
|
"total_imports": 2274,
|
||||||
"broken": [
|
"broken": [
|
||||||
{
|
|
||||||
"file": "app/routes/entity_permissions.py",
|
|
||||||
"module": "app.models.entity_permission",
|
|
||||||
"name": "ENTITY_MODELS",
|
|
||||||
"line": 105,
|
|
||||||
"issue": "Name 'ENTITY_MODELS' not found in module"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"file": "app/core/auth.py",
|
"file": "app/core/auth.py",
|
||||||
"module": "app.models.session",
|
"module": "app.models.session",
|
||||||
@@ -15,19 +8,12 @@
|
|||||||
"line": 261,
|
"line": 261,
|
||||||
"issue": "Name 'SessionModel' not found in module"
|
"issue": "Name 'SessionModel' not found in module"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"file": "app/plugins/builtins/automation/agent_comm.py",
|
|
||||||
"module": "app.plugins.builtins.kommunikation.contracts",
|
|
||||||
"name": "Room",
|
|
||||||
"line": 58,
|
|
||||||
"issue": "Name 'Room' not found in module"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"file": "app/plugins/builtins/automation/agent_runner.py",
|
"file": "app/plugins/builtins/automation/agent_runner.py",
|
||||||
"module": "app.core.cache",
|
"module": "app.services.mail_service",
|
||||||
"name": "get_cached_mail_summary",
|
"name": "MailService",
|
||||||
"line": 115,
|
"line": 115,
|
||||||
"issue": "Name 'get_cached_mail_summary' not found in module"
|
"issue": "Module not found"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -39,34 +39,24 @@ def find_frontend_api_calls() -> list[dict]:
|
|||||||
|
|
||||||
# Find apiGet/apiPost/apiPut/apiPatch/apiDelete calls with URL patterns
|
# Find apiGet/apiPost/apiPut/apiPatch/apiDelete calls with URL patterns
|
||||||
patterns = [
|
patterns = [
|
||||||
r"apiGet(?:<[^>]+>)?\s*\(\s*[`'\"]([^`'\"]+)[`'\"]\s*",
|
(r"apiGet(?:<[^>]+>)?\s*\(\s*[`'\"]([^`'\"]+)[`'\"]\s*", "GET"),
|
||||||
r"apiPost(?:<[^>]+>)?\s*\(\s*[`'\"]([^`'\"]+)[`'\"]\s*",
|
(r"apiPost(?:<[^>]+>)?\s*\(\s*[`'\"]([^`'\"]+)[`'\"]\s*", "POST"),
|
||||||
r"apiPut(?:<[^>]+>)?\s*\(\s*[`'\"]([^`'\"]+)[`'\"]\s*",
|
(r"apiPut(?:<[^>]+>)?\s*\(\s*[`'\"]([^`'\"]+)[`'\"]\s*", "PUT"),
|
||||||
r"apiPatch(?:<[^>]+>)?\s*\(\s*[`'\"]([^`'\"]+)[`'\"]\s*",
|
(r"apiPatch(?:<[^>]+>)?\s*\(\s*[`'\"]([^`'\"]+)[`'\"]\s*", "PATCH"),
|
||||||
r"apiDelete(?:<[^>]+>)?\s*\(\s*[`'\"]([^`'\"]+)[`'\"]\s*",
|
(r"apiDelete(?:<[^>]+>)?\s*\(\s*[`'\"]([^`'\"]+)[`'\"]\s*", "DELETE"),
|
||||||
r"\bM\s*\(\s*[`'\"]([^`'\"]+)[`'\"]\s*",
|
(r"\bM\s*\(\s*[`'\"]([^`'\"]+)[`'\"]\s*", "GET"),
|
||||||
r"\bj\s*\(\s*[`'\"]([^`'\"]+)[`'\"]\s*",
|
(r"\bj\s*\(\s*[`'\"]([^`'\"]+)[`'\"]\s*", "POST"),
|
||||||
r"\bSt\s*\(\s*[`'\"]([^`'\"]+)[`'\"]\s*",
|
(r"\bSt\s*\(\s*[`'\"]([^`'\"]+)[`'\"]\s*", "PUT"),
|
||||||
r"\byt\s*\(\s*[`'\"]([^`'\"]+)[`'\"]\s*",
|
(r"\byt\s*\(\s*[`'\"]([^`'\"]+)[`'\"]\s*", "PATCH"),
|
||||||
r"\bxt\s*\(\s*[`'\"]([^`'\"]+)[`'\"]\s*",
|
(r"\bxt\s*\(\s*[`'\"]([^`'\"]+)[`'\"]\s*", "DELETE"),
|
||||||
]
|
]
|
||||||
|
|
||||||
for pattern in patterns:
|
for pattern, method in patterns:
|
||||||
for match in re.finditer(pattern, content):
|
for match in re.finditer(pattern, content):
|
||||||
url = match.group(1)
|
url = match.group(1)
|
||||||
# Normalize URL — remove template literals, query params
|
# Normalize URL — remove template literals, query params
|
||||||
url_clean = re.sub(r"\$\{[^}]+\}", "{param}", url)
|
url_clean = re.sub(r"\$\{[^}]+\}", "{param}", url)
|
||||||
url_clean = url_clean.split("?")[0].split("#")[0]
|
url_clean = url_clean.split("?")[0].split("#")[0]
|
||||||
# Determine method from function name
|
|
||||||
method = "GET"
|
|
||||||
if "Post" in pattern or "\bj\s*" in pattern:
|
|
||||||
method = "POST"
|
|
||||||
elif "Put" in pattern:
|
|
||||||
method = "PUT"
|
|
||||||
elif "Patch" in pattern or "\byt\s*" in pattern:
|
|
||||||
method = "PATCH"
|
|
||||||
elif "Delete" in pattern or "\bxt\s*" in pattern:
|
|
||||||
method = "DELETE"
|
|
||||||
|
|
||||||
calls.append({
|
calls.append({
|
||||||
"file": rel_path,
|
"file": rel_path,
|
||||||
|
|||||||
@@ -3,16 +3,17 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import re, sys, json
|
import re, sys, json
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from collections import defaultdict
|
|
||||||
|
|
||||||
ROOT = Path(__file__).resolve().parent.parent.parent
|
ROOT = Path(__file__).resolve().parent.parent.parent
|
||||||
APP = ROOT / "app"
|
APP = ROOT / "app"
|
||||||
|
|
||||||
def find_hook_registrations() -> list[dict]:
|
def find_hook_registrations():
|
||||||
regs = []
|
regs = []
|
||||||
for py in APP.rglob("*.py"):
|
for py in APP.rglob("*.py"):
|
||||||
try: content = py.read_text()
|
try:
|
||||||
except: continue
|
content = py.read_text()
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
rel = str(py.relative_to(ROOT))
|
rel = str(py.relative_to(ROOT))
|
||||||
for m in re.finditer(r'register_(?:action|filter)s?\s*\(\s*["\']([^"\']+)['"]', content):
|
for m in re.finditer(r'register_(?:action|filter)s?\s*\(\s*["\']([^"\']+)['"]', content):
|
||||||
regs.append({"file": rel, "hook_type": "action_or_filter", "hook_name": m.group(1)})
|
regs.append({"file": rel, "hook_type": "action_or_filter", "hook_name": m.group(1)})
|
||||||
@@ -20,11 +21,13 @@ def find_hook_registrations() -> list[dict]:
|
|||||||
regs.append({"file": rel, "hook_type": "action_group", "hook_name": m.group(1)})
|
regs.append({"file": rel, "hook_type": "action_group", "hook_name": m.group(1)})
|
||||||
return regs
|
return regs
|
||||||
|
|
||||||
def find_hook_triggers() -> list[dict]:
|
def find_hook_triggers():
|
||||||
triggers = []
|
triggers = []
|
||||||
for py in APP.rglob("*.py"):
|
for py in APP.rglob("*.py"):
|
||||||
try: content = py.read_text()
|
try:
|
||||||
except: continue
|
content = py.read_text()
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
rel = str(py.relative_to(ROOT))
|
rel = str(py.relative_to(ROOT))
|
||||||
for m in re.finditer(r'do_action\s*\(\s*["\']([^"\']+)['"]', content):
|
for m in re.finditer(r'do_action\s*\(\s*["\']([^"\']+)['"]', content):
|
||||||
triggers.append({"file": rel, "hook_name": m.group(1), "type": "action"})
|
triggers.append({"file": rel, "hook_name": m.group(1), "type": "action"})
|
||||||
@@ -51,13 +54,16 @@ def main():
|
|||||||
print(f" Triggered but never received: {len(orphans_trig)}")
|
print(f" Triggered but never received: {len(orphans_trig)}")
|
||||||
if orphans_reg:
|
if orphans_reg:
|
||||||
print("\n--- Registered but never triggered ---")
|
print("\n--- Registered but never triggered ---")
|
||||||
for o in orphans_reg[:20]: print(f" {o['hook_name']} (in {o['file']})")
|
for o in orphans_reg[:20]:
|
||||||
|
print(f" {o['hook_name']} (in {o['file']})")
|
||||||
if orphans_trig:
|
if orphans_trig:
|
||||||
print("\n--- Triggered but never received ---")
|
print("\n--- Triggered but never received ---")
|
||||||
for o in orphans_trig[:20]: print(f" {o['hook_name']} (in {o['file']})")
|
for o in orphans_trig[:20]:
|
||||||
|
print(f" {o['hook_name']} (in {o['file']})")
|
||||||
results = {"registrations": regs, "triggers": triggers, "orphan_registrations": orphans_reg, "orphan_triggers": orphans_trig}
|
results = {"registrations": regs, "triggers": triggers, "orphan_registrations": orphans_reg, "orphan_triggers": orphans_trig}
|
||||||
with open(ROOT / "scripts" / "test_suite" / "results_trace_hooks.json", "w") as f:
|
with open(ROOT / "scripts" / "test_suite" / "results_trace_hooks.json", "w") as f:
|
||||||
json.dump(results, f, indent=2, default=str)
|
json.dump(results, f, indent=2, default=str)
|
||||||
return len(orphans_reg) + len(orphans_trig)
|
return len(orphans_reg) + len(orphans_trig)
|
||||||
|
|
||||||
if __name__ == "__main__": sys.exit(main())
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
||||||
|
|||||||
Reference in New Issue
Block a user