Skip to content

Commit a3dff10

Browse files
authored
feat(tools): added workflow tools to agent tools dropdown for discoverability, enforce perms on client for redeploying via the agent (#2778)
* feat(tools): added workflow tools to agent tools dropdown for discoverability, enforce perms on client for redeploying via the agent * added perms enforcement to workflow block header as well
1 parent 0aec9ef commit a3dff10

File tree

3 files changed

+60
-10
lines changed

3 files changed

+60
-10
lines changed

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tool-input/tool-input.tsx

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
Switch,
1717
Tooltip,
1818
} from '@/components/emcn'
19-
import { McpIcon } from '@/components/icons'
19+
import { McpIcon, WorkflowIcon } from '@/components/icons'
2020
import { cn } from '@/lib/core/utils/cn'
2121
import {
2222
getIssueBadgeLabel,
@@ -30,6 +30,7 @@ import {
3030
type OAuthProvider,
3131
type OAuthService,
3232
} from '@/lib/oauth'
33+
import { useUserPermissionsContext } from '@/app/workspace/[workspaceId]/providers/workspace-permissions-provider'
3334
import {
3435
CheckboxList,
3536
Code,
@@ -769,9 +770,10 @@ function WorkflowToolDeployBadge({
769770
}) {
770771
const { isDeployed, needsRedeploy, isLoading, refetch } = useChildDeployment(workflowId)
771772
const [isDeploying, setIsDeploying] = useState(false)
773+
const userPermissions = useUserPermissionsContext()
772774

773775
const deployWorkflow = useCallback(async () => {
774-
if (isDeploying || !workflowId) return
776+
if (isDeploying || !workflowId || !userPermissions.canAdmin) return
775777

776778
try {
777779
setIsDeploying(true)
@@ -796,7 +798,7 @@ function WorkflowToolDeployBadge({
796798
} finally {
797799
setIsDeploying(false)
798800
}
799-
}, [isDeploying, workflowId, refetch, onDeploySuccess])
801+
}, [isDeploying, workflowId, refetch, onDeploySuccess, userPermissions.canAdmin])
800802

801803
if (isLoading || (isDeployed && !needsRedeploy)) {
802804
return null
@@ -811,13 +813,13 @@ function WorkflowToolDeployBadge({
811813
<Tooltip.Trigger asChild>
812814
<Badge
813815
variant={!isDeployed ? 'red' : 'amber'}
814-
className='cursor-pointer'
816+
className={userPermissions.canAdmin ? 'cursor-pointer' : 'cursor-not-allowed'}
815817
size='sm'
816818
dot
817819
onClick={(e: React.MouseEvent) => {
818820
e.stopPropagation()
819821
e.preventDefault()
820-
if (!isDeploying) {
822+
if (!isDeploying && userPermissions.canAdmin) {
821823
deployWorkflow()
822824
}
823825
}}
@@ -826,7 +828,13 @@ function WorkflowToolDeployBadge({
826828
</Badge>
827829
</Tooltip.Trigger>
828830
<Tooltip.Content>
829-
<span className='text-sm'>{!isDeployed ? 'Click to deploy' : 'Click to redeploy'}</span>
831+
<span className='text-sm'>
832+
{!userPermissions.canAdmin
833+
? 'Admin permission required to deploy'
834+
: !isDeployed
835+
? 'Click to deploy'
836+
: 'Click to redeploy'}
837+
</span>
830838
</Tooltip.Content>
831839
</Tooltip.Root>
832840
)
@@ -933,6 +941,13 @@ export function ToolInput({
933941
const forceRefreshMcpTools = useForceRefreshMcpTools()
934942
const openSettingsModal = useSettingsModalStore((state) => state.openModal)
935943
const mcpDataLoading = mcpLoading || mcpServersLoading
944+
945+
// Fetch workflows for the Workflows section in the dropdown
946+
const { data: workflowsList = [] } = useWorkflows(workspaceId, { syncRegistry: false })
947+
const availableWorkflows = useMemo(
948+
() => workflowsList.filter((w) => w.id !== workflowId),
949+
[workflowsList, workflowId]
950+
)
936951
const hasRefreshedRef = useRef(false)
937952

938953
const hasMcpTools = selectedTools.some((tool) => tool.type === 'mcp')
@@ -1735,6 +1750,36 @@ export function ToolInput({
17351750
})
17361751
}
17371752

1753+
// Workflows section - shows available workflows that can be executed as tools
1754+
if (availableWorkflows.length > 0) {
1755+
groups.push({
1756+
section: 'Workflows',
1757+
items: availableWorkflows.map((workflow) => ({
1758+
label: workflow.name,
1759+
value: `workflow-${workflow.id}`,
1760+
iconElement: createToolIcon('#6366F1', WorkflowIcon),
1761+
onSelect: () => {
1762+
const newTool: StoredTool = {
1763+
type: 'workflow',
1764+
title: 'Workflow',
1765+
toolId: 'workflow_executor',
1766+
params: {
1767+
workflowId: workflow.id,
1768+
},
1769+
isExpanded: true,
1770+
usageControl: 'auto',
1771+
}
1772+
setStoreValue([
1773+
...selectedTools.map((tool) => ({ ...tool, isExpanded: false })),
1774+
newTool,
1775+
])
1776+
setOpen(false)
1777+
},
1778+
disabled: isPreview || disabled,
1779+
})),
1780+
})
1781+
}
1782+
17381783
return groups
17391784
}, [
17401785
customTools,
@@ -1749,6 +1794,7 @@ export function ToolInput({
17491794
handleSelectTool,
17501795
permissionConfig.disableCustomTools,
17511796
permissionConfig.disableMcpTools,
1797+
availableWorkflows,
17521798
])
17531799

17541800
const toolRequiresOAuth = (toolId: string): boolean => {

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/workflow-block.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,11 +1021,11 @@ export const WorkflowBlock = memo(function WorkflowBlock({
10211021
<Tooltip.Trigger asChild>
10221022
<Badge
10231023
variant={!childIsDeployed ? 'red' : 'amber'}
1024-
className='cursor-pointer'
1024+
className={userPermissions.canAdmin ? 'cursor-pointer' : 'cursor-not-allowed'}
10251025
dot
10261026
onClick={(e) => {
10271027
e.stopPropagation()
1028-
if (childWorkflowId && !isDeploying) {
1028+
if (childWorkflowId && !isDeploying && userPermissions.canAdmin) {
10291029
deployWorkflow(childWorkflowId)
10301030
}
10311031
}}
@@ -1035,7 +1035,11 @@ export const WorkflowBlock = memo(function WorkflowBlock({
10351035
</Tooltip.Trigger>
10361036
<Tooltip.Content>
10371037
<span className='text-sm'>
1038-
{!childIsDeployed ? 'Click to deploy' : 'Click to redeploy'}
1038+
{!userPermissions.canAdmin
1039+
? 'Admin permission required to deploy'
1040+
: !childIsDeployed
1041+
? 'Click to deploy'
1042+
: 'Click to redeploy'}
10391043
</span>
10401044
</Tooltip.Content>
10411045
</Tooltip.Root>

apps/sim/tools/params.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ export function getToolParametersConfig(
163163
id: 'workflowId',
164164
type: 'string',
165165
required: true,
166-
visibility: 'user-or-llm',
166+
visibility: 'user-only',
167167
description: 'The ID of the workflow to execute',
168168
uiComponent: {
169169
type: 'workflow-selector',

0 commit comments

Comments
 (0)