@oomol-lab/open-flow 0.1.0-beta.77 → 0.1.0-beta.79

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/README.md +2 -0
  2. package/dist/browser/{ContentIcon-VZQO8VZU.js → ContentIcon-CMn0c-kl.js} +93 -3
  3. package/dist/browser/{FlowCanvas-BNGDMaWr.js → FlowCanvas-BQGBcfoL.js} +1675 -591
  4. package/dist/browser/{createResourceDialog-BmtakfVg.js → createResourceDialog-DkovGogv.js} +3 -3
  5. package/dist/browser/{dialog-BcFBfRB1.js → dialog-CFFuRM8s.js} +37 -86
  6. package/dist/browser/{exportSvg-CG8hEUNk.js → exportSvg-CYwyYiuH.js} +2 -2
  7. package/dist/browser/{flowChanges-BGo_4Ypo.js → flowChanges-CN2R-m1M.js} +1258 -422
  8. package/dist/browser/{flowWorkspace-BFHGev7s.js → flowWorkspace-CXVL1FNv.js} +634 -628
  9. package/dist/browser/licenses.md +1 -1
  10. package/dist/browser/preview.css +512 -462
  11. package/dist/browser/preview.js +8183 -6384
  12. package/dist/browser/{tooltip-BAWSUexx.js → tooltip-BDcVTNpu.js} +65 -2
  13. package/dist/browser/{typeScriptSession-CRoezJPN.js → typeScriptSession-CoEIptNC.js} +1 -1
  14. package/dist/browser/ui.css +5 -24
  15. package/dist/browser/workbench.css +512 -462
  16. package/dist/browser/workbench.d.ts +2 -3
  17. package/dist/browser/workbench.js +65 -690
  18. package/dist/browser/{workbenchSelect-CjK-xdm3.js → workbenchSelect-CkOS95gX.js} +2 -2
  19. package/dist/command/index.js +31 -31
  20. package/dist/common/authoring.d.ts +3 -3
  21. package/dist/common/authoringExamples.d.ts +3 -3
  22. package/dist/common/authoringSchema.d.ts +14 -22
  23. package/dist/common/control-api-conformance.js +91 -25
  24. package/dist/common/control-api.d.ts +8 -3
  25. package/dist/common/control-api.js +51 -25
  26. package/dist/common/control-requests.d.ts +9 -3
  27. package/dist/common/control-requests.js +54 -42
  28. package/dist/common/flow-authoring.js +32 -19
  29. package/dist/common/flow-change.d.ts +1 -1
  30. package/dist/common/flow-change.js +32 -19
  31. package/dist/common/flow-encoding.js +31 -18
  32. package/dist/common/flow-semantics.js +41 -26
  33. package/dist/common/flow-state.d.ts +49 -43
  34. package/dist/common/flow-state.js +95 -110
  35. package/dist/common/mcp.d.ts +35 -4
  36. package/dist/common/mcp.js +51 -26
  37. package/dist/common/run-events.js +19 -9
  38. package/dist/common/runtime-contract.d.ts +4 -1
  39. package/dist/common/runtime-contract.js +66 -17
  40. package/dist/common/runtime-nodejs-compat.js +11 -12
  41. package/dist/common/scheduler.d.ts +2 -1
  42. package/dist/common/scheduler.js +82 -55
  43. package/dist/common/state-conformance.d.ts +3 -3
  44. package/dist/index.d.ts +1 -0
  45. package/package.json +1 -1
  46. package/src/control/common/api.ts +36 -7
  47. package/src/control/common/authoring.ts +6 -5
  48. package/src/control/common/authoringExamples.ts +6 -5
  49. package/src/control/common/authoringSchema.ts +7 -7
  50. package/src/control/common/conformance.ts +31 -0
  51. package/src/control/common/mcp.ts +7 -2
  52. package/src/control/common/requests.ts +10 -1
  53. package/src/execution/common/events.ts +22 -10
  54. package/src/execution/common/node-execution.ts +1 -1
  55. package/src/execution/common/scheduler.ts +28 -14
  56. package/src/flow/common/change.ts +1 -1
  57. package/src/flow/common/changeSchema.ts +4 -4
  58. package/src/flow/common/errorHandling.ts +1 -1
  59. package/src/flow/common/semantics.ts +12 -6
  60. package/src/runtime/common/nodejsGuest.generated.json +11 -12
  61. package/src/runtime/common/runtime.ts +45 -12
  62. package/src/state/common/conformance.ts +32 -21
  63. package/src/state/common/state.ts +85 -80
  64. package/src/types/index.ts +1 -0
@@ -1,15 +1,15 @@
1
1
  import { i as __require, o as __toESM, r as __exportAll, t as __commonJSMin } from "./rolldown-runtime-CEgmsyvS.js";
2
- import { A as DropdownMenuSub, C as DropdownMenuContent, D as DropdownMenuRadioGroup, E as DropdownMenuLabel, I as useCompositeItem, J as waitBranchDescription, M as DropdownMenuSubTrigger, N as DropdownMenuTrigger, O as DropdownMenuRadioItem, P as isElementDisabled, S as DropdownMenuCheckboxItem, T as DropdownMenuItem, _ as NativeScrollArea, at as Checkbox, b as Z$1, c as useIconifyData, d as PopoverContent, f as PopoverDescription, g as PopoverTrigger, h as PopoverTitle, j as DropdownMenuSubContent, k as DropdownMenuSeparator, m as PopoverPanelContent, o as IconifyProvider, ot as useAriaLabelledBy, p as PopoverHeader, s as useIconifyCollectionLoader, t as ContentIcon, u as Popover, v as ScrollArea, w as DropdownMenuGroup, x as DropdownMenu, y as VirtualScrollArea } from "./ContentIcon-VZQO8VZU.js";
2
+ import { A as DropdownMenuSeparator, C as DropdownMenuCheckboxItem, D as DropdownMenuLabel, E as DropdownMenuItem, M as DropdownMenuSubContent, N as DropdownMenuSubTrigger, O as DropdownMenuRadioGroup, P as DropdownMenuTrigger, R as useCompositeItem, S as DropdownMenu, T as DropdownMenuGroup, X as waitBranchDescription, _ as PopoverTrigger, b as VirtualScrollArea, c as useIconifyData, ct as useAriaLabelledBy, d as Popover, f as PopoverContent, g as PopoverTitle, h as PopoverPanelContent, j as DropdownMenuSub, k as DropdownMenuRadioItem, m as PopoverHeader, o as IconifyProvider, p as PopoverDescription, s as useIconifyCollectionLoader, st as Checkbox, t as ContentIcon, v as NativeScrollArea, w as DropdownMenuContent, x as Z$1, y as ScrollArea } from "./ContentIcon-CMn0c-kl.js";
3
3
  import { i as compute, l as val } from "./dist-bO8nvHFH.js";
4
4
  import { c as useLang, l as useTranslate, o as I18nProvider, r as isPlainObject, s as useI18n, u as useVal } from "./dist-BFmpkX4P.js";
5
- import { Ar as useButton, B as ARROW_KEYS, Cr as clsx, En as getTarget, Er as EMPTY_OBJECT, Fn as useOpenChangeComplete, Fr as useIsoLayoutEffect, Gn as clearPress, H as ARROW_RIGHT, Hn as createChangeEventDetails, J as MODIFIER_KEYS, K as HORIZONTAL_KEYS, L as useCompositeListItem, Ln as TransitionStatusDataAttributes, Lr as useStableCallback, Nr as formatErrorMessage, Pn as useTransitionStatus, Pr as mergeProps, Q as scrollIntoViewIfNeeded, R as ALL_KEYS, Rn as transitionStatusMapping, Sr as cva, Tn as contains, Tr as EMPTY_ARRAY$1, U as ARROW_UP, V as ARROW_LEFT, Vn as useValueChanged, X as VERTICAL_KEYS_WITH_EXTRA_KEYS, Y as VERTICAL_KEYS, Z as isNativeInput, Zt as useStore, _n as getMinListIndex, _r as visuallyHiddenInput, a as createTooltipHandle, br as buttonVariants, c as TooltipPositioner, cr as useLabelableContext, ct as CompositeList, d as TooltipRoot, dn as createGridCellMap, dr as useFieldRootContext, fn as findNonDisabledListIndex, fr as useBaseUiId, gn as getMaxListIndex, gr as visuallyHidden, hn as getGridNavigatedIndex, hr as fieldValidityMapping, i as TooltipTrigger, j as string, jn as ownerDocument, jr as CompositeRootContext, kr as useMergedRefs, l as TooltipPortal, lr as useFormContext, lt as inertValue, mn as getGridCellIndices, mt as triggerOpenStateMapping, n as TooltipContent, o as TooltipArrow, p as timeZoneOffsetMinutes, pn as getGridCellIndexOfCorner, q as HORIZONTAL_KEYS_WITH_EXTRA_KEYS, r as TooltipProvider, s as TooltipPopup, st as useDirection, t as Tooltip, tn as require_builtin_esm_external_require_react, tr as none, u as TooltipTrigger$1, ur as useRegisterFieldControl, vn as isIndexOutOfListBounds, vr as useControlled, wn as activeElement, wr as useRenderElement, xr as cn, yn as isListIndexDisabled, yr as Button$1, z as ARROW_DOWN } from "./tooltip-BAWSUexx.js";
6
- import { $ as waitAutoContinueSchema, A as comparisonIssue, At as variableInputCompatible, Bt as SelectGroup, Ct as limitDecisionQuestions, D as nodeSystemOutputPorts, Dt as matchesSchema, E as nodeErrorSchema, F as operatorsForType, Ht as SelectSeparator, It as dequal, J as webhookResponseAllowsBody, K as webhookHeaderValuePort, L as unaryOperator, Lt as Select$1, O as supportsNodeErrorHandling, Ot as portsAssignable, P as operandHandle, Q as workflowOutputsPort, R as valueType, Rt as SelectChevron, St as defaultDecisionQuestion, T as workflowToolNameIssue, Tt as webhookSupportsBody, U as decodeRevisionContent, Ut as SelectTrigger, Vt as SelectItem, Wt as SelectValue, X as webhookResponseTimeout, Y as webhookResponseInputs, Z as webhookStatusCodePort, _t as isHttpHost, a as DialogFooter, at as httpHeaderSchema, b as nodeNameIssue, bt as decisionQuestionIssues, c as DialogTrigger, d as Field, et as defaultNodeRetry, f as FieldDescription, h as FieldLabel, i as DialogDescription, in as ChevronDown, kt as schemaObject, l as Icon, lt as httpRequestIssues, m as FieldGroup, nn as Input, nt as retryConfigurationSchema, o as DialogHeader, ot as httpQuerySchema, p as FieldError, pt as httpHeaderNameIssue, q as webhookHeadersPort, r as DialogContent, rn as useLabelableId, rt as supportsNodeRetry, s as DialogTitle, t as Dialog, tn as Label, tt as nodeRetryLimits, u as Spinner, ut as httpRequestTask, vt as decisionLimits, wt as webhookMethods, xt as decisionTask, zt as SelectContent } from "./dialog-BcFBfRB1.js";
7
- import { C as isMac, S as toManifestNodeId, _ as E$1, a as JSONViewer, b as toViewEdge, c as CanvasNodeIcon, d as IconStack, f as selectableTimeZones, g as cronDescription, h as timeZoneOffset, i as Textarea, l as defaultTriggerIcon, m as timeZoneLongLabel, n as setAddItemId, o as collapseAllNested, p as timeZoneLabel, r as NodeHistoryContext, s as formatDuration, t as FlowCanvas, u as useDebouncedValue, v as CanvasTooltip, w as isSameViewport, x as toManifestHandleName, y as CanvasStore } from "./FlowCanvas-BNGDMaWr.js";
8
- import { $n as openApiFieldIssues, $t as GroupCollectionProvider, A as schemaForEditor, An as decodeResultList, B as datePickerValue, Bn as triggerOutputDefinitions, Cn as FeishuEventPicker, D as defaultValueEditorSchema, E as supportsFeishuChatFilter, F as calendarChange, Fn as webhookResponseDiagnostics, Ft as dequal$1, G as indexAddNodeOptions, Gt as ValueEditorFeedback, H as isDateFormat, Ht as selectionMenuContentClass, I as calendarDate, In as sourceOutputLabel, It as WorkflowExportMenuItem, Jn as triggerConfigValue, Jt as ComboboxItem, Kt as valueEditor_module_default, L as dateFromTimeZone, Ln as sourcePort, Lt as IdTooltip, M as getDefaultValue, Mn as executionReachableNodes, N as isUnconstrainedSchema, Nn as inputSourceCandidates, O as editorComponent, P as typeOfSchema, Pn as resolutionOutputPorts, Q as resourceValue, Qn as object$1, Qt as ComboboxList, R as dateInTimeZone, Rt as FlowSettingsButton, Sn as createI18n, T as feishuResourceKind, Tn as errorNotice, Ut as selectionMenuItemClass, V as dateTimeWall, Vn as isJsonObject, Wt as ValueControl, X as observeResource, Xn as inputValue, Xt as ComboboxPositioner, Yn as triggerConfigValues, Yt as ComboboxPopup, Z as resourceData, Zn as listOperations, Zt as ComboboxPortal, _n as EmptyTitle, _r as eventSourceKind, _t as connectionCatalog, an as useComboboxInputValueContext, ar as sameWorkflowInterface, bn as SourceForm, cn as followWorkbenchLink, cr as workflowCandidateGroup, ct as revisionView, dn as InputGroupInput, en as ComboboxTrigger, er as openApiTask, et as designerGraph, fn as Empty, gn as EmptyMedia, gr as controlErrorCode, hn as EmptyHeader, ht as schemaMismatchMessage, in as selectors, ir as servers, it as providerIcon, j as valueForEditor, k as editorGroups, ln as InputGroup, lr as workflowCapability, mn as EmptyDescription, mt as diagnosticNodeId, n as agentTool, nn as ComboboxInput, nr as selectOperation, nt as triggerNodeIcon, on as useComboboxRootContext, or as workflowAgentTool, ot as canCancelRun, pn as EmptyContent, pt as diagnosticMessage, q as mapSource, qt as ComboboxItemIndicator, rn as ComboboxRoot, rr as serverAddress, rt as actionSummary, st as hasRunFilter, tn as ComboboxInputGroup, tr as securityOptions, tt as semanticNodeIcon, un as InputGroupAddon, ur as workflowSelectionTask, vn as Badge, wn as EventSourceSetup, xn as SourceSelect, z as datePickerChange } from "./flowChanges-BGo_4Ypo.js";
5
+ import { A as string, Bn as transitionStatusMapping, Cr as cn, Dr as EMPTY_ARRAY, En as contains, Er as useRenderElement, Fr as formatErrorMessage, I as useCompositeListItem, In as useTransitionStatus, Ir as mergeProps, Ln as useOpenChangeComplete, Lr as useIsoLayoutEffect, Mn as ownerDocument, Mr as useButton, Nn as useLabelableId, Or as EMPTY_OBJECT, Qt as useStore, Sr as buttonVariants, Tn as activeElement, Tr as clsx, Un as useValueChanged, Wn as createChangeEventDetails, _r as fieldValidityMapping, a as createTooltipHandle, br as useControlled, c as TooltipPositioner, ct as CompositeList, d as TooltipRoot, dr as useFormContext, fr as useRegisterFieldControl, i as TooltipTrigger, jr as useMergedRefs, l as TooltipPortal, lt as inertValue, mr as useBaseUiId, mt as triggerOpenStateMapping, n as TooltipContent, nn as require_builtin_esm_external_require_react, o as TooltipArrow, p as timeZoneOffsetMinutes, pr as useFieldRootContext, qn as clearPress, r as TooltipProvider, rr as none, s as TooltipPopup, t as Tooltip, u as TooltipTrigger$1, ur as useLabelableContext, vr as visuallyHidden, wr as cva, xr as Button$1, yr as visuallyHiddenInput, zn as TransitionStatusDataAttributes, zr as useStableCallback } from "./tooltip-BDcVTNpu.js";
6
+ import { $ as waitAutoContinueSchema, A as comparisonIssue, At as variableInputCompatible, Bt as SelectContent, Ct as limitDecisionQuestions, D as nodeSystemOutputPorts, Dt as matchesSchema, E as nodeErrorSchema, F as operatorsForType, Ft as skipDuplicatesConfigSchema, Gt as SelectValue, Ht as SelectItem, J as webhookResponseAllowsBody, K as webhookHeaderValuePort, L as unaryOperator, Lt as dequal, O as supportsNodeErrorHandling, Ot as portsAssignable, P as operandHandle, Q as workflowOutputsPort, R as valueType, Rt as Select$1, St as defaultDecisionQuestion, T as workflowToolNameIssue, Tt as webhookSupportsBody, U as decodeRevisionContent, Ut as SelectSeparator, Vt as SelectGroup, Wt as SelectTrigger, X as webhookResponseTimeout, Y as webhookResponseInputs, Z as webhookStatusCodePort, _t as isHttpHost, a as DialogFooter, at as httpHeaderSchema, b as nodeNameIssue, bt as decisionQuestionIssues, c as DialogTrigger, d as Field, et as defaultNodeRetry, f as FieldDescription, h as FieldLabel, i as DialogDescription, in as ChevronDown, kt as schemaObject, l as Icon, lt as httpRequestIssues, m as FieldGroup, nn as Label, nt as retryConfigurationSchema, o as DialogHeader, ot as httpQuerySchema, p as FieldError, pt as httpHeaderNameIssue, q as webhookHeadersPort, r as DialogContent, rn as Input, rt as supportsNodeRetry, s as DialogTitle, t as Dialog, tt as nodeRetryLimits, u as Spinner, ut as httpRequestTask, vt as decisionLimits, wt as webhookMethods, xt as decisionTask, zt as SelectChevron } from "./dialog-CFFuRM8s.js";
7
+ import { C as toManifestHandleName, E as isSameViewport, S as toViewEdge, T as isMac, _ as timeZoneOffset, a as NodeHistoryContext, b as CanvasTooltip, c as defaultTriggerIcon, d as formatDuration, f as useDebouncedValue, g as timeZoneLongLabel, h as timeZoneLabel, i as setAddItemId, l as JSONViewer, m as selectableTimeZones, n as CompositeRoot, o as Textarea, p as IconStack, r as ACTIVE_COMPOSITE_ITEM, s as CanvasNodeIcon, t as FlowCanvas, u as collapseAllNested, v as cronDescription, w as toManifestNodeId, x as CanvasStore, y as E$1 } from "./FlowCanvas-BQGBcfoL.js";
8
+ import { $n as triggerOutputDefinitions, A as schemaForEditor, An as EmptyTitle, B as datePickerValue, Cn as InputGroupAddon, Cr as workflowSelectionTask, D as defaultValueEditorSchema, Dn as EmptyDescription, Dr as controlErrorCode, E as supportsFeishuChatFilter, En as EmptyContent, Et as schemaMismatchMessage, F as calendarChange, Fn as createI18n, G as indexAddNodeOptions, Gn as executionReachableNodes, H as isDateFormat, I as calendarDate, In as FeishuEventPicker, Jn as webhookResponseDiagnostics, Jt as dequal$1, Kn as inputSourceCandidates, L as dateFromTimeZone, Ln as EventSourceSetup, M as getDefaultValue, N as isUnconstrainedSchema, Nn as SourceForm, O as editorComponent, On as EmptyHeader, Or as eventSourceKind, Ot as connectionCatalog, P as typeOfSchema, Pn as SourceSelect, Q as resourceValue, R as dateInTimeZone, Rn as errorNotice, Sn as InputGroup, Sr as workflowCapability, T as feishuResourceKind, Tn as Empty, Tt as diagnosticNodeId, Un as decodeResultList, V as dateTimeWall, X as observeResource, Xn as sourcePort, Xt as IdTooltip, Yn as sourceOutputLabel, Yt as WorkflowExportMenuItem, Z as resourceData, Zt as FlowSettingsButton, _n as selectors, _r as servers, _t as canCancelRun, an as valueEditor_module_default, at as getAppCatalogCache, cn as ComboboxPopup, cr as triggerConfigValues, dn as ComboboxList, dr as object$1, dt as designerGraph, er as isJsonObject, et as provider, fn as GroupCollectionProvider, fr as openApiFieldIssues, ft as semanticNodeIcon, gn as ComboboxRoot, gr as serverAddress, hn as ComboboxInput, hr as selectOperation, ht as providerIcon, in as ValueEditorFeedback, j as valueForEditor, jn as Badge, k as editorGroups, kn as EmptyMedia, ln as ComboboxPositioner, lr as inputValue, mn as ComboboxInputGroup, mr as securityOptions, mt as actionSummary, n as agentTool, nn as selectionMenuItemClass, on as ComboboxItemIndicator, pn as ComboboxTrigger, pr as openApiTask, pt as triggerNodeIcon, q as mapSource, qn as resolutionOutputPorts, rn as ValueControl, rt as decodeAppCatalogResponse, sn as ComboboxItem, sr as triggerConfigValue, tn as selectionMenuContentClass, un as ComboboxPortal, ur as listOperations, ut as loadJson, vn as useComboboxInputValueContext, vr as sameWorkflowInterface, vt as hasRunFilter, wn as InputGroupInput, wt as diagnosticMessage, xn as followWorkbenchLink, xr as workflowCandidateGroup, yn as useComboboxRootContext, yr as workflowAgentTool, yt as revisionView, z as datePickerChange } from "./flowChanges-CN2R-m1M.js";
9
9
  import { r as resolveUiLanguage } from "./languages-gYzoQqCi.js";
