mirror of
https://github.com/lone-cloud/gerbil
synced 2026-06-03 09:33:10 -07:00
code cleanup continues, adding MMAP support, extra polish
This commit is contained in:
parent
d5323d8b3e
commit
ded8acb436
22 changed files with 170 additions and 115 deletions
|
|
@ -74,9 +74,11 @@ trycloudflare
|
|||
unquantized
|
||||
useclblast
|
||||
usecuda
|
||||
usemmap
|
||||
usevulkan
|
||||
vram
|
||||
vulkan
|
||||
vulkaninfo
|
||||
wayland
|
||||
websearch
|
||||
MMAP
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "friendly-kobold",
|
||||
"productName": "Friendly Kobold",
|
||||
"version": "0.4.0",
|
||||
"version": "0.4.1",
|
||||
"description": "A modern Electron shell for KoboldCpp",
|
||||
"main": "out/main/index.js",
|
||||
"homepage": "./",
|
||||
|
|
|
|||
12
src/App.tsx
12
src/App.tsx
|
|
@ -6,7 +6,7 @@ import { InterfaceScreen } from '@/components/screens/Interface';
|
|||
import { WelcomeScreen } from '@/components/screens/Welcome';
|
||||
import { UpdateAvailableModal } from '@/components/UpdateAvailableModal';
|
||||
import { SettingsModal } from '@/components/settings/SettingsModal';
|
||||
import { EjectConfirmDialog } from '@/components/EjectConfirmDialog';
|
||||
import { EjectConfirmModal } from '@/components/EjectConfirmModal';
|
||||
import { ScreenTransition } from '@/components/ScreenTransition';
|
||||
import { AppHeader } from '@/components/AppHeader';
|
||||
import { useUpdateChecker } from '@/hooks/useUpdateChecker';
|
||||
|
|
@ -20,7 +20,7 @@ export const App = () => {
|
|||
const [currentScreen, setCurrentScreen] = useState<Screen | null>(null);
|
||||
const [settingsOpened, setSettingsOpened] = useState(false);
|
||||
const [hasInitialized, setHasInitialized] = useState(false);
|
||||
const [showEjectDialog, setShowEjectDialog] = useState(false);
|
||||
const [showEjectModal, setShowEjectModal] = useState(false);
|
||||
const [activeInterfaceTab, setActiveInterfaceTab] = useState<string | null>(
|
||||
'terminal'
|
||||
);
|
||||
|
|
@ -179,7 +179,7 @@ export const App = () => {
|
|||
if (skipEjectConfirmation) {
|
||||
performEject();
|
||||
} else {
|
||||
setShowEjectDialog(true);
|
||||
setShowEjectModal(true);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -309,9 +309,9 @@ export const App = () => {
|
|||
onClose={() => setSettingsOpened(false)}
|
||||
currentScreen={currentScreen || undefined}
|
||||
/>
|
||||
<EjectConfirmDialog
|
||||
opened={showEjectDialog}
|
||||
onClose={() => setShowEjectDialog(false)}
|
||||
<EjectConfirmModal
|
||||
opened={showEjectModal}
|
||||
onClose={() => setShowEjectModal(false)}
|
||||
onConfirm={handleEjectConfirm}
|
||||
/>
|
||||
</AppShell>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import { Settings, ArrowLeft } from 'lucide-react';
|
|||
import { StyledTooltip } from '@/components/StyledTooltip';
|
||||
import { soundAssets, playSound, initializeAudio } from '@/utils';
|
||||
import iconUrl from '/icon.png';
|
||||
import '@/styles/AppHeader.css';
|
||||
|
||||
type Screen = 'welcome' | 'download' | 'launch' | 'interface';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
import { useState } from 'react';
|
||||
import { Modal, Text, Group, Button, Checkbox, Stack } from '@mantine/core';
|
||||
|
||||
interface EjectConfirmDialogProps {
|
||||
interface EjectConfirmModalProps {
|
||||
opened: boolean;
|
||||
onClose: () => void;
|
||||
onConfirm: (skipConfirmation: boolean) => void;
|
||||
}
|
||||
|
||||
export const EjectConfirmDialog = ({
|
||||
export const EjectConfirmModal = ({
|
||||
opened,
|
||||
onClose,
|
||||
onConfirm,
|
||||
}: EjectConfirmDialogProps) => {
|
||||
}: EjectConfirmModalProps) => {
|
||||
const [skipConfirmation, setSkipConfirmation] = useState(false);
|
||||
|
||||
const handleConfirm = () => {
|
||||
|
|
@ -15,7 +15,7 @@ export const ScreenTransition = ({
|
|||
<Transition
|
||||
mounted={isActive}
|
||||
transition="fade"
|
||||
duration={shouldAnimate ? 150 : 0}
|
||||
duration={shouldAnimate ? 100 : 0}
|
||||
timingFunction="ease-out"
|
||||
>
|
||||
{(styles) => (
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ export const AdvancedTab = () => {
|
|||
failsafe,
|
||||
lowvram,
|
||||
quantmatmul,
|
||||
usemmap,
|
||||
backend,
|
||||
handleAdditionalArgumentsChange,
|
||||
handleNoshiftChange,
|
||||
|
|
@ -21,6 +22,7 @@ export const AdvancedTab = () => {
|
|||
handleFailsafeChange,
|
||||
handleLowvramChange,
|
||||
handleQuantmatmulChange,
|
||||
handleUsemmapChange,
|
||||
} = useLaunchConfig();
|
||||
const [backendSupport, setBackendSupport] = useState<{
|
||||
noavx2: boolean;
|
||||
|
|
@ -148,6 +150,19 @@ export const AdvancedTab = () => {
|
|||
/>
|
||||
</Group>
|
||||
</div>
|
||||
|
||||
<div className={styles.minWidth200}>
|
||||
<Group gap="xs" align="center">
|
||||
<Checkbox
|
||||
checked={usemmap}
|
||||
onChange={(event) =>
|
||||
handleUsemmapChange(event.currentTarget.checked)
|
||||
}
|
||||
label="MMAP"
|
||||
/>
|
||||
<InfoTooltip label="Use MMAP to load models when enabled." />
|
||||
</Group>
|
||||
</div>
|
||||
</Group>
|
||||
</Stack>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ export const LaunchScreen = ({
|
|||
failsafe,
|
||||
lowvram,
|
||||
quantmatmul,
|
||||
usemmap,
|
||||
backend,
|
||||
gpuDevice,
|
||||
gpuPlatform,
|
||||
|
|
@ -148,6 +149,7 @@ export const LaunchScreen = ({
|
|||
flashattention,
|
||||
noavx2,
|
||||
failsafe,
|
||||
usemmap,
|
||||
usecuda: backend === 'cuda' || backend === 'rocm',
|
||||
usevulkan: backend === 'vulkan',
|
||||
useclblast: backend === 'clblast',
|
||||
|
|
@ -248,10 +250,13 @@ export const LaunchScreen = ({
|
|||
websearch,
|
||||
noshift,
|
||||
flashattention,
|
||||
noavx2,
|
||||
failsafe,
|
||||
backend,
|
||||
lowvram,
|
||||
gpuDevice,
|
||||
quantmatmul,
|
||||
usemmap,
|
||||
additionalArguments,
|
||||
sdt5xxl,
|
||||
sdclipl,
|
||||
|
|
|
|||
|
|
@ -2,5 +2,3 @@ export const DEFAULT_CONTEXT_SIZE = 4096;
|
|||
|
||||
export const DEFAULT_MODEL_URL =
|
||||
'https://huggingface.co/MaziyarPanahi/gemma-3-4b-it-GGUF/resolve/main/gemma-3-4b-it.Q8_0.gguf?download=true';
|
||||
|
||||
export const DEFAULT_HOST = '';
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ export const useLaunchConfig = () => {
|
|||
failsafe: state.failsafe,
|
||||
lowvram: state.lowvram,
|
||||
quantmatmul: state.quantmatmul,
|
||||
usemmap: state.usemmap,
|
||||
backend: state.backend,
|
||||
gpuDevice: state.gpuDevice,
|
||||
gpuPlatform: state.gpuPlatform,
|
||||
|
|
@ -55,6 +56,7 @@ export const useLaunchConfig = () => {
|
|||
handleFailsafeChange: state.setFailsafe,
|
||||
handleLowvramChange: state.setLowvram,
|
||||
handleQuantmatmulChange: state.setQuantmatmul,
|
||||
handleUsemmapChange: state.setUsemmap,
|
||||
handleBackendChange: state.setBackend,
|
||||
handleGpuDeviceChange: state.setGpuDevice,
|
||||
handleGpuPlatformChange: state.setGpuPlatform,
|
||||
|
|
|
|||
|
|
@ -21,10 +21,13 @@ interface LaunchArgs {
|
|||
websearch: boolean;
|
||||
noshift: boolean;
|
||||
flashattention: boolean;
|
||||
noavx2: boolean;
|
||||
failsafe: boolean;
|
||||
backend: string;
|
||||
lowvram: boolean;
|
||||
gpuDevice: number | string;
|
||||
quantmatmul: boolean;
|
||||
usemmap: boolean;
|
||||
additionalArguments: string;
|
||||
sdt5xxl: string;
|
||||
sdclipl: string;
|
||||
|
|
@ -98,6 +101,9 @@ const buildConfigArgs = (launchArgs: LaunchArgs): string[] => {
|
|||
[launchArgs.websearch, '--websearch'],
|
||||
[launchArgs.noshift, '--noshift'],
|
||||
[launchArgs.flashattention, '--flashattention'],
|
||||
[launchArgs.noavx2, '--noavx2'],
|
||||
[launchArgs.failsafe, '--failsafe'],
|
||||
[launchArgs.usemmap, '--usemmap'],
|
||||
];
|
||||
|
||||
flagMappings.forEach(([condition, flag, value]) => {
|
||||
|
|
|
|||
|
|
@ -384,6 +384,7 @@ export class KoboldCppManager {
|
|||
flashattention?: boolean;
|
||||
noavx2?: boolean;
|
||||
failsafe?: boolean;
|
||||
usemmap?: boolean;
|
||||
usecuda?: boolean;
|
||||
usevulkan?: boolean;
|
||||
useclblast?: [number, number] | boolean;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,4 @@
|
|||
import {
|
||||
BrowserWindow,
|
||||
app,
|
||||
Menu,
|
||||
shell,
|
||||
ipcMain,
|
||||
nativeImage,
|
||||
} from 'electron';
|
||||
import { BrowserWindow, app, Menu, shell, nativeImage } from 'electron';
|
||||
import * as os from 'os';
|
||||
import { join } from 'path';
|
||||
import { GITHUB_API } from '../../constants';
|
||||
|
|
@ -311,8 +304,9 @@ OS: ${osInfo}`;
|
|||
maximizable: false,
|
||||
show: false,
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
contextIsolation: false,
|
||||
nodeIntegration: false,
|
||||
contextIsolation: true,
|
||||
preload: join(__dirname, '../preload/index.js'),
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -328,21 +322,6 @@ OS: ${osInfo}`;
|
|||
aboutWindow.once('ready-to-show', () => {
|
||||
aboutWindow.show();
|
||||
});
|
||||
|
||||
ipcMain.once('open-github', () => {
|
||||
shell.openExternal(
|
||||
`https://github.com/${GITHUB_API.FRIENDLY_KOBOLD_REPO}`
|
||||
);
|
||||
});
|
||||
|
||||
ipcMain.once('close-about-dialog', () => {
|
||||
aboutWindow.close();
|
||||
});
|
||||
|
||||
aboutWindow.on('closed', () => {
|
||||
ipcMain.removeAllListeners('open-github');
|
||||
ipcMain.removeAllListeners('close-about-dialog');
|
||||
});
|
||||
}
|
||||
|
||||
private getTemplatePath(filename: string): string {
|
||||
|
|
|
|||
|
|
@ -131,8 +131,6 @@
|
|||
</div>
|
||||
|
||||
<script>
|
||||
const { ipcRenderer } = require('electron');
|
||||
|
||||
function setVersionInfo(info) {
|
||||
document.getElementById('version-info').innerHTML = info.replace(
|
||||
/\n/g,
|
||||
|
|
@ -141,11 +139,16 @@
|
|||
}
|
||||
|
||||
function openGitHub() {
|
||||
ipcRenderer.send('open-github');
|
||||
// Send IPC message directly since this is a simple modal
|
||||
if (window.electronAPI && window.electronAPI.app) {
|
||||
window.electronAPI.app.openExternal(
|
||||
'https://github.com/lone-cloud/friendly-kobold'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function closeDialog() {
|
||||
ipcRenderer.send('close-about-dialog');
|
||||
window.close();
|
||||
}
|
||||
|
||||
// Handle keyboard shortcuts
|
||||
|
|
|
|||
|
|
@ -2,14 +2,10 @@ import { contextBridge, ipcRenderer, type IpcRendererEvent } from 'electron';
|
|||
import type { KoboldAPI, AppAPI, ConfigAPI, LogsAPI } from '@/types/electron';
|
||||
|
||||
const koboldAPI: KoboldAPI = {
|
||||
getInstalledVersion: () => ipcRenderer.invoke('kobold:getInstalledVersion'),
|
||||
getInstalledVersions: () => ipcRenderer.invoke('kobold:getInstalledVersions'),
|
||||
getCurrentVersion: () => ipcRenderer.invoke('kobold:getCurrentVersion'),
|
||||
getCurrentBinaryInfo: () => ipcRenderer.invoke('kobold:getCurrentBinaryInfo'),
|
||||
setCurrentVersion: (version: string) =>
|
||||
ipcRenderer.invoke('kobold:setCurrentVersion', version),
|
||||
getVersionFromBinary: (binaryPath: string) =>
|
||||
ipcRenderer.invoke('kobold:getVersionFromBinary', binaryPath),
|
||||
getLatestReleaseWithStatus: () =>
|
||||
ipcRenderer.invoke('kobold:getLatestReleaseWithStatus'),
|
||||
getROCmDownload: () => ipcRenderer.invoke('kobold:getROCmDownload'),
|
||||
|
|
@ -18,11 +14,7 @@ const koboldAPI: KoboldAPI = {
|
|||
getPlatform: () => ipcRenderer.invoke('kobold:getPlatform'),
|
||||
detectGPU: () => ipcRenderer.invoke('kobold:detectGPU'),
|
||||
detectCPU: () => ipcRenderer.invoke('kobold:detectCPU'),
|
||||
detectGPUCapabilities: () =>
|
||||
ipcRenderer.invoke('kobold:detectGPUCapabilities'),
|
||||
detectROCm: () => ipcRenderer.invoke('kobold:detectROCm'),
|
||||
detectAllCapabilities: () =>
|
||||
ipcRenderer.invoke('kobold:detectAllCapabilities'),
|
||||
detectBackendSupport: (binaryPath: string) =>
|
||||
ipcRenderer.invoke('kobold:detectBackendSupport', binaryPath),
|
||||
getAvailableBackends: () => ipcRenderer.invoke('kobold:getAvailableBackends'),
|
||||
|
|
@ -33,7 +25,6 @@ const koboldAPI: KoboldAPI = {
|
|||
ipcRenderer.invoke('kobold:downloadRelease', asset),
|
||||
launchKoboldCpp: (args?: string[], configFilePath?: string) =>
|
||||
ipcRenderer.invoke('kobold:launchKoboldCpp', args, configFilePath),
|
||||
checkForUpdates: () => ipcRenderer.invoke('kobold:checkForUpdates'),
|
||||
getConfigFiles: () => ipcRenderer.invoke('kobold:getConfigFiles'),
|
||||
saveConfigFile: (
|
||||
configName: string,
|
||||
|
|
@ -52,6 +43,7 @@ const koboldAPI: KoboldAPI = {
|
|||
flashattention?: boolean;
|
||||
noavx2?: boolean;
|
||||
failsafe?: boolean;
|
||||
usemmap?: boolean;
|
||||
usecuda?: boolean;
|
||||
usevulkan?: boolean;
|
||||
useclblast?: boolean;
|
||||
|
|
@ -107,7 +99,6 @@ const koboldAPI: KoboldAPI = {
|
|||
};
|
||||
|
||||
const appAPI: AppAPI = {
|
||||
getVersion: () => ipcRenderer.invoke('app:getVersion'),
|
||||
openExternal: (url) => ipcRenderer.invoke('app:openExternal', url),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { create } from 'zustand';
|
||||
import type { ConfigFile } from '@/types';
|
||||
import type { ImageModelPreset } from '@/utils/imageModelPresets';
|
||||
import { DEFAULT_CONTEXT_SIZE, DEFAULT_HOST } from '@/constants';
|
||||
import { DEFAULT_CONTEXT_SIZE } from '@/constants';
|
||||
|
||||
interface LaunchConfigState {
|
||||
gpuLayers: number;
|
||||
|
|
@ -22,6 +22,7 @@ interface LaunchConfigState {
|
|||
failsafe: boolean;
|
||||
lowvram: boolean;
|
||||
quantmatmul: boolean;
|
||||
usemmap: boolean;
|
||||
backend: string;
|
||||
gpuDevice: number;
|
||||
gpuPlatform: number;
|
||||
|
|
@ -51,6 +52,7 @@ interface LaunchConfigState {
|
|||
setFailsafe: (failsafe: boolean) => void;
|
||||
setLowvram: (lowvram: boolean) => void;
|
||||
setQuantmatmul: (quantmatmul: boolean) => void;
|
||||
setUsemmap: (usemmap: boolean) => void;
|
||||
setBackend: (backend: string) => void;
|
||||
setGpuDevice: (device: number) => void;
|
||||
setGpuPlatform: (platform: number) => void;
|
||||
|
|
@ -86,7 +88,7 @@ export const useLaunchConfigStore = create<LaunchConfigState>((set, get) => ({
|
|||
modelPath: '',
|
||||
additionalArguments: '',
|
||||
port: undefined,
|
||||
host: DEFAULT_HOST,
|
||||
host: '',
|
||||
multiuser: false,
|
||||
multiplayer: false,
|
||||
remotetunnel: false,
|
||||
|
|
@ -98,6 +100,7 @@ export const useLaunchConfigStore = create<LaunchConfigState>((set, get) => ({
|
|||
failsafe: false,
|
||||
lowvram: false,
|
||||
quantmatmul: true,
|
||||
usemmap: true,
|
||||
backend: '',
|
||||
gpuDevice: 0,
|
||||
gpuPlatform: 0,
|
||||
|
|
@ -127,6 +130,7 @@ export const useLaunchConfigStore = create<LaunchConfigState>((set, get) => ({
|
|||
setFailsafe: (failsafe) => set({ failsafe }),
|
||||
setLowvram: (lowvram) => set({ lowvram }),
|
||||
setQuantmatmul: (quantmatmul) => set({ quantmatmul }),
|
||||
setUsemmap: (usemmap) => set({ usemmap }),
|
||||
setBackend: (backend) => set({ backend }),
|
||||
setGpuDevice: (device) => set({ gpuDevice: device }),
|
||||
setGpuPlatform: (platform) => set({ gpuPlatform: platform }),
|
||||
|
|
@ -171,7 +175,7 @@ export const useLaunchConfigStore = create<LaunchConfigState>((set, get) => ({
|
|||
if (typeof configData.host === 'string') {
|
||||
updates.host = configData.host;
|
||||
} else {
|
||||
updates.host = DEFAULT_HOST;
|
||||
updates.host = '';
|
||||
}
|
||||
|
||||
if (typeof configData.multiuser === 'number') {
|
||||
|
|
@ -236,6 +240,12 @@ export const useLaunchConfigStore = create<LaunchConfigState>((set, get) => ({
|
|||
updates.quantmatmul = configData.quantmatmul;
|
||||
}
|
||||
|
||||
if (typeof configData.usemmap === 'boolean') {
|
||||
updates.usemmap = configData.usemmap;
|
||||
} else {
|
||||
updates.usemmap = true;
|
||||
}
|
||||
|
||||
if (configData.usecuda === true) {
|
||||
const gpuInfo = await window.electronAPI.kobold.detectGPU();
|
||||
updates.backend = gpuInfo.hasNVIDIA ? 'cuda' : 'rocm';
|
||||
|
|
|
|||
|
|
@ -1,45 +0,0 @@
|
|||
@keyframes elephantShake {
|
||||
0%,
|
||||
100% {
|
||||
transform: scale(1.3) rotate(5deg) translateX(0px);
|
||||
}
|
||||
10% {
|
||||
transform: scale(1.4) rotate(-3deg) translateX(-2px);
|
||||
}
|
||||
20% {
|
||||
transform: scale(1.5) rotate(8deg) translateX(2px);
|
||||
}
|
||||
30% {
|
||||
transform: scale(1.4) rotate(-5deg) translateX(-1px);
|
||||
}
|
||||
40% {
|
||||
transform: scale(1.6) rotate(10deg) translateX(3px);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.3) rotate(-8deg) translateX(-2px);
|
||||
}
|
||||
60% {
|
||||
transform: scale(1.5) rotate(6deg) translateX(1px);
|
||||
}
|
||||
70% {
|
||||
transform: scale(1.2) rotate(-4deg) translateX(-1px);
|
||||
}
|
||||
80% {
|
||||
transform: scale(1.4) rotate(3deg) translateX(2px);
|
||||
}
|
||||
90% {
|
||||
transform: scale(1.1) rotate(-2deg) translateX(-1px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes mouseSqueak {
|
||||
0% {
|
||||
transform: scale(1) rotate(0deg);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.15) rotate(2deg);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1) rotate(0deg);
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +1,97 @@
|
|||
@import '@mantine/core/styles.css';
|
||||
|
||||
/* Global smooth scrolling */
|
||||
* {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
/* Custom scrollbars */
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: rgba(134, 142, 150, 0.5);
|
||||
border-radius: 4px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: rgba(134, 142, 150, 0.8);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:active {
|
||||
background: rgba(73, 80, 87, 0.9);
|
||||
}
|
||||
|
||||
/* Dark mode scrollbar support */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: rgba(173, 181, 189, 0.5);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: rgba(173, 181, 189, 0.8);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:active {
|
||||
background: rgba(206, 212, 218, 0.9);
|
||||
}
|
||||
}
|
||||
|
||||
/* AppHeader animations */
|
||||
@keyframes elephantShake {
|
||||
0%,
|
||||
100% {
|
||||
transform: scale(1.3) rotate(5deg) translateX(0px);
|
||||
}
|
||||
10% {
|
||||
transform: scale(1.4) rotate(-3deg) translateX(-2px);
|
||||
}
|
||||
20% {
|
||||
transform: scale(1.5) rotate(8deg) translateX(2px);
|
||||
}
|
||||
30% {
|
||||
transform: scale(1.4) rotate(-5deg) translateX(-1px);
|
||||
}
|
||||
40% {
|
||||
transform: scale(1.6) rotate(10deg) translateX(3px);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.3) rotate(-8deg) translateX(-2px);
|
||||
}
|
||||
60% {
|
||||
transform: scale(1.5) rotate(6deg) translateX(1px);
|
||||
}
|
||||
70% {
|
||||
transform: scale(1.2) rotate(-4deg) translateX(-1px);
|
||||
}
|
||||
80% {
|
||||
transform: scale(1.4) rotate(3deg) translateX(2px);
|
||||
}
|
||||
90% {
|
||||
transform: scale(1.1) rotate(-2deg) translateX(-1px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes mouseSqueak {
|
||||
0% {
|
||||
transform: scale(1) rotate(0deg);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.15) rotate(2deg);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1) rotate(0deg);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
8
src/types/electron.d.ts
vendored
8
src/types/electron.d.ts
vendored
|
|
@ -57,22 +57,17 @@ export interface DownloadItem {
|
|||
}
|
||||
|
||||
export interface KoboldAPI {
|
||||
getInstalledVersion: () => Promise<string | undefined>;
|
||||
getInstalledVersions: () => Promise<InstalledVersion[]>;
|
||||
getCurrentVersion: () => Promise<InstalledVersion | null>;
|
||||
getCurrentBinaryInfo: () => Promise<{
|
||||
path: string;
|
||||
filename: string;
|
||||
} | null>;
|
||||
setCurrentVersion: (version: string) => Promise<boolean>;
|
||||
getVersionFromBinary: (binaryPath: string) => Promise<string | null>;
|
||||
getLatestRelease: () => Promise<DownloadItem[]>;
|
||||
getPlatform: () => Promise<PlatformInfo>;
|
||||
detectGPU: () => Promise<BasicGPUInfo>;
|
||||
detectCPU: () => Promise<CPUCapabilities>;
|
||||
detectGPUCapabilities: () => Promise<GPUCapabilities>;
|
||||
detectROCm: () => Promise<{ supported: boolean; devices: string[] }>;
|
||||
detectAllCapabilities: () => Promise<HardwareInfo>;
|
||||
detectBackendSupport: (binaryPath: string) => Promise<{
|
||||
rocm: boolean;
|
||||
vulkan: boolean;
|
||||
|
|
@ -95,7 +90,6 @@ export interface KoboldAPI {
|
|||
error?: string;
|
||||
}>;
|
||||
getROCmDownload: () => Promise<DownloadItem | null>;
|
||||
checkForUpdates: () => Promise<UpdateInfo | null>;
|
||||
getLatestReleaseWithStatus: () => Promise<ReleaseWithStatus | null>;
|
||||
launchKoboldCpp: (
|
||||
args?: string[],
|
||||
|
|
@ -121,6 +115,7 @@ export interface KoboldAPI {
|
|||
flashattention?: boolean;
|
||||
noavx2?: boolean;
|
||||
failsafe?: boolean;
|
||||
usemmap?: boolean;
|
||||
usecuda?: boolean;
|
||||
usevulkan?: boolean;
|
||||
useclblast?: boolean;
|
||||
|
|
@ -152,7 +147,6 @@ export interface KoboldAPI {
|
|||
}
|
||||
|
||||
export interface AppAPI {
|
||||
getVersion: () => Promise<string>;
|
||||
openExternal: (url: string) => Promise<void>;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import { formatFileSizeInMB } from '@/utils/fileSize';
|
||||
import { KOBOLDAI_URLS } from '@/constants';
|
||||
|
||||
export const formatDownloadSize = (size: number, url?: string): string => {
|
||||
|
|
@ -35,3 +34,9 @@ export const compareVersions = (versionA: string, versionB: string): number => {
|
|||
|
||||
return 0;
|
||||
};
|
||||
|
||||
const formatFileSizeInMB = (bytes: number) => {
|
||||
if (bytes === 0) return '0 MB';
|
||||
const mb = bytes / (1024 * 1024);
|
||||
return parseFloat(mb.toFixed(1)) + ' MB';
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
export const formatFileSizeInMB = (bytes: number) => {
|
||||
if (bytes === 0) return '0 MB';
|
||||
const mb = bytes / (1024 * 1024);
|
||||
return parseFloat(mb.toFixed(1)) + ' MB';
|
||||
};
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
export * from './assets';
|
||||
export * from './clblast';
|
||||
export * from './downloadUtils';
|
||||
export * from './fileSize';
|
||||
export * from './hardware';
|
||||
export * from './imageModelPresets';
|
||||
export * from './platform';
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue