From f531e8e2efb8302ebac01288f3ca8f2beb82b0b0 Mon Sep 17 00:00:00 2001 From: luckyyzh Date: Mon, 3 Aug 2026 17:10:30 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20pi-agent-public.ps1=20=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E6=A0=B9=E4=B8=8A=E4=B8=A4=E7=BA=A7=E5=AE=9A=E4=BD=8D=20+=20?= =?UTF-8?q?=E8=87=AA=E5=8A=A0=E8=BD=BD=20.env=EF=BC=88=E7=8B=AC=E7=AB=8B?= =?UTF-8?q?=E8=BF=9B=E7=A8=8B=E4=B8=8D=E8=AF=BB=20env=EF=BC=89+=20?= =?UTF-8?q?=E8=AE=A1=E5=88=92=E4=BB=BB=E5=8A=A1=E8=87=AA=E5=8A=A8=E6=B3=A8?= =?UTF-8?q?=E5=86=8C=EF=BC=88Web=20=E5=BF=85=E9=9C=80/Tunnel=20=E6=8C=89?= =?UTF-8?q?=20PI=5FAGENT=5FTUNNEL=5FCOMMAND=EF=BC=89+=20ps1=20=E5=8A=A0=20?= =?UTF-8?q?BOM=20=E4=BF=9D=E4=B8=AD=E6=96=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 5 ++ data/local-tools/pi-agent-public.ps1 | 58 +++++++++++++++++++- data/local-tools/pi-agent-web-supervisor.ps1 | 2 +- 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/.env.example b/.env.example index b133765..d9f0e94 100644 --- a/.env.example +++ b/.env.example @@ -8,6 +8,11 @@ SEARXNG_TOKEN= # Optional public URL reported by pi-agent-public.ps1 (e.g. your own tunnel domain). PI_AGENT_PUBLIC_URL= +# Optional SSH reverse-tunnel command for public access, run as a scheduled task +# by pi-agent-public.ps1 (registered only when set). Example for an "aliyun" host +# in ~/.ssh/config forwarding remote 8090 to local 30141: +# PI_AGENT_TUNNEL_COMMAND=C:\WINDOWS\System32\OpenSSH\ssh.exe -n -N -T -o BatchMode=yes -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -R 127.0.0.1:8090:127.0.0.1:30141 aliyun + # Optional higher Context7 quota. Context7 also works at its public unauthenticated limit. CONTEXT7_API_KEY= diff --git a/data/local-tools/pi-agent-public.ps1 b/data/local-tools/pi-agent-public.ps1 index 1083194..445baa6 100644 --- a/data/local-tools/pi-agent-public.ps1 +++ b/data/local-tools/pi-agent-public.ps1 @@ -1,4 +1,4 @@ -[CmdletBinding()] +[CmdletBinding()] param( [ValidateSet('status', 'start', 'restart', 'stop')] [string]$Action = 'status' @@ -8,12 +8,65 @@ $ErrorActionPreference = 'Stop' $webTaskName = 'PiAgentIntegratedWeb' $tunnelTaskName = 'PiAgentIntegratedTunnel' $localUrl = 'http://127.0.0.1:30141/' +# local-tools 位于 data/ 下,上两级才是项目根 +$projectRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot) + +# 加载项目 .env(独立运行的脚本不会自动加载,需手动解析) +$envFile = Join-Path $projectRoot '.env' +if (Test-Path $envFile) { + Get-Content $envFile -Encoding UTF8 | ForEach-Object { + if ($_ -match '^\s*([A-Za-z_][A-Za-z0-9_]*)=(.*)$') { + $envName = $matches[1] + $envValue = $matches[2].Trim() + if (-not [string]::IsNullOrWhiteSpace($envValue) -and -not [Environment]::GetEnvironmentVariable($envName, 'Process')) { + Set-Item -Path "Env:$envName" -Value $envValue + } + } + } +} + +# 隧道命令从环境变量读取(.env 中设置 PI_AGENT_TUNNEL_COMMAND),例如: +# C:\WINDOWS\System32\OpenSSH\ssh.exe -n -N -T -o BatchMode=yes -R 127.0.0.1:8090:127.0.0.1:30141 aliyun +$tunnelCommand = $env:PI_AGENT_TUNNEL_COMMAND # 公网地址从环境变量读取(.env 中设置 PI_AGENT_PUBLIC_URL),不在代码里写死个人域名 $publicUrl = $env:PI_AGENT_PUBLIC_URL if ([string]::IsNullOrWhiteSpace($publicUrl)) { $publicUrl = '(未配置 PI_AGENT_PUBLIC_URL)' } +function Ensure-Tasks { + # Web supervisor 任务:必需,自动注册(相对路径,新机器可直接用) + if (-not (Get-ScheduledTask -TaskName $webTaskName -ErrorAction SilentlyContinue)) { + Write-Host " 注册计划任务 $webTaskName ..." + $supervisorPath = Join-Path $PSScriptRoot 'pi-agent-web-supervisor.ps1' + $action = New-ScheduledTaskAction -Execute 'powershell.exe' ` + -Argument "-NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File `\"$supervisorPath`\"" ` + -WorkingDirectory $projectRoot + $trigger = New-ScheduledTaskTrigger -AtLogOn + $settings = New-ScheduledTaskSettingsSet -StartWhenAvailable ` + -RestartCount 999 -RestartInterval (New-TimeSpan -Minutes 1) ` + -ExecutionTimeLimit ([TimeSpan]::Zero) + Register-ScheduledTask -TaskName $webTaskName -Action $action -Trigger $trigger ` + -Settings $settings -Description 'Pi Agent Integrated Web supervisor' -Force | Out-Null + } + + # Tunnel 任务:可选,仅在配置了 PI_AGENT_TUNNEL_COMMAND 时注册 + if (Get-ScheduledTask -TaskName $tunnelTaskName -ErrorAction SilentlyContinue) { return } + if ([string]::IsNullOrWhiteSpace($tunnelCommand)) { + Write-Host " - 未配置 PI_AGENT_TUNNEL_COMMAND,跳过隧道任务" + return + } + Write-Host " 注册计划任务 $tunnelTaskName ..." + $parts = $tunnelCommand.Trim() -split '\s+', 2 + $action = New-ScheduledTaskAction -Execute $parts[0] -Argument $parts[1] + $trigger = New-ScheduledTaskTrigger -AtLogOn + $settings = New-ScheduledTaskSettingsSet -StartWhenAvailable ` + -RestartCount 999 -RestartInterval (New-TimeSpan -Minutes 1) ` + -ExecutionTimeLimit ([TimeSpan]::Zero) + Register-ScheduledTask -TaskName $tunnelTaskName -Action $action -Trigger $trigger ` + -Settings $settings -Description 'Pi Agent Integrated public tunnel' -Force | Out-Null +} + function Get-PublicAccessStatus { $webTask = Get-ScheduledTask -TaskName $webTaskName -ErrorAction SilentlyContinue $tunnelTask = Get-ScheduledTask -TaskName $tunnelTaskName -ErrorAction SilentlyContinue @@ -44,7 +97,8 @@ switch ($Action) { Get-PublicAccessStatus } 'start' { - Start-ScheduledTask -TaskName $tunnelTaskName + Ensure-Tasks + Start-ScheduledTask -TaskName $tunnelTaskName -ErrorAction SilentlyContinue Start-ScheduledTask -TaskName $webTaskName Start-Sleep -Seconds 3 Get-PublicAccessStatus diff --git a/data/local-tools/pi-agent-web-supervisor.ps1 b/data/local-tools/pi-agent-web-supervisor.ps1 index c7db677..6a8b133 100644 --- a/data/local-tools/pi-agent-web-supervisor.ps1 +++ b/data/local-tools/pi-agent-web-supervisor.ps1 @@ -1,4 +1,4 @@ -[CmdletBinding()] +[CmdletBinding()] param() $ErrorActionPreference = 'Stop'