freesolo-flash-dev 1.2.33__tar.gz → 1.2.37__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 (541) hide show
  1. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/PKG-INFO +1 -1
  2. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cli/__init__.py +2 -2
  3. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cli/commands/__init__.py +13 -5
  4. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cli/commands/env/episode.py +72 -30
  5. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cli/commands/env/eval.py +7 -4
  6. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cli/commands/env/setup.py +9 -7
  7. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cli/commands/env/test.py +26 -20
  8. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cli/commands/env/test_evaluations.py +58 -4
  9. freesolo_flash_dev-1.2.37/flash/cli/commands/prompt_budget.py +146 -0
  10. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cli/commands/train_cost.py +3 -0
  11. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cli/scaffold/TRAINING.md +5 -0
  12. freesolo_flash_dev-1.2.37/flash/engine/plan/prompt_budget.py +63 -0
  13. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/opd_train_runner.py +6 -2
  14. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/rl/inputs.py +5 -5
  15. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/envs/evaluations.py +41 -7
  16. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/runner/__init__.py +7 -0
  17. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/runner/preparation.py +5 -4
  18. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/runner/submit.py +17 -5
  19. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/runner/supervise/transitions.py +24 -3
  20. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/serve/deploy.py +17 -9
  21. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/serve/errors.py +16 -0
  22. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/routes/serving.py +3 -3
  23. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/routes/serving_completion.py +133 -59
  24. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/routes/serving_revisions.py +38 -7
  25. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/routes/serving_smoke.py +109 -29
  26. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/pyproject.toml +2 -2
  27. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_cli_commands.py +6 -0
  28. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_client_server_integration.py +5 -0
  29. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_env_evaluations.py +92 -14
  30. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_env_test.py +370 -23
  31. freesolo_flash_dev-1.2.37/tests/test_prompt_budget.py +392 -0
  32. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_serve.py +11 -8
  33. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_server_api.py +624 -47
  34. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_server_envs_coverage.py +310 -5
  35. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_warmstart_cross_repo.py +13 -3
  36. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/uv.lock +1 -1
  37. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/.dockerignore +0 -0
  38. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/.env.example +0 -0
  39. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/.github/CODEOWNERS +0 -0
  40. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  41. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  42. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  43. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  44. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/.github/dependabot.yml +0 -0
  45. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/.github/workflows/auto-rebake.yml +0 -0
  46. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/.github/workflows/bake-kernel-cache.yml +0 -0
  47. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/.github/workflows/ci.yml +0 -0
  48. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/.github/workflows/main-source-guard.yml +0 -0
  49. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/.github/workflows/notify-tests-repo.yml +0 -0
  50. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/.github/workflows/publish-dev.yml +0 -0
  51. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/.github/workflows/publish-image.yml +0 -0
  52. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/.github/workflows/publish.yml +0 -0
  53. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/.github/workflows/version-parity.yml +0 -0
  54. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/.github/workflows/worker-image.yml +0 -0
  55. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/.gitignore +0 -0
  56. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/CHANGELOG.md +0 -0
  57. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/CODE_OF_CONDUCT.md +0 -0
  58. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/CONTRIBUTING.md +0 -0
  59. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/Dockerfile +0 -0
  60. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/Dockerfile.worker +0 -0
  61. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/LICENSE +0 -0
  62. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/NOTICE +0 -0
  63. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/README.md +0 -0
  64. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/SECURITY.md +0 -0
  65. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/SELF_HOSTING.md +0 -0
  66. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/build/kernel_cache/.gitignore +0 -0
  67. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/build/kernel_cache/.keep +0 -0
  68. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/deploy/infisical/README.md +0 -0
  69. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/deploy/infisical/entrypoint.sh +0 -0
  70. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/docker/Dockerfile.kernelcache +0 -0
  71. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/docker/Dockerfile.kernelcache.relayer +0 -0
  72. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/docker/bake_kernel_cache.py +0 -0
  73. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/docker/bake_pod_entry.py +0 -0
  74. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/docker/extract_cudart_fix.py +0 -0
  75. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/docker/kernel_fingerprint.py +0 -0
  76. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/docker/make_rp_handler.py +0 -0
  77. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/__init__.py +0 -0
  78. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/_internal/__init__.py +0 -0
  79. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/_internal/channel.py +0 -0
  80. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/_internal/diagnostics.py +0 -0
  81. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/_internal/fileio.py +0 -0
  82. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/_internal/logging.py +0 -0
  83. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/_internal/paths.py +0 -0
  84. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/adapters/__init__.py +0 -0
  85. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/adapters/artifacts.py +0 -0
  86. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/adapters/lora_rank.py +0 -0
  87. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cli/__main__.py +0 -0
  88. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cli/commands/deploy.py +0 -0
  89. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cli/commands/env/__init__.py +0 -0
  90. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cli/commands/env/eval_args.py +0 -0
  91. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cli/commands/env/imports.py +0 -0
  92. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cli/commands/env/list.py +0 -0
  93. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cli/commands/env/push.py +0 -0
  94. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cli/commands/env/retained.py +0 -0
  95. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cli/commands/env/test_params.py +0 -0
  96. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cli/commands/env/test_warnings.py +0 -0
  97. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cli/commands/traces.py +0 -0
  98. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cli/scaffold/__init__.py +0 -0
  99. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cli/ui/__init__.py +0 -0
  100. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cli/ui/cost.py +0 -0
  101. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cli/ui/env_panels.py +0 -0
  102. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cli/ui/heartbeat.py +0 -0
  103. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cli/ui/render.py +0 -0
  104. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cli/ui/tables.py +0 -0
  105. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cli/ui/tty.py +0 -0
  106. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/client/__init__.py +0 -0
  107. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/client/config.py +0 -0
  108. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/client/freesolo_api.py +0 -0
  109. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/client/http.py +0 -0
  110. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/client/runtime_secrets.py +0 -0
  111. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/client/shapes.py +0 -0
  112. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/client/specs.py +0 -0
  113. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/client/streaming.py +0 -0
  114. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/content/__init__.py +0 -0
  115. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/content/multimodal.py +0 -0
  116. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/content/structured_outputs.py +0 -0
  117. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/content/thinking.py +0 -0
  118. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/core/__init__.py +0 -0
  119. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/core/catalog.py +0 -0
  120. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/core/spec.py +0 -0
  121. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cost/__init__.py +0 -0
  122. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cost/analytical.py +0 -0
  123. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cost/facts.py +0 -0
  124. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cost/spec.py +0 -0
  125. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/cost/types.py +0 -0
  126. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/__init__.py +0 -0
  127. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/plan/__init__.py +0 -0
  128. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/plan/kv_sizing.py +0 -0
  129. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/plan/model_config_probe.py +0 -0
  130. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/plan/recipe.py +0 -0
  131. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/plan/steps.py +0 -0
  132. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/plan/vram.py +0 -0
  133. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/profiling/__init__.py +0 -0
  134. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/profiling/dataset_profile.py +0 -0
  135. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/profiling/reasoning_render.py +0 -0
  136. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/profiling/sft_workload.py +0 -0
  137. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/profiling/tokenizer.py +0 -0
  138. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/profiling/workload_profile.py +0 -0
  139. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/result/__init__.py +0 -0
  140. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/result/accounting.py +0 -0
  141. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/result/rollout_samples.py +0 -0
  142. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/__init__.py +0 -0
  143. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/__main__.py +0 -0
  144. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/backend_common.py +0 -0
  145. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/entry/__init__.py +0 -0
  146. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/entry/opd.py +0 -0
  147. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/entry/rl.py +0 -0
  148. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/entry/sft.py +0 -0
  149. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/io/__init__.py +0 -0
  150. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/io/heartbeat.py +0 -0
  151. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/io/hf.py +0 -0
  152. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/io/prefetch.py +0 -0
  153. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/io/wandb_log.py +0 -0
  154. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/model/__init__.py +0 -0
  155. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/model/adapter.py +0 -0
  156. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/model/decoding.py +0 -0
  157. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/model/lora.py +0 -0
  158. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/model/packing.py +0 -0
  159. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/opd_train.py +0 -0
  160. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/perf/__init__.py +0 -0
  161. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/perf/diagnostics.py +0 -0
  162. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/perf/lifecycle.py +0 -0
  163. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/perf/liger.py +0 -0
  164. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/perf/memory.py +0 -0
  165. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/rl_train.py +0 -0
  166. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/rl_train_runner.py +0 -0
  167. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/runtime/__init__.py +0 -0
  168. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/runtime/kernel_warmup.py +0 -0
  169. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/runtime/pkg_proxy.py +0 -0
  170. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/runtime/rng.py +0 -0
  171. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/score_batcher.py +0 -0
  172. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/sft_train.py +0 -0
  173. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/sft_train_runner.py +0 -0
  174. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/teacher/__init__.py +0 -0
  175. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/teacher/client.py +0 -0
  176. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/teacher/encoding.py +0 -0
  177. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/teacher/tokenizer_align.py +0 -0
  178. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/__init__.py +0 -0
  179. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/core/__init__.py +0 -0
  180. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/core/child/__init__.py +0 -0
  181. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/core/child/glue.py +0 -0
  182. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/core/step_timing.py +0 -0
  183. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/finalize.py +0 -0
  184. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/opd/__init__.py +0 -0
  185. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/opd/batching.py +0 -0
  186. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/opd/bridge.py +0 -0
  187. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/opd/child/__init__.py +0 -0
  188. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/opd/child/bridge.py +0 -0
  189. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/opd/child/multiturn.py +0 -0
  190. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/opd/child/plugin.py +0 -0
  191. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/opd/child/structured.py +0 -0
  192. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/opd/failures.py +0 -0
  193. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/opd/gkd.py +0 -0
  194. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/opd/multiturn_validation.py +0 -0
  195. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/opd/overrides.py +0 -0
  196. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/opd/prompts.py +0 -0
  197. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/opd/reporting.py +0 -0
  198. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/opd/scoring.py +0 -0
  199. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/opd/state.py +0 -0
  200. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/opd/validation.py +0 -0
  201. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/rl/__init__.py +0 -0
  202. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/rl/checkpoints.py +0 -0
  203. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/rl/child/__init__.py +0 -0
  204. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/rl/child/multiturn.py +0 -0
  205. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/rl/child/plugin.py +0 -0
  206. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/rl/config.py +0 -0
  207. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/rl/multi_turn.py +0 -0
  208. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/rl/scoring.py +0 -0
  209. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/rl/shims.py +0 -0
  210. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/rl/single_turn.py +0 -0
  211. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/rl/verl_config.py +0 -0
  212. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/sft/__init__.py +0 -0
  213. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/sft/checkpoints.py +0 -0
  214. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/train/sft/config.py +0 -0
  215. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/verl/__init__.py +0 -0
  216. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/verl/capabilities.py +0 -0
  217. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/verl/checkpoints.py +0 -0
  218. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/verl/child_io.py +0 -0
  219. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/verl/diagnostics.py +0 -0
  220. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker/verl/parallelism.py +0 -0
  221. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/engine/worker_entrypoint.py +0 -0
  222. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/envs/__init__.py +0 -0
  223. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/envs/adapter.py +0 -0
  224. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/envs/base.py +0 -0
  225. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/envs/cache_security.py +0 -0
  226. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/envs/dataset_selection.py +0 -0
  227. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/envs/identity.py +0 -0
  228. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/envs/loader.py +0 -0
  229. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/envs/namespace_listing.py +0 -0
  230. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/envs/package/__init__.py +0 -0
  231. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/envs/package/limits.py +0 -0
  232. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/envs/package/unpack.py +0 -0
  233. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/envs/pull.py +0 -0
  234. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/__init__.py +0 -0
  235. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/_lifecycle/__init__.py +0 -0
  236. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/_lifecycle/auth.py +0 -0
  237. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/_lifecycle/bootstrap.py +0 -0
  238. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/_lifecycle/bootstrap_pip.py +0 -0
  239. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/_lifecycle/bootstrap_secrets.py +0 -0
  240. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/_lifecycle/deadline.py +0 -0
  241. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/_lifecycle/http.py +0 -0
  242. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/_lifecycle/instance.py +0 -0
  243. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/_lifecycle/poll.py +0 -0
  244. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/_lifecycle/poll_instance.py +0 -0
  245. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/_lifecycle/provider.py +0 -0
  246. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/_lifecycle/worker.py +0 -0
  247. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/allocator.py +0 -0
  248. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/artifacts/__init__.py +0 -0
  249. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/artifacts/hf.py +0 -0
  250. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/artifacts/preload_runpod.py +0 -0
  251. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/artifacts/weight_cache.py +0 -0
  252. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/base.py +0 -0
  253. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/fit_errors.py +0 -0
  254. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/lambda_/__init__.py +0 -0
  255. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/lambda_/api.py +0 -0
  256. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/lambda_/auth.py +0 -0
  257. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/lambda_/gpus.py +0 -0
  258. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/lambda_/jobs/__init__.py +0 -0
  259. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/lambda_/jobs/builders.py +0 -0
  260. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/lambda_/jobs/reap.py +0 -0
  261. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/lambda_/preflight.py +0 -0
  262. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/lambda_/pricing.py +0 -0
  263. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/preflight.py +0 -0
  264. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/realized.py +0 -0
  265. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/runpod/__init__.py +0 -0
  266. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/runpod/api.py +0 -0
  267. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/runpod/auth.py +0 -0
  268. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/runpod/cost.py +0 -0
  269. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/runpod/gpus.py +0 -0
  270. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/runpod/job_execution.py +0 -0
  271. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/runpod/jobs.py +0 -0
  272. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/runpod/preflight.py +0 -0
  273. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/runpod/pricing.py +0 -0
  274. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/runpod/resources.py +0 -0
  275. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/runpod/serverless/__init__.py +0 -0
  276. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/runpod/serverless/endpoints.py +0 -0
  277. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/sharding.py +0 -0
  278. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/vast/__init__.py +0 -0
  279. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/vast/api.py +0 -0
  280. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/vast/auth.py +0 -0
  281. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/vast/jobs/__init__.py +0 -0
  282. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/vast/jobs/builders.py +0 -0
  283. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/vast/preflight.py +0 -0
  284. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/providers/vast/pricing.py +0 -0
  285. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/py.typed +0 -0
  286. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/runner/artifacts.py +0 -0
  287. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/runner/attempts.py +0 -0
  288. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/runner/costs.py +0 -0
  289. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/runner/deadlines.py +0 -0
  290. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/runner/reconciliation.py +0 -0
  291. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/runner/results/__init__.py +0 -0
  292. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/runner/results/checkpoints.py +0 -0
  293. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/runner/results/verified_revisions.py +0 -0
  294. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/runner/status.py +0 -0
  295. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/runner/supervise/__init__.py +0 -0
  296. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/runner/supervise/attach.py +0 -0
  297. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/runner/supervise/deploy.py +0 -0
  298. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/runner/supervise/lifecycle.py +0 -0
  299. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/runner/supervise/recovery.py +0 -0
  300. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/runner/supervise/retry_decision.py +0 -0
  301. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/runner/supervise/seed_submission.py +0 -0
  302. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/runner/weight_cache.py +0 -0
  303. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/schema/__init__.py +0 -0
  304. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/schema/fields.py +0 -0
  305. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/serve/__init__.py +0 -0
  306. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/serve/adapter_check.py +0 -0
  307. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/serve/export.py +0 -0
  308. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/serve/preflight.py +0 -0
  309. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/serve/responses.py +0 -0
  310. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/serve/streaming.py +0 -0
  311. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/serve/thinking.py +0 -0
  312. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/serve/urls.py +0 -0
  313. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/__init__.py +0 -0
  314. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/__main__.py +0 -0
  315. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/app.py +0 -0
  316. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/billing/__init__.py +0 -0
  317. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/billing/charges.py +0 -0
  318. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/billing/retry.py +0 -0
  319. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/domain/__init__.py +0 -0
  320. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/domain/checkpoints.py +0 -0
  321. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/domain/environment_registry.py +0 -0
  322. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/domain/envs.py +0 -0
  323. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/domain/projects.py +0 -0
  324. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/domain/reconcile.py +0 -0
  325. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/domain/repo_cleanup.py +0 -0
  326. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/domain/run_registry.py +0 -0
  327. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/domain/teacher_broker.py +0 -0
  328. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/domain/teacher_errors.py +0 -0
  329. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/domain/teacher_requests.py +0 -0
  330. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/platform/__init__.py +0 -0
  331. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/platform/auth.py +0 -0
  332. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/platform/db.py +0 -0
  333. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/platform/deps.py +0 -0
  334. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/platform/internal_client.py +0 -0
  335. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/platform/locks.py +0 -0
  336. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/platform/runtime.py +0 -0
  337. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/routes/__init__.py +0 -0
  338. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/routes/envs.py +0 -0
  339. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/routes/meta.py +0 -0
  340. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/routes/runs.py +0 -0
  341. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/server/routes/teacher.py +0 -0
  342. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/teacher/__init__.py +0 -0
  343. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/teacher/limits.py +0 -0
  344. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/flash/teacher/retry_contract.py +0 -0
  345. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/scripts/build_dev_dist.py +0 -0
  346. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/scripts/check_file_size.py +0 -0
  347. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/scripts/check_function_size.py +0 -0
  348. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/scripts/check_verl_pin_exists.py +0 -0
  349. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/scripts/scrub_history.sh +0 -0
  350. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/__init__.py +0 -0
  351. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/_helpers/__init__.py +0 -0
  352. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/_helpers/profile.py +0 -0
  353. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/_helpers/runner.py +0 -0
  354. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/_helpers/specs.py +0 -0
  355. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/_helpers/teacher.py +0 -0
  356. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/_helpers/vast.py +0 -0
  357. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/conftest.py +0 -0
  358. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/fixtures/math_eval.jsonl +0 -0
  359. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/fixtures/math_train.jsonl +0 -0
  360. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/live/__init__.py +0 -0
  361. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/live/conftest.py +0 -0
  362. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/live/test_lambda_live.py +0 -0
  363. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/live/test_runpod_live.py +0 -0
  364. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/live/test_sft_thinking_render_live.py +0 -0
  365. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/live/test_vast_live.py +0 -0
  366. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_accounting_coverage.py +0 -0
  367. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_adapter_shard_completeness.py +0 -0
  368. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_agent_flash_cli_contract.py +0 -0
  369. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_algorithms.py +0 -0
  370. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_allocator.py +0 -0
  371. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_backend_common.py +0 -0
  372. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_backend_jobspec_contract.py +0 -0
  373. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_bake_kernel_cache.py +0 -0
  374. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_base_model_provenance.py +0 -0
  375. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_billing_retry.py +0 -0
  376. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_build_context_contract.py +0 -0
  377. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_cancel_remote.py +0 -0
  378. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_catalog_consistency.py +0 -0
  379. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_catalog_only_models.py +0 -0
  380. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_charge_pricing.py +0 -0
  381. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_checkpoints.py +0 -0
  382. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_cli_commands_coverage.py +0 -0
  383. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_cli_credential_shadowing.py +0 -0
  384. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_cli_errors.py +0 -0
  385. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_cli_estimate.py +0 -0
  386. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_cli_gpus_flag.py +0 -0
  387. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_cli_help.py +0 -0
  388. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_cli_main_coverage.py +0 -0
  389. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_cli_managed.py +0 -0
  390. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_cli_render_coverage.py +0 -0
  391. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_cli_render_theme.py +0 -0
  392. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_cli_traces.py +0 -0
  393. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_cli_wandb_warning.py +0 -0
  394. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_client.py +0 -0
  395. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_client_import_purity.py +0 -0
  396. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_client_stream_reads.py +0 -0
  397. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_config_env_vars.py +0 -0
  398. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_config_overrides.py +0 -0
  399. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_controlled_experiment_repairs.py +0 -0
  400. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_cost_analytical.py +0 -0
  401. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_cost_equation.py +0 -0
  402. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_cost_estimate.py +0 -0
  403. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_cost_hardware.py +0 -0
  404. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_cost_models.py +0 -0
  405. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_dataset_profile.py +0 -0
  406. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_deploy_alias_move_warning.py +0 -0
  407. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_deploy_latency.py +0 -0
  408. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_dev_channel.py +0 -0
  409. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_disk_gb.py +0 -0
  410. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_endpoint_name.py +0 -0
  411. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_env_cache_evict.py +0 -0
  412. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_env_delete.py +0 -0
  413. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_env_download.py +0 -0
  414. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_env_download_api.py +0 -0
  415. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_env_list_api.py +0 -0
  416. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_env_list_cli.py +0 -0
  417. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_env_list_hub.py +0 -0
  418. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_env_no_install.py +0 -0
  419. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_env_publish.py +0 -0
  420. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_env_pull.py +0 -0
  421. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_env_pull_coverage.py +0 -0
  422. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_env_pull_loader_coverage.py +0 -0
  423. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_env_pull_managed_control_plane.py +0 -0
  424. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_env_push.py +0 -0
  425. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_env_rate_limit_resolve.py +0 -0
  426. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_env_ref_pinning.py +0 -0
  427. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_envs_coverage.py +0 -0
  428. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_export.py +0 -0
  429. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_flash_mvp.py +0 -0
  430. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_flash_worker.py +0 -0
  431. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_flashinfer_cache_dirs.py +0 -0
  432. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_freesolo_api_transport.py +0 -0
  433. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_github_urlopen_retry.py +0 -0
  434. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_gpu_type_single_field.py +0 -0
  435. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_gpus.py +0 -0
  436. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_grpo_params.py +0 -0
  437. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_grpo_resident_sizing.py +0 -0
  438. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_grpo_reward_batching.py +0 -0
  439. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_health_liveness.py +0 -0
  440. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_hf_retry.py +0 -0
  441. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_idle_endpoint_reaper.py +0 -0
  442. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_infisical_secrets.py +0 -0
  443. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_instance_bootstrap_coverage.py +0 -0
  444. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_internal_client.py +0 -0
  445. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_jobs.py +0 -0
  446. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_kernel_cache.py +0 -0
  447. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_kernel_fingerprint.py +0 -0
  448. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_kv_util.py +0 -0
  449. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_lambda_api_coverage.py +0 -0
  450. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_lambda_runner.py +0 -0
  451. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_logging.py +0 -0
  452. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_login_perms.py +0 -0
  453. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_lora_rank_coverage.py +0 -0
  454. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_lora_rank_preflight.py +0 -0
  455. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_managed_config_fields.py +0 -0
  456. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_managed_hf_repo.py +0 -0
  457. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_metrics_schema_agent_contract.py +0 -0
  458. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_mig_guard.py +0 -0
  459. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_multi_gpu_gate.py +0 -0
  460. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_multimodal_training.py +0 -0
  461. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_named_reward_metrics.py +0 -0
  462. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_oom_escalate_gpu.py +0 -0
  463. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_opd.py +0 -0
  464. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_opd_limits.py +0 -0
  465. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_opd_multiturn_eos_boundary.py +0 -0
  466. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_opd_resume_safety.py +0 -0
  467. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_opd_train.py +0 -0
  468. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_orchestrator_flash.py +0 -0
  469. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_packing.py +0 -0
  470. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_packing_coverage.py +0 -0
  471. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_parasail_teacher.py +0 -0
  472. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_poll_helpers.py +0 -0
  473. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_preflight.py +0 -0
  474. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_projects.py +0 -0
  475. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_provider_preflight_coverage.py +0 -0
  476. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_provider_routing.py +0 -0
  477. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_provider_teardown_robustness.py +0 -0
  478. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_providers_symmetry.py +0 -0
  479. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_realized_cost.py +0 -0
  480. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_repo_cleanup.py +0 -0
  481. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_resolve_params_b.py +0 -0
  482. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_resume_on_retry.py +0 -0
  483. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_rl_train.py +0 -0
  484. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_rollout_samples.py +0 -0
  485. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_runmgmt.py +0 -0
  486. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_runpod_api_delete.py +0 -0
  487. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_runpod_key_fingerprint.py +0 -0
  488. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_runpod_key_waterfall.py +0 -0
  489. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_serve_reasoning_content.py +0 -0
  490. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_server_app_coverage.py +0 -0
  491. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_server_auth_singleflight.py +0 -0
  492. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_server_billing.py +0 -0
  493. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_server_checkpoints_coverage.py +0 -0
  494. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_server_db.py +0 -0
  495. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_server_locks_coverage.py +0 -0
  496. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_server_standalone.py +0 -0
  497. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_serving_context_preflight.py +0 -0
  498. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_serving_contract.py +0 -0
  499. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_serving_schema_coverage.py +0 -0
  500. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_sft_chunked_nll.py +0 -0
  501. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_sft_example_selection.py +0 -0
  502. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_sft_gc_off.py +0 -0
  503. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_sft_max_context.py +0 -0
  504. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_sft_startup_block.py +0 -0
  505. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_sft_train.py +0 -0
  506. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_sft_workload.py +0 -0
  507. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_spec_and_validation.py +0 -0
  508. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_step_floor.py +0 -0
  509. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_step_metrics.py +0 -0
  510. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_step_timing.py +0 -0
  511. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_structured_outputs.py +0 -0
  512. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_teacher_broker.py +0 -0
  513. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_teacher_encoding_contract.py +0 -0
  514. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_thinking_config.py +0 -0
  515. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_train_context_preflight.py +0 -0
  516. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_training_controls.py +0 -0
  517. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_type_comment_prose.py +0 -0
  518. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_vast_api.py +0 -0
  519. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_vast_api_coverage.py +0 -0
  520. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_vast_offers.py +0 -0
  521. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_vast_provider_coverage.py +0 -0
  522. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_vast_runner.py +0 -0
  523. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_verified_revisions.py +0 -0
  524. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_verifiers.py +0 -0
  525. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_version.py +0 -0
  526. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_vl_warmstart_adapter_keys.py +0 -0
  527. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_vram_architecture.py +0 -0
  528. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_wandb_link.py +0 -0
  529. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_wandb_naming.py +0 -0
  530. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_warmstart_adapter_download.py +0 -0
  531. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_warmstart_error_attribution.py +0 -0
  532. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_weight_cache.py +0 -0
  533. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_worker_dryrun.py +0 -0
  534. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_worker_hardexit.py +0 -0
  535. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_worker_image.py +0 -0
  536. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_worker_init_heartbeat.py +0 -0
  537. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_worker_stack.py +0 -0
  538. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_worker_thinking.py +0 -0
  539. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_workflow_contracts.py +0 -0
  540. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_workload_profile.py +0 -0
  541. {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.37}/tests/test_zero2_sharding_gate.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: freesolo-flash-dev
