HerrHruby commited on
Commit
cfeedf8
·
verified ·
1 Parent(s): 602ca09

Upload viewer

Browse files
Files changed (1) hide show
  1. index.html +290 -17
index.html CHANGED
@@ -1,19 +1,292 @@
1
  <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  </html>
 
1
  <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>SFT v4 Dataset Viewer</title>
7
+ <link rel="stylesheet" href="vendor/katex.min.css" />
8
+ <script src="vendor/katex.min.js"></script>
9
+ <script src="vendor/marked.min.js"></script>
10
+ <style>
11
+ :root{
12
+ --bg:#fbfbfd; --panel:#fff; --ink:#16181d; --muted:#5d6470; --line:#e3e6ec;
13
+ --accent:#3b5bdb; --accent-soft:#eef2ff; --mr:#7048e8; --mr-soft:#f3f0ff;
14
+ --exec:#0b7285; --exec-soft:#e7f5f8; --warn:#c92a2a; --ok:#2b8a3e;
15
+ --code:#f4f5f8;
16
+ }
17
+ @media (prefers-color-scheme: dark){
18
+ :root:not([data-theme="light"]){
19
+ --bg:#101216; --panel:#171a20; --ink:#e6e8ec; --muted:#9aa2b1; --line:#272b33;
20
+ --accent:#8ea2ff; --accent-soft:#1c2333; --mr:#b197fc; --mr-soft:#221c33;
21
+ --exec:#66d9e8; --exec-soft:#12262b; --warn:#ff8787; --ok:#69db7c;
22
+ --code:#1c2027;
23
+ }
24
+ }
25
+ :root[data-theme="dark"]{
26
+ --bg:#101216; --panel:#171a20; --ink:#e6e8ec; --muted:#9aa2b1; --line:#272b33;
27
+ --accent:#8ea2ff; --accent-soft:#1c2333; --mr:#b197fc; --mr-soft:#221c33;
28
+ --exec:#66d9e8; --exec-soft:#12262b; --warn:#ff8787; --ok:#69db7c;
29
+ --code:#1c2027;
30
+ }
31
+ *{box-sizing:border-box}
32
+ body{margin:0;background:var(--bg);color:var(--ink);
33
+ font:15px/1.62 ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif}
34
+ header{position:sticky;top:0;z-index:20;background:var(--panel);
35
+ border-bottom:1px solid var(--line);padding:12px 20px;
36
+ display:flex;gap:16px;align-items:baseline;flex-wrap:wrap}
37
+ header h1{margin:0;font-size:16px;letter-spacing:-.01em}
38
+ header .sub{color:var(--muted);font-size:13px}
39
+ header .spacer{flex:1}
40
+ .layout{display:grid;grid-template-columns:290px minmax(0,1fr);gap:0;
41
+ align-items:start;min-height:calc(100vh - 52px)}
42
+ @media (max-width:900px){ .layout{grid-template-columns:1fr} #side{position:static;height:auto;max-height:none;border-right:0;border-bottom:1px solid var(--line)} }
43
+ #side{position:sticky;top:52px;height:calc(100vh - 52px);overflow-y:auto;
44
+ border-right:1px solid var(--line);background:var(--panel);padding:10px}
45
+ .item{padding:9px 10px;border-radius:8px;cursor:pointer;border:1px solid transparent}
46
+ .item:hover{background:var(--accent-soft)}
47
+ .item.on{background:var(--accent-soft);border-color:var(--accent)}
48
+ .item .pid{font:12px/1.35 ui-monospace,SFMono-Regular,Menlo,monospace;
49
+ word-break:break-all;color:var(--ink)}
50
+ .item .meta{margin-top:3px;display:flex;gap:6px;flex-wrap:wrap}
51
+ .tag{font-size:11px;padding:1px 7px;border-radius:999px;border:1px solid var(--line);
52
+ color:var(--muted);white-space:nowrap}
53
+ .tag.d{background:var(--accent-soft);border-color:transparent;color:var(--accent)}
54
+ .tag.s{background:var(--exec-soft);border-color:transparent;color:var(--exec)}
55
+ .tag.cap{background:var(--mr-soft);border-color:transparent;color:var(--mr)}
56
+ main{padding:20px;min-width:0;max-width:1080px}
57
+ .card{background:var(--panel);border:1px solid var(--line);border-radius:12px;
58
+ padding:16px 18px;margin-bottom:14px}
59
+ h2{font-size:15px;margin:0 0 10px;letter-spacing:-.01em}
60
+ h3{font-size:13px;margin:16px 0 6px;color:var(--muted);
61
+ text-transform:uppercase;letter-spacing:.06em}
62
+ .prose{overflow-wrap:anywhere}
63
+ .prose p{margin:.5em 0}
64
+ .prose pre{background:var(--code);padding:10px 12px;border-radius:8px;overflow-x:auto}
65
+ .prose code{background:var(--code);padding:1px 5px;border-radius:4px;
66
+ font:13px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace}
67
+ .prose pre code{background:none;padding:0}
68
+ .katex{font-size:1.01em}
69
+ .katex-display{overflow-x:auto;overflow-y:hidden;margin:8px 0}
70
+ .rawtex{color:var(--warn)}
71
+ .layer{border:1px solid var(--line);border-radius:10px;margin-bottom:12px;overflow:hidden}
72
+ .layer>summary{cursor:pointer;padding:10px 14px;background:var(--accent-soft);
73
+ font-weight:600;font-size:14px;list-style:none;display:flex;
74
+ gap:10px;align-items:center;flex-wrap:wrap}
75
+ .layer>summary::-webkit-details-marker{display:none}
76
+ .layer>summary::before{content:"▸";color:var(--accent);font-size:12px}
77
+ .layer[open]>summary::before{content:"▾"}
78
+ .layer .body{padding:12px 14px}
79
+ .mr{background:var(--mr-soft);border-left:3px solid var(--mr);
80
+ border-radius:0 8px 8px 0;padding:12px 14px;margin:6px 0}
81
+ .mr .lab{font-size:11px;text-transform:uppercase;letter-spacing:.06em;
82
+ color:var(--mr);font-weight:700;margin-bottom:6px}
83
+ .ex{background:var(--exec-soft);border-left:3px solid var(--exec);
84
+ border-radius:0 8px 8px 0;padding:10px 12px;margin:8px 0}
85
+ .ex .lab{font-size:11px;color:var(--exec);font-weight:700;margin-bottom:4px}
86
+ .dir{font-style:italic;color:var(--muted);margin-bottom:6px}
87
+ .frag{display:inline-block;font-size:11px;padding:1px 7px;border-radius:999px;margin:0 4px 4px 0}
88
+ .frag.sel{background:var(--ok);color:#fff}
89
+ .frag.rej{background:var(--muted);color:var(--bg)}
90
+ .kv{display:grid;grid-template-columns:auto 1fr;gap:4px 14px;font-size:13px}
91
+ .kv dt{color:var(--muted)}
92
+ .kv dd{margin:0}
93
+ details.raw>summary{cursor:pointer;color:var(--muted);font-size:13px;padding:4px 0}
94
+ .note{color:var(--muted);font-size:13px}
95
+ button.theme{background:none;border:1px solid var(--line);border-radius:8px;
96
+ color:var(--muted);padding:4px 10px;cursor:pointer;font-size:12px}
97
+ </style>
98
+ </head>
99
+ <body>
100
+ <header>
101
+ <h1>SFT v4 Dataset Viewer</h1>
102
+ <span class="sub" id="hdr">loading…</span>
103
+ <span class="spacer"></span>
104
+ <button class="theme" onclick="toggleTheme()">theme</button>
105
+ </header>
106
+
107
+ <div class="layout">
108
+ <nav id="side"></nav>
109
+ <main id="main"><p class="note">Loading trajectories…</p></main>
110
+ </div>
111
+
112
+ <script>
113
+ const DATA = "data/trajectories.json";
114
+ let state = { rows: [], i: 0 };
115
+
116
+ function toggleTheme(){
117
+ const cur = document.documentElement.getAttribute("data-theme");
118
+ const dark = cur ? cur === "dark"
119
+ : window.matchMedia("(prefers-color-scheme: dark)").matches;
120
+ document.documentElement.setAttribute("data-theme", dark ? "light" : "dark");
121
+ }
122
+ const escapeHtml = s => (s||"").replace(/[&<>"']/g, c =>
123
+ ({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[c]));
124
+
125
+ // Math is extracted to placeholders before markdown runs, then restored, so
126
+ // marked never mangles LaTeX (and $ inside code stays untouched).
127
+ const MATH = [
128
+ { re: /\$\$([\s\S]+?)\$\$/g, display: true },
129
+ { re: /\\\[([\s\S]+?)\\\]/g, display: true },
130
+ { re: /\\\(([\s\S]+?)\\\)/g, display: false },
131
+ { re: /(?<![\\$])\$(?!\$)([^\n$]+?)\$(?!\$)/g, display: false },
132
+ ];
133
+ function katexSpan(tex, display){
134
+ if (window.katex){
135
+ try { return katex.renderToString(tex, {displayMode:display, throwOnError:false, output:"html"}); }
136
+ catch(e){}
137
+ }
138
+ return `<code class="rawtex">${escapeHtml(tex)}</code>`;
139
+ }
140
+ function md(s){
141
+ if(!s) return "";
142
+ const spans=[]; let text=s;
143
+ for(const {re,display} of MATH){
144
+ text = text.replace(re,(_m,tex)=>{ const t=`@@M${spans.length}@@`;
145
+ spans.push(katexSpan(tex.trim(),display)); return t; });
146
+ }
147
+ let html;
148
+ try { html = window.marked ? marked.parse(text,{breaks:true}) : "<pre>"+escapeHtml(text)+"</pre>"; }
149
+ catch(e){ html = "<pre>"+escapeHtml(text)+"</pre>"; }
150
+ return html.replace(/@@M(\d+)@@/g,(_m,i)=>spans[+i] ?? "");
151
+ }
152
+ function prose(t){ const d=document.createElement("div"); d.className="prose";
153
+ d.innerHTML=md(t||""); return d; }
154
+
155
+ // The MR target ships as "<think>…</think>" followed by <direction> tags. Split
156
+ // them so the reasoning reads as prose and the commitments stand out.
157
+ function splitTarget(t){
158
+ const out={think:"",dirs:[]};
159
+ if(!t) return out;
160
+ const m = t.match(/<think>([\s\S]*?)<\/think>/);
161
+ out.think = m ? m[1].trim() : t;
162
+ const rest = m ? t.slice(m.index + m[0].length) : "";
163
+ const re = /<direction>([\s\S]*?)<\/direction>/g; let d;
164
+ while((d = re.exec(rest))) out.dirs.push(d[1].trim());
165
+ return out;
166
+ }
167
+
168
+ function sidebar(){
169
+ const nav=document.getElementById("side"); nav.innerHTML="";
170
+ state.rows.forEach((r,i)=>{
171
+ const el=document.createElement("div");
172
+ el.className="item"+(i===state.i?" on":"");
173
+ const capped = r.outcome.excluded_reason === "guided_step_cap";
174
+ el.innerHTML =
175
+ `<div class="pid">${escapeHtml(r.problem_id)}</div>
176
+ <div class="meta">
177
+ <span class="tag d">depth ${r.outcome.productive_layers ?? "?"}</span>
178
+ ${r.score!=null?`<span class="tag s">score ${r.score.toFixed(2)}</span>`:""}
179
+ ${capped?`<span class="tag cap">step-cap</span>`:""}
180
+ </div>`;
181
+ el.onclick=()=>{ state.i=i; sidebar(); render(); window.scrollTo(0,0); };
182
+ nav.appendChild(el);
183
+ });
184
+ }
185
+
186
+ function render(){
187
+ const r = state.rows[state.i];
188
+ const m = document.getElementById("main");
189
+ m.innerHTML="";
190
+
191
+ const head=document.createElement("div"); head.className="card";
192
+ head.innerHTML=`<h2>${escapeHtml(r.problem_id)}</h2>
193
+ <dl class="kv">
194
+ <dt>source</dt><dd>${escapeHtml(r.source||"—")}</dd>
195
+ <dt>run</dt><dd>${escapeHtml(r.run)}</dd>
196
+ <dt>outcome</dt><dd>${escapeHtml(r.outcome.excluded_reason||"COMPLETE")}
197
+ ${r.outcome.terminated?" (self-terminated)":""}</dd>
198
+ <dt>layers</dt><dd>${r.outcome.productive_layers ?? "?"}</dd>
199
+ <dt>judge</dt><dd>${r.score!=null?r.score.toFixed(2):"—"}</dd>
200
+ </dl>`;
201
+ head.appendChild(Object.assign(document.createElement("h3"),{textContent:"Problem"}));
202
+ head.appendChild(prose(r.problem));
203
+ if(r.rubric){
204
+ const d=document.createElement("details"); d.className="raw";
205
+ d.innerHTML="<summary>rubric</summary>";
206
+ d.appendChild(prose(r.rubric)); head.appendChild(d);
207
+ }
208
+ m.appendChild(head);
209
+
210
+ r.layers.forEach(L=>{
211
+ const det=document.createElement("details"); det.className="layer";
212
+ if(L.layer_idx===0) det.open=true;
213
+ const kept=L.reviews.filter(x=>x.retain).length;
214
+ det.innerHTML=`<summary>Layer ${L.layer_idx}
215
+ <span class="tag">${L.executions.length} executions</span>
216
+ <span class="tag">${kept} retained</span></summary>`;
217
+ const body=document.createElement("div"); body.className="body";
218
+
219
+ if(L.mr_target){
220
+ const t=splitTarget(L.mr_target);
221
+ const box=document.createElement("div"); box.className="mr";
222
+ box.innerHTML=`<div class="lab">MR reasoning — the SFT target for this layer</div>`;
223
+ box.appendChild(prose(t.think));
224
+ if(t.dirs.length){
225
+ const h=document.createElement("h3"); h.textContent="committed directions";
226
+ box.appendChild(h);
227
+ t.dirs.forEach(d=>box.appendChild(prose("- "+d)));
228
+ }
229
+ if(L.mr_fragments.length){
230
+ const f=document.createElement("div"); f.style.marginTop="8px";
231
+ f.innerHTML = L.mr_fragments.map(x=>
232
+ `<span class="frag ${x.disposition==="selected"?"sel":"rej"}">${escapeHtml(x.candidate_id||"?")} · ${escapeHtml(x.disposition||"")}</span>`
233
+ ).join("");
234
+ box.appendChild(f);
235
+ }
236
+ body.appendChild(box);
237
+ }
238
+
239
+ L.executions.forEach(e=>{
240
+ const box=document.createElement("div"); box.className="ex";
241
+ box.innerHTML=`<div class="lab">execution ${escapeHtml(e.candidate_id||"")}</div>
242
+ <div class="dir">${escapeHtml(e.direction||"")}</div>`;
243
+ const d=document.createElement("details"); d.className="raw";
244
+ d.innerHTML="<summary>execution report</summary>";
245
+ d.appendChild(prose(e.report)); box.appendChild(d);
246
+ body.appendChild(box);
247
+ });
248
+
249
+ const kepts=L.reviews.filter(x=>x.retain&&x.summary);
250
+ if(kepts.length){
251
+ const h=document.createElement("h3"); h.textContent="retained into the frontier";
252
+ body.appendChild(h);
253
+ kepts.forEach(x=>body.appendChild(prose(x.summary)));
254
+ }
255
+ det.appendChild(body); m.appendChild(det);
256
+ });
257
+
258
+ if(r.termination_target){
259
+ const c=document.createElement("div"); c.className="card";
260
+ c.innerHTML="<h2>Termination decision</h2>";
261
+ const t=splitTarget(r.termination_target);
262
+ c.appendChild(prose(t.think)); m.appendChild(c);
263
+ }
264
+ if(r.final_answer){
265
+ const c=document.createElement("div"); c.className="card";
266
+ c.innerHTML="<h2>Final answer</h2>";
267
+ c.appendChild(prose(r.final_answer));
268
+ if(r.judge_explanation){
269
+ const d=document.createElement("details"); d.className="raw";
270
+ d.innerHTML="<summary>judge</summary>";
271
+ d.appendChild(prose(r.judge_explanation)); c.appendChild(d);
272
+ }
273
+ m.appendChild(c);
274
+ }
275
+ }
276
+
277
+ fetch(DATA).then(r=>r.json()).then(j=>{
278
+ state.rows = j.trajectories || [];
279
+ const d = state.rows.map(r=>r.outcome.productive_layers).filter(x=>x!=null);
280
+ const s = state.rows.map(r=>r.score).filter(x=>x!=null);
281
+ document.getElementById("hdr").textContent =
282
+ `${state.rows.length} trajectories · depth ${Math.min(...d)}–${Math.max(...d)}`
283
+ + (s.length?` · judge ${Math.min(...s).toFixed(1)}–${Math.max(...s).toFixed(1)}`:"")
284
+ + " · MR shown is the F1-ordered (repaired) target";
285
+ sidebar(); render();
286
+ }).catch(e=>{
287
+ document.getElementById("main").innerHTML =
288
+ `<p class="note">Failed to load ${DATA}: ${escapeHtml(String(e))}</p>`;
289
+ });
290
+ </script>
291
+ </body>
292
  </html>