@datatechsolutions/ui 2.11.6 → 2.11.8

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.
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { GlassModalShell, ContextMenu, FormInput, FormTextarea, FormSelect, Button, Card, CardContent, IconButton, Input } from './chunk-46ZM5VJJ.mjs';
2
+ import { GlassModalShell, ContextMenu, FormInput, FormTextarea, FormSelect, Button, IconButton } from './chunk-46ZM5VJJ.mjs';
3
3
  import { GraphNodeHeader, GraphNodeMeta, GraphNodeBadge, GraphNodeIconBubble } from './chunk-OZNTQROP.mjs';
4
4
  import { getAgentTier, createDefaultLogicNodeConfig, applyDagreLayout } from './chunk-TLPPVL3W.mjs';
5
5
  import { useTranslations, I18nProvider, createI18nFromMessages } from './chunk-7VJ7CMMT.mjs';
@@ -208,47 +208,84 @@ var useWorkflowStore = create((set, get) => ({
208
208
  });
209
209
  }
210
210
  }));
211
- var useModalStore = create((set) => ({
211
+ var EMPTY_STATE = {
212
212
  activeModal: null,
213
213
  agentData: null,
214
- subworkflowData: null,
215
214
  logicNodeData: null,
216
- pipelineSettingsData: null,
217
- openAgentModal: (agent, models, isCreateMode = false) => set({
218
- activeModal: "agent",
219
- agentData: { agent, models, isCreateMode },
220
- subworkflowData: null,
221
- logicNodeData: null,
222
- pipelineSettingsData: null
223
- }),
224
- openSubworkflowModal: (tool) => set({
225
- activeModal: "subworkflow",
226
- subworkflowData: { tool },
227
- agentData: null,
228
- logicNodeData: null,
229
- pipelineSettingsData: null
230
- }),
231
- openLogicNodeModal: (nodeId, nodeLabel, config) => set({
232
- activeModal: "logic-node",
233
- logicNodeData: { nodeId, nodeLabel, config },
234
- agentData: null,
235
- subworkflowData: null,
236
- pipelineSettingsData: null
237
- }),
238
- openPipelineSettingsModal: (name, description) => set({
239
- activeModal: "pipeline-settings",
240
- pipelineSettingsData: { name, description },
241
- agentData: null,
242
- subworkflowData: null,
243
- logicNodeData: null
244
- }),
245
- closeModal: () => set({
246
- activeModal: null,
247
- agentData: null,
248
- subworkflowData: null,
249
- logicNodeData: null,
250
- pipelineSettingsData: null
251
- })
215
+ pipelineSettingsData: null
216
+ };
217
+ var useModalStore = create((set, get) => ({
218
+ ...EMPTY_STATE,
219
+ stack: [],
220
+ openAgentModal: (agent, models, isCreateMode = false) => {
221
+ const current = get();
222
+ const entry = {
223
+ type: current.activeModal,
224
+ agentData: current.agentData,
225
+ logicNodeData: current.logicNodeData,
226
+ pipelineSettingsData: current.pipelineSettingsData
227
+ };
228
+ const newStack = current.activeModal ? [...current.stack, entry] : current.stack;
229
+ set({
230
+ activeModal: "agent",
231
+ agentData: { agent, models, isCreateMode },
232
+ logicNodeData: null,
233
+ pipelineSettingsData: null,
234
+ stack: newStack
235
+ });
236
+ },
237
+ openLogicNodeModal: (nodeId, nodeLabel, config) => {
238
+ const current = get();
239
+ const entry = {
240
+ type: current.activeModal,
241
+ agentData: current.agentData,
242
+ logicNodeData: current.logicNodeData,
243
+ pipelineSettingsData: current.pipelineSettingsData
244
+ };
245
+ const newStack = current.activeModal ? [...current.stack, entry] : current.stack;
246
+ set({
247
+ activeModal: "logic-node",
248
+ logicNodeData: { nodeId, nodeLabel, config },
249
+ agentData: null,
250
+ pipelineSettingsData: null,
251
+ stack: newStack
252
+ });
253
+ },
254
+ openPipelineSettingsModal: (name, description) => {
255
+ const current = get();
256
+ const entry = {
257
+ type: current.activeModal,
258
+ agentData: current.agentData,
259
+ logicNodeData: current.logicNodeData,
260
+ pipelineSettingsData: current.pipelineSettingsData
261
+ };
262
+ const newStack = current.activeModal ? [...current.stack, entry] : current.stack;
263
+ set({
264
+ activeModal: "pipeline-settings",
265
+ pipelineSettingsData: { name, description },
266
+ agentData: null,
267
+ logicNodeData: null,
268
+ stack: newStack
269
+ });
270
+ },
271
+ closeModal: () => {
272
+ const { stack } = get();
273
+ if (stack.length > 0) {
274
+ const previous = stack[stack.length - 1];
275
+ set({
276
+ activeModal: previous.type,
277
+ agentData: previous.agentData,
278
+ logicNodeData: previous.logicNodeData,
279
+ pipelineSettingsData: previous.pipelineSettingsData,
280
+ stack: stack.slice(0, -1)
281
+ });
282
+ } else {
283
+ set({ ...EMPTY_STATE, stack: [] });
284
+ }
285
+ },
286
+ closeAllModals: () => {
287
+ set({ ...EMPTY_STATE, stack: [] });
288
+ }
252
289
  }));
253
290
  var GRAPH_ACTIVE_EDGE_COLOR = "#14b8a6";
254
291
  var GRAPH_TRUE_EDGE_COLOR = "#22c55e";
@@ -2888,203 +2925,214 @@ var GroupFlowNode = memo(function GroupFlowNode2({ id, data, selected }) {
2888
2925
  /* @__PURE__ */ jsx(WorkflowHandle, { type: "source", position: Position.Right, id: "right-out", colorClass: "!bg-slate-500" })
2889
2926
  ] });
2890
2927
  });
