First GUI version
This commit is contained in:
		
							
								
								
									
										6
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| node_modules/ | ||||
| main-linux | ||||
| main-macos | ||||
| *.exe | ||||
| kuzco-cli* | ||||
| gui/dist/ | ||||
| *.exe | ||||
|   | ||||
							
								
								
									
										56
									
								
								gui/css/styles.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								gui/css/styles.css
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										25
									
								
								gui/index.html
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										36
									
								
								gui/kuzco-gui.js
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										57
									
								
								gui/kuzcoCore.js
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										3506
									
								
								gui/package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										56
									
								
								gui/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								gui/package.json
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										5
									
								
								gui/preload.js
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										41
									
								
								gui/renderer.js
									
									
									
									
									
										Normal 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!'); | ||||
|     } | ||||
| }); | ||||
		Reference in New Issue
	
	Block a user