# 工作流执行接口文档

## 概述
工作流执行分为**同步执行**和**异步执行**两种模式，通过 `async` 参数控制。

---

## 1. 调试执行接口

### 接口信息
- **URL**: `POST /open/workflow/execute`
- **超时**: 600000ms (10分钟)

### 请求参数
```json
{
  "workflow": {
    "nodes": [...],
    "edges": [...]
  },
  "inputs": {
    "param1": "value1",
    "param2": "value2"
  },
  "saveLog": false,
  "async": true
}
```

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| workflow | Object | 是 | 工作流配置（节点和边） |
| inputs | Object | 否 | 开始节点的输入参数 |
| saveLog | Boolean | 否 | 是否保存执行日志 |
| async | Boolean | 否 | 是否异步执行（默认 false） |

---

## 2. 响应处理

### 2.1 同步执行响应 (async=false)
直接返回完整执行结果：

```json
{
  "code": 200,
  "data": {
    "success": true,
    "status": "success",
    "duration": 2.5,
    "nodes_executed": 5,
    "errors_count": 0,
    "final_output": {...},
    "execution_history": [
      {
        "node_id": "node_1",
        "node_type": "start",
        "status": "success",
        "inputs": {...},
        "outputs": {...},
        "error": null,
        "duration": 0.1,
        "timestamp": "2024-01-20T10:00:00"
      }
    ]
  }
}
```

### 2.2 异步执行响应 (async=true)
返回执行 ID，需要轮询查询状态：

```json
{
  "code": 200,
  "data": {
    "status": "pending",
    "execution_id": "exec_123456",
    "workflow_id": "wf_789"
  }
}
```

---

## 3. 异步执行状态查询

### 接口信息
- **URL**: `GET /open/workflow/status/{executionId}?workflowId={workflowId}`

### 请求参数
| 参数 | 位置 | 类型 | 必填 | 说明 |
|------|------|------|------|------|
| executionId | Path | String | 是 | 执行ID |
| workflowId | Query | String | 是 | 工作流ID |

### 响应数据
```json
{
  "code": 200,
  "data": {
    "status": "success",
    "success": true,
    "execution_id": "exec_123456",
    "workflow_id": "wf_789",
    "duration": 2.5,
    "nodes_executed": 5,
    "errors_count": 0,
    "final_output": {...},
    "execution_history": [...]
  }
}
```

### 状态值说明
| 状态 | 说明 | 处理方式 |
|------|------|----------|
| pending | 等待执行 | 继续轮询 |
| running | 执行中 | 继续轮询 |
| success | 执行成功 | 停止轮询，显示结果 |
| failed | 执行失败 | 停止轮询，显示错误 |

---

## 4. 轮询策略

### 前端实现参数
```javascript
const POLLING_INTERVAL = 1000;      // 轮询间隔：1秒
const MAX_POLL_COUNT = 120;         // 最大轮询次数：2分钟
const MAX_ERROR_COUNT = 3;          // 最大连续错误次数
```

### 轮询逻辑
1. 提交异步执行请求，获取 `execution_id` 和 `workflow_id`
2. 每隔 1 秒调用状态查询接口
3. 根据返回的 `status` 判断：
   - `pending/running`: 继续轮询
   - `success/failed`: 停止轮询，处理结果
4. 超过 120 次轮询或连续 3 次错误，停止轮询

---

## 5. Python 实现示例

### 5.1 同步执行
```python
import requests

def execute_workflow_sync(workflow_config, inputs=None):
    """同步执行工作流"""
    url = "http://your-api/api/system/workflowManage/debug"
    
    payload = {
        "workflow": workflow_config,
        "inputs": inputs or {},
        "saveLog": False,
        "async": False
    }
    
    response = requests.post(url, json=payload, timeout=600)
    result = response.json()
    
    if result["code"] == 200:
        return result["data"]
    else:
        raise Exception(f"执行失败: {result.get('msg')}")
```

