oagi-core 0.11.0__tar.gz → 0.12.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.12.0/.github/ISSUE_TEMPLATE/bug-report.yml +86 -0
- oagi_core-0.12.0/.github/ISSUE_TEMPLATE/config.yml +6 -0
- oagi_core-0.12.0/.github/ISSUE_TEMPLATE/feature-request.yml +37 -0
- oagi_core-0.12.0/.github/ISSUE_TEMPLATE/question.yml +22 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/PKG-INFO +57 -10
- {oagi_core-0.11.0 → oagi_core-0.12.0}/README.md +47 -1
- oagi_core-0.12.0/examples/openai_agent_loop_example.py +118 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/metapackage/pyproject.toml +2 -2
- {oagi_core-0.11.0 → oagi_core-0.12.0}/metapackage/uv.lock +5 -5
- {oagi_core-0.11.0 → oagi_core-0.12.0}/pyproject.toml +10 -9
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/__init__.py +1 -3
- {oagi_core-0.11.0/src/oagi/task → oagi_core-0.12.0/src/oagi/actor}/async_.py +23 -7
- {oagi_core-0.11.0/src/oagi/task → oagi_core-0.12.0/src/oagi/actor}/async_short.py +1 -1
- oagi_core-0.12.0/src/oagi/actor/base.py +222 -0
- {oagi_core-0.11.0/src/oagi/task → oagi_core-0.12.0/src/oagi/actor}/short.py +1 -1
- {oagi_core-0.11.0/src/oagi/task → oagi_core-0.12.0/src/oagi/actor}/sync.py +21 -5
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/agent/default.py +1 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/agent/observer/exporters.py +6 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/agent/observer/report_template.html +19 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/agent/tasker/planner.py +14 -12
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/agent/tasker/taskee_agent.py +7 -3
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/client/async_.py +54 -96
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/client/base.py +81 -133
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/client/sync.py +52 -99
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/constants.py +7 -2
- oagi_core-0.12.0/src/oagi/task/__init__.py +35 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/types/models/__init__.py +0 -2
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/types/models/action.py +4 -1
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/types/models/client.py +1 -17
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/types/step_observer.py +2 -0
- oagi_core-0.12.0/src/oagi/utils/__init__.py +12 -0
- oagi_core-0.12.0/src/oagi/utils/output_parser.py +166 -0
- oagi_core-0.12.0/src/oagi/utils/prompt_builder.py +44 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/tests/conftest.py +51 -81
- {oagi_core-0.11.0 → oagi_core-0.12.0}/tests/test_action_parsing.py +3 -0
- oagi_core-0.12.0/tests/test_actor.py +503 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/tests/test_agent/test_default_agent.py +1 -0
- oagi_core-0.12.0/tests/test_async_actor.py +190 -0
- oagi_core-0.12.0/tests/test_async_client.py +293 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/tests/test_logging.py +12 -99
- {oagi_core-0.11.0 → oagi_core-0.12.0}/tests/test_planner.py +10 -5
- oagi_core-0.12.0/tests/test_sync_client.py +268 -0
- oagi_core-0.12.0/tests/utils/__init__.py +7 -0
- oagi_core-0.12.0/tests/utils/test_output_parser.py +256 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/uv.lock +148 -9
- oagi_core-0.11.0/src/oagi/task/base.py +0 -158
- oagi_core-0.11.0/tests/test_actor.py +0 -440
- oagi_core-0.11.0/tests/test_async_actor.py +0 -180
- oagi_core-0.11.0/tests/test_async_client.py +0 -385
- oagi_core-0.11.0/tests/test_sync_client.py +0 -603
- {oagi_core-0.11.0 → oagi_core-0.12.0}/.github/workflows/ci.yml +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/.github/workflows/release.yml +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/.gitignore +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/.python-version +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/CONTRIBUTING.md +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/LICENSE +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/Makefile +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/examples/async_google_weather.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/examples/execute_task_auto.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/examples/execute_task_manual.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/examples/google_weather.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/examples/screenshot_with_config.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/examples/tasker_agent_example.py +0 -0
- {oagi_core-0.11.0/src/oagi/task → oagi_core-0.12.0/src/oagi/actor}/__init__.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/agent/__init__.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/agent/factories.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/agent/observer/__init__.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/agent/observer/agent_observer.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/agent/observer/events.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/agent/observer/protocol.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/agent/protocol.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/agent/registry.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/agent/tasker/__init__.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/agent/tasker/memory.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/agent/tasker/models.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/agent/tasker/tasker_agent.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/cli/__init__.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/cli/agent.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/cli/display.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/cli/main.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/cli/server.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/cli/tracking.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/cli/utils.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/client/__init__.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/exceptions.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/handler/__init__.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/handler/_macos.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/handler/_windows.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/handler/async_pyautogui_action_handler.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/handler/async_screenshot_maker.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/handler/capslock_manager.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/handler/pil_image.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/handler/pyautogui_action_handler.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/handler/screenshot_maker.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/logging.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/server/__init__.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/server/agent_wrappers.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/server/config.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/server/main.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/server/models.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/server/session_store.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/server/socketio_server.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/types/__init__.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/types/action_handler.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/types/async_action_handler.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/types/async_image_provider.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/types/image.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/types/image_provider.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/types/models/image_config.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/types/models/step.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/src/oagi/types/url.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/tests/__init__.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/tests/test_agent/test_agent_wrappers.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/tests/test_agent_registry.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/tests/test_async_handlers.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/tests/test_cli.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/tests/test_mac_double_click.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/tests/test_observer.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/tests/test_pil_image.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/tests/test_planner_memory.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/tests/test_pyautogui_action_handler.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/tests/test_screenshot_maker.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/tests/test_server/__init__.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/tests/test_server/test_config.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/tests/test_server/test_session_store.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/tests/test_server/test_socketio_integration.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/tests/test_taskee_agent.py +0 -0
- {oagi_core-0.11.0 → oagi_core-0.12.0}/tests/test_tasker_agent.py +0 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Report a problem installing or using the OpenAGI (oagi) Python SDK.
|
|
3
|
+
title: "[Bug]: "
|
|
4
|
+
labels: ["bug"]
|
|
5
|
+
body:
|
|
6
|
+
- type: checkboxes
|
|
7
|
+
id: checks
|
|
8
|
+
attributes:
|
|
9
|
+
label: Pre-checks
|
|
10
|
+
options:
|
|
11
|
+
- label: I have searched existing issues.
|
|
12
|
+
required: true
|
|
13
|
+
- label: I am using Python 3.10 or newer (per docs).
|
|
14
|
+
required: true
|
|
15
|
+
- label: I included the full error output/logs.
|
|
16
|
+
required: false
|
|
17
|
+
- type: input
|
|
18
|
+
id: version
|
|
19
|
+
attributes:
|
|
20
|
+
label: oagi package version
|
|
21
|
+
description: Output of `pip show oagi`.
|
|
22
|
+
placeholder: e.g. 0.11.0
|
|
23
|
+
validations:
|
|
24
|
+
required: true
|
|
25
|
+
- type: dropdown
|
|
26
|
+
id: python
|
|
27
|
+
attributes:
|
|
28
|
+
label: Python version (docs require 3.10+)
|
|
29
|
+
options:
|
|
30
|
+
- 3.10
|
|
31
|
+
- 3.11
|
|
32
|
+
- 3.12
|
|
33
|
+
- 3.13
|
|
34
|
+
- Other (>=3.10)
|
|
35
|
+
validations:
|
|
36
|
+
required: true
|
|
37
|
+
- type: dropdown
|
|
38
|
+
id: os
|
|
39
|
+
attributes:
|
|
40
|
+
label: Operating system
|
|
41
|
+
options:
|
|
42
|
+
- Windows
|
|
43
|
+
- macOS
|
|
44
|
+
- Linux
|
|
45
|
+
validations:
|
|
46
|
+
required: true
|
|
47
|
+
- type: dropdown
|
|
48
|
+
id: installer
|
|
49
|
+
attributes:
|
|
50
|
+
label: How did you install? (docs recommend `pip install oagi`)
|
|
51
|
+
options:
|
|
52
|
+
- pip
|
|
53
|
+
- uv
|
|
54
|
+
- other
|
|
55
|
+
validations:
|
|
56
|
+
required: true
|
|
57
|
+
- type: textarea
|
|
58
|
+
id: steps
|
|
59
|
+
attributes:
|
|
60
|
+
label: Steps to reproduce
|
|
61
|
+
description: Include exact commands and any virtual env/tooling used.
|
|
62
|
+
placeholder: |
|
|
63
|
+
1. ...
|
|
64
|
+
2. ...
|
|
65
|
+
validations:
|
|
66
|
+
required: true
|
|
67
|
+
- type: textarea
|
|
68
|
+
id: expected
|
|
69
|
+
attributes:
|
|
70
|
+
label: Expected behavior
|
|
71
|
+
validations:
|
|
72
|
+
required: true
|
|
73
|
+
- type: textarea
|
|
74
|
+
id: actual
|
|
75
|
+
attributes:
|
|
76
|
+
label: Actual behavior and logs
|
|
77
|
+
description: Paste full traceback/build logs if applicable.
|
|
78
|
+
render: shell
|
|
79
|
+
validations:
|
|
80
|
+
required: true
|
|
81
|
+
- type: textarea
|
|
82
|
+
id: extra
|
|
83
|
+
attributes:
|
|
84
|
+
label: Additional context
|
|
85
|
+
description: Environment details, proxies, system architecture, etc.
|
|
86
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Suggest an improvement or new capability for the OAGI Python SDK.
|
|
3
|
+
title: "[Feature]: "
|
|
4
|
+
labels: ["enhancement"]
|
|
5
|
+
body:
|
|
6
|
+
- type: textarea
|
|
7
|
+
id: summary
|
|
8
|
+
attributes:
|
|
9
|
+
label: Summary
|
|
10
|
+
description: Short description of the feature.
|
|
11
|
+
validations:
|
|
12
|
+
required: true
|
|
13
|
+
- type: textarea
|
|
14
|
+
id: problem
|
|
15
|
+
attributes:
|
|
16
|
+
label: Problem to solve
|
|
17
|
+
description: What problem or workflow does this address?
|
|
18
|
+
validations:
|
|
19
|
+
required: true
|
|
20
|
+
- type: textarea
|
|
21
|
+
id: proposal
|
|
22
|
+
attributes:
|
|
23
|
+
label: Proposed solution
|
|
24
|
+
description: Describe the desired behavior or API shape.
|
|
25
|
+
validations:
|
|
26
|
+
required: true
|
|
27
|
+
- type: textarea
|
|
28
|
+
id: alternatives
|
|
29
|
+
attributes:
|
|
30
|
+
label: Alternatives considered
|
|
31
|
+
description: Other approaches you tried or considered.
|
|
32
|
+
- type: textarea
|
|
33
|
+
id: extra
|
|
34
|
+
attributes:
|
|
35
|
+
label: Additional context
|
|
36
|
+
description: Screenshots, links, or related issues.
|
|
37
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
name: Question
|
|
2
|
+
description: Ask a question about using the OAGI Python SDK.
|
|
3
|
+
title: "[Question]: "
|
|
4
|
+
labels: ["question"]
|
|
5
|
+
body:
|
|
6
|
+
- type: textarea
|
|
7
|
+
id: question
|
|
8
|
+
attributes:
|
|
9
|
+
label: What do you need help with?
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
- type: input
|
|
13
|
+
id: version
|
|
14
|
+
attributes:
|
|
15
|
+
label: Relevant package/version info
|
|
16
|
+
description: e.g. oagi version, Python version.
|
|
17
|
+
- type: textarea
|
|
18
|
+
id: context
|
|
19
|
+
attributes:
|
|
20
|
+
label: Context
|
|
21
|
+
description: What you tried, expected results, and any logs.
|
|
22
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: oagi-core
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.12.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>
|
|
@@ -26,25 +26,71 @@ License: MIT License
|
|
|
26
26
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
27
27
|
SOFTWARE.
|
|
28
28
|
Requires-Python: >=3.10
|
|
29
|
-
Requires-Dist: httpx>=0.
|
|
29
|
+
Requires-Dist: httpx>=0.24.0
|
|
30
|
+
Requires-Dist: openai>=1.3.0
|
|
30
31
|
Requires-Dist: pydantic>=2.0.0
|
|
31
|
-
Requires-Dist: rich>=
|
|
32
|
+
Requires-Dist: rich>=10.0.0
|
|
32
33
|
Provides-Extra: desktop
|
|
33
|
-
Requires-Dist: pillow>=
|
|
34
|
+
Requires-Dist: pillow>=9.0.0; extra == 'desktop'
|
|
34
35
|
Requires-Dist: pyautogui>=0.9.54; extra == 'desktop'
|
|
35
|
-
Requires-Dist: pyobjc-framework-applicationservices>=
|
|
36
|
-
Requires-Dist: pyobjc-framework-quartz>=
|
|
36
|
+
Requires-Dist: pyobjc-framework-applicationservices>=8.0; (sys_platform == 'darwin') and extra == 'desktop'
|
|
37
|
+
Requires-Dist: pyobjc-framework-quartz>=8.0; (sys_platform == 'darwin') and extra == 'desktop'
|
|
37
38
|
Provides-Extra: server
|
|
38
|
-
Requires-Dist: fastapi[standard]>=0.
|
|
39
|
+
Requires-Dist: fastapi[standard]>=0.100.0; extra == 'server'
|
|
39
40
|
Requires-Dist: pydantic-settings>=2.0.0; extra == 'server'
|
|
40
|
-
Requires-Dist: python-socketio>=5.
|
|
41
|
-
Requires-Dist: uvicorn[standard]>=0.
|
|
41
|
+
Requires-Dist: python-socketio>=5.5.0; extra == 'server'
|
|
42
|
+
Requires-Dist: uvicorn[standard]>=0.20.0; extra == 'server'
|
|
42
43
|
Description-Content-Type: text/markdown
|
|
43
44
|
|
|
44
45
|
# OAGI Python SDK
|
|
45
46
|
|
|
47
|
+
[](https://pypi.org/project/oagi-core/)
|
|
48
|
+
[](https://pypi.org/project/oagi-core/)
|
|
49
|
+
[](https://github.com/agiopen-org/oagi-python/blob/main/LICENSE)
|
|
50
|
+
[](https://github.com/agiopen-org/oagi-python/actions/workflows/ci.yml)
|
|
51
|
+
|
|
46
52
|
Python SDK for the OAGI API - vision-based task automation.
|
|
47
53
|
|
|
54
|
+
## What is OAGI?
|
|
55
|
+
|
|
56
|
+
OAGI is the Python SDK for **Lux**, the world's most advanced computer-use model from the OpenAGI Foundation.
|
|
57
|
+
|
|
58
|
+
**Computer Use** is AI's ability to operate human-facing software — not just through APIs, but by operating computers natively, just as human users do. It's a paradigm shift in what AI can do: not just generating, reasoning, or researching, but actually operating on your computer.
|
|
59
|
+
|
|
60
|
+
Lux comes in three modes, giving you control over depth, speed, and style of execution:
|
|
61
|
+
|
|
62
|
+
- **Tasker** — Strictly follows step-by-step instructions with ultra-stable, controllable execution
|
|
63
|
+
- **Actor** — Ideal for immediate tasks, completing actions at near-instant speed
|
|
64
|
+
- **Thinker** — Understands vague, complex goals, performing hour-long executions
|
|
65
|
+
|
|
66
|
+
### Use Cases
|
|
67
|
+
|
|
68
|
+
With Lux, possibilities are endless. Here are a few examples:
|
|
69
|
+
|
|
70
|
+
- **Web Scraping & Data Crawl** — Navigate websites, sort results, and collect product information autonomously
|
|
71
|
+
- **Software QA** — Automate repetitive testing tasks, navigate applications, perform test actions, and validate expected behaviors
|
|
72
|
+
- **Financial Data Extraction** — Navigate to sites like NASDAQ and extract insider activity data
|
|
73
|
+
- **Data Entry** — Enter accurate data across dashboards and forms
|
|
74
|
+
- **Workflow Automation** — Chain together multi-step tasks across different applications
|
|
75
|
+
|
|
76
|
+
## Table of Contents
|
|
77
|
+
|
|
78
|
+
- [What is OAGI?](#what-is-oagi)
|
|
79
|
+
- [Installation](#installation)
|
|
80
|
+
- [Quick Start](#quick-start)
|
|
81
|
+
- [Automated Task Execution](#automated-task-execution)
|
|
82
|
+
- [Command Line Interface](#command-line-interface)
|
|
83
|
+
- [Image Processing](#image-processing)
|
|
84
|
+
- [Manual Control with Actor](#manual-control-with-actor)
|
|
85
|
+
- [Examples](#examples)
|
|
86
|
+
- [Socket.IO Server (Optional)](#socketio-server-optional)
|
|
87
|
+
- [Installation](#installation-1)
|
|
88
|
+
- [Running the Server](#running-the-server)
|
|
89
|
+
- [Server Features](#server-features)
|
|
90
|
+
- [Client Integration](#client-integration)
|
|
91
|
+
- [Documentation](#documentation)
|
|
92
|
+
- [License](#license)
|
|
93
|
+
|
|
48
94
|
## Installation
|
|
49
95
|
|
|
50
96
|
```bash
|
|
@@ -74,7 +120,7 @@ pip install oagi-core[server] # Server support
|
|
|
74
120
|
|
|
75
121
|
Set your API credentials:
|
|
76
122
|
```bash
|
|
77
|
-
export OAGI_API_KEY="your-api-key" # get your API key from https://developer.
|
|
123
|
+
export OAGI_API_KEY="your-api-key" # get your API key from https://developer.agiopen.org/
|
|
78
124
|
# export OAGI_BASE_URL="https://api.agiopen.org/", # optional, defaults to production endpoint
|
|
79
125
|
```
|
|
80
126
|
|
|
@@ -272,6 +318,7 @@ See [`examples/socketio_client_example.py`](examples/socketio_client_example.py)
|
|
|
272
318
|
|
|
273
319
|
## Documentation
|
|
274
320
|
|
|
321
|
+
For full Lux documentation and guides, visit the [OAGI Developer Documentation](https://developer.agiopen.org/docs/index).
|
|
275
322
|
|
|
276
323
|
## License
|
|
277
324
|
|
|
@@ -1,7 +1,52 @@
|
|
|
1
1
|
# OAGI Python SDK
|
|
2
2
|
|
|
3
|
+
[](https://pypi.org/project/oagi-core/)
|
|
4
|
+
[](https://pypi.org/project/oagi-core/)
|
|
5
|
+
[](https://github.com/agiopen-org/oagi-python/blob/main/LICENSE)
|
|
6
|
+
[](https://github.com/agiopen-org/oagi-python/actions/workflows/ci.yml)
|
|
7
|
+
|
|
3
8
|
Python SDK for the OAGI API - vision-based task automation.
|
|
4
9
|
|
|
10
|
+
## What is OAGI?
|
|
11
|
+
|
|
12
|
+
OAGI is the Python SDK for **Lux**, the world's most advanced computer-use model from the OpenAGI Foundation.
|
|
13
|
+
|
|
14
|
+
**Computer Use** is AI's ability to operate human-facing software — not just through APIs, but by operating computers natively, just as human users do. It's a paradigm shift in what AI can do: not just generating, reasoning, or researching, but actually operating on your computer.
|
|
15
|
+
|
|
16
|
+
Lux comes in three modes, giving you control over depth, speed, and style of execution:
|
|
17
|
+
|
|
18
|
+
- **Tasker** — Strictly follows step-by-step instructions with ultra-stable, controllable execution
|
|
19
|
+
- **Actor** — Ideal for immediate tasks, completing actions at near-instant speed
|
|
20
|
+
- **Thinker** — Understands vague, complex goals, performing hour-long executions
|
|
21
|
+
|
|
22
|
+
### Use Cases
|
|
23
|
+
|
|
24
|
+
With Lux, possibilities are endless. Here are a few examples:
|
|
25
|
+
|
|
26
|
+
- **Web Scraping & Data Crawl** — Navigate websites, sort results, and collect product information autonomously
|
|
27
|
+
- **Software QA** — Automate repetitive testing tasks, navigate applications, perform test actions, and validate expected behaviors
|
|
28
|
+
- **Financial Data Extraction** — Navigate to sites like NASDAQ and extract insider activity data
|
|
29
|
+
- **Data Entry** — Enter accurate data across dashboards and forms
|
|
30
|
+
- **Workflow Automation** — Chain together multi-step tasks across different applications
|
|
31
|
+
|
|
32
|
+
## Table of Contents
|
|
33
|
+
|
|
34
|
+
- [What is OAGI?](#what-is-oagi)
|
|
35
|
+
- [Installation](#installation)
|
|
36
|
+
- [Quick Start](#quick-start)
|
|
37
|
+
- [Automated Task Execution](#automated-task-execution)
|
|
38
|
+
- [Command Line Interface](#command-line-interface)
|
|
39
|
+
- [Image Processing](#image-processing)
|
|
40
|
+
- [Manual Control with Actor](#manual-control-with-actor)
|
|
41
|
+
- [Examples](#examples)
|
|
42
|
+
- [Socket.IO Server (Optional)](#socketio-server-optional)
|
|
43
|
+
- [Installation](#installation-1)
|
|
44
|
+
- [Running the Server](#running-the-server)
|
|
45
|
+
- [Server Features](#server-features)
|
|
46
|
+
- [Client Integration](#client-integration)
|
|
47
|
+
- [Documentation](#documentation)
|
|
48
|
+
- [License](#license)
|
|
49
|
+
|
|
5
50
|
## Installation
|
|
6
51
|
|
|
7
52
|
```bash
|
|
@@ -31,7 +76,7 @@ pip install oagi-core[server] # Server support
|
|
|
31
76
|
|
|
32
77
|
Set your API credentials:
|
|
33
78
|
```bash
|
|
34
|
-
export OAGI_API_KEY="your-api-key" # get your API key from https://developer.
|
|
79
|
+
export OAGI_API_KEY="your-api-key" # get your API key from https://developer.agiopen.org/
|
|
35
80
|
# export OAGI_BASE_URL="https://api.agiopen.org/", # optional, defaults to production endpoint
|
|
36
81
|
```
|
|
37
82
|
|
|
@@ -229,6 +274,7 @@ See [`examples/socketio_client_example.py`](examples/socketio_client_example.py)
|
|
|
229
274
|
|
|
230
275
|
## Documentation
|
|
231
276
|
|
|
277
|
+
For full Lux documentation and guides, visit the [OAGI Developer Documentation](https://developer.agiopen.org/docs/index).
|
|
232
278
|
|
|
233
279
|
## License
|
|
234
280
|
|
|
@@ -0,0 +1,118 @@
|
|
|
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
|
+
"""
|
|
9
|
+
Example: OpenAI-Compatible Agent Loop
|
|
10
|
+
|
|
11
|
+
This example demonstrates how to build an agent loop using:
|
|
12
|
+
1. OAGI file upload for screenshots
|
|
13
|
+
2. OAGI action handler for execution
|
|
14
|
+
3. OAGI utilities for prompt building and action parsing
|
|
15
|
+
4. OpenAI-compatible API endpoint for LLM calls
|
|
16
|
+
|
|
17
|
+
Environment variables:
|
|
18
|
+
- OAGI_API_KEY: Your OAGI API key
|
|
19
|
+
- OAGI_BASE_URL: API base URL (default: https://api.agiopen.org)
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
import os
|
|
23
|
+
|
|
24
|
+
from openai import OpenAI
|
|
25
|
+
|
|
26
|
+
from oagi import PyautoguiActionHandler, ScreenshotMaker, SyncClient
|
|
27
|
+
from oagi.utils.output_parser import parse_raw_output
|
|
28
|
+
from oagi.utils.prompt_builder import build_prompt
|
|
29
|
+
|
|
30
|
+
DEFAULT_BASE_URL = "https://api.agiopen.org"
|
|
31
|
+
DEFAULT_MODEL = "lux-actor-1"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def agent_loop(task_description: str, max_steps: int = 10) -> bool:
|
|
35
|
+
"""
|
|
36
|
+
Run an agent loop to complete a task.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
task_description: The task to complete
|
|
40
|
+
max_steps: Maximum number of steps to take
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
True if task completed, False if max steps reached
|
|
44
|
+
"""
|
|
45
|
+
# Get configuration from environment
|
|
46
|
+
api_key = os.environ.get("OAGI_API_KEY")
|
|
47
|
+
base_url = os.environ.get("OAGI_BASE_URL", DEFAULT_BASE_URL)
|
|
48
|
+
|
|
49
|
+
if not api_key:
|
|
50
|
+
raise ValueError("OAGI_API_KEY environment variable is required")
|
|
51
|
+
|
|
52
|
+
# Initialize clients and handlers
|
|
53
|
+
oagi_client = SyncClient(api_key=api_key, base_url=base_url)
|
|
54
|
+
openai_client = OpenAI(api_key=api_key, base_url=f"{base_url}/v1")
|
|
55
|
+
action_handler = PyautoguiActionHandler()
|
|
56
|
+
image_provider = ScreenshotMaker()
|
|
57
|
+
|
|
58
|
+
messages: list[dict] = []
|
|
59
|
+
|
|
60
|
+
print(f"Starting task: {task_description}")
|
|
61
|
+
print(f"Max steps: {max_steps}")
|
|
62
|
+
print("-" * 50)
|
|
63
|
+
|
|
64
|
+
try:
|
|
65
|
+
for step_num in range(max_steps):
|
|
66
|
+
# 1. Capture screenshot
|
|
67
|
+
screenshot = image_provider()
|
|
68
|
+
|
|
69
|
+
# 2. Upload to S3
|
|
70
|
+
upload_resp = oagi_client.put_s3_presigned_url(screenshot)
|
|
71
|
+
screenshot_url = upload_resp.download_url
|
|
72
|
+
|
|
73
|
+
# 3. Build message (with prompt on first step)
|
|
74
|
+
content = []
|
|
75
|
+
if step_num == 0:
|
|
76
|
+
content.append({"type": "text", "text": build_prompt(task_description)})
|
|
77
|
+
content.append({"type": "image_url", "image_url": {"url": screenshot_url}})
|
|
78
|
+
messages.append({"role": "user", "content": content})
|
|
79
|
+
|
|
80
|
+
# 4. Call OpenAI-compatible API
|
|
81
|
+
response = openai_client.chat.completions.create(
|
|
82
|
+
model=DEFAULT_MODEL,
|
|
83
|
+
messages=messages,
|
|
84
|
+
)
|
|
85
|
+
raw_output = response.choices[0].message.content or ""
|
|
86
|
+
|
|
87
|
+
# 5. Add assistant message to history
|
|
88
|
+
messages.append({"role": "assistant", "content": raw_output})
|
|
89
|
+
|
|
90
|
+
# 6. Parse output using oagi utility
|
|
91
|
+
step = parse_raw_output(raw_output)
|
|
92
|
+
print(f"Step {step_num}: {step.reason}")
|
|
93
|
+
print(f" Actions: {step.actions}")
|
|
94
|
+
|
|
95
|
+
# 7. Check for completion
|
|
96
|
+
if step.stop:
|
|
97
|
+
print("-" * 50)
|
|
98
|
+
print("Task completed!")
|
|
99
|
+
return True
|
|
100
|
+
|
|
101
|
+
# 8. Execute actions
|
|
102
|
+
action_handler(step.actions)
|
|
103
|
+
|
|
104
|
+
print("-" * 50)
|
|
105
|
+
print("Max steps reached without completion")
|
|
106
|
+
return False
|
|
107
|
+
|
|
108
|
+
finally:
|
|
109
|
+
oagi_client.close()
|
|
110
|
+
openai_client.close()
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
if __name__ == "__main__":
|
|
114
|
+
# Example task
|
|
115
|
+
task = "Find some shoes on amazon"
|
|
116
|
+
|
|
117
|
+
success = agent_loop(task, max_steps=20)
|
|
118
|
+
print(f"\nFinal result: {'Success' if success else 'Failed'}")
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "oagi"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.12.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.12.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.12.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.
|
|
407
|
+
requires-dist = [{ name = "oagi-core", extras = ["desktop", "server"], specifier = "==0.11.0" }]
|
|
408
408
|
|
|
409
409
|
[[package]]
|
|
410
410
|
name = "oagi-core"
|
|
411
|
-
version = "0.
|
|
411
|
+
version = "0.11.0"
|
|
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/aa/ea/dab8d3e9eb7cf98de7aa5cc993a76ee3bd082e9ba78c09256f6f2a1e06ae/oagi_core-0.11.0.tar.gz", hash = "sha256:b8e0a78b7d6253ba969ffc8256d6f5cbea226d0fedc28935664875c12b8a391a", size = 273296, upload-time = "2025-12-01T09:33:52.654Z" }
|
|
419
419
|
wheels = [
|
|
420
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
420
|
+
{ url = "https://files.pythonhosted.org/packages/5a/b8/6c9a2f0d5295c66875d2c7dd5d3057c6d71b468baea3737a3a7c1153e0f6/oagi_core-0.11.0-py3-none-any.whl", hash = "sha256:59e47e6e6f2fff30665d748dcf0afde5a84c8da1529ed4da4e3d96803d4005d6", size = 94638, upload-time = "2025-12-01T09:33:51.435Z" },
|
|
421
421
|
]
|
|
422
422
|
|
|
423
423
|
[package.optional-dependencies]
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "oagi-core"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.12.0"
|
|
8
8
|
description = "Official API of OpenAGI Foundation"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { file = "LICENSE" }
|
|
@@ -15,9 +15,10 @@ authors = [
|
|
|
15
15
|
requires-python = ">= 3.10"
|
|
16
16
|
|
|
17
17
|
dependencies = [
|
|
18
|
-
"httpx>=0.
|
|
18
|
+
"httpx>=0.24.0",
|
|
19
|
+
"openai>=1.3.0",
|
|
19
20
|
"pydantic>=2.0.0",
|
|
20
|
-
"rich>=
|
|
21
|
+
"rich>=10.0.0",
|
|
21
22
|
]
|
|
22
23
|
|
|
23
24
|
[project.urls]
|
|
@@ -28,15 +29,15 @@ oagi = "oagi.cli.main:main"
|
|
|
28
29
|
|
|
29
30
|
[project.optional-dependencies]
|
|
30
31
|
desktop = [
|
|
31
|
-
"pillow>=
|
|
32
|
+
"pillow>=9.0.0",
|
|
32
33
|
"pyautogui>=0.9.54",
|
|
33
|
-
"pyobjc-framework-Quartz>=
|
|
34
|
-
"pyobjc-framework-ApplicationServices>=
|
|
34
|
+
"pyobjc-framework-Quartz>=8.0; sys_platform == 'darwin'",
|
|
35
|
+
"pyobjc-framework-ApplicationServices>=8.0; sys_platform == 'darwin'",
|
|
35
36
|
]
|
|
36
37
|
server = [
|
|
37
|
-
"fastapi[standard]>=0.
|
|
38
|
-
"uvicorn[standard]>=0.
|
|
39
|
-
"python-socketio>=5.
|
|
38
|
+
"fastapi[standard]>=0.100.0",
|
|
39
|
+
"uvicorn[standard]>=0.20.0",
|
|
40
|
+
"python-socketio>=5.5.0",
|
|
40
41
|
"pydantic-settings>=2.0.0",
|
|
41
42
|
]
|
|
42
43
|
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import importlib
|
|
9
9
|
from typing import TYPE_CHECKING
|
|
10
10
|
|
|
11
|
+
from oagi.actor import Actor, AsyncActor, AsyncShortTask, AsyncTask, ShortTask, Task
|
|
11
12
|
from oagi.client import AsyncClient, SyncClient
|
|
12
13
|
from oagi.exceptions import (
|
|
13
14
|
APIError,
|
|
@@ -22,13 +23,11 @@ from oagi.exceptions import (
|
|
|
22
23
|
ValidationError,
|
|
23
24
|
check_optional_dependency,
|
|
24
25
|
)
|
|
25
|
-
from oagi.task import Actor, AsyncActor, AsyncShortTask, AsyncTask, ShortTask, Task
|
|
26
26
|
from oagi.types import ImageConfig
|
|
27
27
|
from oagi.types.models import (
|
|
28
28
|
ErrorDetail,
|
|
29
29
|
ErrorResponse,
|
|
30
30
|
GenerateResponse,
|
|
31
|
-
LLMResponse,
|
|
32
31
|
UploadFileResponse,
|
|
33
32
|
)
|
|
34
33
|
|
|
@@ -116,7 +115,6 @@ __all__ = [
|
|
|
116
115
|
# Configuration
|
|
117
116
|
"ImageConfig",
|
|
118
117
|
# Response models
|
|
119
|
-
"LLMResponse",
|
|
120
118
|
"GenerateResponse",
|
|
121
119
|
"UploadFileResponse",
|
|
122
120
|
"ErrorResponse",
|
|
@@ -10,9 +10,12 @@ import warnings
|
|
|
10
10
|
|
|
11
11
|
from ..client import AsyncClient
|
|
12
12
|
from ..constants import DEFAULT_MAX_STEPS, MODEL_ACTOR
|
|
13
|
+
from ..logging import get_logger
|
|
13
14
|
from ..types import URL, Image, Step
|
|
14
15
|
from .base import BaseActor
|
|
15
16
|
|
|
17
|
+
logger = get_logger("actor.async")
|
|
18
|
+
|
|
16
19
|
|
|
17
20
|
class AsyncActor(BaseActor):
|
|
18
21
|
"""Async base class for task automation with the OAGI API."""
|
|
@@ -51,20 +54,33 @@ class AsyncActor(BaseActor):
|
|
|
51
54
|
"""Send screenshot to the server and get the next actions.
|
|
52
55
|
|
|
53
56
|
Args:
|
|
54
|
-
screenshot: Screenshot as Image object or raw bytes
|
|
55
|
-
instruction: Optional additional instruction for this step
|
|
57
|
+
screenshot: Screenshot as Image object, URL string, or raw bytes
|
|
58
|
+
instruction: Optional additional instruction for this step (currently unused)
|
|
56
59
|
temperature: Sampling temperature for this step (overrides task default if provided)
|
|
57
60
|
|
|
58
61
|
Returns:
|
|
59
62
|
Step: The actions and reasoning for this step
|
|
60
63
|
"""
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
)
|
|
64
|
+
self._validate_and_increment_step()
|
|
65
|
+
self._log_step_execution(prefix="async ")
|
|
64
66
|
|
|
65
67
|
try:
|
|
66
|
-
|
|
67
|
-
|
|
68
|
+
screenshot_url = await self._ensure_screenshot_url_async(
|
|
69
|
+
screenshot, self.client
|
|
70
|
+
)
|
|
71
|
+
self._add_user_message_to_history(screenshot_url, self._build_step_prompt())
|
|
72
|
+
|
|
73
|
+
step, raw_output, usage = await self.client.chat_completion(
|
|
74
|
+
model=self.model,
|
|
75
|
+
messages=self.message_history,
|
|
76
|
+
temperature=self._get_temperature(temperature),
|
|
77
|
+
task_id=self.task_id,
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
self._add_assistant_message_to_history(raw_output)
|
|
81
|
+
self._log_step_completion(step, prefix="Async ")
|
|
82
|
+
return step
|
|
83
|
+
|
|
68
84
|
except Exception as e:
|
|
69
85
|
self._handle_step_error(e, prefix="async ")
|
|
70
86
|
|
|
@@ -14,7 +14,7 @@ from ..types import AsyncActionHandler, AsyncImageProvider
|
|
|
14
14
|
from .async_ import AsyncActor
|
|
15
15
|
from .base import BaseAutoMode
|
|
16
16
|
|
|
17
|
-
logger = get_logger("
|
|
17
|
+
logger = get_logger("async_short_actor")
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
class AsyncShortTask(AsyncActor, BaseAutoMode):
|