Branches: routing with ConditionalRouter
ConditionalRouter checks Jinja conditions against its inputs and sends a value out of the first route that matches, so a pipeline can take different branches.
router = ConditionalRouter(routes=[
{"condition": "{{ 'refund' in question|lower }}", "output": "{{ question }}", "output_name": "billing", "output_type": str},
{"condition": "{{ True }}", "output": "{{ question }}", "output_name": "general", "output_type": str},
])
print(router.run(question="How long does a Refund take?"))
print(router.run(question="Where is my parcel?"))Jinja is a template language: {{ ... }} is an expression whose value is filled in. Each route has a condition, an output, both Jinja templates, and an output_name that becomes an output socket. The router's inputs come from the variables the templates use, here question. Routes are checked in order and only the first match fires, so the last route with {{ True }} catches the rest.
pipeline = Pipeline()
pipeline.add_component("router", router)
pipeline.add_component("billing_desk", Desk(team="billing"))
pipeline.add_component("general_desk", Desk(team="general"))
pipeline.connect("router.billing", "billing_desk.question")
pipeline.connect("router.general", "general_desk.question")
print(pipeline.run({"router": {"question": "How long does a refund take?"}}))Only the branch that received a value ran: general_desk had no input, so it produced nothing. Desk takes its team in __init__, the usual place for settings, so one class serves both branches.
- Send "Where is my parcel?" through the pipeline.
- Remove the
{{ True }}route and route a parcel question. - Add a route for questions containing
staff.
This is what real progress feels like.