3
- Version: 1.2.33
3
+ Version: 1.2.37
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
@@ -738,11 +738,11 @@ def _add_deployment_commands(models_sub: argparse._SubParsersAction) -> None:
738
738
  "--wait",
739
739
  nargs="?",
740
740
  type=_wait_seconds,
741
- const=1800.0,
741
+ const=2400.0,
742
742
  default=None,
743
743
  metavar="SECONDS",
744
744
  help=(
745
- "block until the requested revision is ready or failed (default timeout 1800s). "
745
+ "block until the requested revision is ready or failed (default timeout 2400s). "
746
746
  "without it, deploy returns while the revision is still queued"
747
747
  ),
748
748
  )
@@ -399,6 +399,7 @@ def cmd_train(args) -> int:
399
399
  # equally not a verification -- so treat anything but an explicit True as unverified.
400
400
  affordability_verified = status.pop("affordability_verified", None) is True
401
401
  cost = "and cost" if affordability_verified else "but NOT cost"
402
+ budget_validated = prompt_budget_validation_suffix(status)
402
403
  environment = (
403
404
  "it did NOT import or run your environment.py. packaged input/output fields and the "
404
405
  "statically readable training contract were tokenized together; tokens, retention, "
@@ -411,8 +412,8 @@ def cmd_train(args) -> int:
411
412
  )
