docs: clean standalone LangGraph server remnants (#3301)

This commit is contained in:
Eilen Shin
2026-05-29 11:36:45 +08:00
committed by GitHub
parent cbf8b194e8
commit 872079b894
16 changed files with 92 additions and 113 deletions
+5 -5
View File
@@ -59,7 +59,7 @@ smoke-test/
2. **Check pnpm** - Package manager 2. **Check pnpm** - Package manager
3. **Check uv** - Python package manager 3. **Check uv** - Python package manager
4. **Check nginx** - Reverse proxy 4. **Check nginx** - Reverse proxy
5. **Check required ports** - Confirm that ports 2026, 3000, 8001, and 2024 are not occupied 5. **Check required ports** - Confirm that ports 2026, 3000, and 8001 are not occupied
**Docker mode environment check** (if Docker is selected): **Docker mode environment check** (if Docker is selected):
1. **Check whether Docker is installed** - Run `docker --version` 1. **Check whether Docker is installed** - Run `docker --version`
@@ -93,17 +93,17 @@ smoke-test/
### Phase 5: Service Health Check ### Phase 5: Service Health Check
**Local mode health check**: **Local mode health check**:
1. **Check process status** - Confirm that LangGraph, Gateway, Frontend, and Nginx processes are all running 1. **Check process status** - Confirm that Gateway, Frontend, and Nginx processes are all running
2. **Check frontend service** - Visit `http://localhost:2026` and verify that the page loads 2. **Check frontend service** - Visit `http://localhost:2026` and verify that the page loads
3. **Check API Gateway** - Verify the `http://localhost:2026/health` endpoint 3. **Check API Gateway** - Verify the `http://localhost:2026/health` endpoint
4. **Check LangGraph service** - Verify the availability of relevant endpoints 4. **Check LangGraph-compatible API** - Verify the `/api/langgraph/*` route exposed by Gateway
5. **Frontend route smoke check** - Run `bash .agent/skills/smoke-test/scripts/frontend_check.sh` to verify key routes under `/workspace` 5. **Frontend route smoke check** - Run `bash .agent/skills/smoke-test/scripts/frontend_check.sh` to verify key routes under `/workspace`
**Docker mode health check** (when using Docker): **Docker mode health check** (when using Docker):
1. **Check container status** - Run `docker ps` and confirm that all containers are running 1. **Check container status** - Run `docker ps` and confirm that all containers are running
2. **Check frontend service** - Visit `http://localhost:2026` and verify that the page loads 2. **Check frontend service** - Visit `http://localhost:2026` and verify that the page loads
3. **Check API Gateway** - Verify the `http://localhost:2026/health` endpoint 3. **Check API Gateway** - Verify the `http://localhost:2026/health` endpoint
4. **Check LangGraph service** - Verify the availability of relevant endpoints 4. **Check LangGraph-compatible API** - Verify the `/api/langgraph/*` route exposed by Gateway
5. **Frontend route smoke check** - Run `bash .agent/skills/smoke-test/scripts/frontend_check.sh` to verify key routes under `/workspace` 5. **Frontend route smoke check** - Run `bash .agent/skills/smoke-test/scripts/frontend_check.sh` to verify key routes under `/workspace`
### Optional Functional Verification ### Optional Functional Verification
@@ -135,7 +135,7 @@ smoke-test/
The following warnings can appear during smoke testing and do not block a successful result: The following warnings can appear during smoke testing and do not block a successful result:
- Feishu/Lark SSL errors in Gateway logs (certificate verification failure) can be ignored if that channel is not enabled - Feishu/Lark SSL errors in Gateway logs (certificate verification failure) can be ignored if that channel is not enabled
- Warnings in LangGraph logs about missing methods in the custom checkpointer, such as `adelete_for_runs` or `aprune`, do not affect the core functionality - Warnings in Gateway logs about missing methods in the custom checkpointer, such as `adelete_for_runs` or `aprune`, do not affect the core functionality
## Key Tools ## Key Tools
+8 -10
View File
@@ -138,7 +138,6 @@ This document describes the detailed operating steps for each phase of the DeerF
lsof -i :2026 # Main port lsof -i :2026 # Main port
lsof -i :3000 # Frontend lsof -i :3000 # Frontend
lsof -i :8001 # Gateway lsof -i :8001 # Gateway
lsof -i :2024 # LangGraph
``` ```
**Success Criteria**: All ports are free, or they are occupied only by DeerFlow-related processes. **Success Criteria**: All ports are free, or they are occupied only by DeerFlow-related processes.
@@ -258,7 +257,7 @@ This document describes the detailed operating steps for each phase of the DeerF
**Steps**: **Steps**:
1. Run `make dev-daemon` (background mode) 1. Run `make dev-daemon` (background mode)
**Description**: This command starts all services (LangGraph, Gateway, Frontend, Nginx). **Description**: This command starts all services (Gateway embedded runtime, Frontend, Nginx).
**Notes**: **Notes**:
- `make dev` runs in the foreground and stops with Ctrl+C - `make dev` runs in the foreground and stops with Ctrl+C
@@ -272,7 +271,6 @@ This document describes the detailed operating steps for each phase of the DeerF
**Steps**: **Steps**:
1. Wait 90-120 seconds for all services to start completely 1. Wait 90-120 seconds for all services to start completely
2. You can monitor startup progress by checking these log files: 2. You can monitor startup progress by checking these log files:
- `logs/langgraph.log`
- `logs/gateway.log` - `logs/gateway.log`
- `logs/frontend.log` - `logs/frontend.log`
- `logs/nginx.log` - `logs/nginx.log`
@@ -316,11 +314,10 @@ This document describes the detailed operating steps for each phase of the DeerF
**Steps**: **Steps**:
1. Run the following command to check processes: 1. Run the following command to check processes:
```bash ```bash
ps aux | grep -E "(langgraph|uvicorn|next|nginx)" | grep -v grep ps aux | grep -E "(uvicorn|next|nginx)" | grep -v grep
``` ```
**Success Criteria**: Confirm that the following processes are running: **Success Criteria**: Confirm that the following processes are running:
- LangGraph (`langgraph dev`)
- Gateway (`uvicorn app.gateway.app:app`) - Gateway (`uvicorn app.gateway.app:app`)
- Frontend (`next dev` or `next start`) - Frontend (`next dev` or `next start`)
- Nginx (`nginx`) - Nginx (`nginx`)
@@ -356,10 +353,11 @@ curl http://localhost:2026/health
--- ---
#### 5.1.4 Check LangGraph Service #### 5.1.4 Check LangGraph-compatible API
**Steps**: **Steps**:
1. Visit relevant LangGraph endpoints to verify availability 1. Visit `http://localhost:2026/api/langgraph/assistants/lead_agent` to verify Gateway's LangGraph-compatible API route is reachable.
2. A `401` response is acceptable when authentication is enabled and no session cookie is provided.
--- ---
@@ -373,7 +371,6 @@ curl http://localhost:2026/health
- `deer-flow-nginx` - `deer-flow-nginx`
- `deer-flow-frontend` - `deer-flow-frontend`
- `deer-flow-gateway` - `deer-flow-gateway`
- `deer-flow-langgraph` (if not in gateway mode)
--- ---
@@ -406,10 +403,11 @@ curl http://localhost:2026/health
--- ---
#### 5.2.4 Check LangGraph Service #### 5.2.4 Check LangGraph-compatible API
**Steps**: **Steps**:
1. Visit relevant LangGraph endpoints to verify availability 1. Visit `http://localhost:2026/api/langgraph/assistants/lead_agent` to verify Gateway's LangGraph-compatible API route is reachable.
2. A `401` response is acceptable when authentication is enabled and no session cookie is provided.
--- ---
@@ -254,7 +254,6 @@ Processes exit quickly after running `make dev-daemon`.
**Solutions**: **Solutions**:
1. Check log files: 1. Check log files:
```bash ```bash
tail -f logs/langgraph.log
tail -f logs/gateway.log tail -f logs/gateway.log
tail -f logs/frontend.log tail -f logs/frontend.log
tail -f logs/nginx.log tail -f logs/nginx.log
@@ -367,24 +366,7 @@ Errors appear in `gateway.log`.
uv sync uv sync
``` ```
4. Confirm that the LangGraph service is running normally (if not in gateway mode) 4. Confirm that the Gateway process is running normally.
---
### Issue: LangGraph Fails to Start
**Symptoms**:
Errors appear in `langgraph.log`.
**Solutions**:
1. Check LangGraph logs:
```bash
tail -f logs/langgraph.log
```
2. Check config.yaml
3. Check whether Python dependencies are complete
4. Confirm that port 2024 is not occupied
--- ---
@@ -519,7 +501,7 @@ Accessing `/health` returns an error or times out.
2. Confirm that config.yaml exists and has valid formatting 2. Confirm that config.yaml exists and has valid formatting
3. Check whether Python dependencies are complete 3. Check whether Python dependencies are complete
4. Confirm that the LangGraph service is running normally 4. Confirm that the Gateway process is running normally.
**Solutions** (Docker mode): **Solutions** (Docker mode):
1. Check gateway container logs: 1. Check gateway container logs:
@@ -529,7 +511,7 @@ Accessing `/health` returns an error or times out.
2. Confirm that config.yaml is mounted correctly 2. Confirm that config.yaml is mounted correctly
3. Check whether Python dependencies are complete 3. Check whether Python dependencies are complete
4. Confirm that the LangGraph service is running normally 4. Confirm that the Gateway process is running normally.
--- ---
@@ -539,7 +521,7 @@ Accessing `/health` returns an error or times out.
#### View All Service Processes #### View All Service Processes
```bash ```bash
ps aux | grep -E "(langgraph|uvicorn|next|nginx)" | grep -v grep ps aux | grep -E "(uvicorn|next|nginx)" | grep -v grep
``` ```
#### View Service Logs #### View Service Logs
@@ -548,7 +530,6 @@ ps aux | grep -E "(langgraph|uvicorn|next|nginx)" | grep -v grep
tail -f logs/*.log tail -f logs/*.log
# View specific service logs # View specific service logs
tail -f logs/langgraph.log
tail -f logs/gateway.log tail -f logs/gateway.log
tail -f logs/frontend.log tail -f logs/frontend.log
tail -f logs/nginx.log tail -f logs/nginx.log
@@ -65,7 +65,7 @@ if ! command -v lsof >/dev/null 2>&1; then
echo " Install lsof and rerun this check" echo " Install lsof and rerun this check"
all_passed=false all_passed=false
else else
for port in 2026 3000 8001 2024; do for port in 2026 3000 8001; do
if lsof -i :$port >/dev/null 2>&1; then if lsof -i :$port >/dev/null 2>&1; then
echo "⚠ Port $port is already in use:" echo "⚠ Port $port is already in use:"
lsof -i :$port | head -2 lsof -i :$port | head -2
@@ -54,7 +54,6 @@ echo "=========================================="
echo "" echo ""
echo "🌐 Access URL: http://localhost:2026" echo "🌐 Access URL: http://localhost:2026"
echo "📋 View logs:" echo "📋 View logs:"
echo " - logs/langgraph.log"
echo " - logs/gateway.log" echo " - logs/gateway.log"
echo " - logs/frontend.log" echo " - logs/frontend.log"
echo " - logs/nginx.log" echo " - logs/nginx.log"
@@ -76,12 +76,11 @@ if [ "$mode" = "docker" ]; then
all_passed=false all_passed=false
fi fi
else else
summary_hint="logs/{langgraph,gateway,frontend,nginx}.log" summary_hint="logs/{gateway,frontend,nginx}.log"
print_step "1. Checking local service ports..." print_step "1. Checking local service ports..."
check_listen_port "Nginx" 2026 check_listen_port "Nginx" 2026
check_listen_port "Frontend" 3000 check_listen_port "Frontend" 3000
check_listen_port "Gateway" 8001 check_listen_port "Gateway" 8001
check_listen_port "LangGraph" 2024
fi fi
echo "" echo ""
@@ -104,8 +103,8 @@ else
fi fi
echo "" echo ""
echo "5. Checking LangGraph service..." echo "5. Checking LangGraph-compatible Gateway API..."
check_http_status "LangGraph service" "http://localhost:2024/" "200|301|302|307|308|404" check_http_status "LangGraph-compatible Gateway API" "http://localhost:2026/api/langgraph/assistants/lead_agent" "200|401"
echo "" echo ""
echo "==========================================" echo "=========================================="
@@ -78,7 +78,7 @@
- [x] Container status - {{status_containers}} - [x] Container status - {{status_containers}}
- [x] Frontend service - {{status_frontend}} - [x] Frontend service - {{status_frontend}}
- [x] API Gateway - {{status_api_gateway}} - [x] API Gateway - {{status_api_gateway}}
- [x] LangGraph service - {{status_langgraph}} - [x] LangGraph-compatible Gateway API - {{status_langgraph}}
**Phase Status**: {{stage5_status}} **Phase Status**: {{stage5_status}}
@@ -147,7 +147,6 @@ Commit Message: {{git_commit_message}}
| deer-flow-nginx | {{nginx_status}} | {{nginx_uptime}} | | deer-flow-nginx | {{nginx_status}} | {{nginx_uptime}} |
| deer-flow-frontend | {{frontend_status}} | {{frontend_uptime}} | | deer-flow-frontend | {{frontend_status}} | {{frontend_uptime}} |
| deer-flow-gateway | {{gateway_status}} | {{gateway_uptime}} | | deer-flow-gateway | {{gateway_status}} | {{gateway_uptime}} |
| deer-flow-langgraph | {{langgraph_status}} | {{langgraph_uptime}} |
--- ---
@@ -80,7 +80,7 @@
- [x] Process status - {{status_processes}} - [x] Process status - {{status_processes}}
- [x] Frontend service - {{status_frontend}} - [x] Frontend service - {{status_frontend}}
- [x] API Gateway - {{status_api_gateway}} - [x] API Gateway - {{status_api_gateway}}
- [x] LangGraph service - {{status_langgraph}} - [x] LangGraph-compatible Gateway API - {{status_langgraph}}
**Phase Status**: {{stage5_status}} **Phase Status**: {{stage5_status}}
@@ -152,7 +152,7 @@ Commit Message: {{git_commit_message}}
| Nginx | {{nginx_status}} | {{nginx_endpoint}} | | Nginx | {{nginx_status}} | {{nginx_endpoint}} |
| Frontend | {{frontend_status}} | {{frontend_endpoint}} | | Frontend | {{frontend_status}} | {{frontend_endpoint}} |
| Gateway | {{gateway_status}} | {{gateway_endpoint}} | | Gateway | {{gateway_status}} | {{gateway_endpoint}} |
| LangGraph | {{langgraph_status}} | {{langgraph_endpoint}} | | Gateway LangGraph API | {{langgraph_status}} | {{langgraph_endpoint}} |
--- ---
@@ -166,7 +166,7 @@ Commit Message: {{git_commit_message}}
### If the Test Fails ### If the Test Fails
1. [ ] Review references/troubleshooting.md for common solutions 1. [ ] Review references/troubleshooting.md for common solutions
2. [ ] Check local logs: `logs/{langgraph,gateway,frontend,nginx}.log` 2. [ ] Check local logs: `logs/{gateway,frontend,nginx}.log`
3. [ ] Verify configuration file format and content 3. [ ] Verify configuration file format and content
4. [ ] If needed, fully reset the environment: `make stop && make clean && make install && make dev-daemon` 4. [ ] If needed, fully reset the environment: `make stop && make clean && make install && make dev-daemon`
+2 -2
View File
@@ -343,7 +343,7 @@ Proxied through nginx: `/api/langgraph/*` → Gateway LangGraph-compatible runti
- **Cache invalidation**: Detects config file changes via mtime comparison - **Cache invalidation**: Detects config file changes via mtime comparison
- **Transports**: stdio (command-based), SSE, HTTP - **Transports**: stdio (command-based), SSE, HTTP
- **OAuth (HTTP/SSE)**: Supports token endpoint flows (`client_credentials`, `refresh_token`) with automatic token refresh + Authorization header injection - **OAuth (HTTP/SSE)**: Supports token endpoint flows (`client_credentials`, `refresh_token`) with automatic token refresh + Authorization header injection
- **Runtime updates**: Gateway API saves to extensions_config.json; LangGraph detects via mtime - **Runtime updates**: Gateway API saves to extensions_config.json; the Gateway-embedded runtime detects changes via mtime
### Skills System (`packages/harness/deerflow/skills/`) ### Skills System (`packages/harness/deerflow/skills/`)
@@ -370,7 +370,7 @@ Proxied through nginx: `/api/langgraph/*` → Gateway LangGraph-compatible runti
### IM Channels System (`app/channels/`) ### IM Channels System (`app/channels/`)
Bridges external messaging platforms (Feishu, Slack, Telegram, DingTalk) to the DeerFlow agent via the LangGraph Server. Bridges external messaging platforms (Feishu, Slack, Telegram, DingTalk) to the DeerFlow agent via Gateway's LangGraph-compatible API.
**Architecture**: Channels communicate with Gateway through the `langgraph-sdk` HTTP client (same as the frontend), ensuring threads are created and managed server-side. The internal SDK client injects process-local internal auth plus a matching CSRF cookie/header pair so Gateway accepts state-changing thread/run requests from channel workers without relying on browser session cookies. **Architecture**: Channels communicate with Gateway through the `langgraph-sdk` HTTP client (same as the frontend), ensuring threads are created and managed server-side. The internal SDK client injects process-local internal auth plus a matching CSRF cookie/header pair so Gateway accepts state-changing thread/run requests from channel workers without relying on browser session cookies.
+3 -4
View File
@@ -276,10 +276,9 @@ async def update_mcp_configuration(request: McpConfigUpdateRequest) -> McpConfig
logger.info(f"MCP configuration updated and saved to: {config_path}") logger.info(f"MCP configuration updated and saved to: {config_path}")
# NOTE: No need to reload/reset cache here - LangGraph Server (separate process) # Reload the Gateway configuration and update the global cache. The
# will detect config file changes via mtime and reinitialize MCP tools automatically # agent runtime lives in Gateway, so this keeps API reads and tool
# execution aligned after extensions_config.json changes.
# Reload the configuration and update the global cache
reloaded_config = reload_extensions_config() reloaded_config = reload_extensions_config()
servers = {name: _mask_server_config(McpServerConfigResponse(**server.model_dump())) for name, server in reloaded_config.mcp_servers.items()} servers = {name: _mask_server_config(McpServerConfigResponse(**server.model_dump())) for name, server in reloaded_config.mcp_servers.items()}
return McpConfigResponse(mcp_servers=servers) return McpConfigResponse(mcp_servers=servers)
+30 -51
View File
@@ -4,10 +4,12 @@
| 模式 | 启动命令 | Auth 层 | 端口 | | 模式 | 启动命令 | Auth 层 | 端口 |
|------|---------|---------|------| |------|---------|---------|------|
| 标准模式 | `make dev` | Gateway AuthMiddleware + LangGraph auth | 2026 (nginx) | | 标准模式 | `make dev` | Gateway AuthMiddleware(全量) | 2026 (nginx) |
| Gateway 模式 | `make dev-pro` | Gateway AuthMiddleware(全量) | 2026 (nginx) |
| 直连 Gateway | `cd backend && make gateway` | Gateway AuthMiddleware | 8001 | | 直连 Gateway | `cd backend && make gateway` | Gateway AuthMiddleware | 8001 |
| 直连 LangGraph | `cd backend && make dev` | LangGraph auth | 2024 | | 直连 LangGraph 兼容性 | 手动运行 LangGraph 工具链时使用 | LangGraph auth | 2024 |
`make dev`、Docker dev 和生产部署默认都运行 Gateway embedded runtime。
`app.gateway.langgraph_auth` 仅用于保留的直连 LangGraph 工具链 / Studio 兼容性测试,不是标准服务启动路径。
每种模式下都需执行以下测试。 每种模式下都需执行以下测试。
@@ -21,10 +23,8 @@
# 清除已有数据 # 清除已有数据
rm -f backend/.deer-flow/data/deerflow.db rm -f backend/.deer-flow/data/deerflow.db
# 选择模式启动 # 启动标准模式(Gateway embedded runtime
make dev # 标准模式 make dev
# 或
make dev-pro # Gateway 模式
``` ```
**验证点:** **验证点:**
@@ -57,7 +57,7 @@ make dev
## 二、接口流程测试 ## 二、接口流程测试
> 以下用 `BASE=http://localhost:2026` 为例。标准模式和 Gateway 模式都用此地址。 > 以下用 `BASE=http://localhost:2026` 为例。标准模式经 nginx 暴露此地址。
> 直连测试替换为对应端口。 > 直连测试替换为对应端口。
> >
> **CSRF token 提取**:多处用到从 cookie jar 提取 CSRF token,统一使用: > **CSRF token 提取**:多处用到从 cookie jar 提取 CSRF token,统一使用:
@@ -211,20 +211,18 @@ curl -s -X POST $BASE/api/threads/search \
**预期:** 返回 0 或仅包含 user2 自己的 thread **预期:** 返回 0 或仅包含 user2 自己的 thread
### 2.3 标准模式 LangGraph Server 隔离 ### 2.3 LangGraph-compatible Gateway 路由隔离
> 仅在标准模式下测试。Gateway 模式不跑 LangGraph Server。 #### TC-API-10: LangGraph-compatible 端点需要 cookie
#### TC-API-10: LangGraph 端点需要 cookie
```bash ```bash
# 不带 cookie 访问 LangGraph 接口 # 不带 cookie 访问 LangGraph-compatible 接口
curl -s -w "%{http_code}" $BASE/api/langgraph/threads curl -s -w "%{http_code}" $BASE/api/langgraph/threads
``` ```
**预期:** 401 **预期:** 401
#### TC-API-11: LangGraph 带 cookie 可访问 #### TC-API-11: LangGraph-compatible 路由带 cookie 可访问
```bash ```bash
curl -s $BASE/api/langgraph/threads -b user1.txt | jq length curl -s $BASE/api/langgraph/threads -b user1.txt | jq length
@@ -232,10 +230,10 @@ curl -s $BASE/api/langgraph/threads -b user1.txt | jq length
**预期:** 200,返回 user1 的 thread 列表 **预期:** 200,返回 user1 的 thread 列表
#### TC-API-12: LangGraph 隔离 — 用户只看到自己的 #### TC-API-12: LangGraph-compatible 路由隔离 — 用户只看到自己的
```bash ```bash
# user2 查 LangGraph threads # user2 查 threads
curl -s $BASE/api/langgraph/threads -b user2.txt | jq length curl -s $BASE/api/langgraph/threads -b user2.txt | jq length
``` ```
@@ -1234,21 +1232,11 @@ P2=$(awk -F': ' '/^password:/ {print $2}' /tmp/deerflow-reset-p2.txt)
## 七、模式差异测试 ## 七、模式差异测试
> 以下用 `GW=http://localhost:8001` 表示直连 Gateway`BASE=http://localhost:2026` 表示经 nginx。 > 以下用 `GW=http://localhost:8001` 表示直连 Gateway`BASE=http://localhost:2026` 表示经 nginx。
> Gateway 模式启动命令:`make dev-pro`(或 `./scripts/serve.sh --dev --gateway`)。 > 标准启动命令:`make dev`(或 `./scripts/serve.sh --dev`)。
### 7.1 标准模式独有 ### 7.1 标准启动模式
> 启动命令:`make dev`(或 `./scripts/serve.sh --dev` #### TC-MODE-01: Gateway AuthMiddleware 的 token_version 检查
#### TC-MODE-01: LangGraph Server 独立运行,需 cookie
```bash
# 无 cookie 访问 LangGraph
curl -s -w "%{http_code}" -o /dev/null $BASE/api/langgraph/threads/search
# 预期: 403LangGraph auth handler 拒绝)
```
#### TC-MODE-02: LangGraph auth 的 token_version 检查
```bash ```bash
# 登录拿 cookie # 登录拿 cookie
@@ -1261,9 +1249,9 @@ curl -s -X POST $BASE/api/v1/auth/change-password \
-b cookies.txt -H "Content-Type: application/json" -H "X-CSRF-Token: $CSRF" \ -b cookies.txt -H "Content-Type: application/json" -H "X-CSRF-Token: $CSRF" \
-d '{"current_password":"正确密码","new_password":"NewPass1!"}' -c new_cookies.txt -d '{"current_password":"正确密码","new_password":"NewPass1!"}' -c new_cookies.txt
# 用旧 cookie 访问 LangGraph # 用旧 cookie 访问 LangGraph-compatible 路由
curl -s -w "%{http_code}" $BASE/api/langgraph/threads/search -b cookies.txt curl -s -w "%{http_code}" $BASE/api/langgraph/threads/search -b cookies.txt
# 预期: 403token_version 不匹配) # 预期: 401token_version 不匹配)
# 用新 cookie 访问 # 用新 cookie 访问
CSRF2=$(grep csrf_token new_cookies.txt | awk '{print $NF}') CSRF2=$(grep csrf_token new_cookies.txt | awk '{print $NF}')
@@ -1272,7 +1260,7 @@ curl -s -w "%{http_code}" -X POST $BASE/api/langgraph/threads/search \
# 预期: 200 # 预期: 200
``` ```
#### TC-MODE-03: LangGraph auth 的 owner filter 隔离 #### TC-MODE-02: Gateway owner filter 隔离
```bash ```bash
# user1 创建 thread # user1 创建 thread
@@ -1297,18 +1285,9 @@ print('OK: user2 sees', len(threads), 'threads, none belong to user1')
" "
``` ```
### 7.2 Gateway 模式独有 #### TC-MODE-03: 所有请求经 AuthMiddleware
> 启动命令:`make dev-pro`(或 `./scripts/serve.sh --dev --gateway`
> 无 LangGraph Server 进程,agent runtime 嵌入 Gateway。
#### TC-MODE-04: 所有请求经 AuthMiddleware
```bash ```bash
# 确认 LangGraph Server 未运行
curl -s -w "%{http_code}" -o /dev/null http://localhost:2024/ok
# 预期: 000(连接被拒)
# Gateway API 受保护 # Gateway API 受保护
curl -s -w "%{http_code}" -o /dev/null $BASE/api/models curl -s -w "%{http_code}" -o /dev/null $BASE/api/models
# 预期: 401 # 预期: 401
@@ -1319,7 +1298,7 @@ curl -s -w "%{http_code}" -o /dev/null -X POST $BASE/api/langgraph/threads/searc
# 预期: 401 # 预期: 401
``` ```
#### TC-MODE-05: Gateway 模式下完整 auth 流程 #### TC-MODE-04: 标准模式下完整 auth 流程
```bash ```bash
# 登录 # 登录
@@ -1334,7 +1313,7 @@ curl -s -X POST $BASE/api/langgraph/threads \
-d '{"metadata":{}}' | python3 -c "import sys,json; print(json.load(sys.stdin)['thread_id'])" -d '{"metadata":{}}' | python3 -c "import sys,json; print(json.load(sys.stdin)['thread_id'])"
# 预期: 返回 thread_id # 预期: 返回 thread_id
# CSRF 保护(Gateway 模式下 CSRFMiddleware 直接覆盖所有路由) # CSRF 保护(CSRFMiddleware 覆盖所有 Gateway 路由)
curl -s -w "%{http_code}" -o /dev/null -X POST $BASE/api/langgraph/threads \ curl -s -w "%{http_code}" -o /dev/null -X POST $BASE/api/langgraph/threads \
-b cookies.txt -H "Content-Type: application/json" -d '{"metadata":{}}' -b cookies.txt -H "Content-Type: application/json" -d '{"metadata":{}}'
# 预期: 403CSRF token missing # 预期: 403CSRF token missing
@@ -1433,7 +1412,7 @@ done
### 7.4 Docker 部署 ### 7.4 Docker 部署
> 启动命令:`./scripts/deploy.sh`(标准)或 `./scripts/deploy.sh --gateway`Gateway 模式) > 启动命令:`./scripts/deploy.sh`
> Docker Compose 文件:`docker/docker-compose.yaml` > Docker Compose 文件:`docker/docker-compose.yaml`
> >
> 前置条件: > 前置条件:
@@ -1542,16 +1521,16 @@ docker logs deer-flow-gateway 2>&1 | grep -iE "Password: .{15,}" && echo "FAIL:
- 容器日志输出**路径**(不是密码本身),符合 CodeQL `py/clear-text-logging-sensitive-data` 规则 - 容器日志输出**路径**(不是密码本身),符合 CodeQL `py/clear-text-logging-sensitive-data` 规则
- `grep "Password:"` 在日志中**应当无匹配**(旧行为已废弃,simplify pass 移除了日志泄露路径) - `grep "Password:"` 在日志中**应当无匹配**(旧行为已废弃,simplify pass 移除了日志泄露路径)
#### TC-DOCKER-06: Gateway 模式 Docker 部署 #### TC-DOCKER-06: Docker 部署
```bash ```bash
# Gateway 模式:无 langgraph 容器 # 标准 Docker 模式:runtime 嵌入 gateway 容器
./scripts/deploy.sh --gateway ./scripts/deploy.sh
sleep 15 sleep 15
# 确认 langgraph 容器存在 # 确认 gateway 容器存在
docker ps --filter name=deer-flow-langgraph --format '{{.Names}}' | wc -l docker ps --filter name=deer-flow-gateway --format '{{.Names}}'
# 预期: 0 # 预期: deer-flow-gateway
# auth 流程正常:未登录受保护接口返回 401 # auth 流程正常:未登录受保护接口返回 401
curl -s -w "%{http_code}" -o /dev/null $BASE/api/models curl -s -w "%{http_code}" -o /dev/null $BASE/api/models
+1 -1
View File
@@ -26,7 +26,7 @@
- Replace sync `requests` with `httpx.AsyncClient` in community tools (tavily, jina_ai, firecrawl, infoquest, image_search) - Replace sync `requests` with `httpx.AsyncClient` in community tools (tavily, jina_ai, firecrawl, infoquest, image_search)
- [x] Replace sync `model.invoke()` with async `model.ainvoke()` in title_middleware and memory updater - [x] Replace sync `model.invoke()` with async `model.ainvoke()` in title_middleware and memory updater
- Consider `asyncio.to_thread()` wrapper for remaining blocking file I/O - Consider `asyncio.to_thread()` wrapper for remaining blocking file I/O
- For production: use `langgraph up` (multi-worker) instead of `langgraph dev` (single-worker) - For production: tune Gateway worker/runtime settings for long-running agent workloads
## Resolved Issues ## Resolved Issues
@@ -87,8 +87,7 @@ def get_cached_mcp_tools() -> list[BaseTool]:
Also checks if the config file has been modified since last initialization, Also checks if the config file has been modified since last initialization,
and re-initializes if needed. This ensures that changes made through the and re-initializes if needed. This ensures that changes made through the
Gateway API (which runs in a separate process) are reflected in the Gateway API are reflected in the Gateway-embedded LangGraph runtime.
LangGraph Server.
Returns: Returns:
List of cached MCP tools. List of cached MCP tools.
@@ -83,3 +83,24 @@ def test_frontend_rewrites_langgraph_prefix_to_gateway():
assert "DEER_FLOW_INTERNAL_LANGGRAPH_BASE_URL" not in next_config assert "DEER_FLOW_INTERNAL_LANGGRAPH_BASE_URL" not in next_config
assert "http://127.0.0.1:2024" not in next_config assert "http://127.0.0.1:2024" not in next_config
assert "langgraph-compat" not in api_client assert "langgraph-compat" not in api_client
def test_smoke_test_docs_do_not_expect_standalone_langgraph_server():
smoke_files = {
".agent/skills/smoke-test/SKILL.md": _read(".agent/skills/smoke-test/SKILL.md"),
".agent/skills/smoke-test/references/SOP.md": _read(".agent/skills/smoke-test/references/SOP.md"),
".agent/skills/smoke-test/references/troubleshooting.md": _read(".agent/skills/smoke-test/references/troubleshooting.md"),
".agent/skills/smoke-test/scripts/check_local_env.sh": _read(".agent/skills/smoke-test/scripts/check_local_env.sh"),
".agent/skills/smoke-test/scripts/deploy_local.sh": _read(".agent/skills/smoke-test/scripts/deploy_local.sh"),
".agent/skills/smoke-test/scripts/health_check.sh": _read(".agent/skills/smoke-test/scripts/health_check.sh"),
".agent/skills/smoke-test/templates/report.local.template.md": _read(".agent/skills/smoke-test/templates/report.local.template.md"),
".agent/skills/smoke-test/templates/report.docker.template.md": _read(".agent/skills/smoke-test/templates/report.docker.template.md"),
}
for path, content in smoke_files.items():
assert "localhost:2024" not in content, path
assert "127.0.0.1:2024" not in content, path
assert "deer-flow-langgraph" not in content, path
assert "langgraph.log" not in content, path
assert "LangGraph service" not in content, path
assert "langgraph dev" not in content, path
+4 -3
View File
@@ -10,10 +10,11 @@
# should be updated accordingly. # should be updated accordingly.
# Backend API URLs (optional) # Backend API URLs (optional)
# Leave these commented out to use the default nginx proxy (recommended for `make dev`) # Leave these commented out to use the default nginx proxy (recommended for `make dev`).
# Only set these if you need to connect to backend services directly # Only set these if you need to connect to the Gateway service directly.
# For split-origin browser access, also configure GATEWAY_CORS_ORIGINS.
# NEXT_PUBLIC_BACKEND_BASE_URL="http://localhost:8001" # NEXT_PUBLIC_BACKEND_BASE_URL="http://localhost:8001"
# NEXT_PUBLIC_LANGGRAPH_BASE_URL="http://localhost:2024" # NEXT_PUBLIC_LANGGRAPH_BASE_URL="http://localhost:8001/api"
# Server-only Gateway wiring used by SSR (auth checks, /api/* rewrites). # Server-only Gateway wiring used by SSR (auth checks, /api/* rewrites).
# Defaults to localhost — only override for non-local deployments. # Defaults to localhost — only override for non-local deployments.
+5 -1
View File
@@ -88,7 +88,11 @@ Backend API URLs are optional; an nginx proxy is used by default:
``` ```
NEXT_PUBLIC_BACKEND_BASE_URL=http://localhost:8001 NEXT_PUBLIC_BACKEND_BASE_URL=http://localhost:8001
NEXT_PUBLIC_LANGGRAPH_BASE_URL=http://localhost:2024 NEXT_PUBLIC_LANGGRAPH_BASE_URL=http://localhost:8001/api
``` ```
Leave these unset for the standard `make dev` / Docker flow, where nginx serves
the public `/api/langgraph/*` prefix and rewrites it to Gateway's native `/api/*`
routes.
Requires Node.js 22+ and pnpm 10.26.2+. Requires Node.js 22+ and pnpm 10.26.2+.