oagi-core 0.14.0__tar.gz → 0.14.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {oagi_core-0.14.0 → oagi_core-0.14.2}/PKG-INFO +14 -10
- {oagi_core-0.14.0 → oagi_core-0.14.2}/README.md +13 -9
- {oagi_core-0.14.0 → oagi_core-0.14.2}/metapackage/pyproject.toml +2 -2
- {oagi_core-0.14.0 → oagi_core-0.14.2}/metapackage/uv.lock +15 -5
- {oagi_core-0.14.0 → oagi_core-0.14.2}/pyproject.toml +1 -1
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/__init__.py +10 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/agent/default.py +4 -6
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/agent/tasker/taskee_agent.py +4 -6
- oagi_core-0.14.2/src/oagi/converters/__init__.py +56 -0
- oagi_core-0.14.2/src/oagi/converters/base.py +292 -0
- oagi_core-0.14.2/src/oagi/converters/oagi.py +194 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/handler/async_pyautogui_action_handler.py +2 -1
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/handler/pyautogui_action_handler.py +31 -39
- oagi_core-0.14.2/src/oagi/handler/utils.py +622 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/handler/ydotool_action_handler.py +31 -41
- {oagi_core-0.14.0 → oagi_core-0.14.2}/tests/test_mac_double_click.py +6 -3
- oagi_core-0.14.2/tests/test_oagi_action_converter.py +171 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/tests/test_pyautogui_action_handler.py +55 -27
- {oagi_core-0.14.0 → oagi_core-0.14.2}/uv.lock +1 -1
- oagi_core-0.14.0/src/oagi/handler/utils.py +0 -21
- {oagi_core-0.14.0 → oagi_core-0.14.2}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/.github/ISSUE_TEMPLATE/feature-request.yml +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/.github/ISSUE_TEMPLATE/question.yml +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/.github/workflows/ci.yml +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/.github/workflows/release.yml +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/.gitignore +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/.python-version +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/CONTRIBUTING.md +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/LICENSE +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/Makefile +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/examples/async_google_weather.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/examples/execute_task_auto.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/examples/execute_task_manual.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/examples/google_weather.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/examples/multi_screen_execution.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/examples/openai_agent_loop_example.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/examples/screenshot_with_config.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/examples/tasker_agent_example.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/actor/__init__.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/actor/async_.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/actor/async_short.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/actor/base.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/actor/short.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/actor/sync.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/agent/__init__.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/agent/factories.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/agent/observer/__init__.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/agent/observer/agent_observer.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/agent/observer/events.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/agent/observer/exporters.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/agent/observer/protocol.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/agent/observer/report_template.html +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/agent/protocol.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/agent/registry.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/agent/tasker/__init__.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/agent/tasker/memory.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/agent/tasker/models.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/agent/tasker/planner.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/agent/tasker/tasker_agent.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/cli/__init__.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/cli/agent.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/cli/display.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/cli/main.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/cli/server.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/cli/tracking.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/cli/utils.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/client/__init__.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/client/async_.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/client/base.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/client/sync.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/constants.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/exceptions.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/handler/__init__.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/handler/_macos.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/handler/_windows.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/handler/_ydotool.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/handler/async_screenshot_maker.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/handler/async_ydotool_action_handler.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/handler/capslock_manager.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/handler/pil_image.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/handler/screen_manager.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/handler/screenshot_maker.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/handler/wayland_support.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/logging.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/platform_info.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/server/__init__.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/server/agent_wrappers.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/server/config.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/server/main.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/server/models.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/server/session_store.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/server/socketio_server.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/task/__init__.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/types/__init__.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/types/action_handler.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/types/async_action_handler.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/types/async_image_provider.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/types/image.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/types/image_provider.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/types/models/__init__.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/types/models/action.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/types/models/client.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/types/models/image_config.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/types/models/step.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/types/step_observer.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/types/url.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/utils/__init__.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/utils/output_parser.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/src/oagi/utils/prompt_builder.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/tests/__init__.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/tests/conftest.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/tests/test_action_parsing.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/tests/test_actor.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/tests/test_agent/test_agent_wrappers.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/tests/test_agent/test_default_agent.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/tests/test_agent_registry.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/tests/test_async_actor.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/tests/test_async_client.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/tests/test_async_handlers.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/tests/test_cli.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/tests/test_logging.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/tests/test_observer.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/tests/test_pil_image.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/tests/test_planner.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/tests/test_planner_memory.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/tests/test_screenshot_maker.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/tests/test_server/__init__.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/tests/test_server/test_config.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/tests/test_server/test_session_store.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/tests/test_server/test_socketio_integration.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/tests/test_sync_client.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/tests/test_taskee_agent.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/tests/test_tasker_agent.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/tests/utils/__init__.py +0 -0
- {oagi_core-0.14.0 → oagi_core-0.14.2}/tests/utils/test_output_parser.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: oagi-core
|
|
3
|
-
Version: 0.14.
|
|
3
|
+
Version: 0.14.2
|
|
4
4
|
Summary: Official API of OpenAGI Foundation
|
|
5
5
|
Project-URL: Homepage, https://github.com/agiopen-org/oagi
|
|
6
6
|
Author-email: OpenAGI Foundation <contact@agiopen.org>
|
|
@@ -154,12 +154,15 @@ from oagi import AsyncPyautoguiActionHandler, PyautoguiConfig
|
|
|
154
154
|
|
|
155
155
|
# Customize action behavior
|
|
156
156
|
config = PyautoguiConfig(
|
|
157
|
-
drag_duration=1.0,
|
|
158
|
-
scroll_amount=50,
|
|
159
|
-
wait_duration=2.0,
|
|
160
|
-
action_pause=0.2,
|
|
161
|
-
hotkey_interval=0.1,
|
|
162
|
-
capslock_mode="session" # Caps lock mode: 'session' or 'system' (default: 'session')
|
|
157
|
+
drag_duration=1.0, # Slower drags for precision (default: 0.5)
|
|
158
|
+
scroll_amount=50, # Larger scroll steps (default: 2 on macOS, 100 on others)
|
|
159
|
+
wait_duration=2.0, # Longer waits for WAIT action (default: 1.0)
|
|
160
|
+
action_pause=0.2, # Pause between PyAutoGUI calls (default: 0.1)
|
|
161
|
+
hotkey_interval=0.1, # Interval between keys in hotkey combos (default: 0.1)
|
|
162
|
+
capslock_mode="session", # Caps lock mode: 'session' or 'system' (default: 'session')
|
|
163
|
+
macos_ctrl_to_cmd=True, # Replace ctrl with cmd on macOS (default: True)
|
|
164
|
+
click_pre_delay=0.1, # Delay after move before click (default: 0.1)
|
|
165
|
+
post_batch_delay=1.0, # Delay after actions before next screenshot (default: 1.0)
|
|
163
166
|
)
|
|
164
167
|
|
|
165
168
|
action_handler = AsyncPyautoguiActionHandler(config=config)
|
|
@@ -279,10 +282,11 @@ from oagi import AsyncYdotoolActionHandler, YdotoolConfig
|
|
|
279
282
|
# Customize action behavior
|
|
280
283
|
config = YdotoolConfig(
|
|
281
284
|
scroll_amount=50, # Larger scroll steps (default: 20)
|
|
282
|
-
wait_duration=2.0, # Longer waits (default: 1.0)
|
|
283
|
-
action_pause=1.0, #
|
|
285
|
+
wait_duration=2.0, # Longer waits for WAIT action (default: 1.0)
|
|
286
|
+
action_pause=1.0, # Pause between Ydotool calls (default: 0.5)
|
|
284
287
|
capslock_mode="session", # Caps lock mode: 'session' or 'system' (default: 'session')
|
|
285
|
-
socket_address="/tmp/ydotool.sock" #
|
|
288
|
+
socket_address="/tmp/ydotool.sock", # Custom socket address (default: YDOTOOL_SOCKET env var)
|
|
289
|
+
post_batch_delay=1.0, # Delay after actions before next screenshot (default: 1.0)
|
|
286
290
|
)
|
|
287
291
|
|
|
288
292
|
action_handler = AsyncYdotoolActionHandler(config=config)
|
|
@@ -108,12 +108,15 @@ from oagi import AsyncPyautoguiActionHandler, PyautoguiConfig
|
|
|
108
108
|
|
|
109
109
|
# Customize action behavior
|
|
110
110
|
config = PyautoguiConfig(
|
|
111
|
-
drag_duration=1.0,
|
|
112
|
-
scroll_amount=50,
|
|
113
|
-
wait_duration=2.0,
|
|
114
|
-
action_pause=0.2,
|
|
115
|
-
hotkey_interval=0.1,
|
|
116
|
-
capslock_mode="session" # Caps lock mode: 'session' or 'system' (default: 'session')
|
|
111
|
+
drag_duration=1.0, # Slower drags for precision (default: 0.5)
|
|
112
|
+
scroll_amount=50, # Larger scroll steps (default: 2 on macOS, 100 on others)
|
|
113
|
+
wait_duration=2.0, # Longer waits for WAIT action (default: 1.0)
|
|
114
|
+
action_pause=0.2, # Pause between PyAutoGUI calls (default: 0.1)
|
|
115
|
+
hotkey_interval=0.1, # Interval between keys in hotkey combos (default: 0.1)
|
|
116
|
+
capslock_mode="session", # Caps lock mode: 'session' or 'system' (default: 'session')
|
|
117
|
+
macos_ctrl_to_cmd=True, # Replace ctrl with cmd on macOS (default: True)
|
|
118
|
+
click_pre_delay=0.1, # Delay after move before click (default: 0.1)
|
|
119
|
+
post_batch_delay=1.0, # Delay after actions before next screenshot (default: 1.0)
|
|
117
120
|
)
|
|
118
121
|
|
|
119
122
|
action_handler = AsyncPyautoguiActionHandler(config=config)
|
|
@@ -233,10 +236,11 @@ from oagi import AsyncYdotoolActionHandler, YdotoolConfig
|
|
|
233
236
|
# Customize action behavior
|
|
234
237
|
config = YdotoolConfig(
|
|
235
238
|
scroll_amount=50, # Larger scroll steps (default: 20)
|
|
236
|
-
wait_duration=2.0, # Longer waits (default: 1.0)
|
|
237
|
-
action_pause=1.0, #
|
|
239
|
+
wait_duration=2.0, # Longer waits for WAIT action (default: 1.0)
|
|
240
|
+
action_pause=1.0, # Pause between Ydotool calls (default: 0.5)
|
|
238
241
|
capslock_mode="session", # Caps lock mode: 'session' or 'system' (default: 'session')
|
|
239
|
-
socket_address="/tmp/ydotool.sock" #
|
|
242
|
+
socket_address="/tmp/ydotool.sock", # Custom socket address (default: YDOTOOL_SOCKET env var)
|
|
243
|
+
post_batch_delay=1.0, # Delay after actions before next screenshot (default: 1.0)
|
|
240
244
|
)
|
|
241
245
|
|
|
242
246
|
action_handler = AsyncYdotoolActionHandler(config=config)
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "oagi"
|
|
7
|
-
version = "0.14.
|
|
7
|
+
version = "0.14.2"
|
|
8
8
|
description = "Official API of OpenAGI Foundation (metapackage with all features)"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -16,7 +16,7 @@ authors = [
|
|
|
16
16
|
requires-python = ">= 3.10"
|
|
17
17
|
|
|
18
18
|
dependencies = [
|
|
19
|
-
"oagi-core[desktop,server]==0.14.
|
|
19
|
+
"oagi-core[desktop,server]==0.14.2",
|
|
20
20
|
]
|
|
21
21
|
|
|
22
22
|
[project.urls]
|
|
@@ -516,20 +516,29 @@ dependencies = [
|
|
|
516
516
|
]
|
|
517
517
|
sdist = { url = "https://files.pythonhosted.org/packages/28/fa/b2ba8229b9381e8f6381c1dcae6f4159a7f72349e414ed19cfbbd1817173/MouseInfo-0.1.3.tar.gz", hash = "sha256:2c62fb8885062b8e520a3cce0a297c657adcc08c60952eb05bc8256ef6f7f6e7", size = 10850, upload-time = "2020-03-27T21:20:10.136Z" }
|
|
518
518
|
|
|
519
|
+
[[package]]
|
|
520
|
+
name = "mss"
|
|
521
|
+
version = "10.1.0"
|
|
522
|
+
source = { registry = "https://pypi.org/simple" }
|
|
523
|
+
sdist = { url = "https://files.pythonhosted.org/packages/40/ca/49b67437a8c46d9732c9c274d7b1fc0c181cfe290d699a0c5e94701dfe79/mss-10.1.0.tar.gz", hash = "sha256:7182baf7ee16ca569e2804028b6ab9bcbf6be5c46fc2880840f33b513b9cb4f8", size = 84200, upload-time = "2025-08-16T12:11:00.119Z" }
|
|
524
|
+
wheels = [
|
|
525
|
+
{ url = "https://files.pythonhosted.org/packages/23/28/1e3e5cd1d677cca68b26166f704f72e35b1e8b6d5076d8ebeebc4e40a649/mss-10.1.0-py3-none-any.whl", hash = "sha256:9179c110cadfef5dc6dc4a041a0cd161c74c379218648e6640b48c6b5cfe8918", size = 24525, upload-time = "2025-08-16T12:10:59.111Z" },
|
|
526
|
+
]
|
|
527
|
+
|
|
519
528
|
[[package]]
|
|
520
529
|
name = "oagi"
|
|
521
|
-
version = "0.14.
|
|
530
|
+
version = "0.14.2"
|
|
522
531
|
source = { editable = "." }
|
|
523
532
|
dependencies = [
|
|
524
533
|
{ name = "oagi-core", extra = ["desktop", "server"] },
|
|
525
534
|
]
|
|
526
535
|
|
|
527
536
|
[package.metadata]
|
|
528
|
-
requires-dist = [{ name = "oagi-core", extras = ["desktop", "server"], specifier = "==0.
|
|
537
|
+
requires-dist = [{ name = "oagi-core", extras = ["desktop", "server"], specifier = "==0.14.1" }]
|
|
529
538
|
|
|
530
539
|
[[package]]
|
|
531
540
|
name = "oagi-core"
|
|
532
|
-
version = "0.
|
|
541
|
+
version = "0.14.1"
|
|
533
542
|
source = { registry = "https://pypi.org/simple" }
|
|
534
543
|
dependencies = [
|
|
535
544
|
{ name = "httpx" },
|
|
@@ -537,13 +546,14 @@ dependencies = [
|
|
|
537
546
|
{ name = "pydantic" },
|
|
538
547
|
{ name = "rich" },
|
|
539
548
|
]
|
|
540
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
549
|
+
sdist = { url = "https://files.pythonhosted.org/packages/94/20/3dfff9883e8786fc0b79ea915ba83cfbce3addd3149568601b80c3bc83a3/oagi_core-0.14.1.tar.gz", hash = "sha256:407faa59b3ced203901a1b35a5b3bc25407e8b61f82ab9b202f01412c73175bf", size = 310008, upload-time = "2026-01-23T08:09:08.54Z" }
|
|
541
550
|
wheels = [
|
|
542
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
551
|
+
{ url = "https://files.pythonhosted.org/packages/62/d1/4485bbddbdf1868aa46deaa98d49ad4624e243c9b32321c81374402bcde8/oagi_core-0.14.1-py3-none-any.whl", hash = "sha256:36b0e10a79c0508eedd28f8a5d89230b7236452ed64bed7150b22f99a50f1a18", size = 114938, upload-time = "2026-01-23T08:09:07.4Z" },
|
|
543
552
|
]
|
|
544
553
|
|
|
545
554
|
[package.optional-dependencies]
|
|
546
555
|
desktop = [
|
|
556
|
+
{ name = "mss", marker = "sys_platform == 'win32'" },
|
|
547
557
|
{ name = "pillow" },
|
|
548
558
|
{ name = "pyautogui" },
|
|
549
559
|
{ name = "pyobjc-framework-applicationservices", marker = "sys_platform == 'darwin'" },
|
|
@@ -38,6 +38,10 @@ from oagi.types.models import (
|
|
|
38
38
|
# Format: name -> (module_path, package_to_check, extra_name)
|
|
39
39
|
# package_to_check is None if no optional dependency is required
|
|
40
40
|
_LAZY_IMPORTS_DATA: dict[str, tuple[str, str | None, str | None]] = {
|
|
41
|
+
# Action converters (no optional dependencies)
|
|
42
|
+
"OagiActionConverter": ("oagi.converters.oagi", None, None),
|
|
43
|
+
"ConverterConfig": ("oagi.converters.base", None, None),
|
|
44
|
+
"BaseActionConverter": ("oagi.converters.base", None, None),
|
|
41
45
|
# Desktop handlers (require pyautogui/PIL)
|
|
42
46
|
"AsyncPyautoguiActionHandler": (
|
|
43
47
|
"oagi.handler.async_pyautogui_action_handler",
|
|
@@ -88,6 +92,8 @@ if TYPE_CHECKING:
|
|
|
88
92
|
from oagi.agent.default import AsyncDefaultAgent
|
|
89
93
|
from oagi.agent.observer.agent_observer import AsyncAgentObserver
|
|
90
94
|
from oagi.agent.tasker import TaskerAgent
|
|
95
|
+
from oagi.converters.base import BaseActionConverter, ConverterConfig
|
|
96
|
+
from oagi.converters.oagi import OagiActionConverter
|
|
91
97
|
from oagi.handler.async_pyautogui_action_handler import AsyncPyautoguiActionHandler
|
|
92
98
|
from oagi.handler.async_screenshot_maker import AsyncScreenshotMaker
|
|
93
99
|
from oagi.handler.async_ydotool_action_handler import AsyncYdotoolActionHandler
|
|
@@ -174,4 +180,8 @@ __all__ = [
|
|
|
174
180
|
"YdotoolConfig",
|
|
175
181
|
# Lazy imports - Screen manager
|
|
176
182
|
"ScreenManager",
|
|
183
|
+
# Lazy imports - Action converters
|
|
184
|
+
"OagiActionConverter",
|
|
185
|
+
"ConverterConfig",
|
|
186
|
+
"BaseActionConverter",
|
|
177
187
|
]
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
# Licensed under the MIT License.
|
|
7
7
|
# -----------------------------------------------------------------------------
|
|
8
8
|
|
|
9
|
-
import asyncio
|
|
10
9
|
import logging
|
|
11
10
|
|
|
12
11
|
from .. import AsyncActor
|
|
@@ -16,7 +15,7 @@ from ..constants import (
|
|
|
16
15
|
DEFAULT_TEMPERATURE,
|
|
17
16
|
MODEL_ACTOR,
|
|
18
17
|
)
|
|
19
|
-
from ..handler.utils import reset_handler
|
|
18
|
+
from ..handler.utils import configure_handler_delay, reset_handler
|
|
20
19
|
from ..types import (
|
|
21
20
|
ActionEvent,
|
|
22
21
|
AsyncActionHandler,
|
|
@@ -72,6 +71,9 @@ class AsyncDefaultAgent:
|
|
|
72
71
|
# Reset handler state at automation start
|
|
73
72
|
reset_handler(action_handler)
|
|
74
73
|
|
|
74
|
+
# Configure handler's post_batch_delay from agent's step_delay
|
|
75
|
+
configure_handler_delay(action_handler, self.step_delay)
|
|
76
|
+
|
|
75
77
|
for i in range(self.max_steps):
|
|
76
78
|
step_num = i + 1
|
|
77
79
|
logger.debug(f"Executing step {step_num}/{self.max_steps}")
|
|
@@ -127,10 +129,6 @@ class AsyncDefaultAgent:
|
|
|
127
129
|
)
|
|
128
130
|
)
|
|
129
131
|
|
|
130
|
-
# Wait after actions before next screenshot
|
|
131
|
-
if self.step_delay > 0:
|
|
132
|
-
await asyncio.sleep(self.step_delay)
|
|
133
|
-
|
|
134
132
|
# Check if task is complete
|
|
135
133
|
if step.stop:
|
|
136
134
|
logger.info(f"Task completed successfully after {step_num} steps")
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
# Licensed under the MIT License.
|
|
7
7
|
# -----------------------------------------------------------------------------
|
|
8
8
|
|
|
9
|
-
import asyncio
|
|
10
9
|
import logging
|
|
11
10
|
from datetime import datetime
|
|
12
11
|
from typing import Any
|
|
@@ -19,7 +18,7 @@ from oagi.constants import (
|
|
|
19
18
|
DEFAULT_TEMPERATURE,
|
|
20
19
|
MODEL_ACTOR,
|
|
21
20
|
)
|
|
22
|
-
from oagi.handler.utils import reset_handler
|
|
21
|
+
from oagi.handler.utils import configure_handler_delay, reset_handler
|
|
23
22
|
from oagi.types import (
|
|
24
23
|
URL,
|
|
25
24
|
ActionEvent,
|
|
@@ -126,6 +125,9 @@ class TaskeeAgent(AsyncAgent):
|
|
|
126
125
|
# Reset handler state at todo execution start
|
|
127
126
|
reset_handler(action_handler)
|
|
128
127
|
|
|
128
|
+
# Configure handler's post_batch_delay from agent's step_delay
|
|
129
|
+
configure_handler_delay(action_handler, self.step_delay)
|
|
130
|
+
|
|
129
131
|
self.current_todo = instruction
|
|
130
132
|
self.actions = []
|
|
131
133
|
self.total_actions = 0
|
|
@@ -355,10 +357,6 @@ class TaskeeAgent(AsyncAgent):
|
|
|
355
357
|
self.total_actions += len(step.actions)
|
|
356
358
|
self.since_reflection += len(step.actions)
|
|
357
359
|
|
|
358
|
-
# Wait after actions before next screenshot
|
|
359
|
-
if self.step_delay > 0:
|
|
360
|
-
await asyncio.sleep(self.step_delay)
|
|
361
|
-
|
|
362
360
|
steps_taken += 1
|
|
363
361
|
|
|
364
362
|
# Check if task is complete
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# -----------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) OpenAGI Foundation
|
|
3
|
+
# All rights reserved.
|
|
4
|
+
#
|
|
5
|
+
# This file is part of the official API project.
|
|
6
|
+
# Licensed under the MIT License.
|
|
7
|
+
# -----------------------------------------------------------------------------
|
|
8
|
+
"""Action converters for VLM support.
|
|
9
|
+
|
|
10
|
+
This module provides the base class and OAGI implementation for action converters.
|
|
11
|
+
Third parties can inherit from BaseActionConverter to create custom converters.
|
|
12
|
+
|
|
13
|
+
Example usage:
|
|
14
|
+
from oagi.converters import OagiActionConverter, ConverterConfig
|
|
15
|
+
|
|
16
|
+
# Configure for 1920x1080 sandbox
|
|
17
|
+
config = ConverterConfig(sandbox_width=1920, sandbox_height=1080)
|
|
18
|
+
converter = OagiActionConverter(config=config)
|
|
19
|
+
|
|
20
|
+
# Convert OAGI actions to pyautogui strings
|
|
21
|
+
result = converter(actions) # list[str]
|
|
22
|
+
|
|
23
|
+
# Convert to runtime API steps
|
|
24
|
+
for cmd in result:
|
|
25
|
+
step = converter.action_string_to_step(cmd)
|
|
26
|
+
# Execute step via runtime API...
|
|
27
|
+
|
|
28
|
+
Creating custom converters:
|
|
29
|
+
from oagi.converters import BaseActionConverter, ConverterConfig
|
|
30
|
+
|
|
31
|
+
class MyActionConverter(BaseActionConverter[MyAction]):
|
|
32
|
+
@property
|
|
33
|
+
def coord_width(self) -> int:
|
|
34
|
+
return 1000 # Your model's coordinate width
|
|
35
|
+
|
|
36
|
+
@property
|
|
37
|
+
def coord_height(self) -> int:
|
|
38
|
+
return 1000 # Your model's coordinate height
|
|
39
|
+
|
|
40
|
+
def _convert_single_action(self, action: MyAction) -> list[str]:
|
|
41
|
+
# Convert action to pyautogui command strings
|
|
42
|
+
...
|
|
43
|
+
|
|
44
|
+
def serialize_actions(self, actions: list[MyAction]) -> list[dict]:
|
|
45
|
+
# Serialize actions for trajectory logging
|
|
46
|
+
...
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
from .base import BaseActionConverter, ConverterConfig
|
|
50
|
+
from .oagi import OagiActionConverter
|
|
51
|
+
|
|
52
|
+
__all__ = [
|
|
53
|
+
"BaseActionConverter",
|
|
54
|
+
"ConverterConfig",
|
|
55
|
+
"OagiActionConverter",
|
|
56
|
+
]
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
# -----------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) OpenAGI Foundation
|
|
3
|
+
# All rights reserved.
|
|
4
|
+
#
|
|
5
|
+
# This file is part of the official API project.
|
|
6
|
+
# Licensed under the MIT License.
|
|
7
|
+
# -----------------------------------------------------------------------------
|
|
8
|
+
"""Base class for action converters.
|
|
9
|
+
|
|
10
|
+
This module provides the abstract base class for converting model-specific
|
|
11
|
+
actions to pyautogui command strings for remote execution.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import re
|
|
15
|
+
from abc import ABC, abstractmethod
|
|
16
|
+
from dataclasses import dataclass
|
|
17
|
+
from typing import Any, Generic, TypeVar
|
|
18
|
+
|
|
19
|
+
from ..handler.capslock_manager import CapsLockManager
|
|
20
|
+
from ..handler.utils import (
|
|
21
|
+
CoordinateScaler,
|
|
22
|
+
normalize_key,
|
|
23
|
+
parse_hotkey,
|
|
24
|
+
validate_keys,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
T = TypeVar("T")
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass
|
|
31
|
+
class ConverterConfig:
|
|
32
|
+
"""Configuration for action converters.
|
|
33
|
+
|
|
34
|
+
Matches the configuration options in PyautoguiConfig for consistency.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
sandbox_width: int = 1920
|
|
38
|
+
sandbox_height: int = 1080
|
|
39
|
+
drag_duration: float = 0.5
|
|
40
|
+
scroll_amount: int = 2
|
|
41
|
+
wait_duration: float = 1.0
|
|
42
|
+
hotkey_interval: float = 0.1
|
|
43
|
+
capslock_mode: str = "session"
|
|
44
|
+
strict_coordinate_validation: bool = False
|
|
45
|
+
"""If True, raise ValueError when coordinates are outside valid range.
|
|
46
|
+
If False (default), clamp coordinates to valid range (original behavior)."""
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class BaseActionConverter(ABC, Generic[T]):
|
|
50
|
+
"""Abstract base class for action converters.
|
|
51
|
+
|
|
52
|
+
Subclasses must implement:
|
|
53
|
+
- coord_width/coord_height properties for input coordinate space
|
|
54
|
+
- _convert_single_action() for model-specific conversion logic
|
|
55
|
+
- serialize_actions() for trajectory logging
|
|
56
|
+
|
|
57
|
+
Provides common functionality:
|
|
58
|
+
- Coordinate scaling via CoordinateScaler
|
|
59
|
+
- Key normalization via shared utils
|
|
60
|
+
- __call__ interface returning list of action strings
|
|
61
|
+
- action_string_to_step() for runtime API format
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
def __init__(
|
|
65
|
+
self,
|
|
66
|
+
*,
|
|
67
|
+
config: ConverterConfig | None = None,
|
|
68
|
+
logger: Any | None = None,
|
|
69
|
+
):
|
|
70
|
+
"""Initialize the converter.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
config: Converter configuration. Uses defaults if not provided.
|
|
74
|
+
logger: Optional logger instance for debug/error logging.
|
|
75
|
+
"""
|
|
76
|
+
self.config = config or ConverterConfig()
|
|
77
|
+
self.logger = logger
|
|
78
|
+
|
|
79
|
+
# Initialize coordinate scaler
|
|
80
|
+
self._coord_scaler = CoordinateScaler(
|
|
81
|
+
source_width=self.coord_width,
|
|
82
|
+
source_height=self.coord_height,
|
|
83
|
+
target_width=self.config.sandbox_width,
|
|
84
|
+
target_height=self.config.sandbox_height,
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
# Initialize caps lock manager
|
|
88
|
+
self.caps_manager = CapsLockManager(mode=self.config.capslock_mode)
|
|
89
|
+
|
|
90
|
+
# Track last cursor position (for actions without explicit coordinates)
|
|
91
|
+
self._last_x: int | None = None
|
|
92
|
+
self._last_y: int | None = None
|
|
93
|
+
|
|
94
|
+
@property
|
|
95
|
+
@abstractmethod
|
|
96
|
+
def coord_width(self) -> int:
|
|
97
|
+
"""Input coordinate space width (e.g., 1024 for XGA, 1000 for OAGI)."""
|
|
98
|
+
...
|
|
99
|
+
|
|
100
|
+
@property
|
|
101
|
+
@abstractmethod
|
|
102
|
+
def coord_height(self) -> int:
|
|
103
|
+
"""Input coordinate space height (e.g., 768 for XGA, 1000 for OAGI)."""
|
|
104
|
+
...
|
|
105
|
+
|
|
106
|
+
@property
|
|
107
|
+
def scale_x(self) -> float:
|
|
108
|
+
"""X scaling factor from input to sandbox coordinates."""
|
|
109
|
+
return self._coord_scaler.scale_x
|
|
110
|
+
|
|
111
|
+
@property
|
|
112
|
+
def scale_y(self) -> float:
|
|
113
|
+
"""Y scaling factor from input to sandbox coordinates."""
|
|
114
|
+
return self._coord_scaler.scale_y
|
|
115
|
+
|
|
116
|
+
def scale_coordinate(self, x: int | float, y: int | float) -> tuple[int, int]:
|
|
117
|
+
"""Scale coordinates from model space to sandbox space.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
x: X coordinate in model space
|
|
121
|
+
y: Y coordinate in model space
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
Tuple of (scaled_x, scaled_y) in sandbox space
|
|
125
|
+
"""
|
|
126
|
+
return self._coord_scaler.scale(x, y)
|
|
127
|
+
|
|
128
|
+
def normalize_key(self, key: str) -> str:
|
|
129
|
+
"""Normalize a key name to pyautogui format.
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
key: Key name to normalize
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
Normalized key name
|
|
136
|
+
"""
|
|
137
|
+
return normalize_key(key)
|
|
138
|
+
|
|
139
|
+
def parse_hotkey(self, hotkey_str: str, *, validate: bool = True) -> list[str]:
|
|
140
|
+
"""Parse a hotkey string into a list of normalized key names.
|
|
141
|
+
|
|
142
|
+
Args:
|
|
143
|
+
hotkey_str: Hotkey string (e.g., "ctrl+c")
|
|
144
|
+
validate: If True, validate keys against PYAUTOGUI_VALID_KEYS
|
|
145
|
+
|
|
146
|
+
Returns:
|
|
147
|
+
List of normalized key names
|
|
148
|
+
"""
|
|
149
|
+
return parse_hotkey(hotkey_str, validate=validate)
|
|
150
|
+
|
|
151
|
+
def validate_keys(self, keys: list[str]) -> None:
|
|
152
|
+
"""Validate that all keys are recognized by pyautogui.
|
|
153
|
+
|
|
154
|
+
Args:
|
|
155
|
+
keys: List of key names to validate
|
|
156
|
+
|
|
157
|
+
Raises:
|
|
158
|
+
ValueError: If any key is invalid
|
|
159
|
+
"""
|
|
160
|
+
validate_keys(keys)
|
|
161
|
+
|
|
162
|
+
def _get_last_or_center(self) -> tuple[int, int]:
|
|
163
|
+
"""Get last cursor position or screen center as fallback.
|
|
164
|
+
|
|
165
|
+
Returns:
|
|
166
|
+
Tuple of (x, y) coordinates
|
|
167
|
+
"""
|
|
168
|
+
if self._last_x is not None and self._last_y is not None:
|
|
169
|
+
return self._last_x, self._last_y
|
|
170
|
+
return self.config.sandbox_width // 2, self.config.sandbox_height // 2
|
|
171
|
+
|
|
172
|
+
def _log_error(self, message: str) -> None:
|
|
173
|
+
"""Log an error message if logger is available."""
|
|
174
|
+
if self.logger:
|
|
175
|
+
self.logger.error(message)
|
|
176
|
+
|
|
177
|
+
def _log_info(self, message: str) -> None:
|
|
178
|
+
"""Log an info message if logger is available."""
|
|
179
|
+
if self.logger:
|
|
180
|
+
self.logger.info(message)
|
|
181
|
+
|
|
182
|
+
def _log_debug(self, message: str) -> None:
|
|
183
|
+
"""Log a debug message if logger is available."""
|
|
184
|
+
if self.logger:
|
|
185
|
+
self.logger.debug(message)
|
|
186
|
+
|
|
187
|
+
def __call__(self, actions: list[T]) -> list[str]:
|
|
188
|
+
"""Convert actions to list of pyautogui command strings.
|
|
189
|
+
|
|
190
|
+
Args:
|
|
191
|
+
actions: List of model-specific action objects
|
|
192
|
+
|
|
193
|
+
Returns:
|
|
194
|
+
List of pyautogui command strings
|
|
195
|
+
|
|
196
|
+
Raises:
|
|
197
|
+
RuntimeError: If all action conversions failed
|
|
198
|
+
"""
|
|
199
|
+
converted: list[str] = []
|
|
200
|
+
failed: list[tuple[str, str]] = []
|
|
201
|
+
skipped: list[str] = []
|
|
202
|
+
|
|
203
|
+
if not actions:
|
|
204
|
+
return converted
|
|
205
|
+
|
|
206
|
+
for action in actions:
|
|
207
|
+
try:
|
|
208
|
+
action_strings = self._convert_single_action(action)
|
|
209
|
+
|
|
210
|
+
if not action_strings:
|
|
211
|
+
# No-op action (e.g., screenshot, cursor_position)
|
|
212
|
+
action_type = getattr(action, "action_type", repr(action))
|
|
213
|
+
skipped.append(str(action_type))
|
|
214
|
+
continue
|
|
215
|
+
|
|
216
|
+
converted.extend(action_strings)
|
|
217
|
+
|
|
218
|
+
except Exception as e:
|
|
219
|
+
action_repr = repr(action)
|
|
220
|
+
self._log_error(f"Failed to convert action: {action_repr}, error: {e}")
|
|
221
|
+
failed.append((action_repr, str(e)))
|
|
222
|
+
|
|
223
|
+
if skipped:
|
|
224
|
+
self._log_debug(f"Skipped no-op actions: {skipped}")
|
|
225
|
+
|
|
226
|
+
if not converted and actions and failed:
|
|
227
|
+
raise RuntimeError(
|
|
228
|
+
f"All action conversions failed ({len(failed)}/{len(actions)}): {failed}"
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
return converted
|
|
232
|
+
|
|
233
|
+
@abstractmethod
|
|
234
|
+
def _convert_single_action(self, action: T) -> list[str]:
|
|
235
|
+
"""Convert a single action to pyautogui command string(s).
|
|
236
|
+
|
|
237
|
+
Args:
|
|
238
|
+
action: Model-specific action object
|
|
239
|
+
|
|
240
|
+
Returns:
|
|
241
|
+
List of pyautogui command strings (may be empty for no-op actions)
|
|
242
|
+
|
|
243
|
+
Raises:
|
|
244
|
+
ValueError: If action format is invalid
|
|
245
|
+
"""
|
|
246
|
+
...
|
|
247
|
+
|
|
248
|
+
@abstractmethod
|
|
249
|
+
def serialize_actions(self, actions: list[T]) -> list[dict[str, Any]]:
|
|
250
|
+
"""Serialize actions for trajectory logging.
|
|
251
|
+
|
|
252
|
+
Args:
|
|
253
|
+
actions: List of model-specific action objects
|
|
254
|
+
|
|
255
|
+
Returns:
|
|
256
|
+
List of serialized action dictionaries
|
|
257
|
+
"""
|
|
258
|
+
...
|
|
259
|
+
|
|
260
|
+
def action_string_to_step(self, action: str) -> dict[str, Any]:
|
|
261
|
+
"""Convert an action string into a step for runtime/do API.
|
|
262
|
+
|
|
263
|
+
Args:
|
|
264
|
+
action: Action string (e.g., "pyautogui.click(x=100, y=200)")
|
|
265
|
+
|
|
266
|
+
Returns:
|
|
267
|
+
Step dict for runtime API
|
|
268
|
+
"""
|
|
269
|
+
action_str = str(action).strip()
|
|
270
|
+
|
|
271
|
+
# Special markers
|
|
272
|
+
upper = action_str.upper()
|
|
273
|
+
if upper in ["DONE", "FAIL"]:
|
|
274
|
+
return {"type": "sleep", "parameters": {"seconds": 0}}
|
|
275
|
+
|
|
276
|
+
# WAIT(seconds)
|
|
277
|
+
wait_match = re.match(
|
|
278
|
+
r"^WAIT\((?P<sec>[0-9]*\.?[0-9]+)\)$", action_str, re.IGNORECASE
|
|
279
|
+
)
|
|
280
|
+
if wait_match:
|
|
281
|
+
seconds = float(wait_match.group("sec"))
|
|
282
|
+
return {"type": "sleep", "parameters": {"seconds": seconds}}
|
|
283
|
+
|
|
284
|
+
# pyautogui code path
|
|
285
|
+
if "pyautogui" in action_str.lower():
|
|
286
|
+
return {
|
|
287
|
+
"type": "pyautogui",
|
|
288
|
+
"parameters": {"code": action_str},
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
# Default: shell command
|
|
292
|
+
return {"type": "execute", "parameters": {"command": action_str, "shell": True}}
|