2891
- function StartNodeConfigForm({ config, onSave, onCancel }) {
2892
- const t = useTranslations("agents.workflow.startNodeConfig");
2893
- const [inputVariables, setInputVariables] = useState([...config.inputVariables]);
2928
+ function ConfigFormActions({
2929
+ cancelLabel,
2930
+ saveLabel,
2931
+ onCancel,
2932
+ onSave,
2933
+ saveDisabled = false
2934
+ }) {
2935
+ return /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2 border-t border-gray-200 pt-4 dark:border-gray-700", children: [
2936
+ /* @__PURE__ */ jsx(Button, { type: "button", outline: true, onClick: onCancel, children: cancelLabel }),
2937
+ /* @__PURE__ */ jsx(Button, { type: "button", onClick: onSave, disabled: saveDisabled, children: saveLabel })
2938
+ ] });
2939
+ }
2940
+ var COLOR_CLASSES = {
2941
+ green: {
2942
+ badge: "bg-green-100 text-green-700 dark:bg-green-500/20 dark:text-green-300",
2943
+ input: "focus:border-green-400 focus:ring-green-400/20",
2944
+ row: "border-green-200/30 dark:border-green-500/15",
2945
+ add: "text-green-600 hover:text-green-700 dark:text-green-400 dark:hover:text-green-300",
2946
+ dot: "bg-green-500"
2947
+ },
2948
+ blue: {
2949
+ badge: "bg-blue-100 text-blue-700 dark:bg-blue-500/20 dark:text-blue-300",
2950
+ input: "focus:border-blue-400 focus:ring-blue-400/20",
2951
+ row: "border-blue-200/30 dark:border-blue-500/15",
2952
+ add: "text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300",
2953
+ dot: "bg-blue-500"
2954
+ },
2955
+ purple: {
2956
+ badge: "bg-purple-100 text-purple-700 dark:bg-purple-500/20 dark:text-purple-300",
2957
+ input: "focus:border-purple-400 focus:ring-purple-400/20",
2958
+ row: "border-purple-200/30 dark:border-purple-500/15",
2959
+ add: "text-purple-600 hover:text-purple-700 dark:text-purple-400 dark:hover:text-purple-300",
2960
+ dot: "bg-purple-500"
2961
+ },
2962
+ red: {
2963
+ badge: "bg-red-100 text-red-700 dark:bg-red-500/20 dark:text-red-300",
2964
+ input: "focus:border-red-400 focus:ring-red-400/20",
2965
+ row: "border-red-200/30 dark:border-red-500/15",
2966
+ add: "text-red-600 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300",
2967
+ dot: "bg-red-500"
2968
+ },
2969
+ teal: {
2970
+ badge: "bg-teal-100 text-teal-700 dark:bg-teal-500/20 dark:text-teal-300",
2971
+ input: "focus:border-teal-400 focus:ring-teal-400/20",
2972
+ row: "border-teal-200/30 dark:border-teal-500/15",
2973
+ add: "text-teal-600 hover:text-teal-700 dark:text-teal-400 dark:hover:text-teal-300",
2974
+ dot: "bg-teal-500"
2975
+ }
2976
+ };
2977
+ function VariableListEditor({
2978
+ variables,
2979
+ onChange,
2980
+ placeholder = "Variable name",
2981
+ label,
2982
+ addLabel = "Add",
2983
+ color = "green",
2984
+ numbered = false,
2985
+ editable = false,
2986
+ max = 0
2987
+ }) {
2894
2988
  const [newVariable, setNewVariable] = useState("");
2895
- const handleAddVariable = () => {
2989
+ const inputRef = useRef(null);
2990
+ const colors = COLOR_CLASSES[color];
2991
+ const canAdd = max === 0 || variables.length < max;
2992
+ const handleAdd = useCallback(() => {
2896
2993
  const trimmed = newVariable.trim();
2897
- if (trimmed && !inputVariables.includes(trimmed)) {
2898
- setInputVariables([...inputVariables, trimmed]);
2899
- setNewVariable("");
2900
- }
2901
- };
2902
- const handleRemoveVariable = (variable) => {
2903
- setInputVariables(inputVariables.filter((existingVariable) => existingVariable !== variable));
2904
- };
2905
- const handleKeyDown = (event) => {
2994
+ if (!trimmed || variables.includes(trimmed)) return;
2995
+ onChange([...variables, trimmed]);
2996
+ setNewVariable("");
2997
+ inputRef.current?.focus();
2998
+ }, [newVariable, variables, onChange]);
2999
+ const handleRemove = useCallback((index) => {
3000
+ onChange(variables.filter((_, i) => i !== index));
3001
+ }, [variables, onChange]);
3002
+ const handleEdit = useCallback((index, value) => {
3003
+ const updated = [...variables];
3004
+ updated[index] = value;
3005
+ onChange(updated);
3006
+ }, [variables, onChange]);
3007
+ const handleKeyDown = useCallback((event) => {
2906
3008
  if (event.key === "Enter") {
2907
3009
  event.preventDefault();
2908
- handleAddVariable();
3010
+ handleAdd();
2909
3011
  }
2910
- };
3012
+ }, [handleAdd]);
3013
+ return /* @__PURE__ */ jsxs("div", { children: [
3014
+ label && /* @__PURE__ */ jsx("label", { className: "mb-2 block text-xs font-medium text-gray-500 dark:text-gray-400", children: label }),
3015
+ variables.length > 0 && /* @__PURE__ */ jsx("div", { className: "mb-2 space-y-1", children: variables.map((variable, index) => /* @__PURE__ */ jsxs(
3016
+ "div",
3017
+ {
3018
+ className: `group flex items-center gap-2 rounded-lg border px-2.5 py-1.5 transition-colors ${colors.row} hover:bg-white/5`,
3019
+ children: [
3020
+ numbered ? /* @__PURE__ */ jsx("span", { className: `inline-flex h-5 min-w-5 items-center justify-center rounded-full text-[10px] font-bold ${colors.badge}`, children: index + 1 }) : /* @__PURE__ */ jsx("span", { className: `h-1.5 w-1.5 shrink-0 rounded-full ${colors.dot}` }),
3021
+ editable ? /* @__PURE__ */ jsx(
3022
+ "input",
3023
+ {
3024
+ type: "text",
3025
+ value: variable,
3026
+ onChange: (event) => handleEdit(index, event.target.value),
3027
+ className: `flex-1 rounded-md border-0 bg-transparent px-1 py-0.5 text-sm font-medium text-gray-900 outline-none ${colors.input} focus:ring-1 dark:text-white`
3028
+ }
3029
+ ) : /* @__PURE__ */ jsx("span", { className: "flex-1 text-sm font-medium text-gray-900 dark:text-white", children: variable }),
3030
+ /* @__PURE__ */ jsx(
3031
+ "button",
3032
+ {
3033
+ type: "button",
3034
+ onClick: () => handleRemove(index),
3035
+ className: "shrink-0 rounded p-0.5 text-gray-400 opacity-0 transition-all hover:bg-red-100 hover:text-red-500 group-hover:opacity-100 dark:hover:bg-red-500/10 dark:hover:text-red-400",
3036
+ "aria-label": `Remove ${variable}`,
3037
+ children: /* @__PURE__ */ jsx(XMarkIcon$1, { className: "h-3.5 w-3.5" })
3038
+ }
3039
+ )
3040
+ ]
3041
+ },
3042
+ `${index}-${variable}`
3043
+ )) }),
3044
+ canAdd && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
3045
+ /* @__PURE__ */ jsx(
3046
+ "input",
3047
+ {
3048
+ ref: inputRef,
3049
+ type: "text",
3050
+ value: newVariable,
3051
+ onChange: (event) => setNewVariable(event.target.value),
3052
+ onKeyDown: handleKeyDown,
3053
+ placeholder,
3054
+ className: "flex-1 rounded-lg border border-gray-200/50 bg-gray-50/50 px-3 py-1.5 text-sm text-gray-700 outline-none transition-colors placeholder:text-gray-400 focus:border-gray-300 focus:ring-1 focus:ring-gray-300/30 dark:border-white/10 dark:bg-white/5 dark:text-gray-300 dark:placeholder:text-gray-600"
3055
+ }
3056
+ ),
3057
+ /* @__PURE__ */ jsxs(
3058
+ "button",
3059
+ {
3060
+ type: "button",
3061
+ onClick: handleAdd,
3062
+ disabled: !newVariable.trim(),
3063
+ className: `flex items-center gap-1 rounded-lg px-3 py-1.5 text-xs font-semibold transition-all disabled:cursor-not-allowed disabled:opacity-40 ${colors.add} hover:bg-white/10`,
3064
+ children: [
3065
+ /* @__PURE__ */ jsx(PlusIcon$1, { className: "h-3.5 w-3.5" }),
3066
+ addLabel
3067
+ ]
3068
+ }
3069
+ )
3070
+ ] }),
3071
+ variables.length === 0 && !canAdd && /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-400 dark:text-gray-500", children: "No variables defined" })
3072
+ ] });
3073
+ }
3074
+ function StartNodeConfigForm({ config, onSave, onCancel }) {
3075
+ const t = useTranslations("agents.workflow.startNodeConfig");
3076
+ const [inputVariables, setInputVariables] = useState([...config.inputVariables]);
2911
3077
  const handleSave = () => {
2912
3078
  onSave({ ...config, inputVariables });
2913
3079
  };
2914
3080
  return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
2915
3081
  /* @__PURE__ */ jsxs("div", { children: [
2916
- /* @__PURE__ */ jsx("label", { className: "mb-1 block text-sm font-medium text-gray-700 dark:text-gray-300", children: t("inputVariablesLabel") }),
2917
3082
  /* @__PURE__ */ jsx("p", { className: "mb-2 text-xs text-gray-500 dark:text-gray-400", children: t("inputVariablesHelp") }),
2918
- /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
2919
- /* @__PURE__ */ jsx(
2920
- Input,
2921
- {
2922
- value: newVariable,
2923
- onChange: (event) => setNewVariable(event.target.value),
2924
- onKeyDown: handleKeyDown,
2925
- placeholder: t("variablePlaceholder"),
2926
- className: "flex-1"
2927
- }
2928
- ),
2929
- /* @__PURE__ */ jsx(
2930
- Button,
2931
- {
2932
- type: "button",
2933
- onClick: handleAddVariable,
2934
- outline: true,
2935
- size: "sm",
2936
- children: t("addVariable")
2937
- }
2938
- )
2939
- ] }),
2940
- /* @__PURE__ */ jsx("div", { className: "mt-2 flex flex-wrap gap-2", children: inputVariables.map((variable) => /* @__PURE__ */ jsxs(
2941
- "span",
2942
- {
2943
- className: "inline-flex items-center gap-1 rounded-full bg-green-100 px-2.5 py-1 text-xs font-medium text-green-700 dark:bg-green-500/20 dark:text-green-300",
2944
- children: [
2945
- variable,
2946
- /* @__PURE__ */ jsx(
2947
- IconButton,
2948
- {
2949
- icon: /* @__PURE__ */ jsx(XMarkIcon$1, { className: "h-3 w-3" }),
2950
- label: `Remove ${variable}`,
2951
- onClick: () => handleRemoveVariable(variable),
2952
- variant: "ghost",
2953
- size: "sm",
2954
- className: "!p-0"
2955
- }
2956
- )
2957
- ]
2958
- },
2959
- variable
2960
- )) })
2961
- ] }),
2962
- /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2 border-t border-gray-200 pt-4 dark:border-gray-700", children: [
2963
3083
  /* @__PURE__ */ jsx(
2964
- Button,
3084
+ VariableListEditor,
2965
3085
  {
2966
- type: "button",
2967
- onClick: onCancel,
2968
- outline: true,
2969
- size: "sm",
2970
- children: t("cancel")
2971
- }
2972
- ),
2973
- /* @__PURE__ */ jsx(
2974
- Button,
2975
- {
2976
- type: "button",
2977
- onClick: handleSave,
2978
- color: "ios-glass-blue",
2979
- size: "sm",
2980
- children: t("save")
3086
+ variables: inputVariables,
3087
+ onChange: setInputVariables,
3088
+ label: t("inputVariablesLabel"),
3089
+ placeholder: t("variablePlaceholder"),
3090
+ addLabel: t("addVariable"),
3091
+ color: "green"
2981
3092
  }
2982
3093
  )
