File size: 2,035 Bytes
3ea6625
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0314e5b
3ea6625
0726d27
9b487db
3ea6625
0726d27
 
40b0e49
0726d27
 
0314e5b
 
 
3a94de3
8799da1
0726d27
 
 
3ea6625
281044f
 
3a94de3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
281044f
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// helpers: timing and small utilities
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}));
}


/**
 * Log text to a given HTML element with timestamp to show the log in the UI
 *
 * @param el - HTML element to log to
 * @param evt - Event object with job, route, latency, response, and timing metrics
 */
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;
}

/**
 * Escapes HTML special characters in a string to prevent HTML injection
 *
 * @param str - Input string
 * @returns {string} - Escaped string
 */
function escapeHtml(str) {
    return str.replace(/[&<>"']/g, (char) => {
        const escapeMap = {
            '&': '&amp;',
            '<': '&lt;',
            '>': '&gt;',
            '"': '&quot;',
            "'": '&#039;',
        };
        return escapeMap[char];
    });
}

/**
 * Approximates the number of words in a given text string
 *
 * @param text - Input text string
 * @returns {number} - Approximate number of words
 */
export function getNumberOfWords(text) {
    return text.trim().split(/\s+/).length;
}