Files
opencode_gesis/Install-OpenCode-GESIS.ps1
2026-06-29 19:36:31 +02:00

170 lines
5.7 KiB
PowerShell

#Requires -Version 5.1
[CmdletBinding()]
param(
[switch]$ConfigOnly,
[switch]$SkipDesktopInstall,
[switch]$SilentDesktopInstall,
[string]$GitHubToken = $env:GITHUB_TOKEN,
[string]$ConfigPath = (Join-Path $env:USERPROFILE ".config\opencode\opencode.json")
)
$ErrorActionPreference = "Stop"
$ProgressPreference = "SilentlyContinue"
$repo = "anomalyco/opencode"
$windowsAssetName = "opencode-desktop-win-x64.exe"
$releaseApiUrl = "https://api.github.com/repos/$repo/releases/latest"
$baseUrl = "https://ai-openwebui.gesis.org/api"
function Write-Step {
param([string]$Message)
Write-Host ""
Write-Host "==> $Message" -ForegroundColor Cyan
}
function ConvertFrom-SecureStringToPlainText {
param([Parameter(Mandatory = $true)][securestring]$SecureString)
$bstr = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecureString)
try {
[Runtime.InteropServices.Marshal]::PtrToStringBSTR($bstr)
}
finally {
if ($bstr -ne [IntPtr]::Zero) {
[Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr)
}
}
}
function Invoke-GitHubGet {
param([Parameter(Mandatory = $true)][string]$Uri)
$headers = @{
"Accept" = "application/vnd.github+json"
"User-Agent" = "GESIS-OpenCode-Installer"
}
if (-not [string]::IsNullOrWhiteSpace($GitHubToken)) {
$headers["Authorization"] = "Bearer $GitHubToken"
}
Invoke-RestMethod -Uri $Uri -Headers $headers -Method Get
}
function Install-OpenCodeDesktop {
if ($SkipDesktopInstall -or $ConfigOnly) {
Write-Host "Skipping OpenCode Desktop installation."
return
}
if (-not [Environment]::Is64BitOperatingSystem) {
throw "This installer expects 64-bit Windows because OpenCode publishes a Windows x64 desktop installer."
}
Write-Step "Finding latest OpenCode Desktop release"
$release = Invoke-GitHubGet -Uri $releaseApiUrl
$asset = $release.assets | Where-Object { $_.name -eq $windowsAssetName } | Select-Object -First 1
if ($null -eq $asset) {
throw "Could not find $windowsAssetName in the latest $repo release ($($release.tag_name))."
}
Write-Host "Latest release: $($release.tag_name)"
Write-Host "Downloading: $($asset.name)"
$downloadPath = Join-Path $env:TEMP $asset.name
Invoke-WebRequest -Uri $asset.browser_download_url -OutFile $downloadPath -Headers @{ "User-Agent" = "GESIS-OpenCode-Installer" }
Write-Step "Starting OpenCode Desktop installer"
if ($SilentDesktopInstall) {
$process = Start-Process -FilePath $downloadPath -ArgumentList "/S" -Wait -PassThru
}
else {
$process = Start-Process -FilePath $downloadPath -Wait -PassThru
}
if ($process.ExitCode -ne 0) {
throw "OpenCode Desktop installer exited with code $($process.ExitCode)."
}
}
function New-GesisOpenCodeConfig {
param([Parameter(Mandatory = $true)][string]$ApiKey)
[ordered]@{
'$schema' = 'https://opencode.ai/config.json'
enabled_providers = @('gesis')
disabled_providers = @('zen', 'opencode')
provider = [ordered]@{
gesis = [ordered]@{
npm = '@ai-sdk/openai-compatible'
name = 'GESIS AI Server'
options = [ordered]@{
baseURL = $baseUrl
apiKey = $ApiKey
}
models = [ordered]@{
'gemma3:27b' = @{ name = 'Gemma 3 27B' }
'gpt-4.1' = @{ name = 'GPT-4.1' }
'gpt-4.1-mini' = @{ name = 'GPT-4.1 Mini' }
'llama4:latest' = @{ name = 'Llama 4 Latest' }
'o4-mini' = @{ name = 'O4 Mini' }
'de-fr' = @{ name = 'De-Fr Translation' }
'de-ru' = @{ name = 'De-Ru Translation' }
'en-de' = @{ name = 'En-De Translation' }
'en-fr' = @{ name = 'En-Fr Translation' }
'en-ru' = @{ name = 'En-Ru Translation' }
'pdf-extractor' = @{ name = 'PDF Extractor' }
'gpt-5' = @{ name = 'GPT-5' }
'gpt-5-mini' = @{ name = 'GPT-5 Mini' }
'gpt-oss:120b' = @{ name = 'GPT-OSS 120B' }
'gpt-oss:latest' = @{ name = 'GPT-OSS Latest' }
}
}
}
}
}
function Write-OpenCodeConfig {
Write-Step "Configuring GESIS AI Server"
$secureApiKey = Read-Host "Enter your personal GESIS AI Server API key" -AsSecureString
$apiKey = ConvertFrom-SecureStringToPlainText -SecureString $secureApiKey
if ([string]::IsNullOrWhiteSpace($apiKey)) {
throw "API key cannot be empty."
}
$configDirectory = Split-Path -Parent $ConfigPath
New-Item -Path $configDirectory -ItemType Directory -Force | Out-Null
if (Test-Path -LiteralPath $ConfigPath) {
$timestamp = Get-Date -Format "yyyyMMdd-HHmmss"
$backupPath = "$ConfigPath.backup-$timestamp"
Copy-Item -LiteralPath $ConfigPath -Destination $backupPath -Force
Write-Host "Existing config backed up to: $backupPath"
}
$config = New-GesisOpenCodeConfig -ApiKey $apiKey
$json = $config | ConvertTo-Json -Depth 20
$utf8NoBom = New-Object System.Text.UTF8Encoding($false)
[System.IO.File]::WriteAllText($ConfigPath, $json, $utf8NoBom)
Write-Host "OpenCode config written to: $ConfigPath"
}
try {
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Install-OpenCodeDesktop
Write-OpenCodeConfig
Write-Step "Done"
Write-Host "OpenCode Desktop is installed and configured for the GESIS AI Server."
}
catch {
Write-Host ""
Write-Host "Installation failed: $($_.Exception.Message)" -ForegroundColor Red
exit 1
}