Skip to content

Commit b65a9d3

Browse files
committed
Fix router block
1 parent 796f73e commit b65a9d3

File tree

5 files changed

+36
-23
lines changed

5 files changed

+36
-23
lines changed

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -654,16 +654,19 @@ export function ConditionInput({
654654
}
655655

656656
const removeBlock = (id: string) => {
657-
if (isPreview || disabled || conditionalBlocks.length <= 2) return
657+
if (isPreview || disabled) return
658+
// Condition mode requires at least 2 blocks (if/else), router mode requires at least 1
659+
const minBlocks = isRouterMode ? 1 : 2
660+
if (conditionalBlocks.length <= minBlocks) return
658661

659662
// Remove any associated edges before removing the block
663+
const handlePrefix = isRouterMode ? `router-${id}` : `condition-${id}`
660664
edges.forEach((edge) => {
661-
if (edge.sourceHandle?.startsWith(`condition-${id}`)) {
665+
if (edge.sourceHandle?.startsWith(handlePrefix)) {
662666
removeEdge(edge.id)
663667
}
664668
})
665669

666-
if (conditionalBlocks.length === 1) return
667670
shouldPersistRef.current = true
668671
setConditionalBlocks((blocks) => updateBlockTitles(blocks.filter((block) => block.id !== id)))
669672

@@ -815,7 +818,11 @@ export function ConditionInput({
815818
<Button
816819
variant='ghost'
817820
onClick={() => removeBlock(block.id)}
818-
disabled={isPreview || disabled || conditionalBlocks.length === 1}
821+
disabled={
822+
isPreview ||
823+
disabled ||
824+
conditionalBlocks.length <= (isRouterMode ? 1 : 2)
825+
}
819826
className='h-auto p-0 text-[var(--text-error)] hover:text-[var(--text-error)]'
820827
>
821828
<Trash className='h-[14px] w-[14px]' />

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -863,7 +863,8 @@ export const WorkflowBlock = memo(function WorkflowBlock({
863863
return parsed.map((item: unknown, index: number) => {
864864
const routeItem = item as { id?: string; value?: string }
865865
return {
866-
id: routeItem?.id ?? `${id}-route-${index}`,
866+
// Use stable ID format that matches ConditionInput's generateStableId
867+
id: routeItem?.id ?? `${id}-route${index + 1}`,
867868
value: routeItem?.value ?? '',
868869
}
869870
})
@@ -873,7 +874,8 @@ export const WorkflowBlock = memo(function WorkflowBlock({
873874
logger.warn('Failed to parse router routes value', { error, blockId: id })
874875
}
875876

876-
return [{ id: `${id}-route-route1`, value: '' }]
877+
// Fallback must match ConditionInput's default: generateStableId(blockId, 'route1') = `${blockId}-route1`
878+
return [{ id: `${id}-route1`, value: '' }]
877879
}, [type, subBlockState, id])
878880

879881
/**

apps/sim/blocks/blocks/router.ts

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -115,25 +115,29 @@ Description: ${route.value || 'No description provided'}
115115
)
116116
.join('\n')
117117

118-
return `You are an intelligent routing agent. Your task is to analyze the provided context and select the most appropriate route from the available options.
118+
return `You are a DETERMINISTIC routing agent. You MUST select exactly ONE route. There is NO other option.
119+
120+
CRITICAL RULES:
121+
- You MUST output a route ID. Period.
122+
- You CANNOT say "I need more information"
123+
- You CANNOT refuse to choose
124+
- You CANNOT explain your reasoning
125+
- You CANNOT ask questions
126+
- You CANNOT output anything except a route ID
127+
- There is ALWAYS a best option. Pick it.
119128
120129
Available Routes:
121130
${routesInfo}
122131
123-
Context to analyze:
132+
Context:
124133
${context}
125134
126-
Instructions:
127-
1. Carefully analyze the context against each route's description
128-
2. Select the route that best matches the context's intent and requirements
129-
3. Consider the semantic meaning, not just keyword matching
130-
4. If multiple routes could match, choose the most specific one
131-
132-
Response Format:
133-
Return ONLY the route ID as a single string, no punctuation, no explanation.
134-
Example: "route-abc123"
135+
MANDATORY BEHAVIOR:
136+
1. Analyze the context against each route description
137+
2. ALWAYS pick the BEST matching route - one route is always better than the others
138+
3. Output ONLY the route ID - nothing else
135139
136-
Remember: Your response must be ONLY the route ID - no additional text, formatting, or explanation.`
140+
Your response must be EXACTLY one route ID from the list above. No punctuation. No explanation. No refusal. Just the ID.`
137141
}
138142

139143
/**

apps/sim/executor/handlers/router/router-handler.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -273,14 +273,15 @@ export class RouterBlockHandler implements BlockHandler {
273273
const result = await response.json()
274274

275275
const chosenRouteId = result.content.trim()
276-
const chosenRoute = routes.find((r) => r.id === chosenRouteId)
276+
let chosenRoute = routes.find((r) => r.id === chosenRouteId)
277277

278+
// Fallback to first route if LLM returns invalid route ID
278279
if (!chosenRoute) {
279-
logger.error(
280-
`Invalid routing decision. Response content: "${result.content}", available routes:`,
280+
logger.warn(
281+
`Invalid routing decision. Response content: "${result.content}", falling back to first route. Available routes:`,
281282
routes.map((r) => ({ id: r.id, title: r.title }))
282283
)
283-
throw new Error(`Invalid routing decision: ${chosenRouteId}`)
284+
chosenRoute = routes[0]
284285
}
285286

286287
// Find the target block connected to this route's handle

bun.lock

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

0 commit comments

Comments
 (0)