openrunner-sdk 2.37.7__tar.gz → 2.37.9__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 (186) hide show
  1. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/PKG-INFO +1 -1
  2. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/__init__.py +1 -1
  3. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/api_client.py +108 -0
  4. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/cli.py +179 -0
  5. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/install_commands.py +82 -0
  6. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/pyproject.toml +1 -1
  7. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/.gitignore +0 -0
  8. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/=6.0 +0 -0
  9. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/=8.1 +0 -0
  10. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/README.md +0 -0
  11. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/CLAUDE.md +0 -0
  12. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/_safepath.py +0 -0
  13. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/_secret_rules.py +0 -0
  14. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/artifact.py +0 -0
  15. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/autoresearch.py +0 -0
  16. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/buffer.py +0 -0
  17. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/cache.py +0 -0
  18. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/config.py +0 -0
  19. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/cost.py +0 -0
  20. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/dataset.py +0 -0
  21. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/datasets.py +0 -0
  22. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/environment.py +0 -0
  23. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/evaluation.py +0 -0
  24. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/feedback.py +0 -0
  25. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/git_info.py +0 -0
  26. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/gpu/__init__.py +0 -0
  27. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/gpu/api_integration.py +0 -0
  28. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/gpu/cost_guard.py +0 -0
  29. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/gpu/gpu_types.py +0 -0
  30. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/gpu/price_compare.py +0 -0
  31. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/gpu/provider_base.py +0 -0
  32. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/gpu/providers/__init__.py +0 -0
  33. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/gpu/providers/lambda_cloud.py +0 -0
  34. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/gpu/providers/modal_provider.py +0 -0
  35. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/gpu/providers/ovhcloud.py +0 -0
  36. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/gpu/providers/runpod.py +0 -0
  37. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/gpu/providers/vastai.py +0 -0
  38. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/gpu/runner.py +0 -0
  39. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/gpu/workspace_sync.py +0 -0
  40. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/guardrails.py +0 -0
  41. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/handover.py +0 -0
  42. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/hooks/patent-lab-post-commit +0 -0
  43. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/__init__.py +0 -0
  44. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/accelerate.py +0 -0
  45. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/anthropic_tracer.py +0 -0
  46. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/catboost.py +0 -0
  47. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/diffusers.py +0 -0
  48. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/fastai.py +0 -0
  49. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/forced_alignment.py +0 -0
  50. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/gladia.py +0 -0
  51. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/gymnasium.py +0 -0
  52. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/huggingface.py +0 -0
  53. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/hydra.py +0 -0
  54. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/ignite.py +0 -0
  55. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/jax.py +0 -0
  56. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/keras.py +0 -0
  57. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/langchain.py +0 -0
  58. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/lightgbm.py +0 -0
  59. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/lightning.py +0 -0
  60. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/llamaindex.py +0 -0
  61. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/openai_finetune.py +0 -0
  62. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/openai_tracer.py +0 -0
  63. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/optuna.py +0 -0
  64. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/pytorch.py +0 -0
  65. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/sb3.py +0 -0
  66. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/sklearn.py +0 -0
  67. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/skypilot.py +0 -0
  68. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/tensorflow.py +0 -0
  69. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/trl.py +0 -0
  70. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/tts.py +0 -0
  71. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/ultralytics.py +0 -0
  72. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/voice_agent.py +0 -0
  73. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/whisper.py +0 -0
  74. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/integration/xgboost.py +0 -0
  75. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/launch.py +0 -0
  76. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/machine.py +0 -0
  77. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/mcp_server.py +0 -0
  78. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/media.py +0 -0
  79. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/migrate.py +0 -0
  80. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/model.py +0 -0
  81. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/model_card.py +0 -0
  82. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/offline.py +0 -0
  83. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/patent_scan.py +0 -0
  84. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/pii.py +0 -0
  85. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/plot.py +0 -0
  86. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/projects.py +0 -0
  87. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/prompt.py +0 -0
  88. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/query_api.py +0 -0
  89. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/redact.py +0 -0
  90. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/reload.py +0 -0
  91. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/research.py +0 -0
  92. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/research_policy.py +0 -0
  93. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/run.py +0 -0
  94. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/scorers.py +0 -0
  95. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/sender.py +0 -0
  96. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/session.py +0 -0
  97. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/settings.py +0 -0
  98. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/summary.py +0 -0
  99. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/sweep.py +0 -0
  100. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/sync.py +0 -0
  101. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/system_metrics.py +0 -0
  102. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/tensorboard.py +0 -0
  103. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/tools/__init__.py +0 -0
  104. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/tools/patent_report.py +0 -0
  105. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/trace.py +0 -0
  106. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/transcript_formatter.py +0 -0
  107. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/wal.py +0 -0
  108. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/wandb_compat/__init__.py +0 -0
  109. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/wandb_compat/_shim.py +0 -0
  110. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/openrunner/wer.py +0 -0
  111. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/scripts/gen_betterleaks_rules.py +0 -0
  112. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/__init__.py +0 -0
  113. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/conftest.py +0 -0
  114. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/fixtures/wandb-export-mini/run-aaa/config.json +0 -0
  115. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/fixtures/wandb-export-mini/run-aaa/metadata.json +0 -0
  116. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/fixtures/wandb-export-mini/run-aaa/metrics.jsonl +0 -0
  117. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/fixtures/wandb-export-mini/run-aaa/summary.json +0 -0
  118. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/fixtures/wandb-export-mini/run-bbb/artifacts/model-checkpoint/manifest.json +0 -0
  119. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/fixtures/wandb-export-mini/run-bbb/artifacts/model-checkpoint/weights.bin +0 -0
  120. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/fixtures/wandb-export-mini/run-bbb/artifacts/sample-image/manifest.json +0 -0
  121. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/fixtures/wandb-export-mini/run-bbb/artifacts/sample-image/preview.png +0 -0
  122. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/fixtures/wandb-export-mini/run-bbb/config.json +0 -0
  123. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/fixtures/wandb-export-mini/run-bbb/metadata.json +0 -0
  124. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/fixtures/wandb-export-mini/run-bbb/metrics.jsonl +0 -0
  125. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/fixtures/wandb-export-mini/run-bbb/summary.json +0 -0
  126. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/integration/__init__.py +0 -0
  127. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/integration/conftest.py +0 -0
  128. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/integration/test_artifact_round_trip.py +0 -0
  129. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_alert.py +0 -0
  130. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_aliases.py +0 -0
  131. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_api_client.py +0 -0
  132. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_artifact.py +0 -0
  133. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_buffer.py +0 -0
  134. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_cache.py +0 -0
  135. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_class_scorers.py +0 -0
  136. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_cli.py +0 -0
  137. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_config.py +0 -0
  138. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_evaluation.py +0 -0
  139. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_finish.py +0 -0
  140. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_git_info.py +0 -0
  141. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_gpu/__init__.py +0 -0
  142. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_gpu/conftest.py +0 -0
  143. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_gpu/test_cost_guard.py +0 -0
  144. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_gpu/test_gpu_types.py +0 -0
  145. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_gpu/test_lambda.py +0 -0
  146. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_gpu/test_modal.py +0 -0
  147. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_gpu/test_ovhcloud.py +0 -0
  148. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_gpu/test_price_compare.py +0 -0
  149. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_gpu/test_provider_base.py +0 -0
  150. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_gpu/test_runner.py +0 -0
  151. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_gpu/test_runpod.py +0 -0
  152. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_gpu/test_sdk_gpu_api.py +0 -0
  153. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_gpu/test_vastai.py +0 -0
  154. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_gpu/test_workspace_sync.py +0 -0
  155. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_init.py +0 -0
  156. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_install_commands.py +0 -0
  157. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_integration_fastai.py +0 -0
  158. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_integration_huggingface.py +0 -0
  159. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_integration_keras.py +0 -0
  160. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_integration_langchain.py +0 -0
  161. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_integration_lightning.py +0 -0
  162. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_integration_pytorch.py +0 -0
  163. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_integration_sklearn.py +0 -0
  164. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_integration_xgboost.py +0 -0
  165. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_launch.py +0 -0
  166. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_log.py +0 -0
  167. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_log_code.py +0 -0
  168. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_mcp_decisions.py +0 -0
  169. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_mcp_monitor.py +0 -0
  170. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_mcp_predictions.py +0 -0
  171. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_media.py +0 -0
  172. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_migrate.py +0 -0
  173. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_offline.py +0 -0
  174. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_offline_sync.py +0 -0
  175. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_pii.py +0 -0
  176. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_plot.py +0 -0
  177. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_query_api.py +0 -0
  178. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_resume.py +0 -0
  179. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_sdk_features.py +0 -0
  180. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_sender.py +0 -0
  181. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_session_sync.py +0 -0
  182. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_summary.py +0 -0
  183. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_sweep.py +0 -0
  184. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_system_metrics.py +0 -0
  185. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_trace.py +0 -0
  186. {openrunner_sdk-2.37.7 → openrunner_sdk-2.37.9}/tests/test_wandb_compat.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openrunner-sdk
