Upload 9 files
Browse files- ExecuteCodeAtomicFlow.py +56 -0
- ExecuteCodeAtomicFlow.yaml +12 -0
- RunCodeAskUserFlow.py +39 -0
- RunCodeAskUserFlow.yaml +14 -0
- RunCodeFileEditAtomicFlow.py +80 -0
- RunCodeFileEditAtomicFlow.yaml +12 -0
- RunCodeFlow.py +8 -0
- RunCodeFlow.yaml +46 -0
- __init__.py +14 -0
ExecuteCodeAtomicFlow.py
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import time
|
3 |
+
from typing import Dict, Any
|
4 |
+
import subprocess
|
5 |
+
from flow_modules.Tachi67.InterpreterFlowModule import InterpreterAtomicFlow
|
6 |
+
|
7 |
+
|
8 |
+
class ExecuteCodeAtomicFlow(InterpreterAtomicFlow):
|
9 |
+
def _prepare_code(self, input_data: Dict[str, Any]):
|
10 |
+
file_location = input_data["temp_code_file_location"]
|
11 |
+
start_marker = "# Code:\n"
|
12 |
+
end_marker = "############"
|
13 |
+
code_started = False
|
14 |
+
code_str = ""
|
15 |
+
with open(file_location, 'r') as file:
|
16 |
+
for line in file:
|
17 |
+
if line.strip() == start_marker.strip():
|
18 |
+
code_started = True
|
19 |
+
continue
|
20 |
+
if line.strip() == end_marker.strip():
|
21 |
+
break
|
22 |
+
if code_started:
|
23 |
+
code_str += line
|
24 |
+
input_data["code"] = code_str
|
25 |
+
|
26 |
+
def _check_input(self, input_data: Dict[str, Any]):
|
27 |
+
assert "temp_code_file_location" in input_data, "temp_code_file_location not passed to ExecuteCodeAtomicFlow"
|
28 |
+
assert "language" in input_data, "language not passed to ExecuteCodeAtomicFlow"
|
29 |
+
|
30 |
+
def _delete_file(self, file_location):
|
31 |
+
if os.path.exists(file_location):
|
32 |
+
os.remove(file_location)
|
33 |
+
|
34 |
+
def _open_file_and_wait_for_upd(self, file_location):
|
35 |
+
try:
|
36 |
+
process = subprocess.Popen(["code", file_location])
|
37 |
+
except Exception:
|
38 |
+
raise
|
39 |
+
while True:
|
40 |
+
if process.poll() is not None:
|
41 |
+
break
|
42 |
+
time.sleep(1)
|
43 |
+
|
44 |
+
def run(
|
45 |
+
self,
|
46 |
+
input_data: Dict[str, Any]):
|
47 |
+
self._check_input(input_data)
|
48 |
+
file_loc = input_data["temp_code_file_location"]
|
49 |
+
self._open_file_and_wait_for_upd(file_loc)
|
50 |
+
self._prepare_code(input_data)
|
51 |
+
self._process_input_data(input_data)
|
52 |
+
execution_output = self._call()
|
53 |
+
self._delete_file(file_loc)
|
54 |
+
code_ran = input_data["code"].deepcopy()
|
55 |
+
response = {"interpreter_output": execution_output, "code_ran": code_ran}
|
56 |
+
return response
|
ExecuteCodeAtomicFlow.yaml
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
_target_: Tachi67.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"
|
RunCodeAskUserFlow.py
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from flow_modules.aiflows.HumanStandardInputFlowModule import HumanStandardInputFlow
|
2 |
+
|
3 |
+
from typing import Dict, Any
|
4 |
+
|
5 |
+
from flows.messages import UpdateMessage_Generic
|
6 |
+
|
7 |
+
from flows.utils import logging
|
8 |
+
|
9 |
+
log = logging.get_logger(f"flows.{__name__}")
|
10 |
+
|
11 |
+
|
12 |
+
class RunCodeAskUserFlow(HumanStandardInputFlow):
|
13 |
+
def run(self,
|
14 |
+
input_data: Dict[str, Any]) -> Dict[str, Any]:
|
15 |
+
|
16 |
+
query_message = self._get_message(self.query_message_prompt_template, input_data)
|
17 |
+
state_update_message = UpdateMessage_Generic(
|
18 |
+
created_by=self.flow_config['name'],
|
19 |
+
updated_flow=self.flow_config["name"],
|
20 |
+
data={"query_message": query_message},
|
21 |
+
)
|
22 |
+
self._log_message(state_update_message)
|
23 |
+
|
24 |
+
log.info(query_message)
|
25 |
+
human_input = self._read_input()
|
26 |
+
|
27 |
+
response = {}
|
28 |
+
result = f"""
|
29 |
+
The following code was ran:
|
30 |
+
{input_data['code_ran']}
|
31 |
+
The execution result is:
|
32 |
+
{input_data['interpreter_output']}
|
33 |
+
The user's feedback is:
|
34 |
+
{human_input}
|
35 |
+
"""
|
36 |
+
response["result"] = result
|
37 |
+
response["summary"] = f"Coder/run_code: \n" + result
|
38 |
+
|
39 |
+
return response
|
RunCodeAskUserFlow.yaml
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
_target_: Tachi67.RunCodeFlowModule.RunCodeAskUserFlow.instantiate_from_default_config
|
2 |
+
request_multi_line_input_flag: False
|
3 |
+
end_of_input_string: EOI
|
4 |
+
|
5 |
+
query_message_prompt_template:
|
6 |
+
template: |2-
|
7 |
+
The following code was ran by the interpreter:
|
8 |
+
{{code_ran}}
|
9 |
+
Here's the execution result of the code:
|
10 |
+
{{interpreter_output}}
|
11 |
+
Please provide your feedback.
|
12 |
+
input_variables:
|
13 |
+
- "code_ran"
|
14 |
+
- "interpreter_output"
|
RunCodeFileEditAtomicFlow.py
ADDED
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
from typing import Dict, Any
|
3 |
+
from flow_modules.Tachi67.CodeFileEditFlowModule import CodeFileEditAtomicFlow
|
4 |
+
|
5 |
+
class RunCodeFileEditAtomicFlow(CodeFileEditAtomicFlow):
|
6 |
+
|
7 |
+
def _generate_content(self, code_str, comment_sign) -> str:
|
8 |
+
if comment_sign == "<!-- -->":
|
9 |
+
instruction = (
|
10 |
+
"<!-- The below code will be executed.\n"
|
11 |
+
"Change the code if you consider necessary.\n"
|
12 |
+
"Shut this vscode session completely to start running the code. -->\n"
|
13 |
+
)
|
14 |
+
else:
|
15 |
+
instruction = (
|
16 |
+
f"{comment_sign} The below code will be executed.\n"
|
17 |
+
f"{comment_sign} Change the code if you consider necessary.\n"
|
18 |
+
f"{comment_sign} Shut this vscode session completely to start running the code.\n"
|
19 |
+
)
|
20 |
+
content = (
|
21 |
+
instruction +
|
22 |
+
"###########\n"
|
23 |
+
"# Code:\n" +
|
24 |
+
code_str +
|
25 |
+
"\n############\n"
|
26 |
+
)
|
27 |
+
return content
|
28 |
+
|
29 |
+
def _generate_temp_file_location(self, code_lib_location, file_extension):
|
30 |
+
directory = os.path.dirname(code_lib_location)
|
31 |
+
ret = os.path.join(directory, 'run_code_temp'+'.'+file_extension)
|
32 |
+
return ret
|
33 |
+
|
34 |
+
def _check_input(self, input_data: Dict[str, Any]):
|
35 |
+
assert "code" in input_data, "code is not passed to RunCodeFileEditAtomicFlow"
|
36 |
+
assert "memory_files" in input_data, "memory_files is not passed to RunCodeFileEditAtomicFlow"
|
37 |
+
assert "language" in input_data, "language is not passed to RunCodeFileEditAtomicFlow"
|
38 |
+
|
39 |
+
def _generate_file_extension_and_comment_sign(self, language: str):
|
40 |
+
details = {
|
41 |
+
"python": {"extension": ".py", "comment": "#"},
|
42 |
+
"bash": {"extension": ".sh", "comment": "#"},
|
43 |
+
"shell": {"extension": ".sh", "comment": "#"},
|
44 |
+
"javascript": {"extension": ".js", "comment": "//"},
|
45 |
+
"html": {"extension": ".html", "comment": "<!-- -->"},
|
46 |
+
"applescript": {"extension": ".scpt", "comment": "--"},
|
47 |
+
"r": {"extension": ".r", "comment": "#"},
|
48 |
+
"powershell": {"extension": ".ps1", "comment": "#"}
|
49 |
+
}
|
50 |
+
if language.lower() not in details:
|
51 |
+
raise NotImplemented
|
52 |
+
return details.get(language.lower())
|
53 |
+
|
54 |
+
def _generate_input_to_writer(self, input_data: Dict[str, Any]):
|
55 |
+
code_str = input_data['code']
|
56 |
+
code_lib_location = input_data["memory_files"]["code_library"]
|
57 |
+
lang_details = self._generate_file_extension_and_comment_sign(input_data["language"])
|
58 |
+
content_to_write = self._generate_content(code_str, lang_details["comment"])
|
59 |
+
file_location_to_write = self._generate_temp_file_location(code_lib_location, lang_details["extension"])
|
60 |
+
return content_to_write, file_location_to_write
|
61 |
+
|
62 |
+
def run(
|
63 |
+
self,
|
64 |
+
input_data: Dict[str, Any]
|
65 |
+
):
|
66 |
+
self._check_input(input_data)
|
67 |
+
|
68 |
+
# ~~~ Getting input data to the file editor ~~~
|
69 |
+
content_to_write, file_location_to_write = self._generate_input_to_writer(input_data)
|
70 |
+
|
71 |
+
# ~~~ Calling the writer function ~~~
|
72 |
+
_, code_editor_output, temp_file_location, _ = self._write_code_content_to_file(
|
73 |
+
file_location_to_write, content_to_write)
|
74 |
+
|
75 |
+
|
76 |
+
# ~~~ Generating return variables ~~~
|
77 |
+
response = {}
|
78 |
+
response["code_editor_output"] = code_editor_output
|
79 |
+
response["temp_code_file_location"] = temp_file_location
|
80 |
+
return response
|
RunCodeFileEditAtomicFlow.yaml
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
_target_: Tachi67.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,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from flows.base_flows import SequentialFlow
|
2 |
+
from flows.utils import logging
|
3 |
+
|
4 |
+
logging.set_verbosity_debug()
|
5 |
+
log = logging.get_logger(__name__)
|
6 |
+
|
7 |
+
class RunCodeFlow(SequentialFlow):
|
8 |
+
pass
|
RunCodeFlow.yaml
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: "RunCodeFlow"
|
2 |
+
description: "Run code in an interactive fashion"
|
3 |
+
|
4 |
+
_target_: Tachi67.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_: Tachi67.RunCodeFlowModule.RunCodeFileEditAtomicFlow.instantiate_from_default_config
|
18 |
+
|
19 |
+
ExecuteCode:
|
20 |
+
_target_: Tachi67.RunCodeFlowModule.ExecuteCodeAtomicFlow.instantiate_from_default_config
|
21 |
+
|
22 |
+
AskUser:
|
23 |
+
_target_: Tachi67.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_: flows.interfaces.KeyInterface
|
31 |
+
additional_transformations:
|
32 |
+
- _target_: flows.data_transformations.KeyMatchInput
|
33 |
+
flow: RunCodeFileEdit
|
34 |
+
reset: false
|
35 |
+
|
36 |
+
- goal: "Run the code"
|
37 |
+
input_interface:
|
38 |
+
_target_: flows.interfaces.KeyInterface
|
39 |
+
additional_transformations:
|
40 |
+
- _target_: flows.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": "Tachi67/CodeFileEditFlowModule", "revision": "main"},
|
3 |
+
{"url": "Tachi67/InterpreterFlowModule", "revision": "main"},
|
4 |
+
{"url": "aiflows/HumanStandardInputFlowModule", "revision": "5683a922372c5fa90be9f6447d6662d8d80341fc"},
|
5 |
+
]
|
6 |
+
|
7 |
+
from flows 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
|