Tachi67 commited on
Commit
428252c
·
1 Parent(s): da41e3b

Upload 12 files

Browse files
ExecuteCodeAtomicFlow.py ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import time
3
+ from typing import Dict, Any
4
+ import subprocess
5
+ from flow_modules.aiflows.InterpreterFlowModule import InterpreterAtomicFlow
6
+
7
+
8
+ class ExecuteCodeAtomicFlow(InterpreterAtomicFlow):
9
+ """This class inherits from InterpreterAtomicFlow and is used to execute code in a file.
10
+ It opens up the file in VSCode and waits for the user to save the file. Once the file is saved, it reads the code
11
+ from the file and executes it. It then returns the output of the execution.
12
+
13
+ *Input Interface*:
14
+ - temp_code_file_location: The location of the file containing the code to be executed.
15
+ - language: The language of the code to be executed.
16
+
17
+ *Output Interface*:
18
+ - interpreter_output: The output of the execution of the code.
19
+ - code_ran: The code that was executed.
20
+ """
21
+ def _prepare_code(self, input_data: Dict[str, Any]):
22
+ file_location = input_data["temp_code_file_location"]
23
+ start_marker = "# Code:\n"
24
+ end_marker = "############"
25
+ code_started = False
26
+ code_str = ""
27
+ with open(file_location, 'r') as file:
28
+ for line in file:
29
+ if line.strip() == start_marker.strip():
30
+ code_started = True
31
+ continue
32
+ if line.strip() == end_marker.strip():
33
+ break
34
+ if code_started:
35
+ code_str += line
36
+ input_data["code"] = code_str
37
+
38
+ def _check_input(self, input_data: Dict[str, Any]):
39
+ assert "temp_code_file_location" in input_data, "temp_code_file_location not passed to ExecuteCodeAtomicFlow"
40
+ assert "language" in input_data, "language not passed to ExecuteCodeAtomicFlow"
41
+
42
+ def _delete_file(self, file_location):
43
+ if os.path.exists(file_location):
44
+ os.remove(file_location)
45
+
46
+ def _open_file_and_wait_for_upd(self, file_location):
47
+ process = subprocess.Popen(["code", "--wait", file_location])
48
+ while True:
49
+ if process.poll() is not None:
50
+ break
51
+ time.sleep(1)
52
+
53
+ def run(
54
+ self,
55
+ input_data: Dict[str, Any]):
56
+ self._check_input(input_data)
57
+ file_loc = input_data["temp_code_file_location"]
58
+ self._open_file_and_wait_for_upd(file_loc)
59
+ self._prepare_code(input_data)
60
+ self._process_input_data(input_data)
61
+ execution_output = self._call()
62
+ self._delete_file(file_loc)
63
+ response = {"interpreter_output": execution_output, "code_ran": input_data['code']}
64
+ return response
ExecuteCodeAtomicFlow.yaml ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ _target_: flow_modules.aiflows.RunCodeFlowModule.ExecuteCodeAtomicFlow.instantiate_from_default_config
2
+ name: "ExecuteCodeAtomicFlow"
3
+ description: "A flow that opens up temp code file location, waits for update, runs code and deletes temp code file"
4
+
5
+
6
+ input_interface:
7
+ - "temp_code_file_location"
8
+ - "language"
9
+
10
+ output_interface:
11
+ - "interpreter_output"
12
+ - "code_ran"
README.md CHANGED
@@ -1,3 +1,103 @@
1
- ---
2
- license: mit
3
- ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Table of Contents
2
+
3
+ * [RunCodeFlow](#RunCodeFlow)
4
+ * [RunCodeFlow](#RunCodeFlow.RunCodeFlow)
5
+ * [ExecuteCodeAtomicFlow](#ExecuteCodeAtomicFlow)
6
+ * [ExecuteCodeAtomicFlow](#ExecuteCodeAtomicFlow.ExecuteCodeAtomicFlow)
7
+ * [RunCodeAskUserFlow](#RunCodeAskUserFlow)
8
+ * [RunCodeAskUserFlow](#RunCodeAskUserFlow.RunCodeAskUserFlow)
9
+ * [library](#library)
10
+ * [run](#run)
11
+ * [RunCodeFileEditAtomicFlow](#RunCodeFileEditAtomicFlow)
12
+ * [RunCodeFileEditAtomicFlow](#RunCodeFileEditAtomicFlow.RunCodeFileEditAtomicFlow)
13
+ * [\_\_init\_\_](#__init__)
14
+
15
+ <a id="RunCodeFlow"></a>
16
+
17
+ # RunCodeFlow
18
+
19
+ <a id="RunCodeFlow.RunCodeFlow"></a>
20
+
21
+ ## RunCodeFlow Objects
22
+
23
+ ```python
24
+ class RunCodeFlow(SequentialFlow)
25
+ ```
26
+
27
+ This flow is used to run code in a file. It opens up the file in VSCode and waits for the user to save the file.
28
+ Once the file is saved, it reads the code from the file and executes it. It then returns the output of the execution.
29
+ Finally, the flow asks the user for feedback on the execution of the code.
30
+
31
+ *Input Interface*:
32
+ - code: The code to be executed.
33
+ - language: The language of the code to be executed.
34
+ - memory_files: The dictionary containing the location of the code library.
35
+
36
+ *Output Interface*:
37
+ - summary: The summary of the execution of the code. (To be written to the logs of the caller flow)
38
+ - result: The result of the execution of the code. (To be returned to the controller of the caller flow)
39
+
40
+ <a id="ExecuteCodeAtomicFlow"></a>
41
+
42
+ # ExecuteCodeAtomicFlow
43
+
44
+ <a id="ExecuteCodeAtomicFlow.ExecuteCodeAtomicFlow"></a>
45
+
46
+ ## ExecuteCodeAtomicFlow Objects
47
+
48
+ ```python
49
+ class ExecuteCodeAtomicFlow(InterpreterAtomicFlow)
50
+ ```
51
+
52
+ This class inherits from InterpreterAtomicFlow and is used to execute code in a file.
53
+ It opens up the file in VSCode and waits for the user to save the file. Once the file is saved, it reads the code
54
+ from the file and executes it. It then returns the output of the execution.
55
+
56
+ *Input Interface*:
57
+ - temp_code_file_location: The location of the file containing the code to be executed.
58
+ - language: The language of the code to be executed.
59
+
60
+ *Output Interface*:
61
+ - interpreter_output: The output of the execution of the code.
62
+ - code_ran: The code that was executed.
63
+
64
+ <a id="RunCodeAskUserFlow"></a>
65
+
66
+ # RunCodeAskUserFlow
67
+
68
+ <a id="RunCodeAskUserFlow.RunCodeAskUserFlow"></a>
69
+
70
+ ## RunCodeAskUserFlow Objects
71
+
72
+ ```python
73
+ class RunCodeAskUserFlow(HumanStandardInputFlow)
74
+ ```
75
+
76
+ Refer to: https://huggingface.co/Tachi67/ExtendLibraryFlowModule/blob/main/ExtLibAskUserFlow.py
77
+
78
+ <a id="library"></a>
79
+
80
+ # library
81
+
82
+ <a id="run"></a>
83
+
84
+ # run
85
+
86
+ <a id="RunCodeFileEditAtomicFlow"></a>
87
+
88
+ # RunCodeFileEditAtomicFlow
89
+
90
+ <a id="RunCodeFileEditAtomicFlow.RunCodeFileEditAtomicFlow"></a>
91
+
92
+ ## RunCodeFileEditAtomicFlow Objects
93
+
94
+ ```python
95
+ class RunCodeFileEditAtomicFlow(CodeFileEditAtomicFlow)
96
+ ```
97
+
98
+ Refer to: https://huggingface.co/Tachi67/CodeFileEditFlowModule
99
+
100
+ <a id="__init__"></a>
101
+
102
+ # \_\_init\_\_
103
+
RunCodeAskUserFlow.py ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flow_modules.aiflows.HumanStandardInputFlowModule import HumanStandardInputFlow
2
+
3
+ from typing import Dict, Any
4
+
5
+ from aiflows.messages import UpdateMessage_Generic
6
+
7
+ from aiflows.utils import logging
8
+
9
+ log = logging.get_logger(f"aiflows.{__name__}")
10
+
11
+
12
+ class RunCodeAskUserFlow(HumanStandardInputFlow):
13
+ """Refer to: https://huggingface.co/Tachi67/ExtendLibraryFlowModule/blob/main/ExtLibAskUserFlow.py"""
14
+ def run(self,
15
+ input_data: Dict[str, Any]) -> Dict[str, Any]:
16
+
17
+ query_message = self._get_message(self.query_message_prompt_template, input_data)
18
+ state_update_message = UpdateMessage_Generic(
19
+ created_by=self.flow_config['name'],
20
+ updated_flow=self.flow_config["name"],
21
+ data={"query_message": query_message},
22
+ )
23
+ self._log_message(state_update_message)
24
+
25
+ log.info(query_message)
26
+ human_input = self._read_input()
27
+
28
+ response = {}
29
+ result = f"""
30
+ The following code was ran:
31
+ {input_data['code_ran']}
32
+ The execution result is:
33
+ {input_data['interpreter_output']}
34
+ The user's feedback is:
35
+ {human_input}
36
+ """
37
+ response["result"] = result
38
+ response["summary"] = f"Coder/run_code: \n" + result
39
+
40
+ return response
RunCodeAskUserFlow.yaml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ _target_: flow_modules.aiflows.RunCodeFlowModule.RunCodeAskUserFlow.instantiate_from_default_config
2
+
3
+ input_interface:
4
+ - "interpreter_output"
5
+ - "code_ran"
6
+ output_interface:
7
+ - "summary"
8
+ - "result"
9
+
10
+ request_multi_line_input_flag: False
11
+ end_of_input_string: EOI
12
+
13
+ query_message_prompt_template:
14
+ template: |2-
15
+ The following code was ran by the interpreter:
16
+ {{code_ran}}
17
+ Here's the execution result of the code:
18
+ {{interpreter_output}}
19
+ Please provide your feedback.
20
+ input_variables:
21
+ - "code_ran"
22
+ - "interpreter_output"
RunCodeFileEditAtomicFlow.py ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from typing import Dict, Any
3
+ from flow_modules.aiflows.CodeFileEditFlowModule import CodeFileEditAtomicFlow
4
+
5
+ class RunCodeFileEditAtomicFlow(CodeFileEditAtomicFlow):
6
+ """Refer to: https://huggingface.co/Tachi67/CodeFileEditFlowModule"""
7
+
8
+ def _generate_content(self, code_str, comment_sign) -> str:
9
+ if comment_sign == "<!-- -->":
10
+ instruction = (
11
+ "<!-- The below code will be executed.\n"
12
+ "Change the code if you consider necessary.\n"
13
+ "Shut this vscode session completely to start running the code. -->\n"
14
+ )
15
+ else:
16
+ instruction = (
17
+ f"{comment_sign} The below code will be executed.\n"
18
+ f"{comment_sign} Change the code if you consider necessary.\n"
19
+ f"{comment_sign} Shut this vscode session completely to start running the code.\n"
20
+ )
21
+ content = (
22
+ instruction +
23
+ "###########\n"
24
+ "# Code:\n" +
25
+ code_str +
26
+ "\n############\n"
27
+ )
28
+ return content
29
+
30
+ def _generate_temp_file_location(self, code_lib_location, file_extension):
31
+ directory = os.path.dirname(code_lib_location)
32
+ ret = os.path.join(directory, 'run_code_temp'+file_extension)
33
+ return ret
34
+
35
+ def _check_input(self, input_data: Dict[str, Any]):
36
+ assert "code" in input_data, "code is not passed to RunCodeFileEditAtomicFlow"
37
+ assert "memory_files" in input_data, "memory_files is not passed to RunCodeFileEditAtomicFlow"
38
+ assert "language" in input_data, "language is not passed to RunCodeFileEditAtomicFlow"
39
+
40
+ def _generate_file_extension_and_comment_sign(self, language: str):
41
+ details = {
42
+ "python": {"extension": ".py", "comment": "#"},
43
+ "bash": {"extension": ".sh", "comment": "#"},
44
+ "shell": {"extension": ".sh", "comment": "#"},
45
+ "javascript": {"extension": ".js", "comment": "//"},
46
+ "html": {"extension": ".html", "comment": "<!-- -->"},
47
+ "applescript": {"extension": ".scpt", "comment": "--"},
48
+ "r": {"extension": ".r", "comment": "#"},
49
+ "powershell": {"extension": ".ps1", "comment": "#"}
50
+ }
51
+ if language.lower() not in details:
52
+ raise NotImplemented
53
+ return details.get(language.lower())
54
+
55
+ def _generate_input_to_writer(self, input_data: Dict[str, Any]):
56
+ code_str = input_data['code']
57
+ code_lib_location = input_data["memory_files"]["code_library"]
58
+
59
+ # if we are running python code and if the code is importing the code library after one modification, we need
60
+ # to re-import the library.
61
+ code_lang = input_data["language"].lower()
62
+ code_lib_name = os.path.splitext(os.path.basename(code_lib_location))[0]
63
+ if code_lang == 'python' and code_lib_name in code_str and 'importlib.reload' not in code_str:
64
+ prepend_code = f"import importlib\nimport {code_lib_name}\nimportlib.reload({code_lib_name})\n"
65
+ code_str = prepend_code + code_str
66
+
67
+ lang_details = self._generate_file_extension_and_comment_sign(input_data["language"])
68
+ content_to_write = self._generate_content(code_str, lang_details["comment"])
69
+ file_location_to_write = self._generate_temp_file_location(code_lib_location, lang_details["extension"])
70
+ return content_to_write, file_location_to_write
RunCodeFileEditAtomicFlow.yaml ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ _target_: flow_modules.aiflows.RunCodeFlowModule.RunCodeFileEditAtomicFlow.instantiate_from_default_config
2
+ name: "RunCodeFileEditorAtomicFlow"
3
+ description: "A flow that writes code to be ran to a temp file"
4
+
5
+ input_interface:
6
+ - "code"
7
+ - "language"
8
+ - "memory_files"
9
+
10
+ output_interface:
11
+ - "code_editor_output"
12
+ - "temp_code_file_location"
RunCodeFlow.py ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from aiflows.base_flows import SequentialFlow
2
+ from aiflows.utils import logging
3
+
4
+ logging.set_verbosity_debug()
5
+ log = logging.get_logger(__name__)
6
+
7
+ class RunCodeFlow(SequentialFlow):
8
+ """This flow is used to run code in a file. It opens up the file in VSCode and waits for the user to save the file.
9
+ Once the file is saved, it reads the code from the file and executes it. It then returns the output of the execution.
10
+ Finally, the flow asks the user for feedback on the execution of the code.
11
+
12
+ *Input Interface*:
13
+ - code: The code to be executed.
14
+ - language: The language of the code to be executed.
15
+ - memory_files: The dictionary containing the location of the code library.
16
+
17
+ *Output Interface*:
18
+ - summary: The summary of the execution of the code. (To be written to the logs of the caller flow)
19
+ - result: The result of the execution of the code. (To be returned to the controller of the caller flow)
20
+ """
21
+ pass
RunCodeFlow.yaml ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: "RunCodeFlow"
2
+ description: "Run code in an interactive fashion"
3
+
4
+ _target_: flow_modules.aiflows.RunCodeFlowModule.RunCodeFlow.instantiate_from_default_config
5
+
6
+ input_interface:
7
+ - "memory_files"
8
+ - "language"
9
+ - "code"
10
+
11
+ output_interface:
12
+ - "summary"
13
+ - "result"
14
+
15
+ subflows_config:
16
+ RunCodeFileEdit:
17
+ _target_: flow_modules.aiflows.RunCodeFlowModule.RunCodeFileEditAtomicFlow.instantiate_from_default_config
18
+
19
+ ExecuteCode:
20
+ _target_: flow_modules.aiflows.RunCodeFlowModule.ExecuteCodeAtomicFlow.instantiate_from_default_config
21
+
22
+ AskUser:
23
+ _target_: flow_modules.aiflows.RunCodeFlowModule.RunCodeAskUserFlow.instantiate_from_default_config
24
+
25
+ early_exit_key: "EARLY_EXIT"
26
+
27
+ topology:
28
+ - goal: "Write the code & instructions to a temp file"
29
+ input_interface:
30
+ _target_: aiflows.interfaces.KeyInterface
31
+ additional_transformations:
32
+ - _target_: aiflows.data_transformations.KeyMatchInput
33
+ flow: RunCodeFileEdit
34
+ reset: false
35
+
36
+ - goal: "Run the code"
37
+ input_interface:
38
+ _target_: aiflows.interfaces.KeyInterface
39
+ additional_transformations:
40
+ - _target_: aiflows.data_transformations.KeyMatchInput
41
+ flow: ExecuteCode
42
+ reset: false
43
+
44
+ - goal: "Ask user for feedback"
45
+ flow: AskUser
46
+ reset: false
__init__.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ dependencies = [
2
+ {"url": "aiflows/CodeFileEditFlowModule", "revision": "main"},
3
+ {"url": "aiflows/InterpreterFlowModule", "revision": "main"},
4
+ {"url": "aiflows/HumanStandardInputFlowModule", "revision": "4ff043522c89a964ea3a928ce09811c51a2b5b98"},
5
+ ]
6
+
7
+ from aiflows import flow_verse
8
+
9
+ flow_verse.sync_dependencies(dependencies)
10
+
11
+ from .RunCodeFlow import RunCodeFlow
12
+ from .ExecuteCodeAtomicFlow import ExecuteCodeAtomicFlow
13
+ from .RunCodeFileEditAtomicFlow import RunCodeFileEditAtomicFlow
14
+ from .RunCodeAskUserFlow import RunCodeAskUserFlow
library.py ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ def add_two_numbers(a, b):
2
+ return a + b
run.py ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ import hydra
4
+
5
+ from aiflows.messages import InputMessage
6
+ from aiflows.utils.general_helpers import read_yaml_file
7
+
8
+ from aiflows import logging
9
+ from aiflows.flow_cache import CACHING_PARAMETERS, clear_cache
10
+
11
+ CACHING_PARAMETERS.do_caching = False # Set to True in order to disable caching
12
+ # clear_cache() # Uncomment this line to clear the cache
13
+
14
+ logging.set_verbosity_debug()
15
+ logging.auto_set_dir()
16
+
17
+ dependencies = [
18
+ {"url": "aiflows/CodeFileEditFlowModule", "revision": "main"},
19
+ {"url": "aiflows/InterpreterFlowModule", "revision": "main"},
20
+ {"url": "aiflows/HumanStandardInputFlowModule", "revision": "4ff043522c89a964ea3a928ce09811c51a2b5b98"},
21
+ {"url": "aiflows/RunCodeFlowModule", "revision": "main"}
22
+ ]
23
+
24
+ from aiflows import flow_verse
25
+
26
+ flow_verse.sync_dependencies(dependencies)
27
+
28
+ if __name__ == "__main__":
29
+ current_dir = os.getcwd()
30
+ cfg_path = os.path.join(current_dir, "RunCodeFlow.yaml")
31
+ cfg = read_yaml_file(cfg_path)
32
+
33
+
34
+ # ~~~ instantiating the flow and input data ~~~
35
+ RunCodeFlow = hydra.utils.instantiate(cfg, _recursive_=False, _convert_="partial")
36
+ memory_files = {"code_library": os.path.join(current_dir, "library.py")}
37
+ code = """
38
+ from library import add_two_numbers
39
+
40
+ add_two_numbers(1,1)
41
+ """
42
+ input_data = {
43
+ "memory_files": memory_files,
44
+ "language": "Python",
45
+ "code": code,
46
+ }
47
+ input_message = InputMessage.build(
48
+ data_dict=input_data,
49
+ src_flow="Launcher",
50
+ dst_flow=RunCodeFlow.name
51
+ )
52
+
53
+ # ~~~ calling the flow ~~~
54
+ output_message = RunCodeFlow(input_message)
55
+
56
+ print(output_message)