How to deal with flow interruptions

So I am developing a rasa calm chatbot for interacting with a simulated robot of sorts. I ask it to move objects and once it has all the required slots, it will trigger a custom action. However, if I interrupt a ongoing flow, it behaves weirdly and sets slots automatically.

Here is an example: user : move the brush

robot: Where would you like me to move the brush to?

user: move the can from the kitchen to the dining room

robot: Moving brush from bedroom table to dining room table

Let’s continue with move object no location.

Ok, I am updating object to can respectively.

Where would you like me to move the can to?


Here move object no location is the name of the flow when the user does not specify the source location of the object. For something like “move the cup to the kitchen” and I have a custom action that determines the location of the cup and all that. In the above example, the brush location is determined to be bedroom table which is correct, but nowhere did I set a destination to dining room table

Here’s the end2end from the inspector:

    - user: move the brush
    - utter: utter_ask_destination_location
    - user: move the can from the kitchen to the dining room
    - utter: Moving brush from bedroomtable to diningroomtable
    - utter: utter_flow_continue_interrupted
    - utter: utter_corrected_previous_input
    - utter: utter_ask_destination_location

Hi @Elliot94 ,

Can you share the Flow that shows this behavior?

this is for when the user does not specify the source location

  move_object_no_location:
    description: This flow is triggered when the user requests the robot to move an object to a destination without specifying its source location. 
    steps:
      - collect: object
        description: Extract and store the name of the object the user wants the robot to move. Ensure the input is a valid string representing an object, rejecting any empty strings.
      - action: action_check_if_object_in_kb
        next:
          - if: slots.object_in_kb
            then: "collect_destination_location_to_move_object_to"
          - else:
              - action: utter_object_not_in_kb
                next: END
      - id: "collect_destination_location_to_move_object_to"
        collect: destination_location
        description: Extract and store the specific location to where the user wants the robot to move the object. Ensure the input is a valid location, rejecting any empty strings.
      - action: action_check_if_destination_location_in_kb
        next:
          - if: slots.location_in_kb
            then: 
              - action: action_set_params_move_object
              - action: action_send_move_object_goal
              - set_slots:
                  - object_in_kb: False
                  - location_in_kb: False
                  - source_location: null
                  - destination_location: null
                next: END
          - else:
              - action: utter_destination_location_not_in_kb
              - set_slots:
                  - destination_location: null
                next: "collect_destination_location_to_move_object_to"

and here is the one for when the user gives both source and destination

  move_object_from_location:
    description: This flow is triggered when the user requests the robot to move an object from one location to another. 
    steps:
      - collect: object
        description: Extract and store the name of the object the user wants the robot to move. Ensure the input is a valid string representing an object, rejecting any empty strings.
      - action: action_check_if_object_in_kb
        next:
          - if: slots.object_in_kb
            then: "collect_location_to_move_object_from"
          - else:
              - action: utter_object_not_in_kb
                next: END
      - id: "collect_location_to_move_object_from"
        collect: source_location
        description: Extract and store the specific location from where the user wants the robot to move the object. Ensure the input is a valid location, rejecting any empty strings.
      - call: "verify_or_update_source_location"
        next:
          - if: slots.location_in_kb
            then: 
              - set_slots:
                  - location_in_kb: False
                next: "collect_destination_location_to_move_object_to"
          - else:
              - action: utter_source_location_not_in_kb
              - set_slots:
                  - source_location: null
                  - location_in_kb: False
                next: "collect_location_to_move_object_from"
      - id: "collect_destination_location_to_move_object_to"
        collect: destination_location
        description: Extract and store the specific location to where the user wants the robot to move the object. Ensure the input is a valid location, rejecting any empty strings.
      - action: action_check_if_destination_location_in_kb
        next:
          - if: slots.location_in_kb
            then: 
              - action: action_set_params_move_object
              - action: action_send_move_object_goal
              - set_slots:
                  - object_in_kb: False
                  - location_in_kb: False
                  - source_location: null
                  - destination_location: null
                next: END
          - else:
              - action: utter_destination_location_not_in_kb
              - set_slots:
                  - destination_location: null
                  - location_in_kb: False
                next: "collect_destination_location_to_move_object_to"

I can understand it confusing these two and asking for a source location, but it straight up assumed a location

Hi @Elliot94 ,

These two flows are likely too similar for the LLM to distinguish between them.

I recommend that you have just one flow: move_object

In that flow, you always first collect the object and the destination_location.

But for the source_location, I would build a conditional statement. If the source_location slot is already filled, your done. If the source_location slot is not filled, you could first ask a question: do you know the current location of the object?

If the answer is yes, you ask for it, if the answer is no, you leave it null.

Then, in the remainder of the flow, you can handle the behavior based on the source_location slot being null or having a value.

yes these two flows are two similar, and I would understand it if the LLM made a mistake in choosing between one of these. But what happened is that it assigned a value to the slot without asking anything. There was no mention of a bedroom in that conversation, and yet it assigned that in the source location slot. I was looking for a way to deal with that.

You might need to implement session management or context resetting to handle interruptions more effectively, ensuring correct slot filling and responses.