3
- Version: 2.37.7
3
+ Version: 2.37.9
4
4
  Summary: OpenRunner SDK - W&B-compatible ML experiment tracking client
5
5
  Project-URL: Homepage, https://github.com/jqueguiner/openrunner
6
6
  Project-URL: Repository, https://github.com/jqueguiner/openrunner
@@ -181,7 +181,7 @@ launch.from_run = _launch_from_run # type: ignore[attr-defined]
181
181
  # openrunner.trace.patch_openai() syntax
182
182
  trace.patch_openai = _patch_openai # type: ignore[attr-defined]
183
183
 
184
- __version__ = "2.37.7"
184
+ __version__ = "2.37.9"
185
185
 
186
186
  logger = logging.getLogger("openrunner")
187
187
 
@@ -429,6 +429,114 @@ class APIClient:
429
429
  logger.warning("list_projects failed: %s", e)
430
430
  return []
431
431
 
432
+ # -- Deployments + project images ---------------------------------------
433
+
434
+ def list_project_images(self, project_id: str) -> list[dict[str, Any]]:
435
+ """GET /projects/{id}/images -- images linked to a project (deploy gate)."""
436
+ try:
437
+ r = self._request("get", f"/projects/{project_id}/images")
438
+ r.raise_for_status()
439
+ return r.json()
440
+ except Exception as e:
441
+ logger.warning("list_project_images failed: %s", e)
442
+ return []
443
+
444
+ def link_project_image(
445
+ self,
446
+ project_id: str,
447
+ image: str,
448
+ registry_id: str | None = None,
449
+ repository: str | None = None,
450
+ tag: str | None = None,
451
+ ) -> dict[str, Any] | None:
452
+ """POST /projects/{id}/images -- link a deployable image to a project."""
453
+ try:
454
+ body: dict[str, Any] = {"image": image}
455
+ if registry_id:
456
+ body["registry_id"] = registry_id
457
+ if repository:
458
+ body["repository"] = repository
459
+ if tag:
460
+ body["tag"] = tag
461
+ r = self._request("post", f"/projects/{project_id}/images", json=body)
462
+ r.raise_for_status()
463
+ return r.json()
464
+ except Exception as e:
465
+ logger.warning("link_project_image failed: %s", e)
466
+ return None
467
+
468
+ def list_deployments(self, project_id: str) -> list[dict[str, Any]]:
469
+ """GET /projects/{id}/deployments -- list a project's GPU deployments."""
470
+ try:
471
+ r = self._request("get", f"/projects/{project_id}/deployments")
472
+ r.raise_for_status()
473
+ return r.json()
474
+ except Exception as e:
475
+ logger.warning("list_deployments failed: %s", e)
476
+ return []
477
+
478
+ def create_deployment(
479
+ self, project_id: str, body: dict[str, Any]
480
+ ) -> dict[str, Any] | None:
481
+ """POST /projects/{id}/deployments -- create a serverless GPU deployment.
482
+
483
+ ``body`` keys: name, image, provider, gpu_type, gpu_count, min_nodes,
484
+ max_nodes, scale_metric?, scale_target?, container_port. The image must
485
+ already be linked to the project.
486
+ """
487
+ try:
488
+ r = self._request("post", f"/projects/{project_id}/deployments", json=body)
489
+ r.raise_for_status()
490
+ return r.json()
491
+ except Exception as e:
492
+ logger.warning("create_deployment failed: %s", e)
493
+ return None
494
+
495
+ def scale_deployment(
496
+ self, project_id: str, deployment_id: str, desired_nodes: int
497
+ ) -> dict[str, Any] | None:
498
+ """POST /projects/{id}/deployments/{dep}/scale -- set desired replicas."""
499
+ try:
500
+ r = self._request(
501
+ "post",
502
+ f"/projects/{project_id}/deployments/{deployment_id}/scale",
503
+ json={"desired_nodes": desired_nodes},
504
+ )
505
+ r.raise_for_status()
506
+ return r.json()
507
+ except Exception as e:
508
+ logger.warning("scale_deployment failed: %s", e)
509
+ return None
510
+
511
+ def delete_deployment(
512
+ self, project_id: str, deployment_id: str
513
+ ) -> dict[str, Any] | None:
514
+ """DELETE /projects/{id}/deployments/{dep} -- tear down a deployment."""
515
+ try:
516
+ r = self._request(
517
+ "delete", f"/projects/{project_id}/deployments/{deployment_id}"
518
+ )
519
+ r.raise_for_status()
520
+ return r.json()
521
+ except Exception as e:
522
+ logger.warning("delete_deployment failed: %s", e)
523
+ return None
524
+
525
+ def deployment_replicas(
526
+ self, project_id: str, deployment_id: str
527
+ ) -> list[dict[str, Any]]:
528
+ """GET /projects/{id}/deployments/{dep}/replicas -- a deployment's pods."""
529
+ try:
530
+ r = self._request(
531
+ "get",
532
+ f"/projects/{project_id}/deployments/{deployment_id}/replicas",
533
+ )
534
+ r.raise_for_status()
535
+ return r.json()
536
+ except Exception as e:
537
+ logger.warning("deployment_replicas failed: %s", e)
538
+ return []
539
+
432
540
  def list_runs(self, project_id: str) -> list[dict[str, Any]]:
