"""Feature D — KI-Test-Generierung (Vorschlag als PR-Kommentar). Per Slash-Command `/gen-tests` an einem PR (issue_comment) ODER aus einem pull_request-Event. Holt den Diff, lässt das LLM passende Unit-Tests vorschlagen und postet sie als idempotenten Kommentar. Bewusst NUR Vorschlag — kein Auto-Commit (der Mensch entscheidet, was übernommen wird). """ import sys import context import gitea_api import llm MARKER = "" DIFF_CAP = 30000 SYSTEM = ( "Du bist ein erfahrener Test-Engineer. Schlage sinnvolle, lauffähige Unit-Tests " "für die geänderten Stellen vor. Erkenne Sprache und Test-Framework aus dem Diff. " "Antworte auf Deutsch, Test-Code in passenden Code-Blöcken. Keine Tests für reine " "Trivialitäten; erfinde keine nicht vorhandenen APIs." ) PROMPT = """\ Generiere Unit-Tests für die Änderungen in diesem Pull-Request. PR-Titel: {title} Pro relevanter Datei/Funktion: ein kurzer Hinweis + der Test-Code (richtige Sprache, lauffähig, Framework benennen). Wenn nichts sinnvoll testbar ist, sag das ehrlich. --- DIFF --- {diff} """ def _pr_index(): pr = context.pull_request() if pr and pr.get("index"): return pr["index"], pr.get("title", "") iss = context.issue() if iss and iss.get("is_pr"): return iss["index"], iss.get("title", "") return None, "" def main() -> int: owner, repo = context.repo_slug() index, title = _pr_index() if not index: print("[ai_tests] Kein PR-Kontext — Test-Generierung läuft nur auf PRs. Übersprungen.") return 0 ok, why = llm.configured() if not ok: print(f"[ai_tests] KI inaktiv ({why}) — übersprungen, kein Fehler.") return 0 diff = gitea_api.get_pr_diff(owner, repo, index) if not diff.strip(): print("[ai_tests] Leerer Diff — nichts zu testen.") return 0 answer = llm.complete(SYSTEM, PROMPT.format(title=title, diff=diff[:DIFF_CAP]), max_tokens=2000) gitea_api.upsert_comment(owner, repo, index, MARKER, f"## 🧪 KI-Test-Vorschläge\n\n{answer}") print("[ai_tests] Kommentar gepostet/aktualisiert.") return 0 if __name__ == "__main__": sys.exit(main())