diffusiongemma-agent-iq3-cuda13 / Install-DiffusionGemmaAgent.ps1
aogavrilov's picture
Add files using upload-large-folder tool
76a38cb verified
Raw
History Blame Contribute Delete
5.26 kB
[CmdletBinding()]
param(
[string]$WslRoot = '',
[switch]$NoStart,
[switch]$VerifyOnly
)
$ErrorActionPreference = 'Stop'
$bundle = Split-Path -Parent $PSCommandPath
$model = 'diffusiongemma-26B-A4B-it-IQ3_M-from-Q4_K_M.gguf'
$pythonArchive = "$bundle\payload\python\cpython-3.12.13.tar.gz"
foreach ($required in @("$bundle\payload\app\server.py", "$bundle\payload\bin\llama-diffusion-gemma-visual-server", "$bundle\payload\models\$model", $pythonArchive, "$bundle\manifest.json")) {
if (-not (Test-Path -LiteralPath $required)) { throw "Incomplete portable bundle: $required is missing." }
}
$manifest = Get-Content -LiteralPath "$bundle\manifest.json" -Raw | ConvertFrom-Json
$manifestHash = (Get-FileHash -LiteralPath "$bundle\manifest.json" -Algorithm SHA256).Hash.ToLowerInvariant()
$modelEntry = $manifest.files | Where-Object path -eq "payload/models/$model" | Select-Object -First 1
if (-not $modelEntry -or [int64]$modelEntry.bytes -ne (Get-Item -LiteralPath "$bundle\payload\models\$model").Length) {
throw 'The bundled GGUF size does not match manifest.json.'
}
$modelBytes = [int64]$modelEntry.bytes
if (-not (Get-Command wsl.exe -ErrorAction SilentlyContinue)) { throw 'WSL2 is required. Run wsl --install, reboot if requested, then run this command again.' }
& wsl.exe --exec true
if ($LASTEXITCODE -ne 0) { throw 'A default WSL distribution must be initialized once before installation.' }
$bundleWsl = (& wsl.exe --exec wslpath -a $bundle).Trim()
if (-not $bundleWsl) { throw 'Could not translate the bundle path for WSL.' }
if (-not $WslRoot) { $WslRoot = '~/.local/share/diffusiongemma-agent' }
$WslRoot = (& wsl.exe --exec python3 -c 'import os,sys; print(os.path.abspath(os.path.expandvars(os.path.expanduser(sys.argv[1]))))' $WslRoot).Trim()
if (-not $WslRoot.StartsWith('/') -or $WslRoot -in @('/', '/root', '/home', '/usr', '/var')) {
throw "Unsafe WSL installation path: $WslRoot"
}
if ($WslRoot.Contains("'")) { throw "WslRoot cannot contain an apostrophe." }
$runtimeBin = "$bundleWsl/payload/bin"
$ldd = & wsl.exe --exec env "LD_LIBRARY_PATH=$runtimeBin" ldd "$runtimeBin/llama-diffusion-gemma-visual-server" 2>&1
if ($LASTEXITCODE -ne 0 -or ($ldd -join "`n") -match 'not found') { throw "Portable CUDA runtime check failed:`n$($ldd -join "`n")" }
if ($VerifyOnly) { Write-Output 'Portable bundle verification passed.'; exit 0 }
$quotedBundle = $bundleWsl
$quotedRoot = $WslRoot
$setup = @"
set -euo pipefail
mkdir -p '$quotedRoot/runtime/bin' '$quotedRoot/models/diffusiongemma'
if ! grep -Fqx '$manifestHash' '$quotedRoot/runtime/installed-manifest.sha256' 2>/dev/null; then
cp -a '$quotedBundle/payload/app/.' '$quotedRoot/'
cp -a '$quotedBundle/payload/bin/.' '$quotedRoot/runtime/bin/'
if [ ! -f '$quotedRoot/models/diffusiongemma/$model' ] || [ `$(stat -c %s '$quotedRoot/models/diffusiongemma/$model') -ne $modelBytes ]; then
cp -a '$quotedBundle/payload/models/.' '$quotedRoot/models/diffusiongemma/'
fi
fi
if [ ! -x '$quotedRoot/python/bin/python3.12' ] || \
! '$quotedRoot/python/bin/python3.12' -c 'import sys; raise SystemExit(0 if (3, 10) <= sys.version_info[:2] < (3, 13) else 1)' >/dev/null 2>&1; then
rm -rf '$quotedRoot/python'
mkdir -p '$quotedRoot/python'
tar -xzf '$quotedBundle/payload/python/cpython-3.12.13.tar.gz' -C '$quotedRoot/python'
fi
'$quotedRoot/python/bin/python3.12' -c 'import sys; raise SystemExit(0 if (3, 10) <= sys.version_info[:2] < (3, 13) else 1)' || exit 43
if [ ! -x '$quotedRoot/.venv-runtime/bin/python' ] || \
! '$quotedRoot/.venv-runtime/bin/python' -c 'import aider, fastapi, haystack, pydantic, uvicorn' >/dev/null 2>&1; then
if ! timeout 15 bash -c 'cat < /dev/null > /dev/tcp/pypi.org/443'; then
exit 42
fi
rm -rf '$quotedRoot/.venv-runtime'
'$quotedRoot/python/bin/python3.12' -m venv '$quotedRoot/.venv-runtime'
'$quotedRoot/.venv-runtime/bin/python' -m pip install --disable-pip-version-check --upgrade 'pip==25.0.1'
'$quotedRoot/.venv-runtime/bin/python' -m pip install --disable-pip-version-check --prefer-binary \
'aider-chat==0.86.2' \
'fastapi==0.128.8' \
'haystack-ai==2.31.0' \
'pydantic==2.12.5' \
'uvicorn[standard]==0.51.0'
fi
chmod +x '$quotedRoot/runtime/bin/'* '$quotedRoot/scripts/'*.sh '$quotedRoot/start-runtime.sh'
printf '%s\n' '$manifestHash' > '$quotedRoot/runtime/installed-manifest.sha256'
"@
& wsl.exe --exec bash -lc $setup
if ($LASTEXITCODE -eq 42) { throw 'WSL cannot reach PyPI. Pause or reconfigure the VPN/proxy for WSL, then retry; the downloaded model files will be reused.' }
if ($LASTEXITCODE -eq 43) { throw 'The bundled Python runtime is incompatible. Download the current runtime bundle and retry.' }
if ($LASTEXITCODE -ne 0) { throw "WSL runtime installation failed (exit $LASTEXITCODE). The downloaded model files were kept and will be reused." }
[ordered]@{ format = 1; runtime_version = '0.1.2'; bundle = $bundle; wsl_root = $WslRoot; model = $model; installed_at = (Get-Date).ToUniversalTime().ToString('o') } |
ConvertTo-Json | Set-Content -LiteralPath "$bundle\installed.json" -Encoding utf8
if (-not $NoStart) { & "$bundle\dg.ps1" -StartOnly }
Write-Output "Installed. Use: & '$bundle\dg.ps1' -Repo C:\path\to\repo -Task 'fix ... and run tests'"