mirror of
https://github.com/lone-cloud/gerbil
synced 2026-06-03 19:54:44 -07:00
add jinja UI controls, smooth download ETA, filter new kcpp spam, fix right-click in popups
This commit is contained in:
parent
ca7fd211ff
commit
826d63c68a
11 changed files with 122 additions and 32 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "gerbil",
|
"name": "gerbil",
|
||||||
"version": "1.21.2",
|
"version": "1.22.0",
|
||||||
"description": "Run Large Language Models locally",
|
"description": "Run Large Language Models locally",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"ai",
|
"ai",
|
||||||
|
|
|
||||||
8
pnpm-lock.yaml
generated
8
pnpm-lock.yaml
generated
|
|
@ -1163,8 +1163,8 @@ packages:
|
||||||
base64-js@1.5.1:
|
base64-js@1.5.1:
|
||||||
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
|
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
|
||||||
|
|
||||||
baseline-browser-mapping@2.10.14:
|
baseline-browser-mapping@2.10.15:
|
||||||
resolution: {integrity: sha512-fOVLPAsFTsQfuCkvahZkzq6nf8KvGWanlYoTh0SVA0A/PIUxQGU2AOZAoD95n2gFLVDW/jP6sbGLny95nmEuHA==}
|
resolution: {integrity: sha512-1nfKCq9wuAZFTkA2ey/3OXXx7GzFjLdkTiFVNwlJ9WqdI706CZRIhEqjuwanjMIja+84jDLa9rcyZDPDiVkASQ==}
|
||||||
engines: {node: '>=6.0.0'}
|
engines: {node: '>=6.0.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
|
@ -4082,7 +4082,7 @@ snapshots:
|
||||||
|
|
||||||
base64-js@1.5.1: {}
|
base64-js@1.5.1: {}
|
||||||
|
|
||||||
baseline-browser-mapping@2.10.14: {}
|
baseline-browser-mapping@2.10.15: {}
|
||||||
|
|
||||||
bl@4.1.0:
|
bl@4.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -4108,7 +4108,7 @@ snapshots:
|
||||||
|
|
||||||
browserslist@4.28.2:
|
browserslist@4.28.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
baseline-browser-mapping: 2.10.14
|
baseline-browser-mapping: 2.10.15
|
||||||
caniuse-lite: 1.0.30001785
|
caniuse-lite: 1.0.30001785
|
||||||
electron-to-chromium: 1.5.331
|
electron-to-chromium: 1.5.331
|
||||||
node-releases: 2.0.37
|
node-releases: 2.0.37
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,17 @@ export const AdvancedTab = () => {
|
||||||
noavx2,
|
noavx2,
|
||||||
failsafe,
|
failsafe,
|
||||||
debugmode,
|
debugmode,
|
||||||
|
jinja,
|
||||||
|
jinjatools,
|
||||||
|
jinjakwargs,
|
||||||
setAdditionalArguments,
|
setAdditionalArguments,
|
||||||
setPreLaunchCommands,
|
setPreLaunchCommands,
|
||||||
setNoavx2,
|
setNoavx2,
|
||||||
setFailsafe,
|
setFailsafe,
|
||||||
setDebugmode,
|
setDebugmode,
|
||||||
|
setJinja,
|
||||||
|
setJinjatools,
|
||||||
|
setJinjakwargs,
|
||||||
} = useLaunchConfigStore();
|
} = useLaunchConfigStore();
|
||||||
const [commandLineModalOpen, setCommandLineModalOpen] = useState(false);
|
const [commandLineModalOpen, setCommandLineModalOpen] = useState(false);
|
||||||
const [backendSupport, setBackendSupport] = useState<{
|
const [backendSupport, setBackendSupport] = useState<{
|
||||||
|
|
@ -86,11 +92,47 @@ export const AdvancedTab = () => {
|
||||||
label="Debug Mode"
|
label="Debug Mode"
|
||||||
tooltip="Shows additional debug info in the terminal."
|
tooltip="Shows additional debug info in the terminal."
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<CheckboxWithTooltip
|
||||||
|
checked={jinja}
|
||||||
|
onChange={(val) => {
|
||||||
|
setJinja(val);
|
||||||
|
if (!val) setJinjatools(false);
|
||||||
|
}}
|
||||||
|
label="Use Jinja"
|
||||||
|
tooltip="Enables using jinja chat template formatting for chat completions endpoint."
|
||||||
|
/>
|
||||||
|
|
||||||
|
<CheckboxWithTooltip
|
||||||
|
checked={jinjatools}
|
||||||
|
onChange={(val) => {
|
||||||
|
setJinjatools(val);
|
||||||
|
if (val) setJinja(true);
|
||||||
|
}}
|
||||||
|
label="Jinja for Tools"
|
||||||
|
tooltip="Allows jinja even with tool calls. If unchecked, jinja will be disabled when tools are used."
|
||||||
|
/>
|
||||||
</SimpleGrid>
|
</SimpleGrid>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{(jinja || jinjatools) && (
|
||||||
|
<div>
|
||||||
|
<Group>
|
||||||
|
<Text size="sm" fw={500}>
|
||||||
|
Jinja Kwargs
|
||||||
|
</Text>
|
||||||
|
<InfoTooltip label="Set additional fields for the Jinja JSON template parser, must be a valid JSON object." />
|
||||||
|
</Group>
|
||||||
|
<TextInput
|
||||||
|
placeholder='e.g. {"enable_thinking":true}'
|
||||||
|
value={jinjakwargs}
|
||||||
|
onChange={(event) => setJinjakwargs(event.currentTarget.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<Group mb="xs" justify="space-between">
|
<Group justify="space-between">
|
||||||
<Group>
|
<Group>
|
||||||
<Text size="sm" fw={500}>
|
<Text size="sm" fw={500}>
|
||||||
Additional Arguments
|
Additional Arguments
|
||||||
|
|
@ -109,7 +151,7 @@ export const AdvancedTab = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<Group mb="xs">
|
<Group>
|
||||||
<Text size="sm" fw={500}>
|
<Text size="sm" fw={500}>
|
||||||
Pre-Launch Commands
|
Pre-Launch Commands
|
||||||
</Text>
|
</Text>
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,9 @@ const UI_COVERED_ARGS = new Set([
|
||||||
'--tensor_split',
|
'--tensor_split',
|
||||||
'--debugmode',
|
'--debugmode',
|
||||||
'--lowvram',
|
'--lowvram',
|
||||||
|
'--jinja',
|
||||||
|
'--jinja_tools',
|
||||||
|
'--jinja_kwargs',
|
||||||
'--smartcache',
|
'--smartcache',
|
||||||
'--pipelineparallel',
|
'--pipelineparallel',
|
||||||
'--nopipelineparallel',
|
'--nopipelineparallel',
|
||||||
|
|
@ -396,30 +399,6 @@ const COMMAND_LINE_ARGUMENTS = [
|
||||||
flag: '--chatcompletionsadapter',
|
flag: '--chatcompletionsadapter',
|
||||||
metavar: '[filename]',
|
metavar: '[filename]',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
category: 'Advanced',
|
|
||||||
description:
|
|
||||||
'Enables using jinja chat template formatting for chat completions endpoint. Other endpoints are unaffected. Tool calls are done without jinja.',
|
|
||||||
flag: '--jinja',
|
|
||||||
type: 'boolean',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
aliases: ['--jinja-tools', '--jinjatools'],
|
|
||||||
category: 'Advanced',
|
|
||||||
description:
|
|
||||||
'Enables using jinja chat template formatting for chat completions endpoint. Other endpoints are unaffected. Tool calls are done with jinja.',
|
|
||||||
flag: '--jinja_tools',
|
|
||||||
type: 'boolean',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
aliases: ['--jinja-kwargs', '--jinjakwargs', '--chat-template-kwargs'],
|
|
||||||
category: 'Advanced',
|
|
||||||
default: '',
|
|
||||||
description:
|
|
||||||
'Set additional fields for Jinja JSON template parser, must be a valid JSON object.',
|
|
||||||
flag: '--jinja_kwargs',
|
|
||||||
metavar: '{"parameter":"value",...}',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
category: 'Advanced',
|
category: 'Advanced',
|
||||||
description:
|
description:
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,9 @@ export const LaunchScreen = ({ onLaunch }: LaunchScreenProps) => {
|
||||||
smartcache,
|
smartcache,
|
||||||
pipelineparallel,
|
pipelineparallel,
|
||||||
quantkv,
|
quantkv,
|
||||||
|
jinja,
|
||||||
|
jinjatools,
|
||||||
|
jinjakwargs,
|
||||||
parseAndApplyConfigFile,
|
parseAndApplyConfigFile,
|
||||||
loadConfigFromFile,
|
loadConfigFromFile,
|
||||||
setModel,
|
setModel,
|
||||||
|
|
@ -187,6 +190,9 @@ export const LaunchScreen = ({ onLaunch }: LaunchScreenProps) => {
|
||||||
usevulkan: acceleration === 'vulkan',
|
usevulkan: acceleration === 'vulkan',
|
||||||
websearch,
|
websearch,
|
||||||
quantkv,
|
quantkv,
|
||||||
|
jinja,
|
||||||
|
jinjatools,
|
||||||
|
jinjakwargs,
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleCreateNewConfig = async (configName: string) => {
|
const handleCreateNewConfig = async (configName: string) => {
|
||||||
|
|
@ -301,6 +307,9 @@ export const LaunchScreen = ({ onLaunch }: LaunchScreenProps) => {
|
||||||
usemmap,
|
usemmap,
|
||||||
websearch,
|
websearch,
|
||||||
quantkv,
|
quantkv,
|
||||||
|
jinja,
|
||||||
|
jinjatools,
|
||||||
|
jinjakwargs,
|
||||||
});
|
});
|
||||||
}, [
|
}, [
|
||||||
handleLaunch,
|
handleLaunch,
|
||||||
|
|
@ -342,6 +351,9 @@ export const LaunchScreen = ({ onLaunch }: LaunchScreenProps) => {
|
||||||
smartcache,
|
smartcache,
|
||||||
pipelineparallel,
|
pipelineparallel,
|
||||||
quantkv,
|
quantkv,
|
||||||
|
jinja,
|
||||||
|
jinjatools,
|
||||||
|
jinjakwargs,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,9 @@ interface LaunchArgs {
|
||||||
smartcache: boolean;
|
smartcache: boolean;
|
||||||
pipelineparallel: boolean;
|
pipelineparallel: boolean;
|
||||||
quantkv: number;
|
quantkv: number;
|
||||||
|
jinja: boolean;
|
||||||
|
jinjatools: boolean;
|
||||||
|
jinjakwargs: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const buildModelArgs = (model: string, sdmodel: string, launchArgs: LaunchArgs) => {
|
const buildModelArgs = (model: string, sdmodel: string, launchArgs: LaunchArgs) => {
|
||||||
|
|
@ -162,6 +165,16 @@ const buildConfigArgs = (isImageMode: boolean, launchArgs: LaunchArgs) => {
|
||||||
args.push('--quantkv', launchArgs.quantkv.toString());
|
args.push('--quantkv', launchArgs.quantkv.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (launchArgs.jinjatools) {
|
||||||
|
args.push('--jinja_tools');
|
||||||
|
} else if (launchArgs.jinja) {
|
||||||
|
args.push('--jinja');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((launchArgs.jinja || launchArgs.jinjatools) && launchArgs.jinjakwargs.trim()) {
|
||||||
|
args.push('--jinja_kwargs', launchArgs.jinjakwargs.trim());
|
||||||
|
}
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -149,6 +149,8 @@ export function filterSpam(output: string) {
|
||||||
/^done_getting_tensors:/,
|
/^done_getting_tensors:/,
|
||||||
/^sched_reserve:/,
|
/^sched_reserve:/,
|
||||||
/^llama_memory_recurrent:/,
|
/^llama_memory_recurrent:/,
|
||||||
|
/^str: cannot properly format tensor name/,
|
||||||
|
/^tensor .+ buffer type overridden to /,
|
||||||
];
|
];
|
||||||
|
|
||||||
return output
|
return output
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,8 @@ async function downloadFile(
|
||||||
let downloadedBytes = 0;
|
let downloadedBytes = 0;
|
||||||
let lastReportTime = Date.now();
|
let lastReportTime = Date.now();
|
||||||
let lastReportedBytes = 0;
|
let lastReportedBytes = 0;
|
||||||
|
const speedSamples: number[] = [];
|
||||||
|
const SPEED_WINDOW = 10;
|
||||||
|
|
||||||
fileStream = createWriteStream(tempPath);
|
fileStream = createWriteStream(tempPath);
|
||||||
|
|
||||||
|
|
@ -154,7 +156,10 @@ async function downloadFile(
|
||||||
|
|
||||||
if (timeDiff >= 0.5) {
|
if (timeDiff >= 0.5) {
|
||||||
const bytesDiff = downloadedBytes - lastReportedBytes;
|
const bytesDiff = downloadedBytes - lastReportedBytes;
|
||||||
const speedBytesPerSec = bytesDiff / timeDiff;
|
const instantSpeed = bytesDiff / timeDiff;
|
||||||
|
speedSamples.push(instantSpeed);
|
||||||
|
if (speedSamples.length > SPEED_WINDOW) speedSamples.shift();
|
||||||
|
const speedBytesPerSec = speedSamples.reduce((a, b) => a + b, 0) / speedSamples.length;
|
||||||
const percent = totalBytes ? Math.round((downloadedBytes / totalBytes) * 100) : 0;
|
const percent = totalBytes ? Math.round((downloadedBytes / totalBytes) * 100) : 0;
|
||||||
const downloadedMB = (downloadedBytes / 1024 / 1024).toFixed(2);
|
const downloadedMB = (downloadedBytes / 1024 / 1024).toFixed(2);
|
||||||
const totalMB = (totalBytes / 1024 / 1024).toFixed(2);
|
const totalMB = (totalBytes / 1024 / 1024).toFixed(2);
|
||||||
|
|
|
||||||
|
|
@ -148,6 +148,10 @@ export async function createMainWindow(options?: { startHidden?: boolean }) {
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
mainWindow.webContents.on('did-create-window', (popupWindow) => {
|
||||||
|
setupContextMenu(popupWindow);
|
||||||
|
});
|
||||||
|
|
||||||
mainWindow.on('close', (event) => {
|
mainWindow.on('close', (event) => {
|
||||||
saveBounds();
|
saveBounds();
|
||||||
if (getEnableSystemTray() && isTrayActive()) {
|
if (getEnableSystemTray() && isTrayActive()) {
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,9 @@ interface LaunchConfigState {
|
||||||
smartcache: boolean;
|
smartcache: boolean;
|
||||||
pipelineparallel: boolean;
|
pipelineparallel: boolean;
|
||||||
quantkv: number;
|
quantkv: number;
|
||||||
|
jinja: boolean;
|
||||||
|
jinjatools: boolean;
|
||||||
|
jinjakwargs: string;
|
||||||
isImageGenerationMode: boolean;
|
isImageGenerationMode: boolean;
|
||||||
isTextMode: boolean;
|
isTextMode: boolean;
|
||||||
|
|
||||||
|
|
@ -88,6 +91,9 @@ interface LaunchConfigState {
|
||||||
setSmartcache: (smartcache: boolean) => void;
|
setSmartcache: (smartcache: boolean) => void;
|
||||||
setPipelineparallel: (pipelineparallel: boolean) => void;
|
setPipelineparallel: (pipelineparallel: boolean) => void;
|
||||||
setQuantkv: (quantkv: number) => void;
|
setQuantkv: (quantkv: number) => void;
|
||||||
|
setJinja: (jinja: boolean) => void;
|
||||||
|
setJinjatools: (jinjatools: boolean) => void;
|
||||||
|
setJinjakwargs: (jinjakwargs: string) => void;
|
||||||
|
|
||||||
parseAndApplyConfigFile: (configPath: string) => Promise<void>;
|
parseAndApplyConfigFile: (configPath: string) => Promise<void>;
|
||||||
loadConfigFromFile: (
|
loadConfigFromFile: (
|
||||||
|
|
@ -400,11 +406,32 @@ export const useLaunchConfigStore = create<LaunchConfigState>((set, get) => ({
|
||||||
updates.quantkv = 0;
|
updates.quantkv = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeof configData.jinja === 'boolean') {
|
||||||
|
updates.jinja = configData.jinja;
|
||||||
|
} else {
|
||||||
|
updates.jinja = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof configData.jinjatools === 'boolean') {
|
||||||
|
updates.jinjatools = configData.jinjatools;
|
||||||
|
} else {
|
||||||
|
updates.jinjatools = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof configData.jinjakwargs === 'string') {
|
||||||
|
updates.jinjakwargs = configData.jinjakwargs;
|
||||||
|
} else {
|
||||||
|
updates.jinjakwargs = '';
|
||||||
|
}
|
||||||
|
|
||||||
set(updates);
|
set(updates);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
pipelineparallel: false,
|
pipelineparallel: false,
|
||||||
quantkv: 0,
|
quantkv: 0,
|
||||||
|
jinja: false,
|
||||||
|
jinjatools: false,
|
||||||
|
jinjakwargs: '',
|
||||||
port: undefined,
|
port: undefined,
|
||||||
preLaunchCommands: [''],
|
preLaunchCommands: [''],
|
||||||
quantmatmul: true,
|
quantmatmul: true,
|
||||||
|
|
@ -482,6 +509,9 @@ export const useLaunchConfigStore = create<LaunchConfigState>((set, get) => ({
|
||||||
setSdvae: (vae) => set({ sdvae: vae }),
|
setSdvae: (vae) => set({ sdvae: vae }),
|
||||||
setSdvaecpu: (enabled) => set({ sdvaecpu: enabled }),
|
setSdvaecpu: (enabled) => set({ sdvaecpu: enabled }),
|
||||||
setSmartcache: (smartcache) => set({ smartcache }),
|
setSmartcache: (smartcache) => set({ smartcache }),
|
||||||
|
setJinja: (jinja) => set({ jinja }),
|
||||||
|
setJinjatools: (jinjatools) => set({ jinjatools }),
|
||||||
|
setJinjakwargs: (jinjakwargs) => set({ jinjakwargs }),
|
||||||
setTensorSplit: (split) => set({ tensorSplit: split }),
|
setTensorSplit: (split) => set({ tensorSplit: split }),
|
||||||
setUsemmap: (usemmap) => set({ usemmap }),
|
setUsemmap: (usemmap) => set({ usemmap }),
|
||||||
|
|
||||||
|
|
|
||||||
3
src/types/electron.d.ts
vendored
3
src/types/electron.d.ts
vendored
|
|
@ -120,6 +120,9 @@ export interface KoboldConfig {
|
||||||
smartcache?: boolean;
|
smartcache?: boolean;
|
||||||
pipelineparallel?: boolean;
|
pipelineparallel?: boolean;
|
||||||
quantkv?: number;
|
quantkv?: number;
|
||||||
|
jinja?: boolean;
|
||||||
|
jinjatools?: boolean;
|
||||||
|
jinjakwargs?: string;
|
||||||
autoGpuLayers?: boolean;
|
autoGpuLayers?: boolean;
|
||||||
model?: string;
|
model?: string;
|
||||||
backend?: string;
|
backend?: string;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue