feat: add Chinese UI, Responses models, and mirrored Windows setup
CI / Python 3.12 / ubuntu-latest (push) Canceled after 0s
CI / Python 3.12 / windows-latest (push) Canceled after 0s
CI / Frontend tests and production build (push) Canceled after 0s
CI / Build and smoke-test Python packages (push) Canceled after 0s

Localize the web console and persist custom model and capability settings.
Use OpenAI Responses exclusively and move runtime limits into environment configuration.
Bootstrap uv and the virtual environment on Windows, support optional China mirrors,
and package source distributions without environments, build output, or credentials.

Update regression tests and repository quality checks for the new behavior.
This commit is contained in:
chenmingxuan committed 2026-09-22 19:16:17 +08:00
1 parent 371aa6df56
commit 2ddec53954
183 files changed
+3427 -11857

No files matched your search

+57 -51
View File
@@ -15,7 +15,9 @@
[CmdletBinding()]
param(
[int]$Port = 8000,
[switch]$NoOpen = $false
[switch]$NoOpen = $false,
[switch]$SetupOnly = $false,
[ValidateSet('Official', 'China')][string]$Mirror
)
$ErrorActionPreference = "Continue"
@@ -30,6 +32,14 @@ $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition
$RootDir = Split-Path -Parent $ScriptDir
Set-Location $RootDir
. (Join-Path $ScriptDir 'download_config.ps1')
try {
Initialize-ArtemisDownloads -ProjectRoot $RootDir -Mode $Mirror
} catch {
Write-Host " [ERROR] Invalid download settings: $_" -ForegroundColor Red
exit 1
}
Write-Host "======================================================" -ForegroundColor Cyan
Write-Host " Artemis Autonomous Mobile Agent UI " -ForegroundColor Cyan
Write-Host "======================================================" -ForegroundColor Cyan
@@ -105,7 +115,7 @@ function Invoke-DownloadFile {
param(
[Parameter(Mandatory=$true)][string]$Uri,
[Parameter(Mandatory=$true)][string]$OutFile,
[int]$TimeoutSec = 45
[int]$TimeoutSec = $ArtemisDownloads.timeout_seconds
)
if (Test-Path $OutFile) {
Remove-Item -Path $OutFile -Force -ErrorAction SilentlyContinue
@@ -152,7 +162,7 @@ function Install-PortablePlatformTools {
Write-Host " [INFO] Installing Android platform-tools (adb) in user space..." -ForegroundColor Cyan
try {
$zipPath = "$env:TEMP\platform-tools-windows.zip"
if (Invoke-DownloadFile -Uri "https://dl.google.com/android/repository/platform-tools-latest-windows.zip" -OutFile $zipPath -TimeoutSec 60) {
if (Invoke-DownloadFile -Uri $ArtemisDownloads.adb_url -OutFile $zipPath) {
New-Item -ItemType Directory -Path "$env:LOCALAPPDATA\Programs" -Force | Out-Null
Expand-Archive -Path $zipPath -DestinationPath "$env:LOCALAPPDATA\Programs" -Force
Remove-Item $zipPath -Force -ErrorAction SilentlyContinue
@@ -186,9 +196,12 @@ function Install-PortableScrcpy {
}
Write-Host " [INFO] Installing portable scrcpy in user space..." -ForegroundColor Cyan
if ($ArtemisDownloads.mode -eq 'China' -and $ArtemisDownloads.scrcpy_url.StartsWith('https://github.com/')) {
Write-Host ' [INFO] scrcpy uses GitHub. If unreachable, set overrides.scrcpy_url in config/downloads.json.' -ForegroundColor Yellow
}
try {
$zipPath = "$env:TEMP\scrcpy-win64.zip"
if (Invoke-DownloadFile -Uri "https://github.com/Genymobile/scrcpy/releases/download/v4.1/scrcpy-win64-v4.1.zip" -OutFile $zipPath -TimeoutSec 60) {
if (Invoke-DownloadFile -Uri $ArtemisDownloads.scrcpy_url -OutFile $zipPath) {
$extractDir = "$env:TEMP\scrcpy_extract"
if (Test-Path $extractDir) { Remove-Item $extractDir -Recurse -Force -ErrorAction SilentlyContinue }
New-Item -ItemType Directory -Path $extractDir -Force | Out-Null
@@ -262,7 +275,8 @@ function Install-PortableNode {
if ($env:PROCESSOR_ARCHITECTURE -match "ARM64") { "arm64" } else { "x64" }
} else { "x64" }
$zipPath = "$env:TEMP\node-$nodeVer-win-$arch.zip"
if (Invoke-DownloadFile -Uri "https://nodejs.org/dist/$nodeVer/node-$nodeVer-win-$arch.zip" -OutFile $zipPath -TimeoutSec 60) {
$nodeBase = $ArtemisDownloads.node_mirror.TrimEnd('/')
if (Invoke-DownloadFile -Uri "$nodeBase/$nodeVer/node-$nodeVer-win-$arch.zip" -OutFile $zipPath) {
$extractDir = "$env:TEMP\node_extract"
if (Test-Path $extractDir) { Remove-Item $extractDir -Recurse -Force -ErrorAction SilentlyContinue }
New-Item -ItemType Directory -Path $extractDir -Force | Out-Null
@@ -291,33 +305,39 @@ function Install-PortableNode {
# 1. Refresh PATH with standard toolchain paths
Update-EnvironmentPath
# 2. Check or install uv
if (-not (Test-CommandExists "uv")) {
Write-Host " [INFO] uv not found. Installing Astral uv..." -ForegroundColor Yellow
try {
Invoke-Expression (Invoke-RestMethod -Uri "https://astral.sh/uv/install.ps1")
} catch {
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
}
Update-EnvironmentPath
# 2. Prepare the project Python environment before optional device/UI setup.
. (Join-Path $ScriptDir 'bootstrap_python.ps1')
try {
$ArtemisPython = Initialize-ArtemisPython -ProjectRoot $RootDir
} catch {
Write-Host " [ERROR] $_" -ForegroundColor Red
exit 1
}
if (-not (Test-CommandExists "uv")) {
Write-Host " [ERROR] Astral 'uv' package manager could not be installed or found in PATH." -ForegroundColor Red
Write-Host " Please install uv manually from https://astral.sh/ or run:" -ForegroundColor Yellow
Write-Host " powershell -c ""irm https://astral.sh/uv/install.ps1 | iex""" -ForegroundColor Cyan
exit 1
if (-not (Test-Path -LiteralPath (Join-Path $RootDir '.env'))) {
if (Test-Path -LiteralPath (Join-Path $RootDir '.env.example')) {
Copy-Item -LiteralPath (Join-Path $RootDir '.env.example') -Destination (Join-Path $RootDir '.env') -ErrorAction Stop
Write-Host ' [OK] Created .env from .env.example. Configure your model in the web UI.' -ForegroundColor Green
}
}
if ($SetupOnly) {
Write-Host ' [OK] Setup complete. Run start.bat to launch Artemis.' -ForegroundColor Green
exit 0
}
# 3. Check and try installing missing system toolchains (ADB, FFmpeg, scrcpy)
$missingCore = @()
if (-not (Test-CommandExists "adb")) { $missingCore += "adb" }
if (-not (Test-CommandExists "ffmpeg")) { $missingCore += "ffmpeg" }
# imageio-ffmpeg ships a working executable in its wheel, including mirror installs.
if (-not (Test-CommandExists "ffmpeg")) {
& $ArtemisPython -c 'import imageio_ffmpeg; imageio_ffmpeg.get_ffmpeg_exe()' 2>$null | Out-Null
if ($LASTEXITCODE -ne 0) { $missingCore += "ffmpeg" }
}
if (-not (Test-CommandExists "scrcpy")) { $missingCore += "scrcpy" }
if ($missingCore.Count -gt 0) {
$useWinGet = $false
if (Test-CommandExists "winget") {
if ($ArtemisDownloads.mode -ne 'China' -and (Test-CommandExists "winget")) {
if ([Console]::IsInputRedirected -eq $false) {
Write-Host " [INFO] Missing components detected: $($missingCore -join ', ')." -ForegroundColor Cyan
$ans = Read-Host " Install system packages via WinGet? [Y/n]"
@@ -348,27 +368,15 @@ if ($missingCore.Count -gt 0) {
Install-PortablePlatformTools
}
if (-not (Test-CommandExists "scrcpy")) {
Install-PortableScrcpy
if (-not (Install-PortableScrcpy)) {
Write-Host ' [WARN] scrcpy download failed. Set overrides.scrcpy_url in config/downloads.json to a reachable release ZIP, then retry.' -ForegroundColor Yellow
}
}
}
# Ensure local ADB daemon is warm & listening so probes do not hit 'Connection refused'
Start-LocalAdbServer
# 4. Check or initialize .env
if (-not (Test-Path ".env")) {
if (Test-Path ".env.example") {
Copy-Item ".env.example" ".env"
Write-Host " [OK] Initialized .env configuration file." -ForegroundColor Green
} else {
New-Item -ItemType File -Path ".env" | Out-Null
}
}
# 5. Synchronize dependencies
Write-Host " [INFO] Synchronizing Python runtime and project dependencies..." -ForegroundColor Cyan
uv sync --quiet
# 6. Check and build Showcase UI if not already compiled
$ShowcaseIndex = "$RootDir\apps\showcase_ui\dist\frontend\browser\index.html"
$ShowcaseIndexAlt1 = "$RootDir\apps\showcase_ui\dist\browser\index.html"
@@ -383,7 +391,7 @@ if ((-not (Test-Path $ShowcaseIndex)) -and (-not (Test-Path $ShowcaseIndexAlt1))
}
# 1. Try nvm if available on Windows
if (Test-CommandExists "nvm") {
if ($ArtemisDownloads.mode -ne 'China' -and (Test-CommandExists "nvm")) {
Write-Host " [INFO] Installing Node.js 22 LTS via nvm..." -ForegroundColor Cyan
& nvm install 22.23.2 | Out-Null
& nvm use 22.23.2 | Out-Null
@@ -393,7 +401,7 @@ if ((-not (Test-Path $ShowcaseIndex)) -and (-not (Test-Path $ShowcaseIndexAlt1))
# 2. Try WinGet
if (-not (Test-NodeCompatible)) {
$useWinGetNode = $false
if (Test-CommandExists "winget") {
if ($ArtemisDownloads.mode -ne 'China' -and (Test-CommandExists "winget")) {
if ([Console]::IsInputRedirected -eq $false) {
Write-Host " [INFO] Node.js >= v22.22.0 required for Showcase UI." -ForegroundColor Cyan
$ans = Read-Host " Install/Upgrade Node.js via WinGet (may require Administrator)? [Y/n]"
@@ -426,31 +434,29 @@ if ((-not (Test-Path $ShowcaseIndex)) -and (-not (Test-Path $ShowcaseIndexAlt1))
try {
$npmExec = if (Test-CommandExists "npm.cmd") { "npm.cmd" } else { "npm" }
Write-Host " [INFO] Installing frontend npm dependencies..." -ForegroundColor Cyan
& $npmExec install --no-audit --no-fund --loglevel=error
& $npmExec ci --no-audit --no-fund --loglevel=error
if ($LASTEXITCODE -ne 0) {
Write-Host " [WARN] npm install returned exit code $LASTEXITCODE. Trying silent install..." -ForegroundColor DarkYellow
& $npmExec install --silent
}
$cliNodeVersion = "$RootDir\apps\showcase_ui\node_modules\@angular\cli\src\utilities\node-version.js"
if (Test-Path $cliNodeVersion) {
(Get-Content $cliNodeVersion) -replace '22\.22\.3', '22.22.0' | Set-Content $cliNodeVersion
throw "npm ci failed (exit $LASTEXITCODE). Check the network and retry."
}
Write-Host " [INFO] Building Angular frontend application..." -ForegroundColor Cyan
& $npmExec run build
if ($LASTEXITCODE -ne 0) { throw "Frontend build failed (exit $LASTEXITCODE)." }
if (Test-Path $ShowcaseIndex) {
Write-Host " [OK] Showcase UI compiled successfully." -ForegroundColor Green
} elseif (Test-Path $ShowcaseIndexAlt1) {
Write-Host " [OK] Showcase UI compiled successfully." -ForegroundColor Green
} else {
Write-Host " [WARN] Showcase UI build finished but index.html was not found in expected dist directory." -ForegroundColor DarkYellow
throw 'Frontend build did not produce index.html.'
}
} catch {
Write-Host " [WARN] Failed to build Showcase UI: $_" -ForegroundColor DarkYellow
Write-Host " [ERROR] Failed to build Showcase UI: $_" -ForegroundColor Red
exit 1
} finally {
Pop-Location
}
} else {
Write-Host " [WARN] Node.js >= v22.22.0 not found. Showcase UI will show fallback notice on launch." -ForegroundColor DarkYellow
Write-Host " [ERROR] A compatible Node.js/npm could not be installed. Install Node.js LTS and retry." -ForegroundColor Red
exit 1
}
}
@@ -470,7 +476,7 @@ if ([Console]::IsInputRedirected -eq $false) {
if ($installMcp -match "^[Yy]") {
Write-Host " Installing MCP server configuration & testing rules..." -ForegroundColor Cyan
uv run python -m artemis mcp --install all
& $ArtemisPython -m artemis mcp --install all
if ($LASTEXITCODE -eq 0) {
Write-Host " [OK] MCP configuration and rules installed successfully." -ForegroundColor Green
Write-Host " [TIP] You can update or re-install anytime with: uv run artemis mcp --install all" -ForegroundColor Cyan
@@ -490,9 +496,9 @@ Start-LocalAdbServer
# long-running server never locks .venv\Scripts\artemis.exe against `uv sync` reinstalls.
Write-Host " [INFO] Launching Artemis Showcase UI & Admin Console..." -ForegroundColor Green
if ($NoOpen) {
uv run python -m artemis ui --port $Port --no-open
& $ArtemisPython -m artemis ui --port $Port --no-open
} else {
uv run python -m artemis ui --port $Port --open
& $ArtemisPython -m artemis ui --port $Port --open
}
if ($LASTEXITCODE -ne 0) {