oagi-core 0.9.0__py3-none-any.whl → 0.9.2__py3-none-any.whl
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/__init__.py +13 -16
- oagi/agent/default.py +26 -10
- oagi/agent/factories.py +5 -0
- oagi/agent/tasker/planner.py +11 -2
- oagi/agent/tasker/taskee_agent.py +45 -20
- oagi/agent/tasker/tasker_agent.py +11 -7
- oagi/cli/agent.py +39 -21
- oagi/cli/display.py +56 -0
- oagi/cli/tracking.py +45 -0
- oagi/cli/utils.py +11 -4
- oagi/client/base.py +3 -7
- oagi/handler/__init__.py +24 -0
- oagi/handler/_macos.py +55 -0
- oagi/{async_pyautogui_action_handler.py → handler/async_pyautogui_action_handler.py} +1 -1
- oagi/{async_screenshot_maker.py → handler/async_screenshot_maker.py} +1 -1
- oagi/{pil_image.py → handler/pil_image.py} +2 -2
- oagi/{pyautogui_action_handler.py → handler/pyautogui_action_handler.py} +14 -4
- oagi/{screenshot_maker.py → handler/screenshot_maker.py} +2 -2
- oagi/logging.py +8 -0
- oagi/server/config.py +3 -3
- oagi/server/models.py +1 -1
- oagi/server/socketio_server.py +1 -1
- oagi/task/__init__.py +10 -3
- oagi/task/async_.py +27 -2
- oagi/task/async_short.py +16 -4
- oagi/task/base.py +2 -0
- oagi/task/short.py +16 -4
- oagi/task/sync.py +27 -2
- oagi/types/__init__.py +2 -0
- oagi/types/step_observer.py +34 -0
- {oagi_core-0.9.0.dist-info → oagi_core-0.9.2.dist-info}/METADATA +4 -29
- oagi_core-0.9.2.dist-info/RECORD +63 -0
- oagi/async_single_step.py +0 -85
- oagi/single_step.py +0 -87
- oagi_core-0.9.0.dist-info/RECORD +0 -60
- {oagi_core-0.9.0.dist-info → oagi_core-0.9.2.dist-info}/WHEEL +0 -0
- {oagi_core-0.9.0.dist-info → oagi_core-0.9.2.dist-info}/entry_points.txt +0 -0
- {oagi_core-0.9.0.dist-info → oagi_core-0.9.2.dist-info}/licenses/LICENSE +0 -0
oagi/handler/__init__.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
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.handler.async_pyautogui_action_handler import AsyncPyautoguiActionHandler
|
|
9
|
+
from oagi.handler.async_screenshot_maker import AsyncScreenshotMaker
|
|
10
|
+
from oagi.handler.pil_image import PILImage
|
|
11
|
+
from oagi.handler.pyautogui_action_handler import (
|
|
12
|
+
PyautoguiActionHandler,
|
|
13
|
+
PyautoguiConfig,
|
|
14
|
+
)
|
|
15
|
+
from oagi.handler.screenshot_maker import ScreenshotMaker
|
|
16
|
+
|
|
17
|
+
__all__ = [
|
|
18
|
+
"PILImage",
|
|
19
|
+
"PyautoguiActionHandler",
|
|
20
|
+
"PyautoguiConfig",
|
|
21
|
+
"AsyncPyautoguiActionHandler",
|
|
22
|
+
"ScreenshotMaker",
|
|
23
|
+
"AsyncScreenshotMaker",
|
|
24
|
+
]
|
oagi/handler/_macos.py
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
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 pyautogui
|
|
10
|
+
|
|
11
|
+
from ..exceptions import check_optional_dependency
|
|
12
|
+
|
|
13
|
+
check_optional_dependency("Quartz", "macOS multiple clicks", "desktop")
|
|
14
|
+
import Quartz # noqa: E402
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def macos_click(x: int, y: int, clicks: int = 1) -> None:
|
|
18
|
+
"""
|
|
19
|
+
Execute a mouse click sequence on macOS with correct click state.
|
|
20
|
+
|
|
21
|
+
This avoids the PyAutoGUI bug where multi-clicks are sent as separate
|
|
22
|
+
single clicks (clickState=1), which macOS interprets as distinct events
|
|
23
|
+
rather than double/triple clicks.
|
|
24
|
+
|
|
25
|
+
Check https://github.com/asweigart/pyautogui/issues/672
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
x: X coordinate
|
|
29
|
+
y: Y coordinate
|
|
30
|
+
clicks: Number of clicks (1=single, 2=double, 3=triple)
|
|
31
|
+
"""
|
|
32
|
+
# Move to position first using pyautogui to ensure consistency
|
|
33
|
+
pyautogui.moveTo(x, y)
|
|
34
|
+
|
|
35
|
+
point = Quartz.CGPoint(x=x, y=y)
|
|
36
|
+
|
|
37
|
+
# Create and post events for each click in the sequence
|
|
38
|
+
for i in range(1, clicks + 1):
|
|
39
|
+
# Create Down/Up events
|
|
40
|
+
mouse_down = Quartz.CGEventCreateMouseEvent(
|
|
41
|
+
None, Quartz.kCGEventLeftMouseDown, point, Quartz.kCGMouseButtonLeft
|
|
42
|
+
)
|
|
43
|
+
mouse_up = Quartz.CGEventCreateMouseEvent(
|
|
44
|
+
None, Quartz.kCGEventLeftMouseUp, point, Quartz.kCGMouseButtonLeft
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
# Set the click state (1 for first click, 2 for second, etc.)
|
|
48
|
+
Quartz.CGEventSetIntegerValueField(
|
|
49
|
+
mouse_down, Quartz.kCGMouseEventClickState, i
|
|
50
|
+
)
|
|
51
|
+
Quartz.CGEventSetIntegerValueField(mouse_up, Quartz.kCGMouseEventClickState, i)
|
|
52
|
+
|
|
53
|
+
# Post events
|
|
54
|
+
Quartz.CGEventPost(Quartz.kCGHIDEventTap, mouse_down)
|
|
55
|
+
Quartz.CGEventPost(Quartz.kCGHIDEventTap, mouse_up)
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
|
|
9
9
|
import io
|
|
10
10
|
|
|
11
|
-
from
|
|
12
|
-
from
|
|
11
|
+
from ..exceptions import check_optional_dependency
|
|
12
|
+
from ..types.models.image_config import ImageConfig
|
|
13
13
|
|
|
14
14
|
check_optional_dependency("PIL", "PILImage", "desktop")
|
|
15
15
|
from PIL import Image as PILImageLib # noqa: E402
|
|
@@ -7,16 +7,20 @@
|
|
|
7
7
|
# -----------------------------------------------------------------------------
|
|
8
8
|
|
|
9
9
|
import re
|
|
10
|
+
import sys
|
|
10
11
|
import time
|
|
11
12
|
|
|
12
13
|
from pydantic import BaseModel, Field
|
|
13
14
|
|
|
14
|
-
from
|
|
15
|
-
from
|
|
15
|
+
from ..exceptions import check_optional_dependency
|
|
16
|
+
from ..types import Action, ActionType
|
|
16
17
|
|
|
17
18
|
check_optional_dependency("pyautogui", "PyautoguiActionHandler", "desktop")
|
|
18
19
|
import pyautogui # noqa: E402
|
|
19
20
|
|
|
21
|
+
if sys.platform == "darwin":
|
|
22
|
+
from . import _macos
|
|
23
|
+
|
|
20
24
|
|
|
21
25
|
class CapsLockManager:
|
|
22
26
|
"""Manages caps lock state for text transformation."""
|
|
@@ -186,11 +190,17 @@ class PyautoguiActionHandler:
|
|
|
186
190
|
|
|
187
191
|
case ActionType.LEFT_DOUBLE:
|
|
188
192
|
x, y = self._parse_coords(arg)
|
|
189
|
-
|
|
193
|
+
if sys.platform == "darwin":
|
|
194
|
+
_macos.macos_click(x, y, clicks=2)
|
|
195
|
+
else:
|
|
196
|
+
pyautogui.doubleClick(x, y)
|
|
190
197
|
|
|
191
198
|
case ActionType.LEFT_TRIPLE:
|
|
192
199
|
x, y = self._parse_coords(arg)
|
|
193
|
-
|
|
200
|
+
if sys.platform == "darwin":
|
|
201
|
+
_macos.macos_click(x, y, clicks=3)
|
|
202
|
+
else:
|
|
203
|
+
pyautogui.tripleClick(x, y)
|
|
194
204
|
|
|
195
205
|
case ActionType.RIGHT_SINGLE:
|
|
196
206
|
x, y = self._parse_coords(arg)
|
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
|
|
9
9
|
from typing import Optional
|
|
10
10
|
|
|
11
|
+
from ..types import Image
|
|
12
|
+
from ..types.models.image_config import ImageConfig
|
|
11
13
|
from .pil_image import PILImage
|
|
12
|
-
from .types import Image
|
|
13
|
-
from .types.models.image_config import ImageConfig
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class ScreenshotMaker:
|
oagi/logging.py
CHANGED
|
@@ -44,4 +44,12 @@ def get_logger(name: str) -> logging.Logger:
|
|
|
44
44
|
# Always update level in case environment variable changed
|
|
45
45
|
oagi_root.setLevel(level)
|
|
46
46
|
|
|
47
|
+
# Suppress verbose httpx logs unless DEBUG level is enabled
|
|
48
|
+
# httpx logs every HTTP request at INFO level by default
|
|
49
|
+
httpx_logger = logging.getLogger("httpx")
|
|
50
|
+
if level == logging.DEBUG:
|
|
51
|
+
httpx_logger.setLevel(logging.DEBUG)
|
|
52
|
+
else:
|
|
53
|
+
httpx_logger.setLevel(logging.WARNING)
|
|
54
|
+
|
|
47
55
|
return logger
|
oagi/server/config.py
CHANGED
|
@@ -28,11 +28,11 @@ class ServerConfig(BaseSettings):
|
|
|
28
28
|
session_timeout_seconds: float = Field(default=10.0)
|
|
29
29
|
|
|
30
30
|
# Model settings
|
|
31
|
-
default_model: str = Field(default="lux-
|
|
32
|
-
default_temperature: float = Field(default=0.
|
|
31
|
+
default_model: str = Field(default="lux-actor-1", alias="OAGI_DEFAULT_MODEL")
|
|
32
|
+
default_temperature: float = Field(default=0.5, ge=0.0, le=2.0)
|
|
33
33
|
|
|
34
34
|
# Agent settings
|
|
35
|
-
max_steps: int = Field(default=
|
|
35
|
+
max_steps: int = Field(default=20, alias="OAGI_MAX_STEPS", ge=1, le=100)
|
|
36
36
|
|
|
37
37
|
# Socket.IO settings
|
|
38
38
|
socketio_path: str = Field(default="/socket.io")
|
oagi/server/models.py
CHANGED
|
@@ -75,7 +75,7 @@ class ScreenshotResponseData(BaseModel):
|
|
|
75
75
|
|
|
76
76
|
# Action acknowledgement
|
|
77
77
|
class ActionAckData(BaseModel):
|
|
78
|
-
|
|
78
|
+
index: int = Field(...)
|
|
79
79
|
success: bool = Field(...)
|
|
80
80
|
error: str | None = Field(None)
|
|
81
81
|
execution_time_ms: int | None = Field(None)
|
oagi/server/socketio_server.py
CHANGED
|
@@ -224,7 +224,7 @@ class SessionNamespace(socketio.AsyncNamespace):
|
|
|
224
224
|
# Emit finish event
|
|
225
225
|
await self.call(
|
|
226
226
|
"finish",
|
|
227
|
-
FinishEventData(
|
|
227
|
+
FinishEventData(index=0, total=1).model_dump(),
|
|
228
228
|
to=session.socket_id,
|
|
229
229
|
timeout=self.config.socketio_timeout,
|
|
230
230
|
)
|
oagi/task/__init__.py
CHANGED
|
@@ -6,9 +6,16 @@
|
|
|
6
6
|
# Licensed under the MIT License.
|
|
7
7
|
# -----------------------------------------------------------------------------
|
|
8
8
|
|
|
9
|
-
from .async_ import AsyncTask
|
|
9
|
+
from .async_ import AsyncActor, AsyncTask
|
|
10
10
|
from .async_short import AsyncShortTask
|
|
11
11
|
from .short import ShortTask
|
|
12
|
-
from .sync import Task
|
|
12
|
+
from .sync import Actor, Task
|
|
13
13
|
|
|
14
|
-
__all__ = [
|
|
14
|
+
__all__ = [
|
|
15
|
+
"Actor",
|
|
16
|
+
"AsyncActor",
|
|
17
|
+
"Task", # Deprecated: Use Actor instead
|
|
18
|
+
"AsyncTask", # Deprecated: Use AsyncActor instead
|
|
19
|
+
"ShortTask", # Deprecated
|
|
20
|
+
"AsyncShortTask", # Deprecated
|
|
21
|
+
]
|
oagi/task/async_.py
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
# Licensed under the MIT License.
|
|
7
7
|
# -----------------------------------------------------------------------------
|
|
8
8
|
|
|
9
|
+
import warnings
|
|
10
|
+
|
|
9
11
|
from ..client import AsyncClient
|
|
10
12
|
from ..logging import get_logger
|
|
11
13
|
from ..types import Image, Step
|
|
@@ -14,14 +16,14 @@ from .base import BaseTask
|
|
|
14
16
|
logger = get_logger("async_task")
|
|
15
17
|
|
|
16
18
|
|
|
17
|
-
class
|
|
19
|
+
class AsyncActor(BaseTask):
|
|
18
20
|
"""Async base class for task automation with the OAGI API."""
|
|
19
21
|
|
|
20
22
|
def __init__(
|
|
21
23
|
self,
|
|
22
24
|
api_key: str | None = None,
|
|
23
25
|
base_url: str | None = None,
|
|
24
|
-
model: str = "
|
|
26
|
+
model: str = "lux-actor-1",
|
|
25
27
|
temperature: float | None = None,
|
|
26
28
|
):
|
|
27
29
|
super().__init__(api_key, base_url, model, temperature)
|
|
@@ -95,3 +97,26 @@ class AsyncTask(BaseTask):
|
|
|
95
97
|
|
|
96
98
|
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
|
97
99
|
await self.close()
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class AsyncTask(AsyncActor):
|
|
103
|
+
"""Deprecated: Use AsyncActor instead.
|
|
104
|
+
|
|
105
|
+
This class is deprecated and will be removed in a future version.
|
|
106
|
+
Please use AsyncActor instead.
|
|
107
|
+
"""
|
|
108
|
+
|
|
109
|
+
def __init__(
|
|
110
|
+
self,
|
|
111
|
+
api_key: str | None = None,
|
|
112
|
+
base_url: str | None = None,
|
|
113
|
+
model: str = "lux-actor-1",
|
|
114
|
+
temperature: float | None = None,
|
|
115
|
+
):
|
|
116
|
+
warnings.warn(
|
|
117
|
+
"AsyncTask is deprecated and will be removed in a future version. "
|
|
118
|
+
"Please use AsyncActor instead.",
|
|
119
|
+
DeprecationWarning,
|
|
120
|
+
stacklevel=2,
|
|
121
|
+
)
|
|
122
|
+
super().__init__(api_key, base_url, model, temperature)
|
oagi/task/async_short.py
CHANGED
|
@@ -6,24 +6,36 @@
|
|
|
6
6
|
# Licensed under the MIT License.
|
|
7
7
|
# -----------------------------------------------------------------------------
|
|
8
8
|
|
|
9
|
+
import warnings
|
|
10
|
+
|
|
9
11
|
from ..logging import get_logger
|
|
10
12
|
from ..types import AsyncActionHandler, AsyncImageProvider
|
|
11
|
-
from .async_ import
|
|
13
|
+
from .async_ import AsyncActor
|
|
12
14
|
from .base import BaseAutoMode
|
|
13
15
|
|
|
14
16
|
logger = get_logger("async_short_task")
|
|
15
17
|
|
|
16
18
|
|
|
17
|
-
class AsyncShortTask(
|
|
18
|
-
"""
|
|
19
|
+
class AsyncShortTask(AsyncActor, BaseAutoMode):
|
|
20
|
+
"""Deprecated: This class is deprecated and will be removed in a future version.
|
|
21
|
+
|
|
22
|
+
Async task implementation with automatic mode for short-duration tasks.
|
|
23
|
+
Please use AsyncActor directly with custom automation logic instead.
|
|
24
|
+
"""
|
|
19
25
|
|
|
20
26
|
def __init__(
|
|
21
27
|
self,
|
|
22
28
|
api_key: str | None = None,
|
|
23
29
|
base_url: str | None = None,
|
|
24
|
-
model: str = "
|
|
30
|
+
model: str = "lux-actor-1",
|
|
25
31
|
temperature: float | None = None,
|
|
26
32
|
):
|
|
33
|
+
warnings.warn(
|
|
34
|
+
"AsyncShortTask is deprecated and will be removed in a future version. "
|
|
35
|
+
"Please use AsyncActor with custom automation logic instead.",
|
|
36
|
+
DeprecationWarning,
|
|
37
|
+
stacklevel=2,
|
|
38
|
+
)
|
|
27
39
|
super().__init__(
|
|
28
40
|
api_key=api_key, base_url=base_url, model=model, temperature=temperature
|
|
29
41
|
)
|
oagi/task/base.py
CHANGED
|
@@ -45,7 +45,9 @@ class BaseTask:
|
|
|
45
45
|
task_desc: Task description
|
|
46
46
|
max_steps: Maximum number of steps
|
|
47
47
|
"""
|
|
48
|
+
self.task_id = uuid4().hex
|
|
48
49
|
self.task_description = task_desc
|
|
50
|
+
self.message_history = []
|
|
49
51
|
logger.info(f"Task initialized: '{task_desc}' (max_steps: {max_steps})")
|
|
50
52
|
|
|
51
53
|
def _validate_step_preconditions(self):
|
oagi/task/short.py
CHANGED
|
@@ -6,24 +6,36 @@
|
|
|
6
6
|
# Licensed under the MIT License.
|
|
7
7
|
# -----------------------------------------------------------------------------
|
|
8
8
|
|
|
9
|
+
import warnings
|
|
10
|
+
|
|
9
11
|
from ..logging import get_logger
|
|
10
12
|
from ..types import ActionHandler, ImageProvider
|
|
11
13
|
from .base import BaseAutoMode
|
|
12
|
-
from .sync import
|
|
14
|
+
from .sync import Actor
|
|
13
15
|
|
|
14
16
|
logger = get_logger("short_task")
|
|
15
17
|
|
|
16
18
|
|
|
17
|
-
class ShortTask(
|
|
18
|
-
"""
|
|
19
|
+
class ShortTask(Actor, BaseAutoMode):
|
|
20
|
+
"""Deprecated: This class is deprecated and will be removed in a future version.
|
|
21
|
+
|
|
22
|
+
Task implementation with automatic mode for short-duration tasks.
|
|
23
|
+
Please use Actor directly with custom automation logic instead.
|
|
24
|
+
"""
|
|
19
25
|
|
|
20
26
|
def __init__(
|
|
21
27
|
self,
|
|
22
28
|
api_key: str | None = None,
|
|
23
29
|
base_url: str | None = None,
|
|
24
|
-
model: str = "
|
|
30
|
+
model: str = "lux-actor-1",
|
|
25
31
|
temperature: float | None = None,
|
|
26
32
|
):
|
|
33
|
+
warnings.warn(
|
|
34
|
+
"ShortTask is deprecated and will be removed in a future version. "
|
|
35
|
+
"Please use Actor with custom automation logic instead.",
|
|
36
|
+
DeprecationWarning,
|
|
37
|
+
stacklevel=2,
|
|
38
|
+
)
|
|
27
39
|
super().__init__(
|
|
28
40
|
api_key=api_key, base_url=base_url, model=model, temperature=temperature
|
|
29
41
|
)
|
oagi/task/sync.py
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
# Licensed under the MIT License.
|
|
7
7
|
# -----------------------------------------------------------------------------
|
|
8
8
|
|
|
9
|
+
import warnings
|
|
10
|
+
|
|
9
11
|
from ..client import SyncClient
|
|
10
12
|
from ..logging import get_logger
|
|
11
13
|
from ..types import Image, Step
|
|
@@ -14,14 +16,14 @@ from .base import BaseTask
|
|
|
14
16
|
logger = get_logger("task")
|
|
15
17
|
|
|
16
18
|
|
|
17
|
-
class
|
|
19
|
+
class Actor(BaseTask):
|
|
18
20
|
"""Base class for task automation with the OAGI API."""
|
|
19
21
|
|
|
20
22
|
def __init__(
|
|
21
23
|
self,
|
|
22
24
|
api_key: str | None = None,
|
|
23
25
|
base_url: str | None = None,
|
|
24
|
-
model: str = "
|
|
26
|
+
model: str = "lux-actor-1",
|
|
25
27
|
temperature: float | None = None,
|
|
26
28
|
):
|
|
27
29
|
super().__init__(api_key, base_url, model, temperature)
|
|
@@ -95,3 +97,26 @@ class Task(BaseTask):
|
|
|
95
97
|
|
|
96
98
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
97
99
|
self.close()
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class Task(Actor):
|
|
103
|
+
"""Deprecated: Use Actor instead.
|
|
104
|
+
|
|
105
|
+
This class is deprecated and will be removed in a future version.
|
|
106
|
+
Please use Actor instead.
|
|
107
|
+
"""
|
|
108
|
+
|
|
109
|
+
def __init__(
|
|
110
|
+
self,
|
|
111
|
+
api_key: str | None = None,
|
|
112
|
+
base_url: str | None = None,
|
|
113
|
+
model: str = "lux-actor-1",
|
|
114
|
+
temperature: float | None = None,
|
|
115
|
+
):
|
|
116
|
+
warnings.warn(
|
|
117
|
+
"Task is deprecated and will be removed in a future version. "
|
|
118
|
+
"Please use Actor instead.",
|
|
119
|
+
DeprecationWarning,
|
|
120
|
+
stacklevel=2,
|
|
121
|
+
)
|
|
122
|
+
super().__init__(api_key, base_url, model, temperature)
|
oagi/types/__init__.py
CHANGED
|
@@ -12,6 +12,7 @@ from .async_image_provider import AsyncImageProvider
|
|
|
12
12
|
from .image import Image
|
|
13
13
|
from .image_provider import ImageProvider
|
|
14
14
|
from .models import Action, ActionType, ImageConfig, Step
|
|
15
|
+
from .step_observer import AsyncStepObserver
|
|
15
16
|
from .url_image import URLImage
|
|
16
17
|
|
|
17
18
|
__all__ = [
|
|
@@ -24,5 +25,6 @@ __all__ = [
|
|
|
24
25
|
"AsyncActionHandler",
|
|
25
26
|
"ImageProvider",
|
|
26
27
|
"AsyncImageProvider",
|
|
28
|
+
"AsyncStepObserver",
|
|
27
29
|
"URLImage",
|
|
28
30
|
]
|
|
@@ -0,0 +1,34 @@
|
|
|
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
|
+
from typing import Protocol
|
|
10
|
+
|
|
11
|
+
from .models import Action
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class AsyncStepObserver(Protocol):
|
|
15
|
+
"""Protocol for observing agent step execution.
|
|
16
|
+
|
|
17
|
+
Observers receive step information (reasoning and actions) as agents
|
|
18
|
+
execute tasks, enabling tracking, logging, or other side effects.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
async def on_step(
|
|
22
|
+
self,
|
|
23
|
+
step_num: int,
|
|
24
|
+
reasoning: str | None,
|
|
25
|
+
actions: list[Action],
|
|
26
|
+
) -> None:
|
|
27
|
+
"""Called when an agent executes a step.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
step_num: The step number (1-indexed)
|
|
31
|
+
reasoning: The reasoning/thinking for this step (if available)
|
|
32
|
+
actions: The list of actions being executed in this step
|
|
33
|
+
"""
|
|
34
|
+
...
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: oagi-core
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.2
|
|
4
4
|
Summary: Official API of OpenAGI Foundation
|
|
5
5
|
Project-URL: Homepage, https://github.com/agiopen-org/oagi
|
|
6
6
|
Author-email: OpenAGI Foundation <contact@agiopen.org>
|
|
@@ -28,9 +28,11 @@ License: MIT License
|
|
|
28
28
|
Requires-Python: >=3.10
|
|
29
29
|
Requires-Dist: httpx>=0.28.0
|
|
30
30
|
Requires-Dist: pydantic>=2.0.0
|
|
31
|
+
Requires-Dist: rich>=13.0.0
|
|
31
32
|
Provides-Extra: desktop
|
|
32
33
|
Requires-Dist: pillow>=11.3.0; extra == 'desktop'
|
|
33
34
|
Requires-Dist: pyautogui>=0.9.54; extra == 'desktop'
|
|
35
|
+
Requires-Dist: pyobjc-framework-quartz>=9.0; (sys_platform == 'darwin') and extra == 'desktop'
|
|
34
36
|
Provides-Extra: server
|
|
35
37
|
Requires-Dist: fastapi[standard]>=0.115.0; extra == 'server'
|
|
36
38
|
Requires-Dist: pydantic-settings>=2.0.0; extra == 'server'
|
|
@@ -75,22 +77,6 @@ export OAGI_API_KEY="your-api-key"
|
|
|
75
77
|
export OAGI_BASE_URL="https://api.oagi.com" # or your server URL
|
|
76
78
|
```
|
|
77
79
|
|
|
78
|
-
### Single-Step Analysis
|
|
79
|
-
|
|
80
|
-
Analyze a screenshot and get recommended actions:
|
|
81
|
-
|
|
82
|
-
```python
|
|
83
|
-
from oagi import single_step
|
|
84
|
-
|
|
85
|
-
step = single_step(
|
|
86
|
-
task_description="Click the submit button",
|
|
87
|
-
screenshot="screenshot.png" # or bytes, or Image object
|
|
88
|
-
)
|
|
89
|
-
|
|
90
|
-
print(f"Actions: {step.actions}")
|
|
91
|
-
print(f"Complete: {step.is_complete}")
|
|
92
|
-
```
|
|
93
|
-
|
|
94
80
|
### Automated Task Execution
|
|
95
81
|
|
|
96
82
|
Run tasks automatically with screenshot capture and action execution:
|
|
@@ -142,9 +128,6 @@ config = ImageConfig(
|
|
|
142
128
|
height=700
|
|
143
129
|
)
|
|
144
130
|
compressed = image.transform(config)
|
|
145
|
-
|
|
146
|
-
# Use with single_step
|
|
147
|
-
step = single_step("Click button", screenshot=compressed)
|
|
148
131
|
```
|
|
149
132
|
|
|
150
133
|
### Async Support
|
|
@@ -153,16 +136,9 @@ Use async client for non-blocking operations and better concurrency:
|
|
|
153
136
|
|
|
154
137
|
```python
|
|
155
138
|
import asyncio
|
|
156
|
-
from oagi import
|
|
139
|
+
from oagi import AsyncShortTask
|
|
157
140
|
|
|
158
141
|
async def main():
|
|
159
|
-
# Single-step async analysis
|
|
160
|
-
step = await async_single_step(
|
|
161
|
-
"Find the search bar",
|
|
162
|
-
screenshot="screenshot.png"
|
|
163
|
-
)
|
|
164
|
-
print(f"Found {len(step.actions)} actions")
|
|
165
|
-
|
|
166
142
|
# Async task automation
|
|
167
143
|
task = AsyncShortTask()
|
|
168
144
|
async with task:
|
|
@@ -176,7 +152,6 @@ asyncio.run(main())
|
|
|
176
152
|
|
|
177
153
|
See the [`examples/`](examples/) directory for more usage patterns:
|
|
178
154
|
- `google_weather.py` - Basic task execution with `ShortTask`
|
|
179
|
-
- `single_step.py` - Basic single-step inference
|
|
180
155
|
- `screenshot_with_config.py` - Image compression and optimization
|
|
181
156
|
- `execute_task_auto.py` - Automated task execution
|
|
182
157
|
- `socketio_server_basic.py` - Socket.IO server example
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
oagi/__init__.py,sha256=cSqJ61OyscGJLHBCn53cS4PrCKC4DQl5xRDNkGR0TXo,3041
|
|
2
|
+
oagi/exceptions.py,sha256=Rco37GQTPYUfc2vRO3hozxPF_s8mKFDpFvBg2UKWo3Y,3066
|
|
3
|
+
oagi/logging.py,sha256=YT3KCMFj5fzO98R9xlDDgfSotUuz1xRD6OZeYM2rKoo,1760
|
|
4
|
+
oagi/agent/__init__.py,sha256=JU9zuWuDzpzitsVJB4z5ddvx8RMm5nbP-bjUCL1Sfvo,834
|
|
5
|
+
oagi/agent/default.py,sha256=0rnv-ZY5Gs4o25B6eVb1BFrOKWgNFo0TobLicNDkiHM,3095
|
|
6
|
+
oagi/agent/factories.py,sha256=eE0hcXyJX4dk2nvRRlEvQPJqkBraeIaT7nXiED2lH_Q,1605
|
|
7
|
+
oagi/agent/protocol.py,sha256=IQJGiMN4yZIacrh5e9JQsoM9TyHb8wJRQR4LAk8dSA0,1615
|
|
8
|
+
oagi/agent/registry.py,sha256=4oG65E_bV47Xl6F-HX9KaVoV0pcoC1uRRDU4RT_m3uU,4841
|
|
9
|
+
oagi/agent/tasker/__init__.py,sha256=faOC5ONY8ZKr4CjofC6HYg1WKWc1UiaGB9VHy8W280M,800
|
|
10
|
+
oagi/agent/tasker/memory.py,sha256=JsJjUMpnJoKW4VFzd8FI4M-FhnEihTecL61KVgO_YBI,6051
|
|
11
|
+
oagi/agent/tasker/models.py,sha256=VzvHB5hLv6qyYcyNiojVIEDlTzeGE4Quswk4EVIbzoI,2180
|
|
12
|
+
oagi/agent/tasker/planner.py,sha256=PGBSMMpADSSWCcGnCPYm1TbxDgcqXLC_IKMzhQIGYn4,13972
|
|
13
|
+
oagi/agent/tasker/taskee_agent.py,sha256=LzjsD0NQlGiKoHZGirmcJNHV46kmWK-njoup-YVgzwQ,14111
|
|
14
|
+
oagi/agent/tasker/tasker_agent.py,sha256=jxXAopGEUQu7OB4jU8PDTMOBxwnRbOSEmBTLURK7X7M,10992
|
|
15
|
+
oagi/cli/__init__.py,sha256=aDnJViTseShpo5fdGPTj-ELysZhmdvB6Z8mEj2D-_N4,359
|
|
16
|
+
oagi/cli/agent.py,sha256=UdAhKeXTQTC3TIfrugUblTnQ7vZ9e069EAFJlJvt1PE,4477
|
|
17
|
+
oagi/cli/display.py,sha256=rkAxuHa40ZtKdmvwARev1rgyfsNyVvQ-J6RdjOZIPwc,1729
|
|
18
|
+
oagi/cli/main.py,sha256=faHns0HaQCGyylDn2YZLpjQESuEiMYjoQVoMkt8FsH4,2292
|
|
19
|
+
oagi/cli/server.py,sha256=Z1ic8r55yaeQBFRCsMNZStC1jRiJdnDGqe9On9LmFzQ,3031
|
|
20
|
+
oagi/cli/tracking.py,sha256=jPH6QDUUwnfZ8bjQU6deofBmBflTEOOCINwinQJz9OI,1147
|
|
21
|
+
oagi/cli/utils.py,sha256=BI6C7WvC51NBsXEsjDONjSNwqdD4i0nHA_rsfpyLwmA,2986
|
|
22
|
+
oagi/client/__init__.py,sha256=F9DShPUdb6vZYmN1fpM1VYzp4MWqUao_e_R1KYmM4Q4,410
|
|
23
|
+
oagi/client/async_.py,sha256=t-GPHcz6xbHx_RPFv1V_hwZ1_f-O9ONH-Ahr0w-Nz8M,11046
|
|
24
|
+
oagi/client/base.py,sha256=4ZfhouEyIcldStJG5ipxpxpD6iVRGrMUZruQX0WKiXE,16934
|
|
25
|
+
oagi/client/sync.py,sha256=QKd6nTUXtyn1Am8YlFcpsoLh1KuHhQgbMemIkb7r39g,10882
|
|
26
|
+
oagi/handler/__init__.py,sha256=Ha11L42K33K3L9S4lQ10UC0DnD5g6egtQUsJpS_tKgg,835
|
|
27
|
+
oagi/handler/_macos.py,sha256=aHkp-xGzvWL_SBjuS690i9jf93OITFJfGHzHeYCK65I,1957
|
|
28
|
+
oagi/handler/async_pyautogui_action_handler.py,sha256=hQzseR1yBD0QMpgsEVNsUmuApGVAIIyGYD06BXd82Dc,1615
|
|
29
|
+
oagi/handler/async_screenshot_maker.py,sha256=8QCtUV59ozpOpvkqhUMb8QDI2qje2gsoFT1qB60tfJM,1689
|
|
30
|
+
oagi/handler/pil_image.py,sha256=yUcAoGBL-aZ0PCjSaAmQsDwtyzjldXHqXQp_OYRk6e4,4080
|
|
31
|
+
oagi/handler/pyautogui_action_handler.py,sha256=8jXF7Muc68JVjJY-cGUQN58WO44bCwI6AIc0mkEV5Nw,10272
|
|
32
|
+
oagi/handler/screenshot_maker.py,sha256=j1jTW-awx3vAnb1N5_FIMBC0Z-rNVQbiBP-S6Gh5dlE,1284
|
|
33
|
+
oagi/server/__init__.py,sha256=uZx8u3vJUb87kkNzwmmVrgAgbqRu0WxyMIQCLSx56kk,452
|
|
34
|
+
oagi/server/agent_wrappers.py,sha256=4f6ZKvqy9TDA57QRHGjAQVhpHmPE5QNeewmmURg5Ajo,3288
|
|
35
|
+
oagi/server/config.py,sha256=2gJ-pDpYAxNUubwSsGKOieGcOtNX9b5YGuSqtf6g2P0,1607
|
|
36
|
+
oagi/server/main.py,sha256=jnTxk7Prc5CzlsUnkBNJp4MOoYN-7HN_Be_m1d3COa8,4829
|
|
37
|
+
oagi/server/models.py,sha256=m04q03thCPMCrY1Urgc3t6yAvuy8XK4jQBa3Z-3iWWg,2588
|
|
38
|
+
oagi/server/session_store.py,sha256=UI14NiApAwvZWmMOG4SvPE2WkbGkNTHToZhTXQjN2_U,3624
|
|
39
|
+
oagi/server/socketio_server.py,sha256=NFw5Zu7yCFLW-gOu9OX8k6mNFaCN2jtX1Tob_9w5YM0,14344
|
|
40
|
+
oagi/task/__init__.py,sha256=g_8_7ZLDLKuCGzyrB42OzY3gSOjd_SxzkJW3_pf-PXs,662
|
|
41
|
+
oagi/task/async_.py,sha256=u1vJKkyRzxmnwbMxj0GekLkH6cRCKDZQAy_5myjBUb8,3916
|
|
42
|
+
oagi/task/async_short.py,sha256=tyJb0onY5FASMvhsK175vJUZrsp2T6Ow_60I-gBLTmA,2751
|
|
43
|
+
oagi/task/base.py,sha256=Udp_Yl5GVUWR7RtayrQlwa8Yg_Nrsyal3mGEkaG8FmE,4447
|
|
44
|
+
oagi/task/short.py,sha256=b8cNpZvm5zSEwYE0dZX8uuRLLBmq6yKTTmjUGcXsbFM,2560
|
|
45
|
+
oagi/task/sync.py,sha256=Qm4eXmOEo6fDjMWPW8sona6b1QJxGOWU104cQqk2rvo,3779
|
|
46
|
+
oagi/types/__init__.py,sha256=Vz6JArE8XvBWlES8CVLy-Nx97gooh1OSsltBL6iaFiM,884
|
|
47
|
+
oagi/types/action_handler.py,sha256=NH8E-m5qpGqWcXzTSWfF7W0Xdp8SkzJsbhCmQ0B96cg,1075
|
|
48
|
+
oagi/types/async_action_handler.py,sha256=k1AaqSkFcXlxwW8sn-w0WFHGsIqHFLbcOPrkknmSVug,1116
|
|
49
|
+
oagi/types/async_image_provider.py,sha256=wnhRyPtTmuALt45Qore74-RCkP5yxU9sZGjvOzFqzOk,1170
|
|
50
|
+
oagi/types/image.py,sha256=KgPCCTJ6D5vHIaGZdbTE7eQEa1WlT6G9tf59ZuUCV2U,537
|
|
51
|
+
oagi/types/image_provider.py,sha256=oYFdOYznrK_VOR9egzOjw5wFM5w8EY2sY01pH0ANAgU,1112
|
|
52
|
+
oagi/types/step_observer.py,sha256=KDw7yQxA_I6T2DqElspAOMa8rBJTYFWBNHfC-9NmasM,1025
|
|
53
|
+
oagi/types/url_image.py,sha256=iOwtXj2uwY6dVtDP7uvQLPvK-aTxkdrzhw_R4C6GwBw,1334
|
|
54
|
+
oagi/types/models/__init__.py,sha256=I86Z2moM8hCog_1K1FG_uATcBmWFv_UFetLAjzPzWAY,742
|
|
55
|
+
oagi/types/models/action.py,sha256=hh6mRRSSWgrW4jpZo71zGMCOcZpV5_COu4148uG6G48,967
|
|
56
|
+
oagi/types/models/client.py,sha256=fCN18DBq5XDjNyYB8w-2dFeQ_K9ywwdyh-rXa0GToU4,1357
|
|
57
|
+
oagi/types/models/image_config.py,sha256=tl6abVg_-IAPLwpaWprgknXu7wRWriMg-AEVyUX73v0,1567
|
|
58
|
+
oagi/types/models/step.py,sha256=RSI4H_2rrUBq_xyCoWKaq7JHdJWNobtQppaKC1l0aWU,471
|
|
59
|
+
oagi_core-0.9.2.dist-info/METADATA,sha256=aOVV3474s0JOmFZ2hGbVvqnBTH1UdK0vLTE2HRnUWS4,7638
|
|
60
|
+
oagi_core-0.9.2.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
|
|
61
|
+
oagi_core-0.9.2.dist-info/entry_points.txt,sha256=zzgsOSWX6aN3KUB0Z1it8DMxFFBJBqmZVqMVAJRjYuw,44
|
|
62
|
+
oagi_core-0.9.2.dist-info/licenses/LICENSE,sha256=sy5DLA2M29jFT4UfWsuBF9BAr3FnRkYtnAu6oDZiIf8,1075
|
|
63
|
+
oagi_core-0.9.2.dist-info/RECORD,,
|