From a16c099f02d3cd73bcdb12b5bebe3b318c332f89 Mon Sep 17 00:00:00 2001 From: yujiangping Date: Wed, 14 Jan 2026 12:06:43 +0800 Subject: [PATCH 1/4] feat(workflow): refactor port configuration and enhance edge styling - Extract port markup and attributes to shared constants for reusability - Add text label support to ports with '+' symbol and styling - Update port radius from 4 to 6 pixels for better visibility - Remove duplicate port configuration definitions from hook - Replace all port group definitions to use centralized portMarkup and portAttrs - Update edge connector to use smooth curve styling - Change edge target marker from block to diamond shape - Consolidate port styling logic to reduce code duplication and improve maintainability --- web/src/views/Workflow/constant.ts | 54 ++++++++++++++----- .../views/Workflow/hooks/useWorkflowGraph.ts | 46 ++++++---------- 2 files changed, 58 insertions(+), 42 deletions(-) diff --git a/web/src/views/Workflow/constant.ts b/web/src/views/Workflow/constant.ts index 692339da..ca44f2df 100644 --- a/web/src/views/Workflow/constant.ts +++ b/web/src/views/Workflow/constant.ts @@ -503,16 +503,44 @@ interface NodeConfig { ports?: PortsConfig; } -const portAttrs = { - circle: { - r: 4, magnet: true, stroke: '#155EEF', strokeWidth: 2, fill: '#155EEF', position: { top: 22 } +// 统一的端口 markup 配置 +export const portMarkup = [ + { + tagName: 'circle', + selector: 'body', }, + { + tagName: 'text', + selector: 'label', + }, +]; + +// 统一的端口属性配置 +export const portAttrs = { + body: { + r: 6, + magnet: true, + stroke: '#155EEF', + strokeWidth: 2, + fill: '#155EEF', + }, + label: { + text: '+', + fontSize: 12, + fontWeight: 'bold', + fill: '#FFFFFF', + textAnchor: 'middle', + textVerticalAnchor: 'middle', + pointerEvents: 'none', + } } + +// 统一的端口组配置 const defaultPortGroups = { - // top: { position: 'top', attrs: portAttrs }, - right: { position: 'right', attrs: portAttrs }, - // bottom: { position: 'bottom', attrs: portAttrs }, - left: { position: 'left', attrs: portAttrs }, + // top: { position: 'top', markup: portMarkup, attrs: portAttrs }, + right: { position: 'right', markup: portMarkup, attrs: portAttrs }, + // bottom: { position: 'bottom', markup: portMarkup, attrs: portAttrs }, + left: { position: 'left', markup: portMarkup, attrs: portAttrs }, } const defaultPortItems = [ // { group: 'top' }, @@ -570,7 +598,7 @@ export const graphNodeLibrary: Record = { height: 64, shape: 'normal-node', ports: { - groups: {right: { position: 'right', attrs: portAttrs }}, + groups: {right: { position: 'right', markup: portMarkup, attrs: portAttrs }}, items: [{ group: 'right' }], }, }, @@ -579,7 +607,7 @@ export const graphNodeLibrary: Record = { height: 64, shape: 'normal-node', ports: { - groups: {left: { position: 'left', attrs: portAttrs }}, + groups: {left: { position: 'left', markup: portMarkup, attrs: portAttrs }}, items: [{ group: 'left' }], }, }, @@ -588,7 +616,7 @@ export const graphNodeLibrary: Record = { height: 44, shape: 'cycle-start', ports: { - groups: {right: { position: 'right', attrs: portAttrs }}, + groups: {right: { position: 'right', markup: portMarkup, attrs: portAttrs }}, items: [{ group: 'right' }], }, }, @@ -597,7 +625,7 @@ export const graphNodeLibrary: Record = { height: 44, shape: 'add-node', ports: { - groups: {left: { position: 'left', attrs: portAttrs }}, + groups: {left: { position: 'left', markup: portMarkup, attrs: portAttrs }}, items: [{ group: 'left' }], }, }, @@ -615,7 +643,7 @@ export const graphNodeLibrary: Record = { height: 44, shape: 'cycle-start', ports: { - groups: {right: { position: 'right', attrs: portAttrs }}, + groups: {right: { position: 'right', markup: portMarkup, attrs: portAttrs }}, items: [{ group: 'right' }], }, }, @@ -624,7 +652,7 @@ export const graphNodeLibrary: Record = { height: 44, shape: 'add-node', ports: { - groups: {left: { position: 'left', attrs: portAttrs }}, + groups: {left: { position: 'left', markup: portMarkup, attrs: portAttrs }}, items: [{ group: 'left' }], }, } diff --git a/web/src/views/Workflow/hooks/useWorkflowGraph.ts b/web/src/views/Workflow/hooks/useWorkflowGraph.ts index dc7001e5..ce01d103 100644 --- a/web/src/views/Workflow/hooks/useWorkflowGraph.ts +++ b/web/src/views/Workflow/hooks/useWorkflowGraph.ts @@ -5,7 +5,7 @@ import { App } from 'antd' import { Graph, Node, MiniMap, Snapline, Clipboard, Keyboard, type Edge } from '@antv/x6'; import { register } from '@antv/x6-react-shape'; -import { nodeRegisterLibrary, graphNodeLibrary, nodeLibrary } from '../constant'; +import { nodeRegisterLibrary, graphNodeLibrary, nodeLibrary, portMarkup, portAttrs } from '../constant'; import type { WorkflowConfig, NodeProperties } from '../types'; import { getWorkflowConfig, saveWorkflowConfig } from '@/api/application' import type { PortMetadata } from '@antv/x6/lib/model/port'; @@ -39,7 +39,6 @@ export interface UseWorkflowGraphReturn { export const edge_color = '#155EEF'; const edge_selected_color = '#4DA8FF' - export const useWorkflowGraph = ({ containerRef, miniMapRef, @@ -128,12 +127,6 @@ export const useWorkflowGraph = ({ const baseHeight = 88; const newHeight = baseHeight + (totalPorts - 2) * 30; - const portAttrs = { - circle: { - r: 4, magnet: true, stroke: '#155EEF', strokeWidth: 2, fill: '#155EEF', position: { top: 22 } - }, - }; - const portItems: PortMetadata[] = [ { group: 'left' }, { group: 'right', id: 'CASE1', args: { dy: 24 }, attrs: { text: { text: 'IF', fontSize: 12, fill: '#5B6167' }} } @@ -157,8 +150,8 @@ export const useWorkflowGraph = ({ nodeConfig.ports = { groups: { - right: { position: 'right', attrs: portAttrs }, - left: { position: 'left', attrs: portAttrs }, + right: { position: 'right', markup: portMarkup, attrs: portAttrs }, + left: { position: 'left', markup: portMarkup, attrs: portAttrs }, }, items: portItems }; @@ -172,12 +165,6 @@ export const useWorkflowGraph = ({ const baseHeight = 88; const newHeight = baseHeight + (categoryCount - 1) * 30; - const portAttrs = { - circle: { - r: 4, magnet: true, stroke: '#155EEF', strokeWidth: 2, fill: '#155EEF', position: { top: 22 } - }, - }; - const portItems: PortMetadata[] = [ { group: 'left' } ]; @@ -194,8 +181,8 @@ export const useWorkflowGraph = ({ nodeConfig.ports = { groups: { - right: { position: 'right', attrs: portAttrs }, - left: { position: 'left', attrs: portAttrs }, + right: { position: 'right', markup: portMarkup, attrs: portAttrs }, + left: { position: 'left', markup: portMarkup, attrs: portAttrs }, }, items: portItems }; @@ -205,16 +192,10 @@ export const useWorkflowGraph = ({ // 如果是http-request节点,检查error_handle.method配置 if (type === 'http-request' && (config as any).error_handle?.method === 'branch') { - const portAttrs = { - circle: { - r: 4, magnet: true, stroke: '#155EEF', strokeWidth: 2, fill: '#155EEF', position: { top: 22 } - }, - }; - nodeConfig.ports = { groups: { - right: { position: 'right', attrs: portAttrs }, - left: { position: 'left', attrs: portAttrs }, + right: { position: 'right', markup: portMarkup, attrs: portAttrs }, + left: { position: 'left', markup: portMarkup, attrs: portAttrs }, }, items: [ { group: 'left' }, @@ -344,13 +325,15 @@ export const useWorkflowGraph = ({ cell: targetCell.id, port: targetPorts.find((port: any) => port.group === 'left')?.id || 'left' }, + connector: { name: 'smooth' }, attrs: { line: { stroke: edge_color, strokeWidth: 1, targetMarker: { - name: 'block', - size: 8, + name: 'diamond', + width: 4, + height: 4, }, }, }, @@ -703,7 +686,7 @@ export const useWorkflowGraph = ({ // router: 'orth', // router: 'manhattan', connector: { - name: 'rounded', + name: 'smooth', args: { radius: 8, }, @@ -723,6 +706,11 @@ export const useWorkflowGraph = ({ line: { stroke: edge_color, strokeWidth: 1, + targetMarker: { + name: 'diamond', + width: 4, + height: 4, + }, }, }, zIndex: 0, From cdcac262a3aec86038d08d8a92fd4364581c414c Mon Sep 17 00:00:00 2001 From: Eternity <1533512157@qq.com> Date: Wed, 14 Jan 2026 12:24:41 +0800 Subject: [PATCH 2/4] fix(workflow): fix LLM node streaming execution configuration error --- api/app/core/workflow/nodes/llm/node.py | 1 + 1 file changed, 1 insertion(+) diff --git a/api/app/core/workflow/nodes/llm/node.py b/api/app/core/workflow/nodes/llm/node.py index 6395d3b8..bfa1b99f 100644 --- a/api/app/core/workflow/nodes/llm/node.py +++ b/api/app/core/workflow/nodes/llm/node.py @@ -226,6 +226,7 @@ class LLMNode(BaseNode): Yields: 文本片段(chunk)或完成标记 """ + self.typed_config = LLMNodeConfig(**self.config) from langgraph.config import get_stream_writer llm, prompt_or_messages = self._prepare_llm(state, True) From c166615ec8bb0d843428284bb1e1b7804ccd29fa Mon Sep 17 00:00:00 2001 From: lixinyue11 <94037597+lixinyue11@users.noreply.github.com> Date: Wed, 14 Jan 2026 14:11:05 +0800 Subject: [PATCH 3/4] Fix/memory bug fix (#107) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 图谱数据量限制数量去掉 * 图谱数据量限制数量去掉 --- api/app/services/user_memory_service.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/api/app/services/user_memory_service.py b/api/app/services/user_memory_service.py index 67a6ab2c..59bbc211 100644 --- a/api/app/services/user_memory_service.py +++ b/api/app/services/user_memory_service.py @@ -1416,11 +1416,10 @@ async def analytics_graph_data( elementId(n) as id, labels(n)[0] as label, properties(n) as properties - LIMIT $limit """ node_params = { "group_id": end_user_id, - "limit": limit + # "limit": limit } # 执行节点查询 @@ -1567,9 +1566,9 @@ async def _extract_node_properties(label: str, properties: Dict[str, Any],node_ allowed_fields = field_whitelist.get(label, []) # 如果没有定义白名单,返回空字典(或者可以返回所有字段) - if not allowed_fields: - # 对于未定义的节点类型,只返回基本字段 - allowed_fields = ["name", "created_at", "caption"] + # if not allowed_fields: + # # 对于未定义的节点类型,只返回基本字段 + # allowed_fields = ["name", "created_at", "caption"] count_neo4j=f"""MATCH (n)-[r]-(m) WHERE elementId(n) ="{node_id}" RETURN count(r) AS rel_count;""" node_results = await (_neo4j_connector.execute_query(count_neo4j)) # 提取白名单中的字段 @@ -1621,6 +1620,5 @@ def _clean_neo4j_value(value: Any) -> Any: return str(value) except Exception: return None - # 返回原始值 - return value + return value \ No newline at end of file From 5ec9ac1fbaca1d40a73d4f9efe0df5cf7550c473 Mon Sep 17 00:00:00 2001 From: Mark Date: Wed, 14 Jan 2026 14:17:09 +0800 Subject: [PATCH 4/4] [fix] Object of type UUID is not JSON serializable --- api/app/controllers/public_share_controller.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/app/controllers/public_share_controller.py b/api/app/controllers/public_share_controller.py index 02c73718..354a58ef 100644 --- a/api/app/controllers/public_share_controller.py +++ b/api/app/controllers/public_share_controller.py @@ -583,7 +583,7 @@ async def chat( event_data = event.get("data", {}) # 转换为标准 SSE 格式(字符串) - sse_message = f"event: {event_type}\ndata: {json.dumps(event_data)}\n\n" + sse_message = f"event: {event_type}\ndata: {json.dumps(event_data, default=str, ensure_ascii=False)}\n\n" yield sse_message return StreamingResponse(