From 295b697407154f0a0bf91d85849b02b2dd4d8918 Mon Sep 17 00:00:00 2001 From: ChangxuHan Date: Thu, 16 Jul 2026 02:11:40 +0800 Subject: [PATCH] chore: add loopback ReMe deployment --- local-deploy/Start-ReMe.ps1 | 68 ++++++++++++++++++++++++++++++++++++ local-deploy/Stop-ReMe.ps1 | 32 +++++++++++++++++ local-deploy/Test-ReMe.ps1 | 56 +++++++++++++++++++++++++++++ local-deploy/deployment.json | 10 ++++++ 4 files changed, 166 insertions(+) create mode 100644 local-deploy/Start-ReMe.ps1 create mode 100644 local-deploy/Stop-ReMe.ps1 create mode 100644 local-deploy/Test-ReMe.ps1 create mode 100644 local-deploy/deployment.json diff --git a/local-deploy/Start-ReMe.ps1 b/local-deploy/Start-ReMe.ps1 new file mode 100644 index 00000000..d5d7c1c5 --- /dev/null +++ b/local-deploy/Start-ReMe.ps1 @@ -0,0 +1,68 @@ +[CmdletBinding()] +param() + +$ErrorActionPreference = 'Stop' + +$ReMeRoot = 'D:\projects\reme' +$DataRoot = 'D:\projects\reme-data' +$Executable = Join-Path $ReMeRoot '.venv\Scripts\reme.exe' +$LogRoot = Join-Path $ReMeRoot 'local-deploy\logs' +$PidFile = Join-Path $LogRoot 'reme.pid' +$Port = 2333 + +if (-not (Test-Path -LiteralPath $Executable)) { + throw "ReMe executable not found: $Executable" +} + +$listeners = @(Get-NetTCPConnection -State Listen -LocalPort $Port -ErrorAction SilentlyContinue) +if ($listeners.Count -gt 0) { + $owners = $listeners | Select-Object -ExpandProperty OwningProcess -Unique + foreach ($owner in $owners) { + $process = Get-CimInstance Win32_Process -Filter "ProcessId = $owner" + if ($process.CommandLine -like "*$ReMeRoot*" -and $process.CommandLine -match '\bstart\b') { + Write-Output "ReMe is already running on 127.0.0.1:$Port (PID $owner)." + exit 0 + } + } + throw "Port $Port is already owned by another process." +} + +New-Item -ItemType Directory -Force -Path $DataRoot, $LogRoot | Out-Null + +# Keep optional model-backed jobs unavailable in this deployment process. +foreach ($name in @('LLM_API_KEY', 'EMBEDDING_API_KEY', 'CLAUDE_CODE_API_KEY')) { + Remove-Item -LiteralPath "Env:$name" -ErrorAction SilentlyContinue +} +$env:NO_PROXY = '127.0.0.1,localhost,::1' +$env:PYTHONUTF8 = '1' +$env:PYTHONIOENCODING = 'utf-8' + +$arguments = @( + 'start' + "workspace_dir=$DataRoot" + 'service.host=127.0.0.1' + "service.port=$Port" +) + +$process = Start-Process ` + -FilePath $Executable ` + -ArgumentList $arguments ` + -WorkingDirectory $ReMeRoot ` + -WindowStyle Hidden ` + -RedirectStandardOutput (Join-Path $LogRoot 'reme.out.log') ` + -RedirectStandardError (Join-Path $LogRoot 'reme.err.log') ` + -PassThru + +Set-Content -LiteralPath $PidFile -Value $process.Id -Encoding ascii +Start-Sleep -Milliseconds 750 +if ($process.HasExited) { + $errorLog = Join-Path $LogRoot 'reme.err.log' + $details = if (Test-Path -LiteralPath $errorLog) { + (Get-Content -LiteralPath $errorLog -Tail 20 -Encoding UTF8) -join [Environment]::NewLine + } else { + 'No error log was produced.' + } + throw "ReMe exited during startup.$([Environment]::NewLine)$details" +} + +Write-Output "Started ReMe on 127.0.0.1:$Port (PID $($process.Id))." diff --git a/local-deploy/Stop-ReMe.ps1 b/local-deploy/Stop-ReMe.ps1 new file mode 100644 index 00000000..4a091ed0 --- /dev/null +++ b/local-deploy/Stop-ReMe.ps1 @@ -0,0 +1,32 @@ +[CmdletBinding()] +param() + +$ErrorActionPreference = 'Stop' + +$ReMeRoot = 'D:\projects\reme' +$LogRoot = Join-Path $ReMeRoot 'local-deploy\logs' +$PidFile = Join-Path $LogRoot 'reme.pid' +$Port = 2333 +$listeners = @(Get-NetTCPConnection -State Listen -LocalPort $Port -ErrorAction SilentlyContinue) + +if ($listeners.Count -eq 0) { + Write-Output "No listener is running on port $Port." + exit 0 +} + +$owners = $listeners | Select-Object -ExpandProperty OwningProcess -Unique +foreach ($owner in $owners) { + $process = Get-CimInstance Win32_Process -Filter "ProcessId = $owner" + if ($null -eq $process) { + continue + } + if ($process.CommandLine -notlike "*$ReMeRoot*" -or $process.CommandLine -notmatch '\bstart\b') { + throw "Refusing to stop PID $owner because it is not the local ReMe service." + } + Stop-Process -Id $owner -Force + Write-Output "Stopped ReMe process $owner." +} + +if (Test-Path -LiteralPath $PidFile) { + Remove-Item -LiteralPath $PidFile -Force +} diff --git a/local-deploy/Test-ReMe.ps1 b/local-deploy/Test-ReMe.ps1 new file mode 100644 index 00000000..9d09ab53 --- /dev/null +++ b/local-deploy/Test-ReMe.ps1 @@ -0,0 +1,56 @@ +[CmdletBinding()] +param( + [ValidateRange(1, 600)] + [int]$TimeoutSeconds = 120 +) + +$ErrorActionPreference = 'Stop' + +$ReMeRoot = 'D:\projects\reme' +$Executable = Join-Path $ReMeRoot '.venv\Scripts\reme.exe' +$Port = 2333 +$Uri = "http://127.0.0.1:$Port/version" +$env:NO_PROXY = '127.0.0.1,localhost,::1' +$env:PYTHONUTF8 = '1' +$env:PYTHONIOENCODING = 'utf-8' +$deadline = [DateTime]::UtcNow.AddSeconds($TimeoutSeconds) +$version = $null + +do { + try { + $version = Invoke-RestMethod -Method Post -Uri $Uri -ContentType 'application/json' -Body '{}' + break + } catch { + if ([DateTime]::UtcNow -ge $deadline) { + throw "ReMe did not become ready within $TimeoutSeconds seconds: $($_.Exception.Message)" + } + Start-Sleep -Milliseconds 500 + } +} while ($true) + +$listeners = @(Get-NetTCPConnection -State Listen -LocalPort $Port -ErrorAction Stop) +$invalid = @($listeners | Where-Object { $_.LocalAddress -ne '127.0.0.1' }) +if ($invalid.Count -gt 0) { + $addresses = ($invalid | Select-Object -ExpandProperty LocalAddress -Unique) -join ', ' + throw "ReMe is listening outside loopback: $addresses" +} + +$owners = $listeners | Select-Object -ExpandProperty OwningProcess -Unique +foreach ($owner in $owners) { + $process = Get-CimInstance Win32_Process -Filter "ProcessId = $owner" + if ($null -eq $process -or $process.CommandLine -notlike "*$ReMeRoot*") { + throw "Port $Port is not owned by the expected ReMe deployment." + } +} + +$health = & $Executable health_check 2>&1 +if ($LASTEXITCODE -ne 0) { + throw "ReMe health_check failed: $($health -join [Environment]::NewLine)" +} + +[pscustomobject]@{ + Address = "127.0.0.1:$Port" + Version = $version + ListenerPids = @($owners) + HealthCheck = ($health -join [Environment]::NewLine) +} diff --git a/local-deploy/deployment.json b/local-deploy/deployment.json new file mode 100644 index 00000000..7f9615f4 --- /dev/null +++ b/local-deploy/deployment.json @@ -0,0 +1,10 @@ +{ + "upstream": "https://github.com/agentscope-ai/ReMe", + "commit": "c3b1e9391840537e769c32985f1ae4c6523be87b", + "remeVersion": "0.4.1.1", + "pythonVersion": "3.13.0", + "serviceAddress": "http://127.0.0.1:2333", + "workspace": "D:\\projects\\reme-data", + "llmFeatures": "disabled-no-credentials", + "verifiedAtUtc": "2026-07-15T18:05:38.8732886Z" +}