2983
- ] })
3094
+ ] }),
3095
+ /* @__PURE__ */ jsx(
3096
+ ConfigFormActions,
3097
+ {
3098
+ cancelLabel: t("cancel"),
3099
+ saveLabel: t("save"),
3100
+ onCancel,
3101
+ onSave: handleSave
3102
+ }
3103
+ )
2984
3104
  ] });
2985
3105
  }
2986
3106
  function EndNodeConfigForm({ config, onSave, onCancel }) {
2987
3107
  const t = useTranslations("agents.workflow.endNodeConfig");
2988
3108
  const [outputVariables, setOutputVariables] = useState([...config.outputVariables]);
2989
- const [newVariable, setNewVariable] = useState("");
2990
- const handleAddVariable = () => {
2991
- const trimmed = newVariable.trim();
2992
- if (trimmed && !outputVariables.includes(trimmed)) {
2993
- setOutputVariables([...outputVariables, trimmed]);
2994
- setNewVariable("");
2995
- }
2996
- };
2997
- const handleRemoveVariable = (variable) => {
2998
- setOutputVariables(outputVariables.filter((existingVariable) => existingVariable !== variable));
2999
- };
3000
- const handleKeyDown = (event) => {
3001
- if (event.key === "Enter") {
3002
- event.preventDefault();
3003
- handleAddVariable();
3004
- }
3005
- };
3006
3109
  const handleSave = () => {
3007
3110
  onSave({ ...config, outputVariables });
3008
3111
  };
3009
3112
  return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
3010
3113
  /* @__PURE__ */ jsxs("div", { children: [
3011
- /* @__PURE__ */ jsx("label", { className: "mb-1 block text-sm font-medium text-gray-700 dark:text-gray-300", children: t("outputVariablesLabel") }),
3012
3114
  /* @__PURE__ */ jsx("p", { className: "mb-2 text-xs text-gray-500 dark:text-gray-400", children: t("outputVariablesHelp") }),
3013
- /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
3014
- /* @__PURE__ */ jsx(
3015
- "input",
3016
- {
3017
- type: "text",
3018
- value: newVariable,
3019
- onChange: (event) => setNewVariable(event.target.value),
3020
- onKeyDown: handleKeyDown,
3021
- placeholder: t("variablePlaceholder"),
3022
- className: "w-full flex-1 rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm text-gray-900 placeholder-gray-400 outline-none focus:border-indigo-400 focus:ring-2 focus:ring-indigo-400/20 dark:border-gray-600 dark:bg-gray-800 dark:text-white dark:placeholder-gray-500"
3023
- }
3024
- ),
3025
- /* @__PURE__ */ jsx(
3026
- "button",
3027
- {
3028
- type: "button",
3029
- onClick: handleAddVariable,
3030
- className: "text-sm text-indigo-600 hover:text-indigo-700 dark:text-indigo-400",
3031
- children: t("addVariable")
3032
- }
3033
- )
3034
- ] }),
3035
- /* @__PURE__ */ jsx("div", { className: "mt-2 flex flex-wrap gap-2", children: outputVariables.map((variable) => /* @__PURE__ */ jsxs(
3036
- "span",
3037
- {
3038
- className: "inline-flex items-center gap-1 rounded-full bg-red-100 px-2.5 py-1 text-xs font-medium text-red-700 dark:bg-red-500/20 dark:text-red-300",
3039
- children: [
3040
- variable,
3041
- /* @__PURE__ */ jsx(
3042
- "button",
3043
- {
3044
- type: "button",
3045
- onClick: () => handleRemoveVariable(variable),
3046
- className: "text-sm text-red-500 hover:text-red-600",
3047
- "aria-label": `Remove ${variable}`,
3048
- children: /* @__PURE__ */ jsx(XMarkIcon$1, { className: "h-3 w-3" })
3049
- }
3050
- )
3051
- ]
3052
- },
3053
- variable
3054
- )) })
3055
- ] }),
3056
- /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2 pt-4 border-t border-gray-200 dark:border-gray-700", children: [
3057
- /* @__PURE__ */ jsx(
3058
- "button",
3059
- {
3060
- type: "button",
3061
- onClick: onCancel,
3062
- className: "rounded-lg border border-gray-300 px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-800",
3063
- children: t("cancel")
3064
- }
3065
- ),
3066
3115
  /* @__PURE__ */ jsx(
3067
- "button",
3116
+ VariableListEditor,
3068
3117
  {
3069
- type: "button",
3070
- onClick: handleSave,
3071
- className: "rounded-lg bg-indigo-600 px-4 py-2 text-sm font-medium text-white hover:bg-indigo-700 dark:bg-indigo-500 dark:hover:bg-indigo-600",
3072
- children: t("save")
3118
+ variables: outputVariables,
3119
+ onChange: setOutputVariables,
3120
+ label: t("outputVariablesLabel"),
3121
+ placeholder: t("variablePlaceholder"),
3122
+ addLabel: t("addVariable"),
3123
+ color: "red"
3073
3124
  }
3074
3125
  )
