oagi-core 0.10.2__tar.gz → 0.11.0__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.10.2 → oagi_core-0.11.0}/PKG-INFO +34 -1
- {oagi_core-0.10.2 → oagi_core-0.11.0}/README.md +33 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/examples/tasker_agent_example.py +1 -1
- {oagi_core-0.10.2 → oagi_core-0.11.0}/metapackage/pyproject.toml +2 -2
- {oagi_core-0.10.2 → oagi_core-0.11.0}/metapackage/uv.lock +5 -5
- {oagi_core-0.10.2 → oagi_core-0.11.0}/pyproject.toml +1 -1
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/agent/default.py +14 -4
- oagi_core-0.11.0/src/oagi/agent/factories.py +162 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/agent/tasker/planner.py +19 -8
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/agent/tasker/taskee_agent.py +31 -9
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/agent/tasker/tasker_agent.py +16 -5
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/cli/agent.py +70 -31
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/cli/display.py +2 -1
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/cli/server.py +1 -1
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/cli/utils.py +4 -3
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/client/async_.py +19 -6
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/client/base.py +14 -16
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/client/sync.py +19 -6
- oagi_core-0.11.0/src/oagi/constants.py +43 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/handler/__init__.py +16 -0
- oagi_core-0.11.0/src/oagi/handler/_macos.py +192 -0
- oagi_core-0.11.0/src/oagi/handler/_windows.py +101 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/handler/async_pyautogui_action_handler.py +8 -0
- oagi_core-0.11.0/src/oagi/handler/capslock_manager.py +55 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/handler/pyautogui_action_handler.py +23 -40
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/server/config.py +6 -3
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/server/models.py +5 -3
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/server/session_store.py +8 -6
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/server/socketio_server.py +6 -5
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/task/async_.py +4 -3
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/task/async_short.py +3 -2
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/task/base.py +2 -1
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/task/short.py +3 -2
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/task/sync.py +4 -3
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/types/__init__.py +2 -1
- oagi_core-0.11.0/src/oagi/types/url.py +28 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/tests/conftest.py +4 -3
- {oagi_core-0.10.2 → oagi_core-0.11.0}/tests/test_actor.py +6 -5
- {oagi_core-0.10.2 → oagi_core-0.11.0}/tests/test_agent_registry.py +13 -11
- {oagi_core-0.10.2 → oagi_core-0.11.0}/tests/test_async_client.py +25 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/tests/test_cli.py +2 -1
- {oagi_core-0.10.2 → oagi_core-0.11.0}/tests/test_pyautogui_action_handler.py +102 -29
- {oagi_core-0.10.2 → oagi_core-0.11.0}/tests/test_server/test_session_store.py +8 -7
- {oagi_core-0.10.2 → oagi_core-0.11.0}/tests/test_sync_client.py +24 -2
- {oagi_core-0.10.2 → oagi_core-0.11.0}/tests/test_taskee_agent.py +2 -1
- {oagi_core-0.10.2 → oagi_core-0.11.0}/uv.lock +1 -1
- oagi_core-0.10.2/src/oagi/agent/factories.py +0 -80
- oagi_core-0.10.2/src/oagi/handler/_macos.py +0 -55
- oagi_core-0.10.2/src/oagi/types/url.py +0 -3
- {oagi_core-0.10.2 → oagi_core-0.11.0}/.github/workflows/ci.yml +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/.github/workflows/release.yml +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/.gitignore +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/.python-version +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/CONTRIBUTING.md +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/LICENSE +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/Makefile +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/examples/async_google_weather.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/examples/execute_task_auto.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/examples/execute_task_manual.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/examples/google_weather.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/examples/screenshot_with_config.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/__init__.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/agent/__init__.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/agent/observer/__init__.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/agent/observer/agent_observer.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/agent/observer/events.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/agent/observer/exporters.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/agent/observer/protocol.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/agent/observer/report_template.html +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/agent/protocol.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/agent/registry.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/agent/tasker/__init__.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/agent/tasker/memory.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/agent/tasker/models.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/cli/__init__.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/cli/main.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/cli/tracking.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/client/__init__.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/exceptions.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/handler/async_screenshot_maker.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/handler/pil_image.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/handler/screenshot_maker.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/logging.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/server/__init__.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/server/agent_wrappers.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/server/main.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/task/__init__.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/types/action_handler.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/types/async_action_handler.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/types/async_image_provider.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/types/image.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/types/image_provider.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/types/models/__init__.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/types/models/action.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/types/models/client.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/types/models/image_config.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/types/models/step.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/src/oagi/types/step_observer.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/tests/__init__.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/tests/test_action_parsing.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/tests/test_agent/test_agent_wrappers.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/tests/test_agent/test_default_agent.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/tests/test_async_actor.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/tests/test_async_handlers.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/tests/test_logging.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/tests/test_mac_double_click.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/tests/test_observer.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/tests/test_pil_image.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/tests/test_planner.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/tests/test_planner_memory.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/tests/test_screenshot_maker.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/tests/test_server/__init__.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/tests/test_server/test_config.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/tests/test_server/test_socketio_integration.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.11.0}/tests/test_tasker_agent.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: oagi-core
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.0
|
|
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>
|
|
@@ -116,6 +116,39 @@ config = PyautoguiConfig(
|
|
|
116
116
|
action_handler = AsyncPyautoguiActionHandler(config=config)
|
|
117
117
|
```
|
|
118
118
|
|
|
119
|
+
### Command Line Interface
|
|
120
|
+
|
|
121
|
+
Run agents directly from the terminal:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# Run with actor model
|
|
125
|
+
oagi agent run "Go to nasdaq.com, search for AAPL. Under More, go to Insider Activity" --model lux-actor-1
|
|
126
|
+
|
|
127
|
+
# Run with thinker mode (uses lux-thinker-1 model with more steps)
|
|
128
|
+
oagi agent run "Look up the store hours for the nearest Apple Store to zip code 23456 using the Apple Store Locator" --model lux-thinker-1
|
|
129
|
+
|
|
130
|
+
# Run pre-configured tasker workflows (no instruction needed)
|
|
131
|
+
oagi agent run --mode tasker:software_qa
|
|
132
|
+
|
|
133
|
+
# List all available modes
|
|
134
|
+
oagi agent modes
|
|
135
|
+
|
|
136
|
+
# Check macOS permissions (screen recording & accessibility)
|
|
137
|
+
oagi agent permission
|
|
138
|
+
|
|
139
|
+
# Export execution history
|
|
140
|
+
oagi agent run "Complete the form" --export html --export-file report.html
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
CLI options:
|
|
144
|
+
- `--mode`: Agent mode (default: actor). Use `oagi agent modes` to list available modes
|
|
145
|
+
- `--model`: Override the model (default: determined by mode)
|
|
146
|
+
- `--max-steps`: Maximum steps (default: determined by mode)
|
|
147
|
+
- `--temperature`: Sampling temperature (default: determined by mode)
|
|
148
|
+
- `--step-delay`: Delay after each action before next screenshot (default: 0.3s)
|
|
149
|
+
- `--export`: Export format (markdown, html, json)
|
|
150
|
+
- `--export-file`: Output file path for export
|
|
151
|
+
|
|
119
152
|
### Image Processing
|
|
120
153
|
|
|
121
154
|
Process and optimize images before sending to API:
|
|
@@ -73,6 +73,39 @@ config = PyautoguiConfig(
|
|
|
73
73
|
action_handler = AsyncPyautoguiActionHandler(config=config)
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
+
### Command Line Interface
|
|
77
|
+
|
|
78
|
+
Run agents directly from the terminal:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# Run with actor model
|
|
82
|
+
oagi agent run "Go to nasdaq.com, search for AAPL. Under More, go to Insider Activity" --model lux-actor-1
|
|
83
|
+
|
|
84
|
+
# Run with thinker mode (uses lux-thinker-1 model with more steps)
|
|
85
|
+
oagi agent run "Look up the store hours for the nearest Apple Store to zip code 23456 using the Apple Store Locator" --model lux-thinker-1
|
|
86
|
+
|
|
87
|
+
# Run pre-configured tasker workflows (no instruction needed)
|
|
88
|
+
oagi agent run --mode tasker:software_qa
|
|
89
|
+
|
|
90
|
+
# List all available modes
|
|
91
|
+
oagi agent modes
|
|
92
|
+
|
|
93
|
+
# Check macOS permissions (screen recording & accessibility)
|
|
94
|
+
oagi agent permission
|
|
95
|
+
|
|
96
|
+
# Export execution history
|
|
97
|
+
oagi agent run "Complete the form" --export html --export-file report.html
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
CLI options:
|
|
101
|
+
- `--mode`: Agent mode (default: actor). Use `oagi agent modes` to list available modes
|
|
102
|
+
- `--model`: Override the model (default: determined by mode)
|
|
103
|
+
- `--max-steps`: Maximum steps (default: determined by mode)
|
|
104
|
+
- `--temperature`: Sampling temperature (default: determined by mode)
|
|
105
|
+
- `--step-delay`: Delay after each action before next screenshot (default: 0.3s)
|
|
106
|
+
- `--export`: Export format (markdown, html, json)
|
|
107
|
+
- `--export-file`: Output file path for export
|
|
108
|
+
|
|
76
109
|
### Image Processing
|
|
77
110
|
|
|
78
111
|
Process and optimize images before sending to API:
|
|
@@ -27,7 +27,7 @@ async def main():
|
|
|
27
27
|
tasker = TaskerAgent(
|
|
28
28
|
api_key=os.getenv("OAGI_API_KEY"),
|
|
29
29
|
base_url=os.getenv("OAGI_BASE_URL", "https://api.agiopen.org"),
|
|
30
|
-
model="
|
|
30
|
+
model="lux-actor-1",
|
|
31
31
|
max_steps=30,
|
|
32
32
|
temperature=0.5,
|
|
33
33
|
step_observer=observer,
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "oagi"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.11.0"
|
|
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.
|
|
19
|
+
"oagi-core[desktop,server]==0.11.0",
|
|
20
20
|
]
|
|
21
21
|
|
|
22
22
|
[project.urls]
|
|
@@ -397,27 +397,27 @@ sdist = { url = "https://files.pythonhosted.org/packages/28/fa/b2ba8229b9381e8f6
|
|
|
397
397
|
|
|
398
398
|
[[package]]
|
|
399
399
|
name = "oagi"
|
|
400
|
-
version = "0.
|
|
400
|
+
version = "0.11.0"
|
|
401
401
|
source = { editable = "." }
|
|
402
402
|
dependencies = [
|
|
403
403
|
{ name = "oagi-core", extra = ["desktop", "server"] },
|
|
404
404
|
]
|
|
405
405
|
|
|
406
406
|
[package.metadata]
|
|
407
|
-
requires-dist = [{ name = "oagi-core", extras = ["desktop", "server"], specifier = "==0.10.
|
|
407
|
+
requires-dist = [{ name = "oagi-core", extras = ["desktop", "server"], specifier = "==0.10.3" }]
|
|
408
408
|
|
|
409
409
|
[[package]]
|
|
410
410
|
name = "oagi-core"
|
|
411
|
-
version = "0.10.
|
|
411
|
+
version = "0.10.3"
|
|
412
412
|
source = { registry = "https://pypi.org/simple" }
|
|
413
413
|
dependencies = [
|
|
414
414
|
{ name = "httpx" },
|
|
415
415
|
{ name = "pydantic" },
|
|
416
416
|
{ name = "rich" },
|
|
417
417
|
]
|
|
418
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
418
|
+
sdist = { url = "https://files.pythonhosted.org/packages/60/97/c54ecd43969132f902086d4f7fa7eb8d1f5e5087774c81df463a27b3017f/oagi_core-0.10.3.tar.gz", hash = "sha256:46417fde3b20427338d7e2798246960fd4bc6515e93f95bd32b8236337d6cfcd", size = 268408, upload-time = "2025-11-30T11:34:46.494Z" }
|
|
419
419
|
wheels = [
|
|
420
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
420
|
+
{ url = "https://files.pythonhosted.org/packages/81/22/47271b7d2ac5b7bcaa9d58819b00dfa8e3c0aa57ea3db6e2f6fd681fd0ce/oagi_core-0.10.3-py3-none-any.whl", hash = "sha256:fc91a7bb29ffdcf490bb7edc2574826229ba86726ec6acd505379bdf09645721", size = 88927, upload-time = "2025-11-30T11:34:45.531Z" },
|
|
421
421
|
]
|
|
422
422
|
|
|
423
423
|
[package.optional-dependencies]
|
|
@@ -10,6 +10,13 @@ import asyncio
|
|
|
10
10
|
import logging
|
|
11
11
|
|
|
12
12
|
from .. import AsyncActor
|
|
13
|
+
from ..constants import (
|
|
14
|
+
DEFAULT_MAX_STEPS,
|
|
15
|
+
DEFAULT_STEP_DELAY,
|
|
16
|
+
DEFAULT_TEMPERATURE,
|
|
17
|
+
MODEL_ACTOR,
|
|
18
|
+
)
|
|
19
|
+
from ..handler import reset_handler
|
|
13
20
|
from ..types import (
|
|
14
21
|
ActionEvent,
|
|
15
22
|
AsyncActionHandler,
|
|
@@ -36,11 +43,11 @@ class AsyncDefaultAgent:
|
|
|
36
43
|
self,
|
|
37
44
|
api_key: str | None = None,
|
|
38
45
|
base_url: str | None = None,
|
|
39
|
-
model: str =
|
|
40
|
-
max_steps: int =
|
|
41
|
-
temperature: float | None =
|
|
46
|
+
model: str = MODEL_ACTOR,
|
|
47
|
+
max_steps: int = DEFAULT_MAX_STEPS,
|
|
48
|
+
temperature: float | None = DEFAULT_TEMPERATURE,
|
|
42
49
|
step_observer: AsyncObserver | None = None,
|
|
43
|
-
step_delay: float =
|
|
50
|
+
step_delay: float = DEFAULT_STEP_DELAY,
|
|
44
51
|
):
|
|
45
52
|
self.api_key = api_key
|
|
46
53
|
self.base_url = base_url
|
|
@@ -62,6 +69,9 @@ class AsyncDefaultAgent:
|
|
|
62
69
|
logger.info(f"Starting async task execution: {instruction}")
|
|
63
70
|
await self.actor.init_task(instruction, max_steps=self.max_steps)
|
|
64
71
|
|
|
72
|
+
# Reset handler state at automation start
|
|
73
|
+
reset_handler(action_handler)
|
|
74
|
+
|
|
65
75
|
for i in range(self.max_steps):
|
|
66
76
|
step_num = i + 1
|
|
67
77
|
logger.debug(f"Executing step {step_num}/{self.max_steps}")
|
|
@@ -0,0 +1,162 @@
|
|
|
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
|
+
from oagi.agent.tasker import TaskerAgent
|
|
9
|
+
from oagi.constants import (
|
|
10
|
+
DEFAULT_MAX_STEPS,
|
|
11
|
+
DEFAULT_MAX_STEPS_TASKER,
|
|
12
|
+
DEFAULT_MAX_STEPS_THINKER,
|
|
13
|
+
DEFAULT_REFLECTION_INTERVAL_TASKER,
|
|
14
|
+
DEFAULT_STEP_DELAY,
|
|
15
|
+
DEFAULT_TEMPERATURE_LOW,
|
|
16
|
+
MODEL_ACTOR,
|
|
17
|
+
MODEL_THINKER,
|
|
18
|
+
)
|
|
19
|
+
from oagi.types import AsyncStepObserver
|
|
20
|
+
|
|
21
|
+
from .default import AsyncDefaultAgent
|
|
22
|
+
from .protocol import AsyncAgent
|
|
23
|
+
from .registry import async_agent_register
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@async_agent_register(mode="actor")
|
|
27
|
+
def create_default_agent(
|
|
28
|
+
api_key: str | None = None,
|
|
29
|
+
base_url: str | None = None,
|
|
30
|
+
model: str = MODEL_ACTOR,
|
|
31
|
+
max_steps: int = DEFAULT_MAX_STEPS,
|
|
32
|
+
temperature: float = DEFAULT_TEMPERATURE_LOW,
|
|
33
|
+
step_observer: AsyncStepObserver | None = None,
|
|
34
|
+
step_delay: float = DEFAULT_STEP_DELAY,
|
|
35
|
+
) -> AsyncAgent:
|
|
36
|
+
return AsyncDefaultAgent(
|
|
37
|
+
api_key=api_key,
|
|
38
|
+
base_url=base_url,
|
|
39
|
+
model=model,
|
|
40
|
+
max_steps=max_steps,
|
|
41
|
+
temperature=temperature,
|
|
42
|
+
step_observer=step_observer,
|
|
43
|
+
step_delay=step_delay,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@async_agent_register(mode="thinker")
|
|
48
|
+
def create_thinker_agent(
|
|
49
|
+
api_key: str | None = None,
|
|
50
|
+
base_url: str | None = None,
|
|
51
|
+
model: str = MODEL_THINKER,
|
|
52
|
+
max_steps: int = DEFAULT_MAX_STEPS_THINKER,
|
|
53
|
+
temperature: float = DEFAULT_TEMPERATURE_LOW,
|
|
54
|
+
step_observer: AsyncStepObserver | None = None,
|
|
55
|
+
step_delay: float = DEFAULT_STEP_DELAY,
|
|
56
|
+
) -> AsyncAgent:
|
|
57
|
+
return AsyncDefaultAgent(
|
|
58
|
+
api_key=api_key,
|
|
59
|
+
base_url=base_url,
|
|
60
|
+
model=model,
|
|
61
|
+
max_steps=max_steps,
|
|
62
|
+
temperature=temperature,
|
|
63
|
+
step_observer=step_observer,
|
|
64
|
+
step_delay=step_delay,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@async_agent_register(mode="tasker:cvs_appointment")
|
|
69
|
+
def create_cvs_appointment_agent(
|
|
70
|
+
api_key: str | None = None,
|
|
71
|
+
base_url: str | None = None,
|
|
72
|
+
model: str = MODEL_ACTOR,
|
|
73
|
+
max_steps: int = DEFAULT_MAX_STEPS_TASKER,
|
|
74
|
+
temperature: float = DEFAULT_TEMPERATURE_LOW,
|
|
75
|
+
reflection_interval: int = DEFAULT_REFLECTION_INTERVAL_TASKER,
|
|
76
|
+
step_observer: AsyncStepObserver | None = None,
|
|
77
|
+
step_delay: float = DEFAULT_STEP_DELAY,
|
|
78
|
+
# CVS-specific parameters
|
|
79
|
+
first_name: str = "First",
|
|
80
|
+
last_name: str = "Last",
|
|
81
|
+
email: str = "user@example.com",
|
|
82
|
+
birthday: str = "01-01-1990", # MM-DD-YYYY
|
|
83
|
+
zip_code: str = "00000",
|
|
84
|
+
) -> AsyncAgent:
|
|
85
|
+
tasker = TaskerAgent(
|
|
86
|
+
api_key=api_key,
|
|
87
|
+
base_url=base_url,
|
|
88
|
+
model=model,
|
|
89
|
+
max_steps=max_steps,
|
|
90
|
+
temperature=temperature,
|
|
91
|
+
reflection_interval=reflection_interval,
|
|
92
|
+
step_observer=step_observer,
|
|
93
|
+
step_delay=step_delay,
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
month, day, year = birthday.split("-")
|
|
97
|
+
instruction = (
|
|
98
|
+
f"Schedule an appointment at CVS for {first_name} {last_name} "
|
|
99
|
+
f"with email {email} and birthday {birthday}"
|
|
100
|
+
)
|
|
101
|
+
todos = [
|
|
102
|
+
"Open a new tab, go to www.cvs.com, type 'flu shot' in the search bar and press enter, "
|
|
103
|
+
"wait for the page to load, then click on the button of Schedule vaccinations on the "
|
|
104
|
+
"top of the page",
|
|
105
|
+
f"Enter the first name '{first_name}', last name '{last_name}', and email '{email}' "
|
|
106
|
+
"in the form. Do not use any suggested autofills. Make sure the mobile phone number "
|
|
107
|
+
"is empty.",
|
|
108
|
+
f"Slightly scroll down to see the date of birth, enter Month '{month}', Day '{day}', "
|
|
109
|
+
f"and Year '{year}' in the form",
|
|
110
|
+
"Click on 'Continue as guest' button, wait for the page to load with wait, "
|
|
111
|
+
"click on 'Add vaccines' button, select 'Flu' and click on 'Add vaccines'",
|
|
112
|
+
f"Click on 'next' to enter the page with recommendation vaccines, then click on "
|
|
113
|
+
f"'next' again, until on the page of entering zip code, enter '{zip_code}', select "
|
|
114
|
+
"the first option from the dropdown menu, and click on 'Search'",
|
|
115
|
+
]
|
|
116
|
+
|
|
117
|
+
tasker.set_task(instruction, todos)
|
|
118
|
+
return tasker
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@async_agent_register(mode="tasker:software_qa")
|
|
122
|
+
def create_software_qa_agent(
|
|
123
|
+
api_key: str | None = None,
|
|
124
|
+
base_url: str | None = None,
|
|
125
|
+
model: str = MODEL_ACTOR,
|
|
126
|
+
max_steps: int = DEFAULT_MAX_STEPS_TASKER,
|
|
127
|
+
temperature: float = DEFAULT_TEMPERATURE_LOW,
|
|
128
|
+
reflection_interval: int = DEFAULT_REFLECTION_INTERVAL_TASKER,
|
|
129
|
+
step_observer: AsyncStepObserver | None = None,
|
|
130
|
+
step_delay: float = DEFAULT_STEP_DELAY,
|
|
131
|
+
) -> AsyncAgent:
|
|
132
|
+
tasker = TaskerAgent(
|
|
133
|
+
api_key=api_key,
|
|
134
|
+
base_url=base_url,
|
|
135
|
+
model=model,
|
|
136
|
+
max_steps=max_steps,
|
|
137
|
+
temperature=temperature,
|
|
138
|
+
reflection_interval=reflection_interval,
|
|
139
|
+
step_observer=step_observer,
|
|
140
|
+
step_delay=step_delay,
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
instruction = "QA: click through every sidebar button in the Nuclear Player UI"
|
|
144
|
+
todos = [
|
|
145
|
+
"Click on 'Dashboard' in the left sidebar",
|
|
146
|
+
"Click on 'Downloads' in the left sidebar",
|
|
147
|
+
"Click on 'Lyrics' in the left sidebar",
|
|
148
|
+
"Click on 'Plugins' in the left sidebar",
|
|
149
|
+
"Click on 'Search Results' in the left sidebar",
|
|
150
|
+
"Click on 'Settings' in the left sidebar",
|
|
151
|
+
"Click on 'Equalizer' in the left sidebar",
|
|
152
|
+
"Click on 'Visualizer' in the left sidebar",
|
|
153
|
+
"Click on 'Listening History' in the left sidebar",
|
|
154
|
+
"Click on 'Favorite Albums' in the left sidebar",
|
|
155
|
+
"Click on 'Favorite Tracks' in the left sidebar",
|
|
156
|
+
"Click on 'Favorite Artists' in the left sidebar",
|
|
157
|
+
"Click on 'Local Library' in the left sidebar",
|
|
158
|
+
"Click on 'Playlists' in the left sidebar",
|
|
159
|
+
]
|
|
160
|
+
|
|
161
|
+
tasker.set_task(instruction, todos)
|
|
162
|
+
return tasker
|
|
@@ -10,7 +10,8 @@ import json
|
|
|
10
10
|
from typing import Any
|
|
11
11
|
|
|
12
12
|
from ...client import AsyncClient
|
|
13
|
-
from ...
|
|
13
|
+
from ...constants import DEFAULT_REFLECTION_INTERVAL
|
|
14
|
+
from ...types import URL, Image, extract_uuid_from_url
|
|
14
15
|
from .memory import PlannerMemory
|
|
15
16
|
from .models import Action, PlannerOutput, ReflectionOutput
|
|
16
17
|
|
|
@@ -137,11 +138,16 @@ class Planner:
|
|
|
137
138
|
# Ensure we have a client
|
|
138
139
|
client = self._ensure_client()
|
|
139
140
|
|
|
140
|
-
#
|
|
141
|
+
# Get screenshot UUID - either extract from URL or upload
|
|
141
142
|
screenshot_uuid = None
|
|
142
143
|
if screenshot:
|
|
143
|
-
|
|
144
|
-
|
|
144
|
+
# Check if screenshot is already a URL (already uploaded to S3)
|
|
145
|
+
if isinstance(screenshot, str):
|
|
146
|
+
screenshot_uuid = extract_uuid_from_url(screenshot)
|
|
147
|
+
# If not a URL or UUID extraction failed, upload the image
|
|
148
|
+
if not screenshot_uuid:
|
|
149
|
+
upload_response = await client.put_s3_presigned_url(screenshot)
|
|
150
|
+
screenshot_uuid = upload_response.uuid
|
|
145
151
|
|
|
146
152
|
# Extract memory data if provided
|
|
147
153
|
(
|
|
@@ -175,7 +181,7 @@ class Planner:
|
|
|
175
181
|
memory: PlannerMemory | None = None,
|
|
176
182
|
todo_index: int | None = None,
|
|
177
183
|
current_instruction: str | None = None,
|
|
178
|
-
reflection_interval: int =
|
|
184
|
+
reflection_interval: int = DEFAULT_REFLECTION_INTERVAL,
|
|
179
185
|
) -> ReflectionOutput:
|
|
180
186
|
"""Reflect on recent actions and progress.
|
|
181
187
|
|
|
@@ -194,11 +200,16 @@ class Planner:
|
|
|
194
200
|
# Ensure we have a client
|
|
195
201
|
client = self._ensure_client()
|
|
196
202
|
|
|
197
|
-
#
|
|
203
|
+
# Get screenshot UUID - either extract from URL or upload
|
|
198
204
|
result_screenshot_uuid = None
|
|
199
205
|
if screenshot:
|
|
200
|
-
|
|
201
|
-
|
|
206
|
+
# Check if screenshot is already a URL (already uploaded to S3)
|
|
207
|
+
if isinstance(screenshot, str):
|
|
208
|
+
result_screenshot_uuid = extract_uuid_from_url(screenshot)
|
|
209
|
+
# If not a URL or UUID extraction failed, upload the image
|
|
210
|
+
if not result_screenshot_uuid:
|
|
211
|
+
upload_response = await client.put_s3_presigned_url(screenshot)
|
|
212
|
+
result_screenshot_uuid = upload_response.uuid
|
|
202
213
|
|
|
203
214
|
# Extract memory data if provided
|
|
204
215
|
(
|
|
@@ -12,6 +12,14 @@ from datetime import datetime
|
|
|
12
12
|
from typing import Any
|
|
13
13
|
|
|
14
14
|
from oagi import AsyncActor
|
|
15
|
+
from oagi.constants import (
|
|
16
|
+
DEFAULT_MAX_STEPS,
|
|
17
|
+
DEFAULT_REFLECTION_INTERVAL,
|
|
18
|
+
DEFAULT_STEP_DELAY,
|
|
19
|
+
DEFAULT_TEMPERATURE,
|
|
20
|
+
MODEL_ACTOR,
|
|
21
|
+
)
|
|
22
|
+
from oagi.handler import reset_handler
|
|
15
23
|
from oagi.types import (
|
|
16
24
|
URL,
|
|
17
25
|
ActionEvent,
|
|
@@ -21,6 +29,7 @@ from oagi.types import (
|
|
|
21
29
|
Image,
|
|
22
30
|
PlanEvent,
|
|
23
31
|
StepEvent,
|
|
32
|
+
extract_uuid_from_url,
|
|
24
33
|
)
|
|
25
34
|
|
|
26
35
|
from ..protocol import AsyncAgent
|
|
@@ -52,15 +61,15 @@ class TaskeeAgent(AsyncAgent):
|
|
|
52
61
|
self,
|
|
53
62
|
api_key: str | None = None,
|
|
54
63
|
base_url: str | None = None,
|
|
55
|
-
model: str =
|
|
56
|
-
max_steps: int =
|
|
57
|
-
reflection_interval: int =
|
|
58
|
-
temperature: float =
|
|
64
|
+
model: str = MODEL_ACTOR,
|
|
65
|
+
max_steps: int = DEFAULT_MAX_STEPS,
|
|
66
|
+
reflection_interval: int = DEFAULT_REFLECTION_INTERVAL,
|
|
67
|
+
temperature: float = DEFAULT_TEMPERATURE,
|
|
59
68
|
planner: Planner | None = None,
|
|
60
69
|
external_memory: PlannerMemory | None = None,
|
|
61
70
|
todo_index: int | None = None,
|
|
62
71
|
step_observer: AsyncObserver | None = None,
|
|
63
|
-
step_delay: float =
|
|
72
|
+
step_delay: float = DEFAULT_STEP_DELAY,
|
|
64
73
|
):
|
|
65
74
|
"""Initialize the taskee agent.
|
|
66
75
|
|
|
@@ -114,6 +123,9 @@ class TaskeeAgent(AsyncAgent):
|
|
|
114
123
|
Returns:
|
|
115
124
|
True if successful, False otherwise
|
|
116
125
|
"""
|
|
126
|
+
# Reset handler state at todo execution start
|
|
127
|
+
reset_handler(action_handler)
|
|
128
|
+
|
|
117
129
|
self.current_todo = instruction
|
|
118
130
|
self.actions = []
|
|
119
131
|
self.total_actions = 0
|
|
@@ -249,11 +261,21 @@ class TaskeeAgent(AsyncAgent):
|
|
|
249
261
|
# Capture screenshot
|
|
250
262
|
screenshot = await image_provider()
|
|
251
263
|
|
|
252
|
-
#
|
|
264
|
+
# Get screenshot UUID - either extract from URL or upload
|
|
253
265
|
try:
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
266
|
+
screenshot_uuid = None
|
|
267
|
+
screenshot_url = None
|
|
268
|
+
|
|
269
|
+
# Check if screenshot is already a URL (from SocketIOImageProvider)
|
|
270
|
+
if isinstance(screenshot, str):
|
|
271
|
+
screenshot_uuid = extract_uuid_from_url(screenshot)
|
|
272
|
+
screenshot_url = screenshot
|
|
273
|
+
|
|
274
|
+
# If not a URL or UUID extraction failed, upload the image
|
|
275
|
+
if not screenshot_uuid:
|
|
276
|
+
upload_response = await client.put_s3_presigned_url(screenshot)
|
|
277
|
+
screenshot_uuid = upload_response.uuid
|
|
278
|
+
screenshot_url = upload_response.download_url
|
|
257
279
|
except Exception as e:
|
|
258
280
|
logger.error(f"Error uploading screenshot: {e}")
|
|
259
281
|
self._record_action(
|
|
@@ -9,6 +9,14 @@
|
|
|
9
9
|
import logging
|
|
10
10
|
from typing import Any
|
|
11
11
|
|
|
12
|
+
from oagi.constants import (
|
|
13
|
+
DEFAULT_MAX_STEPS_TASKER,
|
|
14
|
+
DEFAULT_REFLECTION_INTERVAL,
|
|
15
|
+
DEFAULT_STEP_DELAY,
|
|
16
|
+
DEFAULT_TEMPERATURE,
|
|
17
|
+
MODEL_ACTOR,
|
|
18
|
+
)
|
|
19
|
+
from oagi.handler import reset_handler
|
|
12
20
|
from oagi.types import AsyncActionHandler, AsyncImageProvider, AsyncObserver, SplitEvent
|
|
13
21
|
|
|
14
22
|
from ..protocol import AsyncAgent
|
|
@@ -34,13 +42,13 @@ class TaskerAgent(AsyncAgent):
|
|
|
34
42
|
self,
|
|
35
43
|
api_key: str | None = None,
|
|
36
44
|
base_url: str | None = None,
|
|
37
|
-
model: str =
|
|
38
|
-
max_steps: int =
|
|
39
|
-
temperature: float =
|
|
40
|
-
reflection_interval: int =
|
|
45
|
+
model: str = MODEL_ACTOR,
|
|
46
|
+
max_steps: int = DEFAULT_MAX_STEPS_TASKER,
|
|
47
|
+
temperature: float = DEFAULT_TEMPERATURE,
|
|
48
|
+
reflection_interval: int = DEFAULT_REFLECTION_INTERVAL,
|
|
41
49
|
planner: Planner | None = None,
|
|
42
50
|
step_observer: AsyncObserver | None = None,
|
|
43
|
-
step_delay: float =
|
|
51
|
+
step_delay: float = DEFAULT_STEP_DELAY,
|
|
44
52
|
):
|
|
45
53
|
"""Initialize the tasker agent.
|
|
46
54
|
|
|
@@ -105,6 +113,9 @@ class TaskerAgent(AsyncAgent):
|
|
|
105
113
|
Returns:
|
|
106
114
|
True if all todos completed successfully, False otherwise
|
|
107
115
|
"""
|
|
116
|
+
# Reset handler state at automation start
|
|
117
|
+
reset_handler(action_handler)
|
|
118
|
+
|
|
108
119
|
overall_success = True
|
|
109
120
|
|
|
110
121
|
# Execute todos until none remain
|