10
10
  import { a as renameObjectField, i as objectValue, n as isJsonValue, o as setObjectField, r as jsonDataTypes, s as valueType$1, t as initialValue } from "./value-BbFQZZ_V.js";
11
11
  import { n as compile, r as validate } from "./flowRunInputEditorStore-ys1-w9GW.js";
12
- import { t as WorkbenchSelect } from "./workbenchSelect-CjK-xdm3.js";
12
+ import { t as WorkbenchSelect } from "./workbenchSelect-CkOS95gX.js";
13
13
  import * as React from "react";
14
14
  import reactExports, { Children, Fragment, Suspense, createContext, forwardRef, isValidElement, lazy, memo, useCallback, useContext, useEffect, useId, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from "react";
15
15
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
@@ -761,9 +761,6 @@ function computeActivationDirection(oldValue, newValue, orientation, tabMap) {
761
761
  return "none";
762
762
  }
763
763
  //#endregion
764
- //#region ../../node_modules/.bun/@base-ui+react@1.4.1+fa6c2f29eeb10566/node_modules/@base-ui/react/esm/internals/composite/constants.js
765
- var ACTIVE_COMPOSITE_ITEM = "data-composite-item-active";
766
- //#endregion
767
764
  //#region ../../node_modules/.bun/@base-ui+react@1.4.1+fa6c2f29eeb10566/node_modules/@base-ui/react/esm/tabs/list/TabsListContext.js
768
765
  var TabsListContext = /*#__PURE__*/ React.createContext(void 0);
769
766
  if (process.env.NODE_ENV !== "production") TabsListContext.displayName = "TabsListContext";
@@ -994,238 +991,6 @@ var TabsPanel = /*#__PURE__*/ React.forwardRef(function TabPanel(componentProps,
994
991
  });
995
992
  if (process.env.NODE_ENV !== "production") TabsPanel.displayName = "TabsPanel";
996
993
  //#endregion
997
- //#region ../../node_modules/.bun/@base-ui+react@1.4.1+fa6c2f29eeb10566/node_modules/@base-ui/react/esm/internals/composite/root/useCompositeRoot.js
998
- var EMPTY_ARRAY = [];
999
- function useCompositeRoot(params) {
1000
- const { itemSizes, cols = 1, loopFocus = true, onLoop, dense = false, orientation = "both", direction, highlightedIndex: externalHighlightedIndex, onHighlightedIndexChange: externalSetHighlightedIndex, rootRef: externalRef, enableHomeAndEndKeys = false, stopEventPropagation = false, disabledIndices, modifierKeys = EMPTY_ARRAY } = params;
1001
- const [internalHighlightedIndex, internalSetHighlightedIndex] = React.useState(0);
1002
- const isGrid = cols > 1;
1003
- const rootRef = React.useRef(null);
1004
- const mergedRef = useMergedRefs(rootRef, externalRef);
1005
- const elementsRef = React.useRef([]);
1006
- const hasSetDefaultIndexRef = React.useRef(false);
1007
- const highlightedIndex = externalHighlightedIndex ?? internalHighlightedIndex;
1008
- const onHighlightedIndexChange = useStableCallback((index, shouldScrollIntoView = false) => {
1009
- (externalSetHighlightedIndex ?? internalSetHighlightedIndex)(index);
1010
- if (shouldScrollIntoView) {
1011
- const newActiveItem = elementsRef.current[index];
1012
- scrollIntoViewIfNeeded(rootRef.current, newActiveItem, direction, orientation);
1013
- }
1014
- });
1015
- const onMapChange = useStableCallback((map) => {
1016
- if (map.size === 0 || hasSetDefaultIndexRef.current) return;
1017
- hasSetDefaultIndexRef.current = true;
1018
- const sortedElements = Array.from(map.keys());
1019
- const activeItem = sortedElements.find((compositeElement) => compositeElement?.hasAttribute("data-composite-item-active")) ?? null;
1020
- const activeIndex = activeItem ? sortedElements.indexOf(activeItem) : -1;
1021
- if (activeIndex !== -1) onHighlightedIndexChange(activeIndex);
1022
- scrollIntoViewIfNeeded(rootRef.current, activeItem, direction, orientation);
1023
- });
1024
- const wrappedOnLoop = useStableCallback((event, prevIndex, nextIndex) => {
1025
- if (!onLoop) return nextIndex;
1026
- return onLoop?.(event, prevIndex, nextIndex, elementsRef);
1027
- });
1028
- const props = React.useMemo(() => ({
1029
- "aria-orientation": orientation === "both" ? void 0 : orientation,
1030
- ref: mergedRef,
1031
- onFocus(event) {
1032
- const element = rootRef.current;
1033
- const target = getTarget(event.nativeEvent);
1034
- if (!element || target == null || !isNativeInput(target)) return;
1035
- target.setSelectionRange(0, target.value.length ?? 0);
1036
- },
1037
- onKeyDown(event) {
1038
- const RELEVANT_KEYS = enableHomeAndEndKeys ? ALL_KEYS : ARROW_KEYS;
1039
- if (!RELEVANT_KEYS.has(event.key)) return;
1040
- if (isModifierKeySet(event, modifierKeys)) return;
1041
- if (!rootRef.current) return;
1042
- const isRtl = direction === "rtl";
1043
- const horizontalForwardKey = isRtl ? ARROW_LEFT : ARROW_RIGHT;
1044
- const forwardKey = {
1045
- horizontal: horizontalForwardKey,
1046
- vertical: ARROW_DOWN,
1047
- both: horizontalForwardKey
1048
- }[orientation];
1049
- const horizontalBackwardKey = isRtl ? ARROW_RIGHT : ARROW_LEFT;
1050
- const backwardKey = {
1051
- horizontal: horizontalBackwardKey,
1052
- vertical: ARROW_UP,
1053
- both: horizontalBackwardKey
1054
- }[orientation];
1055
- const target = getTarget(event.nativeEvent);
1056
- if (target != null && isNativeInput(target) && !isElementDisabled(target)) {
1057
- const selectionStart = target.selectionStart;
1058
- const selectionEnd = target.selectionEnd;
1059
- const textContent = target.value ?? "";
1060
- if (selectionStart == null || event.shiftKey || selectionStart !== selectionEnd) return;
1061
- if (event.key !== backwardKey && selectionStart < textContent.length) return;
1062
- if (event.key !== forwardKey && selectionStart > 0) return;
1063
- }
1064
- let nextIndex = highlightedIndex;
1065
- const minIndex = getMinListIndex(elementsRef, disabledIndices);
1066
- const maxIndex = getMaxListIndex(elementsRef, disabledIndices);
1067
- if (isGrid) {
1068
- const sizes = itemSizes || Array.from({ length: elementsRef.current.length }, () => ({
1069
- width: 1,
1070
- height: 1
1071
- }));
1072
- const cellMap = createGridCellMap(sizes, cols, dense);
1073
- const minGridIndex = cellMap.findIndex((index) => index != null && !isListIndexDisabled(elementsRef.current, index, disabledIndices));
1074
- const maxGridIndex = cellMap.reduce((foundIndex, index, cellIndex) => index != null && !isListIndexDisabled(elementsRef.current, index, disabledIndices) ? cellIndex : foundIndex, -1);
1075
- nextIndex = cellMap[getGridNavigatedIndex(cellMap.map((itemIndex) => itemIndex != null ? elementsRef.current[itemIndex] : null), {
1076
- event,
1077
- orientation,
1078
- loopFocus,
1079
- onLoop: wrappedOnLoop,
1080
- cols,
1081
- disabledIndices: getGridCellIndices([...disabledIndices || elementsRef.current.map((_, index) => isListIndexDisabled(elementsRef.current, index) ? index : void 0), void 0], cellMap),
1082
- minIndex: minGridIndex,
1083
- maxIndex: maxGridIndex,
1084
- prevIndex: getGridCellIndexOfCorner(highlightedIndex > maxIndex ? minIndex : highlightedIndex, sizes, cellMap, cols, event.key === "ArrowDown" ? "bl" : event.key === "ArrowRight" ? "tr" : "tl"),
1085
- rtl: isRtl
1086
- })];
1087
- }
1088
- const forwardKeys = {
1089
- horizontal: [horizontalForwardKey],
1090
- vertical: [ARROW_DOWN],
1091
- both: [horizontalForwardKey, ARROW_DOWN]
1092
- }[orientation];
1093
- const backwardKeys = {
1094
- horizontal: [horizontalBackwardKey],
1095
- vertical: [ARROW_UP],
1096
- both: [horizontalBackwardKey, ARROW_UP]
1097
- }[orientation];
1098
- const preventedKeys = isGrid ? RELEVANT_KEYS : {
1099
- horizontal: enableHomeAndEndKeys ? HORIZONTAL_KEYS_WITH_EXTRA_KEYS : HORIZONTAL_KEYS,
1100
- vertical: enableHomeAndEndKeys ? VERTICAL_KEYS_WITH_EXTRA_KEYS : VERTICAL_KEYS,
1101
- both: RELEVANT_KEYS
1102
- }[orientation];
1103
- if (enableHomeAndEndKeys) {
1104
- if (event.key === "Home") nextIndex = minIndex;
1105
- else if (event.key === "End") nextIndex = maxIndex;
1106
- }
1107
- if (nextIndex === highlightedIndex && (forwardKeys.includes(event.key) || backwardKeys.includes(event.key))) {
1108
- if (loopFocus && nextIndex === maxIndex && forwardKeys.includes(event.key)) {
1109
- nextIndex = minIndex;
1110
- if (onLoop) nextIndex = onLoop(event, highlightedIndex, nextIndex, elementsRef);
1111
- } else if (loopFocus && nextIndex === minIndex && backwardKeys.includes(event.key)) {
1112
- nextIndex = maxIndex;
1113
- if (onLoop) nextIndex = onLoop(event, highlightedIndex, nextIndex, elementsRef);
1114
- } else nextIndex = findNonDisabledListIndex(elementsRef.current, {
1115
- startingIndex: nextIndex,
1116
- decrement: backwardKeys.includes(event.key),
1117
- disabledIndices
1118
- });
1119
- }
1120
- if (nextIndex !== highlightedIndex && !isIndexOutOfListBounds(elementsRef.current, nextIndex)) {
1121
- if (stopEventPropagation) event.stopPropagation();
1122
- if (preventedKeys.has(event.key)) event.preventDefault();
1123
- onHighlightedIndexChange(nextIndex, true);
1124
- queueMicrotask(() => {
1125
- elementsRef.current[nextIndex]?.focus();
1126
- });
1127
- }
1128
- }
1129
- }), [
1130
- cols,
1131
- dense,
1132
- direction,
1133
- disabledIndices,
1134
- elementsRef,
1135
- enableHomeAndEndKeys,
1136
- highlightedIndex,
1137
- isGrid,
1138
- itemSizes,
1139
- loopFocus,
1140
- onLoop,
1141
- wrappedOnLoop,
1142
- mergedRef,
1143
- modifierKeys,
1144
- onHighlightedIndexChange,
1145
- orientation,
1146
- stopEventPropagation
1147
- ]);
1148
- return React.useMemo(() => ({
1149
- props,
1150
- highlightedIndex,
1151
- onHighlightedIndexChange,
1152
- elementsRef,
1153
- disabledIndices,
1154
- onMapChange,
1155
- relayKeyboardEvent: props.onKeyDown
1156
- }), [
1157
- props,
1158
- highlightedIndex,
1159
- onHighlightedIndexChange,
1160
- elementsRef,
1161
- disabledIndices,
1162
- onMapChange
1163
- ]);
1164
- }
1165
- function isModifierKeySet(event, ignoredModifierKeys) {
1166
- for (const key of MODIFIER_KEYS.values()) {
1167
- if (ignoredModifierKeys.includes(key)) continue;
1168
- if (event.getModifierState(key)) return true;
1169
- }
1170
- return false;
1171
- }
1172
- //#endregion
1173
- //#region ../../node_modules/.bun/@base-ui+react@1.4.1+fa6c2f29eeb10566/node_modules/@base-ui/react/esm/internals/composite/root/CompositeRoot.js
1174
- /**
1175
- * @internal
1176
- */
1177
- function CompositeRoot(componentProps) {
1178
- const { render, className, style, refs = EMPTY_ARRAY$1, props = EMPTY_ARRAY$1, state = EMPTY_OBJECT, stateAttributesMapping, highlightedIndex: highlightedIndexProp, onHighlightedIndexChange: onHighlightedIndexChangeProp, orientation, dense, itemSizes, loopFocus, onLoop, cols, enableHomeAndEndKeys, onMapChange: onMapChangeProp, stopEventPropagation = true, rootRef, disabledIndices, modifierKeys, highlightItemOnHover = false, tag = "div", ...elementProps } = componentProps;
1179
- const { props: defaultProps, highlightedIndex, onHighlightedIndexChange, elementsRef, onMapChange: onMapChangeUnwrapped, relayKeyboardEvent } = useCompositeRoot({
1180
- itemSizes,
1181
- cols,
1182
- loopFocus,
1183
- onLoop,
1184
- dense,
1185
- orientation,
1186
- highlightedIndex: highlightedIndexProp,
1187
- onHighlightedIndexChange: onHighlightedIndexChangeProp,
1188
- rootRef,
1189
- stopEventPropagation,
1190
- enableHomeAndEndKeys,
1191
- direction: useDirection(),
1192
- disabledIndices,
1193
- modifierKeys
1194
- });
1195
- const element = useRenderElement(tag, componentProps, {
1196
- state,
1197
- ref: refs,
1198
- props: [
1199
- defaultProps,
1200
- ...props,
1201
- elementProps
1202
- ],
1203
- stateAttributesMapping
1204
- });
1205
- const contextValue = React.useMemo(() => ({
1206
- highlightedIndex,
1207
- onHighlightedIndexChange,
1208
- highlightItemOnHover,
1209
- relayKeyboardEvent
1210
- }), [
1211
- highlightedIndex,
1212
- onHighlightedIndexChange,
1213
- highlightItemOnHover,
1214
- relayKeyboardEvent
1215
- ]);
1216
- return /*#__PURE__*/ jsx(CompositeRootContext.Provider, {
1217
- value: contextValue,
1218
- children: /*#__PURE__*/ jsx(CompositeList, {
1219
- elementsRef,
1220
- onMapChange: (newMap) => {
1221
- onMapChangeProp?.(newMap);
1222
- onMapChangeUnwrapped(newMap);
1223
- },
1224
- children: element
1225
- })
1226
- });
1227
- }
1228
- //#endregion
1229
994
  //#region ../../node_modules/.bun/@base-ui+react@1.4.1+fa6c2f29eeb10566/node_modules/@base-ui/react/esm/tabs/list/TabsList.js
1230
995
  /**
1231
996
  * Groups the individual tab buttons.
@@ -1320,7 +1085,7 @@ var TabsList$1 = /*#__PURE__*/ React.forwardRef(function TabsList(componentProps
1320
1085
  orientation,
1321
1086
  onHighlightedIndexChange: setHighlightedTabIndex,
1322
1087
  onMapChange: setTabMap,
1323
- disabledIndices: EMPTY_ARRAY$1
1088
+ disabledIndices: EMPTY_ARRAY
1324
1089
  })
1325
1090
  });