433
541
  """GET /projects/{project_id}/runs -- list runs in a project.
434
542
 
@@ -4450,5 +4450,184 @@ def drift_ask_cmd(question, project) -> None:
4450
4450
  click.echo("No answer (LLM provider may be unconfigured).")
4451
4451
  return
4452
4452
  click.echo(f"[{r.get('action')}] {r.get('interpretation')}")
4453
+
4454
+
4455
+ # ---------------------------------------------------------------------------
4456
+ # deploy group — vendor-agnostic serverless GPU deployments
4457
+ # ---------------------------------------------------------------------------
4458
+
4459
+
4460
+ def _project_org(client, pid: str) -> str | None:
4461
+ """Best-effort resolve a project's org id (for the GPU price lookup)."""
4462
+ try:
4463
+ r = client._request("get", f"/projects/{pid}")
4464
+ r.raise_for_status()
4465
+ return r.json().get("org_id")
4466
+ except Exception:
4467
+ return None
4468
+
4469
+
4470
+ @main.group("deploy")
4471
+ def deploy_group() -> None:
4472
+ """Serverless GPU deployments (link image, pick GPU, deploy, scale)."""
4473
+ pass
4474
+
4475
+
4476
+ @deploy_group.command("images")
4477
+ @click.option("--project", "-p", default=None, help="Project org/name or UUID")
4478
+ def deploy_images(project) -> None:
4479
+ """List images linked to a project (the deploy gate)."""
4480
+ client, pid = _drift_client_project(project)
4481
+ imgs = client.list_project_images(pid)
4482
+ client.close()
4483
+ if not imgs:
4484
+ click.echo("No linked images. Link one: openrunner deploy link IMAGE -p ORG/NAME")
4485
+ return
4486
+ for i in imgs:
4487
+ click.echo(f"- {i['image']} (tag={i.get('tag') or 'latest'}, digest={(i.get('digest') or '-')[:19]})")
4488
+
4489
+
4490
+ @deploy_group.command("link")
4491
+ @click.argument("image")
4492
+ @click.option("--project", "-p", default=None, help="Project org/name or UUID")
4493
+ @click.option("--registry-id", default=None, help="Connected registry UUID (private pull)")
4494
+ def deploy_link(image, project, registry_id) -> None:
4495
+ """Link a deployable image to a project."""
4496
+ client, pid = _drift_client_project(project)
4497
+ rec = client.link_project_image(pid, image, registry_id=registry_id)
4498
+ client.close()
4499
+ if not rec:
4500
+ click.echo("Error: failed to link image.", err=True)
4501
+ raise SystemExit(1)
4502
+ click.echo(f"Linked {rec['image']} — Deploy is now active for this project.")
4503
+
4504
+
4505
+ @deploy_group.command("gpus")
4506
+ @click.option("--project", "-p", default=None, help="Project org/name or UUID")
4507
+ @click.option("--provider", default="runpod", help="Filter by provider (default: runpod)")
4508
+ def deploy_gpus(project, provider) -> None:
4509
+ """List deployable GPU offers (provider · GPU · VRAM · price) for recommendations."""
4510
+ client, pid = _drift_client_project(project)
4511
+ org = _project_org(client, pid)
4512
+ if not org:
4513
+ client.close()
4514
+ click.echo("Error: could not resolve org for prices.", err=True)
4515
+ raise SystemExit(1)
4516
+ try:
4517
+ r = client._request("get", "/gpu/prices", params={"org_id": org})
4518
+ r.raise_for_status()
4519
+ offers = r.json()
4520
+ except Exception as e:
4521
+ client.close()
4522
+ click.echo(f"Error fetching prices: {e}", err=True)
4523
+ raise SystemExit(1)
4524
+ client.close()
4525
+ seen = set()
4526
+ for o in offers:
4527
+ if provider and o.get("provider") != provider:
4528
+ continue
4529
+ key = (o.get("provider"), o.get("gpu_type_normalized"))
4530
+ if key in seen:
4531
+ continue
4532
+ seen.add(key)
4533
+ click.echo(
4534
+ f"- {o.get('provider')} · {o.get('gpu_type_normalized')} · "
4535
+ f"{o.get('gpu_memory_gb')}GB · ${o.get('price_per_hour')}/hr"
4536
+ )
4537
+
4538
+
4539
+ @deploy_group.command("create")
4540
+ @click.option("--project", "-p", default=None, help="Project org/name or UUID")
4541
+ @click.option("--name", "-n", required=True, help="Deployment name")
4542
+ @click.option("--image", required=True, help="Image (must be linked to the project)")
4543
+ @click.option("--provider", default="runpod", help="Provider (RunPod supported today)")
4544
+ @click.option("--gpu", required=True, help="GPU type, e.g. A100_80GB")
4545
+ @click.option("--gpu-count", default=1, type=int, help="GPUs per replica")
4546
+ @click.option("--min", "min_nodes", default=1, type=int, help="Min replicas")
4547
+ @click.option("--max", "max_nodes", default=1, type=int, help="Max replicas")
4548
+ @click.option("--metric", default=None, type=click.Choice(["gpu_util", "request_rate", "inflight"]), help="Autoscale metric")
4549
+ @click.option("--target", default=None, type=float, help="Autoscale target for --metric")
4550
+ @click.option("--port", default=8000, type=int, help="Container port")
4551
+ def deploy_create(project, name, image, provider, gpu, gpu_count, min_nodes, max_nodes, metric, target, port) -> None:
4552
+ """Create a serverless GPU deployment for a linked image."""
4553
+ client, pid = _drift_client_project(project)
4554
+ body = {
4555
+ "name": name, "image": image, "provider": provider, "gpu_type": gpu,
4556
+ "gpu_count": gpu_count, "min_nodes": min_nodes, "max_nodes": max_nodes,
4557
+ "container_port": port,
4558
+ }
4559
+ if metric:
4560
+ body["scale_metric"] = metric
4561
+ if target is not None:
4562
+ body["scale_target"] = target
4563
+ dep = client.create_deployment(pid, body)
4564
+ client.close()
4565
+ if not dep:
4566
+ click.echo("Error: failed to create deployment (is the image linked? provider supported?).", err=True)
4567
+ raise SystemExit(1)
4568
+ click.echo(f"Created deployment {dep['name']} [{dep['id']}] status={dep['status']} "
4569
+ f"desired={dep['desired_nodes']} (min {dep['min_nodes']} / max {dep['max_nodes']}).")
4570
+
4571
+
4572
+ @deploy_group.command("ls")
4573
+ @click.option("--project", "-p", default=None, help="Project org/name or UUID")
4574
+ def deploy_ls(project) -> None:
4575
+ """List a project's deployments."""
4576
+ client, pid = _drift_client_project(project)
4577
+ deps = client.list_deployments(pid)
4578
+ client.close()
4579
+ if not deps:
4580
+ click.echo("No deployments.")
4581
+ return
4582
+ for d in deps:
4583
+ click.echo(
4584
+ f"- {d['name']} [{d['id']}] {d['status']} · {d['provider']}/{d['gpu_type']}×{d['gpu_count']} "
4585
+ f"· {d['desired_nodes']}/{d['max_nodes']} desired · {d['image']}"
4586
+ )
4587
+
4588
+
4589
+ @deploy_group.command("scale")
4590
+ @click.argument("deployment_id")
4591
+ @click.option("--project", "-p", default=None, help="Project org/name or UUID")
4592
+ @click.option("--to", "desired", required=True, type=int, help="Desired replica count")
4593
+ def deploy_scale(deployment_id, project, desired) -> None:
4594
+ """Set a deployment's desired replica count (clamped to [min,max])."""
4595
+ client, pid = _drift_client_project(project)
4596
+ d = client.scale_deployment(pid, deployment_id, desired)
4597
+ client.close()
4598
+ if not d:
4599
+ click.echo("Error: scale failed.", err=True)
4600
+ raise SystemExit(1)
4601
+ click.echo(f"{d['name']} → desired={d['desired_nodes']} status={d['status']}")
4602
+
4603
+
4604
+ @deploy_group.command("replicas")
4605
+ @click.argument("deployment_id")
4606
+ @click.option("--project", "-p", default=None, help="Project org/name or UUID")
4607
+ def deploy_replicas(deployment_id, project) -> None:
4608
+ """List a deployment's replica pods."""
4609
+ client, pid = _drift_client_project(project)
4610
+ reps = client.deployment_replicas(pid, deployment_id)
4611
+ client.close()
4612
+ if not reps:
4613
+ click.echo("No replicas.")
4614
+ return
4615
+ for r in reps:
4616
+ host = f"{r.get('ssh_host')}:{r.get('ssh_port')}" if r.get("ssh_host") else "-"
4617
+ click.echo(f"- #{r.get('replica_index')} {r['status']} {host}")
4618
+
4619
+
4620
+ @deploy_group.command("rm")
4621
+ @click.argument("deployment_id")
4622
+ @click.option("--project", "-p", default=None, help="Project org/name or UUID")
4623
+ def deploy_rm(deployment_id, project) -> None:
4624
+ """Tear down a deployment (terminates all replicas)."""
4625
+ client, pid = _drift_client_project(project)
4626
+ d = client.delete_deployment(pid, deployment_id)
4627
+ client.close()
4628
+ if not d:
4629
+ click.echo("Error: delete failed.", err=True)
4630
+ raise SystemExit(1)
4631
+ click.echo(f"Deployment {d['name']} deleted (replicas terminating).")
4453
4632
  import json as _json
