Download frontend/index.html from umairali64488/multi_llm_debugging_engine: direct link, hf CLI and curl.
- Browser
- Download file 28 kB
-
https://huggingface.co/spaces/umairali64488/multi_llm_debugging_engine/resolve/main/frontend/index.html
- Command line
-
hf download hf://spaces/umairali64488/multi_llm_debugging_engine/frontend/index.html
-
curl -L -o index.html https://huggingface.co/spaces/umairali64488/multi_llm_debugging_engine/resolve/main/frontend/index.html
28 kB
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"/> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"/> | |
| <title>⚡ CodeDebug</title> | |
| <link rel="preconnect" href="https://fonts.googleapis.com"> | |
| <link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;500;700&family=Syne:wght@600;700;800&display=swap" rel="stylesheet"> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github.min.css"> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/9.1.6/marked.min.js"></script> | |
| <style> | |
| /* ════════════════════════════════════════ | |
| BASE - PROFESSIONAL MONOCHROME | |
| ════════════════════════════════════════ */ | |
| *,*::before,*::after{box-sizing:border-box;margin:0;padding:0} | |
| :root{ | |
| /* Professional grayscale palette */ | |
| --bg: #ffffff; | |
| --bg2: #f8f9fa; | |
| --bg3: #f1f3f4; | |
| --bg4: #e8eaed; | |
| --bg5: #dadce0; | |
| --line: #dadce0; | |
| --line2: #c6c9ce; | |
| --ink: #202124; | |
| --ink2: #5f6368; | |
| --ink3: #80868b; | |
| /* Single accent: Deep Navy */ | |
| --accent: #1a73e8; | |
| --accent-light: rgba(26,115,232,0.08); | |
| --accent-glow: rgba(26,115,232,0.15); | |
| /* Status colors - muted */ | |
| --green: #137333; | |
| --red: #d93025; | |
| --amber: #f9ab00; | |
| --mono:'JetBrains Mono',monospace; | |
| --sans:'Syne',sans-serif; | |
| --r:4px; | |
| } | |
| html,body{height:100%;overflow:hidden} | |
| body{ | |
| background:var(--bg);color:var(--ink); | |
| font-family:var(--mono);font-size:13px; | |
| display:flex;flex-direction:column; | |
| } | |
| /* Subtle grid pattern instead of scanlines */ | |
| body::after{ | |
| content:'';position:fixed;inset:0;pointer-events:none;z-index:9999; | |
| background-image: | |
| linear-gradient(var(--bg5) 1px, transparent 1px), | |
| linear-gradient(90deg, var(--bg5) 1px, transparent 1px); | |
| background-size: 50px 50px; | |
| opacity: 0.3; | |
| } | |
| /* ════════════════════════════════════════ | |
| HEADER BAR | |
| ════════════════════════════════════════ */ | |
| .hdr{ | |
| flex-shrink:0;height:48px; | |
| background:var(--bg);border-bottom:1px solid var(--line); | |
| display:flex;align-items:center;padding:0 20px;gap:16px; | |
| box-shadow: 0 1px 2px rgba(60,64,67,0.1); | |
| } | |
| .logo{display:flex;align-items:center;gap:10px} | |
| .logo-gem{ | |
| width:28px;height:28px;border-radius:6px; | |
| background:var(--accent); | |
| display:flex;align-items:center;justify-content:center;font-size:14px; | |
| color: white; | |
| } | |
| .logo-txt{font-family:var(--sans);font-size:16px;font-weight:700;letter-spacing:-0.3px;color:var(--ink)} | |
| .logo-txt b{color:var(--accent);font-weight:800} | |
| .hdr-sep{width:1px;height:20px;background:var(--line)} | |
| .hdr-pills{display:flex;gap:8px} | |
| .hp{padding:4px 12px;border-radius:4px;font-size:11px;border:1px solid var(--line);white-space:nowrap;background:var(--bg2);color:var(--ink2);font-weight:500} | |
| .hp1{color:var(--accent);border-color:var(--accent);background:var(--accent-light)} | |
| .hdr-right{margin-left:auto;font-size:11px;color:var(--ink2)} | |
| .hdr-right b{color:var(--accent);font-weight:600} | |
| /* ════════════════════════════════════════ | |
| STATUS STRIP | |
| ════════════════════════════════════════ */ | |
| .sbar{ | |
| flex-shrink:0;height:32px; | |
| background:var(--bg2);border-bottom:1px solid var(--line); | |
| display:flex;align-items:center;padding:0 20px;gap:12px; | |
| font-size:12px;color:var(--ink2); | |
| } | |
| .sdot{width:6px;height:6px;border-radius:50%;background:var(--ink3);flex-shrink:0;transition:background .3s} | |
| .sdot.idle {background:var(--ink3)} | |
| .sdot.run {background:var(--accent);animation:pulse 1.5s ease-in-out infinite} | |
| .sdot.done {background:var(--green)} | |
| .sdot.err {background:var(--red)} | |
| @keyframes pulse{0%,100%{opacity:1}50%{opacity:.5}} | |
| #sMsg{flex:1;font-weight:500} | |
| #sTime{color:var(--accent);font-weight:600} | |
| /* ════════════════════════════════════════ | |
| 3-COLUMN BODY 25 | 50 | 25 | |
| ════════════════════════════════════════ */ | |
| .body{ | |
| flex:1;display:grid; | |
| grid-template-columns:25% 50% 25%; | |
| overflow:hidden;min-height:0; | |
| } | |
| /* shared column chrome */ | |
| .col{display:flex;flex-direction:column;overflow:hidden;min-height:0} | |
| .col+.col{border-left:1px solid var(--line)} | |
| .col-hdr{ | |
| flex-shrink:0;padding:10px 16px; | |
| background:var(--bg);border-bottom:1px solid var(--line); | |
| font-size:11px;text-transform:uppercase;letter-spacing:1px; | |
| color:var(--ink2);display:flex;align-items:center;gap:8px; | |
| font-weight:600; | |
| } | |
| .chd{width:6px;height:6px;border-radius:50%;flex-shrink:0;background:var(--accent)} | |
| .col-body{flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:12px} | |
| /* ════════════════════════════════════════ | |
| LEFT 25% — INPUT | |
| ════════════════════════════════════════ */ | |
| .query-wrap{position:relative} | |
| .q-prompt{ | |
| position:absolute;left:12px;top:12px; | |
| color:var(--accent);font-size:14px;font-weight:700;pointer-events:none;z-index:1 | |
| } | |
| #qInput{ | |
| width:100%;min-height:140px;max-height:360px; | |
| padding:12px 12px 12px 28px; | |
| background:var(--bg);border:1px solid var(--line2);border-radius:var(--r); | |
| color:var(--ink);font-family:var(--mono);font-size:13px; | |
| resize:vertical;outline:none;line-height:1.6; | |
| transition:border-color .2s,box-shadow .2s; | |
| } | |
| #qInput:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-glow)} | |
| #qInput::placeholder{color:var(--ink3)} | |
| .field-lbl{font-size:11px;color:var(--ink2);margin-bottom:6px;text-transform:uppercase;letter-spacing:0.5px;font-weight:600} | |
| .temp-row{display:flex;align-items:center;gap:12px;font-size:12px;color:var(--ink2)} | |
| .temp-row input[type=range]{flex:1;accent-color:var(--accent);cursor:pointer;height:4px;border-radius:2px} | |
| #tVal{color:var(--accent);min-width:32px;text-align:right;font-weight:600} | |
| .btn-run{ | |
| width:100%;padding:12px; | |
| background:var(--accent); | |
| color:#fff;border:none;border-radius:var(--r); | |
| font-family:var(--sans);font-size:13px;font-weight:700; | |
| letter-spacing:0.5px;text-transform:uppercase;cursor:pointer; | |
| transition:all .2s;box-shadow:0 1px 3px rgba(26,115,232,0.3); | |
| } | |
| .btn-run:hover{background:#1557b0;transform:translateY(-1px);box-shadow:0 4px 8px rgba(26,115,232,0.25)} | |
| .btn-run:active{transform:translateY(0)} | |
| .btn-run:disabled{background:var(--bg5);color:var(--ink3);cursor:not-allowed;box-shadow:none;transform:none} | |
| .hint-txt{font-size:11px;color:var(--ink3);text-align:center} | |
| kbd{background:var(--bg3);border:1px solid var(--line2);border-radius:3px;padding:2px 6px;font-size:10px;color:var(--ink2);font-family:var(--mono)} | |
| /* divider line in left col */ | |
| .field-sep{height:1px;background:var(--line);margin:8px 0} | |
| /* previous queries list */ | |
| .q-history{display:flex;flex-direction:column;gap:8px} | |
| .q-hist-item{ | |
| padding:10px 12px;background:var(--bg);border:1px solid var(--line); | |
| border-radius:var(--r);font-size:12px;color:var(--ink2); | |
| cursor:pointer;line-height:1.5;transition:all .15s; | |
| overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical; | |
| } | |
| .q-hist-item:hover{border-color:var(--accent);color:var(--ink);background:var(--bg2);box-shadow:0 1px 2px rgba(0,0,0,0.05)} | |
| /* ════════════════════════════════════════ | |
| MIDDLE 50% — JUDGE OUTPUT | |
| ════════════════════════════════════════ */ | |
| .judge-panel{ | |
| background:var(--bg);border:1px solid var(--line); | |
| border-radius:var(--r);display:flex;flex-direction:column; | |
| flex:1;min-height:0;overflow:hidden;transition:border-color .3s; | |
| box-shadow: 0 1px 3px rgba(60,64,67,0.08); | |
| } | |
| .judge-panel.done{border-color:var(--green);background:var(--bg)} | |
| .jp-head{ | |
| flex-shrink:0;display:flex;align-items:center;gap:12px; | |
| padding:12px 16px; | |
| background:var(--bg2);border-bottom:1px solid var(--line); | |
| } | |
| .jp-icon{ | |
| width:28px;height:28px;border-radius:6px;flex-shrink:0; | |
| background:var(--accent); | |
| display:flex;align-items:center;justify-content:center;font-size:14px; | |
| color: white; | |
| } | |
| .jp-title{font-family:var(--sans);font-size:14px;font-weight:700;color:var(--ink)} | |
| .jp-sub {font-size:11px;color:var(--ink2);margin-top:2px} | |
| .jp-lat { | |
| margin-left:auto;font-size:11px;color:var(--accent); | |
| padding:4px 10px;background:var(--accent-light); | |
| border:1px solid var(--accent-glow);border-radius:12px; | |
| font-weight:600; | |
| } | |
| /* error analysis box */ | |
| .err-box{ | |
| flex-shrink:0;margin:16px 16px 0; | |
| background:var(--bg2);border:1px solid var(--line2); | |
| border-radius:var(--r);overflow:hidden; | |
| } | |
| .err-box-hdr{ | |
| padding:10px 14px;background:var(--bg3); | |
| font-size:11px;text-transform:uppercase;letter-spacing:0.5px; | |
| color:var(--red);border-bottom:1px solid var(--line); | |
| display:flex;align-items:center;gap:8px;font-weight:600; | |
| } | |
| .err-box-body{padding:14px;font-size:13px;line-height:1.7;color:var(--ink)} | |
| /* corrected code box */ | |
| .code-box{ | |
| flex:1;display:flex;flex-direction:column; | |
| margin:12px 16px 16px;min-height:0; | |
| background:var(--bg);border:1px solid var(--line2);border-radius:var(--r); | |
| overflow:hidden; | |
| } | |
| .code-box-hdr{ | |
| flex-shrink:0;padding:10px 14px;background:var(--bg2); | |
| font-size:11px;text-transform:uppercase;letter-spacing:0.5px; | |
| color:var(--green);border-bottom:1px solid var(--line); | |
| display:flex;align-items:center;gap:8px;font-weight:600; | |
| } | |
| .copy-code-btn{ | |
| margin-left:auto;padding:4px 12px;background:var(--bg); | |
| border:1px solid var(--line2);border-radius:3px; | |
| color:var(--ink2);font-size:10px;font-family:var(--mono);cursor:pointer;transition:all .15s;font-weight:500; | |
| } | |
| .copy-code-btn:hover{color:var(--accent);border-color:var(--accent);background:var(--bg3)} | |
| .code-box-body{flex:1;overflow-y:auto;padding:0} | |
| .code-box-body pre{margin:0;border-radius:0;border:none !important;height:100%;background:var(--bg3) !important} | |
| .code-box-body pre code{font-size:13px;line-height:1.6} | |
| /* judge placeholder / skeleton */ | |
| .jp-placeholder{ | |
| flex:1;display:flex;flex-direction:column; | |
| align-items:center;justify-content:center; | |
| gap:16px;color:var(--ink3);text-align:center;padding:60px 24px; | |
| } | |
| .jp-ph-icon{font-size:48px;opacity:0.2} | |
| .jp-ph-txt{font-size:13px;line-height:1.7;max-width:320px} | |
| .jp-skel{padding:20px 16px;display:flex;flex-direction:column;gap:12px} | |
| .jsk{ | |
| height:12px;border-radius:3px; | |
| background:linear-gradient(90deg,var(--bg3) 25%,var(--bg4) 50%,var(--bg3) 75%); | |
| background-size:200% 100%;animation:shim 2s infinite; | |
| } | |
| @keyframes shim{0%{background-position:200% 0}100%{background-position:-200% 0}} | |
| /* ════════════════════════════════════════ | |
| RIGHT 25% — PANEL MODELS | |
| ════════════════════════════════════════ */ | |
| .model-card{ | |
| background:var(--bg);border:1px solid var(--line); | |
| border-radius:var(--r);overflow:hidden;transition:all .3s; | |
| box-shadow: 0 1px 2px rgba(60,64,67,0.05); | |
| } | |
| .model-card[data-s="d1"]{border-color:var(--accent);box-shadow:0 2px 8px var(--accent-glow)} | |
| .model-card[data-s="d2"]{border-color:var(--ink2)} | |
| .model-card[data-s="er"]{border-color:var(--red)} | |
| .mc-hdr{ | |
| display:flex;align-items:center;gap:12px;padding:12px 14px; | |
| background:var(--bg2);border-bottom:1px solid var(--line); | |
| cursor:pointer;user-select:none; | |
| } | |
| .mc-hdr:hover{background:var(--bg3)} | |
| .mc-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0;transition:all .3s} | |
| .mcd1{background:var(--accent)} .mcd2{background:var(--ink2)} | |
| .model-card[data-s="d1"] .mcd1{box-shadow:0 0 0 3px var(--accent-glow)} | |
| .model-card[data-s="d2"] .mcd2{box-shadow:0 0 0 3px rgba(95,99,104,0.15)} | |
| .mc-info{flex:1} | |
| .mc-name{font-family:var(--sans);font-size:12px;font-weight:700;color:var(--ink)} | |
| .mc-id{font-size:10px;color:var(--ink2);margin-top:2px} | |
| .mc-lat{font-size:11px;padding:4px 10px;border-radius:12px;background:var(--bg3);min-width:42px;text-align:center;font-weight:600;color:var(--ink2)} | |
| .model-card[data-s="d1"] .mc-lat{color:var(--accent);background:var(--accent-light)} | |
| .mc-chev{color:var(--ink2);font-size:10px;transition:transform .2s;flex-shrink:0} | |
| .model-card.coll .mc-chev{transform:rotate(-90deg)} | |
| .mc-body{overflow:hidden;transition:max-height .3s ease;max-height:480px} | |
| .model-card.coll .mc-body{max-height:0!important} | |
| .mc-inner{padding:14px;max-height:430px;overflow-y:auto} | |
| /* skeleton */ | |
| .skel{display:flex;flex-direction:column;gap:8px;padding:14px} | |
| .sk{ | |
| height:10px;border-radius:2px; | |
| background:linear-gradient(90deg,var(--bg3) 25%,var(--bg4) 50%,var(--bg3) 75%); | |
| background-size:200% 100%;animation:shim 1.6s infinite; | |
| } | |
| .sk:nth-child(2){width:78%;animation-delay:.15s} | |
| .sk:nth-child(3){width:62%;animation-delay:.3s} | |
| .sk:nth-child(4){width:85%;animation-delay:.45s} | |
| .mc-empty{padding:28px 14px;text-align:center;color:var(--ink2);font-size:12px} | |
| .mc-eicon{font-size:24px;margin-bottom:8px;opacity:0.3} | |
| .mc-err{color:var(--red);font-size:12px;padding:14px;font-style:italic;background:var(--bg2);border-radius:var(--r)} | |
| /* ════════════════════════════════════════ | |
| MARKDOWN RENDERER | |
| ════════════════════════════════════════ */ | |
| .md p{margin-bottom:10px;line-height:1.7} | |
| .md ul,.md ol{padding-left:20px;margin-bottom:10px} | |
| .md li{margin-bottom:4px} | |
| .md h1,.md h2,.md h3{font-family:var(--sans);font-weight:700;margin:16px 0 8px;color:var(--ink)} | |
| .md h1{font-size:16px;border-bottom:1px solid var(--line);padding-bottom:8px} | |
| .md h2{font-size:14px;color:var(--accent)} | |
| .md h3{font-size:13px;color:var(--ink2)} | |
| .md code{ | |
| font-family:var(--mono);font-size:12px; | |
| background:var(--bg3);border:1px solid var(--line2); | |
| padding:2px 6px;border-radius:3px;color:var(--accent); | |
| } | |
| .md pre{ | |
| background:var(--bg3)!important;border:1px solid var(--line2); | |
| border-radius:var(--r);padding:14px;overflow-x:auto;margin:12px 0; | |
| } | |
| .md pre code{background:none!important;border:none!important;padding:0!important;color:inherit!important} | |
| .md blockquote{border-left:3px solid var(--accent);padding-left:14px;color:var(--ink2);font-style:italic;margin:12px 0;background:var(--bg2);padding:12px 14px;border-radius:0 var(--r) var(--r) 0} | |
| .md strong{color:var(--ink);font-weight:700} | |
| .md em{color:var(--ink2)} | |
| .md hr{border:none;border-top:1px solid var(--line);margin:16px 0} | |
| .md a{color:var(--accent);text-decoration:none;font-weight:500} | |
| .md a:hover{text-decoration:underline} | |
| .md table{width:100%;border-collapse:collapse;margin:12px 0;font-size:12px;border:1px solid var(--line)} | |
| .md th{background:var(--bg2);color:var(--ink);padding:10px 12px;text-align:left;border:1px solid var(--line);font-weight:600} | |
| .md td{padding:8px 12px;border:1px solid var(--line)} | |
| /* ════════════════════════════════════════ | |
| SCROLLBARS | |
| ════════════════════════════════════════ */ | |
| ::-webkit-scrollbar{width:6px;height:6px} | |
| ::-webkit-scrollbar-track{background:var(--bg2)} | |
| ::-webkit-scrollbar-thumb{background:var(--line2);border-radius:3px} | |
| ::-webkit-scrollbar-thumb:hover{background:var(--ink3)} | |
| /* ════════════════════════════════════════ | |
| UTILS | |
| ════════════════════════════════════════ */ | |
| @keyframes fadeUp{from{opacity:0;transform:translateY(5px)}to{opacity:1;transform:translateY(0)}} | |
| .fu{animation:fadeUp .3s ease forwards} | |
| @media(max-width:800px){ | |
| .body{grid-template-columns:1fr;grid-template-rows:auto auto auto;overflow-y:auto} | |
| html,body{overflow-y:auto;height:auto} | |
| .col{overflow:visible;min-height:auto} | |
| .col-body{overflow:visible} | |
| .judge-panel{min-height:300px} | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- HEADER --> | |
| <div class="hdr"> | |
| <div class="logo"> | |
| <div class="logo-gem">⚡</div> | |
| <div class="logo-txt"><b>Code</b>Debug</div> | |
| </div> | |
| <div class="hdr-sep"></div> | |
| <div class="hdr-pills"> | |
| <span class="hp hp1">Trinity Large</span> | |
| <span class="hp">Nemotron Nano</span> | |
| <span class="hp">StepFun Judge</span> | |
| </div> | |
| <div class="hdr-right">Queries: <b id="qCnt">0</b></div> | |
| </div> | |
| <!-- STATUS --> | |
| <div class="sbar"> | |
| <div class="sdot idle" id="sDot"></div> | |
| <span id="sMsg">Ready — enter your code or describe the bug</span> | |
| <span id="sTime"></span> | |
| </div> | |
| <!-- 3-COLUMN BODY --> | |
| <div class="body"> | |
| <!-- ══ LEFT 25%: INPUT ══ --> | |
| <div class="col"> | |
| <div class="col-hdr"><div class="chd"></div>Input</div> | |
| <div class="col-body"> | |
| <div> | |
| <div class="field-lbl">Your code / question</div> | |
| <div class="query-wrap"> | |
| <div class="q-prompt">></div> | |
| <textarea id="qInput" rows="5" | |
| placeholder="Paste buggy code or describe the issue… e.g. def divide(a,b): return a/b divide(10,0)"></textarea> | |
| </div> | |
| </div> | |
| <div> | |
| <div class="field-lbl">Temperature</div> | |
| <div class="temp-row"> | |
| <input type="range" id="tSlider" min="0" max="1" step="0.05" value="0.3" | |
| oninput="document.getElementById('tVal').textContent=this.value"> | |
| <span id="tVal">0.3</span> | |
| </div> | |
| </div> | |
| <button class="btn-run" id="runBtn" onclick="runDebug()">▶ Run Debug</button> | |
| <div class="hint-txt"><kbd>Ctrl</kbd>+<kbd>Enter</kbd> to submit</div> | |
| <div class="field-sep"></div> | |
| <!-- history --> | |
| <div id="histWrap" style="display:none"> | |
| <div class="field-lbl" style="margin-bottom:7px">Recent</div> | |
| <div class="q-history" id="histList"></div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- ══ MIDDLE 50%: JUDGE OUTPUT ══ --> | |
| <div class="col"> | |
| <div class="col-hdr"> | |
| <div class="chd" style="background:var(--green)"></div> | |
| Judge Output — StepFun Flash | |
| </div> | |
| <div class="col-body"> | |
| <div class="judge-panel" id="jPanel"> | |
| <div class="jp-head"> | |
| <div class="jp-icon">⚖</div> | |
| <div> | |
| <div class="jp-title">StepFun Flash Judge</div> | |
| <div class="jp-sub">stepfun/step-3.5-flash:free · synthesized verdict</div> | |
| </div> | |
| <div class="jp-lat" id="jLat">—</div> | |
| </div> | |
| <div id="jBody" style="display:flex;flex-direction:column;flex:1;min-height:0;overflow:hidden"> | |
| <div class="jp-placeholder" id="jPlaceholder"> | |
| <div class="jp-ph-icon">⚖️</div> | |
| <div class="jp-ph-txt"> | |
| The judge analyzes both model responses<br> | |
| and returns the exact bug + corrected code. | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- ══ RIGHT 25%: PANEL MODELS ══ --> | |
| <div class="col"> | |
| <div class="col-hdr"><div class="chd" style="background:var(--ink2)"></div>Debugger Models</div> | |
| <div class="col-body"> | |
| <!-- Card 1: Trinity --> | |
| <div class="model-card" id="c0" data-s="idle"> | |
| <div class="mc-hdr" onclick="toggleCard(0)"> | |
| <div class="mc-dot mcd1"></div> | |
| <div class="mc-info"> | |
| <div class="mc-name">Trinity Large</div> | |
| <div class="mc-id">arcee-ai/trinity-large-preview</div> | |
| </div> | |
| <div class="mc-lat" id="l0">—</div> | |
| <div class="mc-chev">▾</div> | |
| </div> | |
| <div class="mc-body"> | |
| <div class="mc-empty"><div class="mc-eicon">🔵</div>Awaiting query…</div> | |
| </div> | |
| </div> | |
| <!-- Card 2: Nemotron --> | |
| <div class="model-card" id="c1" data-s="idle"> | |
| <div class="mc-hdr" onclick="toggleCard(1)"> | |
| <div class="mc-dot mcd2"></div> | |
| <div class="mc-info"> | |
| <div class="mc-name">Nemotron Nano</div> | |
| <div class="mc-id">nvidia/nemotron-3-nano-30b-a3b</div> | |
| </div> | |
| <div class="mc-lat" id="l1">—</div> | |
| <div class="mc-chev">▾</div> | |
| </div> | |
| <div class="mc-body"> | |
| <div class="mc-empty"><div class="mc-eicon">🟡</div>Awaiting query…</div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div><!-- /.body --> | |
| <script> | |
| /* ── Config ── */ | |
| const API = ''; | |
| marked.setOptions({breaks:true,gfm:true}); | |
| /* ── State ── */ | |
| let running = false; | |
| let qCount = 0; | |
| const coll = [false, false]; | |
| const hist = []; | |
| /* ── Utils ── */ | |
| function esc(s){ return String(s??'').replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>') } | |
| function md(text){ | |
| if(!text) return '<em style="color:var(--ink3)">—</em>'; | |
| return `<div class="md">${marked.parse(text)}</div>`; | |
| } | |
| function hlCode(el){ | |
| el.querySelectorAll('pre code').forEach(b => hljs.highlightElement(b)); | |
| } | |
| function setStatus(state, msg, time=''){ | |
| document.getElementById('sDot').className = `sdot ${state}`; | |
| document.getElementById('sMsg').textContent = msg; | |
| document.getElementById('sTime').textContent = time; | |
| } | |
| function toggleCard(i){ | |
| coll[i] = !coll[i]; | |
| document.getElementById(`c${i}`).classList.toggle('coll', coll[i]); | |
| } | |
| /* ── Panel card rendering ── */ | |
| function panelSkel(i){ | |
| document.getElementById(`c${i}`).dataset.s = 'loading'; | |
| document.getElementById(`l${i}`).textContent = '…'; | |
| document.querySelector(`#c${i} .mc-body`).innerHTML = | |
| '<div class="skel"><div class="sk"></div><div class="sk"></div><div class="sk"></div><div class="sk"></div></div>'; | |
| } | |
| function panelResult(i, r){ | |
| const card = document.getElementById(`c${i}`); | |
| const body = document.querySelector(`#c${i} .mc-body`); | |
| document.getElementById(`l${i}`).textContent = `${r.latency_ms}ms`; | |
| if(r.error){ | |
| card.dataset.s = 'er'; | |
| body.innerHTML = `<div class="mc-err">⚠ ${esc(r.error)}</div>`; | |
| return; | |
| } | |
| card.dataset.s = `d${i+1}`; | |
| body.innerHTML = `<div class="mc-inner fu">${md(r.response)}</div>`; | |
| hlCode(body); | |
| } | |
| /* ── Judge rendering ── */ | |
| function judgeSkel(){ | |
| document.getElementById('jLat').textContent = '…'; | |
| document.getElementById('jPanel').className = 'judge-panel'; | |
| document.getElementById('jBody').innerHTML = ` | |
| <div class="jp-skel"> | |
| <div class="jsk" style="width:55%"></div><div class="jsk"></div> | |
| <div class="jsk" style="width:78%"></div><div class="jsk" style="width:40%"></div> | |
| <div class="jsk"></div><div class="jsk" style="width:68%"></div> | |
| </div>`; | |
| } | |
| function judgeResult(r){ | |
| const jb = document.getElementById('jBody'); | |
| const jp = document.getElementById('jPanel'); | |
| document.getElementById('jLat').textContent = `${r.latency_ms}ms`; | |
| if(r.error){ | |
| jp.className = 'judge-panel'; | |
| jb.innerHTML = `<div style="padding:16px 14px"><div class="mc-err">⚠ ${esc(r.error)}</div></div>`; | |
| return; | |
| } | |
| jp.className = 'judge-panel done'; | |
| /* Extract raw code from corrected_code field (strip fences for display) */ | |
| let rawCode = r.corrected_code || ''; | |
| let lang = 'python'; | |
| const fenceMatch = rawCode.match(/^```(\w+)?\n?([\s\S]*?)```$/s); | |
| if(fenceMatch){ lang = fenceMatch[1] || 'python'; rawCode = fenceMatch[2].trim(); } | |
| const errHtml = r.error_analysis | |
| ? `<div class="err-box"> | |
| <div class="err-box-hdr">🐛 Error Analysis</div> | |
| <div class="err-box-body fu">${md(r.error_analysis)}</div> | |
| </div>` | |
| : ''; | |
| const codeHtml = rawCode | |
| ? `<div class="code-box"> | |
| <div class="code-box-hdr"> | |
| ✅ Corrected Code | |
| <button class="copy-code-btn" id="copyCodeBtn" onclick="copyCode()">Copy</button> | |
| </div> | |
| <div class="code-box-body"> | |
| <pre><code id="correctedCode" class="language-${esc(lang)}">${esc(rawCode)}</code></pre> | |
| </div> | |
| </div>` | |
| : `<div style="padding:14px;color:var(--ink2)">No corrected code returned.</div>`; | |
| jb.innerHTML = errHtml + codeHtml; | |
| /* highlight */ | |
| const codeEl = document.getElementById('correctedCode'); | |
| if(codeEl) hljs.highlightElement(codeEl); | |
| /* highlight err-box md code blocks */ | |
| if(r.error_analysis) hlCode(jb); | |
| } | |
| function copyCode(){ | |
| const el = document.getElementById('correctedCode'); | |
| if(!el) return; | |
| navigator.clipboard.writeText(el.textContent); | |
| const btn = document.getElementById('copyCodeBtn'); | |
| if(btn){ btn.textContent = 'Copied ✓'; setTimeout(()=>btn.textContent='Copy', 1800); } | |
| } | |
| /* ── History ── */ | |
| function addHistory(q){ | |
| if(hist.includes(q)) return; | |
| hist.unshift(q); | |
| if(hist.length > 6) hist.pop(); | |
| renderHistory(); | |
| } | |
| function renderHistory(){ | |
| const list = document.getElementById('histList'); | |
| const wrap = document.getElementById('histWrap'); | |
| if(!hist.length){ wrap.style.display='none'; return; } | |
| wrap.style.display = ''; | |
| list.innerHTML = hist.map(q => | |
| `<div class="q-hist-item" onclick="fillQuery(this)" title="${esc(q)}">${esc(q)}</div>` | |
| ).join(''); | |
| } | |
| function fillQuery(el){ | |
| const ta = document.getElementById('qInput'); | |
| ta.value = el.title; | |
| ta.style.height='auto'; | |
| ta.style.height = Math.min(ta.scrollHeight,340)+'px'; | |
| ta.focus(); | |
| } | |
| /* ── Main ── */ | |
| async function runDebug(){ | |
| if(running) return; | |
| const q = document.getElementById('qInput').value.trim(); | |
| const temp = parseFloat(document.getElementById('tSlider').value); | |
| if(!q){ document.getElementById('qInput').focus(); return; } | |
| running = true; | |
| document.getElementById('runBtn').disabled = true; | |
| const t0 = Date.now(); | |
| setStatus('run','Querying Trinity Large + Nemotron Nano in parallel…'); | |
| panelSkel(0); panelSkel(1); | |
| judgeSkel(); | |
| try{ | |
| const res = await fetch(`${API}/api/v1/debug`,{ | |
| method:'POST', | |
| headers:{'Content-Type':'application/json'}, | |
| body:JSON.stringify({question:q, temperature:temp}) | |
| }); | |
| if(!res.ok){ | |
| const e = await res.json().catch(()=>({})); | |
| throw new Error(e.detail || e.error || `HTTP ${res.status}`); | |
| } | |
| const data = await res.json(); | |
| const ms = Date.now()-t0; | |
| data.panel.forEach((r,i)=>panelResult(i,r)); | |
| await new Promise(r=>setTimeout(r,150)); | |
| judgeResult(data.judge); | |
| const ok = data.panel.filter(p=>!p.error).length; | |
| setStatus('done',`Done — ${ok}/2 models + judge completed`, `${ms}ms`); | |
| qCount++; | |
| document.getElementById('qCnt').textContent = qCount; | |
| addHistory(q); | |
| }catch(err){ | |
| setStatus('err',`Error: ${err.message}`); | |
| document.getElementById('jBody').innerHTML = | |
| `<div style="padding:16px 14px"><div class="mc-err">⚠ ${esc(err.message)}</div></div>`; | |
| [0,1].forEach(i=>{ | |
| document.getElementById(`c${i}`).dataset.s='er'; | |
| document.querySelector(`#c${i} .mc-body`).innerHTML='<div class="mc-err">Request failed</div>'; | |
| }); | |
| } | |
| running=false; | |
| document.getElementById('runBtn').disabled=false; | |
| } | |
| /* ── textarea auto-resize ── */ | |
| const ta = document.getElementById('qInput'); | |
| ta.addEventListener('input',()=>{ | |
| ta.style.height='auto'; | |
| ta.style.height=Math.min(ta.scrollHeight,340)+'px'; | |
| }); | |
| /* ── Ctrl+Enter ── */ | |
| ta.addEventListener('keydown',e=>{ | |
| if((e.ctrlKey||e.metaKey)&&e.key==='Enter'){e.preventDefault();runDebug();} | |
| }); | |
| </script> | |
| </body> | |
| </html> |