Compare commits

...

4 Commits

Author SHA1 Message Date
waleed
961649565a updated to account for workflow input tool on top of just workflow as well 2026-01-14 15:26:48 -08:00
waleed
1b38b2e6cd ack comments 2026-01-14 14:02:02 -08:00
waleed
db9f9ec4e5 FF react grab 2026-01-14 13:03:10 -08:00
waleed
0a860b3e01 fix(agent-tools): added special handling for workflow tool in agent tool input, added react grab 2026-01-14 12:56:55 -08:00
6 changed files with 47 additions and 7 deletions

View File

@@ -1,12 +1,13 @@
import type { Metadata, Viewport } from 'next'
import Script from 'next/script'
import { PublicEnvScript } from 'next-runtime-env'
import { BrandedLayout } from '@/components/branded-layout'
import { generateThemeCSS } from '@/lib/branding/inject-theme'
import { generateBrandedMetadata, generateStructuredData } from '@/lib/branding/metadata'
import { PostHogProvider } from '@/app/_shell/providers/posthog-provider'
import '@/app/_styles/globals.css'
import { OneDollarStats } from '@/components/analytics/onedollarstats'
import { isReactGrabEnabled } from '@/lib/core/config/feature-flags'
import { HydrationErrorHandler } from '@/app/_shell/hydration-error-handler'
import { QueryProvider } from '@/app/_shell/providers/query-provider'
import { SessionProvider } from '@/app/_shell/providers/session-provider'
@@ -33,6 +34,19 @@ export default function RootLayout({ children }: { children: React.ReactNode })
return (
<html lang='en' suppressHydrationWarning>
<head>
{isReactGrabEnabled && (
<Script
src='https://unpkg.com/react-grab/dist/index.global.js'
crossOrigin='anonymous'
strategy='beforeInteractive'
/>
)}
{isReactGrabEnabled && (
<Script
src='https://unpkg.com/@react-grab/cursor/dist/client.global.js'
strategy='lazyOnload'
/>
)}
{/* Structured Data for SEO */}
<script
type='application/ld+json'

View File

@@ -1036,6 +1036,7 @@ export function ToolInput({
block.type === 'api' ||
block.type === 'webhook_request' ||
block.type === 'workflow' ||
block.type === 'workflow_input' ||
block.type === 'knowledge' ||
block.type === 'function') &&
block.type !== 'evaluator' &&
@@ -1761,7 +1762,7 @@ export function ToolInput({
iconElement: createToolIcon('#6366F1', WorkflowIcon),
onSelect: () => {
const newTool: StoredTool = {
type: 'workflow',
type: 'workflow_input',
title: 'Workflow',
toolId: 'workflow_executor',
params: {
@@ -2195,9 +2196,10 @@ export function ToolInput({
{/* Selected Tools List */}
{selectedTools.length > 0 &&
selectedTools.map((tool, toolIndex) => {
// Handle custom tools and MCP tools differently
// Handle custom tools, MCP tools, and workflow tools differently
const isCustomTool = tool.type === 'custom-tool'
const isMcpTool = tool.type === 'mcp'
const isWorkflowTool = tool.type === 'workflow'
const toolBlock =
!isCustomTool && !isMcpTool
? toolBlocks.find((block) => block.type === tool.type)
@@ -2323,13 +2325,17 @@ export function ToolInput({
? '#3B82F6'
: isMcpTool
? mcpTool?.bgColor || '#6366F1'
: toolBlock?.bgColor,
: isWorkflowTool
? '#6366F1'
: toolBlock?.bgColor,
}}
>
{isCustomTool ? (
<WrenchIcon className='h-[10px] w-[10px] text-white' />
) : isMcpTool ? (
<IconComponent icon={McpIcon} className='h-[10px] w-[10px] text-white' />
) : isWorkflowTool ? (
<IconComponent icon={WorkflowIcon} className='h-[10px] w-[10px] text-white' />
) : (
<IconComponent
icon={toolBlock?.icon}
@@ -2369,9 +2375,10 @@ export function ToolInput({
</Tooltip.Root>
)
})()}
{tool.type === 'workflow' && tool.params?.workflowId && (
<WorkflowToolDeployBadge workflowId={tool.params.workflowId} />
)}
{(tool.type === 'workflow' || tool.type === 'workflow_input') &&
tool.params?.workflowId && (
<WorkflowToolDeployBadge workflowId={tool.params.workflowId} />
)}
</div>
<div className='flex flex-shrink-0 items-center gap-[8px]'>
{supportsToolControl && !(isMcpTool && isMcpToolUnavailable(tool)) && (

View File

@@ -256,6 +256,7 @@ const Combobox = forwardRef<HTMLDivElement, ComboboxProps>(
customOnSelect()
setOpen(false)
setHighlightedIndex(-1)
setSearchQuery('')
return
}
@@ -269,6 +270,7 @@ const Combobox = forwardRef<HTMLDivElement, ComboboxProps>(
onChange?.(selectedValue)
setOpen(false)
setHighlightedIndex(-1)
setSearchQuery('')
if (editable && inputRef.current) {
inputRef.current.blur()
}
@@ -312,6 +314,7 @@ const Combobox = forwardRef<HTMLDivElement, ComboboxProps>(
if (!activeElement || (!isInContainer && !isInDropdown && !isSearchInput)) {
setOpen(false)
setHighlightedIndex(-1)
setSearchQuery('')
}
}, 150)
}, [])
@@ -326,6 +329,7 @@ const Combobox = forwardRef<HTMLDivElement, ComboboxProps>(
if (e.key === 'Escape') {
setOpen(false)
setHighlightedIndex(-1)
setSearchQuery('')
if (editable && inputRef.current) {
inputRef.current.blur()
}

View File

@@ -260,6 +260,9 @@ export const env = createEnv({
// Invitations - for self-hosted deployments
DISABLE_INVITATIONS: z.boolean().optional(), // Disable workspace invitations globally (for self-hosted deployments)
// Development Tools
REACT_GRAB_ENABLED: z.boolean().optional(), // Enable React Grab for UI element debugging in Cursor/AI agents (dev only)
// SSO Configuration (for script-based registration)
SSO_ENABLED: z.boolean().optional(), // Enable SSO functionality
SSO_PROVIDER_TYPE: z.enum(['oidc', 'saml']).optional(), // [REQUIRED] SSO provider type

View File

@@ -111,6 +111,12 @@ export const isE2bEnabled = isTruthy(env.E2B_ENABLED)
*/
export const isInvitationsDisabled = isTruthy(env.DISABLE_INVITATIONS)
/**
* Is React Grab enabled for UI element debugging
* When true and in development mode, enables React Grab for copying UI element context to clipboard
*/
export const isReactGrabEnabled = isDev && isTruthy(env.REACT_GRAB_ENABLED)
/**
* Get cost multiplier based on environment
*/

View File

@@ -3154,6 +3154,10 @@
"seq-queue": ["seq-queue@0.0.5", "", {}, "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q=="],
"seroval": ["seroval@1.3.2", "", {}, "sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ=="],
"seroval-plugins": ["seroval-plugins@1.3.3", "", { "peerDependencies": { "seroval": "^1.0" } }, "sha512-16OL3NnUBw8JG1jBLUoZJsLnQq0n5Ua6aHalhJK4fMQkz1lqR7Osz1sA30trBtd9VUDc2NgkuRCn8+/pBwqZ+w=="],
"serve-static": ["serve-static@2.2.1", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw=="],
"set-cookie-parser": ["set-cookie-parser@2.7.2", "", {}, "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw=="],
@@ -3220,6 +3224,8 @@
"socks-proxy-agent": ["socks-proxy-agent@8.0.5", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" } }, "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw=="],
"solid-js": ["solid-js@1.9.10", "", { "dependencies": { "csstype": "^3.1.0", "seroval": "~1.3.0", "seroval-plugins": "~1.3.0" } }, "sha512-Coz956cos/EPDlhs6+jsdTxKuJDPT7B5SVIWgABwROyxjY7Xbr8wkzD68Et+NxnV7DLJ3nJdAC2r9InuV/4Jew=="],
"sonic-boom": ["sonic-boom@4.2.0", "", { "dependencies": { "atomic-sleep": "^1.0.0" } }, "sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww=="],
"source-map": ["source-map@0.7.6", "", {}, "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ=="],