Skip to content

Commit 41f9374

Browse files
authored
fix(agent-tools): added special handling for workflow tool in agent tool input, added react grab and feature flag (#2820)
* fix(agent-tools): added special handling for workflow tool in agent tool input, added react grab * FF react grab * ack comments * updated to account for workflow input tool on top of just workflow as well
1 parent 6c8c3d6 commit 41f9374

File tree

6 files changed

+47
-7
lines changed

6 files changed

+47
-7
lines changed

apps/sim/app/layout.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import type { Metadata, Viewport } from 'next'
2+
import Script from 'next/script'
23
import { PublicEnvScript } from 'next-runtime-env'
34
import { BrandedLayout } from '@/components/branded-layout'
45
import { generateThemeCSS } from '@/lib/branding/inject-theme'
56
import { generateBrandedMetadata, generateStructuredData } from '@/lib/branding/metadata'
67
import { PostHogProvider } from '@/app/_shell/providers/posthog-provider'
78
import '@/app/_styles/globals.css'
8-
99
import { OneDollarStats } from '@/components/analytics/onedollarstats'
10+
import { isReactGrabEnabled } from '@/lib/core/config/feature-flags'
1011
import { HydrationErrorHandler } from '@/app/_shell/hydration-error-handler'
1112
import { QueryProvider } from '@/app/_shell/providers/query-provider'
1213
import { SessionProvider } from '@/app/_shell/providers/session-provider'
@@ -33,6 +34,19 @@ export default function RootLayout({ children }: { children: React.ReactNode })
3334
return (
3435
<html lang='en' suppressHydrationWarning>
3536
<head>
37+
{isReactGrabEnabled && (
38+
<Script
39+
src='https://unpkg.com/react-grab/dist/index.global.js'
40+
crossOrigin='anonymous'
41+
strategy='beforeInteractive'
42+
/>
43+
)}
44+
{isReactGrabEnabled && (
45+
<Script
46+
src='https://unpkg.com/@react-grab/cursor/dist/client.global.js'
47+
strategy='lazyOnload'
48+
/>
49+
)}
3650
{/* Structured Data for SEO */}
3751
<script
3852
type='application/ld+json'

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

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,6 +1036,7 @@ export function ToolInput({
10361036
block.type === 'api' ||
10371037
block.type === 'webhook_request' ||
10381038
block.type === 'workflow' ||
1039+
block.type === 'workflow_input' ||
10391040
block.type === 'knowledge' ||
10401041
block.type === 'function') &&
10411042
block.type !== 'evaluator' &&
@@ -1761,7 +1762,7 @@ export function ToolInput({
17611762
iconElement: createToolIcon('#6366F1', WorkflowIcon),
17621763
onSelect: () => {
17631764
const newTool: StoredTool = {
1764-
type: 'workflow',
1765+
type: 'workflow_input',
17651766
title: 'Workflow',
17661767
toolId: 'workflow_executor',
17671768
params: {
@@ -2195,9 +2196,10 @@ export function ToolInput({
21952196
{/* Selected Tools List */}
21962197
{selectedTools.length > 0 &&
21972198
selectedTools.map((tool, toolIndex) => {
2198-
// Handle custom tools and MCP tools differently
2199+
// Handle custom tools, MCP tools, and workflow tools differently
21992200
const isCustomTool = tool.type === 'custom-tool'
22002201
const isMcpTool = tool.type === 'mcp'
2202+
const isWorkflowTool = tool.type === 'workflow'
22012203
const toolBlock =
22022204
!isCustomTool && !isMcpTool
22032205
? toolBlocks.find((block) => block.type === tool.type)
@@ -2323,13 +2325,17 @@ export function ToolInput({
23232325
? '#3B82F6'
23242326
: isMcpTool
23252327
? mcpTool?.bgColor || '#6366F1'
2326-
: toolBlock?.bgColor,
2328+
: isWorkflowTool
2329+
? '#6366F1'
2330+
: toolBlock?.bgColor,
23272331
}}
23282332
>
23292333
{isCustomTool ? (
23302334
<WrenchIcon className='h-[10px] w-[10px] text-white' />
23312335
) : isMcpTool ? (
23322336
<IconComponent icon={McpIcon} className='h-[10px] w-[10px] text-white' />
2337+
) : isWorkflowTool ? (
2338+
<IconComponent icon={WorkflowIcon} className='h-[10px] w-[10px] text-white' />
23332339
) : (
23342340
<IconComponent
23352341
icon={toolBlock?.icon}
@@ -2369,9 +2375,10 @@ export function ToolInput({
23692375
</Tooltip.Root>
23702376
)
23712377
})()}
2372-
{tool.type === 'workflow' && tool.params?.workflowId && (
2373-
<WorkflowToolDeployBadge workflowId={tool.params.workflowId} />
2374-
)}
2378+
{(tool.type === 'workflow' || tool.type === 'workflow_input') &&
2379+
tool.params?.workflowId && (
2380+
<WorkflowToolDeployBadge workflowId={tool.params.workflowId} />
2381+
)}
23752382
</div>
23762383
<div className='flex flex-shrink-0 items-center gap-[8px]'>
23772384
{supportsToolControl && !(isMcpTool && isMcpToolUnavailable(tool)) && (

apps/sim/components/emcn/components/combobox/combobox.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ const Combobox = forwardRef<HTMLDivElement, ComboboxProps>(
256256
customOnSelect()
257257
setOpen(false)
258258
setHighlightedIndex(-1)
259+
setSearchQuery('')
259260
return
260261
}
261262

@@ -269,6 +270,7 @@ const Combobox = forwardRef<HTMLDivElement, ComboboxProps>(
269270
onChange?.(selectedValue)
270271
setOpen(false)
271272
setHighlightedIndex(-1)
273+
setSearchQuery('')
272274
if (editable && inputRef.current) {
273275
inputRef.current.blur()
274276
}
@@ -312,6 +314,7 @@ const Combobox = forwardRef<HTMLDivElement, ComboboxProps>(
312314
if (!activeElement || (!isInContainer && !isInDropdown && !isSearchInput)) {
313315
setOpen(false)
314316
setHighlightedIndex(-1)
317+
setSearchQuery('')
315318
}
316319
}, 150)
317320
}, [])
@@ -326,6 +329,7 @@ const Combobox = forwardRef<HTMLDivElement, ComboboxProps>(
326329
if (e.key === 'Escape') {
327330
setOpen(false)
328331
setHighlightedIndex(-1)
332+
setSearchQuery('')
329333
if (editable && inputRef.current) {
330334
inputRef.current.blur()
331335
}

apps/sim/lib/core/config/env.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,9 @@ export const env = createEnv({
260260
// Invitations - for self-hosted deployments
261261
DISABLE_INVITATIONS: z.boolean().optional(), // Disable workspace invitations globally (for self-hosted deployments)
262262

263+
// Development Tools
264+
REACT_GRAB_ENABLED: z.boolean().optional(), // Enable React Grab for UI element debugging in Cursor/AI agents (dev only)
265+
263266
// SSO Configuration (for script-based registration)
264267
SSO_ENABLED: z.boolean().optional(), // Enable SSO functionality
265268
SSO_PROVIDER_TYPE: z.enum(['oidc', 'saml']).optional(), // [REQUIRED] SSO provider type

apps/sim/lib/core/config/feature-flags.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,12 @@ export const isE2bEnabled = isTruthy(env.E2B_ENABLED)
111111
*/
112112
export const isInvitationsDisabled = isTruthy(env.DISABLE_INVITATIONS)
113113

114+
/**
115+
* Is React Grab enabled for UI element debugging
116+
* When true and in development mode, enables React Grab for copying UI element context to clipboard
117+
*/
118+
export const isReactGrabEnabled = isDev && isTruthy(env.REACT_GRAB_ENABLED)
119+
114120
/**
115121
* Get cost multiplier based on environment
116122
*/

bun.lock

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)