4454
4633
  click.echo(_json.dumps(r.get("data", {}), indent=2)[:2000])
@@ -2746,6 +2746,15 @@ the reference). Do each step; ask only when genuinely ambiguous.
2746
2746
  ## Step 2 -- resolve project + mint a DRIFT-ONLY key for the container
2747
2747
  - `openrunner login` if needed. Resolve the project id (from the `org/name` arg,
2748
2748
  else `APIClient.list_projects()`; ask if ambiguous).
2749
+ - **Auto-create the drift project if missing.** If the target has no drift project
2750
+ yet, but a project of the **same name already exists with runs** (a training
2751
+ project, found via `list_projects()`), create a dedicated drift project with that
2752
+ same name in the same org
2753
+ (`create_project_api(org_id, {{"name": <name>, "description": "Inference drift
2754
+ for <source project> (<id>)"}})`) and use its id for drift + the scoped key.
2755
+ **Link them** so lineage is explicit: record the source project's id in the new
2756
+ project's description and reuse the name as the drift `monitor`. Only auto-create
2757
+ when a same-name run project exists -- never silently create on a typo.
2749
2758
  - **Mint a scoped key for this container** -- do NOT reuse the user's full key.
2750
2759
  Run `openrunner drift key --project ORG/NAME --name drift-<service>` (add
2751
2760
  `--json` to capture it). It returns a key carrying ONLY `drift:read` +
