/* rundays_test.js — runs the AI running-days test one train at a time so no single request hits the nginx gateway timeout. */ (function () { function esc(s) { return String(s == null ? '' : s).replace(/[&<>"]/g, function (c) { return { '&': '&', '<': '<', '>': '>', '"': '"' }[c]; }); } function rowOk(tn, exp, got, match, conf, src) { var color = match === true ? '#197b3a' : (match === false ? '#c0392b' : '#888'); var label = match === true ? 'PASS' : (match === false ? 'FAIL' : '—'); return '' + esc(tn) + '' + '' + esc(exp || '—') + '' + '' + esc(got || '(none)') + '' + '' + label + '' + '' + esc(conf) + '' + '' + esc(src) + ''; } function rowErr(tn, exp, msg) { return '' + esc(tn) + '' + '' + esc(exp || '—') + '' + '⚠ ' + esc(msg) + ''; } function verdict(p, f, e, judged) { var cls = (f > 0 || e > 0) ? 'flash-error' : 'flash-info'; var msg = 'PASS ' + p + ' · FAIL ' + f + ' · ERROR ' + e + '. '; if (judged === 0) msg += 'No answer key given, so nothing was judged — add expected days to decide.'; else if (f > 0) msg += 'Failed. Per your rule, drop the OpenAI approach and use irctc1.'; else if (e > 0) msg += 'Some calls errored/timed out (API, quota, or model too slow) — fix those before judging.'; else msg += 'Passed this set. A small pass is weak evidence — widen the list before trusting it.'; return '
' + msg + '
'; } document.addEventListener('DOMContentLoaded', function () { var form = document.getElementById('rd-form'); if (!form) return; form.addEventListener('submit', function (ev) { ev.preventDefault(); var btn = document.getElementById('rd-run'); var orig = btn.textContent; var model = (document.getElementById('model').value || '').trim() || 'gpt-5.5'; var csrf = form.querySelector('input[name=csrf]').value; var tbody = document.getElementById('rd-rows'); var summary = document.getElementById('rd-summary'); var box = document.getElementById('rd-results'); var lines = (document.getElementById('trains').value || '').split(/\r?\n/); tbody.innerHTML = ''; summary.innerHTML = ''; box.style.display = 'block'; btn.disabled = true; var jobs = []; for (var i = 0; i < lines.length; i++) { var line = lines[i].trim(); if (!line) continue; var c = line.indexOf(':'); var tn = (c === -1 ? line : line.slice(0, c)).replace(/\D/g, ''); if (!tn) continue; var exp = c === -1 ? '' : line.slice(c + 1).trim(); jobs.push({ tn: tn, exp: exp }); } var idx = 0, pass = 0, fail = 0, err = 0, judged = 0; function next() { if (idx >= jobs.length) { btn.disabled = false; btn.textContent = orig; summary.innerHTML = verdict(pass, fail, err, judged); return; } var job = jobs[idx++]; btn.textContent = 'Testing ' + job.tn + ' (' + idx + '/' + jobs.length + ')…'; var row = document.createElement('tr'); row.style.borderBottom = '1px solid #eee'; row.style.verticalAlign = 'top'; row.innerHTML = '' + esc(job.tn) + '' + '' + esc(job.exp || '—') + '…querying…'; tbody.appendChild(row); var body = new URLSearchParams({ action: 'one', train: job.tn, exp: job.exp, model: model, csrf: csrf }); fetch(window.location.pathname, { method: 'POST', headers: { 'X-Requested-With': 'XMLHttpRequest' }, body: body }).then(function (resp) { if (!resp.ok) { var extra = resp.status === 504 ? ' (gateway timeout — model too slow for this host; try gpt-5.4-mini)' : ''; throw new Error('HTTP ' + resp.status + extra); } return resp.json(); }).then(function (data) { if (data.err) { err++; row.innerHTML = rowErr(job.tn, job.exp, data.err); } else { var got = (data.got || []).join(','); if (data.match === true) pass++; else if (data.match === false) fail++; if (data.match !== null) judged++; row.innerHTML = rowOk(job.tn, job.exp, got, data.match, data.conf, data.src); } }).catch(function (e) { err++; row.innerHTML = rowErr(job.tn, job.exp, e.message); }).then(next); } next(); }); }); })();