Dateien nach "/" hochladen
This commit is contained in:
1 parent
387779a4ef
commit
d47d039331
1 file changed
+49
-8
@@ -25,6 +25,7 @@ import tempfile
|
||||
import threading
|
||||
import time
|
||||
import urllib.request
|
||||
import zipfile
|
||||
from datetime import datetime
|
||||
from functools import wraps
|
||||
from pathlib import Path
|
||||
@@ -208,10 +209,43 @@ def normalize_components(raw_components: list) -> list:
|
||||
return normalized
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Anfang der eigentlichen Skill-Datei (Name/Beschreibung/Einleitung) holen –
|
||||
# getrennt von SkillSpectors eigenem Scan, nur um der KI echten Kontext für
|
||||
# den "Wofür ist das?"-Absatz zu geben statt nur der Sicherheitsfunde.
|
||||
# --------------------------------------------------------------------------- #
|
||||
def extract_skill_context(target: str, is_zip: bool, work_dir: str) -> str:
|
||||
context_dir = Path(work_dir) / "context_extract"
|
||||
try:
|
||||
context_dir.mkdir(exist_ok=True)
|
||||
if is_zip:
|
||||
with zipfile.ZipFile(target) as zf:
|
||||
zf.extractall(context_dir)
|
||||
else:
|
||||
subprocess.run(
|
||||
["git", "clone", "--depth", "1", target, str(context_dir / "repo")],
|
||||
timeout=60,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
candidates = (
|
||||
list(context_dir.rglob("SKILL.md"))
|
||||
or list(context_dir.rglob("skill.md"))
|
||||
or list(context_dir.rglob("README.md"))
|
||||
)
|
||||
if not candidates:
|
||||
return ""
|
||||
return candidates[0].read_text(errors="ignore")[:3000]
|
||||
except Exception:
|
||||
return ""
|
||||
finally:
|
||||
shutil.rmtree(context_dir, ignore_errors=True)
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Deutsche Klartext-Zusammenfassung des Reports per LLM (OpenRouter-kompatibel)
|
||||
# --------------------------------------------------------------------------- #
|
||||
def generate_report_summary(result: dict) -> str | None:
|
||||
def generate_report_summary(result: dict, skill_context: str = "") -> str | None:
|
||||
if not OPENAI_API_KEY:
|
||||
return None
|
||||
|
||||
@@ -243,16 +277,20 @@ def generate_report_summary(result: dict) -> str | None:
|
||||
|
||||
prompt = (
|
||||
"Du bekommst das JSON-Ergebnis eines automatisierten Sicherheits-Scans für einen "
|
||||
"AI-Agent-Skill. Schreibe auf Deutsch einen kurzen, laienverständlichen Bericht für "
|
||||
"jemanden ohne Security-Hintergrund, als Fließtext in 4 kurzen Absätzen, getrennt "
|
||||
"durch eine Leerzeile (keine Überschriften, keine Code-Blöcke, keine Aufzählungszeichen):\n"
|
||||
"Absatz 1: Wofür dieser Skill laut den vorliegenden Daten (Dateinamen, Metadaten, "
|
||||
"Fundtexte) gedacht ist – 1-2 Sätze. Falls der Zweck nicht erkennbar ist, schreibe "
|
||||
"das ehrlich so.\n"
|
||||
"AI-Agent-Skill, sowie (falls vorhanden) den Anfang der eigentlichen Skill-Datei. "
|
||||
"Schreibe auf Deutsch einen kurzen, laienverständlichen Bericht für jemanden ohne "
|
||||
"Security-Hintergrund, als Fließtext in 4 kurzen Absätzen, getrennt durch eine "
|
||||
"Leerzeile (keine Überschriften, keine Code-Blöcke, keine Aufzählungszeichen):\n"
|
||||
"Absatz 1: Wofür dieser Skill gedacht ist – nutze dafür in erster Linie den Auszug "
|
||||
"aus der Skill-Datei (Name/Beschreibung/Einleitung), 1-2 Sätze. Nur falls kein "
|
||||
"Auszug vorliegt oder daraus kein Zweck erkennbar ist, stütze dich ersatzweise auf "
|
||||
"Dateinamen und Fundtexte aus dem Scan-Ergebnis; ist auch daraus nichts erkennbar, "
|
||||
"schreibe das ehrlich so.\n"
|
||||
"Absatz 2: Gesamteinschätzung des Risikos in 1-2 Sätzen.\n"
|
||||
"Absatz 3: Die wichtigsten Funde in einfachen Worten, ohne unerklärte Fachbegriffe.\n"
|
||||
"Absatz 4: Konkrete Handlungsempfehlung (bedenkenlos nutzbar / mit Vorsicht "
|
||||
"nutzbar / besser nicht installieren) und eine kurze Begründung warum.\n\n"
|
||||
f"Auszug aus der Skill-Datei:\n{skill_context or '(kein Auszug verfügbar)'}\n\n"
|
||||
f"Scan-Ergebnis:\n{json.dumps(compact, ensure_ascii=False)}"
|
||||
)
|
||||
|
||||
@@ -561,7 +599,10 @@ def index():
|
||||
summary_text = None
|
||||
summary_failed = False
|
||||
if use_llm:
|
||||
summary_text = generate_report_summary(result)
|
||||
skill_context = extract_skill_context(
|
||||
target, is_zip=bool(zip_file and zip_file.filename), work_dir=work_dir
|
||||
)
|
||||
summary_text = generate_report_summary(result, skill_context)
|
||||
summary_failed = summary_text is None
|
||||
|
||||
target_label = git_url if git_url else (zip_file.filename if zip_file else "-")
|
||||
|
||||
Reference in new issue
Block a user