[CmdletBinding()]
param()
$ErrorActionPreference = "Stop"
[System.Environment]::SetEnvironmentVariable("PYTHONUTF8", "1", "Process")
[System.Environment]::SetEnvironmentVariable("PYTHONIOENCODING", "utf-8", "Process")
[Console]::OutputEncoding = [System.Text.UTF8Encoding]::new($false)
function Write-Info {
param([string]$Message)
Write-Host $Message
}
function Remove-LinesContaining {
param(
[Parameter(Mandatory)][string]$Path,
[Parameter(Mandatory)][string]$Keyword
)
if (-not (Test-Path $Path)) {
return
}
$content = Get-Content -Path $Path -ErrorAction Stop
$updated = $content | Where-Object { $_ -notlike "*$Keyword*" }
$utf8NoBom = New-Object System.Text.UTF8Encoding($false)
[System.IO.File]::WriteAllLines($Path, $updated, $utf8NoBom)
}
function Convert-FileToUtf8NoBom {
param([Parameter(Mandatory)][string]$Path)
if (-not (Test-Path $Path)) {
return
}
$text = [System.IO.File]::ReadAllText($Path)
$utf8NoBom = New-Object System.Text.UTF8Encoding($false)
[System.IO.File]::WriteAllText($Path, $text, $utf8NoBom)
}
function Resolve-DistDir {
param([Parameter(Mandatory)][string]$ProjectDir)
$distDir = $env:DIST_DIR
if ([string]::IsNullOrWhiteSpace($distDir)) {
return (Join-Path $ProjectDir "dist")
}
if ([System.IO.Path]::IsPathRooted($distDir)) {
return $distDir
}
return (Join-Path $ProjectDir $distDir)
}
function Invoke-CheckedCommand {
param(
[Parameter(Mandatory)][string]$FilePath,
[Parameter()][string[]]$Arguments = @(),
[Parameter(Mandatory)][string]$ErrorMessage
)
& $FilePath @Arguments
if ($LASTEXITCODE -ne 0) {
throw "$ErrorMessage (exit code: $LASTEXITCODE)"
}
}
function Import-DotEnv {
param([Parameter(Mandatory)][string]$EnvFile)
if (-not (Test-Path $EnvFile)) {
throw "Environment file not found: $EnvFile"
}
Write-Info "Loading environment variables from $EnvFile"
foreach ($line in (Get-Content -Path $EnvFile -ErrorAction Stop)) {
$trimmed = $line.Trim()
if ([string]::IsNullOrWhiteSpace($trimmed) -or $trimmed.StartsWith("#")) {
continue
}
$eqIndex = $trimmed.IndexOf("=")
if ($eqIndex -le 0) {
continue
}
$key = $trimmed.Substring(0, $eqIndex).Trim()
$value = $trimmed.Substring($eqIndex + 1).Trim().Trim('"').Trim("'")
[System.Environment]::SetEnvironmentVariable($key, $value, "Process")
}
}
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$ProjectDir = Split-Path -Parent $ScriptDir
$ServerDir = Join-Path $ProjectDir "server"
$EnvFile = Join-Path $ServerDir ".env"
Import-DotEnv -EnvFile $EnvFile
$FoundationInstallTarget = "..\foundation"
if (($env:DB_TYPE ?? "").Trim().ToLower() -in @("gaussdb", "opengauss")) {
$FoundationInstallTarget = "..\foundation[gaussdb]"
Write-Info "Detected DB_TYPE=$($env:DB_TYPE); install foundation with [gaussdb] optional dependency."
}
Push-Location $ProjectDir
try {
Invoke-CheckedCommand -FilePath "git" -Arguments @("submodule", "update", "--init", "--recursive") -ErrorMessage "git submodule update --init failed"
Invoke-CheckedCommand -FilePath "git" -Arguments @("submodule", "update", "--remote", "--recursive") -ErrorMessage "git submodule update --remote failed"
Remove-LinesContaining -Path (Join-Path $ProjectDir "applications\lowcode_agent\pyproject.toml") -Keyword "openjiuwen-runtime-service"
Remove-LinesContaining -Path (Join-Path $ProjectDir "management\pyproject.toml") -Keyword "openjiuwen-runtime-foundation"
Remove-LinesContaining -Path (Join-Path $ProjectDir "server\pyproject.toml") -Keyword "openjiuwen-runtime-management"
Convert-FileToUtf8NoBom -Path (Join-Path $ProjectDir "applications\lowcode_agent\pyproject.toml")
Convert-FileToUtf8NoBom -Path (Join-Path $ProjectDir "management\pyproject.toml")
Convert-FileToUtf8NoBom -Path (Join-Path $ProjectDir "server\pyproject.toml")
$StudioBackendDir = Join-Path $ProjectDir "agent-studio\backend"
if (Test-Path $StudioBackendDir) {
Convert-FileToUtf8NoBom -Path (Join-Path $StudioBackendDir "pyproject.toml")
}
$FinalDistDir = Resolve-DistDir -ProjectDir $ProjectDir
Write-Info "Final dist dir: $FinalDistDir"
if (Test-Path $FinalDistDir) {
Remove-Item -Path $FinalDistDir -Recurse -Force -ErrorAction SilentlyContinue
}
New-Item -Path $FinalDistDir -ItemType Directory -Force | Out-Null
$UvExtraArgs = @()
if (-not [string]::IsNullOrWhiteSpace($env:UV_EXTRA_ARGS)) {
$UvExtraArgs = $env:UV_EXTRA_ARGS -split "\s+"
}
if (Test-Path $StudioBackendDir) {
Push-Location $StudioBackendDir
try {
Invoke-CheckedCommand -FilePath "uv" -Arguments (@("sync") + $UvExtraArgs) -ErrorMessage "uv sync failed in agent-studio/backend"
if (Test-Path "dist") { Remove-Item "dist" -Recurse -Force -ErrorAction SilentlyContinue }
Invoke-CheckedCommand -FilePath "uv" -Arguments (@("build", "--out-dir", $FinalDistDir) + $UvExtraArgs) -ErrorMessage "uv build failed in agent-studio/backend"
} finally { Pop-Location }
} else {
Write-Info "agent-studio/backend not found, use openjiuwen_studio from package index."
}
$AgentCoreDir = Join-Path $ProjectDir "..\agent-core"
if (Test-Path $AgentCoreDir) {
Push-Location $AgentCoreDir
try {
Invoke-CheckedCommand -FilePath "uv" -Arguments (@("sync") + $UvExtraArgs) -ErrorMessage "uv sync failed in agent-core"
if (Test-Path "dist") { Remove-Item "dist" -Recurse -Force -ErrorAction SilentlyContinue }
Invoke-CheckedCommand -FilePath "uv" -Arguments (@("build", "--out-dir", $FinalDistDir) + $UvExtraArgs) -ErrorMessage "uv build failed in agent-core"
} finally { Pop-Location }
}
Push-Location (Join-Path $ProjectDir "applications\lowcode_agent")
try {
Invoke-CheckedCommand -FilePath "uv" -Arguments (@("sync") + $UvExtraArgs) -ErrorMessage "uv sync failed in applications/lowcode_agent"
if (Test-Path "dist") { Remove-Item "dist" -Recurse -Force -ErrorAction SilentlyContinue }
Invoke-CheckedCommand -FilePath "uv" -Arguments (@("build", "--out-dir", $FinalDistDir) + $UvExtraArgs) -ErrorMessage "uv build failed in applications/lowcode_agent"
} finally { Pop-Location }
Push-Location (Join-Path $ProjectDir "service")
try {
Invoke-CheckedCommand -FilePath "uv" -Arguments (@("sync") + $UvExtraArgs) -ErrorMessage "uv sync failed in service"
if (Test-Path "dist") { Remove-Item "dist" -Recurse -Force -ErrorAction SilentlyContinue }
Invoke-CheckedCommand -FilePath "uv" -Arguments (@("build", "--out-dir", $FinalDistDir) + $UvExtraArgs) -ErrorMessage "uv build failed in service"
} finally { Pop-Location }
Push-Location $ServerDir
try {
Invoke-CheckedCommand -FilePath "uv" -Arguments (@("sync") + $UvExtraArgs) -ErrorMessage "uv sync failed in server"
$VenvPython = Join-Path $ServerDir ".venv\Scripts\python.exe"
if (-not (Test-Path $VenvPython)) {
throw "Runtime python not found: $VenvPython"
}
Invoke-CheckedCommand -FilePath "uv" -Arguments (@("pip", "install", "-e", "..\management") + $UvExtraArgs) -ErrorMessage "uv pip install management failed"
Invoke-CheckedCommand -FilePath "uv" -Arguments (@("pip", "install", "-e", $FoundationInstallTarget) + $UvExtraArgs) -ErrorMessage "uv pip install foundation failed"
& $VenvPython -m openjiuwen_runtime.server.main
if ($LASTEXITCODE -ne 0) {
throw "Runtime server exited with non-zero code: $LASTEXITCODE"
}
} finally { Pop-Location }
} finally {
Pop-Location
}