First GUI version

This commit is contained in:
Wizzard 2024-03-09 02:15:01 -05:00
parent 006ce3a7c4
commit fd8bba8199
9 changed files with 3785 additions and 3 deletions

4
.gitignore vendored
View File

@ -1,4 +1,4 @@
node_modules/ node_modules/
main-linux kuzco-cli*
main-macos gui/dist/
*.exe *.exe

56
gui/css/styles.css Normal file
View File

@ -0,0 +1,56 @@
body {
background-color: #2c3e50;
color: #ecf0f1;
font-family: Arial, sans-serif;
display: flex;
flex-direction: column;
height: 100vh;
margin: 0;
padding: 20px;
box-sizing: border-box;
}
#chatHistory {
height: 300px;
flex-grow: 1;
overflow-y: auto;
padding: 10px;
margin-bottom: 20px;
border: 1px solid #34495e;
border-radius: 5px;
}
.message {
font-size: 0.9em;
padding: 5px 10px;
margin-bottom: 15px;
padding: 10px;
background-color: #34495e;
border-radius: 5px;
}
.userMessage {
align-self: flex-end;
background-color: #2980b9;
}
.assistantMessage {
align-self: flex-start;
background-color: #16a085;
}
#chatForm {
display: flex;
gap: 10px;
}
#promptInput {
flex-grow: 1;
padding: 10px;
border: 1px solid #34495e;
border-radius: 5px;
color: inherit;
background-color: #2c3e50;
}
#sendPrompt {
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
background-color: #2980b9;
color: #ecf0f1;
}

25
gui/index.html Normal file
View File

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Kuzco Chat</title>
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<div id="app">
<header>
<h1>Welcome to Kuzco Chat</h1>
</header>
<main id="chatHistory" class="chat-history">
</main>
<footer>
<form id="chatForm" class="chat-form">
<input id="promptInput" type="text" placeholder="Enter your prompt" autofocus>
<button type="submit" id="sendPrompt">Send</button>
</form>
</footer>
</div>
<script src="renderer.js"></script>
</body>
</html>

36
gui/kuzco-gui.js Normal file
View File

@ -0,0 +1,36 @@
const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('path');
const KuzcoCore = require('./kuzcoCore');
function createWindow() {
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
nodeIntegration: false,
contextIsolation: true,
enableRemoteModule: false,
},
});
mainWindow.loadFile('index.html');
}
app.whenReady().then(() => {
createWindow();
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow();
});
});
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit();
});
const kuzcoCore = new KuzcoCore();
ipcMain.handle('send-prompt', async (event, prompt) => {
return await kuzcoCore.sendPrompt(prompt);
});

57
gui/kuzcoCore.js Normal file
View File

@ -0,0 +1,57 @@
const fs = require('fs');
const path = require('path');
const os = require('os');
const fetch = require('node-fetch');
async function fetchData(url, options = {}) {
const { default: fetch } = await import('node-fetch');
const response = await fetch(url, options);
return response;
}
class KuzcoCore {
constructor() {
this.API_KEY = this.loadApiKey();
}
loadApiKey() {
const configPath = path.join(os.homedir(), '.kuzco-cli', 'config.json');
try {
const configFile = fs.readFileSync(configPath);
const config = JSON.parse(configFile);
return config.API_KEY;
} catch (error) {
console.error(`An error occurred while reading the API key: ${error.message}`);
return '';
}
}
async sendPrompt(prompt) {
try {
const response = await fetch('https://relay.kuzco.xyz/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
messages: [{ role: 'user', 'content': prompt + '\n' }],
model: 'mistral',
stream: false,
}),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error(`An error occurred: ${error.message}`);
return { error: error.message };
}
}
}
module.exports = KuzcoCore;

3506
gui/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

56
gui/package.json Normal file
View File

@ -0,0 +1,56 @@
{
"name": "kuzco-gui",
"version": "1.0.0",
"description": "Simple gui for kuzco api",
"author": "Wizzard",
"main": "kuzco-gui.js",
"homepage": "https://git.deadzone.lol/Wizzard/kuzco-cli",
"scripts": {
"start": "electron .",
"pack": "electron-builder --dir",
"dist-linux": "electron-builder --linux"
},
"build": {
"appId": "com.yourname.kuzco",
"productName": "KuzcoChat",
"directories": {
"output": "dist"
},
"files": [
"**/*",
"!**/*.ts",
"!*.code-workspace",
"!**/*.js.map",
"!**/node_modules/*/{CHANGELOG.md,README.md,README,readme.md,readme}",
"!**/node_modules/*/{test,__tests__,tests,powered-test,example,examples}",
"!**/node_modules/*.d.ts",
"!**/node_modules/.bin",
"!**/*.{o,hprof,orig,pyc,pyo,rbc}",
"!**/._*",
"!**/{.DS_Store,.git,.hg,.svn,CVS,RCS,SCCS,__pycache__,thumbs.db,.db,desktop.ini}"
],
"win": {
"target": [
"nsis",
"portable"
]
},
"mac": {
"target": "dmg",
"category": "public.app-category.utilities"
},
"linux": {
"target": [
"AppImage",
"deb"
]
}
},
"devDependencies": {
"electron": "latest",
"electron-builder": "^22.0.0"
},
"dependencies": {
"node-fetch": "^2.7.0"
}
}

5
gui/preload.js Normal file
View File

@ -0,0 +1,5 @@
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electronAPI', {
sendPrompt: (prompt) => ipcRenderer.invoke('send-prompt', prompt),
});

41
gui/renderer.js Normal file
View File

@ -0,0 +1,41 @@
function displayMessage(message, sender) {
const chatHistory = document.getElementById('chatHistory');
const messageDiv = document.createElement('div');
messageDiv.classList.add('message');
if (sender === 'user') {
messageDiv.classList.add('userMessage');
} else if (sender === 'assistant') {
messageDiv.classList.add('assistantMessage');
}
messageDiv.textContent = message;
chatHistory.appendChild(messageDiv);
chatHistory.scrollTop = chatHistory.scrollHeight;
}
document.addEventListener('DOMContentLoaded', () => {
const chatForm = document.getElementById('chatForm');
const promptInput = document.getElementById('promptInput');
if (chatForm && promptInput) {
chatForm.addEventListener('submit', async (event) => {
event.preventDefault();
const userInput = promptInput.value;
promptInput.value = '';
displayMessage(userInput, 'user');
try {
const response = await window.electronAPI.sendPrompt(userInput);
const assistantMessage = response.choices[0].message.content.trim();
displayMessage(assistantMessage, 'assistant');
} catch (error) {
console.error(`Error sending prompt: ${error.message}`);
displayMessage(`Error: ${error.message}`, 'assistant');
}
});
} else {
console.error('chatForm or promptInput elements not found!');
}
});