hud-python 0.4.0__py3-none-any.whl → 0.4.2__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 -17
  3. hud/agents/base.py +599 -599
  4. hud/agents/claude.py +373 -373
  5. hud/agents/langchain.py +250 -250
  6. hud/agents/misc/__init__.py +7 -7
  7. hud/agents/misc/response_agent.py +80 -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 +427 -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 +281 -281
  25. hud/cli/interactive.py +353 -353
  26. hud/cli/mcp_server.py +789 -756
  27. hud/cli/pull.py +336 -336
  28. hud/cli/push.py +370 -379
  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 +379 -354
  44. hud/clients/fastmcp.py +202 -202
  45. hud/clients/mcp_use.py +278 -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 +322 -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 +168 -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.0.dist-info → hud_python-0.4.2.dist-info}/METADATA +23 -19
  125. hud_python-0.4.2.dist-info/RECORD +131 -0
  126. {hud_python-0.4.0.dist-info → hud_python-0.4.2.dist-info}/licenses/LICENSE +21 -21
  127. hud/agents/art.py +0 -101
  128. hud_python-0.4.0.dist-info/RECORD +0 -132
  129. {hud_python-0.4.0.dist-info → hud_python-0.4.2.dist-info}/WHEEL +0 -0
  130. {hud_python-0.4.0.dist-info → hud_python-0.4.2.dist-info}/entry_points.txt +0 -0
