This file provides guidance to Qoder (qoder.com) when working with code in this repository.
PaiAgent-one is an enterprise-grade AI workflow orchestration platform with visual flow editor. It uses a custom DAG (Directed Acyclic Graph) engine to execute workflows composed of LLM nodes (OpenAI, DeepSeek, Qwen) and tool nodes (TTS, etc.).
cd backend
./mvnw spring-boot:run # Start backend server (port 8080)
./mvnw clean package # Build JAR package
./mvnw test # Run testscd frontend
npm install # Install dependencies
npm run dev # Start dev server (port 5173)
npm run build # Build for production (TypeScript check + Vite build)
npm run lint # Run ESLint
npm run preview # Preview production buildmysql -u root -p < backend/src/main/resources/schema.sqlUpdate database credentials in backend/src/main/resources/application.yml:
spring:
datasource:
url: jdbc:mysql://localhost:3306/paiagent?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: your_passwordCore DAG Engine (engine/):
WorkflowEngine.java: Main orchestration engine that executes workflows end-to-enddag/DAGParser.java: Parses workflow config into DAG, performs topological sorting using Kahn's algorithm, and detects cycles using DFSexecutor/NodeExecutor.java: Interface for all node executorsexecutor/NodeExecutorFactory.java: Factory pattern to get executors by node typeexecutor/impl/: Concrete implementations (InputNodeExecutor, OutputNodeExecutor, OpenAINodeExecutor, TTSNodeExecutor)model/: Data models (WorkflowConfig, WorkflowNode, WorkflowEdge)
Application Layers:
controller/: REST API endpointsservice/: Business logic layermapper/: MyBatis-Plus data access layerentity/: Database entities (Workflow, ExecutionRecord, NodeDefinition, User)dto/: Data transfer objectsconfig/: Configuration classes (WebMvcConfig, MyBatisConfig)interceptor/: AuthInterceptor for token-based authenticationcommon/: Common utilities and result wrappers
Core Components:
components/FlowCanvas.tsx: ReactFlow-based visual workflow editorcomponents/NodePanel.tsx: Draggable node palette (LLM/Tool categories)components/DebugDrawer.tsx: Execution debugging panel with real-time logs and resultscomponents/AudioPlayer.tsx: Audio playback component for TTS output
Pages:
pages/LoginPage.tsx: Authentication pagepages/MainPage.tsx: Workflow list managementpages/EditorPage.tsx: Main workflow editor with canvas, node panel, and debug drawer
State Management (Zustand):
store/authStore.ts: User authentication state (token, user info)store/workflowStore.ts: Workflow editing state (nodes, edges, selected workflow)
API Layer:
api/: Axios-based API client for backend communicationutils/request.ts: Axios instance with auth interceptors (base URL: http://localhost:8080)
Tables: workflow, node_definition, execution_record, user
Key features:
- JSON columns for workflow config (
flow_data), execution results (node_results) - Logical deletion using
deletedfield - Pre-seeded node definitions for OpenAI, DeepSeek, Qwen, and TTS
- User designs workflow in ReactFlow canvas (frontend)
- Frontend serializes nodes/edges to JSON and saves via API
- Backend stores workflow config in
workflow.flow_data - On execution:
WorkflowEngineparses JSON intoWorkflowConfigDAGParservalidates (cycle detection) and sorts nodes topologically- Engine executes nodes sequentially, passing output of node N as input to node N+1
- Each node result is recorded in
ExecutionRecord.node_results
- Frontend displays execution results in
DebugDrawerwith logs and output data
- Backend: Spring Boot 3.4.1, Java 21, MyBatis-Plus 3.5.5, MySQL, FastJSON2
- Frontend: React 18, TypeScript, Vite, ReactFlow (@xyflow/react), Ant Design, Tailwind CSS, Zustand
- Authentication: Simple token-based auth (default: admin/123)
- API Docs: Swagger UI at http://localhost:8080/swagger-ui.html
- Backend API requires authentication token in
Authorizationheader - Frontend stores token in Zustand store and localStorage
- ReactFlow node types must match backend
NodeExecutorimplementations - Node executors follow a common interface:
execute(WorkflowNode node, Map<String, Object> input) -> Map<String, Object> - DAG engine uses Kahn's algorithm for topological sort and DFS for cycle detection