import request from '../utils/request' /** * 工作流 API。 * * 路由策略(方案C):URL 路径参数统一使用 name(kebab-case); * 旧数字 id 作为字符串传入时也可被后端 getWorkflow(nameOrId) 兜底解析。 */ export function getWorkflows(params = {}) { return request.get('/workflows', { params }) } export function setWorkflowCategory(nameOrId, categoryId) { return request.put(`/workflows/${nameOrId}/category`, { categoryId }) } export function getWorkflow(nameOrId) { return request.get(`/workflows/${nameOrId}`) } export function createWorkflow(data) { return request.post('/workflows', data) } export function saveWorkflow(nameOrId, data) { return request.post(`/workflows/${nameOrId}/save`, data) } /** * AI 生成工作流描述(LLM 单轮调用,timeout 加长到 120s)。 * 返回 Result{ data: { skipped, reason, description } }: * skipped=true 表示当前描述已清晰无需修改。 * 接口只生成、不保存,由调用方决定是否再调 saveWorkflow 写回。 */ export function generateWorkflowDescription(nameOrId) { return request.post(`/workflows/${nameOrId}/generate-description`, null, { timeout: 120000 }) } /** * 仅更新工作流描述(不建版本快照)。 * 用于批量生成描述后的自动保存,避免污染版本历史。 */ export function updateWorkflowDescription(nameOrId, description) { return request.put(`/workflows/${nameOrId}/description`, { description }) } export function deleteWorkflow(nameOrId) { return request.post(`/workflows/${nameOrId}/delete`) } /** * 运行工作流(POST SSE 流式响应) * 支持文件/目录上传:使用 FormData 提交 * paths 为每个文件在工作目录中的相对路径(目录上传时保留目录结构) * 返回原生 fetch Response,需自行解析 SSE 流 */ export function runWorkflow(nameOrId, inputs, files = [], paths = []) { const formData = new FormData() formData.append('inputs', JSON.stringify(inputs || {})) files.forEach((file, i) => { formData.append('files', file) formData.append('paths', paths[i] || file.name) }) return fetch(`/api/workflows/${nameOrId}/run`, { method: 'POST', body: formData }) } /** * v1.1:断线重连入口 —— 按 runId 重新订阅 SSE。 * 客户端 reader.read() 抛错时记录 lastEventId 后通过此端点续接。 * 返回原生 fetch Response,需自行解析 SSE 流(与 runWorkflow 一致)。 * * @param {string} runId 工作流运行 ID * @param {number} lastEventId 上次收到的最大事件 id(来自 SSE event.id 字段) */ export function reconnectRunStream(runId, lastEventId) { const url = `/api/workflows/runs/${runId}/stream` + (lastEventId != null ? `?lastEventId=${lastEventId}` : '') return fetch(url) } /** * v1.1:查询运行状态 + 当前未答暂停点。 * 用户离开几小时后回来时,前端先调此端点: * 若 status=RUNNING 且 currentPause 非空,立即恢复 Askfor UI; * 然后再调 reconnectRunStream 续接 SSE。 */ export function getRunState(runId) { return request.get(`/workflows/runs/${runId}/state`) } /** * v1.1:提交用户对 clarify_request 的回答。 * 唤醒后端 Bridge 中阻塞等待的 Hermes Agent 线程,工作流继续执行。 */ export function submitClarifyAnswer(runId, clarifyId, answer) { return request.post(`/workflows/runs/${runId}/resume`, { clarifyId, answer }) } /** * 自动关联分析:识别 Skill/SmartAction 节点隐式引用的其他 Skill */ export function autoAssociate(graphData) { return request.post('/workflows/auto-associate', { graphData }) } // ==================== 版本管理 ==================== export function listWorkflowVersions(nameOrId) { return request.get(`/workflows/${nameOrId}/versions`) } export function getWorkflowVersionContent(nameOrId, version) { return request.get(`/workflows/${nameOrId}/versions/${version}/content`) } export function rollbackWorkflowVersion(nameOrId, version) { return request.post(`/workflows/${nameOrId}/versions/${version}/rollback`) } export function updateWorkflowVersionMessage(nameOrId, version, message) { return request.put(`/workflows/${nameOrId}/versions/${version}/message`, { message }) }