Add workflow editor and node types support in frontend and backend

- Introduce a new workflow editor component for visualizing and managing workflows, allowing users to add nodes and define connections.
- Implement backend support for node types, including validation and constraints for workflow graphs.
- Add new API endpoints for retrieving node types and their specifications.
- Enhance the AssistantPage to integrate the workflow editor, enabling users to create and edit workflows directly.
- Update frontend components to support new workflow functionalities, including condition edges and generic nodes.
- Refactor existing code to accommodate the new workflow features and improve overall structure.
This commit is contained in:
Xin Wang
2026-06-15 10:12:41 +08:00
parent 0309c154b5
commit c2a39257ff
15 changed files with 1733 additions and 54 deletions

View File

@@ -7,6 +7,7 @@ from db.session import get_session
from fastapi import APIRouter, Depends, HTTPException
from schemas import AssistantOut, AssistantUpsert
from services.masking import mask, resolve_incoming_key
from services.node_specs import validate_graph
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
@@ -14,6 +15,15 @@ router = APIRouter(prefix="/api/assistants", tags=["assistants"])
CAPABILITIES = ("LLM", "ASR", "TTS", "Realtime", "Embedding")
def _validate_workflow(body: AssistantUpsert) -> None:
"""workflow 类型:保存前校验图结构,不通过则 400。其他类型跳过。"""
if body.type != "workflow":
return
errors = validate_graph(body.graph or {})
if errors:
raise HTTPException(400, "工作流校验失败:" + ";".join(errors))
async def _sync_bindings(
session: AsyncSession, assistant_id: str, resource_ids: dict[str, str]
) -> None:
@@ -82,6 +92,7 @@ async def list_assistants(session: AsyncSession = Depends(get_session)):
async def create_assistant(
body: AssistantUpsert, session: AsyncSession = Depends(get_session)
):
_validate_workflow(body)
data = body.model_dump()
resource_ids = data.pop("model_resource_ids")
assistant = Assistant(id=f"asst_{uuid.uuid4().hex[:12]}", **data)
@@ -141,6 +152,7 @@ async def update_assistant(
assistant = await session.get(Assistant, assistant_id)
if not assistant:
raise HTTPException(404, "助手不存在")
_validate_workflow(body)
data = body.model_dump()
resource_ids = data.pop("model_resource_ids")
data["api_key"] = resolve_incoming_key(data["api_key"], assistant.api_key)

View File

@@ -0,0 +1,14 @@
"""工作流节点类型目录。前端画布据此渲染「添加节点」面板与节点编辑表单。
规格是只读的、与代码同生命周期(改了要重启后端 + 前端刷新),所以无需鉴权与缓存层。
"""
from fastapi import APIRouter
from services.node_specs import node_types_response
router = APIRouter(prefix="/api/node-types", tags=["workflow"])
@router.get("")
async def list_node_types():
return node_types_response()