oagi-core 0.9.2__tar.gz → 0.10.1__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.
Files changed (117) hide show
  1. {oagi_core-0.9.2 → oagi_core-0.10.1}/PKG-INFO +38 -25
  2. {oagi_core-0.9.2 → oagi_core-0.10.1}/README.md +36 -24
  3. oagi_core-0.10.1/examples/execute_task_auto.py +37 -0
  4. {oagi_core-0.9.2 → oagi_core-0.10.1}/examples/google_weather.py +1 -1
  5. oagi_core-0.10.1/examples/tasker_agent_example.py +73 -0
  6. {oagi_core-0.9.2 → oagi_core-0.10.1}/metapackage/pyproject.toml +2 -2
  7. {oagi_core-0.9.2 → oagi_core-0.10.1}/metapackage/uv.lock +7 -6
  8. {oagi_core-0.9.2 → oagi_core-0.10.1}/pyproject.toml +2 -1
  9. oagi_core-0.10.1/src/oagi/__init__.py +148 -0
  10. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/agent/__init__.py +2 -0
  11. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/agent/default.py +41 -8
  12. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/agent/factories.py +22 -3
  13. oagi_core-0.10.1/src/oagi/agent/observer/__init__.py +38 -0
  14. oagi_core-0.10.1/src/oagi/agent/observer/agent_observer.py +99 -0
  15. oagi_core-0.10.1/src/oagi/agent/observer/events.py +28 -0
  16. oagi_core-0.10.1/src/oagi/agent/observer/exporters.py +445 -0
  17. oagi_core-0.10.1/src/oagi/agent/observer/protocol.py +12 -0
  18. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/agent/registry.py +2 -2
  19. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/agent/tasker/__init__.py +0 -2
  20. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/agent/tasker/memory.py +3 -27
  21. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/agent/tasker/models.py +1 -7
  22. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/agent/tasker/planner.py +32 -18
  23. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/agent/tasker/taskee_agent.py +171 -79
  24. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/agent/tasker/tasker_agent.py +23 -26
  25. oagi_core-0.10.1/src/oagi/cli/agent.py +281 -0
  26. oagi_core-0.10.1/src/oagi/cli/tracking.py +55 -0
  27. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/client/async_.py +0 -3
  28. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/client/base.py +0 -4
  29. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/client/sync.py +0 -3
  30. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/handler/pyautogui_action_handler.py +15 -2
  31. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/server/agent_wrappers.py +5 -5
  32. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/server/models.py +1 -1
  33. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/server/session_store.py +2 -2
  34. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/task/async_.py +11 -32
  35. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/task/async_short.py +1 -1
  36. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/task/base.py +41 -7
  37. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/task/short.py +1 -1
  38. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/task/sync.py +9 -32
  39. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/types/__init__.py +24 -4
  40. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/types/async_image_provider.py +3 -2
  41. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/types/image_provider.py +3 -2
  42. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/types/models/client.py +7 -3
  43. oagi_core-0.10.1/src/oagi/types/step_observer.py +93 -0
  44. oagi_core-0.10.1/src/oagi/types/url.py +3 -0
  45. {oagi_core-0.9.2 → oagi_core-0.10.1}/tests/conftest.py +2 -2
  46. oagi_core-0.9.2/tests/test_task.py → oagi_core-0.10.1/tests/test_actor.py +12 -0
  47. {oagi_core-0.9.2 → oagi_core-0.10.1}/tests/test_agent/test_agent_wrappers.py +7 -7
  48. {oagi_core-0.9.2 → oagi_core-0.10.1}/tests/test_agent/test_default_agent.py +7 -4
  49. {oagi_core-0.9.2 → oagi_core-0.10.1}/tests/test_agent_registry.py +5 -5
  50. oagi_core-0.9.2/tests/test_async_task.py → oagi_core-0.10.1/tests/test_async_actor.py +24 -85
  51. {oagi_core-0.9.2 → oagi_core-0.10.1}/tests/test_cli.py +1 -1
  52. {oagi_core-0.9.2 → oagi_core-0.10.1}/tests/test_logging.py +2 -2
  53. oagi_core-0.10.1/tests/test_observer.py +378 -0
  54. {oagi_core-0.9.2 → oagi_core-0.10.1}/tests/test_planner.py +6 -7
  55. {oagi_core-0.9.2 → oagi_core-0.10.1}/tests/test_planner_memory.py +0 -13
  56. {oagi_core-0.9.2 → oagi_core-0.10.1}/tests/test_pyautogui_action_handler.py +57 -3
  57. {oagi_core-0.9.2 → oagi_core-0.10.1}/tests/test_server/test_session_store.py +3 -3
  58. {oagi_core-0.9.2 → oagi_core-0.10.1}/tests/test_taskee_agent.py +34 -23
  59. {oagi_core-0.9.2 → oagi_core-0.10.1}/tests/test_tasker_agent.py +10 -23
  60. {oagi_core-0.9.2 → oagi_core-0.10.1}/uv.lock +71 -28
  61. oagi_core-0.9.2/examples/continued_session.py +0 -53
  62. oagi_core-0.9.2/examples/execute_task_auto.py +0 -42
  63. oagi_core-0.9.2/examples/hotel_booking.py +0 -52
  64. oagi_core-0.9.2/src/oagi/__init__.py +0 -105
  65. oagi_core-0.9.2/src/oagi/cli/agent.py +0 -143
  66. oagi_core-0.9.2/src/oagi/cli/tracking.py +0 -45
  67. oagi_core-0.9.2/src/oagi/types/step_observer.py +0 -34
  68. oagi_core-0.9.2/src/oagi/types/url_image.py +0 -47
  69. oagi_core-0.9.2/tests/test_short_task.py +0 -150
  70. oagi_core-0.9.2/tests/test_url_image.py +0 -41
  71. {oagi_core-0.9.2 → oagi_core-0.10.1}/.github/workflows/ci.yml +0 -0
  72. {oagi_core-0.9.2 → oagi_core-0.10.1}/.github/workflows/release.yml +0 -0
  73. {oagi_core-0.9.2 → oagi_core-0.10.1}/.gitignore +0 -0
  74. {oagi_core-0.9.2 → oagi_core-0.10.1}/.python-version +0 -0
  75. {oagi_core-0.9.2 → oagi_core-0.10.1}/CONTRIBUTING.md +0 -0
  76. {oagi_core-0.9.2 → oagi_core-0.10.1}/LICENSE +0 -0
  77. {oagi_core-0.9.2 → oagi_core-0.10.1}/Makefile +0 -0
  78. {oagi_core-0.9.2 → oagi_core-0.10.1}/examples/async_google_weather.py +0 -0
  79. {oagi_core-0.9.2 → oagi_core-0.10.1}/examples/execute_task_manual.py +0 -0
  80. {oagi_core-0.9.2 → oagi_core-0.10.1}/examples/screenshot_with_config.py +0 -0
  81. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/agent/protocol.py +0 -0
  82. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/cli/__init__.py +0 -0
  83. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/cli/display.py +0 -0
  84. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/cli/main.py +0 -0
  85. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/cli/server.py +0 -0
  86. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/cli/utils.py +0 -0
  87. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/client/__init__.py +0 -0
  88. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/exceptions.py +0 -0
  89. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/handler/__init__.py +0 -0
  90. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/handler/_macos.py +0 -0
  91. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/handler/async_pyautogui_action_handler.py +0 -0
  92. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/handler/async_screenshot_maker.py +0 -0
  93. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/handler/pil_image.py +0 -0
  94. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/handler/screenshot_maker.py +0 -0
  95. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/logging.py +0 -0
  96. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/server/__init__.py +0 -0
  97. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/server/config.py +0 -0
  98. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/server/main.py +0 -0
  99. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/server/socketio_server.py +0 -0
  100. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/task/__init__.py +0 -0
  101. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/types/action_handler.py +0 -0
  102. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/types/async_action_handler.py +0 -0
  103. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/types/image.py +0 -0
  104. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/types/models/__init__.py +0 -0
  105. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/types/models/action.py +0 -0
  106. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/types/models/image_config.py +0 -0
  107. {oagi_core-0.9.2 → oagi_core-0.10.1}/src/oagi/types/models/step.py +0 -0
  108. {oagi_core-0.9.2 → oagi_core-0.10.1}/tests/__init__.py +0 -0
  109. {oagi_core-0.9.2 → oagi_core-0.10.1}/tests/test_async_client.py +0 -0
  110. {oagi_core-0.9.2 → oagi_core-0.10.1}/tests/test_async_handlers.py +0 -0
  111. {oagi_core-0.9.2 → oagi_core-0.10.1}/tests/test_mac_double_click.py +0 -0
  112. {oagi_core-0.9.2 → oagi_core-0.10.1}/tests/test_pil_image.py +0 -0
  113. {oagi_core-0.9.2 → oagi_core-0.10.1}/tests/test_screenshot_maker.py +0 -0
  114. {oagi_core-0.9.2 → oagi_core-0.10.1}/tests/test_server/__init__.py +0 -0
  115. {oagi_core-0.9.2 → oagi_core-0.10.1}/tests/test_server/test_config.py +0 -0
  116. {oagi_core-0.9.2 → oagi_core-0.10.1}/tests/test_server/test_socketio_integration.py +0 -0
  117. {oagi_core-0.9.2 → oagi_core-0.10.1}/tests/test_sync_client.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: oagi-core
