|
|
|
|
|
export function nowMs() { |
|
|
return performance.now(); |
|
|
} |
|
|
|
|
|
export function sleep(ms) { |
|
|
return new Promise(res => setTimeout(res, ms)); |
|
|
} |
|
|
|
|
|
|
|
|
export function measureAsync(fn) { |
|
|
const start = nowMs(); |
|
|
return Promise.resolve() |
|
|
.then(() => fn()) |
|
|
.then(res => ({res, ms: nowMs() - start})); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function logTo(el, evt) { |
|
|
console.log(evt.job) |
|
|
if (!el) return; |
|
|
const row = document.createElement('tr'); |
|
|
row.innerHTML = ` |
|
|
<td>${evt.job.id}</td> |
|
|
<td>${new Date().toLocaleTimeString()}</td> |
|
|
<td>${evt.route}</td> |
|
|
<td>${evt.totalLatency?.toFixed(2) || evt.latency?.toFixed(2) || 0}ms</td> |
|
|
<td>${evt.queueingTime?.toFixed(2) || 0}ms</td> |
|
|
<td>${evt.inferenceTime?.toFixed(2) || evt.latency?.toFixed(2) || 0}ms</td> |
|
|
<td title="${escapeHtml(evt.job.prompt)}">${escapeHtml(evt.job.prompt.substring(0, 30))}...</td> |
|
|
<td title="${evt.response || ''}">${(evt.response || '').substring(0, 30)}</td> |
|
|
<td>${evt.evalRes.exactMatch}</td> |
|
|
`; |
|
|
el.appendChild(row); |
|
|
el.scrollTop = el.scrollHeight; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function escapeHtml(str) { |
|
|
return str.replace(/[&<>"']/g, (char) => { |
|
|
const escapeMap = { |
|
|
'&': '&', |
|
|
'<': '<', |
|
|
'>': '>', |
|
|
'"': '"', |
|
|
"'": ''', |
|
|
}; |
|
|
return escapeMap[char]; |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function getNumberOfWords(text) { |
|
|
return text.trim().split(/\s+/).length; |
|
|
} |
|
|
|