freesolo-flash-dev 1.2.61__tar.gz → 1.2.64__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 (587) hide show
  1. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/CHANGELOG.md +4 -0
  2. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/PKG-INFO +1 -1
  3. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/env/setup.py +40 -20
  4. freesolo_flash_dev-1.2.64/flash/cli/commands/env/setup_wandb.py +30 -0
  5. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/traces.py +2 -2
  6. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/scaffold/TRAINING.md +4 -2
  7. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/client/__init__.py +14 -4
  8. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/content/multimodal.py +135 -19
  9. freesolo_flash_dev-1.2.64/flash/engine/huggingface.py +61 -0
  10. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/profiling/dataset_profile.py +4 -7
  11. freesolo_flash_dev-1.2.64/flash/engine/profiling/image_tokens.py +294 -0
  12. freesolo_flash_dev-1.2.64/flash/engine/profiling/sft_image_rows.py +226 -0
  13. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/profiling/sft_workload.py +144 -156
  14. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/profiling/tokenizer.py +1 -4
  15. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/entry/sft.py +41 -2
  16. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/io/prefetch.py +3 -37
  17. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/model/chatml_mask.py +73 -42
  18. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/opd_train_runner.py +35 -17
  19. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/core/child/glue.py +158 -0
  20. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/core/child/runtime.py +15 -0
  21. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/bridge.py +90 -117
  22. freesolo_flash_dev-1.2.64/flash/engine/worker/train/opd/bridge_failures.py +117 -0
  23. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/child/multiturn.py +30 -9
  24. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/child/plugin.py +3 -21
  25. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/prompts.py +2 -2
  26. freesolo_flash_dev-1.2.64/flash/engine/worker/train/opd/scoring.py +86 -0
  27. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/rl/child/multiturn.py +3 -58
  28. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/rl/verl_config.py +2 -2
  29. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/sft/child/plugin.py +3 -2
  30. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/routes/runs.py +7 -5
  31. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/pyproject.toml +2 -2
  32. freesolo_flash_dev-1.2.64/tests/capture_image_sft_processor_oracle.py +23 -0
  33. freesolo_flash_dev-1.2.64/tests/fixtures/image_sft_processor_oracle.json +1 -0
  34. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cli_commands.py +242 -11
  35. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_controlled_experiment_repairs.py +4 -1
  36. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_dataset_profile.py +255 -11
  37. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_dev_channel.py +5 -1
  38. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_envs_coverage.py +8 -2
  39. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_flash_worker.py +7 -5
  40. freesolo_flash_dev-1.2.64/tests/test_image_sft_markers.py +337 -0
  41. freesolo_flash_dev-1.2.64/tests/test_image_sft_processor_parity.py +549 -0
  42. freesolo_flash_dev-1.2.64/tests/test_image_tokens.py +464 -0
  43. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_multimodal_training.py +1 -1
  44. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_opd_multiturn_failure_exit.py +10 -1
  45. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_opd_train.py +689 -4
  46. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_sft_train.py +156 -6
  47. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_wandb_link.py +163 -6
  48. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/uv.lock +1 -1
  49. freesolo_flash_dev-1.2.61/flash/engine/worker/train/opd/scoring.py +0 -73
  50. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.dockerignore +0 -0
  51. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.env.example +0 -0
  52. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/CODEOWNERS +0 -0
  53. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  54. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  55. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  56. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  57. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/dependabot.yml +0 -0
  58. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/workflows/auto-rebake.yml +0 -0
  59. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/workflows/bake-kernel-cache.yml +0 -0
  60. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/workflows/ci.yml +0 -0
  61. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/workflows/main-source-guard.yml +0 -0
  62. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/workflows/notify-tests-repo.yml +0 -0
  63. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/workflows/publish-dev.yml +0 -0
  64. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/workflows/publish-image.yml +0 -0
  65. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/workflows/publish.yml +0 -0
  66. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/workflows/version-parity.yml +0 -0
  67. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/workflows/worker-image.yml +0 -0
  68. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.gitignore +0 -0
  69. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/CODE_OF_CONDUCT.md +0 -0
  70. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/CONTRIBUTING.md +0 -0
  71. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/Dockerfile +0 -0
  72. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/Dockerfile.worker +0 -0
  73. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/LICENSE +0 -0
  74. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/NOTICE +0 -0
  75. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/README.md +0 -0
  76. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/SECURITY.md +0 -0
  77. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/SELF_HOSTING.md +0 -0
  78. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/build/kernel_cache/.gitignore +0 -0
  79. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/build/kernel_cache/.keep +0 -0
  80. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/deploy/infisical/README.md +0 -0
  81. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/deploy/infisical/entrypoint.sh +0 -0
  82. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/docker/Dockerfile.kernelcache +0 -0
  83. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/docker/Dockerfile.kernelcache.relayer +0 -0
  84. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/docker/bake_kernel_cache.py +0 -0
  85. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/docker/bake_pod_entry.py +0 -0
  86. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/docker/extract_cudart_fix.py +0 -0
  87. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/docker/kernel_fingerprint.py +0 -0
  88. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/docker/make_rp_handler.py +0 -0
  89. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/__init__.py +0 -0
  90. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/_internal/__init__.py +0 -0
  91. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/_internal/channel.py +0 -0
  92. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/_internal/diagnostics.py +0 -0
  93. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/_internal/fileio.py +0 -0
  94. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/_internal/logging.py +0 -0
  95. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/_internal/paths.py +0 -0
  96. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/adapters/__init__.py +0 -0
  97. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/adapters/artifacts.py +0 -0
  98. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/adapters/fused_experts.py +0 -0
  99. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/adapters/lora_rank.py +0 -0
  100. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/__init__.py +0 -0
  101. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/__main__.py +0 -0
  102. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/__init__.py +0 -0
  103. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/deploy.py +0 -0
  104. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/env/__init__.py +0 -0
  105. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/env/episode.py +0 -0
  106. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/env/eval.py +0 -0
  107. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/env/eval_args.py +0 -0
  108. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/env/imports.py +0 -0
  109. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/env/list.py +0 -0
  110. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/env/push.py +0 -0
  111. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/env/retained.py +0 -0
  112. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/env/test.py +0 -0
  113. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/env/test_evaluations.py +0 -0
  114. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/env/test_params.py +0 -0
  115. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/env/test_warnings.py +0 -0
  116. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/prompt_budget.py +0 -0
  117. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/train_cost.py +0 -0
  118. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/scaffold/__init__.py +0 -0
  119. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/ui/__init__.py +0 -0
  120. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/ui/cost.py +0 -0
  121. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/ui/env_panels.py +0 -0
  122. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/ui/heartbeat.py +0 -0
  123. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/ui/render.py +0 -0
  124. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/ui/tables.py +0 -0
  125. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/ui/tty.py +0 -0
  126. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/client/config.py +0 -0
  127. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/client/freesolo_api.py +0 -0
  128. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/client/http.py +0 -0
  129. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/client/runtime_secrets.py +0 -0
  130. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/client/shapes.py +0 -0
  131. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/client/specs.py +0 -0
  132. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/client/streaming.py +0 -0
  133. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/content/__init__.py +0 -0
  134. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/content/structured_outputs.py +0 -0
  135. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/content/thinking.py +0 -0
  136. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/core/__init__.py +0 -0
  137. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/core/catalog.py +0 -0
  138. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/core/spec.py +0 -0
  139. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/core/spec_persistence.py +0 -0
  140. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cost/__init__.py +0 -0
  141. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cost/analytical.py +0 -0
  142. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cost/facts.py +0 -0
  143. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cost/spec.py +0 -0
  144. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cost/types.py +0 -0
  145. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/__init__.py +0 -0
  146. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/plan/__init__.py +0 -0
  147. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/plan/kv_sizing.py +0 -0
  148. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/plan/model_config_probe.py +0 -0
  149. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/plan/prompt_budget.py +0 -0
  150. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/plan/recipe.py +0 -0
  151. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/plan/steps.py +0 -0
  152. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/plan/vram.py +0 -0
  153. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/profiling/__init__.py +0 -0
  154. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/profiling/reasoning_render.py +0 -0
  155. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/profiling/workload_profile.py +0 -0
  156. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/result/__init__.py +0 -0
  157. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/result/accounting.py +0 -0
  158. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/result/rollout_samples.py +0 -0
  159. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/__init__.py +0 -0
  160. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/__main__.py +0 -0
  161. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/backend_common.py +0 -0
  162. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/entry/__init__.py +0 -0
  163. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/entry/opd.py +0 -0
  164. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/entry/rl.py +0 -0
  165. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/io/__init__.py +0 -0
  166. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/io/heartbeat.py +0 -0
  167. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/io/hf.py +0 -0
  168. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/io/wandb_log.py +0 -0
  169. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/model/__init__.py +0 -0
  170. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/model/adapter.py +0 -0
  171. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/model/decoding.py +0 -0
  172. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/model/lora.py +0 -0
  173. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/model/packing.py +0 -0
  174. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/opd_train.py +0 -0
  175. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/perf/__init__.py +0 -0
  176. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/perf/diagnostics.py +0 -0
  177. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/perf/lifecycle.py +0 -0
  178. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/perf/liger.py +0 -0
  179. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/perf/memory.py +0 -0
  180. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/rl_train.py +0 -0
  181. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/rl_train_runner.py +0 -0
  182. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/runtime/__init__.py +0 -0
  183. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/runtime/kernel_warmup.py +0 -0
  184. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/runtime/pkg_proxy.py +0 -0
  185. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/runtime/rng.py +0 -0
  186. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/score_batcher.py +0 -0
  187. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/sft_train.py +0 -0
  188. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/sft_train_runner.py +0 -0
  189. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/teacher/__init__.py +0 -0
  190. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/teacher/client.py +0 -0
  191. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/teacher/encoding.py +0 -0
  192. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/teacher/tokenizer_align.py +0 -0
  193. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/__init__.py +0 -0
  194. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/core/__init__.py +0 -0
  195. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/core/checkpoint_lifecycle.py +0 -0
  196. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/core/child/__init__.py +0 -0
  197. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/core/step_timing.py +0 -0
  198. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/finalize.py +0 -0
  199. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/__init__.py +0 -0
  200. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/batching.py +0 -0
  201. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/child/__init__.py +0 -0
  202. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/child/bridge.py +0 -0
  203. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/child/entry.py +0 -0
  204. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/child/replay_guard.py +0 -0
  205. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/child/runtime.py +0 -0
  206. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/child/structured.py +0 -0
  207. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/failures.py +0 -0
  208. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/gkd.py +0 -0
  209. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/multiturn_validation.py +0 -0
  210. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/overrides.py +0 -0
  211. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/reporting.py +0 -0
  212. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/state.py +0 -0
  213. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/validation.py +0 -0
  214. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/rl/__init__.py +0 -0
  215. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/rl/checkpoints.py +0 -0
  216. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/rl/child/__init__.py +0 -0
  217. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/rl/child/entry.py +0 -0
  218. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/rl/child/patches.py +0 -0
  219. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/rl/child/plugin.py +0 -0
  220. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/rl/config.py +0 -0
  221. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/rl/inputs.py +0 -0
  222. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/rl/multi_turn.py +0 -0
  223. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/rl/reward_module.py +0 -0
  224. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/rl/scoring.py +0 -0
  225. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/rl/single_turn.py +0 -0
  226. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/sft/__init__.py +0 -0
  227. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/sft/checkpoints.py +0 -0
  228. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/sft/child/entry.py +0 -0
  229. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/sft/config.py +0 -0
  230. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/verl/__init__.py +0 -0
  231. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/verl/capabilities.py +0 -0
  232. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/verl/checkpoints.py +0 -0
  233. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/verl/child_io.py +0 -0
  234. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/verl/diagnostics.py +0 -0
  235. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/verl/parallelism.py +0 -0
  236. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/verl/parent_work.py +0 -0
  237. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker_entrypoint.py +0 -0
  238. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/envs/__init__.py +0 -0
  239. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/envs/adapter.py +0 -0
  240. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/envs/base.py +0 -0
  241. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/envs/cache_security.py +0 -0
  242. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/envs/dataset_selection.py +0 -0
  243. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/envs/evaluations.py +0 -0
  244. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/envs/identity.py +0 -0
  245. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/envs/loader.py +0 -0
  246. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/envs/namespace_listing.py +0 -0
  247. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/envs/package/__init__.py +0 -0
  248. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/envs/package/limits.py +0 -0
  249. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/envs/package/unpack.py +0 -0
  250. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/envs/pull.py +0 -0
  251. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/__init__.py +0 -0
  252. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/__init__.py +0 -0
  253. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/auth.py +0 -0
  254. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/bootstrap.py +0 -0
  255. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/bootstrap_console.py +0 -0
  256. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/bootstrap_pip.py +0 -0
  257. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/bootstrap_secrets.py +0 -0
  258. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/deadline.py +0 -0
  259. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/host/__init__.py +0 -0
  260. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/host/deadline_sleep.py +0 -0
  261. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/host/failmark.py +0 -0
  262. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/host/hostlog.py +0 -0
  263. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/http.py +0 -0
  264. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/instance.py +0 -0
  265. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/poll.py +0 -0
  266. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/poll_instance.py +0 -0
  267. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/provider.py +0 -0
  268. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/terminal_artifacts.py +0 -0
  269. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/worker.py +0 -0
  270. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/allocator.py +0 -0
  271. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/artifacts/__init__.py +0 -0
  272. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/artifacts/hf.py +0 -0
  273. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/artifacts/preload_runpod.py +0 -0
  274. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/artifacts/weight_cache.py +0 -0
  275. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/base.py +0 -0
  276. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/fit_errors.py +0 -0
  277. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/lambda_/__init__.py +0 -0
  278. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/lambda_/api.py +0 -0
  279. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/lambda_/auth.py +0 -0
  280. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/lambda_/gpus.py +0 -0
  281. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/lambda_/jobs/__init__.py +0 -0
  282. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/lambda_/jobs/builders.py +0 -0
  283. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/lambda_/jobs/reap.py +0 -0
  284. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/lambda_/preflight.py +0 -0
  285. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/lambda_/pricing.py +0 -0
  286. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/preflight.py +0 -0
  287. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/realized.py +0 -0
  288. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/runpod/__init__.py +0 -0
  289. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/runpod/api.py +0 -0
  290. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/runpod/auth.py +0 -0
  291. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/runpod/cost.py +0 -0
  292. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/runpod/gpus.py +0 -0
  293. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/runpod/job_execution.py +0 -0
  294. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/runpod/jobs.py +0 -0
  295. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/runpod/preflight.py +0 -0
  296. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/runpod/pricing.py +0 -0
  297. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/runpod/resources.py +0 -0
  298. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/runpod/serverless/__init__.py +0 -0
  299. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/runpod/serverless/endpoints.py +0 -0
  300. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/sharding.py +0 -0
  301. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/vast/__init__.py +0 -0
  302. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/vast/api.py +0 -0
  303. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/vast/auth.py +0 -0
  304. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/vast/jobs/__init__.py +0 -0
  305. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/vast/jobs/builders.py +0 -0
  306. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/vast/preflight.py +0 -0
  307. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/vast/pricing.py +0 -0
  308. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/py.typed +0 -0
  309. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/__init__.py +0 -0
  310. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/artifacts.py +0 -0
  311. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/attempts.py +0 -0
  312. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/costs.py +0 -0
  313. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/deadlines.py +0 -0
  314. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/preparation.py +0 -0
  315. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/reconciliation.py +0 -0
  316. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/results/__init__.py +0 -0
  317. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/results/checkpoints.py +0 -0
  318. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/results/verified_revisions.py +0 -0
  319. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/status.py +0 -0
  320. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/submit.py +0 -0
  321. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/supervise/__init__.py +0 -0
  322. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/supervise/attach.py +0 -0
  323. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/supervise/deploy.py +0 -0
  324. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/supervise/lifecycle.py +0 -0
  325. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/supervise/recovery.py +0 -0
  326. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/supervise/retry_decision.py +0 -0
  327. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/supervise/seed_submission.py +0 -0
  328. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/supervise/transitions.py +0 -0
  329. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/weight_cache.py +0 -0
  330. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runtime_capsule/__init__.py +0 -0
  331. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runtime_capsule/build.py +0 -0
  332. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runtime_capsule/manifest.py +0 -0
  333. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runtime_capsule/profiles.py +0 -0
  334. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/schema/__init__.py +0 -0
  335. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/schema/fields.py +0 -0
  336. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/serve/__init__.py +0 -0
  337. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/serve/adapter_check.py +0 -0
  338. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/serve/deploy.py +0 -0
  339. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/serve/errors.py +0 -0
  340. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/serve/export.py +0 -0
  341. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/serve/preflight.py +0 -0
  342. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/serve/responses.py +0 -0
  343. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/serve/streaming.py +0 -0
  344. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/serve/thinking.py +0 -0
  345. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/serve/urls.py +0 -0
  346. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/__init__.py +0 -0
  347. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/__main__.py +0 -0
  348. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/app.py +0 -0
  349. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/billing/__init__.py +0 -0
  350. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/billing/charges.py +0 -0
  351. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/billing/retry.py +0 -0
  352. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/domain/__init__.py +0 -0
  353. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/domain/checkpoints.py +0 -0
  354. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/domain/environment_registry.py +0 -0
  355. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/domain/envs.py +0 -0
  356. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/domain/projects.py +0 -0
  357. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/domain/reconcile.py +0 -0
  358. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/domain/repo_cleanup.py +0 -0
  359. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/domain/run_registry.py +0 -0
  360. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/domain/teacher_broker.py +0 -0
  361. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/domain/teacher_errors.py +0 -0
  362. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/domain/teacher_requests.py +0 -0
  363. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/platform/__init__.py +0 -0
  364. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/platform/auth.py +0 -0
  365. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/platform/db.py +0 -0
  366. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/platform/deps.py +0 -0
  367. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/platform/internal_client.py +0 -0
  368. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/platform/locks.py +0 -0
  369. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/platform/runtime.py +0 -0
  370. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/routes/__init__.py +0 -0
  371. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/routes/envs.py +0 -0
  372. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/routes/meta.py +0 -0
  373. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/routes/serving.py +0 -0
  374. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/routes/serving_completion.py +0 -0
  375. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/routes/serving_revisions.py +0 -0
  376. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/routes/serving_smoke.py +0 -0
  377. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/routes/teacher.py +0 -0
  378. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/teacher/__init__.py +0 -0
  379. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/teacher/limits.py +0 -0
  380. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/teacher/retry_contract.py +0 -0
  381. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/scripts/build_dev_dist.py +0 -0
  382. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/scripts/check_file_size.py +0 -0
  383. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/scripts/check_function_size.py +0 -0
  384. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/scripts/check_verl_pin_exists.py +0 -0
  385. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/scripts/scrub_history.sh +0 -0
  386. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/__init__.py +0 -0
  387. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/_helpers/__init__.py +0 -0
  388. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/_helpers/profile.py +0 -0
  389. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/_helpers/runner.py +0 -0
  390. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/_helpers/specs.py +0 -0
  391. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/_helpers/teacher.py +0 -0
  392. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/_helpers/vast.py +0 -0
  393. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/conftest.py +0 -0
  394. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/fixtures/math_eval.jsonl +0 -0
  395. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/fixtures/math_train.jsonl +0 -0
  396. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/live/__init__.py +0 -0
  397. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/live/conftest.py +0 -0
  398. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/live/test_lambda_live.py +0 -0
  399. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/live/test_runpod_live.py +0 -0
  400. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/live/test_sft_thinking_render_live.py +0 -0
  401. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/live/test_vast_live.py +0 -0
  402. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_accounting_coverage.py +0 -0
  403. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_adapter_shard_completeness.py +0 -0
  404. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_agent_flash_cli_contract.py +0 -0
  405. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_algorithms.py +0 -0
  406. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_allocator.py +0 -0
  407. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_backend_common.py +0 -0
  408. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_backend_jobspec_contract.py +0 -0
  409. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_bake_kernel_cache.py +0 -0
  410. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_base_model_provenance.py +0 -0
  411. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_billing_retry.py +0 -0
  412. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_build_context_contract.py +0 -0
  413. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cancel_remote.py +0 -0
  414. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_catalog_consistency.py +0 -0
  415. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_catalog_only_models.py +0 -0
  416. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_charge_pricing.py +0 -0
  417. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_checkpoint_lifecycle.py +0 -0
  418. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_checkpoints.py +0 -0
  419. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cli_commands_coverage.py +0 -0
  420. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cli_credential_shadowing.py +0 -0
  421. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cli_errors.py +0 -0
  422. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cli_estimate.py +0 -0
  423. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cli_gpus_flag.py +0 -0
  424. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cli_help.py +0 -0
  425. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cli_main_coverage.py +0 -0
  426. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cli_managed.py +0 -0
  427. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cli_render_coverage.py +0 -0
  428. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cli_render_theme.py +0 -0
  429. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cli_traces.py +0 -0
  430. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cli_wandb_warning.py +0 -0
  431. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_client.py +0 -0
  432. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_client_import_purity.py +0 -0
  433. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_client_server_integration.py +0 -0
  434. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_client_stream_reads.py +0 -0
  435. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_config_env_vars.py +0 -0
  436. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_config_overrides.py +0 -0
  437. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_console_upload.py +0 -0
  438. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cost_analytical.py +0 -0
  439. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cost_equation.py +0 -0
  440. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cost_estimate.py +0 -0
  441. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cost_hardware.py +0 -0
  442. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cost_models.py +0 -0
  443. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_deploy_alias_move_warning.py +0 -0
  444. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_deploy_latency.py +0 -0
  445. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_disk_gb.py +0 -0
  446. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_endpoint_name.py +0 -0
  447. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_cache_evict.py +0 -0
  448. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_delete.py +0 -0
  449. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_download.py +0 -0
  450. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_download_api.py +0 -0
  451. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_evaluations.py +0 -0
  452. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_list_api.py +0 -0
  453. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_list_cli.py +0 -0
  454. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_list_hub.py +0 -0
  455. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_no_install.py +0 -0
  456. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_publish.py +0 -0
  457. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_pull.py +0 -0
  458. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_pull_coverage.py +0 -0
  459. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_pull_loader_coverage.py +0 -0
  460. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_pull_managed_control_plane.py +0 -0
  461. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_push.py +0 -0
  462. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_rate_limit_resolve.py +0 -0
  463. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_ref_pinning.py +0 -0
  464. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_test.py +0 -0
  465. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_export.py +0 -0
  466. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_flash_mvp.py +0 -0
  467. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_flashinfer_cache_dirs.py +0 -0
  468. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_freesolo_api_transport.py +0 -0
  469. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_fused_expert_warmstart.py +0 -0
  470. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_github_urlopen_retry.py +0 -0
  471. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_gpu_type_single_field.py +0 -0
  472. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_gpus.py +0 -0
  473. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_grpo_params.py +0 -0
  474. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_grpo_resident_sizing.py +0 -0
  475. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_grpo_reward_batching.py +0 -0
  476. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_health_liveness.py +0 -0
  477. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_hf_retry.py +0 -0
  478. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_idle_endpoint_reaper.py +0 -0
  479. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_infisical_secrets.py +0 -0
  480. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_instance_bootstrap_coverage.py +0 -0
  481. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_internal_client.py +0 -0
  482. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_jobs.py +0 -0
  483. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_kernel_cache.py +0 -0
  484. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_kernel_fingerprint.py +0 -0
  485. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_kv_util.py +0 -0
  486. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_lambda_api_coverage.py +0 -0
  487. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_lambda_runner.py +0 -0
  488. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_logging.py +0 -0
  489. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_login_perms.py +0 -0
  490. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_lora_rank_coverage.py +0 -0
  491. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_lora_rank_preflight.py +0 -0
  492. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_managed_config_fields.py +0 -0
  493. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_managed_hf_repo.py +0 -0
  494. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_metrics_schema_agent_contract.py +0 -0
  495. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_mig_guard.py +0 -0
  496. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_multi_gpu_gate.py +0 -0
  497. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_named_reward_metrics.py +0 -0
  498. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_oom_escalate_gpu.py +0 -0
  499. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_opd.py +0 -0
  500. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_opd_limits.py +0 -0
  501. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_opd_multiturn_eos_boundary.py +0 -0
  502. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_opd_replay_guard.py +0 -0
  503. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_opd_resume_safety.py +0 -0
  504. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_orchestrator_flash.py +0 -0
  505. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_packing.py +0 -0
  506. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_packing_coverage.py +0 -0
  507. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_parasail_teacher.py +0 -0
  508. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_persisted_spec_envelope.py +0 -0
  509. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_poll_helpers.py +0 -0
  510. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_preflight.py +0 -0
  511. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_projects.py +0 -0
  512. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_prompt_budget.py +0 -0
  513. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_provider_preflight_coverage.py +0 -0
  514. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_provider_routing.py +0 -0
  515. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_provider_teardown_robustness.py +0 -0
  516. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_providers_symmetry.py +0 -0
  517. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_realized_cost.py +0 -0
  518. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_repo_cleanup.py +0 -0
  519. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_resolve_params_b.py +0 -0
  520. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_resume_on_retry.py +0 -0
  521. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_rl_train.py +0 -0
  522. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_rollout_samples.py +0 -0
  523. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_runmgmt.py +0 -0
  524. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_runpod_api_delete.py +0 -0
  525. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_runpod_key_fingerprint.py +0 -0
  526. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_runpod_key_waterfall.py +0 -0
  527. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_runtime_capsule.py +0 -0
  528. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_serve.py +0 -0
  529. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_serve_reasoning_content.py +0 -0
  530. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_server_api.py +0 -0
  531. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_server_app_coverage.py +0 -0
  532. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_server_auth_singleflight.py +0 -0
  533. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_server_billing.py +0 -0
  534. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_server_checkpoints_coverage.py +0 -0
  535. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_server_db.py +0 -0
  536. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_server_envs_coverage.py +0 -0
  537. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_server_locks_coverage.py +0 -0
  538. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_server_standalone.py +0 -0
  539. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_serving_context_preflight.py +0 -0
  540. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_serving_contract.py +0 -0
  541. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_serving_schema_coverage.py +0 -0
  542. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_sft_chunked_nll.py +0 -0
  543. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_sft_example_selection.py +0 -0
  544. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_sft_gc_off.py +0 -0
  545. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_sft_max_context.py +0 -0
  546. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_sft_startup_block.py +0 -0
  547. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_sft_workload.py +0 -0
  548. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_spec_and_validation.py +0 -0
  549. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_spec_contract_bytes.py +0 -0
  550. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_step_floor.py +0 -0
  551. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_step_metrics.py +0 -0
  552. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_step_timing.py +0 -0
  553. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_structured_outputs.py +0 -0
  554. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_teacher_broker.py +0 -0
  555. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_teacher_encoding_contract.py +0 -0
  556. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_terminal_artifacts.py +0 -0
  557. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_thinking_config.py +0 -0
  558. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_train_context_preflight.py +0 -0
  559. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_training_controls.py +0 -0
  560. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_type_comment_prose.py +0 -0
  561. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_vast_api.py +0 -0
  562. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_vast_api_coverage.py +0 -0
  563. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_vast_offers.py +0 -0
  564. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_vast_provider_coverage.py +0 -0
  565. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_vast_runner.py +0 -0
  566. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_verified_revisions.py +0 -0
  567. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_verifiers.py +0 -0
  568. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_verl_checkpoint_export.py +0 -0
  569. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_verl_child_plugins.py +0 -0
  570. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_verl_silence_watchdog.py +0 -0
  571. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_version.py +0 -0
  572. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_vl_warmstart_adapter_keys.py +0 -0
  573. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_vram_architecture.py +0 -0
  574. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_wandb_naming.py +0 -0
  575. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_warmstart_adapter_download.py +0 -0
  576. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_warmstart_cross_repo.py +0 -0
  577. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_warmstart_error_attribution.py +0 -0
  578. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_weight_cache.py +0 -0
  579. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_worker_dryrun.py +0 -0
  580. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_worker_hardexit.py +0 -0
  581. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_worker_image.py +0 -0
  582. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_worker_init_heartbeat.py +0 -0
  583. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_worker_stack.py +0 -0
  584. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_worker_thinking.py +0 -0
  585. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_workflow_contracts.py +0 -0
  586. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_workload_profile.py +0 -0
  587. {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_zero2_sharding_gate.py +0 -0
@@ -54,6 +54,10 @@ This file starts at 1.1.35. Earlier releases are not reconstructed here; use
54
54
 
55
55
  ### Fixed
56
56
 
57
+ - Completed verl children now finish each captured W&B run before the W&B service shuts down,
58
+ avoiding teardown tracebacks, and `flash env setup` now gives every starter config explicit W&B
59
+ project and folder-derived run metadata.
60
+
57
61
  - An ordered `[gpu] type` list is now priced over every class it declares acceptable, not just the
58
62
  first. Allocation cost-ranks the whole set, so quoting the head alone priced a shape the run may
59
63
  never be given — an authored `["B200", "H100"]` quoted roughly 3x the H100 the allocator would
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: freesolo-flash-dev
3
- Version: 1.2.61
3
+ Version: 1.2.64
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
@@ -5,6 +5,7 @@ from __future__ import annotations
5
5
  import json
6
6
  import sys
7
7
  import tomllib
8
+ from collections.abc import Mapping
8
9
  from pathlib import Path
9
10
 
10
11
  from flash._internal.channel import CLI_NAME
@@ -13,6 +14,7 @@ from flash.cli.commands.env.retained import (
13
14
  _warn_if_environment_form_disagrees,
14
15
  _warn_if_retained_starter_files_describe_another_plane,
15
16
  )
17
+ from flash.cli.commands.env.setup_wandb import _wandb_block, _wandb_project
16
18
  from flash.cli.scaffold import TRAINING_MD
17
19
  from flash.cli.ui import render
18
20
  from flash.envs.evaluations import _DEFAULT_EVALUATIONS_PATH
@@ -358,22 +360,14 @@ _REASONING_OPTIONS = [
358
360
  _SKIP_TRACES = "" # sentinel option value: scaffold the starter rows instead of importing
359
361
 
360
362
 
361
- def _require_setup_project(args) -> str:
363
+ def _require_setup_project(args, *, api_url: str | None, api_key: str) -> Mapping[str, object]:
362
364
  """Resolve and validate the one explicit project used by the whole scaffold."""
363
- from flash.client import ClientError, list_projects, resolve_project_id
364
- from flash.client.config import load_credentials
365
+ from flash.client import ClientError, list_projects, resolve_project
365
366
  from flash.client.http import has_freesolo_backend
366
367
 
367
- api_url, api_key = load_credentials()
368
- if not api_key:
369
- raise ClientError(
370
- f"not logged in. Run `{CLI_NAME} login` before `{CLI_NAME} env setup` "
371
- "so the project can be validated"
372
- )
373
-
374
368
  supplied = str(getattr(args, "project", "") or "").strip()
375
369
  if supplied:
376
- return resolve_project_id(supplied, api_key, api_url)
370
+ return resolve_project(supplied, api_key, api_url)
377
371
  if not _setup_interactive(args):
378
372
  raise ClientError(
379
373
  "--project PROJECT_UUID is required in noninteractive mode, with redirected stdin, or with --yes"
@@ -395,7 +389,7 @@ def _require_setup_project(args) -> str:
395
389
  f"`{CLI_NAME} projects create NAME`"
396
390
  )
397
391
  selected = render.select_required("Choose the Freesolo project for this environment", options)
398
- return resolve_project_id(selected, api_key, api_url)
392
+ return resolve_project(selected, api_key, api_url)
399
393
 
400
394
 
401
395
  # Guidance the starter .py docstrings carry, per plane kind. The templates hold placeholders
@@ -450,7 +444,7 @@ def _render_starter(template: str, project_id: str, *, can_publish: bool) -> str
450
444
  return template.replace("PROJECT_UUID", project_id)
451
445
 
452
446
 
453
- def _plane_can_publish_environments() -> bool:
447
+ def _plane_can_publish_environments(api_url: str | None) -> bool:
454
448
  """Whether `flash env push` can actually publish for the logged-in plane.
455
449
 
456
450
  Publishing uploads to the plane, which commits into the managed environment hub
@@ -462,10 +456,8 @@ def _plane_can_publish_environments() -> bool:
462
456
  operator-run Freesolo-compatible backend has a project directory (which is what that helper
463
457
  answers) but still cannot publish to the hub.
464
458
  """
465
- from flash.client.config import load_credentials
466
459
  from flash.serve.urls import is_freesolo_hosted_url
467
460
 
468
- api_url, _ = load_credentials()
469
461
  # Unset means the built-in default, which is the managed plane.
470
462
  return api_url is None or is_freesolo_hosted_url(api_url)
471
463
 
@@ -553,7 +545,7 @@ def _existing_reasoning(configs: tuple[Path, ...]) -> bool | None:
553
545
  return next(iter(found.values()), None)
554
546
 
555
547
 
556
- def _traces_dataset(args, project_id: str) -> str | None:
548
+ def _traces_dataset(args, project_id: str, api_key: str) -> str | None:
557
549
  """Optionally export traces from the already-selected project."""
558
550
  if not _setup_interactive(args):
559
551
  return None
@@ -568,7 +560,7 @@ def _traces_dataset(args, project_id: str) -> str | None:
568
560
  if use_traces == _SKIP_TRACES:
569
561
  return None
570
562
  try:
571
- exported = traces.fetch_records(project_id)
563
+ exported = traces.fetch_records(project_id, api_key)
572
564
  except Exception as exc: # trace import is optional after project validation succeeds
573
565
  _warn(f"could not export traces from {project_id} ({exc}); using the starter dataset")
574
566
  return None
@@ -692,6 +684,7 @@ def _write_rl_config(
692
684
  rl: Path,
693
685
  project_line: str,
694
686
  thinking_line: str,
687
+ wandb_block: str,
695
688
  env_comment: str,
696
689
  max_examples_line: str,
697
690
  rl_reasoning_train: str,
@@ -704,6 +697,7 @@ def _write_rl_config(
704
697
  'algorithm = "grpo"\n'
705
698
  f"{thinking_line}"
706
699
  "\n"
700
+ f"{wandb_block}"
707
701
  f"{env_comment}"
708
702
  "[train]\n"
709
703
  "epochs = 1\n"
@@ -722,6 +716,7 @@ def _write_sft_config(
722
716
  sft: Path,
723
717
  project_line: str,
724
718
  thinking_line: str,
719
+ wandb_block: str,
725
720
  env_comment: str,
726
721
  max_examples_line: str,
727
722
  sft_reasoning_note: str,
@@ -734,6 +729,7 @@ def _write_sft_config(
734
729
  'algorithm = "sft"\n'
735
730
  f"{thinking_line}"
736
731
  "\n"
732
+ f"{wandb_block}"
737
733
  f"{env_comment}"
738
734
  "[train]\n"
739
735
  "epochs = 1\n"
@@ -766,6 +762,7 @@ def _write_opd_config(
766
762
  project_line: str,
767
763
  project_id: str,
768
764
  thinking_line: str,
765
+ wandb_block: str,
769
766
  max_examples_line: str,
770
767
  *,
771
768
  can_publish: bool = True,
@@ -788,6 +785,7 @@ def _write_opd_config(
788
785
  'algorithm = "opd" # on-policy distillation from a managed parasail teacher (default glm 5.2)\n'
789
786
  f"{thinking_line}"
790
787
  "\n"
788
+ f"{wandb_block}"
791
789
  + _environment_comment(
792
790
  project_id,
793
791
  can_publish=can_publish,
@@ -816,15 +814,34 @@ def _write_training_guide(training: Path, project_id: str) -> None:
816
814
  )
817
815
 
818
816
 
817
+ def _resolve_setup_identity(args) -> tuple[str, str, str, str, str]:
818
+ """Resolve the credential, project, and folder identity used by every setup phase."""
819
+ from flash.client import ClientError
820
+ from flash.client.config import load_credentials
821
+
822
+ api_url, api_key = load_credentials()
823
+ if not api_key:
824
+ raise ClientError(
825
+ f"not logged in. Run `{CLI_NAME} login` before `{CLI_NAME} env setup` "
826
+ "so the project can be validated"
827
+ )
828
+ project = _require_setup_project(args, api_url=api_url, api_key=api_key)
829
+ project_id = str(project["id"])
830
+ folder_name = Path.cwd().name
831
+ if not folder_name.strip():
832
+ raise ClientError("the current environment folder name must be nonblank")
833
+ return api_url, api_key, project_id, _wandb_project(project), folder_name
834
+
835
+
819
836
  def cmd_env_setup(args) -> int:
820
- project_id = _require_setup_project(args)
837
+ api_url, api_key, project_id, project_name, folder_name = _resolve_setup_identity(args)
821
838
  _validate_existing_config_projects(project_id)
822
839
  starter_env = Path("environment.py")
823
840
  starter_evaluations = Path(_DEFAULT_EVALUATIONS_PATH)
824
841
  dataset = Path("dataset/train.jsonl")
825
842
  # trace import is optional and can only read the selected project. an existing dataset is never
826
843
  # overwritten, so importing into it would be a silently discarded download.
827
- traces_jsonl = None if dataset.exists() else _traces_dataset(args, project_id)
844
+ traces_jsonl = None if dataset.exists() else _traces_dataset(args, project_id, api_key)
828
845
  multi_turn, starter_env_exists = _resolve_turn_mode(args, starter_env, dataset)
829
846
 
830
847
  rl = Path("configs/rl.toml")
@@ -837,7 +854,7 @@ def cmd_env_setup(args) -> int:
837
854
  reasoning_configs = (rl, opd, sft)
838
855
  reasoning = _resolve_reasoning_mode(args, reasoning_configs)
839
856
 
840
- can_publish = _plane_can_publish_environments()
857
+ can_publish = _plane_can_publish_environments(api_url)
841
858
  _warn_if_environment_form_disagrees(reasoning_configs, can_publish=can_publish, warn=_warn)
842
859
  env_py = _render_starter(
843
860
  _STARTER_ENV_MULTITURN_PY if multi_turn else _STARTER_ENV_PY,
@@ -908,6 +925,7 @@ def cmd_env_setup(args) -> int:
908
925
  rl,
909
926
  project_line,
910
927
  thinking_line,
928
+ _wandb_block(project_name, f"{folder_name}-grpo"),
911
929
  env_comment,
912
930
  max_examples_line,
913
931
  rl_reasoning_train,
@@ -916,6 +934,7 @@ def cmd_env_setup(args) -> int:
916
934
  sft,
917
935
  project_line,
918
936
  thinking_line,
937
+ _wandb_block(project_name, f"{folder_name}-sft"),
919
938
  env_comment,
920
939
  max_examples_line,
921
940
  sft_reasoning_note,
@@ -927,6 +946,7 @@ def cmd_env_setup(args) -> int:
927
946
  project_line,
928
947
  project_id,
929
948
  thinking_line,
949
+ _wandb_block(project_name, f"{folder_name}-opd"),
930
950
  max_examples_line,
931
951
  can_publish=can_publish,
932
952
  )
@@ -0,0 +1,30 @@
1
+ """W&B metadata helpers for environment scaffolds."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ from collections.abc import Mapping
7
+
8
+ _WANDB_PROJECT_MAX_LENGTH = 128
9
+ _WANDB_PROJECT_FORBIDDEN = frozenset("/\\#?%:")
10
+
11
+
12
+ def _wandb_project(project: Mapping[str, object]) -> str:
13
+ """Adapt a resolved canonical project to a W&B-safe project name."""
14
+ project_id = str(project["id"])
15
+ name = project.get("name")
16
+ if not isinstance(name, str) or not name.strip():
17
+ return project_id
18
+ if len(name) > _WANDB_PROJECT_MAX_LENGTH or any(
19
+ character in _WANDB_PROJECT_FORBIDDEN for character in name
20
+ ):
21
+ return project_id
22
+ return name
23
+
24
+
25
+ def _wandb_block(project_name: str, run_name: str) -> str:
26
+ return (
27
+ "[wandb]\n"
28
+ f"project = {json.dumps(project_name, ensure_ascii=False)}\n"
29
+ f"run_name = {json.dumps(run_name, ensure_ascii=False)}\n\n"
30
+ )
@@ -77,8 +77,8 @@ def fetch_records(
77
77
  ) -> dict:
78
78
  """A project's traces in the requested shape, converted server-side.
79
79
 
80
- Omitting `api_key` reads the stored credential, which is right for `env_setup`'s call: it holds
81
- no snapshot this key has to agree with.
80
+ Omitting `api_key` reads the stored credential. Callers that already resolved configuration
81
+ should pass the key from that snapshot so a concurrent login cannot change the request identity.
82
82
  """
83
83
  key = _require_api_key(api_key or load_credentials()[1])
84
84
  return export_trace_records(project_id, key, export_format=export_format)
@@ -272,8 +272,10 @@ lora_rank = 32 # lora_alpha defaults to 2 x lora_rank; set it to ov
272
272
  # All knobs live under [train]. Do not add [sft], [grpo], or [opd] tables.
273
273
 
274
274
  [wandb]
275
- # project = "my-project" # the table allows exactly `project` and `run_name`;
276
- # run_name = "sft-run-1" # `name` is rejected
275
+ # new scaffolds set `project` from the selected Freesolo project and `run_name` from the folder
276
+ # plus algorithm. edit either value as needed; only `project` and `run_name` are allowed.
277
+ # project = "my-project"
278
+ # run_name = "sft-run-1"
277
279
  ```
278
280
 
279
281
  **Knobs are scoped by algorithm.** `[train]` is one flat table shared by all three algorithms,
@@ -1,5 +1,7 @@
1
1
  """HTTP client for the managed Flash control plane (used by the CLI)."""
2
2
 
3
+ from collections.abc import Mapping
4
+
3
5
  from flash._internal.channel import CLI_NAME
4
6
  from flash.client.config import load_credentials, save_credentials
5
7
  from flash.client.http import (
@@ -20,8 +22,10 @@ from flash.client.http import (
20
22
  from flash.core.spec import require_project_id
21
23
 
22
24
 
23
- def resolve_project_id(project_id: str, api_key: str, api_url: str | None = None) -> str:
24
- """Resolve one project id, turning "not yours / not there" into the actionable CLI refusal.
25
+ def resolve_project(
26
+ project_id: str, api_key: str, api_url: str | None = None
27
+ ) -> Mapping[str, object]:
28
+ """Resolve one project, turning "not yours / not there" into the actionable CLI refusal.
25
29
 
26
30
  403 and 404 are the same answer to a CLI user -- this project is not one you can record against
27
31
  -- and neither is distinguishable from a typo, so they collapse into one message naming the way
@@ -48,9 +52,9 @@ def resolve_project_id(project_id: str, api_key: str, api_url: str | None = None
48
52
  at call time, which is the binding the CLI tests patch.
49
53
  """
50
54
  if api_url is not None and not has_freesolo_backend(api_url):
51
- return require_project_id(project_id)
55
+ return {"id": require_project_id(project_id)}
52
56
  try:
53
- return str(get_project(project_id, api_key)["id"])
57
+ return get_project(project_id, api_key)
54
58
  except ApiError as exc:
55
59
  if exc.status not in {403, 404}:
56
60
  raise
@@ -60,6 +64,11 @@ def resolve_project_id(project_id: str, api_key: str, api_url: str | None = None
60
64
  ) from exc
61
65
 
62
66
 
67
+ def resolve_project_id(project_id: str, api_key: str, api_url: str | None = None) -> str:
68
+ """Resolve and return one canonical project id."""
69
+ return str(resolve_project(project_id, api_key, api_url)["id"])
70
+
71
+
63
72
  __all__ = [
64
73
  "ApiClient",
65
74
  "ApiError",
@@ -72,6 +81,7 @@ __all__ = [
72
81
  "list_projects",
73
82
  "list_trace_projects",
74
83
  "load_credentials",
84
+ "resolve_project",
75
85
  "resolve_project_id",
76
86
  "save_credentials",
77
87
  "upload_eval_run",
@@ -9,6 +9,7 @@ import json
9
9
  import urllib.parse
10
10
  from dataclasses import dataclass
11
11
  from pathlib import Path
12
+ from typing import Any
12
13
 
13
14
  MAX_IMAGES_PER_EXAMPLE = 8
14
15
  MAX_IMAGE_SOURCE_BYTES = 20 * 1024 * 1024
@@ -140,20 +141,32 @@ def _validate_dimensions(width: int, height: int) -> int:
140
141
  return pixels * 3
141
142
 
142
143
 
143
- def _inspect_image_bytes(data: bytes) -> int:
144
+ def inspect_image_bytes(data: bytes) -> tuple[int, int, int]:
145
+ """Validate one image's header and return its (decoded_rgb_bytes, width, height).
146
+
147
+ Reads the header only: the pixels are not decoded here.
148
+ """
144
149
  try:
145
150
  from PIL import Image
146
151
  except ImportError as exc:
147
152
  raise RuntimeError("Pillow is required for multimodal image training") from exc
148
153
  try:
149
154
  with Image.open(io.BytesIO(data)) as image:
150
- return _validate_dimensions(image.width, image.height)
155
+ return (
156
+ _validate_dimensions(image.width, image.height),
157
+ image.width,
158
+ image.height,
159
+ )
151
160
  except ValueError:
152
161
  raise
153
162
  except Exception as exc:
154
163
  raise ValueError("image source is not a valid image") from exc
155
164
 
156
165
 
166
+ def _inspect_image_bytes(data: bytes) -> int:
167
+ return inspect_image_bytes(data)[0]
168
+
169
+
157
170
  def _pil_descriptor(image: object) -> str:
158
171
  width = int(getattr(image, "width", 0) or 0)
159
172
  height = int(getattr(image, "height", 0) or 0)
@@ -165,14 +178,26 @@ def _pil_descriptor(image: object) -> str:
165
178
  return _descriptor("bytes", base64.b64encode(data).decode("ascii"))
166
179
 
167
180
 
168
- def normalize_image_source(source: object, package_root: str | Path | None) -> str:
169
- """Convert one supported image source to an Arrow-safe descriptor."""
181
+ def normalize_image_source(
182
+ source: object,
183
+ package_root: str | Path | None,
184
+ *,
185
+ defer_validation: bool = False,
186
+ ) -> str:
187
+ """Convert one supported image source to an Arrow-safe descriptor.
188
+
189
+ ``defer_validation`` skips the per-source pixel inspection for EVERY source kind, for a caller
190
+ that validates the resulting descriptors itself. Profiling does exactly that, through one cached
191
+ pass that bounds total decode work; inspecting here as well would decode each image twice and
192
+ charge only some kinds to that budget. Every other caller validates eagerly.
193
+ """
170
194
  root = Path(package_root) if package_root is not None else None
171
195
  if isinstance(source, bytearray):
172
196
  source = bytes(source)
173
197
  if isinstance(source, bytes):
174
198
  _check_source_size(len(source))
175
- _inspect_image_bytes(source)
199
+ if not defer_validation:
200
+ _inspect_image_bytes(source)
176
201
  return _descriptor("bytes", base64.b64encode(source).decode("ascii"))
177
202
  if _is_pil_image(source):
178
203
  return _pil_descriptor(source)
@@ -183,7 +208,8 @@ def normalize_image_source(source: object, package_root: str | Path | None) -> s
183
208
  scheme = parsed.scheme.lower()
184
209
  if scheme == "data":
185
210
  data = _data_uri_bytes(value)
186
- _inspect_image_bytes(data)
211
+ if not defer_validation:
212
+ _inspect_image_bytes(data)
187
213
  return _descriptor("data_uri", value)
188
214
  if scheme in {"http", "https"}:
189
215
  # flash never fetches a user-supplied URL server-side. download the image ahead of time
@@ -198,8 +224,10 @@ def normalize_image_source(source: object, package_root: str | Path | None) -> s
198
224
  if scheme:
199
225
  raise ValueError(f"unsupported image URL scheme: {scheme}")
200
226
  path = _package_image_path(value, root)
201
- _inspect_image_bytes(path.read_bytes())
202
- return _descriptor("path", path.relative_to(root.resolve()).as_posix())
227
+ descriptor = _descriptor("path", path.relative_to(root.resolve()).as_posix())
228
+ if not defer_validation:
229
+ _inspect_image_bytes(path.read_bytes())
230
+ return descriptor
203
231
 
204
232
 
205
233
  def _image_source_from_block(block: dict) -> object | None:
@@ -284,7 +312,11 @@ def text_only_prompt_messages(messages: list[dict]) -> list[dict]:
284
312
  return stripped
285
313
 
286
314
 
287
- def _reject_literal_image_placeholder(text: str, message_index: int) -> None:
315
+ def _reject_literal_image_placeholder(
316
+ text: str,
317
+ message_index: int,
318
+ markers: tuple[str, ...] = (IMAGE_TEACHER_PLACEHOLDER, IMAGE_PAD_TOKEN),
319
+ ) -> None:
288
320
  """Reject prompt text that already contains a reserved image marker.
289
321
 
290
322
  two distinct markers, one reason. the rendered prompt marks image positions with
@@ -298,8 +330,12 @@ def _reject_literal_image_placeholder(text: str, message_index: int) -> None:
298
330
  contributes a run the renderer never produced -- and a run from text can make up for an image
299
331
  the provider silently dropped, which is exactly the failure the guard exists to catch. keeping
300
332
  it out of the source text is what makes "one run per image" mean what it says.
333
+
334
+ ``markers`` narrows the set for callers where only one of the two is live. local sft training
335
+ never renders the teacher placeholder, so a literal ``<|media_pad|>`` there is ordinary text
336
+ for a qwen tokenizer and rejecting it would be a false refusal.
301
337
  """
302
- for marker in (IMAGE_TEACHER_PLACEHOLDER, IMAGE_PAD_TOKEN):
338
+ for marker in markers:
303
339
  if marker in text:
304
340
  raise ValueError(
305
341
  f"message {message_index} text contains the reserved image marker "
@@ -364,8 +400,14 @@ def normalize_prompt_images(
364
400
  record: dict,
365
401
  messages: list[dict],
366
402
  package_root: str | Path | None,
403
+ *,
404
+ defer_validation: bool = False,
367
405
  ) -> NormalizedImages:
368
- """Normalize prompt image blocks and top-level fields without mutating the record."""
406
+ """Normalize prompt image blocks and top-level fields without mutating the record.
407
+
408
+ ``defer_validation`` is forwarded to :func:`normalize_image_source`; see it for when a caller
409
+ may skip the per-source pixel inspection.
410
+ """
369
411
  if not isinstance(messages, list) or not all(isinstance(message, dict) for message in messages):
370
412
  raise ValueError("prompt messages must be a list of message objects")
371
413
  pending = list(_top_level_sources(record))
@@ -381,14 +423,18 @@ def normalize_prompt_images(
381
423
  f"example contains {image_count} images, exceeding the "
382
424
  f"{MAX_IMAGES_PER_EXAMPLE}-image limit"
383
425
  )
384
- descriptor = normalize_image_source(source, package_root)
426
+ descriptor = normalize_image_source(
427
+ source,
428
+ package_root,
429
+ defer_validation=defer_validation,
430
+ )
385
431
  descriptor_bytes += _descriptor_size(descriptor)
386
432
  if descriptor_bytes > MAX_TOTAL_IMAGE_DESCRIPTOR_BYTES:
387
433
  raise ValueError(
388
434
  f"example encoded image descriptors total {descriptor_bytes} bytes, exceeding the "
389
435
  f"{MAX_TOTAL_IMAGE_DESCRIPTOR_BYTES}-byte limit"
390
436
  )
391
- source_bytes += descriptor_source_size(descriptor, package_root)
437
+ source_bytes += _descriptor_source_size(descriptor, package_root)
392
438
  if source_bytes > MAX_TOTAL_IMAGE_SOURCE_BYTES:
393
439
  raise ValueError(
394
440
  f"example image sources total {source_bytes} bytes, exceeding the "
@@ -465,10 +511,27 @@ def normalize_prompt_images(
465
511
  add_descriptor(source)
466
512
  image_blocks.append({"type": "image"})
467
513
  normalized[first_user]["content"] = [*content, *image_blocks]
514
+ # checked here, on the finished blocks, rather than inside the loop above: string content never
515
+ # enters that loop, and the top-level-image path appends to a message the loop already passed.
516
+ # this is the one point every shape has converged to the same form.
517
+ #
518
+ # the unit is a RUN of consecutive text blocks, not one block, for the reason the teacher
519
+ # renderer already documents: "<|image_" and "pad|>" are each harmless alone and only become
520
+ # the reserved marker once the template concatenates them. an image block ends a run, since the
521
+ # processor puts its own expansion there and user text cannot reach across it.
522
+ for message_index, message in enumerate(normalized):
523
+ text_run: list[str] = []
524
+ for block in message["content"]:
525
+ if block.get("type") == "text":
526
+ text_run.append(block["text"])
527
+ continue
528
+ _reject_literal_image_placeholder("".join(text_run), message_index, (IMAGE_PAD_TOKEN,))
529
+ text_run = []
530
+ _reject_literal_image_placeholder("".join(text_run), message_index, (IMAGE_PAD_TOKEN,))
468
531
  return NormalizedImages(normalized, descriptors)
469
532
 
470
533
 
471
- def descriptor_source_size(descriptor: str, package_root: str | Path | None) -> int:
534
+ def _descriptor_source_size(descriptor: str, package_root: str | Path | None) -> int:
472
535
  kind, value = _parse_descriptor(descriptor)
473
536
  if kind == "bytes":
474
537
  return len(base64.b64decode(value, validate=True))
@@ -481,7 +544,8 @@ def descriptor_source_size(descriptor: str, package_root: str | Path | None) ->
481
544
  raise ValueError("invalid internal image descriptor kind")
482
545
 
483
546
 
484
- def _read_descriptor_source(descriptor: str, package_root: str | Path | None) -> bytes:
547
+ def read_descriptor_source(descriptor: str, package_root: str | Path | None) -> bytes:
548
+ """Read one descriptor's raw source bytes under the per-source size limit."""
485
549
  kind, value = _parse_descriptor(descriptor)
486
550
  if kind == "bytes":
487
551
  try:
@@ -532,7 +596,7 @@ def image_descriptors_to_data_uris(
532
596
  source_bytes = 0
533
597
  decoded_bytes = 0
534
598
  for descriptor in descriptors:
535
- data = _read_descriptor_source(descriptor, package_root)
599
+ data = read_descriptor_source(descriptor, package_root)
536
600
  source_bytes += len(data)
537
601
  if source_bytes > MAX_TOTAL_IMAGE_SOURCE_BYTES:
538
602
  raise ValueError(
@@ -553,20 +617,65 @@ def _decode_image_bytes(data: bytes):
553
617
  from PIL import Image
554
618
  except ImportError as exc:
555
619
  raise RuntimeError("Pillow is required for multimodal image training") from exc
620
+ converted = None
556
621
  try:
557
622
  with Image.open(io.BytesIO(data)) as image:
558
623
  _validate_dimensions(image.width, image.height)
559
624
  image.load()
560
- return image.convert("RGB")
625
+ converted = image.convert("RGB")
626
+ converted.load()
627
+ return converted
561
628
  except ValueError:
629
+ if converted is not None:
630
+ converted.close()
562
631
  raise
563
632
  except Exception as exc:
633
+ if converted is not None:
634
+ converted.close()
564
635
  raise ValueError("image source is not a valid image") from exc
565
636
 
566
637
 
638
+ def messages_with_decoded_images(messages: list[dict], images: list[object]) -> list[dict]:
639
+ """Bind decoded images into a message list's image blocks, in order.
640
+
641
+ Shared by sft, opd, and grpo: each algorithm decodes the row's descriptors itself and then
642
+ needs the same binding into the chat-template input.
643
+ """
644
+ image_iter = iter(images)
645
+ prepared = []
646
+ for message in messages:
647
+ copied = dict(message)
648
+ content = copied.get("content")
649
+ if isinstance(content, list):
650
+ blocks = []
651
+ for block in content:
652
+ copied_block = dict(block)
653
+ if copied_block.get("type") == "image":
654
+ copied_block["image"] = next(image_iter)
655
+ blocks.append(copied_block)
656
+ copied["content"] = blocks
657
+ prepared.append(copied)
658
+ try:
659
+ next(image_iter)
660
+ except StopIteration:
661
+ return prepared
662
+ raise ValueError("unused decoded image while preparing multimodal sft tokens")
663
+
664
+
665
+ def decode_descriptor_pixels(data: bytes) -> None:
666
+ """Fully decode one image's pixels for validation, then release it.
667
+
668
+ Header inspection accepts an image whose pixel data is truncated or corrupt; only a full decode
669
+ finds that, and the caller wants the failure, not the image.
670
+ """
671
+ image = _decode_image_bytes(data)
672
+ image.close()
673
+
674
+
567
675
  def decode_image_descriptors(
568
676
  descriptors: list[str], package_root: str | Path | None
569
677
  ) -> list[object]:
678
+ """decode one row to fully loaded rgb images under aggregate limits."""
570
679
  if len(descriptors) > MAX_IMAGES_PER_EXAMPLE:
571
680
  raise ValueError(
572
681
  f"example contains {len(descriptors)} images, exceeding the {MAX_IMAGES_PER_EXAMPLE}-image limit"
@@ -575,7 +684,7 @@ def decode_image_descriptors(
575
684
  source_bytes = 0
576
685
  decoded_bytes = 0
577
686
  for descriptor in descriptors:
578
- data = _read_descriptor_source(descriptor, package_root)
687
+ data = read_descriptor_source(descriptor, package_root)
579
688
  source_bytes += len(data)
580
689
  if source_bytes > MAX_TOTAL_IMAGE_SOURCE_BYTES:
581
690
  raise ValueError(
@@ -587,7 +696,14 @@ def decode_image_descriptors(
587
696
  f"example decoded images exceed the {MAX_TOTAL_DECODED_BYTES}-byte limit"
588
697
  )
589
698
  prepared.append(data)
590
- return [_decode_image_bytes(data) for data in prepared]
699
+ images: list[Any] = []
700
+ try:
701
+ images.extend(_decode_image_bytes(data) for data in prepared)
702
+ except Exception:
703
+ for image in images:
704
+ image.close()
705
+ raise
706
+ return images
591
707
 
592
708
 
593
709
  def resolve_image_pad_token_id(processor, tok) -> int: