feat: фаза 3 (часть 1) — disclaimer, очередь, initiator + IP

3.6 UI: убрать stat-minibar и heatmap с дашборда
3.2 AI disclaimer под каждым LLM-вердиктом
3.4 LLM_MAX_CONCURRENT_ANALYSES + Semaphore в llm.py
3.1 Scan.initiator + source_ip, webhook захватывает, UI показывает
This commit is contained in:
Marker689
2026-05-10 07:32:14 +03:00
parent 0069331119
commit 4ae893a025
13 changed files with 69 additions and 52 deletions

View File

@@ -3,6 +3,7 @@
Supports any OpenAI-compatible API endpoint with configurable model.
"""
import asyncio
import json
import httpx
@@ -11,6 +12,8 @@ from ..config import config
from ..constants import LLM_ANALYSIS_SYSTEM_PROMPT
from ..logging_setup import log
_llm_semaphore = asyncio.Semaphore(config.llm_max_concurrent)
def _build_user_message(finding: dict) -> str:
"""Build a concise prompt from a finding's data."""
@@ -62,12 +65,13 @@ async def analyze_finding(finding_data: dict) -> dict | None:
}
try:
async with httpx.AsyncClient(
timeout=config.llm_timeout, headers=headers
) as client:
resp = await client.post(url, json=payload)
resp.raise_for_status()
body = resp.json()
async with _llm_semaphore:
async with httpx.AsyncClient(
timeout=config.llm_timeout, headers=headers
) as client:
resp = await client.post(url, json=payload)
resp.raise_for_status()
body = resp.json()
except httpx.TimeoutException:
log.error(
"LLM analysis timed out after %ds for rule=%s",