@fudanda/workflow 2.20261024.1-beta.2 → 2.20261109.1-beta.1
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.
- package/LICENSE +21 -21
- package/README.md +114 -114
- package/THIRD-PARTY-NOTICES.md +57 -57
- package/dist/{ai-markdown-esl-I5ck.js → ai-markdown--SqEglSn.js} +1 -2
- package/dist/chrome.js +46 -53
- package/dist/core.js +3 -3
- package/dist/{header-shortcuts-BQZuNfpA.js → header-shortcuts-BcwVJV2g.js} +1 -2
- package/dist/index.js +925 -1000
- package/dist/{schema-tree-CTM6hEdm.js → schema-tree-B4yoWS9A.js} +5 -10
- package/dist/{start-form-L6xw9phk.js → start-form-DWlAhZhs.js} +169 -335
- package/dist/styles.css +1 -1
- package/dist/{test-input-validation-CkORPCfm.js → test-input-validation-Ch9pS4X8.js} +1 -2
- package/package.json +108 -106
- package/vendor/coze/LICENSE-APACHE +177 -177
- package/vendor/coze/UPSTREAM.json +8 -8
- package/vendor/coze/original/base-test-button.tsx +22 -22
- package/vendor/coze/original/comment-container.tsx +68 -68
- package/vendor/coze/original/condition-container.tsx +60 -60
- package/vendor/coze/original/condition-tag.tsx +58 -58
- package/vendor/coze/original/coze-global.less +234 -234
- package/vendor/coze/original/create-loop-function-json.ts +134 -134
- package/vendor/coze/original/create-loop-function.ts +56 -56
- package/vendor/coze/original/end-registry.ts +41 -41
- package/vendor/coze/original/execute-result-panel.less +97 -97
- package/vendor/coze/original/execute-result-panel.tsx +171 -171
- package/vendor/coze/original/form-item.less +39 -39
- package/vendor/coze/original/form-item.tsx +200 -200
- package/vendor/coze/original/http-api-field.tsx +42 -42
- package/vendor/coze/original/http-form-render.tsx +102 -102
- package/vendor/coze/original/icon-add.svg +3 -3
- package/vendor/coze/original/icon-arrow-left.svg +3 -3
- package/vendor/coze/original/icon-auto-layout.svg +18 -18
- package/vendor/coze/original/icon-code.svg +13 -13
- package/vendor/coze/original/icon-condition.svg +12 -12
- package/vendor/coze/original/icon-database.svg +18 -18
- package/vendor/coze/original/icon-delete.svg +5 -5
- package/vendor/coze/original/icon-fullscreen.svg +9 -9
- package/vendor/coze/original/icon-more.svg +11 -11
- package/vendor/coze/original/icon-play-round-outlined.svg +8 -8
- package/vendor/coze/original/icon-plugin-tool.svg +6 -6
- package/vendor/coze/original/icon-standard-copy.svg +8 -8
- package/vendor/coze/original/icon-unknown.svg +7 -7
- package/vendor/coze/original/icon-var.svg +6 -6
- package/vendor/coze/original/icon-workflow-end.svg +5 -5
- package/vendor/coze/original/icon-workflow-start.svg +5 -5
- package/vendor/coze/original/icon-workflow.svg +21 -21
- package/vendor/coze/original/icon-workflows.svg +5 -5
- package/vendor/coze/original/if-form-meta.tsx +88 -88
- package/vendor/coze/original/logic-display.tsx +33 -33
- package/vendor/coze/original/mouse-icon.tsx +35 -35
- package/vendor/coze/original/mouse-pad-selector.tsx +180 -180
- package/vendor/coze/original/node-card.tsx +77 -77
- package/vendor/coze/original/node-category-panel.less +4 -4
- package/vendor/coze/original/node-category-panel.tsx +53 -53
- package/vendor/coze/original/node-config-form.tsx +67 -67
- package/vendor/coze/original/node-header.less +165 -165
- package/vendor/coze/original/node-header.tsx +552 -552
- package/vendor/coze/original/node-panel.less +183 -183
- package/vendor/coze/original/node-render.less +20 -20
- package/vendor/coze/original/node-side-sheet.less +57 -57
- package/vendor/coze/original/node-side-sheet.tsx +214 -214
- package/vendor/coze/original/node-wrapper.tsx +71 -71
- package/vendor/coze/original/pad-icon.tsx +45 -45
- package/vendor/coze/original/resizable-side-panel-constants.ts +18 -18
- package/vendor/coze/original/resizable-side-panel.tsx +42 -42
- package/vendor/coze/original/start-registry.ts +53 -53
- package/vendor/coze/original/sub-canvas-background.less +4 -4
- package/vendor/coze/original/sub-canvas-background.tsx +48 -48
- package/vendor/coze/original/sub-canvas-container.less +16 -16
- package/vendor/coze/original/sub-canvas-container.tsx +97 -97
- package/vendor/coze/original/sub-canvas-header.less +75 -75
- package/vendor/coze/original/sub-canvas-header.tsx +95 -95
- package/vendor/coze/original/test-form-sheet-header.tsx +82 -82
- package/vendor/coze/original/test-form-sheet.less +178 -178
- package/vendor/coze/original/toolbar-add-node.tsx +68 -68
- package/vendor/coze/original/toolbar-auto-layout.tsx +61 -61
- package/vendor/coze/original/toolbar-comment.tsx +121 -121
- package/vendor/coze/original/toolbar-container.tsx +42 -42
- package/vendor/coze/original/toolbar-interactive.tsx +98 -98
- package/vendor/coze/original/toolbar-minimap-switch.tsx +41 -41
- package/vendor/coze/original/toolbar-tools.less +46 -46
- package/vendor/coze/original/toolbar-tools.tsx +89 -89
- package/vendor/coze/original/toolbar-zoom.tsx +134 -134
- package/vendor/coze/original/tree-variable-selector.less +291 -291
- package/vendor/coze/original/tree-variable-selector.tsx +298 -298
- package/vendor/coze/original/workflow-document-custom-options.ts +151 -151
- package/vendor/coze/original/workflow-header.less +65 -65
- package/vendor/coze/original/workflow-header.tsx +85 -85
- package/vendor/coze/source/agent-models/model-option/index.module.less +18 -18
- package/vendor/coze/source/agent-models/model-option/index.tsx +321 -321
- package/vendor/coze/source/agent-models/model-option-avatar/index.tsx +175 -175
- package/vendor/coze/source/agent-models/model-option-group/index.tsx +87 -87
- package/vendor/coze/source/agent-models/model-option-thumb/index.tsx +41 -41
- package/vendor/coze/source/agent-models/model-select-ui/index.tsx +238 -238
- package/vendor/coze/source/agent-models/popover-model-list-view/index.tsx +146 -146
- package/vendor/coze/source/components/code-editor/text-editor.tsx +71 -71
- package/vendor/coze/source/components/comment/components/editor/block.tsx +117 -117
- package/vendor/coze/source/components/comment/components/editor/leaf.tsx +64 -64
- package/vendor/coze/source/components/comment/components/toolbar.tsx +366 -366
- package/vendor/coze/source/components/comment/constant.ts +94 -94
- package/vendor/coze/source/components/editor-container/expand-editor/index.module.less +107 -107
- package/vendor/coze/source/components/editor-container/expand-editor/index.tsx +117 -117
- package/vendor/coze/source/components/model-select/components/model-setting.tsx +300 -300
- package/vendor/coze/source/components/model-select/components/settings.tsx +144 -144
- package/vendor/coze/source/components/model-select/index.module.less +34 -34
- package/vendor/coze/source/components/model-select/utils/index.tsx +100 -100
- package/vendor/coze/source/components/node-render/node-render-new/fields/constants.tsx +79 -79
- package/vendor/coze/source/components/node-render/node-render-new/fields/field-empty.module.less +12 -12
- package/vendor/coze/source/components/node-render/node-render-new/fields/field-empty.tsx +37 -37
- package/vendor/coze/source/components/node-render/node-render-new/fields/field.module.less +19 -19
- package/vendor/coze/source/components/node-render/node-render-new/fields/field.tsx +52 -52
- package/vendor/coze/source/components/node-render/node-render-new/fields/http-api-field/index.tsx +42 -42
- package/vendor/coze/source/components/node-render/node-render-new/fields/overflow-tag-list.module.less +47 -47
- package/vendor/coze/source/components/node-render/node-render-new/fields/overflow-tag-list.tsx +162 -162
- package/vendor/coze/source/components/node-render/node-render-new/fields/variable-tag-list.module.less +48 -48
- package/vendor/coze/source/components/node-render/node-render-new/fields/variable-tag-list.tsx +126 -126
- package/vendor/coze/source/components/node-wrapper/execute-result-panel/index.module.less +97 -97
- package/vendor/coze/source/components/node-wrapper/execute-result-panel/index.tsx +171 -171
- package/vendor/coze/source/components/sub-canvas/components/background/index.module.less +4 -4
- package/vendor/coze/source/components/sub-canvas/components/header/index.module.less +75 -75
- package/vendor/coze/source/components/test-run/test-run-button/single-node.tsx +158 -158
- package/vendor/coze/source/execution-panel/panel.module.less +48 -48
- package/vendor/coze/source/execution-panel/panel.tsx +99 -99
- package/vendor/coze/source/execution-panel/use-resize.ts +79 -79
- package/vendor/coze/source/external/features/log/components/data-viewer/constants.ts +28 -28
- package/vendor/coze/source/external/features/log/components/data-viewer/context/context.ts +21 -21
- package/vendor/coze/source/external/features/log/components/data-viewer/context/create-store.ts +48 -48
- package/vendor/coze/source/external/features/log/components/data-viewer/context/index.ts +19 -19
- package/vendor/coze/source/external/features/log/components/data-viewer/context/provider.tsx +50 -50
- package/vendor/coze/source/external/features/log/components/data-viewer/data-viewer.module.less +26 -26
- package/vendor/coze/source/external/features/log/components/data-viewer/data-viewer.tsx +79 -79
- package/vendor/coze/source/external/features/log/components/data-viewer/hooks/index.ts +18 -18
- package/vendor/coze/source/external/features/log/components/data-viewer/hooks/use-data-viewer-store.ts +29 -29
- package/vendor/coze/source/external/features/log/components/data-viewer/hooks/use-expand.ts +35 -35
- package/vendor/coze/source/external/features/log/components/data-viewer/hooks/use-value.tsx +66 -66
- package/vendor/coze/source/external/features/log/components/data-viewer/index.tsx +21 -21
- package/vendor/coze/source/external/features/log/components/data-viewer/json-field/index.tsx +186 -186
- package/vendor/coze/source/external/features/log/components/data-viewer/json-field/json-field.module.less +79 -79
- package/vendor/coze/source/external/features/log/components/data-viewer/types.ts +50 -50
- package/vendor/coze/source/external/features/log/components/data-viewer/utils/big-number.ts +35 -35
- package/vendor/coze/source/external/features/log/components/data-viewer/utils/generate-field.ts +104 -104
- package/vendor/coze/source/external/features/log/components/log-parser/log-wrap.module.less +27 -27
- package/vendor/coze/source/external/features/log/components/log-parser/log-wrap.tsx +109 -109
- package/vendor/coze/source/external/features/log/components/node-status-bar/node-status-bar.module.less +52 -52
- package/vendor/coze/source/external/features/log/components/node-status-bar/node-status-bar.tsx +113 -113
- package/vendor/coze/source/form/components/field-empty.tsx +45 -45
- package/vendor/coze/source/form/components/section.tsx +91 -91
- package/vendor/coze/source/form-extensions/components/add-item-button/index.tsx +64 -64
- package/vendor/coze/source/form-extensions/components/form-card/index.module.less +131 -131
- package/vendor/coze/source/form-extensions/components/form-card/index.tsx +309 -309
- package/vendor/coze/source/form-extensions/components/form-item/index.module.less +39 -39
- package/vendor/coze/source/form-extensions/components/form-item/index.tsx +200 -200
- package/vendor/coze/source/form-extensions/components/form-item-feedback/index.module.less +7 -7
- package/vendor/coze/source/form-extensions/components/form-item-feedback/index.tsx +39 -39
- package/vendor/coze/source/form-extensions/components/level-line/index.module.less +346 -346
- package/vendor/coze/source/form-extensions/components/level-line/index.ts +17 -17
- package/vendor/coze/source/form-extensions/components/level-line/level-line.tsx +460 -460
- package/vendor/coze/source/form-extensions/components/level-line/types.ts +38 -38
- package/vendor/coze/source/form-extensions/components/level-line/utils.ts +60 -60
- package/vendor/coze/source/form-extensions/components/literal-value-input/constants.ts +61 -61
- package/vendor/coze/source/form-extensions/components/literal-value-input/input-boolean.tsx +80 -80
- package/vendor/coze/source/form-extensions/components/literal-value-input/input-integer.tsx +68 -68
- package/vendor/coze/source/form-extensions/components/literal-value-input/input-number.tsx +62 -62
- package/vendor/coze/source/form-extensions/components/literal-value-input/input-select.tsx +59 -59
- package/vendor/coze/source/form-extensions/components/literal-value-input/input-string.tsx +55 -55
- package/vendor/coze/source/form-extensions/components/literal-value-input/literal-value-input.tsx +35 -35
- package/vendor/coze/source/form-extensions/components/literal-value-input/styles.module.less +46 -46
- package/vendor/coze/source/form-extensions/components/literal-value-input/type.ts +61 -61
- package/vendor/coze/source/form-extensions/components/literal-value-input/utils.tsx +117 -117
- package/vendor/coze/source/form-extensions/components/node-header/components/close-button.tsx +44 -44
- package/vendor/coze/source/form-extensions/components/node-header/description-display.tsx +52 -52
- package/vendor/coze/source/form-extensions/components/node-header/description.tsx +131 -131
- package/vendor/coze/source/form-extensions/components/node-header/index.module.less +165 -165
- package/vendor/coze/source/form-extensions/components/node-header/index.tsx +552 -552
- package/vendor/coze/source/form-extensions/components/output-tree/components/custom-tree-node/components/expand-btn/index.tsx +43 -43
- package/vendor/coze/source/form-extensions/components/output-tree/components/custom-tree-node/components/expand-content/default-value-input.tsx +276 -276
- package/vendor/coze/source/form-extensions/components/output-tree/components/custom-tree-node/components/expand-content/index.module.less +124 -124
- package/vendor/coze/source/form-extensions/components/output-tree/components/custom-tree-node/components/expand-content/index.tsx +131 -131
- package/vendor/coze/source/form-extensions/components/output-tree/components/custom-tree-node/components/expand-content/types.ts +32 -32
- package/vendor/coze/source/form-extensions/components/output-tree/components/custom-tree-node/components/param-name/index.module.less +38 -38
- package/vendor/coze/source/form-extensions/components/output-tree/components/custom-tree-node/components/param-name/index.tsx +101 -101
- package/vendor/coze/source/form-extensions/components/output-tree/components/custom-tree-node/components/param-operator/index.module.less +51 -51
- package/vendor/coze/source/form-extensions/components/output-tree/components/custom-tree-node/components/param-operator/index.tsx +107 -107
- package/vendor/coze/source/form-extensions/components/output-tree/components/custom-tree-node/components/param-required/index.module.less +17 -17
- package/vendor/coze/source/form-extensions/components/output-tree/components/custom-tree-node/components/param-required/index.tsx +53 -53
- package/vendor/coze/source/form-extensions/components/output-tree/components/custom-tree-node/components/param-type/constants.tsx +77 -77
- package/vendor/coze/source/form-extensions/components/output-tree/components/custom-tree-node/components/param-type/index.module.less +97 -97
- package/vendor/coze/source/form-extensions/components/output-tree/components/custom-tree-node/components/param-type/index.tsx +155 -155
- package/vendor/coze/source/form-extensions/components/output-tree/components/custom-tree-node/constants.ts +38 -38
- package/vendor/coze/source/form-extensions/components/output-tree/components/custom-tree-node/index.module.less +138 -138
- package/vendor/coze/source/form-extensions/components/output-tree/components/custom-tree-node/index.tsx +360 -360
- package/vendor/coze/source/form-extensions/components/output-tree/components/custom-tree-node/type.ts +88 -88
- package/vendor/coze/source/form-extensions/components/output-tree/components/header/index.module.less +36 -36
- package/vendor/coze/source/form-extensions/components/output-tree/components/header/index.tsx +104 -104
- package/vendor/coze/source/form-extensions/components/output-tree/constants.ts +22 -22
- package/vendor/coze/source/form-extensions/components/output-tree/context.ts +28 -28
- package/vendor/coze/source/form-extensions/components/output-tree/hooks/use-columns-style.ts +39 -39
- package/vendor/coze/source/form-extensions/components/output-tree/index.module.less +83 -83
- package/vendor/coze/source/form-extensions/components/output-tree/index.tsx +692 -692
- package/vendor/coze/source/form-extensions/components/output-tree/utils.ts +185 -185
- package/vendor/coze/source/form-extensions/components/setting-on-error/components/process-type/index.tsx +97 -97
- package/vendor/coze/source/form-extensions/components/setting-on-error/components/process-type/option-item.tsx +30 -30
- package/vendor/coze/source/form-extensions/components/setting-on-error/components/process-type/types.ts +23 -23
- package/vendor/coze/source/form-extensions/components/setting-on-error/components/retry-times/index.tsx +45 -45
- package/vendor/coze/source/form-extensions/components/setting-on-error/components/timeout/index.tsx +102 -102
- package/vendor/coze/source/form-extensions/components/tree-variable-selector/composite-select-option.tsx +167 -167
- package/vendor/coze/source/form-extensions/components/tree-variable-selector/composite-select-tree-panel.tsx +165 -165
- package/vendor/coze/source/form-extensions/components/tree-variable-selector/composite-select.module.less +96 -96
- package/vendor/coze/source/form-extensions/components/tree-variable-selector/composite-select.tsx +265 -265
- package/vendor/coze/source/form-extensions/components/tree-variable-selector/context.tsx +42 -42
- package/vendor/coze/source/form-extensions/components/tree-variable-selector/expand-icon.tsx +30 -30
- package/vendor/coze/source/form-extensions/components/tree-variable-selector/index.module.less +291 -291
- package/vendor/coze/source/form-extensions/components/tree-variable-selector/node-variable-tree.module.less +48 -48
- package/vendor/coze/source/form-extensions/components/tree-variable-selector/node-variable-tree.tsx +149 -149
- package/vendor/coze/source/form-extensions/components/tree-variable-selector/utils.tsx +500 -500
- package/vendor/coze/source/form-extensions/components/tree-variable-selector/value-display.tsx +130 -130
- package/vendor/coze/source/form-extensions/components/value-expression-input/const.ts +68 -68
- package/vendor/coze/source/form-extensions/components/value-expression-input/context.ts +27 -27
- package/vendor/coze/source/form-extensions/components/value-expression-input/index.module.less +144 -144
- package/vendor/coze/source/form-extensions/components/value-expression-input/value-expression-input.tsx +418 -418
- package/vendor/coze/source/form-extensions/components/variable-type-selector/constants.tsx +77 -77
- package/vendor/coze/source/form-extensions/components/variable-type-selector/index.module.less +31 -31
- package/vendor/coze/source/form-extensions/components/variable-type-selector/index.tsx +17 -17
- package/vendor/coze/source/form-extensions/components/variable-type-selector/utils.tsx +298 -298
- package/vendor/coze/source/form-extensions/components/variable-type-selector/variable-type-selector.tsx +235 -235
- package/vendor/coze/source/form-extensions/components/variable-type-tag/index.tsx +54 -54
- package/vendor/coze/source/form-extensions/setters/condition/multi-condition/condition-branch.module.less +9 -9
- package/vendor/coze/source/form-extensions/setters/condition/multi-condition/condition-branch.tsx +249 -249
- package/vendor/coze/source/form-extensions/setters/condition/multi-condition/condition-header.tsx +50 -50
- package/vendor/coze/source/form-extensions/setters/condition/multi-condition/condition-item-logic.module.less +13 -13
- package/vendor/coze/source/form-extensions/setters/condition/multi-condition/condition-item-logic.tsx +73 -73
- package/vendor/coze/source/form-extensions/setters/condition/multi-condition/condition-params-item/delete/index.module.less +10 -10
- package/vendor/coze/source/form-extensions/setters/condition/multi-condition/condition-params-item/delete/index.tsx +42 -42
- package/vendor/coze/source/form-extensions/setters/condition/multi-condition/condition-params-item/index.module.less +9 -9
- package/vendor/coze/source/form-extensions/setters/condition/multi-condition/condition-params-item/index.tsx +254 -254
- package/vendor/coze/source/form-extensions/setters/condition/multi-condition/condition-params-item/operator/index.module.less +7 -7
- package/vendor/coze/source/form-extensions/setters/condition/multi-condition/condition-params-item/operator/index.tsx +144 -144
- package/vendor/coze/source/form-extensions/setters/condition/multi-condition/condition-params-item/value-expression-with-state/index.tsx +69 -69
- package/vendor/coze/source/form-extensions/setters/condition/multi-condition/context.ts +36 -36
- package/vendor/coze/source/form-extensions/setters/condition/multi-condition/draggable/condition-branch-preview.tsx +44 -44
- package/vendor/coze/source/form-extensions/setters/condition/multi-condition/draggable/condition-branch.tsx +152 -152
- package/vendor/coze/source/form-extensions/setters/condition/multi-condition/draggable/container.tsx +19 -19
- package/vendor/coze/source/form-extensions/setters/condition/multi-condition/draggable/custom-drag-layer.tsx +117 -117
- package/vendor/coze/source/form-extensions/setters/condition/multi-condition/draggable/types.ts +18 -18
- package/vendor/coze/source/form-extensions/setters/condition/multi-condition/types.ts +58 -58
- package/vendor/coze/source/node-registries/end/components/terminate-plan-field.tsx +29 -29
- package/vendor/coze/source/node-registries/end/constants.ts +34 -34
- package/vendor/coze/source/node-registries/end/form.tsx +66 -66
- package/vendor/coze/source/node-registries/end/types.ts +45 -45
- package/vendor/coze/source/node-registries/http/components/base-editor/raw-text-editor.tsx +80 -80
- package/vendor/coze/source/node-registries/http/constants.ts +80 -80
- package/vendor/coze/source/node-registries/http/fields/json-import-editor/index.module.less +191 -191
- package/vendor/coze/source/node-registries/http/fields/json-import-editor/json-import-components/json-expand-editor.tsx +141 -141
- package/vendor/coze/source/node-registries/http/fields/json-import-editor/json-import-components/json-import.tsx +99 -99
- package/vendor/coze/source/node-registries/http/form-render.tsx +102 -102
- package/vendor/coze/source/node-registries/http/setters/api/curl-expand-editor.tsx +161 -161
- package/vendor/coze/source/node-registries/http/setters/api/curl-import.tsx +96 -96
- package/vendor/coze/source/node-registries/http/setters/api/index.module.less +199 -199
- package/vendor/coze/source/node-registries/http/setters/api/index.tsx +149 -149
- package/vendor/coze/source/node-registries/http/setters/api/utils.ts +41 -41
- package/vendor/coze/source/node-registries/http/setters/body/index.tsx +201 -201
- package/vendor/coze/source/node-registries/http/setters/constants.ts +83 -83
- package/vendor/coze/source/node-registries/if/components/else/index.tsx +41 -41
- package/vendor/coze/source/node-registries/intent/components/intents/index.module.less +14 -14
- package/vendor/coze/source/node-registries/intent/components/intents/option-item/index.tsx +189 -189
- package/vendor/coze/source/node-registries/json-stringify/constants.ts +32 -32
- package/vendor/coze/source/node-registries/json-stringify/form.tsx +46 -46
- package/vendor/coze/source/node-registries/loop/constants.ts +43 -43
- package/vendor/coze/source/node-registries/loop/loop-fields/loop-settings-section/index.tsx +48 -48
- package/vendor/coze/source/node-registries/loop/loop-fields/loop-type/index.tsx +81 -81
- package/vendor/coze/source/node-registries/loop/loop-fields/loop-type/options.ts +34 -34
- package/vendor/coze/source/node-registries/start/form.tsx +209 -209
- package/vendor/coze/source/node-registries/text-process/components/method-selector/index.tsx +46 -46
- package/vendor/coze/source/node-registries/text-process/constants.ts +132 -132
- package/vendor/coze/source/nodes-v2/components/form-item-feedback/index.module.less +7 -7
- package/vendor/coze/source/nodes-v2/components/form-item-feedback/index.tsx +47 -47
- package/vendor/coze/source/nodes-v2/components/system-prompt/index.module.less +66 -66
- package/vendor/coze/source/nodes-v2/components/system-prompt/prompt-kit-bar.tsx +129 -129
- package/vendor/coze/source/nodes-v2/components/system-prompt/system-prompt-editor.tsx +110 -110
- package/vendor/coze/source/nodes-v2/llm/user-prompt/index.tsx +64 -64
- package/vendor/coze/source/prompt-kit/input-config-popover/index.tsx +80 -80
- package/vendor/coze/source/prompt-kit/input-slot-widget/index.css +34 -34
- package/vendor/coze/source/prompt-kit/input-slot-widget/index.ts +169 -169
- package/vendor/coze/source/prompt-kit/library-item.tsx +141 -141
- package/vendor/coze/source/prompt-kit/prompt-info-input.tsx +90 -90
- package/vendor/coze/source/ui-components/add-operation/index.module.less +19 -19
- package/vendor/coze/source/ui-components/add-operation/index.tsx +67 -67
- package/vendor/coze/source/ui-components/auto-size-tooltip/index.module.less +39 -39
- package/vendor/coze/source/ui-components/auto-size-tooltip/index.tsx +74 -74
- package/vendor/coze/source/ui-components/workflow-sl-input/index.module.less +36 -36
- package/vendor/coze/source/ui-components/workflow-sl-input/index.tsx +194 -194
- package/vendor/coze/source/utils/create-slots/index.tsx +126 -126
- package/vendor/coze/source/utils/create-slots/use-force-update.ts +23 -23
|
@@ -1,692 +1,692 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright 2025 coze-dev Authors
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
/* eslint-disable max-lines */
|
|
18
|
-
/* eslint-disable complexity */
|
|
19
|
-
/* eslint-disable max-lines-per-function */
|
|
20
|
-
import React, {
|
|
21
|
-
useCallback,
|
|
22
|
-
useEffect,
|
|
23
|
-
useMemo,
|
|
24
|
-
useRef,
|
|
25
|
-
useState,
|
|
26
|
-
type PropsWithChildren,
|
|
27
|
-
} from 'react';
|
|
28
|
-
|
|
29
|
-
import { nanoid } from 'nanoid';
|
|
30
|
-
import cloneDeep from 'lodash-es/cloneDeep';
|
|
31
|
-
import classNames from 'classnames';
|
|
32
|
-
import { useLatest } from 'ahooks';
|
|
33
|
-
import { WorkflowBatchService } from '@coze-workflow/variable';
|
|
34
|
-
import {
|
|
35
|
-
ResponseFormat,
|
|
36
|
-
ViewVariableType,
|
|
37
|
-
type ViewVariableTreeNode,
|
|
38
|
-
} from '@coze-workflow/base';
|
|
39
|
-
import { useNodeTestId } from '@coze-workflow/base';
|
|
40
|
-
import { I18n } from '@coze-arch/i18n';
|
|
41
|
-
import { type TreeNodeData, type TreeProps } from '@coze-arch/bot-semi/Tree';
|
|
42
|
-
import { Toast, Tree } from '@coze-arch/coze-design';
|
|
43
|
-
|
|
44
|
-
import { FormCard } from '../form-card';
|
|
45
|
-
import { AddItemButton } from '../add-item-button';
|
|
46
|
-
import {
|
|
47
|
-
findCustomTreeNodeDataResult,
|
|
48
|
-
formatTreeData,
|
|
49
|
-
traverse,
|
|
50
|
-
} from './utils';
|
|
51
|
-
import { OutputTreeContextProvider } from './context';
|
|
52
|
-
import { TreeCollapseWidth } from './constants';
|
|
53
|
-
import { ResponseFormatSelect } from './components/response-format';
|
|
54
|
-
import { JSONImport, JSONImportPlaceholder } from './components/json-import';
|
|
55
|
-
import Header from './components/header';
|
|
56
|
-
import {
|
|
57
|
-
type ActiveMultiInfo,
|
|
58
|
-
type TreeNodeCustomData,
|
|
59
|
-
} from './components/custom-tree-node/type';
|
|
60
|
-
import { ChangeMode } from './components/custom-tree-node/constants';
|
|
61
|
-
import CustomTreeNode from './components/custom-tree-node';
|
|
62
|
-
|
|
63
|
-
import styles from './index.module.less';
|
|
64
|
-
|
|
65
|
-
export interface SimpleTreeNodeCustomData {
|
|
66
|
-
key: string;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export interface OutputTreeProps {
|
|
70
|
-
id: string;
|
|
71
|
-
testId?: string;
|
|
72
|
-
// Whether to allow new root nodes, the default is true
|
|
73
|
-
allowAppendRootData?: boolean;
|
|
74
|
-
// Is it allowed to delete the last piece of data?
|
|
75
|
-
allowDeleteLast?: boolean;
|
|
76
|
-
// Is it batch processing?
|
|
77
|
-
isBatch?: boolean;
|
|
78
|
-
treeProps?: TreeProps;
|
|
79
|
-
readonly?: boolean;
|
|
80
|
-
disabled?: boolean;
|
|
81
|
-
disabledTooltip?: string;
|
|
82
|
-
/** @default I18n.t('workflow_detail_node_output') */
|
|
83
|
-
title?: string;
|
|
84
|
-
/** @default title */
|
|
85
|
-
titleTooltip?: string;
|
|
86
|
-
className?: string;
|
|
87
|
-
style?: React.CSSProperties;
|
|
88
|
-
value: Array<TreeNodeCustomData>;
|
|
89
|
-
onChange: (value: Array<TreeNodeCustomData>) => void;
|
|
90
|
-
withDescription: boolean;
|
|
91
|
-
withRequired: boolean;
|
|
92
|
-
/** Types not supported */
|
|
93
|
-
disabledTypes?: ViewVariableType[];
|
|
94
|
-
/** hidden type */
|
|
95
|
-
hiddenTypes?: ViewVariableType[];
|
|
96
|
-
topLevelReadonly?: boolean;
|
|
97
|
-
emptyPlaceholder?: string;
|
|
98
|
-
responseFormat?: {
|
|
99
|
-
visible?: boolean;
|
|
100
|
-
value?: number;
|
|
101
|
-
readonly?: boolean;
|
|
102
|
-
onChange?: (value?: number) => void;
|
|
103
|
-
};
|
|
104
|
-
/** Default variable type */
|
|
105
|
-
defaultVariableType?: ViewVariableType;
|
|
106
|
-
jsonImport?: boolean;
|
|
107
|
-
noCard?: boolean;
|
|
108
|
-
addItemTitle?: string;
|
|
109
|
-
defaultCollapse?: boolean;
|
|
110
|
-
|
|
111
|
-
// Is the outermost output folded by default?
|
|
112
|
-
formCardDefaultCollapse?: boolean;
|
|
113
|
-
children?: React.ReactNode;
|
|
114
|
-
/** You can still add children to a node preset */
|
|
115
|
-
needAppendChildWhenNodeIsPreset?: boolean;
|
|
116
|
-
maxLimit?: number;
|
|
117
|
-
/**
|
|
118
|
-
* Can the default value be configured, the default is false
|
|
119
|
-
*/
|
|
120
|
-
withDefaultValue?: boolean;
|
|
121
|
-
/**
|
|
122
|
-
* Default expanded parameter name
|
|
123
|
-
*/
|
|
124
|
-
defaultExpandParams?: string[];
|
|
125
|
-
/**
|
|
126
|
-
* Column widths such as 6:4 represent 6 copies of the name and 4 copies of the type
|
|
127
|
-
*/
|
|
128
|
-
columnsRatio?: string;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const getDefaultAppendValue = (
|
|
132
|
-
withRequired = false,
|
|
133
|
-
defaultVariableType = ViewVariableType.String,
|
|
134
|
-
) => {
|
|
135
|
-
const defaultValue: {
|
|
136
|
-
fieldRandomKey: string;
|
|
137
|
-
type: ViewVariableType;
|
|
138
|
-
required?: boolean;
|
|
139
|
-
} = {
|
|
140
|
-
fieldRandomKey: nanoid(),
|
|
141
|
-
type: defaultVariableType,
|
|
142
|
-
};
|
|
143
|
-
if (withRequired) {
|
|
144
|
-
defaultValue.required = true;
|
|
145
|
-
}
|
|
146
|
-
return defaultValue;
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
function useExpandedKeys(keys: string[], defaultCollapse: boolean) {
|
|
150
|
-
const [expandedKeys, setExpandedKeys] = useState(defaultCollapse ? [] : keys);
|
|
151
|
-
|
|
152
|
-
const expandTreeNode = useCallback(
|
|
153
|
-
(key: string) => {
|
|
154
|
-
setExpandedKeys([...new Set([...expandedKeys, key])]);
|
|
155
|
-
},
|
|
156
|
-
[keys],
|
|
157
|
-
);
|
|
158
|
-
|
|
159
|
-
const collapseTreeNode = useCallback(
|
|
160
|
-
(key: string) => {
|
|
161
|
-
setExpandedKeys([
|
|
162
|
-
...expandedKeys.filter(expandedKey => expandedKey !== key),
|
|
163
|
-
]);
|
|
164
|
-
},
|
|
165
|
-
[keys],
|
|
166
|
-
);
|
|
167
|
-
|
|
168
|
-
return { expandedKeys, expandTreeNode, collapseTreeNode };
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
export function OutputTree(props: PropsWithChildren<OutputTreeProps>) {
|
|
172
|
-
const {
|
|
173
|
-
id,
|
|
174
|
-
testId,
|
|
175
|
-
readonly = false,
|
|
176
|
-
isBatch = false,
|
|
177
|
-
disabled,
|
|
178
|
-
disabledTooltip,
|
|
179
|
-
children,
|
|
180
|
-
allowAppendRootData = true,
|
|
181
|
-
allowDeleteLast = false,
|
|
182
|
-
treeProps,
|
|
183
|
-
title = I18n.t('workflow_detail_node_output'),
|
|
184
|
-
titleTooltip = title,
|
|
185
|
-
className,
|
|
186
|
-
style,
|
|
187
|
-
value,
|
|
188
|
-
onChange,
|
|
189
|
-
withDescription = false,
|
|
190
|
-
withRequired = false,
|
|
191
|
-
disabledTypes = [],
|
|
192
|
-
hiddenTypes,
|
|
193
|
-
topLevelReadonly = false,
|
|
194
|
-
emptyPlaceholder,
|
|
195
|
-
responseFormat = {},
|
|
196
|
-
defaultVariableType = ViewVariableType.String,
|
|
197
|
-
jsonImport = true,
|
|
198
|
-
noCard = false,
|
|
199
|
-
addItemTitle = I18n.t('workflow_add_output'),
|
|
200
|
-
defaultCollapse = false,
|
|
201
|
-
formCardDefaultCollapse = false,
|
|
202
|
-
needAppendChildWhenNodeIsPreset = true,
|
|
203
|
-
maxLimit,
|
|
204
|
-
withDefaultValue,
|
|
205
|
-
defaultExpandParams = [],
|
|
206
|
-
columnsRatio,
|
|
207
|
-
} = props;
|
|
208
|
-
|
|
209
|
-
// Monitor for changes in this value
|
|
210
|
-
const cardRef = useRef<HTMLDivElement>(null);
|
|
211
|
-
const isValueEmpty = !value || value.length === 0;
|
|
212
|
-
const {
|
|
213
|
-
data: formattedTreeData = [],
|
|
214
|
-
hasObjectLike,
|
|
215
|
-
itemKeysWithChildren,
|
|
216
|
-
} = formatTreeData(cloneDeep(value), id);
|
|
217
|
-
const isDataEmpty = formattedTreeData.length === 0;
|
|
218
|
-
const { expandedKeys, expandTreeNode, collapseTreeNode } = useExpandedKeys(
|
|
219
|
-
itemKeysWithChildren,
|
|
220
|
-
defaultCollapse,
|
|
221
|
-
);
|
|
222
|
-
|
|
223
|
-
const disableAdd = useMemo(() => {
|
|
224
|
-
if (maxLimit === undefined) {
|
|
225
|
-
return false;
|
|
226
|
-
}
|
|
227
|
-
return (value?.length ?? 0) >= maxLimit;
|
|
228
|
-
}, [value, maxLimit]);
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* The description of the parent node of which row is currently in a multi-row state (LLM node)
|
|
232
|
-
* For rendering tree vertical lines, the next vertical line in multiple lines of text should be extended
|
|
233
|
-
* If the param name has an error message, the vertical bar extends below the error message and the length changes
|
|
234
|
-
*/
|
|
235
|
-
const [activeMultiInfo, setActiveMultiInfo] = useState<ActiveMultiInfo>({
|
|
236
|
-
activeMultiKey: '',
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
const { concatTestId } = useNodeTestId();
|
|
240
|
-
|
|
241
|
-
const onAdd = () => {
|
|
242
|
-
if (onChange) {
|
|
243
|
-
onChange(
|
|
244
|
-
(formattedTreeData || []).concat({
|
|
245
|
-
...getDefaultAppendValue(withRequired, defaultVariableType),
|
|
246
|
-
// Add field
|
|
247
|
-
field: `[${formattedTreeData.length}]`,
|
|
248
|
-
// At this time, there is no need to specify the type, so as as is used to cancel the type and report an error.
|
|
249
|
-
} as unknown as TreeNodeCustomData),
|
|
250
|
-
);
|
|
251
|
-
}
|
|
252
|
-
};
|
|
253
|
-
|
|
254
|
-
// How to change this component
|
|
255
|
-
const onValueChange = (freshValue?: Array<TreeNodeCustomData>) => {
|
|
256
|
-
if (onChange) {
|
|
257
|
-
freshValue = (freshValue || []).concat([]);
|
|
258
|
-
// Clean up useless fields
|
|
259
|
-
traverse<TreeNodeCustomData>(freshValue, node => {
|
|
260
|
-
const {
|
|
261
|
-
key,
|
|
262
|
-
name,
|
|
263
|
-
type,
|
|
264
|
-
description,
|
|
265
|
-
required,
|
|
266
|
-
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
267
|
-
children,
|
|
268
|
-
isPreset,
|
|
269
|
-
enabled,
|
|
270
|
-
readonly: _readonly,
|
|
271
|
-
defaultValue,
|
|
272
|
-
} = node;
|
|
273
|
-
// eslint-disable-next-line guard-for-in
|
|
274
|
-
for (const prop in node) {
|
|
275
|
-
delete node[prop];
|
|
276
|
-
}
|
|
277
|
-
node.key = key || nanoid();
|
|
278
|
-
node.name = name;
|
|
279
|
-
node.type = type;
|
|
280
|
-
node.description = description;
|
|
281
|
-
if (defaultValue !== null) {
|
|
282
|
-
node.defaultValue = defaultValue;
|
|
283
|
-
}
|
|
284
|
-
if (isPreset) {
|
|
285
|
-
node.isPreset = isPreset;
|
|
286
|
-
node.enabled = enabled || false;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
if (withRequired) {
|
|
290
|
-
node.required = required || false; // Undefined to false
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
if (children) {
|
|
294
|
-
node.children = children;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
if (_readonly) {
|
|
298
|
-
node.readonly = _readonly;
|
|
299
|
-
}
|
|
300
|
-
});
|
|
301
|
-
onChange(freshValue);
|
|
302
|
-
}
|
|
303
|
-
};
|
|
304
|
-
|
|
305
|
-
// Tree node change method
|
|
306
|
-
const onTreeNodeChange = (mode: ChangeMode, param: TreeNodeCustomData) => {
|
|
307
|
-
// Clone one first, because the Tree will execute isEqual on treeData, cloning one must be false.
|
|
308
|
-
const cloneDeepTreeData = cloneDeep(
|
|
309
|
-
formattedTreeData,
|
|
310
|
-
) as Array<TreeNodeCustomData>;
|
|
311
|
-
|
|
312
|
-
const findResult = findCustomTreeNodeDataResult(
|
|
313
|
-
cloneDeepTreeData,
|
|
314
|
-
param.field as string,
|
|
315
|
-
);
|
|
316
|
-
|
|
317
|
-
if (findResult) {
|
|
318
|
-
switch (mode) {
|
|
319
|
-
case ChangeMode.Append: {
|
|
320
|
-
// You can't use parentData as a standard for adding, you need to add it under the current data.
|
|
321
|
-
const { data } = findResult;
|
|
322
|
-
const currentChildren = data.children || [];
|
|
323
|
-
// @ts-expect-error Some values do not need to be specified at this time because format is executed during rerender
|
|
324
|
-
data.children = currentChildren.concat({
|
|
325
|
-
...getDefaultAppendValue(false, defaultVariableType),
|
|
326
|
-
// Add field
|
|
327
|
-
field: `${data.field}.children[${currentChildren.length}]`,
|
|
328
|
-
});
|
|
329
|
-
onValueChange(cloneDeepTreeData);
|
|
330
|
-
|
|
331
|
-
// Add a new node under the current node and expand the current node
|
|
332
|
-
if (findResult?.data?.key) {
|
|
333
|
-
expandTreeNode(findResult.data.key);
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
break;
|
|
337
|
-
}
|
|
338
|
-
case ChangeMode.Update: {
|
|
339
|
-
const targetArray = findResult.isRoot
|
|
340
|
-
? cloneDeepTreeData
|
|
341
|
-
: findResult.parentData?.children;
|
|
342
|
-
const index = targetArray?.findIndex(item => item.key === param.key);
|
|
343
|
-
|
|
344
|
-
if (index !== undefined) {
|
|
345
|
-
targetArray?.splice(index, 1, param);
|
|
346
|
-
onValueChange(cloneDeepTreeData);
|
|
347
|
-
}
|
|
348
|
-
break;
|
|
349
|
-
}
|
|
350
|
-
case ChangeMode.Delete: {
|
|
351
|
-
if (findResult.isRoot) {
|
|
352
|
-
const freshValue = (cloneDeepTreeData || []).filter(
|
|
353
|
-
item => item.key !== param.key,
|
|
354
|
-
);
|
|
355
|
-
onValueChange(freshValue);
|
|
356
|
-
} else {
|
|
357
|
-
const parentData = findResult.parentData as TreeNodeData;
|
|
358
|
-
parentData.children = (parentData.children || []).filter(
|
|
359
|
-
item => item.key !== param.key,
|
|
360
|
-
);
|
|
361
|
-
onValueChange(cloneDeepTreeData);
|
|
362
|
-
}
|
|
363
|
-
break;
|
|
364
|
-
}
|
|
365
|
-
case ChangeMode.DeleteChildren: {
|
|
366
|
-
const { data } = findResult;
|
|
367
|
-
data.children = [];
|
|
368
|
-
onValueChange(cloneDeepTreeData);
|
|
369
|
-
break;
|
|
370
|
-
}
|
|
371
|
-
default:
|
|
372
|
-
}
|
|
373
|
-
} else {
|
|
374
|
-
Toast.error(I18n.t('workflow_detail_node_output_parsingfailed'));
|
|
375
|
-
}
|
|
376
|
-
};
|
|
377
|
-
|
|
378
|
-
const onJSONImportChange = (freshValue?: Array<TreeNodeCustomData>) => {
|
|
379
|
-
const nextValue: Array<TreeNodeCustomData> = [];
|
|
380
|
-
value
|
|
381
|
-
.filter(item => item.isPreset)
|
|
382
|
-
.forEach(item => {
|
|
383
|
-
const matched = (freshValue || []).find(it => it.name === item.name);
|
|
384
|
-
if (matched) {
|
|
385
|
-
nextValue.push({
|
|
386
|
-
...item,
|
|
387
|
-
enabled: true,
|
|
388
|
-
});
|
|
389
|
-
} else {
|
|
390
|
-
nextValue.push(item);
|
|
391
|
-
}
|
|
392
|
-
});
|
|
393
|
-
|
|
394
|
-
(freshValue || []).forEach(item => {
|
|
395
|
-
const matched = value.find(it => it.isPreset && it.name === item.name);
|
|
396
|
-
if (!matched) {
|
|
397
|
-
nextValue.push(item);
|
|
398
|
-
}
|
|
399
|
-
});
|
|
400
|
-
|
|
401
|
-
onChange(
|
|
402
|
-
maxLimit === undefined ? nextValue : nextValue?.slice(0, maxLimit),
|
|
403
|
-
);
|
|
404
|
-
};
|
|
405
|
-
|
|
406
|
-
const onlyString = useMemo(
|
|
407
|
-
() =>
|
|
408
|
-
([ResponseFormat.Text, ResponseFormat.Markdown] as number[]).includes(
|
|
409
|
-
responseFormat?.value ?? ResponseFormat.JSON,
|
|
410
|
-
),
|
|
411
|
-
[responseFormat.value],
|
|
412
|
-
);
|
|
413
|
-
|
|
414
|
-
const latestValue = useLatest(value);
|
|
415
|
-
const responseFormatValue = useRef(-1);
|
|
416
|
-
useEffect(() => {
|
|
417
|
-
const isUserChangeType =
|
|
418
|
-
responseFormatValue.current !== -1 &&
|
|
419
|
-
responseFormatValue.current !== responseFormat.value;
|
|
420
|
-
|
|
421
|
-
if (responseFormat.value !== undefined) {
|
|
422
|
-
responseFormatValue.current = responseFormat.value;
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
// If you switch to text mode
|
|
426
|
-
if (onlyString && isUserChangeType) {
|
|
427
|
-
let newValue = [
|
|
428
|
-
{
|
|
429
|
-
key: nanoid(),
|
|
430
|
-
name: 'output',
|
|
431
|
-
type: ViewVariableType.String,
|
|
432
|
-
},
|
|
433
|
-
] as TreeNodeCustomData[];
|
|
434
|
-
|
|
435
|
-
const _value = latestValue.current;
|
|
436
|
-
if (isBatch) {
|
|
437
|
-
newValue = WorkflowBatchService.singleOutputMetasToList(
|
|
438
|
-
newValue as ViewVariableTreeNode[],
|
|
439
|
-
) as TreeNodeCustomData[];
|
|
440
|
-
// If there is a value in itself, take the first one, expect: reuse variable name/description
|
|
441
|
-
if (_value?.[0]) {
|
|
442
|
-
newValue = [_value[0]];
|
|
443
|
-
}
|
|
444
|
-
if (_value?.[0].children?.[0]) {
|
|
445
|
-
const [first, ...rest] = _value[0].children;
|
|
446
|
-
newValue[0].children = [first, ...rest.filter(c => c?.readonly)];
|
|
447
|
-
}
|
|
448
|
-
// Modify type to string only
|
|
449
|
-
if (
|
|
450
|
-
newValue?.[0].children?.[0].type &&
|
|
451
|
-
newValue?.[0].children?.[0].type !== ViewVariableType.String
|
|
452
|
-
) {
|
|
453
|
-
newValue[0].children[0].type = ViewVariableType.String;
|
|
454
|
-
|
|
455
|
-
// Remove children
|
|
456
|
-
if (newValue[0].children[0].children) {
|
|
457
|
-
delete newValue[0].children[0].children;
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
} else {
|
|
461
|
-
// If there is a value in itself, take the first one, expect: reuse variable name/description
|
|
462
|
-
if (_value?.[0]) {
|
|
463
|
-
const [first, ...rest] = _value;
|
|
464
|
-
newValue = [first, ...rest.filter(c => c?.readonly)];
|
|
465
|
-
}
|
|
466
|
-
// Modify type to string only
|
|
467
|
-
if (newValue[0].type !== ViewVariableType.String) {
|
|
468
|
-
newValue[0].type = ViewVariableType.String;
|
|
469
|
-
|
|
470
|
-
// Remove children
|
|
471
|
-
if (newValue[0].children) {
|
|
472
|
-
delete newValue[0].children;
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
onChange(newValue);
|
|
477
|
-
}
|
|
478
|
-
}, [responseFormat.value]);
|
|
479
|
-
|
|
480
|
-
if (readonly && isValueEmpty) {
|
|
481
|
-
return null;
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
const Card = noCard ? React.Fragment : FormCard;
|
|
485
|
-
const showAddButton =
|
|
486
|
-
!readonly &&
|
|
487
|
-
!topLevelReadonly &&
|
|
488
|
-
allowAppendRootData &&
|
|
489
|
-
!onlyString &&
|
|
490
|
-
!disableAdd;
|
|
491
|
-
return (
|
|
492
|
-
<OutputTreeContextProvider value={{ testId }}>
|
|
493
|
-
<div
|
|
494
|
-
className={classNames({
|
|
495
|
-
[styles.container]: true,
|
|
496
|
-
[styles['not-readonly']]: !readonly,
|
|
497
|
-
[className || '']: Boolean(className),
|
|
498
|
-
[styles['could-collapse']]: itemKeysWithChildren.length > 0,
|
|
499
|
-
})}
|
|
500
|
-
style={style}
|
|
501
|
-
ref={cardRef}
|
|
502
|
-
>
|
|
503
|
-
<Card
|
|
504
|
-
autoExpandWhenDomChange
|
|
505
|
-
defaultExpand={!formCardDefaultCollapse}
|
|
506
|
-
showBottomBorder
|
|
507
|
-
header={title}
|
|
508
|
-
tooltip={titleTooltip}
|
|
509
|
-
contentClassName="nowheel"
|
|
510
|
-
noPadding
|
|
511
|
-
testId={testId}
|
|
512
|
-
actionButton={
|
|
513
|
-
<div className="flex gap-[4px] items-center">
|
|
514
|
-
{responseFormat.visible ? (
|
|
515
|
-
<ResponseFormatSelect
|
|
516
|
-
testId={concatTestId(testId ?? '', 'json-format')}
|
|
517
|
-
readonly={readonly || responseFormat.readonly}
|
|
518
|
-
value={responseFormat.value}
|
|
519
|
-
outputValue={value}
|
|
520
|
-
onlyString={onlyString}
|
|
521
|
-
onChange={onChange}
|
|
522
|
-
onResponseFormatChange={responseFormat.onChange}
|
|
523
|
-
isBatch={isBatch}
|
|
524
|
-
/>
|
|
525
|
-
) : undefined}
|
|
526
|
-
{!readonly &&
|
|
527
|
-
!topLevelReadonly &&
|
|
528
|
-
allowAppendRootData &&
|
|
529
|
-
!onlyString ? (
|
|
530
|
-
<>
|
|
531
|
-
<JSONImportPlaceholder
|
|
532
|
-
enable={jsonImport}
|
|
533
|
-
hideAddButton={isBatch || !!disabled}
|
|
534
|
-
/>
|
|
535
|
-
</>
|
|
536
|
-
) : null}
|
|
537
|
-
</div>
|
|
538
|
-
}
|
|
539
|
-
>
|
|
540
|
-
{!isDataEmpty && (
|
|
541
|
-
<Header
|
|
542
|
-
readonly={readonly}
|
|
543
|
-
config={{
|
|
544
|
-
hasObjectLike,
|
|
545
|
-
hasCollapse: itemKeysWithChildren.length > 0,
|
|
546
|
-
hasDescription: withDescription,
|
|
547
|
-
hasRequired: withRequired,
|
|
548
|
-
}}
|
|
549
|
-
columnsRatio={columnsRatio}
|
|
550
|
-
/>
|
|
551
|
-
)}
|
|
552
|
-
<Tree
|
|
553
|
-
expandAll={!readonly}
|
|
554
|
-
style={readonly ? {} : { overflow: 'inherit' }}
|
|
555
|
-
motion={false}
|
|
556
|
-
disabled={disabled}
|
|
557
|
-
className={classNames({
|
|
558
|
-
[styles.content]: true,
|
|
559
|
-
[styles.readonly]: readonly,
|
|
560
|
-
[styles['content-fix-pop-container']]: !readonly,
|
|
561
|
-
})}
|
|
562
|
-
renderFullLabel={renderFullLabelProps => {
|
|
563
|
-
const { level, data } = renderFullLabelProps;
|
|
564
|
-
const isTopLevel = level === 0;
|
|
565
|
-
const isSecondLevel = level === 1;
|
|
566
|
-
// Planting the errorbody
|
|
567
|
-
const isOnlyOneData = value.filter(v => !v.readonly).length <= 1;
|
|
568
|
-
|
|
569
|
-
const currentLevelDisabled =
|
|
570
|
-
Boolean(isTopLevel && (isBatch || topLevelReadonly)) ||
|
|
571
|
-
disabled;
|
|
572
|
-
|
|
573
|
-
const disableDelete = (() => {
|
|
574
|
-
// When disabled, deletion is not allowed
|
|
575
|
-
if (currentLevelDisabled) {
|
|
576
|
-
return true;
|
|
577
|
-
}
|
|
578
|
-
// If there is only one non-read-only data
|
|
579
|
-
if (isOnlyOneData) {
|
|
580
|
-
if (isTopLevel && !allowDeleteLast) {
|
|
581
|
-
// And it is the top-level data, and the last piece of data is not allowed to be deleted. It cannot be deleted.
|
|
582
|
-
return true;
|
|
583
|
-
}
|
|
584
|
-
// @Tips hack logic. When batch processing is changed to single processing, the outermost structure will be deleted. You must ensure that children are not empty data.
|
|
585
|
-
// At this time, there is only one piece of data, and it is in batch mode, and it is currently the second layer of data, and there is only one piece of second-layer non-read-only data.
|
|
586
|
-
// It cannot be deleted at this time.
|
|
587
|
-
if (
|
|
588
|
-
isBatch &&
|
|
589
|
-
isSecondLevel &&
|
|
590
|
-
(value.at(0)?.children || []).filter(v => !v.readonly)
|
|
591
|
-
.length <= 1
|
|
592
|
-
) {
|
|
593
|
-
return true;
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
return false;
|
|
597
|
-
})();
|
|
598
|
-
|
|
599
|
-
const onCollapse = (collapsed: boolean) => {
|
|
600
|
-
const { key } = renderFullLabelProps.data;
|
|
601
|
-
|
|
602
|
-
if (!key) {
|
|
603
|
-
return;
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
if (collapsed) {
|
|
607
|
-
expandTreeNode(key);
|
|
608
|
-
} else {
|
|
609
|
-
collapseTreeNode(key);
|
|
610
|
-
}
|
|
611
|
-
};
|
|
612
|
-
|
|
613
|
-
return (
|
|
614
|
-
<CustomTreeNode
|
|
615
|
-
{...renderFullLabelProps}
|
|
616
|
-
readonly={data.readonly || readonly}
|
|
617
|
-
typeReadonly={onlyString}
|
|
618
|
-
needRenderAppendChild={
|
|
619
|
-
data.isPreset
|
|
620
|
-
? !onlyString && needAppendChildWhenNodeIsPreset
|
|
621
|
-
: !onlyString
|
|
622
|
-
}
|
|
623
|
-
onChange={onTreeNodeChange}
|
|
624
|
-
hasObjectLike={hasObjectLike}
|
|
625
|
-
onActiveMultiInfoChange={setActiveMultiInfo}
|
|
626
|
-
activeMultiInfo={activeMultiInfo}
|
|
627
|
-
withDescription={withDescription}
|
|
628
|
-
withRequired={withRequired}
|
|
629
|
-
withDefaultValue={withDefaultValue}
|
|
630
|
-
disabledTypes={disabledTypes}
|
|
631
|
-
hiddenTypes={hiddenTypes}
|
|
632
|
-
disableDelete={disableDelete}
|
|
633
|
-
disabled={currentLevelDisabled}
|
|
634
|
-
couldCollapse={itemKeysWithChildren.length > 0}
|
|
635
|
-
collapsed={renderFullLabelProps.expandStatus.expanded}
|
|
636
|
-
onCollapse={onCollapse}
|
|
637
|
-
defaultExpand={defaultExpandParams?.includes(data.name)}
|
|
638
|
-
columnsRatio={columnsRatio}
|
|
639
|
-
readonlyTooltip={data.readonlyTooltip}
|
|
640
|
-
/>
|
|
641
|
-
);
|
|
642
|
-
}}
|
|
643
|
-
emptyContent={
|
|
644
|
-
emptyPlaceholder && (
|
|
645
|
-
<p className={styles.emptyPlaceholder}>{emptyPlaceholder}</p>
|
|
646
|
-
)
|
|
647
|
-
}
|
|
648
|
-
expandedKeys={[...expandedKeys, nanoid()]} // The nanoid is added to prevent the internal memo state of the component from causing out of sync, and force a recalculation of the hidden state
|
|
649
|
-
treeData={formattedTreeData}
|
|
650
|
-
{...treeProps}
|
|
651
|
-
/>
|
|
652
|
-
{showAddButton ? (
|
|
653
|
-
<AddItemButton
|
|
654
|
-
className="absolute right-0 top-0"
|
|
655
|
-
// Solve the problem that onClick does not trigger due to Button displacement
|
|
656
|
-
onMouseDown={onAdd}
|
|
657
|
-
disabled={isBatch || disabled}
|
|
658
|
-
disabledTooltip={disabledTooltip}
|
|
659
|
-
testId={concatTestId(testId ?? '', 'add-output-item')}
|
|
660
|
-
style={{
|
|
661
|
-
marginLeft:
|
|
662
|
-
itemKeysWithChildren.length > 0 ? TreeCollapseWidth : 0,
|
|
663
|
-
}}
|
|
664
|
-
title={addItemTitle}
|
|
665
|
-
/>
|
|
666
|
-
) : null}
|
|
667
|
-
{children}
|
|
668
|
-
</Card>
|
|
669
|
-
{disableAdd ? null : (
|
|
670
|
-
<JSONImport
|
|
671
|
-
startField={id}
|
|
672
|
-
testId={concatTestId(testId ?? '', 'json-import-btn')}
|
|
673
|
-
onChange={onJSONImportChange}
|
|
674
|
-
treeData={formattedTreeData}
|
|
675
|
-
disabledTypes={disabledTypes}
|
|
676
|
-
disabledTooltip={disabledTooltip}
|
|
677
|
-
hideAddButton={isBatch || !!disabled}
|
|
678
|
-
rules={{
|
|
679
|
-
jsonImport,
|
|
680
|
-
readonly,
|
|
681
|
-
topLevelReadonly,
|
|
682
|
-
disabled: Boolean(disabled),
|
|
683
|
-
isBatch,
|
|
684
|
-
withRequired,
|
|
685
|
-
onlyString,
|
|
686
|
-
}}
|
|
687
|
-
/>
|
|
688
|
-
)}
|
|
689
|
-
</div>
|
|
690
|
-
</OutputTreeContextProvider>
|
|
691
|
-
);
|
|
692
|
-
}
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 coze-dev Authors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/* eslint-disable max-lines */
|
|
18
|
+
/* eslint-disable complexity */
|
|
19
|
+
/* eslint-disable max-lines-per-function */
|
|
20
|
+
import React, {
|
|
21
|
+
useCallback,
|
|
22
|
+
useEffect,
|
|
23
|
+
useMemo,
|
|
24
|
+
useRef,
|
|
25
|
+
useState,
|
|
26
|
+
type PropsWithChildren,
|
|
27
|
+
} from 'react';
|
|
28
|
+
|
|
29
|
+
import { nanoid } from 'nanoid';
|
|
30
|
+
import cloneDeep from 'lodash-es/cloneDeep';
|
|
31
|
+
import classNames from 'classnames';
|
|
32
|
+
import { useLatest } from 'ahooks';
|
|
33
|
+
import { WorkflowBatchService } from '@coze-workflow/variable';
|
|
34
|
+
import {
|
|
35
|
+
ResponseFormat,
|
|
36
|
+
ViewVariableType,
|
|
37
|
+
type ViewVariableTreeNode,
|
|
38
|
+
} from '@coze-workflow/base';
|
|
39
|
+
import { useNodeTestId } from '@coze-workflow/base';
|
|
40
|
+
import { I18n } from '@coze-arch/i18n';
|
|
41
|
+
import { type TreeNodeData, type TreeProps } from '@coze-arch/bot-semi/Tree';
|
|
42
|
+
import { Toast, Tree } from '@coze-arch/coze-design';
|
|
43
|
+
|
|
44
|
+
import { FormCard } from '../form-card';
|
|
45
|
+
import { AddItemButton } from '../add-item-button';
|
|
46
|
+
import {
|
|
47
|
+
findCustomTreeNodeDataResult,
|
|
48
|
+
formatTreeData,
|
|
49
|
+
traverse,
|
|
50
|
+
} from './utils';
|
|
51
|
+
import { OutputTreeContextProvider } from './context';
|
|
52
|
+
import { TreeCollapseWidth } from './constants';
|
|
53
|
+
import { ResponseFormatSelect } from './components/response-format';
|
|
54
|
+
import { JSONImport, JSONImportPlaceholder } from './components/json-import';
|
|
55
|
+
import Header from './components/header';
|
|
56
|
+
import {
|
|
57
|
+
type ActiveMultiInfo,
|
|
58
|
+
type TreeNodeCustomData,
|
|
59
|
+
} from './components/custom-tree-node/type';
|
|
60
|
+
import { ChangeMode } from './components/custom-tree-node/constants';
|
|
61
|
+
import CustomTreeNode from './components/custom-tree-node';
|
|
62
|
+
|
|
63
|
+
import styles from './index.module.less';
|
|
64
|
+
|
|
65
|
+
export interface SimpleTreeNodeCustomData {
|
|
66
|
+
key: string;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface OutputTreeProps {
|
|
70
|
+
id: string;
|
|
71
|
+
testId?: string;
|
|
72
|
+
// Whether to allow new root nodes, the default is true
|
|
73
|
+
allowAppendRootData?: boolean;
|
|
74
|
+
// Is it allowed to delete the last piece of data?
|
|
75
|
+
allowDeleteLast?: boolean;
|
|
76
|
+
// Is it batch processing?
|
|
77
|
+
isBatch?: boolean;
|
|
78
|
+
treeProps?: TreeProps;
|
|
79
|
+
readonly?: boolean;
|
|
80
|
+
disabled?: boolean;
|
|
81
|
+
disabledTooltip?: string;
|
|
82
|
+
/** @default I18n.t('workflow_detail_node_output') */
|
|
83
|
+
title?: string;
|
|
84
|
+
/** @default title */
|
|
85
|
+
titleTooltip?: string;
|
|
86
|
+
className?: string;
|
|
87
|
+
style?: React.CSSProperties;
|
|
88
|
+
value: Array<TreeNodeCustomData>;
|
|
89
|
+
onChange: (value: Array<TreeNodeCustomData>) => void;
|
|
90
|
+
withDescription: boolean;
|
|
91
|
+
withRequired: boolean;
|
|
92
|
+
/** Types not supported */
|
|
93
|
+
disabledTypes?: ViewVariableType[];
|
|
94
|
+
/** hidden type */
|
|
95
|
+
hiddenTypes?: ViewVariableType[];
|
|
96
|
+
topLevelReadonly?: boolean;
|
|
97
|
+
emptyPlaceholder?: string;
|
|
98
|
+
responseFormat?: {
|
|
99
|
+
visible?: boolean;
|
|
100
|
+
value?: number;
|
|
101
|
+
readonly?: boolean;
|
|
102
|
+
onChange?: (value?: number) => void;
|
|
103
|
+
};
|
|
104
|
+
/** Default variable type */
|
|
105
|
+
defaultVariableType?: ViewVariableType;
|
|
106
|
+
jsonImport?: boolean;
|
|
107
|
+
noCard?: boolean;
|
|
108
|
+
addItemTitle?: string;
|
|
109
|
+
defaultCollapse?: boolean;
|
|
110
|
+
|
|
111
|
+
// Is the outermost output folded by default?
|
|
112
|
+
formCardDefaultCollapse?: boolean;
|
|
113
|
+
children?: React.ReactNode;
|
|
114
|
+
/** You can still add children to a node preset */
|
|
115
|
+
needAppendChildWhenNodeIsPreset?: boolean;
|
|
116
|
+
maxLimit?: number;
|
|
117
|
+
/**
|
|
118
|
+
* Can the default value be configured, the default is false
|
|
119
|
+
*/
|
|
120
|
+
withDefaultValue?: boolean;
|
|
121
|
+
/**
|
|
122
|
+
* Default expanded parameter name
|
|
123
|
+
*/
|
|
124
|
+
defaultExpandParams?: string[];
|
|
125
|
+
/**
|
|
126
|
+
* Column widths such as 6:4 represent 6 copies of the name and 4 copies of the type
|
|
127
|
+
*/
|
|
128
|
+
columnsRatio?: string;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const getDefaultAppendValue = (
|
|
132
|
+
withRequired = false,
|
|
133
|
+
defaultVariableType = ViewVariableType.String,
|
|
134
|
+
) => {
|
|
135
|
+
const defaultValue: {
|
|
136
|
+
fieldRandomKey: string;
|
|
137
|
+
type: ViewVariableType;
|
|
138
|
+
required?: boolean;
|
|
139
|
+
} = {
|
|
140
|
+
fieldRandomKey: nanoid(),
|
|
141
|
+
type: defaultVariableType,
|
|
142
|
+
};
|
|
143
|
+
if (withRequired) {
|
|
144
|
+
defaultValue.required = true;
|
|
145
|
+
}
|
|
146
|
+
return defaultValue;
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
function useExpandedKeys(keys: string[], defaultCollapse: boolean) {
|
|
150
|
+
const [expandedKeys, setExpandedKeys] = useState(defaultCollapse ? [] : keys);
|
|
151
|
+
|
|
152
|
+
const expandTreeNode = useCallback(
|
|
153
|
+
(key: string) => {
|
|
154
|
+
setExpandedKeys([...new Set([...expandedKeys, key])]);
|
|
155
|
+
},
|
|
156
|
+
[keys],
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
const collapseTreeNode = useCallback(
|
|
160
|
+
(key: string) => {
|
|
161
|
+
setExpandedKeys([
|
|
162
|
+
...expandedKeys.filter(expandedKey => expandedKey !== key),
|
|
163
|
+
]);
|
|
164
|
+
},
|
|
165
|
+
[keys],
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
return { expandedKeys, expandTreeNode, collapseTreeNode };
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export function OutputTree(props: PropsWithChildren<OutputTreeProps>) {
|
|
172
|
+
const {
|
|
173
|
+
id,
|
|
174
|
+
testId,
|
|
175
|
+
readonly = false,
|
|
176
|
+
isBatch = false,
|
|
177
|
+
disabled,
|
|
178
|
+
disabledTooltip,
|
|
179
|
+
children,
|
|
180
|
+
allowAppendRootData = true,
|
|
181
|
+
allowDeleteLast = false,
|
|
182
|
+
treeProps,
|
|
183
|
+
title = I18n.t('workflow_detail_node_output'),
|
|
184
|
+
titleTooltip = title,
|
|
185
|
+
className,
|
|
186
|
+
style,
|
|
187
|
+
value,
|
|
188
|
+
onChange,
|
|
189
|
+
withDescription = false,
|
|
190
|
+
withRequired = false,
|
|
191
|
+
disabledTypes = [],
|
|
192
|
+
hiddenTypes,
|
|
193
|
+
topLevelReadonly = false,
|
|
194
|
+
emptyPlaceholder,
|
|
195
|
+
responseFormat = {},
|
|
196
|
+
defaultVariableType = ViewVariableType.String,
|
|
197
|
+
jsonImport = true,
|
|
198
|
+
noCard = false,
|
|
199
|
+
addItemTitle = I18n.t('workflow_add_output'),
|
|
200
|
+
defaultCollapse = false,
|
|
201
|
+
formCardDefaultCollapse = false,
|
|
202
|
+
needAppendChildWhenNodeIsPreset = true,
|
|
203
|
+
maxLimit,
|
|
204
|
+
withDefaultValue,
|
|
205
|
+
defaultExpandParams = [],
|
|
206
|
+
columnsRatio,
|
|
207
|
+
} = props;
|
|
208
|
+
|
|
209
|
+
// Monitor for changes in this value
|
|
210
|
+
const cardRef = useRef<HTMLDivElement>(null);
|
|
211
|
+
const isValueEmpty = !value || value.length === 0;
|
|
212
|
+
const {
|
|
213
|
+
data: formattedTreeData = [],
|
|
214
|
+
hasObjectLike,
|
|
215
|
+
itemKeysWithChildren,
|
|
216
|
+
} = formatTreeData(cloneDeep(value), id);
|
|
217
|
+
const isDataEmpty = formattedTreeData.length === 0;
|
|
218
|
+
const { expandedKeys, expandTreeNode, collapseTreeNode } = useExpandedKeys(
|
|
219
|
+
itemKeysWithChildren,
|
|
220
|
+
defaultCollapse,
|
|
221
|
+
);
|
|
222
|
+
|
|
223
|
+
const disableAdd = useMemo(() => {
|
|
224
|
+
if (maxLimit === undefined) {
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
return (value?.length ?? 0) >= maxLimit;
|
|
228
|
+
}, [value, maxLimit]);
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* The description of the parent node of which row is currently in a multi-row state (LLM node)
|
|
232
|
+
* For rendering tree vertical lines, the next vertical line in multiple lines of text should be extended
|
|
233
|
+
* If the param name has an error message, the vertical bar extends below the error message and the length changes
|
|
234
|
+
*/
|
|
235
|
+
const [activeMultiInfo, setActiveMultiInfo] = useState<ActiveMultiInfo>({
|
|
236
|
+
activeMultiKey: '',
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
const { concatTestId } = useNodeTestId();
|
|
240
|
+
|
|
241
|
+
const onAdd = () => {
|
|
242
|
+
if (onChange) {
|
|
243
|
+
onChange(
|
|
244
|
+
(formattedTreeData || []).concat({
|
|
245
|
+
...getDefaultAppendValue(withRequired, defaultVariableType),
|
|
246
|
+
// Add field
|
|
247
|
+
field: `[${formattedTreeData.length}]`,
|
|
248
|
+
// At this time, there is no need to specify the type, so as as is used to cancel the type and report an error.
|
|
249
|
+
} as unknown as TreeNodeCustomData),
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
// How to change this component
|
|
255
|
+
const onValueChange = (freshValue?: Array<TreeNodeCustomData>) => {
|
|
256
|
+
if (onChange) {
|
|
257
|
+
freshValue = (freshValue || []).concat([]);
|
|
258
|
+
// Clean up useless fields
|
|
259
|
+
traverse<TreeNodeCustomData>(freshValue, node => {
|
|
260
|
+
const {
|
|
261
|
+
key,
|
|
262
|
+
name,
|
|
263
|
+
type,
|
|
264
|
+
description,
|
|
265
|
+
required,
|
|
266
|
+
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
267
|
+
children,
|
|
268
|
+
isPreset,
|
|
269
|
+
enabled,
|
|
270
|
+
readonly: _readonly,
|
|
271
|
+
defaultValue,
|
|
272
|
+
} = node;
|
|
273
|
+
// eslint-disable-next-line guard-for-in
|
|
274
|
+
for (const prop in node) {
|
|
275
|
+
delete node[prop];
|
|
276
|
+
}
|
|
277
|
+
node.key = key || nanoid();
|
|
278
|
+
node.name = name;
|
|
279
|
+
node.type = type;
|
|
280
|
+
node.description = description;
|
|
281
|
+
if (defaultValue !== null) {
|
|
282
|
+
node.defaultValue = defaultValue;
|
|
283
|
+
}
|
|
284
|
+
if (isPreset) {
|
|
285
|
+
node.isPreset = isPreset;
|
|
286
|
+
node.enabled = enabled || false;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (withRequired) {
|
|
290
|
+
node.required = required || false; // Undefined to false
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if (children) {
|
|
294
|
+
node.children = children;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (_readonly) {
|
|
298
|
+
node.readonly = _readonly;
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
onChange(freshValue);
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
// Tree node change method
|
|
306
|
+
const onTreeNodeChange = (mode: ChangeMode, param: TreeNodeCustomData) => {
|
|
307
|
+
// Clone one first, because the Tree will execute isEqual on treeData, cloning one must be false.
|
|
308
|
+
const cloneDeepTreeData = cloneDeep(
|
|
309
|
+
formattedTreeData,
|
|
310
|
+
) as Array<TreeNodeCustomData>;
|
|
311
|
+
|
|
312
|
+
const findResult = findCustomTreeNodeDataResult(
|
|
313
|
+
cloneDeepTreeData,
|
|
314
|
+
param.field as string,
|
|
315
|
+
);
|
|
316
|
+
|
|
317
|
+
if (findResult) {
|
|
318
|
+
switch (mode) {
|
|
319
|
+
case ChangeMode.Append: {
|
|
320
|
+
// You can't use parentData as a standard for adding, you need to add it under the current data.
|
|
321
|
+
const { data } = findResult;
|
|
322
|
+
const currentChildren = data.children || [];
|
|
323
|
+
// @ts-expect-error Some values do not need to be specified at this time because format is executed during rerender
|
|
324
|
+
data.children = currentChildren.concat({
|
|
325
|
+
...getDefaultAppendValue(false, defaultVariableType),
|
|
326
|
+
// Add field
|
|
327
|
+
field: `${data.field}.children[${currentChildren.length}]`,
|
|
328
|
+
});
|
|
329
|
+
onValueChange(cloneDeepTreeData);
|
|
330
|
+
|
|
331
|
+
// Add a new node under the current node and expand the current node
|
|
332
|
+
if (findResult?.data?.key) {
|
|
333
|
+
expandTreeNode(findResult.data.key);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
break;
|
|
337
|
+
}
|
|
338
|
+
case ChangeMode.Update: {
|
|
339
|
+
const targetArray = findResult.isRoot
|
|
340
|
+
? cloneDeepTreeData
|
|
341
|
+
: findResult.parentData?.children;
|
|
342
|
+
const index = targetArray?.findIndex(item => item.key === param.key);
|
|
343
|
+
|
|
344
|
+
if (index !== undefined) {
|
|
345
|
+
targetArray?.splice(index, 1, param);
|
|
346
|
+
onValueChange(cloneDeepTreeData);
|
|
347
|
+
}
|
|
348
|
+
break;
|
|
349
|
+
}
|
|
350
|
+
case ChangeMode.Delete: {
|
|
351
|
+
if (findResult.isRoot) {
|
|
352
|
+
const freshValue = (cloneDeepTreeData || []).filter(
|
|
353
|
+
item => item.key !== param.key,
|
|
354
|
+
);
|
|
355
|
+
onValueChange(freshValue);
|
|
356
|
+
} else {
|
|
357
|
+
const parentData = findResult.parentData as TreeNodeData;
|
|
358
|
+
parentData.children = (parentData.children || []).filter(
|
|
359
|
+
item => item.key !== param.key,
|
|
360
|
+
);
|
|
361
|
+
onValueChange(cloneDeepTreeData);
|
|
362
|
+
}
|
|
363
|
+
break;
|
|
364
|
+
}
|
|
365
|
+
case ChangeMode.DeleteChildren: {
|
|
366
|
+
const { data } = findResult;
|
|
367
|
+
data.children = [];
|
|
368
|
+
onValueChange(cloneDeepTreeData);
|
|
369
|
+
break;
|
|
370
|
+
}
|
|
371
|
+
default:
|
|
372
|
+
}
|
|
373
|
+
} else {
|
|
374
|
+
Toast.error(I18n.t('workflow_detail_node_output_parsingfailed'));
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
const onJSONImportChange = (freshValue?: Array<TreeNodeCustomData>) => {
|
|
379
|
+
const nextValue: Array<TreeNodeCustomData> = [];
|
|
380
|
+
value
|
|
381
|
+
.filter(item => item.isPreset)
|
|
382
|
+
.forEach(item => {
|
|
383
|
+
const matched = (freshValue || []).find(it => it.name === item.name);
|
|
384
|
+
if (matched) {
|
|
385
|
+
nextValue.push({
|
|
386
|
+
...item,
|
|
387
|
+
enabled: true,
|
|
388
|
+
});
|
|
389
|
+
} else {
|
|
390
|
+
nextValue.push(item);
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
(freshValue || []).forEach(item => {
|
|
395
|
+
const matched = value.find(it => it.isPreset && it.name === item.name);
|
|
396
|
+
if (!matched) {
|
|
397
|
+
nextValue.push(item);
|
|
398
|
+
}
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
onChange(
|
|
402
|
+
maxLimit === undefined ? nextValue : nextValue?.slice(0, maxLimit),
|
|
403
|
+
);
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
const onlyString = useMemo(
|
|
407
|
+
() =>
|
|
408
|
+
([ResponseFormat.Text, ResponseFormat.Markdown] as number[]).includes(
|
|
409
|
+
responseFormat?.value ?? ResponseFormat.JSON,
|
|
410
|
+
),
|
|
411
|
+
[responseFormat.value],
|
|
412
|
+
);
|
|
413
|
+
|
|
414
|
+
const latestValue = useLatest(value);
|
|
415
|
+
const responseFormatValue = useRef(-1);
|
|
416
|
+
useEffect(() => {
|
|
417
|
+
const isUserChangeType =
|
|
418
|
+
responseFormatValue.current !== -1 &&
|
|
419
|
+
responseFormatValue.current !== responseFormat.value;
|
|
420
|
+
|
|
421
|
+
if (responseFormat.value !== undefined) {
|
|
422
|
+
responseFormatValue.current = responseFormat.value;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// If you switch to text mode
|
|
426
|
+
if (onlyString && isUserChangeType) {
|
|
427
|
+
let newValue = [
|
|
428
|
+
{
|
|
429
|
+
key: nanoid(),
|
|
430
|
+
name: 'output',
|
|
431
|
+
type: ViewVariableType.String,
|
|
432
|
+
},
|
|
433
|
+
] as TreeNodeCustomData[];
|
|
434
|
+
|
|
435
|
+
const _value = latestValue.current;
|
|
436
|
+
if (isBatch) {
|
|
437
|
+
newValue = WorkflowBatchService.singleOutputMetasToList(
|
|
438
|
+
newValue as ViewVariableTreeNode[],
|
|
439
|
+
) as TreeNodeCustomData[];
|
|
440
|
+
// If there is a value in itself, take the first one, expect: reuse variable name/description
|
|
441
|
+
if (_value?.[0]) {
|
|
442
|
+
newValue = [_value[0]];
|
|
443
|
+
}
|
|
444
|
+
if (_value?.[0].children?.[0]) {
|
|
445
|
+
const [first, ...rest] = _value[0].children;
|
|
446
|
+
newValue[0].children = [first, ...rest.filter(c => c?.readonly)];
|
|
447
|
+
}
|
|
448
|
+
// Modify type to string only
|
|
449
|
+
if (
|
|
450
|
+
newValue?.[0].children?.[0].type &&
|
|
451
|
+
newValue?.[0].children?.[0].type !== ViewVariableType.String
|
|
452
|
+
) {
|
|
453
|
+
newValue[0].children[0].type = ViewVariableType.String;
|
|
454
|
+
|
|
455
|
+
// Remove children
|
|
456
|
+
if (newValue[0].children[0].children) {
|
|
457
|
+
delete newValue[0].children[0].children;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
} else {
|
|
461
|
+
// If there is a value in itself, take the first one, expect: reuse variable name/description
|
|
462
|
+
if (_value?.[0]) {
|
|
463
|
+
const [first, ...rest] = _value;
|
|
464
|
+
newValue = [first, ...rest.filter(c => c?.readonly)];
|
|
465
|
+
}
|
|
466
|
+
// Modify type to string only
|
|
467
|
+
if (newValue[0].type !== ViewVariableType.String) {
|
|
468
|
+
newValue[0].type = ViewVariableType.String;
|
|
469
|
+
|
|
470
|
+
// Remove children
|
|
471
|
+
if (newValue[0].children) {
|
|
472
|
+
delete newValue[0].children;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
onChange(newValue);
|
|
477
|
+
}
|
|
478
|
+
}, [responseFormat.value]);
|
|
479
|
+
|
|
480
|
+
if (readonly && isValueEmpty) {
|
|
481
|
+
return null;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
const Card = noCard ? React.Fragment : FormCard;
|
|
485
|
+
const showAddButton =
|
|
486
|
+
!readonly &&
|
|
487
|
+
!topLevelReadonly &&
|
|
488
|
+
allowAppendRootData &&
|
|
489
|
+
!onlyString &&
|
|
490
|
+
!disableAdd;
|
|
491
|
+
return (
|
|
492
|
+
<OutputTreeContextProvider value={{ testId }}>
|
|
493
|
+
<div
|
|
494
|
+
className={classNames({
|
|
495
|
+
[styles.container]: true,
|
|
496
|
+
[styles['not-readonly']]: !readonly,
|
|
497
|
+
[className || '']: Boolean(className),
|
|
498
|
+
[styles['could-collapse']]: itemKeysWithChildren.length > 0,
|
|
499
|
+
})}
|
|
500
|
+
style={style}
|
|
501
|
+
ref={cardRef}
|
|
502
|
+
>
|
|
503
|
+
<Card
|
|
504
|
+
autoExpandWhenDomChange
|
|
505
|
+
defaultExpand={!formCardDefaultCollapse}
|
|
506
|
+
showBottomBorder
|
|
507
|
+
header={title}
|
|
508
|
+
tooltip={titleTooltip}
|
|
509
|
+
contentClassName="nowheel"
|
|
510
|
+
noPadding
|
|
511
|
+
testId={testId}
|
|
512
|
+
actionButton={
|
|
513
|
+
<div className="flex gap-[4px] items-center">
|
|
514
|
+
{responseFormat.visible ? (
|
|
515
|
+
<ResponseFormatSelect
|
|
516
|
+
testId={concatTestId(testId ?? '', 'json-format')}
|
|
517
|
+
readonly={readonly || responseFormat.readonly}
|
|
518
|
+
value={responseFormat.value}
|
|
519
|
+
outputValue={value}
|
|
520
|
+
onlyString={onlyString}
|
|
521
|
+
onChange={onChange}
|
|
522
|
+
onResponseFormatChange={responseFormat.onChange}
|
|
523
|
+
isBatch={isBatch}
|
|
524
|
+
/>
|
|
525
|
+
) : undefined}
|
|
526
|
+
{!readonly &&
|
|
527
|
+
!topLevelReadonly &&
|
|
528
|
+
allowAppendRootData &&
|
|
529
|
+
!onlyString ? (
|
|
530
|
+
<>
|
|
531
|
+
<JSONImportPlaceholder
|
|
532
|
+
enable={jsonImport}
|
|
533
|
+
hideAddButton={isBatch || !!disabled}
|
|
534
|
+
/>
|
|
535
|
+
</>
|
|
536
|
+
) : null}
|
|
537
|
+
</div>
|
|
538
|
+
}
|
|
539
|
+
>
|
|
540
|
+
{!isDataEmpty && (
|
|
541
|
+
<Header
|
|
542
|
+
readonly={readonly}
|
|
543
|
+
config={{
|
|
544
|
+
hasObjectLike,
|
|
545
|
+
hasCollapse: itemKeysWithChildren.length > 0,
|
|
546
|
+
hasDescription: withDescription,
|
|
547
|
+
hasRequired: withRequired,
|
|
548
|
+
}}
|
|
549
|
+
columnsRatio={columnsRatio}
|
|
550
|
+
/>
|
|
551
|
+
)}
|
|
552
|
+
<Tree
|
|
553
|
+
expandAll={!readonly}
|
|
554
|
+
style={readonly ? {} : { overflow: 'inherit' }}
|
|
555
|
+
motion={false}
|
|
556
|
+
disabled={disabled}
|
|
557
|
+
className={classNames({
|
|
558
|
+
[styles.content]: true,
|
|
559
|
+
[styles.readonly]: readonly,
|
|
560
|
+
[styles['content-fix-pop-container']]: !readonly,
|
|
561
|
+
})}
|
|
562
|
+
renderFullLabel={renderFullLabelProps => {
|
|
563
|
+
const { level, data } = renderFullLabelProps;
|
|
564
|
+
const isTopLevel = level === 0;
|
|
565
|
+
const isSecondLevel = level === 1;
|
|
566
|
+
// Planting the errorbody
|
|
567
|
+
const isOnlyOneData = value.filter(v => !v.readonly).length <= 1;
|
|
568
|
+
|
|
569
|
+
const currentLevelDisabled =
|
|
570
|
+
Boolean(isTopLevel && (isBatch || topLevelReadonly)) ||
|
|
571
|
+
disabled;
|
|
572
|
+
|
|
573
|
+
const disableDelete = (() => {
|
|
574
|
+
// When disabled, deletion is not allowed
|
|
575
|
+
if (currentLevelDisabled) {
|
|
576
|
+
return true;
|
|
577
|
+
}
|
|
578
|
+
// If there is only one non-read-only data
|
|
579
|
+
if (isOnlyOneData) {
|
|
580
|
+
if (isTopLevel && !allowDeleteLast) {
|
|
581
|
+
// And it is the top-level data, and the last piece of data is not allowed to be deleted. It cannot be deleted.
|
|
582
|
+
return true;
|
|
583
|
+
}
|
|
584
|
+
// @Tips hack logic. When batch processing is changed to single processing, the outermost structure will be deleted. You must ensure that children are not empty data.
|
|
585
|
+
// At this time, there is only one piece of data, and it is in batch mode, and it is currently the second layer of data, and there is only one piece of second-layer non-read-only data.
|
|
586
|
+
// It cannot be deleted at this time.
|
|
587
|
+
if (
|
|
588
|
+
isBatch &&
|
|
589
|
+
isSecondLevel &&
|
|
590
|
+
(value.at(0)?.children || []).filter(v => !v.readonly)
|
|
591
|
+
.length <= 1
|
|
592
|
+
) {
|
|
593
|
+
return true;
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
return false;
|
|
597
|
+
})();
|
|
598
|
+
|
|
599
|
+
const onCollapse = (collapsed: boolean) => {
|
|
600
|
+
const { key } = renderFullLabelProps.data;
|
|
601
|
+
|
|
602
|
+
if (!key) {
|
|
603
|
+
return;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
if (collapsed) {
|
|
607
|
+
expandTreeNode(key);
|
|
608
|
+
} else {
|
|
609
|
+
collapseTreeNode(key);
|
|
610
|
+
}
|
|
611
|
+
};
|
|
612
|
+
|
|
613
|
+
return (
|
|
614
|
+
<CustomTreeNode
|
|
615
|
+
{...renderFullLabelProps}
|
|
616
|
+
readonly={data.readonly || readonly}
|
|
617
|
+
typeReadonly={onlyString}
|
|
618
|
+
needRenderAppendChild={
|
|
619
|
+
data.isPreset
|
|
620
|
+
? !onlyString && needAppendChildWhenNodeIsPreset
|
|
621
|
+
: !onlyString
|
|
622
|
+
}
|
|
623
|
+
onChange={onTreeNodeChange}
|
|
624
|
+
hasObjectLike={hasObjectLike}
|
|
625
|
+
onActiveMultiInfoChange={setActiveMultiInfo}
|
|
626
|
+
activeMultiInfo={activeMultiInfo}
|
|
627
|
+
withDescription={withDescription}
|
|
628
|
+
withRequired={withRequired}
|
|
629
|
+
withDefaultValue={withDefaultValue}
|
|
630
|
+
disabledTypes={disabledTypes}
|
|
631
|
+
hiddenTypes={hiddenTypes}
|
|
632
|
+
disableDelete={disableDelete}
|
|
633
|
+
disabled={currentLevelDisabled}
|
|
634
|
+
couldCollapse={itemKeysWithChildren.length > 0}
|
|
635
|
+
collapsed={renderFullLabelProps.expandStatus.expanded}
|
|
636
|
+
onCollapse={onCollapse}
|
|
637
|
+
defaultExpand={defaultExpandParams?.includes(data.name)}
|
|
638
|
+
columnsRatio={columnsRatio}
|
|
639
|
+
readonlyTooltip={data.readonlyTooltip}
|
|
640
|
+
/>
|
|
641
|
+
);
|
|
642
|
+
}}
|
|
643
|
+
emptyContent={
|
|
644
|
+
emptyPlaceholder && (
|
|
645
|
+
<p className={styles.emptyPlaceholder}>{emptyPlaceholder}</p>
|
|
646
|
+
)
|
|
647
|
+
}
|
|
648
|
+
expandedKeys={[...expandedKeys, nanoid()]} // The nanoid is added to prevent the internal memo state of the component from causing out of sync, and force a recalculation of the hidden state
|
|
649
|
+
treeData={formattedTreeData}
|
|
650
|
+
{...treeProps}
|
|
651
|
+
/>
|
|
652
|
+
{showAddButton ? (
|
|
653
|
+
<AddItemButton
|
|
654
|
+
className="absolute right-0 top-0"
|
|
655
|
+
// Solve the problem that onClick does not trigger due to Button displacement
|
|
656
|
+
onMouseDown={onAdd}
|
|
657
|
+
disabled={isBatch || disabled}
|
|
658
|
+
disabledTooltip={disabledTooltip}
|
|
659
|
+
testId={concatTestId(testId ?? '', 'add-output-item')}
|
|
660
|
+
style={{
|
|
661
|
+
marginLeft:
|
|
662
|
+
itemKeysWithChildren.length > 0 ? TreeCollapseWidth : 0,
|
|
663
|
+
}}
|
|
664
|
+
title={addItemTitle}
|
|
665
|
+
/>
|
|
666
|
+
) : null}
|
|
667
|
+
{children}
|
|
668
|
+
</Card>
|
|
669
|
+
{disableAdd ? null : (
|
|
670
|
+
<JSONImport
|
|
671
|
+
startField={id}
|
|
672
|
+
testId={concatTestId(testId ?? '', 'json-import-btn')}
|
|
673
|
+
onChange={onJSONImportChange}
|
|
674
|
+
treeData={formattedTreeData}
|
|
675
|
+
disabledTypes={disabledTypes}
|
|
676
|
+
disabledTooltip={disabledTooltip}
|
|
677
|
+
hideAddButton={isBatch || !!disabled}
|
|
678
|
+
rules={{
|
|
679
|
+
jsonImport,
|
|
680
|
+
readonly,
|
|
681
|
+
topLevelReadonly,
|
|
682
|
+
disabled: Boolean(disabled),
|
|
683
|
+
isBatch,
|
|
684
|
+
withRequired,
|
|
685
|
+
onlyString,
|
|
686
|
+
}}
|
|
687
|
+
/>
|
|
688
|
+
)}
|
|
689
|
+
</div>
|
|
690
|
+
</OutputTreeContextProvider>
|
|
691
|
+
);
|
|
692
|
+
}
|