1326
1091
  });
@@ -2682,7 +2447,7 @@ function fallbackIcon$1(item) {
2682
2447
  case "agent": return "llm";
2683
2448
  case "condition": return "condition";
2684
2449
  case "decision": return "decision";
2685
- case "dedupe":
2450
+ case "skip-duplicates":
2686
2451
  case "http-request":
2687
2452
  case "openapi":
2688
2453
  case "connector":
@@ -3376,7 +3141,7 @@ function ConnectorAccessSettings({ connectionHref, onManage, onSelectReference,
3376
3141
  const referenceIcon = (reference) => {
3377
3142
  const node = displayed?.node(reference.nodeId);
3378
3143
  if (node == null) return;
3379
- return node.kind == "trigger" ? triggerNodeIcon(node.trigger, providerMetadata) : semanticNodeIcon(node, actions);
3144
+ return node.kind == "trigger" ? triggerNodeIcon(node.trigger, providerMetadata) : semanticNodeIcon(node, actions, providerMetadata);
3380
3145
  };
3381
3146
  const affected = removing == null ? void 0 : accounts.get(removing);
3382
3147
  return /* @__PURE__ */ jsxs("section", {
@@ -5759,10 +5524,73 @@ function NativeSelectOption({ className, ...props }) {
5759
5524
  }
5760
5525
  //#endregion
5761
5526
  //#region src/workbench/browser/runtime/editor/flowStatePanel.tsx
5762
- function FlowStatePanel({ value, nodeIds, busy, onClearValues, onClearSpace, space }) {
5527
+ function StateValueRow({ item, client, flowId, scope, busy, onClear }) {
5763
5528
  const t = useTranslate();
5764
- const count = value.spaces.reduce((total, item) => total + item.count, 0);
5765
- const spaces = space == null ? value.spaces : value.spaces.filter((item) => typeof space === "string" ? item.space === space : space.includes(item.space));
5529
+ const [open, setOpen] = useState(false);
5530
+ const [result, setResult] = useState();
5531
+ const [error, setError] = useState();
5532
+ useEffect(() => {
5533
+ if (!open) return;
5534
+ const controller = new AbortController();
5535
+ setResult(void 0);
5536
+ setError(void 0);
5537
+ client.getFlowStateValues(flowId, scope, [item.key], controller.signal).then((response) => {
5538
+ if (!controller.signal.aborted) setResult(response.values[0]);
5539
+ }, (reason) => {
5540
+ if (!controller.signal.aborted) setError(String(reason));
5541
+ });
5542
+ return () => controller.abort();
5543
+ }, [
5544
+ client,
5545
+ flowId,
5546
+ scope,
5547
+ item.key,
5548
+ item.updatedAt,
5549
+ open
5550
+ ]);
5551
+ return /* @__PURE__ */ jsxs("div", {
5552
+ className: "flex items-start justify-between gap-3 border-b border-border/60 py-2",
5553
+ children: [/* @__PURE__ */ jsxs("div", {
5554
+ className: "min-w-0 flex-1",
5555
+ children: [/* @__PURE__ */ jsx("p", {
5556
+ className: "m-0 break-all font-medium",
5557
+ children: item.key
5558
+ }), open && (result != null ? /* @__PURE__ */ jsx("pre", {
5559
+ className: "max-h-40 overflow-auto whitespace-pre-wrap break-all text-xs",
5560
+ children: JSON.stringify(result.value, null, 2)
5561
+ }) : error != null ? /* @__PURE__ */ jsx("p", {
5562
+ role: "alert",
5563
+ className: "text-destructive text-sm",
5564
+ children: error
5565
+ }) : /* @__PURE__ */ jsx("p", {
5566
+ role: "status",
5567
+ className: "text-muted-foreground text-sm",
5568
+ children: t("flowState.loading")
5569
+ }))]
5570
+ }), /* @__PURE__ */ jsxs("div", {
5571
+ className: "flex shrink-0 gap-2",
5572
+ children: [/* @__PURE__ */ jsx(Button$1, {
5573
+ variant: "outline",
5574
+ size: "sm",
5575
+ disabled: busy,
5576
+ "aria-expanded": open,
5577
+ "aria-label": `${t(open ? "flowState.hideValue" : "flowState.showValue")}: ${item.key}`,
5578
+ onClick: () => setOpen((value) => !value),
5579
+ children: t(open ? "flowState.hideValue" : "flowState.showValue")
5580
+ }), /* @__PURE__ */ jsx(Button$1, {
5581
+ variant: "outline",
5582
+ size: "sm",
5583
+ disabled: busy,
5584
+ onClick: (event) => onClear(item.key, event.currentTarget),
5585
+ children: t("flowState.delete")
5586
+ })]
5587
+ })]
5588
+ });
5589
+ }
5590
+ function FlowStatePanel({ value, client, flowId, nodeIds, busy, onClearValues, onClearSpace, space }) {
5591
+ const t = useTranslate();
5592
+ const count = value.spaces.reduce((total, item) => total + item.reservedCount, 0);
5593
+ const spaces = space == null ? value.spaces : value.spaces.filter((item) => item.space === space);
5766
5594
  return /* @__PURE__ */ jsxs("div", {
5767
5595
  className: "flex flex-col gap-4",
5768
5596
  children: [space == null && /* @__PURE__ */ jsxs("section", {
@@ -5786,7 +5614,7 @@ function FlowStatePanel({ value, nodeIds, busy, onClearValues, onClearSpace, spa
5786
5614
  variant: "outline",
5787
5615
  size: "sm",
5788
5616
  disabled: busy,
5789
- onClick: () => onClearValues(),
5617
+ onClick: (event) => onClearValues(void 0, event.currentTarget),
5790
5618
  children: t("flowState.clearAll")
5791
5619
  })
5792
5620
  ]
@@ -5795,24 +5623,13 @@ function FlowStatePanel({ value, nodeIds, busy, onClearValues, onClearSpace, spa
5795
5623
  className: "m-0 text-sm text-muted-foreground",
5796
5624
  children: t("flowState.emptyValues")
5797
5625
  }),
5798
- value.values.map((item) => /* @__PURE__ */ jsxs("div", {
5799
- className: "flex items-start justify-between gap-3 border-b border-border/60 py-2",
5800
- children: [/* @__PURE__ */ jsxs("div", {
5801
- className: "min-w-0",
5802
- children: [/* @__PURE__ */ jsx("p", {
5803
- className: "m-0 break-all font-medium",
5804
- children: item.key
5805
- }), item.value !== void 0 && /* @__PURE__ */ jsx("pre", {
5806
- className: "max-h-40 overflow-auto whitespace-pre-wrap break-all text-xs",
5807
- children: JSON.stringify(item.value, null, 2)
5808
- })]
5809
- }), /* @__PURE__ */ jsx(Button$1, {
5810
- variant: "outline",
5811
- size: "sm",
5812
- disabled: busy,
5813
- onClick: () => onClearValues(item.key),
5814
- children: t("flowState.delete")
5815
- })]
5626
+ value.values.map((item) => /* @__PURE__ */ jsx(StateValueRow, {
5627
+ item,
5628
+ client,
5629
+ flowId,
5630
+ scope: value.scope,
5631
+ busy,
5632
+ onClear: onClearValues
5816
5633
  }, item.key))
5817
5634
  ]
5818
5635
  }), /* @__PURE__ */ jsxs("section", {
@@ -5858,15 +5675,15 @@ function FlowStatePanel({ value, nodeIds, busy, onClearValues, onClearSpace, spa
5858
5675
  ]
5859
5676
  })
5860
5677
  ]
5861
- }), /* @__PURE__ */ jsx("p", {
5678
+ }), /* @__PURE__ */ jsxs("p", {
5862
5679
  className: "m-0 text-xs",
5863
- children: item.mode === "new" ? t("flowState.records", { count: item.count.toLocaleString() }) : `${t("flowState.watermark")}: ${item.watermark ?? "-"}`
5680
+ children: [t("flowState.records", { count: item.count.toLocaleString() }), item.pendingCount > 0 && /* @__PURE__ */ jsxs(Fragment$1, { children: [" · ", t("flowState.pendingRecords", { count: item.pendingCount.toLocaleString() })] })]
5864
5681
  })]
5865
5682
  }), /* @__PURE__ */ jsx(Button$1, {
5866
5683
  variant: "outline",
5867
5684
  size: "sm",
5868
- disabled: busy,
5869
- onClick: () => onClearSpace(item.space),
5685
+ disabled: busy || item.pendingCount > 0,
5686
+ onClick: (event) => onClearSpace(item.space, event.currentTarget),
5870
5687
  children: t("flowState.clear")
5871
5688
  })]
5872
5689
  }, item.space))
@@ -5882,19 +5699,27 @@ function FlowStateButton({ client, flowId, nodeIds, history, onClose }) {
5882
5699
  }, []);
5883
5700
  const [open, setOpen] = useState(onClose != null);
5884
5701
  const [scope, setScope] = useState("draft");
5885
- const space = history?.space;
5886
- const [values, setValues] = useState(false);
5702
+ const space = history == null ? void 0 : `node:${history.nodeId}`;
5887
5703
  const [data, setData] = useState();
5888
5704
  const [error, setError] = useState();
5889
5705
  const [busy, setBusy] = useState(false);
5890
5706
  const [refresh, setRefresh] = useState(0);
5891
5707
  const [confirm, setConfirm] = useState();
5708
+ const cancelButton = useRef(null);
5709
+ const confirmTrigger = useRef();
5710
+ useEffect(() => {
5711
+ if (confirm != null) cancelButton.current?.focus();
5712
+ }, [confirm]);
5713
+ const cancelConfirm = () => {
5714
+ setConfirm(void 0);
5715
+ confirmTrigger.current?.focus();
5716
+ };
5892
5717
  useEffect(() => {
5893
- if (!open && space == null) return;
5718
+ if (!open) return;
5894
5719
  let active = true;
5895
5720
  setData(void 0);
5896
5721
  setError(void 0);
5897
- client.getFlowState(flowId, scope, values).then((result) => {
5722
+ client.getFlowState(flowId, scope).then((result) => {
5898
5723
  if (active) setData(result);
5899
5724
  }, (reason) => {
5900
5725
  if (active) setError(String(reason));
@@ -5906,7 +5731,6 @@ function FlowStateButton({ client, flowId, nodeIds, history, onClose }) {
5906
5731
  client,
5907
5732
  flowId,
5908
5733
  scope,
5909
- values,
5910
5734
  refresh,
5911
5735
  open,
5912
5736
  space
@@ -5925,7 +5749,11 @@ function FlowStateButton({ client, flowId, nodeIds, history, onClose }) {
5925
5749
  setBusy(false);
5926
5750
  }
5927
5751
  };
5928
- const request = (target) => scope === "live" ? setConfirm(target) : void clear(target);
5752
+ const request = (target, trigger) => {
5753
+ confirmTrigger.current = trigger;
5754
+ if (scope === "live") setConfirm(target);
5755
+ else clear(target);
5756
+ };
5929
5757
  return /* @__PURE__ */ jsx("span", {
5930
5758
  className: "contents",
5931
5759
  ref: portal,
@@ -5934,13 +5762,14 @@ function FlowStateButton({ client, flowId, nodeIds, history, onClose }) {
5934
5762
  onOpenChange: (next) => {
5935
5763
  if (!busy) {
5936
5764
  setOpen(next);
5765
+ if (next) setScope("draft");
5937
5766
  if (!next) onClose?.();
5938
5767
  setConfirm(void 0);
5939
5768
  }
5940
5769
  },
5941
5770
  children: [onClose == null && /* @__PURE__ */ jsxs(DialogTrigger, {
5942
5771
  render: /* @__PURE__ */ jsx(Button$1, {
5943
- variant: space != null && data != null && data.spaces.reduce((total, item) => total + item.count, 0) >= data.limits.maxIdentities * .8 ? "destructive" : "ghost",
5772
+ variant: "ghost",
5944
5773
  size: "sm"
5945
5774
  }),
5946
5775
  children: [/* @__PURE__ */ jsx("i", {
@@ -5952,7 +5781,7 @@ function FlowStateButton({ client, flowId, nodeIds, history, onClose }) {
5952
5781
  className: "max-h-[80vh] overflow-auto",
5953
5782
  closeLabel: t("common.close"),
5954
5783
  children: [
5955
- /* @__PURE__ */ jsx(DialogTitle, { children: t("flowState.title") }),
5784
+ /* @__PURE__ */ jsx(DialogTitle, { children: t(space == null ? "flowState.title" : "flowState.history") }),
5956
5785
  /* @__PURE__ */ jsxs("div", {
5957
5786
  className: "flex flex-wrap items-center gap-3",
5958
5787
  children: [
@@ -5972,13 +5801,6 @@ function FlowStateButton({ client, flowId, nodeIds, history, onClose }) {
5972
5801
  children: t("flowState.live")
5973
5802
  })]
5974
5803
  }),
5975
- space == null && (values || (data?.values.length ?? 0) > 0) && /* @__PURE__ */ jsxs(Label, {
5976
- className: "flex items-center gap-2 text-sm",
5977
- children: [/* @__PURE__ */ jsx(Checkbox, {
5978
- checked: values,
5979
- onCheckedChange: setValues
5980
- }), t("flowState.showValues")]
5981
- }),
5982
5804
  /* @__PURE__ */ jsx(Button$1, {
5983
5805
  variant: "outline",
5984
5806
  size: "sm",
@@ -6044,9 +5866,10 @@ function FlowStateButton({ client, flowId, nodeIds, history, onClose }) {
6044
5866
  onClick: () => void clear(confirm),
6045
5867
  children: t("flowState.clear")
6046
5868
  }), /* @__PURE__ */ jsx(Button$1, {
5869
+ ref: cancelButton,
6047
5870
  disabled: busy,
6048
5871
  variant: "outline",
6049
- onClick: () => setConfirm(void 0),
5872
+ onClick: cancelConfirm,
6050
5873
  children: t("flowState.cancel")
6051
5874
  })]
6052
5875
  })
@@ -6057,12 +5880,18 @@ function FlowStateButton({ client, flowId, nodeIds, history, onClose }) {
6057
5880
  children: error == null ? t("flowState.loading") : ""
6058
5881
  }) : /* @__PURE__ */ jsx(FlowStatePanel, {
6059
5882
  value: data,
6060
- space: scope === "live" && history != null ? ["flow", `node:${history.nodeId}`] : space,
5883
+ client,
5884
+ flowId,
5885
+ space,
6061
5886
  nodeIds,
6062
5887
  busy,
6063
- onClearValues: (key) => request({ key }),
6064
- onClearSpace: (targetSpace) => request({ space: targetSpace })
6065
- })
5888
+ onClearValues: (key, trigger) => request({ key }, trigger),
5889
+ onClearSpace: (targetSpace, trigger) => request({ space: targetSpace }, trigger)
5890
+ }, JSON.stringify([
5891
+ flowId,
5892
+ scope,
5893
+ refresh
5894
+ ]))
6066
5895
  ]
6067
5896
  })]
6068
5897
  })
@@ -6737,7 +6566,7 @@ function SelectedToolRow({ icon, title, subtitle, actions, children }) {
6737
6566
  })]
6738
6567
  }),
6739
6568
  actions,
6740
- /* @__PURE__ */ jsx("div", {
6569
+ children != null && /* @__PURE__ */ jsx("div", {
6741
6570
  className: "col-start-2 min-w-0",
6742
6571
  children
6743
6572
  })
@@ -7128,6 +6957,27 @@ function WorkflowToolPicker({ catalog, selected, disabled, onToggle }) {
7128
6957
  onChoose: onToggle
7129
6958
  });
7130
6959
  }
6960
+ function SelectedWorkflowToolRow({ entry, workflowName = entry.flowId, title = entry.name, actions, children }) {
6961
+ const t = useTranslate();
6962
+ return /* @__PURE__ */ jsx(SelectedToolRow, {
6963
+ icon: /* @__PURE__ */ jsx(ProviderAppIcon, { children: /* @__PURE__ */ jsx("i", {
6964
+ "aria-hidden": "true",
6965
+ className: "i-lucide-light:workflow size-4 text-muted-foreground"
6966
+ }) }),
6967
+ title,
6968
+ subtitle: /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("span", {
6969
+ className: "truncate",
6970
+ title: workflowName,
6971
+ children: [
6972
+ t("toolPicker.workflow"),
6973
+ " · ",
6974
+ workflowName
6975
+ ]
6976
+ }), /* @__PURE__ */ jsx(OpenWorkflowLink, { flowId: entry.flowId })] }),
6977
+ actions,
6978
+ children
6979
+ });
6980
+ }
7131
6981
  function SelectedWorkflowTool({ entry, workflowName, disabled, load, onRefresh, onChange, otherNames, onValidChange, onRemove, children, portalRoot }) {
7132
6982
  const t = useTranslate();
7133
6983
  const [issue, setIssue] = useState();
@@ -7167,11 +7017,9 @@ function SelectedWorkflowTool({ entry, workflowName, disabled, load, onRefresh,
7167
7017
  ]);
7168
7018
  const targetName = target?.name ?? workflowName ?? entry.flowId;
7169
7019
  const removeLabel = t("actionPicker.remove", { action: targetName });
7170
- return /* @__PURE__ */ jsx(SelectedToolRow, {
7171
- icon: /* @__PURE__ */ jsx(ProviderAppIcon, { children: /* @__PURE__ */ jsx("i", {
7172
- "aria-hidden": "true",
7173
- className: "i-lucide-light:workflow size-4 text-muted-foreground"
7174
- }) }),
7020
+ return /* @__PURE__ */ jsx(SelectedWorkflowToolRow, {
7021
+ entry,
7022
+ workflowName: targetName,
7175
7023
  title: children == null ? /* @__PURE__ */ jsx(WorkflowToolTitle, {
7176
7024
  name: entry.name,
7177
7025
  disabled,
@@ -7179,15 +7027,6 @@ function SelectedWorkflowTool({ entry, workflowName, disabled, load, onRefresh,
7179
7027
  otherNames,
7180
7028
  onValidChange
7181
7029
  }) : entry.name,
7182
- subtitle: /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("span", {
7183
- className: "truncate",
7184
- title: targetName,
7185
- children: [
7186
- t("toolPicker.workflow"),
7187
- " · ",
7188
- targetName
7189
- ]
7190
- }), /* @__PURE__ */ jsx(OpenWorkflowLink, { flowId: entry.flowId })] }),
7191
7030
  actions: children ?? /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, { render: /* @__PURE__ */ jsx(Button$1, {
7192
7031
  type: "button",
7193
7032
  size: "icon-sm",
@@ -7334,7 +7173,9 @@ function WorkflowToolTitle({ name, disabled, onChange, otherNames, onValidChange
7334
7173
  function entryKey(entry) {
7335
7174
  return entry.kind == "workflow" ? `workflow:${entry.flowId}` : entry.action;
7336
7175
  }
7337
- function ActionSelectionDialog({ title, entries, connectors, prepareAction, workflows, disabled, createEntry, onSave, notify, settings, trigger, triggerHint }) {
7176
+ function ActionSelectionDialog(props) {
7177
+ const { title, entries, settings, trigger, triggerHint } = props;
7178
+ const editor = props.readOnly === true ? void 0 : props;
7338
7179
  const t = useTranslate();
7339
7180
  const [open, setOpen] = useState(false);
7340
7181
  const [root, setRoot] = useState(null);
@@ -7379,7 +7220,7 @@ function ActionSelectionDialog({ title, entries, connectors, prepareAction, work
7379
7220
  variant: "outline",
7380
7221
  size: "xs"
7381
7222
  }),
7382
- disabled,
7223
+ disabled: editor?.disabled ?? false,
7383
7224
  "aria-label": `${title} · ${entries.length}`,
7384
7225
  children: trigger?.props.children ?? `${title} · ${entries.length}`
7385
7226
  }) }), /* @__PURE__ */ jsx(TooltipContent, {
@@ -7388,7 +7229,7 @@ function ActionSelectionDialog({ title, entries, connectors, prepareAction, work
7388
7229
  })] }), /* @__PURE__ */ jsxs(DialogContent, {
7389
7230
  container: root,
7390
7231
  closeLabel: t("common.close"),
7391
- className: "flex h-[min(640px,85dvh)] flex-col gap-0 p-0 text-[13px] leading-5 font-normal sm:max-w-[min(46rem,calc(100%-2rem))]",
7232
+ className: cn("flex flex-col gap-0 p-0 text-[13px] leading-5 font-normal", editor == null ? "max-h-[85dvh] sm:max-w-sm" : "h-[min(640px,85dvh)] sm:max-w-[min(46rem,calc(100%-2rem))]"),
7392
7233
  showCloseButton: !pending,
7393
7234
  children: [
7394
7235
  /* @__PURE__ */ jsx(DialogTitle, {
@@ -7396,32 +7237,35 @@ function ActionSelectionDialog({ title, entries, connectors, prepareAction, work
7396
7237
  children: title
7397
7238
  }),
7398
7239
  /* @__PURE__ */ jsx("div", { className: "mx-4 h-px shrink-0 bg-border/50" }),
7399
- /* @__PURE__ */ jsx(DialogDescription, {
7240
+ props.readOnly === true ? /* @__PURE__ */ jsx(ReadonlyToolSelection, {
7241
+ entries,
7242
+ providers: props.providers,
7243
+ settings
7244
+ }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(DialogDescription, {
7400
7245
  className: "m-0 shrink-0 px-4 pt-3 text-[13px] leading-5",
7401
7246
  children: t("actionPicker.description")
7402
- }),
7403
- /* @__PURE__ */ jsx(ActionSelectionEditor, {
7404
- notify,
7247
+ }), /* @__PURE__ */ jsx(ActionSelectionEditor, {
7248
+ notify: props.notify,
7405
7249
  entries,
7406
- connectors,
7407
- prepareAction,
7408
- workflows,
7409
- disabled: disabled || pending,
7410
- createEntry,
7250
+ connectors: props.connectors,
7251
+ prepareAction: props.prepareAction,
7252
+ workflows: props.workflows,
7253
+ disabled: props.disabled || pending,
7254
+ createEntry: props.createEntry,
7411
7255
  settings,
7412
7256
  onDirtyChange: setDirty,
7413
7257
  onCancel: requestClose,
7414
7258
  onSave: async (next) => {
7415
7259
  setPending(true);
7416
7260
  try {
7417
- const saved = await onSave(next);
7261
+ const saved = await props.onSave(next);
7418
7262
  if (saved) setOpen(false);
7419
7263
  return saved;
7420
7264
  } finally {
7421
7265
  setPending(false);
7422
7266
  }
7423
7267
  }
7424
- }),
7268
+ })] }),
7425
7269
  /* @__PURE__ */ jsx(Dialog, {
7426
7270
  open: confirmDiscard,
7427
7271
  onOpenChange: setConfirmDiscard,
@@ -7460,6 +7304,121 @@ function ActionSelectionDialog({ title, entries, connectors, prepareAction, work
7460
7304
  })
7461
7305
  });
7462
7306
  }
7307
+ function SelectedToolsList({ count, actions, children, containerRef, headingRef, className }) {
7308
+ const t = useTranslate();
7309
+ return /* @__PURE__ */ jsxs("div", {
7310
+ ref: containerRef,
7311
+ className: cn("flex min-h-0 min-w-0 flex-1 flex-col gap-2", className),
7312
+ children: [/* @__PURE__ */ jsxs("div", {
7313
+ className: "flex h-8 shrink-0 items-center justify-between gap-2 px-4",
7314
+ children: [/* @__PURE__ */ jsx("h3", {
7315
+ ref: headingRef,
7316
+ tabIndex: -1,
7317
+ className: "m-0 text-[13px] font-normal text-muted-foreground outline-none",
7318
+ children: t("actionPicker.selected", { count })
7319
+ }), actions]
7320
+ }), count === 0 ? /* @__PURE__ */ jsx(Empty, { children: /* @__PURE__ */ jsxs(EmptyHeader, { children: [/* @__PURE__ */ jsx(EmptyMedia, {
7321
+ variant: "icon",
7322
+ children: /* @__PURE__ */ jsx("i", {
7323
+ "aria-hidden": "true",
7324
+ className: "i-lucide-light:list-checks size-4"
7325
+ })
7326
+ }), /* @__PURE__ */ jsx(EmptyDescription, {
7327
+ className: "text-[13px]",
7328
+ children: t("actionPicker.empty")
7329
+ })] }) }) : /* @__PURE__ */ jsx(ScrollArea, {
7330
+ className: "min-h-0 flex-1",
7331
+ children: /* @__PURE__ */ jsx("div", {
7332
+ className: "flex flex-col divide-y divide-border/50 px-4",
7333
+ children
7334
+ })
7335
+ })]
7336
+ });
7337
+ }
7338
+ function SelectedToolSettings({ title, name, container, disabled = false, footer, children }) {
7339
+ const t = useTranslate();
7340
+ return /* @__PURE__ */ jsxs(Popover, { children: [/* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
7341
+ render: /* @__PURE__ */ jsx(PopoverTrigger, { render: /* @__PURE__ */ jsx(Button$1, {
7342
+ type: "button",
7343
+ size: "icon-sm",
7344
+ variant: "ghost",
7345
+ disabled,
7346
+ "aria-label": `${title} · ${name}`
7347
+ }) }),
7348
+ children: /* @__PURE__ */ jsx("i", {
7349
+ "aria-hidden": "true",
7350
+ className: "i-lucide-light:settings size-4 text-muted-foreground"
7351
+ })
7352
+ }), /* @__PURE__ */ jsx(TooltipContent, {
7353
+ container,
7354
+ children: title
7355
+ })] }), /* @__PURE__ */ jsx(PopoverPanelContent, {
7356
+ keepMounted: true,
7357
+ container,
7358
+ title,
7359
+ closeLabel: t("common.close"),
7360
+ className: "open-flow-property-panel w-96",
7361
+ footer,
7362
+ children
7363
+ })] });
7364
+ }
7365
+ function ReadonlyToolSelection({ entries, providers, settings }) {
7366
+ const t = useTranslate();
7367
+ const [root, setRoot] = useState(null);
7368
+ return /* @__PURE__ */ jsx("div", {
7369
+ className: "flex min-h-0 flex-1 py-4",
7370
+ children: /* @__PURE__ */ jsx(SelectedToolsList, {
7371
+ count: entries.length,
7372
+ containerRef: setRoot,
7373
+ children: entries.map((entry) => {
7374
+ const name = entry.kind === "workflow" ? entry.name : entry.action;
7375
+ const controls = settings && /* @__PURE__ */ jsx(SelectedToolSettings, {
7376
+ title: settings.title,
7377
+ name,
7378
+ container: root,
7379
+ children: settings.render({
7380
+ entry,
7381
+ disabled: true
7382
+ })
7383
+ });
7384
+ if (entry.kind === "workflow") return /* @__PURE__ */ jsx(SelectedWorkflowToolRow, {
7385
+ entry,
7386
+ actions: controls
7387
+ }, entry.id ?? entryKey(entry));
7388
+ const service = entry.action.split(".")[0];
7389
+ const provider = providers?.[service];
7390
+ return /* @__PURE__ */ jsx(SelectedToolRow, {
7391
+ icon: /* @__PURE__ */ jsx(ProviderAppIcon, { src: providerIcon(provider ?? {
7392
+ serviceId: service,
7393
+ serviceName: service
7394
+ }) }),
7395
+ title: name,
7396
+ subtitle: /* @__PURE__ */ jsxs("span", {
7397
+ className: "truncate",
7398
+ children: [
7399
+ t("toolPicker.connector"),
7400
+ " · ",
7401
+ provider?.serviceName ?? service
7402
+ ]
7403
+ }),
7404
+ actions: controls,
7405
+ children: provider?.noSetup ? /* @__PURE__ */ jsx("div", {
7406
+ className: "text-muted-foreground",
7407
+ children: t("actionPicker.noAccount")
7408
+ }) : entry.connectionId == null ? null : /* @__PURE__ */ jsx("div", {
7409
+ className: "open-flow-property-panel flex min-h-[30px] min-w-0 items-center [&>*]:w-full",
7410
+ children: /* @__PURE__ */ jsx(Input, {
7411
+ controlSize: "field",
7412
+ readOnly: true,
7413
+ "aria-label": t("actionPicker.accountFor", { action: name }),
7414
+ value: entry.connectionId === "" ? t("inspector.account.deferred") : entry.connectionId
7415
+ })
7416
+ })
7417
+ }, entry.id ?? entry.action);
7418
+ })
7419
+ })
7420
+ });
7421
+ }
7463
7422
  function ActionSelectionEditor({ entries, connectors, prepareAction, workflows, disabled, createEntry, onSave, notify, onCancel, onDirtyChange, settings }) {
7464
7423
  const t = useTranslate();
7465
7424
  const [draft, setDraft] = useState(entries);
@@ -7624,27 +7583,11 @@ function ActionSelectionEditor({ entries, connectors, prepareAction, workflows,
7624
7583
  controller.abort();
7625
7584
  }
7626
7585
  };
7627
- const renderSettings = (entry, index, name, ready = true) => settings == null ? void 0 : /* @__PURE__ */ jsxs(Popover, { children: [/* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
7628
- render: /* @__PURE__ */ jsx(PopoverTrigger, { render: /* @__PURE__ */ jsx(Button$1, {
7629
- type: "button",
7630
- size: "icon-sm",
7631
- variant: "ghost",
7632
- disabled,
7633
- "aria-label": `${settings.title} · ${name}`
7634
- }) }),
7635
- children: /* @__PURE__ */ jsx("i", {
7636
- "aria-hidden": "true",
7637
- className: "i-lucide-light:settings size-4 text-muted-foreground"
7638
- })
7639
- }), /* @__PURE__ */ jsx(TooltipContent, {
7640
- container: portalRoot,
7641
- children: settings.title
7642
- })] }), /* @__PURE__ */ jsx(PopoverPanelContent, {
7643
- keepMounted: true,
7644
- container: portalRoot,
7586
+ const renderSettings = (entry, index, name, ready = true) => settings == null ? void 0 : /* @__PURE__ */ jsx(SelectedToolSettings, {
7645
7587
  title: settings.title,
7646
- closeLabel: t("common.close"),
7647
- className: "open-flow-property-panel w-96",
7588
+ name,
7589
+ container: portalRoot,
7590
+ disabled,
7648
7591
  footer: /* @__PURE__ */ jsx(Button$1, {
7649
7592
  type: "button",
7650
7593
  size: "field",
@@ -7660,7 +7603,7 @@ function ActionSelectionEditor({ entries, connectors, prepareAction, workflows,
7660
7603
  disabled: disabled || !ready,
7661
7604
  onValidChange: (key, value) => setValidity(`${entry.id ?? entryKey(entry)}:${key}`, value)
7662
7605
  })
7663
- })] });
7606
+ });
7664
7607
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [
7665
7608
  /* @__PURE__ */ jsxs("div", {
7666
7609
  className: "grid min-h-0 flex-1 grid-cols-1 gap-y-4 py-4 sm:grid-cols-2",
@@ -7721,128 +7664,108 @@ function ActionSelectionEditor({ entries, connectors, prepareAction, workflows,
7721
7664
  }));
7722
7665
  }
7723
7666
  })]
