From 29befbc5f6d843509caa6d71a294af811f78791d Mon Sep 17 00:00:00 2001 From: Waleed Date: Tue, 16 Dec 2025 11:23:57 -0800 Subject: [PATCH 1/2] feat(schedule): add input form to schedule (#2405) * feat(schedule): add input form to schedule * change placeholder --- .../sub-block/components/starter/input-format.tsx | 4 +--- apps/sim/blocks/blocks/schedule.ts | 9 +++++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/starter/input-format.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/starter/input-format.tsx index 11aca94bbc..960356aaf0 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/starter/input-format.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/starter/input-format.tsx @@ -91,8 +91,7 @@ export function FieldFormat({ placeholder = 'fieldName', showType = true, showValue = false, - valuePlaceholder = 'Enter test value', - config, + valuePlaceholder = 'Enter default value', }: FieldFormatProps) { const [storeValue, setStoreValue] = useSubBlockValue(blockId, subBlockId) const valueInputRefs = useRef>({}) @@ -454,7 +453,6 @@ export function FieldFormat({ ) } -// Export specific components for backward compatibility export function InputFormat(props: Omit) { return } diff --git a/apps/sim/blocks/blocks/schedule.ts b/apps/sim/blocks/blocks/schedule.ts index edf21e2df3..1b6de427c5 100644 --- a/apps/sim/blocks/blocks/schedule.ts +++ b/apps/sim/blocks/blocks/schedule.ts @@ -155,6 +155,15 @@ export const ScheduleBlock: BlockConfig = { condition: { field: 'scheduleType', value: ['minutes', 'hourly'], not: true }, }, + { + id: 'inputFormat', + title: 'Input Format', + type: 'input-format', + description: + 'Define input parameters that will be available when the schedule triggers. Use Value to set default values for scheduled executions.', + mode: 'trigger', + }, + { id: 'scheduleSave', type: 'schedule-save', From f7d2c9667fd0c16d0d5349cbbc0021e5a4a9f8ed Mon Sep 17 00:00:00 2001 From: Vikhyath Mondreti Date: Tue, 16 Dec 2025 14:36:40 -0800 Subject: [PATCH 2/2] fix(serializer): condition check should check if any condition are met (#2410) * fix(serializer): condition check should check if any condition are met * remove comments * remove more comments --- apps/sim/serializer/index.ts | 52 ++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/apps/sim/serializer/index.ts b/apps/sim/serializer/index.ts index db9401824c..6500f7fb22 100644 --- a/apps/sim/serializer/index.ts +++ b/apps/sim/serializer/index.ts @@ -402,8 +402,7 @@ export class Serializer { // Second pass: filter by mode and conditions Object.entries(block.subBlocks).forEach(([id, subBlock]) => { - // Find the corresponding subblock config to check its mode and condition - const subBlockConfig = blockConfig.subBlocks.find((config) => config.id === id) + const matchingConfigs = blockConfig.subBlocks.filter((config) => config.id === id) // Include field if it matches current mode OR if it's the starter inputFormat with values const hasStarterInputFormatValues = @@ -417,13 +416,17 @@ export class Serializer { const isLegacyAgentField = isAgentBlock && ['systemPrompt', 'userPrompt', 'memories'].includes(id) - // Check if field's condition is met (conditionally-hidden fields should be excluded) - const conditionMet = subBlockConfig - ? evaluateCondition(subBlockConfig.condition, allValues) - : true + const anyConditionMet = + matchingConfigs.length === 0 + ? true + : matchingConfigs.some( + (config) => + shouldIncludeField(config, isAdvancedMode) && + evaluateCondition(config.condition, allValues) + ) if ( - (subBlockConfig && shouldIncludeField(subBlockConfig, isAdvancedMode) && conditionMet) || + (matchingConfigs.length > 0 && anyConditionMet) || hasStarterInputFormatValues || isLegacyAgentField ) { @@ -540,26 +543,26 @@ export class Serializer { // Iterate through the tool's parameters, not the block's subBlocks Object.entries(currentTool.params || {}).forEach(([paramId, paramConfig]) => { if (paramConfig.required && paramConfig.visibility === 'user-only') { - const subBlockConfig = blockConfig.subBlocks?.find((sb: any) => sb.id === paramId) + const matchingConfigs = blockConfig.subBlocks?.filter((sb: any) => sb.id === paramId) || [] let shouldValidateParam = true - if (subBlockConfig) { + if (matchingConfigs.length > 0) { const isAdvancedMode = block.advancedMode ?? false - const includedByMode = shouldIncludeField(subBlockConfig, isAdvancedMode) - // Check visibility condition - const includedByCondition = evaluateCondition(subBlockConfig.condition, params) + shouldValidateParam = matchingConfigs.some((subBlockConfig: any) => { + const includedByMode = shouldIncludeField(subBlockConfig, isAdvancedMode) - // Check if field is required based on its required condition (if it's a condition object) - const isRequired = (() => { - if (!subBlockConfig.required) return false - if (typeof subBlockConfig.required === 'boolean') return subBlockConfig.required - // If required is a condition object, evaluate it - return evaluateCondition(subBlockConfig.required, params) - })() + const includedByCondition = evaluateCondition(subBlockConfig.condition, params) - shouldValidateParam = includedByMode && includedByCondition && isRequired + const isRequired = (() => { + if (!subBlockConfig.required) return false + if (typeof subBlockConfig.required === 'boolean') return subBlockConfig.required + return evaluateCondition(subBlockConfig.required, params) + })() + + return includedByMode && includedByCondition && isRequired + }) } if (!shouldValidateParam) { @@ -568,7 +571,12 @@ export class Serializer { const fieldValue = params[paramId] if (fieldValue === undefined || fieldValue === null || fieldValue === '') { - const displayName = subBlockConfig?.title || paramId + const activeConfig = matchingConfigs.find( + (config: any) => + shouldIncludeField(config, block.advancedMode ?? false) && + evaluateCondition(config.condition, params) + ) + const displayName = activeConfig?.title || paramId missingFields.push(displayName) } } @@ -596,8 +604,6 @@ export class Serializer { const accessibleIds = new Set(ancestorIds) accessibleIds.add(blockId) - // Only add starter block if it's actually upstream (already in ancestorIds) - // Don't add it just because it exists on the canvas if (starterBlock && ancestorIds.includes(starterBlock.id)) { accessibleIds.add(starterBlock.id) }