3
- Version: 0.9.2
3
+ Version: 0.10.1
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>
@@ -32,6 +32,7 @@ Requires-Dist: rich>=13.0.0
32
32
  Provides-Extra: desktop
33
33
  Requires-Dist: pillow>=11.3.0; extra == 'desktop'
34
34
  Requires-Dist: pyautogui>=0.9.54; extra == 'desktop'
35
+ Requires-Dist: pyobjc-framework-applicationservices>=9.0; (sys_platform == 'darwin') and extra == 'desktop'
35
36
  Requires-Dist: pyobjc-framework-quartz>=9.0; (sys_platform == 'darwin') and extra == 'desktop'
36
37
  Provides-Extra: server
37
38
  Requires-Dist: fastapi[standard]>=0.115.0; extra == 'server'
@@ -73,8 +74,8 @@ pip install oagi-core[server] # Server support
73
74
 
74
75
  Set your API credentials:
75
76
  ```bash
76
- export OAGI_API_KEY="your-api-key"
77
- export OAGI_BASE_URL="https://api.oagi.com" # or your server URL
77
+ export OAGI_API_KEY="your-api-key" # get your API key from https://developer.openagi.org/
78
+ # export OAGI_BASE_URL="https://api.agiopen.org/", # optional, defaults to production endpoint
78
79
  ```