7724
- }), /* @__PURE__ */ jsxs("div", {
7725
- ref: setPortalRoot,
7726
- className: "flex min-h-0 min-w-0 flex-col gap-2 sm:border-l sm:border-border/50",
7727
- children: [/* @__PURE__ */ jsxs("div", {
7728
- className: "flex h-8 shrink-0 items-center justify-between gap-2 px-4",
7729
- children: [/* @__PURE__ */ jsx("h3", {
7730
- ref: selectedHeading,
7731
- tabIndex: -1,
7732
- className: "m-0 text-[13px] font-normal text-muted-foreground outline-none",
7733
- children: t("actionPicker.selected", { count: draft.length })
7734
- }), /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, { render: /* @__PURE__ */ jsx(Button$1, {
7735
- type: "button",
7736
- size: "icon-sm",
7737
- variant: "ghost",
7738
- disabled: disabled || refreshing || !draft.some((entry) => entry.kind != "workflow" && prepared[entry.action]?.action.authenticated),
7739
- "aria-label": t("actionPicker.refresh"),
7740
- onClick: () => void refresh(),
7741
- children: refreshing ? /* @__PURE__ */ jsx(Spinner, {}) : /* @__PURE__ */ jsx("i", {
7742
- "aria-hidden": "true",
7743
- className: "i-lucide-light:rotate-cw size-4 text-muted-foreground"
7744
- })
7745
- }) }), /* @__PURE__ */ jsx(TooltipContent, {
7746
- container: portalRoot,
7747
- children: t("actionPicker.refresh")
7748
- })] })]
7749
- }), draft.length == 0 ? /* @__PURE__ */ jsx(Empty, { children: /* @__PURE__ */ jsxs(EmptyHeader, { children: [/* @__PURE__ */ jsx(EmptyMedia, {
7750
- variant: "icon",
7751
- children: /* @__PURE__ */ jsx("i", {
7667
+ }), /* @__PURE__ */ jsx(SelectedToolsList, {
7668
+ count: draft.length,
7669
+ containerRef: setPortalRoot,
7670
+ headingRef: selectedHeading,
7671
+ className: "sm:border-l sm:border-border/50",
7672
+ actions: /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, { render: /* @__PURE__ */ jsx(Button$1, {
7673
+ type: "button",
7674
+ size: "icon-sm",
7675
+ variant: "ghost",
7676
+ disabled: disabled || refreshing || !draft.some((entry) => entry.kind != "workflow" && prepared[entry.action]?.action.authenticated),
7677
+ "aria-label": t("actionPicker.refresh"),
7678
+ onClick: () => void refresh(),
7679
+ children: refreshing ? /* @__PURE__ */ jsx(Spinner, {}) : /* @__PURE__ */ jsx("i", {
7752
7680
  "aria-hidden": "true",
7753
- className: "i-lucide-light:list-checks size-4"
7681
+ className: "i-lucide-light:rotate-cw size-4 text-muted-foreground"
7754
7682
  })
7755
- }), /* @__PURE__ */ jsx(EmptyDescription, {
7756
- className: "text-[13px]",
7757
- children: t("actionPicker.empty")
7758
- })] }) }) : /* @__PURE__ */ jsx(ScrollArea, {
7759
- className: "min-h-0 flex-1",
7760
- children: /* @__PURE__ */ jsx("div", {
7761
- className: "flex flex-col divide-y divide-border/50 px-4",
7762
- children: sortedEntries.map(({ entry, index }) => {
7763
- if (entry.kind == "workflow") return /* @__PURE__ */ jsx(SelectedWorkflowTool, {
7764
- entry,
7765
- workflowName: workflowCatalog.choices.find((item) => item.flowId == entry.flowId)?.name,
7683
+ }) }), /* @__PURE__ */ jsx(TooltipContent, {
7684
+ container: portalRoot,
7685
+ children: t("actionPicker.refresh")
7686
+ })] }),
7687
+ children: sortedEntries.map(({ entry, index }) => {
7688
+ if (entry.kind == "workflow") return /* @__PURE__ */ jsx(SelectedWorkflowTool, {
7689
+ entry,
7690
+ workflowName: workflowCatalog.choices.find((item) => item.flowId == entry.flowId)?.name,
7691
+ disabled,
7692
+ load: workflows?.load,
7693
+ onChange: (name) => replace(index, {
7694
+ ...entry,
7695
+ name
7696
+ }),
7697
+ otherNames: workflowEntries.filter((other) => other.flowId != entry.flowId).map((other) => other.name),
7698
+ onValidChange: (value) => setValidity(`${entry.id ?? entryKey(entry)}:alias`, value),
7699
+ portalRoot,
7700
+ onRemove: () => remove(index),
7701
+ onRefresh: (contract) => {
7702
+ if (workflows) setDraft((current) => current.map((item) => item.kind == "workflow" && item.flowId == entry.flowId ? workflows.refresh(item, contract) : item));
7703
+ },
7704
+ children: renderSettings(entry, index, entry.name)
7705
+ }, entry.id ?? entryKey(entry));
7706
+ const resolved = prepared[entry.action];
7707
+ const action = resolved?.action ?? discovered.current.get(entry.action) ?? actions[entry.action];
7708
+ const accounts = resolved?.connections ?? [];
7709
+ const selected = connections.find((account) => account.connectionId == entry.connectionId);
7710
+ const accountInvalid = resolved != null && action?.authenticated && entry.connectionId != null && entry.connectionId !== "" && !accounts.some((account) => account.connectionId == entry.connectionId && account.status == "active");
7711
+ return /* @__PURE__ */ jsx(SelectedToolRow, {
7712
+ icon: /* @__PURE__ */ jsx(ProviderAppIcon, { src: action == null ? void 0 : providerIcon(action) }),
7713
+ title: action?.name ?? entry.action,
7714
+ subtitle: /* @__PURE__ */ jsxs("span", {
7715
+ className: "truncate",
7716
+ children: [t("toolPicker.connector"), action == null ? "" : ` · ${action.serviceName}`]
7717
+ }),
7718
+ actions: settings ? renderSettings(entry, index, action?.name ?? entry.action, resolved != null) : /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, { render: /* @__PURE__ */ jsx(Button$1, {
7719
+ type: "button",
7720
+ size: "icon-sm",
7721
+ variant: "ghost",
7722
+ disabled,
7723
+ "aria-label": t("actionPicker.remove", { action: action?.name ?? entry.action }),
7724
+ onClick: () => remove(index),
7725
+ children: /* @__PURE__ */ jsx("i", {
7726
+ "aria-hidden": "true",
7727
+ className: "i-lucide-light:trash-2 size-4 text-muted-foreground"
7728
+ })
7729
+ }) }), /* @__PURE__ */ jsx(TooltipContent, {
7730
+ container: portalRoot,
7731
+ children: t("actionPicker.remove", { action: action?.name ?? entry.action })
7732
+ })] }),
7733
+ children: /* @__PURE__ */ jsx("div", {
7734
+ className: "open-flow-property-panel flex min-h-[30px] min-w-0 items-center [&>*]:w-full",
7735
+ children: resolved == null && preparationErrors[entry.action] != null ? /* @__PURE__ */ jsx(AccountControlButton, {
7736
+ status: "danger",
7766
7737
  disabled,
7767
- load: workflows?.load,
7768
- onChange: (name) => replace(index, {
7769
- ...entry,
7770
- name
7771
- }),
7772
- otherNames: workflowEntries.filter((other) => other.flowId != entry.flowId).map((other) => other.name),
7773
- onValidChange: (value) => setValidity(`${entry.id ?? entryKey(entry)}:alias`, value),
7774
- portalRoot,
7775
- onRemove: () => remove(index),
7776
- onRefresh: (contract) => {
7777
- if (workflows) setDraft((current) => current.map((item) => item.kind == "workflow" && item.flowId == entry.flowId ? workflows.refresh(item, contract) : item));
7738
+ label: t("inspector.account.retry"),
7739
+ hint: preparationErrors[entry.action],
7740
+ onClick: () => {
7741
+ connectors.retryAction(entry.action);
7742
+ setAttempt((value) => value + 1);
7743
+ }
7744
+ }) : action?.authenticated === false ? /* @__PURE__ */ jsx("div", {
7745
+ className: "text-muted-foreground",
7746
+ children: t("actionPicker.noAccount")
7747
+ }) : /* @__PURE__ */ jsx(AccountSelect, {
7748
+ loading: resolved == null,
7749
+ connections: accounts.filter((account) => account.status == "active"),
7750
+ selectedConnection: selected,
7751
+ selectedId: entry.connectionId,
7752
+ invalid: accountInvalid === true,
7753
+ warning: entry.connectionId == null,
7754
+ allowDeferred: true,
7755
+ label: t("actionPicker.accountFor", { action: action?.name ?? entry.action }),
7756
+ disabled,
7757
+ onChange: (connectionId) => {
7758
+ const { connectionId: _previous, ...rest } = entry;
7759
+ replace(index, connectionId == null ? rest : {
7760
+ ...rest,
7761
+ connectionId
7762
+ });
7778
7763
  },
7779
- children: renderSettings(entry, index, entry.name)
7780
- }, entry.id ?? entryKey(entry));
7781
- const resolved = prepared[entry.action];
7782
- const action = resolved?.action ?? discovered.current.get(entry.action) ?? actions[entry.action];
7783
- const accounts = resolved?.connections ?? [];
7784
- const selected = connections.find((account) => account.connectionId == entry.connectionId);
7785
- const accountInvalid = resolved != null && action?.authenticated && entry.connectionId != null && entry.connectionId !== "" && !accounts.some((account) => account.connectionId == entry.connectionId && account.status == "active");
7786
- return /* @__PURE__ */ jsx(SelectedToolRow, {
7787
- icon: /* @__PURE__ */ jsx(ProviderAppIcon, { src: action == null ? void 0 : providerIcon(action) }),
7788
- title: action?.name ?? entry.action,
7789
- subtitle: /* @__PURE__ */ jsxs("span", {
7790
- className: "truncate",
7791
- children: [t("toolPicker.connector"), action == null ? "" : ` · ${action.serviceName}`]
7792
- }),
7793
- actions: settings ? renderSettings(entry, index, action?.name ?? entry.action, resolved != null) : /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, { render: /* @__PURE__ */ jsx(Button$1, {
7794
- type: "button",
7795
- size: "icon-sm",
7796
- variant: "ghost",
7797
- disabled,
7798
- "aria-label": t("actionPicker.remove", { action: action?.name ?? entry.action }),
7799
- onClick: () => remove(index),
7800
- children: /* @__PURE__ */ jsx("i", {
7801
- "aria-hidden": "true",
7802
- className: "i-lucide-light:trash-2 size-4 text-muted-foreground"
7803
- })
7804
- }) }), /* @__PURE__ */ jsx(TooltipContent, {
7805
- container: portalRoot,
7806
- children: t("actionPicker.remove", { action: action?.name ?? entry.action })
7807
- })] }),
7808
- children: /* @__PURE__ */ jsx("div", {
7809
- className: "open-flow-property-panel flex min-h-[30px] min-w-0 items-center [&>*]:w-full",
7810
- children: resolved == null && preparationErrors[entry.action] != null ? /* @__PURE__ */ jsx(AccountControlButton, {
7811
- status: "danger",
7812
- disabled,
7813
- label: t("inspector.account.retry"),
7814
- hint: preparationErrors[entry.action],
7815
- onClick: () => {
7816
- connectors.retryAction(entry.action);
7817
- setAttempt((value) => value + 1);
7818
- }
7819
- }) : action?.authenticated === false ? /* @__PURE__ */ jsx("div", {
7820
- className: "text-muted-foreground",
7821
- children: t("actionPicker.noAccount")
7822
- }) : /* @__PURE__ */ jsx(AccountSelect, {
7823
- loading: resolved == null,
7824
- connections: accounts.filter((account) => account.status == "active"),
7825
- selectedConnection: selected,
7826
- selectedId: entry.connectionId,
7827
- invalid: accountInvalid === true,
7828
- warning: entry.connectionId == null,
7829
- allowDeferred: true,
7830
- label: t("actionPicker.accountFor", { action: action?.name ?? entry.action }),
7831
- disabled,
7832
- onChange: (connectionId) => {
7833
- const { connectionId: _previous, ...rest } = entry;
7834
- replace(index, connectionId == null ? rest : {
7835
- ...rest,
7836
- connectionId
7837
- });
7838
- },
7839
- onManage: resolved == null ? void 0 : () => void connectors.connect(resolved.action.serviceId)
7840
- })
7841
- })
7842
- }, entry.id ?? entry.action);
7764
+ onManage: resolved == null ? void 0 : () => void connectors.connect(resolved.action.serviceId)
7765
+ })
7843
7766
  })
7844
- })
7845
- })]
7767
+ }, entry.id ?? entry.action);
7768
+ })
7846
7769
  })]
