$ErrorActionPreference = 'Stop' $project = Split-Path -Parent $MyInvocation.MyCommand.Path $env:SOVEREIGNAI_WORKSPACE = if ($env:SOVEREIGNAI_WORKSPACE) { $env:SOVEREIGNAI_WORKSPACE } else { $project } Write-Host "Read-only agent workspace: $env:SOVEREIGNAI_WORKSPACE" $env:GROQ_API_KEY = if ($env:GROQ_API_KEY) { $env:GROQ_API_KEY } else { [Environment]::GetEnvironmentVariable('GROQ_API_KEY', 'User') } if ($env:GROQ_API_KEY) { Write-Host 'Groq transcription: configured (key hidden)' } else { Write-Warning 'GROQ_API_KEY is not configured; local chat works, but voice transcription will return 503.' } $ollama = Invoke-RestMethod -Uri 'http://127.0.0.1:11434/api/tags' -TimeoutSec 45 $env:LOCAL_MODEL = if ($env:LOCAL_MODEL) { $env:LOCAL_MODEL } else { 'gemma4:e2b' } $model = $env:LOCAL_MODEL Write-Host "Local model: $model" if (-not ($ollama.models.name -contains $model)) { throw "Ollama is running, but model '$model' is missing. Run: ollama pull $model" } $port = if ($env:SOVEREIGNAI_API_PORT) { $env:SOVEREIGNAI_API_PORT } else { '8000' } $uvicornArgs = @( '-m', 'uvicorn', 'app.main:app', '--app-dir', $project, '--host', '127.0.0.1', '--port', $port ) $tlsCertificate = $env:SOVEREIGNAI_TLS_CERTFILE $tlsPrivateKey = $env:SOVEREIGNAI_TLS_KEYFILE if ([string]::IsNullOrWhiteSpace($tlsCertificate) -ne [string]::IsNullOrWhiteSpace($tlsPrivateKey)) { throw 'Set both SOVEREIGNAI_TLS_CERTFILE and SOVEREIGNAI_TLS_KEYFILE, or leave both empty.' } if (-not [string]::IsNullOrWhiteSpace($tlsCertificate)) { if (-not (Test-Path -LiteralPath $tlsCertificate -PathType Leaf) -or -not (Test-Path -LiteralPath $tlsPrivateKey -PathType Leaf)) { throw 'The configured TLS certificate or private-key file does not exist.' } $uvicornArgs += @('--ssl-certfile', $tlsCertificate, '--ssl-keyfile', $tlsPrivateKey) Write-Host 'Local HTTPS enabled with the configured certificate (loopback only).' } else { Write-Host 'Local HTTP enabled (loopback only).' } & (Join-Path $project '.venv\Scripts\python.exe') @uvicornArgs