79
80
 
80
81
  ### Automated Task Execution
@@ -82,21 +83,25 @@ export OAGI_BASE_URL="https://api.oagi.com" # or your server URL
82
83
  Run tasks automatically with screenshot capture and action execution:
83
84
 
84
85
  ```python
85
- from oagi import ShortTask, ScreenshotMaker, PyautoguiActionHandler
86
-
87
- task = ShortTask()
88
- completed = task.auto_mode(
89
- "Search weather on Google",
90
- max_steps=10,
91
- executor=PyautoguiActionHandler(), # Executes mouse/keyboard actions
92
- image_provider=ScreenshotMaker(), # Captures screenshots
93
- )
86
+ import asyncio
87
+ from oagi import AsyncDefaultAgent, AsyncPyautoguiActionHandler, AsyncScreenshotMaker
88
+
89
+ async def main():
90
+ agent = AsyncDefaultAgent(max_steps=10)
91
+ completed = await agent.execute(
92
+ "Search weather on Google",
93
+ action_handler=AsyncPyautoguiActionHandler(), # Executes mouse/keyboard actions
94
+ image_provider=AsyncScreenshotMaker(), # Captures screenshots
95
+ )
96
+ return completed
97
+
98
+ asyncio.run(main())
94
99
  ```
95
100
 
96
101
  Configure PyAutoGUI behavior with custom settings:
97
102
 
98
103
  ```python
99
- from oagi import PyautoguiActionHandler, PyautoguiConfig
104
+ from oagi import AsyncPyautoguiActionHandler, PyautoguiConfig
100
105
 
101
106
  # Customize action behavior
102
107
  config = PyautoguiConfig(
@@ -108,8 +113,7 @@ config = PyautoguiConfig(
108
113
  capslock_mode="session" # Caps lock mode: 'session' or 'system' (default: 'session')
109
114
  )
110
115
 
111
- executor = PyautoguiActionHandler(config=config)
112
- task.auto_mode("Complete form", executor=executor, image_provider=ScreenshotMaker())
116
+ action_handler = AsyncPyautoguiActionHandler(config=config)
113
117
  ```
