param( [string]$Engine = "$env:APPDATA\XianrenStudio\engines\cpu\llama-server.exe", [string]$Model = "$env:APPDATA\XianrenStudio\models\Qwen\Qwen2.5-0.5B-Instruct-GGUF\qwen2.5-0.5b-instruct-q4_k_m.gguf", [int]$Port = 8088 ) $ErrorActionPreference = "Stop" if (-not (Test-Path $Engine)) { throw "engine not found: $Engine" } if (-not (Test-Path $Model)) { throw "model not found: $Model" } $log = Join-Path $env:TEMP "llama-server-smoke.log" $args = @( "--model", "`"$Model`"", "--host", "127.0.0.1", "--port", "$Port", "--ctx-size", "2048", "-ngl", "0", "--no-webui" ) $p = Start-Process -FilePath $Engine -ArgumentList $args ` -RedirectStandardOutput $log -RedirectStandardError "$log.err" ` -WindowStyle Hidden -PassThru try { $ready = $false for ($i = 0; $i -lt 240; $i++) { Start-Sleep -Milliseconds 500 try { $r = Invoke-RestMethod -Uri "http://127.0.0.1:$Port/health" -TimeoutSec 2 if ($r.status -eq "ok") { $ready = $true; break } } catch {} } if (-not $ready) { Get-Content $log -ErrorAction SilentlyContinue | Select-Object -Last 20 throw "engine did not become ready; log: $log" } Write-Host "engine ready (pid $($p.Id), port $Port)" $body = @{ model = "qwen-test" messages = @(@{ role = "user"; content = "Introduce yourself in one sentence." }) stream = $false max_tokens = 128 } | ConvertTo-Json -Depth 6 $resp = Invoke-RestMethod -Uri "http://127.0.0.1:$Port/v1/chat/completions" ` -Method Post -ContentType "application/json; charset=utf-8" -Body $body -TimeoutSec 120 Write-Host "NON-STREAM REPLY: $($resp.choices[0].message.content)" $body2 = @{ model = "qwen-test" messages = @(@{ role = "user"; content = "Count from 1 to 5." }) stream = $true max_tokens = 64 } | ConvertTo-Json -Depth 6 $sse = Invoke-RestMethod -Uri "http://127.0.0.1:$Port/v1/chat/completions" ` -Method Post -ContentType "application/json; charset=utf-8" -Body $body2 -TimeoutSec 120 $hasDone = $sse -match "\[DONE\]" $dataLines = ($sse -split "`n" | Where-Object { $_ -match "^data:" }).Count Write-Host "STREAM: done-marker=$hasDone data-lines=$dataLines" if (-not $hasDone -or $dataLines -lt 2) { throw "streaming check failed" } Write-Host "SMOKE TEST PASSED" } finally { try { Invoke-RestMethod -Method Post -Uri "http://127.0.0.1:$Port/shutdown" -TimeoutSec 5 | Out-Null } catch {} Start-Sleep -Seconds 1 if (-not $p.HasExited) { Stop-Process -Id $p.Id -Force -ErrorAction SilentlyContinue } }