TestCodeFlowModule / TestCodeFlow.py
Tachi67's picture
add more docs & comments
e81ee32 verified
from copy import deepcopy
from typing import Any, Dict
from aiflows.base_flows import SequentialFlow
from aiflows.utils import logging
logging.set_verbosity_debug()
log = logging.get_logger(__name__)
class TestCodeFlow(SequentialFlow):
"""This class is used to test code. It is a sequential flow that runs the following steps:
1. Prepares the code to be tested, it is composed of the code to be tested and necessary import statements manually added.
2. Opens the code in VSCode and waits for the user to clode the vscode session. The user is able to add tests.
3. The following will be tested:
a. (Default & Compulsory) Code syntax;
b. (Added by user) Any other tests.
4. Runs the test and returns the output.
*Input Interface*:
- `code` (str): The code to be tested.
*Output Interface*:
- `feedback` (str): The test results.
*Configuration Parameters*:
- `memory_files`: The memory files to be used in the flow, typically we need to have the code library as memory file here.
- `input_interface`: The input interface of the flow.
- `output_interface`: The output interface of the flow.
- `subflows_config`: The subflows configuration.
- `topology`: The topology of the subflows.
"""
REQUIRED_KEYS_CONFIG = ["max_rounds", "early_exit_key", "topology", "memory_files"]
def __init__(
self,
memory_files: Dict[str, Any],
**kwargs
):
"""
This function instantiates the class.
:param memory_files: The memory files to be used in the flow, typically we need to have the code library as memory file here.
:type memory_files: Dict[str, Any]
:param kwargs: The keyword arguments.
:type kwargs: Any
"""
super().__init__(**kwargs)
self.memory_files = memory_files
@classmethod
def instantiate_from_config(cls, config):
"""
This function instantiates the class from a configuration dictionary.
:param config: The configuration dictionary.
:type config: Dict[str, Any]
:return: The instantiated class.
:rtype: TestCodeFlow
"""
flow_config = deepcopy(config)
kwargs = {"flow_config": flow_config}
# ~~~ Set up memory file ~~~
memory_files = flow_config["memory_files"]
kwargs.update({"memory_files": memory_files})
# ~~~ Set up subflows ~~~
kwargs.update({"subflows": cls._set_up_subflows(flow_config)})
# ~~~ Instantiate flow ~~~
return cls(**kwargs)
def run(self, input_data: Dict[str, Any]) -> Dict[str, Any]:
"""
This function runs the flow.
:param input_data: The input data.
:type input_data: Dict[str, Any]
:return: The output data.
:rtype: Dict[str, Any]
"""
# ~~~ sets the input_data in the flow_state dict ~~~
self._state_update_dict(update_data=input_data)
# ~~~ set the memory file to the flow state ~~~
self._state_update_dict(update_data={"memory_files": self.memory_files})
max_rounds = self.flow_config.get("max_rounds", 1)
if max_rounds is None:
log.info(f"Running {self.flow_config['name']} without `max_rounds` until the early exit condition is met.")
self._sequential_run(max_rounds=max_rounds)
output = self._get_output_from_state()
return output