workflow.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. import request from '../utils/request'
  2. /**
  3. * 工作流 API。
  4. *
  5. * 路由策略(方案C):URL 路径参数统一使用 name(kebab-case);
  6. * 旧数字 id 作为字符串传入时也可被后端 getWorkflow(nameOrId) 兜底解析。
  7. */
  8. export function getWorkflows(params = {}) {
  9. return request.get('/workflows', { params })
  10. }
  11. export function setWorkflowCategory(nameOrId, categoryId) {
  12. return request.put(`/workflows/${nameOrId}/category`, { categoryId })
  13. }
  14. export function getWorkflow(nameOrId) {
  15. return request.get(`/workflows/${nameOrId}`)
  16. }
  17. export function createWorkflow(data) {
  18. return request.post('/workflows', data)
  19. }
  20. export function saveWorkflow(nameOrId, data) {
  21. return request.post(`/workflows/${nameOrId}/save`, data)
  22. }
  23. export function deleteWorkflow(nameOrId) {
  24. return request.post(`/workflows/${nameOrId}/delete`)
  25. }
  26. /**
  27. * 运行工作流(POST SSE 流式响应)
  28. * 支持文件/目录上传:使用 FormData 提交
  29. * paths 为每个文件在工作目录中的相对路径(目录上传时保留目录结构)
  30. * 返回原生 fetch Response,需自行解析 SSE 流
  31. */
  32. export function runWorkflow(nameOrId, inputs, files = [], paths = []) {
  33. const formData = new FormData()
  34. formData.append('inputs', JSON.stringify(inputs || {}))
  35. files.forEach((file, i) => {
  36. formData.append('files', file)
  37. formData.append('paths', paths[i] || file.name)
  38. })
  39. return fetch(`/api/workflows/${nameOrId}/run`, {
  40. method: 'POST',
  41. body: formData
  42. })
  43. }
  44. /**
  45. * v1.1:断线重连入口 —— 按 runId 重新订阅 SSE。
  46. * 客户端 reader.read() 抛错时记录 lastEventId 后通过此端点续接。
  47. * 返回原生 fetch Response,需自行解析 SSE 流(与 runWorkflow 一致)。
  48. *
  49. * @param {string} runId 工作流运行 ID
  50. * @param {number} lastEventId 上次收到的最大事件 id(来自 SSE event.id 字段)
  51. */
  52. export function reconnectRunStream(runId, lastEventId) {
  53. const url = `/api/workflows/runs/${runId}/stream`
  54. + (lastEventId != null ? `?lastEventId=${lastEventId}` : '')
  55. return fetch(url)
  56. }
  57. /**
  58. * v1.1:查询运行状态 + 当前未答暂停点。
  59. * 用户离开几小时后回来时,前端先调此端点:
  60. * 若 status=RUNNING 且 currentPause 非空,立即恢复 Askfor UI;
  61. * 然后再调 reconnectRunStream 续接 SSE。
  62. */
  63. export function getRunState(runId) {
  64. return request.get(`/workflows/runs/${runId}/state`)
  65. }
  66. /**
  67. * v1.1:提交用户对 clarify_request 的回答。
  68. * 唤醒后端 Bridge 中阻塞等待的 Hermes Agent 线程,工作流继续执行。
  69. */
  70. export function submitClarifyAnswer(runId, clarifyId, answer) {
  71. return request.post(`/workflows/runs/${runId}/resume`, { clarifyId, answer })
  72. }
  73. /**
  74. * 自动关联分析:识别 Skill/SmartAction 节点隐式引用的其他 Skill
  75. */
  76. export function autoAssociate(graphData) {
  77. return request.post('/workflows/auto-associate', { graphData })
  78. }
  79. // ==================== 版本管理 ====================
  80. export function listWorkflowVersions(nameOrId) {
  81. return request.get(`/workflows/${nameOrId}/versions`)
  82. }
  83. export function getWorkflowVersionContent(nameOrId, version) {
  84. return request.get(`/workflows/${nameOrId}/versions/${version}/content`)
  85. }
  86. export function rollbackWorkflowVersion(nameOrId, version) {
  87. return request.post(`/workflows/${nameOrId}/versions/${version}/rollback`)
  88. }
  89. export function updateWorkflowVersionMessage(nameOrId, version, message) {
  90. return request.put(`/workflows/${nameOrId}/versions/${version}/message`, { message })
  91. }