freesolo-flash-dev 1.2.28__tar.gz → 1.2.33__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 (540) hide show
  1. freesolo_flash_dev-1.2.33/CHANGELOG.md +113 -0
  2. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/PKG-INFO +1 -1
  3. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/deploy.py +214 -1
  4. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/scaffold/TRAINING.md +2 -2
  5. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/ui/tables.py +3 -1
  6. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/client/http.py +62 -18
  7. freesolo_flash_dev-1.2.33/flash/client/streaming.py +145 -0
  8. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/core/spec.py +106 -11
  9. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/allocator.py +92 -58
  10. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/runpod/__init__.py +16 -1
  11. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/preparation.py +11 -0
  12. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/status.py +14 -2
  13. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/submit.py +9 -4
  14. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/supervise/attach.py +2 -5
  15. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/supervise/lifecycle.py +8 -6
  16. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/supervise/seed_submission.py +6 -0
  17. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/schema/__init__.py +63 -55
  18. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/app.py +3 -2
  19. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/billing/charges.py +4 -3
  20. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/domain/run_registry.py +2 -3
  21. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/platform/runtime.py +2 -5
  22. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/pyproject.toml +2 -2
  23. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_allocator.py +83 -0
  24. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cancel_remote.py +53 -0
  25. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cli_commands.py +14 -1
  26. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cli_render_coverage.py +30 -0
  27. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_client.py +267 -6
  28. freesolo_flash_dev-1.2.33/tests/test_deploy_alias_move_warning.py +554 -0
  29. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_publish.py +56 -0
  30. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_idle_endpoint_reaper.py +40 -0
  31. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_provider_routing.py +125 -31
  32. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_spec_and_validation.py +205 -1
  33. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/uv.lock +1 -1
  34. freesolo_flash_dev-1.2.28/CHANGELOG.md +0 -200
  35. freesolo_flash_dev-1.2.28/flash/client/streaming.py +0 -94
  36. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.dockerignore +0 -0
  37. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.env.example +0 -0
  38. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/CODEOWNERS +0 -0
  39. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  40. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  41. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  42. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  43. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/dependabot.yml +0 -0
  44. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/workflows/auto-rebake.yml +0 -0
  45. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/workflows/bake-kernel-cache.yml +0 -0
  46. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/workflows/ci.yml +0 -0
  47. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/workflows/main-source-guard.yml +0 -0
  48. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/workflows/notify-tests-repo.yml +0 -0
  49. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/workflows/publish-dev.yml +0 -0
  50. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/workflows/publish-image.yml +0 -0
  51. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/workflows/publish.yml +0 -0
  52. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/workflows/version-parity.yml +0 -0
  53. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/workflows/worker-image.yml +0 -0
  54. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.gitignore +0 -0
  55. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/CODE_OF_CONDUCT.md +0 -0
  56. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/CONTRIBUTING.md +0 -0
  57. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/Dockerfile +0 -0
  58. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/Dockerfile.worker +0 -0
  59. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/LICENSE +0 -0
  60. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/NOTICE +0 -0
  61. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/README.md +0 -0
  62. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/SECURITY.md +0 -0
  63. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/SELF_HOSTING.md +0 -0
  64. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/build/kernel_cache/.gitignore +0 -0
  65. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/build/kernel_cache/.keep +0 -0
  66. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/deploy/infisical/README.md +0 -0
  67. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/deploy/infisical/entrypoint.sh +0 -0
  68. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/docker/Dockerfile.kernelcache +0 -0
  69. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/docker/Dockerfile.kernelcache.relayer +0 -0
  70. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/docker/bake_kernel_cache.py +0 -0
  71. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/docker/bake_pod_entry.py +0 -0
  72. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/docker/extract_cudart_fix.py +0 -0
  73. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/docker/kernel_fingerprint.py +0 -0
  74. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/docker/make_rp_handler.py +0 -0
  75. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/__init__.py +0 -0
  76. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/_internal/__init__.py +0 -0
  77. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/_internal/channel.py +0 -0
  78. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/_internal/diagnostics.py +0 -0
  79. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/_internal/fileio.py +0 -0
  80. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/_internal/logging.py +0 -0
  81. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/_internal/paths.py +0 -0
  82. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/adapters/__init__.py +0 -0
  83. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/adapters/artifacts.py +0 -0
  84. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/adapters/lora_rank.py +0 -0
  85. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/__init__.py +0 -0
  86. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/__main__.py +0 -0
  87. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/__init__.py +0 -0
  88. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/env/__init__.py +0 -0
  89. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/env/episode.py +0 -0
  90. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/env/eval.py +0 -0
  91. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/env/eval_args.py +0 -0
  92. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/env/imports.py +0 -0
  93. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/env/list.py +0 -0
  94. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/env/push.py +0 -0
  95. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/env/retained.py +0 -0
  96. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/env/setup.py +0 -0
  97. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/env/test.py +0 -0
  98. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/env/test_evaluations.py +0 -0
  99. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/env/test_params.py +0 -0
  100. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/env/test_warnings.py +0 -0
  101. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/traces.py +0 -0
  102. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/train_cost.py +0 -0
  103. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/scaffold/__init__.py +0 -0
  104. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/ui/__init__.py +0 -0
  105. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/ui/cost.py +0 -0
  106. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/ui/env_panels.py +0 -0
  107. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/ui/heartbeat.py +0 -0
  108. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/ui/render.py +0 -0
  109. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/ui/tty.py +0 -0
  110. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/client/__init__.py +0 -0
  111. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/client/config.py +0 -0
  112. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/client/freesolo_api.py +0 -0
  113. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/client/runtime_secrets.py +0 -0
  114. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/client/shapes.py +0 -0
  115. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/client/specs.py +0 -0
  116. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/content/__init__.py +0 -0
  117. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/content/multimodal.py +0 -0
  118. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/content/structured_outputs.py +0 -0
  119. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/content/thinking.py +0 -0
  120. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/core/__init__.py +0 -0
  121. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/core/catalog.py +0 -0
  122. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cost/__init__.py +0 -0
  123. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cost/analytical.py +0 -0
  124. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cost/facts.py +0 -0
  125. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cost/spec.py +0 -0
  126. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cost/types.py +0 -0
  127. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/__init__.py +0 -0
  128. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/plan/__init__.py +0 -0
  129. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/plan/kv_sizing.py +0 -0
  130. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/plan/model_config_probe.py +0 -0
  131. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/plan/recipe.py +0 -0
  132. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/plan/steps.py +0 -0
  133. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/plan/vram.py +0 -0
  134. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/profiling/__init__.py +0 -0
  135. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/profiling/dataset_profile.py +0 -0
  136. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/profiling/reasoning_render.py +0 -0
  137. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/profiling/sft_workload.py +0 -0
  138. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/profiling/tokenizer.py +0 -0
  139. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/profiling/workload_profile.py +0 -0
  140. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/result/__init__.py +0 -0
  141. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/result/accounting.py +0 -0
  142. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/result/rollout_samples.py +0 -0
  143. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/__init__.py +0 -0
  144. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/__main__.py +0 -0
  145. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/backend_common.py +0 -0
  146. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/entry/__init__.py +0 -0
  147. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/entry/opd.py +0 -0
  148. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/entry/rl.py +0 -0
  149. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/entry/sft.py +0 -0
  150. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/io/__init__.py +0 -0
  151. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/io/heartbeat.py +0 -0
  152. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/io/hf.py +0 -0
  153. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/io/prefetch.py +0 -0
  154. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/io/wandb_log.py +0 -0
  155. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/model/__init__.py +0 -0
  156. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/model/adapter.py +0 -0
  157. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/model/decoding.py +0 -0
  158. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/model/lora.py +0 -0
  159. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/model/packing.py +0 -0
  160. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/opd_train.py +0 -0
  161. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/opd_train_runner.py +0 -0
  162. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/perf/__init__.py +0 -0
  163. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/perf/diagnostics.py +0 -0
  164. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/perf/lifecycle.py +0 -0
  165. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/perf/liger.py +0 -0
  166. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/perf/memory.py +0 -0
  167. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/rl_train.py +0 -0
  168. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/rl_train_runner.py +0 -0
  169. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/runtime/__init__.py +0 -0
  170. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/runtime/kernel_warmup.py +0 -0
  171. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/runtime/pkg_proxy.py +0 -0
  172. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/runtime/rng.py +0 -0
  173. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/score_batcher.py +0 -0
  174. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/sft_train.py +0 -0
  175. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/sft_train_runner.py +0 -0
  176. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/teacher/__init__.py +0 -0
  177. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/teacher/client.py +0 -0
  178. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/teacher/encoding.py +0 -0
  179. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/teacher/tokenizer_align.py +0 -0
  180. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/__init__.py +0 -0
  181. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/core/__init__.py +0 -0
  182. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/core/child/__init__.py +0 -0
  183. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/core/child/glue.py +0 -0
  184. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/core/step_timing.py +0 -0
  185. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/finalize.py +0 -0
  186. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/__init__.py +0 -0
  187. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/batching.py +0 -0
  188. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/bridge.py +0 -0
  189. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/child/__init__.py +0 -0
  190. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/child/bridge.py +0 -0
  191. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/child/multiturn.py +0 -0
  192. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/child/plugin.py +0 -0
  193. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/child/structured.py +0 -0
  194. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/failures.py +0 -0
  195. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/gkd.py +0 -0
  196. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/multiturn_validation.py +0 -0
  197. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/overrides.py +0 -0
  198. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/prompts.py +0 -0
  199. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/reporting.py +0 -0
  200. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/scoring.py +0 -0
  201. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/state.py +0 -0
  202. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/validation.py +0 -0
  203. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/rl/__init__.py +0 -0
  204. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/rl/checkpoints.py +0 -0
  205. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/rl/child/__init__.py +0 -0
  206. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/rl/child/multiturn.py +0 -0
  207. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/rl/child/plugin.py +0 -0
  208. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/rl/config.py +0 -0
  209. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/rl/inputs.py +0 -0
  210. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/rl/multi_turn.py +0 -0
  211. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/rl/scoring.py +0 -0
  212. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/rl/shims.py +0 -0
  213. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/rl/single_turn.py +0 -0
  214. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/rl/verl_config.py +0 -0
  215. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/sft/__init__.py +0 -0
  216. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/sft/checkpoints.py +0 -0
  217. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/sft/config.py +0 -0
  218. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/verl/__init__.py +0 -0
  219. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/verl/capabilities.py +0 -0
  220. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/verl/checkpoints.py +0 -0
  221. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/verl/child_io.py +0 -0
  222. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/verl/diagnostics.py +0 -0
  223. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/verl/parallelism.py +0 -0
  224. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker_entrypoint.py +0 -0
  225. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/envs/__init__.py +0 -0
  226. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/envs/adapter.py +0 -0
  227. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/envs/base.py +0 -0
  228. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/envs/cache_security.py +0 -0
  229. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/envs/dataset_selection.py +0 -0
  230. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/envs/evaluations.py +0 -0
  231. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/envs/identity.py +0 -0
  232. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/envs/loader.py +0 -0
  233. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/envs/namespace_listing.py +0 -0
  234. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/envs/package/__init__.py +0 -0
  235. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/envs/package/limits.py +0 -0
  236. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/envs/package/unpack.py +0 -0
  237. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/envs/pull.py +0 -0
  238. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/__init__.py +0 -0
  239. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/_lifecycle/__init__.py +0 -0
  240. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/_lifecycle/auth.py +0 -0
  241. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/_lifecycle/bootstrap.py +0 -0
  242. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/_lifecycle/bootstrap_pip.py +0 -0
  243. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/_lifecycle/bootstrap_secrets.py +0 -0
  244. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/_lifecycle/deadline.py +0 -0
  245. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/_lifecycle/http.py +0 -0
  246. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/_lifecycle/instance.py +0 -0
  247. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/_lifecycle/poll.py +0 -0
  248. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/_lifecycle/poll_instance.py +0 -0
  249. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/_lifecycle/provider.py +0 -0
  250. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/_lifecycle/worker.py +0 -0
  251. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/artifacts/__init__.py +0 -0
  252. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/artifacts/hf.py +0 -0
  253. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/artifacts/preload_runpod.py +0 -0
  254. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/artifacts/weight_cache.py +0 -0
  255. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/base.py +0 -0
  256. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/fit_errors.py +0 -0
  257. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/lambda_/__init__.py +0 -0
  258. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/lambda_/api.py +0 -0
  259. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/lambda_/auth.py +0 -0
  260. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/lambda_/gpus.py +0 -0
  261. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/lambda_/jobs/__init__.py +0 -0
  262. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/lambda_/jobs/builders.py +0 -0
  263. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/lambda_/jobs/reap.py +0 -0
  264. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/lambda_/preflight.py +0 -0
  265. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/lambda_/pricing.py +0 -0
  266. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/preflight.py +0 -0
  267. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/realized.py +0 -0
  268. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/runpod/api.py +0 -0
  269. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/runpod/auth.py +0 -0
  270. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/runpod/cost.py +0 -0
  271. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/runpod/gpus.py +0 -0
  272. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/runpod/job_execution.py +0 -0
  273. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/runpod/jobs.py +0 -0
  274. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/runpod/preflight.py +0 -0
  275. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/runpod/pricing.py +0 -0
  276. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/runpod/resources.py +0 -0
  277. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/runpod/serverless/__init__.py +0 -0
  278. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/runpod/serverless/endpoints.py +0 -0
  279. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/sharding.py +0 -0
  280. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/vast/__init__.py +0 -0
  281. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/vast/api.py +0 -0
  282. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/vast/auth.py +0 -0
  283. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/vast/jobs/__init__.py +0 -0
  284. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/vast/jobs/builders.py +0 -0
  285. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/vast/preflight.py +0 -0
  286. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/vast/pricing.py +0 -0
  287. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/py.typed +0 -0
  288. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/__init__.py +0 -0
  289. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/artifacts.py +0 -0
  290. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/attempts.py +0 -0
  291. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/costs.py +0 -0
  292. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/deadlines.py +0 -0
  293. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/reconciliation.py +0 -0
  294. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/results/__init__.py +0 -0
  295. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/results/checkpoints.py +0 -0
  296. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/results/verified_revisions.py +0 -0
  297. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/supervise/__init__.py +0 -0
  298. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/supervise/deploy.py +0 -0
  299. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/supervise/recovery.py +0 -0
  300. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/supervise/retry_decision.py +0 -0
  301. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/supervise/transitions.py +0 -0
  302. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/weight_cache.py +0 -0
  303. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/schema/fields.py +0 -0
  304. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/serve/__init__.py +0 -0
  305. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/serve/adapter_check.py +0 -0
  306. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/serve/deploy.py +0 -0
  307. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/serve/errors.py +0 -0
  308. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/serve/export.py +0 -0
  309. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/serve/preflight.py +0 -0
  310. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/serve/responses.py +0 -0
  311. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/serve/streaming.py +0 -0
  312. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/serve/thinking.py +0 -0
  313. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/serve/urls.py +0 -0
  314. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/__init__.py +0 -0
  315. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/__main__.py +0 -0
  316. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/billing/__init__.py +0 -0
  317. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/billing/retry.py +0 -0
  318. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/domain/__init__.py +0 -0
  319. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/domain/checkpoints.py +0 -0
  320. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/domain/environment_registry.py +0 -0
  321. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/domain/envs.py +0 -0
  322. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/domain/projects.py +0 -0
  323. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/domain/reconcile.py +0 -0
  324. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/domain/repo_cleanup.py +0 -0
  325. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/domain/teacher_broker.py +0 -0
  326. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/domain/teacher_errors.py +0 -0
  327. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/domain/teacher_requests.py +0 -0
  328. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/platform/__init__.py +0 -0
  329. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/platform/auth.py +0 -0
  330. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/platform/db.py +0 -0
  331. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/platform/deps.py +0 -0
  332. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/platform/internal_client.py +0 -0
  333. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/platform/locks.py +0 -0
  334. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/routes/__init__.py +0 -0
  335. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/routes/envs.py +0 -0
  336. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/routes/meta.py +0 -0
  337. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/routes/runs.py +0 -0
  338. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/routes/serving.py +0 -0
  339. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/routes/serving_completion.py +0 -0
  340. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/routes/serving_revisions.py +0 -0
  341. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/routes/serving_smoke.py +0 -0
  342. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/routes/teacher.py +0 -0
  343. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/teacher/__init__.py +0 -0
  344. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/teacher/limits.py +0 -0
  345. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/teacher/retry_contract.py +0 -0
  346. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/scripts/build_dev_dist.py +0 -0
  347. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/scripts/check_file_size.py +0 -0
  348. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/scripts/check_function_size.py +0 -0
  349. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/scripts/check_verl_pin_exists.py +0 -0
  350. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/scripts/scrub_history.sh +0 -0
  351. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/__init__.py +0 -0
  352. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/_helpers/__init__.py +0 -0
  353. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/_helpers/profile.py +0 -0
  354. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/_helpers/runner.py +0 -0
  355. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/_helpers/specs.py +0 -0
  356. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/_helpers/teacher.py +0 -0
  357. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/_helpers/vast.py +0 -0
  358. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/conftest.py +0 -0
  359. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/fixtures/math_eval.jsonl +0 -0
  360. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/fixtures/math_train.jsonl +0 -0
  361. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/live/__init__.py +0 -0
  362. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/live/conftest.py +0 -0
  363. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/live/test_lambda_live.py +0 -0
  364. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/live/test_runpod_live.py +0 -0
  365. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/live/test_sft_thinking_render_live.py +0 -0
  366. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/live/test_vast_live.py +0 -0
  367. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_accounting_coverage.py +0 -0
  368. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_adapter_shard_completeness.py +0 -0
  369. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_agent_flash_cli_contract.py +0 -0
  370. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_algorithms.py +0 -0
  371. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_backend_common.py +0 -0
  372. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_backend_jobspec_contract.py +0 -0
  373. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_bake_kernel_cache.py +0 -0
  374. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_base_model_provenance.py +0 -0
  375. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_billing_retry.py +0 -0
  376. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_build_context_contract.py +0 -0
  377. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_catalog_consistency.py +0 -0
  378. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_catalog_only_models.py +0 -0
  379. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_charge_pricing.py +0 -0
  380. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_checkpoints.py +0 -0
  381. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cli_commands_coverage.py +0 -0
  382. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cli_credential_shadowing.py +0 -0
  383. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cli_errors.py +0 -0
  384. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cli_estimate.py +0 -0
  385. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cli_gpus_flag.py +0 -0
  386. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cli_help.py +0 -0
  387. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cli_main_coverage.py +0 -0
  388. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cli_managed.py +0 -0
  389. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cli_render_theme.py +0 -0
  390. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cli_traces.py +0 -0
  391. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cli_wandb_warning.py +0 -0
  392. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_client_import_purity.py +0 -0
  393. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_client_server_integration.py +0 -0
  394. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_client_stream_reads.py +0 -0
  395. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_config_env_vars.py +0 -0
  396. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_config_overrides.py +0 -0
  397. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_controlled_experiment_repairs.py +0 -0
  398. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cost_analytical.py +0 -0
  399. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cost_equation.py +0 -0
  400. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cost_estimate.py +0 -0
  401. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cost_hardware.py +0 -0
  402. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cost_models.py +0 -0
  403. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_dataset_profile.py +0 -0
  404. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_deploy_latency.py +0 -0
  405. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_dev_channel.py +0 -0
  406. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_disk_gb.py +0 -0
  407. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_endpoint_name.py +0 -0
  408. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_cache_evict.py +0 -0
  409. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_delete.py +0 -0
  410. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_download.py +0 -0
  411. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_download_api.py +0 -0
  412. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_evaluations.py +0 -0
  413. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_list_api.py +0 -0
  414. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_list_cli.py +0 -0
  415. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_list_hub.py +0 -0
  416. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_no_install.py +0 -0
  417. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_pull.py +0 -0
  418. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_pull_coverage.py +0 -0
  419. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_pull_loader_coverage.py +0 -0
  420. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_pull_managed_control_plane.py +0 -0
  421. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_push.py +0 -0
  422. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_rate_limit_resolve.py +0 -0
  423. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_ref_pinning.py +0 -0
  424. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_test.py +0 -0
  425. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_envs_coverage.py +0 -0
  426. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_export.py +0 -0
  427. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_flash_mvp.py +0 -0
  428. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_flash_worker.py +0 -0
  429. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_flashinfer_cache_dirs.py +0 -0
  430. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_freesolo_api_transport.py +0 -0
  431. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_github_urlopen_retry.py +0 -0
  432. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_gpu_type_single_field.py +0 -0
  433. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_gpus.py +0 -0
  434. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_grpo_params.py +0 -0
  435. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_grpo_resident_sizing.py +0 -0
  436. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_grpo_reward_batching.py +0 -0
  437. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_health_liveness.py +0 -0
  438. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_hf_retry.py +0 -0
  439. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_infisical_secrets.py +0 -0
  440. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_instance_bootstrap_coverage.py +0 -0
  441. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_internal_client.py +0 -0
  442. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_jobs.py +0 -0
  443. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_kernel_cache.py +0 -0
  444. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_kernel_fingerprint.py +0 -0
  445. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_kv_util.py +0 -0
  446. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_lambda_api_coverage.py +0 -0
  447. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_lambda_runner.py +0 -0
  448. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_logging.py +0 -0
  449. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_login_perms.py +0 -0
  450. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_lora_rank_coverage.py +0 -0
  451. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_lora_rank_preflight.py +0 -0
  452. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_managed_config_fields.py +0 -0
  453. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_managed_hf_repo.py +0 -0
  454. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_metrics_schema_agent_contract.py +0 -0
  455. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_mig_guard.py +0 -0
  456. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_multi_gpu_gate.py +0 -0
  457. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_multimodal_training.py +0 -0
  458. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_named_reward_metrics.py +0 -0
  459. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_oom_escalate_gpu.py +0 -0
  460. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_opd.py +0 -0
  461. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_opd_limits.py +0 -0
  462. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_opd_multiturn_eos_boundary.py +0 -0
  463. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_opd_resume_safety.py +0 -0
  464. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_opd_train.py +0 -0
  465. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_orchestrator_flash.py +0 -0
  466. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_packing.py +0 -0
  467. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_packing_coverage.py +0 -0
  468. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_parasail_teacher.py +0 -0
  469. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_poll_helpers.py +0 -0
  470. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_preflight.py +0 -0
  471. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_projects.py +0 -0
  472. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_provider_preflight_coverage.py +0 -0
  473. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_provider_teardown_robustness.py +0 -0
  474. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_providers_symmetry.py +0 -0
  475. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_realized_cost.py +0 -0
  476. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_repo_cleanup.py +0 -0
  477. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_resolve_params_b.py +0 -0
  478. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_resume_on_retry.py +0 -0
  479. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_rl_train.py +0 -0
  480. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_rollout_samples.py +0 -0
  481. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_runmgmt.py +0 -0
  482. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_runpod_api_delete.py +0 -0
  483. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_runpod_key_fingerprint.py +0 -0
  484. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_runpod_key_waterfall.py +0 -0
  485. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_serve.py +0 -0
  486. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_serve_reasoning_content.py +0 -0
  487. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_server_api.py +0 -0
  488. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_server_app_coverage.py +0 -0
  489. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_server_auth_singleflight.py +0 -0
  490. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_server_billing.py +0 -0
  491. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_server_checkpoints_coverage.py +0 -0
  492. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_server_db.py +0 -0
  493. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_server_envs_coverage.py +0 -0
  494. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_server_locks_coverage.py +0 -0
  495. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_server_standalone.py +0 -0
  496. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_serving_context_preflight.py +0 -0
  497. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_serving_contract.py +0 -0
  498. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_serving_schema_coverage.py +0 -0
  499. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_sft_chunked_nll.py +0 -0
  500. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_sft_example_selection.py +0 -0
  501. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_sft_gc_off.py +0 -0
  502. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_sft_max_context.py +0 -0
  503. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_sft_startup_block.py +0 -0
  504. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_sft_train.py +0 -0
  505. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_sft_workload.py +0 -0
  506. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_step_floor.py +0 -0
  507. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_step_metrics.py +0 -0
  508. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_step_timing.py +0 -0
  509. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_structured_outputs.py +0 -0
  510. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_teacher_broker.py +0 -0
  511. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_teacher_encoding_contract.py +0 -0
  512. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_thinking_config.py +0 -0
  513. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_train_context_preflight.py +0 -0
  514. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_training_controls.py +0 -0
  515. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_type_comment_prose.py +0 -0
  516. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_vast_api.py +0 -0
  517. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_vast_api_coverage.py +0 -0
  518. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_vast_offers.py +0 -0
  519. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_vast_provider_coverage.py +0 -0
  520. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_vast_runner.py +0 -0
  521. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_verified_revisions.py +0 -0
  522. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_verifiers.py +0 -0
  523. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_version.py +0 -0
  524. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_vl_warmstart_adapter_keys.py +0 -0
  525. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_vram_architecture.py +0 -0
  526. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_wandb_link.py +0 -0
  527. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_wandb_naming.py +0 -0
  528. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_warmstart_adapter_download.py +0 -0
  529. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_warmstart_cross_repo.py +0 -0
  530. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_warmstart_error_attribution.py +0 -0
  531. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_weight_cache.py +0 -0
  532. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_worker_dryrun.py +0 -0
  533. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_worker_hardexit.py +0 -0
  534. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_worker_image.py +0 -0
  535. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_worker_init_heartbeat.py +0 -0
  536. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_worker_stack.py +0 -0
  537. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_worker_thinking.py +0 -0
  538. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_workflow_contracts.py +0 -0
  539. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_workload_profile.py +0 -0
  540. {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_zero2_sharding_gate.py +0 -0
@@ -0,0 +1,113 @@
1
+ # Changelog
2
+
3
+ Notable changes to `freesolo-flash`. The dev-channel package `freesolo-flash-dev` ships in
4
+ lockstep at the same version.
5
+
6
+ Releases happen by merging a version bump from `dev` into `main`, which publishes to PyPI
7
+ (`.github/workflows/publish.yml`). Versions are `MAJOR.MINOR.PATCH`.
8
+
9
+ This file starts at 1.1.35. Earlier releases are not reconstructed here; use
10
+ `git log` for anything before that.
11
+
12
+ ## Unreleased
13
+
14
+ ### Added
15
+
16
+ - A `flash-cli` console script, the same entry point as `flash` under a name nothing else
17
+ claims. The `server` and `dev` extras install `runpod-flash`, which declares its own `flash`
18
+ script; whichever distribution is installed last wins, so on a control-plane host
19
+ `pip install 'freesolo-flash[server]'` could leave `flash` running RunPod's CLI, which exits 0
20
+ and does nothing. `flash` is unchanged and remains correct on a base (client-only) install.
21
+
22
+ ### Changed
23
+
24
+ - CI runs the offline test suite on both supported interpreters (3.11 and 3.12) rather than
25
+ 3.11 alone, and sets `HF_HUB_OFFLINE` / `TRANSFORMERS_OFFLINE` so a test that reaches the
26
+ network fails deterministically instead of depending on runner connectivity.
27
+ - Every GitHub Action is pinned to a commit SHA rather than a mutable tag.
28
+ - `mypy` runs in CI as an advisory (non-blocking) job.
29
+
30
+ ### Fixed
31
+
32
+ - `flash models deploy` now warns before it moves the shared `<run-id>` model id onto a
33
+ different checkpoint. Every checkpoint of a run is served under that one id, so deploying
34
+ `<run-id>/step-50` while `step-100` was live silently changed what `<run-id>` served for
35
+ everyone using it — which made "deploy a second checkpoint to compare" a destructive
36
+ operation on the first, and read as a serving regression rather than the deploy that caused
37
+ it. The warning names both checkpoints and points at `flash models chat <run-id>/step-N`,
38
+ which addresses a checkpoint directly and does not depend on where the id points. It is
39
+ advisory: the deploy still proceeds, the pre-deploy read is abandoned outright once it exceeds
40
+ a few seconds so no shape of slow plane can hold a deploy behind it, and a control plane that
41
+ cannot answer (or answers with a checkpoint step this client cannot read) does not fail the
42
+ command. A deployment whose activation outcome was never settled still warns, but without
43
+ naming a checkpoint: that record's step describes the incoming attempt rather than what the id
44
+ currently serves, and the authoritative target is server-side only, so the warning says the
45
+ live checkpoint cannot be determined and points at `flash models deployments`.
46
+
47
+ - A response deadline did not actually bound a response that arrived slowly. The deadline is
48
+ checked between reads, but each read asked for a fixed number of bytes and blocked until all of
49
+ them arrived, so a peer trickling a short body kept one read inside the socket timeout
50
+ indefinitely and the check never ran: a 2s deadline took 12s on a 42-byte body, and 61s when
51
+ the socket timeout was the client default. Reading whatever has already arrived lets the check
52
+ run, which bounds every stall shape. This affected `flash env list`, whose deadline exists to
53
+ stop a slow environment hub hanging the command, as well as the new pre-deploy read.
54
+
55
+ - A response deadline could still be overrun by a read that began near its end. The socket timeout
56
+ is installed once, when the request opens, and time spent connecting and waiting for headers is
57
+ charged to the deadline but not to that timeout, so a peer that delayed its headers and then
58
+ stalled mid-body held the call open past the deadline: 3.5s against a 2s budget. Each read now
59
+ re-caps the socket to the remaining budget, so the two bounds agree instead of stacking. On a
60
+ body still arriving this surfaces as a timeout rather than the "stalled" message; both bound the
61
+ call, and which one wins is a race not worth depending on.
62
+
63
+ - Commands printed for the operator to run (the resume/cancel hand-off after `flash train`,
64
+ usage strings, `next:` hints) now name the executable actually invoked rather than always
65
+ `flash`. On a host where `runpod-flash` owns the `flash` script, the printed
66
+ `flash runs cancel <run-id>` exited 0 without cancelling, leaving a run billing while the
67
+ operator believed they had stopped it. Reached through the `python -m flash.cli` escape hatch,
68
+ the printed command now names the interpreter that is actually running, rather than a bare
69
+ `python` that is absent on a python3-only host and may resolve to a different environment
70
+ inside a virtualenv.
71
+
72
+ - `flash env setup` scaffolded hosted-only environment instructions on every plane. A
73
+ self-hosted plane cannot publish to Freesolo's managed environment hub, so the generated
74
+ configs left `[environment] id` empty (which fails validation) beside a `flash env push`
75
+ command that could not work. Against a self-hosted plane the scaffold now emits the
76
+ `github:owner/repo@ref:path` id form, which such a plane resolves directly. Output against
77
+ the managed plane is unchanged.
78
+
79
+ - `flash-server` reported missing operator configuration as an unhandled ASGI startup
80
+ exception, so the actionable message arrived under ~20 frames of starlette/contextlib. The
81
+ refusing half of the preflight now runs before uvicorn starts, and `flash-server` prints
82
+ `error: ...` and exits 3 (uvicorn's `STARTUP_FAILURE`, which this path already used, so
83
+ supervision keying on it is unaffected). The advisory warnings still come from the lifespan
84
+ alone, so a booted plane logs them once.
85
+ - `flash env test` blamed the reward function for a gold answer that scored zero, when the
86
+ gold completion is equally likely to be at fault: with no `sft_completion` hook the replayed
87
+ answer is the dataset row's raw `output`, so a dataset whose `output` is a bare value fails a
88
+ grader that (correctly) requires a wrapper. The warning now names both candidates and prints
89
+ the exact text it scored, verbatim rather than through the whitespace-collapsing, 200-character
90
+ preview that hid the formatting faults it exists to reveal. The scaffolded `environment.py`
91
+ documents that `output` is also the gold assistant turn SFT trains on, and that per-row scorer
92
+ state belongs in `metadata`.
93
+ - `flash env test` labelled the replayed dataset turns as the text that scored zero, but a
94
+ multi-turn environment whose `step_episode` returns a `final_response_text` has that override
95
+ replace the episode's response before scoring, so the diagnostic named text the grader never
96
+ saw. It now reports what the scorer actually received, captured at the scoring call.
97
+ - An environment that overrode its answer to the empty string had `flash env test` report the
98
+ replayed turns instead: the captured text was tested for truth, so a graded `""` was
99
+ indistinguishable from an episode that never reached the scorer. The override propagates on
100
+ `is not None`, so `""` really is what the grader saw -- and an empty answer explains a zero
101
+ reward on its own, making it the reading a reader most needs named rather than hidden.
102
+ - A crashed scorer went unreported on an `echo` episode -- a row with no gold answer to replay,
103
+ which is also the case that leaves the GRPO gate with nothing to count. `flash env test` could
104
+ exit `overall: PASS` with every reward coming from a scorer that never ran. The scorer's error is
105
+ now surfaced for any policy.
106
+ - A scorer that crashed behind the SDK's guard reached `flash env test` as a bare `0.000000`,
107
+ indistinguishable from a judged-wrong answer, because the adapter kept only
108
+ `RewardResult.score`. The new `FreesoloEnvironment.reward_with_error` returns the reward and the
109
+ discarded error from a single scoring call, so a missing runtime dependency names itself without
110
+ re-scoring the episode -- which would bill a paid judge twice and, for a non-deterministic
111
+ scorer, could report an error that did not produce the printed reward.
112
+ - Two tests resolved Hugging Face model metadata over the network and passed only on a
113
+ connected runner. They now stub the resolver like their siblings already did.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: freesolo-flash-dev
3
- Version: 1.2.28
3
+ Version: 1.2.33
4
4
  Summary: Flash — managed LoRA post-training (SFT/GRPO/OPD) for Freesolo environments, driven by the `flash` CLI
5
5
  Project-URL: Homepage, https://github.com/freesolo-co/flash
6
6
  Project-URL: Repository, https://github.com/freesolo-co/flash
@@ -11,6 +11,7 @@ from __future__ import annotations
11
11
 
12
12
  import json
13
13
  import sys
14
+ import threading
14
15
  import time
15
16
 
16
17
  from flash.cli.ui import render
@@ -41,6 +42,10 @@ _DEPLOYMENT_BUSY_STATES = frozenset({"queued", "smoke_testing", "reconciling"})
41
42
  # plane introduces are both non-busy and non-servable, so `--wait` must fail closed on them
42
43
  # rather than let `deploy --wait && evaluate` proceed against nothing.
43
44
  _DEPLOYMENT_READY_STATES = frozenset({"ready", "deployed"})
45
+ # an undeploy whose backend cleanup failed (flash/runner/supervise/transitions.py). local serving
46
+ # authority is revoked, but the alias may still resolve to the old target -- neither servable nor
47
+ # safely assumed idle.
48
+ _REVOCATION_FAILED_STATE = "revocation_failed"
44
49
  _DEPLOY_POLL_SECONDS = 5.0
45
50
  # `--wait 0` still owes the caller its one read, and a read needs a positive timeout. keep that
46
51
  # bound short enough that "check once, do not block" stays true against a stalled plane: a longer
@@ -57,6 +62,14 @@ _DEPLOY_FINAL_READ_FRACTION = 0.9
57
62
  # an auth or authorization rejection answers the same way every time; polling through it just
58
63
  # spends the whole timeout to arrive at the identical error.
59
64
  _PERMANENT_POLL_STATUSES = frozenset({401, 403})
65
+ # the pre-deploy alias read is advisory, so it must not spend the client's default 60s budget
66
+ # deciding whether to print a warning: a stalled read would delay every real deploy behind a
67
+ # line nobody asked for. short enough to stay unnoticed, long enough for a healthy plane.
68
+ # it is spent three ways, because the client's own bounds are per-phase: as a socket timeout it
69
+ # bounds one socket operation, and as a body deadline it bounds the body but is only consulted
70
+ # once headers are parsed. a peer trickling headers just inside the socket timeout escapes both.
71
+ # `_read_within` bounds the total in wall-clock time, which is the one that actually holds.
72
+ _ALIAS_WARNING_READ_SECONDS = 5.0
60
73
 
61
74
 
62
75
  def _await_deployment(client, run_id: str, deployment: dict, timeout: float) -> dict:
@@ -189,6 +202,196 @@ def _rollback_record(client, run_id: str, timeout: float) -> dict | None:
189
202
  return None
190
203
 
191
204
 
205
+ def _served_step_label(step: int | None) -> str:
206
+ """Name a deployment's checkpoint the way the user addressed it: `step-N`, or `final`."""
207
+ return "final" if step is None else f"step-{step}"
208
+
209
+
210
+ def _read_within(budget: float, read):
211
+ """Run an advisory read, giving up on it entirely once ``budget`` seconds have passed.
212
+
213
+ The client's two bounds are both per-phase, not total: `timeout` restarts on every socket
214
+ operation and the body deadline is only checked once `urlopen` has finished parsing headers.
215
+ A peer that trickles the status line or headers just inside the socket timeout therefore
216
+ stalls for timeout x however many pauses it takes -- 12s against a 2s budget, measured -- and
217
+ the whole point of the bound is that the deploy the user actually asked for is waiting behind
218
+ it. Only wall-clock time outside the call bounds every phase at once.
219
+
220
+ A daemon thread rather than a cancellation: a blocked socket read cannot be interrupted from
221
+ outside, so the read is abandoned rather than stopped. That is sound only because this result
222
+ is discardable -- no warning is the documented outcome for a plane that cannot answer, so an
223
+ overrunning read degrades to silence. Daemon, so a stuck thread cannot keep the interpreter
224
+ alive after the deploy finishes.
225
+ """
226
+ result: list = []
227
+ worker = threading.Thread(
228
+ target=lambda: result.append(_read_or_none(read)),
229
+ daemon=True,
230
+ )
231
+ worker.start()
232
+ worker.join(budget)
233
+ return result[0] if result else None
234
+
235
+
236
+ def _read_or_none(read):
237
+ """The advisory read's failure contract: a plane that cannot answer produces no warning.
238
+
239
+ Deliberately broader than `ApiError`/`ClientError`. The client translates urllib's HTTPError
240
+ and URLError, and documents that anything else propagates -- so a connection reset or a
241
+ truncated body mid-read surfaces as the bare `ConnectionResetError` / `IncompleteRead` that
242
+ urllib raised. Those are exactly the "plane cannot answer" case this exists to absorb, and on
243
+ the worker thread an escaping one reaches the thread hook and prints a traceback across a
244
+ deploy that is otherwise proceeding normally: a warning nobody asked for turning into noise
245
+ on a command that worked.
246
+ """
247
+ try:
248
+ return read()
249
+ except Exception:
250
+ # the deploy itself is the authority on whether it can proceed. failing it here -- or
251
+ # printing a traceback beside it -- would turn a warning nobody asked for into a fault in
252
+ # the command it decorates. BaseException still propagates, so KeyboardInterrupt is
253
+ # unaffected.
254
+ return None
255
+
256
+
257
+ def _alias_move_warning(client, base_run_id: str, requested_step: int | None) -> str | None:
258
+ """Warn when deploying moves the shared `<run_id>` alias off a different checkpoint.
259
+
260
+ `deploy` registers under the bare run id whatever step it is given, so deploying a second
261
+ checkpoint of the same run does not stand up a second endpoint -- it repoints the one alias,
262
+ and everyone chatting bare `<run_id>` silently changes model. That makes "deploy another
263
+ checkpoint to compare" a destructive operation on the first, which reads as a serving fault
264
+ rather than the deploy that caused it.
265
+
266
+ Best-effort by construction: the read is advisory, so a plane that cannot answer must not
267
+ stop the deploy. Returns None when nothing is being displaced -- no deployment, the same
268
+ checkpoint again, or an unreadable current record.
269
+ """
270
+ current = _read_within(
271
+ _ALIAS_WARNING_READ_SECONDS,
272
+ # not `deployment_for`: its step filter hides exactly the record this asks about, a
273
+ # DIFFERENT checkpoint holding the alias.
274
+ lambda: client.deployed_checkpoint(
275
+ base_run_id,
276
+ timeout=_ALIAS_WARNING_READ_SECONDS,
277
+ body_deadline=_ALIAS_WARNING_READ_SECONDS,
278
+ ),
279
+ )
280
+ if current is None:
281
+ return None
282
+ # a `reconciling` record whose activation outcome was never recorded may ALREADY hold the
283
+ # alias. the plane permits replacing exactly that record rather than rejecting it as busy,
284
+ # and resolves the authoritative target through `_activation_predecessor` when it does
285
+ # (flash/server/routes/serving.py). reading it as "not serving" suppressed the warning in
286
+ # the very case the alias is most likely to move out from under someone.
287
+ unknown_activation = current.get("activation_outcome_unknown") is True
288
+ # `revocation_failed` is an undeploy whose BACKEND cleanup failed: local authority is revoked
289
+ # but the alias may still resolve to the old target, and `_validate_deploy_request` rejects
290
+ # only the busy set, so a deploy proceeds from here. reading it as "not serving" suppressed
291
+ # the warning in the case where cleanup already left the alias ambiguous.
292
+ revocation_failed = str(current.get("state") or "") == _REVOCATION_FAILED_STATE
293
+ ambiguous = unknown_activation or revocation_failed
294
+ if str(current.get("state") or "") not in _DEPLOYMENT_READY_STATES and not ambiguous:
295
+ # nothing is being served off the alias yet, so nothing is lost by moving it.
296
+ return None
297
+ cli = _commands().CLI_NAME
298
+ # `step-N` is not universally available: `ApiClient.chat` gates a step target behind
299
+ # `_require_chat_step_selector`, which refuses outright on a plane that does not advertise
300
+ # `chat_step_selector_v1`. the capability cannot be read here without spending a /v1/health on
301
+ # an advisory warning, and `_chat_step_selector_available` starts False, so a negative reading
302
+ # cannot tell "unsupported" from "not checked yet". state the condition instead of asserting
303
+ # the command works, and name the selector that works on every plane.
304
+ tail = (
305
+ f"so every client using bare `{base_run_id}` changes model. address a specific "
306
+ f"checkpoint with `{cli} models chat {base_run_id}/step-N` to compare them, or by "
307
+ "immutable adapter revision if this control plane does not support step selectors."
308
+ )
309
+ if revocation_failed:
310
+ # same reason as the unknown-activation arm: this record's `checkpoint_step` describes the
311
+ # deployment whose revocation failed, and whether the backend still answers on the alias
312
+ # is exactly what could not be determined. hedge rather than name a checkpoint.
313
+ return (
314
+ f"{base_run_id} has a deployment whose revocation did not complete, so whether it "
315
+ f"still serves off that shared model id cannot be determined from here; deploying "
316
+ f"{_served_step_label(requested_step)} may move it, "
317
+ f"{tail} run `{cli} models deployments` to see the current state first."
318
+ )
319
+ if unknown_activation:
320
+ # this record's `checkpoint_step` names the INCOMING attempt, not what the alias holds:
321
+ # the plane resolves the live target from `adapter_alias_target` / `previous_deployment`,
322
+ # and both are server-side (`public_deployment` strips the predecessor). naming a
323
+ # checkpoint here would report the wrong one -- worse than naming none -- so say only what
324
+ # this side can actually stand behind.
325
+ return (
326
+ f"{base_run_id} has a deployment whose activation never settled, so the checkpoint "
327
+ f"it currently serves cannot be determined from here; deploying "
328
+ f"{_served_step_label(requested_step)} may move that shared model id, "
329
+ f"{tail} run `{cli} models deployments` to see the current state first."
330
+ )
331
+ raw_step = current.get("checkpoint_step")
332
+ # `int()` does not just reject what it cannot read -- it silently COERCES. `true` becomes 1,
333
+ # `false` becomes 0, and `1.5` truncates to 1, none of them raising. a step this client cannot
334
+ # read as an exact whole number is an unreadable record, not checkpoint 1: reading it as a
335
+ # number either suppresses the warning (deploying step-1 against a `true`) or names a
336
+ # checkpoint that was never live. bool is checked first because it is a subclass of int.
337
+ if isinstance(raw_step, bool):
338
+ return None
339
+ if isinstance(raw_step, float) and not raw_step.is_integer():
340
+ return None
341
+ try:
342
+ served_step = None if raw_step is None else int(raw_step)
343
+ except (TypeError, ValueError, OverflowError):
344
+ # a proxy or older plane can answer 2xx with a step this client cannot read. that is an
345
+ # unreadable current record like any other, NOT a reason to fail the deploy: leaving the
346
+ # conversion unguarded let an advisory read traceback out of the command it decorates.
347
+ # all three arms are reachable from one JSON body: `json.loads` accepts the non-standard
348
+ # `Infinity`/`NaN` literals, and int() answers those with OverflowError and ValueError
349
+ # respectively -- so catching only the obvious two still crashed the deploy.
350
+ return None
351
+ if served_step == requested_step:
352
+ return None
353
+ reach_displaced = ""
354
+ # the record being displaced carries the one identifier that survives the alias move, so name
355
+ # it whenever it is there. `step-N` is not a substitute: it is rejected outright on a plane
356
+ # without `chat_step_selector_v1`, and after this deploy the listing shows only the NEW record
357
+ # -- `public_deployment` strips `previous_deployment` (flash/serve/urls.py) -- so a revision
358
+ # not printed here is not recoverable from anywhere afterwards.
359
+ revision = str(current.get("adapter_revision") or "").strip()
360
+ if served_step is None:
361
+ # the displaced checkpoint is the FINAL adapter, and `_parse_chat_target` accepts only a
362
+ # bare run id, `RUN/step-N`, or a full immutable revision -- there is no `/final`
363
+ # selector. once the alias moves, `step-N` addresses the incoming checkpoint and the bare
364
+ # id is the thing that just changed, so the generic advice cannot reach the final adapter
365
+ # at all. its immutable revision can, and the record being displaced carries one.
366
+ reach_displaced = (
367
+ f" the displaced final adapter has no `/final` selector; reach it by its immutable "
368
+ f"revision `{revision}`."
369
+ if revision
370
+ # without a revision on the record there is nothing to hand the user, and deferring
371
+ # them to a later command would be worse than saying so: `client.deploy` fires as soon
372
+ # as this prints, and the deployments listing then shows only the NEW record --
373
+ # `public_deployment` strips `previous_deployment` (flash/serve/urls.py), so the
374
+ # displaced revision is not in it. promising a selector that the next command cannot
375
+ # produce is the one outcome worse than admitting there is none.
376
+ else (
377
+ " the displaced final adapter has no `/final` selector and this plane did not "
378
+ "report its immutable revision, so it will not be addressable after this deploy; "
379
+ "undeploy and redeploy it to serve it again."
380
+ )
381
+ )
382
+ elif revision:
383
+ # a numbered checkpoint keeps its `step-N` selector, but only on a plane that advertises
384
+ # `chat_step_selector_v1`; where it does not, the qualified advice above leaves the user
385
+ # holding no identifier at all. this is that identifier, and this is the last moment it
386
+ # can be printed.
387
+ reach_displaced = f" the displaced checkpoint's immutable revision is `{revision}`."
388
+ return (
389
+ f"{base_run_id} currently serves {_served_step_label(served_step)}; deploying "
390
+ f"{_served_step_label(requested_step)} moves that shared model id onto the new "
391
+ f"checkpoint, {tail}{reach_displaced}"
392
+ )
393
+
394
+
192
395
  def _deployment_attempt_failed(requested: dict, final: dict) -> bool:
193
396
  """True when the requested revision is not the one now served.
194
397
 
@@ -229,8 +432,18 @@ def cmd_deploy(args) -> int:
229
432
  file=sys.stderr,
230
433
  )
231
434
  return 1
232
- base_run_id, _step = parsed
435
+ base_run_id, step = parsed
233
436
  client = _commands().client_from_config()
437
+ # before the POST: after it the alias has already moved, and a warning about a checkpoint that
438
+ # is no longer served reads as history rather than a decision the reader still has. a dry run
439
+ # registers nothing, so it displaces nothing and gets no warning.
440
+ if not args.dry_run:
441
+ alias_warning = _alias_move_warning(client, base_run_id, step)
442
+ if alias_warning:
443
+ print(
444
+ render.warn(alias_warning) if render.styled() else f"warning: {alias_warning}",
445
+ file=sys.stderr,
446
+ )
234
447
  dep = client.deploy(args.run_id, dry_run=args.dry_run)
235
448
  wait_seconds = getattr(args, "wait", None)
236
449
  # a dry run creates no deployment to poll for, so --wait has nothing to observe. test against
@@ -668,8 +668,8 @@ spending another GPU run:
668
668
  | Environment id is blank or stale | A blank id fails config validation. A stale published id can pass `flash train --dry-run` because dry-run does not import or run `environment.py`; the worker then uses old reward/data. | Run `flash env push --project <project-uuid> --name my-env .` after every environment/data edit and paste the returned id into every config you submit. **Self-hosted:** `env push` targets the managed hub, so instead commit the edit and re-point `[environment] id` at the new ref -- see "Publish the environment" above. |
669
669
  | Local-only env path in config | Config validation says there is no local path mode | Publish first, then use the returned slug in `[environment] id`. `flash train` only runs published env ids, not local paths. |
670
670
  | Config knobs are in the wrong table | Validation rejects `[grpo]`, `[sft]`, or unknown `[train]` keys | Put `epochs`, `group_size`, `max_completion_tokens`, `temperature`, `max_context_tokens`, LoRA, and other training knobs under `[train]`. |
671
- | GPU selection is not what you expected | Leaving `[gpu] type` unset may select a different fitting class as prices or capacity change | Set `[gpu] type` to an active validated class to hard-pin it, or leave it unset for managed cheapest-fit allocation. `train.hf_repo` remains platform-managed. |
672
- | A pinned run stops after two capacity refusals | The pinned class had no capacity, and no other class was allowed, so there was nowhere to fail over | Widen the search: drop the `[gpu] type` pin for managed allocation, or drop `[gpu] provider`. Flash stops once the class a retry would land on has refused capacity twice, rather than re-queueing on a class the provider keeps refusing. One refusal always earns a retry, since a momentary shortage is not a sold-out class. |
671
+ | GPU selection is not what you expected | Leaving `[gpu] type` unset may select a different fitting class as prices or capacity change | Set `[gpu] type` to an active validated class to hard-pin it, to a list (`["A100 PCIe", "A100 SXM"]`) to allow several, or leave it unset for managed cheapest-fit allocation. `train.hf_repo` remains platform-managed. |
672
+ | A pinned run stops after two capacity refusals | The pinned class had no capacity, and no other class was allowed, so there was nowhere to fail over | Widen the search: drop the `[gpu] type` pin for managed allocation, name alternatives with `type = ["A100 PCIe", "A100 SXM"]`, or drop `[gpu] provider`. Flash stops once the class a retry would land on has refused capacity twice, rather than re-queueing on a class the provider keeps refusing. One refusal always earns a retry, since a momentary shortage is not a sold-out class. |
673
673
  | Secrets are not available on the worker | Reward code works locally but remote logs show missing API keys or auth failures | List secret names under `[environment] secrets = [...]`, export those env vars locally before submit, or put them in local `.env` / `.env.local`. Never hard-code secret values in the config. |
674
674
  | Scorer dependency is missing on the worker | Reward code works locally but every reward is `0.0` remotely; the import your scorer needs is installed in your venv, not the worker's | List the packages your scorer imports under `[environment] pip = ["pymongo>=4.6"]`. They are installed alongside Flash's own worker requirement. `flash env test` names the failing import locally before you spend a GPU on it. Entries name packages only: pip options and URLs with inline credentials are rejected, because the spec is stored and uploaded in plaintext (put the credential in `[environment] secrets`). |
675
675
  | Wrong model / thinking setting | Config validation fails, or chat behavior does not match the run | Config validation is authoritative for model and thinking compatibility. Thinking is a run-level choice, and `flash models chat` does not expose an override flag. |
@@ -30,6 +30,7 @@ from flash.cli.ui.render import (
30
30
  header,
31
31
  run_cost,
32
32
  )
33
+ from flash.core.spec import persisted_gpu_types
33
34
 
34
35
 
35
36
  def models_table(rows: list[dict]) -> str:
@@ -71,7 +72,8 @@ def gpus_table(rows: list[tuple[str, int, float | None]], tip: str) -> str:
71
72
 
72
73
  def gpu_label(spec: dict, remote: dict) -> str:
73
74
  """Human-facing GPU label. Provider metadata stays internal."""
74
- return remote.get("allocated_gpu") or (spec.get("gpu") or {}).get("type", "")
75
+ authored = " | ".join(persisted_gpu_types(spec))
76
+ return remote.get("allocated_gpu") or authored
75
77
 
76
78
 
77
79
  def runs_table(runs: list[dict]) -> str:
@@ -661,26 +661,34 @@ class ApiClient:
661
661
  "GET", "/v1/deployments", timeout=timeout, require={"deployments": [dict]}
662
662
  )["deployments"]
663
663
 
664
- def deployment_for(self, run_id: str, timeout: float | None = None) -> dict | None:
665
- """The current deployment record for one run, or None when it is not listed.
666
-
667
- ``deploy`` returns as soon as the record is persisted, which is normally before the
668
- requested revision is servable. This is the read side a caller needs to tell "queued"
669
- from "actually ready".
670
-
671
- ``timeout`` bounds the single request. A caller polling against its own deadline needs
672
- that: the default client timeout is 60s, so one stalled read inside a `--wait 5` would
673
- overshoot the bound the user asked for by an order of magnitude.
664
+ def _serving_deployment(
665
+ self,
666
+ base_run_id: str,
667
+ timeout: float | None,
668
+ *,
669
+ body_deadline: float | None = None,
670
+ ) -> dict | None:
671
+ """The run's servable deployment record, or None when it has none.
674
672
 
675
673
  Read from the run-scoped route rather than the listing. `/v1/deployments` walks every run
676
- the key owns and loads each one's status before this picks a single record out, so on an
677
- account with a long run history the poll's cost grows with that history and the wait can
674
+ the key owns and loads each one's status before a caller picks a single record out, so on
675
+ an account with a long run history the poll's cost grows with that history and a wait can
678
676
  expire scanning unrelated runs while the requested revision is already ready
679
677
  `/v1/runs/{run_id}/deploy` resolves the one run directly.
678
+
679
+ ``body_deadline`` additionally bounds the read in WALL-CLOCK time. ``timeout`` alone is a
680
+ per-socket-operation bound, so a peer that trickles bytes just inside it can hold the read
681
+ open indefinitely; a caller that must return within a fixed budget has to pass both (see
682
+ ``env_list``). ``--wait`` polling deliberately does not: it owns a deadline spanning many
683
+ reads and recomputes each one's share.
680
684
  """
681
- base_run_id, step = _parse_adapter_target(run_id)
682
685
  try:
683
- deployment = self._request("GET", f"/v1/runs/{base_run_id}/deploy", timeout=timeout)
686
+ deployment = self._request(
687
+ "GET",
688
+ f"/v1/runs/{base_run_id}/deploy",
689
+ timeout=timeout,
690
+ body_deadline=body_deadline,
691
+ )
684
692
  except ApiError as exc:
685
693
  # a run the key cannot see reads the same as one that is not deployed. the listing said
686
694
  # "absent" by omitting the row; saying it by raising would turn a vanished deployment
@@ -695,6 +703,27 @@ class ApiClient:
695
703
  # the listing's meaning: neither is a revision anyone can serve.
696
704
  if str(deployment.get("state") or "") in {"undeployed", "dry_run"}:
697
705
  return None
706
+ if not deployment.get("run_id"):
707
+ # `models deploy --wait` prints this record in place of the POST body, so without the
708
+ # id styled output renders an empty run field and the json omits it entirely.
709
+ deployment = {**deployment, "run_id": base_run_id}
710
+ return deployment
711
+
712
+ def deployment_for(self, run_id: str, timeout: float | None = None) -> dict | None:
713
+ """The deployment record for the checkpoint named in ``run_id``, or None.
714
+
715
+ ``deploy`` returns as soon as the record is persisted, which is normally before the
716
+ requested revision is servable. This is the read side a caller needs to tell "queued"
717
+ from "actually ready".
718
+
719
+ ``timeout`` bounds the single request. A caller polling against its own deadline needs
720
+ that: the default client timeout is 60s, so one stalled read inside a `--wait 5` would
721
+ overshoot the bound the user asked for by an order of magnitude.
722
+ """
723
+ base_run_id, step = _parse_adapter_target(run_id)
724
+ deployment = self._serving_deployment(base_run_id, timeout)
725
+ if deployment is None:
726
+ return None
698
727
  # the requested step is part of the identity, not decoration. matching on the run id
699
728
  # alone lets `deploy RUN/step-40 --wait` settle on whichever revision happens to be
700
729
  # deployed -- an older one still marked ready, or a replacement another shell deployed
@@ -704,12 +733,27 @@ class ApiClient:
704
733
  # None is the final adapter, an int is RUN/step-N (see the deployments renderer).
705
734
  if (listed if listed is None else int(listed)) != step:
706
735
  return None
707
- if not deployment.get("run_id"):
708
- # `models deploy --wait` prints this record in place of the POST body, so without the
709
- # id styled output renders an empty run field and the json omits it entirely.
710
- deployment = {**deployment, "run_id": base_run_id}
711
736
  return deployment
712
737
 
738
+ def deployed_checkpoint(
739
+ self,
740
+ run_id: str,
741
+ timeout: float | None = None,
742
+ *,
743
+ body_deadline: float | None = None,
744
+ ) -> dict | None:
745
+ """Whatever checkpoint the run serves right now, whichever step that is.
746
+
747
+ The counterpart to ``deployment_for``, which answers the narrower "is MY revision live?"
748
+ and hides any other. A caller about to deploy needs the opposite: the record it is about
749
+ to displace is by definition the one the step filter drops.
750
+
751
+ ``body_deadline`` bounds the whole read in wall-clock time; ``timeout`` alone bounds each
752
+ socket operation, which a peer trickling bytes just inside it can extend without limit.
753
+ """
754
+ base_run_id, _ = _parse_adapter_target(run_id)
755
+ return self._serving_deployment(base_run_id, timeout, body_deadline=body_deadline)
756
+
713
757
  def chat(
714
758
  self,
715
759
  run_id: str,