--- name: langgraph-vivado-install description: 在 Windows 原生环境下自动化配置基于 Conda 的 LangGraph 开发环境,并强制完成 Vivado 链路的闭环验证。当用户提到"配置langgraph"、"安装langgraph"、"LangGraph环境"、"langgraph vivado"、"配置开发环境 langgraph"、"LangGraph+Vivado"、"搭建langgraph"时,必须触发此技能。即使用户未明确说"用这个技能",只要涉及在 Windows 上安装或配置 LangGraph(含与 Vivado 集成),都应触发。 --- # LangGraph + Vivado 环境配置技能 本技能在 Windows 原生环境(Git Bash / 命令提示符)中自动完成以下工作: 1. 检测并安装 Conda 2. 确认 conda 路径已永久写入 Windows 用户级 PATH 3. 创建 `langgraph` 虚拟环境并安装所需包 4. 迭代检测 Vivado 链路直至成功 5. 写出配置文件与冒烟测试脚本并运行验证 --- ## 整体流程 ``` Step 1: Conda 检测与安装 Step 1b: 确认 conda 路径已写入 Windows PATH(新安装或已有均执行) Step 2: 创建 langgraph 环境,安装依赖 Step 2c: 检测并安装 Codex CLI,验证 Auth Step 3: Vivado 链路迭代检测(循环直到成功) Step 4: 写出 env_config.json,提示持久化 Step 5: 生成并运行 smoke_test.py ``` --- ## Step 1 — Conda 检测与安装 运行: ```bash conda --version ``` - **若成功**:记录版本,进入 **Step 1b**。 - **若失败**:执行安装命令: ```bash winget install -e --id Anaconda.Miniconda3 ``` 安装完成后,提示用户: > "Miniconda 安装完成。请重启 Shell 或运行 `conda init bash` 使 conda 命令生效,然后重新触发本技能。" **在用户确认 conda 可用之前,不继续执行后续步骤。用户确认后,进入 Step 1b。** --- ## Step 1b — 确认 conda 路径已写入 Windows PATH 无论 conda 是刚安装的还是之前已存在,都必须执行此步骤,确保 conda 的路径被永久写入 Windows 用户级 PATH,方便在任何新 Shell 中直接使用。 ### 1. 定位 conda 所在目录 在 PowerShell 中运行: ```powershell $condaPath = (Get-Command conda -ErrorAction SilentlyContinue).Source $condaBin = if ($condaPath) { Split-Path $condaPath -Parent } else { $null } Write-Host "conda 所在目录: $condaBin" ``` 若 `$condaBin` 为空(conda 命令本身来自 conda init 脚本而非独立可执行文件),则改用: ```powershell # 方法 B:通过 conda info 获取 base 目录,再拼接 condabin $baseDir = (conda info --base 2>$null).Trim() $condaBin = Join-Path $baseDir "condabin" Write-Host "conda condabin 目录: $condaBin" ``` ### 2. 检查路径是否已在 PATH 中 ```powershell $userPath = [System.Environment]::GetEnvironmentVariable("PATH", "User") $sysPath = [System.Environment]::GetEnvironmentVariable("PATH", "Machine") $inUserPath = ($userPath -split ";") -contains $condaBin $inSysPath = ($sysPath -split ";") -contains $condaBin if ($inUserPath -or $inSysPath) { Write-Host "[OK] conda 路径已在 PATH 中,无需修改。" } else { Write-Host "[INFO] conda 路径不在 PATH 中,准备写入用户级 PATH..." } ``` ### 3. 若不在 PATH 中则写入 ```powershell if (-not ($inUserPath -or $inSysPath)) { $newUserPath = $condaBin + ";" + $userPath [System.Environment]::SetEnvironmentVariable("PATH", $newUserPath, "User") Write-Host "[OK] 已将以下路径写入用户级 PATH: $condaBin" Write-Host " 新开终端后即可直接使用 conda 命令。" } ``` > **为什么写用户级 PATH 而非系统级?** 用户级 PATH 不需要管理员权限,且只影响当前用户,更安全。若该机器是多用户共享环境,可改为 `"Machine"` 并以管理员身份运行。 完成后进入 Step 2。 --- ## Step 2 — 创建 langgraph Conda 环境 ### 2a. 检查环境是否已存在 ```bash conda env list | grep "^langgraph" ``` - 若已存在:跳过创建,直接进入 2b。 - 若不存在: ```bash conda create -n langgraph python=3.11 -y ``` ### 2b. 安装所需 Python 包 一条命令安装全部依赖(包含 `/langgraph-plan-review` skill 所需包): ```bash conda run -n langgraph pip install \ langgraph \ langchain-anthropic \ pandas \ "langgraph-cli[inmem]" \ langgraph-sdk \ httpx \ langgraph-checkpoint-sqlite ``` > **为什么这些包?** > | 包 | 用途 | > |---|---| > | `langgraph` | 核心图执行引擎 | > | `langchain-anthropic` | Anthropic LLM 集成 | > | `pandas` | 数据处理 | > | `langgraph-cli[inmem]` | 提供 `langgraph dev` 服务器命令(`/langgraph-plan-review` 必需) | > | `langgraph-sdk` | `run_workflow.py` 通过 SDK 向 dev server 提交 run(`/langgraph-plan-review` 必需) | > | `httpx` | `run_workflow.py` 健康检查(`/langgraph-plan-review` 必需) | > | `langgraph-checkpoint-sqlite` | dev server 状态持久化(`/langgraph-plan-review` 必需) | 验证安装: ```bash conda run -n langgraph python -c "import langgraph; print('LangGraph OK:', langgraph.__version__)" conda run -n langgraph python -c "from langgraph_sdk import get_sync_client; print('langgraph-sdk OK')" conda run -n langgraph python -c "import httpx; print('httpx OK')" conda run -n langgraph langgraph --version ``` 若任一导入失败,报告错误并停止,请用户检查网络或 pip 源配置。 --- ## Step 2c — 检测并安装 Codex CLI,验证 Auth Codex CLI 是 OpenAI 发布的命令行代码审查工具,以 npm 全局包形式安装在 `langgraph` conda 环境中,供 LangGraph 工作流的 Codex review 节点调用。 ### 2c-1. 检测 Codex CLI 是否已安装 在 PowerShell 中运行: ```powershell $condaEnvPath = (C:\Users\bowei\miniconda3\Scripts\conda.exe run -n langgraph python -c "import sys; print(sys.prefix)").Trim() $codexCmd = Join-Path $condaEnvPath "codex.cmd" if (Test-Path $codexCmd) { Write-Host "[OK] Codex CLI 已安装: $codexCmd" $codexInstalled = $true } else { Write-Host "[INFO] 未检测到 Codex CLI,准备安装..." $codexInstalled = $false } ``` ### 2c-2. 若未安装,通过 npm 安装 首先确认 npm 可用(Node.js 需已安装在 conda 环境或系统 PATH 中): ```powershell C:\Users\bowei\miniconda3\Scripts\conda.exe run -n langgraph npm --version ``` - **若 npm 可用**:执行安装: ```powershell C:\Users\bowei\miniconda3\Scripts\conda.exe run -n langgraph npm install -g @openai/codex ``` 安装完成后,再次执行 2c-1 检查 `codex.cmd` 是否出现。若仍不存在,报告错误并停止,请用户手动检查 npm 全局安装路径。 - **若 npm 不可用**:停止并提示: > "langgraph conda 环境中未找到 npm。请先安装 Node.js(建议通过 `winget install OpenJS.NodeJS.LTS`),重启 Shell 后重新触发本技能。" **在用户确认 npm 可用之前,不继续后续步骤。** ### 2c-3. 验证 Codex CLI 可执行 ```powershell $env:CODEX_HOME = "C:\Users\bowei\.codex" cmd /c "$codexCmd" --version ``` - 若命令输出版本号(如 `0.133.0`):记录版本,继续。 - 若命令失败:报告错误(输出内容),停止执行,请用户检查 Node.js 版本兼容性。 > **为什么用 `cmd /c`?** `.cmd` 文件在 Windows 上不能直接被 PowerShell 或 Python subprocess 执行,必须通过 `cmd /c` 转发。 ### 2c-4. 验证 Codex Auth Codex CLI 的认证 token 存储在 `$CODEX_HOME\auth.json`(默认 `C:\Users\bowei\.codex\auth.json`)。 ```powershell $codexHome = if ($env:CODEX_HOME) { $env:CODEX_HOME } else { "$env:USERPROFILE\.codex" } $authFile = Join-Path $codexHome "auth.json" if (Test-Path $authFile) { $authContent = (Get-Content $authFile -Raw -Encoding utf8).Trim() if ($authContent.Length -gt 20) { Write-Host "[OK] Codex auth.json 存在且内容有效。" $authOk = $true } else { Write-Host "[WARN] auth.json 内容过短,可能已损坏或未完成认证。" $authOk = $false } } else { Write-Host "[WARN] 未找到 auth.json: $authFile" $authOk = $false } ``` - **若 `$authOk = $true`**:继续进入 Step 3。 - **若 `$authOk = $false`**:停止并提示: > "Codex CLI 尚未完成认证,或认证已失效。请在终端运行 `codex` 并按提示完成 ChatGPT OAuth 登录,登录成功后 auth.json 将自动写入 `C:\Users\bowei\.codex\`。完成后重新触发本技能或手动继续到 Step 3。" **在用户确认认证完成之前,不继续后续步骤。** > **为什么检查 auth.json 而非运行 `codex auth status`?** Codex CLI 目前没有独立的状态查询子命令;auth.json 存在且非空即表示 OAuth 流程已完成。若需更严格验证,可在 Step 5 冒烟测试中加入一次受控的 `codex exec --ephemeral` 调用。 --- ## Step 3 — Vivado 链路迭代检测循环 这是本技能的核心环节。目标是确保在 `langgraph` 环境中可以调用 Vivado。 ### Step A:首次尝试检测 ```bash conda run -n langgraph vivado -version ``` ### Step B:若成功 - 打印版本信息(取输出第一行)。 - 进入 Step 4。 ### Step C:若失败(命令未找到)— 交互式路径收集 **停止自动化**,向用户提问: > "未能检测到 Vivado 环境。请输入 Vivado 的 bin 文件夹完整路径(例如:`C:\Xilinx\Vivado\2023.2\bin`):" **收到用户输入后执行:** 1. **验证路径有效性** — 检查该目录下 `vivado.bat` 是否存在: ```bash # 将用户输入的 Windows 路径转换为 bash 路径后检查 # 例:C:\Xilinx\Vivado\2023.2\bin → /c/Xilinx/Vivado/2023.2/bin ls "/vivado.bat" ``` - 若不存在:提示 "路径无效或找不到 vivado.bat,请重新输入。" 并**重复 Step C**。 - 若存在:继续。 2. **将路径临时加入当前会话 PATH**(Windows 反斜杠转为正斜杠): ```bash export PATH=":$PATH" ``` 3. **记录该路径**供后续 Step 4/5 使用(内部变量 `VIVADO_BIN_PATH`)。 4. **重试检测**: ```bash vivado -version ``` - 若成功:打印版本,进入 Step 4。 - 若再次失败:回到 Step C 顶部,重新向用户询问路径。 > **循环逻辑**:重复 Step C 直到 `vivado -version` 执行成功为止。不要跳过,不要假设路径正确。 --- ## Step 4 — 持久化配置 `vivado -version` 成功后: ### 4a. 提示用户持久化 向用户说明: > "为了在每次新开 Shell 时自动识别 Vivado,建议将该路径永久添加到 Windows 系统环境变量 PATH 中。操作方法:系统属性 → 高级 → 环境变量 → 编辑 PATH → 新建,粘贴路径。" ### 4b. 写出 env_config.json 在当前工作目录创建: ```json { "VIVADO_BIN_PATH": "", "conda_env": "langgraph", "python_version": "3.11", "packages": [ "langgraph", "langchain-anthropic", "pandas", "langgraph-cli[inmem]", "langgraph-sdk", "httpx", "langgraph-checkpoint-sqlite" ] } ``` --- ## Step 5 — 生成冒烟测试脚本并运行 在当前工作目录创建 `smoke_test.py`,内容如下: ```python import subprocess import sys import json import os def test_langgraph(): try: import langgraph import importlib.metadata version = importlib.metadata.version("langgraph") print(f"[OK] LangGraph import OK, version: {version}") return True except ImportError as e: print(f"[FAIL] LangGraph import failed: {e}") return False def test_langgraph_plan_review_deps(): """Verify packages required by the /langgraph-plan-review skill.""" ok = True checks = [ ("langgraph_sdk", "from langgraph_sdk import get_sync_client"), ("httpx", "import httpx"), ("langgraph_checkpoint_sqlite", "from langgraph.checkpoint.sqlite import SqliteSaver"), ] for name, stmt in checks: try: exec(stmt) import importlib.metadata try: ver = importlib.metadata.version(name.replace("_", "-")) print(f"[OK] {name} OK (version: {ver})") except importlib.metadata.PackageNotFoundError: print(f"[OK] {name} importable") except Exception as e: print(f"[FAIL] {name}: {e}") ok = False # Check langgraph dev CLI try: result = subprocess.run( [sys.executable, "-m", "langgraph", "--version"], capture_output=True, text=True, timeout=10 ) if result.returncode == 0: print(f"[OK] langgraph-cli OK: {result.stdout.strip() or result.stderr.strip()}") else: # Try via entry point script import shutil lg = shutil.which("langgraph") if lg: r2 = subprocess.run([lg, "--version"], capture_output=True, text=True, timeout=10) if r2.returncode == 0: print(f"[OK] langgraph dev CLI OK: {r2.stdout.strip()}") else: print(f"[WARN] langgraph CLI found but --version failed: {r2.stderr.strip()}") else: print("[FAIL] langgraph CLI not found on PATH — install: pip install 'langgraph-cli[inmem]'") ok = False except Exception as e: print(f"[FAIL] langgraph CLI check error: {e}") ok = False return ok def test_vivado(): config_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "env_config.json") env = os.environ.copy() vivado_bin = "" if os.path.exists(config_path): with open(config_path, encoding="utf-8") as f: config = json.load(f) vivado_bin = config.get("VIVADO_BIN_PATH", "").strip() if vivado_bin: env["PATH"] = vivado_bin + os.pathsep + env["PATH"] # On Windows use the full path to vivado.bat to avoid shell PATH issues if vivado_bin and (os.name == "nt" or sys.platform == "win32"): cmd = [os.path.join(vivado_bin, "vivado.bat"), "-version"] else: cmd = ["vivado", "-version"] try: result = subprocess.run(cmd, capture_output=True, text=True, timeout=30, env=env) if result.returncode == 0: first_line = (result.stdout.strip().splitlines() or ["(no output)"])[0] print(f"[OK] Vivado detected: {first_line}") return True else: print(f"[FAIL] vivado -version non-zero exit: {result.stderr.strip()}") return False except FileNotFoundError: print(f"[FAIL] vivado not found. CMD tried: {cmd}") return False except subprocess.TimeoutExpired: print("[FAIL] vivado -version timed out (30s)") return False if __name__ == "__main__": print("=" * 50) print("LangGraph + Vivado smoke test") print("=" * 50) ok_lg = test_langgraph() print("-" * 50) print("langgraph-plan-review deps:") ok_pr = test_langgraph_plan_review_deps() print("-" * 50) ok_vv = test_vivado() print("=" * 50) if ok_lg and ok_pr and ok_vv: print("[PASS] All checks passed. LangGraph + Vivado + plan-review pipeline OK!") sys.exit(0) else: print("[FAIL] Some checks failed. See above.") sys.exit(1) ``` ### 运行冒烟测试 ```bash conda run -n langgraph python smoke_test.py ``` - **全部通过**:向用户报告"环境配置完成,LangGraph + Vivado 链路闭环成功。" - **有失败项**:读取具体错误,向用户说明原因(路径问题、包未安装等),并提供修复建议。 --- ## 注意事项 - Windows 路径转换规则:`C:\Xilinx\Vivado\2023.2\bin` → `/c/Xilinx/Vivado/2023.2/bin`(首字母小写,冒号去掉,反斜杠换正斜杠)。 - `conda run -n langgraph vivado -version` 需要 PATH 在 conda 激活前已包含 Vivado bin 目录,若不行则用 `export PATH=... && conda run ...` 形式或直接用绝对路径调用。 - 本技能产生的文件:`env_config.json`、`smoke_test.py`(均在调用时的当前目录)。