hud-python 0.5.12__tar.gz → 0.5.13__tar.gz

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.
Files changed (306) hide show
  1. {hud_python-0.5.12 → hud_python-0.5.13}/PKG-INFO +2 -2
  2. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/__init__.py +14 -1
  3. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/build.py +27 -4
  4. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/eval.py +33 -1
  5. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/tests/test_build.py +2 -2
  6. {hud_python-0.5.12 → hud_python-0.5.13}/hud/datasets/runner.py +2 -0
  7. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/scenarios.py +13 -8
  8. {hud_python-0.5.12 → hud_python-0.5.13}/hud/eval/manager.py +79 -12
  9. {hud_python-0.5.12 → hud_python-0.5.13}/hud/eval/types.py +2 -0
  10. {hud_python-0.5.12 → hud_python-0.5.13}/hud/utils/tests/test_version.py +1 -1
  11. {hud_python-0.5.12 → hud_python-0.5.13}/hud/version.py +1 -1
  12. {hud_python-0.5.12 → hud_python-0.5.13}/pyproject.toml +2 -2
  13. {hud_python-0.5.12 → hud_python-0.5.13}/.gitignore +0 -0
  14. {hud_python-0.5.12 → hud_python-0.5.13}/LICENSE +0 -0
  15. {hud_python-0.5.12 → hud_python-0.5.13}/README.md +0 -0
  16. {hud_python-0.5.12 → hud_python-0.5.13}/examples/README.md +0 -0
  17. {hud_python-0.5.12 → hud_python-0.5.13}/hud/__init__.py +0 -0
  18. {hud_python-0.5.12 → hud_python-0.5.13}/hud/__main__.py +0 -0
  19. {hud_python-0.5.12 → hud_python-0.5.13}/hud/agents/__init__.py +0 -0
  20. {hud_python-0.5.12 → hud_python-0.5.13}/hud/agents/base.py +0 -0
  21. {hud_python-0.5.12 → hud_python-0.5.13}/hud/agents/claude.py +0 -0
  22. {hud_python-0.5.12 → hud_python-0.5.13}/hud/agents/gateway.py +0 -0
  23. {hud_python-0.5.12 → hud_python-0.5.13}/hud/agents/gemini.py +0 -0
  24. {hud_python-0.5.12 → hud_python-0.5.13}/hud/agents/gemini_cua.py +0 -0
  25. {hud_python-0.5.12 → hud_python-0.5.13}/hud/agents/grounded_openai.py +0 -0
  26. {hud_python-0.5.12 → hud_python-0.5.13}/hud/agents/misc/__init__.py +0 -0
  27. {hud_python-0.5.12 → hud_python-0.5.13}/hud/agents/misc/integration_test_agent.py +0 -0
  28. {hud_python-0.5.12 → hud_python-0.5.13}/hud/agents/misc/response_agent.py +0 -0
  29. {hud_python-0.5.12 → hud_python-0.5.13}/hud/agents/openai.py +0 -0
  30. {hud_python-0.5.12 → hud_python-0.5.13}/hud/agents/openai_chat.py +0 -0
  31. {hud_python-0.5.12 → hud_python-0.5.13}/hud/agents/operator.py +0 -0
  32. {hud_python-0.5.12 → hud_python-0.5.13}/hud/agents/resolver.py +0 -0
  33. {hud_python-0.5.12 → hud_python-0.5.13}/hud/agents/tests/__init__.py +0 -0
  34. {hud_python-0.5.12 → hud_python-0.5.13}/hud/agents/tests/conftest.py +0 -0
  35. {hud_python-0.5.12 → hud_python-0.5.13}/hud/agents/tests/test_base.py +0 -0
  36. {hud_python-0.5.12 → hud_python-0.5.13}/hud/agents/tests/test_base_runtime.py +0 -0
  37. {hud_python-0.5.12 → hud_python-0.5.13}/hud/agents/tests/test_claude.py +0 -0
  38. {hud_python-0.5.12 → hud_python-0.5.13}/hud/agents/tests/test_client.py +0 -0
  39. {hud_python-0.5.12 → hud_python-0.5.13}/hud/agents/tests/test_gemini.py +0 -0
  40. {hud_python-0.5.12 → hud_python-0.5.13}/hud/agents/tests/test_grounded_openai_agent.py +0 -0
  41. {hud_python-0.5.12 → hud_python-0.5.13}/hud/agents/tests/test_openai.py +0 -0
  42. {hud_python-0.5.12 → hud_python-0.5.13}/hud/agents/tests/test_operator.py +0 -0
  43. {hud_python-0.5.12 → hud_python-0.5.13}/hud/agents/tests/test_resolver.py +0 -0
  44. {hud_python-0.5.12 → hud_python-0.5.13}/hud/agents/tests/test_run_eval.py +0 -0
  45. {hud_python-0.5.12 → hud_python-0.5.13}/hud/agents/types.py +0 -0
  46. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/__main__.py +0 -0
  47. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/analyze.py +0 -0
  48. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/clone.py +0 -0
  49. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/debug.py +0 -0
  50. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/dev.py +0 -0
  51. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/flows/__init__.py +0 -0
  52. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/flows/dev.py +0 -0
  53. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/flows/init.py +0 -0
  54. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/flows/tasks.py +0 -0
  55. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/flows/templates.py +0 -0
  56. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/flows/tests/__init__.py +0 -0
  57. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/flows/tests/test_dev.py +0 -0
  58. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/get.py +0 -0
  59. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/init.py +0 -0
  60. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/list_func.py +0 -0
  61. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/pull.py +0 -0
  62. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/push.py +0 -0
  63. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/remove.py +0 -0
  64. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/rft.py +0 -0
  65. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/rft_status.py +0 -0
  66. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/tests/__init__.py +0 -0
  67. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/tests/test_analyze.py +0 -0
  68. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/tests/test_analyze_metadata.py +0 -0
  69. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/tests/test_analyze_module.py +0 -0
  70. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/tests/test_build_failure.py +0 -0
  71. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/tests/test_build_module.py +0 -0
  72. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/tests/test_cli_init.py +0 -0
  73. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/tests/test_cli_main.py +0 -0
  74. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/tests/test_cli_more_wrappers.py +0 -0
  75. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/tests/test_cli_root.py +0 -0
  76. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/tests/test_clone.py +0 -0
  77. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/tests/test_convert.py +0 -0
  78. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/tests/test_cursor.py +0 -0
  79. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/tests/test_debug.py +0 -0
  80. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/tests/test_dev.py +0 -0
  81. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/tests/test_eval.py +0 -0
  82. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/tests/test_eval_bedrock.py +0 -0
  83. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/tests/test_init.py +0 -0
  84. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/tests/test_list_func.py +0 -0
  85. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/tests/test_main_module.py +0 -0
  86. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/tests/test_mcp_server.py +0 -0
  87. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/tests/test_pull.py +0 -0
  88. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/tests/test_push.py +0 -0
  89. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/tests/test_push_happy.py +0 -0
  90. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/tests/test_push_wrapper.py +0 -0
  91. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/tests/test_registry.py +0 -0
  92. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/tests/test_utils.py +0 -0
  93. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/__init__.py +0 -0
  94. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/celebrate.py +0 -0
  95. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/config.py +0 -0
  96. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/cursor.py +0 -0
  97. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/docker.py +0 -0
  98. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/env_check.py +0 -0
  99. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/environment.py +0 -0
  100. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/git.py +0 -0
  101. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/interactive.py +0 -0
  102. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/local_runner.py +0 -0
  103. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/logging.py +0 -0
  104. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/metadata.py +0 -0
  105. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/package_runner.py +0 -0
  106. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/registry.py +0 -0
  107. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/remote_runner.py +0 -0
  108. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/runner.py +0 -0
  109. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/server.py +0 -0
  110. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/source_hash.py +0 -0
  111. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/tasks.py +0 -0
  112. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/tests/__init__.py +0 -0
  113. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/tests/test_config.py +0 -0
  114. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/tests/test_docker.py +0 -0
  115. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/tests/test_docker_hints.py +0 -0
  116. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/tests/test_env_check.py +0 -0
  117. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/tests/test_environment.py +0 -0
  118. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/tests/test_git.py +0 -0
  119. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/tests/test_interactive_module.py +0 -0
  120. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/tests/test_local_runner.py +0 -0
  121. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/tests/test_logging_utils.py +0 -0
  122. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/tests/test_metadata.py +0 -0
  123. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/tests/test_package_runner.py +0 -0
  124. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/tests/test_registry_utils.py +0 -0
  125. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/tests/test_remote_runner.py +0 -0
  126. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/tests/test_runner_modules.py +0 -0
  127. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/tests/test_source_hash.py +0 -0
  128. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/tests/test_tasks.py +0 -0
  129. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/version_check.py +0 -0
  130. {hud_python-0.5.12 → hud_python-0.5.13}/hud/cli/utils/viewer.py +0 -0
  131. {hud_python-0.5.12 → hud_python-0.5.13}/hud/clients/README.md +0 -0
  132. {hud_python-0.5.12 → hud_python-0.5.13}/hud/clients/__init__.py +0 -0
  133. {hud_python-0.5.12 → hud_python-0.5.13}/hud/clients/base.py +0 -0
  134. {hud_python-0.5.12 → hud_python-0.5.13}/hud/clients/environment.py +0 -0
  135. {hud_python-0.5.12 → hud_python-0.5.13}/hud/clients/fastmcp.py +0 -0
  136. {hud_python-0.5.12 → hud_python-0.5.13}/hud/clients/mcp_use.py +0 -0
  137. {hud_python-0.5.12 → hud_python-0.5.13}/hud/clients/tests/__init__.py +0 -0
  138. {hud_python-0.5.12 → hud_python-0.5.13}/hud/clients/tests/test_analyze_scenarios.py +0 -0
  139. {hud_python-0.5.12 → hud_python-0.5.13}/hud/clients/tests/test_client_integration.py +0 -0
  140. {hud_python-0.5.12 → hud_python-0.5.13}/hud/clients/tests/test_fastmcp.py +0 -0
  141. {hud_python-0.5.12 → hud_python-0.5.13}/hud/clients/tests/test_mcp_use_retry.py +0 -0
  142. {hud_python-0.5.12 → hud_python-0.5.13}/hud/clients/tests/test_protocol.py +0 -0
  143. {hud_python-0.5.12 → hud_python-0.5.13}/hud/clients/utils/__init__.py +0 -0
  144. {hud_python-0.5.12 → hud_python-0.5.13}/hud/clients/utils/mcp_use_retry.py +0 -0
  145. {hud_python-0.5.12 → hud_python-0.5.13}/hud/clients/utils/retry.py +0 -0
  146. {hud_python-0.5.12 → hud_python-0.5.13}/hud/clients/utils/retry_transport.py +0 -0
  147. {hud_python-0.5.12 → hud_python-0.5.13}/hud/datasets/__init__.py +0 -0
  148. {hud_python-0.5.12 → hud_python-0.5.13}/hud/datasets/loader.py +0 -0
  149. {hud_python-0.5.12 → hud_python-0.5.13}/hud/datasets/tests/__init__.py +0 -0
  150. {hud_python-0.5.12 → hud_python-0.5.13}/hud/datasets/tests/test_loader.py +0 -0
  151. {hud_python-0.5.12 → hud_python-0.5.13}/hud/datasets/tests/test_utils.py +0 -0
  152. {hud_python-0.5.12 → hud_python-0.5.13}/hud/datasets/utils.py +0 -0
  153. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/__init__.py +0 -0
  154. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/connection.py +0 -0
  155. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/connectors/__init__.py +0 -0
  156. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/connectors/base.py +0 -0
  157. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/connectors/local.py +0 -0
  158. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/connectors/mcp_config.py +0 -0
  159. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/connectors/openai.py +0 -0
  160. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/connectors/remote.py +0 -0
  161. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/environment.py +0 -0
  162. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/integrations/__init__.py +0 -0
  163. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/integrations/adk.py +0 -0
  164. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/integrations/anthropic.py +0 -0
  165. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/integrations/gemini.py +0 -0
  166. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/integrations/langchain.py +0 -0
  167. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/integrations/llamaindex.py +0 -0
  168. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/integrations/openai.py +0 -0
  169. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/mock.py +0 -0
  170. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/router.py +0 -0
  171. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/tests/__init__.py +0 -0
  172. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/tests/test_connection.py +0 -0
  173. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/tests/test_connectors.py +0 -0
  174. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/tests/test_environment.py +0 -0
  175. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/tests/test_integrations.py +0 -0
  176. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/tests/test_local_connectors.py +0 -0
  177. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/tests/test_scenarios.py +0 -0
  178. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/tests/test_tools.py +0 -0
  179. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/types.py +0 -0
  180. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/utils/__init__.py +0 -0
  181. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/utils/formats.py +0 -0
  182. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/utils/schema.py +0 -0
  183. {hud_python-0.5.12 → hud_python-0.5.13}/hud/environment/utils/tool_wrappers.py +0 -0
  184. {hud_python-0.5.12 → hud_python-0.5.13}/hud/eval/__init__.py +0 -0
  185. {hud_python-0.5.12 → hud_python-0.5.13}/hud/eval/context.py +0 -0
  186. {hud_python-0.5.12 → hud_python-0.5.13}/hud/eval/display.py +0 -0
  187. {hud_python-0.5.12 → hud_python-0.5.13}/hud/eval/instrument.py +0 -0
  188. {hud_python-0.5.12 → hud_python-0.5.13}/hud/eval/parallel.py +0 -0
  189. {hud_python-0.5.12 → hud_python-0.5.13}/hud/eval/task.py +0 -0
  190. {hud_python-0.5.12 → hud_python-0.5.13}/hud/eval/tests/__init__.py +0 -0
  191. {hud_python-0.5.12 → hud_python-0.5.13}/hud/eval/tests/test_context.py +0 -0
  192. {hud_python-0.5.12 → hud_python-0.5.13}/hud/eval/tests/test_eval.py +0 -0
  193. {hud_python-0.5.12 → hud_python-0.5.13}/hud/eval/tests/test_manager.py +0 -0
  194. {hud_python-0.5.12 → hud_python-0.5.13}/hud/eval/tests/test_parallel.py +0 -0
  195. {hud_python-0.5.12 → hud_python-0.5.13}/hud/eval/tests/test_task.py +0 -0
  196. {hud_python-0.5.12 → hud_python-0.5.13}/hud/eval/utils.py +0 -0
  197. {hud_python-0.5.12 → hud_python-0.5.13}/hud/native/__init__.py +0 -0
  198. {hud_python-0.5.12 → hud_python-0.5.13}/hud/native/comparator.py +0 -0
  199. {hud_python-0.5.12 → hud_python-0.5.13}/hud/native/tests/__init__.py +0 -0
  200. {hud_python-0.5.12 → hud_python-0.5.13}/hud/native/tests/test_comparator.py +0 -0
  201. {hud_python-0.5.12 → hud_python-0.5.13}/hud/native/tests/test_native_init.py +0 -0
  202. {hud_python-0.5.12 → hud_python-0.5.13}/hud/patches/__init__.py +0 -0
  203. {hud_python-0.5.12 → hud_python-0.5.13}/hud/patches/mcp_patches.py +0 -0
  204. {hud_python-0.5.12 → hud_python-0.5.13}/hud/patches/warnings.py +0 -0
  205. {hud_python-0.5.12 → hud_python-0.5.13}/hud/py.typed +0 -0
  206. {hud_python-0.5.12 → hud_python-0.5.13}/hud/samples/__init__.py +0 -0
  207. {hud_python-0.5.12 → hud_python-0.5.13}/hud/samples/browser.py +0 -0
  208. {hud_python-0.5.12 → hud_python-0.5.13}/hud/server/__init__.py +0 -0
  209. {hud_python-0.5.12 → hud_python-0.5.13}/hud/server/context.py +0 -0
  210. {hud_python-0.5.12 → hud_python-0.5.13}/hud/server/helper/__init__.py +0 -0
  211. {hud_python-0.5.12 → hud_python-0.5.13}/hud/server/low_level.py +0 -0
  212. {hud_python-0.5.12 → hud_python-0.5.13}/hud/server/router.py +0 -0
  213. {hud_python-0.5.12 → hud_python-0.5.13}/hud/server/server.py +0 -0
  214. {hud_python-0.5.12 → hud_python-0.5.13}/hud/server/tests/__init__.py +0 -0
  215. {hud_python-0.5.12 → hud_python-0.5.13}/hud/server/tests/test_add_tool.py +0 -0
  216. {hud_python-0.5.12 → hud_python-0.5.13}/hud/server/tests/test_context.py +0 -0
  217. {hud_python-0.5.12 → hud_python-0.5.13}/hud/server/tests/test_mcp_server_handlers.py +0 -0
  218. {hud_python-0.5.12 → hud_python-0.5.13}/hud/server/tests/test_mcp_server_integration.py +0 -0
  219. {hud_python-0.5.12 → hud_python-0.5.13}/hud/server/tests/test_mcp_server_more.py +0 -0
  220. {hud_python-0.5.12 → hud_python-0.5.13}/hud/server/tests/test_run_wrapper.py +0 -0
  221. {hud_python-0.5.12 → hud_python-0.5.13}/hud/server/tests/test_server_extra.py +0 -0
  222. {hud_python-0.5.12 → hud_python-0.5.13}/hud/server/tests/test_sigterm_runner.py +0 -0
  223. {hud_python-0.5.12 → hud_python-0.5.13}/hud/settings.py +0 -0
  224. {hud_python-0.5.12 → hud_python-0.5.13}/hud/shared/__init__.py +0 -0
  225. {hud_python-0.5.12 → hud_python-0.5.13}/hud/shared/exceptions.py +0 -0
  226. {hud_python-0.5.12 → hud_python-0.5.13}/hud/shared/hints.py +0 -0
  227. {hud_python-0.5.12 → hud_python-0.5.13}/hud/shared/requests.py +0 -0
  228. {hud_python-0.5.12 → hud_python-0.5.13}/hud/shared/tests/__init__.py +0 -0
  229. {hud_python-0.5.12 → hud_python-0.5.13}/hud/shared/tests/test_exceptions.py +0 -0
  230. {hud_python-0.5.12 → hud_python-0.5.13}/hud/shared/tests/test_hints.py +0 -0
  231. {hud_python-0.5.12 → hud_python-0.5.13}/hud/shared/tests/test_requests.py +0 -0
  232. {hud_python-0.5.12 → hud_python-0.5.13}/hud/telemetry/__init__.py +0 -0
  233. {hud_python-0.5.12 → hud_python-0.5.13}/hud/telemetry/exporter.py +0 -0
  234. {hud_python-0.5.12 → hud_python-0.5.13}/hud/telemetry/instrument.py +0 -0
  235. {hud_python-0.5.12 → hud_python-0.5.13}/hud/telemetry/tests/__init__.py +0 -0
  236. {hud_python-0.5.12 → hud_python-0.5.13}/hud/telemetry/tests/test_eval_telemetry.py +0 -0
  237. {hud_python-0.5.12 → hud_python-0.5.13}/hud/telemetry/tests/test_exporter.py +0 -0
  238. {hud_python-0.5.12 → hud_python-0.5.13}/hud/telemetry/tests/test_instrument.py +0 -0
  239. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/__init__.py +0 -0
  240. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/agent.py +0 -0
  241. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/apply_patch.py +0 -0
  242. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/base.py +0 -0
  243. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/bash.py +0 -0
  244. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/computer/__init__.py +0 -0
  245. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/computer/anthropic.py +0 -0
  246. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/computer/gemini.py +0 -0
  247. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/computer/hud.py +0 -0
  248. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/computer/openai.py +0 -0
  249. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/computer/qwen.py +0 -0
  250. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/computer/settings.py +0 -0
  251. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/edit.py +0 -0
  252. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/executors/__init__.py +0 -0
  253. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/executors/base.py +0 -0
  254. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/executors/pyautogui.py +0 -0
  255. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/executors/tests/__init__.py +0 -0
  256. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/executors/tests/test_base_executor.py +0 -0
  257. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/executors/tests/test_pyautogui_executor.py +0 -0
  258. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/executors/xdo.py +0 -0
  259. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/grounding/__init__.py +0 -0
  260. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/grounding/config.py +0 -0
  261. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/grounding/grounded_tool.py +0 -0
  262. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/grounding/grounder.py +0 -0
  263. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/grounding/tests/__init__.py +0 -0
  264. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/grounding/tests/test_grounded_tool.py +0 -0
  265. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/jupyter.py +0 -0
  266. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/playwright.py +0 -0
  267. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/response.py +0 -0
  268. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/shell.py +0 -0
  269. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/submit.py +0 -0
  270. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/tests/__init__.py +0 -0
  271. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/tests/test_agent_tool.py +0 -0
  272. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/tests/test_apply_patch.py +0 -0
  273. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/tests/test_base.py +0 -0
  274. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/tests/test_bash.py +0 -0
  275. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/tests/test_bash_extended.py +0 -0
  276. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/tests/test_computer.py +0 -0
  277. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/tests/test_computer_actions.py +0 -0
  278. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/tests/test_edit.py +0 -0
  279. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/tests/test_init.py +0 -0
  280. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/tests/test_jupyter_tool.py +0 -0
  281. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/tests/test_playwright_tool.py +0 -0
  282. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/tests/test_response.py +0 -0
  283. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/tests/test_shell.py +0 -0
  284. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/tests/test_submit.py +0 -0
  285. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/tests/test_tools.py +0 -0
  286. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/tests/test_tools_init.py +0 -0
  287. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/tests/test_types.py +0 -0
  288. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/tests/test_utils.py +0 -0
  289. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/types.py +0 -0
  290. {hud_python-0.5.12 → hud_python-0.5.13}/hud/tools/utils.py +0 -0
  291. {hud_python-0.5.12 → hud_python-0.5.13}/hud/types.py +0 -0
  292. {hud_python-0.5.12 → hud_python-0.5.13}/hud/utils/__init__.py +0 -0
  293. {hud_python-0.5.12 → hud_python-0.5.13}/hud/utils/env.py +0 -0
  294. {hud_python-0.5.12 → hud_python-0.5.13}/hud/utils/hud_console.py +0 -0
  295. {hud_python-0.5.12 → hud_python-0.5.13}/hud/utils/mcp.py +0 -0
  296. {hud_python-0.5.12 → hud_python-0.5.13}/hud/utils/pretty_errors.py +0 -0
  297. {hud_python-0.5.12 → hud_python-0.5.13}/hud/utils/strict_schema.py +0 -0
  298. {hud_python-0.5.12 → hud_python-0.5.13}/hud/utils/telemetry.py +0 -0
  299. {hud_python-0.5.12 → hud_python-0.5.13}/hud/utils/tests/__init__.py +0 -0
  300. {hud_python-0.5.12 → hud_python-0.5.13}/hud/utils/tests/test_init.py +0 -0
  301. {hud_python-0.5.12 → hud_python-0.5.13}/hud/utils/tests/test_mcp.py +0 -0
  302. {hud_python-0.5.12 → hud_python-0.5.13}/hud/utils/tests/test_pretty_errors.py +0 -0
  303. {hud_python-0.5.12 → hud_python-0.5.13}/hud/utils/tests/test_telemetry.py +0 -0
  304. {hud_python-0.5.12 → hud_python-0.5.13}/hud/utils/tests/test_tool_shorthand.py +0 -0
  305. {hud_python-0.5.12 → hud_python-0.5.13}/hud/utils/tool_shorthand.py +0 -0
  306. {hud_python-0.5.12 → hud_python-0.5.13}/hud/utils/types.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hud-python
