param([switch]$DownloadModel, [string]$Cmake = '') $ErrorActionPreference = 'Stop' $root = (Resolve-Path (Join-Path $PSScriptRoot '../..')).Path Push-Location $root try { $manifest = Get-Content ai/model.json -Raw | ConvertFrom-Json $vendor = Join-Path $root 'tools/vendor/llama.cpp' if (!(Test-Path -LiteralPath (Join-Path $vendor '.git'))) { & git clone --depth 1 https://github.com/ggml-org/llama.cpp.git $vendor if ($LASTEXITCODE -ne 0) { throw 'Cannot obtain the inference source' } } $revision = & git -C $vendor rev-parse HEAD if ($revision -ne $manifest.llama_commit) { & git -C $vendor fetch --depth 1 origin $manifest.llama_commit if ($LASTEXITCODE -ne 0) { throw 'Cannot obtain pinned inference source' } & git -C $vendor checkout --detach $manifest.llama_commit if ($LASTEXITCODE -ne 0) { throw 'Cannot select pinned inference source' } } if (!$Cmake) { $local = Join-Path $root 'tools/vendor/python/cmake/data/bin/cmake.exe' if (Test-Path -LiteralPath $local) { $Cmake = $local } else { $Cmake = (Get-Command cmake -ErrorAction Stop).Source } } $env:VSLANG = '1033' & $Cmake -S tools/fortune_ai -B build/fortune-ai -G 'Visual Studio 18 2026' -A x64 if ($LASTEXITCODE -ne 0) { throw 'Inference configuration failed' } & $Cmake --build build/fortune-ai --config Release --target fortune-engine --parallel 8 -- /p:UseStructuredOutput=false if ($LASTEXITCODE -ne 0) { throw 'Inference compilation failed' } Copy-Item -LiteralPath build/fortune-ai/Release/fortune-engine.exe -Destination ai/fortune-engine.exe New-Item -ItemType Directory -Force -Path ai/licenses,ai/models | Out-Null Copy-Item -LiteralPath tools/vendor/llama.cpp/LICENSE -Destination ai/licenses/llama.cpp.txt $model = Join-Path (Join-Path $root 'ai') $manifest.file if ($DownloadModel) { & powershell.exe -NoProfile -ExecutionPolicy Bypass -File tools/fortune_ai/download_model.ps1 if ($LASTEXITCODE -ne 0) { throw 'Model setup failed' } } if (!(Test-Path -LiteralPath $model)) { throw 'Distribution is incomplete: missing bundled model' } if ((Get-Item -LiteralPath $model).Length -ne $manifest.bytes -or (Get-FileHash -LiteralPath $model -Algorithm SHA256).Hash -ne $manifest.sha256) { throw 'Bundled model integrity check failed' } Write-Output 'Built the offline x64 worker and verified the bundled model.' } finally { Pop-Location }