Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fb2a6fe315 | ||
|
|
ade2a82b19 |
@ -1,4 +1,4 @@
|
||||
import React, { useState } from "react";
|
||||
import React from "react";
|
||||
import { BOTTOMTEXT } from "../constants/constants";
|
||||
import { useMessageFetching } from "../context/MessageFetch";
|
||||
import { send } from "./Icons";
|
||||
@ -8,6 +8,7 @@ type InputProps = {
|
||||
input: string;
|
||||
setInput: (value: string) => void;
|
||||
inputRef: React.RefObject<HTMLDivElement>;
|
||||
socket: any;
|
||||
};
|
||||
|
||||
export default function Input({
|
||||
@ -15,6 +16,7 @@ export default function Input({
|
||||
input,
|
||||
setInput,
|
||||
inputRef,
|
||||
socket,
|
||||
}: InputProps) {
|
||||
const {
|
||||
messageFetching,
|
||||
@ -171,7 +173,9 @@ export default function Input({
|
||||
|
||||
{messageFetching && (
|
||||
<button
|
||||
onClick={stopFetching}
|
||||
onClick={() => {
|
||||
stopFetching(socket);
|
||||
}}
|
||||
style={{
|
||||
position: "absolute",
|
||||
bottom: "18vh",
|
||||
|
||||
@ -30,7 +30,7 @@ export const MessageFetchContext = createContext({
|
||||
setFetchedMessages: (value: string) => {},
|
||||
fetchedMessages: "",
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
stopFetching: () => {},
|
||||
stopFetching: (message: string) => {},
|
||||
});
|
||||
|
||||
export const useMessageFetching = () => React.useContext(MessageFetchContext);
|
||||
@ -45,7 +45,8 @@ const MessageFetchProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
setMessageFetching(!messageFetching);
|
||||
};
|
||||
|
||||
const stopFetching = () => {
|
||||
const stopFetching = (socket: any) => {
|
||||
socket.emit("stopResponding");
|
||||
setMessageFetching(false);
|
||||
setDisableinput(false);
|
||||
|
||||
|
||||
@ -19,6 +19,7 @@ export default function Main() {
|
||||
disableinput,
|
||||
setDisableinput,
|
||||
setFetchedMessages,
|
||||
messageFetching,
|
||||
} = useMessageFetching();
|
||||
|
||||
const inputRef = useRef<HTMLDivElement>(null);
|
||||
@ -55,14 +56,17 @@ export default function Main() {
|
||||
|
||||
if (messages.length > 0) {
|
||||
setResponse((prevResponse) => prevResponse + justText);
|
||||
setFetchedMessages(response);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
setMessages((prev) => {
|
||||
prev[prev.length - 1].message = response;
|
||||
return [...prev];
|
||||
});
|
||||
if (messageFetching) {
|
||||
setFetchedMessages(response);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
setMessages((prev) => {
|
||||
prev[prev.length - 1].message = response;
|
||||
return [...prev];
|
||||
});
|
||||
}
|
||||
|
||||
// console.log(JSON.stringify(response));
|
||||
}
|
||||
@ -170,6 +174,7 @@ export default function Main() {
|
||||
input={input}
|
||||
setInput={setInput}
|
||||
inputRef={inputRef}
|
||||
socket={socket}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
197
src/index.ts
197
src/index.ts
@ -1,11 +1,8 @@
|
||||
import axios from "axios";
|
||||
import { spawn } from "child_process";
|
||||
import cors from "cors";
|
||||
import { app, BrowserWindow } from "electron";
|
||||
import express from "express";
|
||||
import fs from "fs";
|
||||
import http from "http";
|
||||
import path from "path";
|
||||
import { Server } from "socket.io";
|
||||
|
||||
const expressapp = express();
|
||||
@ -24,192 +21,28 @@ expressapp.use(cors());
|
||||
|
||||
const EXPRESSPORT = 8889;
|
||||
const CHAT_APP_LOCATION = app.getAppPath() + "/src/models/chat";
|
||||
const homeDir = app.getPath("home");
|
||||
const MODEL_LOCATION = path.join(homeDir, "FreedomGPT");
|
||||
const MODEL_URL =
|
||||
"https://huggingface.co/Sosaka/Alpaca-native-4bit-ggml/resolve/main/ggml-alpaca-7b-q4.bin";
|
||||
const FILESIZE = 4212727017;
|
||||
|
||||
const FILEPATH = path.join(MODEL_LOCATION, "ggml-alpaca-7b-q4.bin");
|
||||
|
||||
const downloadFile = async (
|
||||
url: string,
|
||||
dest: string,
|
||||
loaderWindow: BrowserWindow
|
||||
) => {
|
||||
const response = await axios({
|
||||
url,
|
||||
method: "GET",
|
||||
responseType: "stream",
|
||||
});
|
||||
const totalLength = response.headers["content-length"];
|
||||
const writer = fs.createWriteStream(dest);
|
||||
response.data.pipe(writer);
|
||||
return new Promise<number>((resolve, reject) => {
|
||||
writer.on("finish", () => resolve(Number(totalLength)));
|
||||
writer.on("error", reject);
|
||||
response.data.on("data", () => {
|
||||
const downloadedLength = writer.bytesWritten;
|
||||
const downloadedFileInMB = (downloadedLength / 1000000).toFixed(2);
|
||||
|
||||
loaderWindow.webContents.executeJavaScript(`
|
||||
document.getElementById("downloadedFile").innerText = "${downloadedFileInMB}";
|
||||
`);
|
||||
});
|
||||
|
||||
response.data.on("error", reject);
|
||||
});
|
||||
};
|
||||
|
||||
const createLoaderWindow = (): BrowserWindow => {
|
||||
const loaderWindow = new BrowserWindow({
|
||||
height: 1080,
|
||||
width: 1080,
|
||||
alwaysOnTop: true,
|
||||
});
|
||||
loaderWindow.loadURL(
|
||||
`data:text/html,
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Loading...</title>
|
||||
<style>
|
||||
body {
|
||||
background-color: rgb(60, 59, 59);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
.loader {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
text-align: center;
|
||||
color: white;
|
||||
z-index: 9999;
|
||||
}
|
||||
.loader .lds-ring {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
}
|
||||
.loader .lds-ring div {
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 51px;
|
||||
height: 51px;
|
||||
margin: 6px;
|
||||
border: 6px solid white;
|
||||
border-radius: 50%;
|
||||
animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
|
||||
border-color: white transparent transparent transparent;
|
||||
}
|
||||
.loader .lds-ring div:nth-child(1) {
|
||||
animation-delay: -0.45s;
|
||||
}
|
||||
.loader .lds-ring div:nth-child(2) {
|
||||
animation-delay: -0.3s;
|
||||
}
|
||||
.loader .lds-ring div:nth-child(3) {
|
||||
animation-delay: -0.15s;
|
||||
}
|
||||
@keyframes lds-ring {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
.loader p {
|
||||
margin-top: 20px;
|
||||
font-size: 18px;
|
||||
width: 80vw;
|
||||
}
|
||||
.download-time {
|
||||
margin-top: 20px;
|
||||
font-size: 16px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="loader">
|
||||
<p class="checkInternet">
|
||||
</p>
|
||||
<div class="lds-ring"><div></div><div></div><div></div><div></div></div>
|
||||
<p>Please wait while we finalize the installation of your software. This process may take a several minutes depending upon your internet connection, so please refrain from closing this window and disconnecting from the internet.</p>
|
||||
|
||||
<p>
|
||||
Downloaded: <span id="downloadedFile">0</span> MB / ${(
|
||||
FILESIZE / 1000000
|
||||
).toFixed(2)}MB
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
);
|
||||
return loaderWindow;
|
||||
};
|
||||
|
||||
const checkIfFileExists = async () => {
|
||||
if (!fs.existsSync(FILEPATH)) {
|
||||
console.log("File does not exist");
|
||||
const loaderWindow = createLoaderWindow();
|
||||
if (fs.existsSync(MODEL_LOCATION)) {
|
||||
fs.rmdirSync(MODEL_LOCATION, { recursive: true });
|
||||
}
|
||||
fs.mkdirSync(MODEL_LOCATION);
|
||||
await downloadFile(MODEL_URL, FILEPATH, loaderWindow)
|
||||
.then((res) => {
|
||||
console.log(res);
|
||||
console.log("Model downloaded successfully.");
|
||||
createWindow();
|
||||
loaderWindow.close();
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
loaderWindow.close();
|
||||
});
|
||||
} else {
|
||||
console.log("File exists, but it is not the correct size");
|
||||
const mainFileSize = fs.statSync(FILEPATH).size;
|
||||
if (mainFileSize !== FILESIZE) {
|
||||
const loaderWindow = createLoaderWindow();
|
||||
if (fs.existsSync(MODEL_LOCATION)) {
|
||||
fs.rmdirSync(MODEL_LOCATION, { recursive: true });
|
||||
}
|
||||
fs.mkdirSync(MODEL_LOCATION);
|
||||
await downloadFile(MODEL_URL, FILEPATH, loaderWindow)
|
||||
.then((res) => {
|
||||
console.log(res);
|
||||
console.log("Model downloaded successfully.");
|
||||
createWindow();
|
||||
loaderWindow.close();
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
loaderWindow.close();
|
||||
});
|
||||
} else {
|
||||
createWindow();
|
||||
}
|
||||
}
|
||||
};
|
||||
const MODEL_LOCATION = app.getAppPath() + "/src/models/ggml-alpaca-7b-q4.bin";
|
||||
|
||||
/* Make sure to use the actual path to your app, not the relative path ( )
|
||||
Donot use ../ or ./
|
||||
*/
|
||||
io.on("connection", (socket) => {
|
||||
console.log("A user connecteddd");
|
||||
|
||||
let program = spawn(CHAT_APP_LOCATION, ["-m", FILEPATH]);
|
||||
let program = spawn(CHAT_APP_LOCATION, ["-m", MODEL_LOCATION]);
|
||||
|
||||
socket.on("chatstart", () => {
|
||||
program = spawn(CHAT_APP_LOCATION, ["-m", FILEPATH]);
|
||||
program = spawn(CHAT_APP_LOCATION, ["-m", MODEL_LOCATION]);
|
||||
console.log("S2", program.pid);
|
||||
});
|
||||
|
||||
socket.on("stopResponding", () => {
|
||||
console.log("E1", program.pid);
|
||||
program.kill();
|
||||
program = null;
|
||||
socket.emit("chatend");
|
||||
});
|
||||
|
||||
socket.on("message", (message) => {
|
||||
console.log("M1", program.pid);
|
||||
program.stdin.write(message + "\n");
|
||||
@ -256,7 +89,7 @@ const createWindow = (): void => {
|
||||
width: 1080,
|
||||
webPreferences: {
|
||||
preload: MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY,
|
||||
devTools: false,
|
||||
devTools: true,
|
||||
},
|
||||
});
|
||||
|
||||
@ -268,7 +101,7 @@ const createWindow = (): void => {
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.on("ready", () => {
|
||||
checkIfFileExists();
|
||||
createWindow();
|
||||
});
|
||||
|
||||
// Quit when all windows are closed, except on macOS. There, it's common
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user