Skip to content

Commit 6855327

Browse files
authored
Merge pull request #200 from microsoft/vyokky/dev
release of UFO2
2 parents 521735d + ab9e589 commit 6855327

File tree

99 files changed

+5515
-641
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

99 files changed

+5515
-641
lines changed

README.md

Lines changed: 117 additions & 158 deletions
Large diffs are not rendered by default.

README_v1.md

Lines changed: 320 additions & 0 deletions
Large diffs are not rendered by default.

assets/comparison.png

37.7 KB
Loading

assets/framework2.png

80.9 KB
Loading

dataflow/config/config_dev.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
version: 0.1
22

3-
CONTROL_BACKEND: "uia" # The backend for control action
3+
CONTROL_BACKEND: "uia" # The list of backend for control action, currently we support uia and win32,
44
CONTROL_LIST: ["Button", "Edit", "TabItem", "Document", "ListItem", "MenuItem", "ScrollBar", "TreeItem", "Hyperlink", "ComboBox", "RadioButton", "DataItem", "Spinner"]
55
PRINT_LOG: False # Whether to print the log
66
LOG_LEVEL: "INFO" # The log level

dataflow/env/env_manager.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
_ufo_configs = UFOConfig.get_instance().config_data
1717

1818
if _ufo_configs is not None:
19-
_BACKEND = _ufo_configs["CONTROL_BACKEND"]
19+
_BACKEND = "uia"
2020
if _configs is not None:
2121
_MATCH_STRATEGY = _configs.get("MATCH_STRATEGY", "contains")
2222

@@ -64,14 +64,16 @@ def close(self) -> None:
6464
if self.app_window and self.app_window.process_id():
6565
self.app_window.close()
6666
sleep(1)
67-
# Forcefully close the application window
68-
if self.app_window.element_info.name.lower() != '':
67+
# Forcefully close the application window
68+
if self.app_window.element_info.name.lower() != "":
6969
self._check_and_kill_process()
7070
except Exception as e:
71-
logging.warning(f"Graceful close failed: {e}. Attempting to forcefully terminate the process.")
71+
logging.warning(
72+
f"Graceful close failed: {e}. Attempting to forcefully terminate the process."
73+
)
7274
self._check_and_kill_process()
7375
raise e
74-
76+
7577
def _check_and_kill_process(self) -> None:
7678
"""
7779
Checks if the process is still running and kills it if it is.
@@ -151,9 +153,11 @@ def _calculate_match_score(self, control, control_text) -> int:
151153
return 100 if re.search(pattern, control_content) else 0
152154
else:
153155
raise ValueError(f"Unknown match strategy: {_MATCH_STRATEGY}")
154-
155-
def find_matching_controller(self, filtered_annotation_dict: Dict[int, UIAWrapper], control_text: str) -> Tuple[str, UIAWrapper]:
156-
""""
156+
157+
def find_matching_controller(
158+
self, filtered_annotation_dict: Dict[int, UIAWrapper], control_text: str
159+
) -> Tuple[str, UIAWrapper]:
160+
""" "
157161
Select the best matched controller.
158162
:param filtered_annotation_dict: The filtered annotation dictionary.
159163
:param control_text: The text content of the control for additional context.

dataflow/execution/workflow/execute_flow.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515

1616
_configs = InstantiationConfig.get_instance().config_data
1717
_ufo_configs = UFOConfig.get_instance().config_data
18-
if _ufo_configs is not None:
19-
BACKEND = _ufo_configs["CONTROL_BACKEND"]
2018

2119

2220
class ExecuteFlow(AppAgentProcessor):
@@ -316,9 +314,11 @@ def execute_action(self) -> None:
316314
if self.control_text == "":
317315
control_selected = self.application_window
318316
else:
319-
self._control_label, control_selected = self._app_env.find_matching_controller(
320-
self.filtered_annotation_dict, self.control_text
317+
self._control_label, control_selected = (
318+
self._app_env.find_matching_controller(
319+
self.filtered_annotation_dict, self.control_text
321320
)
321+
)
322322
if control_selected:
323323
self._matched_control = control_selected.window_text()
324324

dataflow/instantiation/agent/prefill_agent.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,13 @@ def message_constructor(
5959
dynamic_examples: str,
6060
given_task: str,
6161
reference_steps: List[str],
62-
doc_control_state: Dict[str, str],
6362
log_path: str,
6463
) -> List[str]:
6564
"""
6665
Construct the prompt message for the PrefillAgent.
6766
:param dynamic_examples: The dynamic examples retrieved from the self-demonstration and human demonstration.
6867
:param given_task: The given task.
6968
:param reference_steps: The reference steps.
70-
:param doc_control_state: The document control state.
7169
:param log_path: The path of the log.
7270
:return: The prompt message.
7371
"""
@@ -76,7 +74,7 @@ def message_constructor(
7674
dynamic_examples
7775
)
7876
prefill_agent_prompt_user_message = self.prompter.user_content_construction(
79-
given_task, reference_steps, doc_control_state, log_path
77+
given_task, reference_steps, log_path
8078
)
8179
appagent_prompt_message = self.prompter.prompt_construction(
8280
prefill_agent_prompt_system_message,

dataflow/instantiation/workflow/prefill_flow.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@
1515

1616
_configs = Config.get_instance().config_data
1717
_ufo_configs = UFOConfig.get_instance().config_data
18-
if _ufo_configs is not None:
19-
_BACKEND = _ufo_configs["CONTROL_BACKEND"]
18+
_BACKEND = "uia"
2019

2120

2221
class PrefillFlow(AppAgentProcessor):
@@ -98,10 +97,10 @@ def execute(
9897
finally:
9998
self.execution_time = round(time.time() - start_time, 3)
10099

101-
return {
100+
return {
102101
"instantiated_request": instantiated_request,
103102
"instantiated_plan": instantiated_plan,
104-
}
103+
}
105104

106105
def _instantiate_task(
107106
self, template_copied_path: str, original_task: str, refined_steps: List[str]
@@ -131,7 +130,7 @@ def _instantiate_task(
131130
raise e
132131

133132
return instantiated_request, instantiated_plan
134-
133+
135134
def _update_state(self, file_path: str) -> None:
136135
"""
137136
Update the current state of the app by inspecting UI elements.
@@ -194,7 +193,6 @@ def _get_prefill_actions(
194193
"",
195194
given_task,
196195
reference_steps,
197-
self._filtered_control_info,
198196
self._log_path_configs,
199197
)
200198

