更新了langgraph-plan-view,支持windows下使用 langgraph cli;更新了langgraph-vivado-install,要求安装langgraph cli,确定conda环境的名称为langgraph
This commit is contained in:
@@ -0,0 +1,193 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Manage the langgraph dev server on Windows.
|
||||
.DESCRIPTION
|
||||
Start, stop, or check the status of the langgraph dev server.
|
||||
The server starts from the skill root (where langgraph.json lives) so the
|
||||
graph module is discovered correctly.
|
||||
.PARAMETER Command
|
||||
start | stop | status
|
||||
.EXAMPLE
|
||||
manage_dev_server.ps1 start # idempotent — safe to call if already running
|
||||
manage_dev_server.ps1 stop # call once workflow returns {"status":"done"}
|
||||
manage_dev_server.ps1 status # print running/stopped + Studio URL
|
||||
#>
|
||||
param([string]$Command = "status")
|
||||
|
||||
$SkillDir = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path
|
||||
$PidFile = Join-Path $env:TEMP "langgraph_dev_server.pid"
|
||||
$StdoutLog = Join-Path $env:TEMP "langgraph_dev_server.stdout.log"
|
||||
$StderrLog = Join-Path $env:TEMP "langgraph_dev_server.stderr.log"
|
||||
$ApiUrl = "http://127.0.0.1:2024"
|
||||
$MaxWait = 45 # seconds to wait for the server to become ready
|
||||
|
||||
# --- helpers -----------------------------------------------------------
|
||||
|
||||
function Test-HttpOk([string]$Url) {
|
||||
try {
|
||||
$r = Invoke-WebRequest -Uri $Url -UseBasicParsing -TimeoutSec 3 -ErrorAction Stop
|
||||
return ($r.StatusCode -ge 200 -and $r.StatusCode -lt 300)
|
||||
} catch {
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
function Get-StoredPid {
|
||||
if (-not (Test-Path $PidFile)) { return 0 }
|
||||
$raw = (Get-Content $PidFile -Raw -ErrorAction SilentlyContinue).Trim()
|
||||
if (-not $raw) { return 0 }
|
||||
[int]$raw
|
||||
}
|
||||
|
||||
function Test-ServerRunning {
|
||||
$pid = Get-StoredPid
|
||||
if ($pid -eq 0) { return $false }
|
||||
$proc = Get-Process -Id $pid -ErrorAction SilentlyContinue
|
||||
if (-not $proc) { return $false }
|
||||
return (Test-HttpOk "$ApiUrl/ok")
|
||||
}
|
||||
|
||||
function Find-LangGraphExe {
|
||||
$up = $env:USERPROFILE
|
||||
$candidates = @(
|
||||
"$up\.conda\envs\langgraph\Scripts\langgraph.exe",
|
||||
"$up\miniconda3\envs\langgraph\Scripts\langgraph.exe",
|
||||
"$up\anaconda3\envs\langgraph\Scripts\langgraph.exe",
|
||||
"$up\miniforge3\envs\langgraph\Scripts\langgraph.exe",
|
||||
"$up\AppData\Local\miniconda3\envs\langgraph\Scripts\langgraph.exe",
|
||||
"C:\ProgramData\miniconda3\envs\langgraph\Scripts\langgraph.exe",
|
||||
"C:\ProgramData\anaconda3\envs\langgraph\Scripts\langgraph.exe"
|
||||
)
|
||||
foreach ($c in $candidates) {
|
||||
if (Test-Path $c) { return $c }
|
||||
}
|
||||
# Try PATH
|
||||
$cmd = Get-Command langgraph -ErrorAction SilentlyContinue
|
||||
if ($cmd) { return $cmd.Source }
|
||||
# Try resolving via conda
|
||||
$condaCandidates = @($env:CONDA_EXE, "C:\ProgramData\miniconda3\Scripts\conda.exe",
|
||||
"$up\AppData\Local\miniconda3\Scripts\conda.exe")
|
||||
foreach ($conda in $condaCandidates) {
|
||||
if ($conda -and (Test-Path $conda)) {
|
||||
try {
|
||||
$lgPath = (& $conda run -n langgraph python -c "import shutil; print(shutil.which('langgraph') or '')" 2>$null).Trim()
|
||||
if ($lgPath -and (Test-Path $lgPath)) { return $lgPath }
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
throw ("Cannot find langgraph.exe in the 'langgraph' conda env. " +
|
||||
"Install it: conda run -n langgraph pip install 'langgraph-cli[inmem]'")
|
||||
}
|
||||
|
||||
function Stop-ServerProcess([int]$PidValue) {
|
||||
$stopped = $false
|
||||
if ($PidValue -gt 0) {
|
||||
$proc = Get-Process -Id $PidValue -ErrorAction SilentlyContinue
|
||||
if ($proc) {
|
||||
Stop-Process -Id $PidValue -Force -ErrorAction SilentlyContinue
|
||||
$stopped = $true
|
||||
}
|
||||
}
|
||||
# Fallback: kill whoever is listening on port 2024
|
||||
if (-not $stopped) {
|
||||
$conn = Get-NetTCPConnection -LocalPort 2024 -State Listen -ErrorAction SilentlyContinue |
|
||||
Select-Object -First 1
|
||||
if ($conn) {
|
||||
Stop-Process -Id $conn.OwningProcess -Force -ErrorAction SilentlyContinue
|
||||
Write-Host "[dev-server] Stopped process on port 2024 (PID $($conn.OwningProcess))"
|
||||
$stopped = $true
|
||||
}
|
||||
}
|
||||
return $stopped
|
||||
}
|
||||
|
||||
# --- command dispatch ---------------------------------------------------
|
||||
|
||||
switch ($Command) {
|
||||
|
||||
"start" {
|
||||
if (Test-ServerRunning) {
|
||||
$pid = Get-StoredPid
|
||||
Write-Host "[dev-server] Already running (PID $pid) at $ApiUrl"
|
||||
Write-Host "[dev-server] Studio: https://smith.langchain.com/studio/?baseUrl=$ApiUrl"
|
||||
exit 0
|
||||
}
|
||||
|
||||
$lgExe = Find-LangGraphExe
|
||||
Write-Host "[dev-server] Starting langgraph dev server..."
|
||||
Write-Host "[dev-server] exe: $lgExe"
|
||||
Write-Host "[dev-server] dir: $SkillDir"
|
||||
|
||||
# Remove stale logs
|
||||
Remove-Item $StdoutLog -ErrorAction SilentlyContinue
|
||||
Remove-Item $StderrLog -ErrorAction SilentlyContinue
|
||||
|
||||
$proc = Start-Process -FilePath $lgExe `
|
||||
-ArgumentList "dev", "--no-browser" `
|
||||
-WorkingDirectory $SkillDir `
|
||||
-RedirectStandardOutput $StdoutLog `
|
||||
-RedirectStandardError $StderrLog `
|
||||
-WindowStyle Hidden -PassThru
|
||||
|
||||
if (-not $proc) {
|
||||
Write-Error "[dev-server] Failed to launch process"
|
||||
exit 1
|
||||
}
|
||||
$proc.Id | Out-File -FilePath $PidFile -Encoding ascii -NoNewline
|
||||
|
||||
# Wait for server to respond
|
||||
$elapsed = 0
|
||||
while (-not (Test-HttpOk "$ApiUrl/ok") -and $elapsed -lt $MaxWait) {
|
||||
Start-Sleep -Seconds 1
|
||||
$elapsed++
|
||||
if ($proc.HasExited) {
|
||||
Write-Error "[dev-server] Process exited unexpectedly (code $($proc.ExitCode))"
|
||||
Write-Host "--- stdout ($StdoutLog) ---"
|
||||
if (Test-Path $StdoutLog) { Get-Content $StdoutLog -Tail 30 }
|
||||
Write-Host "--- stderr ($StderrLog) ---"
|
||||
if (Test-Path $StderrLog) { Get-Content $StderrLog -Tail 30 }
|
||||
Remove-Item $PidFile -ErrorAction SilentlyContinue
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
if ($elapsed -ge $MaxWait) {
|
||||
Write-Error "[dev-server] Server did not become ready within ${MaxWait}s"
|
||||
Write-Host "--- stdout ($StdoutLog) ---"
|
||||
if (Test-Path $StdoutLog) { Get-Content $StdoutLog -Tail 30 }
|
||||
Write-Host "--- stderr ($StderrLog) ---"
|
||||
if (Test-Path $StderrLog) { Get-Content $StderrLog -Tail 30 }
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "[dev-server] Ready in ${elapsed}s"
|
||||
Write-Host "[dev-server] API: $ApiUrl"
|
||||
Write-Host "[dev-server] Studio: https://smith.langchain.com/studio/?baseUrl=$ApiUrl"
|
||||
Write-Host "[dev-server] Logs: $StdoutLog / $StderrLog"
|
||||
}
|
||||
|
||||
"stop" {
|
||||
$pid = Get-StoredPid
|
||||
if ((Stop-ServerProcess -PidValue $pid)) {
|
||||
Write-Host "[dev-server] Stopped (PID $pid)"
|
||||
} else {
|
||||
Write-Host "[dev-server] Not running (nothing to stop)"
|
||||
}
|
||||
Remove-Item $PidFile -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
"status" {
|
||||
if (Test-ServerRunning) {
|
||||
$pid = Get-StoredPid
|
||||
Write-Host "[dev-server] Running (PID $pid) at $ApiUrl"
|
||||
Write-Host "[dev-server] Studio: https://smith.langchain.com/studio/?baseUrl=$ApiUrl"
|
||||
} else {
|
||||
Write-Host "[dev-server] Not running"
|
||||
}
|
||||
}
|
||||
|
||||
default {
|
||||
Write-Error "Usage: manage_dev_server.ps1 {start|stop|status}"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user