mirror of
https://github.com/lone-cloud/gerbil
synced 2026-06-03 19:54:44 -07:00
don't need to recommend ROCm as it's not that good compared to generally available Vulkan
This commit is contained in:
parent
f2aaa6ff4c
commit
ed4fa55478
8 changed files with 42 additions and 208 deletions
|
|
@ -9,7 +9,6 @@ A koboldcpp manager. <!-- markdownlint-disable MD033 -->
|
||||||
|
|
||||||
- modern UI for [koboldcpp](https://github.com/LostRuins/koboldcpp) with full support for Linux Wayland
|
- modern UI for [koboldcpp](https://github.com/LostRuins/koboldcpp) with full support for Linux Wayland
|
||||||
- download and keep up-to-date your [koboldcpp](https://github.com/LostRuins/koboldcpp/releases) binary
|
- download and keep up-to-date your [koboldcpp](https://github.com/LostRuins/koboldcpp/releases) binary
|
||||||
- better surface the ROCm-specific builds of koboldcpp from YellowRoseCx and from [koboldai.org](https://koboldai.org/cpplinuxrocm)
|
|
||||||
- manage the koboldcpp binary to prevent it from running in the background indefinitely
|
- manage the koboldcpp binary to prevent it from running in the background indefinitely
|
||||||
- automatically unpack all downloaded koboldcpp binaries for significantly faster operation and reduced RAM+HDD utilization (up to ~4GB less RAM usage for ROCm)
|
- automatically unpack all downloaded koboldcpp binaries for significantly faster operation and reduced RAM+HDD utilization (up to ~4GB less RAM usage for ROCm)
|
||||||
- added presets for a basic flux or chroma image generation setup
|
- added presets for a basic flux or chroma image generation setup
|
||||||
|
|
|
||||||
|
|
@ -113,13 +113,7 @@ export const App = () => {
|
||||||
|
|
||||||
const handleBinaryUpdate = async (download: DownloadItem) => {
|
const handleBinaryUpdate = async (download: DownloadItem) => {
|
||||||
try {
|
try {
|
||||||
const downloadType = download.type === 'rocm' ? 'rocm' : 'asset';
|
const success = await sharedHandleDownload('asset', download, true, true);
|
||||||
const success = await sharedHandleDownload(
|
|
||||||
downloadType,
|
|
||||||
download,
|
|
||||||
true,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
dismissUpdate();
|
dismissUpdate();
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ interface DownloadCardProps {
|
||||||
size: string;
|
size: string;
|
||||||
version?: string;
|
version?: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
isRecommended?: boolean;
|
|
||||||
isCurrent?: boolean;
|
isCurrent?: boolean;
|
||||||
isInstalled?: boolean;
|
isInstalled?: boolean;
|
||||||
isDownloading?: boolean;
|
isDownloading?: boolean;
|
||||||
|
|
@ -36,7 +35,6 @@ export const DownloadCard = ({
|
||||||
size,
|
size,
|
||||||
version,
|
version,
|
||||||
description,
|
description,
|
||||||
isRecommended = false,
|
|
||||||
isCurrent = false,
|
isCurrent = false,
|
||||||
isInstalled = false,
|
isInstalled = false,
|
||||||
isDownloading = false,
|
isDownloading = false,
|
||||||
|
|
@ -122,11 +120,6 @@ export const DownloadCard = ({
|
||||||
Current
|
Current
|
||||||
</Badge>
|
</Badge>
|
||||||
)}
|
)}
|
||||||
{isRecommended && (
|
|
||||||
<Badge variant="light" color="blue" size="sm">
|
|
||||||
Recommended
|
|
||||||
</Badge>
|
|
||||||
)}
|
|
||||||
{hasUpdate && (
|
{hasUpdate && (
|
||||||
<Badge variant="light" color="orange" size="sm">
|
<Badge variant="light" color="orange" size="sm">
|
||||||
Update Available
|
Update Available
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,8 @@
|
||||||
import { useState, useCallback, useEffect, useRef } from 'react';
|
import { useState, useCallback, useEffect, useRef } from 'react';
|
||||||
import {
|
import { Card, Text, Title, Loader, Stack, Container } from '@mantine/core';
|
||||||
Card,
|
|
||||||
Text,
|
|
||||||
Title,
|
|
||||||
Loader,
|
|
||||||
Stack,
|
|
||||||
Container,
|
|
||||||
Anchor,
|
|
||||||
} from '@mantine/core';
|
|
||||||
import { DownloadCard } from '@/components/DownloadCard';
|
import { DownloadCard } from '@/components/DownloadCard';
|
||||||
import { getPlatformDisplayName, formatDownloadSize } from '@/utils';
|
import { getPlatformDisplayName, formatDownloadSize } from '@/utils';
|
||||||
import {
|
import { getAssetDescription, sortDownloadsByType } from '@/utils/assets';
|
||||||
isAssetRecommended,
|
|
||||||
sortAssetsByRecommendation,
|
|
||||||
getAssetDescription,
|
|
||||||
} from '@/utils/assets';
|
|
||||||
import { useKoboldVersions } from '@/hooks/useKoboldVersions';
|
import { useKoboldVersions } from '@/hooks/useKoboldVersions';
|
||||||
import type { DownloadItem } from '@/types/electron';
|
import type { DownloadItem } from '@/types/electron';
|
||||||
|
|
||||||
|
|
@ -33,27 +21,20 @@ export const DownloadScreen = ({ onDownloadComplete }: DownloadScreenProps) => {
|
||||||
handleDownload: sharedHandleDownload,
|
handleDownload: sharedHandleDownload,
|
||||||
} = useKoboldVersions();
|
} = useKoboldVersions();
|
||||||
|
|
||||||
const [downloadingType, setDownloadingType] = useState<
|
|
||||||
'asset' | 'rocm' | null
|
|
||||||
>(null);
|
|
||||||
const [downloadingAsset, setDownloadingAsset] = useState<string | null>(null);
|
const [downloadingAsset, setDownloadingAsset] = useState<string | null>(null);
|
||||||
const downloadingItemRef = useRef<HTMLDivElement>(null);
|
const downloadingItemRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const loading = loadingPlatform || loadingRemote;
|
const loading = loadingPlatform || loadingRemote;
|
||||||
|
|
||||||
const regularDownloads = availableDownloads.filter((d) => d.type === 'asset');
|
const sortedDownloads = sortDownloadsByType(availableDownloads);
|
||||||
const rocmDownload = availableDownloads.find((d) => d.type === 'rocm');
|
|
||||||
|
|
||||||
const handleDownload = useCallback(
|
const handleDownload = useCallback(
|
||||||
async (type: 'asset' | 'rocm', download?: DownloadItem) => {
|
async (download: DownloadItem) => {
|
||||||
if (type === 'asset' && !download) return;
|
setDownloadingAsset(download.name);
|
||||||
|
|
||||||
setDownloadingType(type);
|
|
||||||
setDownloadingAsset(type === 'asset' ? download!.name : null);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const success = await sharedHandleDownload(
|
const success = await sharedHandleDownload(
|
||||||
type,
|
'asset',
|
||||||
download,
|
download,
|
||||||
false,
|
false,
|
||||||
false
|
false
|
||||||
|
|
@ -63,17 +44,15 @@ export const DownloadScreen = ({ onDownloadComplete }: DownloadScreenProps) => {
|
||||||
onDownloadComplete();
|
onDownloadComplete();
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setDownloadingType(null);
|
|
||||||
setDownloadingAsset(null);
|
setDownloadingAsset(null);
|
||||||
}, 200);
|
}, 200);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.electronAPI.logs.logError(
|
window.electronAPI.logs.logError(
|
||||||
`Failed to download ${type}:`,
|
`Failed to download ${download.name}:`,
|
||||||
error as Error
|
error as Error
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
setDownloadingType(null);
|
|
||||||
setDownloadingAsset(null);
|
setDownloadingAsset(null);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -89,38 +68,6 @@ export const DownloadScreen = ({ onDownloadComplete }: DownloadScreenProps) => {
|
||||||
}
|
}
|
||||||
}, [downloading]);
|
}, [downloading]);
|
||||||
|
|
||||||
const renderROCmCard = () => {
|
|
||||||
if (!rocmDownload) return null;
|
|
||||||
|
|
||||||
const isDownloading = Boolean(downloading) && downloadingType === 'rocm';
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div ref={isDownloading ? downloadingItemRef : null}>
|
|
||||||
<DownloadCard
|
|
||||||
name={rocmDownload.name}
|
|
||||||
size={formatDownloadSize(rocmDownload.size, rocmDownload.url, true)}
|
|
||||||
description={getAssetDescription(rocmDownload.name)}
|
|
||||||
version={rocmDownload.version}
|
|
||||||
isRecommended={isAssetRecommended(
|
|
||||||
rocmDownload.name,
|
|
||||||
platformInfo.hasAMDGPU
|
|
||||||
)}
|
|
||||||
isDownloading={isDownloading}
|
|
||||||
downloadProgress={
|
|
||||||
downloadingType === 'rocm'
|
|
||||||
? downloadProgress[rocmDownload.name] || 0
|
|
||||||
: 0
|
|
||||||
}
|
|
||||||
disabled={Boolean(downloading) && downloadingType !== 'rocm'}
|
|
||||||
onDownload={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
handleDownload('rocm', rocmDownload);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container size="sm">
|
<Container size="sm">
|
||||||
<Stack gap="xl">
|
<Stack gap="xl">
|
||||||
|
|
@ -139,54 +86,9 @@ export const DownloadScreen = ({ onDownloadComplete }: DownloadScreenProps) => {
|
||||||
<>
|
<>
|
||||||
{availableDownloads.length > 0 ? (
|
{availableDownloads.length > 0 ? (
|
||||||
<Stack gap="sm">
|
<Stack gap="sm">
|
||||||
{platformInfo.hasAMDGPU &&
|
{sortedDownloads.map((download) => {
|
||||||
!platformInfo.hasROCm &&
|
|
||||||
platformInfo.platform === 'linux' && (
|
|
||||||
<Card withBorder p="md" bg="orange.0">
|
|
||||||
<Stack gap="xs">
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
gap: '8px',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Text fw={600} c="orange.9">
|
|
||||||
AMD GPU Detected
|
|
||||||
</Text>
|
|
||||||
</div>
|
|
||||||
<Text size="sm" c="orange.8">
|
|
||||||
For best performance with your AMD GPU,
|
|
||||||
consider installing ROCm support.{' '}
|
|
||||||
<Anchor
|
|
||||||
href="#"
|
|
||||||
onClick={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
window.electronAPI.app.openExternal(
|
|
||||||
'https://rocm.docs.amd.com/projects/install-on-linux/en/latest/reference/system-requirements.html'
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
size="sm"
|
|
||||||
c="orange.8"
|
|
||||||
>
|
|
||||||
Learn more
|
|
||||||
</Anchor>
|
|
||||||
</Text>
|
|
||||||
</Stack>
|
|
||||||
</Card>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{rocmDownload &&
|
|
||||||
platformInfo.hasAMDGPU &&
|
|
||||||
renderROCmCard()}
|
|
||||||
|
|
||||||
{sortAssetsByRecommendation(
|
|
||||||
regularDownloads,
|
|
||||||
platformInfo.hasAMDGPU
|
|
||||||
).map((download) => {
|
|
||||||
const isDownloading =
|
const isDownloading =
|
||||||
Boolean(downloading) &&
|
Boolean(downloading) &&
|
||||||
downloadingType === 'asset' &&
|
|
||||||
downloadingAsset === download.name;
|
downloadingAsset === download.name;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -202,10 +104,6 @@ export const DownloadScreen = ({ onDownloadComplete }: DownloadScreenProps) => {
|
||||||
)}
|
)}
|
||||||
version={download.version}
|
version={download.version}
|
||||||
description={getAssetDescription(download.name)}
|
description={getAssetDescription(download.name)}
|
||||||
isRecommended={isAssetRecommended(
|
|
||||||
download.name,
|
|
||||||
platformInfo.hasAMDGPU
|
|
||||||
)}
|
|
||||||
isDownloading={isDownloading}
|
isDownloading={isDownloading}
|
||||||
downloadProgress={
|
downloadProgress={
|
||||||
isDownloading
|
isDownloading
|
||||||
|
|
@ -218,16 +116,12 @@ export const DownloadScreen = ({ onDownloadComplete }: DownloadScreenProps) => {
|
||||||
}
|
}
|
||||||
onDownload={(e) => {
|
onDownload={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
handleDownload('asset', download);
|
handleDownload(download);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
||||||
{rocmDownload &&
|
|
||||||
!platformInfo.hasAMDGPU &&
|
|
||||||
renderROCmCard()}
|
|
||||||
</Stack>
|
</Stack>
|
||||||
) : (
|
) : (
|
||||||
<Card withBorder p="md" bg="yellow.0" c="yellow.9">
|
<Card withBorder p="md" bg="yellow.0" c="yellow.9">
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,7 @@ import {
|
||||||
} from '@mantine/core';
|
} from '@mantine/core';
|
||||||
import { RotateCcw, ExternalLink } from 'lucide-react';
|
import { RotateCcw, ExternalLink } from 'lucide-react';
|
||||||
import { DownloadCard } from '@/components/DownloadCard';
|
import { DownloadCard } from '@/components/DownloadCard';
|
||||||
import {
|
import { getAssetDescription, sortDownloadsByType } from '@/utils/assets';
|
||||||
getAssetDescription,
|
|
||||||
sortAssetsByRecommendation,
|
|
||||||
isAssetRecommended,
|
|
||||||
} from '@/utils/assets';
|
|
||||||
import {
|
import {
|
||||||
getDisplayNameFromPath,
|
getDisplayNameFromPath,
|
||||||
formatDownloadSize,
|
formatDownloadSize,
|
||||||
|
|
@ -34,14 +30,12 @@ interface VersionInfo {
|
||||||
isCurrent: boolean;
|
isCurrent: boolean;
|
||||||
downloadUrl?: string;
|
downloadUrl?: string;
|
||||||
installedPath?: string;
|
installedPath?: string;
|
||||||
isROCm?: boolean;
|
|
||||||
hasUpdate?: boolean;
|
hasUpdate?: boolean;
|
||||||
newerVersion?: string;
|
newerVersion?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const VersionsTab = () => {
|
export const VersionsTab = () => {
|
||||||
const {
|
const {
|
||||||
platformInfo,
|
|
||||||
availableDownloads,
|
availableDownloads,
|
||||||
loadingPlatform,
|
loadingPlatform,
|
||||||
loadingRemote,
|
loadingRemote,
|
||||||
|
|
@ -131,7 +125,9 @@ export const VersionsTab = () => {
|
||||||
const versions: VersionInfo[] = [];
|
const versions: VersionInfo[] = [];
|
||||||
const processedInstalled = new Set<string>();
|
const processedInstalled = new Set<string>();
|
||||||
|
|
||||||
availableDownloads.forEach((download) => {
|
const sortedDownloads = sortDownloadsByType(availableDownloads);
|
||||||
|
|
||||||
|
sortedDownloads.forEach((download) => {
|
||||||
const downloadBaseName = stripAssetExtensions(download.name);
|
const downloadBaseName = stripAssetExtensions(download.name);
|
||||||
|
|
||||||
const installedVersion = installedVersions.find((v) => {
|
const installedVersion = installedVersions.find((v) => {
|
||||||
|
|
@ -162,7 +158,6 @@ export const VersionsTab = () => {
|
||||||
isCurrent,
|
isCurrent,
|
||||||
downloadUrl: download.url,
|
downloadUrl: download.url,
|
||||||
installedPath: installedVersion.path,
|
installedPath: installedVersion.path,
|
||||||
isROCm: download.type === 'rocm',
|
|
||||||
hasUpdate,
|
hasUpdate,
|
||||||
newerVersion: hasUpdate ? download.version : undefined,
|
newerVersion: hasUpdate ? download.version : undefined,
|
||||||
});
|
});
|
||||||
|
|
@ -174,7 +169,6 @@ export const VersionsTab = () => {
|
||||||
isInstalled: false,
|
isInstalled: false,
|
||||||
isCurrent: false,
|
isCurrent: false,
|
||||||
downloadUrl: download.url,
|
downloadUrl: download.url,
|
||||||
isROCm: download.type === 'rocm',
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -193,18 +187,12 @@ export const VersionsTab = () => {
|
||||||
isInstalled: true,
|
isInstalled: true,
|
||||||
isCurrent,
|
isCurrent,
|
||||||
installedPath: installed.path,
|
installedPath: installed.path,
|
||||||
isROCm: false,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return sortAssetsByRecommendation(versions, platformInfo.hasAMDGPU);
|
return versions;
|
||||||
}, [
|
}, [availableDownloads, installedVersions, currentVersion]);
|
||||||
availableDownloads,
|
|
||||||
installedVersions,
|
|
||||||
currentVersion,
|
|
||||||
platformInfo.hasAMDGPU,
|
|
||||||
]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (downloading && downloadingItemRef.current) {
|
if (downloading && downloadingItemRef.current) {
|
||||||
|
|
@ -222,9 +210,8 @@ export const VersionsTab = () => {
|
||||||
throw new Error('Download not found');
|
throw new Error('Download not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
const downloadType = download.type === 'rocm' ? 'rocm' : 'asset';
|
|
||||||
const success = await sharedHandleDownload(
|
const success = await sharedHandleDownload(
|
||||||
downloadType,
|
'asset',
|
||||||
download,
|
download,
|
||||||
false,
|
false,
|
||||||
false
|
false
|
||||||
|
|
@ -245,10 +232,9 @@ export const VersionsTab = () => {
|
||||||
throw new Error('Download not found');
|
throw new Error('Download not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
const downloadType = download.type === 'rocm' ? 'rocm' : 'asset';
|
|
||||||
const wasCurrentBinary = version.isCurrent;
|
const wasCurrentBinary = version.isCurrent;
|
||||||
const success = await sharedHandleDownload(
|
const success = await sharedHandleDownload(
|
||||||
downloadType,
|
'asset',
|
||||||
download,
|
download,
|
||||||
true,
|
true,
|
||||||
wasCurrentBinary
|
wasCurrentBinary
|
||||||
|
|
@ -368,19 +354,11 @@ export const VersionsTab = () => {
|
||||||
name={version.name}
|
name={version.name}
|
||||||
size={
|
size={
|
||||||
version.size
|
version.size
|
||||||
? formatDownloadSize(
|
? formatDownloadSize(version.size, version.downloadUrl)
|
||||||
version.size,
|
|
||||||
version.downloadUrl,
|
|
||||||
version.isROCm
|
|
||||||
)
|
|
||||||
: ''
|
: ''
|
||||||
}
|
}
|
||||||
version={version.version}
|
version={version.version}
|
||||||
description={getAssetDescription(version.name)}
|
description={getAssetDescription(version.name)}
|
||||||
isRecommended={isAssetRecommended(
|
|
||||||
version.name,
|
|
||||||
platformInfo.hasAMDGPU
|
|
||||||
)}
|
|
||||||
isCurrent={version.isCurrent}
|
isCurrent={version.isCurrent}
|
||||||
isInstalled={version.isInstalled}
|
isInstalled={version.isInstalled}
|
||||||
isDownloading={isDownloading}
|
isDownloading={isDownloading}
|
||||||
|
|
|
||||||
|
|
@ -38,10 +38,6 @@ export const KOBOLDAI_URLS = {
|
||||||
DOMAIN: 'koboldai.org',
|
DOMAIN: 'koboldai.org',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const GITHUB_URLS = {
|
|
||||||
DOMAIN: 'github.com',
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export const ROCM = {
|
export const ROCM = {
|
||||||
BINARY_NAME: 'koboldcpp-linux-x64-rocm',
|
BINARY_NAME: 'koboldcpp-linux-x64-rocm',
|
||||||
DOWNLOAD_URL: KOBOLDAI_URLS.ROCM_DOWNLOAD,
|
DOWNLOAD_URL: KOBOLDAI_URLS.ROCM_DOWNLOAD,
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,11 @@ export const getAssetDescription = (assetName: string): string => {
|
||||||
const name = stripAssetExtensions(assetName).toLowerCase();
|
const name = stripAssetExtensions(assetName).toLowerCase();
|
||||||
|
|
||||||
if (name.includes(ASSET_SUFFIXES.ROCM)) {
|
if (name.includes(ASSET_SUFFIXES.ROCM)) {
|
||||||
return 'Optimized for AMD GPUs with ROCm support.';
|
return 'Adds dedicated ROCm support for AMD GPUs. Note that ROCm is unlikely to perform better than modern Vulkan in most cases.';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name.endsWith(ASSET_SUFFIXES.OLDPC)) {
|
if (name.endsWith(ASSET_SUFFIXES.OLDPC)) {
|
||||||
return 'Meant for old PCs that cannot run the standard build.';
|
return 'Meant for old PCs with outdated CPUs that may not work with the standard build. Does not support modern AVX2 CPU architectures.';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name.endsWith(ASSET_SUFFIXES.NOCUDA)) {
|
if (name.endsWith(ASSET_SUFFIXES.NOCUDA)) {
|
||||||
|
|
@ -19,24 +19,6 @@ export const getAssetDescription = (assetName: string): string => {
|
||||||
return "Standard build that's ideal for most cases.";
|
return "Standard build that's ideal for most cases.";
|
||||||
};
|
};
|
||||||
|
|
||||||
export const isAssetRecommended = (
|
|
||||||
assetName: string,
|
|
||||||
hasAMDGPU: boolean
|
|
||||||
): boolean => {
|
|
||||||
const name = stripAssetExtensions(assetName).toLowerCase();
|
|
||||||
|
|
||||||
if (hasAMDGPU && name.includes(ASSET_SUFFIXES.ROCM)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
!hasAMDGPU &&
|
|
||||||
!name.includes(ASSET_SUFFIXES.ROCM) &&
|
|
||||||
!name.endsWith(ASSET_SUFFIXES.OLDPC) &&
|
|
||||||
!name.endsWith(ASSET_SUFFIXES.NOCUDA)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const isAssetStandard = (assetName: string): boolean => {
|
export const isAssetStandard = (assetName: string): boolean => {
|
||||||
const name = stripAssetExtensions(assetName).toLowerCase();
|
const name = stripAssetExtensions(assetName).toLowerCase();
|
||||||
|
|
||||||
|
|
@ -47,23 +29,27 @@ export const isAssetStandard = (assetName: string): boolean => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const sortAssetsByRecommendation = <T extends { name: string }>(
|
export const sortDownloadsByType = <T extends { name: string }>(
|
||||||
assets: T[],
|
downloads: T[]
|
||||||
hasAMDGPU: boolean
|
|
||||||
): T[] =>
|
): T[] =>
|
||||||
[...assets].sort((a, b) => {
|
[...downloads].sort((a, b) => {
|
||||||
const aRecommended = isAssetRecommended(a.name, hasAMDGPU);
|
const aName = stripAssetExtensions(a.name).toLowerCase();
|
||||||
const bRecommended = isAssetRecommended(b.name, hasAMDGPU);
|
const bName = stripAssetExtensions(b.name).toLowerCase();
|
||||||
const aStandard = isAssetStandard(a.name);
|
|
||||||
const bStandard = isAssetStandard(b.name);
|
|
||||||
|
|
||||||
if (aRecommended && !bRecommended) return -1;
|
const getOrderPriority = (name: string): number => {
|
||||||
if (!aRecommended && bRecommended) return 1;
|
if (isAssetStandard(name)) return 0;
|
||||||
|
if (name.includes(ASSET_SUFFIXES.ROCM)) return 1;
|
||||||
|
if (name.endsWith(ASSET_SUFFIXES.NOCUDA)) return 2;
|
||||||
|
if (name.endsWith(ASSET_SUFFIXES.OLDPC)) return 3;
|
||||||
|
return 4;
|
||||||
|
};
|
||||||
|
|
||||||
if (aRecommended === bRecommended) {
|
const aPriority = getOrderPriority(aName);
|
||||||
if (aStandard && !bStandard) return -1;
|
const bPriority = getOrderPriority(bName);
|
||||||
if (!aStandard && bStandard) return 1;
|
|
||||||
|
if (aPriority !== bPriority) {
|
||||||
|
return aPriority - bPriority;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return a.name.localeCompare(b.name);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,10 @@
|
||||||
import { formatFileSizeInMB } from '@/utils/fileSize';
|
import { formatFileSizeInMB } from '@/utils/fileSize';
|
||||||
import { KOBOLDAI_URLS, GITHUB_URLS } from '@/constants';
|
import { KOBOLDAI_URLS } from '@/constants';
|
||||||
|
|
||||||
export const formatDownloadSize = (
|
export const formatDownloadSize = (size: number, url?: string): string => {
|
||||||
size: number,
|
|
||||||
url?: string,
|
|
||||||
isROCm?: boolean
|
|
||||||
): string => {
|
|
||||||
if (!size) return '';
|
if (!size) return '';
|
||||||
|
|
||||||
const isApproximateSize =
|
const isApproximateSize = url?.includes(KOBOLDAI_URLS.DOMAIN);
|
||||||
url?.includes(KOBOLDAI_URLS.DOMAIN) ||
|
|
||||||
(isROCm && !url?.includes(GITHUB_URLS.DOMAIN));
|
|
||||||
|
|
||||||
return isApproximateSize
|
return isApproximateSize
|
||||||
? `~${formatFileSizeInMB(size)}`
|
? `~${formatFileSizeInMB(size)}`
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue