Skip to content

Commit f1b8745

Browse files
committed
router block error path decision
1 parent d7718e6 commit f1b8745

File tree

3 files changed

+33
-16
lines changed

3 files changed

+33
-16
lines changed

apps/docs/content/docs/en/blocks/router.mdx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
title: Router
33
---
44

5-
import { Callout } from 'fumadocs-ui/components/callout'
65
import { Tab, Tabs } from 'fumadocs-ui/components/tabs'
76
import { Image } from '@/components/ui/image'
87

@@ -90,11 +89,18 @@ Input (Lead) → Router → Agent (Enterprise Sales) or Workflow (Self-serve)
9089
```
9190

9291

92+
## Error Handling
93+
94+
When the Router cannot determine an appropriate route for the given context, it will route to the **error path** instead of arbitrarily selecting a route. This happens when:
95+
96+
- The context doesn't clearly match any of the defined route descriptions
97+
- The AI determines that none of the available routes are appropriate
98+
9399
## Best Practices
94100

95101
- **Provide clear target descriptions**: Help the Router understand when to select each destination with specific, detailed descriptions
96102
- **Use specific routing criteria**: Define clear conditions and examples for each path to improve accuracy
97-
- **Implement fallback paths**: Connect a default destination for when no specific path is appropriate
103+
- **Connect an error path**: Handle cases where no route matches by connecting an error handler for graceful fallback behavior
98104
- **Test with diverse inputs**: Ensure the Router handles various input types, edge cases, and unexpected content
99105
- **Monitor routing performance**: Review routing decisions regularly and refine criteria based on actual usage patterns
100106
- **Choose appropriate models**: Use models with strong reasoning capabilities for complex routing decisions

apps/sim/blocks/blocks/router.ts

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

118-
return `You are a DETERMINISTIC routing agent. You MUST select exactly ONE route. There is NO other option.
118+
return `You are a DETERMINISTIC routing agent. You MUST select exactly ONE option.
119119
120120
CRITICAL RULES:
121-
- You MUST output a route ID. Period.
121+
- You MUST output ONLY a route ID or "NO_MATCH" - copy it EXACTLY as shown
122122
- You CANNOT say "I need more information"
123-
- You CANNOT refuse to choose
124123
- You CANNOT explain your reasoning
125124
- You CANNOT ask questions
126-
- You CANNOT output anything except a route ID
127-
- There is ALWAYS a best option. Pick it.
125+
- You CANNOT output anything except the exact route ID or "NO_MATCH"
128126
129127
Available Routes:
130128
${routesInfo}
131129
130+
Special Option:
131+
- If the context does NOT clearly match ANY route description, output exactly: NO_MATCH
132+
132133
Context:
133134
${context}
134135
135136
MANDATORY BEHAVIOR:
136137
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
138+
2. If one route clearly matches the context, output that route's ID exactly as shown
139+
3. If NO route is appropriate for the context, output exactly: NO_MATCH
140+
4. Output ONLY the route ID or NO_MATCH - nothing else
139141
140-
Your response must be EXACTLY one route ID from the list above. No punctuation. No explanation. No refusal. Just the ID.`
142+
Your response must be EXACTLY one route ID from the list above OR "NO_MATCH". No punctuation. No explanation. Just the ID or NO_MATCH.`
141143
}
142144

143145
/**

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

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

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

278-
// Fallback to first route if LLM returns invalid route ID
277+
if (chosenRouteId === 'NO_MATCH' || chosenRouteId.toUpperCase() === 'NO_MATCH') {
278+
logger.info('Router determined no route matches the context, routing to error path')
279+
throw new Error('Router could not determine a matching route for the given context')
280+
}
281+
282+
const chosenRoute = routes.find((r) => r.id === chosenRouteId)
283+
284+
// Throw error if LLM returns invalid route ID - this routes through error path
279285
if (!chosenRoute) {
280-
logger.warn(
281-
`Invalid routing decision. Response content: "${result.content}", falling back to first route. Available routes:`,
282-
routes.map((r) => ({ id: r.id, title: r.title }))
286+
const availableRoutes = routes.map((r) => ({ id: r.id, title: r.title }))
287+
logger.error(
288+
`Invalid routing decision. Response content: "${result.content}". Available routes:`,
289+
availableRoutes
290+
)
291+
throw new Error(
292+
`Router could not determine a valid route. LLM response: "${result.content}". Available route IDs: ${routes.map((r) => r.id).join(', ')}`
283293
)
284-
chosenRoute = routes[0]
285294
}
286295

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

0 commit comments

Comments
 (0)