File size: 3,458 Bytes
13143c5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dd1b723
 
13143c5
 
 
 
 
 
 
dd1b723
13143c5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dd1b723
13143c5
 
 
 
dd1b723
13143c5
 
 
 
dd1b723
 
13143c5
 
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import { pipeline, TextStreamer } from 'https://cdn.jsdelivr.net/npm/@huggingface/[email protected]';

document.addEventListener('DOMContentLoaded', () => {
    const chatContainer = document.getElementById('chat-container');
    const chatForm = document.getElementById('chat-form');
    const userInput = document.getElementById('user-input');
    const loading = document.getElementById('loading');
    const errorDiv = document.getElementById('error');
    let generator = null;
    let messages = [{ role: "system", content: "You are a helpful assistant." }];

    async function initGenerator() {
        try {
            loading.classList.remove('hidden');
            errorDiv.classList.add('hidden');
            generator = await pipeline(
                "text-generation",
                "onnx-community/gemma-3-270m-it-ONNX",
                { dtype: "fp32" }
            );
            loading.classList.add('hidden');
            addMessage('system', 'Chatbot is ready! How can I help you?');
        } catch (err) {
            loading.classList.add('hidden');
            errorDiv.textContent = 'Failed to load the model. Please try refreshing the page.';
            errorDiv.classList.remove('hidden');
            console.error(err);
        }
    }

    function addMessage(role, content) {
        const messageDiv = document.createElement('div');
        messageDiv.classList.add('message', role === 'user' ? 'user-message' : 'bot-message');
        messageDiv.textContent = content;
        chatContainer.appendChild(messageDiv);
        chatContainer.scrollTop = chatContainer.scrollHeight;
    }

    async function generateResponse() {
        if (!generator) return;

        loading.classList.remove('hidden');
        document.getElementById('send-btn').disabled = true;
        userInput.disabled = true;

        const botMessageDiv = document.createElement('div');
        botMessageDiv.classList.add('message', 'bot-message');
        chatContainer.appendChild(botMessageDiv);
        chatContainer.scrollTop = chatContainer.scrollHeight;

        try {
            const streamer = new TextStreamer(generator.tokenizer, {
                skip_prompt: true,
                skip_special_tokens: true,
                callback_function: (text) => {
                    botMessageDiv.textContent += text;
                    chatContainer.scrollTop = chatContainer.scrollHeight;
                }
            });

            const output = await generator(messages, {
                max_new_tokens: 512,
                do_sample: false,
                streamer: streamer
            });

            const response = output[0].generated_text.at(-1).content;
            messages.push({ role: "assistant", content: response });
        } catch (err) {
            botMessageDiv.textContent = 'Error generating response.';
            console.error(err);
        } finally {
            loading.classList.add('hidden');
            document.getElementById('send-btn').disabled = false;
            userInput.disabled = false;
            userInput.focus();
        }
    }

    chatForm.addEventListener('submit', (e) => {
        e.preventDefault();
        const userText = userInput.value.trim();
        if (!userText) return;

        addMessage('user', userText);
        messages.push({ role: "user", content: userText });
        userInput.value = '';
        generateResponse();
    });

    initGenerator();
});