426e9eeabd
Voice Workbench / headless workbench (mocked backends) (push) Has been cancelled
Voice Workbench / real acoustic lane (nightly, provisioned only) (push) Has been cancelled
ci / test (push) Has been cancelled
ci / lint-and-format (push) Has been cancelled
ci / build (push) Has been cancelled
ci / dev-startup (push) Has been cancelled
gitleaks / gitleaks (push) Has been cancelled
Markdown Links / Relative Markdown Links (push) Has been cancelled
Quality (Extended) / Homepage Build (PR smoke) (push) Has been cancelled
Quality (Extended) / Comment-only diff guard (push) Has been cancelled
Quality (Extended) / Format + Type Safety Ratchet (push) Has been cancelled
Quality (Extended) / Develop Gate (secret scan + UI determinism) (push) Has been cancelled
Quality (Extended) / Develop Gate (lint) (push) Has been cancelled
Chat shell gestures / Chat shell gesture + parity e2e (push) Has been cancelled
Cloud Gateway Discord / Test (push) Has been cancelled
Benchmark Bridge Tests / benchmark (bunx @biomejs/biome check packages/lifeops-bench/src, benchmark-lint) (push) Has been cancelled
Benchmark Bridge Tests / benchmark (bunx vitest run --config packages/lifeops-bench/vitest.config.ts --root packages/lifeops-bench --passWithNoTests, benchmark-tests) (push) Has been cancelled
Build Agent Image / build-and-push (push) Has been cancelled
Dev Smoke / bun run dev onboarding chat (push) Has been cancelled
Dev Smoke / Vite HMR dependency-level smoke (push) Has been cancelled
Electrobun Submodule Guard / electrobun gitlink is fetchable (push) Has been cancelled
Publish @elizaos/example-code / check_npm (push) Has been cancelled
Publish @elizaos/example-code / publish_npm (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / verify_version (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / publish_npm (push) Has been cancelled
Sandbox Live Smoke / Sandbox live smoke (push) Has been cancelled
Snap Build & Test / Build Snap (amd64) (push) Has been cancelled
Snap Build & Test / Build Snap (arm64) (push) Has been cancelled
Test Packaging / elizaos CLI global-install smoke (node + bun) (push) Has been cancelled
Cloud Gateway Webhook / Test (push) Has been cancelled
Cloud Tests / lint-and-types (push) Has been cancelled
Cloud Tests / unit-tests (push) Has been cancelled
Cloud Tests / integration-tests (push) Has been cancelled
Cloud Tests / e2e-tests (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Apps Worker (Product 2) / Determine environment (push) Has been cancelled
Deploy Apps Worker (Product 2) / Deploy apps worker to apps-control host (${{ needs.determine-env.outputs.environment }}) (push) Has been cancelled
Deploy Eliza Provisioning Worker / Determine environment (push) Has been cancelled
Deploy Eliza Provisioning Worker / Deploy worker to Hetzner host (${{ needs.determine-env.outputs.environment }} @ ${{ needs.determine-env.outputs.deployment_sha }}) (push) Has been cancelled
Dev Smoke / Classify changed paths (push) Has been cancelled
supply-chain / sbom (push) Has been cancelled
supply-chain / vulnerability-scan (push) Has been cancelled
Build, Push & Deploy to Phala Cloud / build-and-push (push) Has been cancelled
Test Packaging / Validate Packaging Configs (push) Has been cancelled
Test Packaging / Build & Test PyPI Package (push) Has been cancelled
Test Packaging / PyPI on Python ${{ matrix.python }} (push) Has been cancelled
Test Packaging / Pack & Test JS Tarballs (push) Has been cancelled
UI Fixture E2E / ui-fixture-e2e (push) Has been cancelled
UI Fixture E2E / fixture-e2e (push) Has been cancelled
UI Story Gate / story-gate (push) Has been cancelled
vault-ci / test (macos-latest) (push) Has been cancelled
vault-ci / test (ubuntu-latest) (push) Has been cancelled
vault-ci / test (windows-latest) (push) Has been cancelled
vault-ci / app-core wiring tests (push) Has been cancelled
verify-patches / verify patches/CHECKSUMS.sha256 (push) Has been cancelled
Voice Benchmark Smoke / voice-emotion fixture smoke (push) Has been cancelled
Voice Benchmark Smoke / voiceagentbench fixture smoke (push) Has been cancelled
Voice Benchmark Smoke / voicebench-quality unit smoke (push) Has been cancelled
Voice Benchmark Smoke / voicebench TypeScript unit (no audio) (push) Has been cancelled
Voice Benchmark Smoke / voice bench smoke summary (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/app-core test bun run --cwd packages/elizaos test bun run --cwd packages/cloud/shared test], app-and-cli) (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/scenario-runner test bun run --cwd packages/vault test bun run --cwd packages/security test bun run --cwd plugins/plugin-coding-tools test], framework-packages) (push) Has been cancelled
Windows CI / windows ([bun run --cwd plugins/plugin-elizacloud test bun run --cwd plugins/plugin-discord test bun run --cwd plugins/plugin-anthropic test bun run --cwd plugins/plugin-openai test bun run --cwd plugins/plugin-app-control test bun run --cwd plugins/pl… (push) Has been cancelled
Windows CI / windows ([node packages/scripts/run-turbo.mjs run build --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/agent --concurrency=4 node packages/scripts/run-bash-linux-only.mjs scripts/verify-riscv64-buildpaths.sh node packages/scripts/run… (push) Has been cancelled
Windows CI / windows ([node packages/scripts/run-turbo.mjs run typecheck --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/cloud-shared --concurrency=4 bun run --cwd packages/core test bun run --cwd packages/shared test], core-runtime, 75) (push) Has been cancelled
334 lines
12 KiB
PowerShell
334 lines
12 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
Native Windows hardware verification runner for Eliza-1 local inference.
|
|
|
|
.DESCRIPTION
|
|
Builds the requested Windows target, then runs model-backed llama-bench + llama-completion graph
|
|
smoke with --cache-type-k for TurboQuant, QJL, and PolarQuant aliases. This
|
|
script fails when hardware/toolchain/model prerequisites are missing. A pass
|
|
is a runtime dispatch smoke, not a symbol check.
|
|
|
|
Example:
|
|
pwsh -File packages/inference/verify/windows_runner.ps1 `
|
|
-Backend cuda `
|
|
-Model C:\models\eliza-1-smoke.gguf
|
|
|
|
Environment overrides:
|
|
WINDOWS_BUILD_FORK=0 skips the build step for an existing native binary.
|
|
WINDOWS_SKIP_GRAPH_SMOKE=1 exits non-zero after preflight; it is not
|
|
recordable hardware evidence.
|
|
ELIZA_MTP_SMOKE_CACHE_TYPES/TOKENS/NGL/PROMPT/EXTRA_ARGS tune the
|
|
llama-bench graph smoke.
|
|
ELIZA_STATE_DIR controls the default native binary lookup root.
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
param(
|
|
[ValidateSet("cuda", "vulkan", "cpu")]
|
|
[string] $Backend = "cuda",
|
|
|
|
[string] $Target = "",
|
|
|
|
[string] $Model = $env:ELIZA_MTP_SMOKE_MODEL,
|
|
|
|
[string] $BinDir = "",
|
|
|
|
[string] $ReportDir = "",
|
|
|
|
[string] $Report = $env:ELIZA_MTP_HARDWARE_REPORT,
|
|
|
|
[string[]] $CacheTypes = @()
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
$script:StartedAt = (Get-Date).ToUniversalTime()
|
|
$script:Target = $Target
|
|
$script:FailureReason = $null
|
|
$script:GpuInfo = $null
|
|
$script:ToolchainInfo = $null
|
|
$script:GraphSmokeStatus = "required"
|
|
$script:ResolvedModel = $Model
|
|
$script:Runs = @()
|
|
|
|
function Get-FileSha256([string] $Path) {
|
|
if ([string]::IsNullOrWhiteSpace($Path) -or -not (Test-Path $Path)) {
|
|
return $null
|
|
}
|
|
return (Get-FileHash -Algorithm SHA256 -Path $Path).Hash.ToLowerInvariant()
|
|
}
|
|
|
|
function Write-EvidenceReport([int] $ExitCode) {
|
|
if ([string]::IsNullOrWhiteSpace($Report)) {
|
|
return
|
|
}
|
|
$status = if ($ExitCode -eq 0) { "pass" } else { "fail" }
|
|
$passRecordable = ($ExitCode -eq 0 -and $script:GraphSmokeStatus -eq "required")
|
|
$parent = Split-Path -Parent $Report
|
|
if (-not [string]::IsNullOrWhiteSpace($parent)) {
|
|
New-Item -ItemType Directory -Force -Path $parent | Out-Null
|
|
}
|
|
$payload = [ordered]@{
|
|
schemaVersion = 1
|
|
runner = "windows_runner.ps1"
|
|
status = $status
|
|
passRecordable = $passRecordable
|
|
exitCode = $ExitCode
|
|
failureReason = $script:FailureReason
|
|
startedAt = $script:StartedAt.ToString("s") + "Z"
|
|
finishedAt = (Get-Date).ToUniversalTime().ToString("s") + "Z"
|
|
host = [ordered]@{
|
|
os = if ($IsWindows) { "Windows" } else { [System.Runtime.InteropServices.RuntimeInformation]::OSDescription }
|
|
arch = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString()
|
|
}
|
|
target = $script:Target
|
|
backend = $Backend
|
|
requirements = [ordered]@{
|
|
os = "Native Windows"
|
|
toolchain = switch ($Backend) {
|
|
"cuda" { @("nvidia-smi", "nvcc") }
|
|
"vulkan" { @("vulkaninfo") }
|
|
default { @() }
|
|
}
|
|
hardware = switch ($Backend) {
|
|
"cuda" { "NVIDIA GPU reported by nvidia-smi" }
|
|
"vulkan" { "Vulkan device reported by vulkaninfo" }
|
|
default { "Native Windows CPU execution" }
|
|
}
|
|
graphSmoke = $script:GraphSmokeStatus
|
|
}
|
|
evidence = [ordered]@{
|
|
gpuInfo = $script:GpuInfo
|
|
toolchainInfo = $script:ToolchainInfo
|
|
model = $script:ResolvedModel
|
|
modelSha256 = Get-FileSha256 $script:ResolvedModel
|
|
cacheRuns = $script:Runs
|
|
}
|
|
}
|
|
$payload | ConvertTo-Json -Depth 8 | Set-Content -Path $Report -Encoding UTF8
|
|
}
|
|
|
|
function Fail([string] $Message) {
|
|
$script:FailureReason = $Message
|
|
Write-EvidenceReport 1
|
|
[Console]::Error.WriteLine("[windows_runner] $Message")
|
|
exit 1
|
|
}
|
|
|
|
function Require-Command([string] $Name) {
|
|
if (-not (Get-Command $Name -ErrorAction SilentlyContinue)) {
|
|
Fail "$Name not found on PATH"
|
|
}
|
|
}
|
|
|
|
function Resolve-RepoRoot {
|
|
$root = (& git rev-parse --show-toplevel 2>$null)
|
|
if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($root)) {
|
|
Fail "could not resolve git repository root"
|
|
}
|
|
return $root.Trim()
|
|
}
|
|
|
|
function Resolve-CacheType([string] $Help, [string] $Family, [string[]] $Aliases) {
|
|
foreach ($alias in $Aliases) {
|
|
$pattern = "(^|[^A-Za-z0-9_+-])$([regex]::Escape($alias))([^A-Za-z0-9_+-]|$)"
|
|
if ($Help -match $pattern) {
|
|
return [pscustomobject]@{ Family = $Family; Cache = $alias }
|
|
}
|
|
}
|
|
Fail "llama-bench help does not advertise a cache-type alias for $Family"
|
|
}
|
|
|
|
trap {
|
|
if ([string]::IsNullOrWhiteSpace($script:FailureReason)) {
|
|
$script:FailureReason = "unhandled error: $($_.Exception.Message)"
|
|
}
|
|
try {
|
|
Write-EvidenceReport 1
|
|
} catch {
|
|
[Console]::Error.WriteLine("[windows_runner] failed to write evidence report: $($_.Exception.Message)")
|
|
}
|
|
[Console]::Error.WriteLine("[windows_runner] $($script:FailureReason)")
|
|
exit 1
|
|
}
|
|
|
|
if (-not $IsWindows) {
|
|
Fail "native Windows verification requires a Windows host"
|
|
}
|
|
|
|
$repoRoot = Resolve-RepoRoot
|
|
|
|
if ([string]::IsNullOrWhiteSpace($Target)) {
|
|
$arch = (Get-CimInstance Win32_OperatingSystem).OSArchitecture
|
|
if ($arch -match "ARM") {
|
|
if ($Backend -eq "cuda") {
|
|
Fail "windows-arm64-cuda is not a supported target; use -Backend vulkan or cpu on Snapdragon/ARM64 Windows"
|
|
}
|
|
$Target = "windows-arm64-$Backend"
|
|
} else {
|
|
$Target = "windows-x64-$Backend"
|
|
}
|
|
}
|
|
$script:Target = $Target
|
|
|
|
switch ($Backend) {
|
|
"cuda" {
|
|
Require-Command "nvidia-smi"
|
|
Require-Command "nvcc"
|
|
$script:GpuInfo = (& nvidia-smi --query-gpu=name,driver_version,compute_cap --format=csv,noheader 2>&1 | Out-String).Trim()
|
|
Write-Host $script:GpuInfo
|
|
if ($LASTEXITCODE -ne 0) { Fail "nvidia-smi did not report an NVIDIA GPU" }
|
|
$script:ToolchainInfo = (& nvcc --version 2>&1 | Out-String).Trim()
|
|
Write-Host $script:ToolchainInfo
|
|
}
|
|
"vulkan" {
|
|
if (-not (Get-Command "vulkaninfo" -ErrorAction SilentlyContinue)) {
|
|
Fail "vulkaninfo not found; install Vulkan SDK/runtime before Windows Vulkan verification"
|
|
}
|
|
$script:GpuInfo = (& vulkaninfo --summary 2>&1 | Out-String).Trim()
|
|
Write-Host $script:GpuInfo
|
|
if ($LASTEXITCODE -ne 0) { Fail "vulkaninfo failed to enumerate a Vulkan device" }
|
|
}
|
|
"cpu" {
|
|
Write-Host "[windows_runner] CPU backend selected; this verifies native Windows execution but no GPU dispatch."
|
|
}
|
|
}
|
|
|
|
$buildScript = Join-Path $repoRoot "packages/app-core/scripts/build-llama-cpp-mtp.mjs"
|
|
if ($env:WINDOWS_BUILD_FORK -ne "0") {
|
|
& node $buildScript --target $Target
|
|
if ($LASTEXITCODE -ne 0) { Fail "build target failed: $Target" }
|
|
}
|
|
|
|
if ([string]::IsNullOrWhiteSpace($BinDir)) {
|
|
$stateDir = $env:ELIZA_STATE_DIR
|
|
if ([string]::IsNullOrWhiteSpace($stateDir)) {
|
|
$stateDir = Join-Path $HOME ".eliza"
|
|
}
|
|
$BinDir = Join-Path $stateDir "local-inference/bin/mtp/$Target"
|
|
}
|
|
|
|
# Driver: llama-bench, not llama-cli. The fork's llama-cli is conversation-only
|
|
# and busy-loops on stdin EOF; llama-bench runs the same prompt-eval + token-gen
|
|
# graph passes (incl. the Turbo/QJL/Polar KV-cache ops) non-interactively and
|
|
# exits cleanly. llama-completion handles the real GGUF generation step.
|
|
$bench = Join-Path $BinDir "llama-bench.exe"
|
|
if (-not (Test-Path $bench)) {
|
|
Fail "missing llama-bench.exe in $BinDir (rebuild target $Target; the build script ships llama-bench + llama-completion alongside llama-server)"
|
|
}
|
|
$completion = Join-Path $BinDir "llama-completion.exe"
|
|
$env:PATH = "$BinDir;$env:PATH"
|
|
|
|
if ($env:WINDOWS_SKIP_GRAPH_SMOKE -eq "1") {
|
|
$script:GraphSmokeStatus = "skipped"
|
|
Fail "WINDOWS_SKIP_GRAPH_SMOKE=1 - build/hardware preflight only; graph dispatch NOT verified, so no hardware pass can be recorded."
|
|
}
|
|
|
|
if ([string]::IsNullOrWhiteSpace($Model) -or -not (Test-Path $Model)) {
|
|
Fail "ELIZA_MTP_SMOKE_MODEL / -Model must point at a GGUF model for graph dispatch verification"
|
|
}
|
|
$script:ResolvedModel = $Model
|
|
|
|
if ([string]::IsNullOrWhiteSpace($ReportDir)) {
|
|
$ReportDir = Join-Path $PSScriptRoot "hardware-results"
|
|
}
|
|
New-Item -ItemType Directory -Force -Path $ReportDir | Out-Null
|
|
|
|
$helpLog = Join-Path $ReportDir "$Target-llama-bench-help.log"
|
|
$helpText = (& $bench --help 2>&1 | Tee-Object -FilePath $helpLog | Out-String)
|
|
if ($helpText -notmatch "--cache-type-k") {
|
|
Fail "llama-bench help does not expose --cache-type-k; see $helpLog"
|
|
}
|
|
|
|
$runs = @()
|
|
if ($CacheTypes.Count -gt 0) {
|
|
foreach ($cache in $CacheTypes) {
|
|
$runs += [pscustomobject]@{ Family = $cache; Cache = $cache }
|
|
}
|
|
} elseif (-not [string]::IsNullOrWhiteSpace($env:ELIZA_MTP_SMOKE_CACHE_TYPES)) {
|
|
foreach ($cache in ($env:ELIZA_MTP_SMOKE_CACHE_TYPES -split "[,\s]+" | Where-Object { $_ })) {
|
|
$runs += [pscustomobject]@{ Family = $cache; Cache = $cache }
|
|
}
|
|
} else {
|
|
$runs += Resolve-CacheType $helpText "turbo3" @("tbq3_0", "turbo3")
|
|
$runs += Resolve-CacheType $helpText "turbo4" @("tbq4_0", "turbo4")
|
|
$runs += Resolve-CacheType $helpText "turbo3_tcq" @("tbq3_tcq", "turbo3_tcq", "turbo3-tcq")
|
|
$runs += Resolve-CacheType $helpText "qjl" @("qjl1_256", "qjl_full", "qjl")
|
|
$runs += Resolve-CacheType $helpText "polar" @("q4_polar", "polarquant", "polar")
|
|
}
|
|
|
|
$backendPattern = switch ($Backend) {
|
|
"cuda" { "CUDA|cuda|cuBLAS|ggml_cuda|NVIDIA" }
|
|
"vulkan" { "Vulkan|vulkan|ggml_vulkan" }
|
|
default { "AVX|AVX2|CPU|ggml_backend_cpu|llama" }
|
|
}
|
|
|
|
$prompt = if ($env:ELIZA_MTP_SMOKE_PROMPT) { $env:ELIZA_MTP_SMOKE_PROMPT } else { "Eliza Windows backend graph dispatch smoke." }
|
|
$tokens = if ($env:ELIZA_MTP_SMOKE_TOKENS) { $env:ELIZA_MTP_SMOKE_TOKENS } else { "4" }
|
|
$ngl = if ($env:ELIZA_MTP_SMOKE_NGL) { $env:ELIZA_MTP_SMOKE_NGL } else { "99" }
|
|
$extraArgs = @()
|
|
if ($env:ELIZA_MTP_SMOKE_EXTRA_ARGS) {
|
|
$extraArgs = $env:ELIZA_MTP_SMOKE_EXTRA_ARGS -split "\s+"
|
|
}
|
|
|
|
$summary = Join-Path $ReportDir "$Target-graph-smoke.summary"
|
|
@(
|
|
"target=$Target",
|
|
"backend=$Backend",
|
|
"bin_dir=$BinDir",
|
|
"model=$Model",
|
|
"tokens=$tokens",
|
|
"ngl=$ngl",
|
|
"started_at=$((Get-Date).ToUniversalTime().ToString("s"))Z"
|
|
) | Set-Content -Path $summary -Encoding UTF8
|
|
|
|
foreach ($run in $runs) {
|
|
$log = Join-Path $ReportDir "$Target-$($run.Family)-$($run.Cache).log"
|
|
Write-Host "[windows_runner] target=$Target family=$($run.Family) cache=$($run.Cache) (llama-bench)"
|
|
& $bench -m $Model -ngl $ngl --cache-type-k $run.Cache -p 16 -n $tokens -fa 1 -r 1 @extraArgs *> $log
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Fail "llama-bench graph smoke failed for cache=$($run.Cache); see $log"
|
|
}
|
|
$logText = Get-Content -Raw -Path $log
|
|
if ($logText -notmatch $backendPattern) {
|
|
Fail "backend pattern '$backendPattern' not observed for cache=$($run.Cache); see $log"
|
|
}
|
|
$script:Runs += [ordered]@{
|
|
family = $run.Family
|
|
cache = $run.Cache
|
|
log = $log
|
|
backendPattern = $backendPattern
|
|
status = "pass"
|
|
}
|
|
Add-Content -Path $summary -Value "PASS $($run.Family) cache=$($run.Cache) log=$log"
|
|
}
|
|
|
|
# Real GGUF next-token generation via llama-completion (the conversation-free
|
|
# generation driver). Skipped only if the build didn't ship it.
|
|
if (Test-Path $completion) {
|
|
$genLog = Join-Path $ReportDir "$Target-gen-check.log"
|
|
Write-Host "[windows_runner] target=$Target GGUF generation (llama-completion)"
|
|
& $completion -m $Model -p $prompt -n $tokens -ngl $ngl --no-warmup @extraArgs *> $genLog
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Fail "llama-completion GGUF generation failed; see $genLog"
|
|
}
|
|
$genText = Get-Content -Raw -Path $genLog
|
|
if ($genText -notmatch $backendPattern) {
|
|
Fail "backend pattern '$backendPattern' not observed during GGUF generation; see $genLog"
|
|
}
|
|
$script:Runs += [ordered]@{
|
|
family = "gen-check"
|
|
cache = "n/a"
|
|
log = $genLog
|
|
backendPattern = $backendPattern
|
|
status = "pass"
|
|
}
|
|
Add-Content -Path $summary -Value "PASS gen-check log=$genLog"
|
|
} else {
|
|
Add-Content -Path $summary -Value "SKIP gen-check (llama-completion.exe not installed)"
|
|
}
|
|
|
|
Add-Content -Path $summary -Value "finished_at=$((Get-Date).ToUniversalTime().ToString("s"))Z"
|
|
Write-EvidenceReport 0
|
|
Write-Host "[windows_runner] PASS target=$Target report=$summary"
|