Custom actions, which inherit from main code

Hello Rasa Community,

I am facing a problem in developing a chatbot. The chatbot just runs through python files, so therefore I dont use Rasa X or Rasa Shell. My objective is that i want to trigger a custom action, which then executes some specific code. The code that is executed in the custom action, should be able to interact with my some of my variable values from my self-created GUI. I now face the problem that inheritance doesnt really work like in the usual programming sense, cause the custom actions run on the action server. I also want to send a variable to the action server that contains a started MATLAB with Python-Engine object. So that I can execute some MATLAB Code in a custom action that is triggered by chatbot text (for example: i type “show me plot of X”, then the bot executes some specific MATLAB code through the custom action).

Some of the approaches I tried:

  1. I set a slot, with this code ( main.py):
from rasa.core.agent import Agent

from rasa.core.interpreter import RasaNLUInterpreter
from rasa.core.utils import EndpointConfig
import asyncio
import os

os.popen("rasa run actions")

interpreter = RasaNLUInterpreter("./models/current/nlu")
# endpoint is uncommented in endpoints.yml
action_endpoint = EndpointConfig(url="http://localhost:5055/webhook")

agent = Agent.load(model_path="./models/current", interpreter=interpreter,
                   action_endpoint=action_endpoint)  

from rasa.core.channels.channel import UserMessage
from rasa.core.events import SlotSet

tracker = agent.tracker_store.get_or_create_tracker(UserMessage.DEFAULT_SENDER_ID)
ss = SlotSet("aTestSlot", "testing123")
tracker.update(ss)
agent.tracker_store.save(tracker)

The actions.py file looks like this:

from typing import Any, Text, Dict, List

from rasa_sdk import Action, Tracker
from rasa_sdk.executor import CollectingDispatcher

class ActionShowPlotXXX(Action):

    def name(self) -> Text:
        return "action_show_plot_XXX"

    def run(self, dispatcher: CollectingDispatcher,
            tracker: Tracker,
            domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:

        # getIt gives "None" Type back (slot is set in domain.yml as empty unfeaturized slot)
        getIt = tracker.get_slot("aTestSlot")  
        print(getIt)

        print("from show plot action")
        return []

I process a message that triggers the actions.py action, with: (after the other main.py code)

import asyncio

loop = asyncio.get_event_loop()
answer = loop.run_until_complete(agent.handle_text("show me the plot of XXX"))
loop.close()

But this doesnt get me the correct slot, I also tried this for the agent

answer = loop.run_until_complete(agent.parse_message_using_nlu_interpreter(message_data="show me the plot of XXX",
                                                                            tracker= tracker))

but this didnt even execute the action. The problem in this approach is for me: How can I use the newly updated tracker in the file actions.py ?

  1. The other approach i tried for testing, is by setting a slot via the curl command, like (i set a breakpoint after it to make sure it was fully executed): (before starting this file i open two command windows, one with rasa run actions, another one with rasa shell --enable-api)
import os
os.popen('curl -X POST \
  "http://localhost:5005/conversations/default/tracker/events" \
  -H "Content-Type: application/json" \
  -d "{"event":"slot","name":"aTestSlot","value":"testing12","timestamp":0}')

What i get back from the python commandline is:

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   229  100   186  100    43     20      4  0:00:10  0:00:09  0:00:01    43

So apparently something was send somewhere. But when I now type the text in the rasa shell window, which triggers the same class from actions.py as in approach 1., it still gives me an unset variable back.

The problem therefore is quite similar, when I execute it isomething, the actions.py file cant seem to resolve any of the newly changed slot values.


All in all I believe that my config files (domain, nlu, stories, endpoints) are correctly set up (if you suspect an error there I can send them here too), with all entities, slots, intents,… correctly specified. Which approach do you (the Community) finds better? Or do I have a fundamental thinking error and you might be able to recommend a better approach.

Thanks in advance if you have read this and understand my mistake :smiley:

My versions: rasa: 1.10.7, rasa_core: 0.14.5, rasa_sdk: 1.10.2, python: 3.6.8

I mean design-wise I could also just have a custom actions with

dispatcher.utter_message(text="1")

and from the returned answer[0]['text'] in main.py I could just call a specific function in my main code then and I wouldnt bother about further communication. But I though it would be nicer to have it all in the custom actions, but maybe just with a returned index it is more elegant?