Router with CEL: route based on a named previous step's output

Uses previous_step_outputs map to access the classifier step by name, then routes to the appropriate handler based on the classification.

cel_previous_step_route.py
"""Router with CEL: route based on a named previous step's output.
===============================================================

Uses previous_step_outputs map to access the classifier step by name,
then routes to the appropriate handler based on the classification.

Requirements:
    pip install cel-python
"""

from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.workflow import CEL_AVAILABLE, Step, Workflow
from agno.workflow.router import Router

# ---------------------------------------------------------------------------
# Setup
# ---------------------------------------------------------------------------
if not CEL_AVAILABLE:
    print("CEL is not available. Install with: pip install cel-python")
    exit(1)

# ---------------------------------------------------------------------------
# Create Agents
# ---------------------------------------------------------------------------
classifier = Agent(
    name="Classifier",
    model=OpenAIChat(id="gpt-5.6-luna"),
    instructions=(
        "Classify the request into exactly one category. "
        "Respond with only one word: BILLING, TECHNICAL, or GENERAL."
    ),
    markdown=False,
)

billing_agent = Agent(
    name="Billing Support",
    model=OpenAIChat(id="gpt-5.6-luna"),
    instructions="You handle billing inquiries. Help with invoices, payments, and subscriptions.",
    markdown=True,
)

technical_agent = Agent(
    name="Technical Support",
    model=OpenAIChat(id="gpt-5.6-luna"),
    instructions="You handle technical issues. Help with debugging and configuration.",
    markdown=True,
)

general_agent = Agent(
    name="General Support",
    model=OpenAIChat(id="gpt-5.6-luna"),
    instructions="You handle general inquiries.",
    markdown=True,
)

# ---------------------------------------------------------------------------
# Create Workflow
# ---------------------------------------------------------------------------
workflow = Workflow(
    name="CEL Previous Step Outputs Router",
    steps=[
        Step(name="Classify", agent=classifier),
        Router(
            name="Support Router",
            # Access the classifier output by step name via previous_step_outputs map
            selector=(
                'previous_step_outputs.Classify.contains("BILLING") ? "Billing Support" : '
                'previous_step_outputs.Classify.contains("TECHNICAL") ? "Technical Support" : '
                '"General Support"'
            ),
            choices=[
                Step(name="Billing Support", agent=billing_agent),
                Step(name="Technical Support", agent=technical_agent),
                Step(name="General Support", agent=general_agent),
            ],
        ),
    ],
)

# ---------------------------------------------------------------------------
# Run Workflow
# ---------------------------------------------------------------------------
if __name__ == "__main__":
    print("--- Billing question ---")
    workflow.print_response(input="I was charged twice on my last invoice.")
    print()

    print("--- Technical question ---")
    workflow.print_response(input="My API keeps returning 503 errors.")

Forward the original question

The classifier emits only a category. Keep the named Classify output for the selector, and restore the original request inside the selected branch before calling its support agent:

run_cel_previous_step_route.py
from agno.workflow.step import Step
from agno.workflow.steps import Steps
from agno.workflow.types import StepInput, StepOutput
from cel_previous_step_route import workflow


def restore_question(step_input: StepInput) -> StepOutput:
    return StepOutput(content=step_input.input)


router = workflow.steps[1]
router.choices = [
    Steps(
        name=handler.name,
        steps=[Step(name="Restore Question", executor=restore_question), handler],
    )
    for handler in router.choices
]
workflow.print_response(input="I was charged twice on my last invoice.")
workflow.print_response(input="My API keeps returning 503 errors.")

Each sequence retains the choice name used by the CEL expression. The handler receives the original question rather than just BILLING or TECHNICAL.

Run the Example

Set up your virtual environment

uv venv --python 3.12
source .venv/bin/activate

Install dependencies

uv pip install -U agno cel-python fastapi openai

Export your OpenAI API key

export OPENAI_API_KEY="your_openai_api_key_here"

Run the example

Save the source as cel_previous_step_route.py and the separate runner above, then run:

python run_cel_previous_step_route.py

Full source: cookbook/04_workflows/07_cel_expressions/router/cel_previous_step_route.py