From 0e34ea79c6ecbc8c1a816e0079b5eb12602748f9 Mon Sep 17 00:00:00 2001 From: fluzzi Date: Wed, 10 May 2023 12:34:19 -0300 Subject: [PATCH] add history in ai chat --- connpy/_version.py | 2 +- connpy/ai.py | 24 +++++++++++++++++------- connpy/api.py | 6 +++++- docs/connpy/index.html | 38 +++++++++++++++++++++++++++----------- 4 files changed, 50 insertions(+), 20 deletions(-) diff --git a/connpy/_version.py b/connpy/_version.py index fa986f1..c2cc2aa 100644 --- a/connpy/_version.py +++ b/connpy/_version.py @@ -1,2 +1,2 @@ -__version__ = "3.2.1" +__version__ = "3.2.2" diff --git a/connpy/ai.py b/connpy/ai.py index dc23cf6..5acbc42 100755 --- a/connpy/ai.py +++ b/connpy/ai.py @@ -164,8 +164,10 @@ class ai: key, value = line.split(":", 1) key = key.strip() newvalue = {} + pattern = r'\[.*?\]' + match = re.search(pattern, value.strip()) try: - value = ast.literal_eval(value.strip()) + value = ast.literal_eval(match.group(0)) for i,e in enumerate(value, start=1): newvalue[f"command{i}"] = e if f"{{command{i}}}" not in info_dict["commands"]: @@ -205,14 +207,16 @@ class ai: output["response"] = self._clean_command_response(output["raw_response"]) return output - def _get_filter(self, user_input): + def _get_filter(self, user_input, chat_history = None): #Send the request to identify the filter and other attributes from the user input to GPT. message = [] message.append({"role": "system", "content": dedent(self.__prompt["original_system"])}) message.append({"role": "user", "content": dedent(self.__prompt["original_user"])}) message.append({"role": "assistant", "content": dedent(self.__prompt["original_assistant"])}) - message.append({"role": "user", "content": user_input}) - + if not chat_history: + chat_history = [] + chat_history.append({"role": "user", "content": user_input}) + message.extend(chat_history) response = openai.ChatCompletion.create( model=self.model, messages=message, @@ -223,11 +227,13 @@ class ai: output = {} output["dict_response"] = response output["raw_response"] = response["choices"][0]["message"]["content"] + chat_history.append({"role": "assistant", "content": output["raw_response"]}) + output["chat_history"] = chat_history clear_response = self._clean_original_response(output["raw_response"]) output["response"] = self._clean_original_response(output["raw_response"]) return output - def ask(self, user_input, dryrun = False): + def ask(self, user_input, dryrun = False, chat_history = None): ''' Send the user input to openAI GPT and parse the response to run an action in the application. @@ -266,14 +272,18 @@ class ai: on the nodes. - result: A dictionary with the output of the commands or the test. + - chat_history: The chat history between user and chatbot. + It can be used as an attribute for next request. + ''' output = {} - original = self._get_filter(user_input) + original = self._get_filter(user_input, chat_history) output["input"] = user_input output["app_related"] = original["response"]["app_related"] output["dryrun"] = dryrun + output["chat_history"] = original["chat_history"] if not output["app_related"]: output["response"] = original["response"]["response"] else: @@ -289,7 +299,7 @@ class ai: thisnodes = self.config._getallnodesfull(output["filter"]) output["nodes"] = list(thisnodes.keys()) if not type == "command": - output["action"] = type + output["action"] = "list_nodes" else: commands = self._get_commands(user_input, thisnodes) output["args"] = {} diff --git a/connpy/api.py b/connpy/api.py index a4c3357..6d4b0e7 100755 --- a/connpy/api.py +++ b/connpy/api.py @@ -63,8 +63,12 @@ def ask_ai(): dryrun = data["dryrun"] else: dryrun = False + if "chat_history" in data: + chat_history = data["chat_history"] + else: + chat_history = None ai = myai(conf) - return ai.ask(input, dryrun) + return ai.ask(input, dryrun, chat_history) @app.route("/run_commands", methods=["POST"]) diff --git a/docs/connpy/index.html b/docs/connpy/index.html index 6af6391..28b3bf7 100644 --- a/docs/connpy/index.html +++ b/docs/connpy/index.html @@ -730,8 +730,10 @@ __pdoc__ = { key, value = line.split(":", 1) key = key.strip() newvalue = {} + pattern = r'\[.*?\]' + match = re.search(pattern, value.strip()) try: - value = ast.literal_eval(value.strip()) + value = ast.literal_eval(match.group(0)) for i,e in enumerate(value, start=1): newvalue[f"command{i}"] = e if f"{{command{i}}}" not in info_dict["commands"]: @@ -771,14 +773,16 @@ __pdoc__ = { output["response"] = self._clean_command_response(output["raw_response"]) return output - def _get_filter(self, user_input): + def _get_filter(self, user_input, chat_history = None): #Send the request to identify the filter and other attributes from the user input to GPT. message = [] message.append({"role": "system", "content": dedent(self.__prompt["original_system"])}) message.append({"role": "user", "content": dedent(self.__prompt["original_user"])}) message.append({"role": "assistant", "content": dedent(self.__prompt["original_assistant"])}) - message.append({"role": "user", "content": user_input}) - + if not chat_history: + chat_history = [] + chat_history.append({"role": "user", "content": user_input}) + message.extend(chat_history) response = openai.ChatCompletion.create( model=self.model, messages=message, @@ -789,11 +793,13 @@ __pdoc__ = { output = {} output["dict_response"] = response output["raw_response"] = response["choices"][0]["message"]["content"] + chat_history.append({"role": "assistant", "content": output["raw_response"]}) + output["chat_history"] = chat_history clear_response = self._clean_original_response(output["raw_response"]) output["response"] = self._clean_original_response(output["raw_response"]) return output - def ask(self, user_input, dryrun = False): + def ask(self, user_input, dryrun = False, chat_history = None): ''' Send the user input to openAI GPT and parse the response to run an action in the application. @@ -832,14 +838,18 @@ __pdoc__ = { on the nodes. - result: A dictionary with the output of the commands or the test. + - chat_history: The chat history between user and chatbot. + It can be used as an attribute for next request. + ''' output = {} - original = self._get_filter(user_input) + original = self._get_filter(user_input, chat_history) output["input"] = user_input output["app_related"] = original["response"]["app_related"] output["dryrun"] = dryrun + output["chat_history"] = original["chat_history"] if not output["app_related"]: output["response"] = original["response"]["response"] else: @@ -855,7 +865,7 @@ __pdoc__ = { thisnodes = self.config._getallnodesfull(output["filter"]) output["nodes"] = list(thisnodes.keys()) if not type == "command": - output["action"] = type + output["action"] = "list_nodes" else: commands = self._get_commands(user_input, thisnodes) output["args"] = {} @@ -877,7 +887,7 @@ __pdoc__ = {

