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.

Files changed (130) hide show
  1. hud/__init__.py +22 -22
  2. hud/agents/__init__.py +13 -15
  3. hud/agents/base.py +599 -599
  4. hud/agents/claude.py +373 -373
  5. hud/agents/langchain.py +261 -250
  6. hud/agents/misc/__init__.py +7 -7
  7. hud/agents/misc/response_agent.py +82 -80
  8. hud/agents/openai.py +352 -352
  9. hud/agents/openai_chat_generic.py +154 -154
  10. hud/agents/tests/__init__.py +1 -1
  11. hud/agents/tests/test_base.py +742 -742
  12. hud/agents/tests/test_claude.py +324 -324
  13. hud/agents/tests/test_client.py +363 -363
  14. hud/agents/tests/test_openai.py +237 -237
  15. hud/cli/__init__.py +617 -617
  16. hud/cli/__main__.py +8 -8
  17. hud/cli/analyze.py +371 -371
  18. hud/cli/analyze_metadata.py +230 -230
  19. hud/cli/build.py +498 -427
  20. hud/cli/clone.py +185 -185
  21. hud/cli/cursor.py +92 -92
  22. hud/cli/debug.py +392 -392
  23. hud/cli/docker_utils.py +83 -83
  24. hud/cli/init.py +280 -281
  25. hud/cli/interactive.py +353 -353
  26. hud/cli/mcp_server.py +764 -756
  27. hud/cli/pull.py +330 -336
  28. hud/cli/push.py +404 -370
  29. hud/cli/remote_runner.py +311 -311
  30. hud/cli/runner.py +160 -160
  31. hud/cli/tests/__init__.py +3 -3
  32. hud/cli/tests/test_analyze.py +284 -284
  33. hud/cli/tests/test_cli_init.py +265 -265
  34. hud/cli/tests/test_cli_main.py +27 -27
  35. hud/cli/tests/test_clone.py +142 -142
  36. hud/cli/tests/test_cursor.py +253 -253
  37. hud/cli/tests/test_debug.py +453 -453
  38. hud/cli/tests/test_mcp_server.py +139 -139
  39. hud/cli/tests/test_utils.py +388 -388
  40. hud/cli/utils.py +263 -263
  41. hud/clients/README.md +143 -143
  42. hud/clients/__init__.py +16 -16
  43. hud/clients/base.py +378 -379
  44. hud/clients/fastmcp.py +222 -222
  45. hud/clients/mcp_use.py +298 -278
  46. hud/clients/tests/__init__.py +1 -1
  47. hud/clients/tests/test_client_integration.py +111 -111
  48. hud/clients/tests/test_fastmcp.py +342 -342
  49. hud/clients/tests/test_protocol.py +188 -188
  50. hud/clients/utils/__init__.py +1 -1
  51. hud/clients/utils/retry_transport.py +160 -160
  52. hud/datasets.py +327 -322
  53. hud/misc/__init__.py +1 -1
  54. hud/misc/claude_plays_pokemon.py +292 -292
  55. hud/otel/__init__.py +35 -35
  56. hud/otel/collector.py +142 -142
  57. hud/otel/config.py +164 -164
  58. hud/otel/context.py +536 -536
  59. hud/otel/exporters.py +366 -366
  60. hud/otel/instrumentation.py +97 -97
  61. hud/otel/processors.py +118 -118
  62. hud/otel/tests/__init__.py +1 -1
  63. hud/otel/tests/test_processors.py +197 -197
  64. hud/server/__init__.py +5 -5
  65. hud/server/context.py +114 -114
  66. hud/server/helper/__init__.py +5 -5
  67. hud/server/low_level.py +132 -132
  68. hud/server/server.py +170 -166
  69. hud/server/tests/__init__.py +3 -3
  70. hud/settings.py +73 -73
  71. hud/shared/__init__.py +5 -5
  72. hud/shared/exceptions.py +180 -180
  73. hud/shared/requests.py +264 -264
  74. hud/shared/tests/test_exceptions.py +157 -157
  75. hud/shared/tests/test_requests.py +275 -275
  76. hud/telemetry/__init__.py +25 -25
  77. hud/telemetry/instrument.py +379 -379
  78. hud/telemetry/job.py +309 -309
  79. hud/telemetry/replay.py +74 -74
  80. hud/telemetry/trace.py +83 -83
  81. hud/tools/__init__.py +33 -33
  82. hud/tools/base.py +365 -365
  83. hud/tools/bash.py +161 -161
  84. hud/tools/computer/__init__.py +15 -15
  85. hud/tools/computer/anthropic.py +437 -437
  86. hud/tools/computer/hud.py +376 -376
  87. hud/tools/computer/openai.py +295 -295
  88. hud/tools/computer/settings.py +82 -82
  89. hud/tools/edit.py +314 -314
  90. hud/tools/executors/__init__.py +30 -30
  91. hud/tools/executors/base.py +539 -539
  92. hud/tools/executors/pyautogui.py +621 -621
  93. hud/tools/executors/tests/__init__.py +1 -1
  94. hud/tools/executors/tests/test_base_executor.py +338 -338
  95. hud/tools/executors/tests/test_pyautogui_executor.py +165 -165
  96. hud/tools/executors/xdo.py +511 -511
  97. hud/tools/playwright.py +412 -412
  98. hud/tools/tests/__init__.py +3 -3
  99. hud/tools/tests/test_base.py +282 -282
  100. hud/tools/tests/test_bash.py +158 -158
  101. hud/tools/tests/test_bash_extended.py +197 -197
  102. hud/tools/tests/test_computer.py +425 -425
  103. hud/tools/tests/test_computer_actions.py +34 -34
  104. hud/tools/tests/test_edit.py +259 -259
  105. hud/tools/tests/test_init.py +27 -27
  106. hud/tools/tests/test_playwright_tool.py +183 -183
  107. hud/tools/tests/test_tools.py +145 -145
  108. hud/tools/tests/test_utils.py +156 -156
  109. hud/tools/types.py +72 -72
  110. hud/tools/utils.py +50 -50
  111. hud/types.py +136 -136
  112. hud/utils/__init__.py +10 -10
  113. hud/utils/async_utils.py +65 -65
  114. hud/utils/design.py +236 -168
  115. hud/utils/mcp.py +55 -55
  116. hud/utils/progress.py +149 -149
  117. hud/utils/telemetry.py +66 -66
  118. hud/utils/tests/test_async_utils.py +173 -173
  119. hud/utils/tests/test_init.py +17 -17
  120. hud/utils/tests/test_progress.py +261 -261
  121. hud/utils/tests/test_telemetry.py +82 -82
  122. hud/utils/tests/test_version.py +8 -8
  123. hud/version.py +7 -7
  124. {hud_python-0.4.1.dist-info → hud_python-0.4.3.dist-info}/METADATA +10 -8
  125. hud_python-0.4.3.dist-info/RECORD +131 -0
  126. {hud_python-0.4.1.dist-info → hud_python-0.4.3.dist-info}/licenses/LICENSE +21 -21
  127. hud/agents/art.py +0 -101
  128. hud_python-0.4.1.dist-info/RECORD +0 -132
  129. {hud_python-0.4.1.dist-info → hud_python-0.4.3.dist-info}/WHEEL +0 -0
  130. {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