Tachi67 commited on
Commit
0c97269
·
1 Parent(s): a20c3ed

Upload 6 files

Browse files
PlanGeneratorAtomicFlow.py ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ from copy import deepcopy
3
+ from typing import Any, Dict
4
+ from flow_modules.aiflows.ChatFlowModule import ChatAtomicFlow
5
+
6
+ class PlanGeneratorAtomicFlow(ChatAtomicFlow):
7
+ """This class wraps around the Chat API to generate plan from a goal.
8
+
9
+ *Input Interface Non Initialized*:
10
+ - `goal`
11
+
12
+ *Input Interface Initialized*:
13
+ - `goal`
14
+
15
+ *Output Interface*:
16
+ - `plan`
17
+ """
18
+ def __init__(self, **kwargs):
19
+ super().__init__(**kwargs)
20
+ self.hint_for_model = """
21
+ Make sure your response is in the following format:
22
+ Response Format:
23
+ {
24
+ "plan": "A step-by-step plan to finish the given goal, each step of plan should contain full information about writing a function",
25
+ }
26
+ """
27
+
28
+ @classmethod
29
+ def instantiate_from_config(cls, config):
30
+ flow_config = deepcopy(config)
31
+
32
+ kwargs = {"flow_config": flow_config}
33
+
34
+ # ~~~ Set up prompts ~~~
35
+ kwargs.update(cls._set_up_prompts(flow_config))
36
+
37
+ # ~~~ Set up backend ~~~
38
+ kwargs.update(cls._set_up_backend(flow_config))
39
+
40
+ # ~~~ Instantiate flow ~~~
41
+ return cls(**kwargs)
42
+
43
+ def _update_prompts_and_input(self, input_data: Dict[str, Any]):
44
+ if 'goal' in input_data:
45
+ input_data['goal'] += self.hint_for_model
46
+
47
+ def run(self, input_data: Dict[str, Any]) -> Dict[str, Any]:
48
+ self._update_prompts_and_input(input_data)
49
+ while True:
50
+ api_output = super().run(input_data)["api_output"].strip()
51
+ try:
52
+ response = json.loads(api_output)
53
+ return response
54
+ except (json.decoder.JSONDecodeError, json.JSONDecodeError):
55
+ new_goal = "The previous respond cannot be parsed with json.loads. Next time, do not provide any comments or code blocks. Make sure your next response is purely json parsable."
56
+ new_input_data = input_data.copy()
57
+ new_input_data['goal'] = new_goal
58
+ input_data = new_input_data
PlanGeneratorAtomicFlow.yaml ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ _target_: flow_modules.aiflows.PlanGeneratorFlowModule.PlanGeneratorAtomicFlow.instantiate_from_default_config
2
+ name: "PlanGeneratorAtomicFlow"
3
+ description: "Writes step by step plan with given goal"
4
+ enable_cache: True
5
+
6
+ input_interface_non_initialized: # initial input keys
7
+ - "goal"
8
+
9
+ input_interface_initialized: # input_keys
10
+ - "goal"
11
+
12
+ #######################################################
13
+ # Output keys
14
+ #######################################################
15
+
16
+ output_interface:
17
+ - 'plan'
18
+
19
+ #######################################################
20
+ system_message_prompt_template:
21
+ _target_: aiflows.prompt_template.JinjaPrompt
22
+ template: |2-
23
+ You are a planner of a coding department, your task is to make a step-by-step plan for the coders to follow, inorder to solve the task.
24
+
25
+ The coding department is only able to write functions, at a higher level, your job is to tell what function to write at each step.
26
+
27
+ The details of your task are:
28
+ 1. Decompose the goal into step-by-step plans, each step should contain full information about a function to write, do not decompose an action of writing one function into more than one step, give all information of writing a function in exactly one line.
29
+ 2. Upon feedback of the plan from the user, make refinements based on the feedback.
30
+
31
+ Notice that:
32
+ 1. If the goal given to you is simple enough that is doable within one function, it is okay that your plan only has one step.
33
+ 2. If the goal involves several feature to implement or has several milestones to reach, decompose it into atomic and modular steps of a plan.
34
+ 3. **Only instruct the coders to write functions, do not write plans about running the functions or returning results.**
35
+ 4. **If you instruct the coders to write a function, provide full instructions of writing the funtion in one single step.**
36
+ 5. **If there are multiple information about one specific function you instruct to write, put it all in exactly the same one line as the line of the function**
37
+
38
+ The coding department is able to access the Internet, so it may be useful to use some online services via APIs.
39
+
40
+ An example of input and output plan you should have:
41
+ ### begin of input ###
42
+ Extend the code library with a function named 'extract_birth_date'. This function should take in the content of a Wikipedia page and return the birth date of the person the page is about. The function should be able to handle different date formats and return the date in a consistent format.
43
+ ### end of input ###
44
+
45
+ ### begin of plan ###
46
+ 1. Write a function named 'extract_birth_date'. This function should take in a string parameter which represents the content of a Wikipedia page, inside the function, use a regular expression to search for the birth date in the content, the regular expression should be able to handle different date formats. If a birth date is found, convert it to a consistent format using a date parsing library. Return the birth date in the consistent format. If no birth date is found, return an appropriate message indicating that the birth date could not be found.
47
+ ### end of plan ###
48
+
49
+ Another example of input and output plan you should have:
50
+ ### begin of input ###
51
+ Write code to fetch a certain day's weather data at a certain city, and print the data to the console.
52
+ ### end of input ###
53
+
54
+ ### begin of plan ###
55
+ 1. Write a function that fetches weather data from OpenWeatherMap, given a date and the city name.
56
+ 2. Write a function that prints fetched weather data to the console.
57
+ ### end of plan ###
58
+
59
+ Takeaway message: Decompose the goal into writing functions, **for each function, provide every information about the function in exactly one line.**
60
+ **It is VERY IMPORTANT that each step should instruct exactly one function, do not instruct a function in more than 1 step.**
61
+
62
+ Performance Evaluation:
63
+ 1. Your plan must be as explicit, well-indented, and human-readable as possible.
64
+ 2. Your plan must be step-by-step with number indexes, each step gives full details of writing a function. **DO NOT** separate one action to write a function into more than one step.
65
+ 3. You should make plans with as few steps as possible.
66
+
67
+ **It's important that you should only respond in JSON format as described below:**
68
+ Response Format:
69
+ {
70
+ "plan": "A step-by-step plan to finish the given goal, each step of plan should contain full information about writing a function",
71
+ }
72
+ Ensure your responses can be parsed by Python json.loads
73
+
74
+ human_message_prompt_template:
75
+ _target_: aiflows.prompt_template.JinjaPrompt
76
+ template: |2-
77
+ Here is the response to your last action:
78
+ {{goal}}
79
+ input_variables:
80
+ - "goal"
81
+
82
+ init_human_message_prompt_template:
83
+ _target_: aiflows.prompt_template.JinjaPrompt
84
+ template: |2-
85
+ Here is the goal you need to achieve:
86
+ {{goal}}
87
+ input_variables:
88
+ - "goal"
README.md CHANGED
@@ -1,3 +1,33 @@
1
- ---
2
- license: mit
3
- ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Table of Contents
2
+
3
+ * [PlanGeneratorAtomicFlow](#PlanGeneratorAtomicFlow)
4
+ * [PlanGeneratorAtomicFlow](#PlanGeneratorAtomicFlow.PlanGeneratorAtomicFlow)
5
+ * [\_\_init\_\_](#__init__)
6
+
7
+ <a id="PlanGeneratorAtomicFlow"></a>
8
+
9
+ # PlanGeneratorAtomicFlow
10
+
11
+ <a id="PlanGeneratorAtomicFlow.PlanGeneratorAtomicFlow"></a>
12
+
13
+ ## PlanGeneratorAtomicFlow Objects
14
+
15
+ ```python
16
+ class PlanGeneratorAtomicFlow(ChatAtomicFlow)
17
+ ```
18
+
19
+ This class wraps around the Chat API to generate plan from a goal.
20
+
21
+ *Input Interface Non Initialized*:
22
+ - `goal`
23
+
24
+ *Input Interface Initialized*:
25
+ - `goal`
26
+
27
+ *Output Interface*:
28
+ - `plan`
29
+
30
+ <a id="__init__"></a>
31
+
32
+ # \_\_init\_\_
33
+
__init__.py ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ dependencies = [
2
+ {"url": "aiflows/ChatFlowModule", "revision": "297c90d08087d9ff3139521f11d1a48d7dc63ed4"},
3
+ ]
4
+ from aiflows import flow_verse
5
+
6
+ flow_verse.sync_dependencies(dependencies)
7
+
8
+ from .PlanGeneratorAtomicFlow import PlanGeneratorAtomicFlow
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
run.py ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ import hydra
4
+
5
+ from aiflows.backends.api_info import ApiInfo
6
+ from aiflows.messages import InputMessage
7
+ from aiflows.utils.general_helpers import read_yaml_file, quick_load
8
+
9
+ from aiflows import logging
10
+ from aiflows.flow_cache import CACHING_PARAMETERS, clear_cache
11
+
12
+ CACHING_PARAMETERS.do_caching = False # Set to True in order to disable caching
13
+
14
+ logging.set_verbosity_debug()
15
+ logging.auto_set_dir()
16
+
17
+ dependencies = [
18
+ {"url": "aiflows/PlanGeneratorFlowModule", "revision": "main"},
19
+ ]
20
+
21
+ from aiflows import flow_verse
22
+
23
+ flow_verse.sync_dependencies(dependencies)
24
+
25
+ if __name__ == "__main__":
26
+ # ~~~ make sure to set the openai api key in the envs ~~~
27
+ key = os.getenv("OPENAI_API_KEY")
28
+ api_information = [ApiInfo(backend_used="openai", api_key=os.getenv("OPENAI_API_KEY"))]
29
+ current_dir = os.getcwd()
30
+ cfg_path = os.path.join(current_dir, "PlanGeneratorAtomicFlow.yaml")
31
+ cfg = read_yaml_file(cfg_path)
32
+
33
+
34
+ # configuring api information
35
+ quick_load(cfg, api_information)
36
+
37
+ PlanGenFlow = hydra.utils.instantiate(cfg, _recursive_=False, _convert_="partial")
38
+
39
+
40
+ input_data = {
41
+ "goal": "fetch google's stock prices from 2021-01-01 to 2021-06-01 and plot it."
42
+ }
43
+ input_message = InputMessage.build(
44
+ data_dict=input_data,
45
+ src_flow="Launcher",
46
+ dst_flow=PlanGenFlow.name
47
+ )
48
+
49
+ # ~~~ calling the flow ~~~
50
+ output_message = PlanGenFlow(input_message)
51
+
52
+ print(output_message.data)