@@ -1,82 +1,82 @@
1
- from __future__ import annotations
2
-
3
- from unittest.mock import patch
4
-
5
- from hud.utils.telemetry import stream
6
-
7
-
8
- def test_stream():
9
- html_content = stream("https://example.com")
10
- assert html_content is not None
11
- assert "<div style=" in html_content
12
- assert 'src="https://example.com"' in html_content
13
-
14
-
15
- def test_stream_with_display_exception():
16
- """Test stream when IPython display raises an exception."""
17
- with (
18
- patch("IPython.display.display", side_effect=Exception("Display error")),
19
- patch("hud.utils.telemetry.logger") as mock_logger,
20
- ):
21
- html_content = stream("https://example.com")
22
-
23
- # Should still return the HTML content
24
- assert html_content is not None
25
- assert 'src="https://example.com"' in html_content
26
-
27
- # Should log the warning
28
- mock_logger.warning.assert_called_once()
29
- args = mock_logger.warning.call_args[0]
30
- assert "Display error" in str(args[0])
31
-
32
-
33
- def test_display_screenshot():
34
- from hud.utils.telemetry import display_screenshot
35
-
36
- # This is a simple 1x1 transparent PNG image in base64 format
37
- base64_image = (
38
- "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQ"
39
- "AAABJRU5ErkJggg=="
40
- )
41
-
42
- html_content = display_screenshot(base64_image)
43
- assert html_content is not None
44
- assert "<div style=" in html_content
45
- assert "width: 960px" in html_content
46
- assert "height: 540px" in html_content
47
- assert f"data:image/png;base64,{base64_image}" in html_content
48
-
49
- # Test with custom dimensions
50
- custom_html = display_screenshot(base64_image, width=800, height=600)
51
- assert "width: 800px" in custom_html
52
- assert "height: 600px" in custom_html
53
-
54
- # Test with data URI already included
55
- data_uri = f"data:image/png;base64,{base64_image}"
56
- uri_html = display_screenshot(data_uri)
57
- assert data_uri in uri_html
58
-
59
-
60
- def test_display_screenshot_with_exception():
61
- """Test display_screenshot when IPython display raises an exception."""
62
- from hud.utils.telemetry import display_screenshot
63
-
64
- base64_image = (
65
- "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQ"
66
- "AAABJRU5ErkJggg=="
67
- )
68
-
69
- with (
70
- patch("IPython.display.display", side_effect=Exception("Display error")),
71
- patch("hud.utils.telemetry.logger") as mock_logger,
72
- ):
73
- html_content = display_screenshot(base64_image)
74
-
75
- # Should still return the HTML content
76
- assert html_content is not None
77
- assert f"data:image/png;base64,{base64_image}" in html_content
78
-
79
- # Should log the warning
80
- mock_logger.warning.assert_called_once()
81
- args = mock_logger.warning.call_args[0]
82
- assert "Display error" in str(args[0])
1
+ from __future__ import annotations
2
+
3
+ from unittest.mock import patch
4
+
5
+ from hud.utils.telemetry import stream
6
+
7
+
8
+ def test_stream():
9
+ html_content = stream("https://example.com")
10
+ assert html_content is not None
11
+ assert "<div style=" in html_content
12
+ assert 'src="https://example.com"' in html_content
13
+
14
+
15
+ def test_stream_with_display_exception():
16
+ """Test stream when IPython display raises an exception."""
17
+ with (
18
+ patch("IPython.display.display", side_effect=Exception("Display error")),
19
+ patch("hud.utils.telemetry.logger") as mock_logger,
20
+ ):
21
+ html_content = stream("https://example.com")
22
+
23
+ # Should still return the HTML content
24
+ assert html_content is not None
25
+ assert 'src="https://example.com"' in html_content
26
+
27
+ # Should log the warning
28
+ mock_logger.warning.assert_called_once()
29
+ args = mock_logger.warning.call_args[0]
30
+ assert "Display error" in str(args[0])
31
+
32
+
33
+ def test_display_screenshot():
34
+ from hud.utils.telemetry import display_screenshot
35
+
36
+ # This is a simple 1x1 transparent PNG image in base64 format
37
+ base64_image = (
38
+ "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQ"
39
+ "AAABJRU5ErkJggg=="
40
+ )
41
+
42
+ html_content = display_screenshot(base64_image)
43
+ assert html_content is not None
44
+ assert "<div style=" in html_content
45
+ assert "width: 960px" in html_content
46
+ assert "height: 540px" in html_content
47
+ assert f"data:image/png;base64,{base64_image}" in html_content
48
+
49
+ # Test with custom dimensions
50
+ custom_html = display_screenshot(base64_image, width=800, height=600)
51
+ assert "width: 800px" in custom_html
52
+ assert "height: 600px" in custom_html
53
+
54
+ # Test with data URI already included
55
+ data_uri = f"data:image/png;base64,{base64_image}"
56
+ uri_html = display_screenshot(data_uri)
57
+ assert data_uri in uri_html
58
+
59
+
60
+ def test_display_screenshot_with_exception():
61
+ """Test display_screenshot when IPython display raises an exception."""
62
+ from hud.utils.telemetry import display_screenshot
63
+
64
+ base64_image = (
65
+ "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQ"
66
+ "AAABJRU5ErkJggg=="
67
+ )
68
+
69
+ with (
70
+ patch("IPython.display.display", side_effect=Exception("Display error")),
71
+ patch("hud.utils.telemetry.logger") as mock_logger,
72
+ ):
73
+ html_content = display_screenshot(base64_image)
74
+
75
+ # Should still return the HTML content
76
+ assert html_content is not None
77
+ assert f"data:image/png;base64,{base64_image}" in html_content
78
+
79
+ # Should log the warning
80
+ mock_logger.warning.assert_called_once()
81
+ args = mock_logger.warning.call_args[0]
82
+ assert "Display error" in str(args[0])
@@ -1,8 +1,8 @@
1
- from __future__ import annotations
2
-
3
-
4
- def test_import():
5
- """Test that the package can be imported."""
6
- import hud
7
-
8
- assert hud.__version__ == "0.4.0"
1
+ from __future__ import annotations
2
+
3
+
4
+ def test_import():
5
+ """Test that the package can be imported."""
6
+ import hud
7
+
8
+ assert hud.__version__ == "0.4.2"
hud/version.py CHANGED
@@ -1,7 +1,7 @@
1
- """
2
- Version information for the HUD SDK.
3
- """
4
-
5
- from __future__ import annotations
6
-
7
- __version__ = "0.4.0"
1
+ """
2
+ Version information for the HUD SDK.
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ __version__ = "0.4.2"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hud-python
3
- Version: 0.4.0
3
+ Version: 0.4.2
4
4
  Summary: SDK for the HUD platform.
5
5
  Project-URL: Homepage, https://github.com/hud-evals/hud-python
6
6
  Project-URL: Bug Tracker, https://github.com/hud-evals/hud-python/issues
@@ -114,10 +114,10 @@ OSS RL environment + evals toolkit. Wrap software as environments, run benchmark
114
114
 
115
115
  ## Highlights
116
116
 
117
- - 🚀 **[MCP-native connectivity](https://docs.hud.so/core-concepts/mcp-protocol)** – any agent can call any hud environment.
117
+ - 🚀 **[MCP environment skeleton](https://docs.hud.so/core-concepts/mcp-protocol)** – any agent can call any environment.
118
118
  - ⚡️ **[Live telemetry](https://app.hud.so)** – inspect every tool call, observation, and reward in real time.
119
119
  - 🗂️ **[Public benchmarks](https://app.hud.so/leaderboards)** – OSWorld-Verified, SheetBench-50, and more.
120
- - 🌱 **[Reinforcement learning built-in](rl/)** – Verifiers gym pipelines for GRPO training.
120
+ - 🌱 **[Reinforcement learning built-in](rl/)** – Verifiers gym pipelines for GRPO on any environment.
121
121
  - 🌐 **[Cloud browsers](environments/remote_browser/)** – AnchorBrowser, Steel, BrowserBase integrations for browser automation.
122
122
  - 🛠️ **[Hot-reload dev loop](environments/README.md#phase-5-hot-reload-development-with-cursor-agent)** – `hud dev` for iterating on environments without rebuilds.
123
123
 
@@ -129,11 +129,12 @@ OSS RL environment + evals toolkit. Wrap software as environments, run benchmark
129
129
  # Core installation - MCP servers, telemetry, basic tools for environment design
130
130
  pip install hud-python
131
131
 
132
- # Agent installation - Adds AI providers, telemetry, datasets
132
+ # Agent installation - Adds AI providers, datasets
133
133
  pip install "hud-python[agent]"
134
134
 
135
135
  # CLI utilities
136
136
  uv tool install hud-python
137
+ # uv tool update-shell
137
138
 
138
139
  # From source (latest)
139
140
  git clone https://github.com/hud-evals/hud-python
@@ -151,7 +152,7 @@ For a tutorial that explains the agent and evaluation design, run ([see quicksta
151
152
  uvx hud-python quickstart
152
153
  ```
153
154
 
154
- Or just write your own agent loop (more [examples here](examples/)):
155
+ Or just write your own agent loop (more [examples here](examples/)).
155
156
 
156
157
  ```python
157
158
  import asyncio, hud, os
@@ -162,19 +163,20 @@ from hud.datasets import Task # See docs: https://docs.hud.so/reference/tasks
162
163
 
163
164
  async def main() -> None:
164
165
  with hud.trace("Quick Start 2048"): # All telemetry works for any MCP-based agent (see https://app.hud.so)
165
- task = Task(
166
- prompt="Reach 64 in 2048.",
167
- mcp_config={
166
+ task = {
167
+ "prompt": "Reach 64 in 2048.",
168
+ "mcp_config": {
168
169
  "hud": {
169
- "url": "https://mcp.hud.so", # HUD's cloud MCP server (see https://docs.hud.so/core-concepts/architecture)
170
+ "url": "https://mcp.hud.so/v3/mcp", # HUD's cloud MCP server (see https://docs.hud.so/core-concepts/architecture)
170
171
  "headers": {
171
- "Authorization": f"Bearer {os.getenv('HUD_API_KEY')}", # Get your key at https://app.hud.so
172
- "Mcp-Image": "hudpython/hud-text-2048:v1.1" # Docker image from https://hub.docker.com/u/hudpython
172
+ "Authorization": f"Bearer {settings.api_key}", # Get your key at https://app.hud.so
173
+ "Mcp-Image": "hudpython/hud-text-2048:v1.2" # Docker image from https://hub.docker.com/u/hudpython
173
174
  }
174
175
  }
175
176
  },
176
- evaluate_tool={"name": "evaluate", "arguments": {"name": "max_number", "target": 64}},
177
- )
177
+ "evaluate_tool": {"name": "evaluate", "arguments": {"name": "max_number", "arguments": {"target": 64}}},
178
+ }
179
+ task = Task(**task)
178
180
 
179
181
  # 1. Define the client explicitly:
180
182
  client = MCPClient(mcp_config=task.mcp_config)
@@ -189,16 +191,18 @@ async def main() -> None:
189
191
  # result = await ClaudeAgent().run(task)
190
192
 
191
193
  print(f"Reward: {result.reward}")
192
- await client.close()
194
+ await client.shutdown()
193
195
 
194
196
  asyncio.run(main())
195
197
  ```
196
198
 
197
- > Every HUD environment is MCP-based and interactable from anywhere. Requires `HUD_API_KEY` and `ANTHROPIC_API_KEY`.
199
+ The above example let's the agent play 2048 ([See replay](https://app.hud.so/trace/6feed7bd-5f67-4d66-b77f-eb1e3164604f))
200
+
201
+ ![Agent playing 2048](https://raw.githubusercontent.com/hud-evals/hud-python/main/docs/src/images/2048_1.gif)
198
202
 
199
203
  ## Reinforcement Learning with GRPO
200
204
 
201
- This is a Qwen-2.5-3B agent training a policy on the [`text-2048`](environments/text_2048/) environment using [Verifiers](rl/verifiers/):
205
+ This is a Qwen-2.5-3B agent training a policy on the [`text-2048`](environments/text_2048/) environment (see above) using [Verifiers](rl/README):
202
206
 
203
207
  ![RL curve](https://raw.githubusercontent.com/hud-evals/hud-python/main/docs/src/images/rl_2.png)
204
208
 
@@ -206,8 +210,8 @@ To start training, check out the [`rl/README.md`](rl/README.md) folder:
206
210
 
207
211
  ```bash
208
212
  git clone https://github.com/hud-evals/hud-python
209
- cd hud-python
210
- python rl/verifiers/train_2048.py
213
+ cd hud-python/rl
214
+ python train_2048.py
211
215
  ```
212
216
 
213
217
  Any hud MCP environment and evaluation works with our RL pipeline. Even our remote configurations!
@@ -346,7 +350,7 @@ result = await ClaudeAgent().run({ # See all agents: https://docs.hud.so/refere
346
350
  "prompt": "Please explore this environment",
347
351
  "mcp_config": {
348
352
  "my-environment": {
349
- "url": "https://mcp.hud.so",
353
+ "url": "https://mcp.hud.so/v3/mcp",
350
354
  "headers": {
351
355
  "Authorization": f"Bearer {os.getenv('HUD_API_KEY')}",
352
356
  "Mcp-Image": "my-name/my-environment:latest"
@@ -0,0 +1,131 @@
1
+ hud/__init__.py,sha256=BjAhZtsHbGN371Q8t3o4v4jltedkmDE85xW0yOILU9g,397
2
+ hud/datasets.py,sha256=3QIZyAdbzlSghE44EIhehWOAoE8CPvLyS40FM2X2a4U,11892
3
+ hud/settings.py,sha256=WIJDsyrfwBZGcaGT46YUOpW8xjBZl3siXXprd92ASAg,2039
4
+ hud/types.py,sha256=pQWOPYXUZ2hhK0h-AHBc3DCj5tkbRXHqKZnsQQIcSFA,4237
5
+ hud/version.py,sha256=npIZLGW0QouBuUp2GO8yLq33HW7-l4Zd9UXWHtiYJos,104
6
+ hud/agents/__init__.py,sha256=UoIkljWdbq4bM0LD-mSaw6w826EqdEjOk7r6glNYwYQ,286
7
+ hud/agents/base.py,sha256=OdvuPMMZFGMft5PEkImjs_nWi-05hJyGJMBSOGbtxBo,22258
8
+ hud/agents/claude.py,sha256=snbYFPW-KAkw4n9Rdz7dC2f46RuSHJKC53HPm8SucFM,14273
9
+ hud/agents/langchain.py,sha256=FTofalIKYZEM7W2AQ1OErk8Jdo47V4tDT7xaiR8RDsA,9129
10
+ hud/agents/openai.py,sha256=kHG73mohO4uru49qmQiygUFt0eDCGJU06weqIUwTO3Y,14323
11
+ hud/agents/openai_chat_generic.py,sha256=jTJ-KY6HkglPK0iwZH5v3PVnaUjDsWc9IbRo3AbXlyE,5322
12
+ hud/agents/misc/__init__.py,sha256=BYi4Ytp9b_vycpZFXnr5Oyw6ncKLNNGml8Jrb7bWUb4,136
13
+ hud/agents/misc/response_agent.py,sha256=qqvRSH-e5NaLXXUFSt3aXZauDE8JlWAabMymrJr9bd4,3036
14
+ hud/agents/tests/__init__.py,sha256=W-O-_4i34d9TTyEHV-O_q1Ai1gLhzwDaaPo02_TWQIY,34
15
+ hud/agents/tests/test_base.py,sha256=F39ajSqASGUbPyPoWSY9KARFav62qNTK74W11Tr1Tg4,28970
16
+ hud/agents/tests/test_claude.py,sha256=wqEKlzEvx8obz1sSm4NY0j-Zyt1qWNfDOmRqYIuAEd0,13069
17
+ hud/agents/tests/test_client.py,sha256=Sk5bGZw2hL5GsVi2LMp9tsLngl5ZQ18pkpeeQmts0ao,13908
18
+ hud/agents/tests/test_openai.py,sha256=VcAUMcmwWttOxy9CCSu8QFIvAHG8ZMLUdQMeP04oK9Q,9026
19
+ hud/cli/__init__.py,sha256=IsP148YyCod5gC-CduIN6MGGCLsITBe-kEtzE4NqbLo,21734
20
+ hud/cli/__main__.py,sha256=fDH7XITyuDITwSDIVwRso06aouADO0CzTHKqp5TOwJE,143
21
+ hud/cli/analyze.py,sha256=G-tjT1xLPLcYhDhZEaI7TAIS0z0OACUksnGFoAWd2ag,14416
22
+ hud/cli/analyze_metadata.py,sha256=Mgs_je-XbPulG6noRLRNXe3_3a1eb20Cvxz5OQJ2NeU,8262
23
+ hud/cli/build.py,sha256=4wMigENf6dpL9Eu0wN9SvgGWMHIh85IEJ1WKuNyVrfs,14263
24
+ hud/cli/clone.py,sha256=AwVDIuhr8mHb1oT2Af2HrD25SiTdwATpE6zd93vzLgA,6099
25
+ hud/cli/cursor.py,sha256=fy850p0rVp5k_1wwOCI7rK1SggbselJrywFInSQ2gio,3009
26
+ hud/cli/debug.py,sha256=pa24bP4KVE0vdvrODuN57i2t8YDHxKJgwzXy7eD2tBE,13613
27
+ hud/cli/docker_utils.py,sha256=5k5sXtI4V5d4VWRJR6lzVRy_Hu8Wf1nLsmW-dBNW0cM,2695
28
+ hud/cli/init.py,sha256=wbGfKx-A17mSYw1aubRT3Ggt12A3PIkvZL6aW0AxoxU,7780
29
+ hud/cli/interactive.py,sha256=w1fAoefizNKqjcl5Fi5EgEsUdPpXKcCFuU-Z-S3CL9o,12863
30
+ hud/cli/mcp_server.py,sha256=ZdJA8M8DtLvda4xQOQ0MuEOTvRR8_ZEIaIW-Qs8DfZ0,29609
31
+ hud/cli/pull.py,sha256=SmbaHXaDKgazovYbw4we1og1qtT-B4opEjiDOlaNZcs,11939
32
+ hud/cli/push.py,sha256=Cbjiy0AAcvgFcatAz3H2t3IhxsHMbLlc0WcdQwXe9V0,14163
33
+ hud/cli/remote_runner.py,sha256=X01x6DeVkyc9HgxVCGEZJxEhhVPvHpAMoeYR44R8_BQ,9405
34
+ hud/cli/runner.py,sha256=ukEr6ZmD5rs-taoEBu0P_-hr275d-ZE5_WAR-dvSqrw,4888
35
+ hud/cli/utils.py,sha256=ZgjjKVPAa7dcfJ6SMBrdfZ63d1UnnhYC-zeh7gFBXsI,8841
36
+ hud/cli/tests/__init__.py,sha256=ZrGVkmH7DHXGqOvjOSNGZeMYaFIRB2K8c6hwr8FPJ-8,68
37
+ hud/cli/tests/test_analyze.py,sha256=1VGIjpvZXD6N4j2yRoVddug2jQ6tJn41NWw-ScAVztw,10971
38
+ hud/cli/tests/test_cli_init.py,sha256=_H0bAn5_skJ91Zj8P5P_wtZoPWvrN7jMhPZvmnnf0n8,11289
39
+ hud/cli/tests/test_cli_main.py,sha256=0wMho9p9NcGjp0jLiUtCQh_FYdbMaCJtSY3sBbSgPwA,697
40
+ hud/cli/tests/test_clone.py,sha256=oC2mf-41QQVc7ODJkjrWbVPNMB2fDW3nZ6jY6w93gvQ,4458
41
+ hud/cli/tests/test_cursor.py,sha256=cvQ6dudMGmY4LifaJKm9iRIRvqvbFwibZgowd5goWPY,9815
42
+ hud/cli/tests/test_debug.py,sha256=FPKWeKgOSBXoMyRphb0Q52QiJSNbGAS40f9r3ZVSMBE,18028
43
+ hud/cli/tests/test_mcp_server.py,sha256=e5fh6AUcqdv0jp0rJ8VL-DdJ-1nNgS85N8Ua53ehdgo,4378
44
+ hud/cli/tests/test_utils.py,sha256=dKmHgyLtDEqKVXlvs5tyNHyHhpBlZHUpmJF-iUraBVM,13466
45
+ hud/clients/README.md,sha256=XNE3mch95ozDgVqfwCGcrhlHY9CwT1GKfNANNboowto,3826
46
+ hud/clients/__init__.py,sha256=bcPIa7dwH5ENsjh7CzjsJ84fm7Ma93NBc2lGfSjGAKM,328
47
+ hud/clients/base.py,sha256=vm8pQS7lwbfhOUyZsti94yzig6dcWIa6NOO3wwhl39w,13497
48
+ hud/clients/fastmcp.py,sha256=kpVwgyltQB_gCeoD0kU9HYC1RHELaib-675qPztwfRg,8125
49
+ hud/clients/mcp_use.py,sha256=G7jnfsFvGgye-LxyEMobgL47wxZ-Id1aq_5AQLuEaBE,11024
50
+ hud/clients/tests/__init__.py,sha256=sKOtJFFa4mDIXh1U6O8ZUHjigE8CiRMQ2PzJTIBZuVE,33
51
+ hud/clients/tests/test_client_integration.py,sha256=kohU6jfCNfwSnAushHeB1_CmDlRfQc7VBL0GEdJYSeI,4198
52
+ hud/clients/tests/test_fastmcp.py,sha256=4q3TzDjuieTZa89taiNJIrzbUncNkYOG4MaubypA21k,13030
53
+ hud/clients/tests/test_protocol.py,sha256=aK4CS4g3j1D5jPo83ykzZuHUvcZFAulYtIq9T9Hb_fQ,6640
54
+ hud/clients/utils/__init__.py,sha256=ucYJqOVpEsN-D9OFE2YTNLG628MgxcZAzfYhnbzx02k,32
55
+ hud/clients/utils/retry_transport.py,sha256=-DyiXTtNBqHMg6Xb340q0wTyYv6qVPQv1zyJskD4JrE,5358
56
+ hud/misc/__init__.py,sha256=m_pprQQ-G-Y0Sd0NEiR8MtAMbElnuFZ2OWT8TXrw7c4,43
57
+ hud/misc/claude_plays_pokemon.py,sha256=IthAkjDVr2Q-GNvX-QLJyMzN7-0pHqqJbagGNv2m7yo,10453
58
+ hud/otel/__init__.py,sha256=ii17ayoWiS5vAhA7UAmZ8TkmP52gs2pWyHsD46-uYbE,1003
59
+ hud/otel/collector.py,sha256=jLZymZ8r7xt2VDuWexfbnT7PY1-0aiyLMgjBy8KDY1M,4497
60
+ hud/otel/config.py,sha256=6np_C2UXhtKHHjY41HQxZElua2Eh_EUCBiRB_YuiSuc,6249
61
+ hud/otel/context.py,sha256=C9MvO99cRSNNDEDC7ehO3eoTPnb6J7AemUYvEp57yEU,17774
62
+ hud/otel/exporters.py,sha256=TP7SF6ySCP-gFV1i-u5-HbpYsK3n9GP3OjW_ZBfsj-w,14246
63
+ hud/otel/instrumentation.py,sha256=ieKHEnMMSMZxPYvZokYJG-UQYXTNyEnaYG1lGY4zIHA,3575
64
+ hud/otel/processors.py,sha256=yI5BWsDBMEPfwMzD-iWbJd4KWH3qUDSe-5-C1yT6fjU,4615
65
+ hud/otel/tests/__init__.py,sha256=VNJKBMaxTtbn7trW-1Ph50zCvCok_wTSGcI1HD6GOLA,43
66
+ hud/otel/tests/test_processors.py,sha256=np0R4ssd9j6LJSJykJ5bNjl0POwNYNhgb7BqOZHwcMY,6778
67
+ hud/server/__init__.py,sha256=8LUwgsXO8xiViWP7uImDwcOsWLu01r5F4r8U8qH3rSY,91
68
+ hud/server/context.py,sha256=6bCdSzv1FGyItu9472HbbYef279H7QuMGJDR8EtYg5Y,3210
69
+ hud/server/low_level.py,sha256=XYs2pOJ9kN4OcJ6ahDmXM5mWkzq5wJLpKFInUYrWEok,4701
70
+ hud/server/server.py,sha256=3IfYyxVfdlh-mVSiBqDQSkWM2gH8NoPjrULvOSW-VI0,6598
71
+ hud/server/helper/__init__.py,sha256=ZxO8VP3RZEBBp-q65VixuhzQgqEPSVzW0hEY9J9QqDA,116
72
+ hud/server/tests/__init__.py,sha256=eEYYkxX5Hz9woXVOBJ2H2_CQoEih0vH6nRt3sH2Z8v8,49
73
+ hud/shared/__init__.py,sha256=IPxPCqtPLguryN-nBq78Sakypw2bRiE2iHv3SXG8YRk,139
74
+ hud/shared/exceptions.py,sha256=Xna_pdEK_ESwkcffsRmT5GXq4xSHLV5cu7Qu3MjstSE,5516
75
+ hud/shared/requests.py,sha256=og2jEbBHCebrg4kiBShunWKMaxQSaO2V7SHU5HPslHg,8848
76
+ hud/shared/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
77
+ hud/shared/tests/test_exceptions.py,sha256=7lzEYHblbKguXHJPyy7J6dUsPFrufos6H5Cliopy6TM,5315
78
+ hud/shared/tests/test_requests.py,sha256=nKFcSN1sjrOouVU2xik9lE5Wxapy3EWsO8iIXrM_Sts,9114
79
+ hud/telemetry/__init__.py,sha256=pPqkq4XekqJEkzwoCwGHGAv1NcytZ55yIB1aLxBpo6U,663
80
+ hud/telemetry/instrument.py,sha256=m3u6YK02PTk39Jr4L3se7l-cYyKx0maCaqf5Z5JqWNA,14096
81
+ hud/telemetry/job.py,sha256=DSZU_yVpag4VOGkCC5egcjVYuZ02nuzMqFZCgJqcQvM,9998
82
+ hud/telemetry/replay.py,sha256=YW17s314s5Wy6Rl8MXHqg1FU8EF9_XcHBMJI0rrkyS4,2306
83
+ hud/telemetry/trace.py,sha256=gem9pcioNI71hLs18vNidv-7KAZBJAn35stjVvOu_Ic,2208
84
+ hud/tools/__init__.py,sha256=f7M3MkPEgoUsNPanLBUJKA_Y3a30arPf5bHdIwyXQZU,905
85
+ hud/tools/base.py,sha256=avk6dLHEmlOMfozTzga4SbjCuAN0n5zyLwIn6OfLN60,14984
86
+ hud/tools/bash.py,sha256=LJViMGb3lTGBm_gequVVTM7ySh1Xh9bOOIZXU29Lmrw,5209
87
+ hud/tools/edit.py,sha256=N0AYFXp07-vAJy2li7lvHOL6hfgJOU4LL3iLSZrbRWU,12745
88
+ hud/tools/playwright.py,sha256=lF7NxyEu8YbB7tpmCoTf8p9HxIrejahC67x3Xs0Jjb4,15007
89
+ hud/tools/types.py,sha256=g-CWnUUDSxxIfUy54S1bpY1nfTzdYO1R_nPKYReABjQ,2734
90
+ hud/tools/utils.py,sha256=bfVyYMcBOJvr1QdptCjVb6jaHVGIL5WUxmY59kzMekQ,1447
91
+ hud/tools/computer/__init__.py,sha256=3tQBXPtGX0WPCwFXzEs3-duwg0rPEgj_0-K7aHskeQE,367
92
+ hud/tools/computer/anthropic.py,sha256=oJfNMnjNFAn9mW1xY1nbWnTY2IqwFqdDR0mWSf8lu-s,17352
93
+ hud/tools/computer/hud.py,sha256=kleQcW1qaBqQGC5iNK-0wOUHiCWvMSxKZNR4FEOPJg4,16240
94
+ hud/tools/computer/openai.py,sha256=QEsF45LWOHftDrAoIOnCFZZT1cL--s-ArSov5aluWb8,11189
95
+ hud/tools/computer/settings.py,sha256=b1XJsEQjB9qhN1xHfVENATkzinEebe0ZPyLzMgCGkKY,2763
96
+ hud/tools/executors/__init__.py,sha256=jHxfus9SLhkL6YGtebR5RyKYyVAix3yu5EkUp2Q27Kg,732
97
+ hud/tools/executors/base.py,sha256=VP2SiIEBSXvklnkasGxVuy-OmDMd9rjuxZh_YuUQH7A,14481
98
+ hud/tools/executors/pyautogui.py,sha256=11eUQJAgFmHxwd9INAb2L9tgBmEv2Vgn0cwhwvGKlC8,22361
99
+ hud/tools/executors/xdo.py,sha256=vc3ciSojmJ58HoL1VC2MC-F_KFrk4_YQHmoJp4rgv1k,18136
100
+ hud/tools/executors/tests/__init__.py,sha256=opFpGSH6cEqIZgt9izXd3Yt85pC7xkxiYmOZQTHf4AY,32
101
+ hud/tools/executors/tests/test_base_executor.py,sha256=toINFwhKyjWrsiOKpIOcCwUo_sUkuukycNcNHfXBOfo,12468
102
+ hud/tools/executors/tests/test_pyautogui_executor.py,sha256=Shv6pnWtlsMXBMlN5DjlttCu6rZ1H447d1QZumduOnU,6640
103
+ hud/tools/tests/__init__.py,sha256=eEYYkxX5Hz9woXVOBJ2H2_CQoEih0vH6nRt3sH2Z8v8,49
104
+ hud/tools/tests/test_base.py,sha256=m6EelJ47F_hMqvRjrr6vEdiW1AtLgz3ZH1V1IUzTxzI,8983
105
+ hud/tools/tests/test_bash.py,sha256=-g9a6sYgKKXRXmqYGYQBgpKEF_OlKE_uDDQXYMx6rT0,5113
106
+ hud/tools/tests/test_bash_extended.py,sha256=G1pgl2e7_7ILYYS2FE6pTwI3_IPzmkPjBjGnxMGwGq8,7000
107
+ hud/tools/tests/test_computer.py,sha256=BmrX2PV3wzHC4-xPJnWvenDV_kWt8LF8ia0kELBgHho,16394
108
+ hud/tools/tests/test_computer_actions.py,sha256=YtUNFL7anhpXrcvg8EoUY1CqIV-TAAyaNFLZO9CiJ40,1194
109
+ hud/tools/tests/test_edit.py,sha256=pHw1MSs-P8mDKrwKUDW77vQfoMNwmbrEBt_MkKr2rE0,9734
110
+ hud/tools/tests/test_init.py,sha256=fl4Tf4IUUFOKhdSRHu9GE4mkaTDiXw-2auxj4s84HuE,698
111
+ hud/tools/tests/test_playwright_tool.py,sha256=0va9IuZ7P5vXZDzan_sn-89ahu3piQMQDaiREzEvXNc,6736
112
+ hud/tools/tests/test_tools.py,sha256=paz28V98Am-oR7MBJPDgY-BRV14HQo_0F6X5JIC8aic,4563
113
+ hud/tools/tests/test_utils.py,sha256=oYxEnLpSA5sEeYFGUTj74QRNv0AHP3AjmYYHXgIW0BY,5496
114
+ hud/utils/__init__.py,sha256=ckuIzwqgTxkzASa04XTPsOu_TqsRYUKBWUYfcSi3Xnc,164
115
+ hud/utils/async_utils.py,sha256=5cKrJcnaHV2eJNxeyx0r7fPcdPTDBK7kM9-nLaF51X4,2409
116
+ hud/utils/design.py,sha256=JZu4Fgfr_sOpH90oi1pu__woV56jPutCKsKAcmkHsUc,4987
117
+ hud/utils/mcp.py,sha256=0r9_ffRObfAb6Zx6PRDJP6ibOTewOsQxJU0K-6JPveM,1847
118
+ hud/utils/progress.py,sha256=suikwFM8sdSfkV10nAOEaInDhG4XKgOSvFePg4jSj1A,5927
119
+ hud/utils/telemetry.py,sha256=hrVIx2rUjSGyy9IVxTZ_3Jii83PiHjyFRd5ls2whimM,1863
120
+ hud/utils/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
121
+ hud/utils/tests/test_async_utils.py,sha256=RkdSnYErRV3Jn7dfg6CPlcE1RSUL__2B627oIqAyy1s,5945
122
+ hud/utils/tests/test_init.py,sha256=2QLQSGgyP9wJhOvPCusm_zjJad0qApOZi1BXpxcdHXQ,383
123
+ hud/utils/tests/test_progress.py,sha256=QSF7Kpi03Ff_l3mAeqW9qs1nhK50j9vBiSobZq7T4f4,7394
124
+ hud/utils/tests/test_telemetry.py,sha256=5jl7bEx8C8b-FfFUko5pf4UY-mPOR-9HaeL98dGtVHM,2781
125
+ hud/utils/tests/test_version.py,sha256=jy8VM-qboqR_TWjmFy3hCw93dCZsguyIgBsqNmUtzM4,159
126
+ hud/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
127
+ hud_python-0.4.2.dist-info/METADATA,sha256=fTLXYCnwj5LOHUKjMeKQmmRFJ2BgWYCrcPBWD4c2Fng,19675
128
+ hud_python-0.4.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
129
+ hud_python-0.4.2.dist-info/entry_points.txt,sha256=jJbodNFg1m0-CDofe5AHvB4zKBq7sSdP97-ohaQ3ae4,63
130
+ hud_python-0.4.2.dist-info/licenses/LICENSE,sha256=yIzBheVUf86FC1bztAcr7RYWWNxyd3B-UJQ3uddg1HA,1078
131
+ hud_python-0.4.2.dist-info/RECORD,,
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 Human Union Data, Inc
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Human Union Data, Inc
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
hud/agents/art.py DELETED
@@ -1,101 +0,0 @@
1
- """Adapter that plugs a *Trainable* ART model into the HUD MCPAgent stack.
2
-
3
- This extends GenericOpenAIChatAgent to collect messages_and_choices during
4
- execution for ART training.
5
- """
6
-
7
- from __future__ import annotations
8
-
9
- import logging
10
- from typing import TYPE_CHECKING, Any
11
-
12
- import hud
13
-
14
- from .openai_chat_generic import GenericOpenAIChatAgent
15
-
16
- if TYPE_CHECKING:
17
- import mcp.types as types
18
-
19
- from hud.clients import AgentMCPClient
20
- from hud.types import AgentResponse
21
-
22
- logger = logging.getLogger(__name__)
23
-
24
-
25
- system_prompt = (
26
- "You are an MCP (Model Context Protocol) agent.\n\n"
27
- "Use MCP tools through the server to complete your task.\n\n"
28
- "You have a total of {MAX_STEPS} steps."
29
- )
30
-
31
-
32
- class ArtHUDAgent(GenericOpenAIChatAgent):
33
- """Use an ART *TrainableModel* as the LLM behind a HUD `MCPAgent`.
34
-
35
- This agent collects messages_and_choices during execution for ART training.
36
- """
37
-
38
- def __init__(self, art_model: Any, mcp_client: AgentMCPClient, **agent_kwargs: Any) -> None:
39
- # Use ART's openai_client() method to get proper timeouts and patching
40
- openai_client = art_model.openai_client()
41
-
42
- super().__init__(
43
- mcp_client=mcp_client,
44
- openai_client=openai_client,
45
- model_name=art_model.get_inference_name(),
46
- logprobs=True,
47
- **agent_kwargs,
48
- )
49
- self.system_prompt = system_prompt
50
-
51
- self.art_model = art_model
52
- self.messages_and_choices: list[Any] = [] # Collect for ART training
53
-
54
- logger.info(
55
- "ArtHUDAgent initialised with model '%s' (project=%s)",
56
- art_model.name,
57
- getattr(art_model, "project", "unknown"),
58
- )
59
-
60
- async def get_system_messages(self) -> list[Any]:
61
- """Get system messages for ART."""
62
- messages = await super().get_system_messages()
63
- # Store initial messages as dicts for ART
64
- self.messages_and_choices.extend(messages)
65
- return messages
66
-
67
- async def format_blocks(self, blocks: list[types.ContentBlock]) -> list[Any]:
68
- """Format blocks for ART."""
69
- messages = await super().format_blocks(blocks)
70
- # Store initial messages as dicts for ART
71
- self.messages_and_choices.extend(messages)
72
- return messages
73
-
74
- @hud.instrument(
75
- span_type="agent",
76
- record_args=False, # Messages can be large
77
- record_result=True,
78
- )
79
- async def get_response(self, messages: list[Any]) -> AgentResponse:
80
- """Get model response and store the Choice for ART."""
81
- # Call parent's get_model_response
82
- result = await super().get_response(messages)
83
-
84
- # Extract and store the Choice from the raw response
85
- if result.raw and hasattr(result.raw, "choices") and result.raw.choices:
86
- choice = result.raw.choices[0]
87
- # Ensure the message has content (required for ART tokenization)
88
- if choice.message and choice.message.content is None:
89
- choice.message.content = ""
90
- self.messages_and_choices.append(choice)
91
-
92
- return result
93
-
94
- async def format_tool_results(
95
- self, tool_calls: list[Any], tool_results: list[Any]
96
- ) -> list[Any]:
97
- """Format tool results and store them for ART."""
98
- tool_messages = await super().format_tool_results(tool_calls, tool_results)
99
- # Store tool messages for ART
100
- self.messages_and_choices.extend(tool_messages)
101
- return tool_messages