upgrade to latest mantine, improve auto GPU layer detection

This commit is contained in:
lone-cloud 2026-04-06 09:12:59 -07:00
parent 826d63c68a
commit 5cad5bd141
Signed by: lone-cloud
GPG key ID: B0848536D672CD8D
4 changed files with 171 additions and 163 deletions

View file

@ -1,6 +1,6 @@
{ {
"name": "gerbil", "name": "gerbil",
"version": "1.22.0", "version": "1.22.1",
"description": "Run Large Language Models locally", "description": "Run Large Language Models locally",
"keywords": [ "keywords": [
"ai", "ai",
@ -44,8 +44,8 @@
"@codemirror/view": "^6.41.0", "@codemirror/view": "^6.41.0",
"@fontsource/inter": "^5.2.8", "@fontsource/inter": "^5.2.8",
"@huggingface/gguf": "^0.4.1", "@huggingface/gguf": "^0.4.1",
"@mantine/core": "^8.3.18", "@mantine/core": "^9.0.1",
"@mantine/hooks": "^8.3.18", "@mantine/hooks": "^9.0.1",
"@types/mime-types": "^3.0.1", "@types/mime-types": "^3.0.1",
"@types/node": "^25.5.2", "@types/node": "^25.5.2",
"@types/react": "^19.2.14", "@types/react": "^19.2.14",
@ -61,7 +61,7 @@
"lucide-react": "^1.7.0", "lucide-react": "^1.7.0",
"oxfmt": "^0.43.0", "oxfmt": "^0.43.0",
"oxlint": "^1.58.0", "oxlint": "^1.58.0",
"oxlint-tsgolint": "^0.19.0", "oxlint-tsgolint": "^0.20.0",
"react": "^19.2.4", "react": "^19.2.4",
"react-dom": "^19.2.4", "react-dom": "^19.2.4",
"react-error-boundary": "^6.1.1", "react-error-boundary": "^6.1.1",
@ -72,7 +72,7 @@
"remark-gfm": "^4.0.1", "remark-gfm": "^4.0.1",
"rollup-plugin-visualizer": "^7.0.1", "rollup-plugin-visualizer": "^7.0.1",
"typescript": "^6.0.2", "typescript": "^6.0.2",
"vite": "^8.0.3", "vite": "^8.0.5",
"zustand": "^5.0.12" "zustand": "^5.0.12"
}, },
"engines": { "engines": {

214
pnpm-lock.yaml generated
View file

@ -49,11 +49,11 @@ importers:
specifier: ^0.4.1 specifier: ^0.4.1
version: 0.4.1 version: 0.4.1
'@mantine/core': '@mantine/core':
specifier: ^8.3.18 specifier: ^9.0.1
version: 8.3.18(@mantine/hooks@8.3.18(react@19.2.4))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) version: 9.0.1(@mantine/hooks@9.0.1(react@19.2.4))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@mantine/hooks': '@mantine/hooks':
specifier: ^8.3.18 specifier: ^9.0.1
version: 8.3.18(react@19.2.4) version: 9.0.1(react@19.2.4)
'@types/mime-types': '@types/mime-types':
specifier: ^3.0.1 specifier: ^3.0.1
version: 3.0.1 version: 3.0.1
@ -74,7 +74,7 @@ importers:
version: 4.25.9(@babel/runtime@7.29.2)(@codemirror/autocomplete@6.20.1)(@codemirror/language@6.12.3)(@codemirror/lint@6.9.5)(@codemirror/search@6.6.0)(@codemirror/state@6.6.0)(@codemirror/theme-one-dark@6.1.3)(@codemirror/view@6.41.0)(codemirror@6.0.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) version: 4.25.9(@babel/runtime@7.29.2)(@codemirror/autocomplete@6.20.1)(@codemirror/language@6.12.3)(@codemirror/lint@6.9.5)(@codemirror/search@6.6.0)(@codemirror/state@6.6.0)(@codemirror/theme-one-dark@6.1.3)(@codemirror/view@6.41.0)(codemirror@6.0.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@vitejs/plugin-react': '@vitejs/plugin-react':
specifier: ^6.0.1 specifier: ^6.0.1
version: 6.0.1(vite@8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.2)(jiti@2.6.1)) version: 6.0.1(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.2)(jiti@2.6.1))
cross-env: cross-env:
specifier: ^10.1.0 specifier: ^10.1.0
version: 10.1.0 version: 10.1.0
@ -86,7 +86,7 @@ importers:
version: 26.8.1(electron-builder-squirrel-windows@26.8.1) version: 26.8.1(electron-builder-squirrel-windows@26.8.1)
electron-vite: electron-vite:
specifier: ^5.0.0 specifier: ^5.0.0
version: 5.0.0(vite@8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.2)(jiti@2.6.1)) version: 5.0.0(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.2)(jiti@2.6.1))
jiti: jiti:
specifier: ^2.6.1 specifier: ^2.6.1
version: 2.6.1 version: 2.6.1
@ -98,10 +98,10 @@ importers:
version: 0.43.0 version: 0.43.0
oxlint: oxlint:
specifier: ^1.58.0 specifier: ^1.58.0
version: 1.58.0(oxlint-tsgolint@0.19.0) version: 1.58.0(oxlint-tsgolint@0.20.0)
oxlint-tsgolint: oxlint-tsgolint:
specifier: ^0.19.0 specifier: ^0.20.0
version: 0.19.0 version: 0.20.0
react: react:
specifier: ^19.2.4 specifier: ^19.2.4
version: 19.2.4 version: 19.2.4
@ -133,8 +133,8 @@ importers:
specifier: ^6.0.2 specifier: ^6.0.2
version: 6.0.2 version: 6.0.2
vite: vite:
specifier: ^8.0.3 specifier: ^8.0.5
version: 8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.2)(jiti@2.6.1) version: 8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.2)(jiti@2.6.1)
zustand: zustand:
specifier: ^5.0.12 specifier: ^5.0.12
version: 5.0.12(@types/react@19.2.14)(react@19.2.4) version: 5.0.12(@types/react@19.2.14)(react@19.2.4)
@ -541,17 +541,17 @@ packages:
resolution: {integrity: sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==} resolution: {integrity: sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==}
engines: {node: '>= 10.0.0'} engines: {node: '>= 10.0.0'}
'@mantine/core@8.3.18': '@mantine/core@9.0.1':
resolution: {integrity: sha512-9tph1lTVogKPjTx02eUxDUOdXacPzK62UuSqb4TdGliI54/Xgxftq0Dfqu6XuhCxn9J5MDJaNiLDvL/1KRkYqA==} resolution: {integrity: sha512-kSYm8g7p8FTDysOsz9BN14TSqp10O0yAmo9HOZfwe6c08gGKQSytnSCPgnTe2h5DMfpbhTg+krROrT8WQy37fA==}
peerDependencies: peerDependencies:
'@mantine/hooks': 8.3.18 '@mantine/hooks': 9.0.1
react: ^18.x || ^19.x react: ^19.2.0
react-dom: ^18.x || ^19.x react-dom: ^19.2.0
'@mantine/hooks@8.3.18': '@mantine/hooks@9.0.1':
resolution: {integrity: sha512-QoWr9+S8gg5050TQ06aTSxtlpGjYOpIllRbjYYXlRvZeTsUqiTbVfvQROLexu4rEaK+yy9Wwriwl9PMRgbLqPw==} resolution: {integrity: sha512-WM/GbSD8MxZoy3X2IdrbxLq0/0ca4zMA5m7lGw9k1Vecqt1dC/nBed0IJd/w2HGs6avGs9CPlvQ8C4yBEcSnLA==}
peerDependencies: peerDependencies:
react: ^18.x || ^19.x react: ^19.2.0
'@marijn/find-cluster-break@1.0.2': '@marijn/find-cluster-break@1.0.2':
resolution: {integrity: sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==} resolution: {integrity: sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==}
@ -695,33 +695,33 @@ packages:
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
'@oxlint-tsgolint/darwin-arm64@0.19.0': '@oxlint-tsgolint/darwin-arm64@0.20.0':
resolution: {integrity: sha512-FVOIp5Njte8Z6PpINz7sL5blqSro0pAL8VAHYQ+K5Xm4cOrPQ6DGIhH14oXnbRjzn8Kl69qjz8TPteyn8EqwsQ==} resolution: {integrity: sha512-KKQcIHZHMxqpHUA1VXIbOG6chNCFkUWbQy6M+AFVtPKkA/3xAeJkJ3njoV66bfzwPHRcWQO+kcj5XqtbkjakoA==}
cpu: [arm64] cpu: [arm64]
os: [darwin] os: [darwin]
'@oxlint-tsgolint/darwin-x64@0.19.0': '@oxlint-tsgolint/darwin-x64@0.20.0':
resolution: {integrity: sha512-GakDTDACePvqOFq3N4oQCl8SyMMa7VBnqV0gDcXPuK50jdWCUqlxM9tgRJarjyIVvmDEJRGYOen+4uBtVwg4Aw==} resolution: {integrity: sha512-7HeVMuclGfG+NLZi2ybY0T4fMI7/XxO/208rJk+zEIloKkVnlh11Wd241JMGwgNFXn+MLJbOqOfojDb2Dt4L1g==}
cpu: [x64] cpu: [x64]
os: [darwin] os: [darwin]
'@oxlint-tsgolint/linux-arm64@0.19.0': '@oxlint-tsgolint/linux-arm64@0.20.0':
resolution: {integrity: sha512-Ya0R7somo+KDhhkPtENJ9Q28Fost+aqA3MPe86pEqgmukHFc/KO65PgShOSbIFjZNptELEQvsWL8gDxYZWhH3w==} resolution: {integrity: sha512-zxhUwz+WSxE6oWlZLK2z2ps9yC6ebmgoYmjAl0Oa48+GqkZ56NVgo+wb8DURNv6xrggzHStQxqQxe3mK51HZag==}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
'@oxlint-tsgolint/linux-x64@0.19.0': '@oxlint-tsgolint/linux-x64@0.20.0':
resolution: {integrity: sha512-yFH378jWc1k/oJmpk+TKpWbKvFieJJvsOHxVMSNFc+ukqs44ZSHVt4HFfAhXAt/bzVK2f7EIDTGp8Hm1OjoJ6Q==} resolution: {integrity: sha512-/1l6FnahC9im8PK+Ekkx/V3yetO/PzZnJegE2FXcv/iXEhbeVxP/ouiTYcUQu9shT1FWJCSNti1VJHH+21Y1dg==}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
'@oxlint-tsgolint/win32-arm64@0.19.0': '@oxlint-tsgolint/win32-arm64@0.20.0':
resolution: {integrity: sha512-R6NyAtha7OWxh7NGBeFxqDTGAVl1Xj4xLa8Qj39PKbIDqBeVW8BIb+1nEnRp+Mo/VpRoeoFAcqlBsuMcUMd26Q==} resolution: {integrity: sha512-oPZ5Yz8sVdo7P/5q+i3IKeix31eFZ55JAPa1+RGPoe9PoaYVsdMvR6Jvib6YtrqoJnFPlg3fjEjlEPL8VBKYJA==}
cpu: [arm64] cpu: [arm64]
os: [win32] os: [win32]
'@oxlint-tsgolint/win32-x64@0.19.0': '@oxlint-tsgolint/win32-x64@0.20.0':
resolution: {integrity: sha512-2ePvxcbS5tPOmrQvxR8Kc+IqzdTtlrGeMDv+jjTYfkTFPmh2rF9yxVchi/4WM6js3gt2UauQeMV/tfnZNemENQ==} resolution: {integrity: sha512-4stx8RHj3SP9vQyRF/yZbz5igtPvYMEUR8CUoha4BVNZihi39DpCR8qkU7lpjB5Ga1DRMo2pHaA4bdTOMaY4mw==}
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
@ -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.15: baseline-browser-mapping@2.10.16:
resolution: {integrity: sha512-1nfKCq9wuAZFTkA2ey/3OXXx7GzFjLdkTiFVNwlJ9WqdI706CZRIhEqjuwanjMIja+84jDLa9rcyZDPDiVkASQ==} resolution: {integrity: sha512-Lyf3aK28zpsD1yQMiiHD4RvVb6UdMoo8xzG2XzFIfR9luPzOpcBlAsT/qfB1XWS1bxWT+UtE4WmQgsp297FYOA==}
engines: {node: '>=6.0.0'} engines: {node: '>=6.0.0'}
hasBin: true hasBin: true
@ -1230,8 +1230,8 @@ packages:
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
caniuse-lite@1.0.30001785: caniuse-lite@1.0.30001786:
resolution: {integrity: sha512-blhOL/WNR+Km1RI/LCVAvA73xplXA7ZbjzI4YkMK9pa6T/P3F2GxjNpEkyw5repTw9IvkyrjyHpwjnhZ5FOvYQ==} resolution: {integrity: sha512-4oxTZEvqmLLrERwxO76yfKM7acZo310U+v4kqexI2TL1DkkUEMT8UijrxxcnVdxR3qkVf5awGRX+4Z6aPHVKrA==}
ccount@2.0.1: ccount@2.0.1:
resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
@ -2383,8 +2383,8 @@ packages:
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true hasBin: true
oxlint-tsgolint@0.19.0: oxlint-tsgolint@0.20.0:
resolution: {integrity: sha512-pSzUmDjMyjC8iUUZ7fCLo0D1iUaYIfodd/WIQ6Zra11YkjkUQk3BOFoW4I5ec6uZ/0s2FEmxtiZ7hiTXFRp1cg==} resolution: {integrity: sha512-/Uc9TQyN1l8w9QNvXtVHYtz+SzDJHKpb5X0UnHodl0BVzijUPk0LPlDOHAvogd1UI+iy9ZSF6gQxEqfzUxCULQ==}
hasBin: true hasBin: true
oxlint@1.58.0: oxlint@1.58.0:
@ -2559,12 +2559,6 @@ packages:
'@types/react': '@types/react':
optional: true optional: true
react-textarea-autosize@8.5.9:
resolution: {integrity: sha512-U1DGlIQN5AwgjTyOEnI1oCcMuEr1pv1qOtklB2l4nyMGbHzWrI0eFsYK0zos2YWqAolJyG0IWJaqWmWj5ETh0A==}
engines: {node: '>=10'}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
react@19.2.4: react@19.2.4:
resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@ -2811,6 +2805,10 @@ packages:
tabbable@6.4.0: tabbable@6.4.0:
resolution: {integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==} resolution: {integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==}
tagged-tag@1.0.0:
resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==}
engines: {node: '>=20'}
tar@7.5.13: tar@7.5.13:
resolution: {integrity: sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==} resolution: {integrity: sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==}
engines: {node: '>=18'} engines: {node: '>=18'}
@ -2866,9 +2864,9 @@ packages:
resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==}
engines: {node: '>=10'} engines: {node: '>=10'}
type-fest@4.41.0: type-fest@5.5.0:
resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} resolution: {integrity: sha512-PlBfpQwiUvGViBNX84Yxwjsdhd1TUlXr6zjX7eoirtCPIr08NAmxwa+fcYBTeRQxHo9YC9wwF3m9i700sHma8g==}
engines: {node: '>=16'} engines: {node: '>=20'}
typescript@6.0.2: typescript@6.0.2:
resolution: {integrity: sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==} resolution: {integrity: sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==}
@ -2938,33 +2936,6 @@ packages:
'@types/react': '@types/react':
optional: true optional: true
use-composed-ref@1.4.0:
resolution: {integrity: sha512-djviaxuOOh7wkj0paeO1Q/4wMZ8Zrnag5H6yBvzN7AKKe8beOaED9SF5/ByLqsku8NP4zQqsvM2u3ew/tJK8/w==}
peerDependencies:
'@types/react': '*'
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
peerDependenciesMeta:
'@types/react':
optional: true
use-isomorphic-layout-effect@1.2.1:
resolution: {integrity: sha512-tpZZ+EX0gaghDAiFR37hj5MgY6ZN55kLiPkJsKxBMZ6GZdOSPJXiOzPM984oPYZ5AnehYx5WQp1+ME8I/P/pRA==}
peerDependencies:
'@types/react': '*'
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
peerDependenciesMeta:
'@types/react':
optional: true
use-latest@1.3.0:
resolution: {integrity: sha512-mhg3xdm9NaM8q+gLT8KryJPnRFOz1/5XPBhmDEVZK1webPzDjrPk7f/mbpeLqTgB9msytYWANxgALOCJKnLvcQ==}
peerDependencies:
'@types/react': '*'
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
peerDependenciesMeta:
'@types/react':
optional: true
use-sidecar@1.1.3: use-sidecar@1.1.3:
resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==}
engines: {node: '>=10'} engines: {node: '>=10'}
@ -2994,14 +2965,14 @@ packages:
vfile@6.0.3: vfile@6.0.3:
resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
vite@8.0.3: vite@8.0.5:
resolution: {integrity: sha512-B9ifbFudT1TFhfltfaIPgjo9Z3mDynBTJSUYxTjOQruf/zHH+ezCQKcoqO+h7a9Pw9Nm/OtlXAiGT1axBgwqrQ==} resolution: {integrity: sha512-nmu43Qvq9UopTRfMx2jOYW5l16pb3iDC1JH6yMuPkpVbzK0k+L7dfsEDH4jRgYFmsg0sTAqkojoZgzLMlwHsCQ==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
'@types/node': ^20.19.0 || >=22.12.0 '@types/node': ^20.19.0 || >=22.12.0
'@vitejs/devtools': ^0.1.0 '@vitejs/devtools': ^0.1.0
esbuild: ^0.27.0 esbuild: ^0.27.0 || ^0.28.0
jiti: '>=1.21.0' jiti: '>=1.21.0'
less: ^4.0.0 less: ^4.0.0
sass: ^1.70.0 sass: ^1.70.0
@ -3622,21 +3593,20 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.4))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': '@mantine/core@9.0.1(@mantine/hooks@9.0.1(react@19.2.4))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
dependencies: dependencies:
'@floating-ui/react': 0.27.19(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@floating-ui/react': 0.27.19(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@mantine/hooks': 8.3.18(react@19.2.4) '@mantine/hooks': 9.0.1(react@19.2.4)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.4 react: 19.2.4
react-dom: 19.2.4(react@19.2.4) react-dom: 19.2.4(react@19.2.4)
react-number-format: 5.4.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react-number-format: 5.4.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
react-remove-scroll: 2.7.2(@types/react@19.2.14)(react@19.2.4) react-remove-scroll: 2.7.2(@types/react@19.2.14)(react@19.2.4)
react-textarea-autosize: 8.5.9(@types/react@19.2.14)(react@19.2.4) type-fest: 5.5.0
type-fest: 4.41.0
transitivePeerDependencies: transitivePeerDependencies:
- '@types/react' - '@types/react'
'@mantine/hooks@8.3.18(react@19.2.4)': '@mantine/hooks@9.0.1(react@19.2.4)':
dependencies: dependencies:
react: 19.2.4 react: 19.2.4
@ -3722,22 +3692,22 @@ snapshots:
'@oxfmt/binding-win32-x64-msvc@0.43.0': '@oxfmt/binding-win32-x64-msvc@0.43.0':
optional: true optional: true
'@oxlint-tsgolint/darwin-arm64@0.19.0': '@oxlint-tsgolint/darwin-arm64@0.20.0':
optional: true optional: true
'@oxlint-tsgolint/darwin-x64@0.19.0': '@oxlint-tsgolint/darwin-x64@0.20.0':
optional: true optional: true
'@oxlint-tsgolint/linux-arm64@0.19.0': '@oxlint-tsgolint/linux-arm64@0.20.0':
optional: true optional: true
'@oxlint-tsgolint/linux-x64@0.19.0': '@oxlint-tsgolint/linux-x64@0.20.0':
optional: true optional: true
'@oxlint-tsgolint/win32-arm64@0.19.0': '@oxlint-tsgolint/win32-arm64@0.20.0':
optional: true optional: true
'@oxlint-tsgolint/win32-x64@0.19.0': '@oxlint-tsgolint/win32-x64@0.20.0':
optional: true optional: true
'@oxlint/binding-android-arm-eabi@1.58.0': '@oxlint/binding-android-arm-eabi@1.58.0':
@ -3981,10 +3951,10 @@ snapshots:
'@ungap/structured-clone@1.3.0': {} '@ungap/structured-clone@1.3.0': {}
'@vitejs/plugin-react@6.0.1(vite@8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.2)(jiti@2.6.1))': '@vitejs/plugin-react@6.0.1(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.2)(jiti@2.6.1))':
dependencies: dependencies:
'@rolldown/pluginutils': 1.0.0-rc.7 '@rolldown/pluginutils': 1.0.0-rc.7
vite: 8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.2)(jiti@2.6.1) vite: 8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.2)(jiti@2.6.1)
'@xmldom/xmldom@0.8.12': {} '@xmldom/xmldom@0.8.12': {}
@ -4082,7 +4052,7 @@ snapshots:
base64-js@1.5.1: {} base64-js@1.5.1: {}
baseline-browser-mapping@2.10.15: {} baseline-browser-mapping@2.10.16: {}
bl@4.1.0: bl@4.1.0:
dependencies: dependencies:
@ -4108,8 +4078,8 @@ snapshots:
browserslist@4.28.2: browserslist@4.28.2:
dependencies: dependencies:
baseline-browser-mapping: 2.10.15 baseline-browser-mapping: 2.10.16
caniuse-lite: 1.0.30001785 caniuse-lite: 1.0.30001786
electron-to-chromium: 1.5.331 electron-to-chromium: 1.5.331
node-releases: 2.0.37 node-releases: 2.0.37
update-browserslist-db: 1.2.3(browserslist@4.28.2) update-browserslist-db: 1.2.3(browserslist@4.28.2)
@ -4189,7 +4159,7 @@ snapshots:
es-errors: 1.3.0 es-errors: 1.3.0
function-bind: 1.1.2 function-bind: 1.1.2
caniuse-lite@1.0.30001785: {} caniuse-lite@1.0.30001786: {}
ccount@2.0.1: {} ccount@2.0.1: {}
@ -4477,7 +4447,7 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
electron-vite@5.0.0(vite@8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.2)(jiti@2.6.1)): electron-vite@5.0.0(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.2)(jiti@2.6.1)):
dependencies: dependencies:
'@babel/core': 7.29.0 '@babel/core': 7.29.0
'@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.29.0) '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.29.0)
@ -4485,7 +4455,7 @@ snapshots:
esbuild: 0.25.12 esbuild: 0.25.12
magic-string: 0.30.21 magic-string: 0.30.21
picocolors: 1.1.1 picocolors: 1.1.1
vite: 8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.2)(jiti@2.6.1) vite: 8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.2)(jiti@2.6.1)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -5681,16 +5651,16 @@ snapshots:
'@oxfmt/binding-win32-ia32-msvc': 0.43.0 '@oxfmt/binding-win32-ia32-msvc': 0.43.0
'@oxfmt/binding-win32-x64-msvc': 0.43.0 '@oxfmt/binding-win32-x64-msvc': 0.43.0
oxlint-tsgolint@0.19.0: oxlint-tsgolint@0.20.0:
optionalDependencies: optionalDependencies:
'@oxlint-tsgolint/darwin-arm64': 0.19.0 '@oxlint-tsgolint/darwin-arm64': 0.20.0
'@oxlint-tsgolint/darwin-x64': 0.19.0 '@oxlint-tsgolint/darwin-x64': 0.20.0
'@oxlint-tsgolint/linux-arm64': 0.19.0 '@oxlint-tsgolint/linux-arm64': 0.20.0
'@oxlint-tsgolint/linux-x64': 0.19.0 '@oxlint-tsgolint/linux-x64': 0.20.0
'@oxlint-tsgolint/win32-arm64': 0.19.0 '@oxlint-tsgolint/win32-arm64': 0.20.0
'@oxlint-tsgolint/win32-x64': 0.19.0 '@oxlint-tsgolint/win32-x64': 0.20.0
oxlint@1.58.0(oxlint-tsgolint@0.19.0): oxlint@1.58.0(oxlint-tsgolint@0.20.0):
optionalDependencies: optionalDependencies:
'@oxlint/binding-android-arm-eabi': 1.58.0 '@oxlint/binding-android-arm-eabi': 1.58.0
'@oxlint/binding-android-arm64': 1.58.0 '@oxlint/binding-android-arm64': 1.58.0
@ -5711,7 +5681,7 @@ snapshots:
'@oxlint/binding-win32-arm64-msvc': 1.58.0 '@oxlint/binding-win32-arm64-msvc': 1.58.0
'@oxlint/binding-win32-ia32-msvc': 1.58.0 '@oxlint/binding-win32-ia32-msvc': 1.58.0
'@oxlint/binding-win32-x64-msvc': 1.58.0 '@oxlint/binding-win32-x64-msvc': 1.58.0
oxlint-tsgolint: 0.19.0 oxlint-tsgolint: 0.20.0
p-cancelable@2.1.1: {} p-cancelable@2.1.1: {}
@ -5870,15 +5840,6 @@ snapshots:
optionalDependencies: optionalDependencies:
'@types/react': 19.2.14 '@types/react': 19.2.14
react-textarea-autosize@8.5.9(@types/react@19.2.14)(react@19.2.4):
dependencies:
'@babel/runtime': 7.29.2
react: 19.2.4
use-composed-ref: 1.4.0(@types/react@19.2.14)(react@19.2.4)
use-latest: 1.3.0(@types/react@19.2.14)(react@19.2.4)
transitivePeerDependencies:
- '@types/react'
react@19.2.4: {} react@19.2.4: {}
read-binary-file-arch@1.0.6: read-binary-file-arch@1.0.6:
@ -6155,6 +6116,8 @@ snapshots:
tabbable@6.4.0: {} tabbable@6.4.0: {}
tagged-tag@1.0.0: {}
tar@7.5.13: tar@7.5.13:
dependencies: dependencies:
'@isaacs/fs-minipass': 4.0.1 '@isaacs/fs-minipass': 4.0.1
@ -6209,7 +6172,9 @@ snapshots:
type-fest@0.13.1: type-fest@0.13.1:
optional: true optional: true
type-fest@4.41.0: {} type-fest@5.5.0:
dependencies:
tagged-tag: 1.0.0
typescript@6.0.2: {} typescript@6.0.2: {}
@ -6281,25 +6246,6 @@ snapshots:
optionalDependencies: optionalDependencies:
'@types/react': 19.2.14 '@types/react': 19.2.14
use-composed-ref@1.4.0(@types/react@19.2.14)(react@19.2.4):
dependencies:
react: 19.2.4
optionalDependencies:
'@types/react': 19.2.14
use-isomorphic-layout-effect@1.2.1(@types/react@19.2.14)(react@19.2.4):
dependencies:
react: 19.2.4
optionalDependencies:
'@types/react': 19.2.14
use-latest@1.3.0(@types/react@19.2.14)(react@19.2.4):
dependencies:
react: 19.2.4
use-isomorphic-layout-effect: 1.2.1(@types/react@19.2.14)(react@19.2.4)
optionalDependencies:
'@types/react': 19.2.14
use-sidecar@1.1.3(@types/react@19.2.14)(react@19.2.4): use-sidecar@1.1.3(@types/react@19.2.14)(react@19.2.4):
dependencies: dependencies:
detect-node-es: 1.1.0 detect-node-es: 1.1.0
@ -6334,7 +6280,7 @@ snapshots:
'@types/unist': 3.0.3 '@types/unist': 3.0.3
vfile-message: 4.0.3 vfile-message: 4.0.3
vite@8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.2)(jiti@2.6.1): vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.2)(jiti@2.6.1):
dependencies: dependencies:
lightningcss: 1.32.0 lightningcss: 1.32.0
picomatch: 4.0.4 picomatch: 4.0.4

