hud-python 0.4.1__py3-none-any.whl → 0.4.3__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 hud-python might be problematic. Click here for more details.
- hud/__init__.py +22 -22
- hud/agents/__init__.py +13 -15
- hud/agents/base.py +599 -599
- hud/agents/claude.py +373 -373
- hud/agents/langchain.py +261 -250
- hud/agents/misc/__init__.py +7 -7
- hud/agents/misc/response_agent.py +82 -80
- hud/agents/openai.py +352 -352
- hud/agents/openai_chat_generic.py +154 -154
- hud/agents/tests/__init__.py +1 -1
- hud/agents/tests/test_base.py +742 -742
- hud/agents/tests/test_claude.py +324 -324
- hud/agents/tests/test_client.py +363 -363
- hud/agents/tests/test_openai.py +237 -237
- hud/cli/__init__.py +617 -617
- hud/cli/__main__.py +8 -8
- hud/cli/analyze.py +371 -371
- hud/cli/analyze_metadata.py +230 -230
- hud/cli/build.py +498 -427
- hud/cli/clone.py +185 -185
- hud/cli/cursor.py +92 -92
- hud/cli/debug.py +392 -392
- hud/cli/docker_utils.py +83 -83
- hud/cli/init.py +280 -281
- hud/cli/interactive.py +353 -353
- hud/cli/mcp_server.py +764 -756
- hud/cli/pull.py +330 -336
- hud/cli/push.py +404 -370
- hud/cli/remote_runner.py +311 -311
- hud/cli/runner.py +160 -160
- hud/cli/tests/__init__.py +3 -3
- hud/cli/tests/test_analyze.py +284 -284
- hud/cli/tests/test_cli_init.py +265 -265
- hud/cli/tests/test_cli_main.py +27 -27
- hud/cli/tests/test_clone.py +142 -142
- hud/cli/tests/test_cursor.py +253 -253
- hud/cli/tests/test_debug.py +453 -453
- hud/cli/tests/test_mcp_server.py +139 -139
- hud/cli/tests/test_utils.py +388 -388
- hud/cli/utils.py +263 -263
- hud/clients/README.md +143 -143
- hud/clients/__init__.py +16 -16
- hud/clients/base.py +378 -379
- hud/clients/fastmcp.py +222 -222
- hud/clients/mcp_use.py +298 -278
- hud/clients/tests/__init__.py +1 -1
- hud/clients/tests/test_client_integration.py +111 -111
- hud/clients/tests/test_fastmcp.py +342 -342
- hud/clients/tests/test_protocol.py +188 -188
- hud/clients/utils/__init__.py +1 -1
- hud/clients/utils/retry_transport.py +160 -160
- hud/datasets.py +327 -322
- hud/misc/__init__.py +1 -1
- hud/misc/claude_plays_pokemon.py +292 -292
- hud/otel/__init__.py +35 -35
- hud/otel/collector.py +142 -142
- hud/otel/config.py +164 -164
- hud/otel/context.py +536 -536
- hud/otel/exporters.py +366 -366
- hud/otel/instrumentation.py +97 -97
- hud/otel/processors.py +118 -118
- hud/otel/tests/__init__.py +1 -1
- hud/otel/tests/test_processors.py +197 -197
- hud/server/__init__.py +5 -5
- hud/server/context.py +114 -114
- hud/server/helper/__init__.py +5 -5
- hud/server/low_level.py +132 -132
- hud/server/server.py +170 -166
- hud/server/tests/__init__.py +3 -3
- hud/settings.py +73 -73
- hud/shared/__init__.py +5 -5
- hud/shared/exceptions.py +180 -180
- hud/shared/requests.py +264 -264
- hud/shared/tests/test_exceptions.py +157 -157
- hud/shared/tests/test_requests.py +275 -275
- hud/telemetry/__init__.py +25 -25
- hud/telemetry/instrument.py +379 -379
- hud/telemetry/job.py +309 -309
- hud/telemetry/replay.py +74 -74
- hud/telemetry/trace.py +83 -83
- hud/tools/__init__.py +33 -33
- hud/tools/base.py +365 -365
- hud/tools/bash.py +161 -161
- hud/tools/computer/__init__.py +15 -15
- hud/tools/computer/anthropic.py +437 -437
- hud/tools/computer/hud.py +376 -376
- hud/tools/computer/openai.py +295 -295
- hud/tools/computer/settings.py +82 -82
- hud/tools/edit.py +314 -314
- hud/tools/executors/__init__.py +30 -30
- hud/tools/executors/base.py +539 -539
- hud/tools/executors/pyautogui.py +621 -621
- hud/tools/executors/tests/__init__.py +1 -1
- hud/tools/executors/tests/test_base_executor.py +338 -338
- hud/tools/executors/tests/test_pyautogui_executor.py +165 -165
- hud/tools/executors/xdo.py +511 -511
- hud/tools/playwright.py +412 -412
- hud/tools/tests/__init__.py +3 -3
- hud/tools/tests/test_base.py +282 -282
- hud/tools/tests/test_bash.py +158 -158
- hud/tools/tests/test_bash_extended.py +197 -197
- hud/tools/tests/test_computer.py +425 -425
- hud/tools/tests/test_computer_actions.py +34 -34
- hud/tools/tests/test_edit.py +259 -259
- hud/tools/tests/test_init.py +27 -27
- hud/tools/tests/test_playwright_tool.py +183 -183
- hud/tools/tests/test_tools.py +145 -145
- hud/tools/tests/test_utils.py +156 -156
- hud/tools/types.py +72 -72
- hud/tools/utils.py +50 -50
- hud/types.py +136 -136
- hud/utils/__init__.py +10 -10
- hud/utils/async_utils.py +65 -65
- hud/utils/design.py +236 -168
- hud/utils/mcp.py +55 -55
- hud/utils/progress.py +149 -149
- hud/utils/telemetry.py +66 -66
- hud/utils/tests/test_async_utils.py +173 -173
- hud/utils/tests/test_init.py +17 -17
- hud/utils/tests/test_progress.py +261 -261
- hud/utils/tests/test_telemetry.py +82 -82
- hud/utils/tests/test_version.py +8 -8
- hud/version.py +7 -7
- {hud_python-0.4.1.dist-info → hud_python-0.4.3.dist-info}/METADATA +10 -8
- hud_python-0.4.3.dist-info/RECORD +131 -0
- {hud_python-0.4.1.dist-info → hud_python-0.4.3.dist-info}/licenses/LICENSE +21 -21
- hud/agents/art.py +0 -101
- hud_python-0.4.1.dist-info/RECORD +0 -132
- {hud_python-0.4.1.dist-info → hud_python-0.4.3.dist-info}/WHEEL +0 -0
- {hud_python-0.4.1.dist-info → hud_python-0.4.3.dist-info}/entry_points.txt +0 -0
|
@@ -1,157 +1,157 @@
|
|
|
1
|
-
"""Tests for server exceptions."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
from unittest.mock import MagicMock
|
|
6
|
-
|
|
7
|
-
import httpx
|
|
8
|
-
|
|
9
|
-
from hud.shared.exceptions import (
|
|
10
|
-
GymMakeException,
|
|
11
|
-
HudAuthenticationError,
|
|
12
|
-
HudException,
|
|
13
|
-
HudNetworkError,
|
|
14
|
-
HudRequestError,
|
|
15
|
-
HudTimeoutError,
|
|
16
|
-
)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class TestHudRequestError:
|
|
20
|
-
"""Test HudRequestError exception."""
|
|
21
|
-
|
|
22
|
-
def test_from_httpx_error_with_json_detail(self):
|
|
23
|
-
"""Test creating from httpx error with JSON detail."""
|
|
24
|
-
response = MagicMock()
|
|
25
|
-
response.status_code = 400
|
|
26
|
-
response.json.return_value = {"detail": "Bad request details"}
|
|
27
|
-
|
|
28
|
-
error = httpx.HTTPStatusError("Test", request=MagicMock(), response=response)
|
|
29
|
-
|
|
30
|
-
hud_error = HudRequestError.from_httpx_error(error, context="Test context")
|
|
31
|
-
|
|
32
|
-
assert hud_error.status_code == 400
|
|
33
|
-
assert "Test context" in str(hud_error)
|
|
34
|
-
assert "Bad request details" in str(hud_error)
|
|
35
|
-
|
|
36
|
-
def test_from_httpx_error_with_small_json_no_detail(self):
|
|
37
|
-
"""Test creating from httpx error with small JSON but no detail field."""
|
|
38
|
-
response = MagicMock()
|
|
39
|
-
response.status_code = 400
|
|
40
|
-
response.json.return_value = {"error": "test", "code": 123}
|
|
41
|
-
|
|
42
|
-
error = httpx.HTTPStatusError("Test", request=MagicMock(), response=response)
|
|
43
|
-
|
|
44
|
-
hud_error = HudRequestError.from_httpx_error(error)
|
|
45
|
-
|
|
46
|
-
assert hud_error.status_code == 400
|
|
47
|
-
assert "JSON response:" in str(hud_error)
|
|
48
|
-
# Check for the dictionary representation (not exact JSON string)
|
|
49
|
-
assert "'error': 'test'" in str(hud_error)
|
|
50
|
-
assert "'code': 123" in str(hud_error)
|
|
51
|
-
|
|
52
|
-
def test_from_httpx_error_json_parse_failure(self):
|
|
53
|
-
"""Test creating from httpx error when JSON parsing fails."""
|
|
54
|
-
response = MagicMock()
|
|
55
|
-
response.status_code = 500
|
|
56
|
-
response.json.side_effect = ValueError("Invalid JSON")
|
|
57
|
-
|
|
58
|
-
error = httpx.HTTPStatusError("Test", request=MagicMock(), response=response)
|
|
59
|
-
|
|
60
|
-
hud_error = HudRequestError.from_httpx_error(error)
|
|
61
|
-
|
|
62
|
-
assert hud_error.status_code == 500
|
|
63
|
-
assert "Request failed with status 500" in str(hud_error)
|
|
64
|
-
|
|
65
|
-
def test_from_httpx_error_large_json_response(self):
|
|
66
|
-
"""Test creating from httpx error with large JSON response."""
|
|
67
|
-
response = MagicMock()
|
|
68
|
-
response.status_code = 400
|
|
69
|
-
# Large JSON object (more than 5 keys)
|
|
70
|
-
response.json.return_value = {
|
|
71
|
-
"field1": "value1",
|
|
72
|
-
"field2": "value2",
|
|
73
|
-
"field3": "value3",
|
|
74
|
-
"field4": "value4",
|
|
75
|
-
"field5": "value5",
|
|
76
|
-
"field6": "value6",
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
error = httpx.HTTPStatusError("Test", request=MagicMock(), response=response)
|
|
80
|
-
|
|
81
|
-
hud_error = HudRequestError.from_httpx_error(error)
|
|
82
|
-
|
|
83
|
-
assert hud_error.status_code == 400
|
|
84
|
-
# Should not include JSON in message since it's large
|
|
85
|
-
assert "JSON response:" not in str(hud_error)
|
|
86
|
-
assert "Request failed with status 400" in str(hud_error)
|
|
87
|
-
|
|
88
|
-
def test_str_method(self):
|
|
89
|
-
"""Test string representation of HudRequestError."""
|
|
90
|
-
error = HudRequestError("Test error message", 404, '{"extra": "data"}')
|
|
91
|
-
|
|
92
|
-
error_str = str(error)
|
|
93
|
-
assert "Test error message" in error_str
|
|
94
|
-
assert "404" in error_str
|
|
95
|
-
assert "extra" in error_str
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
class TestHudNetworkError:
|
|
99
|
-
"""Test HudNetworkError exception."""
|
|
100
|
-
|
|
101
|
-
def test_initialization_and_str(self):
|
|
102
|
-
"""Test HudNetworkError initialization and string representation."""
|
|
103
|
-
error = HudNetworkError("Network failure: Connection refused")
|
|
104
|
-
|
|
105
|
-
error_str = str(error)
|
|
106
|
-
assert "Network failure" in error_str
|
|
107
|
-
assert "Connection refused" in error_str
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
class TestHudTimeoutError:
|
|
111
|
-
"""Test HudTimeoutError exception."""
|
|
112
|
-
|
|
113
|
-
def test_initialization(self):
|
|
114
|
-
"""Test HudTimeoutError initialization."""
|
|
115
|
-
error = HudTimeoutError("Request timed out after 30.0 seconds")
|
|
116
|
-
|
|
117
|
-
error_str = str(error)
|
|
118
|
-
assert "Request timed out" in error_str
|
|
119
|
-
assert "30.0" in error_str
|
|
120
|
-
|
|
121
|
-
def test_str_method(self):
|
|
122
|
-
"""Test string representation of HudTimeoutError."""
|
|
123
|
-
error = HudTimeoutError("Timeout occurred after 60.0 seconds")
|
|
124
|
-
|
|
125
|
-
error_str = str(error)
|
|
126
|
-
assert "Timeout occurred" in error_str
|
|
127
|
-
assert "60.0" in error_str
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
class TestHudAuthenticationError:
|
|
131
|
-
"""Test HudAuthenticationError exception."""
|
|
132
|
-
|
|
133
|
-
def test_inheritance(self):
|
|
134
|
-
"""Test that HudAuthenticationError inherits from HudException."""
|
|
135
|
-
error = HudAuthenticationError("Auth failed")
|
|
136
|
-
|
|
137
|
-
assert isinstance(error, HudException)
|
|
138
|
-
error_str = str(error)
|
|
139
|
-
assert "Auth failed" in error_str
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
class TestGymMakeException:
|
|
143
|
-
"""Test GymMakeException."""
|
|
144
|
-
|
|
145
|
-
def test_initialization_and_str(self):
|
|
146
|
-
"""Test GymMakeException initialization and string representation."""
|
|
147
|
-
data = {"env_id": "test-env", "error": "invalid config"}
|
|
148
|
-
error = GymMakeException("Failed to create environment", data)
|
|
149
|
-
|
|
150
|
-
assert error.data == data
|
|
151
|
-
|
|
152
|
-
error_str = str(error)
|
|
153
|
-
assert "Failed to create environment" in error_str
|
|
154
|
-
assert "Data:" in error_str
|
|
155
|
-
assert "env_id" in error_str
|
|
156
|
-
assert "test-env" in error_str
|
|
157
|
-
assert "invalid config" in error_str
|
|
1
|
+
"""Tests for server exceptions."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from unittest.mock import MagicMock
|
|
6
|
+
|
|
7
|
+
import httpx
|
|
8
|
+
|
|
9
|
+
from hud.shared.exceptions import (
|
|
10
|
+
GymMakeException,
|
|
11
|
+
HudAuthenticationError,
|
|
12
|
+
HudException,
|
|
13
|
+
HudNetworkError,
|
|
14
|
+
HudRequestError,
|
|
15
|
+
HudTimeoutError,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class TestHudRequestError:
|
|
20
|
+
"""Test HudRequestError exception."""
|
|
21
|
+
|
|
22
|
+
def test_from_httpx_error_with_json_detail(self):
|
|
23
|
+
"""Test creating from httpx error with JSON detail."""
|
|
24
|
+
response = MagicMock()
|
|
25
|
+
response.status_code = 400
|
|
26
|
+
response.json.return_value = {"detail": "Bad request details"}
|
|
27
|
+
|
|
28
|
+
error = httpx.HTTPStatusError("Test", request=MagicMock(), response=response)
|
|
29
|
+
|
|
30
|
+
hud_error = HudRequestError.from_httpx_error(error, context="Test context")
|
|
31
|
+
|
|
32
|
+
assert hud_error.status_code == 400
|
|
33
|
+
assert "Test context" in str(hud_error)
|
|
34
|
+
assert "Bad request details" in str(hud_error)
|
|
35
|
+
|
|
36
|
+
def test_from_httpx_error_with_small_json_no_detail(self):
|
|
37
|
+
"""Test creating from httpx error with small JSON but no detail field."""
|
|
38
|
+
response = MagicMock()
|
|
39
|
+
response.status_code = 400
|
|
40
|
+
response.json.return_value = {"error": "test", "code": 123}
|
|
41
|
+
|
|
42
|
+
error = httpx.HTTPStatusError("Test", request=MagicMock(), response=response)
|
|
43
|
+
|
|
44
|
+
hud_error = HudRequestError.from_httpx_error(error)
|
|
45
|
+
|
|
46
|
+
assert hud_error.status_code == 400
|
|
47
|
+
assert "JSON response:" in str(hud_error)
|
|
48
|
+
# Check for the dictionary representation (not exact JSON string)
|
|
49
|
+
assert "'error': 'test'" in str(hud_error)
|
|
50
|
+
assert "'code': 123" in str(hud_error)
|
|
51
|
+
|
|
52
|
+
def test_from_httpx_error_json_parse_failure(self):
|
|
53
|
+
"""Test creating from httpx error when JSON parsing fails."""
|
|
54
|
+
response = MagicMock()
|
|
55
|
+
response.status_code = 500
|
|
56
|
+
response.json.side_effect = ValueError("Invalid JSON")
|
|
57
|
+
|
|
58
|
+
error = httpx.HTTPStatusError("Test", request=MagicMock(), response=response)
|
|
59
|
+
|
|
60
|
+
hud_error = HudRequestError.from_httpx_error(error)
|
|
61
|
+
|
|
62
|
+
assert hud_error.status_code == 500
|
|
63
|
+
assert "Request failed with status 500" in str(hud_error)
|
|
64
|
+
|
|
65
|
+
def test_from_httpx_error_large_json_response(self):
|
|
66
|
+
"""Test creating from httpx error with large JSON response."""
|
|
67
|
+
response = MagicMock()
|
|
68
|
+
response.status_code = 400
|
|
69
|
+
# Large JSON object (more than 5 keys)
|
|
70
|
+
response.json.return_value = {
|
|
71
|
+
"field1": "value1",
|
|
72
|
+
"field2": "value2",
|
|
73
|
+
"field3": "value3",
|
|
74
|
+
"field4": "value4",
|
|
75
|
+
"field5": "value5",
|
|
76
|
+
"field6": "value6",
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
error = httpx.HTTPStatusError("Test", request=MagicMock(), response=response)
|
|
80
|
+
|
|
81
|
+
hud_error = HudRequestError.from_httpx_error(error)
|
|
82
|
+
|
|
83
|
+
assert hud_error.status_code == 400
|
|
84
|
+
# Should not include JSON in message since it's large
|
|
85
|
+
assert "JSON response:" not in str(hud_error)
|
|
86
|
+
assert "Request failed with status 400" in str(hud_error)
|
|
87
|
+
|
|
88
|
+
def test_str_method(self):
|
|
89
|
+
"""Test string representation of HudRequestError."""
|
|
90
|
+
error = HudRequestError("Test error message", 404, '{"extra": "data"}')
|
|
91
|
+
|
|
92
|
+
error_str = str(error)
|
|
93
|
+
assert "Test error message" in error_str
|
|
94
|
+
assert "404" in error_str
|
|
95
|
+
assert "extra" in error_str
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class TestHudNetworkError:
|
|
99
|
+
"""Test HudNetworkError exception."""
|
|
100
|
+
|
|
101
|
+
def test_initialization_and_str(self):
|
|
102
|
+
"""Test HudNetworkError initialization and string representation."""
|
|
103
|
+
error = HudNetworkError("Network failure: Connection refused")
|
|
104
|
+
|
|
105
|
+
error_str = str(error)
|
|
106
|
+
assert "Network failure" in error_str
|
|
107
|
+
assert "Connection refused" in error_str
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class TestHudTimeoutError:
|
|
111
|
+
"""Test HudTimeoutError exception."""
|
|
112
|
+
|
|
113
|
+
def test_initialization(self):
|
|
114
|
+
"""Test HudTimeoutError initialization."""
|
|
115
|
+
error = HudTimeoutError("Request timed out after 30.0 seconds")
|
|
116
|
+
|
|
117
|
+
error_str = str(error)
|
|
118
|
+
assert "Request timed out" in error_str
|
|
119
|
+
assert "30.0" in error_str
|
|
120
|
+
|
|
121
|
+
def test_str_method(self):
|
|
122
|
+
"""Test string representation of HudTimeoutError."""
|
|
123
|
+
error = HudTimeoutError("Timeout occurred after 60.0 seconds")
|
|
124
|
+
|
|
125
|
+
error_str = str(error)
|
|
126
|
+
assert "Timeout occurred" in error_str
|
|
127
|
+
assert "60.0" in error_str
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
class TestHudAuthenticationError:
|
|
131
|
+
"""Test HudAuthenticationError exception."""
|
|
132
|
+
|
|
133
|
+
def test_inheritance(self):
|
|
134
|
+
"""Test that HudAuthenticationError inherits from HudException."""
|
|
135
|
+
error = HudAuthenticationError("Auth failed")
|
|
136
|
+
|
|
137
|
+
assert isinstance(error, HudException)
|
|
138
|
+
error_str = str(error)
|
|
139
|
+
assert "Auth failed" in error_str
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
class TestGymMakeException:
|
|
143
|
+
"""Test GymMakeException."""
|
|
144
|
+
|
|
145
|
+
def test_initialization_and_str(self):
|
|
146
|
+
"""Test GymMakeException initialization and string representation."""
|
|
147
|
+
data = {"env_id": "test-env", "error": "invalid config"}
|
|
148
|
+
error = GymMakeException("Failed to create environment", data)
|
|
149
|
+
|
|
150
|
+
assert error.data == data
|
|
151
|
+
|
|
152
|
+
error_str = str(error)
|
|
153
|
+
assert "Failed to create environment" in error_str
|
|
154
|
+
assert "Data:" in error_str
|
|
155
|
+
assert "env_id" in error_str
|
|
156
|
+
assert "test-env" in error_str
|
|
157
|
+
assert "invalid config" in error_str
|