Instantiation
There are three key steps in the instantiation process:
Choose a template
file according to the specified app and instruction.
Prefill
the task using the current screenshot.
Filter
the established task.
Given the initial task, the dataflow first choose a template (Phase 1
), the prefill the initial task based on word envrionment to obtain task-action data (Phase 2
). Finnally, it will filter the established task to evaluate the quality of task-action data.
1. Choose Template File
Templates for your app must be defined and described in dataflow/templates/app
. For instance, if you want to instantiate tasks for the Word application, place the relevant .docx
files in dataflow /templates/word
, along with a description.json
file. The appropriate template will be selected based on how well its description matches the instruction.
The ChooseTemplateFlow
uses semantic matching, where task descriptions are compared with template descriptions using embeddings and FAISS for efficient nearest neighbor search. If semantic matching fails, a random template is chosen from the available files.
2. Prefill the Task
PrefillFlow
The PrefillFlow
class orchestrates the refinement of task plans and UI interactions by leveraging PrefillAgent
for task planning and action generation. It automates UI control updates, captures screenshots, and manages logs for messages and responses during execution.
PrefillAgent
The PrefillAgent
class facilitates task instantiation and action sequence generation by constructing tailored prompt messages using the PrefillPrompter
. It integrates system, user, and dynamic context to generate actionable inputs for down-stream workflows.
3. Filter Task
FilterFlow
The FilterFlow
class is designed to process and refine task plans by leveraging a FilterAgent
. The FilterFlow
class acts as a bridge between the instantiation of tasks and the execution of a filtering process, aiming to refine task steps and prefill task-related files based on predefined filtering criteria.
FilterAgent
The FilterAgent
class is a specialized agent used to evaluate whether an instantiated task is correct. It inherits from the BasicAgent class and includes several methods and attributes to handle its functionality.
Reference
ChooseTemplateFlow
Class to select and copy the most relevant template file based on the given task context.
Initialize the flow with the given task context.
Parameters: |
-
app_name
(str )
–
The name of the application.
-
file_extension
(str )
–
The file extension of the template.
-
task_file_name
(str )
–
The name of the task file.
|
Source code in instantiation/workflow/choose_template_flow.py
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 | def __init__(self, app_name: str, task_file_name: str, file_extension: str):
"""
Initialize the flow with the given task context.
:param app_name: The name of the application.
:param file_extension: The file extension of the template.
:param task_file_name: The name of the task file.
"""
self._app_name = app_name
self._file_extension = file_extension
self._task_file_name = task_file_name
self.execution_time = None
self._embedding_model = self._load_embedding_model(
model_name=_configs["CONTROL_FILTER_MODEL_SEMANTIC_NAME"]
)
|
_choose_random_template()
Select a random template file from the template folder.
Returns: |
-
str
–
The path to the randomly selected template file.
|
Source code in instantiation/workflow/choose_template_flow.py
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131 | def _choose_random_template(self) -> str:
"""
Select a random template file from the template folder.
:return: The path to the randomly selected template file.
"""
template_folder = Path(_configs["TEMPLATE_PATH"]) / self._app_name
template_files = [f for f in template_folder.iterdir() if f.is_file()]
if not template_files:
raise Exception("No template files found in the specified directory.")
chosen_template_file = random.choice(template_files)
print(f"Randomly selected template: {chosen_template_file.name}")
return str(chosen_template_file)
|
_choose_target_template_file(given_task, doc_files_description)
Get the target file based on the semantic similarity of the given task and the template file descriptions.
Parameters: |
-
given_task
(str )
–
-
doc_files_description
(Dict[str, str] )
–
A dictionary of template file descriptions.
|
Returns: |
-
str
–
The path to the chosen template file.
|
Source code in instantiation/workflow/choose_template_flow.py
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176 | def _choose_target_template_file(
self, given_task: str, doc_files_description: Dict[str, str]
) -> str:
"""
Get the target file based on the semantic similarity of the given task and the template file descriptions.
:param given_task: The task to be matched.
:param doc_files_description: A dictionary of template file descriptions.
:return: The path to the chosen template file.
"""
if _configs["TEMPLATE_METHOD"] == "SemanticSimilarity":
return self._choose_target_template_file_semantic(
given_task, doc_files_description
)
elif _configs["TEMPLATE_METHOD"] == "LLM":
self.template_agent = TemplateAgent(
"template",
is_visual=True,
main_prompt=_configs["TEMPLATE_PROMPT"],
)
return self._choose_target_template_file_llm(
given_task, doc_files_description
)
else:
raise ValueError("Invalid TEMPLATE_METHOD.")
|
_choose_target_template_file_llm(given_task, doc_files_description)
Get the target file based on the LLM of the given task and the template file descriptions.
Parameters: |
-
given_task
(str )
–
-
doc_files_description
(Dict[str, str] )
–
A dictionary of template file descriptions.
|
Returns: |
-
str
–
The path to the chosen template file.
|
Source code in instantiation/workflow/choose_template_flow.py
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225 | def _choose_target_template_file_llm(
self, given_task: str, doc_files_description: Dict[str, str]
) -> str:
"""
Get the target file based on the LLM of the given task and the template file descriptions.
:param given_task: The task to be matched.
:param doc_files_description: A dictionary of template file descriptions.
:return: The path to the chosen template file.
"""
prompt_message = self.template_agent.message_constructor(
doc_files_description, given_task
)
response_string, _ = self.template_agent.get_response(
prompt_message, "prefill", use_backup_engine=True, configs=_configs
)
if response_string is None:
raise ValueError("No similar templates found.")
elif "```json" in response_string:
response_string = response_string[7:-3]
response_json = json.loads(response_string)
file_name = list(response_json.keys())[0]
if file_name not in doc_files_description:
print(f"Template {file_name} not found in the description.")
raise ValueError("No similar templates found.")
return file_name
|
_choose_target_template_file_semantic(given_task, doc_files_description)
Get the target file based on the semantic similarity of the given task and the template file descriptions.
Parameters: |
-
given_task
(str )
–
-
doc_files_description
(Dict[str, str] )
–
A dictionary of template file descriptions.
|
Returns: |
-
str
–
The path to the chosen template file.
|
Source code in instantiation/workflow/choose_template_flow.py
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198 | def _choose_target_template_file_semantic(
self, given_task: str, doc_files_description: Dict[str, str]
) -> str:
"""
Get the target file based on the semantic similarity of the given task and the template file descriptions.
:param given_task: The task to be matched.
:param doc_files_description: A dictionary of template file descriptions.
:return: The path to the chosen template file.
"""
file_doc_map = {
desc: file_name for file_name, desc in doc_files_description.items()
}
db = FAISS.from_texts(
list(doc_files_description.values()), self._embedding_model
)
most_similar = db.similarity_search(given_task, k=1)
if not most_similar:
raise ValueError("No similar templates found.")
return file_doc_map[most_similar[0].page_content]
|
_choose_template_and_copy()
Choose the template and copy it to the cache folder.
Returns: |
-
str
–
The path to the copied template file.
|
Source code in instantiation/workflow/choose_template_flow.py
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150 | def _choose_template_and_copy(self) -> str:
"""
Choose the template and copy it to the cache folder.
:return: The path to the copied template file.
"""
chosen_template_file_path = self._get_chosen_file_path()
chosen_template_full_path = (
Path(_configs["TEMPLATE_PATH"]) / self._app_name / chosen_template_file_path
)
target_template_folder_path = Path(
_configs["RESULT_HUB"].format(task_type="saved_document")
) / (os.path.dirname(os.path.dirname(self._task_file_name)))
return self._create_copied_file(
chosen_template_full_path, target_template_folder_path, self._task_file_name
)
|
_create_copied_file(copy_from_path, copy_to_folder_path, file_name=None)
Create a cache file from the specified source.
Parameters: |
-
copy_from_path
(Path )
–
The original path of the file.
-
copy_to_folder_path
(Path )
–
The path where the cache file will be created.
-
file_name
(str , default:
None
)
–
Optional; the name of the task file.
|
Returns: |
-
str
–
The path to the newly created cache file.
|
Source code in instantiation/workflow/choose_template_flow.py
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80 | def _create_copied_file(
self, copy_from_path: Path, copy_to_folder_path: Path, file_name: str = None
) -> str:
"""
Create a cache file from the specified source.
:param copy_from_path: The original path of the file.
:param copy_to_folder_path: The path where the cache file will be created.
:param file_name: Optional; the name of the task file.
:return: The path to the newly created cache file.
"""
os.makedirs(copy_to_folder_path, exist_ok=True)
copied_template_path = self._generate_copied_file_path(
copy_to_folder_path, file_name
)
with open(copy_from_path, "rb") as f:
ori_content = f.read()
with open(copied_template_path, "wb") as f:
f.write(ori_content)
return copied_template_path
|
_generate_copied_file_path(folder_path, file_name)
Generate the file path for the copied template.
Parameters: |
-
folder_path
(Path )
–
The folder where the file will be created.
-
file_name
(str )
–
Optional; the name of the task file.
|
Returns: |
-
str
–
The path to the newly created file.
|
Source code in instantiation/workflow/choose_template_flow.py
82
83
84
85
86
87
88
89
90
91
92
93
94 | def _generate_copied_file_path(self, folder_path: Path, file_name: str) -> str:
"""
Generate the file path for the copied template.
:param folder_path: The folder where the file will be created.
:param file_name: Optional; the name of the task file.
:return: The path to the newly created file.
"""
template_extension = self._file_extension
if file_name:
return str(folder_path / f"{file_name}{template_extension}")
timestamp = datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
return str(folder_path / f"{timestamp}{template_extension}")
|
_get_chosen_file_path()
Choose the most relevant template file based on the task.
Returns: |
-
str
–
The path to the most relevant template file.
|
Source code in instantiation/workflow/choose_template_flow.py
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115 | def _get_chosen_file_path(self) -> str:
"""
Choose the most relevant template file based on the task.
:return: The path to the most relevant template file.
"""
templates_description_path = (
Path(_configs["TEMPLATE_PATH"]) / self._app_name / "description.json"
)
try:
with open(templates_description_path, "r") as f:
return self._choose_target_template_file(
self._task_file_name, json.load(f)
)
except FileNotFoundError:
warnings.warn(
f"Warning: {templates_description_path} does not exist. Choosing a random template."
)
return self._choose_random_template()
|
_load_embedding_model(model_name)
staticmethod
Load the embedding model.
Parameters: |
-
model_name
(str )
–
The name of the embedding model to load.
|
Returns: |
-
CacheBackedEmbeddings
–
The loaded embedding model.
|
Source code in instantiation/workflow/choose_template_flow.py
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241 | @staticmethod
def _load_embedding_model(model_name: str) -> CacheBackedEmbeddings:
"""
Load the embedding model.
:param model_name: The name of the embedding model to load.
:return: The loaded embedding model.
"""
store = LocalFileStore(_configs["CONTROL_EMBEDDING_CACHE_PATH"])
if not model_name.startswith(ChooseTemplateFlow._SENTENCE_TRANSFORMERS_PREFIX):
model_name = ChooseTemplateFlow._SENTENCE_TRANSFORMERS_PREFIX + model_name
embedding_model = HuggingFaceEmbeddings(model_name=model_name)
return CacheBackedEmbeddings.from_bytes_store(
embedding_model, store, namespace=model_name
)
|
execute()
Execute the flow and return the copied template path.
Returns: |
-
str
–
The path to the copied template file.
|
Source code in instantiation/workflow/choose_template_flow.py
44
45
46
47
48
49
50
51
52
53
54
55
56
57 | def execute(self) -> str:
"""
Execute the flow and return the copied template path.
:return: The path to the copied template file.
"""
start_time = time.time()
try:
template_copied_path = self._choose_template_and_copy()
except Exception as e:
raise e
finally:
self.execution_time = round(time.time() - start_time, 3)
return template_copied_path
|
PrefillFlow
Bases: AppAgentProcessor
Class to manage the prefill process by refining planning steps and automating UI interactions
Initialize the prefill flow with the application context.
Parameters: |
-
app_name
(str )
–
The name of the application.
-
task_file_name
(str )
–
The name of the task file for logging and tracking.
-
environment
(WindowsAppEnv )
–
The environment of the app.
|
Source code in instantiation/workflow/prefill_flow.py
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77 | def __init__(
self,
app_name: str,
task_file_name: str,
environment: WindowsAppEnv,
) -> None:
"""
Initialize the prefill flow with the application context.
:param app_name: The name of the application.
:param task_file_name: The name of the task file for logging and tracking.
:param environment: The environment of the app.
"""
self.execution_time = None
self._app_name = app_name
self._task_file_name = task_file_name
self._app_env = environment
if self._app_name not in PrefillFlow._app_prefill_agent_dict:
PrefillFlow._app_prefill_agent_dict[self._app_name] = PrefillAgent(
"prefill",
self._app_name,
is_visual=True,
main_prompt=_configs["PREFILL_PROMPT"],
example_prompt=_configs["PREFILL_EXAMPLE_PROMPT"],
api_prompt=_configs["API_PROMPT"],
)
self._prefill_agent = PrefillFlow._app_prefill_agent_dict[self._app_name]
self._execute_step = 0
self._control_inspector = ControlInspectorFacade(_BACKEND)
self._photographer = PhotographerFacade()
self._status = ""
self._log_path_configs = _configs["PREFILL_LOG_PATH"].format(
task=self._task_file_name
)
os.makedirs(self._log_path_configs, exist_ok=True)
self._message_logger = BaseSession.initialize_logger(
self._log_path_configs, "prefill_messages.json", "w", _configs
)
self._response_logger = BaseSession.initialize_logger(
self._log_path_configs, "prefill_responses.json", "w", _configs
)
|
_get_prefill_actions(given_task, reference_steps, file_path)
Generate refined tasks and action plans using the PrefillAgent.
Parameters: |
-
given_task
(str )
–
-
reference_steps
(List[str] )
–
Reference steps for the task.
-
file_path
(str )
–
Path to the task template.
|
Returns: |
-
Tuple[str, List[str]]
–
The refined task and corresponding action plans.
|
Source code in instantiation/workflow/prefill_flow.py
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223 | def _get_prefill_actions(
self, given_task: str, reference_steps: List[str], file_path: str
) -> Tuple[str, List[str]]:
"""
Generate refined tasks and action plans using the PrefillAgent.
:param given_task: The task to refine.
:param reference_steps: Reference steps for the task.
:param file_path: Path to the task template.
:return: The refined task and corresponding action plans.
"""
self._update_state(file_path)
execution_time = 0
screenshot_path = os.path.join(self._log_path_configs, "screenshot.png")
self._save_screenshot(self._task_file_name, screenshot_path)
prompt_message = self._prefill_agent.message_constructor(
"",
given_task,
reference_steps,
self._log_path_configs,
)
self._log_message(prompt_message)
try:
start_time = time.time()
response_string, _ = self._prefill_agent.get_response(
prompt_message, "prefill", use_backup_engine=True, configs=_configs
)
execution_time = round(time.time() - start_time, 3)
response_json = self._prefill_agent.response_to_dict(response_string)
instantiated_request = response_json["New_task"]
instantiated_plan = response_json["Actions_plan"]
except Exception as e:
self._status = "ERROR"
logging.exception(f"Error in prefilling task: {e}")
raise e
finally:
self._log_response(response_json, execution_time)
return instantiated_request, instantiated_plan
|
_instantiate_task(template_copied_path, original_task, refined_steps)
Retrieve and process the instantiated result for the task.
Interacts with the PrefillAgent to refine the task and generate action plans.
Parameters: |
-
template_copied_path
(str )
–
The path of the copied template to use.
-
original_task
(str )
–
The original task to refine.
-
refined_steps
(List[str] )
–
The steps to guide the refinement process.
|
Returns: |
-
Tuple[str, List[str]]
–
The refined task and corresponding action plans.
|
Source code in instantiation/workflow/prefill_flow.py
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132 | def _instantiate_task(
self, template_copied_path: str, original_task: str, refined_steps: List[str]
) -> Tuple[str, List[str]]:
"""
Retrieve and process the instantiated result for the task.
Interacts with the PrefillAgent to refine the task and generate action plans.
:param template_copied_path: The path of the copied template to use.
:param original_task: The original task to refine.
:param refined_steps: The steps to guide the refinement process.
:return: The refined task and corresponding action plans.
"""
try:
instantiated_request, instantiated_plan = self._get_prefill_actions(
original_task,
refined_steps,
template_copied_path,
)
print(f"Original Task: {original_task}")
print(f"Prefilled Task: {instantiated_request}")
except Exception as e:
logging.exception(f"Error in prefilling task: {e}")
raise e
return instantiated_request, instantiated_plan
|
_log_message(prompt_message)
Log the constructed prompt message for the PrefillAgent.
Parameters: |
-
prompt_message
(str )
–
The message constructed for PrefillAgent.
|
Source code in instantiation/workflow/prefill_flow.py
225
226
227
228
229
230
231
232
233
234
235
236 | def _log_message(self, prompt_message: str) -> None:
"""
Log the constructed prompt message for the PrefillAgent.
:param prompt_message: The message constructed for PrefillAgent.
"""
messages_log_entry = {
"step": self._execute_step,
"messages": prompt_message,
"error": "",
}
self._message_logger.info(json.dumps(messages_log_entry, indent=4))
|
_log_response(response_json, execution_time)
Log the response received from PrefillAgent along with execution time.
Parameters: |
-
response_json
(Dict[str, Any] )
–
Response data from PrefillAgent.
-
execution_time
(float )
–
Time taken for the PrefillAgent call.
|
Source code in instantiation/workflow/prefill_flow.py
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253 | def _log_response(
self, response_json: Dict[str, Any], execution_time: float
) -> None:
"""
Log the response received from PrefillAgent along with execution time.
:param response_json: Response data from PrefillAgent.
:param execution_time: Time taken for the PrefillAgent call.
"""
response_log_entry = {
"step": self._execute_step,
"execution_time": execution_time,
"agent_response": response_json,
"error": "",
}
self._response_logger.info(json.dumps(response_log_entry, indent=4))
|
_save_screenshot(doc_name, save_path)
Captures a screenshot of the current window or the full screen if the window is not found.
Parameters: |
-
doc_name
(str )
–
The name or description of the document to match the window.
-
save_path
(str )
–
The path where the screenshot will be saved.
|
Source code in instantiation/workflow/prefill_flow.py
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277 | def _save_screenshot(self, doc_name: str, save_path: str) -> None:
"""
Captures a screenshot of the current window or the full screen if the window is not found.
:param doc_name: The name or description of the document to match the window.
:param save_path: The path where the screenshot will be saved.
"""
try:
matched_window = self._app_env.find_matching_window(doc_name)
if matched_window:
screenshot = self._photographer.capture_app_window_screenshot(
matched_window
)
else:
logging.warning("Window not found, taking a full-screen screenshot.")
screenshot = self._photographer.capture_desktop_screen_screenshot()
screenshot.save(save_path)
print(f"Screenshot saved to {save_path}")
except Exception as e:
logging.exception(f"Failed to save screenshot: {e}")
raise e
|
_update_state(file_path)
Update the current state of the app by inspecting UI elements.
Parameters: |
-
file_path
(str )
–
Path of the app file to inspect.
|
Source code in instantiation/workflow/prefill_flow.py
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172 | def _update_state(self, file_path: str) -> None:
"""
Update the current state of the app by inspecting UI elements.
:param file_path: Path of the app file to inspect.
"""
print(f"Updating the app state using the file: {file_path}")
control_list = self._control_inspector.find_control_elements_in_descendants(
self._app_env.app_window,
control_type_list=_ufo_configs["CONTROL_LIST"],
class_name_list=_ufo_configs["CONTROL_LIST"],
)
self._annotation_dict = self._photographer.get_annotation_dict(
self._app_env.app_window, control_list, annotation_type="number"
)
self._filtered_annotation_dict = self.get_filtered_annotation_dict(
self._annotation_dict, configs=_configs
)
self._control_info = self._control_inspector.get_control_info_list_of_dict(
self._annotation_dict,
["control_text", "control_type" if _BACKEND == "uia" else "control_class"],
)
self._filtered_control_info = (
self._control_inspector.get_control_info_list_of_dict(
self._filtered_annotation_dict,
[
"control_text",
"control_type" if _BACKEND == "uia" else "control_class",
],
)
)
|
execute(template_copied_path, original_task, refined_steps)
Start the execution by retrieving the instantiated result.
Parameters: |
-
template_copied_path
(str )
–
The path of the copied template to use.
-
original_task
(str )
–
The original task to refine.
-
refined_steps
(List[str] )
–
The steps to guide the refinement process.
|
Returns: |
-
Dict[str, Any]
–
The refined task and corresponding action plans.
|
Source code in instantiation/workflow/prefill_flow.py
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103 | def execute(
self, template_copied_path: str, original_task: str, refined_steps: List[str]
) -> Dict[str, Any]:
"""
Start the execution by retrieving the instantiated result.
:param template_copied_path: The path of the copied template to use.
:param original_task: The original task to refine.
:param refined_steps: The steps to guide the refinement process.
:return: The refined task and corresponding action plans.
"""
start_time = time.time()
try:
instantiated_request, instantiated_plan = self._instantiate_task(
template_copied_path, original_task, refined_steps
)
except Exception as e:
raise e
finally:
self.execution_time = round(time.time() - start_time, 3)
return {
"instantiated_request": instantiated_request,
"instantiated_plan": instantiated_plan,
}
|
PrefillAgent
Bases: BasicAgent
The Agent for task instantialization and action sequence generation.
Initialize the PrefillAgent.
Parameters: |
-
name
(str )
–
-
process_name
(str )
–
-
is_visual
(bool )
–
The flag indicating whether the agent is visual or not.
-
main_prompt
(str )
–
-
example_prompt
(str )
–
-
api_prompt
(str )
–
|
Source code in instantiation/agent/prefill_agent.py
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 | def __init__(
self,
name: str,
process_name: str,
is_visual: bool,
main_prompt: str,
example_prompt: str,
api_prompt: str,
):
"""
Initialize the PrefillAgent.
:param name: The name of the agent.
:param process_name: The name of the process.
:param is_visual: The flag indicating whether the agent is visual or not.
:param main_prompt: The main prompt.
:param example_prompt: The example prompt.
:param api_prompt: The API prompt.
"""
self._step = 0
self._complete = False
self._name = name
self._status = None
self.prompter: PrefillPrompter = self.get_prompter(
is_visual, main_prompt, example_prompt, api_prompt
)
self._process_name = process_name
|
get_prompter(is_visual, main_prompt, example_prompt, api_prompt)
Get the prompt for the agent.
This is the abstract method from BasicAgent that needs to be implemented.
Parameters: |
-
is_visual
(bool )
–
The flag indicating whether the agent is visual or not.
-
main_prompt
(str )
–
-
example_prompt
(str )
–
-
api_prompt
(str )
–
|
Source code in instantiation/agent/prefill_agent.py
44
45
46
47
48
49
50
51
52
53
54
55 | def get_prompter(self, is_visual: bool, main_prompt: str, example_prompt: str, api_prompt: str) -> str:
"""
Get the prompt for the agent.
This is the abstract method from BasicAgent that needs to be implemented.
:param is_visual: The flag indicating whether the agent is visual or not.
:param main_prompt: The main prompt.
:param example_prompt: The example prompt.
:param api_prompt: The API prompt.
:return: The prompt string.
"""
return PrefillPrompter(is_visual, main_prompt, example_prompt, api_prompt)
|
message_constructor(dynamic_examples, given_task, reference_steps, log_path)
Construct the prompt message for the PrefillAgent.
Parameters: |
-
dynamic_examples
(str )
–
The dynamic examples retrieved from the self-demonstration and human demonstration.
-
given_task
(str )
–
-
reference_steps
(List[str] )
–
-
log_path
(str )
–
|
Source code in instantiation/agent/prefill_agent.py
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84 | def message_constructor(
self,
dynamic_examples: str,
given_task: str,
reference_steps: List[str],
log_path: str,
) -> List[str]:
"""
Construct the prompt message for the PrefillAgent.
:param dynamic_examples: The dynamic examples retrieved from the self-demonstration and human demonstration.
:param given_task: The given task.
:param reference_steps: The reference steps.
:param log_path: The path of the log.
:return: The prompt message.
"""
prefill_agent_prompt_system_message = self.prompter.system_prompt_construction(
dynamic_examples
)
prefill_agent_prompt_user_message = self.prompter.user_content_construction(
given_task, reference_steps, log_path
)
appagent_prompt_message = self.prompter.prompt_construction(
prefill_agent_prompt_system_message,
prefill_agent_prompt_user_message,
)
return appagent_prompt_message
|
process_comfirmation()
Confirm the process.
This is the abstract method from BasicAgent that needs to be implemented.
Source code in instantiation/agent/prefill_agent.py
| def process_comfirmation(self) -> None:
"""
Confirm the process.
This is the abstract method from BasicAgent that needs to be implemented.
"""
pass
|
FilterFlow
Class to refine the plan steps and prefill the file based on filtering criteria.
Initialize the filter flow for a task.
Parameters: |
-
app_name
(str )
–
Name of the application being processed.
-
task_file_name
(str )
–
Name of the task file being processed.
|
Source code in instantiation/workflow/filter_flow.py
21
22
23
24
25
26
27
28
29
30
31
32 | def __init__(self, app_name: str, task_file_name: str) -> None:
"""
Initialize the filter flow for a task.
:param app_name: Name of the application being processed.
:param task_file_name: Name of the task file being processed.
"""
self.execution_time = None
self._app_name = app_name
self._log_path_configs = _configs["FILTER_LOG_PATH"].format(task=task_file_name)
self._filter_agent = self._get_or_create_filter_agent()
self._initialize_logs()
|
_fix_json_commas(json_string)
Function to add missing commas between key-value pairs in a JSON string
and remove newline characters for proper formatting.
Parameters: |
-
json_string
(str )
–
The JSON string to be fixed.
|
Source code in instantiation/workflow/filter_flow.py
132
133
134
135
136
137
138
139
140
141
142
143 | def _fix_json_commas(self, json_string: str) -> str:
"""
Function to add missing commas between key-value pairs in a JSON string
and remove newline characters for proper formatting.
:param json_string: The JSON string to be fixed.
:return: The fixed JSON string.
"""
json_string = json_string.replace("\n", "")
return json_string
|
_get_filtered_result(instantiated_request)
Get the filtered result from the filter agent.
Parameters: |
-
instantiated_request
(str )
–
Request object containing task details.
|
Returns: |
-
Tuple[bool, str, str]
–
Tuple containing task quality flag, request comment, and request type.
|
Source code in instantiation/workflow/filter_flow.py
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130 | def _get_filtered_result(self, instantiated_request: str) -> Tuple[bool, str, str]:
"""
Get the filtered result from the filter agent.
:param instantiated_request: Request object containing task details.
:return: Tuple containing task quality flag, request comment, and request type.
"""
prompt_message = self._filter_agent.message_constructor(
instantiated_request,
self._app_name,
)
prompt_json = json.dumps(prompt_message, indent=4)
self._filter_message_logger.info(prompt_json)
try:
start_time = time.time()
response_string, _ = self._filter_agent.get_response(
prompt_message, "filter", use_backup_engine=True, configs=_configs
)
try:
fixed_response_string = self._fix_json_commas(response_string)
response_json = self._filter_agent.response_to_dict(
fixed_response_string
)
except json.JSONDecodeError as e:
logging.error(
f"JSONDecodeError: {e.msg} at position {e.pos}. Response: {response_string}"
)
raise e
execution_time = round(time.time() - start_time, 3)
response_json["execution_time"] = execution_time
self._filter_response_logger.info(json.dumps(response_json, indent=4))
return (
response_json["judge"],
response_json["thought"],
response_json["type"],
)
except Exception as e:
logging.error(f"Error occurred while filtering: {e}")
raise e
|
_get_or_create_filter_agent()
Retrieve or create a filter agent for the given application.
Returns: |
-
FilterAgent
–
FilterAgent instance for the specified application.
|
Source code in instantiation/workflow/filter_flow.py
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 | def _get_or_create_filter_agent(self) -> FilterAgent:
"""
Retrieve or create a filter agent for the given application.
:return: FilterAgent instance for the specified application.
"""
if self._app_name not in FilterFlow._app_filter_agent_dict:
FilterFlow._app_filter_agent_dict[self._app_name] = FilterAgent(
"filter",
self._app_name,
is_visual=True,
main_prompt=_configs["FILTER_PROMPT"],
example_prompt="",
api_prompt=_configs["API_PROMPT"],
)
return FilterFlow._app_filter_agent_dict[self._app_name]
|
_initialize_logs()
Initialize logging for filter messages and responses.
Source code in instantiation/workflow/filter_flow.py
73
74
75
76
77
78
79
80
81
82
83
84 | def _initialize_logs(self) -> None:
"""
Initialize logging for filter messages and responses.
"""
os.makedirs(self._log_path_configs, exist_ok=True)
self._filter_message_logger = BaseSession.initialize_logger(
self._log_path_configs, "filter_messages.json", "w", _configs
)
self._filter_response_logger = BaseSession.initialize_logger(
self._log_path_configs, "filter_responses.json", "w", _configs
)
|
execute(instantiated_request)
Execute the filter flow: Filter the task and save the result.
Parameters: |
-
instantiated_request
(str )
–
Request object to be filtered.
|
Returns: |
-
Dict[str, Any]
–
Tuple containing task quality flag, comment, and task type.
|
Source code in instantiation/workflow/filter_flow.py
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 | def execute(self, instantiated_request: str) -> Dict[str, Any]:
"""
Execute the filter flow: Filter the task and save the result.
:param instantiated_request: Request object to be filtered.
:return: Tuple containing task quality flag, comment, and task type.
"""
start_time = time.time()
try:
judge, thought, request_type = self._get_filtered_result(
instantiated_request
)
except Exception as e:
raise e
finally:
self.execution_time = round(time.time() - start_time, 3)
return {
"judge": judge,
"thought": thought,
"request_type": request_type,
}
|
FilterAgent
Bases: BasicAgent
The Agent to evaluate the instantiated task is correct or not.
Initialize the FilterAgent.
Parameters: |
-
name
(str )
–
-
process_name
(str )
–
-
is_visual
(bool )
–
The flag indicating whether the agent is visual or not.
-
main_prompt
(str )
–
-
example_prompt
(str )
–
-
api_prompt
(str )
–
|
Source code in instantiation/agent/filter_agent.py
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 | def __init__(
self,
name: str,
process_name: str,
is_visual: bool,
main_prompt: str,
example_prompt: str,
api_prompt: str,
):
"""
Initialize the FilterAgent.
:param name: The name of the agent.
:param process_name: The name of the process.
:param is_visual: The flag indicating whether the agent is visual or not.
:param main_prompt: The main prompt.
:param example_prompt: The example prompt.
:param api_prompt: The API prompt.
"""
self._step = 0
self._complete = False
self._name = name
self._status = None
self.prompter: FilterPrompter = self.get_prompter(
is_visual, main_prompt, example_prompt, api_prompt
)
self._process_name = process_name
|
get_prompter(is_visual, main_prompt, example_prompt, api_prompt)
Get the prompt for the agent.
Parameters: |
-
is_visual
(bool )
–
The flag indicating whether the agent is visual or not.
-
main_prompt
(str )
–
-
example_prompt
(str )
–
-
api_prompt
(str )
–
|
Source code in instantiation/agent/filter_agent.py
43
44
45
46
47
48
49
50
51
52
53
54
55 | def get_prompter(
self, is_visual: bool, main_prompt: str, example_prompt: str, api_prompt: str
) -> FilterPrompter:
"""
Get the prompt for the agent.
:param is_visual: The flag indicating whether the agent is visual or not.
:param main_prompt: The main prompt.
:param example_prompt: The example prompt.
:param api_prompt: The API prompt.
:return: The prompt string.
"""
return FilterPrompter(is_visual, main_prompt, example_prompt, api_prompt)
|
message_constructor(request, app)
Construct the prompt message for the FilterAgent.
Parameters: |
-
request
(str )
–
-
app
(str )
–
The name of the operated app.
|
Source code in instantiation/agent/filter_agent.py
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75 | def message_constructor(self, request: str, app: str) -> List[str]:
"""
Construct the prompt message for the FilterAgent.
:param request: The request sentence.
:param app: The name of the operated app.
:return: The prompt message.
"""
filter_agent_prompt_system_message = self.prompter.system_prompt_construction(
app=app
)
filter_agent_prompt_user_message = self.prompter.user_content_construction(
request
)
filter_agent_prompt_message = self.prompter.prompt_construction(
filter_agent_prompt_system_message, filter_agent_prompt_user_message
)
return filter_agent_prompt_message
|
process_comfirmation()
Confirm the process.
This is the abstract method from BasicAgent that needs to be implemented.
Source code in instantiation/agent/filter_agent.py
| def process_comfirmation(self) -> None:
"""
Confirm the process.
This is the abstract method from BasicAgent that needs to be implemented.
"""
pass
|