View file

@ -1,4 +1,4 @@
import { createTheme } from '@mantine/core'; import { createTheme, v8CssVariablesResolver } from '@mantine/core';
import type { CSSVariablesResolver } from '@mantine/core'; import type { CSSVariablesResolver } from '@mantine/core';
export const theme = createTheme({ export const theme = createTheme({
@ -59,15 +59,20 @@ export const theme = createTheme({
white: '#fafafa', white: '#fafafa',
}); });
export const cssVariablesResolver: CSSVariablesResolver = () => ({ export const cssVariablesResolver: CSSVariablesResolver = (t) => {
const v8 = v8CssVariablesResolver(t);
return {
variables: { ...v8.variables },
dark: { dark: {
...v8.dark,
'--mantine-color-body': '#0f0f0f', '--mantine-color-body': '#0f0f0f',
'--mantine-color-default-border': '#2a2a2a', '--mantine-color-default-border': '#2a2a2a',
}, },
light: { light: {
...v8.light,
'--mantine-color-body': '#fafafa', '--mantine-color-body': '#fafafa',
'--mantine-color-white': '#fafafa', '--mantine-color-white': '#fafafa',
'--mantine-color-default-border': '#dee2e6', '--mantine-color-default-border': '#dee2e6',
}, },
variables: {}, };
}); };

View file

@ -12,6 +12,14 @@ interface VramCalculationParams {
acceleration: Acceleration; acceleration: Acceleration;
} }
interface LayerKvInfo {
headCountKvByLayer: number[];
globalHeadDim: number;
swaHeadDim: number;
slidingWindow: number;
isSwaByLayer: boolean[];
}
function getAccelerationOverhead(acceleration: Acceleration) { function getAccelerationOverhead(acceleration: Acceleration) {
switch (acceleration) { switch (acceleration) {
case 'cuda': { case 'cuda': {
@ -36,17 +44,27 @@ function getAccelerationOverhead(acceleration: Acceleration) {
function estimateContextVram( function estimateContextVram(
contextSize: number, contextSize: number,
layers: number, layers: number,
kvDim: number,
flashAttention: boolean, flashAttention: boolean,
layerKvInfo: LayerKvInfo | number,
) { ) {
const bytesPerElement = 2; const bytesPerElement = 2;
let kvCacheSizeBytes = 2 * contextSize * layers * kvDim * bytesPerElement; const flashAttnFactor = flashAttention ? 0.5 : 1.0;
if (flashAttention) { if (typeof layerKvInfo === 'number') {
kvCacheSizeBytes *= 0.5; return (2 * contextSize * layers * layerKvInfo * bytesPerElement * flashAttnFactor) / 1024 ** 3;
} }
return kvCacheSizeBytes / 1024 ** 3; const { headCountKvByLayer, globalHeadDim, swaHeadDim, slidingWindow, isSwaByLayer } =
layerKvInfo;
let totalBytes = 0;
for (let i = 0; i < layers; i++) {
const isSwa = isSwaByLayer[i] ?? false;
const effectiveContext = isSwa ? Math.min(contextSize, slidingWindow) : contextSize;
const headDim = isSwa ? swaHeadDim : globalHeadDim;
const kvHeads = headCountKvByLayer[i] ?? headCountKvByLayer[headCountKvByLayer.length - 1];
totalBytes += 2 * effectiveContext * kvHeads * headDim * bytesPerElement * flashAttnFactor;
}
return totalBytes / 1024 ** 3;
} }
export async function calculateOptimalGpuLayers({ export async function calculateOptimalGpuLayers({
@ -86,11 +104,45 @@ export async function calculateOptimalGpuLayers({
const totalLayers = (metadataRecord[`${architecture}.block_count`] as number) || 32; const totalLayers = (metadataRecord[`${architecture}.block_count`] as number) || 32;
const embeddingLength = (metadataRecord[`${architecture}.embedding_length`] as number) || 4096; const embeddingLength = (metadataRecord[`${architecture}.embedding_length`] as number) || 4096;
const headCount = (metadataRecord[`${architecture}.attention.head_count`] as number) || 32; const headCount = (metadataRecord[`${architecture}.attention.head_count`] as number) || 32;
const headCountKv =
(metadataRecord[`${architecture}.attention.head_count_kv`] as number) || headCount;
const headDim = embeddingLength / headCount; const headCountKvRaw = metadataRecord[`${architecture}.attention.head_count_kv`];
const kvDim = headCountKv * headDim; const headCountKvByLayer = Array.isArray(headCountKvRaw) ? (headCountKvRaw as number[]) : null;
const headCountKvScalar = headCountKvByLayer
? Math.max(...headCountKvByLayer)
: (headCountKvRaw as number) || headCount;
const keyLength = metadataRecord[`${architecture}.attention.key_length`] as number | undefined;
const valueLength = metadataRecord[`${architecture}.attention.value_length`] as
| number
| undefined;
const keyLengthSwa = metadataRecord[`${architecture}.attention.key_length_swa`] as
| number
| undefined;
const valueLengthSwa = metadataRecord[`${architecture}.attention.value_length_swa`] as
| number
| undefined;
const globalHeadDim = keyLength ?? valueLength ?? embeddingLength / headCount;
const swaHeadDim = keyLengthSwa ?? valueLengthSwa ?? globalHeadDim;
const slidingWindow = metadataRecord[`${architecture}.attention.sliding_window`] as
| number
| undefined;
const slidingWindowPatternRaw =
metadataRecord[`${architecture}.attention.sliding_window_pattern`];
const isSwaByLayer = Array.isArray(slidingWindowPatternRaw)
? (slidingWindowPatternRaw as boolean[])
: null;
const layerKvInfo: LayerKvInfo | number =
(headCountKvByLayer ?? (slidingWindow !== undefined && isSwaByLayer))
? {
headCountKvByLayer: headCountKvByLayer ?? Array(totalLayers).fill(headCountKvScalar),
globalHeadDim,
swaHeadDim,
slidingWindow: slidingWindow ?? contextSize,
isSwaByLayer: isSwaByLayer ?? Array(totalLayers).fill(false),
}
: headCountKvScalar * globalHeadDim;
const { multiplier, computeBufferGB, headroomGB } = getAccelerationOverhead(acceleration); const { multiplier, computeBufferGB, headroomGB } = getAccelerationOverhead(acceleration);
@ -104,7 +156,7 @@ export async function calculateOptimalGpuLayers({
for (let layers = 1; layers <= totalLayers; layers++) { for (let layers = 1; layers <= totalLayers; layers++) {
const modelVram = layers * vramPerLayerGB; const modelVram = layers * vramPerLayerGB;
const contextVram = estimateContextVram(contextSize, layers, kvDim, flashAttention); const contextVram = estimateContextVram(contextSize, layers, flashAttention, layerKvInfo);
const totalVram = modelVram + contextVram; const totalVram = modelVram + contextVram;
if (totalVram <= availableForModel) { if (totalVram <= availableForModel) {
@ -115,7 +167,12 @@ export async function calculateOptimalGpuLayers({
} }
const modelVramGB = recommendedLayers * vramPerLayerGB; const modelVramGB = recommendedLayers * vramPerLayerGB;
const contextVramGB = estimateContextVram(contextSize, recommendedLayers, kvDim, flashAttention); const contextVramGB = estimateContextVram(
contextSize,
recommendedLayers,
flashAttention,
layerKvInfo,
);
return { return {
contextVramGB, contextVramGB,