@digitalsee-ai/rcs 2.0.0-beta8 → 2.0.0-pre1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/components/digitalsee/workflow/Canvas/hooks/useWorkflowCanvasState.d.ts +0 -2
  2. package/dist/components/digitalsee/workflow/Canvas/utils.d.ts +8 -1
  3. package/dist/components/digitalsee/workflow/Nodes/DeclaredNode.d.ts +4 -0
  4. package/dist/components/digitalsee/workflow/NodesConfig/components/FormFieldRenderer/fields/TextField/index.d.ts +2 -0
  5. package/dist/components/digitalsee/workflow/NodesConfig/components/FormFieldRenderer/fields/WebhookLabelField/index.d.ts +2 -2
  6. package/dist/components/digitalsee/workflow/NodesConfig/context.d.ts +13 -0
  7. package/dist/components/digitalsee/workflow/NodesConfig/useClearVariableTargetOnFormMouseDown.d.ts +15 -0
  8. package/dist/components/digitalsee/workflow/NodesConfig/useVariableActiveTarget.d.ts +13 -0
  9. package/dist/components/digitalsee/workflow/Panels/ModernNodeSelectorPanel/hooks/useNavigation.d.ts +1 -0
  10. package/dist/components/digitalsee/workflow/api/dip.types.d.ts +1 -1
  11. package/dist/components/digitalsee/workflow/hooks/useCanvasNavigate.d.ts +10 -0
  12. package/dist/components/digitalsee/workflow/hooks/useVariables.d.ts +7 -1
  13. package/dist/components/digitalsee/workflow/index.d.ts +12 -2
  14. package/dist/components/digitalsee/workflow/store/workflowSlice.d.ts +1 -3
  15. package/dist/components/digitalsee/workflow/types/engine.d.ts +8 -0
  16. package/dist/components/digitalsee/workflow/utils/nodeCommon.d.ts +5 -0
  17. package/dist/components/digitalsee/workflow/utils/nodeHandleLayout.d.ts +21 -24
  18. package/dist/components/digitalsee/workflow/utils/onNodeRemoveHook.d.ts +4 -6
  19. package/dist/components/dynamic-form/DynamicForm.d.ts +3 -1
  20. package/dist/components/dynamic-form/components/ValueModeWrapper/index.d.ts +1 -1
  21. package/dist/components/dynamic-form/components/ValueModeWrapper/valueModeConfig.d.ts +2 -0
  22. package/dist/components/dynamic-form/index.d.ts +0 -3
  23. package/dist/{index-DBoa8kIP.mjs → index-CRXMCErN.mjs} +28 -28
  24. package/dist/{index-DJvNGsCf.mjs → index-Z4QbEX_e.mjs} +40346 -40709
  25. package/dist/rcs.css +1 -1
  26. package/dist/rcs.es.js +53 -56
  27. package/dist/rcs.umd.js +77 -84
  28. package/package.json +1 -1
  29. package/dist/components/dynamic-form/components/SelectWithExpression/index.d.ts +0 -25
  30. package/dist/components/dynamic-form/components/VariableInput/index.d.ts +0 -26
  31. package/dist/components/dynamic-form/components/VariableInput/utils.d.ts +0 -38
  32. package/dist/components/dynamic-form/components/VariableTextarea/index.d.ts +0 -10
