Tachi67 commited on
Commit
e8c208d
·
1 Parent(s): 72df706

Upload 7 files

Browse files
CodeTestingAtomicFlow.py ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import time
3
+ from typing import Dict, Any
4
+ from flow_modules.Tachi67.InterpreterFlowModule import InterpreterAtomicFlow
5
+
6
+
7
+ class CodeTestingAtomicFlow(InterpreterAtomicFlow):
8
+ def _wait_for_file_update(self, file_location, last_check_time, check_interval=1):
9
+ while True:
10
+ time.sleep(check_interval)
11
+ current_time = os.path.getmtime(file_location)
12
+ if current_time != last_check_time:
13
+ break
14
+ def _prepare_code_and_lang(self, input_data: Dict[str, Any]):
15
+ file_location = input_data["temp_code_file_location"]
16
+ input_data["language"] = "python"
17
+ with open(file_location, "r") as file:
18
+ code_str = file.read()
19
+ input_data["code"] = code_str
20
+
21
+ def _check_input(self, input_data: Dict[str, Any]):
22
+ assert "temp_code_file_location" in input_data, "temp_code_file_location not passed to CodeTestingAtomicFlow"
23
+ assert "temp_code_file_written_timestamp" in input_data, "temp_code_file_written_timestamp not passed to CodeTestingAtomicFlow"
24
+
25
+ def _delete_file(self, file_location):
26
+ if os.path.exists(file_location):
27
+ os.remove(file_location)
28
+
29
+ def run(
30
+ self,
31
+ input_data: Dict[str, Any]):
32
+ self._check_input(input_data)
33
+ file_loc = input_data["temp_code_file_location"]
34
+ last_timestamp = input_data["temp_code_file_written_timestamp"]
35
+ self._wait_for_file_update(file_loc, last_timestamp)
36
+ self._prepare_code_and_lang(input_data)
37
+ response = self._call()
38
+ self._delete_file(file_loc)
39
+ return {"test_results": response}
CodeTestingAtomicFlow.yaml ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ name: "CodeTestingAtomicFlow"
2
+ description: "A flow that runs test code"
3
+
4
+
5
+ input_interface:
6
+ - "temp_code_file_location"
7
+ - "temp_code_file_written_timestamp"
8
+
9
+ output_interface:
10
+ - "test_results"
TestCodeFileEditAtomicFlow.py ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from typing import Dict, Any
3
+ from flow_modules.Tachi67.CodeFileEditFlowModule import CodeFileEditAtomicFlow
4
+
5
+ class TestCodeFileEditAtomicFlow(CodeFileEditAtomicFlow):
6
+ def _generate_import_statement(self, code_lib_location):
7
+ module_dir = os.path.dirname(code_lib_location)
8
+ module_name = os.path.basename(code_lib_location).rstrip('.py')
9
+ import_code = (
10
+ f"import sys\n"
11
+ f"sys.path.insert(0, '{module_dir}')\n"
12
+ f"import {module_name}\n"
13
+ )
14
+ return import_code
15
+
16
+ def _generate_content(self, code_lib_location, code_str) -> str:
17
+ import_code_lib_str = self._generate_import_statement(code_lib_location)
18
+ content = (
19
+ "# Don't touch this import statement \n"
20
+ + import_code_lib_str + "\n"
21
+ "# Here is the code just generated \n" +
22
+ code_str + "\n"
23
+ "# Below, please provide code to test it.\n"
24
+ "# The simplest form could be just calling it with appropriate parameters. \n"
25
+ "# You could also assert the output, anyway, the test results will be informed to JARVIS. \n"
26
+ "# If you do not write anything, JARVIS just checks if the syntax is alright. \n"
27
+ "###########\n"
28
+ "\n # Test Code:\n" +
29
+ "\n############\n"
30
+ )
31
+ return content
32
+
33
+ def _generate_temp_file_location(self, code_lib_location):
34
+ directory = os.path.dirname(code_lib_location)
35
+ ret = os.path.join(directory, 'temp_tests.py')
36
+ return ret
37
+
38
+ def _check_input(self, input_data: Dict[str, Any]):
39
+ assert "code" in input_data, "code is not passed to TestCodeFileEditAtomicFlow"
40
+ assert "code_library" in input_data, "code_library is not passed to TestCodeFileEditAtomicFlow"
41
+
42
+ def _generate_input_to_writer(self, input_data: Dict[str, Any]):
43
+ code_str = input_data['code']
44
+ code_lib_location = input_data["code_library"]
45
+ content_to_write = self._generate_content(code_lib_location, code_str)
46
+ file_location_to_write = self._generate_temp_file_location(code_lib_location)
47
+ return content_to_write, file_location_to_write
TestCodeFileEditAtomicFlow.yaml ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: "TestCodeFileEditorAtomicFlow"
2
+ description: "A flow that writes tests code to a temp file"
3
+
4
+ input_interface:
5
+ - "code"
6
+ - "code_library"
7
+
8
+ output_interface:
9
+ - "code_editor_output"
10
+ - "temp_code_file_location"
11
+ - "temp_code_file_written_timestamp"
TestCodeFlow.py ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from copy import deepcopy
2
+ from typing import Any, Dict
3
+
4
+ from flows.base_flows import SequentialFlow
5
+ from flows.utils import logging
6
+
7
+ logging.set_verbosity_debug()
8
+ log = logging.get_logger(__name__)
9
+
10
+ class TestCodeFlow(SequentialFlow):
11
+ REQUIRED_KEYS_CONFIG = ["max_rounds", "early_exit_key", "topology", "memory_files"]
12
+
13
+ def __init__(
14
+ self,
15
+ memory_files: Dict[str, Any],
16
+ **kwargs
17
+ ):
18
+ super().__init__(**kwargs)
19
+ self.memory_files = memory_files
20
+
21
+ @classmethod
22
+ def instantiate_from_config(cls, config):
23
+ flow_config = deepcopy(config)
24
+
25
+ kwargs = {"flow_config": flow_config}
26
+
27
+ # ~~~ Set up memory file ~~~
28
+ memory_files = flow_config["memory_files"]
29
+ kwargs.update({"memory_files": memory_files})
30
+
31
+ # ~~~ Set up subflows ~~~
32
+ kwargs.update({"subflows": cls._set_up_subflows(flow_config)})
33
+
34
+ # ~~~ Instantiate flow ~~~
35
+ return cls(**kwargs)
36
+
37
+ def run(self, input_data: Dict[str, Any]) -> Dict[str, Any]:
38
+ # ~~~ sets the input_data in the flow_state dict ~~~
39
+ self._state_update_dict(update_data=input_data)
40
+
41
+ # ~~~ set the memory file to the flow state ~~~
42
+ self._state_update_dict(update_data={"memory_files": self.memory_files})
43
+
44
+ max_rounds = self.flow_config.get("max_rounds", 1)
45
+ if max_rounds is None:
46
+ log.info(f"Running {self.flow_config['name']} without `max_rounds` until the early exit condition is met.")
47
+
48
+ self._sequential_run(max_rounds=max_rounds)
49
+
50
+ output = self._get_output_from_state()
51
+
52
+ return output
TestCodeFlow.yaml ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: "TestCodeFlow"
2
+ description: "Test the code generated by InteractiveCodeGenFlow"
3
+
4
+ _target_: Tachi67.TestCodeFlowModule.TestCodeFlow.instantiate_from_default_config
5
+
6
+ memory_files: ???
7
+
8
+ input_interface:
9
+ - "code"
10
+
11
+ output_interface:
12
+ - "test_results"
13
+
14
+ subflows_config:
15
+ MemoryReading:
16
+ _target_: Tachi67.MemoryReadingFlowModule.MemoryReadingAtomicFlow.instantiate_from_default_config
17
+
18
+ TestCodeFileEdit:
19
+ _target_: TestCodeFileEditAtomicFlow.TestCodeFileEditAtomicFlow.instantiate_from_default_config
20
+
21
+ CodeTesting:
22
+ _target_: CodeTestingAtomicFlow.CodeTestingAtomicFlow.instantiate_from_default_config
23
+
24
+ early_exit_key: "EARLY_EXIT"
25
+
26
+ topology:
27
+ - goal: "Read in necessary memory"
28
+ input_interface:
29
+ _target_: flows.interfaces.KeyInterface
30
+ additional_transformations:
31
+ - _target_: flows.data_transformations.KeyMatchInput
32
+ flow: MemoryReading
33
+ reset: false
34
+
35
+ - goal: "Write the code & instructions for testing to a temp file"
36
+ input_interface:
37
+ _target_: flows.interfaces.KeyInterface
38
+ additional_transformations:
39
+ - _target_: flows.data_transformations.KeyMatchInput
40
+ flow: TestCodeFileEdit
41
+ reset: false
42
+
43
+ - goal: "Test the code"
44
+ input_interface:
45
+ _target_: flows.interfaces.KeyInterface
46
+ additional_transformations:
47
+ - _target_: flows.data_transformations.KeyMatchInput
48
+ flow: CodeTesting
49
+ reset: false
__init__.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ dependencies = [
2
+ {"url": "Tachi67/MemoryReadingFlowModule", "revision": "main"},
3
+ {"url": "Tachi67/CodeFileEditFlowModule", "revision": "main"},
4
+ {"url": "Tachi67/InterpreterFlowModule", "revision": "main"},
5
+ ]
6
+
7
+ from flows import flow_verse
8
+
9
+ flow_verse.sync_dependencies(dependencies)
10
+
11
+ from .CodeTestingAtomicFlow import CodeTestingAtomicFlow
12
+ from .TestCodeFileEditAtomicFlow import TestCodeFileEditAtomicFlow
13
+ from .TestCodeFlow import TestCodeFlow