freesolo-flash-dev 1.2.100__tar.gz → 1.2.102__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 (614) hide show
  1. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/PKG-INFO +1 -1
  2. freesolo_flash_dev-1.2.102/flash/cli/commands/worker_output.py +139 -0
  3. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/pyproject.toml +2 -2
  4. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_cli_commands.py +4 -1
  5. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_cli_commands_coverage.py +123 -0
  6. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/uv.lock +1 -1
  7. freesolo_flash_dev-1.2.100/flash/cli/commands/worker_output.py +0 -76
  8. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/.dockerignore +0 -0
  9. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/.env.example +0 -0
  10. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/.github/CODEOWNERS +0 -0
  11. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  12. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  13. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  14. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  15. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/.github/dependabot.yml +0 -0
  16. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/.github/workflows/auto-rebake.yml +0 -0
  17. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/.github/workflows/bake-kernel-cache.yml +0 -0
  18. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/.github/workflows/ci.yml +0 -0
  19. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/.github/workflows/dev-kernel-cache.yml +0 -0
  20. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/.github/workflows/main-source-guard.yml +0 -0
  21. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/.github/workflows/notify-tests-repo.yml +0 -0
  22. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/.github/workflows/production-kernel-cache-ready.yml +0 -0
  23. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/.github/workflows/publish-dev.yml +0 -0
  24. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/.github/workflows/publish-image.yml +0 -0
  25. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/.github/workflows/publish.yml +0 -0
  26. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/.github/workflows/version-parity.yml +0 -0
  27. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/.github/workflows/worker-image.yml +0 -0
  28. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/.gitignore +0 -0
  29. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/CHANGELOG.md +0 -0
  30. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/CODE_OF_CONDUCT.md +0 -0
  31. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/CONTRIBUTING.md +0 -0
  32. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/Dockerfile +0 -0
  33. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/Dockerfile.worker +0 -0
  34. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/LICENSE +0 -0
  35. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/NOTICE +0 -0
  36. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/README.md +0 -0
  37. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/SECURITY.md +0 -0
  38. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/SELF_HOSTING.md +0 -0
  39. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/build/kernel_cache/.gitignore +0 -0
  40. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/build/kernel_cache/.keep +0 -0
  41. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/deploy/infisical/README.md +0 -0
  42. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/deploy/infisical/entrypoint.sh +0 -0
  43. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/docker/Dockerfile.kernelcache +0 -0
  44. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/docker/Dockerfile.kernelcache.relayer +0 -0
  45. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/docker/bake_kernel_cache.py +0 -0
  46. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/docker/bake_pod_entry.py +0 -0
  47. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/docker/extract_cudart_fix.py +0 -0
  48. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/docker/kernel_fingerprint.py +0 -0
  49. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/docker/make_rp_handler.py +0 -0
  50. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/__init__.py +0 -0
  51. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/_internal/__init__.py +0 -0
  52. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/_internal/channel.py +0 -0
  53. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/_internal/diagnostics.py +0 -0
  54. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/_internal/fileio.py +0 -0
  55. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/_internal/logging.py +0 -0
  56. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/_internal/paths.py +0 -0
  57. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/adapters/__init__.py +0 -0
  58. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/adapters/artifacts.py +0 -0
  59. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/adapters/fused_experts.py +0 -0
  60. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/adapters/lora_rank.py +0 -0
  61. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/adapters/targets.py +0 -0
  62. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/__init__.py +0 -0
  63. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/__main__.py +0 -0
  64. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/commands/__init__.py +0 -0
  65. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/commands/deploy.py +0 -0
  66. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/commands/env/__init__.py +0 -0
  67. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/commands/env/episode.py +0 -0
  68. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/commands/env/eval.py +0 -0
  69. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/commands/env/eval_args.py +0 -0
  70. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/commands/env/imports.py +0 -0
  71. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/commands/env/list.py +0 -0
  72. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/commands/env/push.py +0 -0
  73. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/commands/env/retained.py +0 -0
  74. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/commands/env/setup.py +0 -0
  75. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/commands/env/setup_wandb.py +0 -0
  76. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/commands/env/test.py +0 -0
  77. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/commands/env/test_evaluations.py +0 -0
  78. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/commands/env/test_params.py +0 -0
  79. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/commands/env/test_warnings.py +0 -0
  80. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/commands/prompt_budget.py +0 -0
  81. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/commands/traces.py +0 -0
  82. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/commands/train_cost.py +0 -0
  83. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/errors.py +0 -0
  84. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/scaffold/TRAINING.md +0 -0
  85. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/scaffold/__init__.py +0 -0
  86. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/ui/__init__.py +0 -0
  87. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/ui/cost.py +0 -0
  88. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/ui/env_panels.py +0 -0
  89. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/ui/heartbeat.py +0 -0
  90. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/ui/render.py +0 -0
  91. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/ui/tables.py +0 -0
  92. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cli/ui/tty.py +0 -0
  93. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/client/__init__.py +0 -0
  94. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/client/config.py +0 -0
  95. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/client/freesolo_api.py +0 -0
  96. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/client/http.py +0 -0
  97. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/client/runtime_secrets.py +0 -0
  98. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/client/shapes.py +0 -0
  99. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/client/specs.py +0 -0
  100. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/client/streaming.py +0 -0
  101. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/content/__init__.py +0 -0
  102. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/content/image_descriptors.py +0 -0
  103. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/content/multimodal.py +0 -0
  104. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/content/structured_outputs.py +0 -0
  105. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/content/thinking.py +0 -0
  106. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/core/__init__.py +0 -0
  107. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/core/catalog.py +0 -0
  108. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/core/grpo.py +0 -0
  109. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/core/spec.py +0 -0
  110. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/core/spec_persistence.py +0 -0
  111. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cost/__init__.py +0 -0
  112. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cost/analytical.py +0 -0
  113. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cost/facts.py +0 -0
  114. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cost/spec.py +0 -0
  115. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/cost/types.py +0 -0
  116. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/__init__.py +0 -0
  117. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/huggingface.py +0 -0
  118. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/plan/__init__.py +0 -0
  119. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/plan/kv_sizing.py +0 -0
  120. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/plan/model_config_probe.py +0 -0
  121. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/plan/prompt_budget.py +0 -0
  122. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/plan/recipe.py +0 -0
  123. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/plan/steps.py +0 -0
  124. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/plan/vram.py +0 -0
  125. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/profiling/__init__.py +0 -0
  126. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/profiling/dataset_profile.py +0 -0
  127. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/profiling/image_tokens.py +0 -0
  128. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/profiling/reasoning_render.py +0 -0
  129. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/profiling/sft_image_rows.py +0 -0
  130. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/profiling/sft_workload.py +0 -0
  131. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/profiling/tokenizer.py +0 -0
  132. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/profiling/workload_profile.py +0 -0
  133. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/result/__init__.py +0 -0
  134. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/result/accounting.py +0 -0
  135. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/result/rollout_samples.py +0 -0
  136. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/__init__.py +0 -0
  137. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/__main__.py +0 -0
  138. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/backend_common.py +0 -0
  139. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/entry/__init__.py +0 -0
  140. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/entry/opd.py +0 -0
  141. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/entry/rl.py +0 -0
  142. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/entry/sft.py +0 -0
  143. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/io/__init__.py +0 -0
  144. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/io/heartbeat.py +0 -0
  145. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/io/hf.py +0 -0
  146. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/io/prefetch.py +0 -0
  147. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/io/wandb_log.py +0 -0
  148. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/model/__init__.py +0 -0
  149. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/model/adapter.py +0 -0
  150. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/model/chatml_mask.py +0 -0
  151. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/model/decoding.py +0 -0
  152. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/model/lora.py +0 -0
  153. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/model/packing.py +0 -0
  154. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/opd_train.py +0 -0
  155. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/opd_train_runner.py +0 -0
  156. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/perf/__init__.py +0 -0
  157. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/perf/diagnostics.py +0 -0
  158. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/perf/lifecycle.py +0 -0
  159. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/perf/liger.py +0 -0
  160. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/perf/memory.py +0 -0
  161. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/rl_train.py +0 -0
  162. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/rl_train_runner.py +0 -0
  163. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/runtime/__init__.py +0 -0
  164. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/runtime/kernel_warmup.py +0 -0
  165. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/runtime/pkg_proxy.py +0 -0
  166. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/runtime/rng.py +0 -0
  167. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/score_batcher.py +0 -0
  168. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/sft_train.py +0 -0
  169. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/sft_train_runner.py +0 -0
  170. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/teacher/__init__.py +0 -0
  171. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/teacher/client.py +0 -0
  172. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/teacher/encoding.py +0 -0
  173. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/teacher/tokenizer_align.py +0 -0
  174. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/__init__.py +0 -0
  175. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/core/__init__.py +0 -0
  176. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/core/checkpoint_lifecycle.py +0 -0
  177. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/core/child/__init__.py +0 -0
  178. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/core/child/glue.py +0 -0
  179. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/core/child/runtime.py +0 -0
  180. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/core/step_timing.py +0 -0
  181. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/finalize.py +0 -0
  182. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/__init__.py +0 -0
  183. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/batching.py +0 -0
  184. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/bridge.py +0 -0
  185. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/bridge_failures.py +0 -0
  186. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/child/__init__.py +0 -0
  187. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/child/bridge.py +0 -0
  188. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/child/entry.py +0 -0
  189. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/child/multiturn.py +0 -0
  190. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/child/plugin.py +0 -0
  191. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/child/replay_guard.py +0 -0
  192. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/child/runtime.py +0 -0
  193. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/child/structured.py +0 -0
  194. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/failures.py +0 -0
  195. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/gkd.py +0 -0
  196. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/multiturn_media.py +0 -0
  197. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/multiturn_validation.py +0 -0
  198. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/overrides.py +0 -0
  199. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/prompts.py +0 -0
  200. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/reporting.py +0 -0
  201. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/scoring.py +0 -0
  202. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/state.py +0 -0
  203. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/validation.py +0 -0
  204. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/__init__.py +0 -0
  205. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/checkpoints.py +0 -0
  206. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/child/__init__.py +0 -0
  207. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/child/entry.py +0 -0
  208. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/child/multiturn.py +0 -0
  209. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/child/patches.py +0 -0
  210. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/child/plugin.py +0 -0
  211. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/config.py +0 -0
  212. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/identity.py +0 -0
  213. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/inputs.py +0 -0
  214. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/multi_turn.py +0 -0
  215. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/reward_module.py +0 -0
  216. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/scoring.py +0 -0
  217. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/single_turn.py +0 -0
  218. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/verl_config.py +0 -0
  219. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/sft/__init__.py +0 -0
  220. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/sft/checkpoints.py +0 -0
  221. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/sft/child/entry.py +0 -0
  222. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/sft/child/plugin.py +0 -0
  223. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/sft/config.py +0 -0
  224. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/verl/__init__.py +0 -0
  225. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/verl/capabilities.py +0 -0
  226. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/verl/checkpoints.py +0 -0
  227. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/verl/child_io.py +0 -0
  228. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/verl/diagnostics.py +0 -0
  229. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/verl/parallelism.py +0 -0
  230. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/verl/parent_work.py +0 -0
  231. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker/verl/process_census.py +0 -0
  232. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/engine/worker_entrypoint.py +0 -0
  233. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/envs/__init__.py +0 -0
  234. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/envs/adapter.py +0 -0
  235. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/envs/base.py +0 -0
  236. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/envs/cache_security.py +0 -0
  237. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/envs/dataset_selection.py +0 -0
  238. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/envs/evaluations.py +0 -0
  239. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/envs/identity.py +0 -0
  240. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/envs/loader.py +0 -0
  241. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/envs/namespace_listing.py +0 -0
  242. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/envs/package/__init__.py +0 -0
  243. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/envs/package/direct_tokens.py +0 -0
  244. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/envs/package/limits.py +0 -0
  245. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/envs/package/unpack.py +0 -0
  246. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/envs/pull.py +0 -0
  247. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/envs/staged.py +0 -0
  248. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/__init__.py +0 -0
  249. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/__init__.py +0 -0
  250. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/auth.py +0 -0
  251. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/bootstrap.py +0 -0
  252. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/bootstrap_console.py +0 -0
  253. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/bootstrap_pip.py +0 -0
  254. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/bootstrap_secrets.py +0 -0
  255. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/deadline.py +0 -0
  256. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/host/__init__.py +0 -0
  257. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/host/deadline_sleep.py +0 -0
  258. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/host/failmark.py +0 -0
  259. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/host/hostlog.py +0 -0
  260. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/http.py +0 -0
  261. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/instance.py +0 -0
  262. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/poll.py +0 -0
  263. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/poll_instance.py +0 -0
  264. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/provider.py +0 -0
  265. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/terminal_artifacts.py +0 -0
  266. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/worker.py +0 -0
  267. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/allocator.py +0 -0
  268. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/artifacts/__init__.py +0 -0
  269. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/artifacts/hf.py +0 -0
  270. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/artifacts/preload_runpod.py +0 -0
  271. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/artifacts/weight_cache.py +0 -0
  272. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/base.py +0 -0
  273. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/fit_errors.py +0 -0
  274. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/lambda_/__init__.py +0 -0
  275. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/lambda_/api.py +0 -0
  276. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/lambda_/auth.py +0 -0
  277. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/lambda_/gpus.py +0 -0
  278. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/lambda_/jobs/__init__.py +0 -0
  279. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/lambda_/jobs/builders.py +0 -0
  280. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/lambda_/jobs/reap.py +0 -0
  281. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/lambda_/preflight.py +0 -0
  282. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/lambda_/pricing.py +0 -0
  283. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/preflight.py +0 -0
  284. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/realized.py +0 -0
  285. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/runpod/__init__.py +0 -0
  286. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/runpod/api.py +0 -0
  287. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/runpod/auth.py +0 -0
  288. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/runpod/cost.py +0 -0
  289. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/runpod/gpus.py +0 -0
  290. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/runpod/job_execution.py +0 -0
  291. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/runpod/jobs.py +0 -0
  292. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/runpod/preflight.py +0 -0
  293. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/runpod/pricing.py +0 -0
  294. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/runpod/resources.py +0 -0
  295. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/runpod/serverless/__init__.py +0 -0
  296. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/runpod/serverless/endpoints.py +0 -0
  297. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/sharding.py +0 -0
  298. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/vast/__init__.py +0 -0
  299. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/vast/api.py +0 -0
  300. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/vast/auth.py +0 -0
  301. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/vast/jobs/__init__.py +0 -0
  302. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/vast/jobs/builders.py +0 -0
  303. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/vast/preflight.py +0 -0
  304. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/providers/vast/pricing.py +0 -0
  305. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/py.typed +0 -0
  306. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/runner/__init__.py +0 -0
  307. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/runner/artifacts.py +0 -0
  308. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/runner/attempts.py +0 -0
  309. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/runner/costs.py +0 -0
  310. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/runner/deadlines.py +0 -0
  311. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/runner/preparation.py +0 -0
  312. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/runner/reconciliation.py +0 -0
  313. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/runner/results/__init__.py +0 -0
  314. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/runner/results/checkpoints.py +0 -0
  315. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/runner/results/verified_revisions.py +0 -0
  316. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/runner/status.py +0 -0
  317. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/runner/submit.py +0 -0
  318. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/runner/supervise/__init__.py +0 -0
  319. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/runner/supervise/attach.py +0 -0
  320. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/runner/supervise/deploy.py +0 -0
  321. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/runner/supervise/lifecycle.py +0 -0
  322. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/runner/supervise/recovery.py +0 -0
  323. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/runner/supervise/retry_decision.py +0 -0
  324. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/runner/supervise/seed_submission.py +0 -0
  325. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/runner/supervise/transitions.py +0 -0
  326. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/runner/weight_cache.py +0 -0
  327. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/runtime_capsule/__init__.py +0 -0
  328. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/runtime_capsule/build.py +0 -0
  329. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/runtime_capsule/manifest.py +0 -0
  330. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/runtime_capsule/profiles.py +0 -0
  331. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/schema/__init__.py +0 -0
  332. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/schema/fields.py +0 -0
  333. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/serve/__init__.py +0 -0
  334. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/serve/adapter_check.py +0 -0
  335. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/serve/deploy.py +0 -0
  336. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/serve/errors.py +0 -0
  337. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/serve/export.py +0 -0
  338. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/serve/preflight.py +0 -0
  339. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/serve/responses.py +0 -0
  340. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/serve/streaming.py +0 -0
  341. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/serve/thinking.py +0 -0
  342. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/serve/urls.py +0 -0
  343. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/__init__.py +0 -0
  344. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/__main__.py +0 -0
  345. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/app.py +0 -0
  346. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/billing/__init__.py +0 -0
  347. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/billing/charges.py +0 -0
  348. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/billing/retry.py +0 -0
  349. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/domain/__init__.py +0 -0
  350. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/domain/checkpoints.py +0 -0
  351. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/domain/environment_registry.py +0 -0
  352. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/domain/envs.py +0 -0
  353. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/domain/projects.py +0 -0
  354. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/domain/reconcile.py +0 -0
  355. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/domain/repo_cleanup.py +0 -0
  356. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/domain/run_registry.py +0 -0
  357. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/domain/teacher_broker.py +0 -0
  358. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/domain/teacher_errors.py +0 -0
  359. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/domain/teacher_requests.py +0 -0
  360. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/platform/__init__.py +0 -0
  361. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/platform/auth.py +0 -0
  362. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/platform/db.py +0 -0
  363. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/platform/deps.py +0 -0
  364. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/platform/internal_client.py +0 -0
  365. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/platform/locks.py +0 -0
  366. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/platform/runtime.py +0 -0
  367. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/routes/__init__.py +0 -0
  368. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/routes/envs.py +0 -0
  369. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/routes/meta.py +0 -0
  370. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/routes/runs.py +0 -0
  371. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/routes/serving.py +0 -0
  372. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/routes/serving_completion.py +0 -0
  373. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/routes/serving_revisions.py +0 -0
  374. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/routes/serving_smoke.py +0 -0
  375. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/server/routes/teacher.py +0 -0
  376. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/source_snapshot.py +0 -0
  377. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/teacher/__init__.py +0 -0
  378. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/teacher/limits.py +0 -0
  379. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/teacher/provider_status.py +0 -0
  380. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/flash/teacher/retry_contract.py +0 -0
  381. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/scripts/build_dev_dist.py +0 -0
  382. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/scripts/check_file_size.py +0 -0
  383. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/scripts/check_function_size.py +0 -0
  384. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/scripts/check_rollout_identity_actor.py +0 -0
  385. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/scripts/check_verl_pin_exists.py +0 -0
  386. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/scripts/scrub_history.sh +0 -0
  387. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/__init__.py +0 -0
  388. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/_helpers/__init__.py +0 -0
  389. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/_helpers/profile.py +0 -0
  390. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/_helpers/runner.py +0 -0
  391. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/_helpers/source_snapshot.py +0 -0
  392. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/_helpers/specs.py +0 -0
  393. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/_helpers/teacher.py +0 -0
  394. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/_helpers/vast.py +0 -0
  395. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/capture_image_sft_processor_oracle.py +0 -0
  396. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/conftest.py +0 -0
  397. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/fixtures/image_sft_processor_oracle.json +0 -0
  398. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/fixtures/qwen35_08b_target_metadata.json +0 -0
  399. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/live/__init__.py +0 -0
  400. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/live/conftest.py +0 -0
  401. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/live/test_lambda_live.py +0 -0
  402. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/live/test_runpod_live.py +0 -0
  403. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/live/test_sft_thinking_render_live.py +0 -0
  404. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/live/test_vast_live.py +0 -0
  405. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_accounting_coverage.py +0 -0
  406. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_adapter_shard_completeness.py +0 -0
  407. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_agent_flash_cli_contract.py +0 -0
  408. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_algorithms.py +0 -0
  409. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_allocator.py +0 -0
  410. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_backend_common.py +0 -0
  411. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_backend_jobspec_contract.py +0 -0
  412. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_bake_kernel_cache.py +0 -0
  413. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_base_model_provenance.py +0 -0
  414. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_billing_retry.py +0 -0
  415. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_build_context_contract.py +0 -0
  416. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_cancel_remote.py +0 -0
  417. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_catalog_consistency.py +0 -0
  418. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_catalog_only_models.py +0 -0
  419. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_charge_pricing.py +0 -0
  420. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_checkpoint_lifecycle.py +0 -0
  421. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_checkpoints.py +0 -0
  422. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_cli_credential_shadowing.py +0 -0
  423. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_cli_errors.py +0 -0
  424. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_cli_estimate.py +0 -0
  425. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_cli_gpus_flag.py +0 -0
  426. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_cli_help.py +0 -0
  427. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_cli_main_coverage.py +0 -0
  428. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_cli_managed.py +0 -0
  429. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_cli_render_coverage.py +0 -0
  430. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_cli_render_theme.py +0 -0
  431. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_cli_traces.py +0 -0
  432. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_cli_wandb_warning.py +0 -0
  433. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_client.py +0 -0
  434. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_client_import_purity.py +0 -0
  435. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_client_server_integration.py +0 -0
  436. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_client_stream_reads.py +0 -0
  437. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_config_env_vars.py +0 -0
  438. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_config_overrides.py +0 -0
  439. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_console_upload.py +0 -0
  440. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_controlled_experiment_repairs.py +0 -0
  441. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_cost_analytical.py +0 -0
  442. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_cost_equation.py +0 -0
  443. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_cost_estimate.py +0 -0
  444. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_cost_hardware.py +0 -0
  445. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_cost_models.py +0 -0
  446. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_dataset_profile.py +0 -0
  447. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_deploy_alias_move_warning.py +0 -0
  448. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_deploy_latency.py +0 -0
  449. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_dev_channel.py +0 -0
  450. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_disk_gb.py +0 -0
  451. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_endpoint_name.py +0 -0
  452. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_env_cache_evict.py +0 -0
  453. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_env_delete.py +0 -0
  454. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_env_download.py +0 -0
  455. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_env_download_api.py +0 -0
  456. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_env_evaluations.py +0 -0
  457. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_env_list_api.py +0 -0
  458. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_env_list_cli.py +0 -0
  459. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_env_list_hub.py +0 -0
  460. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_env_no_install.py +0 -0
  461. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_env_publish.py +0 -0
  462. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_env_pull.py +0 -0
  463. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_env_pull_coverage.py +0 -0
  464. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_env_pull_loader_coverage.py +0 -0
  465. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_env_pull_managed_control_plane.py +0 -0
  466. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_env_push.py +0 -0
  467. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_env_rate_limit_resolve.py +0 -0
  468. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_env_ref_pinning.py +0 -0
  469. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_env_test.py +0 -0
  470. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_envs_coverage.py +0 -0
  471. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_export.py +0 -0
  472. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_flash_mvp.py +0 -0
  473. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_flash_worker.py +0 -0
  474. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_flashinfer_cache_dirs.py +0 -0
  475. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_freesolo_api_transport.py +0 -0
  476. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_fused_expert_warmstart.py +0 -0
  477. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_github_urlopen_retry.py +0 -0
  478. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_gpu_type_single_field.py +0 -0
  479. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_gpus.py +0 -0
  480. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_grpo_params.py +0 -0
  481. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_grpo_process_census.py +0 -0
  482. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_grpo_resident_sizing.py +0 -0
  483. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_grpo_reward_batching.py +0 -0
  484. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_grpo_rollout_contract.py +0 -0
  485. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_grpo_rollout_identity.py +0 -0
  486. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_health_liveness.py +0 -0
  487. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_hf_retry.py +0 -0
  488. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_idle_endpoint_reaper.py +0 -0
  489. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_image_environment_capability.py +0 -0
  490. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_image_incremental_processor.py +0 -0
  491. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_image_sft_markers.py +0 -0
  492. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_image_sft_processor_parity.py +0 -0
  493. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_image_tokens.py +0 -0
  494. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_infisical_secrets.py +0 -0
  495. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_instance_bootstrap_coverage.py +0 -0
  496. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_internal_client.py +0 -0
  497. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_jobs.py +0 -0
  498. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_kernel_cache.py +0 -0
  499. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_kernel_fingerprint.py +0 -0
  500. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_kv_util.py +0 -0
  501. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_lambda_api_coverage.py +0 -0
  502. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_lambda_runner.py +0 -0
  503. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_logging.py +0 -0
  504. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_login_perms.py +0 -0
  505. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_lora_rank_coverage.py +0 -0
  506. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_lora_rank_nested_rung.py +0 -0
  507. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_lora_rank_preflight.py +0 -0
  508. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_lora_targeting.py +0 -0
  509. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_lora_targeting_pinned_verl.py +0 -0
  510. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_managed_config_fields.py +0 -0
  511. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_managed_hf_repo.py +0 -0
  512. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_metrics_schema_agent_contract.py +0 -0
  513. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_mig_guard.py +0 -0
  514. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_multi_gpu_gate.py +0 -0
  515. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_multimodal_training.py +0 -0
  516. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_named_reward_metrics.py +0 -0
  517. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_oom_escalate_gpu.py +0 -0
  518. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_opd.py +0 -0
  519. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_opd_limits.py +0 -0
  520. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_opd_multiturn_eos_boundary.py +0 -0
  521. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_opd_multiturn_failure_exit.py +0 -0
  522. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_opd_replay_guard.py +0 -0
  523. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_opd_resume_safety.py +0 -0
  524. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_opd_train.py +0 -0
  525. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_orchestrator_flash.py +0 -0
  526. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_packing.py +0 -0
  527. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_packing_coverage.py +0 -0
  528. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_parasail_teacher.py +0 -0
  529. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_persisted_spec_envelope.py +0 -0
  530. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_poll_helpers.py +0 -0
  531. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_preflight.py +0 -0
  532. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_projects.py +0 -0
  533. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_prompt_budget.py +0 -0
  534. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_provider_preflight_coverage.py +0 -0
  535. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_provider_routing.py +0 -0
  536. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_provider_teardown_robustness.py +0 -0
  537. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_providers_symmetry.py +0 -0
  538. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_realized_cost.py +0 -0
  539. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_repo_cleanup.py +0 -0
  540. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_resolve_params_b.py +0 -0
  541. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_resume_on_retry.py +0 -0
  542. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_rl_train.py +0 -0
  543. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_rollout_samples.py +0 -0
  544. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_runmgmt.py +0 -0
  545. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_runpod_api_delete.py +0 -0
  546. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_runpod_key_fingerprint.py +0 -0
  547. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_runpod_key_waterfall.py +0 -0
  548. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_runtime_capsule.py +0 -0
  549. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_serve.py +0 -0
  550. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_serve_reasoning_content.py +0 -0
  551. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_server_api.py +0 -0
  552. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_server_app_coverage.py +0 -0
  553. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_server_auth_singleflight.py +0 -0
  554. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_server_billing.py +0 -0
  555. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_server_checkpoints_coverage.py +0 -0
  556. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_server_db.py +0 -0
  557. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_server_envs_coverage.py +0 -0
  558. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_server_locks_coverage.py +0 -0
  559. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_server_standalone.py +0 -0
  560. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_serving_context_preflight.py +0 -0
  561. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_serving_contract.py +0 -0
  562. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_serving_schema_coverage.py +0 -0
  563. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_sft_chunked_nll.py +0 -0
  564. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_sft_example_selection.py +0 -0
  565. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_sft_gc_off.py +0 -0
  566. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_sft_max_context.py +0 -0
  567. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_sft_startup_block.py +0 -0
  568. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_sft_train.py +0 -0
  569. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_sft_workload.py +0 -0
  570. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_source_attestation_flow.py +0 -0
  571. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_source_snapshot.py +0 -0
  572. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_spec_and_validation.py +0 -0
  573. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_spec_contract_bytes.py +0 -0
  574. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_staged_environment.py +0 -0
  575. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_step_floor.py +0 -0
  576. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_step_metrics.py +0 -0
  577. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_step_timing.py +0 -0
  578. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_structured_outputs.py +0 -0
  579. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_teacher_broker.py +0 -0
  580. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_teacher_encoding_contract.py +0 -0
  581. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_terminal_artifacts.py +0 -0
  582. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_thinking_config.py +0 -0
  583. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_train_context_preflight.py +0 -0
  584. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_training_controls.py +0 -0
  585. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_type_comment_prose.py +0 -0
  586. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_vast_api.py +0 -0
  587. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_vast_api_coverage.py +0 -0
  588. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_vast_offers.py +0 -0
  589. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_vast_provider_coverage.py +0 -0
  590. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_vast_runner.py +0 -0
  591. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_verified_revisions.py +0 -0
  592. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_verifiers.py +0 -0
  593. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_verl_checkpoint_export.py +0 -0
  594. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_verl_child_plugins.py +0 -0
  595. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_verl_silence_watchdog.py +0 -0
  596. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_version.py +0 -0
  597. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_vl_warmstart_adapter_keys.py +0 -0
  598. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_vram_architecture.py +0 -0
  599. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_wandb_link.py +0 -0
  600. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_wandb_naming.py +0 -0
  601. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_warmstart_adapter_download.py +0 -0
  602. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_warmstart_cross_repo.py +0 -0
  603. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_warmstart_error_attribution.py +0 -0
  604. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_warmstart_image_adapters.py +0 -0
  605. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_weight_cache.py +0 -0
  606. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_worker_dryrun.py +0 -0
  607. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_worker_hardexit.py +0 -0
  608. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_worker_image.py +0 -0
  609. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_worker_init_heartbeat.py +0 -0
  610. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_worker_stack.py +0 -0
  611. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_worker_thinking.py +0 -0
  612. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_workflow_contracts.py +0 -0
  613. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/tests/test_workload_profile.py +0 -0
  614. {freesolo_flash_dev-1.2.100 → freesolo_flash_dev-1.2.102}/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.100