@@ -30,8 +30,6 @@ export interface WorkflowCanvasStateResult {
30
30
  hasTriggerNode: boolean;
31
31
  /** 画布是否为 MCP Server 触发画布(由 trigger 节点决定)。 */
32
32
  isMcpServerCanvas: boolean;
33
- /** 用户是否手动删除过 trigger 节点(手动删除后不再展示 NodePlaceholder)。 */
34
- triggerDeleted: boolean;
35
33
  loading: boolean;
36
34
  setLoading: (v: boolean) => void;
37
35
  debugVisible: boolean;
@@ -4,5 +4,12 @@ type GetHelperLinesResult = {
4
4
  vertical?: number;
5
5
  snapPosition: Partial<XYPosition>;
6
6
  };
7
- export declare function getHelperLines(change: NodePositionChange, nodes: Node[], distance?: number): GetHelperLinesResult;
7
+ /**
8
+ * 计算拖拽节点的对齐辅助线(在 onNodesChange 中调用)。
9
+ *
10
+ * 遍历所有其它节点,分别在 x 轴(x1/x2 即左右边缘)与 y 轴(y1/y2 即上下边缘)上
11
+ * 取与当前节点最接近的边缘组合:无论距离多远,参考线始终返回最接近的对齐位置;
12
+ * 仅当距离小于 snapDistance 时才同时返回吸附位置。
13
+ */
14
+ export declare function getHelperLines(change: NodePositionChange, nodes: Node[], snapDistance?: number): GetHelperLinesResult;
8
15
  export {};
@@ -1,6 +1,10 @@
1
1
  import { NodeType } from '../types/Node';
2
2
  import { Node, NodeProps } from '@xyflow/react';
3
3
  import { default as React } from 'react';
4
+ /** Switch 节点高度规则:每个输出端口 30px、基础高度 72px、超过 2 个输出开始撑高。 */
5
+ export declare const SWITCH_LEGACY_HEIGHT_PER_OUTPUT = 30;
6
+ export declare const SWITCH_LEGACY_HEIGHT_BASE = 72;
7
+ export declare const SWITCH_OUTPUT_THRESHOLD = 2;
4
8
  /**
5
9
  * 解析 ReactFlow `node.type` 字符串,拆出 NodeType + nodeKey + version。
6
10
  *
@@ -9,6 +9,8 @@ interface TextFieldProps extends IFieldSuperProps {
9
9
  textAreaMode?: boolean;
10
10
  disabled?: boolean;
11
11
  disableIDE?: boolean;
12
+ onFocus?: () => void;
13
+ onBlur?: () => void;
12
14
  }
13
15
  export declare const TextField: (props: TextFieldProps) => import("react/jsx-runtime").JSX.Element;
14
16
  export {};
@@ -1,6 +1,6 @@
1
- import { FormInstance } from 'antd';
2
- import { ConfigSchema } from '../../../../define/actions';
3
1
  import { IFieldSuperProps } from '../super';
2
+ import { ConfigSchema } from '../../../../define/actions';
3
+ import { FormInstance } from 'antd';
4
4
  interface WebhookLabelFieldProps extends IFieldSuperProps {
5
5
  form: FormInstance;
6
6
  configList: ConfigSchema[];
@@ -2,3 +2,16 @@ import { EventEmitter } from 'ahooks/lib/useEventEmitter';
2
2
  export declare const DrawerContext: import('react').Context<{
3
3
  event$: EventEmitter<any>;
4
4
  }>;
5
+ /**
6
+ * 统一的“当前变量插入目标 id”上下文。
7
+ *
8
+ * 由 NodesConfig/index.tsx 顶部的 Provider 维护:
9
+ * - classic 机制:订阅 event$ 的 setCurrentInputId 事件
10
+ * - 新版机制:读取 VariableSelectorStateContext.activeFieldId
11
+ *
12
+ * 字段组件通过 useVariableActiveTarget(id) 判断自己是否正处于
13
+ * “会接收变量追加”的状态,从而渲染高亮样式。
14
+ */
15
+ export declare const VariableActiveTargetContext: import('react').Context<{
16
+ activeInputId: string;
17
+ }>;
@@ -0,0 +1,15 @@
1
+ import { default as React } from 'react';
2
+ /**
3
+ * 供 .workflow-node-form-shell 使用的 onMouseDownCapture 处理器。
4
+ *
5
+ * 语义:鼠标在表单内容上按下、且落点不在“当前仍聚焦的表达式编辑器”内部时,
6
+ * 说明用户已离开那个输入框 —— 此时清空两套活动变量目标:
7
+ * 1) classic:event$.emit({type:'setCurrentInputId', currentInputId:''})
8
+ * 2) 新版 VariableSelector.activeFieldId:deactivateField()
9
+ * 防止变量被追加进“非最后一次交互”的输入框。
10
+ *
11
+ * 守卫即“区分是不是输入框自己触发的点击”:落点在 document.activeElement 内部
12
+ * (仍在编辑器里移动光标 / 点变量 tag)时不清除,输入框自身的 onFocus 会在
13
+ * mousedown 默认动作阶段重新武装目标。变量面板渲染在 shell DOM 之外,永不触发。
14
+ */
15
+ export declare function useClearVariableTargetOnFormMouseDown(): (e: React.MouseEvent) => void;
@@ -0,0 +1,13 @@
1
+ /** 命中高亮时加到字段最外层容器的 class 名 */
2
+ export declare const VARIABLE_TARGET_ACTIVE_CLASS = "workflow-variable-target--active";
3
+ /**
4
+ * 判断当前字段(inputId)是否是“活动变量插入目标”。
5
+ *
6
+ * 数据源是 NodesConfig 顶层的 VariableActiveTargetContext:
7
+ * classic setCurrentInputId 与新版 VariableSelector.activeFieldId
8
+ * 已被统一汇总,任一变化都会让命中的字段重渲染以获得高亮。
9
+ *
10
+ * @param inputId 字段自身用于接收 insert 事件的 id(genInputId 生成)
11
+ * @returns 当前是否处于活动变量目标状态
12
+ */
13
+ export declare function useVariableActiveTarget(inputId: string): boolean;
@@ -15,6 +15,7 @@ export declare const useNavigation: ({ categories, categoriesReady, initialCateg
15
15
  categoryNodes: NodeTypeItem[];
16
16
  currentCategory: CategoryItem;
17
17
  isLoadingNodes: boolean;
18
+ isLoadingMore: boolean;
18
19
  isRealTriggerMode: boolean;
19
20
  isAIToolMode: boolean;
20
21
  isBuiltinMCPMode: boolean;
@@ -518,7 +518,7 @@ export interface DipPortSchema {
518
518
  /**
519
519
  * 端口在节点边框上的渲染位置,对齐 ReactFlow `Position` 枚举字符串值。
520
520
  *
521
- * 缺省时由前端 `ACTION_KEY_HANDLE_LAYOUT` 兜底,再缺省为 Left/Right。
521
+ * 缺省为 Left/Right;MCP Server 画布会再强制 Left→Top、Right→Bottom
522
522
  * 仅影响视觉布局,不参与连线协议匹配。
523
523
  */
524
524
  position?: 'left' | 'top' | 'right' | 'bottom';
@@ -0,0 +1,10 @@
1
+ import { CanvasNavigate } from '../types/engine';
2
+ /**
3
+ * 画布 URL 跳转统一出口。
4
+ *
5
+ * 优先级:
6
+ * 1. http(s) 开头的外部绝对链接 → 库内直接 window.open,不打扰宿主;
7
+ * 2. 相对路径(站内路由)→ 由宿主 onNavigate 决定如何跳转;
8
+ * 3. 宿主未提供 onNavigate 时 → 回退到历史行为(window.open / history.push)。
9
+ */
10
+ export declare const useCanvasNavigate: () => CanvasNavigate;
@@ -28,12 +28,18 @@ interface UseVariablesOptions {
28
28
  enabled?: boolean;
29
29
  includeGlobalVariables?: boolean;
30
30
  }
31
- interface UseVariablesReturn {
31
+ export interface UseVariablesReturn {
32
32
  globalVariables: EnhancedGlobalVariable[];
33
33
  nodeVariables: EnhancedVarDatum[];
34
34
  isLoading: boolean;
35
+ isGlobalLoading: boolean;
36
+ isNodeLoading: boolean;
35
37
  error: Error | null;
38
+ globalError: Error | null;
39
+ nodeError: Error | null;
36
40
  refresh: () => void;
41
+ refreshGlobal: () => void;
42
+ refreshNode: () => void;
37
43
  }
38
44
  /**
39
45
  * 加载 classic 变量面板需要展示的全局变量和节点变量。
@@ -1,6 +1,6 @@
1
1
  import { WorkflowLoadResponse } from './Canvas/constants';
2
2
  import { default as defaultCanvasEngineConfig } from './config/defaultCanvasEngineConfig';
3
- import { CanvasEngineConfig, DeepPartial, WorkflowCanvasMode, CanvasAPI, HistoryNavigator, HttpClient } from './types/engine';
3
+ import { CanvasEngineConfig, DeepPartial, WorkflowCanvasMode, CanvasAPI, CanvasNavigate, HistoryNavigator, HttpClient } from './types/engine';
4
4
  import { mergeConfig } from './utils/mergeConfig';
5
5
  import { FlowDraftPayload } from './types/flowVersion';
6
6
  import { LocaleType } from '../../../locales';
@@ -59,6 +59,16 @@ export interface DigitalseeWorkFlowProps {
59
59
  * @description 用于处理页面导航,可传入 React Router 的 history 对象
60
60
  */
61
61
  history?: HistoryNavigator;
62
+ /**
63
+ * 画布 URL 跳转回调
64
+ *
65
+ * @description 画布内部需要跳转站内页面(告警日志 / 子流程 / OAuth 应用管理等相对路径)时调用,
66
+ * 由宿主决定如何处理。http(s) 外部链接由画布直接打开、不经此回调。未提供时画布回退到默认跳转行为。
67
+ *
68
+ * @param url 目标 URL
69
+ * @param openInNewTab 是否需要新标签页打开
70
+ */
71
+ onNavigate?: CanvasNavigate;
62
72
  /**
63
73
  * 宿主响应连接流下线逻辑
64
74
  * @param workflowId
@@ -102,7 +112,7 @@ export { useWorkflow } from './hooks/useWorkflow';
102
112
  export { default as AiFlowNodeStatusBadge, type NodeStatusBadgeProps as AiFlowNodeStatusBadgeProps, } from './Nodes/components/NodeStatusBadge';
103
113
  export { default as NodeFactory } from './Nodes/NodeFactory';
104
114
  export * from './types/Edge';
105
- export type { CanvasAPI, CanvasEngineConfig, DeepPartial, HistoryNavigator, HttpClient, } from './types/engine';
115
+ export type { CanvasAPI, CanvasEngineConfig, CanvasNavigate, DeepPartial, HistoryNavigator, HttpClient, } from './types/engine';
106
116
  export * from './types/flowVersion';
107
117
  export * from './types/Node';
108
118
  export * from './types/Workflow';
@@ -24,8 +24,6 @@ export interface WorkflowState {
24
24
  isLocked: boolean;
25
25
  executionControl: ExecutionControlState | null;
26
26
  flowMetadata: Record<string, unknown>;
27
- /** 用户是否手动删除过 trigger 节点(手动删除后不再展示 NodePlaceholder) */
28
- triggerDeleted: boolean;
29
27
  }
30
28
  export declare const setWorkflowId: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<string, "workflow/setWorkflowId">, setWorkflowName: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<string, "workflow/setWorkflowName">, applyNodesChanges: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<NodeChange[], "workflow/applyNodesChanges">, applyEdgesChanges: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<EdgeChange[], "workflow/applyEdgesChanges">, addConnection: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<Connection, "workflow/addConnection">, addNode: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<{
31
29
  type: NodeType;
@@ -43,6 +41,6 @@ export declare const setWorkflowId: import('@reduxjs/toolkit').ActionCreatorWith
43
41
  }, "workflow/updateEdge">, setNodes: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<Node<NodeData>[], "workflow/setNodes">, setEdges: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<Edge<EdgeData>[], "workflow/setEdges">, updateNode: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<{
44
42
  id: string;
45
43
  data: Partial<NodeData>;
46
- }, "workflow/updateNode">, setFlowOpStatus: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<FlowStatus, "workflow/setFlowOpStatus">, refreshFlow: import('@reduxjs/toolkit').ActionCreatorWithoutPayload<"workflow/refreshFlow">, setCurrentNodeConfigVisibleId: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<string, "workflow/setCurrentNodeConfigVisibleId">, setLocked: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<boolean, "workflow/setLocked">, setExecutionControl: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<ExecutionControlState, "workflow/setExecutionControl">, setFlowMetadata: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<Record<string, unknown>, "workflow/setFlowMetadata">, setTriggerDeleted: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<boolean, "workflow/setTriggerDeleted">, resetFlow: import('@reduxjs/toolkit').ActionCreatorWithoutPayload<"workflow/resetFlow">, executeAutoSave: import('@reduxjs/toolkit').ActionCreatorWithoutPayload<"workflow/executeAutoSave">, setFlowVersionMeta: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<FlowVersionStatusVO, "workflow/setFlowVersionMeta">;
44
+ }, "workflow/updateNode">, setFlowOpStatus: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<FlowStatus, "workflow/setFlowOpStatus">, refreshFlow: import('@reduxjs/toolkit').ActionCreatorWithoutPayload<"workflow/refreshFlow">, setCurrentNodeConfigVisibleId: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<string, "workflow/setCurrentNodeConfigVisibleId">, setLocked: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<boolean, "workflow/setLocked">, setExecutionControl: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<ExecutionControlState, "workflow/setExecutionControl">, setFlowMetadata: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<Record<string, unknown>, "workflow/setFlowMetadata">, resetFlow: import('@reduxjs/toolkit').ActionCreatorWithoutPayload<"workflow/resetFlow">, executeAutoSave: import('@reduxjs/toolkit').ActionCreatorWithoutPayload<"workflow/executeAutoSave">, setFlowVersionMeta: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<FlowVersionStatusVO, "workflow/setFlowVersionMeta">;
47
45
  declare const _default: import('@reduxjs/toolkit').Reducer<WorkflowState>;
48
46
  export default _default;
@@ -11,6 +11,13 @@ export interface HistoryNavigator {
11
11
  goForward(): void;
12
12
  listen?(listener: (location: any, action: any) => void): () => void;
13
13
  }
14
+ /**
15
+ * 画布内部 URL 跳转回调,由宿主决定如何处理(同页路由 / 新标签 / 拦截等)。
16
+ *
17
+ * @param url 目标 URL
18
+ * @param openInNewTab 是否需要新标签页打开(原 window.open 场景)
19
+ */
20
+ export type CanvasNavigate = (url: string, openInNewTab?: boolean) => void;
14
21
  /**
15
22
  * 画布模式(单一事实源):取代散落的 readOnly / preview / previewId / appFlowMode 参数。
16
23
  *
@@ -32,6 +39,7 @@ export interface CanvasEngineConfig {
32
39
  nodeConfigPanel: NodeConfigPanelConfig;
33
40
  httpClient?: HttpClient;
34
41
  history?: HistoryNavigator;
42
+ onNavigate?: CanvasNavigate;
35
43
  scene?: string;
36
44
  }
37
45
  /**
@@ -1,5 +1,10 @@
1
1
  import { Node } from '@xyflow/react';
2
2
  import { DipPortSchema } from '../api/dip.types';
3
+ /**
4
+ * 判断 type 是否为动态节点(nodePackage 节点):
5
+ * 描述符含 `@`(形如 `nodeType@nodeKey@version`),不含 `@` 的为经典节点。
6
+ */
7
+ export declare const isDynamicType: (type: string | undefined) => boolean;
3
8
  export declare const getNodeHandleProtocol: (node: Node, handleName: string) => string | null;
4
9
  export declare const getNodeHandle: (node: Node, handleName: string) => DipPortSchema | null;
5
10
  export declare const getNodeHandleByProtocol: (node: Node, protocol: string, isInput: boolean, preferredName?: string) => DipPortSchema | null;
@@ -4,44 +4,42 @@ export interface NodeHandlePositions {
4
4
  sources: Position[];
5
5
  targets: Position[];
6
6
  }
7
- interface ActionKeyHandleLayout {
8
- source: Position;
9
- target: Position;
7
+ export interface NodeHandleLayoutOptions {
8
+ /** MCP Server 画布:强制 Left→Top、Right→Bottom。 */
9
+ isMcpServerCanvas?: boolean;
10
10
  }
11
11
  /**
12
- * NodePackage 节点端口 position 的过渡手工映射。
13
- *
14
- * 字段说明:
15
- * - source:source handle 在节点边框上的位置
16
- * - target:target handle 在节点边框上的位置
17
- *
18
- * 优先级:`DipPortSchema.position` > `ACTION_KEY_HANDLE_LAYOUT` > 缺省 Left/Right。
19
- * 后续 `DipPortSchema.position` 全量铺开后即可删除本表。
12
+ * MCP Server 画布端口位置映射:Left → Top,Right → Bottom;Top/Bottom 保持不变。
13
+ */
14
+ export declare function remapPositionForMcpCanvas(position: Position): Position;
15
+ /**
16
+ * 节点列表是否构成 MCP Server 画布(存在 MCP Server 触发节点)。
20
17
  */
21
- export declare const ACTION_KEY_HANDLE_LAYOUT: Record<string, ActionKeyHandleLayout>;
18
+ export declare function detectIsMcpServerCanvas(nodes: Array<Pick<Node, 'type' | 'data'>>): boolean;
22
19
  /**
23
20
  * 给定一个 ReactFlow 节点,返回它所有 source / target handle 的 `Position`。
24
21
  *
25
22
  * 数据源优先级:
26
- * 1. NodePackage 节点 → `DipPortSchema.position` > `ACTION_KEY_HANDLE_LAYOUT` > 缺省 Left/Right
23
+ * 1. NodePackage 节点 → `DipPortSchema.position` > 缺省 Left/Right
27
24
  * 2. 经典节点 → `nodeTypeRegistry` 中的 legacy handles
28
25
  * 3. 兜底:返回空数组
29
26
  *
30
- * 该函数只读、不发起网络请求;schema 缺失时按 schema 字段的 `position` 映射表 Left/Right 降级。
27
+ * `isMcpServerCanvas` 为真时,再将 LeftTop、Right→Bottom。
28
+ * 该函数只读、不发起网络请求。
31
29
  */
32
- export declare function getNodeHandlePositions(node: Node): NodeHandlePositions;
30
+ export declare function getNodeHandlePositions(node: Node, options?: NodeHandleLayoutOptions): NodeHandlePositions;
33
31
  /**
34
32
  * 节点是否参与垂直布局(子节点在父节点下方 / 上方)。
35
33
  *
36
34
  * 判定:节点的 source 或 target handle 中任一处于 Top/Bottom 即视为垂直。
37
35
  */
38
- export declare function isVerticalLayoutNode(node: Node): boolean;
36
+ export declare function isVerticalLayoutNode(node: Node, options?: NodeHandleLayoutOptions): boolean;
39
37
  /**
40
38
  * 节点是否参与水平布局(子节点在父节点右侧 / 左侧)。
41
39
  *
42
40
  * 判定:节点的 source 或 target handle 中任一处于 Left/Right 即视为水平。
43
41
  */
44
- export declare function isHorizontalLayoutNode(node: Node): boolean;
42
+ export declare function isHorizontalLayoutNode(node: Node, options?: NodeHandleLayoutOptions): boolean;
45
43
  /**
46
44
  * 按边的 target handle 位置判定布局方向。
47
45
  *
@@ -50,12 +48,12 @@ export declare function isHorizontalLayoutNode(node: Node): boolean;
50
48
  * - target handle 在 Left/Right → 'horizontal'
51
49
  * - 缺省 → null(调用方自行决定 fallback)
52
50
  */
53
- export declare function getEdgeLayoutDirection(edge: Pick<Edge, 'source' | 'target' | 'sourceHandle' | 'targetHandle'>, sourceNode?: Node | null, targetNode?: Node | null): LayoutDirection | null;
51
+ export declare function getEdgeLayoutDirection(edge: Pick<Edge, 'source' | 'target' | 'sourceHandle' | 'targetHandle'>, sourceNode?: Node | null, targetNode?: Node | null, options?: NodeHandleLayoutOptions): LayoutDirection | null;
54
52
  /**
55
53
  * 取边 source handle 在节点边框上的 `Position`(供连线风格 / 区间重叠判定使用)。
56
54
  * 无 sourceHandle 时取第一个 source handle;找不到匹配时返回 undefined,调用方按水平处理。
57
55
  */
58
- export declare function getEdgeSourcePosition(edge: Pick<Edge, 'sourceHandle'>, sourceNode: Node): Position | undefined;
56
+ export declare function getEdgeSourcePosition(edge: Pick<Edge, 'sourceHandle'>, sourceNode: Node, options?: NodeHandleLayoutOptions): Position | undefined;
59
57
  /**
60
58
  * 节点是否拥有 Top 输入 handle,用于区分主流程节点与垂直子节点。
61
59
  *
@@ -63,21 +61,20 @@ export declare function getEdgeSourcePosition(edge: Pick<Edge, 'sourceHandle'>,
63
61
  * Top 入桩(典型 AI 子节点升级后通过 Bottom 入桩连接到父节点 ai_* 桩,但若
64
62
  * 仍保留 Top 形态即可识别为"子节点")。
65
63
  */
66
- export declare function hasTopInputHandle(node: Node): boolean;
64
+ export declare function hasTopInputHandle(node: Node, options?: NodeHandleLayoutOptions): boolean;
67
65
  /**
68
66
  * 节点是否拥有 Top source handle。
69
67
  *
70
68
  * 旧版 `calculateNodePosition` 用 `n.type !== AI_SUB_NODE` 过滤主流程节点;
71
69
  * 现在等价语义改为:节点 source 不在 Top(说明它不向上输出,不会作为垂直子节点)。
72
70
  */
73
- export declare function hasTopSourceHandle(node: Node): boolean;
71
+ export declare function hasTopSourceHandle(node: Node, options?: NodeHandleLayoutOptions): boolean;
74
72
  /**
75
73
  * 节点是否属于某个父节点的垂直子布局(向上发送 → 自己即 child)。
76
74
  */
77
- export declare function isVerticalLayoutChild(node: Node): boolean;
75
+ export declare function isVerticalLayoutChild(node: Node, options?: NodeHandleLayoutOptions): boolean;
78
76
  /**
79
77
  * 画布整体方向:按节点 source handle 的方向统计,少数服从多数。
80
- * 缺省(无法判定或平票)走水平。
78
+ * MCP Server 画布强制垂直;缺省(无法判定或平票)走水平。
81
79
  */
82
80
  export declare function inferCanvasDirection(nodes: Node[]): LayoutDirection;
83
- export {};
@@ -1,13 +1,11 @@
1
1
  import { Node } from '@xyflow/react';
2
- /** 删除命中该列表的 Trigger 节点时,级联清空整张画布(删除所有其他节点) */
2
+ /**
3
+ * 删除命中该列表的 Trigger 节点时,级联清空整张画布(删除所有其他节点)。
4
+ * MCP 画布 Trigger 删除时保留其它节点和连线,因此当前为空。
5
+ */
3
6
  export declare const TRIGGER_CASCADE_CLEAR_KEYS: readonly string[];
4
7
  /**
5
8
  * 判断本次待删除节点中是否包含需要级联清空的 Trigger 节点。
6
9
  * 若命中,返回画布上所有其他节点的 id,供调用方一并删除;否则返回空数组。
7
10
  */
8
11
  export declare const onNodeRemoveHook: (nodes: Node[], nodeIds: string[]) => string[];
9
- /**
10
- * 判断本次手动删除的节点中是否包含 trigger 节点。
11
- * 命中表示用户主动删除了画布触发节点,画布据此不再展示 NodePlaceholder。
12
- */
13
- export declare const isManualTriggerDeletion: (nodes: Node[], nodeIds: string[]) => boolean;
@@ -59,5 +59,7 @@ export type DynamicFormProps<T = Record<string, unknown>> = {
59
59
  maxExecutionDepth?: number;
60
60
  /** 是否启用事件系统调试日志(默认 false) */
61
61
  debugEvents?: boolean;
62
+ /**需要插在动态表单最前面的组件 */
63
+ preRender?: React.ReactNode;
62
64
  };
63
- export declare function DynamicForm<T extends Record<string, unknown>>({ schema, disabled: disabledProp, initialValues, onSubmit, onChange, onValuesObserved, submitLabel, showReset, resetLabel, onReset, form: externalForm, showSubmit, optionsLoader, nodeId, mcpMode, validateVariable, renderVariableTag, renderVariableTooltip, availableVariables, theme, customTheme, locale, prefixCls, events, customHandlers, maxExecutionDepth, debugEvents, }: DynamicFormProps<T>): import("react/jsx-runtime").JSX.Element;
65
+ export declare function DynamicForm<T extends Record<string, unknown>>({ schema, disabled: disabledProp, initialValues, onSubmit, onChange, onValuesObserved, submitLabel, showReset, resetLabel, onReset, form: externalForm, showSubmit, optionsLoader, nodeId, mcpMode, validateVariable, renderVariableTag, renderVariableTooltip, availableVariables, theme, customTheme, locale, prefixCls, events, customHandlers, maxExecutionDepth, debugEvents, preRender, }: DynamicFormProps<T>): import("react/jsx-runtime").JSX.Element;
@@ -5,7 +5,7 @@ export { ValueModeFieldScope, withInheritedValueModePolicy, } from './ValueModeF
5
5
  export { useValueModePolicyOptional, type ValueModePolicyContextValue, ValueModePolicyScope, type ValueModePolicyScopeProps, } from './ValueModePolicyContext';
6
6
  export { ValueModeSwitch, type ValueModeSwitchProps, } from './ValueModeSwitch';
7
7
  export type { ValueMode } from './valueModeConfig';
8
- export { getValueModePolicyConfig } from './valueModeConfig';
8
+ export { getValueModePolicyConfig, supportsValueMode, } from './valueModeConfig';
9
9
  export declare function isEncodedExpressionValue(value: unknown): value is string;
10
10
  /**
11
11
  * 将节点配置中的历史值统一转换为输入组件可消费的字符串。
@@ -9,3 +9,5 @@ export declare function getValueModePolicyConfig(policy: ValueModePolicy): {
9
9
  availableModes: ValueMode[];
10
10
  defaultMode: ValueMode;
11
11
  };
12
+ /** 策略是否启用值模式交互(切换器/表达式编码):EXPRESSION 与 BOTH 启用,TEXT 或未配置不启用 */
13
+ export declare function supportsValueMode(policy: ValueModePolicy | null | undefined): policy is Exclude<ValueModePolicy, 'TEXT'>;
@@ -1,9 +1,6 @@
1
1
  export * from './AntdProvider';
2
2
  export { AI_FILL_VALUE, AIFieldWrapper, type AIFieldWrapperProps, } from './components/AIFieldWrapper';
3
- export { type SelectValueMode, SelectWithExpression, type SelectWithExpressionProps, } from './components/SelectWithExpression';
4
3
  export { useValueModePolicyOptional, type ValueMode, ValueModeFieldScope, ValueModePolicyScope, ValueModeSwitch, type ValueModeSwitchProps, ValueModeWrapper, type ValueModeWrapperProps, withInheritedValueModePolicy, } from './components/ValueModeWrapper';
5
- export { VariableInput, type VariableInputProps, } from './components/VariableInput';
6
- export { VariableTextarea, type VariableTextareaProps, } from './components/VariableTextarea';
7
4
  export { useRegisterVariableField, useVariableSelector, useVariableSelectorActionsOptional, useVariableSelectorOptional, type VariableInfo, type VariableSelectorActionsValue, type VariableSelectorContextValue, VariableSelectorProvider, type VariableSelectorProviderProps, type VariableSelectorStateValue, } from './context/VariableSelectorContext';
8
5
  export * from './DynamicForm';
9
6
  export * from './DynamicFormContext';
@@ -1,14 +1,14 @@
1
1
  import { jsx as t, jsxs as v } from "react/jsx-runtime";
2
- import { D as T, V as L, e as x, i as P, t as l, f as R, d as O } from "./index-DJvNGsCf.mjs";
2
+ import { D as T, V as L, e as V, i as P, t as l, f as R, d as O } from "./index-Z4QbEX_e.mjs";
3
3
  import { useEventEmitter as B, useReactive as W, useSize as H } from "ahooks";
4
- import { FormattedMessage as I } from "react-intl";
4
+ import { FormattedMessage as $ } from "react-intl";
5
5
  import { CloseCircleFilled as A, CheckCircleFilled as K } from "@ant-design/icons";
6
6
  import { Button as M } from "antd";
7
7
  import * as z from "monaco-editor";
8
- import { useRef as k, useEffect as N } from "react";
8
+ import { useRef as I, useEffect as j } from "react";
9
9
  import { createPortal as q } from "react-dom";
10
10
  import J from "react-monaco-editor";
11
- const G = "_modalContainer_8inkd_5", Q = "_editorContainer_8inkd_16", U = "_sider_8inkd_25", X = "_main_8inkd_34", Y = "_header_8inkd_40", Z = "_editor_8inkd_16", w = {
11
+ const G = "_modalContainer_1ajlo_5", Q = "_editorContainer_1ajlo_16", U = "_sider_1ajlo_25", X = "_main_1ajlo_34", Y = "_header_1ajlo_40", Z = "_editor_1ajlo_16", w = {
12
12
  modalContainer: G,
13
13
  editorContainer: Q,
14
14
  sider: U,
@@ -30,14 +30,14 @@ function re(e) {
30
30
  }
31
31
  function se({ language: e = "javascript" }) {
32
32
  return /* @__PURE__ */ v("h2", { id: "workflow-online-ide-title", className: "workflow-online-ide-title", children: [
33
- /* @__PURE__ */ t(I, { id: "link.flow.code_editor" }),
33
+ /* @__PURE__ */ t($, { id: "link.flow.code_editor" }),
34
34
  " (Javascript)"
35
35
  ] });
36
36
  }
37
37
  function ae(e) {
38
38
  return /* @__PURE__ */ v("div", { className: "workflow-online-ide-toolbar", children: [
39
- /* @__PURE__ */ t(M, { size: "small", onClick: e.onCancel, icon: /* @__PURE__ */ t(A, {}), children: /* @__PURE__ */ t(I, { id: "app.common.word.cancel" }) }),
40
- /* @__PURE__ */ t(M, { type: "primary", size: "small", onClick: e.onFinish, icon: /* @__PURE__ */ t(K, {}), children: /* @__PURE__ */ t(I, { id: "app.common.word.finish" }) })
39
+ /* @__PURE__ */ t(M, { size: "small", onClick: e.onCancel, icon: /* @__PURE__ */ t(A, {}), children: /* @__PURE__ */ t($, { id: "app.common.word.cancel" }) }),
40
+ /* @__PURE__ */ t(M, { type: "primary", size: "small", onClick: e.onFinish, icon: /* @__PURE__ */ t(K, {}), children: /* @__PURE__ */ t($, { id: "app.common.word.finish" }) })
41
41
  ] });
42
42
  }
43
43
  const le = [{ trigger: "log", content: "console.log('$1');$2", desc: "输出日志" }, { trigger: "imp", content: "import $1 from '$2';$3" }, { trigger: "loop", content: `for (let $1=0; i< $2.length;i++) {
@@ -96,8 +96,8 @@ const ge = (e) => ({
96
96
  relatedInformation: e.relatedInformation,
97
97
  tags: e.tags
98
98
  });
99
- function V(e, i) {
100
- const o = x(i.getValue());
99
+ function N(e, i) {
100
+ const o = V(i.getValue());
101
101
  if (!o.length)
102
102
  return;
103
103
  const c = e.editor.getModelMarkers({ resource: i.uri }), s = /* @__PURE__ */ new Map();
@@ -149,8 +149,8 @@ function fe(e) {
149
149
  })
150
150
  });
151
151
  }
152
- function Ie(e) {
153
- const { open: i, nodeId: o, initialValue: c, language: s = "javascript", showVariableSidebar: a = !0 } = e, d = k(null), u = k([]), g = W({
152
+ function $e(e) {
153
+ const { open: i, nodeId: o, initialValue: c, language: s = "javascript", showVariableSidebar: a = !0 } = e, d = I(null), u = I([]), g = W({
154
154
  code: "",
155
155
  range: new z.Range(1, 1, 1, 1)
156
156
  }), b = (n, r) => {
@@ -158,9 +158,9 @@ function Ie(e) {
158
158
  const m = p.position, { lineNumber: f = 0, column: C = 0 } = m;
159
159
  g.range = new r.Range(f, C, f, C);
160
160
  }), d.current = n, n.focus(), g.code = n.getValue();
161
- const j = r.languages.registerHoverProvider(s, {
161
+ const S = r.languages.registerHoverProvider(s, {
162
162
  provideHover: (p, m) => new Promise((f) => {
163
- const h = x(p.getValue()).find(
163
+ const h = V(p.getValue()).find(
164
164
  (F) => P(F, m.lineNumber, m.column)
165
165
  );
166
166
  if (!h) {
@@ -183,28 +183,28 @@ function Ie(e) {
183
183
  const m = r.editor.onDidChangeMarkers((f) => {
184
184
  p || !f.some((C) => C.toString() === _.uri.toString()) || (p = !0, window.setTimeout(() => {
185
185
  try {
186
- V(r, _);
186
+ N(r, _);
187
187
  } finally {
188
188
  p = !1;
189
189
  }
190
190
  }, 0));
191
191
  });
192
- V(r, _), n.onDidDispose(() => m.dispose());
192
+ N(r, _), n.onDidDispose(() => m.dispose());
193
193
  }
194
- n.onDidDispose(() => j.dispose());
195
- }, E = (n) => {
194
+ n.onDidDispose(() => S.dispose());
195
+ }, x = (n) => {
196
196
  u.current.forEach((r) => {
197
197
  r.dispose();
198
198
  }), u.current = [pe(n, s)], s === "javascript" && u.current.push(fe(n));
199
199
  };
200
- N(
200
+ j(
201
201
  () => () => {
202
202
  u.current.forEach((n) => {
203
203
  n.dispose();
204
204
  }), u.current = [];
205
205
  },
206
206
  []
207
- ), N(() => {
207
+ ), j(() => {
208
208
  if (!i)
209
209
  return;
210
210
  const n = (r) => {
@@ -212,7 +212,7 @@ function Ie(e) {
212
212
  };
213
213
  return window.addEventListener("keydown", n), () => window.removeEventListener("keydown", n);
214
214
  }, [i, e.onCancel]);
215
- const S = (n) => {
215
+ const E = (n) => {
216
216
  const r = [
217
217
  {
218
218
  range: g.range,
@@ -221,10 +221,10 @@ function Ie(e) {
221
221
  }
222
222
  ];
223
223
  d.current && g.range && d.current.executeEdits("my-source", r);
224
- }, $ = () => {
224
+ }, k = () => {
225
225
  var n;
226
226
  (n = e.onFinish) == null || n.call(e, g.code);
227
- }, D = k(null), y = H(D);
227
+ }, D = I(null), y = H(D);
228
228
  return q(
229
229
  /* @__PURE__ */ t(
230
230
  "div",
@@ -240,17 +240,17 @@ function Ie(e) {
240
240
  re,
241
241
  {
242
242
  onCancel: e.onCancel,
243
- onFinish: $,
243
+ onFinish: k,
244
244
  editor: d.current,
245
245
  nodeId: o,
246
246
  open: i,
247
- onInsert: S
247
+ onInsert: E
248
248
  }
249
249
  ) }) : null,
250
250
  /* @__PURE__ */ v("div", { className: w.main, children: [
251
251
  /* @__PURE__ */ v("div", { className: w.header, children: [
252
252
  /* @__PURE__ */ t(se, { language: s }),
253
- /* @__PURE__ */ t(ae, { onCancel: e.onCancel, onFinish: $ })
253
+ /* @__PURE__ */ t(ae, { onCancel: e.onCancel, onFinish: k })
254
254
  ] }),
255
255
  /* @__PURE__ */ t("div", { className: w.editor, children: /* @__PURE__ */ t(
256
256
  J,
@@ -264,7 +264,7 @@ function Ie(e) {
264
264
  onChange: (n) => {
265
265
  g.code = n;
266
266
  },
267
- editorWillMount: E,
267
+ editorWillMount: x,
268
268
  editorDidMount: b
269
269
  },
270
270
  o
@@ -277,6 +277,6 @@ function Ie(e) {
277
277
  );
278
278
  }
279
279
  export {
280
- Ie as default
280
+ $e as default
281
281
  };
282
- //# sourceMappingURL=index-DBoa8kIP.mjs.map
282
+ //# sourceMappingURL=index-CRXMCErN.mjs.map