mirror of
https://github.com/lone-cloud/gerbil
synced 2026-06-03 19:54:44 -07:00
Compare commits
2 commits
7a7519a216
...
6e76d542df
| Author | SHA1 | Date | |
|---|---|---|---|
| 6e76d542df | |||
| 57e103d7e0 |
16 changed files with 224 additions and 98 deletions
56
.github/workflows/release.yml
vendored
56
.github/workflows/release.yml
vendored
|
|
@ -149,6 +149,62 @@ jobs:
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
update-flatpak:
|
||||||
|
needs: release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: needs.release.outputs.is_prerelease != 'true'
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
with:
|
||||||
|
ref: master
|
||||||
|
|
||||||
|
- name: Determine tag name
|
||||||
|
id: tag
|
||||||
|
run: |
|
||||||
|
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||||||
|
echo "tag=${{ github.event.inputs.tag }}" >> $GITHUB_OUTPUT
|
||||||
|
echo "version=${${{ github.event.inputs.tag }}#v}" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
|
||||||
|
echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Compute AppImage sha256
|
||||||
|
id: sha256
|
||||||
|
run: |
|
||||||
|
URL="https://github.com/lone-cloud/gerbil/releases/download/${{ steps.tag.outputs.tag }}/Gerbil-${{ steps.tag.outputs.version }}.AppImage"
|
||||||
|
echo "url=$URL" >> $GITHUB_OUTPUT
|
||||||
|
SHA=$(curl -sL "$URL" | sha256sum | awk '{print $1}')
|
||||||
|
echo "sha256=$SHA" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Update flatpak manifest
|
||||||
|
run: |
|
||||||
|
sed -i "s|url: https://github.com/lone-cloud/gerbil/releases/download/v[^/]*/Gerbil-.*\.AppImage|url: ${{ steps.sha256.outputs.url }}|" flatpak/app.lonecloud.gerbil.yml
|
||||||
|
# Only replace the sha256 that follows the AppImage url (not the uv one)
|
||||||
|
python3 - <<'EOF'
|
||||||
|
import re, pathlib
|
||||||
|
p = pathlib.Path('flatpak/app.lonecloud.gerbil.yml')
|
||||||
|
txt = p.read_text()
|
||||||
|
txt = re.sub(
|
||||||
|
r'(url: https://github\.com/lone-cloud/gerbil/releases/download/v[^\n]+\n\s+sha256: )[a-f0-9]{64}',
|
||||||
|
r'\g<1>${{ steps.sha256.outputs.sha256 }}',
|
||||||
|
txt
|
||||||
|
)
|
||||||
|
p.write_text(txt)
|
||||||
|
EOF
|
||||||
|
|
||||||
|
- name: Commit and push
|
||||||
|
run: |
|
||||||
|
git config user.name "github-actions[bot]"
|
||||||
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
|
git add flatpak/app.lonecloud.gerbil.yml
|
||||||
|
git diff --cached --quiet && echo "No changes" && exit 0
|
||||||
|
git commit -m "chore: update flatpak manifest for ${{ steps.tag.outputs.tag }}"
|
||||||
|
git push origin master
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
aur-release:
|
aur-release:
|
||||||
needs: release
|
needs: release
|
||||||
if: needs.release.outputs.is_prerelease != 'true'
|
if: needs.release.outputs.is_prerelease != 'true'
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,12 @@
|
||||||
[](https://github.com/lone-cloud/gerbil/stargazers)
|
[](https://github.com/lone-cloud/gerbil/stargazers)
|
||||||
[](https://aur.archlinux.org/packages/gerbil)
|
[](https://aur.archlinux.org/packages/gerbil)
|
||||||
|
|
||||||
|
<div style="display: flex; flex-wrap: wrap; justify-content: center; gap: 12px;">
|
||||||
|
<a href="https://github.com/lone-cloud/gerbil/releases"><img src="assets/badges/github-badge.png" alt="Get it on GitHub" height="50" /></a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
[Download](https://github.com/lone-cloud/gerbil/releases/latest) • [Screenshots](#demo--screenshots) • [Installation](#installation)
|
[Download](https://github.com/lone-cloud/gerbil/releases/latest) • [Screenshots](#demo--screenshots) • [Installation](#installation)
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,18 @@ import react from '@vitejs/plugin-react';
|
||||||
import { defineConfig } from 'electron-vite';
|
import { defineConfig } from 'electron-vite';
|
||||||
import { visualizer } from 'rollup-plugin-visualizer';
|
import { visualizer } from 'rollup-plugin-visualizer';
|
||||||
|
|
||||||
|
const watchIgnore = [resolve(__dirname, 'flatpak/build-dir')];
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
main: {
|
main: {
|
||||||
build: {
|
build: {
|
||||||
externalizeDeps: true,
|
externalizeDeps: true,
|
||||||
},
|
},
|
||||||
|
server: {
|
||||||
|
watch: {
|
||||||
|
ignored: watchIgnore,
|
||||||
|
},
|
||||||
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
'@': resolve(__dirname, './src'),
|
'@': resolve(__dirname, './src'),
|
||||||
|
|
@ -19,6 +26,11 @@ export default defineConfig({
|
||||||
build: {
|
build: {
|
||||||
externalizeDeps: true,
|
externalizeDeps: true,
|
||||||
},
|
},
|
||||||
|
server: {
|
||||||
|
watch: {
|
||||||
|
ignored: watchIgnore,
|
||||||
|
},
|
||||||
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
'@': resolve(__dirname, './src'),
|
'@': resolve(__dirname, './src'),
|
||||||
|
|
@ -28,6 +40,12 @@ export default defineConfig({
|
||||||
renderer: {
|
renderer: {
|
||||||
root: '.',
|
root: '.',
|
||||||
publicDir: 'src/assets',
|
publicDir: 'src/assets',
|
||||||
|
server: {
|
||||||
|
port: 5173,
|
||||||
|
watch: {
|
||||||
|
ignored: watchIgnore,
|
||||||
|
},
|
||||||
|
},
|
||||||
build: {
|
build: {
|
||||||
outDir: 'dist',
|
outDir: 'dist',
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
|
|
@ -51,8 +69,5 @@ export default defineConfig({
|
||||||
template: process.env.ANALYZE === 'server' ? 'network' : 'treemap',
|
template: process.env.ANALYZE === 'server' ? 'network' : 'treemap',
|
||||||
}),
|
}),
|
||||||
].filter(Boolean),
|
].filter(Boolean),
|
||||||
server: {
|
|
||||||
port: 5173,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,13 @@ finish-args:
|
||||||
- --share=ipc
|
- --share=ipc
|
||||||
- --socket=wayland
|
- --socket=wayland
|
||||||
- --socket=fallback-x11
|
- --socket=fallback-x11
|
||||||
|
- --socket=pulseaudio
|
||||||
- --device=all
|
- --device=all
|
||||||
- --allow=devel
|
- --allow=devel
|
||||||
- --filesystem=home
|
- --filesystem=home
|
||||||
- --filesystem=host-os
|
- --filesystem=host-os
|
||||||
- --filesystem=/opt/rocm:ro
|
- --filesystem=/opt/rocm:ro
|
||||||
- --talk-name=org.freedesktop.Notifications
|
- --filesystem=/sys/module/amdgpu:ro
|
||||||
- --talk-name=org.freedesktop.Flatpak
|
- --talk-name=org.freedesktop.Flatpak
|
||||||
- --talk-name=org.kde.StatusNotifierWatcher
|
- --talk-name=org.kde.StatusNotifierWatcher
|
||||||
- --talk-name=org.freedesktop.StatusNotifierWatcher
|
- --talk-name=org.freedesktop.StatusNotifierWatcher
|
||||||
|
|
@ -47,14 +48,14 @@ modules:
|
||||||
- install -Dm644 squashfs-root/usr/share/icons/hicolor/512x512/apps/gerbil.png /app/share/icons/hicolor/512x512/apps/app.lonecloud.gerbil.png
|
- install -Dm644 squashfs-root/usr/share/icons/hicolor/512x512/apps/gerbil.png /app/share/icons/hicolor/512x512/apps/app.lonecloud.gerbil.png
|
||||||
sources:
|
sources:
|
||||||
- type: file
|
- type: file
|
||||||
url: https://github.com/lone-cloud/gerbil/releases/download/v1.23.45/Gerbil-1.23.45.AppImage
|
path: ../release/Gerbil-1.24.0.AppImage
|
||||||
sha256: b3ea2b4bdbfbf4b44f091a9568deedbdef9cb8cd4d2d5f5be43cbd525b40c16a
|
|
||||||
- type: script
|
- type: script
|
||||||
dest-filename: gerbil-wrapper.sh
|
dest-filename: gerbil-wrapper.sh
|
||||||
commands:
|
commands:
|
||||||
- export PATH="/run/host/usr/bin:/run/host/usr/local/bin:$HOME/.local/bin:$HOME/.cargo/bin:$PATH"
|
- export PATH="/opt/rocm/bin:/app/bin:/run/host/usr/bin:/run/host/usr/local/bin:$HOME/.local/bin:$HOME/.cargo/bin:$PATH"
|
||||||
|
- export LD_LIBRARY_PATH="/usr/lib/x86_64-linux-gnu/GL/default/lib:/opt/rocm/lib:/opt/rocm/lib64:/run/host/usr/lib:/run/host/usr/lib/x86_64-linux-gnu:${LD_LIBRARY_PATH}"
|
||||||
- export VK_DRIVER_FILES="/run/host/usr/share/vulkan/icd.d:/run/host/etc/vulkan/icd.d"
|
- export VK_DRIVER_FILES="/run/host/usr/share/vulkan/icd.d:/run/host/etc/vulkan/icd.d"
|
||||||
- exec /app/lib/gerbil/gerbil --no-sandbox "$@"
|
- exec /app/lib/gerbil/gerbil --no-sandbox --use-angle=vulkan "$@"
|
||||||
- type: file
|
- type: file
|
||||||
path: app.lonecloud.gerbil.desktop
|
path: app.lonecloud.gerbil.desktop
|
||||||
- type: file
|
- type: file
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "gerbil",
|
"name": "gerbil",
|
||||||
"version": "1.23.45",
|
"version": "1.24.0",
|
||||||
"description": "Run Large Language Models locally",
|
"description": "Run Large Language Models locally",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"ai",
|
"ai",
|
||||||
|
|
@ -27,7 +27,6 @@
|
||||||
"check": "oxlint && oxfmt --check",
|
"check": "oxlint && oxfmt --check",
|
||||||
"fix": "oxlint --fix && oxfmt",
|
"fix": "oxlint --fix && oxfmt",
|
||||||
"release": "node --no-warnings scripts/release.ts",
|
"release": "node --no-warnings scripts/release.ts",
|
||||||
"fp:build": "cd flatpak && flatpak-builder --user --force-clean --state-dir=$HOME/.local/share/flatpak-builder/gerbil build-dir app.lonecloud.gerbil.yml",
|
|
||||||
"fp:install": "cd flatpak && flatpak-builder --user --install --force-clean --state-dir=$HOME/.local/share/flatpak-builder/gerbil build-dir app.lonecloud.gerbil.yml",
|
"fp:install": "cd flatpak && flatpak-builder --user --install --force-clean --state-dir=$HOME/.local/share/flatpak-builder/gerbil build-dir app.lonecloud.gerbil.yml",
|
||||||
"fp:run": "flatpak run app.lonecloud.gerbil",
|
"fp:run": "flatpak run app.lonecloud.gerbil",
|
||||||
"fp:uninstall": "flatpak uninstall --user app.lonecloud.gerbil",
|
"fp:uninstall": "flatpak uninstall --user app.lonecloud.gerbil",
|
||||||
|
|
@ -60,7 +59,7 @@
|
||||||
"@uiw/react-codemirror": "^4.25.9",
|
"@uiw/react-codemirror": "^4.25.9",
|
||||||
"@vitejs/plugin-react": "^6.0.1",
|
"@vitejs/plugin-react": "^6.0.1",
|
||||||
"cross-env": "^10.1.0",
|
"cross-env": "^10.1.0",
|
||||||
"electron": "^41.3.0",
|
"electron": "^41.5.0",
|
||||||
"electron-builder": "^26.8.1",
|
"electron-builder": "^26.8.1",
|
||||||
"electron-vite": "^5.0.0",
|
"electron-vite": "^5.0.0",
|
||||||
"jiti": "^2.6.1",
|
"jiti": "^2.6.1",
|
||||||
|
|
|
||||||
72
pnpm-lock.yaml
generated
72
pnpm-lock.yaml
generated
|
|
@ -82,8 +82,8 @@ importers:
|
||||||
specifier: ^10.1.0
|
specifier: ^10.1.0
|
||||||
version: 10.1.0
|
version: 10.1.0
|
||||||
electron:
|
electron:
|
||||||
specifier: ^41.3.0
|
specifier: ^41.5.0
|
||||||
version: 41.3.0
|
version: 41.5.0
|
||||||
electron-builder:
|
electron-builder:
|
||||||
specifier: ^26.8.1
|
specifier: ^26.8.1
|
||||||
version: 26.8.1(electron-builder-squirrel-windows@26.8.1)
|
version: 26.8.1(electron-builder-squirrel-windows@26.8.1)
|
||||||
|
|
@ -151,8 +151,8 @@ packages:
|
||||||
resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==}
|
resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
'@babel/compat-data@7.29.0':
|
'@babel/compat-data@7.29.3':
|
||||||
resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==}
|
resolution: {integrity: sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
'@babel/core@7.29.0':
|
'@babel/core@7.29.0':
|
||||||
|
|
@ -201,8 +201,8 @@ packages:
|
||||||
resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==}
|
resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
'@babel/parser@7.29.2':
|
'@babel/parser@7.29.3':
|
||||||
resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==}
|
resolution: {integrity: sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==}
|
||||||
engines: {node: '>=6.0.0'}
|
engines: {node: '>=6.0.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
|
@ -1157,8 +1157,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.24:
|
baseline-browser-mapping@2.10.25:
|
||||||
resolution: {integrity: sha512-I2NkZOOrj2XuguvWCK6OVh9GavsNjZjK908Rq3mIBK25+GD8vPX5w2WdxVqnQ7xx3SrZJiCiZFu+/Oz50oSYSA==}
|
resolution: {integrity: sha512-QO/VHsXCQdnzADMfmkeOPvHdIAkoB7i0/rGjINPJEetLx75hNttVWGQ/jycHUDP9zZ9rupbm60WRxcwViB0MiA==}
|
||||||
engines: {node: '>=6.0.0'}
|
engines: {node: '>=6.0.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
|
@ -1449,8 +1449,8 @@ packages:
|
||||||
electron-publish@26.8.1:
|
electron-publish@26.8.1:
|
||||||
resolution: {integrity: sha512-q+jrSTIh/Cv4eGZa7oVR+grEJo/FoLMYBAnSL5GCtqwUpr1T+VgKB/dn1pnzxIxqD8S/jP1yilT9VrwCqINR4w==}
|
resolution: {integrity: sha512-q+jrSTIh/Cv4eGZa7oVR+grEJo/FoLMYBAnSL5GCtqwUpr1T+VgKB/dn1pnzxIxqD8S/jP1yilT9VrwCqINR4w==}
|
||||||
|
|
||||||
electron-to-chromium@1.5.344:
|
electron-to-chromium@1.5.349:
|
||||||
resolution: {integrity: sha512-4MxfbmNDm+KPh066EZy+eUnkcDPcZ35wNmOWzFuh/ijvHsve6kbLTLURy88uCNK5FbpN+yk2nQY6BYh1GEt+wg==}
|
resolution: {integrity: sha512-QsWVGyRuY07Aqb234QytTfwd5d9AJlfNIQ5wIOl1L+PZDzI9d9+Fn0FRale/QYlFxt/bUnB0/nLd1jFPGxGK1A==}
|
||||||
|
|
||||||
electron-updater@6.8.3:
|
electron-updater@6.8.3:
|
||||||
resolution: {integrity: sha512-Z6sgw3jgbikWKXei1ENdqFOxBP0WlXg3TtKfz0rgw2vIZFJUyI4pD7ZN7jrkm7EoMK+tcm/qTnPUdqfZukBlBQ==}
|
resolution: {integrity: sha512-Z6sgw3jgbikWKXei1ENdqFOxBP0WlXg3TtKfz0rgw2vIZFJUyI4pD7ZN7jrkm7EoMK+tcm/qTnPUdqfZukBlBQ==}
|
||||||
|
|
@ -1470,8 +1470,8 @@ packages:
|
||||||
resolution: {integrity: sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg==}
|
resolution: {integrity: sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg==}
|
||||||
engines: {node: '>=8.0.0'}
|
engines: {node: '>=8.0.0'}
|
||||||
|
|
||||||
electron@41.3.0:
|
electron@41.5.0:
|
||||||
resolution: {integrity: sha512-2Q5aeocmFdeheZGDUTrAvSR3t+n0c3d104AJWWEnt7syJU0tE4VdibMYaPtQ47QuXSoUf0/xSsfUUvu/uSXIfg==}
|
resolution: {integrity: sha512-x9j9//PubUA4EjDtQbZhtk3prolandqCKgit0uCIqc1jb8FTskPbnJtxcDFB1aejczJcuERgjPixBUaMwoWyJg==}
|
||||||
engines: {node: '>= 12.20.55'}
|
engines: {node: '>= 12.20.55'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
|
@ -2208,13 +2208,13 @@ packages:
|
||||||
ms@2.1.3:
|
ms@2.1.3:
|
||||||
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
||||||
|
|
||||||
nanoid@3.3.11:
|
nanoid@3.3.12:
|
||||||
resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
|
resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==}
|
||||||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
node-abi@4.28.0:
|
node-abi@4.29.0:
|
||||||
resolution: {integrity: sha512-Qfp5XZL1cJDOabOT8H5gnqMTmM4NjvYzHp4I/Kt/Sl76OVkOBBHRFlPspGV0hYvMoqQsypFjT/Yp7Km0beXW9g==}
|
resolution: {integrity: sha512-bGc7hHz6lrdpMqH3XqfiHc5PKzEhjgUj6OLpTXynkLi9JZKyMByI/tdpm4Liu6O2BjtE1lakBWXjOQS1EnSQLQ==}
|
||||||
engines: {node: '>=22.12.0'}
|
engines: {node: '>=22.12.0'}
|
||||||
|
|
||||||
node-addon-api@1.7.2:
|
node-addon-api@1.7.2:
|
||||||
|
|
@ -2333,8 +2333,8 @@ packages:
|
||||||
resolution: {integrity: sha512-ZIfcLJC+7E7FBFnDxm9MPmt7D+DidyQ26lewieO75AdhA2ayMtsJSES0iWzqJQbcVRSrTufQoy0DR94xHue0oA==}
|
resolution: {integrity: sha512-ZIfcLJC+7E7FBFnDxm9MPmt7D+DidyQ26lewieO75AdhA2ayMtsJSES0iWzqJQbcVRSrTufQoy0DR94xHue0oA==}
|
||||||
engines: {node: '>=10.4.0'}
|
engines: {node: '>=10.4.0'}
|
||||||
|
|
||||||
postcss@8.5.12:
|
postcss@8.5.13:
|
||||||
resolution: {integrity: sha512-W62t/Se6rA0Az3DfCL0AqJwXuKwBeYg6nOaIgzP+xZ7N5BFCI7DYi1qs6ygUYT6rvfi6t9k65UMLJC+PHZpDAA==}
|
resolution: {integrity: sha512-qif0+jGGZoLWdHey3UFHHWP0H7Gbmsk8T5VEqyYFbWqPr1XqvLGBbk/sl8V5exGmcYJklJOhOQq1pV9IcsiFag==}
|
||||||
engines: {node: ^10 || ^12 || >=14}
|
engines: {node: ^10 || ^12 || >=14}
|
||||||
|
|
||||||
postject@1.0.0-alpha.6:
|
postject@1.0.0-alpha.6:
|
||||||
|
|
@ -2991,7 +2991,7 @@ snapshots:
|
||||||
js-tokens: 4.0.0
|
js-tokens: 4.0.0
|
||||||
picocolors: 1.1.1
|
picocolors: 1.1.1
|
||||||
|
|
||||||
'@babel/compat-data@7.29.0': {}
|
'@babel/compat-data@7.29.3': {}
|
||||||
|
|
||||||
'@babel/core@7.29.0':
|
'@babel/core@7.29.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -3000,7 +3000,7 @@ snapshots:
|
||||||
'@babel/helper-compilation-targets': 7.28.6
|
'@babel/helper-compilation-targets': 7.28.6
|
||||||
'@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0)
|
'@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0)
|
||||||
'@babel/helpers': 7.29.2
|
'@babel/helpers': 7.29.2
|
||||||
'@babel/parser': 7.29.2
|
'@babel/parser': 7.29.3
|
||||||
'@babel/template': 7.28.6
|
'@babel/template': 7.28.6
|
||||||
'@babel/traverse': 7.29.0
|
'@babel/traverse': 7.29.0
|
||||||
'@babel/types': 7.29.0
|
'@babel/types': 7.29.0
|
||||||
|
|
@ -3015,7 +3015,7 @@ snapshots:
|
||||||
|
|
||||||
'@babel/generator@7.29.1':
|
'@babel/generator@7.29.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/parser': 7.29.2
|
'@babel/parser': 7.29.3
|
||||||
'@babel/types': 7.29.0
|
'@babel/types': 7.29.0
|
||||||
'@jridgewell/gen-mapping': 0.3.13
|
'@jridgewell/gen-mapping': 0.3.13
|
||||||
'@jridgewell/trace-mapping': 0.3.31
|
'@jridgewell/trace-mapping': 0.3.31
|
||||||
|
|
@ -3023,7 +3023,7 @@ snapshots:
|
||||||
|
|
||||||
'@babel/helper-compilation-targets@7.28.6':
|
'@babel/helper-compilation-targets@7.28.6':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/compat-data': 7.29.0
|
'@babel/compat-data': 7.29.3
|
||||||
'@babel/helper-validator-option': 7.27.1
|
'@babel/helper-validator-option': 7.27.1
|
||||||
browserslist: 4.28.2
|
browserslist: 4.28.2
|
||||||
lru-cache: 5.1.1
|
lru-cache: 5.1.1
|
||||||
|
|
@ -3060,7 +3060,7 @@ snapshots:
|
||||||
'@babel/template': 7.28.6
|
'@babel/template': 7.28.6
|
||||||
'@babel/types': 7.29.0
|
'@babel/types': 7.29.0
|
||||||
|
|
||||||
'@babel/parser@7.29.2':
|
'@babel/parser@7.29.3':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/types': 7.29.0
|
'@babel/types': 7.29.0
|
||||||
|
|
||||||
|
|
@ -3074,7 +3074,7 @@ snapshots:
|
||||||
'@babel/template@7.28.6':
|
'@babel/template@7.28.6':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/code-frame': 7.29.0
|
'@babel/code-frame': 7.29.0
|
||||||
'@babel/parser': 7.29.2
|
'@babel/parser': 7.29.3
|
||||||
'@babel/types': 7.29.0
|
'@babel/types': 7.29.0
|
||||||
|
|
||||||
'@babel/traverse@7.29.0':
|
'@babel/traverse@7.29.0':
|
||||||
|
|
@ -3082,7 +3082,7 @@ snapshots:
|
||||||
'@babel/code-frame': 7.29.0
|
'@babel/code-frame': 7.29.0
|
||||||
'@babel/generator': 7.29.1
|
'@babel/generator': 7.29.1
|
||||||
'@babel/helper-globals': 7.28.0
|
'@babel/helper-globals': 7.28.0
|
||||||
'@babel/parser': 7.29.2
|
'@babel/parser': 7.29.3
|
||||||
'@babel/template': 7.28.6
|
'@babel/template': 7.28.6
|
||||||
'@babel/types': 7.29.0
|
'@babel/types': 7.29.0
|
||||||
debug: 4.4.3
|
debug: 4.4.3
|
||||||
|
|
@ -3223,7 +3223,7 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@malept/cross-spawn-promise': 2.0.0
|
'@malept/cross-spawn-promise': 2.0.0
|
||||||
debug: 4.4.3
|
debug: 4.4.3
|
||||||
node-abi: 4.28.0
|
node-abi: 4.29.0
|
||||||
node-api-version: 0.2.1
|
node-api-version: 0.2.1
|
||||||
node-gyp: 12.3.0
|
node-gyp: 12.3.0
|
||||||
read-binary-file-arch: 1.0.6
|
read-binary-file-arch: 1.0.6
|
||||||
|
|
@ -3874,7 +3874,7 @@ snapshots:
|
||||||
|
|
||||||
base64-js@1.5.1: {}
|
base64-js@1.5.1: {}
|
||||||
|
|
||||||
baseline-browser-mapping@2.10.24: {}
|
baseline-browser-mapping@2.10.25: {}
|
||||||
|
|
||||||
boolean@3.2.0:
|
boolean@3.2.0:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
@ -3894,9 +3894,9 @@ snapshots:
|
||||||
|
|
||||||
browserslist@4.28.2:
|
browserslist@4.28.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
baseline-browser-mapping: 2.10.24
|
baseline-browser-mapping: 2.10.25
|
||||||
caniuse-lite: 1.0.30001791
|
caniuse-lite: 1.0.30001791
|
||||||
electron-to-chromium: 1.5.344
|
electron-to-chromium: 1.5.349
|
||||||
node-releases: 2.0.38
|
node-releases: 2.0.38
|
||||||
update-browserslist-db: 1.2.3(browserslist@4.28.2)
|
update-browserslist-db: 1.2.3(browserslist@4.28.2)
|
||||||
|
|
||||||
|
|
@ -4220,7 +4220,7 @@ snapshots:
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
electron-to-chromium@1.5.344: {}
|
electron-to-chromium@1.5.349: {}
|
||||||
|
|
||||||
electron-updater@6.8.3:
|
electron-updater@6.8.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -4259,7 +4259,7 @@ snapshots:
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
electron@41.3.0:
|
electron@41.5.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@electron/get': 2.0.3
|
'@electron/get': 2.0.3
|
||||||
'@types/node': 24.12.2
|
'@types/node': 24.12.2
|
||||||
|
|
@ -5245,9 +5245,9 @@ snapshots:
|
||||||
|
|
||||||
ms@2.1.3: {}
|
ms@2.1.3: {}
|
||||||
|
|
||||||
nanoid@3.3.11: {}
|
nanoid@3.3.12: {}
|
||||||
|
|
||||||
node-abi@4.28.0:
|
node-abi@4.29.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
semver: 7.7.4
|
semver: 7.7.4
|
||||||
|
|
||||||
|
|
@ -5411,9 +5411,9 @@ snapshots:
|
||||||
xmlbuilder: 15.1.1
|
xmlbuilder: 15.1.1
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
postcss@8.5.12:
|
postcss@8.5.13:
|
||||||
dependencies:
|
dependencies:
|
||||||
nanoid: 3.3.11
|
nanoid: 3.3.12
|
||||||
picocolors: 1.1.1
|
picocolors: 1.1.1
|
||||||
source-map-js: 1.2.1
|
source-map-js: 1.2.1
|
||||||
|
|
||||||
|
|
@ -5925,7 +5925,7 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
lightningcss: 1.32.0
|
lightningcss: 1.32.0
|
||||||
picomatch: 4.0.4
|
picomatch: 4.0.4
|
||||||
postcss: 8.5.12
|
postcss: 8.5.13
|
||||||
rolldown: 1.0.0-rc.17
|
rolldown: 1.0.0-rc.17
|
||||||
tinyglobby: 0.2.16
|
tinyglobby: 0.2.16
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
|
|
|
||||||
|
|
@ -87,11 +87,7 @@ export const StatusBar = () => {
|
||||||
const displayGpuMetrics = systemMonitoringEnabled ? gpuMetrics : null;
|
const displayGpuMetrics = systemMonitoringEnabled ? gpuMetrics : null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppShell.Footer
|
<AppShell.Footer>
|
||||||
style={{
|
|
||||||
borderTop: '1px solid var(--mantine-color-default-border)',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Group
|
<Group
|
||||||
px="xs"
|
px="xs"
|
||||||
gap="xs"
|
gap="xs"
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ export const TitleBar = ({ currentScreen, currentTab, onEject, onTabChange }: Ti
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppShell.Header style={{ border: 'none', display: 'flex', flexDirection: 'column' }}>
|
<AppShell.Header>
|
||||||
<Box
|
<Box
|
||||||
style={{
|
style={{
|
||||||
WebkitAppRegion: isSelectOpen ? 'no-drag' : 'drag',
|
WebkitAppRegion: isSelectOpen ? 'no-drag' : 'drag',
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ export const TerminalTab = forwardRef<TerminalTabRef>((_props, ref) => {
|
||||||
color: 'light-dark(var(--mantine-color-dark-filled), var(--mantine-color-gray-0))',
|
color: 'light-dark(var(--mantine-color-dark-filled), var(--mantine-color-gray-0))',
|
||||||
fontFamily:
|
fontFamily:
|
||||||
'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
|
'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
|
||||||
fontSize: '0.875em',
|
fontSize: '0.8125em',
|
||||||
lineHeight: 1.4,
|
lineHeight: 1.4,
|
||||||
margin: 0,
|
margin: 0,
|
||||||
opacity: isVisible ? 1 : 0,
|
opacity: isVisible ? 1 : 0,
|
||||||
|
|
|
||||||
|
|
@ -439,7 +439,7 @@ export const LaunchScreen = ({ onLaunch }: LaunchScreenProps) => {
|
||||||
</Tabs>
|
</Tabs>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
borderTop: '1px solid var(--gerbil-divider)',
|
borderTop: '1px solid var(--mantine-color-default-border)',
|
||||||
padding: 'var(--mantine-spacing-md) 0',
|
padding: 'var(--mantine-spacing-md) 0',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
justifyContent: 'flex-end',
|
justifyContent: 'flex-end',
|
||||||
|
|
|
||||||
|
|
@ -201,9 +201,21 @@ export async function launchKoboldCpp(
|
||||||
|
|
||||||
await startProxy(koboldHost, koboldPort);
|
await startProxy(koboldHost, koboldPort);
|
||||||
|
|
||||||
|
const rocmEnv =
|
||||||
|
platform !== 'win32'
|
||||||
|
? {
|
||||||
|
HSA_OVERRIDE_GFX_VERSION: process.env.HSA_OVERRIDE_GFX_VERSION,
|
||||||
|
LD_LIBRARY_PATH: ['/opt/rocm/lib', '/opt/rocm/lib64', process.env.LD_LIBRARY_PATH]
|
||||||
|
.filter(Boolean)
|
||||||
|
.join(':'),
|
||||||
|
PATH: ['/opt/rocm/bin', process.env.PATH].filter(Boolean).join(':'),
|
||||||
|
}
|
||||||
|
: {};
|
||||||
|
|
||||||
const child = spawn(currentBackend.path, finalArgs, {
|
const child = spawn(currentBackend.path, finalArgs, {
|
||||||
cwd: binaryDir,
|
cwd: binaryDir,
|
||||||
detached: false,
|
detached: false,
|
||||||
|
env: { ...process.env, ...rocmEnv },
|
||||||
stdio: ['pipe', 'pipe', 'pipe'],
|
stdio: ['pipe', 'pipe', 'pipe'],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -213,10 +225,6 @@ export async function launchKoboldCpp(
|
||||||
|
|
||||||
sendKoboldOutput(commandLine);
|
sendKoboldOutput(commandLine);
|
||||||
|
|
||||||
if (remotetunnel) {
|
|
||||||
void startTunnel(frontendPreference);
|
|
||||||
}
|
|
||||||
|
|
||||||
let readyResolve: ((value: { success: boolean; pid?: number; error?: string }) => void) | null =
|
let readyResolve: ((value: { success: boolean; pid?: number; error?: string }) => void) | null =
|
||||||
null;
|
null;
|
||||||
let readyReject: ((error: Error) => void) | null = null;
|
let readyReject: ((error: Error) => void) | null = null;
|
||||||
|
|
@ -242,6 +250,10 @@ export async function launchKoboldCpp(
|
||||||
}
|
}
|
||||||
|
|
||||||
readyResolve?.({ pid: child.pid, success: true });
|
readyResolve?.({ pid: child.pid, success: true });
|
||||||
|
|
||||||
|
if (remotetunnel) {
|
||||||
|
void startTunnel(frontendPreference, true);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOutput = (data: Buffer) => {
|
const handleOutput = (data: Buffer) => {
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,10 @@ const replaceKoboldWithGerbil = (data: string) => {
|
||||||
|
|
||||||
const proxyRequest = (clientReq: IncomingMessage, clientRes: ServerResponse) => {
|
const proxyRequest = (clientReq: IncomingMessage, clientRes: ServerResponse) => {
|
||||||
const options = {
|
const options = {
|
||||||
headers: clientReq.headers,
|
headers: {
|
||||||
|
...clientReq.headers,
|
||||||
|
host: `${koboldCppHost}:${koboldCppPort}`,
|
||||||
|
},
|
||||||
hostname: koboldCppHost,
|
hostname: koboldCppHost,
|
||||||
method: clientReq.method,
|
method: clientReq.method,
|
||||||
path: clientReq.url,
|
path: clientReq.url,
|
||||||
|
|
|
||||||
|
|
@ -36,19 +36,31 @@ const getCloudflaredAssetName = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getCloudflaredDownloadUrl = async () => {
|
const getCloudflaredLatestVersion = async () => {
|
||||||
const response = await fetch(GITHUB_API.CLOUDFLARED_LATEST_RELEASE_URL);
|
const response = await fetch(GITHUB_API.CLOUDFLARED_LATEST_RELEASE_URL);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`Failed to fetch latest cloudflared release: ${response.statusText}`);
|
throw new Error(`Failed to fetch latest cloudflared release: ${response.statusText}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const release = (await response.json()) as { tag_name: string };
|
const release = (await response.json()) as { tag_name: string };
|
||||||
return GITHUB_API.getCloudflaredDownloadUrl(release.tag_name, getCloudflaredAssetName());
|
return release.tag_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
const downloadCloudflared = async (binPath: string) => {
|
const getCloudflaredDownloadUrl = (version: string) =>
|
||||||
const url = await getCloudflaredDownloadUrl();
|
GITHUB_API.getCloudflaredDownloadUrl(version, getCloudflaredAssetName());
|
||||||
sendKoboldOutput(`Downloading cloudflared from ${url}...`);
|
|
||||||
|
const getInstalledCloudflaredVersion = async (binPath: string) => {
|
||||||
|
try {
|
||||||
|
const result = await execa(binPath, ['--version']);
|
||||||
|
const match = /(\d{4}\.\d+\.\d+)/.exec(result.stdout + result.stderr);
|
||||||
|
return match ? match[1] : null;
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const downloadCloudflared = async (binPath: string, version: string) => {
|
||||||
|
const url = getCloudflaredDownloadUrl(version);
|
||||||
|
sendKoboldOutput(`Downloading cloudflared ${version} from ${url}...`);
|
||||||
|
|
||||||
const response = await fetch(url);
|
const response = await fetch(url);
|
||||||
if (!response.ok || !response.body) {
|
if (!response.ok || !response.body) {
|
||||||
|
|
@ -61,7 +73,7 @@ const downloadCloudflared = async (binPath: string) => {
|
||||||
await chmod(binPath, 0o755);
|
await chmod(binPath, 0o755);
|
||||||
}
|
}
|
||||||
|
|
||||||
sendKoboldOutput(`Downloaded cloudflared to ${binPath}`);
|
sendKoboldOutput(`Downloaded cloudflared ${version} to ${binPath}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getTunnelTarget = (frontendPreference: FrontendPreference) => {
|
const getTunnelTarget = (frontendPreference: FrontendPreference) => {
|
||||||
|
|
@ -97,7 +109,10 @@ const waitForBackend = async (url: string, timeoutMs = 30_000) => {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const startTunnel = async (frontendPreference: FrontendPreference = 'koboldcpp') => {
|
export const startTunnel = async (
|
||||||
|
frontendPreference: FrontendPreference = 'koboldcpp',
|
||||||
|
skipBackendCheck = false,
|
||||||
|
) => {
|
||||||
if (activeTunnel) {
|
if (activeTunnel) {
|
||||||
return tunnelUrl;
|
return tunnelUrl;
|
||||||
}
|
}
|
||||||
|
|
@ -105,6 +120,7 @@ export const startTunnel = async (frontendPreference: FrontendPreference = 'kobo
|
||||||
try {
|
try {
|
||||||
const tunnelTarget = getTunnelTarget(frontendPreference);
|
const tunnelTarget = getTunnelTarget(frontendPreference);
|
||||||
|
|
||||||
|
if (!skipBackendCheck) {
|
||||||
sendKoboldOutput('Waiting for backend to be ready...');
|
sendKoboldOutput('Waiting for backend to be ready...');
|
||||||
const backendReady = await waitForBackend(tunnelTarget);
|
const backendReady = await waitForBackend(tunnelTarget);
|
||||||
|
|
||||||
|
|
@ -113,20 +129,43 @@ export const startTunnel = async (frontendPreference: FrontendPreference = 'kobo
|
||||||
'Backend not ready after 30 seconds. Start your backend first before enabling tunnel.',
|
'Backend not ready after 30 seconds. Start your backend first before enabling tunnel.',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sendKoboldOutput('Starting Cloudflare tunnel...');
|
sendKoboldOutput(`Starting Cloudflare tunnel → ${tunnelTarget}`);
|
||||||
|
|
||||||
const bin = getCloudflaredBin();
|
const bin = getCloudflaredBin();
|
||||||
|
|
||||||
|
const latestVersion = await getCloudflaredLatestVersion();
|
||||||
const binExists = await access(bin)
|
const binExists = await access(bin)
|
||||||
.then(() => true)
|
.then(() => true)
|
||||||
.catch(() => false);
|
.catch(() => false);
|
||||||
|
|
||||||
if (!binExists) {
|
if (binExists) {
|
||||||
await downloadCloudflared(bin);
|
const installedVersion = await getInstalledCloudflaredVersion(bin);
|
||||||
|
const normalizedInstalled = installedVersion?.replace(/^(\d{4}\.\d+\.\d+).*$/, '$1');
|
||||||
|
const normalizedLatest = latestVersion.replace(/^[v]?(\d{4}\.\d+\.\d+).*$/, '$1');
|
||||||
|
if (normalizedInstalled !== normalizedLatest) {
|
||||||
|
sendKoboldOutput(
|
||||||
|
`Updating cloudflared ${installedVersion ?? 'unknown'} → ${latestVersion}`,
|
||||||
|
);
|
||||||
|
await downloadCloudflared(bin, latestVersion);
|
||||||
|
} else {
|
||||||
|
sendKoboldOutput(`cloudflared ${installedVersion} is up to date`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
await downloadCloudflared(bin, latestVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
const tunnel = execa(bin, ['tunnel', '--url', tunnelTarget, '--no-autoupdate']);
|
const nullDevice = platform === 'win32' ? 'NUL' : '/dev/null';
|
||||||
|
const tunnel = execa(bin, [
|
||||||
|
'tunnel',
|
||||||
|
'--config',
|
||||||
|
nullDevice,
|
||||||
|
'--url',
|
||||||
|
tunnelTarget,
|
||||||
|
'--no-autoupdate',
|
||||||
|
]);
|
||||||
|
tunnel.catch(() => {});
|
||||||
|
|
||||||
activeTunnel = tunnel;
|
activeTunnel = tunnel;
|
||||||
|
|
||||||
|
|
@ -134,19 +173,25 @@ export const startTunnel = async (frontendPreference: FrontendPreference = 'kobo
|
||||||
let output = '';
|
let output = '';
|
||||||
let urlFound = false;
|
let urlFound = false;
|
||||||
|
|
||||||
tunnel.stderr?.on('data', (data: Buffer) => {
|
const onTunnelOutput = (text: string) => {
|
||||||
const text = data.toString();
|
|
||||||
output += text;
|
output += text;
|
||||||
if (text.includes('429') || text.includes('Too Many Requests')) {
|
if (text.includes('429') || text.includes('Too Many Requests')) {
|
||||||
rateLimited = true;
|
rateLimited = true;
|
||||||
}
|
}
|
||||||
});
|
const match = /https:\/\/[a-z0-9-]+\.trycloudflare\.com/.exec(text);
|
||||||
|
if (match && match[0] !== tunnelUrl) {
|
||||||
|
tunnelUrl = match[0];
|
||||||
|
if (urlFound) {
|
||||||
|
sendKoboldOutput(`Tunnel URL: ${tunnelUrl}`);
|
||||||
|
}
|
||||||
|
sendToRenderer('tunnel-url-changed', tunnelUrl);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
tunnel.stdout?.on('data', (data: Buffer) => {
|
tunnel.stderr?.on('data', (data: Buffer) => onTunnelOutput(data.toString()));
|
||||||
output += data.toString();
|
tunnel.stdout?.on('data', (data: Buffer) => onTunnelOutput(data.toString()));
|
||||||
});
|
|
||||||
|
|
||||||
const url = await new Promise<string>((resolve, reject) => {
|
await new Promise<void>((resolve, reject) => {
|
||||||
const timeout = setTimeout(() => {
|
const timeout = setTimeout(() => {
|
||||||
const message = rateLimited
|
const message = rateLimited
|
||||||
? 'Cloudflare rate limit exceeded. Please wait a few minutes and try again.'
|
? 'Cloudflare rate limit exceeded. Please wait a few minutes and try again.'
|
||||||
|
|
@ -155,17 +200,14 @@ export const startTunnel = async (frontendPreference: FrontendPreference = 'kobo
|
||||||
reject(new Error(message));
|
reject(new Error(message));
|
||||||
}, 30_000);
|
}, 30_000);
|
||||||
|
|
||||||
const checkForUrl = () => {
|
const checkInterval = setInterval(() => {
|
||||||
const match = /https:\/\/[a-z0-9-]+\.trycloudflare\.com/.exec(output);
|
if (tunnelUrl) {
|
||||||
if (match) {
|
|
||||||
urlFound = true;
|
urlFound = true;
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
clearInterval(checkInterval);
|
clearInterval(checkInterval);
|
||||||
resolve(match[0]);
|
resolve();
|
||||||
}
|
}
|
||||||
};
|
}, 100);
|
||||||
|
|
||||||
const checkInterval = setInterval(checkForUrl, 100);
|
|
||||||
|
|
||||||
tunnel.once('error', (error) => {
|
tunnel.once('error', (error) => {
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
|
|
@ -182,11 +224,7 @@ export const startTunnel = async (frontendPreference: FrontendPreference = 'kobo
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 3000));
|
|
||||||
|
|
||||||
tunnelUrl = url;
|
|
||||||
sendKoboldOutput(`Tunnel ready at ${tunnelUrl}`);
|
sendKoboldOutput(`Tunnel ready at ${tunnelUrl}`);
|
||||||
sendToRenderer('tunnel-url-changed', tunnelUrl);
|
|
||||||
|
|
||||||
tunnel.on('error', (error: Error) => {
|
tunnel.on('error', (error: Error) => {
|
||||||
logError(`Tunnel error: ${error.message}`, error);
|
logError(`Tunnel error: ${error.message}`, error);
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,7 @@ export async function startFrontend(args: string[]) {
|
||||||
|
|
||||||
const envConfig: Record<string, string> = {
|
const envConfig: Record<string, string> = {
|
||||||
DATA_DIR: openWebUIDataDir,
|
DATA_DIR: openWebUIDataDir,
|
||||||
|
OPENSSL_CONF: '/dev/null',
|
||||||
ENABLE_OLLAMA_API: 'false',
|
ENABLE_OLLAMA_API: 'false',
|
||||||
ENABLE_VERSION_UPDATE_CHECK: 'false',
|
ENABLE_VERSION_UPDATE_CHECK: 'false',
|
||||||
GLOBAL_LOG_LEVEL: 'warning',
|
GLOBAL_LOG_LEVEL: 'warning',
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@
|
||||||
:root {
|
:root {
|
||||||
--gerbil-window-border: light-dark(rgba(0, 0, 0, 0.15), rgba(255, 255, 255, 0.08));
|
--gerbil-window-border: light-dark(rgba(0, 0, 0, 0.15), rgba(255, 255, 255, 0.08));
|
||||||
--gerbil-surface-secondary: light-dark(var(--mantine-color-gray-1), var(--mantine-color-dark-6));
|
--gerbil-surface-secondary: light-dark(var(--mantine-color-gray-1), var(--mantine-color-dark-6));
|
||||||
--gerbil-divider: light-dark(var(--mantine-color-default-border), oklch(30% 0.009 240));
|
|
||||||
--gerbil-scrollbar-thumb: color-mix(in srgb, var(--mantine-color-gray-5) 50%, transparent);
|
--gerbil-scrollbar-thumb: color-mix(in srgb, var(--mantine-color-gray-5) 50%, transparent);
|
||||||
--gerbil-scrollbar-thumb-hover: color-mix(in srgb, var(--mantine-color-gray-5) 80%, transparent);
|
--gerbil-scrollbar-thumb-hover: color-mix(in srgb, var(--mantine-color-gray-5) 80%, transparent);
|
||||||
--gerbil-scrollbar-thumb-active: color-mix(in srgb, var(--mantine-color-gray-7) 90%, transparent);
|
--gerbil-scrollbar-thumb-active: color-mix(in srgb, var(--mantine-color-gray-7) 90%, transparent);
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ export const cssVariablesResolver: CSSVariablesResolver = (t) => {
|
||||||
variables: { ...v8.variables },
|
variables: { ...v8.variables },
|
||||||
dark: {
|
dark: {
|
||||||
...v8.dark,
|
...v8.dark,
|
||||||
'--mantine-color-body': 'oklch(18% 0.008 240)',
|
'--mantine-color-body': 'oklch(22% 0.008 240)',
|
||||||
'--mantine-color-default-border': 'oklch(48% 0.009 240)',
|
'--mantine-color-default-border': 'oklch(48% 0.009 240)',
|
||||||
'--gerbil-link-color': 'var(--mantine-color-brand-4)',
|
'--gerbil-link-color': 'var(--mantine-color-brand-4)',
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue