Update index.html
Browse files- index.html +85 -7
index.html
CHANGED
|
@@ -26,6 +26,9 @@
|
|
| 26 |
.ok{background:rgba(46,204,113,.12);border-color:rgba(46,204,113,.35)}
|
| 27 |
.warn{background:rgba(243,156,18,.12);border-color:rgba(243,156,18,.35)}
|
| 28 |
.err{background:rgba(231,76,60,.12);border-color:rgba(231,76,60,.35)}
|
|
|
|
|
|
|
|
|
|
| 29 |
</style>
|
| 30 |
</head>
|
| 31 |
<body>
|
|
@@ -75,6 +78,12 @@
|
|
| 75 |
</div>
|
| 76 |
</div>
|
| 77 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 78 |
<div class="card">
|
| 79 |
<h3 style="margin:6px 0">Debug log</h3>
|
| 80 |
<div id="log"></div>
|
|
@@ -82,7 +91,6 @@
|
|
| 82 |
|
| 83 |
<script type="module">
|
| 84 |
// ================= Configuration =================
|
| 85 |
-
// ONNX repo (3B Instruct), with multiple quantizations in onnx/ (model_q4.onnx, model_q4f16.onnx, model_int8.onnx, model_fp16.onnx, ...)
|
| 86 |
const MODEL_ID = 'onnx-community/Qwen2.5-Coder-3B-Instruct';
|
| 87 |
const CDN_PRIMARY = 'https://cdn.jsdelivr.net/npm/@huggingface/transformers@3.0.0';
|
| 88 |
const CDN_FALLBACK = 'https://cdn.jsdelivr.net/npm/@xenova/transformers@2.17.2';
|
|
@@ -94,6 +102,59 @@
|
|
| 94 |
progress_callback: setProgress,
|
| 95 |
};
|
| 96 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
// ================= DOM & State =================
|
| 98 |
const $ = s=>document.querySelector(s);
|
| 99 |
const logDiv=$('#log'), chatDiv=$('#chat');
|
|
@@ -107,6 +168,8 @@
|
|
| 107 |
const confirmBox=$('#confirm');
|
| 108 |
const confirmYes=$('#confirm-yes');
|
| 109 |
const confirmNo=$('#confirm-no');
|
|
|
|
|
|
|
| 110 |
|
| 111 |
let pipe=null, cancelled=false, abortGen=null;
|
| 112 |
|
|
@@ -126,9 +189,23 @@
|
|
| 126 |
catch(e){ log('Primary failed, fallback:',CDN_FALLBACK,e?.message); return await import(CDN_FALLBACK); }
|
| 127 |
}
|
| 128 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 129 |
// ================= Events =================
|
| 130 |
loadBtn.addEventListener('click', ()=>{
|
| 131 |
-
// Show confirmation instead of starting download immediately
|
| 132 |
loadBtn.style.display='none';
|
| 133 |
confirmBox.style.display='block';
|
| 134 |
});
|
|
@@ -171,18 +248,19 @@
|
|
| 171 |
const botEl=addMsg('…');
|
| 172 |
stopBtn.disabled=false; chip('', 'Generating…');
|
| 173 |
|
| 174 |
-
// Stream tokens with callback_function (API shape may vary slightly between versions)
|
| 175 |
let outText='';
|
| 176 |
abortGen = new AbortController();
|
| 177 |
-
const
|
| 178 |
-
`${sys?`[SYSTEM]
|
| 179 |
${sys}
|
| 180 |
|
| 181 |
-
|
|
|
|
| 182 |
${user}
|
| 183 |
|
| 184 |
[ASSISTANT]
|
| 185 |
-
|
|
|
|
|
|
|
| 186 |
{
|
| 187 |
max_new_tokens: 256,
|
| 188 |
temperature: 0.7,
|
|
|
|
| 26 |
.ok{background:rgba(46,204,113,.12);border-color:rgba(46,204,113,.35)}
|
| 27 |
.warn{background:rgba(243,156,18,.12);border-color:rgba(243,156,18,.35)}
|
| 28 |
.err{background:rgba(231,76,60,.12);border-color:rgba(231,76,60,.35)}
|
| 29 |
+
.examples{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:10px;margin-top:10px}
|
| 30 |
+
.examples button{justify-content:flex-start}
|
| 31 |
+
.toggle{display:flex;align-items:center;gap:8px}
|
| 32 |
</style>
|
| 33 |
</head>
|
| 34 |
<body>
|
|
|
|
| 78 |
</div>
|
| 79 |
</div>
|
| 80 |
|
| 81 |
+
<div class="card">
|
| 82 |
+
<h3 style="margin:6px 0">Examples</h3>
|
| 83 |
+
<div class="toggle"><input id="autorun" type="checkbox" checked/> <label for="autorun" class="muted">Auto‑run on click</label></div>
|
| 84 |
+
<div id="examples" class="examples"></div>
|
| 85 |
+
</div>
|
| 86 |
+
|
| 87 |
<div class="card">
|
| 88 |
<h3 style="margin:6px 0">Debug log</h3>
|
| 89 |
<div id="log"></div>
|
|
|
|
| 91 |
|
| 92 |
<script type="module">
|
| 93 |
// ================= Configuration =================
|
|
|
|
| 94 |
const MODEL_ID = 'onnx-community/Qwen2.5-Coder-3B-Instruct';
|
| 95 |
const CDN_PRIMARY = 'https://cdn.jsdelivr.net/npm/@huggingface/transformers@3.0.0';
|
| 96 |
const CDN_FALLBACK = 'https://cdn.jsdelivr.net/npm/@xenova/transformers@2.17.2';
|
|
|
|
| 102 |
progress_callback: setProgress,
|
| 103 |
};
|
| 104 |
|
| 105 |
+
// Example presets (rendered as buttons)
|
| 106 |
+
const EXAMPLES = [
|
| 107 |
+
{
|
| 108 |
+
title: 'Parse Apache logs (Python)',
|
| 109 |
+
sys: 'You are a senior coding assistant. Keep answers concise and show tested code.',
|
| 110 |
+
prompt: 'Write a Python function parse_log(line: str) that parses Apache *combined* log format into a dict with keys ip, time, method, path, status, bytes, referrer, ua. Include robust regex, timezone handling, and 5 pytest unit tests.'
|
| 111 |
+
},
|
| 112 |
+
{
|
| 113 |
+
title: 'Refactor callbacks → async/await (JS)',
|
| 114 |
+
sys: 'You are a pragmatic JS refactoring assistant.',
|
| 115 |
+
prompt: 'Refactor this Node.js callback code to async/await with proper error handling and backpressure using streams: ```js
|
| 116 |
+
const fs = require(\'fs\'); fs.readFile(\'in.txt\',(e,d)=>{ if(e) throw e; fs.writeFile(\'out.txt\', d.toString().toUpperCase(), err=>{ if(err) throw err; console.log(\'done\'); }); });
|
| 117 |
+
``` Provide a short explanation.'
|
| 118 |
+
},
|
| 119 |
+
{
|
| 120 |
+
title: 'Cohort retention SQL (Postgres)',
|
| 121 |
+
sys: 'You are a data engineer.',
|
| 122 |
+
prompt: 'Given events(user_id, event_time, event_name) with sign_up and active events, write a SQL that computes weekly user retention (cohorted by signup week) as a pivoted table. Assume UTC timestamps. Explain indexes briefly.'
|
| 123 |
+
},
|
| 124 |
+
{
|
| 125 |
+
title: 'Unit tests with pytest',
|
| 126 |
+
sys: 'You are a Python testing expert.',
|
| 127 |
+
prompt: 'Generate pytest tests for a function normalize_phone(s: str) that returns E.164 format or raises ValueError. Cover edge cases and property tests with hypothesis.'
|
| 128 |
+
},
|
| 129 |
+
{
|
| 130 |
+
title: 'Explain code step by step',
|
| 131 |
+
sys: 'Be a clear explainer for junior developers.',
|
| 132 |
+
prompt: 'Explain the following code step by step, then suggest two improvements for readability and performance: ```python
|
| 133 |
+
from collections import defaultdict
|
| 134 |
+
def f(nums):
|
| 135 |
+
d=defaultdict(int)
|
| 136 |
+
for x in nums: d[x]+=1
|
| 137 |
+
m=max(d.values())
|
| 138 |
+
return [k for k,v in d.items() if v==m]
|
| 139 |
+
```'
|
| 140 |
+
},
|
| 141 |
+
{
|
| 142 |
+
title: 'Regex with explanation',
|
| 143 |
+
sys: 'You write readable regex with comments.',
|
| 144 |
+
prompt: 'Write a single regex that matches a valid IPv4 or IPv6 address. Provide a commented, multi-line version and a short, single-line version, plus examples of matches and non-matches.'
|
| 145 |
+
},
|
| 146 |
+
{
|
| 147 |
+
title: 'Document a Go function',
|
| 148 |
+
sys: 'You are a Go reviewer.',
|
| 149 |
+
prompt: 'Write a Go doc comment and improve the signature for a function that merges two sorted slices of ints and returns a deduplicated sorted slice. Provide a fully working example.'
|
| 150 |
+
},
|
| 151 |
+
{
|
| 152 |
+
title: 'GitHub Actions CI',
|
| 153 |
+
sys: 'You are a DevOps assistant.',
|
| 154 |
+
prompt: 'Create a GitHub Actions workflow (YAML) that runs Python tests on 3.11, caches pip, runs flake8 + pytest, and uploads coverage to Codecov with secrets.CODECOV_TOKEN.'
|
| 155 |
+
}
|
| 156 |
+
];
|
| 157 |
+
|
| 158 |
// ================= DOM & State =================
|
| 159 |
const $ = s=>document.querySelector(s);
|
| 160 |
const logDiv=$('#log'), chatDiv=$('#chat');
|
|
|
|
| 168 |
const confirmBox=$('#confirm');
|
| 169 |
const confirmYes=$('#confirm-yes');
|
| 170 |
const confirmNo=$('#confirm-no');
|
| 171 |
+
const exWrap=$('#examples');
|
| 172 |
+
const autoRun=$('#autorun');
|
| 173 |
|
| 174 |
let pipe=null, cancelled=false, abortGen=null;
|
| 175 |
|
|
|
|
| 189 |
catch(e){ log('Primary failed, fallback:',CDN_FALLBACK,e?.message); return await import(CDN_FALLBACK); }
|
| 190 |
}
|
| 191 |
|
| 192 |
+
function renderExamples(){
|
| 193 |
+
exWrap.innerHTML='';
|
| 194 |
+
EXAMPLES.forEach((ex,i)=>{
|
| 195 |
+
const b=document.createElement('button');
|
| 196 |
+
b.textContent=ex.title; b.className='ghost';
|
| 197 |
+
b.addEventListener('click',()=>{
|
| 198 |
+
sysEl.value = ex.sys || '';
|
| 199 |
+
promptEl.value = ex.prompt || '';
|
| 200 |
+
if(autoRun.checked){ sendBtn.click(); }
|
| 201 |
+
});
|
| 202 |
+
exWrap.appendChild(b);
|
| 203 |
+
});
|
| 204 |
+
}
|
| 205 |
+
renderExamples();
|
| 206 |
+
|
| 207 |
// ================= Events =================
|
| 208 |
loadBtn.addEventListener('click', ()=>{
|
|
|
|
| 209 |
loadBtn.style.display='none';
|
| 210 |
confirmBox.style.display='block';
|
| 211 |
});
|
|
|
|
| 248 |
const botEl=addMsg('…');
|
| 249 |
stopBtn.disabled=false; chip('', 'Generating…');
|
| 250 |
|
|
|
|
| 251 |
let outText='';
|
| 252 |
abortGen = new AbortController();
|
| 253 |
+
const sysPrefix = sys ? `[SYSTEM]
|
|
|
|
| 254 |
${sys}
|
| 255 |
|
| 256 |
+
` : '';
|
| 257 |
+
const promptText = `${sysPrefix}[USER]
|
| 258 |
${user}
|
| 259 |
|
| 260 |
[ASSISTANT]
|
| 261 |
+
`;
|
| 262 |
+
const gen = await pipe(
|
| 263 |
+
promptText,
|
| 264 |
{
|
| 265 |
max_new_tokens: 256,
|
| 266 |
temperature: 0.7,
|