File size: 3,771 Bytes
edd8b11
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
document.addEventListener("DOMContentLoaded", () => {
    const chatForm = document.getElementById("chat-form");
    const chatInput = document.getElementById("chat-input");
    const chatContainer = document.getElementById("chat-container");
    const sendBtn = document.getElementById("send-btn");

    let messages = [];

    chatForm.addEventListener("submit", async (e) => {
        e.preventDefault();
        
        const content = chatInput.value.trim();
        if (!content) return;

        // Clear input
        chatInput.value = "";
        
        // Add user message to UI
        addMessageToUI("user", content);
        
        // Add to history
        messages.push({ role: "user", content });

        // Disable input while generating
        chatInput.disabled = true;
        sendBtn.disabled = true;

        // Add an empty assistant message bubble to UI
        const assistantBubble = addMessageToUI("assistant", "");
        
        try {
            const response = await fetch("/chat", {
                method: "POST",
                headers: {
                    "Content-Type": "application/json"
                },
                body: JSON.stringify({ messages })
            });

            if (!response.ok) {
                throw new Error("Failed to fetch response");
            }

            const reader = response.body.getReader();
            const decoder = new TextDecoder();
            let assistantMessage = "";

            while (true) {
                const { done, value } = await reader.read();
                if (done) break;
                
                const chunk = decoder.decode(value, { stream: true });
                const lines = chunk.split("\n");
                
                for (const line of lines) {
                    if (line.startsWith("data: ")) {
                        const dataStr = line.replace("data: ", "");
                        if (dataStr === "[DONE]") {
                            break;
                        }
                        try {
                            const data = JSON.parse(dataStr);
                            assistantMessage += data.content;
                            // Update UI
                            assistantBubble.textContent = assistantMessage;
                            // Scroll to bottom
                            chatContainer.scrollTop = chatContainer.scrollHeight;
                        } catch (err) {
                            console.error("Error parsing SSE data", err);
                        }
                    }
                }
            }

            // Push final assistant message to history
            messages.push({ role: "assistant", content: assistantMessage });

        } catch (error) {
            console.error(error);
            assistantBubble.textContent = "Error: Could not connect to the model. Please try again.";
        } finally {
            chatInput.disabled = false;
            sendBtn.disabled = false;
            chatInput.focus();
        }
    });

    function addMessageToUI(role, content) {
        const msgDiv = document.createElement("div");
        msgDiv.className = `message ${role === "user" ? "user" : "system"}`;

        const avatarDiv = document.createElement("div");
        avatarDiv.className = "avatar";
        avatarDiv.textContent = role === "user" ? "U" : "A";

        const bubbleDiv = document.createElement("div");
        bubbleDiv.className = "bubble";
        bubbleDiv.textContent = content;

        msgDiv.appendChild(avatarDiv);
        msgDiv.appendChild(bubbleDiv);

        chatContainer.appendChild(msgDiv);
        chatContainer.scrollTop = chatContainer.scrollHeight;
        
        return bubbleDiv;
    }
});