oagi-core 0.10.2__tar.gz → 0.10.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {oagi_core-0.10.2 → oagi_core-0.10.3}/PKG-INFO +1 -1
- {oagi_core-0.10.2 → oagi_core-0.10.3}/examples/tasker_agent_example.py +1 -1
- {oagi_core-0.10.2 → oagi_core-0.10.3}/metapackage/pyproject.toml +2 -2
- {oagi_core-0.10.2 → oagi_core-0.10.3}/metapackage/uv.lock +5 -5
- {oagi_core-0.10.2 → oagi_core-0.10.3}/pyproject.toml +1 -1
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/agent/default.py +10 -4
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/agent/factories.py +23 -13
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/agent/tasker/planner.py +2 -1
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/agent/tasker/taskee_agent.py +12 -5
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/agent/tasker/tasker_agent.py +12 -5
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/cli/agent.py +28 -13
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/cli/display.py +2 -1
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/cli/server.py +1 -1
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/cli/utils.py +4 -3
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/client/async_.py +19 -6
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/client/base.py +14 -16
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/client/sync.py +19 -6
- oagi_core-0.10.3/src/oagi/constants.py +43 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/handler/pyautogui_action_handler.py +2 -1
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/server/config.py +6 -3
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/server/models.py +5 -3
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/server/session_store.py +6 -4
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/server/socketio_server.py +2 -1
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/task/async_.py +4 -3
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/task/async_short.py +3 -2
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/task/base.py +2 -1
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/task/short.py +3 -2
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/task/sync.py +4 -3
- {oagi_core-0.10.2 → oagi_core-0.10.3}/tests/conftest.py +4 -3
- {oagi_core-0.10.2 → oagi_core-0.10.3}/tests/test_actor.py +6 -5
- {oagi_core-0.10.2 → oagi_core-0.10.3}/tests/test_agent_registry.py +12 -11
- {oagi_core-0.10.2 → oagi_core-0.10.3}/tests/test_async_client.py +25 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/tests/test_cli.py +2 -1
- {oagi_core-0.10.2 → oagi_core-0.10.3}/tests/test_server/test_session_store.py +7 -6
- {oagi_core-0.10.2 → oagi_core-0.10.3}/tests/test_sync_client.py +24 -2
- {oagi_core-0.10.2 → oagi_core-0.10.3}/tests/test_taskee_agent.py +2 -1
- {oagi_core-0.10.2 → oagi_core-0.10.3}/uv.lock +1 -1
- {oagi_core-0.10.2 → oagi_core-0.10.3}/.github/workflows/ci.yml +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/.github/workflows/release.yml +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/.gitignore +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/.python-version +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/CONTRIBUTING.md +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/LICENSE +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/Makefile +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/README.md +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/examples/async_google_weather.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/examples/execute_task_auto.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/examples/execute_task_manual.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/examples/google_weather.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/examples/screenshot_with_config.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/__init__.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/agent/__init__.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/agent/observer/__init__.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/agent/observer/agent_observer.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/agent/observer/events.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/agent/observer/exporters.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/agent/observer/protocol.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/agent/observer/report_template.html +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/agent/protocol.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/agent/registry.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/agent/tasker/__init__.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/agent/tasker/memory.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/agent/tasker/models.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/cli/__init__.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/cli/main.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/cli/tracking.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/client/__init__.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/exceptions.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/handler/__init__.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/handler/_macos.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/handler/async_pyautogui_action_handler.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/handler/async_screenshot_maker.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/handler/pil_image.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/handler/screenshot_maker.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/logging.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/server/__init__.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/server/agent_wrappers.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/server/main.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/task/__init__.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/types/__init__.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/types/action_handler.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/types/async_action_handler.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/types/async_image_provider.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/types/image.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/types/image_provider.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/types/models/__init__.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/types/models/action.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/types/models/client.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/types/models/image_config.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/types/models/step.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/types/step_observer.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/src/oagi/types/url.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/tests/__init__.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/tests/test_action_parsing.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/tests/test_agent/test_agent_wrappers.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/tests/test_agent/test_default_agent.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/tests/test_async_actor.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/tests/test_async_handlers.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/tests/test_logging.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/tests/test_mac_double_click.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/tests/test_observer.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/tests/test_pil_image.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/tests/test_planner.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/tests/test_planner_memory.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/tests/test_pyautogui_action_handler.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/tests/test_screenshot_maker.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/tests/test_server/__init__.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/tests/test_server/test_config.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/tests/test_server/test_socketio_integration.py +0 -0
- {oagi_core-0.10.2 → oagi_core-0.10.3}/tests/test_tasker_agent.py +0 -0
|
@@ -27,7 +27,7 @@ async def main():
|
|
|
27
27
|
tasker = TaskerAgent(
|
|
28
28
|
api_key=os.getenv("OAGI_API_KEY"),
|
|
29
29
|
base_url=os.getenv("OAGI_BASE_URL", "https://api.agiopen.org"),
|
|
30
|
-
model="
|
|
30
|
+
model="lux-actor-1",
|
|
31
31
|
max_steps=30,
|
|
32
32
|
temperature=0.5,
|
|
33
33
|
step_observer=observer,
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "oagi"
|
|
7
|
-
version = "0.10.
|
|
7
|
+
version = "0.10.3"
|
|
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.10.
|
|
19
|
+
"oagi-core[desktop,server]==0.10.3",
|
|
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.10.
|
|
400
|
+
version = "0.10.3"
|
|
401
401
|
source = { editable = "." }
|
|
402
402
|
dependencies = [
|
|
403
403
|
{ name = "oagi-core", extra = ["desktop", "server"] },
|
|
404
404
|
]
|
|
405
405
|
|
|
406
406
|
[package.metadata]
|
|
407
|
-
requires-dist = [{ name = "oagi-core", extras = ["desktop", "server"], specifier = "==0.10.
|
|
407
|
+
requires-dist = [{ name = "oagi-core", extras = ["desktop", "server"], specifier = "==0.10.2" }]
|
|
408
408
|
|
|
409
409
|
[[package]]
|
|
410
410
|
name = "oagi-core"
|
|
411
|
-
version = "0.10.
|
|
411
|
+
version = "0.10.2"
|
|
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/07/2f/11b7e37049b2faa1e1147a75624c024a93c32287f243c213ca96fc096452/oagi_core-0.10.2.tar.gz", hash = "sha256:2d7fb47031cdc2155ea5ea9c06b4b58c0d70091de95a36fa4dedf5d710a09862", size = 267130, upload-time = "2025-11-26T13:50:36.977Z" }
|
|
419
419
|
wheels = [
|
|
420
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
420
|
+
{ url = "https://files.pythonhosted.org/packages/d0/c8/a1d95327afe6237eaf474d74ba66461e51baaf5948d458cb12be62dbf8a8/oagi_core-0.10.2-py3-none-any.whl", hash = "sha256:3b9dd3ade24a1c605d671ed7f35efcd00f729be603a63173c7f92f8177d56750", size = 87220, upload-time = "2025-11-26T13:50:35.872Z" },
|
|
421
421
|
]
|
|
422
422
|
|
|
423
423
|
[package.optional-dependencies]
|
|
@@ -10,6 +10,12 @@ import asyncio
|
|
|
10
10
|
import logging
|
|
11
11
|
|
|
12
12
|
from .. import AsyncActor
|
|
13
|
+
from ..constants import (
|
|
14
|
+
DEFAULT_MAX_STEPS,
|
|
15
|
+
DEFAULT_STEP_DELAY,
|
|
16
|
+
DEFAULT_TEMPERATURE,
|
|
17
|
+
MODEL_ACTOR,
|
|
18
|
+
)
|
|
13
19
|
from ..types import (
|
|
14
20
|
ActionEvent,
|
|
15
21
|
AsyncActionHandler,
|
|
@@ -36,11 +42,11 @@ class AsyncDefaultAgent:
|
|
|
36
42
|
self,
|
|
37
43
|
api_key: str | None = None,
|
|
38
44
|
base_url: str | None = None,
|
|
39
|
-
model: str =
|
|
40
|
-
max_steps: int =
|
|
41
|
-
temperature: float | None =
|
|
45
|
+
model: str = MODEL_ACTOR,
|
|
46
|
+
max_steps: int = DEFAULT_MAX_STEPS,
|
|
47
|
+
temperature: float | None = DEFAULT_TEMPERATURE,
|
|
42
48
|
step_observer: AsyncObserver | None = None,
|
|
43
|
-
step_delay: float =
|
|
49
|
+
step_delay: float = DEFAULT_STEP_DELAY,
|
|
44
50
|
):
|
|
45
51
|
self.api_key = api_key
|
|
46
52
|
self.base_url = base_url
|
|
@@ -6,6 +6,16 @@
|
|
|
6
6
|
# Licensed under the MIT License.
|
|
7
7
|
# -----------------------------------------------------------------------------
|
|
8
8
|
from oagi.agent.tasker import TaskerAgent
|
|
9
|
+
from oagi.constants import (
|
|
10
|
+
DEFAULT_MAX_STEPS,
|
|
11
|
+
DEFAULT_MAX_STEPS_TASKER,
|
|
12
|
+
DEFAULT_MAX_STEPS_THINKER,
|
|
13
|
+
DEFAULT_REFLECTION_INTERVAL_TASKER,
|
|
14
|
+
DEFAULT_STEP_DELAY,
|
|
15
|
+
DEFAULT_TEMPERATURE_LOW,
|
|
16
|
+
MODEL_ACTOR,
|
|
17
|
+
MODEL_THINKER,
|
|
18
|
+
)
|
|
9
19
|
from oagi.types import AsyncStepObserver
|
|
10
20
|
|
|
11
21
|
from .default import AsyncDefaultAgent
|
|
@@ -17,11 +27,11 @@ from .registry import async_agent_register
|
|
|
17
27
|
def create_default_agent(
|
|
18
28
|
api_key: str | None = None,
|
|
19
29
|
base_url: str | None = None,
|
|
20
|
-
model: str =
|
|
21
|
-
max_steps: int =
|
|
22
|
-
temperature: float =
|
|
30
|
+
model: str = MODEL_ACTOR,
|
|
31
|
+
max_steps: int = DEFAULT_MAX_STEPS,
|
|
32
|
+
temperature: float = DEFAULT_TEMPERATURE_LOW,
|
|
23
33
|
step_observer: AsyncStepObserver | None = None,
|
|
24
|
-
step_delay: float =
|
|
34
|
+
step_delay: float = DEFAULT_STEP_DELAY,
|
|
25
35
|
) -> AsyncAgent:
|
|
26
36
|
return AsyncDefaultAgent(
|
|
27
37
|
api_key=api_key,
|
|
@@ -38,11 +48,11 @@ def create_default_agent(
|
|
|
38
48
|
def create_thinker_agent(
|
|
39
49
|
api_key: str | None = None,
|
|
40
50
|
base_url: str | None = None,
|
|
41
|
-
model: str =
|
|
42
|
-
max_steps: int =
|
|
43
|
-
temperature: float =
|
|
51
|
+
model: str = MODEL_THINKER,
|
|
52
|
+
max_steps: int = DEFAULT_MAX_STEPS_THINKER,
|
|
53
|
+
temperature: float = DEFAULT_TEMPERATURE_LOW,
|
|
44
54
|
step_observer: AsyncStepObserver | None = None,
|
|
45
|
-
step_delay: float =
|
|
55
|
+
step_delay: float = DEFAULT_STEP_DELAY,
|
|
46
56
|
) -> AsyncAgent:
|
|
47
57
|
return AsyncDefaultAgent(
|
|
48
58
|
api_key=api_key,
|
|
@@ -59,12 +69,12 @@ def create_thinker_agent(
|
|
|
59
69
|
def create_planner_agent(
|
|
60
70
|
api_key: str | None = None,
|
|
61
71
|
base_url: str | None = None,
|
|
62
|
-
model: str =
|
|
63
|
-
max_steps: int =
|
|
64
|
-
temperature: float =
|
|
65
|
-
reflection_interval: int =
|
|
72
|
+
model: str = MODEL_ACTOR,
|
|
73
|
+
max_steps: int = DEFAULT_MAX_STEPS_TASKER,
|
|
74
|
+
temperature: float = DEFAULT_TEMPERATURE_LOW,
|
|
75
|
+
reflection_interval: int = DEFAULT_REFLECTION_INTERVAL_TASKER,
|
|
66
76
|
step_observer: AsyncStepObserver | None = None,
|
|
67
|
-
step_delay: float =
|
|
77
|
+
step_delay: float = DEFAULT_STEP_DELAY,
|
|
68
78
|
) -> AsyncAgent:
|
|
69
79
|
tasker = TaskerAgent(
|
|
70
80
|
api_key=api_key,
|
|
@@ -10,6 +10,7 @@ import json
|
|
|
10
10
|
from typing import Any
|
|
11
11
|
|
|
12
12
|
from ...client import AsyncClient
|
|
13
|
+
from ...constants import DEFAULT_REFLECTION_INTERVAL
|
|
13
14
|
from ...types import URL, Image
|
|
14
15
|
from .memory import PlannerMemory
|
|
15
16
|
from .models import Action, PlannerOutput, ReflectionOutput
|
|
@@ -175,7 +176,7 @@ class Planner:
|
|
|
175
176
|
memory: PlannerMemory | None = None,
|
|
176
177
|
todo_index: int | None = None,
|
|
177
178
|
current_instruction: str | None = None,
|
|
178
|
-
reflection_interval: int =
|
|
179
|
+
reflection_interval: int = DEFAULT_REFLECTION_INTERVAL,
|
|
179
180
|
) -> ReflectionOutput:
|
|
180
181
|
"""Reflect on recent actions and progress.
|
|
181
182
|
|
|
@@ -12,6 +12,13 @@ from datetime import datetime
|
|
|
12
12
|
from typing import Any
|
|
13
13
|
|
|
14
14
|
from oagi import AsyncActor
|
|
15
|
+
from oagi.constants import (
|
|
16
|
+
DEFAULT_MAX_STEPS,
|
|
17
|
+
DEFAULT_REFLECTION_INTERVAL,
|
|
18
|
+
DEFAULT_STEP_DELAY,
|
|
19
|
+
DEFAULT_TEMPERATURE,
|
|
20
|
+
MODEL_ACTOR,
|
|
21
|
+
)
|
|
15
22
|
from oagi.types import (
|
|
16
23
|
URL,
|
|
17
24
|
ActionEvent,
|
|
@@ -52,15 +59,15 @@ class TaskeeAgent(AsyncAgent):
|
|
|
52
59
|
self,
|
|
53
60
|
api_key: str | None = None,
|
|
54
61
|
base_url: str | None = None,
|
|
55
|
-
model: str =
|
|
56
|
-
max_steps: int =
|
|
57
|
-
reflection_interval: int =
|
|
58
|
-
temperature: float =
|
|
62
|
+
model: str = MODEL_ACTOR,
|
|
63
|
+
max_steps: int = DEFAULT_MAX_STEPS,
|
|
64
|
+
reflection_interval: int = DEFAULT_REFLECTION_INTERVAL,
|
|
65
|
+
temperature: float = DEFAULT_TEMPERATURE,
|
|
59
66
|
planner: Planner | None = None,
|
|
60
67
|
external_memory: PlannerMemory | None = None,
|
|
61
68
|
todo_index: int | None = None,
|
|
62
69
|
step_observer: AsyncObserver | None = None,
|
|
63
|
-
step_delay: float =
|
|
70
|
+
step_delay: float = DEFAULT_STEP_DELAY,
|
|
64
71
|
):
|
|
65
72
|
"""Initialize the taskee agent.
|
|
66
73
|
|
|
@@ -9,6 +9,13 @@
|
|
|
9
9
|
import logging
|
|
10
10
|
from typing import Any
|
|
11
11
|
|
|
12
|
+
from oagi.constants import (
|
|
13
|
+
DEFAULT_MAX_STEPS_TASKER,
|
|
14
|
+
DEFAULT_REFLECTION_INTERVAL,
|
|
15
|
+
DEFAULT_STEP_DELAY,
|
|
16
|
+
DEFAULT_TEMPERATURE,
|
|
17
|
+
MODEL_ACTOR,
|
|
18
|
+
)
|
|
12
19
|
from oagi.types import AsyncActionHandler, AsyncImageProvider, AsyncObserver, SplitEvent
|
|
13
20
|
|
|
14
21
|
from ..protocol import AsyncAgent
|
|
@@ -34,13 +41,13 @@ class TaskerAgent(AsyncAgent):
|
|
|
34
41
|
self,
|
|
35
42
|
api_key: str | None = None,
|
|
36
43
|
base_url: str | None = None,
|
|
37
|
-
model: str =
|
|
38
|
-
max_steps: int =
|
|
39
|
-
temperature: float =
|
|
40
|
-
reflection_interval: int =
|
|
44
|
+
model: str = MODEL_ACTOR,
|
|
45
|
+
max_steps: int = DEFAULT_MAX_STEPS_TASKER,
|
|
46
|
+
temperature: float = DEFAULT_TEMPERATURE,
|
|
47
|
+
reflection_interval: int = DEFAULT_REFLECTION_INTERVAL,
|
|
41
48
|
planner: Planner | None = None,
|
|
42
49
|
step_observer: AsyncObserver | None = None,
|
|
43
|
-
step_delay: float =
|
|
50
|
+
step_delay: float = DEFAULT_STEP_DELAY,
|
|
44
51
|
):
|
|
45
52
|
"""Initialize the tasker agent.
|
|
46
53
|
|
|
@@ -14,6 +14,17 @@ import time
|
|
|
14
14
|
import traceback
|
|
15
15
|
|
|
16
16
|
from oagi.agent.observer import AsyncAgentObserver
|
|
17
|
+
from oagi.constants import (
|
|
18
|
+
API_KEY_HELP_URL,
|
|
19
|
+
DEFAULT_BASE_URL,
|
|
20
|
+
DEFAULT_MAX_STEPS,
|
|
21
|
+
DEFAULT_MAX_STEPS_THINKER,
|
|
22
|
+
DEFAULT_STEP_DELAY,
|
|
23
|
+
DEFAULT_TEMPERATURE,
|
|
24
|
+
MODE_ACTOR,
|
|
25
|
+
MODEL_ACTOR,
|
|
26
|
+
MODEL_THINKER,
|
|
27
|
+
)
|
|
17
28
|
from oagi.exceptions import check_optional_dependency
|
|
18
29
|
|
|
19
30
|
from .display import display_step_table
|
|
@@ -32,7 +43,7 @@ def add_agent_parser(subparsers: argparse._SubParsersAction) -> None:
|
|
|
32
43
|
"instruction", type=str, help="Task instruction for the agent to execute"
|
|
33
44
|
)
|
|
34
45
|
run_parser.add_argument(
|
|
35
|
-
"--model", type=str, help="Model to use (default:
|
|
46
|
+
"--model", type=str, help=f"Model to use (default: {MODEL_ACTOR})"
|
|
36
47
|
)
|
|
37
48
|
run_parser.add_argument(
|
|
38
49
|
"--max-steps", type=int, help="Maximum number of steps (default: 20)"
|
|
@@ -43,8 +54,8 @@ def add_agent_parser(subparsers: argparse._SubParsersAction) -> None:
|
|
|
43
54
|
run_parser.add_argument(
|
|
44
55
|
"--mode",
|
|
45
56
|
type=str,
|
|
46
|
-
default=
|
|
47
|
-
help="Agent mode to use (default:
|
|
57
|
+
default=MODE_ACTOR,
|
|
58
|
+
help=f"Agent mode to use (default: {MODE_ACTOR}). Available modes: actor, planner",
|
|
48
59
|
)
|
|
49
60
|
run_parser.add_argument(
|
|
50
61
|
"--oagi-api-key", type=str, help="OAGI API key (default: OAGI_API_KEY env var)"
|
|
@@ -52,7 +63,7 @@ def add_agent_parser(subparsers: argparse._SubParsersAction) -> None:
|
|
|
52
63
|
run_parser.add_argument(
|
|
53
64
|
"--oagi-base-url",
|
|
54
65
|
type=str,
|
|
55
|
-
help="OAGI base URL (default:
|
|
66
|
+
help=f"OAGI base URL (default: {DEFAULT_BASE_URL}, or OAGI_BASE_URL env var)",
|
|
56
67
|
)
|
|
57
68
|
run_parser.add_argument(
|
|
58
69
|
"--export",
|
|
@@ -68,7 +79,7 @@ def add_agent_parser(subparsers: argparse._SubParsersAction) -> None:
|
|
|
68
79
|
run_parser.add_argument(
|
|
69
80
|
"--step-delay",
|
|
70
81
|
type=float,
|
|
71
|
-
help="Delay in seconds after each step before next screenshot (default:
|
|
82
|
+
help=f"Delay in seconds after each step before next screenshot (default: {DEFAULT_STEP_DELAY})",
|
|
72
83
|
)
|
|
73
84
|
|
|
74
85
|
# agent permission command
|
|
@@ -189,19 +200,23 @@ def run_agent(args: argparse.Namespace) -> None:
|
|
|
189
200
|
if not api_key:
|
|
190
201
|
print(
|
|
191
202
|
"Error: OAGI API key not provided.\n"
|
|
192
|
-
"Set OAGI_API_KEY environment variable or use --oagi-api-key flag
|
|
203
|
+
"Set OAGI_API_KEY environment variable or use --oagi-api-key flag.\n"
|
|
204
|
+
f"Get your API key at {API_KEY_HELP_URL}",
|
|
193
205
|
file=sys.stderr,
|
|
194
206
|
)
|
|
195
207
|
sys.exit(1)
|
|
196
208
|
|
|
197
|
-
base_url = args.oagi_base_url or os.getenv(
|
|
198
|
-
|
|
209
|
+
base_url = args.oagi_base_url or os.getenv("OAGI_BASE_URL", DEFAULT_BASE_URL)
|
|
210
|
+
model = args.model or MODEL_ACTOR
|
|
211
|
+
default_max_steps = (
|
|
212
|
+
DEFAULT_MAX_STEPS_THINKER if model == MODEL_THINKER else DEFAULT_MAX_STEPS
|
|
199
213
|
)
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
214
|
+
max_steps = args.max_steps or default_max_steps
|
|
215
|
+
temperature = (
|
|
216
|
+
args.temperature if args.temperature is not None else DEFAULT_TEMPERATURE
|
|
217
|
+
)
|
|
218
|
+
mode = args.mode or MODE_ACTOR
|
|
219
|
+
step_delay = args.step_delay if args.step_delay is not None else DEFAULT_STEP_DELAY
|
|
205
220
|
export_format = args.export
|
|
206
221
|
export_file = args.export_file
|
|
207
222
|
|
|
@@ -29,7 +29,8 @@ def display_step_table(
|
|
|
29
29
|
actions_display = []
|
|
30
30
|
for action in step.actions[:3]:
|
|
31
31
|
arg = action.argument[:20] if action.argument else ""
|
|
32
|
-
|
|
32
|
+
count_str = f" x{action.count}" if action.count and action.count > 1 else ""
|
|
33
|
+
actions_display.append(f"{action.type.value}({arg}){count_str}")
|
|
33
34
|
|
|
34
35
|
actions_str = ", ".join(actions_display)
|
|
35
36
|
if len(step.actions) > 3:
|
|
@@ -25,7 +25,7 @@ def add_server_parser(subparsers: argparse._SubParsersAction) -> None:
|
|
|
25
25
|
start_parser.add_argument(
|
|
26
26
|
"--host",
|
|
27
27
|
type=str,
|
|
28
|
-
help="Server host (default:
|
|
28
|
+
help="Server host (default: 127.0.0.1, or OAGI_SERVER_HOST env var)",
|
|
29
29
|
)
|
|
30
30
|
start_parser.add_argument(
|
|
31
31
|
"--port",
|
|
@@ -11,6 +11,7 @@ import os
|
|
|
11
11
|
import sys
|
|
12
12
|
from importlib.metadata import version as get_version
|
|
13
13
|
|
|
14
|
+
from oagi.constants import DEFAULT_BASE_URL, MODEL_ACTOR
|
|
14
15
|
from oagi.exceptions import check_optional_dependency
|
|
15
16
|
|
|
16
17
|
|
|
@@ -55,10 +56,10 @@ def display_version() -> None:
|
|
|
55
56
|
def display_config() -> None:
|
|
56
57
|
config_vars = {
|
|
57
58
|
"OAGI_API_KEY": os.getenv("OAGI_API_KEY", ""),
|
|
58
|
-
"OAGI_BASE_URL": os.getenv("OAGI_BASE_URL",
|
|
59
|
-
"OAGI_DEFAULT_MODEL": os.getenv("OAGI_DEFAULT_MODEL",
|
|
59
|
+
"OAGI_BASE_URL": os.getenv("OAGI_BASE_URL", DEFAULT_BASE_URL),
|
|
60
|
+
"OAGI_DEFAULT_MODEL": os.getenv("OAGI_DEFAULT_MODEL", MODEL_ACTOR),
|
|
60
61
|
"OAGI_LOG_LEVEL": os.getenv("OAGI_LOG_LEVEL", "INFO"),
|
|
61
|
-
"OAGI_SERVER_HOST": os.getenv("OAGI_SERVER_HOST", "
|
|
62
|
+
"OAGI_SERVER_HOST": os.getenv("OAGI_SERVER_HOST", "127.0.0.1"),
|
|
62
63
|
"OAGI_SERVER_PORT": os.getenv("OAGI_SERVER_PORT", "8000"),
|
|
63
64
|
"OAGI_MAX_STEPS": os.getenv("OAGI_MAX_STEPS", "30"),
|
|
64
65
|
}
|
|
@@ -10,6 +10,13 @@ from functools import wraps
|
|
|
10
10
|
|
|
11
11
|
import httpx
|
|
12
12
|
|
|
13
|
+
from ..constants import (
|
|
14
|
+
API_HEALTH_ENDPOINT,
|
|
15
|
+
API_V1_FILE_UPLOAD_ENDPOINT,
|
|
16
|
+
API_V1_GENERATE_ENDPOINT,
|
|
17
|
+
API_V2_MESSAGE_ENDPOINT,
|
|
18
|
+
HTTP_CLIENT_TIMEOUT,
|
|
19
|
+
)
|
|
13
20
|
from ..logging import get_logger
|
|
14
21
|
from ..types import Image
|
|
15
22
|
from ..types.models import GenerateResponse, LLMResponse, UploadFileResponse
|
|
@@ -41,7 +48,7 @@ class AsyncClient(BaseClient[httpx.AsyncClient]):
|
|
|
41
48
|
def __init__(self, base_url: str | None = None, api_key: str | None = None):
|
|
42
49
|
super().__init__(base_url, api_key)
|
|
43
50
|
self.client = httpx.AsyncClient(base_url=self.base_url)
|
|
44
|
-
self.upload_client = httpx.AsyncClient(timeout=
|
|
51
|
+
self.upload_client = httpx.AsyncClient(timeout=HTTP_CLIENT_TIMEOUT)
|
|
45
52
|
logger.info(f"AsyncClient initialized with base_url: {self.base_url}")
|
|
46
53
|
|
|
47
54
|
async def __aenter__(self):
|
|
@@ -121,7 +128,10 @@ class AsyncClient(BaseClient[httpx.AsyncClient]):
|
|
|
121
128
|
# Make request
|
|
122
129
|
try:
|
|
123
130
|
response = await self.client.post(
|
|
124
|
-
|
|
131
|
+
API_V2_MESSAGE_ENDPOINT,
|
|
132
|
+
json=payload,
|
|
133
|
+
headers=headers,
|
|
134
|
+
timeout=self.timeout,
|
|
125
135
|
)
|
|
126
136
|
return self._process_response(response)
|
|
127
137
|
except (httpx.TimeoutException, httpx.NetworkError) as e:
|
|
@@ -136,7 +146,7 @@ class AsyncClient(BaseClient[httpx.AsyncClient]):
|
|
|
136
146
|
"""
|
|
137
147
|
logger.debug("Making async health check request")
|
|
138
148
|
try:
|
|
139
|
-
response = await self.client.get(
|
|
149
|
+
response = await self.client.get(API_HEALTH_ENDPOINT)
|
|
140
150
|
response.raise_for_status()
|
|
141
151
|
result = response.json()
|
|
142
152
|
logger.debug("Async health check successful")
|
|
@@ -158,12 +168,12 @@ class AsyncClient(BaseClient[httpx.AsyncClient]):
|
|
|
158
168
|
Returns:
|
|
159
169
|
UploadFileResponse: The response from /v1/file/upload with uuid and presigned S3 URL
|
|
160
170
|
"""
|
|
161
|
-
logger.debug("Making async API request to
|
|
171
|
+
logger.debug(f"Making async API request to {API_V1_FILE_UPLOAD_ENDPOINT}")
|
|
162
172
|
|
|
163
173
|
try:
|
|
164
174
|
headers = self._build_headers(api_version)
|
|
165
175
|
response = await self.client.get(
|
|
166
|
-
|
|
176
|
+
API_V1_FILE_UPLOAD_ENDPOINT, headers=headers, timeout=self.timeout
|
|
167
177
|
)
|
|
168
178
|
return self._process_upload_response(response)
|
|
169
179
|
except (httpx.TimeoutException, httpx.NetworkError, httpx.HTTPStatusError) as e:
|
|
@@ -283,7 +293,10 @@ class AsyncClient(BaseClient[httpx.AsyncClient]):
|
|
|
283
293
|
# Make request
|
|
284
294
|
try:
|
|
285
295
|
response = await self.client.post(
|
|
286
|
-
|
|
296
|
+
API_V1_GENERATE_ENDPOINT,
|
|
297
|
+
json=payload,
|
|
298
|
+
headers=headers,
|
|
299
|
+
timeout=self.timeout,
|
|
287
300
|
)
|
|
288
301
|
return self._process_generate_response(response)
|
|
289
302
|
except (httpx.TimeoutException, httpx.NetworkError) as e:
|
|
@@ -11,6 +11,7 @@ from typing import Any, Generic, TypeVar
|
|
|
11
11
|
|
|
12
12
|
import httpx
|
|
13
13
|
|
|
14
|
+
from ..constants import API_KEY_HELP_URL, DEFAULT_BASE_URL, HTTP_CLIENT_TIMEOUT
|
|
14
15
|
from ..exceptions import (
|
|
15
16
|
APIError,
|
|
16
17
|
AuthenticationError,
|
|
@@ -41,20 +42,19 @@ class BaseClient(Generic[HttpClientT]):
|
|
|
41
42
|
|
|
42
43
|
def __init__(self, base_url: str | None = None, api_key: str | None = None):
|
|
43
44
|
# Get from environment if not provided
|
|
44
|
-
self.base_url = (
|
|
45
|
-
base_url or os.getenv("OAGI_BASE_URL") or "https://api.agiopen.org"
|
|
46
|
-
)
|
|
45
|
+
self.base_url = base_url or os.getenv("OAGI_BASE_URL") or DEFAULT_BASE_URL
|
|
47
46
|
self.api_key = api_key or os.getenv("OAGI_API_KEY")
|
|
48
47
|
|
|
49
48
|
# Validate required configuration
|
|
50
49
|
if not self.api_key:
|
|
51
50
|
raise ConfigurationError(
|
|
52
51
|
"OAGI API key must be provided either as 'api_key' parameter or "
|
|
53
|
-
"OAGI_API_KEY environment variable"
|
|
52
|
+
"OAGI_API_KEY environment variable. "
|
|
53
|
+
f"Get your API key at {API_KEY_HELP_URL}"
|
|
54
54
|
)
|
|
55
55
|
|
|
56
56
|
self.base_url = self.base_url.rstrip("/")
|
|
57
|
-
self.timeout =
|
|
57
|
+
self.timeout = HTTP_CLIENT_TIMEOUT
|
|
58
58
|
self.client: HttpClientT # Will be set by subclasses
|
|
59
59
|
|
|
60
60
|
logger.info(f"Client initialized with base_url: {self.base_url}")
|
|
@@ -273,22 +273,20 @@ class BaseClient(Generic[HttpClientT]):
|
|
|
273
273
|
NetworkError: If network error occurs
|
|
274
274
|
APIError: If API returns error or invalid response
|
|
275
275
|
"""
|
|
276
|
+
response_data = self._parse_response_json(response)
|
|
277
|
+
|
|
278
|
+
# Check for error status codes first (follows _process_response pattern)
|
|
279
|
+
if response.status_code != 200:
|
|
280
|
+
self._handle_response_error(response, response_data)
|
|
281
|
+
|
|
276
282
|
try:
|
|
277
|
-
response_data = response.json()
|
|
278
283
|
upload_file_response = UploadFileResponse(**response_data)
|
|
279
284
|
logger.debug("Calling /v1/file/upload successful")
|
|
280
285
|
return upload_file_response
|
|
281
|
-
except
|
|
282
|
-
logger.error(f"
|
|
283
|
-
raise APIError(
|
|
284
|
-
f"Invalid response format (status {response.status_code})",
|
|
285
|
-
status_code=response.status_code,
|
|
286
|
-
response=response,
|
|
287
|
-
)
|
|
288
|
-
except KeyError as e:
|
|
289
|
-
logger.error(f"Invalid response: {response.status_code}")
|
|
286
|
+
except Exception as e:
|
|
287
|
+
logger.error(f"Invalid upload response: {response.status_code}")
|
|
290
288
|
raise APIError(
|
|
291
|
-
f"Invalid presigned S3 URL response:
|
|
289
|
+
f"Invalid presigned S3 URL response: {e}",
|
|
292
290
|
status_code=response.status_code,
|
|
293
291
|
response=response,
|
|
294
292
|
)
|
|
@@ -11,6 +11,13 @@ from functools import wraps
|
|
|
11
11
|
import httpx
|
|
12
12
|
from httpx import Response
|
|
13
13
|
|
|
14
|
+
from ..constants import (
|
|
15
|
+
API_HEALTH_ENDPOINT,
|
|
16
|
+
API_V1_FILE_UPLOAD_ENDPOINT,
|
|
17
|
+
API_V1_GENERATE_ENDPOINT,
|
|
18
|
+
API_V2_MESSAGE_ENDPOINT,
|
|
19
|
+
HTTP_CLIENT_TIMEOUT,
|
|
20
|
+
)
|
|
14
21
|
from ..logging import get_logger
|
|
15
22
|
from ..types import Image
|
|
16
23
|
from ..types.models import GenerateResponse, LLMResponse, UploadFileResponse
|
|
@@ -46,7 +53,7 @@ class SyncClient(BaseClient[httpx.Client]):
|
|
|
46
53
|
def __init__(self, base_url: str | None = None, api_key: str | None = None):
|
|
47
54
|
super().__init__(base_url, api_key)
|
|
48
55
|
self.client = httpx.Client(base_url=self.base_url)
|
|
49
|
-
self.upload_client = httpx.Client(timeout=
|
|
56
|
+
self.upload_client = httpx.Client(timeout=HTTP_CLIENT_TIMEOUT)
|
|
50
57
|
logger.info(f"SyncClient initialized with base_url: {self.base_url}")
|
|
51
58
|
|
|
52
59
|
def __enter__(self):
|
|
@@ -124,7 +131,10 @@ class SyncClient(BaseClient[httpx.Client]):
|
|
|
124
131
|
# Make request
|
|
125
132
|
try:
|
|
126
133
|
response = self.client.post(
|
|
127
|
-
|
|
134
|
+
API_V2_MESSAGE_ENDPOINT,
|
|
135
|
+
json=payload,
|
|
136
|
+
headers=headers,
|
|
137
|
+
timeout=self.timeout,
|
|
128
138
|
)
|
|
129
139
|
return self._process_response(response)
|
|
130
140
|
except (httpx.TimeoutException, httpx.NetworkError) as e:
|
|
@@ -139,7 +149,7 @@ class SyncClient(BaseClient[httpx.Client]):
|
|
|
139
149
|
"""
|
|
140
150
|
logger.debug("Making health check request")
|
|
141
151
|
try:
|
|
142
|
-
response = self.client.get(
|
|
152
|
+
response = self.client.get(API_HEALTH_ENDPOINT)
|
|
143
153
|
response.raise_for_status()
|
|
144
154
|
result = response.json()
|
|
145
155
|
logger.debug("Health check successful")
|
|
@@ -161,12 +171,12 @@ class SyncClient(BaseClient[httpx.Client]):
|
|
|
161
171
|
Returns:
|
|
162
172
|
UploadFileResponse: The response from /v1/file/upload with uuid and presigned S3 URL
|
|
163
173
|
"""
|
|
164
|
-
logger.debug("Making API request to
|
|
174
|
+
logger.debug(f"Making API request to {API_V1_FILE_UPLOAD_ENDPOINT}")
|
|
165
175
|
|
|
166
176
|
try:
|
|
167
177
|
headers = self._build_headers(api_version)
|
|
168
178
|
response = self.client.get(
|
|
169
|
-
|
|
179
|
+
API_V1_FILE_UPLOAD_ENDPOINT, headers=headers, timeout=self.timeout
|
|
170
180
|
)
|
|
171
181
|
return self._process_upload_response(response)
|
|
172
182
|
except (httpx.TimeoutException, httpx.NetworkError, httpx.HTTPStatusError) as e:
|
|
@@ -286,7 +296,10 @@ class SyncClient(BaseClient[httpx.Client]):
|
|
|
286
296
|
# Make request
|
|
287
297
|
try:
|
|
288
298
|
response = self.client.post(
|
|
289
|
-
|
|
299
|
+
API_V1_GENERATE_ENDPOINT,
|
|
300
|
+
json=payload,
|
|
301
|
+
headers=headers,
|
|
302
|
+
timeout=self.timeout,
|
|
290
303
|
)
|
|
291
304
|
return self._process_generate_response(response)
|
|
292
305
|
except (httpx.TimeoutException, httpx.NetworkError) as e:
|
|
@@ -0,0 +1,43 @@
|
|
|
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
|
+
# URLs & API Endpoints
|
|
10
|
+
DEFAULT_BASE_URL = "https://api.agiopen.org"
|
|
11
|
+
API_KEY_HELP_URL = "https://developer.agiopen.org/api-keys"
|
|
12
|
+
API_V2_MESSAGE_ENDPOINT = "/v2/message"
|
|
13
|
+
API_V1_FILE_UPLOAD_ENDPOINT = "/v1/file/upload"
|
|
14
|
+
API_V1_GENERATE_ENDPOINT = "/v1/generate"
|
|
15
|
+
API_HEALTH_ENDPOINT = "/health"
|
|
16
|
+
|
|
17
|
+
# Model identifiers
|
|
18
|
+
MODEL_ACTOR = "lux-actor-1"
|
|
19
|
+
MODEL_THINKER = "lux-thinker-1"
|
|
20
|
+
|
|
21
|
+
# Agent modes
|
|
22
|
+
MODE_ACTOR = "actor"
|
|
23
|
+
MODE_THINKER = "thinker"
|
|
24
|
+
MODE_TASKER = "tasker"
|
|
25
|
+
|
|
26
|
+
# Default max steps per model
|
|
27
|
+
DEFAULT_MAX_STEPS = 20
|
|
28
|
+
DEFAULT_MAX_STEPS_THINKER = 100
|
|
29
|
+
DEFAULT_MAX_STEPS_TASKER = 60
|
|
30
|
+
|
|
31
|
+
# Reflection intervals
|
|
32
|
+
DEFAULT_REFLECTION_INTERVAL = 4
|
|
33
|
+
DEFAULT_REFLECTION_INTERVAL_TASKER = 20
|
|
34
|
+
|
|
35
|
+
# Timing & Delays
|
|
36
|
+
DEFAULT_STEP_DELAY = 0.3
|
|
37
|
+
|
|
38
|
+
# Temperature Defaults
|
|
39
|
+
DEFAULT_TEMPERATURE = 0.5
|
|
40
|
+
DEFAULT_TEMPERATURE_LOW = 0.1
|
|
41
|
+
|
|
42
|
+
# Timeout Values
|
|
43
|
+
HTTP_CLIENT_TIMEOUT = 60
|
|
@@ -64,7 +64,8 @@ class PyautoguiConfig(BaseModel):
|
|
|
64
64
|
default=0.5, description="Duration for drag operations in seconds"
|
|
65
65
|
)
|
|
66
66
|
scroll_amount: int = Field(
|
|
67
|
-
default=
|
|
67
|
+
default=2 if sys.platform == "darwin" else 100,
|
|
68
|
+
description="Amount to scroll (positive for up, negative for down)",
|
|
68
69
|
)
|
|
69
70
|
wait_duration: float = Field(
|
|
70
71
|
default=1.0, description="Duration for wait actions in seconds"
|