Skip to content

Commit 33c72bf

Browse files
Merge branch 'main' into chore/act_conversation_with_caching
2 parents f8b416a + 46d3113 commit 33c72bf

9 files changed

Lines changed: 24 additions & 29 deletions

File tree

docs/00_overview.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Overview
22

3+
This documentation is intended for **developers** that want build custom implementation with this SDK.
4+
For tutorials, how-to-guides, and more ressources please visit our user documentation [here](https://docs.askui.com/).
5+
36
## Why AskUI Vision Agent?
47

58
AskUI Vision Agent is a powerful automation framework that bridges the gap between human intent and computer control. Whether you need precise UI automation for testing, want AI agents to handle complex workflows, or need to automate tasks across desktop, mobile, and HMI devices, AskUI Vision Agent provides a unified solution.

examples/model_providers.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,7 @@ def try_act(agent: ComputerAgent, provider_name: str) -> None:
3535
"""Test the act() method with a simple goal."""
3636
logger.info(f"Testing act() with {provider_name}")
3737
agent.act(
38-
goal=(
39-
"Open a new Chrome window and navigate to askui.com. "
40-
),
38+
goal=("Open a new Chrome window and navigate to askui.com. "),
4139
)
4240

4341

@@ -116,19 +114,19 @@ def create_mixed_providers() -> AgentSettings:
116114
if __name__ == "__main__":
117115
# Define which provider configurations to test
118116
provider_configs = {
119-
#"AskUI (default)": create_askui_providers,
120-
#"Anthropic (direct)": create_anthropic_providers,
121-
#"Google (Gemini)": create_google_providers,
117+
# "AskUI (default)": create_askui_providers,
118+
# "Anthropic (direct)": create_anthropic_providers,
119+
# "Google (Gemini)": create_google_providers,
122120
"Mixed providers": create_mixed_providers,
123121
}
124122

125123
# Select which configuration to run (change this to test different providers)
126124
selected_config = "AskUI (default)"
127125

128126
for selected_config in provider_configs.keys():
129-
logger.info("#"*60)
127+
logger.info("#" * 60)
130128
logger.info(f"Running with provider configuration: {selected_config}")
131-
logger.info("#"*60)
129+
logger.info("#" * 60)
132130
settings = provider_configs[selected_config]()
133131

134132
with ComputerAgent(settings=settings, display=1) as agent:

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ dependencies = [
1313
"httpx>=0.28.1",
1414
"Jinja2>=3.1.4",
1515
"openai>=1.61.1",
16+
"opentelemetry-sdk>=1.38.0",
1617
"pillow>=11.0.0",
1718
"py-machineid>=0.7.0",
1819
"pydantic-settings>=2.9.1",
@@ -224,7 +225,7 @@ bedrock = [
224225
]
225226
otel = [
226227
"prometheus-fastapi-instrumentator>=7.1.0",
227-
"opentelemetry-sdk>=1.38.0",
228+
"opentelemetry-api>=1.38.0",
228229
"opentelemetry-instrumentation-fastapi>=0.59b0",
229230
"opentelemetry-exporter-otlp-proto-http>=1.38.0",
230231
"opentelemetry-instrumentation-httpx>=0.59b0",

src/askui/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""AskUI Python SDK"""
22

3-
__version__ = "0.23.1"
3+
__version__ = "0.24.0"
44

55
import logging
66
import os

src/askui/agent_base.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,9 @@ def __init__(
103103
self.act_tool_collection.add_agent_os(agent_os)
104104

105105
# Add provider-based tools to the act loop
106-
self.act_tool_collection.append_tool(self._get_tool)
107-
self.act_tool_collection.append_tool(self._locate_tool)
106+
if self._agent_os is not None:
107+
self.act_tool_collection.append_tool(self._get_tool)
108+
self.act_tool_collection.append_tool(self._locate_tool)
108109

109110
# Settings stored at agent level (mutable)
110111
self.act_settings = ActSettings()

src/askui/models/openrouter/get_model.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -178,11 +178,7 @@ def get(
178178
raise NotImplementedError(err_msg)
179179

180180
# Use system prompt from settings if provided, otherwise use default
181-
system_prompt = (
182-
get_settings.system_prompt
183-
if get_settings.system_prompt
184-
else SYSTEM_PROMPT_GET
185-
)
181+
system_prompt = get_settings.system_prompt or SYSTEM_PROMPT_GET
186182

187183
response = self._predict(
188184
image_url=source.to_data_url(),

src/askui/telemetry/otel.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
from fastapi import FastAPI
22
from opentelemetry import trace
3+
from opentelemetry.sdk.resources import Resource
4+
from opentelemetry.sdk.trace import TracerProvider
5+
from opentelemetry.sdk.trace.export import BatchSpanProcessor
36
from pydantic import BaseModel, Field, SecretStr, model_validator
47
from typing_extensions import Self
58

@@ -57,15 +60,6 @@ def setup_opentelemetry_tracing(app: FastAPI, settings: OtelSettings) -> None:
5760
from opentelemetry.instrumentation.sqlalchemy import ( # type: ignore[import-not-found]
5861
SQLAlchemyInstrumentor,
5962
)
60-
from opentelemetry.sdk.resources import ( # type: ignore[import-not-found]
61-
Resource,
62-
)
63-
from opentelemetry.sdk.trace import ( # type: ignore[import-not-found]
64-
TracerProvider,
65-
)
66-
from opentelemetry.sdk.trace.export import ( # type: ignore[import-not-found]
67-
BatchSpanProcessor,
68-
)
6963
except ImportError:
7064
return
7165

src/askui/tools/askui/askui_controller.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1052,7 +1052,7 @@ def _send_command(self, command: Command) -> AskUIAgentOSSendResponseSchema:
10521052
)
10531053
except grpc.RpcError as e:
10541054
if e.code() == grpc.StatusCode.INVALID_ARGUMENT:
1055-
details = e.details() if e.details() else None
1055+
details = e.details() or None
10561056
raise AskUiControllerInvalidCommandError(details) from e
10571057
raise
10581058

src/askui/utils/not_given.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Any, ClassVar
1+
from typing import Any, ClassVar, final
22
from uuid import uuid4
33

44
from pydantic import (
@@ -7,8 +7,10 @@
77
SerializerFunctionWrapHandler,
88
model_serializer,
99
)
10+
from typing_extensions import Self
1011

1112

13+
@final # Ensures Self resolves to NotGiven in __new__, fixing mypy return-type check
1214
class NotGiven(BaseModel):
1315
"""
1416
A sentinel value that represents a value that is not given.
@@ -19,7 +21,7 @@ class NotGiven(BaseModel):
1921
_uuid: ClassVar[str] = str(uuid4())
2022
_instance: ClassVar["NotGiven | None"] = None
2123

22-
def __new__(cls) -> "NotGiven":
24+
def __new__(cls) -> Self:
2325
if cls._instance is None:
2426
cls._instance = super().__new__(cls)
2527
return cls._instance

0 commit comments

Comments
 (0)