7847
7770
  }),
7848
7771
  attempted && !valid && /* @__PURE__ */ jsx("div", {
@@ -22015,7 +21938,7 @@ function AgentToolSettings({ entry: tool, onChange, disabled, onValidChange, inp
22015
21938
  return /* @__PURE__ */ jsxs("fieldset", {
22016
21939
  className: "m-0 flex min-w-0 flex-col gap-4 border-0 p-0",
22017
21940
  children: [
22018
- /* @__PURE__ */ jsx(PopoverDescription, {
21941
+ onChange != null && /* @__PURE__ */ jsx(PopoverDescription, {
22019
21942
  className: "m-0 text-xs leading-5",
22020
21943
  children: t("agent.toolSettingsHint")
22021
21944
  }),
@@ -22084,28 +22007,25 @@ function AgentTools(props) {
22084
22007
  ...props.editor
22085
22008
  });
22086
22009
  if (props.config.tools.length === 0) return null;
22087
- return /* @__PURE__ */ jsxs(Popover, { children: [/* @__PURE__ */ jsx(PopoverTrigger, {
22088
- render: /* @__PURE__ */ jsx(Button$1, {
22010
+ return /* @__PURE__ */ jsx(ActionSelectionDialog, {
22011
+ readOnly: true,
22012
+ title: t("agent.tools"),
22013
+ entries: props.config.tools,
22014
+ providers: props.providers,
22015
+ trigger: /* @__PURE__ */ jsx(Button$1, {
22089
22016
  type: "button",
22090
22017
  variant: "ghost",
22091
- size: "sm"
22018
+ size: "sm",
22019
+ children: t("agent.tools")
22092
22020
  }),
22093
- children: t("agent.tools")
22094
- }), /* @__PURE__ */ jsx(PopoverContent, { children: /* @__PURE__ */ jsx("div", {
22095
- className: "grid max-h-96 gap-4 overflow-auto",
22096
- children: props.config.tools.map((tool) => /* @__PURE__ */ jsxs("details", { children: [
22097
- /* @__PURE__ */ jsx("summary", { children: tool.name || (tool.kind == "workflow" ? tool.flowId : tool.action) }),
22098
- /* @__PURE__ */ jsxs("p", {
22099
- className: "reference-value",
22100
- children: [tool.kind == "workflow" ? tool.flowId : tool.action, tool.connectionId == null ? "" : ` · ${tool.connectionId === "" ? t("inspector.account.deferred") : tool.connectionId}`]
22101
- }),
22102
- /* @__PURE__ */ jsx(AgentToolSettings, {
22103
- entry: tool,
22104
- disabled: true,
22021
+ settings: {
22022
+ title: t("agent.toolSettings"),
22023
+ render: (settings) => /* @__PURE__ */ jsx(AgentToolSettings, {
22024
+ ...settings,
22105
22025
  inputs: props.inputs
22106
22026
  })
22107
- ] }, tool.id))
22108
- }) })] });
22027
+ }
22028
+ });
22109
22029
  }
22110
22030
  //#endregion
22111
22031
  //#region src/workbench/browser/runtime/editor/codeEditorPlaceholder.tsx
@@ -22422,7 +22342,7 @@ function EditableAgentSettingsProvider({ children, task, nodeId, store, connecto
22422
22342
  saveFailed
22423
22343
  });
22424
22344
  }
22425
- function AgentSettingsContent({ children, task, config, nodeId, toolsEditor, disabled, theme, validationError, setConfig, save, saveFailed = false }) {
22345
+ function AgentSettingsContent({ children, task, config, nodeId, toolsEditor, providers, disabled, theme, validationError, setConfig, save, saveFailed = false }) {
22426
22346
  const t = useTranslate();
22427
22347
  const inputs = task.inputs.filter((port) => "handle" in port);
22428
22348
  const promptSection = /* @__PURE__ */ jsxs("section", {
@@ -22437,7 +22357,8 @@ function AgentSettingsContent({ children, task, config, nodeId, toolsEditor, dis
22437
22357
  config,
22438
22358
  disabled,
22439
22359
  inputs,
22440
- editor: toolsEditor
22360
+ editor: toolsEditor,
22361
+ providers
22441
22362
  })]
22442
22363
  }), /* @__PURE__ */ jsxs("div", {
22443
22364
  className: "inspector-section-content",
@@ -22565,6 +22486,7 @@ function AgentSettingsProvider(props) {
22565
22486
  nodeId: props.nodeId,
22566
22487
  disabled: true,
22567
22488
  theme: props.theme,
22489
+ providers: props.providers,
22568
22490
  children: props.children
22569
22491
  });
22570
22492
  }
@@ -22747,7 +22669,7 @@ function CodeEditor({ ariaDescribedBy, ariaLabel, diagnostics, disabled, errorLa
22747
22669
  darkMode.current = darkMode$;
22748
22670
  setFailed(false);
22749
22671
  setLoading(true);
22750
- const extension = import("./typeScriptSession-CRoezJPN.js").then(({ loadTypeScriptExtension }) => loadTypeScriptExtension(uri, typingRef.current, () => prepareCompletionRef.current?.())).catch(() => void 0);
22672
+ const extension = import("./typeScriptSession-CoEIptNC.js").then(({ loadTypeScriptExtension }) => loadTypeScriptExtension(uri, typingRef.current, () => prepareCompletionRef.current?.())).catch(() => void 0);
22751
22673
  claimEditor(uri).then((nextRelease) => {
22752
22674
  release = nextRelease;
22753
22675
  if (disposed) {
@@ -22834,7 +22756,7 @@ function CodeEditor({ ariaDescribedBy, ariaLabel, diagnostics, disabled, errorLa
22834
22756
  editor.current?.updateOptions({ ariaDescribedBy });
22835
22757
  }, [ariaDescribedBy]);
22836
22758
  useEffect(() => {
22837
- import("./typeScriptSession-CRoezJPN.js").then(({ updateTypeScriptTyping }) => updateTypeScriptTyping(uri, typing)).catch(noop);
22759
+ import("./typeScriptSession-CoEIptNC.js").then(({ updateTypeScriptTyping }) => updateTypeScriptTyping(uri, typing)).catch(noop);
22838
22760
  }, [typing, uri]);
22839
22761
  useEffect(() => {
22840
22762
  if (location != null) editor.current?.revealPosition?.(location.line, location.column);
@@ -25967,122 +25889,6 @@ function DecisionItemActions({ addLabel, removeLabel, canAdd = true, onAdd, onRe
25967
25889
  }), /* @__PURE__ */ jsx(TooltipContent, { children: removeLabel })] })] });
25968
25890
  }
25969
25891
  //#endregion
25970
- //#region src/workbench/browser/runtime/editor/dedupeSection.tsx
25971
- function DedupeSection({ task, disabled, onSave, history }) {
25972
- const t = useTranslate();
25973
- const id = useId();
25974
- const taskRef = useRef(task);
25975
- taskRef.current = task;
25976
- const saveRef = useRef(onSave);
25977
- saveRef.current = onSave;
25978
- const [changes] = useState(() => new TaskExecutorChanges(task.executor, (before, next) => {
25979
- const current = taskRef.current;
25980
- if (before.kind !== "dedupe" || next.kind !== "dedupe" || current.executor.kind !== "dedupe") return Promise.resolve(false);
25981
- const executor = { ...current.executor };
25982
- for (const key of [
25983
- "field",
25984
- "mode",
25985
- "space"
25986
- ]) if (before[key] !== next[key]) Object.assign(executor, { [key]: next[key] });
25987
- return saveRef.current(current, {
25988
- ...current,
25989
- executor
25990
- });
25991
- }));
25992
- const [config, setConfig] = useState(changes.value);
25993
- const [failed, setFailed] = useState(false);
25994
- useEffect(() => {
25995
- changes.sync(task.executor);
25996
- setConfig(changes.value);
25997
- }, [changes, task.executor]);
25998
- async function save() {
25999
- try {
26000
- setFailed(!await changes.save());
26001
- } catch {
26002
- setFailed(true);
26003
- }
26004
- }
26005
- function update(patch) {
26006
- if (disabled || changes.value.kind !== "dedupe") return;
26007
- changes.value = {
26008
- ...changes.value,
26009
- ...patch
26010
- };
26011
- setConfig(changes.value);
26012
- save();
26013
- }
26014
- if (config.kind !== "dedupe") return null;
26015
- return /* @__PURE__ */ jsx(InspectorSection, {
26016
- title: /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
26017
- className: "min-w-0 flex-1",
26018
- children: t("flowState.nodeTitle")
26019
- }), history] }),
26020
- children: /* @__PURE__ */ jsxs("div", {
26021
- className: "node-settings flex flex-col gap-3",
26022
- children: [
26023
- /* @__PURE__ */ jsxs(Field, { children: [/* @__PURE__ */ jsx(FieldLabel, {
26024
- htmlFor: `${id}-field`,
26025
- children: t("flowState.field")
26026
- }), /* @__PURE__ */ jsx(Input, {
26027
- id: `${id}-field`,
26028
- disabled,
26029
- defaultValue: config.field,
26030
- placeholder: t("flowState.fieldPlaceholder"),
26031
- onBlur: (event) => {
26032
- if (event.target.value !== config.field) update({ field: event.target.value });
26033
- }
26034
- }, config.field)] }),
26035
- /* @__PURE__ */ jsxs(Field, { children: [/* @__PURE__ */ jsx(FieldLabel, {
26036
- htmlFor: `${id}-mode`,
26037
- children: t("flowState.mode")
26038
- }), /* @__PURE__ */ jsxs(NativeSelect, {
26039
- id: `${id}-mode`,
26040
- disabled,
26041
- value: config.mode,
26042
- onChange: (event) => update({ mode: event.target.value }),
26043
- children: [/* @__PURE__ */ jsx(NativeSelectOption, {
26044
- value: "new",
26045
- children: t("flowState.new")
26046
- }), /* @__PURE__ */ jsx(NativeSelectOption, {
26047
- value: "increasing",
26048
- children: t("flowState.increasing")
26049
- })]
26050
- })] }),
26051
- /* @__PURE__ */ jsxs(Field, { children: [/* @__PURE__ */ jsx(FieldLabel, {
26052
- htmlFor: `${id}-space`,
26053
- children: t("flowState.space")
26054
- }), /* @__PURE__ */ jsxs(NativeSelect, {
26055
- id: `${id}-space`,
26056
- disabled,
26057
- value: config.space,
26058
- onChange: (event) => update({ space: event.target.value }),
26059
- children: [/* @__PURE__ */ jsx(NativeSelectOption, {
26060
- value: "node",
26061
- children: t("flowState.nodeSpace")
26062
- }), /* @__PURE__ */ jsx(NativeSelectOption, {
26063
- value: "flow",
26064
- children: t("flowState.flowSpace")
26065
- })]
26066
- })] }),
26067
- failed && /* @__PURE__ */ jsxs("div", {
26068
- role: "alert",
26069
- children: [/* @__PURE__ */ jsx("p", { children: t("httpRequest.saveFailed") }), /* @__PURE__ */ jsx(Button$1, {
26070
- disabled,
26071
- onClick: () => void save(),
26072
- variant: "outline",
26073
- size: "sm",
26074
- children: t("httpRequest.retry")
26075
- })]
26076
- }),
26077
- /* @__PURE__ */ jsx("p", {
26078
- className: "m-0 text-muted-foreground text-xs",
26079
- children: t("flowState.warning")
26080
- })
26081
- ]
26082
- })
26083
- });
26084
- }
26085
- //#endregion
26086
25892
  //#region src/workbench/browser/runtime/editor/errorTriggerSources.tsx
26087
25893
  function ErrorTriggerSources({ flows, flowId, value, disabled = false, complete = true, footer, onChange }) {
26088
25894
  const t = useTranslate();
@@ -29563,6 +29369,169 @@ function ResolutionDefinition({ disabled, selection, store }) {
29563
29369
  });
29564
29370
  }
29565
29371
  //#endregion
29372
+ //#region src/workbench/browser/runtime/editor/skipDuplicatesSection.tsx
29373
+ function SkipDuplicatesSection({ task, disabled, onSave, history }) {
29374
+ const t = useTranslate();
29375
+ const id = useId();
29376
+ const taskRef = useRef(task);
29377
+ const saveRef = useRef(onSave);
29378
+ useLayoutEffect(() => {
29379
+ taskRef.current = task;
29380
+ saveRef.current = onSave;
29381
+ }, [task, onSave]);
29382
+ const request = useRef();
29383
+ const [changes] = useState(() => new TaskExecutorChanges(task.executor, (_before, next) => {
29384
+ const current = taskRef.current;
29385
+ if (next.kind !== "skip-duplicates" || current.executor.kind !== "skip-duplicates") return Promise.resolve(false);
29386
+ return saveRef.current(current, {
29387
+ ...current,
29388
+ executor: {
29389
+ ...current.executor,
29390
+ fields: next.fields
29391
+ }
29392
+ });
29393
+ }));
29394
+ const initial = task.executor.kind === "skip-duplicates" ? task.executor.fields : [];
29395
+ const [fields, setFields] = useState(initial.length ? initial : [""]);
29396
+ const inputs = useRef([]);
29397
+ const focusField = useRef();
29398
+ useEffect(() => {
29399
+ if (focusField.current == null) return;
29400
+ inputs.current[focusField.current]?.focus();
29401
+ focusField.current = void 0;
29402
+ }, [fields]);
29403
+ const [error, setError] = useState();
29404
+ useEffect(() => {
29405
+ const previous = changes.value;
29406
+ changes.sync(task.executor);
29407
+ if (previous.kind === "skip-duplicates" && changes.value.kind === "skip-duplicates" && !dequal(previous.fields, changes.value.fields)) {
29408
+ request.current?.abort();
29409
+ setFields(changes.value.fields.length ? changes.value.fields : [""]);
29410
+ setError(void 0);
29411
+ }
29412
+ }, [changes, task.executor]);
29413
+ useEffect(() => () => request.current?.abort(), [disabled]);
29414
+ function change(next) {
29415
+ request.current?.abort();
29416
+ setFields(next);
29417
+ setError(void 0);
29418
+ }
29419
+ async function commit(next = fields) {
29420
+ if (disabled || changes.value.kind !== "skip-duplicates") return;
29421
+ request.current?.abort();
29422
+ const controller = new AbortController();
29423
+ request.current = controller;
29424
+ const rows = next.length ? next : [""];
29425
+ setFields(rows);
29426
+ await Promise.resolve();
29427
+ if (controller.signal.aborted || request.current !== controller) return;
29428
+ const normalized = rows.map((field) => field.trim());
29429
+ const parsed = skipDuplicatesConfigSchema.safeParse({ fields: normalized.filter(Boolean) });
29430
+ if (!parsed.success) {
29431
+ setError("invalid");
29432
+ return;
29433
+ }
29434
+ setFields(normalized);
29435
+ setError(void 0);
29436
+ changes.value = {
29437
+ ...changes.value,
29438
+ fields: parsed.data.fields
29439
+ };
29440
+ try {
29441
+ const saved = await changes.save();
29442
+ if (!controller.signal.aborted && request.current === controller) setError(saved ? void 0 : "save");
29443
+ } catch {
29444
+ if (!controller.signal.aborted && request.current === controller) setError("save");
29445
+ }
29446
+ }
29447
+ if (task.executor.kind !== "skip-duplicates") return null;
29448
+ return /* @__PURE__ */ jsx(InspectorSection, {
29449
+ title: /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
29450
+ className: "min-w-0 flex-1",
29451
+ children: t("flowState.nodeTitle")
29452
+ }), history] }),
29453
+ children: /* @__PURE__ */ jsxs("div", {
29454
+ className: "node-settings flex flex-col gap-3",
29455
+ children: [
29456
+ /* @__PURE__ */ jsxs(Field, { children: [
29457
+ /* @__PURE__ */ jsx(FieldLabel, {
29458
+ htmlFor: `${id}-field-0`,
29459
+ children: t("flowState.field")
29460
+ }),
29461
+ fields.map((field, index) => /* @__PURE__ */ jsxs("div", {
29462
+ className: "flex items-center gap-2",
29463
+ children: [/* @__PURE__ */ jsx(Input, {
29464
+ ref: (element) => {
29465
+ inputs.current[index] = element;
29466
+ },
29467
+ id: `${id}-field-${index}`,
29468
+ "aria-label": t("flowState.fieldIndex", { index: index + 1 }),
29469
+ "aria-invalid": error === "invalid" || void 0,
29470
+ "aria-describedby": error === "invalid" ? `${id}-error` : void 0,
29471
+ disabled,
29472
+ value: field,
29473
+ placeholder: t(fields.length === 1 ? "flowState.fieldPlaceholder" : "flowState.pathPlaceholder"),
29474
+ onChange: (event) => change(fields.map((value, at) => at === index ? event.target.value : value)),
29475
+ onBlur: () => {
29476
+ commit();
29477
+ },
29478
+ onKeyDown: (event) => {
29479
+ if (event.key === "Enter") {
29480
+ event.preventDefault();
29481
+ event.currentTarget.blur();
29482
+ }
29483
+ }
29484
+ }), !disabled && (fields.length > 1 || field !== "") && /* @__PURE__ */ jsx(Button$1, {
29485
+ variant: "ghost",
29486
+ size: "xs",
29487
+ "aria-label": t("flowState.removeField", { index: index + 1 }),
29488
+ onMouseDown: (event) => event.preventDefault(),
29489
+ onClick: () => {
29490
+ focusField.current = Math.max(0, index - 1);
29491
+ commit(fields.filter((_, at) => at !== index));
29492
+ },
29493
+ children: t("flowState.delete")
29494
+ })]
29495
+ }, index)),
29496
+ !disabled && /* @__PURE__ */ jsx("div", {
29497
+ className: "flex",
29498
+ children: /* @__PURE__ */ jsx(Button$1, {
29499
+ variant: "ghost",
29500
+ size: "sm",
29501
+ onMouseDown: (event) => event.preventDefault(),
29502
+ onClick: () => {
29503
+ const empty = fields.findIndex((field) => field.trim() === "");
29504
+ if (empty >= 0) {
29505
+ inputs.current[empty]?.focus();
29506
+ return;
29507
+ }
29508
+ focusField.current = fields.length;
29509
+ change([...fields, ""]);
29510
+ },
29511
+ children: t("flowState.addField")
29512
+ })
29513
+ })
29514
+ ] }),
29515
+ error != null && /* @__PURE__ */ jsxs("div", {
29516
+ role: "alert",
29517
+ id: `${id}-error`,
29518
+ children: [/* @__PURE__ */ jsx("p", { children: t(error === "invalid" ? "flowState.invalidFields" : "flowState.saveFailed") }), error === "save" && /* @__PURE__ */ jsx(Button$1, {
29519
+ disabled,
29520
+ onClick: () => void commit(),
29521
+ variant: "outline",
29522
+ size: "sm",
29523
+ children: t("flowState.retry")
29524
+ })]
29525
+ }),
29526
+ /* @__PURE__ */ jsx("p", {
29527
+ className: "m-0 text-muted-foreground text-xs",
29528
+ children: t("flowState.warning")
29529
+ })
29530
+ ]
29531
+ })
29532
+ });
29533
+ }
29534
+ //#endregion
29566
29535
  //#region src/workbench/browser/runtime/editor/tallyTriggerConfig.tsx