3
- Version: 0.5.12
3
+ Version: 0.5.13
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
@@ -91,7 +91,7 @@ Requires-Dist: pyright==1.1.407; extra == 'dev'
91
91
  Requires-Dist: pytest-asyncio; extra == 'dev'
92
92
  Requires-Dist: pytest-cov; extra == 'dev'
93
93
  Requires-Dist: pytest-mock; extra == 'dev'
94
- Requires-Dist: pytest<9,>=8.1.1; extra == 'dev'
94
+ Requires-Dist: pytest>=8.1.1; extra == 'dev'
95
95
  Requires-Dist: ruff>=0.11.8; extra == 'dev'
96
96
  Requires-Dist: tornado>=6.5.2; extra == 'dev'
97
97
  Description-Content-Type: text/markdown
@@ -741,6 +741,11 @@ def build(
741
741
  platform: str | None = typer.Option(
742
742
  None, "--platform", help="Set Docker target platform (e.g., linux/amd64)"
743
743
  ),
744
+ secrets: list[str] | None = typer.Option( # noqa: B008
745
+ None,
746
+ "--secret",
747
+ help=("Docker build secret (repeatable), e.g. --secret id=GITHUB_TOKEN,env=GITHUB_TOKEN"),
748
+ ),
744
749
  remote_cache: str | None = typer.Option(
745
750
  None, "--remote-cache", help="Enable remote cache using Amazon ECR with specified repo name"
746
751
  ),
@@ -812,7 +817,15 @@ def build(
812
817
  i += 1
813
818
 
814
819
  build_command(
815
- directory, tag, no_cache, verbose, env_vars, platform, remote_cache, build_args or None
820
+ directory,
821
+ tag,
822
+ no_cache,
823
+ verbose,
824
+ env_vars,
825
+ platform,
826
+ secrets,
827
+ remote_cache,
828
+ build_args or None,
816
829
  )
817
830
 
818
831
 
@@ -555,11 +555,13 @@ def build_docker_image(
555
555
  verbose: bool = False,
556
556
  build_args: dict[str, str] | None = None,
557
557
  platform: str | None = None,
558
+ secrets: list[str] | None = None,
558
559
  remote_cache: str | None = None,
559
560
  ) -> bool:
560
561
  """Build a Docker image from a directory."""
561
562
  hud_console = HUDConsole()
562
563
  build_args = build_args or {}
564
+ secrets = secrets or []
563
565
 
564
566
  # Check if Dockerfile exists (prefer Dockerfile.hud)
565
567
  dockerfile = find_dockerfile(directory)
@@ -629,6 +631,10 @@ def build_docker_image(
629
631
  for key, value in build_args.items():
630
632
  cmd.extend(["--build-arg", f"{key}={value}"])
631
633
 
634
+ # Add secrets
635
+ for secret in secrets:
636
+ cmd.extend(["--secret", secret])
637
+
632
638
  cmd.append(str(directory))
633
639
 
634
640
  # Always show build output
@@ -636,7 +642,10 @@ def build_docker_image(
636
642
 
637
643
  try:
638
644
  # Use Docker's native output formatting - no capture, let Docker handle display
639
- result = subprocess.run(cmd, check=False) # noqa: S603
645
+ env = os.environ.copy()
646
+ if secrets:
647
+ env["DOCKER_BUILDKIT"] = "1"
648
+ result = subprocess.run(cmd, check=False, env=env) # noqa: S603
640
649
  return result.returncode == 0
641
650
  except Exception as e:
642
651
  hud_console.error(f"Build error: {e}")
@@ -650,6 +659,7 @@ def build_environment(
650
659
  verbose: bool = False,
651
660
  env_vars: dict[str, str] | None = None,
652
661
  platform: str | None = None,
662
+ secrets: list[str] | None = None,
653
663
  remote_cache: str | None = None,
654
664
  build_args: dict[str, str] | None = None,
655
665
  ) -> None:
@@ -725,6 +735,7 @@ def build_environment(
725
735
  verbose,
726
736
  build_args=build_args or None,
727
737
  platform=platform,
738
+ secrets=secrets,
728
739
  remote_cache=remote_cache,
729
740
  ):
730
741
  hud_console.error("Docker build failed")
@@ -1008,16 +1019,23 @@ def build_environment(
1008
1019
  for key, value in build_args.items():
1009
1020
  label_cmd.extend(["--build-arg", f"{key}={value}"])
1010
1021
 
1022
+ # Add secrets to final image build (same as initial build)
1023
+ for secret in secrets or []:
1024
+ label_cmd.extend(["--secret", secret])
1025
+
1011
1026
  label_cmd.append(str(env_dir))
1012
1027
 
1013
1028
  # Run rebuild using Docker's native output formatting
1029
+ env = os.environ.copy()
1030
+ if secrets:
1031
+ env["DOCKER_BUILDKIT"] = "1"
1014
1032
  if verbose:
1015
1033
  # Show Docker's native output when verbose
1016
- result = subprocess.run(label_cmd, check=False) # noqa: S603
1034
+ result = subprocess.run(label_cmd, check=False, env=env) # noqa: S603
1017
1035
  else:
1018
1036
  # Capture output for error reporting, but don't show unless it fails
1019
1037
  result = subprocess.run( # noqa: S603
1020
- label_cmd, capture_output=True, text=True, check=False
1038
+ label_cmd, capture_output=True, text=True, check=False, env=env
1021
1039
  )
1022
1040
 
1023
1041
  if result.returncode != 0:
@@ -1111,10 +1129,15 @@ def build_command(
1111
1129
  verbose: bool = typer.Option(False, "--verbose", "-v", help="Show detailed output"),
1112
1130
  env_vars: dict[str, str] | None = None,
1113
1131
  platform: str | None = None,
1132
+ secrets: list[str] | None = typer.Option( # noqa: B008
1133
+ None,
1134
+ "--secret",
1135
+ help=("Docker build secret (repeatable), e.g. --secret id=GITHUB_TOKEN,env=GITHUB_TOKEN"),
1136
+ ),
1114
1137
  remote_cache: str | None = None,
1115
1138
  build_args: dict[str, str] | None = None,
1116
1139
  ) -> None:
1117
1140
  """Build a HUD environment and generate lock file."""
1118
1141
  build_environment(
1119
- directory, tag, no_cache, verbose, env_vars, platform, remote_cache, build_args
1142
+ directory, tag, no_cache, verbose, env_vars, platform, secrets, remote_cache, build_args
1120
1143
  )
@@ -164,6 +164,7 @@ class EvalConfig(BaseModel):
164
164
  "auto_respond",
165
165
  "quiet",
166
166
  "gateway",
167
+ "taskset",
167
168
  }
168
169
  # Fields loaded from [agent] section
169
170
  _AGENT_FIELDS: ClassVar[set[str]] = {"allowed_tools", "disallowed_tools"}
@@ -184,6 +185,7 @@ class EvalConfig(BaseModel):
184
185
  remote: bool = False
185
186
  quiet: bool = False # Suppress opening browser for eval links
186
187
  gateway: bool = False # Use HUD Gateway for LLM API calls
188
+ taskset: str | None = None # Taskset slug to associate job with
187
189
 
188
190
  # Base agent config (these merge with task's agent_config)
189
191
  allowed_tools: list[str] | None = None
@@ -655,16 +657,41 @@ async def _run_evaluation(cfg: EvalConfig) -> tuple[list[Any], list[Any]]:
655
657
  agent_kwargs = {
656
658
  k: v for k, v in agent_kwargs.items() if k not in ("api_key", "model_client")
657
659
  }
658
- # Create a job ID for tracking
659
660
  import uuid
660
661
 
661
662
  from hud.datasets.utils import submit_rollouts
663
+ from hud.eval.manager import _send_job_enter
662
664
 
663
665
  job_id = str(uuid.uuid4())
664
666
  hud_console.info(
665
667
  f"Submitting {len(tasks)} task(s) for remote execution (job_id: {job_id})…"
666
668
  )
667
669
 
670
+ if cfg.taskset:
671
+ tasks_to_create = [t for t in tasks if not t.id]
672
+ tasks_data = (
673
+ [t.model_dump(mode="json", exclude_none=True) for t in tasks_to_create]
674
+ if tasks_to_create
675
+ else None
676
+ )
677
+ ids = await _send_job_enter(
678
+ job_id=job_id,
679
+ name=f"eval ({cfg.source})" if cfg.source else "eval",
680
+ variants=None,
681
+ group=cfg.group_size,
682
+ api_key=None,
683
+ taskset=cfg.taskset,
684
+ tasks=tasks_data,
685
+ )
686
+ if ids:
687
+ if len(ids) != len(tasks_to_create):
688
+ hud_console.warning(
689
+ f"Task count mismatch: sent {len(tasks_to_create)} tasks, "
690
+ f"received {len(ids)} IDs. Some tasks may not be linked."
691
+ )
692
+ for task_obj, task_version_id in zip(tasks_to_create, ids, strict=False):
693
+ task_obj.id = task_version_id
694
+
668
695
  await submit_rollouts(
669
696
  tasks=tasks,
670
697
  job_id=job_id,
@@ -701,6 +728,7 @@ async def _run_evaluation(cfg: EvalConfig) -> tuple[list[Any], list[Any]]:
701
728
  max_concurrent=cfg.max_concurrent,
702
729
  group_size=cfg.group_size,
703
730
  quiet=cfg.quiet,
731
+ taskset=cfg.taskset,
704
732
  )
705
733
 
706
734
  # Show reward for single task
@@ -767,6 +795,9 @@ def eval_command(
767
795
  gateway: bool = typer.Option(
768
796
  False, "--gateway", "-g", help="Route LLM API calls through HUD Gateway"
769
797
  ),
798
+ taskset: str | None = typer.Option(
799
+ None, "--taskset", "-t", help="Taskset slug to associate job with"
800
+ ),
770
801
  ) -> None:
771
802
  """🚀 Run evaluation on datasets or individual tasks with agents.
772
803
 
@@ -801,6 +832,7 @@ def eval_command(
801
832
  byok=byok,
802
833
  quiet=quiet,
803
834
  gateway=gateway,
835
+ taskset=taskset,
804
836
  )
805
837
 
806
838
  # Find source if not provided
@@ -60,12 +60,12 @@ class TestIncrementVersion:
60
60
  def test_increment_minor(self):
61
61
  """Test incrementing minor version."""
62
62
  assert increment_version("1.2.3", "minor") == "1.3.0"
63
- assert increment_version("0.5.12", "minor") == "0.6.0"
63
+ assert increment_version("0.5.13", "minor") == "0.6.0"
64
64
 
65
65
  def test_increment_major(self):
66
66
  """Test incrementing major version."""
67
67
  assert increment_version("1.2.3", "major") == "2.0.0"
68
- assert increment_version("0.5.12", "major") == "1.0.0"
68
+ assert increment_version("0.5.13", "major") == "1.0.0"
69
69
 
70
70
  def test_increment_with_v_prefix(self):
71
71
  """Test incrementing version with v prefix."""
@@ -29,6 +29,7 @@ async def run_dataset(
29
29
  max_concurrent: int = 30,
30
30
  group_size: int = 1,
31
31
  quiet: bool = True,
32
+ taskset: str | None = None,
32
33
  ) -> list[EvalContext]:
33
34
  """Run an agent on a dataset of tasks.
34
35
 
@@ -96,6 +97,7 @@ async def run_dataset(
96
97
  group=group_size,
97
98
  max_concurrent=max_concurrent,
98
99
  quiet=quiet,
100
+ taskset=taskset,
99
101
  ) as ctx:
100
102
  # Build agent params - use system_prompt from ctx (set from task.agent_config)
101
103
  final_agent_params = dict(agent_params or {})
@@ -382,6 +382,7 @@ class ScenarioMixin:
382
382
  self,
383
383
  name: str | None = None,
384
384
  description: str | None = None,
385
+ required_env_vars: list[str] | None = None,
385
386
  ) -> Callable[
386
387
  [Callable[..., AsyncGenerator[Any, None]]],
387
388
  Callable[..., AsyncGenerator[Any, None]],
@@ -396,19 +397,21 @@ class ScenarioMixin:
396
397
  Args:
397
398
  name: Optional name for the scenario (defaults to function name)
398
399
  description: Optional description of what the scenario does
400
+ required_env_vars: Optional list of environment variable names this scenario requires.
401
+ These are used by the HUD platform to check if users have configured the
402
+ necessary API keys/credentials before running this specific scenario.
399
403
 
400
404
  Example:
401
- @env.scenario()
402
- async def search_cats(url: str):
403
- await env.call_tool("navigate", url=url)
404
- yield "Find cat images"
405
- result = await env.call_tool("count_cats")
406
- yield float(result > 0)
405
+ @env.scenario(required_env_vars=["OPENAI_API_KEY"])
406
+ async def chat(query: str):
407
+ yield f"Answer this question: {query}"
408
+ # ... evaluate
409
+ yield 1.0
407
410
 
408
411
  # MCP client usage:
409
- # 1. get_prompt("{env_name}:search_cats", {url: "..."}) -> prompt messages
412
+ # 1. get_prompt("{env_name}:chat", {query: "..."}) -> prompt messages
410
413
  # 2. agent runs...
411
- # 3. read_resource("{env_name}:search_cats") -> {"reward": 0.95}
414
+ # 3. read_resource("{env_name}:chat") -> {"reward": 0.95}
412
415
  """
413
416
 
414
417
  def decorator(
@@ -568,6 +571,8 @@ class ScenarioMixin:
568
571
  scenario_meta["code"] = source_code
569
572
  if prompt_args:
570
573
  scenario_meta["arguments"] = prompt_args
574
+ if required_env_vars:
575
+ scenario_meta["required_env_vars"] = required_env_vars
571
576
 
572
577
  prompt = FunctionPrompt(
573
578
  name=scenario_id,
@@ -56,14 +56,16 @@ def _get_eval_name(tasks: list[Task] | None = None) -> str:
56
56
  return "eval"
57
57
 
58
58
 
59
- def _send_job_enter(
59
+ async def _send_job_enter(
60
60
  job_id: str,
61
61
  name: str,
62
62
  variants: dict[str, Any] | None,
63
63
  group: int,
64
64
  api_key: str | None,
65
- ) -> None:
66
- """Send job enter payload (sync request before traces start)."""
65
+ taskset: str | None = None,
66
+ tasks: list[dict[str, Any]] | None = None,
67
+ ) -> list[str] | None:
68
+ """Send job enter payload (async request before traces start)."""
67
69
  import httpx
68
70
 
69
71
  from hud.eval.types import JobEnterPayload
@@ -71,23 +73,35 @@ def _send_job_enter(
71
73
 
72
74
  api_key = api_key or settings.api_key
73
75
  if not settings.telemetry_enabled or not api_key:
74
- return
76
+ return None
75
77
 
76
78
  payload = JobEnterPayload(
77
79
  name=name,
78
80
  variants=variants,
79
81
  group=group,
82
+ taskset=taskset,
83
+ tasks=tasks if taskset else None, # only send tasks if taskset specified
80
84
  )
81
85
 
82
86
  try:
83
- httpx.post(
84
- f"{settings.hud_api_url}/trace/job/{job_id}/enter",
85
- json=payload.model_dump(exclude_none=True),
86
- headers={"Authorization": f"Bearer {api_key}"},
87
- timeout=10.0,
88
- )
87
+ async with httpx.AsyncClient(timeout=10.0) as client:
88
+ resp = await client.post(
89
+ f"{settings.hud_api_url}/trace/job/{job_id}/enter",
90
+ json=payload.model_dump(exclude_none=True),
91
+ headers={"Authorization": f"Bearer {api_key}"},
92
+ )
93
+ if resp.is_success:
94
+ try:
95
+ data = resp.json()
96
+ except Exception:
97
+ return None
98
+ if isinstance(data, dict):
99
+ ids = data.get("task_version_ids")
100
+ if isinstance(ids, list) and all(isinstance(x, str) for x in ids):
101
+ return ids
89
102
  except Exception as e:
90
103
  logger.warning("Failed to send job enter: %s", e)
104
+ return None
91
105
 
92
106
 
93
107
  @asynccontextmanager
@@ -105,6 +119,7 @@ async def run_eval(
105
119
  max_concurrent: int | None = None,
106
120
  trace: bool = True,
107
121
  quiet: bool = False,
122
+ taskset: str | None = None,
108
123
  ) -> AsyncGenerator[EvalContext, None]:
109
124
  """Standalone eval context manager.
110
125
 
@@ -235,13 +250,37 @@ async def run_eval(
235
250
 
236
251
  if total_evals == 1:
237
252
  if tasks:
253
+ # Even for single-task evals, --taskset requires a job_enter call so the run
254
+ # and task are linked to the taskset (via job_id + task_version_id).
255
+ job_id_for_run = job_id
256
+ if taskset:
257
+ eval_name = _get_eval_name(tasks=tasks)
258
+ if job_id_for_run is None:
259
+ job_id_for_run = str(uuid.uuid4())
260
+
261
+ task_data = None
262
+ if not tasks[0].id:
263
+ task_data = [tasks[0].model_dump(mode="json", exclude_none=True)]
264
+
265
+ created_task_version_ids = await _send_job_enter(
266
+ job_id=job_id_for_run,
267
+ name=eval_name,
268
+ variants=variants,
269
+ group=group,
270
+ api_key=api_key,
271
+ taskset=taskset,
272
+ tasks=task_data,
273
+ )
274
+ if created_task_version_ids and not tasks[0].id:
275
+ tasks[0].id = created_task_version_ids[0]
276
+
238
277
  # Single task - use EvalContext.from_task()
239
278
  ctx = EvalContext.from_task(
240
279
  tasks[0],
241
280
  name=name,
242
281
  trace_id=trace_id,
243
282
  api_key=api_key,
244
- job_id=job_id,
283
+ job_id=job_id_for_run,
245
284
  group_id=group_id,
246
285
  variants=variant_combos[0],
247
286
  code_snippet=code_snippet,
@@ -273,13 +312,41 @@ async def run_eval(
273
312
  job_url = f"https://hud.ai/jobs/{implicit_job_id}"
274
313
 
275
314
  # Send job enter (sync request before traces start)
276
- _send_job_enter(
315
+ # Serialize tasks for auto-add to taskset (only tasks without existing backend id).
316
+ # For v5 scenario tasks, the backend task_version_id is carried in Task.id.
317
+ tasks_data = None
318
+ tasks_to_create: list[Task] = []
319
+ if taskset and tasks:
320
+ tasks_to_create = [t for t in tasks if not t.id]
321
+ tasks_data = (
322
+ [t.model_dump(mode="json", exclude_none=True) for t in tasks_to_create]
323
+ if tasks_to_create
324
+ else None
325
+ )
326
+ created_task_version_ids = await _send_job_enter(
277
327
  job_id=implicit_job_id,
278
328
  name=eval_name,
279
329
  variants=variants,
280
330
  group=group,
281
331
  api_key=api_key,
332
+ taskset=taskset,
333
+ tasks=tasks_data,
282
334
  )
335
+ if created_task_version_ids and tasks_to_create:
336
+ # Assign backend IDs back onto the in-memory tasks so trace enter includes
337
+ # task_version_id.
338
+ # Platform guarantees ordered one-to-one mapping, but warn if counts differ.
339
+ if len(created_task_version_ids) != len(tasks_to_create):
340
+ logger.warning(
341
+ "Task count mismatch: sent %d tasks, received %d IDs. "
342
+ "Some tasks may not be linked to the taskset.",
343
+ len(tasks_to_create),
344
+ len(created_task_version_ids),
345
+ )
346
+ for task_obj, task_version_id in zip(
347
+ tasks_to_create, created_task_version_ids, strict=False
348
+ ):
349
+ task_obj.id = task_version_id
283
350
 
284
351
  # Print job URL (not individual trace URLs)
285
352
  if not quiet:
@@ -53,6 +53,8 @@ class JobEnterPayload(BaseModel):
53
53
  name: str | None = None
54
54
  variants: dict[str, Any] | None = None # Full variant config
55
55
  group: int | None = None
56
+ taskset: str | None = None # taskset slug to associate job with
57
+ tasks: list[dict[str, Any]] | None = None # task definitions to add to taskset
56
58
 
57
59
 
58
60
  __all__ = [
@@ -5,4 +5,4 @@ def test_import():
5
5
  """Test that the package can be imported."""
6
6
  import hud
7
7
 
8
- assert hud.__version__ == "0.5.12"
8
+ assert hud.__version__ == "0.5.13"
@@ -4,4 +4,4 @@ Version information for the HUD SDK.
4
4
 
5
5
  from __future__ import annotations
6
6
 
7
- __version__ = "0.5.12"
7
+ __version__ = "0.5.13"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "hud-python"
3
- version = "0.5.12"
3
+ version = "0.5.13"
4
4
  description = "SDK for the HUD platform."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11, <3.13"
@@ -140,7 +140,7 @@ dev = [
140
140
  "dotenv>=0.9.9",
141
141
  # Testing and linting
142
142
  "ruff >=0.11.8",
143
- "pytest >=8.1.1,<9",
143
+ "pytest >=8.1.1",
144
144
  "pytest-asyncio",
145
145
  "pytest-mock",
146
146
  "pytest-cov",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes