AI decision routing
One SWITCH asks a fixed choice question and routes to the selected branch. The choices live in the definition, so the model can only pick a branch you declared.
The shape
route_request (SWITCH, evaluatorType: decision) ──> billing ──> selected_result (INLINE)
└──> technical ──┘
Prerequisites
conductor.integrations.ai.enabled=true and DECISION_API_KEY set on the server.
Runnable definition
Save this as ai-decision-routing.json:
{
"name": "ai_decision_routing",
"version": 1,
"schemaVersion": 2,
"enforceSchema": false,
"failureWorkflow": "",
"timeoutSeconds": 60,
"timeoutPolicy": "ALERT_ONLY",
"tasks": [
{
"name": "route_request",
"taskReferenceName": "route_request",
"type": "SWITCH",
"evaluatorType": "decision",
"expression": "route",
"inputParameters": {
"model": "jev-1.13",
"state": "${workflow.input.request}",
"questions": {
"route": {
"type": "choice",
"instructions": "Choose the team best suited to handle this request.",
"choices": {
"billing": "Payments, invoices, refunds, or subscriptions.",
"technical": "Errors, outages, or product troubleshooting."
}
}
}
},
"decisionCases": {
"billing": [
{
"name": "handle_billing",
"taskReferenceName": "handle_billing",
"type": "INLINE",
"inputParameters": {
"evaluatorType": "graaljs",
"expression": "({team: \"billing\", nextAction: \"review_invoice\", message: \"Check invoice line items and payment records.\", request: $.request})",
"request": "${workflow.input.request}"
}
}
],
"technical": [
{
"name": "handle_technical",
"taskReferenceName": "handle_technical",
"type": "INLINE",
"inputParameters": {
"evaluatorType": "graaljs",
"expression": "({team: \"technical\", nextAction: \"collect_diagnostics\", message: \"Collect error logs and steps to reproduce.\", request: $.request})",
"request": "${workflow.input.request}"
}
}
]
},
"defaultCase": []
},
{
"name": "selected_result",
"taskReferenceName": "selected_result",
"type": "INLINE",
"inputParameters": {
"evaluatorType": "graaljs",
"expression": "$.billing || $.technical",
"billing": "${handle_billing.output.result}",
"technical": "${handle_technical.output.result}"
}
}
],
"outputParameters": {
"selectedCase": "${route_request.output.selectedCase}",
"answers": "${route_request.output.answers}",
"usage": "${route_request.output.usage}",
"cost": "${route_request.output.usage.cost}",
"latencyMs": "${route_request.output.latencyMs}",
"result": "${selected_result.output.result}"
}
}
Register and run
CONDUCTOR_API="${CONDUCTOR_SERVER_URL:-http://localhost:8080/api}"
curl --fail-with-body -X POST "$CONDUCTOR_API/metadata/workflow?overwrite=true" \
-H 'Content-Type: application/json' --data-binary @ai-decision-routing.json
curl --fail-with-body -X POST "$CONDUCTOR_API/workflow/ai_decision_routing?version=1" \
-H 'Content-Type: application/json' \
-d '{"request":"I was charged twice on my latest invoice."}'
Open Executions in your Conductor UI and select the new execution. route_request.output.selectedCase and the workflow's selectedCase output are billing, only handle_billing ran, and result.nextAction is review_invoice. The workflow also exposes answers, usage, cost, and latencyMs from the decision.