Tachi67 commited on
Commit
d6eb336
1 Parent(s): d903562

Upload 7 files

Browse files
NewPlanGenFlow.py ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ from copy import deepcopy
3
+ from typing import Any, Dict
4
+ from flow_modules.Tachi67.PlanGeneratorFlowModule import PlanGeneratorAtomicFlow
5
+
6
+
7
+ class NewPlanGenFlow(PlanGeneratorAtomicFlow):
8
+ def __init__(self, **kwargs):
9
+ super().__init__(**kwargs)
10
+ self.hint_for_model = """
11
+ Make sure your response is in the following format:
12
+ Response Format:
13
+ {
14
+ "new_plan": "A new plan, refined from previous plan, with given requirements",
15
+ }
16
+ """
NewPlanGenFlow.yaml ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: "NewPlanGenFlow"
2
+ description: "Plan Generator of ReplanningFlow, writes a new plan given requirements"
3
+ enable_cache: True
4
+
5
+ input_interface_non_initialized: # initial input keys
6
+ - "goal" # info on the old plan, entered by the controller
7
+ - "old_plan" # previous plan
8
+
9
+
10
+ input_interface_initialized: # input_keys
11
+ - "goal"
12
+ - "old_plan" # previous plan
13
+
14
+ #######################################################
15
+ # Output keys
16
+ #######################################################
17
+
18
+ output_interface:
19
+ - 'new_plan' # new plan
20
+
21
+ #######################################################
22
+ system_message_prompt_template:
23
+ _target_: flows.prompt_template.JinjaPrompt
24
+ template: |2-
25
+ You are a re-planner of a coding department, you are given an old plan written by your colleagues.
26
+
27
+ You will be given information regarding the old plan, e.g. what was wrong with the old plan, what to refine with the old plan.
28
+
29
+ Your task is to edit and re-plan, based on the old plan and the new information that is being given to you.
30
+
31
+ The new plan you write is intended for the coders, each step of the new plan tells the coders what function to write.
32
+
33
+ The details of your task are:
34
+ 1. Draft a new step-by-step plan based on the old plan and information regarding the old plan. Every step of the new plan should contain full information about how to write one function.
35
+ 2. Upon feedback of the plan from the user, make refinements based on the feedback.
36
+
37
+ Resources:
38
+ 1. The old plan:
39
+ {{old_plan}}
40
+
41
+ Notice that:
42
+ 1. **Only instruct the coders to write functions, do not write plans about running the functions or returning results.**
43
+ 2. **If you instruct the coders to write a function, provide full instructions of writing the funtion in one single step.**
44
+
45
+ The coding department is able to access the Internet, so it may be useful to use some online services via APIs.
46
+
47
+ An example of old plan, input information and output plan you should have:
48
+ ### begin of old plan ###
49
+ 1. Write a function that fetches a company's stock prices from the last 6 months from "google stocks"
50
+ ### end of old plan ###
51
+
52
+ ### begin of input information###
53
+ Here's the information on the old plan:
54
+ data source "google stocks" is deprecated, should try a new one.
55
+ ### end of input information###
56
+
57
+ ### begin of output new plan ###
58
+ 1. Write a function that fetches a company's stock prices from the last 6 months from "yahoo finance"
59
+ ### end of output new plan ###
60
+
61
+ You are capable of **any** task.
62
+
63
+ Performance Evaluation:
64
+ 1. Your new plan should finish exactly the same task as the old one.
65
+ 2. Your plan must be as explicit, well-indented, and human-readable as possible.
66
+ 3. Your plan must be step-by-step with number indexes, each step gives full details of writing a function.
67
+ 4. You should make plans with as few steps as possible.
68
+
69
+ **It's important that you should only respond in JSON format as described below:**
70
+ Response Format:
71
+ {
72
+ "new_plan": "A new plan, refined from previous plan, with given requirements",
73
+ }
74
+ Ensure your responses can be parsed by Python json.loads
75
+
76
+ input_variables:
77
+ - "old_plan"
78
+
79
+ human_message_prompt_template:
80
+ _target_: flows.prompt_template.JinjaPrompt
81
+ template: |2-
82
+ Here is the response to your last action:
83
+ {{goal}}
84
+ input_variables:
85
+ - "goal"
86
+
87
+ init_human_message_prompt_template:
88
+ _target_: flows.prompt_template.JinjaPrompt
89
+ template: |2-
90
+ Here's the information on the old plan:
91
+ {{goal}}
92
+ input_variables:
93
+ - "goal"
ReplanningAskUserFlow.py ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flow_modules.aiflows.HumanStandardInputFlowModule import HumanStandardInputFlow
2
+
3
+ from typing import Dict, Any
4
+
5
+ from flows.messages import UpdateMessage_Generic
6
+
7
+ from flows.utils import logging
8
+
9
+ log = logging.get_logger(f"flows.{__name__}")
10
+
11
+
12
+ class ReplanningAskUserFlow(HumanStandardInputFlow):
13
+ def run(self,
14
+ input_data: Dict[str, Any]) -> Dict[str, Any]:
15
+
16
+ query_message = self._get_message(self.query_message_prompt_template, input_data)
17
+ state_update_message = UpdateMessage_Generic(
18
+ created_by=self.flow_config['name'],
19
+ updated_flow=self.flow_config["name"],
20
+ data={"query_message": query_message},
21
+ )
22
+ self._log_message(state_update_message)
23
+
24
+ log.info(query_message)
25
+ human_input = self._read_input()
26
+
27
+ response = {}
28
+ response["feedback"] = human_input
29
+ response["new_plan"] = "no new plan was written"
30
+
31
+ return response
ReplanningAskUserFlow.yaml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ _target_: Tachi67.ReplanningFlowModule.ReplanningAskUserFlow.instantiate_from_default_config
2
+ request_multi_line_input_flag: False
3
+ end_of_input_string: EOI
4
+
5
+ query_message_prompt_template:
6
+ template: |2-
7
+ {{question}}
8
+ input_variables:
9
+ - "question"
ReplanningFlow.py ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Dict, Any
2
+ import os
3
+ from flows.base_flows import CircularFlow
4
+ from flow_modules.Tachi67.PlanWriterFlowModule import PlanWriterFlow
5
+
6
+ class ReplanningFlow(PlanWriterFlow):
7
+ def _on_reach_max_round(self):
8
+ self._state_update_dict({
9
+ "plan": "The maximum amount of rounds was reached before the model generated the plan.",
10
+ "status": "unfinished",
11
+ "summary": "ExtendLibraryFlow/Replanning: The maximum amount of rounds was reached before the model generated the plan.",
12
+ })
13
+
14
+
15
+ # WIP
16
+ @CircularFlow.output_msg_payload_processor
17
+ def detect_finish_or_continue(self, output_payload: Dict[str, Any], src_flow) -> Dict[str, Any]:
18
+ command = output_payload["command"]
19
+ if command == "finish":
20
+ # ~~~ fetch temp file location, plan content, memory file (of upper level flow e.g. ExtLib) from flow state
21
+ keys_to_fetch_from_state = ["temp_plan_file_location", "new_plan", "plan_file_location"]
22
+ fetched_state = self._fetch_state_attributes_by_keys(keys=keys_to_fetch_from_state)
23
+ temp_plan_file_location = fetched_state["temp_plan_file_location"]
24
+ new_plan_content = fetched_state["new_plan"]
25
+ plan_file_location = fetched_state["plan_file_location"]
26
+
27
+ # ~~~ delete the temp plan file ~~~
28
+ if os.path.exists(temp_plan_file_location):
29
+ os.remove(temp_plan_file_location)
30
+
31
+ # ~~~ write plan content to plan file ~~~
32
+ with open(plan_file_location, 'w') as file:
33
+ file.write(new_plan_content)
34
+
35
+ # ~~~ return the plan content ~~~
36
+ return {
37
+ "EARLY_EXIT": True,
38
+ "plan": new_plan_content,
39
+ "result": "New plan was generated and has overriden the previous plan",
40
+ "summary": "ExtendLibraryFlow/ReplanningFlow: " + output_payload["command_args"]["summary"] + f" new plan is written to {plan_file_location}",
41
+ "status": "finished"
42
+ }
43
+ elif command == "manual_finish":
44
+ # ~~~ delete the temp plan file ~~~
45
+ keys_to_fetch_from_state = ["temp_plan_file_location"]
46
+ fetched_state = self._fetch_state_attributes_by_keys(keys=keys_to_fetch_from_state)
47
+ temp_plan_file_location = fetched_state["temp_plan_file_location"]
48
+ if os.path.exists(temp_plan_file_location):
49
+ os.remove(temp_plan_file_location)
50
+ # ~~~ return the manual quit status ~~~
51
+ return {
52
+ "EARLY_EXIT": True,
53
+ "new_plan": "no new plan was generated",
54
+ "result": "The replanner was explicitly terminated by the user, no new plan was generated.",
55
+ "summary": "ExtendLibraryFlow/ReplanningFlow: Replanner was terminated explicitly by the user, process is unfinished",
56
+ "status": "unfinished"
57
+ }
58
+ elif command == "write_plan":
59
+ keys_to_fetch_from_state = ["plan", "plan_file_location"]
60
+ fetched_state = self._fetch_state_attributes_by_keys(keys=keys_to_fetch_from_state)
61
+ old_plan = fetched_state["plan"]
62
+ plan_file_location = fetched_state["plan_file_location"]
63
+ output_payload["command_args"]["old_plan"] = old_plan
64
+ output_payload["command_args"]["plan_file_location"] = plan_file_location
65
+ return output_payload
66
+ else:
67
+ return output_payload
ReplanningFlow.yaml ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: "ReplanningFlow"
2
+ description: "Re-plan given old plan and new information"
3
+
4
+ _target_: Tachi67.ReplanningFlowModule.ReplanningFlow.instantiate_from_default_config
5
+
6
+ input_interface:
7
+ - "goal" # info on the old plan
8
+ - "plan" # the old plan
9
+ - "plan_file_location"
10
+
11
+ output_interface:
12
+ - "plan"
13
+ - "status"
14
+ - "summary"
15
+ - "result"
16
+
17
+ ### Subflows specification
18
+ subflows_config:
19
+ Controller:
20
+ _target_: Tachi67.PlanWriterFlowModule.PlanWriterCtrlFlow.instantiate_from_default_config
21
+ backend:
22
+ api_infos: ???
23
+ model_name:
24
+ openai: gpt-4
25
+ azure: azure/gpt-4
26
+ input_interface_initialized:
27
+ - "new_plan"
28
+ - "feedback"
29
+ system_message_prompt_template:
30
+ _target_: langchain.PromptTemplate
31
+ template: |2-
32
+ You are in charge of a department of rewriting plans to solve a certain goal. You work with a re-planner, who does all the re-planning job.
33
+
34
+ You are not given the old plan, the planner is aware of the old plan, you do not need to care about the details of it.
35
+
36
+ Your **ONLY** task is to take the user's information about the old plan for you, to decide whether to call the re-planner to write or refine the plan, or to finish the current task.
37
+
38
+ When you need to call the plan writer, call the `write_plan` command with the goal specified.
39
+ When the plan is written and the user is satisfied, call the `finish` command to terminate the current process with a summary of what was done in one sentence.
40
+ Whenever you are in doubt, or need to confirm something to the user, call `ask_user` with the question.
41
+
42
+ You **must not** write plans yourself. You only decide whether to call the planner with specified goals or to finish.
43
+
44
+ Your workflow:
45
+ 0. Whenever the user demands to quit or terminate the current process, call `manual_finish` command.
46
+ 1. Upon user request, call the `write_plan` with the information given.
47
+ 2. The planner will write the plan. The user will examine the plan, and provide feedback.
48
+ 3. Depending on the feedback of the user:
49
+ 3.1. The user provides feedback on how to change the plan, **call the planner with user's specific requirements again, to ask the planner to refine the plan**. Go back to step 2.
50
+ 3.2. The user does not provide details about refining the plan, for example, just stating the fact that the user has updated the plan, **this means the user is satisfied with the plan written, call the `finish` command.**
51
+ 3.3. The user is satisfied with the plan, **call the `finish` command with a summary of what was done**
52
+
53
+ If you have completed all your tasks, make sure to use the "finish" command, with a summary of what was done.
54
+
55
+ Constraints:
56
+ 1. Exclusively use the commands listed in double quotes e.g. "command name"
57
+
58
+ Your response **MUST** be in the following format:
59
+ Response Format:
60
+ {
61
+ "command": "call plan writer, or to finish",
62
+ "command_args": {
63
+ "arg name": "value"
64
+ }
65
+ }
66
+ Ensure your responses can be parsed by Python json.loads
67
+
68
+
69
+ Available Functions:
70
+ {{commands}}
71
+ input_variables: [ "commands" ]
72
+ template_format: jinja2
73
+
74
+ human_message_prompt_template:
75
+ _target_: flows.prompt_template.JinjaPrompt
76
+ template: |2-
77
+ Here is the new plan written by the planner, it might have been updated by the user, depending on the user's feedback:
78
+ {{new_plan}}
79
+ Here is the feedback from the user:
80
+ {{feedback}}
81
+ input_variables:
82
+ - "new_plan"
83
+ - "feedback"
84
+ template_format: jinja2
85
+
86
+ init_human_message_prompt_template:
87
+ _target_: flows.prompt_template.JinjaPrompt
88
+ template: |2-
89
+ Here is the information about the old plan:
90
+ {{goal}}
91
+ input_variables:
92
+ - "goal"
93
+ template_format: jinja2
94
+
95
+ Executor:
96
+ _target_: flows.base_flows.BranchingFlow.instantiate_from_default_config
97
+ subflows_config:
98
+ write_plan:
99
+ _target_: Tachi67.InteractivePlanGenFlowModule.InteractivePlanGenFlow.instantiate_from_default_config
100
+ subflows_config:
101
+ PlanGenerator:
102
+ _target_: Tachi67.ReplanningFlowModule.NewPlanGenFlow.instantiate_from_default_config
103
+ backend:
104
+ api_infos: ???
105
+ model_name:
106
+ openai: gpt-4
107
+ azure: azure/gpt-4
108
+
109
+ PlanFileEditor:
110
+ _target_: Tachi67.PlanFileEditFlowModule.PlanFileEditAtomicFlow.instantiate_from_default_config
111
+ input_interface:
112
+ - "new_plan"
113
+ - "plan_file_location"
114
+
115
+ ParseFeedback:
116
+ _target_: Tachi67.ParseFeedbackFlowModule.ParseFeedbackAtomicFlow.instantiate_from_default_config
117
+ input_interface:
118
+ - "temp_plan_file_location"
119
+ - "temp_plan_file_written_timestamp"
120
+ output_interface:
121
+ - "new_plan"
122
+ - "feedback"
123
+
124
+ ask_user:
125
+ _target_: Tachi67.ReplanningFlowModule.ReplanningAskUserFlow.instantiate_from_default_config
126
+
127
+
128
+ early_exit_key: "EARLY_EXIT"
129
+
130
+ topology:
131
+ - goal: "Select the next action and prepare the input for the executor."
132
+ input_interface:
133
+ _target_: flows.interfaces.KeyInterface
134
+ additional_transformations:
135
+ - _target_: flows.data_transformations.KeyMatchInput
136
+ flow: Controller
137
+ output_interface:
138
+ _target_: ReplanningFlow.detect_finish_or_continue
139
+ reset: false
140
+
141
+ - goal: "Execute the action specified by the Controller."
142
+ input_interface:
143
+ _target_: flows.interfaces.KeyInterface
144
+ keys_to_rename:
145
+ command: branch
146
+ command_args: branch_input_data
147
+ keys_to_select: ["branch", "branch_input_data"]
148
+ flow: Executor
149
+ output_interface:
150
+ _target_: flows.interfaces.KeyInterface
151
+ keys_to_rename:
152
+ branch_output_data: observation
153
+ keys_to_unpack: ["observation"]
154
+ reset: false
__init__.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ dependencies = [
2
+ {"url": "Tachi67/PlanGeneratorFlowModule", "revision": "main"},
3
+ {"url": "Tachi67/InteractivePlanGenFlowModule", "revision": "main"},
4
+ {"url": "Tachi67/PlanWriterFlowModule", "revision": "main"},
5
+ {"url": "Tachi67/PlanFileEditFlowModule", "revision": "main"},
6
+ {"url": "Tachi67/ParseFeedbackFlowModule", "revision": "main"},
7
+ {"url": "aiflows/HumanStandardInputFlowModule", "revision": "5683a922372c5fa90be9f6447d6662d8d80341fc"}
8
+ ]
9
+
10
+ from flows import flow_verse
11
+ flow_verse.sync_dependencies(dependencies)
12
+
13
+ from .NewPlanGenFlow import NewPlanGenFlow
14
+ from .ReplanningFlow import ReplanningFlow
15
+ from .ReplanningAskUserFlow import ReplanningAskUserFlow