29567
29536
  function TallyTriggerConfig({ inputs, fieldLabels, config, nodeId, connectionId, disabled, store }) {
29568
29537
  const t = useTranslate();
@@ -30834,7 +30803,7 @@ function inspectorIcon(node) {
30834
30803
  if (node?.kind == "task" && node.definition != null && "executor" in node.definition) {
30835
30804
  if (node.definition.executor.kind == "decision") return "decision";
30836
30805
  if (node.definition.executor.kind == "workflow") return "flow";
30837
- if (node.definition.executor.kind == "openapi" || node.definition.executor.kind == "http-request" || node.definition.executor.kind == "dedupe") return "task";
30806
+ if (node.definition.executor.kind == "openapi" || node.definition.executor.kind == "http-request" || node.definition.executor.kind == "skip-duplicates") return "task";
30838
30807
  return node.definition.executor.kind == "connector" ? "connection" : "llm";
30839
30808
  }
30840
30809
  return "task";
@@ -30867,7 +30836,7 @@ function nodePurposePlaceholder(selection, t, action, displays) {
30867
30836
  case "agent": return t("addNode.agentDescription");
30868
30837
  case "decision": return t("decision.description");
30869
30838
  case "workflow": return t("workflow.description");
30870
- case "dedupe": return;
30839
+ case "skip-duplicates": return;
30871
30840
  case "http-request": return t("httpRequest.description");
30872
30841
  case "openapi": return t("openapi.description");
30873
30842
  case "connector": return action?.description;
@@ -30920,7 +30889,7 @@ function NodeInspector({ onAddWorkflowOutputs, onAddResponseNode, webhookDeploym
30920
30889
  loading: false,
30921
30890
  names: [],
30922
30891
  onOpen: void 0
30923
- }, readOnly = false, connectorAction, connectorActionError, connectorAccessError, connectorAuthorizationPending = false, connectorConnection, connectorConnectionError, activeConnectorConnections, connectors: liveConnectors, connectorAccess, connectorCandidates, onConfigureConnectorAccess, prepareConnectorAction, connectorLoading = false, disabled: temporarilyDisabled = false, diagnostics, focus, revision, selection, sourceNodeIcons, store: writableStore, theme, triggerActiveConnections, triggerAuthorizationPending = false, triggerConnection, triggerConnectionError, triggerConnectionLoading = false, triggerDisplays, triggers: liveTriggers }) {
30892
+ }, readOnly = false, connectorAction, connectorActionError, connectorAccessError, connectorAuthorizationPending = false, connectorConnection, connectorConnectionError, activeConnectorConnections, connectorProviders, connectors: liveConnectors, connectorAccess, connectorCandidates, onConfigureConnectorAccess, prepareConnectorAction, connectorLoading = false, disabled: temporarilyDisabled = false, diagnostics, focus, revision, selection, sourceNodeIcons, store: writableStore, theme, triggerActiveConnections, triggerAuthorizationPending = false, triggerConnection, triggerConnectionError, triggerConnectionLoading = false, triggerDisplays, triggers: liveTriggers }) {
30924
30893
  const store = readOnly ? void 0 : writableStore;
30925
30894
  const connectors = readOnly ? void 0 : liveConnectors;
30926
30895
  const triggers = readOnly ? void 0 : liveTriggers;
@@ -31215,25 +31184,6 @@ function NodeInspector({ onAddWorkflowOutputs, onAddResponseNode, webhookDeploym
31215
31184
  actions: workflowActions,
31216
31185
  list: (signal) => store.listWorkflowTargets(signal)
31217
31186
  }, `workflow:${selection?.id}`),
31218
- task != null && "executor" in task && task.executor.kind === "dedupe" && /* @__PURE__ */ jsx(DedupeSection, {
31219
- task,
31220
- disabled,
31221
- history: store != null && store.$.flowId.value != null ? /* @__PURE__ */ jsx(FlowStateButton, {
31222
- client: store.state,
31223
- flowId: store.$.flowId.value,
31224
- nodeIds: Object.keys(revision.graph()?.nodes ?? {}),
31225
- history: {
31226
- nodeId: selection.id,
31227
- space: task.executor.space === "flow" ? "flow" : `node:${selection.id}`
31228
- }
31229
- }, selection.id) : void 0,
31230
- onSave: (before, value) => store?.nodes.saveTaskSettings(selection.id, {
31231
- kind: "dedupe",
31232
- name: task.name,
31233
- before,
31234
- task: value
31235
- }) ?? Promise.resolve(false)
31236
- }, `${revision.revision.flowId}:${selection.id}`),
31237
31187
  isHttpRequest && task != null && "executor" in task && /* @__PURE__ */ jsx(HttpRequestSection, {
31238
31188
  task,
31239
31189
  disabled,
@@ -31559,6 +31509,22 @@ function NodeInspector({ onAddWorkflowOutputs, onAddResponseNode, webhookDeploym
31559
31509
  onChange: () => {}
31560
31510
  })
31561
31511
  }),
31512
+ task != null && "executor" in task && task.executor.kind === "skip-duplicates" && /* @__PURE__ */ jsx(SkipDuplicatesSection, {
31513
+ task,
31514
+ disabled,
31515
+ history: store != null && store.$.flowId.value != null ? /* @__PURE__ */ jsx(FlowStateButton, {
31516
+ client: store.state,
31517
+ flowId: store.$.flowId.value,
31518
+ nodeIds: Object.keys(revision.graph()?.nodes ?? {}),
31519
+ history: { nodeId: selection.id }
31520
+ }, selection.id) : void 0,
31521
+ onSave: (before, value) => store?.nodes.saveTaskSettings(selection.id, {
31522
+ kind: "skip-duplicates",
31523
+ name: task.name,
31524
+ before,
31525
+ task: value
31526
+ }) ?? Promise.resolve(false)
31527
+ }, `${revision.revision.flowId}:${selection.id}`),
31562
31528
  selection == null ? /* @__PURE__ */ jsx("div", {
31563
31529
  className: "inspector-empty",
31564
31530
  children: t("inspector.selectNode")
@@ -31604,6 +31570,7 @@ function NodeInspector({ onAddWorkflowOutputs, onAddResponseNode, webhookDeploym
31604
31570
  nodeId: selection.id,
31605
31571
  store,
31606
31572
  connectors,
31573
+ providers: connectorProviders,
31607
31574
  prepareAction: prepareConnectorAction,
31608
31575
  disabled,
31609
31576
  theme,
@@ -31724,7 +31691,8 @@ function CanvasNodePicker({ request, centered, ...props }) {
31724
31691
  ...props,
31725
31692
  anchor: request.screenPosition,
31726
31693
  centered,
31727
- isOptionDisabled: (option) => request.connectionSide != null && (option.kind == "trigger" || option.kind == "comment" || request.connectionSide == "left" && (option.kind == "approval" || option.kind == "condition" || option.kind == "wait"))
31694
+ initialTab: request.connectionDirection != null ? "nodes" : props.initialTab,
31695
+ isOptionDisabled: (option) => request.connectionDirection != null && (option.kind == "trigger" || option.kind == "comment" || request.connectionDirection == "downstream" && option.kind == "value" || request.connectionDirection == "upstream" && (option.kind == "approval" || option.kind == "condition" || option.kind == "wait" || option.kind == "outputs"))
31728
31696
  });
31729
31697
  }
31730
31698
  //#endregion
@@ -31806,9 +31774,11 @@ function useInspectorPanel({ identity, preferences, selectedNodeIds, onSelectNod
31806
31774
  function callbacksFromProps(props) {
31807
31775
  return {
31808
31776
  onIgnoreNodes: props.onIgnoreNodes,
31777
+ onChangeDirection: props.onChangeDirection,
31809
31778
  onAddNode: props.onAddNode,
31810
31779
  onMoveNodes: props.onMoveNodes,
31811
31780
  onChangeNodeContentHidden: props.onChangeNodeContentHidden,
31781
+ onChangeNodeWidth: props.onChangeNodeWidth,
31812
31782
  onChangeComment: props.onChangeComment,
31813
31783
  onConnect: props.onConnect,
31814
31784
  onDeleteNodes: props.onDeleteNodes,
@@ -32025,7 +31995,7 @@ function focusPanel(event) {
32025
31995
  if (element instanceof Element && element.closest("a, button, input, label, select, textarea, [contenteditable=\"true\"]")) return;
32026
31996
  event.currentTarget.focus({ preventScroll: true });
32027
31997
  }
32028
- var WorkbenchCanvas = forwardRef(function WorkbenchCanvas({ nodePicker, annotationContext, addNodeControl, addNodeOptions, history, disabled, interactiveMode$, focusNodeRequest, inspectorOpen, model, onAddNode, onConnect, onChangeNodeContentHidden, onChangeComment, onCopy, onDeleteEdge, onDeleteNodes, onDuplicate, onMoveNodes, onMoveViewport, subscribeCanvasCommands, onPaste, provideAddNodeOptions, onSelectNodes, onActivateSelection, onSelectionStart, onSelectionEnd, onToggleInspector, ignoredNodeIds, onIgnoreNodes, runControl, cornerLeading, connectionControl, topLeftTools, bottomRightTools, selectedNodeIds, theme }, ref) {
31998
+ var WorkbenchCanvas = forwardRef(function WorkbenchCanvas({ nodePicker, annotationContext, addNodeControl, addNodeOptions, history, disabled, interactiveMode$, focusNodeRequest, inspectorOpen, model, onAddNode, onConnect, onChangeNodeContentHidden, onChangeNodeWidth, onChangeComment, onCopy, onDeleteEdge, onDeleteNodes, onDuplicate, onMoveNodes, onChangeDirection, onMoveViewport, subscribeCanvasCommands, onPaste, provideAddNodeOptions, onSelectNodes, onActivateSelection, onSelectionStart, onSelectionEnd, onToggleInspector, ignoredNodeIds, onIgnoreNodes, runControl, cornerLeading, connectionControl, topLeftTools, bottomRightTools, selectedNodeIds, theme }, ref) {
32029
31999
  const [pickerRequest, setPickerRequest] = useState();
32030
32000
  const [pickerCentered, setPickerCentered] = useState(false);
32031
32001
  useEffect(() => {
@@ -32220,6 +32190,7 @@ var WorkbenchCanvas = forwardRef(function WorkbenchCanvas({ nodePicker, annotati
32220
32190
  },
32221
32191
  onConnect,
32222
32192
  onChangeNodeContentHidden,
32193
+ onChangeNodeWidth,
32223
32194
  onChangeComment,
32224
32195
  onDeleteNodes: (nodeIds) => {
32225
32196
  canvas.current?.focus({ preventScroll: true });
@@ -32233,6 +32204,7 @@ var WorkbenchCanvas = forwardRef(function WorkbenchCanvas({ nodePicker, annotati
32233
32204
  onDuplicate(positions, offset);
32234
32205
  },
32235
32206
  onMoveNodes,
32207
+ onChangeDirection,
32236
32208
  onMoveViewport,
32237
32209
  subscribeCanvasCommands,
32238
32210
  onCopy: (nodeIds) => {
@@ -32632,10 +32604,45 @@ function RevisionCanvas({ draft, presentation, theme, interactiveMode$, label, b
32632
32604
  const [selected, setSelected] = useState([]);
32633
32605
  const [inspectorOpen, setInspectorOpen] = useState(false);
32634
32606
  const [focus, setFocus] = useState();
32635
- const baseline = useMemo(() => designerGraph(draft, presentation?.value, [], {}, {}, t), [
32607
+ const [catalog, setCatalog] = useState();
32608
+ const needsProviders = revision.connectorProviderIds.size > 0;
32609
+ useEffect(() => {
32610
+ if (!needsProviders) return;
32611
+ const controller = new AbortController();
32612
+ const cache = getAppCatalogCache({
32613
+ locale: language.toLowerCase(),
32614
+ schemaVersion: 1,
32615
+ maxAge: 3e5,
32616
+ decode: decodeAppCatalogResponse,
32617
+ load: ({ locale }, validation) => loadJson(`https://connector.oomol.com/public/v1/apps?locale=${encodeURIComponent(locale)}`, validation, decodeAppCatalogResponse, {
32618
+ credentials: "omit",
32619
+ signal: AbortSignal.timeout(15e3)
32620
+ })
32621
+ });
32622
+ const publish = (response) => {
32623
+ if (controller.signal.aborted) return;
32624
+ setCatalog({
32625
+ language,
32626
+ providers: Object.fromEntries(response.data.map((app) => [app.service, provider(app, response.meta.iconSprite)]))
32627
+ });
32628
+ };
32629
+ (async () => {
32630
+ try {
32631
+ const cached = await cache.peek(void 0);
32632
+ if (cached) publish(cached.data);
32633
+ publish(await cache.get(void 0, { signal: controller.signal }));
32634
+ } catch (error) {
32635
+ if (!controller.signal.aborted) console.warn("Could not load Preview Provider metadata.", error);
32636
+ }
32637
+ })();
32638
+ return () => controller.abort();
32639
+ }, [language, needsProviders]);
32640
+ const providerMetadata = catalog?.language === language ? catalog.providers : void 0;
32641
+ const baseline = useMemo(() => designerGraph(draft, presentation?.value, [], {}, {}, t, void 0, [], providerMetadata), [
32636
32642
  draft,
32637
32643
  presentation,
32638
- t
32644
+ t,
32645
+ providerMetadata
32639
32646
  ]);
32640
32647
  const session = sessions[graphId];
32641
32648
  const model = useMemo(() => ({
@@ -32730,7 +32737,8 @@ function RevisionCanvas({ draft, presentation, theme, interactiveMode$, label, b
32730
32737
  readOnly: true,
32731
32738
  revision,
32732
32739
  selection,
32733
- theme
32740
+ theme,
32741
+ connectorProviders: providerMetadata
32734
32742
  }, `${graphId}:${selection.id}`) : comment?.kind === "comment" ? /* @__PURE__ */ jsx(CommentInspector, {
32735
32743
  title: comment.title,
32736
32744
  content: comment.content ?? "",
@@ -36652,14 +36660,10 @@ function FlowEditor({ navigationIsland, onRun, onRunStarted, onCloseRuns, onConf
36652
36660
  return /* @__PURE__ */ jsx(NodeHistoryContext.Provider, {
36653
36661
  value: (nodeId) => {
36654
36662
  const node = revision?.graph().nodes[nodeId];
36655
- if (flowId == null || node?.kind !== "task" || !("executor" in node.task) || node.task.executor.kind !== "dedupe") return void 0;
36656
- const space = node.task.executor.space === "flow" ? "flow" : `node:${nodeId}`;
36663
+ if (flowId == null || node?.kind !== "task" || !("executor" in node.task) || node.task.executor.kind !== "skip-duplicates") return void 0;
36657
36664
  return {
36658
36665
  label: t("flowState.history"),
36659
- onClick: () => setStateTarget({ history: {
36660
- nodeId,
36661
- space
36662
- } })
36666
+ onClick: () => setStateTarget({ history: { nodeId } })
36663
36667
  };
36664
36668
  },
36665
36669
  children: /* @__PURE__ */ jsxs(CanvasHistoryScope, {
@@ -36801,12 +36805,14 @@ function FlowEditor({ navigationIsland, onRun, onRunStarted, onCloseRuns, onConf
36801
36805
  },
36802
36806
  onConnect: (edge) => void store.workspace.connect(edge),
36803
36807
  onChangeNodeContentHidden: (nodeId, hidden) => void store.workspace.saveNodeContentHidden(nodeId, hidden),
36808
+ onChangeNodeWidth: (nodeId, width, position) => store.workspace.saveNodeWidth(nodeId, width, position),
36804
36809
  onChangeComment: (nodeId, value) => void store.workspace.saveComment(nodeId, value),
36805
36810
  onCopy: () => store.workspace.copySelectedNodes(),
36806
36811
  onDeleteEdge: (edge) => void store.workspace.disconnect(edge),
36807
36812
  onDeleteNodes: () => void store.workspace.deleteSelectedNodes(),
36808
36813
  onDuplicate: (positions, offset) => void store.workspace.duplicateSelectedNodes(positions, offset),
36809
36814
  onMoveNodes: (positions) => void store.workspace.moveNodes(positions),
36815
+ onChangeDirection: (direction, positions) => store.changeDirection(direction, positions),
36810
36816
  onMoveViewport: (viewport) => void store.workspace.moveViewport(viewport),
36811
36817
  onPaste: () => void store.workspace.pasteNodes(),
36812
36818
  provideAddNodeOptions: store.provideAddNodeOptions,