### 5.2 异步执行 + 轮询
```python
import requests
import time

def execute_workflow_async(workflow_config, inputs=None):
    """异步执行工作流并轮询结果"""
    # 1. 提交异步执行
    url = "http://your-api/api/system/workflowManage/debug"
    payload = {
        "workflow": workflow_config,
        "inputs": inputs or {},
        "saveLog": False,
        "async": True
    }
    
    response = requests.post(url, json=payload, timeout=600)
    result = response.json()
    
    if result["code"] != 200:
        raise Exception(f"提交失败: {result.get('msg')}")
    
    execution_id = result["data"]["execution_id"]
    workflow_id = result["data"]["workflow_id"]
    
    # 2. 轮询执行状态
    status_url = f"http://your-api/api/system/workflowManage/status/{execution_id}"
    params = {"workflowId": workflow_id}
    
    max_polls = 120
    poll_interval = 1
    error_count = 0
    
    for i in range(max_polls):
        try:
            response = requests.get(status_url, params=params)
            result = response.json()
            
            if result["code"] == 200:
                error_count = 0  # 重置错误计数
                data = result["data"]
                status = data["status"]
                
                if status == "success":
                    return data
                elif status == "failed":
                    raise Exception(f"执行失败: {data.get('error')}")
                elif status in ["pending", "running"]:
                    time.sleep(poll_interval)
                    continue
                else:
                    raise Exception(f"未知状态: {status}")
            else:
                error_count += 1
                if error_count >= 3:
                    raise Exception("连续错误次数过多")
                time.sleep(poll_interval)
                
        except requests.RequestException as e:
            error_count += 1
            if error_count >= 3:
                raise Exception(f"网络异常: {str(e)}")
            time.sleep(poll_interval)
    
    raise Exception("执行超时")
```

### 5.3 完整使用示例
```python
# 工作流配置
workflow_config = {
    "nodes": [
        {
            "id": "start_1",
            "type": "start",
            "data": {
                "config": {
                    "inputs": [
                        {"name": "text", "type": "string", "required": True}
                    ]
                }
            }
        },
        # ... 其他节点
    ],
    "edges": [
        {"source": "start_1", "target": "node_2"}
    ]
}

# 输入参数
inputs = {
    "text": "Hello World"
}

# 同步执行
try:
    result = execute_workflow_sync(workflow_config, inputs)
    print("执行成功:", result)
except Exception as e:
    print("执行失败:", e)

# 异步执行
try:
    result = execute_workflow_async(workflow_config, inputs)
    print("执行成功:", result)
except Exception as e:
    print("执行失败:", e)
```

---

## 6. 响应数据结构

### execution_history 节点执行记录
```python
{
    "node_id": "node_1",           # 节点ID
    "node_type": "llm",            # 节点类型
    "status": "success",           # 执行状态
    "inputs": {...},               # 输入参数
    "outputs": {...},              # 输出结果
    "error": None,                 # 错误信息
    "duration": 1.2,               # 执行耗时(秒)
    "timestamp": "2024-01-20..."   # 时间戳
}
```

### 节点类型枚举
- `start`: 开始节点
- `end`: 结束节点
- `llm`: 大模型节点
- `code`: 代码节点
- `condition`: 条件分支
- `loop`: 循环节点
- `http`: HTTP请求
- `knowledge`: 知识库
- `agent`: 智能体
- `tool`: 工具节点
- `variable`: 变量节点
- `template`: 模板节点
- `subflow`: 子流程

---

## 7. 注意事项

1. **超时设置**: 调试接口超时时间为 10 分钟，适合长时间运行的工作流
2. **异步推荐**: 对于复杂工作流，建议使用异步模式避免超时
3. **轮询频率**: 建议 1 秒轮询一次，避免过于频繁
4. **错误处理**: 需要处理网络异常、超时、连续错误等情况
5. **日志保存**: `saveLog` 参数控制是否保存执行日志到数据库