@@ -2790,6 +2799,77 @@ AFTER the response is produced, insert a wrapped `record_inference(...)`:
2790
2799
  """
2791
2800
 
2792
2801
 
2802
+ DEPLOY_CMD = """---
2803
+ name: {prefix}deploy
2804
+ description: Interactively deploy a project's model image on serverless GPUs -- reads the model card's measured results to RECOMMEND a GPU (VRAM headroom) + platform (price/availability), asks you to confirm platform + GPU, sets replica bounds/autoscale, creates the deployment and watches it roll out
2805
+ argument-hint: "[project org/name] [--image REF] [--name NAME]"
2806
+ allowed-tools:
2807
+ - Bash
2808
+ - Read
2809
+ - Grep
2810
+ - Glob
2811
+ - AskUserQuestion
2812
+ ---
2813
+
2814
+ Deploy a model image on governed, autoscaled GPUs -- with a GPU/platform
2815
+ **recommendation grounded in the model card's measured results**, then an
2816
+ interactive confirm. Never guess sizing; read real numbers.
2817
+
2818
+ ## Step 1 -- project + a deployable image
2819
+ - Resolve the project (arg `org/name`, else `openrunner` config / ask).
2820
+ - `openrunner deploy images -p ORG/NAME`. If none linked: take `--image REF`
2821
+ (or ask), then `openrunner deploy link REF -p ORG/NAME` (add `--registry-id`
2822
+ for a private image). A project needs >=1 linked image before it can deploy.
2823
+
2824
+ ## Step 2 -- read the model card's MEASURED results (drives the recommendation)
2825
+ Pull the model card + run summary and extract, with numbers only:
2826
+ - parameter count / model size on disk, and serving **precision** (fp16/bf16/int8/
2827
+ fp8) -- from the card or the run `config`/`summary`.
2828
+ - measured **peak VRAM** at inference, **throughput** (req/s or tok/s), **latency**
2829
+ (p50/p95), and the **batch size** they were measured at.
2830
+ - Use MCP when available (`mcp__openrunner__openrunner_search_papers` /
2831
+ model-card tools / `openrunner_get_run_metrics`); else read the card markdown /
2832
+ repo reports. If a figure is missing, say so -- do NOT invent it; estimate VRAM
2833
+ as `params x bytes/param x ~1.2 overhead` and LABEL it an estimate.
2834
+
2835
+ ## Step 3 -- recommend a GPU + platform
2836
+ - `openrunner deploy gpus -p ORG/NAME` lists offers (provider · GPU · VRAM · $/hr).
2837
+ - Recommend the **cheapest GPU whose VRAM comfortably fits** measured/estimated
2838
+ peak VRAM with headroom (>=20-30%% for activations/batch growth); prefer the
2839
+ provider with the best price and availability. Note when a bigger GPU is needed
2840
+ for the target batch/throughput, or when int8/fp8 lets a smaller GPU fit.
2841
+ - Summarise the reasoning in 2-3 lines (VRAM need vs GPU VRAM, $/hr, why).
2842
+
2843
+ ## Step 4 -- confirm platform + GPU (interactive)
2844
+ Use AskUserQuestion with the recommendation FIRST and marked "(Recommended)":
2845
+ - **Platform**: the supported providers (RunPod today; others are pricing-only).
2846
+ - **GPU**: 3-4 offers spanning the recommendation +/- one size, each labelled with
2847
+ VRAM + $/hr so the trade-off is visible.
2848
+ Then ask replica bounds + autoscale:
2849
+ - **min / max replicas** (min 0 = scale-to-zero: cheap + spiky, but cold start ~
2850
+ minutes; min 1 = always warm).
2851
+ - **autoscale**: manual, or a metric (`gpu_util` / `request_rate` / `inflight`)
2852
+ with a target.
2853
+
2854
+ ## Step 5 -- create + watch
2855
+ - `openrunner deploy create -p ORG/NAME --name NAME --image REF --provider P
2856
+ --gpu GPU [--gpu-count N] --min MIN --max MAX [--metric M --target T]`.
2857
+ - Poll `openrunner deploy ls -p ORG/NAME` + `openrunner deploy replicas <id>
2858
+ -p ORG/NAME` until replicas are running; report status + the endpoint URL when
2859
+ the router assigns one. Scale later with `openrunner deploy scale <id> --to N`.
2860
+
2861
+ ## Guardrails
2862
+ - Ground every sizing number in the card/run; label anything estimated. Never
2863
+ fabricate VRAM/throughput.
2864
+ - Deploying spends real money at the provider -- show the picked GPU + $/hr and
2865
+ CONFIRM before `create`. Mention scale-to-zero to cap idle cost.
2866
+ - Fit VRAM with headroom; warn if the recommendation is tight for the target
2867
+ batch.
2868
+ - RunPod is the only real provisioning adapter today; other providers are
2869
+ pricing-only -- say so if picked.
2870
+ """
2871
+
2872
+
2793
2873
  BUILD_API_CMD = """---
