File size: 6,833 Bytes
4346e8f
 
 
 
 
 
 
 
 
9438a57
 
4346e8f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9438a57
4346e8f
 
 
9438a57
4346e8f
 
 
9438a57
 
 
 
 
 
 
 
4346e8f
 
 
9438a57
 
4346e8f
 
 
 
 
 
9438a57
 
4346e8f
9438a57
4346e8f
9438a57
 
 
 
4346e8f
 
 
 
 
9438a57
4346e8f
 
 
 
9438a57
 
4346e8f
 
 
 
 
 
 
 
9438a57
4346e8f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9438a57
 
4346e8f
9438a57
 
 
 
 
 
4346e8f
 
9438a57
4346e8f
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#!/usr/bin/env python3
"""Komut satırından toplu değerlendirme ve başarım raporu üretimi.

Örnekler:
  python scripts/run_benchmark.py --model qwen2.5-coder:7b
  python scripts/run_benchmark.py --model qwen2.5-coder:7b --model llama3.1:8b --max-iterations 4
  python scripts/run_benchmark.py --languages python java --items py-bank java-calc
  python scripts/run_benchmark.py --model qwen2.5-coder:7b --max-iterations 1   # geri beslemesiz taban çizgisi
  python scripts/run_benchmark.py --reference      # insan yazımı referans testlerle ölçüm (LLM gerekmez)
  python scripts/run_benchmark.py --model qwen2.5-coder:14b --split test --repeats 3
  python scripts/run_benchmark.py --model qwen2.5-coder:14b --ablate judge   # hakem kapalı ablasyon
"""
from __future__ import annotations

import argparse
import json
import sys
import time
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "backend"))

from app.eval import benchmark  # noqa: E402
from app.eval.report import render  # noqa: E402
from app.llm.ollama import OllamaClient  # noqa: E402


def main() -> None:
    ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
    ap.add_argument("--model", action="append", help="Model (birden çok verilebilir): Ollama adı ya da openai:<model> / anthropic:<model>")
    ap.add_argument("--languages", nargs="*")
    ap.add_argument("--items", nargs="*", help="benchmarks/manifest.json içindeki id'ler")
    ap.add_argument("--max-iterations", type=int, default=4)
    ap.add_argument("--max-mutants", type=int, default=30)
    ap.add_argument("--coverage-target", type=float, default=85)
    ap.add_argument("--temperature", type=float, default=0.2)
    ap.add_argument("--no-mutation", action="store_true")
    ap.add_argument("--split", choices=["dev", "test", "bagimsiz", "all"], default="all",
                    help="dev: geliştirmede kullanılan, test: geliştirmede görülmemiş, "
                         "bagimsiz: üçüncü kişilerce yazılmış (QuixBugs) öğeler")
    ap.add_argument("--repeats", type=int, default=1, help="her öğe kaç kez koşulsun (rastgelelik için)")
    ap.add_argument("--ablate", nargs="*", default=[],
                    choices=["judge", "prune", "restart", "repair", "planfree", "best", "mutfix"],
                    help="kapatılacak mekanizmalar (ablasyon)")
    ap.add_argument("--label", default="", help="rapora yazılacak yapılandırma etiketi")
    ap.add_argument("--reference", action="store_true",
                    help="LLM yerine benchmarks/reference altındaki insan yazımı testleri kullan (taban çizgisi)")
    ap.add_argument("--out", default=str(ROOT / "reports" / "LLM_SONUCLARI.md"))
    ap.add_argument("--report-lang", choices=["tr", "en"], default="tr",
                    help="Markdown raporunun dili (ajan istemlerini değiştirmez)")
    args = ap.parse_args()

    if args.reference:
        run_reference(args)
        return

    from app.llm import providers
    models = args.model or [OllamaClient().model]
    health = OllamaClient().health()
    if not health["ok"] and any(providers.is_local(m) for m in models):
        sys.exit(f"Ollama'ya ulaşılamadı: {health.get('error')}\n`ollama serve` çalışıyor mu?")
    for p in providers.CLOUD:
        if providers.configured(p) and any(providers.provider_of(m) == p for m in models):
            providers.sync(p)
    missing = [m for m in models if not providers.available(m, health.get("models", []))]
    if missing:
        sys.exit(f"Model(ler) yüklü değil: {missing}. Önce: ollama pull {missing[0]}")

    cfg = {"max_iterations": args.max_iterations, "max_mutants": args.max_mutants,
           "coverage_target": args.coverage_target, "temperature": args.temperature,
           "run_mutation": not args.no_mutation, "ablate": args.ablate}
    evals = []
    for model in models:
        print(f"\n=== {model} ===")
        t0 = time.time()
        ev = benchmark.run_eval(model, cfg, args.items, args.languages, background=False,
                                split=args.split, repeats=args.repeats, label=args.label)
        for it in ev.items:
            print(f"  {it.id:<16} {it.status:<7} kapsama={it.final_coverage} mutasyon={it.mutation_score} "
                  f"yerleştirilmiş={it.seeded_caught}/{it.seeded_total} tur={it.iterations} {it.error}")
        print(f"  süre: {time.time() - t0:.0f} sn")
        evals.append(ev)

    out = Path(args.out)
    out.parent.mkdir(parents=True, exist_ok=True)
    out.write_text(render(evals, lang=args.report_lang), encoding="utf-8")
    out.with_suffix(".json").write_text(json.dumps([e.model_dump() for e in evals], ensure_ascii=False, indent=2))
    print(f"\nRapor: {out}")


def run_reference(args) -> None:
    """İnsan yazımı referans test paketleriyle aynı ölçüm hattını koşar (altyapı doğrulaması + taban çizgisi)."""
    from app.llm.scripted import ScriptedLLM, text, tool

    items = {i["id"]: i for i in benchmark.load_manifest() if i.get("reference_tests")}
    ids = [i for i in (args.items or items) if i in items]

    from app.sandbox.registry import get_runner
    junit4 = get_runner("java").framework() == "junit4"

    def factory(item):
        key = "reference_tests_junit4" if junit4 and item.get("reference_tests_junit4") else "reference_tests"
        ref = (benchmark.BENCH_DIR / item[key]).read_text(encoding="utf-8")
        return ScriptedLLM([text('{"summary": "insan yazımı referans test paketi"}'),
                            tool("write_tests", code=ref), tool("finish", summary="referans")], model="referans")

    cfg = {"max_iterations": 1, "max_mutants": args.max_mutants, "coverage_target": args.coverage_target,
           "run_mutation": not args.no_mutation}
    ev = benchmark.run_eval("referans (insan yazımı)", cfg, ids, None, background=False, llm_factory=factory,
                            split=args.split, label="referans")
    for it in ev.items:
        green = "" if it.final_pass_rate == 100.0 else f"  UYARI: referans paket yeşil değil (geçen %{it.final_pass_rate})"
        print(f"  {it.id:<16} {it.split:<4} {it.status:<7} kapsama={it.final_coverage} mutasyon={it.mutation_score} "
              f"yerleştirilmiş={it.seeded_caught}/{it.seeded_total} {it.error}{green}")
    out = Path(args.out)
    if out.name == "LLM_SONUCLARI.md":
        out = out.with_name("REFERANS_TABAN_CIZGISI.md")
    out.parent.mkdir(parents=True, exist_ok=True)
    out.write_text(render([ev], title="Referans (insan yazımı) taban çizgisi"), encoding="utf-8")
    out.with_suffix(".json").write_text(json.dumps([ev.model_dump()], ensure_ascii=False, indent=2))
    print(f"Rapor: {out}")


if __name__ == "__main__":
    main()