Methods

-def ask(self, user_input, dryrun=False) +def ask(self, user_input, dryrun=False, chat_history=None)

Send the user input to openAI GPT and parse the response to run an action in the application.

@@ -913,12 +923,14 @@ __pdoc__ = { on the nodes. - result: A dictionary with the output of the commands or the test. + - chat_history: The chat history between user and chatbot. + It can be used as an attribute for next request.
Expand source code -
def ask(self, user_input, dryrun = False):
+
def ask(self, user_input, dryrun = False, chat_history = None):
     '''
     Send the user input to openAI GPT and parse the response to run an action in the application.
 
@@ -957,14 +969,18 @@ __pdoc__ = {
                 on the nodes.
               - result: A dictionary with the output of the commands or 
                 the test.
+              - chat_history: The chat history between user and chatbot.
+                It can be used as an attribute for next request.
+            
                 
 
     '''
     output = {}
-    original = self._get_filter(user_input)
+    original = self._get_filter(user_input, chat_history)
     output["input"] = user_input
     output["app_related"] = original["response"]["app_related"]
     output["dryrun"] = dryrun
+    output["chat_history"] = original["chat_history"]
     if not output["app_related"]:
         output["response"] = original["response"]["response"]
     else:
@@ -980,7 +996,7 @@ __pdoc__ = {
                 thisnodes = self.config._getallnodesfull(output["filter"])
                 output["nodes"] = list(thisnodes.keys())
         if not type == "command":
-            output["action"] = type
+            output["action"] = "list_nodes"
         else:
             commands = self._get_commands(user_input, thisnodes)
             output["args"] = {}