2794
2874
  name: {prefix}build-api
2795
2875
  description: Scaffold a production inference API for a model in THIS repo -- FastAPI /predict + /health, typed request/response, Dockerfile (pushable via the OpenRunner registry), env config, and optional baked-in drift monitoring; ready to deploy on governed GPUs
@@ -2890,6 +2970,7 @@ def install_claude_code() -> list[str]:
2890
2970
  "drift.md": DRIFT_CMD,
2891
2971
  "drift-install.md": DRIFT_INSTALL_CMD,
2892
2972
  "build-api.md": BUILD_API_CMD,
2973
+ "deploy.md": DEPLOY_CMD,
2893
2974
  }
2894
2975
 
2895
2976
  files = []
@@ -3095,6 +3176,7 @@ def _install_all_commands_to_dir(cmd_dir: Path, prefix: str = "openrunner:") ->
3095
3176
  "drift.md": DRIFT_CMD,
3096
3177
  "drift-install.md": DRIFT_INSTALL_CMD,
3097
3178
  "build-api.md": BUILD_API_CMD,
3179
+ "deploy.md": DEPLOY_CMD,
3098
3180
  }
3099
3181
 
3100
3182
  files = []
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "openrunner-sdk"
3
- version = "2.37.7"
3
+ version = "2.37.9"
4
4
  description = "OpenRunner SDK - W&B-compatible ML experiment tracking client"
5
5
  readme = "README.md"
6
6
  license = {text = "MIT"}
File without changes
File without changes