412
413
  print(
413
414
  "dry-run validated: config/schema, model+algorithm compatibility, lora rank, "
414
- f"runtime-secret presence, warm-start source, serving context cap, {cost}. "
415
- f"{environment}",
415
+ f"runtime-secret presence, warm-start source, serving context cap{budget_validated}, "
416
+ f"{cost}. {environment}",
416
417
  file=sys.stderr,
417
418
  )
418
419
  if not affordability_verified:
@@ -430,8 +431,10 @@ def cmd_train(args) -> int:
430
431
  else:
431
432
  print(json.dumps(status, indent=2))
432
433
  _print_unpacked_batch_warning(status, spec) # after the payload, so stdout stays parseable
434
+ print_status_prompt_budget_warning(status)
433
435
  _print_reasoning_loss_warning(status)
434
436
  return 0
437
+ local_budget = warn_before_paid_submit(client, spec)
435
438
  status = client.create_run(
436
439
  payload,
437
440
  runtime_secrets=runtime_secrets,
@@ -440,6 +443,7 @@ def cmd_train(args) -> int:
440
443
  run_id = status["run_id"]
441
444
  _print_unpacked_batch_warning(status, spec) # a real submit overrides batch_size the same way
442
445
  _print_reasoning_loss_warning(status) # and trains on whatever reasoning the template kept
446
+ print_warmstart_context_supplement(local_budget, status)
443
447
  logger.info(
444
448
  "submitted run %s: model=%s algorithm=%s gpu=%s",
445
449
  run_id,
@@ -963,9 +967,13 @@ from flash.cli.commands.deploy import ( # noqa: E402,F401
963
967
  cmd_undeploy,
964
968
  )
965
969
 
966
- # re-exported at the bottom rather than imported at the top: `train_cost` resolves names back
967
- # through this package, so a top import would be circular. `cmd_train` below calls these, and the
968
- # estimate tests import `_warn_if_wandb_requested_without_key` from this package by name.
970
+ # imported at the bottom because the train helpers resolve patched command-package names lazily.
971
+ from flash.cli.commands.prompt_budget import ( # noqa: E402
972
+ print_status_prompt_budget_warning,
973
+ print_warmstart_context_supplement,
974
+ prompt_budget_validation_suffix,
975
+ warn_before_paid_submit,
976
+ )
969
977
  from flash.cli.commands.train_cost import ( # noqa: E402,F401
970
978
  _client_train_schema,
971
979
  _cmd_train_cost,
@@ -13,9 +13,11 @@ from __future__ import annotations
13
13
 
14
14
  import contextlib
15
15
  import inspect
16
+ import sys
16
17
 
17
18
  from flash.cli.commands.env.test_evaluations import _evaluation_example
18
- from flash.envs.evaluations import EvalCase, EvalResult
19
+ from flash.cli.ui import render
20
+ from flash.envs.evaluations import EvalCase, EvalResult, _episode_grading_enabled
19
21
 
20
22
 
21
23
  def _eval_module():
@@ -34,7 +36,7 @@ def _grades_episodes(suite) -> bool:
34
36
  Keying off the environment scored the wrong turn there and turned a well-formed first action
35
37
  into an error, so the suite has to say so itself.
36
38
  """
37
- return bool(getattr(suite, "grades_episodes", False))
39
+ return _episode_grading_enabled(suite)
38
40
 
39
41
 
40
42
  def _drive_episode(client, target: str, environment, case: EvalCase, args) -> dict | str:
@@ -123,7 +125,14 @@ def _effective_turn_cap(environment, state: dict) -> int:
123
125
 
124
126
 
125
127
  def _score_episode_case(
126
- suite, case: EvalCase, case_id: str, state: dict, *, thinking: bool = False
128
+ suite,
129
+ case: EvalCase,
130
+ case_id: str,
131
+ state: dict,
132
+ *,
133
+ scorer,
134
+ state_style: str | None,
135
+ thinking: bool = False,
127
136
  ) -> EvalResult:
128
137
  """Grade a finished episode through the suite's own scorer.
129
138
 
@@ -134,18 +143,19 @@ def _score_episode_case(
134
143
  `reward(completion, example, state)`, which is what reaches the SDK's `score_episodes`.
135
144
 
136
145
  `EvalSuite.score(case, response)` is the published two-argument contract, so state is offered
137
- only to a suite that accepts it, detected by signature rather than by try/except: a TypeError
138
- raised INSIDE a scorer that does accept state would otherwise be silently retried as a
139
- two-argument call and graded on the wrong text.
146
+ only to a suite that accepts it. The caller resolves one scorer and signature style for the
147
+ whole suite rather than retrying on TypeError: an error raised INSIDE a state-aware scorer must
148
+ not be retried as a two-argument call and graded on the wrong text.
140
149
  """
141
150
  response = state.get("response_text")
142
151
  if not isinstance(response, str):
143
152
  turns = state.get("turns") or []
144
153
  response = str(turns[-1]) if turns else ""
145
154
  eval_module = _eval_module()
146
- style = _state_argument(getattr(suite, "score", None))
147
- if style is None:
148
- return eval_module._score_case(suite, case, case_id, response, thinking=thinking)
155
+ if state_style is None:
156
+ return eval_module._score_case(
157
+ suite, case, case_id, response, thinking=thinking, scorer=scorer
158
+ )
149
159
  return eval_module._score_case(
150
160
  suite,
151
161
  case,
@@ -153,7 +163,8 @@ def _score_episode_case(
153
163
  response,
154
164
  thinking=thinking,
155
165
  state=state,
156
- state_keyword=style == "keyword",
166
+ state_keyword=state_style == "keyword",
167
+ scorer=scorer,
157
168
  )
158
169
 
159
170
 
@@ -173,27 +184,45 @@ def _state_argument(score) -> str | None:
173
184
  except (TypeError, ValueError):
174
185
  # builtins and C callables expose no signature; treat them as the published contract.
175
186
  return None
176
- named_state = next((p for p in parameters if p.name == "state"), None)
177
- if named_state is not None and named_state.kind in (
178
- inspect.Parameter.KEYWORD_ONLY,
179
- inspect.Parameter.POSITIONAL_OR_KEYWORD,
180
- ):
181
- # By keyword even where positional would also bind: it cannot land on the wrong parameter.
182
- return "keyword"
183
- # Checked before `*args`, since a scorer with both can take `state=` but one with only
184
- # `*args` cannot.
185
- if any(p.kind is inspect.Parameter.VAR_KEYWORD for p in parameters):
186
- return "keyword"
187
- if any(p.kind is inspect.Parameter.VAR_POSITIONAL for p in parameters):
188
- return "positional"
189
187
  positional = [
190
- p
191
- for p in parameters
192
- if p.kind in (inspect.Parameter.POSITIONAL_ONLY, inspect.Parameter.POSITIONAL_OR_KEYWORD)
188
+ parameter
189
+ for parameter in parameters
190
+ if parameter.kind
191
+ in (inspect.Parameter.POSITIONAL_ONLY, inspect.Parameter.POSITIONAL_OR_KEYWORD)
193
192
  ]
194
- # (case, response) is the published contract; a third positional is the episode state. This
195
- # also catches a positional-only `state`, which the named check above deliberately skips.
196
- return "positional" if len(positional) >= 3 else None
193
+ named_state = next((parameter for parameter in parameters if parameter.name == "state"), None)
194
+ if named_state is not None:
195
+ if named_state.kind is inspect.Parameter.POSITIONAL_ONLY:
196
+ return "positional" if positional.index(named_state) == 2 else None
197
+ if named_state.kind in (
198
+ inspect.Parameter.KEYWORD_ONLY,
199
+ inspect.Parameter.POSITIONAL_OR_KEYWORD,
200
+ ):
201
+ # by keyword even where positional would also bind: it cannot land on the wrong parameter.
202
+ return "keyword"
203
+ # checked before `*args`, since a scorer with both can take `state=` but one with only
204
+ # `*args` cannot.
205
+ if any(parameter.kind is inspect.Parameter.VAR_KEYWORD for parameter in parameters):
206
+ return "keyword"
207
+ if any(parameter.kind is inspect.Parameter.VAR_POSITIONAL for parameter in parameters):
208
+ # scorer(case, response, state) reaches *args when the signature has no fixed third slot.
209
+ # zero, one, or two regular positional parameters can all bind that call.
210
+ return "positional" if len(positional) <= 2 else None
211
+ return None
212
+
213
+
214
+ def _warn_if_episode_state_is_hidden(suite, state_style: str | None) -> None:
215
+ """Warn once when full-episode work feeds a scorer that cannot see the transcript."""
216
+ if state_style is not None:
217
+ return
218
+ message = (
219
+ f"suite {getattr(suite, 'name', 'evaluation')!r} sets grades_episodes = True; "
220
+ "each episode will still be played out with one generation per turn, but the scorer "
221
+ "will receive only the episode's final response text, not the transcript. Add a third "
222
+ "`state` argument to "
223
+ "`score(case, response, state)` to grade the transcript."
224
+ )
225
+ print(render.warn(message) if render.styled() else f"warning: {message}", file=sys.stderr)
197
226
 
198
227
 
199
228
  def _run_episode_cases(
@@ -220,6 +249,9 @@ def _run_episode_cases(
220
249
  )
221
250
  for case_id in case_ids
222
251
  )
252
+ scorer = getattr(suite, "score", None)
253
+ state_style = _state_argument(scorer)
254
+ _warn_if_episode_state_is_hidden(suite, state_style)
223
255
  results = []
224
256
  # The adapter defaults to `thinking = False` (flash/envs/adapter.py), and with it off
225
257
  # `_scored_turn_text` returns the turn unstripped -- so `state["response_text"]` keeps its
@@ -237,7 +269,17 @@ def _run_episode_cases(
237
269
  if isinstance(outcome, str):
238
270
  results.append(eval_module._generation_error(case_id, outcome))
239
271
  continue
240
- results.append(_score_episode_case(suite, case, case_id, outcome, thinking=thinking))
272
+ results.append(
273
+ _score_episode_case(
274
+ suite,
275
+ case,
276
+ case_id,
277
+ outcome,
278
+ scorer=scorer,
279
+ state_style=state_style,
280
+ thinking=thinking,
281
+ )
282
+ )
241
283
  return tuple(results)
242
284
 
243
285
 
@@ -162,6 +162,7 @@ def _score_case(
162
162
  thinking: bool = False,
163
163
  state=None,
164
164
  state_keyword: bool = False,
165
+ scorer=None,
165
166
  ) -> EvalResult:
166
167
  """Grade one response on the caller's thread.
167
168
 
@@ -172,7 +173,8 @@ def _score_case(
172
173
  `episode._score_episode_case`); single-turn scoring keeps the two-argument contract.
173
174
  `state_keyword` says which way that suite's signature can take it -- `**kwargs` and
174
175
  keyword-only scorers reject a third positional, `*args` scorers reject the keyword -- so the
175
- caller decides, having read the signature.
176
+ caller decides, having read the signature. Episode scoring also passes the exact callable it
177
+ inspected, so a descriptor cannot change shape between capability detection and invocation.
176
178
 
177
179
  The scorer grades the stripped answer; the RESULT records the raw generation. Stripping for the
178
180
  scorer must not shorten what is recorded, on the error path least of all -- a failed case is
@@ -182,12 +184,13 @@ def _score_case(
182
184
  try:
183
185
  scored_text = _scored_response(response, thinking=thinking)
184
186
  recorded_response = getattr(scored_text, "raw", response)
187
+ score = suite.score if scorer is None else scorer
185
188
  if state is None:
186
- scored = suite.score(case, scored_text)
189
+ scored = score(case, scored_text)
187
190
  elif state_keyword:
188
- scored = suite.score(case, scored_text, state=state)
191
+ scored = score(case, scored_text, state=state)
189
192
  else:
190
- scored = suite.score(case, scored_text, state)
193
+ scored = score(case, scored_text, state)
191
194
  return normalize_eval_result(case, recorded_response, scored, case_id=case_id)
192
195
  except (Exception, SystemExit) as exc:
193
196
  return EvalResult(
@@ -138,12 +138,14 @@ Given the opening prompt, does the model emit the single integer `step_episode`
138
138
  to advance the game? That is a real held-out check of the action format the episode
139
139
  depends on, and it is the honest scope of a single-shot evaluation.
140
140
 
141
- To grade a finished transcript instead, set `grades_episodes = True` on the suite.
142
- `env eval` then plays each case out against the deployed model -- generating, stepping
143
- the environment, and repeating to `max_episode_turns` -- and scores the resulting
144
- transcript. Such a suite needs cases the environment can actually advance (the cases
145
- below carry no `output`, so `step_episode` has no secret to compare against), and each
146
- case then costs one generation per turn rather than one in total.
141
+ To grade a finished transcript instead, set `grades_episodes = True` on the suite
142
+ and define `score(self, case, response, state)`. `env eval` then plays each case out
143
+ against the deployed model -- generating, stepping the environment, and repeating to
144
+ `max_episode_turns` -- and passes the resulting transcript in `state`; without that
145
+ argument the scorer receives only the episode's final response text. Such a suite
146
+ needs cases the environment can actually advance (the cases below carry no `output`,
147
+ so `step_episode` has no secret to compare against), and each case then costs one
148
+ generation per turn rather than one in total.
147
149
 
148
150
  Do NOT grade these by calling `environment.reward(response, example)`: with no episode
149
151
  state that call scores an empty transcript, so an unrelated answer can score 1.0 and
@@ -289,7 +291,7 @@ class StarterMultiTurnEnv(EnvironmentMultiTurn):
289
291
  # Advance the world after one assistant action. Return done=True to end the
290
292
  # episode, or append an observation message and keep going.
291
293
  # `messages` already ends with this action: messages[-1]["content"] is
292
- # `assistant_response`. If you rebuild state by replaying the transcript, replay
294
+ # `assistant_response`. if you rebuild state by replaying the transcript, replay
293
295
  # `messages[:-1]` and apply `assistant_response` once, or you apply it twice.
294
296
  try:
295
297
  guess = int(assistant_response.strip().split()[0])
@@ -9,7 +9,10 @@ from pathlib import Path
9
9
 
10
10
  from flash.cli.commands.env.episode import _effective_turn_cap
11
11
  from flash.cli.commands.env.push import _err, _resolve_local_env_entrypoint
12
- from flash.cli.commands.env.test_evaluations import _check_evaluation_suites
12
+ from flash.cli.commands.env.test_evaluations import (
13
+ _check_evaluation_suites,
14
+ _normalize_prompt_images,
15
+ )
13
16
  from flash.cli.commands.env.test_params import _env_params
14
17
  from flash.cli.commands.env.test_warnings import (
15
18
  _warn_on_low_replay_reward,
@@ -265,9 +268,20 @@ def _drive_single_turn(env, example: dict, record: dict, *, force_echo: bool = F
265
268
  )
266
269
 
267
270
 
268
- def _drive_multi_turn(env, example: dict, record: dict, *, force_echo: bool = False) -> None:
271
+ def _new_multi_turn_replay_state(env, example: dict, record: dict) -> dict:
269
272
  state = env.new_rollout_state(example)
270
273
  record["prompt"] = _check_messages(state.get("prompt") or state.get("messages"), "prompt")
274
+ _normalize_prompt_images(env, example, record["prompt"])
275
+ return state
276
+
277
+
278
+ def _validate_multi_turn_reply(env, example: dict, state: dict, messages: object) -> None:
279
+ _check_messages(messages, "env_reply")
280
+ _normalize_prompt_images(env, example, [dict(message) for message in state["messages"]])
281
+
282
+
283
+ def _drive_multi_turn(env, example: dict, record: dict, *, force_echo: bool = False) -> None:
284
+ state = _new_multi_turn_replay_state(env, example, record)
271
285
  completion = _gold_completion(env, example)
272
286
  record["completion"] = completion
273
287
  reference_turns = _reference_turns(completion)
@@ -326,18 +340,19 @@ def _drive_multi_turn(env, example: dict, record: dict, *, force_echo: bool = Fa
326
340
  break
327
341
  env_msgs = env.env_reply(state["messages"], state)
328
342
  env_step_pending = False
329
- if not env_msgs:
330
- break
331
- # the env's own reply messages feed the chat template for the next turn in the real
332
- # rollout, so validate their envelope here too: a malformed reply that would break
333
- # remotely must fail the episode instead of slipping through on a finite reward.
334
- _check_messages(env_msgs, "env_reply")
335
343
  if gold_finished is None and turns >= len(reference_turns):
336
344
  # the gold answer has just run out and its last turn is applied: this is the only
337
345
  # moment the reference can be judged on its own, before junk padding touches the state.
338
346
  gold_finished = _episode_completed(env, state, hard_cap)
347
+ if not env_msgs:
348
+ break
339
349
  if env.rollout_done(state, max_turns=hard_cap):
340
350
  break
351
+ # the env's own reply messages feed the chat template for the next turn in the real
352
+ # rollout, so validate their envelope and accumulated images here too: a malformed reply
353
+ # that would break remotely must fail the episode instead of slipping through on a finite
354
+ # reward. normalize copies so the check cannot replace authoritative rollout messages.
355
+ _validate_multi_turn_reply(env, example, state, env_msgs)
341
356
 
342
357
  # the driver-side exits above stop before the inter-turn env_reply, so the last replayed turn
343
358
  # is still unapplied. a stateful env would then score a board or transcript missing the last
@@ -351,18 +366,9 @@ def _drive_multi_turn(env, example: dict, record: dict, *, force_echo: bool = Fa
351
366
  # env that replied with nothing, a natural finish) -- stepping again there would be a spurious
352
367
  # extra move. rollout_done covers the env having declared the episode over.
353
368
  if env_step_pending and not env.rollout_done(state, hard_cap):
354
- # validated exactly like the in-loop replies above: a malformed reply breaks the chat
355
- # template on the paid run whether it was the last one or not. this call is the ONLY
356
- # env_reply for an episode stopped at the ceiling, and a per-example `max_episode_turns`
357
- # makes that the common case rather than a rare one -- leaving it unchecked let an env whose
358
- # final reply is malformed reach `overall: PASS`.
359
- #
360
- # an EMPTY reply is allowed first, exactly as the in-loop path does (`if not env_msgs:
361
- # break` precedes its own `_check_messages`): an env with nothing further to observe
362
- # legitimately returns nothing, and `_check_messages` rejects an empty list.
363
- final_msgs = env.env_reply(state["messages"], state)
364
- if final_msgs:
365
- _check_messages(final_msgs, "env_reply")
369
+ # apply the final action's side effects, but do not validate its reply as a future prompt:
370
+ # no later model generation consumes it in the online path.
371
+ env.env_reply(state["messages"], state)
366
372
  if gold_finished is None:
367
373
  # the gold answer never ran out inside the loop -- it covered the whole episode, so the
368
374
  # break came first and the mid-loop sample never fired. NOW is its moment: the deferred
@@ -1,12 +1,13 @@
1
1
  """Offline contract checks for an environment's evaluation sidecar.
2
2
 
3
- Split from `test.py` to keep that file under the 1000-line gate. This group is cohesive and has one
4
- entry point, `check_evaluation_suites`: everything else here exists to build one held-out case's
5
- prompt and replayed response the same way `flash env eval` would.
3
+ Split from `test.py` to keep that file under the 1000-line gate. Single-turn cases validate prompt
4
+ construction and reference replay. Episode cases validate initial rollout and prompt construction,
5
+ then bind the scorer signature without executing it against unfinished state.
6
6
  """
7
7
 
8
8
  from __future__ import annotations
9
9
 
10
+ import inspect
10
11
  from pathlib import Path
11
12
 
12
13
  from flash.cli.commands.env.push import _err
@@ -76,7 +77,41 @@ def _evaluation_response(env, case) -> tuple[str, str]:
76
77
  return policy, response
77
78
 
78
79
 
80
+ def _check_episode_evaluation_prompt(env, case) -> None:
81
+ """Validate the held-out case's initial rollout state and prompt without advancing it."""
82
+ # imported here rather than at module scope: `test.py` imports this module.
83
+ from flash.cli.commands.env.test import _new_multi_turn_replay_state, _new_record
84
+
85
+ _new_multi_turn_replay_state(env, _evaluation_example(case), _new_record())
86
+
87
+
88
+ def _validate_episode_scorer_signature(scorer, case, state_style: str | None) -> None:
89
+ """Bind the online scorer call shape without executing it against unfinished state."""
90
+ if not callable(scorer):
91
+ raise TypeError("evaluation suite score must be callable")
92
+ try:
93
+ signature = inspect.signature(scorer)
94
+ except (TypeError, ValueError):
95
+ # some builtins and extension callables expose no signature, so keep the permissive runtime
96
+ # behavior without calling them during an offline check.
97
+ return
98
+
99
+ response = "response"
100
+ state = {}
101
+ if state_style is None:
102
+ signature.bind(case, response)
103
+ elif state_style == "keyword":
104
+ signature.bind(case, response, state=state)
105
+ else:
106
+ signature.bind(case, response, state)
107
+
108
+
79
109
  def _check_evaluation_suites(entrypoint: Path, env) -> bool:
110
+ from flash.cli.commands.env.episode import (
111
+ _grades_episodes,
112
+ _state_argument,
113
+ _warn_if_episode_state_is_hidden,
114
+ )
80
115
  from flash.envs.evaluations import (
81
116
  _DEFAULT_EVALUATIONS_PATH,
82
117
  EvalSuiteReport,
@@ -107,9 +142,28 @@ def _check_evaluation_suites(entrypoint: Path, env) -> bool:
107
142
  f"evaluation suite {suite.name} failed contract checks: suite produced no cases"
108
143
  )
109
144
  continue
145
+ episode_suite = _grades_episodes(suite)
146
+ if episode_suite and not getattr(env, "multi_turn", False):
147
+ raise TypeError(
148
+ "suite sets grades_episodes = True, but this environment is single-turn "
149
+ "and has no episode to play"
150
+ )
151
+ scorer = getattr(suite, "score", None)
152
+ if episode_suite:
153
+ state_style = _state_argument(scorer)
154
+ _warn_if_episode_state_is_hidden(suite, state_style)
155
+ for case in cases:
156
+ _check_episode_evaluation_prompt(env, case)
157
+ _validate_episode_scorer_signature(scorer, cases[0], state_style)
158
+ print(
159
+ f"evaluation suite {suite.name}: {len(cases)}/{len(cases)} cases "
160
+ "passed contract checks"
161
+ )
162
+ continue
163
+
110
164
  for index, case in enumerate(cases, start=1):
111
165
  _policy, response = _evaluation_response(env, case)
112
- scored = suite.score(case, response)
166
+ scored = scorer(case, response)
113
167
  result = normalize_eval_result(
114
168
  case,
115
169
  response,
@@ -0,0 +1,146 @@
1
+ """prompt-budget warnings and warm-start context lookup for training commands."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import sys
6
+ from typing import TypeGuard, cast
7
+
8
+ from flash import __version__
9
+ from flash.cli.ui import render
10
+ from flash.engine.plan.prompt_budget import PromptBudget, rl_prompt_budget
11
+
12
+
13
+ def _positive_int(value: object) -> TypeGuard[int]:
14
+ return isinstance(value, int) and not isinstance(value, bool) and value > 0
15
+
16
+
17
+ def _budget_from_status(status: object) -> PromptBudget | None:
18
+ budget = status.get("prompt_budget") if isinstance(status, dict) else None
19
+ if not isinstance(budget, dict):
20
+ return None
21
+ if budget.get("algorithm") not in {"grpo", "opd", "rl"}:
22
+ return None
23
+ if budget.get("context_source") not in {"authored", "recipe_default"}:
24
+ return None
25
+ if budget.get("prompt_budget_is_upper_bound") is not True:
26
+ return None
27
+ engine_len = budget.get("engine_len")
28
+ max_completion = budget.get("max_completion")
29
+ prompt_budget = budget.get("prompt_budget")
30
+ if not _positive_int(engine_len):
31
+ return None
32
+ if not _positive_int(max_completion):
33
+ return None
34
+ if not _positive_int(prompt_budget):
35
+ return None
36
+ if prompt_budget != engine_len - max_completion:
37
+ return None
38
+ source_context = budget.get("warm_start_context")
39
+ if source_context is not None and not _positive_int(source_context):
40
+ return None
41
+ return cast("PromptBudget", budget)
42
+
43
+
44
+ def prompt_budget_validation_suffix(status: object) -> str:
45
+ """qualify a dry-run summary only when the server returned a budget."""
46
+ return ", prompt budget (upper bound)" if _budget_from_status(status) is not None else ""
47
+
48
+
49
+ def warmstart_source_context(client, spec) -> int | None:
50
+ """read a warm-start source's authored context through the cli's authenticated client."""
51
+ from flash.core.catalog import samples_on_policy
52
+ from flash.schema import parse_checkpoint_ref
53
+
54
+ ref = getattr(spec.train, "init_from_adapter", "")
55
+ if not ref or not samples_on_policy(spec.algorithm):
56
+ return None
57
+ parsed = parse_checkpoint_ref(ref)
58
+ if parsed is None:
59
+ return None
60
+ try:
61
+ source = client.get_run(parsed[0])
62
+ # reporting is best-effort and must never block a valid submission
63
+ except Exception:
64
+ return None
65
+ train = (source or {}).get("spec", {}).get("train", {}) if isinstance(source, dict) else {}
66
+ context = train.get("max_context_tokens") if isinstance(train, dict) else None
67
+ if isinstance(context, bool) or not isinstance(context, int) or context <= 0:
68
+ return None
69
+ return context
70
+
71
+
72
+ def _warmstart_context_sentence(context: object) -> str | None:
73
+ if isinstance(context, bool) or not isinstance(context, int) or context <= 0:
74
+ return None
75
+ return (
76
+ f"The warm-start source was configured with max_context_tokens={context}; "
77
+ "it is NOT inherited."
78
+ )
79
+
80
+
81
+ def prompt_budget_warning(
82
+ budget: object,
83
+ *,
84
+ derived_locally: bool = False,
85
+ include_warm_start_context: bool = True,
86
+ ) -> str | None:
87
+ """render the defaulted-budget warning for one prompt-budget descriptor."""
88
+ if not isinstance(budget, dict) or budget.get("context_source") != "recipe_default":
89
+ return None
90
+ try:
91
+ prompt_budget = int(budget["prompt_budget"])
92
+ max_completion = int(budget["max_completion"])
93
+ except (KeyError, TypeError, ValueError):
94
+ return None
95
+ algorithm = str(budget.get("algorithm") or "").upper() or "RL"
96
+ message = (
97
+ f"train.max_context_tokens is unset, so {algorithm} derives a prompt budget of at most "
98
+ f"{prompt_budget} tokens from the recipe default (engine {budget.get('engine_len')} minus "
99
+ f"max_completion_tokens {max_completion}), not from the model's context. The worker clamps "
100
+ "the engine length to the model architecture first, so its budget can be smaller than "
101
+ "this. Prompts over the budget are DROPPED, not truncated, so the run trains on a "
102
+ "shorter, biased subset."
103
+ )
104
+ if derived_locally:
105
+ message += (
106
+ f" (Derived locally by this CLI {__version__}; if the control plane is on a "
107
+ "different release its recipe default may differ.)"
108
+ )
109
+ if include_warm_start_context:
110
+ source = _warmstart_context_sentence(budget.get("warm_start_context"))
111
+ if source:
112
+ message += f" {source}"
113
+ return message + " Set train.max_context_tokens explicitly to choose the budget."
114
+
115
+
116
+ def _print_warning(message: str | None) -> None:
117
+ if message:
118
+ print(render.warn(message) if render.styled() else f"warning: {message}", file=sys.stderr)
119
+
120
+
121
+ def print_status_prompt_budget_warning(status: object) -> None:
122
+ """print the server-derived warning carried by a submit or dry-run response."""
123
+ _print_warning(prompt_budget_warning(_budget_from_status(status)))
124
+
125
+
126
+ def warn_before_paid_submit(client, spec) -> PromptBudget | None:
127
+ """print the locally derived warning before create_run can start provisioning."""
128
+ budget = rl_prompt_budget(spec, warm_start_context=warmstart_source_context(client, spec))
129
+ _print_warning(prompt_budget_warning(budget, derived_locally=True))
130
+ return budget
131
+
132
+
133
+ def print_warmstart_context_supplement(local_budget: PromptBudget | None, status: object) -> None:
134
+ """print only context the server resolved after the generic pre-submit warning."""
135
+ served_budget = _budget_from_status(status)
136
+ if served_budget is None or (
137
+ local_budget is not None and local_budget.get("warm_start_context")
138
+ ):
139
+ return
140
+ _print_warning(_warmstart_context_sentence(served_budget.get("warm_start_context")))
141
+
142
+
143
+ def warn_cost_prompt_budget(spec) -> None:
144
+ """print the local prompt-budget warning for the offline ``--cost`` path."""
145
+ budget = rl_prompt_budget(spec)
146
+ _print_warning(prompt_budget_warning(budget, derived_locally=True))
@@ -91,6 +91,9 @@ def _cmd_train_cost_offline(spec) -> int:
91
91
  print(render.cost_panel(estimate))
92
92
  else:
93
93
  print(estimate.breakdown())
94
+ from flash.cli.commands.prompt_budget import warn_cost_prompt_budget
95
+
96
+ warn_cost_prompt_budget(spec)
94
97
  return 0
95
98
 
96
99
 
@@ -224,6 +224,11 @@ int, `strict=true` as a bool, and anything that does not parse as a TOML scalar
224
224
  `flash env eval` takes the same two flags, for the same reason: a held-out suite scored
225
225
  against a differently-configured environment is not measuring your run.
226
226
 
227
+ For a multi-turn environment, `flash env eval` still defaults to one prompt and one reply, which is
228
+ a valid first-action check. Set `grades_episodes = True` on a suite to play one generation per turn.
229
+ A scorer with the recommended `score(case, response, state)` signature receives the finished
230
+ transcript state; otherwise the scorer receives only the episode's final response text.
231
+
227
232
  **It is also a three-example smoke test, not a dataset audit.** `flash env test` runs the
228
233
  contract checks against the **first 3 rows only** (`_DEFAULT_EPISODES = 3`, and it iterates
229
234
  `dataset[:episode_count]`), so a malformed prompt, a scorer that raises, or a bad episode