@@ -260,7 +258,7 @@ def _save_screenshot(self, doc_name: str, save_path: str) -> None:
260258
:param doc_name: The name or description of the document to match the window.
261259
:param save_path: The path where the screenshot will be saved.
262260
"""
263-
261+
264262
try:
265263
# Find the window matching the document name
266264
matched_window = self._app_env.find_matching_window(doc_name)

dataflow/prompter/instantiation/prefill_prompter.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,20 +75,18 @@ def system_prompt_construction(self, additional_examples: List = []) -> str:
7575
return self.prompt_template["system"].format(apis=apis, examples=examples)
7676

7777
def user_prompt_construction(
78-
self, given_task: str, reference_steps: List, doc_control_state: Dict
78+
self, given_task: str, reference_steps: List
7979
) -> str:
8080
"""
8181
Construct the prompt for the user.
8282
:param given_task: The given task.
8383
:param reference_steps: The reference steps.
84-
:param doc_control_state: The document control state.
8584
:return: The prompt for the user.
8685
"""
8786

8887
prompt = self.prompt_template["user"].format(
8988
given_task=given_task,
90-
reference_steps=json.dumps(reference_steps),
91-
doc_control_state=json.dumps(doc_control_state),
89+
reference_steps=json.dumps(reference_steps)
9290
)
9391

9492
return prompt
@@ -110,14 +108,12 @@ def user_content_construction(
110108
self,
111109
given_task: str,
112110
reference_steps: List,
113-
doc_control_state: Dict,
114111
log_path: str,
115112
) -> List[Dict]:
116113
"""
117114
Construct the prompt for LLMs.
118115
:param given_task: The given task.
119116
:param reference_steps: The reference steps.
120-
:param doc_control_state: The document control state.
121117
:param log_path: The path of the log.
122118
:return: The prompt for LLMs.
123119
"""
@@ -135,7 +131,7 @@ def user_content_construction(
135131
{
136132
"type": "text",
137133
"text": self.user_prompt_construction(
138-
given_task, reference_steps, doc_control_state
134+
given_task, reference_steps
139135
),
140136
}
141137
)

0 commit comments

Comments
 (0)