(null);
const loading = loadingPlatform || loadingRemote;
- const regularDownloads = availableDownloads.filter((d) => d.type === 'asset');
- const rocmDownload = availableDownloads.find((d) => d.type === 'rocm');
+ const sortedDownloads = sortDownloadsByType(availableDownloads);
const handleDownload = useCallback(
- async (type: 'asset' | 'rocm', download?: DownloadItem) => {
- if (type === 'asset' && !download) return;
-
- setDownloadingType(type);
- setDownloadingAsset(type === 'asset' ? download!.name : null);
+ async (download: DownloadItem) => {
+ setDownloadingAsset(download.name);
try {
const success = await sharedHandleDownload(
- type,
+ 'asset',
download,
false,
false
@@ -63,17 +44,15 @@ export const DownloadScreen = ({ onDownloadComplete }: DownloadScreenProps) => {
onDownloadComplete();
setTimeout(() => {
- setDownloadingType(null);
setDownloadingAsset(null);
}, 200);
}
} catch (error) {
window.electronAPI.logs.logError(
- `Failed to download ${type}:`,
+ `Failed to download ${download.name}:`,
error as Error
);
} finally {
- setDownloadingType(null);
setDownloadingAsset(null);
}
},
@@ -89,38 +68,6 @@ export const DownloadScreen = ({ onDownloadComplete }: DownloadScreenProps) => {
}
}, [downloading]);
- const renderROCmCard = () => {
- if (!rocmDownload) return null;
-
- const isDownloading = Boolean(downloading) && downloadingType === 'rocm';
-
- return (
-
- {
- e.stopPropagation();
- handleDownload('rocm', rocmDownload);
- }}
- />
-
- );
- };
-
return (
@@ -139,54 +86,9 @@ export const DownloadScreen = ({ onDownloadComplete }: DownloadScreenProps) => {
<>
{availableDownloads.length > 0 ? (
- {platformInfo.hasAMDGPU &&
- !platformInfo.hasROCm &&
- platformInfo.platform === 'linux' && (
-
-
-
-
- AMD GPU Detected
-
-
-
- For best performance with your AMD GPU,
- consider installing ROCm support.{' '}
- {
- 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
-
-
-
-
- )}
-
- {rocmDownload &&
- platformInfo.hasAMDGPU &&
- renderROCmCard()}
-
- {sortAssetsByRecommendation(
- regularDownloads,
- platformInfo.hasAMDGPU
- ).map((download) => {
+ {sortedDownloads.map((download) => {
const isDownloading =
Boolean(downloading) &&
- downloadingType === 'asset' &&
downloadingAsset === download.name;
return (
@@ -202,10 +104,6 @@ export const DownloadScreen = ({ onDownloadComplete }: DownloadScreenProps) => {
)}
version={download.version}
description={getAssetDescription(download.name)}
- isRecommended={isAssetRecommended(
- download.name,
- platformInfo.hasAMDGPU
- )}
isDownloading={isDownloading}
downloadProgress={
isDownloading
@@ -218,16 +116,12 @@ export const DownloadScreen = ({ onDownloadComplete }: DownloadScreenProps) => {
}
onDownload={(e) => {
e.stopPropagation();
- handleDownload('asset', download);
+ handleDownload(download);
}}
/>
);
})}
-
- {rocmDownload &&
- !platformInfo.hasAMDGPU &&
- renderROCmCard()}
) : (
diff --git a/src/components/settings/VersionsTab.tsx b/src/components/settings/VersionsTab.tsx
index 387cfef..ff087a1 100644
--- a/src/components/settings/VersionsTab.tsx
+++ b/src/components/settings/VersionsTab.tsx
@@ -12,11 +12,7 @@ import {
} from '@mantine/core';
import { RotateCcw, ExternalLink } from 'lucide-react';
import { DownloadCard } from '@/components/DownloadCard';
-import {
- getAssetDescription,
- sortAssetsByRecommendation,
- isAssetRecommended,
-} from '@/utils/assets';
+import { getAssetDescription, sortDownloadsByType } from '@/utils/assets';
import {
getDisplayNameFromPath,
formatDownloadSize,
@@ -34,14 +30,12 @@ interface VersionInfo {
isCurrent: boolean;
downloadUrl?: string;
installedPath?: string;
- isROCm?: boolean;
hasUpdate?: boolean;
newerVersion?: string;
}
export const VersionsTab = () => {
const {
- platformInfo,
availableDownloads,
loadingPlatform,
loadingRemote,
@@ -131,7 +125,9 @@ export const VersionsTab = () => {
const versions: VersionInfo[] = [];
const processedInstalled = new Set();
- availableDownloads.forEach((download) => {
+ const sortedDownloads = sortDownloadsByType(availableDownloads);
+
+ sortedDownloads.forEach((download) => {
const downloadBaseName = stripAssetExtensions(download.name);
const installedVersion = installedVersions.find((v) => {
@@ -162,7 +158,6 @@ export const VersionsTab = () => {
isCurrent,
downloadUrl: download.url,
installedPath: installedVersion.path,
- isROCm: download.type === 'rocm',
hasUpdate,
newerVersion: hasUpdate ? download.version : undefined,
});
@@ -174,7 +169,6 @@ export const VersionsTab = () => {
isInstalled: false,
isCurrent: false,
downloadUrl: download.url,
- isROCm: download.type === 'rocm',
});
}
});
@@ -193,18 +187,12 @@ export const VersionsTab = () => {
isInstalled: true,
isCurrent,
installedPath: installed.path,
- isROCm: false,
});
}
});
- return sortAssetsByRecommendation(versions, platformInfo.hasAMDGPU);
- }, [
- availableDownloads,
- installedVersions,
- currentVersion,
- platformInfo.hasAMDGPU,
- ]);
+ return versions;
+ }, [availableDownloads, installedVersions, currentVersion]);
useEffect(() => {
if (downloading && downloadingItemRef.current) {
@@ -222,9 +210,8 @@ export const VersionsTab = () => {
throw new Error('Download not found');
}
- const downloadType = download.type === 'rocm' ? 'rocm' : 'asset';
const success = await sharedHandleDownload(
- downloadType,
+ 'asset',
download,
false,
false
@@ -245,10 +232,9 @@ export const VersionsTab = () => {
throw new Error('Download not found');
}
- const downloadType = download.type === 'rocm' ? 'rocm' : 'asset';
const wasCurrentBinary = version.isCurrent;
const success = await sharedHandleDownload(
- downloadType,
+ 'asset',
download,
true,
wasCurrentBinary
@@ -368,19 +354,11 @@ export const VersionsTab = () => {
name={version.name}
size={
version.size
- ? formatDownloadSize(
- version.size,
- version.downloadUrl,
- version.isROCm
- )
+ ? formatDownloadSize(version.size, version.downloadUrl)
: ''
}
version={version.version}
description={getAssetDescription(version.name)}
- isRecommended={isAssetRecommended(
- version.name,
- platformInfo.hasAMDGPU
- )}
isCurrent={version.isCurrent}
isInstalled={version.isInstalled}
isDownloading={isDownloading}
diff --git a/src/constants/index.ts b/src/constants/index.ts
index 4927ca0..b3e42bf 100644
--- a/src/constants/index.ts
+++ b/src/constants/index.ts
@@ -38,10 +38,6 @@ export const KOBOLDAI_URLS = {
DOMAIN: 'koboldai.org',
} as const;
-export const GITHUB_URLS = {
- DOMAIN: 'github.com',
-} as const;
-
export const ROCM = {
BINARY_NAME: 'koboldcpp-linux-x64-rocm',
DOWNLOAD_URL: KOBOLDAI_URLS.ROCM_DOWNLOAD,
diff --git a/src/utils/assets.ts b/src/utils/assets.ts
index e3fc74e..85a547a 100644
--- a/src/utils/assets.ts
+++ b/src/utils/assets.ts
@@ -5,11 +5,11 @@ export const getAssetDescription = (assetName: string): string => {
const name = stripAssetExtensions(assetName).toLowerCase();
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)) {
- 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)) {
@@ -19,24 +19,6 @@ export const getAssetDescription = (assetName: string): string => {
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 => {
const name = stripAssetExtensions(assetName).toLowerCase();
@@ -47,23 +29,27 @@ export const isAssetStandard = (assetName: string): boolean => {
);
};
-export const sortAssetsByRecommendation = (
- assets: T[],
- hasAMDGPU: boolean
+export const sortDownloadsByType = (
+ downloads: T[]
): T[] =>
- [...assets].sort((a, b) => {
- const aRecommended = isAssetRecommended(a.name, hasAMDGPU);
- const bRecommended = isAssetRecommended(b.name, hasAMDGPU);
- const aStandard = isAssetStandard(a.name);
- const bStandard = isAssetStandard(b.name);
+ [...downloads].sort((a, b) => {
+ const aName = stripAssetExtensions(a.name).toLowerCase();
+ const bName = stripAssetExtensions(b.name).toLowerCase();
- if (aRecommended && !bRecommended) return -1;
- if (!aRecommended && bRecommended) return 1;
+ const getOrderPriority = (name: string): number => {
+ 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) {
- if (aStandard && !bStandard) return -1;
- if (!aStandard && bStandard) return 1;
+ const aPriority = getOrderPriority(aName);
+ const bPriority = getOrderPriority(bName);
+
+ if (aPriority !== bPriority) {
+ return aPriority - bPriority;
}
- return 0;
+ return a.name.localeCompare(b.name);
});
diff --git a/src/utils/downloadUtils.ts b/src/utils/downloadUtils.ts
index 58ab666..e0a521a 100644
--- a/src/utils/downloadUtils.ts
+++ b/src/utils/downloadUtils.ts
@@ -1,16 +1,10 @@
import { formatFileSizeInMB } from '@/utils/fileSize';
-import { KOBOLDAI_URLS, GITHUB_URLS } from '@/constants';
+import { KOBOLDAI_URLS } from '@/constants';
-export const formatDownloadSize = (
- size: number,
- url?: string,
- isROCm?: boolean
-): string => {
+export const formatDownloadSize = (size: number, url?: string): string => {
if (!size) return '';
- const isApproximateSize =
- url?.includes(KOBOLDAI_URLS.DOMAIN) ||
- (isROCm && !url?.includes(GITHUB_URLS.DOMAIN));
+ const isApproximateSize = url?.includes(KOBOLDAI_URLS.DOMAIN);
return isApproximateSize
? `~${formatFileSizeInMB(size)}`