114
118
 
115
119
  ### Image Processing
@@ -130,20 +134,28 @@ config = ImageConfig(
130
134
  compressed = image.transform(config)
131
135
  ```
132
136
 
133
- ### Async Support
137
+ ### Manual Control with Actor
134
138
 
135
- Use async client for non-blocking operations and better concurrency:
139
+ For step-by-step control over task execution:
136
140
 
137
141
  ```python
138
142
  import asyncio
139
- from oagi import AsyncShortTask
143
+ from oagi import AsyncActor, AsyncPyautoguiActionHandler, AsyncScreenshotMaker
140
144
 
141
145
  async def main():
142
- # Async task automation
143
- task = AsyncShortTask()
144
- async with task:
145
- await task.init_task("Complete the form")
146
- # ... continue with async operations
146
+ async with AsyncActor() as actor:
147
+ await actor.init_task("Complete the form")
148
+ image_provider = AsyncScreenshotMaker()
149
+ action_handler = AsyncPyautoguiActionHandler()
150
+
151
+ for _ in range(10):
152
+ image = await image_provider()
153
+ step = await actor.step(image)
154
+
155
+ if step.stop:
156
+ break
157
+
158
+ await action_handler(step.actions)
147
159
 
148
160
  asyncio.run(main())
149
161
  ```
@@ -151,9 +163,10 @@ asyncio.run(main())
151
163
  ## Examples
152
164
 
153
165
  See the [`examples/`](examples/) directory for more usage patterns:
154
- - `google_weather.py` - Basic task execution with `ShortTask`
166
+ - `execute_task_auto.py` - Automated task execution with `AsyncDefaultAgent`
167
+ - `execute_task_manual.py` - Manual step-by-step control with `Actor`
168
+ - `continued_session.py` - Continuing tasks across sessions
155
169
  - `screenshot_with_config.py` - Image compression and optimization
156
- - `execute_task_auto.py` - Automated task execution
157
170
  - `socketio_server_basic.py` - Socket.IO server example
158
171
  - `socketio_client_example.py` - Socket.IO client implementation
159
172
 
@@ -31,8 +31,8 @@ pip install oagi-core[server] # Server support
31
31
 
32
32
  Set your API credentials:
33
33
  ```bash
34
- export OAGI_API_KEY="your-api-key"
35
- export OAGI_BASE_URL="https://api.oagi.com" # or your server URL
34
+ export OAGI_API_KEY="your-api-key" # get your API key from https://developer.openagi.org/
35
+ # export OAGI_BASE_URL="https://api.agiopen.org/", # optional, defaults to production endpoint
36
36
  ```
37
37
 
38
38
  ### Automated Task Execution
@@ -40,21 +40,25 @@ export OAGI_BASE_URL="https://api.oagi.com" # or your server URL
40
40
  Run tasks automatically with screenshot capture and action execution:
41
41
 
42
42
  ```python
43
- from oagi import ShortTask, ScreenshotMaker, PyautoguiActionHandler
44
-
45
- task = ShortTask()
46
- completed = task.auto_mode(
47
- "Search weather on Google",
48
- max_steps=10,
49
- executor=PyautoguiActionHandler(), # Executes mouse/keyboard actions
50
- image_provider=ScreenshotMaker(), # Captures screenshots
51
- )
43
+ import asyncio
44
+ from oagi import AsyncDefaultAgent, AsyncPyautoguiActionHandler, AsyncScreenshotMaker
45
+
46
+ async def main():
47
+ agent = AsyncDefaultAgent(max_steps=10)
48
+ completed = await agent.execute(
49
+ "Search weather on Google",
50
+ action_handler=AsyncPyautoguiActionHandler(), # Executes mouse/keyboard actions
51
+ image_provider=AsyncScreenshotMaker(), # Captures screenshots
52
+ )
53
+ return completed
54
+
55
+ asyncio.run(main())
52
56
  ```
53
57
 
54
58
  Configure PyAutoGUI behavior with custom settings:
55
59
 
56
60
  ```python
57
- from oagi import PyautoguiActionHandler, PyautoguiConfig
61
+ from oagi import AsyncPyautoguiActionHandler, PyautoguiConfig
58
62
 
59
63
  # Customize action behavior
60
64
  config = PyautoguiConfig(
@@ -66,8 +70,7 @@ config = PyautoguiConfig(
66
70
  capslock_mode="session" # Caps lock mode: 'session' or 'system' (default: 'session')
67
71
  )
68
72
 
69
- executor = PyautoguiActionHandler(config=config)
70
- task.auto_mode("Complete form", executor=executor, image_provider=ScreenshotMaker())
73
+ action_handler = AsyncPyautoguiActionHandler(config=config)
71
74
  ```
72
75
 
73
76
  ### Image Processing
@@ -88,20 +91,28 @@ config = ImageConfig(
88
91
  compressed = image.transform(config)
89
92
  ```
90
93
 
91
- ### Async Support
94
+ ### Manual Control with Actor
92
95
 
93
- Use async client for non-blocking operations and better concurrency:
96
+ For step-by-step control over task execution:
94
97
 
95
98
  ```python
96
99
  import asyncio
97
- from oagi import AsyncShortTask
100
+ from oagi import AsyncActor, AsyncPyautoguiActionHandler, AsyncScreenshotMaker
98
101
 
99
102
  async def main():
100
- # Async task automation
101
- task = AsyncShortTask()
102
- async with task:
103
- await task.init_task("Complete the form")
104
- # ... continue with async operations
103
+ async with AsyncActor() as actor:
104
+ await actor.init_task("Complete the form")
105
+ image_provider = AsyncScreenshotMaker()
106
+ action_handler = AsyncPyautoguiActionHandler()
107
+
108
+ for _ in range(10):
109
+ image = await image_provider()
110
+ step = await actor.step(image)
111
+
112
+ if step.stop:
113
+ break
114
+
115
+ await action_handler(step.actions)
105
116
 
106
117
  asyncio.run(main())
107
118
  ```
@@ -109,9 +120,10 @@ asyncio.run(main())
109
120
  ## Examples
110
121
 
111
122
  See the [`examples/`](examples/) directory for more usage patterns:
112
- - `google_weather.py` - Basic task execution with `ShortTask`
123
+ - `execute_task_auto.py` - Automated task execution with `AsyncDefaultAgent`
124
+ - `execute_task_manual.py` - Manual step-by-step control with `Actor`
125
+ - `continued_session.py` - Continuing tasks across sessions
113
126
  - `screenshot_with_config.py` - Image compression and optimization
114
- - `execute_task_auto.py` - Automated task execution
115
127
  - `socketio_server_basic.py` - Socket.IO server example
116
128
  - `socketio_client_example.py` - Socket.IO client implementation
117
129
 
@@ -0,0 +1,37 @@
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
+ import asyncio
9
+
10
+ from oagi import (
11
+ AsyncDefaultAgent,
12
+ AsyncPyautoguiActionHandler,
13
+ AsyncScreenshotMaker,
14
+ )
15
+
16
+
17
+ def execute_task_auto(task_desc, max_steps=5):
18
+ """Synchronous wrapper for async task execution."""
19
+ return asyncio.run(async_execute_task_auto(task_desc, max_steps))
20
+
21
+
22
+ async def async_execute_task_auto(task_desc, max_steps=5):
23
+ # set OAGI_API_KEY and OAGI_BASE_URL
24
+ # or AsyncDefaultAgent(api_key="your_api_key", base_url="your_base_url")
25
+ agent = AsyncDefaultAgent(max_steps=max_steps)
26
+
27
+ # executor = lambda actions: print(actions) for debugging
28
+ action_handler = AsyncPyautoguiActionHandler()
29
+ image_provider = AsyncScreenshotMaker()
30
+
31
+ is_completed = await agent.execute(
32
+ task_desc,
33
+ action_handler=action_handler,
34
+ image_provider=image_provider,
35
+ )
36
+
37
+ return is_completed, await image_provider.last_image()
@@ -9,7 +9,7 @@
9
9
  from examples.execute_task_manual import execute_task_manual
10
10
 
11
11
  is_completed, screenshot = execute_task_manual(
12
- desc := "Search weather with Google", max_steps=5
12
+ desc := "Search weather with Google", max_steps=10
13
13
  )
14
14
 
15
15
  print(f"is_completed: {is_completed}, desc: {desc}")
@@ -0,0 +1,73 @@
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
+ import asyncio
10
+ import os
11
+ import traceback
12
+
13
+ from oagi import (
14
+ AsyncAgentObserver,
15
+ AsyncPyautoguiActionHandler,
16
+ AsyncScreenshotMaker,
17
+ TaskerAgent,
18
+ )
19
+
20
+
21
+ async def main():
22
+ # Create observer for recording execution history
23
+ observer = AsyncAgentObserver()
24
+
25
+ # Initialize the tasker agent
26
+ # Note: Ensure OAGI_API_KEY and OAGI_BASE_URL environment variables are set
27
+ tasker = TaskerAgent(
28
+ api_key=os.getenv("OAGI_API_KEY"),
29
+ base_url=os.getenv("OAGI_BASE_URL", "https://api.agiopen.org"),
30
+ model="lux-actor-1",
31
+ max_steps=30,
32
+ temperature=0.5,
33
+ step_observer=observer,
34
+ )
35
+
36
+ # Define the task with multiple todos
37
+ task_description = "Open a web browser and search for information about Python"
38
+
39
+ # Break down into specific todos
40
+ todos = [
41
+ "Search for 'Python programming language'",
42
+ "Click on the official Python.org website link",
43
+ ]
44
+
45
+ # Set the task
46
+ tasker.set_task(
47
+ task=task_description,
48
+ todos=todos,
49
+ )
50
+
51
+ image_provider = AsyncScreenshotMaker()
52
+ action_handler = AsyncPyautoguiActionHandler()
53
+
54
+ try:
55
+ # Execute the task
56
+ success = await tasker.execute(
57
+ instruction="",
58
+ action_handler=action_handler,
59
+ image_provider=image_provider,
60
+ )
61
+ print(f"Tasker success: {success}")
62
+
63
+ except Exception as e:
64
+ print(f"\nError during execution: {e}")
65
+ traceback.print_exc()
66
+
67
+ observer.export("html", export_file := "export.html")
68
+ print(f"\nExecution history exported: {export_file}")
69
+
70
+
71
+ if __name__ == "__main__":
72
+ # Run the async main function
73
+ asyncio.run(main())
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "oagi"
7
- version = "0.9.2"
7
+ version = "0.10.1"
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.9.2",
19
+ "oagi-core[desktop,server]==0.10.1",
20
20
  ]
21
21
 
22
22
  [project.urls]
@@ -106,7 +106,7 @@ name = "exceptiongroup"
106
106
  version = "1.3.0"
107
107
  source = { registry = "https://pypi.org/simple" }
108
108
  dependencies = [
109
- { name = "typing-extensions", marker = "python_full_version < '3.13'" },
109
+ { name = "typing-extensions", marker = "python_full_version < '3.11'" },
110
110
  ]
111
111
  sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" }
112
112
  wheels = [
@@ -397,33 +397,34 @@ sdist = { url = "https://files.pythonhosted.org/packages/28/fa/b2ba8229b9381e8f6
397
397
 
398
398
  [[package]]
399
399
  name = "oagi"
400
- version = "0.9.2"
400
+ version = "0.10.1"
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.9.1" }]
407
+ requires-dist = [{ name = "oagi-core", extras = ["desktop", "server"], specifier = "==0.10.0" }]
408
408
 
409
409
  [[package]]
410
410
  name = "oagi-core"
411
- version = "0.9.1"
411
+ version = "0.10.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/8c/f5/e7782e86376068d5ce46e746da96dd6692f73aaaa3440cc0b403ff23824c/oagi_core-0.9.1.tar.gz", hash = "sha256:7885e527c4c80121ec946c34f49798948d8df80be6924c79885a219b8ef88330", size = 164972, upload-time = "2025-11-13T17:18:01.912Z" }
418
+ sdist = { url = "https://files.pythonhosted.org/packages/2d/3f/6fa48d2d207051d5f3a8eedf8f7d9cd97f7463746f6578b6655511a4cf47/oagi_core-0.10.0.tar.gz", hash = "sha256:d50c6dac28eb4d395e6910bd24cf412845ffbad25c1be7a2a6a04511691470e9", size = 259893, upload-time = "2025-11-24T04:15:08.503Z" }
419
419
  wheels = [
420
- { url = "https://files.pythonhosted.org/packages/80/5c/a5ba4897bf8522659de7ef379e504c29de1cda4cc0b4fc72a5224a9c00aa/oagi_core-0.9.1-py3-none-any.whl", hash = "sha256:fdb1a880b632911075c7f9ff92493d139ebbc2fd66b4eba6aef7e6798f2c0e3e", size = 74337, upload-time = "2025-11-13T17:18:00.537Z" },
420
+ { url = "https://files.pythonhosted.org/packages/44/9f/582af4d42c1074fe647a3fdbdaddb0bd7b4402ac85e42ea9dcfdf7b52528/oagi_core-0.10.0-py3-none-any.whl", hash = "sha256:f7e19c744586dfb22cfcef0ddc031a457ad4605e6441198cdc6bc4f27bebbb1a", size = 83329, upload-time = "2025-11-24T04:15:07.201Z" },
421
421
  ]
422
422
 
423
423
  [package.optional-dependencies]
424
424
  desktop = [
425
425
  { name = "pillow" },
426
426
  { name = "pyautogui" },
427
+ { name = "pyobjc-framework-quartz", marker = "sys_platform == 'darwin'" },
427
428
  ]
428
429
  server = [
429
430
  { name = "fastapi", extra = ["standard"] },
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "oagi-core"
7
- version = "0.9.2"
7
+ version = "0.10.1"
8
8
  description = "Official API of OpenAGI Foundation"
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
@@ -31,6 +31,7 @@ desktop = [
31
31
  "pillow>=11.3.0",
32
32
  "pyautogui>=0.9.54",
33
33
  "pyobjc-framework-Quartz>=9.0; sys_platform == 'darwin'",
34
+ "pyobjc-framework-ApplicationServices>=9.0; sys_platform == 'darwin'",
34
35
  ]
35
36
  server = [
36
37
  "fastapi[standard]>=0.115.0",
@@ -0,0 +1,148 @@
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
+ import importlib
9
+ from typing import TYPE_CHECKING
10
+
11
+ from oagi.client import AsyncClient, SyncClient
12
+ from oagi.exceptions import (
13
+ APIError,
14
+ AuthenticationError,
15
+ ConfigurationError,
16
+ NetworkError,
17
+ NotFoundError,
18
+ OAGIError,
19
+ RateLimitError,
20
+ RequestTimeoutError,
21
+ ServerError,
22
+ ValidationError,
23
+ check_optional_dependency,
24
+ )
25
+ from oagi.task import Actor, AsyncActor, AsyncShortTask, AsyncTask, ShortTask, Task
26
+ from oagi.types import ImageConfig
27
+ from oagi.types.models import (
28
+ ErrorDetail,
29
+ ErrorResponse,
30
+ GenerateResponse,
31
+ LLMResponse,
32
+ UploadFileResponse,
33
+ )
34
+
35
+ # Lazy imports for optional dependency modules
36
+ # Format: name -> (module_path, package_to_check, extra_name)
37
+ # package_to_check is None if no optional dependency is required
38
+ _LAZY_IMPORTS_DATA: dict[str, tuple[str, str | None, str | None]] = {
39
+ # Desktop handlers (require pyautogui/PIL)
40
+ "AsyncPyautoguiActionHandler": (
41
+ "oagi.handler.async_pyautogui_action_handler",
42
+ "pyautogui",
43
+ "desktop",
44
+ ),
45
+ "AsyncScreenshotMaker": ("oagi.handler.async_screenshot_maker", "PIL", "desktop"),
46
+ "PILImage": ("oagi.handler.pil_image", "PIL", "desktop"),
47
+ "PyautoguiActionHandler": (
48
+ "oagi.handler.pyautogui_action_handler",
49
+ "pyautogui",
50
+ "desktop",
51
+ ),
52
+ "PyautoguiConfig": (
53
+ "oagi.handler.pyautogui_action_handler",
54
+ "pyautogui",
55
+ "desktop",
56
+ ),
57
+ "ScreenshotMaker": ("oagi.handler.screenshot_maker", "PIL", "desktop"),
58
+ # Agent modules (lazy to avoid circular imports)
59
+ "AsyncDefaultAgent": ("oagi.agent.default", None, None),
60
+ "TaskerAgent": ("oagi.agent.tasker", None, None),
61
+ "AsyncAgentObserver": ("oagi.agent.observer.agent_observer", None, None),
62
+ # Server modules (require server dependencies)
63
+ "create_app": ("oagi.server.main", "socketio", "server"),
64
+ "ServerConfig": ("oagi.server.config", "pydantic_settings", "server"),
65
+ "sio": ("oagi.server.socketio_server", "socketio", "server"),
66
+ }
67
+
68
+ if TYPE_CHECKING:
69
+ from oagi.agent.default import AsyncDefaultAgent
70
+ from oagi.agent.observer.agent_observer import AsyncAgentObserver
71
+ from oagi.agent.tasker import TaskerAgent
72
+ from oagi.handler.async_pyautogui_action_handler import AsyncPyautoguiActionHandler
73
+ from oagi.handler.async_screenshot_maker import AsyncScreenshotMaker
74
+ from oagi.handler.pil_image import PILImage
75
+ from oagi.handler.pyautogui_action_handler import (
76
+ PyautoguiActionHandler,
77
+ PyautoguiConfig,
78
+ )
79
+ from oagi.handler.screenshot_maker import ScreenshotMaker
80
+ from oagi.server.config import ServerConfig
81
+ from oagi.server.main import create_app
82
+ from oagi.server.socketio_server import sio
83
+
84
+
85
+ def __getattr__(name: str):
86
+ """Lazy import for optional dependency modules with helpful error messages."""
87
+ if name in _LAZY_IMPORTS_DATA:
88
+ module_path, package, extra = _LAZY_IMPORTS_DATA[name]
89
+ if package is not None:
90
+ check_optional_dependency(package, name, extra)
91
+ module = importlib.import_module(module_path)
92
+ return getattr(module, name)
93
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
94
+
95
+
96
+ def __dir__() -> list[str]:
97
+ """Return all public names including lazy imports."""
98
+ return sorted(set(globals().keys()) | set(_LAZY_IMPORTS_DATA.keys()))
99
+
100
+
101
+ __all__ = [
102
+ # Core sync classes
103
+ "Actor",
104
+ "AsyncActor",
105
+ "Task", # Deprecated: Use Actor instead
106
+ "ShortTask", # Deprecated
107
+ "SyncClient",
108
+ # Core async classes
109
+ "AsyncTask", # Deprecated: Use AsyncActor instead
110
+ "AsyncShortTask", # Deprecated
111
+ "AsyncClient",
112
+ # Agent classes
113
+ "AsyncDefaultAgent",
114
+ "TaskerAgent",
115
+ "AsyncAgentObserver",
116
+ # Configuration
117
+ "ImageConfig",
118
+ # Response models
119
+ "LLMResponse",
120
+ "GenerateResponse",
121
+ "UploadFileResponse",
122
+ "ErrorResponse",
123
+ "ErrorDetail",
124
+ # Exceptions
125
+ "OAGIError",
126
+ "APIError",
127
+ "AuthenticationError",
128
+ "ConfigurationError",
129
+ "NetworkError",
130
+ "NotFoundError",
131
+ "RateLimitError",
132
+ "ServerError",
133
+ "RequestTimeoutError",
134
+ "ValidationError",
135
+ # Lazy imports - Image classes
136
+ "PILImage",
137
+ # Lazy imports - Handler classes
138
+ "PyautoguiActionHandler",
139
+ "PyautoguiConfig",
140
+ "ScreenshotMaker",
141
+ # Lazy imports - Async handler classes
142
+ "AsyncPyautoguiActionHandler",
143
+ "AsyncScreenshotMaker",
144
+ # Lazy imports - Server modules (optional)
145
+ "create_app",
146
+ "ServerConfig",
147
+ "sio",
148
+ ]
@@ -9,6 +9,7 @@
9
9
  # Import factories to trigger registration
10
10
  from . import factories # noqa: F401
11
11
  from .default import AsyncDefaultAgent
12
+ from .observer import AsyncAgentObserver
12
13
  from .protocol import Agent, AsyncAgent
13
14
  from .registry import (
14
15
  async_agent_register,
@@ -21,6 +22,7 @@ from .tasker import TaskeeAgent, TaskerAgent
21
22
  __all__ = [
22
23
  "Agent",
23
24
  "AsyncAgent",
25
+ "AsyncAgentObserver",
24
26
  "AsyncDefaultAgent",
25
27
  "TaskerAgent",
26
28
  "TaskeeAgent",