3075
- ] })
3076
- ] });
3077
- }
3078
- function ConfigFormActions({
3079
- cancelLabel,
3080
- saveLabel,
3081
- onCancel,
3082
- onSave,
3083
- saveDisabled = false
3084
- }) {
3085
- return /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2 border-t border-gray-200 pt-4 dark:border-gray-700", children: [
3086
- /* @__PURE__ */ jsx(Button, { type: "button", outline: true, onClick: onCancel, children: cancelLabel }),
3087
- /* @__PURE__ */ jsx(Button, { type: "button", onClick: onSave, disabled: saveDisabled, children: saveLabel })
3126
+ ] }),
3127
+ /* @__PURE__ */ jsx(
3128
+ ConfigFormActions,
3129
+ {
3130
+ cancelLabel: t("cancel"),
3131
+ saveLabel: t("save"),
3132
+ onCancel,
3133
+ onSave: handleSave
3134
+ }
3135
+ )
3088
3136
  ] });
3089
3137
  }
3090
3138
  var OPERATOR_OPTIONS = [
@@ -3566,23 +3614,6 @@ function AnswerNodeConfigForm({ config, onSave, onCancel }) {
3566
3614
  const t = useTranslations("agents.workflow.answerNodeConfig");
3567
3615
  const [outputTemplate, setOutputTemplate] = useState(config.outputTemplate);
3568
3616
  const [outputVariables, setOutputVariables] = useState([...config.outputVariables]);
3569
- const [newVariable, setNewVariable] = useState("");
3570
- const handleAddVariable = () => {
3571
- const trimmed = newVariable.trim();
3572
- if (trimmed && !outputVariables.includes(trimmed)) {
3573
- setOutputVariables([...outputVariables, trimmed]);
3574
- setNewVariable("");
3575
- }
3576
- };
3577
- const handleRemoveVariable = (variable) => {
3578
- setOutputVariables(outputVariables.filter((existingVariable) => existingVariable !== variable));
3579
- };
3580
- const handleKeyDown = (event) => {
3581
- if (event.key === "Enter") {
3582
- event.preventDefault();
3583
- handleAddVariable();
3584
- }
3585
- };
3586
3617
  const handleSave = () => {
3587
3618
  onSave({ ...config, outputTemplate, outputVariables });
3588
3619
  };
@@ -3599,50 +3630,17 @@ function AnswerNodeConfigForm({ config, onSave, onCancel }) {
3599
3630
  className: "font-mono text-xs"
3600
3631
  }
3601
3632
  ),
3602
- /* @__PURE__ */ jsxs("div", { children: [
3603
- /* @__PURE__ */ jsx("label", { className: "mb-1 block text-sm font-medium text-gray-700 dark:text-gray-300", children: t("outputVariablesLabel") }),
3604
- /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
3605
- /* @__PURE__ */ jsx(
3606
- FormInput,
3607
- {
3608
- type: "text",
3609
- value: newVariable,
3610
- onValueChange: setNewVariable,
3611
- onKeyDown: handleKeyDown,
3612
- placeholder: t("variablePlaceholder"),
3613
- className: "flex-1"
3614
- }
3615
- ),
3616
- /* @__PURE__ */ jsx(
3617
- Button,
3618
- {
3619
- type: "button",
3620
- onClick: handleAddVariable,
3621
- children: t("addVariable")
3622
- }
3623
- )
3624
- ] }),
3625
- /* @__PURE__ */ jsx("div", { className: "mt-2 flex flex-wrap gap-2", children: outputVariables.map((variable) => /* @__PURE__ */ jsxs(
3626
- "span",
3627
- {
3628
- className: "inline-flex items-center gap-1 rounded-full bg-blue-100 px-2.5 py-1 text-xs font-medium text-blue-700 dark:bg-blue-500/20 dark:text-blue-300",
3629
- children: [
3630
- variable,
3631
- /* @__PURE__ */ jsx(
3632
- IconButton,
3633
- {
3634
- onClick: () => handleRemoveVariable(variable),
3635
- icon: /* @__PURE__ */ jsx(XMarkIcon$1, { className: "h-3 w-3" }),
3636
- label: `Remove ${variable}`,
3637
- size: "sm",
3638
- color: "ios-red"
3639
- }
3640
- )
3641
- ]
3642
- },
3643
- variable
3644
- )) })
3645
- ] }),
3633
+ /* @__PURE__ */ jsx(
3634
+ VariableListEditor,
3635
+ {
3636
+ variables: outputVariables,
3637
+ onChange: setOutputVariables,
3638
+ label: t("outputVariablesLabel"),
3639
+ placeholder: t("variablePlaceholder"),
3640
+ addLabel: t("addVariable"),
3641
+ color: "blue"
3642
+ }
3643
+ ),
3646
3644
  /* @__PURE__ */ jsx(
3647
3645
  ConfigFormActions,
3648
3646
  {
@@ -4037,77 +4035,23 @@ function VariableAggregatorNodeConfigForm({ config, onSave, onCancel }) {
4037
4035
  const [inputVariables, setInputVariables] = useState([...config.inputVariables]);
4038
4036
  const [outputVariable, setOutputVariable] = useState(config.outputVariable);
4039
4037
  const [aggregationMode, setAggregationMode] = useState(config.aggregationMode);
4040
- const [newVariable, setNewVariable] = useState("");
4041
- const handleAddVariable = () => {
4042
- const trimmed = newVariable.trim();
4043
- if (trimmed && !inputVariables.includes(trimmed)) {
4044
- setInputVariables([...inputVariables, trimmed]);
4045
- setNewVariable("");
4046
- }
4047
- };
4048
- const handleRemoveVariable = (index) => {
4049
- setInputVariables(inputVariables.filter((_, variableIndex) => variableIndex !== index));
4050
- };
4051
- const handleVariableChange = (index, value) => {
4052
- setInputVariables(inputVariables.map((variable, variableIndex) => variableIndex === index ? value : variable));
4053
- };
4054
- const handleKeyDown = (event) => {
4055
- if (event.key === "Enter") {
4056
- event.preventDefault();
4057
- handleAddVariable();
4058
- }
4059
- };
4060
4038
  const handleSave = () => {
4061
4039
  onSave({ ...config, inputVariables, outputVariable, aggregationMode });
4062
4040
  };
4063
4041
  return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
4064
- /* @__PURE__ */ jsxs("div", { children: [
4065
- /* @__PURE__ */ jsx("p", { className: "mb-1 block text-sm font-medium text-gray-700 dark:text-gray-300", children: t("inputVariablesLabel") }),
4066
- /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
4067
- /* @__PURE__ */ jsx(
4068
- FormInput,
4069
- {
4070
- type: "text",
4071
- value: newVariable,
4072
- onValueChange: setNewVariable,
4073
- onKeyDown: handleKeyDown,
4074
- placeholder: t("variablePlaceholder"),
4075
- className: "flex-1"
4076
- }
4077
- ),
4078
- /* @__PURE__ */ jsx(
4079
- Button,
4080
- {
4081
- type: "button",
4082
- onClick: handleAddVariable,
4083
- children: t("addInputVariable")
4084
- }
4085
- )
4086
- ] }),
4087
- /* @__PURE__ */ jsx("div", { className: "mt-3 space-y-2", children: inputVariables.map((variable, index) => /* @__PURE__ */ jsx(Card, { className: "border-purple-200/70 dark:border-purple-500/30", children: /* @__PURE__ */ jsx(CardContent, { className: "p-3", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
4088
- /* @__PURE__ */ jsx("span", { className: "inline-flex min-w-6 items-center justify-center rounded-full bg-purple-100 px-1.5 py-0.5 text-[10px] font-semibold text-purple-700 dark:bg-purple-500/20 dark:text-purple-300", children: index + 1 }),
4089
- /* @__PURE__ */ jsx(
4090
- FormInput,
4091
- {
4092
- type: "text",
4093
- value: variable,
4094
- onValueChange: (value) => handleVariableChange(index, value),
4095
- placeholder: t("variablePlaceholder"),
4096
- className: "flex-1"
4097
- }
4098
- ),
4099
- /* @__PURE__ */ jsx(
4100
- IconButton,
4101
- {
4102
- icon: /* @__PURE__ */ jsx(XMarkIcon$1, { className: "h-3 w-3" }),
4103
- label: `Remove ${variable || index + 1}`,
4104
- onClick: () => handleRemoveVariable(index),
4105
- size: "sm",
4106
- color: "ios-red"
4107
- }
4108
- )
4109
- ] }) }) }, `${index}-${variable}`)) })
4110
- ] }),
4042
+ /* @__PURE__ */ jsx(
4043
+ VariableListEditor,
4044
+ {
4045
+ variables: inputVariables,
4046
+ onChange: setInputVariables,
4047
+ label: t("inputVariablesLabel"),
4048
+ placeholder: t("variablePlaceholder"),
4049
+ addLabel: t("addInputVariable"),
4050
+ color: "purple",
4051
+ numbered: true,
4052
+ editable: true
4053
+ }
4054
+ ),
4111
4055
  /* @__PURE__ */ jsx(
4112
4056
  FormInput,
4113
4057
  {
@@ -7139,5 +7083,5 @@ function Workspace({
7139
7083
  }
7140
7084
 
7141
7085
  export { AgentFlowNode, AgentToolFlowNode, AnswerFlowNode, AnthropicIcon, CATEGORY_COLORS, CATEGORY_PILL_COLORS, CodeFlowNode, CrewAIIcon, DocumentExtractorFlowNode, EndFlowNode, EntityFlowNode, FRAMEWORK_META, GoogleADKIcon, GroupFlowNode, HttpRequestFlowNode, ICON_MAP, IfElseFlowNode, IterationFlowNode, IterationStartFlowNode, KnowledgeBaseFlowNode, LOGIC_ICON_MAP, LOGIC_NODE_BADGE_COLORS, LOGIC_NODE_GRADIENTS, LOGIC_NODE_HANDLE_COLORS, LangChainIcon, ListOperatorFlowNode, LogicNodeModal, MINIMAP_NODE_COLORS, NodeCard, NodeContextMenu, NoteFlowNode, OpenAIIcon, PanelContextMenu, ParameterExtractorFlowNode, QuestionClassifierFlowNode, RuleFlowNode, SelectionContextMenu, StartFlowNode, StrandsIcon, TemplateTransformFlowNode, ToolFlowNode, VariableAggregatorFlowNode, VariableAssignerFlowNode, WorkflowBuilderProvider, WorkflowCanvas, Workspace, getCompatibleModels, getDefaultFrameworkForModel, getEntityBadgeColor, getEntityGradient, getEntityHandleColor, getEntityIcon, getEntityMinimapColor, getFrameworkMeta, isModelCompatibleWithFramework, useModalStore, useWorkflowBuilderClient, useWorkflowBuilderClientOptional, useWorkflowStore };
7142
- //# sourceMappingURL=chunk-TM2UUOQO.mjs.map
7143
- //# sourceMappingURL=chunk-TM2UUOQO.mjs.map
7086
+ //# sourceMappingURL=chunk-VWKBMTTC.mjs.map
7087
+ //# sourceMappingURL=chunk-VWKBMTTC.mjs.map