File size: 5,658 Bytes
40d87e9
a1da5fa
 
 
 
 
 
 
 
 
40d87e9
a1da5fa
40d87e9
 
a1da5fa
 
 
 
40d87e9
 
a1da5fa
 
 
 
40d87e9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a1da5fa
 
 
 
40d87e9
a1da5fa
40d87e9
a1da5fa
 
 
 
 
40d87e9
 
 
a1da5fa
40d87e9
 
 
a1da5fa
40d87e9
 
 
 
 
 
 
 
 
 
a1da5fa
 
 
 
 
 
40d87e9
 
 
 
 
 
 
 
 
 
 
 
 
a1da5fa
 
 
 
40d87e9
 
 
a1da5fa
40d87e9
 
 
 
a1da5fa
 
40d87e9
 
a1da5fa
 
40d87e9
a1da5fa
 
 
40d87e9
 
 
 
a1da5fa
40d87e9
 
 
 
 
a1da5fa
 
 
40d87e9
a1da5fa
40d87e9
 
 
 
 
a1da5fa
 
 
 
 
40d87e9
 
 
 
a1da5fa
 
 
 
 
 
 
 
 
 
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
"""HTML report for System One vs Laya vs DeepSeek comparison."""
from __future__ import annotations

import html


def _esc(s) -> str:
    return html.escape(str(s) if s is not None else "")


def _bar(probs, options, chosen_index, fill_class="bar-fill"):
    parts = []
    for i, (p, label) in enumerate(zip(probs or [], options or [])):
        w = max(2, int(float(p) * 100))
        hot = i == chosen_index
        parts.append(
            f'<div class="bar-row{" hot" if hot else ""}">'
            f'<span class="bar-label">{_esc(label)}</span>'
            f'<span class="bar-track"><span class="{fill_class}" style="width:{w}%"></span></span>'
            f'<span class="bar-pct">{float(p) * 100:.1f}%</span></div>'
        )
    return "".join(parts)


def _choice_of(block: dict | None) -> tuple[str, float]:
    if not block:
        return "—", 0.0
    return str(block.get("chosen") or "—"), float(block.get("conf") or 0.0)


def _norm(s: str | None) -> str:
    return (s or "").strip().lower()


def _agree_pill(a: str | None, b: str | None, label: str) -> str:
    if not a or not b or a == "—" or b == "—":
        return f'<span class="pill muted">{_esc(label)}: —</span>'
    if _norm(a) == _norm(b):
        return f'<span class="pill ok">{_esc(label)}: match</span>'
    return f'<span class="pill warn">{_esc(label)}: differ</span>'


def render_report(jev: dict, laya: dict, deepseek: dict, qs: list[dict]) -> str:
    from deepseek_lane import answers_by_id

    ds_answers = answers_by_id(deepseek.get("validation") or {})
    jev_qs = {b["id"]: b for b in (jev.get("questions") or [])}
    laya_qs = {b["id"]: b for b in (laya.get("questions") or [])}

    all3 = 0
    comparable = 0
    rows = []
    for q in qs:
        jid = q["id"]
        jb = jev_qs.get(jid)
        lb = laya_qs.get(jid)
        j_choice, j_conf = _choice_of(jb)
        l_choice, l_conf = _choice_of(lb)
        ds_val = ds_answers.get(jid)

        picks = [p for p in (j_choice, l_choice, ds_val) if p and p != "—"]
        if len(picks) >= 2:
            comparable += 1
            if len({_norm(p) for p in picks}) == 1 and len(picks) == 3:
                all3 += 1

        j_bars = _bar(jb["probs"], jb["options"], jb["chosen_index"]) if jb else ""
        l_bars = (
            _bar(lb["probs"], lb["options"], lb["chosen_index"], fill_class="bar-fill laya")
            if lb
            else ""
        )

        ds_status = ""
        for a in (deepseek.get("validation") or {}).get("answers") or []:
            if a["id"] == jid:
                ds_status = a["status"]
                break

        pills = " ".join(
            [
                _agree_pill(j_choice, l_choice, "S1↔Laya"),
                _agree_pill(j_choice, ds_val, "S1↔DS"),
                _agree_pill(l_choice, ds_val, "Laya↔DS"),
            ]
        )

        jev_err = ""
        laya_body = l_bars
        if laya.get("error") and not lb:
            laya_body = f'<p class="meta err">{_esc(laya.get("error"))}</p>'

        rows.append(
            f'<article class="q-card">'
            f'<h3>{_esc(jid)} · {_esc(q["type"])}</h3>'
            f'<p class="q-text">{_esc(q["question"])}</p>'
            f'<div class="cols3">'
            f'<div class="lane jev"><div class="lane-title">System One</div>'
            f'{j_bars or jev_err}'
            f'<p class="pick">→ <b>{_esc(j_choice)}</b> ({j_conf * 100:.1f}%)</p></div>'
            f'<div class="lane laya"><div class="lane-title">Laya</div>'
            f'{laya_body}'
            f'<p class="pick">→ <b>{_esc(l_choice)}</b> ({l_conf * 100:.1f}%)</p></div>'
            f'<div class="lane ds"><div class="lane-title">DeepSeek (API)</div>'
            f'<p class="pick">→ <b>{_esc(ds_val or "—")}</b>'
            f' <span class="status">{_esc(ds_status)}</span></p>'
            f'<div class="pills">{pills}</div></div>'
            f"</div></article>"
        )

    ratio = f"{all3}/{comparable}" if comparable else "—"
    plan = jev.get("plan") or {}
    warn = ""
    if plan.get("beyond_train_len"):
        warn += (
            '<p class="warn">State exceeds System One training length (384 tokens) — '
            "treat S1 probabilities as exploratory.</p>"
        )
    if plan.get("truncated"):
        warn += '<p class="warn">State was truncated to fit the System One scorer limit.</p>'
    if jev.get("error"):
        warn += f'<p class="warn">System One: {_esc(jev["error"])}</p>'
    if laya.get("error"):
        warn += f'<p class="warn">Laya: {_esc(laya["error"])}</p>'

    ds_err = deepseek.get("error")
    ds_meta = (
        f'<p class="meta err">DeepSeek: {_esc(ds_err)}</p>'
        if ds_err
        else (
            f'<p class="meta">DeepSeek: {_esc(deepseek.get("route", ""))} · '
            f'valid JSON {deepseek.get("validation", {}).get("n_valid", 0)}/{len(qs)} · '
            f'Laya: {_esc(laya.get("checkpoint", "—"))}</p>'
        )
    )

    return f"""
<div class="jev-report">
  <div class="stats">
    <div class="stat y"><div class="n">{jev.get("total_ms", 0):.0f} ms</div><div class="l">System One</div></div>
    <div class="stat g"><div class="n">{laya.get("total_ms", 0):.0f} ms</div><div class="l">Laya</div></div>
    <div class="stat b"><div class="n">{deepseek.get("latency_ms", 0):.0f} ms</div><div class="l">DeepSeek API</div></div>
    <div class="stat p"><div class="n">{ratio}</div><div class="l">All-3 agree</div></div>
  </div>
  {warn}
  {ds_meta}
  {"".join(rows)}
</div>
"""


def render_error(msg: str) -> str:
    return f'<div class="jev-report"><p class="meta err">{_esc(msg)}</p></div>'