README + demo +piprequirements
Browse files- .gitignore +2 -0
- LCToolFlow.py +45 -0
- LCToolFlow.yaml +2 -2
- README.md +70 -16
- demo.yaml +4 -0
- pip_requirements.py +0 -1
- pip_requirements.txt +2 -0
- run.py +8 -11
.gitignore
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
__pycache__/
|
2 |
+
.flow_cache/
|
LCToolFlow.py
CHANGED
@@ -9,6 +9,31 @@ from flows.base_flows import AtomicFlow
|
|
9 |
|
10 |
|
11 |
class LCToolFlow(AtomicFlow):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
REQUIRED_KEYS_CONFIG = ["backend"]
|
13 |
|
14 |
SUPPORTS_CACHING: bool = False
|
@@ -21,6 +46,12 @@ class LCToolFlow(AtomicFlow):
|
|
21 |
|
22 |
@classmethod
|
23 |
def _set_up_backend(cls, config: Dict[str, Any]) -> BaseTool:
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
if config["_target_"].startswith("."):
|
25 |
# assumption: cls is associated with relative data_transformation_configs
|
26 |
# for example, CF_Code and CF_Code.yaml should be in the same directory,
|
@@ -33,6 +64,13 @@ class LCToolFlow(AtomicFlow):
|
|
33 |
|
34 |
@classmethod
|
35 |
def instantiate_from_config(cls, config: Dict[str, Any]) -> LCToolFlow:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
flow_config = deepcopy(config)
|
37 |
|
38 |
kwargs = {"flow_config": flow_config}
|
@@ -44,6 +82,13 @@ class LCToolFlow(AtomicFlow):
|
|
44 |
return cls(**kwargs)
|
45 |
|
46 |
def run(self, input_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
observation = self.backend.run(tool_input=input_data)
|
48 |
|
49 |
return {"observation": observation}
|
|
|
9 |
|
10 |
|
11 |
class LCToolFlow(AtomicFlow):
|
12 |
+
r""" A flow that runs a tool using langchain. For example, a tool could be to excute a query with the duckduckgo search engine.
|
13 |
+
|
14 |
+
*Configuration Parameters*:
|
15 |
+
|
16 |
+
- `name` (str): The name of the flow. Default: "search"
|
17 |
+
- `description` (str): A description of the flow. This description is used to generate the help message of the flow.
|
18 |
+
Default: "useful when you need to look for the answer online, especially for recent events."
|
19 |
+
- `keep_raw_response` (bool): If True, the raw response of the tool is kept. Default: False
|
20 |
+
- `clear_flow_namespase_on_run_end` (bool): If True, the flow namespace is cleared at the end of the run. Default: False
|
21 |
+
- `backend` (Dict[str, Any]): The configuration of the backend. Default: langchain.tools.DuckDuckGoSearchRun
|
22 |
+
- Other parameters are inherited from the default configuration of AtomicFlow (see AtomicFlow)
|
23 |
+
|
24 |
+
*Input Interface*:
|
25 |
+
|
26 |
+
- `query` (str): the query to run the tool on
|
27 |
+
|
28 |
+
*Output Interface*:
|
29 |
+
|
30 |
+
- `observation` (str): the observation returned by the tool
|
31 |
+
|
32 |
+
:param backend: The backend of the flow. It is a tool that is run by the flow. (e.g. duckduckgo search engine)
|
33 |
+
:type backend: BaseTool
|
34 |
+
:param \**kwargs: Additional arguments to pass to the flow. See :class:`flows.base_flows.AtomicFlow` for more details.
|
35 |
+
"""
|
36 |
+
|
37 |
REQUIRED_KEYS_CONFIG = ["backend"]
|
38 |
|
39 |
SUPPORTS_CACHING: bool = False
|
|
|
46 |
|
47 |
@classmethod
|
48 |
def _set_up_backend(cls, config: Dict[str, Any]) -> BaseTool:
|
49 |
+
""" This method sets up the backend of the flow.
|
50 |
+
|
51 |
+
:param config: The configuration of the backend.
|
52 |
+
:type config: Dict[str, Any]
|
53 |
+
:return: The backend of the flow.
|
54 |
+
"""
|
55 |
if config["_target_"].startswith("."):
|
56 |
# assumption: cls is associated with relative data_transformation_configs
|
57 |
# for example, CF_Code and CF_Code.yaml should be in the same directory,
|
|
|
64 |
|
65 |
@classmethod
|
66 |
def instantiate_from_config(cls, config: Dict[str, Any]) -> LCToolFlow:
|
67 |
+
""" This method instantiates the flow from a configuration file
|
68 |
+
|
69 |
+
:param config: The configuration of the flow.
|
70 |
+
:type config: Dict[str, Any]
|
71 |
+
:return: The instantiated flow.
|
72 |
+
:rtype: LCToolFlow
|
73 |
+
"""
|
74 |
flow_config = deepcopy(config)
|
75 |
|
76 |
kwargs = {"flow_config": flow_config}
|
|
|
82 |
return cls(**kwargs)
|
83 |
|
84 |
def run(self, input_data: Dict[str, Any]) -> Dict[str, Any]:
|
85 |
+
""" This method runs the flow. It runs the backend on the input data.
|
86 |
+
|
87 |
+
:param input_data: The input data of the flow.
|
88 |
+
:type input_data: Dict[str, Any]
|
89 |
+
:return: The output data of the flow.
|
90 |
+
:rtype: Dict[str, Any]
|
91 |
+
"""
|
92 |
observation = self.backend.run(tool_input=input_data)
|
93 |
|
94 |
return {"observation": observation}
|
LCToolFlow.yaml
CHANGED
@@ -5,7 +5,7 @@ description: "useful when you need to look for the answer online, especially for
|
|
5 |
# Input keys
|
6 |
#######################################################
|
7 |
|
8 |
-
|
9 |
- "query"
|
10 |
|
11 |
|
@@ -13,7 +13,7 @@ input_keys:
|
|
13 |
# Output keys
|
14 |
#######################################################
|
15 |
|
16 |
-
|
17 |
- "observation"
|
18 |
|
19 |
keep_raw_response: false
|
|
|
5 |
# Input keys
|
6 |
#######################################################
|
7 |
|
8 |
+
input_interface:
|
9 |
- "query"
|
10 |
|
11 |
|
|
|
13 |
# Output keys
|
14 |
#######################################################
|
15 |
|
16 |
+
output_interface:
|
17 |
- "observation"
|
18 |
|
19 |
keep_raw_response: false
|
README.md
CHANGED
@@ -1,27 +1,81 @@
|
|
1 |
-
|
2 |
-
license: mit
|
3 |
-
---
|
4 |
-
ToDo
|
5 |
|
6 |
-
|
7 |
-
|
|
|
|
|
8 |
|
9 |
-
|
10 |
|
11 |
-
|
12 |
|
13 |
-
|
14 |
|
15 |
-
|
16 |
|
17 |
-
|
|
|
|
|
18 |
|
19 |
-
|
20 |
|
21 |
-
|
22 |
|
23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
|
25 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
|
27 |
-
(Note that the interface might depend on the state of the Flow.)
|
|
|
1 |
+
# Table of Contents
|
|
|
|
|
|
|
2 |
|
3 |
+
* [LCToolFlow](#LCToolFlow)
|
4 |
+
* [LCToolFlow](#LCToolFlow.LCToolFlow)
|
5 |
+
* [instantiate\_from\_config](#LCToolFlow.LCToolFlow.instantiate_from_config)
|
6 |
+
* [run](#LCToolFlow.LCToolFlow.run)
|
7 |
|
8 |
+
<a id="LCToolFlow"></a>
|
9 |
|
10 |
+
# LCToolFlow
|
11 |
|
12 |
+
<a id="LCToolFlow.LCToolFlow"></a>
|
13 |
|
14 |
+
## LCToolFlow Objects
|
15 |
|
16 |
+
```python
|
17 |
+
class LCToolFlow(AtomicFlow)
|
18 |
+
```
|
19 |
|
20 |
+
A flow that runs a tool using langchain. For example, a tool could be to excute a query with the duckduckgo search engine.
|
21 |
|
22 |
+
*Configuration Parameters*:
|
23 |
|
24 |
+
- `name` (str): The name of the flow. Default: "search"
|
25 |
+
- `description` (str): A description of the flow. This description is used to generate the help message of the flow.
|
26 |
+
Default: "useful when you need to look for the answer online, especially for recent events."
|
27 |
+
- `keep_raw_response` (bool): If True, the raw response of the tool is kept. Default: False
|
28 |
+
- `clear_flow_namespase_on_run_end` (bool): If True, the flow namespace is cleared at the end of the run. Default: False
|
29 |
+
- `backend` (Dict[str, Any]): The configuration of the backend. Default: langchain.tools.DuckDuckGoSearchRun
|
30 |
+
- Other parameters are inherited from the default configuration of AtomicFlow (see AtomicFlow)
|
31 |
|
32 |
+
*Input Interface*:
|
33 |
+
|
34 |
+
- `query` (str): the query to run the tool on
|
35 |
+
|
36 |
+
*Output Interface*:
|
37 |
+
|
38 |
+
- `observation` (str): the observation returned by the tool
|
39 |
+
|
40 |
+
**Arguments**:
|
41 |
+
|
42 |
+
- `backend` (`BaseTool`): The backend of the flow. It is a tool that is run by the flow. (e.g. duckduckgo search engine)
|
43 |
+
- `\**kwargs`: Additional arguments to pass to the flow. See :class:`flows.base_flows.AtomicFlow` for more details.
|
44 |
+
|
45 |
+
<a id="LCToolFlow.LCToolFlow.instantiate_from_config"></a>
|
46 |
+
|
47 |
+
#### instantiate\_from\_config
|
48 |
+
|
49 |
+
```python
|
50 |
+
@classmethod
|
51 |
+
def instantiate_from_config(cls, config: Dict[str, Any]) -> LCToolFlow
|
52 |
+
```
|
53 |
+
|
54 |
+
This method instantiates the flow from a configuration file
|
55 |
+
|
56 |
+
**Arguments**:
|
57 |
+
|
58 |
+
- `config` (`Dict[str, Any]`): The configuration of the flow.
|
59 |
+
|
60 |
+
**Returns**:
|
61 |
+
|
62 |
+
`LCToolFlow`: The instantiated flow.
|
63 |
+
|
64 |
+
<a id="LCToolFlow.LCToolFlow.run"></a>
|
65 |
+
|
66 |
+
#### run
|
67 |
+
|
68 |
+
```python
|
69 |
+
def run(input_data: Dict[str, Any]) -> Dict[str, Any]
|
70 |
+
```
|
71 |
+
|
72 |
+
This method runs the flow. It runs the backend on the input data.
|
73 |
+
|
74 |
+
**Arguments**:
|
75 |
+
|
76 |
+
- `input_data` (`Dict[str, Any]`): The input data of the flow.
|
77 |
+
|
78 |
+
**Returns**:
|
79 |
+
|
80 |
+
`Dict[str, Any]`: The output data of the flow.
|
81 |
|
|
demo.yaml
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
flow:
|
2 |
+
_target_: aiflows.LCToolFlowModule.LCToolFlow.instantiate_from_default_config
|
3 |
+
name: "demoLCToolFlow"
|
4 |
+
description: "An example flow that uses the LCToolFlowModule."
|
pip_requirements.py
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
# ToDo
|
|
|
|
pip_requirements.txt
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
langchain==0.0.336
|
2 |
+
duckduckgo-search==3.9.6
|
run.py
CHANGED
@@ -5,7 +5,7 @@ import os
|
|
5 |
import hydra
|
6 |
|
7 |
import flows
|
8 |
-
from flows.flow_launchers import FlowLauncher
|
9 |
from flows.utils.general_helpers import read_yaml_file
|
10 |
|
11 |
from flows import logging
|
@@ -16,19 +16,17 @@ CACHING_PARAMETERS.do_caching = False # Set to True to enable caching
|
|
16 |
|
17 |
logging.set_verbosity_debug()
|
18 |
|
|
|
|
|
|
|
|
|
|
|
19 |
|
20 |
if __name__ == "__main__":
|
21 |
-
# ~~~ Set the API information ~~~
|
22 |
-
# OpenAI backend
|
23 |
-
# api_information = ApiInfo("openai", os.getenv("OPENAI_API_KEY"))
|
24 |
-
# Azure backend
|
25 |
-
api_information = ApiInfo("azure", os.getenv("AZURE_OPENAI_KEY"), os.getenv("AZURE_OPENAI_ENDPOINT"))
|
26 |
|
27 |
-
# ~~~ Instantiate the Flow ~~~
|
28 |
root_dir = "."
|
29 |
-
cfg_path = os.path.join(root_dir, "
|
30 |
cfg = read_yaml_file(cfg_path)
|
31 |
-
|
32 |
flow_with_interfaces = {
|
33 |
"flow": hydra.utils.instantiate(cfg['flow'], _recursive_=False, _convert_="partial"),
|
34 |
"input_interface": (
|
@@ -45,7 +43,7 @@ if __name__ == "__main__":
|
|
45 |
|
46 |
# ~~~ Get the data ~~~
|
47 |
# This can be a list of samples
|
48 |
-
data = {"id": 0} # Add your data here
|
49 |
|
50 |
# ~~~ Run inference ~~~
|
51 |
path_to_output_file = None
|
@@ -55,7 +53,6 @@ if __name__ == "__main__":
|
|
55 |
flow_with_interfaces=flow_with_interfaces,
|
56 |
data=data,
|
57 |
path_to_output_file=path_to_output_file,
|
58 |
-
api_information=api_information,
|
59 |
)
|
60 |
|
61 |
# ~~~ Print the output ~~~
|
|
|
5 |
import hydra
|
6 |
|
7 |
import flows
|
8 |
+
from flows.flow_launchers import FlowLauncher
|
9 |
from flows.utils.general_helpers import read_yaml_file
|
10 |
|
11 |
from flows import logging
|
|
|
16 |
|
17 |
logging.set_verbosity_debug()
|
18 |
|
19 |
+
dependencies = [
|
20 |
+
{"url": "aiflows/LCToolFlowModule", "revision": os.getcwd()},
|
21 |
+
]
|
22 |
+
from flows import flow_verse
|
23 |
+
flow_verse.sync_dependencies(dependencies)
|
24 |
|
25 |
if __name__ == "__main__":
|
|
|
|
|
|
|
|
|
|
|
26 |
|
|
|
27 |
root_dir = "."
|
28 |
+
cfg_path = os.path.join(root_dir, "demo.yaml")
|
29 |
cfg = read_yaml_file(cfg_path)
|
|
|
30 |
flow_with_interfaces = {
|
31 |
"flow": hydra.utils.instantiate(cfg['flow'], _recursive_=False, _convert_="partial"),
|
32 |
"input_interface": (
|
|
|
43 |
|
44 |
# ~~~ Get the data ~~~
|
45 |
# This can be a list of samples
|
46 |
+
data = {"id": 0, "query": "Michael Jordan age"} # Add your data here
|
47 |
|
48 |
# ~~~ Run inference ~~~
|
49 |
path_to_output_file = None
|
|
|
53 |
flow_with_interfaces=flow_with_interfaces,
|
54 |
data=data,
|
55 |
path_to_output_file=path_to_output_file,
|
|
|
56 |
)
|
57 |
|
58 |
# ~~~ Print the output ~~~
|