File size: 5,733 Bytes
bf64d81
e8fcd85
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fa40931
 
 
 
 
 
 
 
e8fcd85
 
 
bf64d81
 
 
 
 
e8fcd85
bf64d81
e8fcd85
bf64d81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e8fcd85
 
bf64d81
 
 
 
 
 
e8fcd85
 
 
 
 
 
 
 
 
 
bf64d81
 
 
e8fcd85
 
 
 
 
1daa44a
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
110
111
112
113
114
115
116
// application/static/js/chat.js
import requests from "./request.js";

class Chat{
    constructor(uiManager){
        this.uiManager = uiManager;
    }
    async chat(){
        let payload = {
            "model": this.uiManager.initializer.model,
            "prompt": this.uiManager.userP.innerText.trim(),
            "convId": this.uiManager.initializer.convId,
            "system": this.uiManager.initializer.systemPrompt,
            "temperature": 0.7,
            "top_p": 0.9,
            "webSearch": this.uiManager.webSearch
        };

        if (this.uiManager.imageMode) {
            payload.image = this.uiManager.userDiv.querySelector('img')?.src || null;
        }


        try {
            if(this.uiManager.initializer.convId==null){
                // Use the new createConv method in Initialize
                const newConvId = await this.uiManager.initializer.createConv();
                if (!newConvId) { // Check for error
                    console.error("Failed to create new conversation.");
                    return; // Exit if creation failed
                }
                payload["convId"] = newConvId; // Use the returned convId

            }
            this.uiManager.textBox.value='';
            this.uiManager.sendBtn.disabled = true;

            // Display "Reasoning..." and get the reasoning display element.
            const reasoningDisplay = this.uiManager.showReasoning();


            const response = await requests.request('POST','/completions',{"Content-Type": "application/json"},JSON.stringify(payload),true);
            let fullResponse = ""; // Accumulate the full response
            for await (const chunk of response){
                fullResponse += chunk;

                // Check for commands *within* the streamed response
                let commandMatch;
                if ((commandMatch = fullResponse.match(/\/(\w+)\s*\(([^)]*)\)/))) {
                    const command = commandMatch[1];
                    const argument = commandMatch[2];

                    if (command === "search") {
                        // Remove the command from the displayed text
                        fullResponse = fullResponse.replace(commandMatch[0], "");
                        this.uiManager.aiP.innerHTML = fullResponse; // Update with cleaned text
                        this.uiManager.renderSymbols.renderAll(this.uiManager.aiP)
                        // Perform web search
                        const searchData = await requests.request('POST', '/websearch', { "Content-Type": "application/json" }, JSON.stringify({ query: argument }), false);
                        const searchResults = await searchData.json();
                         // Display search results, possibly in a dedicated container
                        this.uiManager.appendAiMsg(searchResults.result);
                    } else if (command === "image") {
                         // Remove the command from the displayed text
                        fullResponse = fullResponse.replace(commandMatch[0], "");
                        this.uiManager.aiP.innerHTML = fullResponse;
                        this.uiManager.renderSymbols.renderAll(this.uiManager.aiP);

                        const imageData = await requests.request('POST', '/generate_image', { "Content-Type": "application/json" }, JSON.stringify({ prompt: argument }), false);
                         const imageResult = await imageData.json();
                         if (imageResult && imageResult.image) {
                             this.uiManager.appendAiMsg(`<img src="data:image/png;base64,${imageResult.image}" alt="Generated Image" style="max-width: 100%; height: auto;">`);
                         } else {
                             this.uiManager.appendAiMsg("Error generating image.");
                         }
                    } else if (command === "memsave") {
                        fullResponse = fullResponse.replace(commandMatch[0], ""); //remove command
                        this.uiManager.aiP.innerHTML = fullResponse;
                        this.uiManager.renderSymbols.renderAll(this.uiManager.aiP)
                        await requests.request('POST', '/save_memory', { "Content-Type": "application/json" }, JSON.stringify({ memory: argument, convId: this.uiManager.initializer.convId }), false);
                        this.uiManager.displayMemory(argument); // Display the saved memory

                    }
                    //Remove the command and only display the rest
                    this.uiManager.aiP.innerHTML = fullResponse;
                } else {
                    // No command found, display the chunk normally
                    this.uiManager.aiP.innerHTML = fullResponse; // accumulate
                }
                this.uiManager.renderSymbols.renderAll(this.uiManager.aiP)
            };

            if (reasoningDisplay) {
              this.uiManager.updateReasoningTime(reasoningDisplay);  // Update with the final time
            }


        } catch (error) {
            this.uiManager.sendBtn.disabled = false;
            this.uiManager.aiP.innerHTML+= `<span class="error" style="color: red;">${error}</span>`;
            return
        }
        this.uiManager.renderSymbols.renderCode(this.uiManager.aiP);
        if(this.uiManager.initializer.convTitle==null){
            this.uiManager.initializer.convTitle = this.uiManager.userP.innerText.substring(0,23);
            this.uiManager.addChat();
        }

        // Add read-aloud button *after* the response is complete
        this.uiManager.addReadAloudButton(this.uiManager.aiDiv);
        this.uiManager.sendBtn.disabled = false;

    }
}

export default Chat