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,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.1"
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.3"
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.1"
1
+ """
2
+ Version information for the HUD SDK.
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ __version__ = "0.4.3"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hud-python
3
- Version: 0.4.1
3
+ Version: 0.4.3
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
 
@@ -152,7 +152,7 @@ For a tutorial that explains the agent and evaluation design, run ([see quicksta
152
152
  uvx hud-python quickstart
153
153
  ```
154
154
 
155
- Or just write your own agent loop (more [examples here](examples/)):
155
+ Or just write your own agent loop (more [examples here](examples/)).
156
156
 
157
157
  ```python
158
158
  import asyncio, hud, os
@@ -196,11 +196,13 @@ async def main() -> None:
196
196
  asyncio.run(main())
197
197
  ```
198
198
 
199
- > 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)
200
202
 
201
203
  ## Reinforcement Learning with GRPO
202
204
 
203
- 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/):
204
206
 
205
207
  ![RL curve](https://raw.githubusercontent.com/hud-evals/hud-python/main/docs/src/images/rl_2.png)
206
208
 
@@ -208,8 +210,8 @@ To start training, check out the [`rl/README.md`](rl/README.md) folder:
208
210
 
209
211
  ```bash
210
212
  git clone https://github.com/hud-evals/hud-python
211
- cd hud-python
212
- python rl/verifiers/train_2048.py
213
+ cd hud-python/rl
214
+ python train_2048.py
213
215
  ```
214
216
 
215
217
  Any hud MCP environment and evaluation works with our RL pipeline. Even our remote configurations!
@@ -0,0 +1,131 @@
1
+ hud/__init__.py,sha256=BjAhZtsHbGN371Q8t3o4v4jltedkmDE85xW0yOILU9g,397
2
+ hud/datasets.py,sha256=8lqC840kcNx01D2CcWZCd1j0eZTpepILmQrvohZIZYU,12056
3
+ hud/settings.py,sha256=WIJDsyrfwBZGcaGT46YUOpW8xjBZl3siXXprd92ASAg,2039
4
+ hud/types.py,sha256=pQWOPYXUZ2hhK0h-AHBc3DCj5tkbRXHqKZnsQQIcSFA,4237
5
+ hud/version.py,sha256=jcTLPFHK9eItf63ms1H-BiD-W2bxmgGtXphzpysflmg,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=_2ZJT1S1yREI0p2WSQkgcTmECaLXwnmSOURQrNXTxkk,9524
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=MsnIVElXM4ABrSJfEc_MMYp1Y_Rxmkq4kEGJ9vDX7hw,3098
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=7GWBte4x6X24hZghEMC4Q0IBrBaFIf_eWZodkEHFba0,16693
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=Jb9h4MJPMNiUhr9GmmJjwjjmGQQOOMG1GadXIEsvKKk,7702
29
+ hud/cli/interactive.py,sha256=w1fAoefizNKqjcl5Fi5EgEsUdPpXKcCFuU-Z-S3CL9o,12863
30
+ hud/cli/mcp_server.py,sha256=kqXlHPm7ABVtP_MTJON5OgUAeVcXRuM-NrqqjBWYgd0,28221
31
+ hud/cli/pull.py,sha256=8caEpiCsvHHMsQ9K7QRfZ8dC5Zq3G_OLF5YrUGHUP6E,11721
32
+ hud/cli/push.py,sha256=MBee7EtcrzAHzmVWneT7hvHV9aF_hgxVRPoc1U1Oi1c,15626
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=y2yH8H4-cefWiI3oey_YPKLpDM2OwZ-hgvpjoOpEb8c,13459
48
+ hud/clients/fastmcp.py,sha256=kocw7fpLbTnFmeE39XrPd5yyl5KY8kvtB_udLzQVRtg,9168
49
+ hud/clients/mcp_use.py,sha256=Q1h3Hb9R1SVeue2CqhC5W7PqnQzuuAQf5T9O8GhzpbI,11981
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=8-GHAegyJelQMdSSnY-MKXks2m3GVYHSW2Dlf17-daM,8965
117
+ hud/utils/mcp.py,sha256=SQgEemHpIc0LshA0ImZw4nMzPPn1SE6qEO0dpNLwxy4,1855
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=HCf9E1JvES6_A04uA0hkW1UdvSMxpkPaBeGNPvAinMw,159
126
+ hud/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
127
+ hud_python-0.4.3.dist-info/METADATA,sha256=t2F4sMfl2cY-Ve2asy2esZCXLgUL1X7g6I1KhPvoQ7w,19669
128
+ hud_python-0.4.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
129
+ hud_python-0.4.3.dist-info/entry_points.txt,sha256=jJbodNFg1m0-CDofe5AHvB4zKBq7sSdP97-ohaQ3ae4,63
130
+ hud_python-0.4.3.dist-info/licenses/LICENSE,sha256=yIzBheVUf86FC1bztAcr7RYWWNxyd3B-UJQ3uddg1HA,1078
131
+ hud_python-0.4.3.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