3
+ Version: 1.2.102
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
@@ -0,0 +1,139 @@
1
+ """Printing the worker-uploaded text artifacts that `flash runs log` appends to a run log.
2
+
3
+ These sections are NOT part of the chronological log. `cmd_log` prints the control-plane log first
4
+ and appends these afterwards, so they always land at the tail no matter how old they are -- and the
5
+ plane returns the highest UPLOADED attempt, which during a retry is the attempt that just died, not
6
+ the one now running. Read without a label, the last thing on screen is a traceback from a worker
7
+ that has already been replaced.
8
+
9
+ So the job here is provenance: say which attempt produced each section, and say when that attempt is
10
+ not the live one. The old output is kept rather than hidden because it carries the failure that
11
+ explains why a retry exists at all.
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import re
17
+ from typing import TYPE_CHECKING
18
+
19
+ from flash.cli.ui import render
20
+ from flash.client import ClientError
21
+
22
+ if TYPE_CHECKING:
23
+ from collections.abc import Mapping
24
+
25
+ from flash.client import ApiClient
26
+
27
+
28
+ # stands in for the live attempt during the teardown window, when the plane has PROVEN there is no
29
+ # live worker (an explicitly null ``remote``). distinct from ``None``, which means UNKNOWN.
30
+ _NO_LIVE_WORKER = "no-live-worker"
31
+
32
+
33
+ def _artifact_attempt(name: str) -> int | None:
34
+ """Return the bounded attempt encoded by a worker artifact name."""
35
+ from flash.providers._lifecycle.poll import _attempt_int
36
+
37
+ match = re.search(r"_attempt(\d+)\.txt$", name)
38
+ return _attempt_int(int(match.group(1))) if match else None
39
+
40
+
41
+ def _worker_section_name(name: str, current_attempt: int | str | None) -> str:
42
+ """Label an attempt-scoped artifact and identify superseded output."""
43
+ attempt = _artifact_attempt(name)
44
+ if attempt is None:
45
+ return name
46
+ if current_attempt == _NO_LIVE_WORKER:
47
+ return f"{name} (attempt={attempt}, worker torn down; no live attempt)"
48
+ if current_attempt is None:
49
+ return f"{name} (attempt={attempt})"
50
+ if attempt != current_attempt:
51
+ return f"{name} (attempt={attempt}, previous attempt; current attempt={current_attempt})"
52
+ return f"{name} (attempt={attempt}, current attempt)"
53
+
54
+
55
+ _HEARTBEAT_LINE_RE = re.compile(r"(?m)^(HEARTBEAT )(?!\[superseded)")
56
+
57
+
58
+ def _mark_superseded_heartbeats(text: str, attempt: int, current_attempt: int | str) -> str:
59
+ """Tag every HEARTBEAT line in a dead attempt's console dump.
60
+
61
+ The section heading already says which attempt produced this text, but a heading is only read
62
+ by a human looking at the whole screen. The monitoring idiom is
63
+ ``runs log | grep HEARTBEAT | tail -1``, which sees ONE line and no heading -- and because the
64
+ plane appends the highest uploaded attempt after the chronological log, that one line is the
65
+ dead attempt's last heartbeat.
66
+
67
+ That is not merely stale, it inverts the reading: the reporter's monitor showed
68
+ ``step 0, 0 completions, device H200`` for twenty minutes while the run was in fact live on
69
+ B200, because H200 was the card that had already OOMed and been torn down.
70
+
71
+ Tagging the line itself means the provenance survives the pipe. A consumer that filters on the
72
+ tag gets only live heartbeats; one that does not at least sees the attempt in the line it
73
+ printed rather than silently trusting a dead worker's last words.
74
+ """
75
+ current = (
76
+ "worker torn down"
77
+ if current_attempt == _NO_LIVE_WORKER
78
+ else f"current attempt={current_attempt}"
79
+ )
80
+ return _HEARTBEAT_LINE_RE.sub(f"\\1[superseded attempt={attempt}; {current}] ", text)
81
+
82
+
83
+ def _worker_sections(client: ApiClient, run_id: str) -> dict[str, str]:
84
+ """Fetch only worker artifacts with printable text."""
85
+ return {name: text for name, text in (client.get_worker_output(run_id) or {}).items() if text}
86
+
87
+
88
+ def _snapshot_live_attempt(client: ApiClient, run_id: str) -> int | str | None:
89
+ """The live attempt, ``_NO_LIVE_WORKER`` during teardown, or ``None`` when unknown.
90
+
91
+ ``live_attempt`` answers ``None`` for two opposite situations: an explicitly null ``remote``,
92
+ which is PROOF the attached heartbeat belongs to a worker that is already gone, and a run whose
93
+ shape carries no attempt at all. Collapsing both to ``None`` disabled heartbeat tagging exactly
94
+ during the retry window the tagging exists for -- the dead attempt's heartbeat went back to
95
+ reaching ``grep HEARTBEAT | tail -1`` unmarked while replacement capacity was still being
96
+ acquired. Keep the two apart so teardown can be labelled as what it is.
97
+
98
+ A lookup failure stays ``None``: not knowing the live attempt must not make this claim there
99
+ is no live worker.
100
+ """
101
+ try:
102
+ run = client.get_run(run_id) or {}
103
+ except ClientError:
104
+ return None
105
+ attempt = render.live_attempt(run)
106
+ if attempt is None and run.get("remote", False) is None:
107
+ return _NO_LIVE_WORKER
108
+ return attempt
109
+
110
+
111
+ def _print_worker_output(
112
+ sections: Mapping[str, str],
113
+ *,
114
+ printed_any: bool = False,
115
+ current_attempt: int | str | None = None,
116
+ ) -> bool:
117
+ """Print worker artifacts under headings naming the attempt that produced them."""
118
+ for name, text in sections.items():
119
+ # label provenance from the filename rather than letting the final section, which is merely
120
+ # the last one appended, read as the live attempt's output.
121
+ section_name = _worker_section_name(name, current_attempt)
122
+ # the heading is invisible to `grep HEARTBEAT | tail -1`, so a superseded attempt's
123
+ # heartbeats carry their own provenance into the pipe. `_NO_LIVE_WORKER` tags every
124
+ # attempt: during teardown the plane has PROVEN no worker is live, so every heartbeat on
125
+ # screen is a dead one and none of them may reach a monitor unmarked.
126
+ attempt = _artifact_attempt(name)
127
+ supersedes = current_attempt is not None and (
128
+ current_attempt == _NO_LIVE_WORKER or attempt != current_attempt
129
+ )
130
+ if attempt is not None and supersedes:
131
+ text = _mark_superseded_heartbeats(text, attempt, current_attempt)
132
+ sep = "\n" if printed_any else ""
133
+ if render.styled():
134
+ print(f"{sep}{render.log_section(section_name)}")
135
+ else:
136
+ print(f"{sep}----- {section_name} -----")
137
+ print(text, end="" if text.endswith("\n") else "\n")
138
+ printed_any = True
139
+ return printed_any
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "freesolo-flash-dev"
3
- version = "1.2.100"
3
+ version = "1.2.102"
4
4
  description ="Flash — managed LoRA post-training (SFT/GRPO/OPD) for Freesolo environments, driven by the `flash` CLI"
5
5
  readme = "README.md"
6
6
  # RunPod Flash supports Python 3.11-3.12 (not 3.13 yet).
@@ -137,7 +137,7 @@ artifacts = ["flash/py.typed"]
137
137
  # auto-published by .github/workflows/publish-dev.yml: a push to `dev` whose version isn't yet on
138
138
  # PyPI publishes it; pushes that don't change it find it already published and no-op. So cutting a
139
139
  # dev-channel release = bump this (and [project].version) and merge to `dev`.
140
- version = "1.2.100"
140
+ version = "1.2.102"
141
141
 
142
142
  [tool.pytest.ini_options]
143
143
  pythonpath = ["."]
@@ -1606,7 +1606,10 @@ def test_log_labels_previous_attempt_artifacts_after_the_live_attempt_log(
1606
1606
  in out
1607
1607
  )
1608
1608
  assert out.index(live_line) < out.index(previous_header)
1609
- assert 'HEARTBEAT {"stage":"rl_step","step":0,"attempt":0' in out
1609
+ # the dead attempt's heartbeat is still printed -- it explains why a retry exists -- but it
1610
+ # carries its provenance inline, because a section heading does not survive
1611
+ # `grep HEARTBEAT | tail -1`.
1612
+ assert 'HEARTBEAT [superseded attempt=0; current attempt=1] {"stage":"rl_step"' in out
1610
1613
 
1611
1614
 
1612
1615
  def test_log_still_prints_artifacts_when_the_attempt_lookup_fails(
@@ -365,3 +365,126 @@ def test_chat_keeps_stdout_empty_when_a_styled_stream_carries_no_text(monkeypatc
365
365
  assert result == 1
366
366
  assert captured.out == ""
367
367
  assert "no response text from flash-1" in captured.err
368
+
369
+
370
+ def test_superseded_attempt_heartbeats_are_tagged_in_the_log_stream(capsys) -> None:
371
+ """`runs log | grep HEARTBEAT | tail -1` must not silently return a dead attempt's heartbeat.
372
+
373
+ The plane appends the highest UPLOADED attempt after the chronological log, so during a retry
374
+ the last heartbeat on screen belongs to the attempt that just died. The section heading says
375
+ so, but a heading does not survive a pipe: the reporter's monitor read
376
+ ``step 0, 0 completions, device H200`` for twenty minutes while the run was live on B200,
377
+ because H200 was the card that had already OOMed and been torn down.
378
+ """
379
+ commands._print_worker_output(
380
+ {
381
+ "console_rl_attempt0.txt": (
382
+ 'HEARTBEAT {"stage":"rl_step","step":76,"attempt":0,"device_name":"H200"}\n'
383
+ "Traceback (most recent call last):\n"
384
+ )
385
+ },
386
+ printed_any=True,
387
+ current_attempt=1,
388
+ )
389
+
390
+ out = capsys.readouterr().out
391
+ lines = [line for line in out.splitlines() if "HEARTBEAT" in line]
392
+ assert lines, "the dead attempt's console dump must still be printed"
393
+ # the stale line carries its own provenance, so it cannot be mistaken for the live attempt
394
+ assert "[superseded attempt=0; current attempt=1]" in lines[-1]
395
+ # and the failure dump itself is preserved -- it is why the retry exists
396
+ assert "Traceback (most recent call last):" in out
397
+
398
+
399
+ def test_filtering_superseded_heartbeats_leaves_the_live_attempt_last(capsys) -> None:
400
+ """A consumer that drops tagged lines gets the LIVE attempt's heartbeat, not the dead one."""
401
+ print('HEARTBEAT {"stage":"rl_step","step":1,"attempt":1,"device_name":"B200"}')
402
+ commands._print_worker_output(
403
+ {
404
+ "console_rl_attempt0.txt": (
405
+ 'HEARTBEAT {"stage":"rl_step","step":76,"attempt":0,"device_name":"H200"}\n'
406
+ )
407
+ },
408
+ printed_any=True,
409
+ current_attempt=1,
410
+ )
411
+
412
+ heartbeats = [line for line in capsys.readouterr().out.splitlines() if "HEARTBEAT" in line]
413
+ live = [line for line in heartbeats if "[superseded" not in line]
414
+ assert live[-1].endswith('{"stage":"rl_step","step":1,"attempt":1,"device_name":"B200"}')
415
+
416
+
417
+ def test_current_attempt_heartbeats_are_left_untouched(capsys) -> None:
418
+ """Only a SUPERSEDED attempt is tagged; the live attempt's own artifact must read normally."""
419
+ commands._print_worker_output(
420
+ {"console_rl_attempt1.txt": 'HEARTBEAT {"stage":"rl_step","step":4,"attempt":1}\n'},
421
+ printed_any=True,
422
+ current_attempt=1,
423
+ )
424
+
425
+ out = capsys.readouterr().out
426
+ assert "[superseded" not in out
427
+
428
+
429
+ def test_teardown_window_still_tags_the_dead_workers_heartbeat(capsys) -> None:
430
+ """An explicitly null ``remote`` is PROOF no worker is live, so every heartbeat is a dead one.
431
+
432
+ ``live_attempt`` answers ``None`` both for "the worker is torn down" and for "no attempt is
433
+ known", and collapsing the two disabled tagging exactly during the retry window the tagging
434
+ exists for -- the dead attempt's heartbeat reached ``grep HEARTBEAT | tail -1`` unmarked while
435
+ replacement capacity was still being acquired.
436
+ """
437
+ from flash.cli.commands.worker_output import _NO_LIVE_WORKER
438
+
439
+ commands._print_worker_output(
440
+ {
441
+ "console_rl_attempt0.txt": (
442
+ 'HEARTBEAT {"stage":"rl_step","step":76,"attempt":0,"device_name":"H200"}\n'
443
+ )
444
+ },
445
+ printed_any=True,
446
+ current_attempt=_NO_LIVE_WORKER,
447
+ )
448
+
449
+ out = capsys.readouterr().out
450
+ lines = [line for line in out.splitlines() if "HEARTBEAT" in line]
451
+ assert lines, "the dead attempt's console dump must still be printed"
452
+ assert "[superseded attempt=0; worker torn down]" in lines[-1], (
453
+ f"a torn-down worker's heartbeat reached the pipe unmarked: {lines[-1]}"
454
+ )
455
+ assert "worker torn down; no live attempt" in out, "the heading must say so too"
456
+
457
+
458
+ def test_snapshot_distinguishes_teardown_from_an_unknown_attempt() -> None:
459
+ """``remote: null`` means torn down; a failed lookup means unknown. They are not the same."""
460
+ from flash.cli.commands.worker_output import _NO_LIVE_WORKER, _snapshot_live_attempt
461
+ from flash.client import ClientError
462
+
463
+ class _Run:
464
+ def __init__(self, payload):
465
+ self._payload = payload
466
+
467
+ def get_run(self, _run_id):
468
+ if isinstance(self._payload, Exception):
469
+ raise self._payload
470
+ return self._payload
471
+
472
+ torn_down = {"state": "running", "remote": None, "last_heartbeat": {"attempt": 0}}
473
+ assert _snapshot_live_attempt(_Run(torn_down), "flash-1") == _NO_LIVE_WORKER
474
+ live = {"state": "running", "remote": {"attempt": 1}, "last_heartbeat": {"attempt": 0}}
475
+ assert _snapshot_live_attempt(_Run(live), "flash-1") == 1
476
+ # a lookup failure must NOT claim there is no live worker
477
+ assert _snapshot_live_attempt(_Run(ClientError("boom")), "flash-1") is None
478
+ # nor must a payload that simply carries no remote key
479
+ no_remote = {"state": "running", "last_heartbeat": {"attempt": 0}}
480
+ assert _snapshot_live_attempt(_Run(no_remote), "flash-1") == 0
481
+
482
+
483
+ def test_heartbeat_tagging_is_idempotent() -> None:
484
+ """Re-printing an already-tagged dump must not stack a second marker onto the line."""
485
+ from flash.cli.commands.worker_output import _mark_superseded_heartbeats
486
+
487
+ once = _mark_superseded_heartbeats('HEARTBEAT {"step":1}\n', 0, 1)
488
+ twice = _mark_superseded_heartbeats(once, 0, 1)
489
+ assert once == twice
490
+ assert once.count("[superseded") == 1
@@ -1052,7 +1052,7 @@ wheels = [
1052
1052
 
1053
1053
  [[package]]
1054
1054
  name = "freesolo-flash"
1055
- version = "1.2.100"
1055
+ version = "1.2.102"
1056
1056
  source = { editable = "." }
1057
1057
 
1058
1058
  [package.optional-dependencies]
@@ -1,76 +0,0 @@
1
- """Printing the worker-uploaded text artifacts that `flash runs log` appends to a run log.
2
-
3
- These sections are NOT part of the chronological log. `cmd_log` prints the control-plane log first
4
- and appends these afterwards, so they always land at the tail no matter how old they are -- and the
5
- plane returns the highest UPLOADED attempt, which during a retry is the attempt that just died, not
6
- the one now running. Read without a label, the last thing on screen is a traceback from a worker
7
- that has already been replaced.
8
-
9
- So the job here is provenance: say which attempt produced each section, and say when that attempt is
10
- not the live one. The old output is kept rather than hidden because it carries the failure that
11
- explains why a retry exists at all.
12
- """
13
-
14
- from __future__ import annotations
15
-
16
- import re
17
- from typing import TYPE_CHECKING
18
-
19
- from flash.cli.ui import render
20
- from flash.client import ClientError
21
-
22
- if TYPE_CHECKING:
23
- from collections.abc import Mapping
24
-
25
- from flash.client import ApiClient
26
-
27
-
28
- def _artifact_attempt(name: str) -> int | None:
29
- """Return the bounded attempt encoded by a worker artifact name."""
30
- from flash.providers._lifecycle.poll import _attempt_int
31
-
32
- match = re.search(r"_attempt(\d+)\.txt$", name)
33
- return _attempt_int(int(match.group(1))) if match else None
34
-
35
-
36
- def _worker_section_name(name: str, current_attempt: int | None) -> str:
37
- """Label an attempt-scoped artifact and identify superseded output."""
38
- attempt = _artifact_attempt(name)
39
- if attempt is None:
40
- return name
41
- if current_attempt is None:
42
- return f"{name} (attempt={attempt})"
43
- if attempt != current_attempt:
44
- return f"{name} (attempt={attempt}, previous attempt; current attempt={current_attempt})"
45
- return f"{name} (attempt={attempt}, current attempt)"
46
-
47
-
48
- def _worker_sections(client: ApiClient, run_id: str) -> dict[str, str]:
49
- """Fetch only worker artifacts with printable text."""
50
- return {name: text for name, text in (client.get_worker_output(run_id) or {}).items() if text}
51
-
52
-
53
- def _snapshot_live_attempt(client: ApiClient, run_id: str) -> int | None:
54
- """Read the live attempt without letting a heading lookup hide diagnostic artifacts."""
55
- try:
56
- return render.live_attempt(client.get_run(run_id) or {})
57
- except ClientError:
58
- return None
59
-
60
-
61
- def _print_worker_output(
62
- sections: Mapping[str, str], *, printed_any: bool = False, current_attempt: int | None = None
63
- ) -> bool:
64
- """Print worker artifacts under headings naming the attempt that produced them."""
65
- for name, text in sections.items():
66
- # label provenance from the filename rather than letting the final section, which is merely
67
- # the last one appended, read as the live attempt's output.
68
- section_name = _worker_section_name(name, current_attempt)
69
- sep = "\n" if printed_any else ""
70
- if render.styled():
71
- print(f"{sep}{render.log_section(section_name)}")
72
- else:
73
- print(f"{sep}----- {section_name} -----")
74
- print(text, end="" if text.endswith("\n") else "\n")
75
- printed_any = True
76
- return printed_any