cua-agent 0.4.22__py3-none-any.whl → 0.7.16__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.
Potentially problematic release.
This version of cua-agent might be problematic. Click here for more details.
- agent/__init__.py +4 -10
- agent/__main__.py +2 -1
- agent/adapters/__init__.py +4 -0
- agent/adapters/azure_ml_adapter.py +283 -0
- agent/adapters/cua_adapter.py +161 -0
- agent/adapters/huggingfacelocal_adapter.py +67 -125
- agent/adapters/human_adapter.py +116 -114
- agent/adapters/mlxvlm_adapter.py +110 -99
- agent/adapters/models/__init__.py +41 -0
- agent/adapters/models/generic.py +78 -0
- agent/adapters/models/internvl.py +290 -0
- agent/adapters/models/opencua.py +115 -0
- agent/adapters/models/qwen2_5_vl.py +78 -0
- agent/agent.py +337 -185
- agent/callbacks/__init__.py +9 -4
- agent/callbacks/base.py +45 -31
- agent/callbacks/budget_manager.py +22 -10
- agent/callbacks/image_retention.py +54 -98
- agent/callbacks/logging.py +55 -42
- agent/callbacks/operator_validator.py +35 -33
- agent/callbacks/otel.py +291 -0
- agent/callbacks/pii_anonymization.py +19 -16
- agent/callbacks/prompt_instructions.py +47 -0
- agent/callbacks/telemetry.py +99 -61
- agent/callbacks/trajectory_saver.py +95 -69
- agent/cli.py +269 -119
- agent/computers/__init__.py +14 -9
- agent/computers/base.py +32 -19
- agent/computers/cua.py +52 -25
- agent/computers/custom.py +78 -71
- agent/decorators.py +23 -14
- agent/human_tool/__init__.py +2 -7
- agent/human_tool/__main__.py +6 -2
- agent/human_tool/server.py +48 -37
- agent/human_tool/ui.py +359 -235
- agent/integrations/hud/__init__.py +38 -99
- agent/integrations/hud/agent.py +369 -0
- agent/integrations/hud/proxy.py +166 -52
- agent/loops/__init__.py +44 -14
- agent/loops/anthropic.py +579 -492
- agent/loops/base.py +19 -15
- agent/loops/composed_grounded.py +136 -150
- agent/loops/fara/__init__.py +8 -0
- agent/loops/fara/config.py +506 -0
- agent/loops/fara/helpers.py +357 -0
- agent/loops/fara/schema.py +143 -0
- agent/loops/gelato.py +183 -0
- agent/loops/gemini.py +935 -0
- agent/loops/generic_vlm.py +601 -0
- agent/loops/glm45v.py +140 -135
- agent/loops/gta1.py +48 -51
- agent/loops/holo.py +218 -0
- agent/loops/internvl.py +180 -0
- agent/loops/moondream3.py +493 -0
- agent/loops/omniparser.py +326 -226
- agent/loops/openai.py +50 -51
- agent/loops/opencua.py +134 -0
- agent/loops/uiins.py +175 -0
- agent/loops/uitars.py +247 -206
- agent/loops/uitars2.py +951 -0
- agent/playground/__init__.py +5 -0
- agent/playground/server.py +301 -0
- agent/proxy/examples.py +61 -57
- agent/proxy/handlers.py +46 -39
- agent/responses.py +447 -347
- agent/tools/__init__.py +24 -0
- agent/tools/base.py +253 -0
- agent/tools/browser_tool.py +423 -0
- agent/types.py +11 -5
- agent/ui/__init__.py +1 -1
- agent/ui/__main__.py +1 -1
- agent/ui/gradio/app.py +25 -22
- agent/ui/gradio/ui_components.py +314 -167
- cua_agent-0.7.16.dist-info/METADATA +85 -0
- cua_agent-0.7.16.dist-info/RECORD +79 -0
- {cua_agent-0.4.22.dist-info → cua_agent-0.7.16.dist-info}/WHEEL +1 -1
- cua_agent-0.4.22.dist-info/METADATA +0 -436
- cua_agent-0.4.22.dist-info/RECORD +0 -51
- {cua_agent-0.4.22.dist-info → cua_agent-0.7.16.dist-info}/entry_points.txt +0 -0
agent/tools/__init__.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Agent tools module.
|
|
3
|
+
Provides base classes and registered tools for agent interactions.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from .base import (
|
|
7
|
+
TOOL_REGISTRY,
|
|
8
|
+
BaseComputerTool,
|
|
9
|
+
BaseTool,
|
|
10
|
+
get_registered_tools,
|
|
11
|
+
get_tool,
|
|
12
|
+
register_tool,
|
|
13
|
+
)
|
|
14
|
+
from .browser_tool import BrowserTool
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"BaseTool",
|
|
18
|
+
"BaseComputerTool",
|
|
19
|
+
"register_tool",
|
|
20
|
+
"get_registered_tools",
|
|
21
|
+
"get_tool",
|
|
22
|
+
"TOOL_REGISTRY",
|
|
23
|
+
"BrowserTool",
|
|
24
|
+
]
|
agent/tools/base.py
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Base tool interface and registration system for agent tools.
|
|
3
|
+
Provides a protocol for implementing tools that can be registered and discovered.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import json
|
|
7
|
+
from abc import ABC, abstractmethod
|
|
8
|
+
from typing import Dict, List, Optional, Union
|
|
9
|
+
|
|
10
|
+
# Global tool registry
|
|
11
|
+
TOOL_REGISTRY: Dict[str, type] = {}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def register_tool(name: str, allow_overwrite: bool = False):
|
|
15
|
+
"""
|
|
16
|
+
Decorator to register a tool class with a given name.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
name: The name to register the tool under
|
|
20
|
+
allow_overwrite: Whether to allow overwriting an existing tool with the same name
|
|
21
|
+
|
|
22
|
+
Returns:
|
|
23
|
+
Decorator function that registers the class
|
|
24
|
+
|
|
25
|
+
Example:
|
|
26
|
+
@register_tool("my_tool")
|
|
27
|
+
class MyTool(BaseTool):
|
|
28
|
+
...
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def decorator(cls):
|
|
32
|
+
if name in TOOL_REGISTRY:
|
|
33
|
+
if allow_overwrite:
|
|
34
|
+
print(f"Warning: Tool `{name}` already exists! Overwriting with class {cls}.")
|
|
35
|
+
else:
|
|
36
|
+
raise ValueError(
|
|
37
|
+
f"Tool `{name}` already exists! Please ensure that the tool name is unique."
|
|
38
|
+
)
|
|
39
|
+
if hasattr(cls, "name") and cls.name and (cls.name != name):
|
|
40
|
+
raise ValueError(
|
|
41
|
+
f'{cls.__name__}.name="{cls.name}" conflicts with @register_tool(name="{name}").'
|
|
42
|
+
)
|
|
43
|
+
cls.name = name
|
|
44
|
+
TOOL_REGISTRY[name] = cls
|
|
45
|
+
return cls
|
|
46
|
+
|
|
47
|
+
return decorator
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def is_tool_schema(obj: dict) -> bool:
|
|
51
|
+
"""
|
|
52
|
+
Check if obj is a valid JSON schema describing a tool compatible with OpenAI's tool calling.
|
|
53
|
+
|
|
54
|
+
Example valid schema:
|
|
55
|
+
{
|
|
56
|
+
"name": "get_current_weather",
|
|
57
|
+
"description": "Get the current weather in a given location",
|
|
58
|
+
"parameters": {
|
|
59
|
+
"type": "object",
|
|
60
|
+
"properties": {
|
|
61
|
+
"location": {
|
|
62
|
+
"type": "string",
|
|
63
|
+
"description": "The city and state, e.g. San Francisco, CA"
|
|
64
|
+
},
|
|
65
|
+
"unit": {
|
|
66
|
+
"type": "string",
|
|
67
|
+
"enum": ["celsius", "fahrenheit"]
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
"required": ["location"]
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
"""
|
|
74
|
+
try:
|
|
75
|
+
# Basic structure validation
|
|
76
|
+
assert set(obj.keys()) == {"name", "description", "parameters"}
|
|
77
|
+
assert isinstance(obj["name"], str)
|
|
78
|
+
assert obj["name"].strip()
|
|
79
|
+
assert isinstance(obj["description"], str)
|
|
80
|
+
assert isinstance(obj["parameters"], dict)
|
|
81
|
+
|
|
82
|
+
# Parameters structure validation
|
|
83
|
+
assert "type" in obj["parameters"]
|
|
84
|
+
assert obj["parameters"]["type"] == "object"
|
|
85
|
+
assert "properties" in obj["parameters"]
|
|
86
|
+
assert isinstance(obj["parameters"]["properties"], dict)
|
|
87
|
+
|
|
88
|
+
if "required" in obj["parameters"]:
|
|
89
|
+
assert isinstance(obj["parameters"]["required"], list)
|
|
90
|
+
assert set(obj["parameters"]["required"]).issubset(
|
|
91
|
+
set(obj["parameters"]["properties"].keys())
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
return True
|
|
95
|
+
except (AssertionError, KeyError, TypeError):
|
|
96
|
+
return False
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class BaseTool(ABC):
|
|
100
|
+
"""
|
|
101
|
+
Base class for all agent tools.
|
|
102
|
+
|
|
103
|
+
Tools must implement:
|
|
104
|
+
- name: str - The tool name (set by @register_tool decorator)
|
|
105
|
+
- description: property that returns str - Tool description
|
|
106
|
+
- parameters: property that returns dict - JSON schema for tool parameters
|
|
107
|
+
- call: method - Execute the tool with given parameters
|
|
108
|
+
"""
|
|
109
|
+
|
|
110
|
+
name: str = ""
|
|
111
|
+
|
|
112
|
+
def __init__(self, cfg: Optional[dict] = None):
|
|
113
|
+
"""
|
|
114
|
+
Initialize the tool.
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
cfg: Optional configuration dictionary
|
|
118
|
+
"""
|
|
119
|
+
self.cfg = cfg or {}
|
|
120
|
+
|
|
121
|
+
if not self.name:
|
|
122
|
+
raise ValueError(
|
|
123
|
+
f"You must set {self.__class__.__name__}.name, either by "
|
|
124
|
+
f"@register_tool(name=...) or explicitly setting "
|
|
125
|
+
f"{self.__class__.__name__}.name"
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
# Validate schema if parameters is a dict
|
|
129
|
+
if isinstance(self.parameters, dict):
|
|
130
|
+
if not is_tool_schema(
|
|
131
|
+
{"name": self.name, "description": self.description, "parameters": self.parameters}
|
|
132
|
+
):
|
|
133
|
+
raise ValueError(
|
|
134
|
+
"The parameters, when provided as a dict, must conform to a "
|
|
135
|
+
"valid openai-compatible JSON schema."
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
@property
|
|
139
|
+
@abstractmethod
|
|
140
|
+
def description(self) -> str:
|
|
141
|
+
"""Return the tool description."""
|
|
142
|
+
raise NotImplementedError
|
|
143
|
+
|
|
144
|
+
@property
|
|
145
|
+
@abstractmethod
|
|
146
|
+
def parameters(self) -> dict:
|
|
147
|
+
"""Return the JSON schema for tool parameters."""
|
|
148
|
+
raise NotImplementedError
|
|
149
|
+
|
|
150
|
+
@abstractmethod
|
|
151
|
+
def call(self, params: Union[str, dict], **kwargs) -> Union[str, list, dict]:
|
|
152
|
+
"""
|
|
153
|
+
Execute the tool with the given parameters.
|
|
154
|
+
|
|
155
|
+
Args:
|
|
156
|
+
params: The parameters for the tool call (JSON string or dict)
|
|
157
|
+
**kwargs: Additional keyword arguments
|
|
158
|
+
|
|
159
|
+
Returns:
|
|
160
|
+
The result of the tool execution
|
|
161
|
+
"""
|
|
162
|
+
raise NotImplementedError
|
|
163
|
+
|
|
164
|
+
def _verify_json_format_args(self, params: Union[str, dict]) -> dict:
|
|
165
|
+
"""
|
|
166
|
+
Verify and parse the parameters as JSON.
|
|
167
|
+
|
|
168
|
+
Args:
|
|
169
|
+
params: Parameters as string or dict
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
Parsed parameters as dict
|
|
173
|
+
|
|
174
|
+
Raises:
|
|
175
|
+
ValueError: If parameters are not valid JSON or don't match schema
|
|
176
|
+
"""
|
|
177
|
+
if isinstance(params, str):
|
|
178
|
+
try:
|
|
179
|
+
params_json: dict = json.loads(params)
|
|
180
|
+
except json.JSONDecodeError as e:
|
|
181
|
+
raise ValueError(f"Parameters must be formatted as valid JSON: {e}")
|
|
182
|
+
else:
|
|
183
|
+
params_json: dict = params
|
|
184
|
+
|
|
185
|
+
# Validate against schema if using dict parameters
|
|
186
|
+
if isinstance(self.parameters, dict):
|
|
187
|
+
try:
|
|
188
|
+
# Basic validation of required fields
|
|
189
|
+
if "required" in self.parameters:
|
|
190
|
+
for field in self.parameters["required"]:
|
|
191
|
+
if field not in params_json:
|
|
192
|
+
raise ValueError(f'Required parameter "{field}" is missing')
|
|
193
|
+
except (KeyError, TypeError) as e:
|
|
194
|
+
raise ValueError(f"Invalid parameters: {e}")
|
|
195
|
+
|
|
196
|
+
return params_json
|
|
197
|
+
|
|
198
|
+
@property
|
|
199
|
+
def function(self) -> dict:
|
|
200
|
+
"""
|
|
201
|
+
Return the function information for this tool.
|
|
202
|
+
|
|
203
|
+
Returns:
|
|
204
|
+
Dict with tool metadata
|
|
205
|
+
"""
|
|
206
|
+
return {
|
|
207
|
+
"name": self.name,
|
|
208
|
+
"description": self.description,
|
|
209
|
+
"parameters": self.parameters,
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def get_registered_tools() -> Dict[str, type]:
|
|
214
|
+
"""
|
|
215
|
+
Get all registered tools.
|
|
216
|
+
|
|
217
|
+
Returns:
|
|
218
|
+
Dictionary mapping tool names to tool classes
|
|
219
|
+
"""
|
|
220
|
+
return TOOL_REGISTRY.copy()
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
def get_tool(name: str) -> Optional[type]:
|
|
224
|
+
"""
|
|
225
|
+
Get a registered tool by name.
|
|
226
|
+
|
|
227
|
+
Args:
|
|
228
|
+
name: The tool name
|
|
229
|
+
|
|
230
|
+
Returns:
|
|
231
|
+
The tool class, or None if not found
|
|
232
|
+
"""
|
|
233
|
+
return TOOL_REGISTRY.get(name)
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
class BaseComputerTool(BaseTool):
|
|
237
|
+
"""
|
|
238
|
+
Base class for computer tools that can provide screenshots.
|
|
239
|
+
|
|
240
|
+
Computer tools must implement:
|
|
241
|
+
- All BaseTool requirements (name, description, parameters, call)
|
|
242
|
+
- screenshot() method that returns screenshot as base64 string
|
|
243
|
+
"""
|
|
244
|
+
|
|
245
|
+
@abstractmethod
|
|
246
|
+
async def screenshot(self) -> str:
|
|
247
|
+
"""
|
|
248
|
+
Take a screenshot of the computer/browser.
|
|
249
|
+
|
|
250
|
+
Returns:
|
|
251
|
+
Screenshot image data as base64-encoded string
|
|
252
|
+
"""
|
|
253
|
+
raise NotImplementedError
|