hud-python 0.6.0__tar.gz → 0.6.2__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.
- {hud_python-0.6.0 → hud_python-0.6.2}/.gitignore +4 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/PKG-INFO +1 -1
- {hud_python-0.6.0 → hud_python-0.6.2}/cookbooks/rl-training/README.md +15 -7
- hud_python-0.6.2/hud/cli/init.py +147 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/models.py +4 -0
- hud_python-0.6.2/hud/cli/presets.py +139 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/tests/test_init.py +3 -3
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/utils/gateway.py +1 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/version.py +1 -1
- {hud_python-0.6.0 → hud_python-0.6.2}/pyproject.toml +1 -1
- hud_python-0.6.0/hud/cli/init.py +0 -76
- {hud_python-0.6.0 → hud_python-0.6.2}/LICENSE +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/README.md +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/cookbooks/a2a-chat/README.md +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/cookbooks/a2a-chat/pyproject.toml +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/cookbooks/codex-coding/README.md +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/cookbooks/codex-coding/pyproject.toml +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/cookbooks/rl-training/pyproject.toml +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/__main__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/_legacy.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/base.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/browser_use/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/browser_use/agent.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/claude/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/claude/agent.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/claude/sdk/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/claude/sdk/agent.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/claude/sdk/computer_mcp.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/claude/tools/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/claude/tools/base.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/claude/tools/coding.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/claude/tools/computer.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/claude/tools/hosted.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/claude/tools/mcp_proxy.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/claude/tools/settings.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/claude/tools/tests/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/claude/tools/tests/test_computer.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/gemini/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/gemini/agent.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/gemini/settings.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/gemini/tools/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/gemini/tools/base.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/gemini/tools/coding.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/gemini/tools/computer.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/gemini/tools/filesystem.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/gemini/tools/hosted.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/gemini/tools/mcp_proxy.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/gemini/tools/tests/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/gemini/tools/tests/test_computer.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/misc/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/misc/response_automation.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/openai/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/openai/agent.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/openai/tools/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/openai/tools/apply_patch.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/openai/tools/base.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/openai/tools/coding.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/openai/tools/computer.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/openai/tools/hosted.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/openai/tools/mcp_proxy.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/openai/tools/strict_schema.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/openai/tools/tests/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/openai/tools/tests/test_computer.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/openai/tools/tests/test_strict_schema.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/openai_compatible/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/openai_compatible/agent.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/openai_compatible/tools/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/openai_compatible/tools/base.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/openai_compatible/tools/filesystem.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/openai_compatible/tools/mcp_proxy.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/robot/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/robot/_types.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/robot/adapter.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/robot/agent.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/robot/model.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/tests/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/tests/test_apply_patch.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/tests/test_base.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/tests/test_claude_agent.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/tests/test_claude_sdk_agent.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/tests/test_gemini_agent.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/tests/test_openai_agent.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/tests/test_openai_compatible_agent.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/tests/test_provider_native_tools.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/tests/test_tool_agent.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/tests/test_trace.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/tool_agent.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/tools/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/tools/base.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/tools/hosted.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/tools/mcp.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/tools/rfb.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/tools/ssh.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/agents/types.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/capabilities/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/capabilities/base.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/capabilities/cdp.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/capabilities/filetracking.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/capabilities/mcp.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/capabilities/rfb.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/capabilities/robot.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/capabilities/ssh.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/__main__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/cancel.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/client.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/deploy.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/eval.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/login.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/serve.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/sync.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/task.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/templates.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/tests/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/tests/test_cli_init.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/tests/test_cli_main.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/tests/test_cli_more_wrappers.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/tests/test_deploy.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/tests/test_eval_bedrock.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/tests/test_eval_config.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/tests/test_main_module.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/tests/test_sync_export.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/utils/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/utils/api.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/utils/build_display.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/utils/build_logs.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/utils/config.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/utils/context.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/utils/display.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/utils/jobs.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/utils/registry.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/utils/source.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/utils/tasks.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/utils/tests/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/utils/tests/test_build_display.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/utils/tests/test_config.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/utils/tests/test_context.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/utils/tests/test_registry.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/utils/tests/test_source.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/utils/tests/test_tasks.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/utils/tests/test_version_check.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/cli/utils/version_check.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/clients/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/clients/client.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/clients/tests/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/clients/tests/test_connect.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/conftest.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/environment/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/environment/env.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/environment/file_tracker.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/environment/file_tracking.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/environment/legacy.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/environment/robot/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/environment/robot/bridge.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/environment/robot/endpoint.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/environment/robot/sim_runner.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/environment/server.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/environment/tests/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/environment/tests/conftest.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/environment/tests/test_capability_backing.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/environment/tests/test_file_tracker.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/environment/tests/test_file_tracking.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/environment/tests/test_legacy.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/environment/tests/test_loader.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/environment/tests/test_manifest.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/environment/tests/test_server.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/environment/tests/test_tunnel.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/environment/utils.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/environment/workspace.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/eval/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/eval/chat.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/eval/file_tracking.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/eval/job.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/eval/run.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/eval/runtime.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/eval/sync.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/eval/task.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/eval/taskset.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/eval/tests/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/eval/tests/test_chat.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/eval/tests/test_docker_provider.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/eval/tests/test_file_tracking_observer.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/eval/tests/test_hosted.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/eval/tests/test_job.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/eval/tests/test_rollout.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/eval/tests/test_sync.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/eval/tests/test_task.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/graders/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/graders/base.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/graders/bash.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/graders/combine.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/graders/judge.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/graders/results.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/graders/text.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/patches/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/patches/mcp_patches.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/patches/tests/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/patches/tests/test_warnings.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/patches/warnings.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/py.typed +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/server.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/settings.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/telemetry/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/telemetry/context.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/telemetry/exporter.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/telemetry/filetracking.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/telemetry/instrument.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/telemetry/span.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/telemetry/tests/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/telemetry/tests/test_exporter.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/telemetry/tests/test_filetracking.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/telemetry/tests/test_instrument.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/train/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/train/base.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/train/client.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/train/types.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/types.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/utils/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/utils/exceptions.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/utils/hints.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/utils/hud_console.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/utils/modules.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/utils/platform.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/utils/requests.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/utils/serialization.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/utils/tests/__init__.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/utils/tests/test_exceptions.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/utils/tests/test_hints.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/utils/tests/test_hud_console.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/utils/tests/test_platform.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/utils/tests/test_requests.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/utils/tests/test_serialization.py +0 -0
- {hud_python-0.6.0 → hud_python-0.6.2}/hud/utils/time.py +0 -0
|
@@ -7,6 +7,10 @@ __pycache__
|
|
|
7
7
|
.pytest_cache
|
|
8
8
|
dist/
|
|
9
9
|
build/
|
|
10
|
+
# The broad build/ rule above also matches docs/v6/build/, which is real docs
|
|
11
|
+
# content (linked from docs.json). Keep tracking it so docs.hud.ai/v6/build/*
|
|
12
|
+
# does not 404.
|
|
13
|
+
!docs/v6/build/
|
|
10
14
|
*.egg-info/
|
|
11
15
|
uv.lock
|
|
12
16
|
|
|
@@ -18,22 +18,30 @@ each `optim_step` closes the on-policy loop.
|
|
|
18
18
|
|
|
19
19
|
## Run
|
|
20
20
|
|
|
21
|
-
Needs `HUD_API_KEY`
|
|
21
|
+
Needs `HUD_API_KEY` (from your environment or `.env`). List the gateway models
|
|
22
|
+
on your account, pick a trainable one (the **Trainable** column marks them), and
|
|
23
|
+
set it as the `MODEL` constant at the top of `simple_train.py` /
|
|
24
|
+
`ppo_custom_loss.py`:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
hud models list # Name | Model (API) | ID | Provider | Agent | Trainable
|
|
28
|
+
```
|
|
22
29
|
|
|
23
30
|
**Train on a deployed taskset (the real flow).** You've built a taskset and
|
|
24
|
-
pushed it (`hud deploy` + `hud sync`); now train on it.
|
|
25
|
-
and rollouts run on **remote HUD
|
|
31
|
+
pushed it (`hud deploy` + `hud sync`); now train on it. Set the `TASKSET`
|
|
32
|
+
constant in `common.py` to its name/id and rollouts run on **remote HUD
|
|
33
|
+
boxes** — nothing local:
|
|
26
34
|
|
|
27
35
|
```bash
|
|
28
|
-
|
|
29
|
-
|
|
36
|
+
uv run simple_train.py --steps 10
|
|
37
|
+
uv run ppo_custom_loss.py --steps 10
|
|
30
38
|
```
|
|
31
39
|
|
|
32
|
-
**Quickstart (self-contained).** Leave `
|
|
40
|
+
**Quickstart (self-contained).** Leave `TASKSET` empty and a tiny local
|
|
33
41
|
arithmetic taskset runs against the bundled `env.py`:
|
|
34
42
|
|
|
35
43
|
```bash
|
|
36
|
-
|
|
44
|
+
uv run simple_train.py --steps 10
|
|
37
45
|
```
|
|
38
46
|
|
|
39
47
|
The swap is `common.py`'s `load_taskset_and_runtime()` — `Taskset.from_api(name)`
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"""``hud init``: scaffold a new HUD environment package.
|
|
2
|
+
|
|
3
|
+
By default (or in a non-interactive shell) it writes a minimal local scaffold —
|
|
4
|
+
no network, no API key. With ``--preset`` (or via the interactive picker) it
|
|
5
|
+
downloads one of the starter environments from GitHub instead — the same set the
|
|
6
|
+
platform's *environments/new* flow offers. See :mod:`hud.cli.presets`.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import shutil
|
|
12
|
+
import sys
|
|
13
|
+
import tarfile
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from typing import Any
|
|
16
|
+
|
|
17
|
+
import httpx
|
|
18
|
+
import typer
|
|
19
|
+
|
|
20
|
+
from hud.utils.hud_console import HUDConsole
|
|
21
|
+
|
|
22
|
+
from .presets import ENVIRONMENT_PRESETS, PRESETS_BY_ID, EnvironmentPreset, materialize_preset
|
|
23
|
+
from .templates import DOCKERFILE_HUD, ENV_PY, PYPROJECT_TOML, TASKS_PY
|
|
24
|
+
|
|
25
|
+
_LOCAL_SCAFFOLD = "__local__"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _python_name(name: str) -> str:
|
|
29
|
+
"""Normalize a package name into a Python-identifier-ish env name."""
|
|
30
|
+
name = name.replace("-", "_").replace(" ", "_")
|
|
31
|
+
return "".join(c if c.isalnum() or c == "_" else "_" for c in name)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _resolve_preset(preset: str | None, hud_console: HUDConsole) -> EnvironmentPreset | None:
|
|
35
|
+
"""Pick the starter: an explicit ``--preset`` id, an interactive choice, or
|
|
36
|
+
``None`` for the minimal local scaffold."""
|
|
37
|
+
if preset is not None:
|
|
38
|
+
chosen = PRESETS_BY_ID.get(preset)
|
|
39
|
+
if chosen is None:
|
|
40
|
+
available = ", ".join(PRESETS_BY_ID)
|
|
41
|
+
hud_console.error(f"Unknown preset {preset!r}. Available: {available}")
|
|
42
|
+
raise typer.Exit(1)
|
|
43
|
+
return chosen
|
|
44
|
+
|
|
45
|
+
# No flag: pick interactively when we have a TTY, else the local scaffold.
|
|
46
|
+
if not (sys.stdin.isatty() and sys.stdout.isatty()):
|
|
47
|
+
return None
|
|
48
|
+
|
|
49
|
+
choices: list[str | dict[str, Any]] = [
|
|
50
|
+
{"name": "Minimal (local scaffold, no download)", "value": _LOCAL_SCAFFOLD},
|
|
51
|
+
*({"name": f"{p.name} — {p.description}", "value": p.id} for p in ENVIRONMENT_PRESETS),
|
|
52
|
+
]
|
|
53
|
+
selected = hud_console.select("Choose a starter", choices, default=0)
|
|
54
|
+
return None if selected == _LOCAL_SCAFFOLD else PRESETS_BY_ID[selected]
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _write_local_scaffold(target: Path, env_name: str, hud_console: HUDConsole) -> None:
|
|
58
|
+
"""Write the bundled minimal env package into ``target``."""
|
|
59
|
+
files = {
|
|
60
|
+
"pyproject.toml": PYPROJECT_TOML.format(name=env_name.replace("_", "-")),
|
|
61
|
+
"env.py": ENV_PY.format(env_name=env_name),
|
|
62
|
+
"tasks.py": TASKS_PY.format(env_name=env_name),
|
|
63
|
+
"Dockerfile.hud": DOCKERFILE_HUD,
|
|
64
|
+
}
|
|
65
|
+
target.mkdir(parents=True, exist_ok=True)
|
|
66
|
+
for filename, content in files.items():
|
|
67
|
+
(target / filename).write_text(content)
|
|
68
|
+
hud_console.status_item(filename, "✓")
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def init_command(
|
|
72
|
+
name: str = typer.Argument(..., help="Environment name (directory to create)"),
|
|
73
|
+
directory: str = typer.Option(".", "--dir", "-d", help="Parent directory"),
|
|
74
|
+
force: bool = typer.Option(False, "--force", "-f", help="Overwrite existing files"),
|
|
75
|
+
preset: str | None = typer.Option(
|
|
76
|
+
None,
|
|
77
|
+
"--preset",
|
|
78
|
+
"-p",
|
|
79
|
+
help="Starter preset to download from GitHub (e.g. blank, coding, browser, "
|
|
80
|
+
"deepresearch, rubrics, remote-browser). Omit for an interactive picker; in a "
|
|
81
|
+
"non-interactive shell, omitting it writes the minimal local scaffold.",
|
|
82
|
+
),
|
|
83
|
+
) -> None:
|
|
84
|
+
"""🚀 Create a new HUD environment package.
|
|
85
|
+
|
|
86
|
+
[not dim]With no --preset, writes a minimal local scaffold (env.py, tasks.py,
|
|
87
|
+
Dockerfile.hud, pyproject.toml) — or, in a TTY, lets you pick a starter. With
|
|
88
|
+
--preset, downloads that starter from GitHub.
|
|
89
|
+
|
|
90
|
+
Examples:
|
|
91
|
+
hud init my-env # interactive picker (or local scaffold)
|
|
92
|
+
hud init my-env --preset coding # download the coding starter
|
|
93
|
+
hud init my-env --dir envs # create ./envs/my-env[/not dim]
|
|
94
|
+
"""
|
|
95
|
+
hud_console = HUDConsole()
|
|
96
|
+
|
|
97
|
+
target = Path(directory) / name
|
|
98
|
+
if target.exists() and any(target.iterdir()) and not force:
|
|
99
|
+
hud_console.error(f"{target} already exists and is not empty (use --force)")
|
|
100
|
+
raise typer.Exit(1)
|
|
101
|
+
|
|
102
|
+
chosen = _resolve_preset(preset, hud_console)
|
|
103
|
+
|
|
104
|
+
hud_console.header(f"HUD Init: {name}")
|
|
105
|
+
if chosen is not None:
|
|
106
|
+
hud_console.info(f"Downloading {chosen.owner}/{chosen.repo} …")
|
|
107
|
+
created = not target.exists()
|
|
108
|
+
try:
|
|
109
|
+
materialize_preset(chosen, target)
|
|
110
|
+
except (httpx.HTTPError, tarfile.TarError, ValueError, OSError) as exc:
|
|
111
|
+
# Don't leave a half-written tree behind — it would trip the
|
|
112
|
+
# non-empty-directory guard on the next run. Only remove a directory
|
|
113
|
+
# this run created (never a dir the user already had).
|
|
114
|
+
if created and target.exists():
|
|
115
|
+
shutil.rmtree(target, ignore_errors=True)
|
|
116
|
+
hud_console.error(f"Failed to fetch preset {chosen.id!r}: {exc}")
|
|
117
|
+
raise typer.Exit(1) from exc
|
|
118
|
+
hud_console.status_item(f"{chosen.owner}/{chosen.repo}", "✓")
|
|
119
|
+
else:
|
|
120
|
+
_write_local_scaffold(target, _python_name(name), hud_console)
|
|
121
|
+
|
|
122
|
+
hud_console.section_title("Next Steps")
|
|
123
|
+
hud_console.info("")
|
|
124
|
+
hud_console.command_example(f"cd {target}", "1. Enter the package")
|
|
125
|
+
hud_console.info("")
|
|
126
|
+
if chosen is not None:
|
|
127
|
+
hud_console.info("2. Read the README for this starter's setup + tasks.")
|
|
128
|
+
hud_console.info("")
|
|
129
|
+
hud_console.command_example("hud eval tasks.py claude", "3. Run an agent over the tasks")
|
|
130
|
+
hud_console.info("")
|
|
131
|
+
hud_console.info("4. Deploy for scale")
|
|
132
|
+
hud_console.info(" hud deploy, then run many evals in parallel.")
|
|
133
|
+
else:
|
|
134
|
+
hud_console.info("2. Define task definitions in env.py")
|
|
135
|
+
hud_console.info(" A @env.template is an async generator: it yields a prompt, then")
|
|
136
|
+
hud_console.info(" (after the agent answers) yields a reward.")
|
|
137
|
+
hud_console.info("")
|
|
138
|
+
hud_console.info("3. List the tasks to run in tasks.py")
|
|
139
|
+
hud_console.info(" Call a task with args to bind a runnable Task.")
|
|
140
|
+
hud_console.info("")
|
|
141
|
+
hud_console.command_example("hud eval tasks.py claude", "4. Run an agent over them")
|
|
142
|
+
hud_console.info("")
|
|
143
|
+
hud_console.info("5. Deploy for scale")
|
|
144
|
+
hud_console.info(" hud deploy, then run many evals in parallel.")
|
|
145
|
+
hud_console.info("")
|
|
146
|
+
hud_console.info("Tip: Install the HUD skill so your coding agent can help you build:")
|
|
147
|
+
hud_console.command_example("npx skills add docs.hud.ai", "Install HUD skill")
|
|
@@ -56,14 +56,18 @@ def list_models(
|
|
|
56
56
|
table = Table()
|
|
57
57
|
table.add_column("Name", style="cyan")
|
|
58
58
|
table.add_column("Model (API)", style="green")
|
|
59
|
+
table.add_column("ID", style="blue", no_wrap=True)
|
|
59
60
|
table.add_column("Provider", style="yellow")
|
|
60
61
|
table.add_column("Agent", style="magenta")
|
|
62
|
+
table.add_column("Trainable", style="green", justify="center")
|
|
61
63
|
for model in models_list:
|
|
62
64
|
table.add_row(
|
|
63
65
|
model.name or model.id or "-",
|
|
64
66
|
model.model_name or model.id or "-",
|
|
67
|
+
model.id or "-",
|
|
65
68
|
model.provider.name or "-",
|
|
66
69
|
model.sdk_agent_type or "-",
|
|
70
|
+
"✓" if model.is_trainable else "",
|
|
67
71
|
)
|
|
68
72
|
console.print(table)
|
|
69
73
|
console.print(f"\n[dim]Gateway: {settings.hud_gateway_url}[/dim]")
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"""Starter presets for ``hud init`` — the same set offered by the platform's
|
|
2
|
+
*environments/new* flow.
|
|
3
|
+
|
|
4
|
+
Each preset is a standalone public GitHub repo under ``hud-evals``. ``hud init``
|
|
5
|
+
downloads the repo tarball (no ``git`` required) and extracts it into the target
|
|
6
|
+
directory. Keep this list in sync with the frontend's ``ENVIRONMENT_TEMPLATES``
|
|
7
|
+
(``app/(auth)/environments/components/EnvironmentTemplates.tsx``).
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import io
|
|
13
|
+
import os
|
|
14
|
+
import tarfile
|
|
15
|
+
from dataclasses import dataclass
|
|
16
|
+
from typing import TYPE_CHECKING
|
|
17
|
+
|
|
18
|
+
import httpx
|
|
19
|
+
|
|
20
|
+
if TYPE_CHECKING:
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass(frozen=True, slots=True)
|
|
25
|
+
class EnvironmentPreset:
|
|
26
|
+
"""A starter environment sourced from a public GitHub repo."""
|
|
27
|
+
|
|
28
|
+
id: str
|
|
29
|
+
name: str
|
|
30
|
+
description: str
|
|
31
|
+
owner: str
|
|
32
|
+
repo: str
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
ENVIRONMENT_PRESETS: tuple[EnvironmentPreset, ...] = (
|
|
36
|
+
EnvironmentPreset(
|
|
37
|
+
"blank",
|
|
38
|
+
"Blank",
|
|
39
|
+
"Minimal starting point for a custom environment.",
|
|
40
|
+
"hud-evals",
|
|
41
|
+
"hud-blank",
|
|
42
|
+
),
|
|
43
|
+
EnvironmentPreset(
|
|
44
|
+
"browser",
|
|
45
|
+
"Browser",
|
|
46
|
+
"Local browser automation environment.",
|
|
47
|
+
"hud-evals",
|
|
48
|
+
"hud-browser",
|
|
49
|
+
),
|
|
50
|
+
EnvironmentPreset(
|
|
51
|
+
"deepresearch",
|
|
52
|
+
"Deep Research",
|
|
53
|
+
"Deep research environment with Exa search integration.",
|
|
54
|
+
"hud-evals",
|
|
55
|
+
"hud-deepresearch",
|
|
56
|
+
),
|
|
57
|
+
EnvironmentPreset(
|
|
58
|
+
"cua",
|
|
59
|
+
"Computer Use",
|
|
60
|
+
"Computer-use agent (CUA) desktop environment.",
|
|
61
|
+
"hud-evals",
|
|
62
|
+
"cua-template",
|
|
63
|
+
),
|
|
64
|
+
EnvironmentPreset(
|
|
65
|
+
"autonomous-businesses",
|
|
66
|
+
"Autonomous Businesses",
|
|
67
|
+
"Autonomous business simulation environment.",
|
|
68
|
+
"hud-evals",
|
|
69
|
+
"autonomous-businesses-template",
|
|
70
|
+
),
|
|
71
|
+
EnvironmentPreset(
|
|
72
|
+
"verilog",
|
|
73
|
+
"Verilog",
|
|
74
|
+
"Verilog hardware-design environment.",
|
|
75
|
+
"hud-evals",
|
|
76
|
+
"verilog-template",
|
|
77
|
+
),
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
PRESETS_BY_ID: dict[str, EnvironmentPreset] = {p.id: p for p in ENVIRONMENT_PRESETS}
|
|
81
|
+
|
|
82
|
+
_TARBALL_TIMEOUT = 60.0
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _is_within(root: Path, path: Path) -> bool:
|
|
86
|
+
try:
|
|
87
|
+
path.relative_to(root)
|
|
88
|
+
return True
|
|
89
|
+
except ValueError:
|
|
90
|
+
return False
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _download_tarball(preset: EnvironmentPreset) -> bytes:
|
|
94
|
+
"""Fetch the repo's ``main`` archive from codeload (no API rate limit)."""
|
|
95
|
+
headers: dict[str, str] = {}
|
|
96
|
+
token = os.environ.get("GITHUB_TOKEN")
|
|
97
|
+
if token:
|
|
98
|
+
headers["Authorization"] = f"Bearer {token}"
|
|
99
|
+
|
|
100
|
+
url = f"https://codeload.github.com/{preset.owner}/{preset.repo}/tar.gz/refs/heads/main"
|
|
101
|
+
with httpx.Client(follow_redirects=True, timeout=_TARBALL_TIMEOUT) as client:
|
|
102
|
+
resp = client.get(url, headers=headers)
|
|
103
|
+
resp.raise_for_status()
|
|
104
|
+
return resp.content
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def materialize_preset(preset: EnvironmentPreset, target: Path) -> None:
|
|
108
|
+
"""Download ``preset``'s repo archive and extract it into ``target``.
|
|
109
|
+
|
|
110
|
+
Uses ``codeload.github.com`` (not the rate-limited API) for the repo's
|
|
111
|
+
``main`` branch — no ``git`` required. Strips the archive's top-level
|
|
112
|
+
``<repo>-main/`` component and refuses any entry that would escape ``target``
|
|
113
|
+
(path-traversal guard). Honors ``GITHUB_TOKEN`` if set.
|
|
114
|
+
"""
|
|
115
|
+
payload = _download_tarball(preset)
|
|
116
|
+
|
|
117
|
+
target.mkdir(parents=True, exist_ok=True)
|
|
118
|
+
target_root = target.resolve()
|
|
119
|
+
with tarfile.open(fileobj=io.BytesIO(payload), mode="r:gz") as tar:
|
|
120
|
+
for member in tar.getmembers():
|
|
121
|
+
# GitHub wraps everything in a "<repo>-<sha>/" top-level dir; drop it.
|
|
122
|
+
parts = member.name.split("/", 1)
|
|
123
|
+
if len(parts) < 2 or not parts[1]:
|
|
124
|
+
continue
|
|
125
|
+
dest = (target_root / parts[1]).resolve()
|
|
126
|
+
if not _is_within(target_root, dest):
|
|
127
|
+
raise ValueError(f"unsafe path in archive: {member.name!r}")
|
|
128
|
+
if member.isdir():
|
|
129
|
+
dest.mkdir(parents=True, exist_ok=True)
|
|
130
|
+
elif member.isfile():
|
|
131
|
+
dest.parent.mkdir(parents=True, exist_ok=True)
|
|
132
|
+
source = tar.extractfile(member)
|
|
133
|
+
if source is not None:
|
|
134
|
+
dest.write_bytes(source.read())
|
|
135
|
+
# Preserve the archive's executable bits so entrypoints and
|
|
136
|
+
# scripts stay runnable (no-op on Windows).
|
|
137
|
+
if member.mode & 0o111:
|
|
138
|
+
dest.chmod(dest.stat().st_mode | (member.mode & 0o111))
|
|
139
|
+
# Symlinks and other special members are intentionally skipped.
|
|
@@ -14,7 +14,7 @@ if TYPE_CHECKING:
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
def test_init_scaffolds_a_runnable_package(tmp_path: Path) -> None:
|
|
17
|
-
init_command(name="my-cool-env", directory=str(tmp_path), force=False)
|
|
17
|
+
init_command(name="my-cool-env", directory=str(tmp_path), force=False, preset=None)
|
|
18
18
|
|
|
19
19
|
target = tmp_path / "my-cool-env"
|
|
20
20
|
assert {p.name for p in target.iterdir()} == {
|
|
@@ -36,7 +36,7 @@ def test_init_refuses_to_clobber_nonempty_directory(tmp_path: Path) -> None:
|
|
|
36
36
|
(target / "precious.txt").write_text("data")
|
|
37
37
|
|
|
38
38
|
with pytest.raises(typer.Exit):
|
|
39
|
-
init_command(name="taken", directory=str(tmp_path), force=False)
|
|
39
|
+
init_command(name="taken", directory=str(tmp_path), force=False, preset=None)
|
|
40
40
|
|
|
41
41
|
assert (target / "precious.txt").read_text() == "data"
|
|
42
42
|
|
|
@@ -46,6 +46,6 @@ def test_init_force_overwrites_existing_files(tmp_path: Path) -> None:
|
|
|
46
46
|
target.mkdir()
|
|
47
47
|
(target / "env.py").write_text("old")
|
|
48
48
|
|
|
49
|
-
init_command(name="env", directory=str(tmp_path), force=True)
|
|
49
|
+
init_command(name="env", directory=str(tmp_path), force=True, preset=None)
|
|
50
50
|
|
|
51
51
|
assert "Environment" in (target / "env.py").read_text()
|
hud_python-0.6.0/hud/cli/init.py
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
"""``hud init``: scaffold a new HUD environment package.
|
|
2
|
-
|
|
3
|
-
Purely local — writes the v6 template files into a fresh directory. No
|
|
4
|
-
network, no API key, no prompts.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
from __future__ import annotations
|
|
8
|
-
|
|
9
|
-
from pathlib import Path
|
|
10
|
-
|
|
11
|
-
import typer
|
|
12
|
-
|
|
13
|
-
from hud.utils.hud_console import HUDConsole
|
|
14
|
-
|
|
15
|
-
from .templates import DOCKERFILE_HUD, ENV_PY, PYPROJECT_TOML, TASKS_PY
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def _python_name(name: str) -> str:
|
|
19
|
-
"""Normalize a package name into a Python-identifier-ish env name."""
|
|
20
|
-
name = name.replace("-", "_").replace(" ", "_")
|
|
21
|
-
return "".join(c if c.isalnum() or c == "_" else "_" for c in name)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def init_command(
|
|
25
|
-
name: str = typer.Argument(..., help="Environment name (directory to create)"),
|
|
26
|
-
directory: str = typer.Option(".", "--dir", "-d", help="Parent directory"),
|
|
27
|
-
force: bool = typer.Option(False, "--force", "-f", help="Overwrite existing files"),
|
|
28
|
-
) -> None:
|
|
29
|
-
"""🚀 Create a new HUD environment package.
|
|
30
|
-
|
|
31
|
-
[not dim]Writes env.py (tasks + capabilities), tasks.py, Dockerfile.hud, and
|
|
32
|
-
pyproject.toml into a new directory.
|
|
33
|
-
|
|
34
|
-
Examples:
|
|
35
|
-
hud init my-env # create ./my-env
|
|
36
|
-
hud init my-env --dir envs # create ./envs/my-env[/not dim]
|
|
37
|
-
"""
|
|
38
|
-
hud_console = HUDConsole()
|
|
39
|
-
|
|
40
|
-
target = Path(directory) / name
|
|
41
|
-
if target.exists() and any(target.iterdir()) and not force:
|
|
42
|
-
hud_console.error(f"{target} already exists and is not empty (use --force)")
|
|
43
|
-
raise typer.Exit(1)
|
|
44
|
-
|
|
45
|
-
env_name = _python_name(name)
|
|
46
|
-
files = {
|
|
47
|
-
"pyproject.toml": PYPROJECT_TOML.format(name=env_name.replace("_", "-")),
|
|
48
|
-
"env.py": ENV_PY.format(env_name=env_name),
|
|
49
|
-
"tasks.py": TASKS_PY.format(env_name=env_name),
|
|
50
|
-
"Dockerfile.hud": DOCKERFILE_HUD,
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
hud_console.header(f"HUD Init: {env_name}")
|
|
54
|
-
target.mkdir(parents=True, exist_ok=True)
|
|
55
|
-
for filename, content in files.items():
|
|
56
|
-
(target / filename).write_text(content)
|
|
57
|
-
hud_console.status_item(filename, "✓")
|
|
58
|
-
|
|
59
|
-
hud_console.section_title("Next Steps")
|
|
60
|
-
hud_console.info("")
|
|
61
|
-
hud_console.command_example(f"cd {target}", "1. Enter the package")
|
|
62
|
-
hud_console.info("")
|
|
63
|
-
hud_console.info("2. Define task definitions in env.py")
|
|
64
|
-
hud_console.info(" A @env.template is an async generator: it yields a prompt, then")
|
|
65
|
-
hud_console.info(" (after the agent answers) yields a reward.")
|
|
66
|
-
hud_console.info("")
|
|
67
|
-
hud_console.info("3. List the tasks to run in tasks.py")
|
|
68
|
-
hud_console.info(" Call a task with args to bind a runnable Task.")
|
|
69
|
-
hud_console.info("")
|
|
70
|
-
hud_console.command_example("hud eval tasks.py claude", "4. Run an agent over them")
|
|
71
|
-
hud_console.info("")
|
|
72
|
-
hud_console.info("5. Deploy for scale")
|
|
73
|
-
hud_console.info(" hud deploy, then run many evals in parallel.")
|
|
74
|
-
hud_console.info("")
|
|
75
|
-
hud_console.info("Tip: Install the HUD skill so your coding agent can help you build:")
|
|
76
|
-
hud_console.command_example("npx skills add docs.hud.ai", "Install HUD skill")
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|