From 2354a0548fc831e83596d6c2aca886eaee5c2af2 Mon Sep 17 00:00:00 2001 From: Vikhyath Mondreti Date: Sat, 2 May 2026 11:14:56 -0700 Subject: [PATCH 1/2] fix(blocks): depends on misalignment --- apps/docs/content/docs/en/tools/stt.mdx | 2 +- apps/sim/app/api/tools/stt/route.ts | 14 +-- apps/sim/blocks/blocks/agent.ts | 6 ++ apps/sim/blocks/blocks/airtable.ts | 1 + apps/sim/blocks/blocks/asana.ts | 2 + apps/sim/blocks/blocks/discord.ts | 2 + apps/sim/blocks/blocks/elasticsearch.ts | 11 +++ apps/sim/blocks/blocks/gmail.ts | 4 + apps/sim/blocks/blocks/google_calendar.ts | 2 + apps/sim/blocks/blocks/google_maps.ts | 4 +- apps/sim/blocks/blocks/google_sheets.ts | 2 +- apps/sim/blocks/blocks/guardrails.ts | 9 ++ apps/sim/blocks/blocks/huggingface.ts | 1 + apps/sim/blocks/blocks/image_generator.ts | 16 +++- apps/sim/blocks/blocks/jira.ts | 2 +- .../blocks/blocks/jira_service_management.ts | 2 + apps/sim/blocks/blocks/knowledge.ts | 1 + apps/sim/blocks/blocks/linear.ts | 4 + apps/sim/blocks/blocks/mcp.ts | 1 + apps/sim/blocks/blocks/microsoft_teams.ts | 3 + apps/sim/blocks/blocks/monday.ts | 2 + apps/sim/blocks/blocks/notion.ts | 3 + apps/sim/blocks/blocks/outlook.ts | 3 + apps/sim/blocks/blocks/sftp.ts | 3 + apps/sim/blocks/blocks/slack.ts | 6 ++ apps/sim/blocks/blocks/ssh.ts | 3 + apps/sim/blocks/blocks/stagehand.ts | 36 +++++-- apps/sim/blocks/blocks/stt.ts | 14 +-- apps/sim/blocks/blocks/table.ts | 1 + apps/sim/blocks/blocks/trello.ts | 1 + apps/sim/blocks/blocks/tts.ts | 27 ++++++ apps/sim/blocks/blocks/video_generator.ts | 39 ++++++++ apps/sim/blocks/blocks/wealthbox.ts | 2 + apps/sim/blocks/blocks/zoom.ts | 1 + apps/sim/blocks/utils.test.ts | 93 +++++++++++++++++++ apps/sim/blocks/utils.ts | 34 +++++-- apps/sim/hooks/use-collaborative-workflow.ts | 5 +- apps/sim/tools/stt/elevenlabs.ts | 6 +- 38 files changed, 317 insertions(+), 51 deletions(-) diff --git a/apps/docs/content/docs/en/tools/stt.mdx b/apps/docs/content/docs/en/tools/stt.mdx index 6920544178b..eecd270fe1c 100644 --- a/apps/docs/content/docs/en/tools/stt.mdx +++ b/apps/docs/content/docs/en/tools/stt.mdx @@ -120,7 +120,7 @@ Transcribe audio and video files to text using leading AI providers. Supports mu | --------- | ---- | -------- | ----------- | | `provider` | string | Yes | STT provider \(elevenlabs\) | | `apiKey` | string | Yes | ElevenLabs API key | -| `model` | string | No | ElevenLabs model to use \(scribe_v1, scribe_v1_experimental\) | +| `model` | string | No | ElevenLabs model to use \(scribe_v2\) | | `audioFile` | file | No | Audio or video file to transcribe \(e.g., MP3, WAV, M4A, WEBM\) | | `audioFileReference` | file | No | Reference to audio/video file from previous blocks | | `audioUrl` | string | No | URL to audio or video file | diff --git a/apps/sim/app/api/tools/stt/route.ts b/apps/sim/app/api/tools/stt/route.ts index 4ff71c05cc0..3779a6b2982 100644 --- a/apps/sim/app/api/tools/stt/route.ts +++ b/apps/sim/app/api/tools/stt/route.ts @@ -20,6 +20,7 @@ import { import type { TranscriptSegment } from '@/tools/stt/types' const logger = createLogger('SttProxyAPI') +const ELEVENLABS_STT_MODEL = 'scribe_v2' export const dynamic = 'force-dynamic' export const maxDuration = 300 // 5 minutes for large files @@ -222,13 +223,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => { duration = result.duration confidence = result.confidence } else if (provider === 'elevenlabs') { - const result = await transcribeWithElevenLabs( - audioBuffer, - apiKey, - language, - timestamps, - model - ) + const result = await transcribeWithElevenLabs(audioBuffer, apiKey, language, timestamps) transcript = result.transcript segments = result.segments detectedLanguage = result.language @@ -470,8 +465,7 @@ async function transcribeWithElevenLabs( audioBuffer: Buffer, apiKey: string, language?: string, - timestamps?: 'none' | 'sentence' | 'word', - model?: string + timestamps?: 'none' | 'sentence' | 'word' ): Promise<{ transcript: string segments?: TranscriptSegment[] @@ -481,7 +475,7 @@ async function transcribeWithElevenLabs( const formData = new FormData() const blob = new Blob([new Uint8Array(audioBuffer)], { type: 'audio/mpeg' }) formData.append('file', blob, 'audio.mp3') - formData.append('model_id', model || 'scribe_v1') + formData.append('model_id', ELEVENLABS_STT_MODEL) if (language && language !== 'auto') { formData.append('language_code', language) diff --git a/apps/sim/blocks/blocks/agent.ts b/apps/sim/blocks/blocks/agent.ts index 7f5a641576a..c0592b60c33 100644 --- a/apps/sim/blocks/blocks/agent.ts +++ b/apps/sim/blocks/blocks/agent.ts @@ -329,6 +329,7 @@ Return ONLY the JSON array.`, value: MODELS_WITHOUT_MEMORY, not: true, }, + dependsOn: ['model'], }, { id: 'conversationId', @@ -344,6 +345,7 @@ Return ONLY the JSON array.`, value: ['conversation', 'sliding_window', 'sliding_window_tokens'], and: { field: 'model', value: MODELS_WITHOUT_MEMORY, not: true }, }, + dependsOn: ['model', 'memoryType'], }, { id: 'slidingWindowSize', @@ -355,6 +357,7 @@ Return ONLY the JSON array.`, value: ['sliding_window'], and: { field: 'model', value: MODELS_WITHOUT_MEMORY, not: true }, }, + dependsOn: ['model', 'memoryType'], }, { id: 'slidingWindowTokens', @@ -366,6 +369,7 @@ Return ONLY the JSON array.`, value: ['sliding_window_tokens'], and: { field: 'model', value: MODELS_WITHOUT_MEMORY, not: true }, }, + dependsOn: ['model', 'memoryType'], }, { id: 'temperature', @@ -422,6 +426,7 @@ Return ONLY the JSON array.`, value: MODELS_WITH_DEEP_RESEARCH, not: true, }, + dependsOn: ['model'], }, { id: 'responseFormat', @@ -445,6 +450,7 @@ Return ONLY the JSON array.`, field: 'model', value: MODELS_WITH_DEEP_RESEARCH, }, + dependsOn: ['model'], }, ], tools: { diff --git a/apps/sim/blocks/blocks/airtable.ts b/apps/sim/blocks/blocks/airtable.ts index ff0e3036040..dd1a4b61d97 100644 --- a/apps/sim/blocks/blocks/airtable.ts +++ b/apps/sim/blocks/blocks/airtable.ts @@ -74,6 +74,7 @@ export const AirtableBlock: BlockConfig = { type: 'short-input', canonicalParamId: 'baseId', placeholder: 'Enter your base ID (e.g., appXXXXXXXXXXXXXX)', + dependsOn: ['credential'], mode: 'advanced', condition: { field: 'operation', value: 'listBases', not: true }, required: { field: 'operation', value: 'listBases', not: true }, diff --git a/apps/sim/blocks/blocks/asana.ts b/apps/sim/blocks/blocks/asana.ts index da9bfe57e60..13e0e072725 100644 --- a/apps/sim/blocks/blocks/asana.ts +++ b/apps/sim/blocks/blocks/asana.ts @@ -74,6 +74,7 @@ export const AsanaBlock: BlockConfig = { canonicalParamId: 'workspace', required: true, placeholder: 'Enter Asana workspace GID', + dependsOn: ['credential'], mode: 'advanced', condition: { field: 'operation', @@ -123,6 +124,7 @@ export const AsanaBlock: BlockConfig = { type: 'short-input', canonicalParamId: 'getTasks_workspace', placeholder: 'Enter workspace GID', + dependsOn: ['credential'], mode: 'advanced', condition: { field: 'operation', diff --git a/apps/sim/blocks/blocks/discord.ts b/apps/sim/blocks/blocks/discord.ts index 992874e4e08..97d79692adb 100644 --- a/apps/sim/blocks/blocks/discord.ts +++ b/apps/sim/blocks/blocks/discord.ts @@ -197,6 +197,7 @@ export const DiscordBlock: BlockConfig = { 'discord_create_webhook', ], }, + dependsOn: ['operation'], }, // Name (optional for updates) { @@ -208,6 +209,7 @@ export const DiscordBlock: BlockConfig = { field: 'operation', value: ['discord_update_channel', 'discord_update_role'], }, + dependsOn: ['operation'], }, // Role ID { diff --git a/apps/sim/blocks/blocks/elasticsearch.ts b/apps/sim/blocks/blocks/elasticsearch.ts index e95a80eba8b..b99c653126e 100644 --- a/apps/sim/blocks/blocks/elasticsearch.ts +++ b/apps/sim/blocks/blocks/elasticsearch.ts @@ -63,6 +63,7 @@ export const ElasticsearchBlock: BlockConfig = { placeholder: 'https://localhost:9200', required: true, condition: { field: 'deploymentType', value: 'self_hosted' }, + dependsOn: ['deploymentType'], }, // Cloud ID @@ -73,6 +74,7 @@ export const ElasticsearchBlock: BlockConfig = { placeholder: 'deployment-name:base64-encoded-data', required: true, condition: { field: 'deploymentType', value: 'cloud' }, + dependsOn: ['deploymentType'], }, // Authentication method @@ -96,6 +98,7 @@ export const ElasticsearchBlock: BlockConfig = { password: true, required: true, condition: { field: 'authMethod', value: 'api_key' }, + dependsOn: ['authMethod'], }, // Username @@ -106,6 +109,7 @@ export const ElasticsearchBlock: BlockConfig = { placeholder: 'Enter username', required: true, condition: { field: 'authMethod', value: 'basic_auth' }, + dependsOn: ['authMethod'], }, // Password @@ -117,6 +121,7 @@ export const ElasticsearchBlock: BlockConfig = { password: true, required: true, condition: { field: 'authMethod', value: 'basic_auth' }, + dependsOn: ['authMethod'], }, // Index name - for most operations @@ -158,6 +163,7 @@ export const ElasticsearchBlock: BlockConfig = { 'elasticsearch_delete_document', ], }, + dependsOn: ['operation'], }, // Optional Document ID - for index document @@ -167,6 +173,7 @@ export const ElasticsearchBlock: BlockConfig = { type: 'short-input', placeholder: 'Leave empty for auto-generated ID', condition: { field: 'operation', value: 'elasticsearch_index_document' }, + dependsOn: ['operation'], }, // Document body - for index @@ -177,6 +184,7 @@ export const ElasticsearchBlock: BlockConfig = { placeholder: '{ "field": "value", "another_field": 123 }', required: true, condition: { field: 'operation', value: 'elasticsearch_index_document' }, + dependsOn: ['operation'], wandConfig: { enabled: true, prompt: `Generate an Elasticsearch document JSON object based on the user's description. @@ -197,6 +205,7 @@ Return ONLY valid JSON - no explanations, no markdown code blocks.`, placeholder: '{ "field_to_update": "new_value" }', required: true, condition: { field: 'operation', value: 'elasticsearch_update_document' }, + dependsOn: ['operation'], wandConfig: { enabled: true, prompt: `Generate an Elasticsearch partial document JSON for updating based on the user's description. @@ -215,6 +224,7 @@ Return ONLY valid JSON - no explanations, no markdown code blocks.`, type: 'code', placeholder: '{ "match": { "field": "search term" } }', condition: { field: 'operation', value: 'elasticsearch_search' }, + dependsOn: ['operation'], wandConfig: { enabled: true, prompt: `Generate an Elasticsearch query DSL JSON based on the user's description. @@ -237,6 +247,7 @@ Return ONLY valid JSON - no explanations, no markdown code blocks.`, type: 'code', placeholder: '{ "match": { "field": "value" } }', condition: { field: 'operation', value: 'elasticsearch_count' }, + dependsOn: ['operation'], wandConfig: { enabled: true, prompt: `Generate an Elasticsearch query DSL JSON for counting documents based on the user's description. diff --git a/apps/sim/blocks/blocks/gmail.ts b/apps/sim/blocks/blocks/gmail.ts index df5fa8f67e9..4385e909521 100644 --- a/apps/sim/blocks/blocks/gmail.ts +++ b/apps/sim/blocks/blocks/gmail.ts @@ -251,6 +251,7 @@ Return ONLY the email body - no explanations, no extra text.`, type: 'short-input', canonicalParamId: 'folder', placeholder: 'Enter Gmail label name (e.g., INBOX, SENT, or custom label)', + dependsOn: ['credential'], mode: 'advanced', condition: { field: 'operation', value: 'read_gmail' }, }, @@ -333,6 +334,7 @@ Return ONLY the search query - no explanations, no extra text.`, type: 'short-input', canonicalParamId: 'addLabelIds', placeholder: 'Enter label ID (e.g., INBOX, Label_123)', + dependsOn: ['credential'], mode: 'advanced', condition: { field: 'operation', value: 'move_gmail' }, required: true, @@ -359,6 +361,7 @@ Return ONLY the search query - no explanations, no extra text.`, type: 'short-input', canonicalParamId: 'removeLabelIds', placeholder: 'Enter label ID to remove (e.g., INBOX)', + dependsOn: ['credential'], mode: 'advanced', condition: { field: 'operation', value: 'move_gmail' }, required: false, @@ -412,6 +415,7 @@ Return ONLY the search query - no explanations, no extra text.`, type: 'short-input', canonicalParamId: 'manageLabelId', placeholder: 'Enter label ID (e.g., INBOX, Label_123)', + dependsOn: ['credential'], mode: 'advanced', condition: { field: 'operation', value: ['add_label_gmail', 'remove_label_gmail'] }, required: true, diff --git a/apps/sim/blocks/blocks/google_calendar.ts b/apps/sim/blocks/blocks/google_calendar.ts index 08ec3faa9d2..307d3fe21a6 100644 --- a/apps/sim/blocks/blocks/google_calendar.ts +++ b/apps/sim/blocks/blocks/google_calendar.ts @@ -81,6 +81,7 @@ export const GoogleCalendarBlock: BlockConfig = { type: 'short-input', canonicalParamId: 'calendarId', placeholder: 'Enter calendar ID (e.g., primary or calendar@gmail.com)', + dependsOn: ['credential'], mode: 'advanced', condition: { field: 'operation', value: 'list_calendars', not: true }, }, @@ -347,6 +348,7 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`, type: 'short-input', canonicalParamId: 'destinationCalendarId', placeholder: 'destination@group.calendar.google.com', + dependsOn: ['credential'], condition: { field: 'operation', value: 'move' }, required: true, mode: 'advanced', diff --git a/apps/sim/blocks/blocks/google_maps.ts b/apps/sim/blocks/blocks/google_maps.ts index 24676cb10ff..7331d45f28d 100644 --- a/apps/sim/blocks/blocks/google_maps.ts +++ b/apps/sim/blocks/blocks/google_maps.ts @@ -411,7 +411,7 @@ export const GoogleMapsBlock: BlockConfig = { config: { tool: (params) => `google_maps_${params.operation}`, params: (params) => { - const { operation, locationBias, ...rest } = params + const { operation, locationBias, addressToValidate, ...rest } = params let location: { lat: number; lng: number } | undefined if (locationBias && typeof locationBias === 'string' && locationBias.includes(',')) { @@ -486,7 +486,7 @@ export const GoogleMapsBlock: BlockConfig = { } } - const address = params.addressToValidate || params.address + const address = operation === 'validate_address' ? addressToValidate : params.address // Parse boolean switches (can come as string or boolean from form) let interpolate: boolean | undefined diff --git a/apps/sim/blocks/blocks/google_sheets.ts b/apps/sim/blocks/blocks/google_sheets.ts index b2258b06c8b..ef61d864445 100644 --- a/apps/sim/blocks/blocks/google_sheets.ts +++ b/apps/sim/blocks/blocks/google_sheets.ts @@ -401,7 +401,7 @@ export const GoogleSheetsV2Block: BlockConfig = { canonicalParamId: 'sheetName', placeholder: 'Name of the sheet/tab (e.g., Sheet1)', required: true, - dependsOn: ['credential'], + dependsOn: { all: ['credential'], any: ['spreadsheetId', 'manualSpreadsheetId'] }, mode: 'advanced', condition: { field: 'operation', value: ['read', 'write', 'update', 'append', 'clear'] }, }, diff --git a/apps/sim/blocks/blocks/guardrails.ts b/apps/sim/blocks/blocks/guardrails.ts index 5eeacd9a638..7f1c08b831f 100644 --- a/apps/sim/blocks/blocks/guardrails.ts +++ b/apps/sim/blocks/blocks/guardrails.ts @@ -70,6 +70,7 @@ export const GuardrailsBlock: BlockConfig = { field: 'validationType', value: ['regex'], }, + dependsOn: ['validationType'], wandConfig: { enabled: true, prompt: `Generate a regular expression pattern based on the user's description. @@ -106,6 +107,7 @@ Return ONLY the regex pattern - no explanations, no quotes, no forward slashes, field: 'validationType', value: ['hallucination'], }, + dependsOn: ['validationType'], }, { id: 'model', @@ -118,6 +120,7 @@ Return ONLY the regex pattern - no explanations, no quotes, no forward slashes, field: 'validationType', value: ['hallucination'], }, + dependsOn: ['validationType'], }, { id: 'threshold', @@ -131,6 +134,7 @@ Return ONLY the regex pattern - no explanations, no quotes, no forward slashes, field: 'validationType', value: ['hallucination'], }, + dependsOn: ['validationType'], }, { id: 'topK', @@ -145,6 +149,7 @@ Return ONLY the regex pattern - no explanations, no quotes, no forward slashes, field: 'validationType', value: ['hallucination'], }, + dependsOn: ['validationType'], }, // Provider credential subblocks - only shown for hallucination validation ...getProviderCredentialSubBlocks().map((subBlock) => ({ @@ -158,6 +163,7 @@ Return ONLY the regex pattern - no explanations, no quotes, no forward slashes, typeof subBlock.condition === 'function' ? subBlock.condition() : subBlock.condition, } : { field: 'validationType' as const, value: ['hallucination'] }, + dependsOn: ['validationType'], })), { id: 'piiEntityTypes', @@ -227,6 +233,7 @@ Return ONLY the regex pattern - no explanations, no quotes, no forward slashes, field: 'validationType', value: ['pii'], }, + dependsOn: ['validationType'], }, { id: 'piiMode', @@ -242,6 +249,7 @@ Return ONLY the regex pattern - no explanations, no quotes, no forward slashes, field: 'validationType', value: ['pii'], }, + dependsOn: ['validationType'], }, { id: 'piiLanguage', @@ -259,6 +267,7 @@ Return ONLY the regex pattern - no explanations, no quotes, no forward slashes, field: 'validationType', value: ['pii'], }, + dependsOn: ['validationType'], }, ], tools: { diff --git a/apps/sim/blocks/blocks/huggingface.ts b/apps/sim/blocks/blocks/huggingface.ts index 9333d0d5902..2e072886a10 100644 --- a/apps/sim/blocks/blocks/huggingface.ts +++ b/apps/sim/blocks/blocks/huggingface.ts @@ -61,6 +61,7 @@ export const HuggingFaceBlock: BlockConfig = { placeholder: 'e.g., deepseek/deepseek-v3-0324, llama3.1-8b, meta-llama/Llama-3.2-3B-Instruct-Turbo', description: 'The model must be available for the selected provider.', + dependsOn: ['provider'], }, { id: 'temperature', diff --git a/apps/sim/blocks/blocks/image_generator.ts b/apps/sim/blocks/blocks/image_generator.ts index 517e25bf7a7..6963cd604fd 100644 --- a/apps/sim/blocks/blocks/image_generator.ts +++ b/apps/sim/blocks/blocks/image_generator.ts @@ -44,6 +44,7 @@ export const ImageGeneratorBlock: BlockConfig = { ], value: () => '1024x1024', condition: { field: 'model', value: 'dall-e-3' }, + dependsOn: ['model'], }, { id: 'size', @@ -57,6 +58,7 @@ export const ImageGeneratorBlock: BlockConfig = { ], value: () => 'auto', condition: { field: 'model', value: 'gpt-image-1' }, + dependsOn: ['model'], }, { id: 'quality', @@ -68,6 +70,7 @@ export const ImageGeneratorBlock: BlockConfig = { ], value: () => 'standard', condition: { field: 'model', value: 'dall-e-3' }, + dependsOn: ['model'], }, { id: 'style', @@ -79,6 +82,7 @@ export const ImageGeneratorBlock: BlockConfig = { ], value: () => 'vivid', condition: { field: 'model', value: 'dall-e-3' }, + dependsOn: ['model'], }, { id: 'background', @@ -91,6 +95,7 @@ export const ImageGeneratorBlock: BlockConfig = { ], value: () => 'auto', condition: { field: 'model', value: 'gpt-image-1' }, + dependsOn: ['model'], }, { id: 'apiKey', @@ -114,22 +119,23 @@ export const ImageGeneratorBlock: BlockConfig = { throw new Error('Prompt is required') } - // Base parameters for all models + const model = params.model || 'dall-e-3' + const size = params.size || (model === 'gpt-image-1' ? 'auto' : '1024x1024') const baseParams = { prompt: params.prompt, - model: params.model || 'dall-e-3', - size: params.size || '1024x1024', + model, + size, apiKey: params.apiKey, } - if (params.model === 'dall-e-3') { + if (model === 'dall-e-3') { return { ...baseParams, quality: params.quality || 'standard', style: params.style || 'vivid', } } - if (params.model === 'gpt-image-1') { + if (model === 'gpt-image-1') { return { ...baseParams, ...(params.background && { background: params.background }), diff --git a/apps/sim/blocks/blocks/jira.ts b/apps/sim/blocks/blocks/jira.ts index de5c671adbc..f5fd53cf39e 100644 --- a/apps/sim/blocks/blocks/jira.ts +++ b/apps/sim/blocks/blocks/jira.ts @@ -168,7 +168,7 @@ export const JiraBlock: BlockConfig = { type: 'short-input', canonicalParamId: 'issueKey', placeholder: 'Enter Jira issue key', - dependsOn: ['credential', 'domain'], + dependsOn: ['credential', 'domain', 'projectId'], condition: { field: 'operation', value: [ diff --git a/apps/sim/blocks/blocks/jira_service_management.ts b/apps/sim/blocks/blocks/jira_service_management.ts index 342cccc0770..9e3952b7837 100644 --- a/apps/sim/blocks/blocks/jira_service_management.ts +++ b/apps/sim/blocks/blocks/jira_service_management.ts @@ -132,6 +132,7 @@ export const JiraServiceManagementBlock: BlockConfig = { type: 'short-input', canonicalParamId: 'serviceDeskId', placeholder: 'Enter service desk ID', + dependsOn: ['credential', 'domain'], mode: 'advanced', required: { field: 'operation', @@ -181,6 +182,7 @@ export const JiraServiceManagementBlock: BlockConfig = { canonicalParamId: 'requestTypeId', required: true, placeholder: 'Enter request type ID', + dependsOn: ['credential', 'domain', 'serviceDeskId'], mode: 'advanced', condition: { field: 'operation', value: ['create_request', 'get_request_type_fields'] }, }, diff --git a/apps/sim/blocks/blocks/knowledge.ts b/apps/sim/blocks/blocks/knowledge.ts index 37c0d5b2914..3d17e9cb402 100644 --- a/apps/sim/blocks/blocks/knowledge.ts +++ b/apps/sim/blocks/blocks/knowledge.ts @@ -171,6 +171,7 @@ export const KnowledgeBlock: BlockConfig = { type: 'short-input', canonicalParamId: 'documentId', placeholder: 'Enter document ID', + dependsOn: ['knowledgeBaseId'], required: true, mode: 'advanced', condition: { diff --git a/apps/sim/blocks/blocks/linear.ts b/apps/sim/blocks/blocks/linear.ts index d8aa7bb493d..eaa1ef39a6f 100644 --- a/apps/sim/blocks/blocks/linear.ts +++ b/apps/sim/blocks/blocks/linear.ts @@ -197,6 +197,7 @@ export const LinearBlock: BlockConfig = { canonicalParamId: 'teamId', placeholder: 'Enter Linear team ID', mode: 'advanced', + dependsOn: ['credential'], required: { field: 'operation', value: [ @@ -271,6 +272,7 @@ export const LinearBlock: BlockConfig = { canonicalParamId: 'projectId', placeholder: 'Enter Linear project ID', mode: 'advanced', + dependsOn: ['credential', 'teamId'], required: { field: 'operation', value: [ @@ -507,6 +509,7 @@ Return ONLY the comment text - no explanations.`, field: 'operation', value: ['linear_create_issue', 'linear_update_issue', 'linear_create_project'], }, + dependsOn: ['operation'], }, // Estimate (for issues) { @@ -1052,6 +1055,7 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n field: 'operation', value: ['linear_create_customer_request', 'linear_update_customer_request'], }, + dependsOn: ['operation'], }, // Customer request ID (for updating) { diff --git a/apps/sim/blocks/blocks/mcp.ts b/apps/sim/blocks/blocks/mcp.ts index 0b5d4da8db6..3a0e51caeae 100644 --- a/apps/sim/blocks/blocks/mcp.ts +++ b/apps/sim/blocks/blocks/mcp.ts @@ -53,6 +53,7 @@ export const McpBlock: BlockConfig = { value: '', not: true, // Show when tool is not empty }, + dependsOn: ['tool'], }, ], tools: { diff --git a/apps/sim/blocks/blocks/microsoft_teams.ts b/apps/sim/blocks/blocks/microsoft_teams.ts index b2a882e489c..0812169a24d 100644 --- a/apps/sim/blocks/blocks/microsoft_teams.ts +++ b/apps/sim/blocks/blocks/microsoft_teams.ts @@ -94,6 +94,7 @@ export const MicrosoftTeamsBlock: BlockConfig = { type: 'short-input', canonicalParamId: 'teamId', placeholder: 'Enter team ID', + dependsOn: ['credential'], mode: 'advanced', condition: { field: 'operation', @@ -132,6 +133,7 @@ export const MicrosoftTeamsBlock: BlockConfig = { type: 'short-input', canonicalParamId: 'chatId', placeholder: 'Enter chat ID', + dependsOn: ['credential'], mode: 'advanced', condition: { field: 'operation', @@ -169,6 +171,7 @@ export const MicrosoftTeamsBlock: BlockConfig = { type: 'short-input', canonicalParamId: 'channelId', placeholder: 'Enter channel ID', + dependsOn: ['credential', 'teamId'], mode: 'advanced', condition: { field: 'operation', diff --git a/apps/sim/blocks/blocks/monday.ts b/apps/sim/blocks/blocks/monday.ts index 7f566c6181b..818e78a1449 100644 --- a/apps/sim/blocks/blocks/monday.ts +++ b/apps/sim/blocks/blocks/monday.ts @@ -128,6 +128,7 @@ export const MondayBlock: BlockConfig = { type: 'short-input', canonicalParamId: 'boardId', placeholder: 'Enter board ID', + dependsOn: ['credential'], mode: 'advanced', condition: { field: 'operation', value: BOARD_OPS }, required: { field: 'operation', value: BOARD_OPS }, @@ -180,6 +181,7 @@ export const MondayBlock: BlockConfig = { type: 'short-input', canonicalParamId: 'groupId', placeholder: 'Enter group ID', + dependsOn: ['credential', 'boardId'], mode: 'advanced', condition: { field: 'operation', diff --git a/apps/sim/blocks/blocks/notion.ts b/apps/sim/blocks/blocks/notion.ts index 5afb6eeeda1..39dfb82b730 100644 --- a/apps/sim/blocks/blocks/notion.ts +++ b/apps/sim/blocks/blocks/notion.ts @@ -79,6 +79,7 @@ export const NotionBlock: BlockConfig = { type: 'short-input', canonicalParamId: 'pageId', placeholder: 'Enter Notion page ID', + dependsOn: ['credential'], mode: 'advanced', condition: { field: 'operation', @@ -108,6 +109,7 @@ export const NotionBlock: BlockConfig = { type: 'short-input', canonicalParamId: 'databaseId', placeholder: 'Enter Notion database ID', + dependsOn: ['credential'], mode: 'advanced', condition: { field: 'operation', @@ -134,6 +136,7 @@ export const NotionBlock: BlockConfig = { type: 'short-input', canonicalParamId: 'parentId', placeholder: 'ID of parent page', + dependsOn: ['credential'], mode: 'advanced', condition: { field: 'operation', value: ['notion_create_page', 'notion_create_database'] }, required: true, diff --git a/apps/sim/blocks/blocks/outlook.ts b/apps/sim/blocks/blocks/outlook.ts index 28b0fadf7e6..50d7179931d 100644 --- a/apps/sim/blocks/blocks/outlook.ts +++ b/apps/sim/blocks/blocks/outlook.ts @@ -186,6 +186,7 @@ export const OutlookBlock: BlockConfig = { type: 'short-input', canonicalParamId: 'folder', placeholder: 'Enter Outlook folder name (e.g., INBOX, SENT, or custom folder)', + dependsOn: ['credential'], mode: 'advanced', condition: { field: 'operation', value: 'read_outlook' }, }, @@ -233,6 +234,7 @@ export const OutlookBlock: BlockConfig = { type: 'short-input', canonicalParamId: 'destinationId', placeholder: 'Enter folder ID', + dependsOn: ['credential'], mode: 'advanced', condition: { field: 'operation', value: 'move_outlook' }, required: true, @@ -280,6 +282,7 @@ export const OutlookBlock: BlockConfig = { type: 'short-input', canonicalParamId: 'copyDestinationId', placeholder: 'Enter folder ID', + dependsOn: ['credential'], mode: 'advanced', condition: { field: 'operation', value: 'copy_outlook' }, required: true, diff --git a/apps/sim/blocks/blocks/sftp.ts b/apps/sim/blocks/blocks/sftp.ts index 18b3bd43f11..7a07bce06d9 100644 --- a/apps/sim/blocks/blocks/sftp.ts +++ b/apps/sim/blocks/blocks/sftp.ts @@ -74,6 +74,7 @@ export const SftpBlock: BlockConfig = { password: true, placeholder: 'Your SFTP password', condition: { field: 'authMethod', value: 'password' }, + dependsOn: ['authMethod'], }, { @@ -82,6 +83,7 @@ export const SftpBlock: BlockConfig = { type: 'code', placeholder: '-----BEGIN OPENSSH PRIVATE KEY-----\n...', condition: { field: 'authMethod', value: 'privateKey' }, + dependsOn: ['authMethod'], }, { id: 'passphrase', @@ -90,6 +92,7 @@ export const SftpBlock: BlockConfig = { password: true, placeholder: 'Passphrase for encrypted key (optional)', condition: { field: 'authMethod', value: 'privateKey' }, + dependsOn: ['authMethod'], }, { diff --git a/apps/sim/blocks/blocks/slack.ts b/apps/sim/blocks/blocks/slack.ts index c303faa1c5a..bf503451921 100644 --- a/apps/sim/blocks/blocks/slack.ts +++ b/apps/sim/blocks/blocks/slack.ts @@ -179,6 +179,7 @@ export const SlackBlock: BlockConfig = { type: 'short-input', canonicalParamId: 'channel', placeholder: 'Enter Slack channel ID (e.g., C1234567890)', + dependsOn: { all: ['authMethod'], any: ['credential', 'botToken'] }, mode: 'advanced', condition: (values?: Record) => { const op = values?.operation as string @@ -238,6 +239,7 @@ export const SlackBlock: BlockConfig = { type: 'short-input', canonicalParamId: 'dmUserId', placeholder: 'Enter Slack user ID (e.g., U1234567890)', + dependsOn: { all: ['authMethod'], any: ['credential', 'botToken'] }, mode: 'advanced', condition: { field: 'destinationType', @@ -267,6 +269,7 @@ export const SlackBlock: BlockConfig = { type: 'short-input', canonicalParamId: 'ephemeralUser', placeholder: 'Enter Slack user ID (e.g., U1234567890)', + dependsOn: { all: ['authMethod'], any: ['credential', 'botToken'] }, mode: 'advanced', condition: { field: 'operation', @@ -529,6 +532,7 @@ Do not include any explanations, markdown formatting, or other text outside the type: 'short-input', canonicalParamId: 'userId', placeholder: 'Enter Slack user ID (e.g., U1234567890)', + dependsOn: { all: ['authMethod'], any: ['credential', 'botToken'] }, mode: 'advanced', condition: { field: 'operation', @@ -748,6 +752,7 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`, type: 'short-input', canonicalParamId: 'presenceUserId', placeholder: 'Enter Slack user ID (e.g., U1234567890)', + dependsOn: { all: ['authMethod'], any: ['credential', 'botToken'] }, mode: 'advanced', condition: { field: 'operation', @@ -1108,6 +1113,7 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`, type: 'short-input', canonicalParamId: 'publishUserId', placeholder: 'Enter Slack user ID (e.g., U0BPQUNTA)', + dependsOn: { all: ['authMethod'], any: ['credential', 'botToken'] }, mode: 'advanced', condition: { field: 'operation', diff --git a/apps/sim/blocks/blocks/ssh.ts b/apps/sim/blocks/blocks/ssh.ts index 6e80f4a88ca..23a8753e08c 100644 --- a/apps/sim/blocks/blocks/ssh.ts +++ b/apps/sim/blocks/blocks/ssh.ts @@ -83,6 +83,7 @@ export const SSHBlock: BlockConfig = { password: true, placeholder: 'Your SSH password', condition: { field: 'authMethod', value: 'password' }, + dependsOn: ['authMethod'], }, // Private key authentication @@ -92,6 +93,7 @@ export const SSHBlock: BlockConfig = { type: 'code', placeholder: '-----BEGIN OPENSSH PRIVATE KEY-----\n...', condition: { field: 'authMethod', value: 'privateKey' }, + dependsOn: ['authMethod'], }, { id: 'passphrase', @@ -100,6 +102,7 @@ export const SSHBlock: BlockConfig = { password: true, placeholder: 'Passphrase for encrypted key (optional)', condition: { field: 'authMethod', value: 'privateKey' }, + dependsOn: ['authMethod'], }, // EXECUTE COMMAND diff --git a/apps/sim/blocks/blocks/stagehand.ts b/apps/sim/blocks/blocks/stagehand.ts index 6c7b0c11e3a..998da6177ba 100644 --- a/apps/sim/blocks/blocks/stagehand.ts +++ b/apps/sim/blocks/blocks/stagehand.ts @@ -351,6 +351,7 @@ Example 3 (Data Collection): type: 'short-input', placeholder: 'Enter your API key for the selected provider', password: true, + dependsOn: ['provider'], required: true, }, ], @@ -361,17 +362,34 @@ Example 3 (Data Collection): return params.operation === 'agent' ? 'stagehand_agent' : 'stagehand_extract' }, params: (params) => { - const next: Record = { ...params } - if (typeof next.maxSteps === 'string') { - const trimmed = next.maxSteps.trim() - if (trimmed === '') { - next.maxSteps = undefined - } else { - const n = Number(trimmed) - next.maxSteps = Number.isFinite(n) ? n : undefined + const baseParams = { + operation: params.operation, + provider: params.provider, + apiKey: params.apiKey, + } + + if (params.operation !== 'agent') { + return { + ...baseParams, + url: params.url, + instruction: params.instruction, + schema: params.schema, } } - return next + + const maxStepsInput = + typeof params.maxSteps === 'string' ? params.maxSteps.trim() : params.maxSteps + const maxSteps = maxStepsInput === '' ? Number.NaN : Number(maxStepsInput) + + return { + ...baseParams, + startUrl: params.startUrl, + task: params.task, + variables: params.variables, + outputSchema: params.outputSchema, + mode: params.mode, + maxSteps: Number.isFinite(maxSteps) ? maxSteps : undefined, + } }, }, }, diff --git a/apps/sim/blocks/blocks/stt.ts b/apps/sim/blocks/blocks/stt.ts index 1f6a3820fcd..9ad540b1d3d 100644 --- a/apps/sim/blocks/blocks/stt.ts +++ b/apps/sim/blocks/blocks/stt.ts @@ -43,6 +43,7 @@ export const SttBlock: BlockConfig = { condition: { field: 'provider', value: 'whisper' }, options: [{ label: 'Whisper-1', id: 'whisper-1' }], value: () => 'whisper-1', + dependsOn: ['provider'], required: true, }, @@ -52,11 +53,9 @@ export const SttBlock: BlockConfig = { title: 'Model', type: 'dropdown', condition: { field: 'provider', value: 'elevenlabs' }, - options: [ - { label: 'Scribe v1', id: 'scribe_v1' }, - { label: 'Scribe v1 Experimental', id: 'scribe_v1_experimental' }, - ], - value: () => 'scribe_v1', + options: [{ label: 'Scribe v2', id: 'scribe_v2' }], + value: () => 'scribe_v2', + dependsOn: ['provider'], required: true, }, @@ -75,6 +74,7 @@ export const SttBlock: BlockConfig = { { label: 'Base', id: 'base' }, ], value: () => 'nova-3', + dependsOn: ['provider'], required: true, }, @@ -86,6 +86,7 @@ export const SttBlock: BlockConfig = { condition: { field: 'provider', value: 'assemblyai' }, options: [{ label: 'Best', id: 'best' }], value: () => 'best', + dependsOn: ['provider'], required: true, }, @@ -104,6 +105,7 @@ export const SttBlock: BlockConfig = { { label: 'Gemini 2.0 Flash', id: 'gemini-2.0-flash-exp' }, ], value: () => 'gemini-2.5-flash', + dependsOn: ['provider'], required: true, }, @@ -295,7 +297,7 @@ export const SttBlock: BlockConfig = { model: { type: 'string', description: - 'Provider-specific model (e.g., scribe_v1 for ElevenLabs, nova-3 for Deepgram, best for AssemblyAI, gemini-2.0-flash-exp for Gemini)', + 'Provider-specific model (e.g., scribe_v2 for ElevenLabs, nova-3 for Deepgram, best for AssemblyAI, gemini-2.0-flash-exp for Gemini)', }, audioFile: { type: 'json', description: 'Audio/video file (UserFile)' }, audioUrl: { type: 'string', description: 'Audio/video URL' }, diff --git a/apps/sim/blocks/blocks/table.ts b/apps/sim/blocks/blocks/table.ts index e75d1731675..a740bb5b872 100644 --- a/apps/sim/blocks/blocks/table.ts +++ b/apps/sim/blocks/blocks/table.ts @@ -230,6 +230,7 @@ export const TableBlock: BlockConfig = { title: 'Row ID', type: 'short-input', placeholder: 'row_xxxxx', + dependsOn: ['tableId'], condition: { field: 'operation', value: ['get_row', 'update_row', 'delete_row'] }, required: true, }, diff --git a/apps/sim/blocks/blocks/trello.ts b/apps/sim/blocks/blocks/trello.ts index 27465ac6ae7..3d1607d4230 100644 --- a/apps/sim/blocks/blocks/trello.ts +++ b/apps/sim/blocks/blocks/trello.ts @@ -125,6 +125,7 @@ export const TrelloBlock: BlockConfig = { type: 'short-input', canonicalParamId: 'boardId', placeholder: 'Enter Trello board ID', + dependsOn: ['credential'], mode: 'advanced', condition: { field: 'operation', diff --git a/apps/sim/blocks/blocks/tts.ts b/apps/sim/blocks/blocks/tts.ts index c6fea970e79..62d050b0c91 100644 --- a/apps/sim/blocks/blocks/tts.ts +++ b/apps/sim/blocks/blocks/tts.ts @@ -56,6 +56,7 @@ export const TtsBlock: BlockConfig = { { label: 'GPT-4o Mini TTS', id: 'gpt-4o-mini-tts' }, ], value: () => 'tts-1', + dependsOn: ['provider'], required: false, }, @@ -78,6 +79,7 @@ export const TtsBlock: BlockConfig = { { label: 'Verse', id: 'verse' }, ], value: () => 'alloy', + dependsOn: ['provider'], required: false, }, @@ -95,6 +97,7 @@ export const TtsBlock: BlockConfig = { { label: 'WAV', id: 'wav' }, ], value: () => 'mp3', + dependsOn: ['provider'], required: false, }, @@ -108,6 +111,7 @@ export const TtsBlock: BlockConfig = { max: 4.0, step: 0.25, value: () => '1.0', + dependsOn: ['provider'], required: false, }, @@ -132,6 +136,7 @@ export const TtsBlock: BlockConfig = { { label: 'Zeus', id: 'aura-zeus-en' }, ], value: () => 'aura-asteria-en', + dependsOn: ['provider'], required: true, }, @@ -149,6 +154,7 @@ export const TtsBlock: BlockConfig = { { label: 'Linear16', id: 'linear16' }, ], value: () => 'mp3', + dependsOn: ['provider'], required: false, }, @@ -169,6 +175,7 @@ export const TtsBlock: BlockConfig = { { label: '48000 Hz', id: '48000' }, ], value: () => '24000', + dependsOn: ['encoding'], required: false, }, @@ -179,6 +186,7 @@ export const TtsBlock: BlockConfig = { type: 'short-input', condition: { field: 'provider', value: 'elevenlabs' }, placeholder: 'Enter ElevenLabs voice ID', + dependsOn: ['provider'], required: true, }, @@ -197,6 +205,7 @@ export const TtsBlock: BlockConfig = { { label: 'Multilingual v1', id: 'eleven_multilingual_v1' }, ], value: () => 'eleven_turbo_v2_5', + dependsOn: ['provider'], required: false, }, @@ -210,6 +219,7 @@ export const TtsBlock: BlockConfig = { max: 1.0, step: 0.05, value: () => '0.5', + dependsOn: ['provider'], required: false, }, @@ -223,6 +233,7 @@ export const TtsBlock: BlockConfig = { max: 1.0, step: 0.05, value: () => '0.8', + dependsOn: ['provider'], required: false, }, @@ -236,6 +247,7 @@ export const TtsBlock: BlockConfig = { max: 1.0, step: 0.05, value: () => '0.0', + dependsOn: ['provider'], required: false, }, @@ -253,6 +265,7 @@ export const TtsBlock: BlockConfig = { { label: 'Sonic Multilingual', id: 'sonic-multilingual' }, ], value: () => 'sonic-3', + dependsOn: ['provider'], required: false, }, @@ -263,6 +276,7 @@ export const TtsBlock: BlockConfig = { type: 'short-input', condition: { field: 'provider', value: 'cartesia' }, placeholder: 'Enter Cartesia voice ID', + dependsOn: ['provider'], required: true, }, @@ -276,6 +290,7 @@ export const TtsBlock: BlockConfig = { max: 2.0, step: 0.1, value: () => '1.0', + dependsOn: ['provider'], required: false, }, @@ -286,6 +301,7 @@ export const TtsBlock: BlockConfig = { type: 'short-input', condition: { field: 'provider', value: 'google' }, placeholder: 'e.g., en-US-Neural2-A', + dependsOn: ['provider'], required: false, }, @@ -297,6 +313,7 @@ export const TtsBlock: BlockConfig = { condition: { field: 'provider', value: 'google' }, placeholder: 'e.g., en-US, es-ES', value: () => 'en-US', + dependsOn: ['provider'], required: true, }, @@ -310,6 +327,7 @@ export const TtsBlock: BlockConfig = { max: 2.0, step: 0.25, value: () => '1.0', + dependsOn: ['provider'], required: false, }, @@ -323,6 +341,7 @@ export const TtsBlock: BlockConfig = { max: 20.0, step: 1.0, value: () => '0.0', + dependsOn: ['provider'], required: false, }, @@ -333,6 +352,7 @@ export const TtsBlock: BlockConfig = { type: 'short-input', condition: { field: 'provider', value: 'azure' }, placeholder: 'e.g., en-US-JennyNeural', + dependsOn: ['provider'], required: false, }, @@ -343,6 +363,7 @@ export const TtsBlock: BlockConfig = { type: 'short-input', condition: { field: 'provider', value: 'azure' }, placeholder: 'e.g., eastus, westus', + dependsOn: ['provider'], required: false, }, @@ -358,6 +379,7 @@ export const TtsBlock: BlockConfig = { { label: 'MP3 48kHz 96kbps', id: 'audio-48khz-96kbitrate-mono-mp3' }, ], value: () => 'audio-24khz-96kbitrate-mono-mp3', + dependsOn: ['provider'], required: false, }, @@ -368,6 +390,7 @@ export const TtsBlock: BlockConfig = { type: 'short-input', condition: { field: 'provider', value: 'azure' }, placeholder: 'e.g., cheerful, sad, angry', + dependsOn: ['provider'], required: false, }, @@ -379,6 +402,7 @@ export const TtsBlock: BlockConfig = { condition: { field: 'provider', value: 'playht' }, placeholder: 'Enter your PlayHT user ID', password: true, + dependsOn: ['provider'], required: true, }, @@ -389,6 +413,7 @@ export const TtsBlock: BlockConfig = { type: 'short-input', condition: { field: 'provider', value: 'playht' }, placeholder: 'Voice ID or manifest URL', + dependsOn: ['provider'], required: false, }, @@ -404,6 +429,7 @@ export const TtsBlock: BlockConfig = { { label: 'Premium', id: 'premium' }, ], value: () => 'standard', + dependsOn: ['provider'], required: false, }, @@ -417,6 +443,7 @@ export const TtsBlock: BlockConfig = { max: 2.0, step: 0.1, value: () => '1.0', + dependsOn: ['provider'], required: false, }, diff --git a/apps/sim/blocks/blocks/video_generator.ts b/apps/sim/blocks/blocks/video_generator.ts index cc7141f3371..eaccc6cde1f 100644 --- a/apps/sim/blocks/blocks/video_generator.ts +++ b/apps/sim/blocks/blocks/video_generator.ts @@ -49,6 +49,7 @@ export const VideoGeneratorBlock: BlockConfig = { { label: 'Veo 3.1', id: 'veo-3.1' }, ], value: () => 'veo-3', + dependsOn: ['provider'], required: false, }, @@ -60,6 +61,7 @@ export const VideoGeneratorBlock: BlockConfig = { condition: { field: 'provider', value: 'luma' }, options: [{ label: 'Ray 2', id: 'ray-2' }], value: () => 'ray-2', + dependsOn: ['provider'], required: false, }, @@ -71,6 +73,7 @@ export const VideoGeneratorBlock: BlockConfig = { condition: { field: 'provider', value: 'minimax' }, options: [{ label: 'Hailuo 2.3', id: 'hailuo-02' }], value: () => 'hailuo-02', + dependsOn: ['provider'], required: false, }, @@ -84,6 +87,7 @@ export const VideoGeneratorBlock: BlockConfig = { { label: 'Standard', id: 'standard' }, ], value: () => 'standard', + dependsOn: ['provider'], required: false, }, @@ -104,6 +108,7 @@ export const VideoGeneratorBlock: BlockConfig = { { label: 'LTXV 0.9.8', id: 'ltxv-0.9.8' }, ], value: () => 'veo-3.1', + dependsOn: ['provider'], required: true, }, @@ -127,6 +132,7 @@ export const VideoGeneratorBlock: BlockConfig = { { label: '10', id: '10' }, ], value: () => '5', + dependsOn: ['provider'], required: false, }, @@ -142,6 +148,7 @@ export const VideoGeneratorBlock: BlockConfig = { { label: '8', id: '8' }, ], value: () => '8', + dependsOn: ['provider'], required: false, }, @@ -156,6 +163,7 @@ export const VideoGeneratorBlock: BlockConfig = { { label: '9', id: '9' }, ], value: () => '5', + dependsOn: ['provider'], required: false, }, @@ -170,6 +178,7 @@ export const VideoGeneratorBlock: BlockConfig = { { label: '10', id: '10' }, ], value: () => '6', + dependsOn: ['provider'], required: false, }, @@ -193,6 +202,7 @@ export const VideoGeneratorBlock: BlockConfig = { { label: '10', id: '10' }, ], value: () => '5', + dependsOn: ['model'], required: false, }, @@ -207,6 +217,7 @@ export const VideoGeneratorBlock: BlockConfig = { { label: '9:16', id: '9:16' }, ], value: () => '16:9', + dependsOn: ['provider'], required: false, }, @@ -222,6 +233,7 @@ export const VideoGeneratorBlock: BlockConfig = { { label: '1:1', id: '1:1' }, ], value: () => '16:9', + dependsOn: ['provider'], required: false, }, @@ -237,6 +249,7 @@ export const VideoGeneratorBlock: BlockConfig = { { label: '1:1', id: '1:1' }, ], value: () => '16:9', + dependsOn: ['provider'], required: false, }, @@ -259,6 +272,7 @@ export const VideoGeneratorBlock: BlockConfig = { { label: '9:16', id: '9:16' }, ], value: () => '16:9', + dependsOn: ['model'], required: false, }, @@ -277,6 +291,7 @@ export const VideoGeneratorBlock: BlockConfig = { { label: '1080p', id: '1080p' }, ], value: () => '1080p', + dependsOn: ['provider'], required: false, }, @@ -292,6 +307,7 @@ export const VideoGeneratorBlock: BlockConfig = { { label: '1080p', id: '1080p' }, ], value: () => '1080p', + dependsOn: ['provider'], required: false, }, @@ -306,6 +322,7 @@ export const VideoGeneratorBlock: BlockConfig = { placeholder: 'Upload reference image', mode: 'basic', multiple: false, + dependsOn: ['provider'], required: true, acceptedTypes: '.jpg,.jpeg,.png,.webp', }, @@ -317,6 +334,7 @@ export const VideoGeneratorBlock: BlockConfig = { type: 'long-input', condition: { field: 'provider', value: 'luma' }, placeholder: 'JSON: [{ "key": "pan_right" }, { "key": "zoom_in" }]', + dependsOn: ['provider'], required: false, }, @@ -326,6 +344,7 @@ export const VideoGeneratorBlock: BlockConfig = { title: 'Prompt Optimizer', type: 'switch', condition: { field: 'provider', value: 'minimax' }, + dependsOn: ['provider'], }, // API Key @@ -463,6 +482,7 @@ export const VideoGeneratorV2Block: BlockConfig = { { label: 'Veo 3.1', id: 'veo-3.1' }, ], value: () => 'veo-3', + dependsOn: ['provider'], required: false, }, { @@ -472,6 +492,7 @@ export const VideoGeneratorV2Block: BlockConfig = { condition: { field: 'provider', value: 'luma' }, options: [{ label: 'Ray 2', id: 'ray-2' }], value: () => 'ray-2', + dependsOn: ['provider'], required: false, }, { @@ -481,6 +502,7 @@ export const VideoGeneratorV2Block: BlockConfig = { condition: { field: 'provider', value: 'minimax' }, options: [{ label: 'Hailuo 2.3', id: 'hailuo-02' }], value: () => 'hailuo-02', + dependsOn: ['provider'], required: false, }, { @@ -493,6 +515,7 @@ export const VideoGeneratorV2Block: BlockConfig = { { label: 'Standard', id: 'standard' }, ], value: () => 'standard', + dependsOn: ['provider'], required: false, }, { @@ -511,6 +534,7 @@ export const VideoGeneratorV2Block: BlockConfig = { { label: 'LTXV 0.9.8', id: 'ltxv-0.9.8' }, ], value: () => 'veo-3.1', + dependsOn: ['provider'], required: true, }, { @@ -530,6 +554,7 @@ export const VideoGeneratorV2Block: BlockConfig = { { label: '10', id: '10' }, ], value: () => '5', + dependsOn: ['provider'], required: false, }, { @@ -543,6 +568,7 @@ export const VideoGeneratorV2Block: BlockConfig = { { label: '8', id: '8' }, ], value: () => '8', + dependsOn: ['provider'], required: false, }, { @@ -555,6 +581,7 @@ export const VideoGeneratorV2Block: BlockConfig = { { label: '9', id: '9' }, ], value: () => '5', + dependsOn: ['provider'], required: false, }, { @@ -567,6 +594,7 @@ export const VideoGeneratorV2Block: BlockConfig = { { label: '10', id: '10' }, ], value: () => '6', + dependsOn: ['provider'], required: false, }, { @@ -588,6 +616,7 @@ export const VideoGeneratorV2Block: BlockConfig = { { label: '10', id: '10' }, ], value: () => '5', + dependsOn: ['model'], required: false, }, { @@ -600,6 +629,7 @@ export const VideoGeneratorV2Block: BlockConfig = { { label: '9:16', id: '9:16' }, ], value: () => '16:9', + dependsOn: ['provider'], required: false, }, { @@ -613,6 +643,7 @@ export const VideoGeneratorV2Block: BlockConfig = { { label: '1:1', id: '1:1' }, ], value: () => '16:9', + dependsOn: ['provider'], required: false, }, { @@ -626,6 +657,7 @@ export const VideoGeneratorV2Block: BlockConfig = { { label: '1:1', id: '1:1' }, ], value: () => '16:9', + dependsOn: ['provider'], required: false, }, { @@ -646,6 +678,7 @@ export const VideoGeneratorV2Block: BlockConfig = { { label: '9:16', id: '9:16' }, ], value: () => '16:9', + dependsOn: ['model'], required: false, }, { @@ -658,6 +691,7 @@ export const VideoGeneratorV2Block: BlockConfig = { { label: '1080p', id: '1080p' }, ], value: () => '1080p', + dependsOn: ['provider'], required: false, }, { @@ -671,6 +705,7 @@ export const VideoGeneratorV2Block: BlockConfig = { { label: '1080p', id: '1080p' }, ], value: () => '1080p', + dependsOn: ['provider'], required: false, }, { @@ -682,6 +717,7 @@ export const VideoGeneratorV2Block: BlockConfig = { placeholder: 'Upload reference image', mode: 'basic', multiple: false, + dependsOn: ['provider'], required: true, acceptedTypes: '.jpg,.jpeg,.png,.webp', }, @@ -693,6 +729,7 @@ export const VideoGeneratorV2Block: BlockConfig = { condition: { field: 'provider', value: 'runway' }, placeholder: 'Reference image from previous blocks', mode: 'advanced', + dependsOn: ['provider'], required: true, }, { @@ -701,6 +738,7 @@ export const VideoGeneratorV2Block: BlockConfig = { type: 'long-input', condition: { field: 'provider', value: 'luma' }, placeholder: 'JSON: [{ "key": "pan_right" }, { "key": "zoom_in" }]', + dependsOn: ['provider'], required: false, }, { @@ -708,6 +746,7 @@ export const VideoGeneratorV2Block: BlockConfig = { title: 'Prompt Optimizer', type: 'switch', condition: { field: 'provider', value: 'minimax' }, + dependsOn: ['provider'], }, { id: 'apiKey', diff --git a/apps/sim/blocks/blocks/wealthbox.ts b/apps/sim/blocks/blocks/wealthbox.ts index abdb86bca24..222d94b5938 100644 --- a/apps/sim/blocks/blocks/wealthbox.ts +++ b/apps/sim/blocks/blocks/wealthbox.ts @@ -69,6 +69,7 @@ export const WealthboxBlock: BlockConfig = { placeholder: 'Enter Contact ID', mode: 'basic', canonicalParamId: 'contactId', + dependsOn: ['credential'], condition: { field: 'operation', value: ['read_contact', 'write_task', 'write_note'] }, }, { @@ -78,6 +79,7 @@ export const WealthboxBlock: BlockConfig = { canonicalParamId: 'contactId', placeholder: 'Enter Contact ID', mode: 'advanced', + dependsOn: ['credential'], condition: { field: 'operation', value: ['read_contact', 'write_task', 'write_note'] }, }, { diff --git a/apps/sim/blocks/blocks/zoom.ts b/apps/sim/blocks/blocks/zoom.ts index c699431a643..93da307012b 100644 --- a/apps/sim/blocks/blocks/zoom.ts +++ b/apps/sim/blocks/blocks/zoom.ts @@ -112,6 +112,7 @@ export const ZoomBlock: BlockConfig = { type: 'short-input', canonicalParamId: 'meetingId', placeholder: 'Enter meeting ID', + dependsOn: ['credential'], mode: 'advanced', required: true, condition: { diff --git a/apps/sim/blocks/utils.test.ts b/apps/sim/blocks/utils.test.ts index b59e0ebd17f..309f5990474 100644 --- a/apps/sim/blocks/utils.test.ts +++ b/apps/sim/blocks/utils.test.ts @@ -66,8 +66,11 @@ vi.mock('@/lib/oauth/utils', () => ({ getScopesForService: vi.fn(() => []), })) +import type { SubBlockConfig } from '@/blocks/types' import { getApiKeyCondition, + getDependsOnFields, + getSubBlocksDependingOnChange, parseOptionalBooleanInput, parseOptionalJsonInput, parseOptionalNumberInput, @@ -359,3 +362,93 @@ describe('parseOptionalBooleanInput', () => { expect(parseOptionalBooleanInput('no')).toBeUndefined() }) }) + +describe('getDependsOnFields', () => { + it('returns an empty array when dependsOn is unset', () => { + expect(getDependsOnFields(undefined)).toEqual([]) + }) + + it('returns array dependencies unchanged', () => { + expect(getDependsOnFields(['credential', 'projectId'])).toEqual(['credential', 'projectId']) + }) + + it('flattens all and any dependencies', () => { + expect(getDependsOnFields({ all: ['credential'], any: ['teamId', 'manualTeamId'] })).toEqual([ + 'credential', + 'teamId', + 'manualTeamId', + ]) + }) +}) + +describe('getSubBlocksDependingOnChange', () => { + it('finds direct dependents of a changed subblock', () => { + const subBlocks: SubBlockConfig[] = [ + { id: 'provider', title: 'Provider', type: 'dropdown' }, + { id: 'model', title: 'Model', type: 'dropdown', dependsOn: ['provider'] }, + { id: 'prompt', title: 'Prompt', type: 'long-input' }, + ] + + expect( + getSubBlocksDependingOnChange(subBlocks, 'provider').map((subBlock) => subBlock.id) + ).toEqual(['model']) + }) + + it('matches dependents through canonical basic and advanced siblings', () => { + const subBlocks: SubBlockConfig[] = [ + { + id: 'channel', + title: 'Channel', + type: 'channel-selector', + canonicalParamId: 'channelId', + mode: 'basic', + }, + { + id: 'manualChannel', + title: 'Channel ID', + type: 'short-input', + canonicalParamId: 'channelId', + mode: 'advanced', + }, + { + id: 'messageId', + title: 'Message ID', + type: 'short-input', + dependsOn: ['channelId'], + }, + { + id: 'threadTs', + title: 'Thread Timestamp', + type: 'short-input', + dependsOn: ['otherField'], + }, + ] + + expect( + getSubBlocksDependingOnChange(subBlocks, 'manualChannel').map((subBlock) => subBlock.id) + ).toEqual(['messageId']) + expect( + getSubBlocksDependingOnChange(subBlocks, 'channel').map((subBlock) => subBlock.id) + ).toEqual(['messageId']) + }) + + it('matches object-form dependencies when any listed dependency changes', () => { + const subBlocks: SubBlockConfig[] = [ + { id: 'credential', title: 'Credential', type: 'oauth-input' }, + { id: 'teamId', title: 'Team', type: 'short-input' }, + { + id: 'projectId', + title: 'Project', + type: 'short-input', + dependsOn: { all: ['credential'], any: ['teamId'] }, + }, + ] + + expect( + getSubBlocksDependingOnChange(subBlocks, 'credential').map((subBlock) => subBlock.id) + ).toEqual(['projectId']) + expect( + getSubBlocksDependingOnChange(subBlocks, 'teamId').map((subBlock) => subBlock.id) + ).toEqual(['projectId']) + }) +}) diff --git a/apps/sim/blocks/utils.ts b/apps/sim/blocks/utils.ts index fd5c15bdc0a..b70ca7af504 100644 --- a/apps/sim/blocks/utils.ts +++ b/apps/sim/blocks/utils.ts @@ -1,6 +1,7 @@ import { toError } from '@sim/utils/errors' import { isAzureConfigured, isHosted, isOllamaConfigured } from '@/lib/core/config/feature-flags' import { getScopesForService } from '@/lib/oauth/utils' +import { buildCanonicalIndex } from '@/lib/workflows/subblocks/visibility' import type { BlockOutput, OutputFieldDefinition, SubBlockConfig } from '@/blocks/types' import { getBaseModelProviders, @@ -63,16 +64,6 @@ export function getModelOptions() { }) } -/** - * Checks if a field is included in the dependsOn config. - * Handles both simple array format and object format with all/any fields. - */ -export function isDependency(dependsOn: SubBlockConfig['dependsOn'], field: string): boolean { - if (!dependsOn) return false - if (Array.isArray(dependsOn)) return dependsOn.includes(field) - return dependsOn.all?.includes(field) || dependsOn.any?.includes(field) || false -} - /** * Gets all dependency fields as a flat array. * Handles both simple array format and object format with all/any fields. @@ -83,6 +74,29 @@ export function getDependsOnFields(dependsOn: SubBlockConfig['dependsOn']): stri return [...(dependsOn.all || []), ...(dependsOn.any || [])] } +/** + * Finds subblocks that depend on a changed field, accounting for canonical pairs. + */ +export function getSubBlocksDependingOnChange( + allSubBlocks: SubBlockConfig[], + changedSubBlockId: string +): SubBlockConfig[] { + const canonicalIndex = buildCanonicalIndex(allSubBlocks) + const canonicalId = canonicalIndex.canonicalIdBySubBlockId[changedSubBlockId] + const group = canonicalId ? canonicalIndex.groupsById[canonicalId] : undefined + const changedFields = new Set([changedSubBlockId]) + + if (canonicalId) changedFields.add(canonicalId) + if (group?.basicId) changedFields.add(group.basicId) + for (const advancedId of group?.advancedIds || []) { + changedFields.add(advancedId) + } + + return allSubBlocks.filter((subBlock) => + getDependsOnFields(subBlock.dependsOn).some((field) => changedFields.has(field)) + ) +} + export function resolveOutputType( outputs: Record ): Record { diff --git a/apps/sim/hooks/use-collaborative-workflow.ts b/apps/sim/hooks/use-collaborative-workflow.ts index b7eeceb6b18..5f3b16e56ee 100644 --- a/apps/sim/hooks/use-collaborative-workflow.ts +++ b/apps/sim/hooks/use-collaborative-workflow.ts @@ -19,6 +19,7 @@ import { getWorkflowStateContract } from '@/lib/api/contracts' import { useSession } from '@/lib/auth/auth-client' import { useSocket } from '@/app/workspace/providers/socket-provider' import { getBlock } from '@/blocks' +import { getSubBlocksDependingOnChange } from '@/blocks/utils' import { normalizeName, RESERVED_BLOCK_NAMES } from '@/executor/constants' import { invalidateDeploymentQueries } from '@/hooks/queries/deployments' import { useUndoRedo } from '@/hooks/use-undo-redo' @@ -1322,9 +1323,7 @@ export function useCollaborativeWorkflow() { const blockType = useWorkflowStore.getState().blocks?.[blockId]?.type const blockConfig = blockType ? getBlock(blockType) : null if (blockConfig?.subBlocks && Array.isArray(blockConfig.subBlocks)) { - const dependents = blockConfig.subBlocks.filter( - (sb: any) => Array.isArray(sb.dependsOn) && sb.dependsOn.includes(subblockId) - ) + const dependents = getSubBlocksDependingOnChange(blockConfig.subBlocks, subblockId) for (const dep of dependents) { if (!dep?.id || dep.id === subblockId) continue const currentDepValue = useSubBlockStore.getState().getValue(blockId, dep.id) diff --git a/apps/sim/tools/stt/elevenlabs.ts b/apps/sim/tools/stt/elevenlabs.ts index 26e074109d5..ee19379d502 100644 --- a/apps/sim/tools/stt/elevenlabs.ts +++ b/apps/sim/tools/stt/elevenlabs.ts @@ -24,7 +24,7 @@ export const elevenLabsSttTool: ToolConfig = { type: 'string', required: false, visibility: 'user-or-llm', - description: 'ElevenLabs model to use (scribe_v1, scribe_v1_experimental)', + description: 'ElevenLabs model to use (scribe_v2)', }, audioFile: { type: 'file', @@ -71,7 +71,7 @@ export const elevenLabsSttTool: ToolConfig = { ) => ({ provider: 'elevenlabs', apiKey: params.apiKey, - model: params.model, + model: 'scribe_v2', audioFile: params.audioFile, audioFileReference: params.audioFileReference, audioUrl: params.audioUrl, @@ -141,7 +141,7 @@ export const elevenLabsSttV2Tool: ToolConfig = { ) => ({ provider: 'elevenlabs', apiKey: params.apiKey, - model: params.model, + model: 'scribe_v2', audioFile: params.audioFile, audioFileReference: params.audioFileReference, language: params.language || 'auto', From adfb2b96c83f5d353691b8b620b463df8a0e8af8 Mon Sep 17 00:00:00 2001 From: Vikhyath Mondreti Date: Sat, 2 May 2026 11:20:27 -0700 Subject: [PATCH 2/2] fix overclearing finds --- apps/sim/blocks/blocks/agent.ts | 9 +++------ apps/sim/blocks/blocks/discord.ts | 2 -- apps/sim/blocks/blocks/elasticsearch.ts | 6 ------ apps/sim/blocks/blocks/linear.ts | 15 ++++++++++----- 4 files changed, 13 insertions(+), 19 deletions(-) diff --git a/apps/sim/blocks/blocks/agent.ts b/apps/sim/blocks/blocks/agent.ts index c0592b60c33..3a8e704859d 100644 --- a/apps/sim/blocks/blocks/agent.ts +++ b/apps/sim/blocks/blocks/agent.ts @@ -329,7 +329,6 @@ Return ONLY the JSON array.`, value: MODELS_WITHOUT_MEMORY, not: true, }, - dependsOn: ['model'], }, { id: 'conversationId', @@ -345,7 +344,7 @@ Return ONLY the JSON array.`, value: ['conversation', 'sliding_window', 'sliding_window_tokens'], and: { field: 'model', value: MODELS_WITHOUT_MEMORY, not: true }, }, - dependsOn: ['model', 'memoryType'], + dependsOn: ['memoryType'], }, { id: 'slidingWindowSize', @@ -357,7 +356,7 @@ Return ONLY the JSON array.`, value: ['sliding_window'], and: { field: 'model', value: MODELS_WITHOUT_MEMORY, not: true }, }, - dependsOn: ['model', 'memoryType'], + dependsOn: ['memoryType'], }, { id: 'slidingWindowTokens', @@ -369,7 +368,7 @@ Return ONLY the JSON array.`, value: ['sliding_window_tokens'], and: { field: 'model', value: MODELS_WITHOUT_MEMORY, not: true }, }, - dependsOn: ['model', 'memoryType'], + dependsOn: ['memoryType'], }, { id: 'temperature', @@ -426,7 +425,6 @@ Return ONLY the JSON array.`, value: MODELS_WITH_DEEP_RESEARCH, not: true, }, - dependsOn: ['model'], }, { id: 'responseFormat', @@ -450,7 +448,6 @@ Return ONLY the JSON array.`, field: 'model', value: MODELS_WITH_DEEP_RESEARCH, }, - dependsOn: ['model'], }, ], tools: { diff --git a/apps/sim/blocks/blocks/discord.ts b/apps/sim/blocks/blocks/discord.ts index 97d79692adb..992874e4e08 100644 --- a/apps/sim/blocks/blocks/discord.ts +++ b/apps/sim/blocks/blocks/discord.ts @@ -197,7 +197,6 @@ export const DiscordBlock: BlockConfig = { 'discord_create_webhook', ], }, - dependsOn: ['operation'], }, // Name (optional for updates) { @@ -209,7 +208,6 @@ export const DiscordBlock: BlockConfig = { field: 'operation', value: ['discord_update_channel', 'discord_update_role'], }, - dependsOn: ['operation'], }, // Role ID { diff --git a/apps/sim/blocks/blocks/elasticsearch.ts b/apps/sim/blocks/blocks/elasticsearch.ts index b99c653126e..952b2884555 100644 --- a/apps/sim/blocks/blocks/elasticsearch.ts +++ b/apps/sim/blocks/blocks/elasticsearch.ts @@ -163,7 +163,6 @@ export const ElasticsearchBlock: BlockConfig = { 'elasticsearch_delete_document', ], }, - dependsOn: ['operation'], }, // Optional Document ID - for index document @@ -173,7 +172,6 @@ export const ElasticsearchBlock: BlockConfig = { type: 'short-input', placeholder: 'Leave empty for auto-generated ID', condition: { field: 'operation', value: 'elasticsearch_index_document' }, - dependsOn: ['operation'], }, // Document body - for index @@ -184,7 +182,6 @@ export const ElasticsearchBlock: BlockConfig = { placeholder: '{ "field": "value", "another_field": 123 }', required: true, condition: { field: 'operation', value: 'elasticsearch_index_document' }, - dependsOn: ['operation'], wandConfig: { enabled: true, prompt: `Generate an Elasticsearch document JSON object based on the user's description. @@ -205,7 +202,6 @@ Return ONLY valid JSON - no explanations, no markdown code blocks.`, placeholder: '{ "field_to_update": "new_value" }', required: true, condition: { field: 'operation', value: 'elasticsearch_update_document' }, - dependsOn: ['operation'], wandConfig: { enabled: true, prompt: `Generate an Elasticsearch partial document JSON for updating based on the user's description. @@ -224,7 +220,6 @@ Return ONLY valid JSON - no explanations, no markdown code blocks.`, type: 'code', placeholder: '{ "match": { "field": "search term" } }', condition: { field: 'operation', value: 'elasticsearch_search' }, - dependsOn: ['operation'], wandConfig: { enabled: true, prompt: `Generate an Elasticsearch query DSL JSON based on the user's description. @@ -247,7 +242,6 @@ Return ONLY valid JSON - no explanations, no markdown code blocks.`, type: 'code', placeholder: '{ "match": { "field": "value" } }', condition: { field: 'operation', value: 'elasticsearch_count' }, - dependsOn: ['operation'], wandConfig: { enabled: true, prompt: `Generate an Elasticsearch query DSL JSON for counting documents based on the user's description. diff --git a/apps/sim/blocks/blocks/linear.ts b/apps/sim/blocks/blocks/linear.ts index eaa1ef39a6f..4f06a9832ea 100644 --- a/apps/sim/blocks/blocks/linear.ts +++ b/apps/sim/blocks/blocks/linear.ts @@ -509,7 +509,6 @@ Return ONLY the comment text - no explanations.`, field: 'operation', value: ['linear_create_issue', 'linear_update_issue', 'linear_create_project'], }, - dependsOn: ['operation'], }, // Estimate (for issues) { @@ -1055,7 +1054,6 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n field: 'operation', value: ['linear_create_customer_request', 'linear_update_customer_request'], }, - dependsOn: ['operation'], }, // Customer request ID (for updating) { @@ -1094,7 +1092,7 @@ Return ONLY the description text - no explanations.`, }, // Customer request priority/urgency { - id: 'priority', + id: 'customerRequestPriority', title: 'Urgency', type: 'dropdown', options: [ @@ -2005,7 +2003,10 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n ...baseParams, customerId: params.customerId.trim(), body: params.requestBody?.trim(), - priority: params.priority !== undefined ? Number(params.priority) : 0, + priority: + params.customerRequestPriority !== undefined + ? Number(params.customerRequestPriority) + : 0, issueId: params.linkedIssueId?.trim(), projectId: effectiveProjectId || undefined, } @@ -2019,7 +2020,10 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n customerNeedId: params.customerNeedId.trim(), customerId: params.customerId?.trim(), body: params.requestBody?.trim(), - priority: params.priority !== undefined ? Number(params.priority) : undefined, + priority: + params.customerRequestPriority !== undefined + ? Number(params.customerRequestPriority) + : undefined, issueId: params.linkedIssueId?.trim(), projectId: effectiveProjectId || undefined, } @@ -2358,6 +2362,7 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n stateId: { type: 'string', description: 'Workflow state identifier' }, assigneeId: { type: 'string', description: 'Assignee user identifier' }, priority: { type: 'string', description: 'Priority level' }, + customerRequestPriority: { type: 'string', description: 'Customer request urgency level' }, estimate: { type: 'string', description: 'Estimate points' }, query: { type: 'string', description: 'Search query' }, includeArchived: { type: 'boolean', description: 'Include archived items' },