Tachi67 commited on
Commit
d30a78e
·
1 Parent(s): 592a9a3

Upload 7 files

Browse files
AbstractBossFlow.py ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from copy import deepcopy
2
+ from typing import Dict, Any
3
+
4
+ from aiflows.base_flows import SequentialFlow
5
+ from aiflows.utils import logging
6
+ from abc import ABC
7
+
8
+
9
+ logging.set_verbosity_debug()
10
+ log = logging.get_logger(__name__)
11
+
12
+ class AbstractBossFlow(SequentialFlow, ABC):
13
+ """This class is an abstraction of memory-planner-controller-executor flow. At a higher level, it is
14
+ an abstract agent empowered by multiple language models and subsequent tools like code interpreters, etc.
15
+ It is designed to cooperate with memory management mechanisms, lm-powered planner and controller, and
16
+ arbitrary executors.
17
+
18
+ *Configuration Parameters*
19
+
20
+ - `name` (str): Name of the flow.
21
+ - `description` (str): Description of the flow.
22
+ - `memory_files` (dict): A dictionary of memory files. The keys are the names of the memory files and the values
23
+ are the path to the memory files. Typical memory files include plan, logs, code library.
24
+ - `subflows_config`:
25
+ - MemoryReading: reads the content of the memory files into the flow states for later use.
26
+ - Planner: make a step-by-step plan based on the current goal.
27
+ - CtrlExMem: controller-executor agent with memory reading and memory writing, it will execute the plan generated by the planner.
28
+ - `early_exit_key` (str): The key in the flow state that indicates the early exit condition.
29
+ - `topology` (list) : The topology of the flow.
30
+
31
+ *Input Interface (expected input)*
32
+
33
+ - `goal` (str): The goal from the caller (source flow)
34
+
35
+ *Output Interface (expected output)*
36
+
37
+ - `result` (str): The result of the flow, the result will be returned to the caller.
38
+ - `summary` (str): The summary of the flow, the summary will be logged into the logs of the caller flow.
39
+
40
+ :param memory_files: A dictionary of memory files. The keys are the names of the memory files and the values are the path to the memory files.
41
+ :type memory_files: dict
42
+ """
43
+ REQUIRED_KEYS_CONFIG = ["max_rounds", "early_exit_key", "topology", "memory_files"]
44
+
45
+ def __init__(
46
+ self,
47
+ memory_files: Dict[str, Any],
48
+ **kwargs
49
+ ):
50
+ super().__init__(**kwargs)
51
+ self.memory_files = memory_files
52
+
53
+ @classmethod
54
+ def instantiate_from_config(cls, config):
55
+ """This method instantiates the flow from a configuration dictionary.
56
+
57
+ :param config: The configuration dictionary.
58
+ :type config: dict
59
+ """
60
+ flow_config = deepcopy(config)
61
+
62
+ kwargs = {"flow_config": flow_config}
63
+
64
+ # ~~~ Set up memory file ~~~
65
+ memory_files = flow_config["memory_files"]
66
+ kwargs.update({"memory_files": memory_files})
67
+
68
+ # ~~~ Set up subflows ~~~
69
+ kwargs.update({"subflows": cls._set_up_subflows(flow_config)})
70
+
71
+ # ~~~ Instantiate flow ~~~
72
+ return cls(**kwargs)
73
+
74
+ def run(self, input_data: Dict[str, Any]) -> Dict[str, Any]:
75
+ """This method runs the flow.
76
+
77
+ :param input_data: The input data, the input_data is supposed to contain 'goal'
78
+ :type input_data: dict
79
+ """
80
+ # ~~~ sets the input_data in the flow_state dict ~~~
81
+ self._state_update_dict(update_data=input_data)
82
+
83
+ # ~~~ set the memory file to the flow state ~~~
84
+ self._state_update_dict(update_data={"memory_files": self.memory_files})
85
+
86
+ max_rounds = self.flow_config.get("max_rounds", 1)
87
+ if max_rounds is None:
88
+ log.info(f"Running {self.flow_config['name']} without `max_rounds` until the early exit condition is met.")
89
+
90
+ self._sequential_run(max_rounds=max_rounds)
91
+
92
+ output = self._get_output_from_state()
93
+
94
+ return output
AbstractBossFlow.yaml ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: "AbstractBossFlow"
2
+ description: "Abstract class of a boss, e.g. coder, ExtendLibrary, etc."
3
+
4
+ _target_: flow_modules.aiflows.AbstractBossFlowModule.AbstractBossFlow.instantiate_from_default_config
5
+
6
+ memory_files: ???
7
+
8
+ input_interface:
9
+ - "goal"
10
+
11
+ output_interface:
12
+ - "result"
13
+ - "summary" # to be written into the logs of the upper level boss
14
+
15
+ subflows_config:
16
+ MemoryReading:
17
+ _target_: flow_modules.aiflows.MemoryReadingFlowModule.MemoryReadingAtomicFlow.instantiate_from_default_config
18
+
19
+ Planner:
20
+ _target_: flow_modules.aiflows.PlanWriterFlowModule.PlanWriterFlow.instantiate_from_default_config
21
+
22
+ # the flow with a controller, few executors in a branch, memory reading and memory writing
23
+ CtrlExMem:
24
+ _target_: flow_modules.aiflows.AbstractBossFlowModule.CtrlExMemFlow.instantiate_from_default_config
25
+
26
+ early_exit_key: "EARLY_EXIT"
27
+
28
+ topology:
29
+ - goal: "Read in necessary memory"
30
+ input_interface:
31
+ _target_: aiflows.interfaces.KeyInterface
32
+ additional_transformations:
33
+ - _target_: aiflows.data_transformations.KeyMatchInput
34
+ flow: MemoryReading
35
+ reset: false
36
+
37
+ - goal: "Make plans in an interactive fashion, write the plan into the plan file"
38
+ input_interface:
39
+ _target_: aiflows.interfaces.KeyInterface
40
+ additional_transformations:
41
+ - _target_: aiflows.data_transformations.KeyMatchInput
42
+ flow: Planner
43
+ reset: false
44
+
45
+ - goal: "Execute the plan and return answer & a summary of what was done"
46
+ input_interface:
47
+ _target_: aiflows.interfaces.KeyInterface
48
+ additional_transformations:
49
+ - _target_: aiflows.data_transformations.KeyMatchInput
50
+ flow: CtrlExMem
51
+ reset: false
CtrlExMemFlow.py ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Dict, Any
2
+
3
+ from aiflows.base_flows import CircularFlow
4
+ from aiflows.utils import logging
5
+ from abc import ABC, abstractmethod
6
+
7
+
8
+ logging.set_verbosity_debug()
9
+ log = logging.get_logger(__name__)
10
+
11
+
12
+ class CtrlExMemFlow(CircularFlow, ABC):
13
+ """This class is the controller-executor agent with memory reading and memory writing, it will execute the plan
14
+ generated by the planner. This flow is, at a higher level, a circular flow, it runs until either max_round is
15
+ reached, or the controller decides to early exit (see: detect_finish_or_continue)
16
+
17
+ The brain of the flow is the controller, the controller decides what action (which branch of the branching flow)
18
+ to take next. The controller can also decide to early exit the flow, in which case the flow will stop. After the
19
+ controller decides what action to take, the controller will pass the action to the executor, the executor will
20
+ execute the action, yielding `result` and `summary`, which respectively will be passed to the controller and the
21
+ memory writer (into logs of the upper layer of flow). Depending on the `result`, the controller will decide what
22
+ action to take next.
23
+
24
+ *Configuration Parameters*:
25
+ - `name` (str): Name of the flow.
26
+ - `description` (str): Description of the flow.
27
+ - `max_round` (int): The maximum number of rounds the flow will run. Default: 30.
28
+ - `subflows_config` (dict): The configuration of the subflows.
29
+ - `Controller` (dict): The configuration of the controller. It is important that the target of the controller (instance customizable by the user) and the api information should be specified.
30
+ - `Executor` (dict): The executor of the flow, it is supposed to be a branching flow. To instantiate the executor, the user needs to specify the subflows of the executor (i.e. the actual tools that can be used by the agent, e.g. a flow for interpreting code)
31
+ - `MemoryWriting` (dict): The configuration of the memory writer. There is an existing memory writing flow implemented.
32
+ - 'MemoryReading' (dict): The configuration of the memory reader. There is an existing memory reading flow implemented.
33
+ - `topology` (List): The topology of the subflows, notice that the output interface of the Controller must be implemented and specified.
34
+
35
+ *Input Interface*:
36
+ - `plan` (str): The plan generated by the planner, the CtrlExMem flow should follow the plan.
37
+ - `memory_files` (dict): mem_name - memfile_path pairs, the memory files that the memory reader will read from.
38
+ - `goal` (str): The goal of the flow
39
+ - `logs` (str): Execution history of the flow, contains all actions taken by each subflow of the flow.
40
+
41
+ *Output Interface*:
42
+ - `result` (str): The result of the flow, will be returned to the controller of the caller flow.
43
+ - `summary` (str): The summary of the flow, will be written to the logs of the caller flow.
44
+
45
+ """
46
+ @abstractmethod
47
+ def _on_reach_max_round(self):
48
+ """This function will be called when the flow reaches the maximum number of rounds."""
49
+ pass
50
+
51
+ @abstractmethod
52
+ @CircularFlow.output_msg_payload_processor
53
+ def detect_finish_or_continue(self, output_payload: Dict[str, Any], src_flow) -> Dict[str, Any]:
54
+ """This function is called after the Controller, it is used to:
55
+ 1. Check if the Controller decides to early-exit, if so, implement necessary logics for exiting e.g. drafting result and summary, etc.
56
+ 2. For other commands called by the controller, implement necessary logics for the flow to continue e.g. providing necessary information to the branching flow.
57
+ :param output_payload: The output payload of the Controller.
58
+ :type output_payload: Dict[str, Any]
59
+ :param src_flow: The source flow of the Controller.
60
+ :type src_flow: Flow
61
+ :return: The input payload of the Executor.
62
+ """
63
+ pass
CtrlExMemFlow.yaml ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Abstract class, should provide more information in subclasses
2
+
3
+ _target_: flow_modules.aiflows.AbstractBossFlowModule.CtrlExMemFlow.instantiate_from_default_config
4
+
5
+ name: "AbstractCtrlExMemFlow"
6
+ description: "Abstract class of controller-executor flow with mem reading and mem writing"
7
+ max_rounds: 30
8
+
9
+ input_interface:
10
+ - "plan"
11
+ - "memory_files"
12
+ - "goal"
13
+ - "logs"
14
+
15
+ output_interface:
16
+ - "summary"
17
+ - "result"
18
+
19
+ subflows_config:
20
+ Controller:
21
+ _target_: ??? # controller of the flow, could be a subclass of ChatAtomic flow, see https://huggingface.co/Tachi67/CodeWriterFlowModule/blob/main/CodeWriterCtrlFlow.py
22
+ backend:
23
+ api_infos: ???
24
+ model_name:
25
+ openai: gpt-4
26
+ azure: azure/gpt-4
27
+ # In subclasses, should provide specific command and command args.
28
+ # E.g.,
29
+ # commands:
30
+ # wiki_search:
31
+ # description: "Performs a search on Wikipedia."
32
+ # input_args: ["search_term"]
33
+
34
+ Executor:
35
+ _target_: aiflows.base_flows.BranchingFlow.instantiate_from_default_config
36
+ # In subclasses, should provide what are the branches of executors
37
+ # E.g.,
38
+ # subflows_config:
39
+ # wiki_search:
40
+ # _target_: .WikiSearchAtomicFlow.instantiate_from_default_config
41
+
42
+ MemoryWriting:
43
+ _target_: flow_modules.aiflows.MemoryWritingFlowModule.MemoryWritingAtomicFlow.instantiate_from_default_config
44
+ # default input interface is summary & memory_files
45
+
46
+ MemoryReading:
47
+ _target_: flow_modules.aiflows.MemoryReadingFlowModule.MemoryReadingAtomicFlow.instantiate_from_default_config
48
+ # should provide the output of MemRead in the CtrlExMem flow e.g. plan, logs, code_library
49
+ # output is then like {"plan":"plan string", "code_library": "function signatures in the code library"}
50
+ # default output interface is code_library
51
+
52
+ topology:
53
+ - goal: "Select the next action and prepare the input for the executor."
54
+ input_interface:
55
+ _target_: aiflows.interfaces.KeyInterface
56
+ additional_transformations:
57
+ - _target_: aiflows.data_transformations.KeyMatchInput
58
+ flow: Controller
59
+ output_interface: ???
60
+ # In subclasses, should provide name of function name of output processor
61
+ #_target_: Controller.detect_finish_or_continue
62
+ reset: false
63
+
64
+ - goal: "Execute the action specified by the Controller."
65
+ input_interface:
66
+ _target_: aiflows.interfaces.KeyInterface
67
+ keys_to_rename:
68
+ command: branch
69
+ command_args: branch_input_data
70
+ keys_to_select: ["branch", "branch_input_data"]
71
+ flow: Executor
72
+ output_interface:
73
+ _target_: aiflows.interfaces.KeyInterface
74
+ # in subclasses, should provide corresponding output interface of branches
75
+ keys_to_rename:
76
+ branch_output_data.summary: summary
77
+ branch_output_data.result: result
78
+ keys_to_delete: [ "branch_output_data" ]
79
+ reset: false
80
+
81
+ - goal: "Write memory to memory files"
82
+ input_interface:
83
+ _target_: aiflows.interfaces.KeyInterface
84
+ additional_transformations:
85
+ - _target_: aiflows.data_transformations.KeyMatchInput
86
+ flow: MemoryWriting
87
+ reset: false
88
+
89
+ - goal: "Read memory from memory files (flow_state)"
90
+ input_interface:
91
+ _target_: aiflows.interfaces.KeyInterface
92
+ additional_transformations:
93
+ - _target_: aiflows.data_transformations.KeyMatchInput
94
+ flow: MemoryReading
95
+ reset: false
README.md CHANGED
@@ -1,3 +1,157 @@
1
- ---
2
- license: mit
3
- ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Table of Contents
2
+
3
+ * [AbstractBossFlow](#AbstractBossFlow)
4
+ * [AbstractBossFlow](#AbstractBossFlow.AbstractBossFlow)
5
+ * [instantiate\_from\_config](#AbstractBossFlow.AbstractBossFlow.instantiate_from_config)
6
+ * [run](#AbstractBossFlow.AbstractBossFlow.run)
7
+ * [CtrlExMemFlow](#CtrlExMemFlow)
8
+ * [CtrlExMemFlow](#CtrlExMemFlow.CtrlExMemFlow)
9
+ * [detect\_finish\_or\_continue](#CtrlExMemFlow.CtrlExMemFlow.detect_finish_or_continue)
10
+ * [\_\_init\_\_](#__init__)
11
+
12
+ <a id="AbstractBossFlow"></a>
13
+
14
+ # AbstractBossFlow
15
+
16
+ <a id="AbstractBossFlow.AbstractBossFlow"></a>
17
+
18
+ ## AbstractBossFlow Objects
19
+
20
+ ```python
21
+ class AbstractBossFlow(SequentialFlow, ABC)
22
+ ```
23
+
24
+ This class is an abstraction of memory-planner-controller-executor flow. At a higher level, it is
25
+
26
+ an abstract agent empowered by multiple language models and subsequent tools like code interpreters, etc.
27
+ It is designed to cooperate with memory management mechanisms, lm-powered planner and controller, and
28
+ arbitrary executors.
29
+
30
+ *Configuration Parameters*
31
+
32
+ - `name` (str): Name of the flow.
33
+ - `description` (str): Description of the flow.
34
+ - `memory_files` (dict): A dictionary of memory files. The keys are the names of the memory files and the values
35
+ are the path to the memory files. Typical memory files include plan, logs, code library.
36
+ - `subflows_config`:
37
+ - MemoryReading: reads the content of the memory files into the flow states for later use.
38
+ - Planner: make a step-by-step plan based on the current goal.
39
+ - CtrlExMem: controller-executor agent with memory reading and memory writing, it will execute the plan generated by the planner.
40
+ - `early_exit_key` (str): The key in the flow state that indicates the early exit condition.
41
+ - `topology` (list) : The topology of the flow.
42
+
43
+ *Input Interface (expected input)*
44
+
45
+ - `goal` (str): The goal from the caller (source flow)
46
+
47
+ *Output Interface (expected output)*
48
+
49
+ - `result` (str): The result of the flow, the result will be returned to the caller.
50
+ - `summary` (str): The summary of the flow, the summary will be logged into the logs of the caller flow.
51
+
52
+ **Arguments**:
53
+
54
+ - `memory_files` (`dict`): A dictionary of memory files. The keys are the names of the memory files and the values are the path to the memory files.
55
+
56
+ <a id="AbstractBossFlow.AbstractBossFlow.instantiate_from_config"></a>
57
+
58
+ #### instantiate\_from\_config
59
+
60
+ ```python
61
+ @classmethod
62
+ def instantiate_from_config(cls, config)
63
+ ```
64
+
65
+ This method instantiates the flow from a configuration dictionary.
66
+
67
+ **Arguments**:
68
+
69
+ - `config` (`dict`): The configuration dictionary.
70
+
71
+ <a id="AbstractBossFlow.AbstractBossFlow.run"></a>
72
+
73
+ #### run
74
+
75
+ ```python
76
+ def run(input_data: Dict[str, Any]) -> Dict[str, Any]
77
+ ```
78
+
79
+ This method runs the flow.
80
+
81
+ **Arguments**:
82
+
83
+ - `input_data` (`dict`): The input data, the input_data is supposed to contain 'goal'
84
+
85
+ <a id="CtrlExMemFlow"></a>
86
+
87
+ # CtrlExMemFlow
88
+
89
+ <a id="CtrlExMemFlow.CtrlExMemFlow"></a>
90
+
91
+ ## CtrlExMemFlow Objects
92
+
93
+ ```python
94
+ class CtrlExMemFlow(CircularFlow, ABC)
95
+ ```
96
+
97
+ This class is the controller-executor agent with memory reading and memory writing, it will execute the plan
98
+ generated by the planner. This flow is, at a higher level, a circular flow, it runs until either max_round is
99
+ reached, or the controller decides to early exit (see: detect_finish_or_continue)
100
+
101
+ The brain of the flow is the controller, the controller decides what action (which branch of the branching flow)
102
+ to take next. The controller can also decide to early exit the flow, in which case the flow will stop. After the
103
+ controller decides what action to take, the controller will pass the action to the executor, the executor will
104
+ execute the action, yielding `result` and `summary`, which respectively will be passed to the controller and the
105
+ memory writer (into logs of the upper layer of flow). Depending on the `result`, the controller will decide what
106
+ action to take next.
107
+
108
+ *Configuration Parameters*:
109
+ - `name` (str): Name of the flow.
110
+ - `description` (str): Description of the flow.
111
+ - `max_round` (int): The maximum number of rounds the flow will run. Default: 30.
112
+ - `subflows_config` (dict): The configuration of the subflows.
113
+ - `Controller` (dict): The configuration of the controller. It is important that the target of the controller (instance customizable by the user) and the api information should be specified.
114
+ - `Executor` (dict): The executor of the flow, it is supposed to be a branching flow. To instantiate the executor, the user needs to specify the subflows of the executor (i.e. the actual tools that can be used by the agent, e.g. a flow for interpreting code)
115
+ - `MemoryWriting` (dict): The configuration of the memory writer. There is an existing memory writing flow implemented.
116
+ - 'MemoryReading' (dict): The configuration of the memory reader. There is an existing memory reading flow implemented.
117
+ - `topology` (List): The topology of the subflows, notice that the output interface of the Controller must be implemented and specified.
118
+
119
+ *Input Interface*:
120
+ - `plan` (str): The plan generated by the planner, the CtrlExMem flow should follow the plan.
121
+ - `memory_files` (dict): mem_name - memfile_path pairs, the memory files that the memory reader will read from.
122
+ - `goal` (str): The goal of the flow
123
+ - `logs` (str): Execution history of the flow, contains all actions taken by each subflow of the flow.
124
+
125
+ *Output Interface*:
126
+ - `result` (str): The result of the flow, will be returned to the controller of the caller flow.
127
+ - `summary` (str): The summary of the flow, will be written to the logs of the caller flow.
128
+
129
+ <a id="CtrlExMemFlow.CtrlExMemFlow.detect_finish_or_continue"></a>
130
+
131
+ #### detect\_finish\_or\_continue
132
+
133
+ ```python
134
+ @abstractmethod
135
+ @CircularFlow.output_msg_payload_processor
136
+ def detect_finish_or_continue(output_payload: Dict[str, Any],
137
+ src_flow) -> Dict[str, Any]
138
+ ```
139
+
140
+ This function is called after the Controller, it is used to:
141
+
142
+ 1. Check if the Controller decides to early-exit, if so, implement necessary logics for exiting e.g. drafting result and summary, etc.
143
+ 2. For other commands called by the controller, implement necessary logics for the flow to continue e.g. providing necessary information to the branching flow.
144
+
145
+ **Arguments**:
146
+
147
+ - `output_payload` (`Dict[str, Any]`): The output payload of the Controller.
148
+ - `src_flow` (`Flow`): The source flow of the Controller.
149
+
150
+ **Returns**:
151
+
152
+ The input payload of the Executor.
153
+
154
+ <a id="__init__"></a>
155
+
156
+ # \_\_init\_\_
157
+
__init__.py ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ dependencies = [
2
+ {"url": "aiflows/MemoryReadingFlowModule", "revision": "main"},
3
+ {"url": "aiflows/PlanWriterFlowModule", "revision":"main"},
4
+ {"url": "aiflows/MemoryReadingFlowModule", "revision":"main"},
5
+ {"url": "aiflows/MemoryWritingFlowModule", "revision":"main"},
6
+ ]
7
+ from aiflows import flow_verse
8
+
9
+ flow_verse.sync_dependencies(dependencies)
10
+ from .AbstractBossFlow import AbstractBossFlow
11
+ from .CtrlExMemFlow import CtrlExMemFlow
pip_requirements.txt ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ colorama==0.4.6
2
+ pytest==7.3.1
3
+ pytest-cov==4.1.0
4
+ hydra-core==1.3.2
5
+ hydra-colorlog==1.1.0
6
+ wrapt-timeout-decorator==1.3.12.2
7
+ diskcache==5.6.1
8
+ openai==1.0.0
9
+ huggingface_hub==0.19.4
10
+ jsonlines==3.1.0
11
+ jinja2==3.1.2
12
+ mock==5.0.2
13
+ rich==12.6.0
14
+ litellm==1.0.0
15
+ aiflows