freesolo-flash-dev 1.2.70__tar.gz → 1.2.88__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 (602) hide show
  1. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/Dockerfile.worker +12 -5
  2. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/PKG-INFO +1 -1
  3. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/adapters/fused_experts.py +30 -28
  4. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cli/scaffold/TRAINING.md +5 -0
  5. freesolo_flash_dev-1.2.88/flash/content/image_descriptors.py +363 -0
  6. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/content/multimodal.py +261 -240
  7. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/core/spec.py +88 -7
  8. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/plan/vram.py +28 -2
  9. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/profiling/image_tokens.py +16 -10
  10. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/__init__.py +36 -10
  11. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/backend_common.py +1 -0
  12. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/entry/sft.py +2 -2
  13. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/opd_train.py +37 -8
  14. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/opd_train_runner.py +73 -3
  15. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/perf/__init__.py +4 -3
  16. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/rl_train.py +5 -2
  17. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/rl_train_runner.py +6 -0
  18. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/sft_train.py +18 -4
  19. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/sft_train_runner.py +7 -1
  20. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/core/child/glue.py +455 -30
  21. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/core/child/runtime.py +34 -0
  22. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/bridge.py +126 -99
  23. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/child/bridge.py +167 -2
  24. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/child/multiturn.py +62 -22
  25. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/child/replay_guard.py +12 -0
  26. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/failures.py +8 -0
  27. freesolo_flash_dev-1.2.88/flash/engine/worker/train/opd/multiturn_media.py +129 -0
  28. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/overrides.py +11 -2
  29. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/prompts.py +8 -6
  30. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/scoring.py +11 -9
  31. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/state.py +2 -0
  32. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/rl/child/multiturn.py +127 -74
  33. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/rl/child/patches.py +6 -24
  34. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/rl/inputs.py +10 -8
  35. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/rl/multi_turn.py +243 -87
  36. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/rl/verl_config.py +11 -2
  37. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/sft/checkpoints.py +13 -7
  38. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/sft/child/plugin.py +4 -2
  39. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/verl/capabilities.py +35 -4
  40. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/envs/adapter.py +3 -0
  41. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/envs/base.py +4 -1
  42. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/envs/identity.py +12 -0
  43. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/envs/loader.py +114 -23
  44. freesolo_flash_dev-1.2.88/flash/envs/staged.py +490 -0
  45. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/bootstrap.py +2 -0
  46. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/bootstrap_pip.py +1 -0
  47. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/worker.py +2 -4
  48. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/runpod/serverless/endpoints.py +3 -0
  49. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/runner/__init__.py +1 -5
  50. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/runner/artifacts.py +114 -5
  51. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/runner/preparation.py +50 -11
  52. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/runner/submit.py +1 -2
  53. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/runner/supervise/attach.py +27 -1
  54. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/runner/supervise/lifecycle.py +52 -52
  55. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/runner/supervise/seed_submission.py +1 -12
  56. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/schema/__init__.py +3 -3
  57. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/serve/deploy.py +6 -0
  58. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/platform/deps.py +4 -6
  59. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/routes/serving_revisions.py +21 -1
  60. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/routes/serving_smoke.py +160 -26
  61. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/pyproject.toml +2 -2
  62. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_controlled_experiment_repairs.py +34 -0
  63. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_dataset_profile.py +1 -1
  64. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_env_evaluations.py +23 -0
  65. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_env_rate_limit_resolve.py +15 -23
  66. freesolo_flash_dev-1.2.88/tests/test_env_ref_pinning.py +73 -0
  67. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_flash_worker.py +19 -6
  68. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_fused_expert_warmstart.py +148 -21
  69. freesolo_flash_dev-1.2.88/tests/test_image_environment_capability.py +92 -0
  70. freesolo_flash_dev-1.2.88/tests/test_image_incremental_processor.py +583 -0
  71. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_image_tokens.py +10 -15
  72. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_jobs.py +1 -0
  73. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_lambda_runner.py +19 -7
  74. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_multi_gpu_gate.py +103 -0
  75. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_multimodal_training.py +404 -21
  76. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_opd.py +173 -8
  77. freesolo_flash_dev-1.2.88/tests/test_opd_multiturn_failure_exit.py +449 -0
  78. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_opd_replay_guard.py +24 -1
  79. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_opd_train.py +542 -15
  80. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_persisted_spec_envelope.py +2 -1
  81. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_provider_routing.py +46 -40
  82. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_rl_train.py +714 -59
  83. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_serve.py +34 -0
  84. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_server_api.py +25 -4
  85. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_server_billing.py +10 -9
  86. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_server_envs_coverage.py +472 -14
  87. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_sft_train.py +105 -1
  88. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_spec_and_validation.py +232 -0
  89. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_spec_contract_bytes.py +2 -1
  90. freesolo_flash_dev-1.2.88/tests/test_staged_environment.py +914 -0
  91. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_teacher_broker.py +0 -10
  92. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_verifiers.py +1 -1
  93. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_verl_checkpoint_export.py +67 -0
  94. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_warmstart_adapter_download.py +43 -0
  95. freesolo_flash_dev-1.2.88/tests/test_warmstart_image_adapters.py +223 -0
  96. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_worker_stack.py +80 -21
  97. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/uv.lock +7 -7
  98. freesolo_flash_dev-1.2.70/tests/test_env_ref_pinning.py +0 -313
  99. freesolo_flash_dev-1.2.70/tests/test_opd_multiturn_failure_exit.py +0 -170
  100. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/.dockerignore +0 -0
  101. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/.env.example +0 -0
  102. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/.github/CODEOWNERS +0 -0
  103. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  104. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  105. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  106. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  107. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/.github/dependabot.yml +0 -0
  108. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/.github/workflows/auto-rebake.yml +0 -0
  109. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/.github/workflows/bake-kernel-cache.yml +0 -0
  110. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/.github/workflows/ci.yml +0 -0
  111. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/.github/workflows/dev-kernel-cache.yml +0 -0
  112. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/.github/workflows/main-source-guard.yml +0 -0
  113. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/.github/workflows/notify-tests-repo.yml +0 -0
  114. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/.github/workflows/production-kernel-cache-ready.yml +0 -0
  115. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/.github/workflows/publish-dev.yml +0 -0
  116. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/.github/workflows/publish-image.yml +0 -0
  117. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/.github/workflows/publish.yml +0 -0
  118. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/.github/workflows/version-parity.yml +0 -0
  119. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/.github/workflows/worker-image.yml +0 -0
  120. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/.gitignore +0 -0
  121. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/CHANGELOG.md +0 -0
  122. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/CODE_OF_CONDUCT.md +0 -0
  123. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/CONTRIBUTING.md +0 -0
  124. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/Dockerfile +0 -0
  125. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/LICENSE +0 -0
  126. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/NOTICE +0 -0
  127. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/README.md +0 -0
  128. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/SECURITY.md +0 -0
  129. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/SELF_HOSTING.md +0 -0
  130. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/build/kernel_cache/.gitignore +0 -0
  131. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/build/kernel_cache/.keep +0 -0
  132. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/deploy/infisical/README.md +0 -0
  133. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/deploy/infisical/entrypoint.sh +0 -0
  134. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/docker/Dockerfile.kernelcache +0 -0
  135. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/docker/Dockerfile.kernelcache.relayer +0 -0
  136. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/docker/bake_kernel_cache.py +0 -0
  137. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/docker/bake_pod_entry.py +0 -0
  138. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/docker/extract_cudart_fix.py +0 -0
  139. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/docker/kernel_fingerprint.py +0 -0
  140. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/docker/make_rp_handler.py +0 -0
  141. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/__init__.py +0 -0
  142. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/_internal/__init__.py +0 -0
  143. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/_internal/channel.py +0 -0
  144. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/_internal/diagnostics.py +0 -0
  145. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/_internal/fileio.py +0 -0
  146. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/_internal/logging.py +0 -0
  147. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/_internal/paths.py +0 -0
  148. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/adapters/__init__.py +0 -0
  149. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/adapters/artifacts.py +0 -0
  150. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/adapters/lora_rank.py +0 -0
  151. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cli/__init__.py +0 -0
  152. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cli/__main__.py +0 -0
  153. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cli/commands/__init__.py +0 -0
  154. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cli/commands/deploy.py +0 -0
  155. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cli/commands/env/__init__.py +0 -0
  156. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cli/commands/env/episode.py +0 -0
  157. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cli/commands/env/eval.py +0 -0
  158. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cli/commands/env/eval_args.py +0 -0
  159. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cli/commands/env/imports.py +0 -0
  160. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cli/commands/env/list.py +0 -0
  161. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cli/commands/env/push.py +0 -0
  162. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cli/commands/env/retained.py +0 -0
  163. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cli/commands/env/setup.py +0 -0
  164. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cli/commands/env/setup_wandb.py +0 -0
  165. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cli/commands/env/test.py +0 -0
  166. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cli/commands/env/test_evaluations.py +0 -0
  167. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cli/commands/env/test_params.py +0 -0
  168. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cli/commands/env/test_warnings.py +0 -0
  169. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cli/commands/prompt_budget.py +0 -0
  170. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cli/commands/traces.py +0 -0
  171. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cli/commands/train_cost.py +0 -0
  172. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cli/scaffold/__init__.py +0 -0
  173. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cli/ui/__init__.py +0 -0
  174. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cli/ui/cost.py +0 -0
  175. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cli/ui/env_panels.py +0 -0
  176. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cli/ui/heartbeat.py +0 -0
  177. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cli/ui/render.py +0 -0
  178. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cli/ui/tables.py +0 -0
  179. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cli/ui/tty.py +0 -0
  180. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/client/__init__.py +0 -0
  181. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/client/config.py +0 -0
  182. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/client/freesolo_api.py +0 -0
  183. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/client/http.py +0 -0
  184. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/client/runtime_secrets.py +0 -0
  185. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/client/shapes.py +0 -0
  186. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/client/specs.py +0 -0
  187. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/client/streaming.py +0 -0
  188. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/content/__init__.py +0 -0
  189. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/content/structured_outputs.py +0 -0
  190. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/content/thinking.py +0 -0
  191. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/core/__init__.py +0 -0
  192. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/core/catalog.py +0 -0
  193. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/core/spec_persistence.py +0 -0
  194. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cost/__init__.py +0 -0
  195. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cost/analytical.py +0 -0
  196. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cost/facts.py +0 -0
  197. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cost/spec.py +0 -0
  198. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/cost/types.py +0 -0
  199. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/__init__.py +0 -0
  200. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/huggingface.py +0 -0
  201. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/plan/__init__.py +0 -0
  202. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/plan/kv_sizing.py +0 -0
  203. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/plan/model_config_probe.py +0 -0
  204. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/plan/prompt_budget.py +0 -0
  205. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/plan/recipe.py +0 -0
  206. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/plan/steps.py +0 -0
  207. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/profiling/__init__.py +0 -0
  208. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/profiling/dataset_profile.py +0 -0
  209. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/profiling/reasoning_render.py +0 -0
  210. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/profiling/sft_image_rows.py +0 -0
  211. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/profiling/sft_workload.py +0 -0
  212. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/profiling/tokenizer.py +0 -0
  213. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/profiling/workload_profile.py +0 -0
  214. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/result/__init__.py +0 -0
  215. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/result/accounting.py +0 -0
  216. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/result/rollout_samples.py +0 -0
  217. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/__main__.py +0 -0
  218. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/entry/__init__.py +0 -0
  219. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/entry/opd.py +0 -0
  220. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/entry/rl.py +0 -0
  221. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/io/__init__.py +0 -0
  222. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/io/heartbeat.py +0 -0
  223. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/io/hf.py +0 -0
  224. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/io/prefetch.py +0 -0
  225. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/io/wandb_log.py +0 -0
  226. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/model/__init__.py +0 -0
  227. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/model/adapter.py +0 -0
  228. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/model/chatml_mask.py +0 -0
  229. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/model/decoding.py +0 -0
  230. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/model/lora.py +0 -0
  231. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/model/packing.py +0 -0
  232. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/perf/diagnostics.py +0 -0
  233. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/perf/lifecycle.py +0 -0
  234. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/perf/liger.py +0 -0
  235. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/perf/memory.py +0 -0
  236. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/runtime/__init__.py +0 -0
  237. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/runtime/kernel_warmup.py +0 -0
  238. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/runtime/pkg_proxy.py +0 -0
  239. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/runtime/rng.py +0 -0
  240. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/score_batcher.py +0 -0
  241. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/teacher/__init__.py +0 -0
  242. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/teacher/client.py +0 -0
  243. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/teacher/encoding.py +0 -0
  244. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/teacher/tokenizer_align.py +0 -0
  245. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/__init__.py +0 -0
  246. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/core/__init__.py +0 -0
  247. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/core/checkpoint_lifecycle.py +0 -0
  248. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/core/child/__init__.py +0 -0
  249. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/core/step_timing.py +0 -0
  250. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/finalize.py +0 -0
  251. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/__init__.py +0 -0
  252. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/batching.py +0 -0
  253. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/bridge_failures.py +0 -0
  254. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/child/__init__.py +0 -0
  255. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/child/entry.py +0 -0
  256. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/child/plugin.py +0 -0
  257. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/child/runtime.py +0 -0
  258. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/child/structured.py +0 -0
  259. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/gkd.py +0 -0
  260. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/multiturn_validation.py +0 -0
  261. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/reporting.py +0 -0
  262. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/validation.py +0 -0
  263. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/rl/__init__.py +0 -0
  264. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/rl/checkpoints.py +0 -0
  265. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/rl/child/__init__.py +0 -0
  266. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/rl/child/entry.py +0 -0
  267. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/rl/child/plugin.py +0 -0
  268. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/rl/config.py +0 -0
  269. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/rl/reward_module.py +0 -0
  270. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/rl/scoring.py +0 -0
  271. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/rl/single_turn.py +0 -0
  272. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/sft/__init__.py +0 -0
  273. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/sft/child/entry.py +0 -0
  274. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/sft/config.py +0 -0
  275. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/verl/__init__.py +0 -0
  276. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/verl/checkpoints.py +0 -0
  277. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/verl/child_io.py +0 -0
  278. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/verl/diagnostics.py +0 -0
  279. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/verl/parallelism.py +0 -0
  280. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker/verl/parent_work.py +0 -0
  281. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/engine/worker_entrypoint.py +0 -0
  282. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/envs/__init__.py +0 -0
  283. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/envs/cache_security.py +0 -0
  284. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/envs/dataset_selection.py +0 -0
  285. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/envs/evaluations.py +0 -0
  286. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/envs/namespace_listing.py +0 -0
  287. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/envs/package/__init__.py +0 -0
  288. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/envs/package/direct_tokens.py +0 -0
  289. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/envs/package/limits.py +0 -0
  290. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/envs/package/unpack.py +0 -0
  291. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/envs/pull.py +0 -0
  292. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/__init__.py +0 -0
  293. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/__init__.py +0 -0
  294. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/auth.py +0 -0
  295. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/bootstrap_console.py +0 -0
  296. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/bootstrap_secrets.py +0 -0
  297. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/deadline.py +0 -0
  298. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/host/__init__.py +0 -0
  299. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/host/deadline_sleep.py +0 -0
  300. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/host/failmark.py +0 -0
  301. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/host/hostlog.py +0 -0
  302. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/http.py +0 -0
  303. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/instance.py +0 -0
  304. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/poll.py +0 -0
  305. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/poll_instance.py +0 -0
  306. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/provider.py +0 -0
  307. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/terminal_artifacts.py +0 -0
  308. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/allocator.py +0 -0
  309. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/artifacts/__init__.py +0 -0
  310. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/artifacts/hf.py +0 -0
  311. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/artifacts/preload_runpod.py +0 -0
  312. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/artifacts/weight_cache.py +0 -0
  313. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/base.py +0 -0
  314. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/fit_errors.py +0 -0
  315. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/lambda_/__init__.py +0 -0
  316. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/lambda_/api.py +0 -0
  317. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/lambda_/auth.py +0 -0
  318. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/lambda_/gpus.py +0 -0
  319. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/lambda_/jobs/__init__.py +0 -0
  320. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/lambda_/jobs/builders.py +0 -0
  321. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/lambda_/jobs/reap.py +0 -0
  322. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/lambda_/preflight.py +0 -0
  323. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/lambda_/pricing.py +0 -0
  324. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/preflight.py +0 -0
  325. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/realized.py +0 -0
  326. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/runpod/__init__.py +0 -0
  327. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/runpod/api.py +0 -0
  328. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/runpod/auth.py +0 -0
  329. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/runpod/cost.py +0 -0
  330. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/runpod/gpus.py +0 -0
  331. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/runpod/job_execution.py +0 -0
  332. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/runpod/jobs.py +0 -0
  333. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/runpod/preflight.py +0 -0
  334. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/runpod/pricing.py +0 -0
  335. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/runpod/resources.py +0 -0
  336. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/runpod/serverless/__init__.py +0 -0
  337. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/sharding.py +0 -0
  338. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/vast/__init__.py +0 -0
  339. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/vast/api.py +0 -0
  340. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/vast/auth.py +0 -0
  341. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/vast/jobs/__init__.py +0 -0
  342. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/vast/jobs/builders.py +0 -0
  343. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/vast/preflight.py +0 -0
  344. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/providers/vast/pricing.py +0 -0
  345. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/py.typed +0 -0
  346. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/runner/attempts.py +0 -0
  347. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/runner/costs.py +0 -0
  348. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/runner/deadlines.py +0 -0
  349. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/runner/reconciliation.py +0 -0
  350. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/runner/results/__init__.py +0 -0
  351. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/runner/results/checkpoints.py +0 -0
  352. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/runner/results/verified_revisions.py +0 -0
  353. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/runner/status.py +0 -0
  354. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/runner/supervise/__init__.py +0 -0
  355. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/runner/supervise/deploy.py +0 -0
  356. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/runner/supervise/recovery.py +0 -0
  357. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/runner/supervise/retry_decision.py +0 -0
  358. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/runner/supervise/transitions.py +0 -0
  359. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/runner/weight_cache.py +0 -0
  360. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/runtime_capsule/__init__.py +0 -0
  361. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/runtime_capsule/build.py +0 -0
  362. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/runtime_capsule/manifest.py +0 -0
  363. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/runtime_capsule/profiles.py +0 -0
  364. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/schema/fields.py +0 -0
  365. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/serve/__init__.py +0 -0
  366. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/serve/adapter_check.py +0 -0
  367. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/serve/errors.py +0 -0
  368. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/serve/export.py +0 -0
  369. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/serve/preflight.py +0 -0
  370. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/serve/responses.py +0 -0
  371. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/serve/streaming.py +0 -0
  372. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/serve/thinking.py +0 -0
  373. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/serve/urls.py +0 -0
  374. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/__init__.py +0 -0
  375. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/__main__.py +0 -0
  376. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/app.py +0 -0
  377. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/billing/__init__.py +0 -0
  378. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/billing/charges.py +0 -0
  379. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/billing/retry.py +0 -0
  380. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/domain/__init__.py +0 -0
  381. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/domain/checkpoints.py +0 -0
  382. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/domain/environment_registry.py +0 -0
  383. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/domain/envs.py +0 -0
  384. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/domain/projects.py +0 -0
  385. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/domain/reconcile.py +0 -0
  386. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/domain/repo_cleanup.py +0 -0
  387. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/domain/run_registry.py +0 -0
  388. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/domain/teacher_broker.py +0 -0
  389. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/domain/teacher_errors.py +0 -0
  390. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/domain/teacher_requests.py +0 -0
  391. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/platform/__init__.py +0 -0
  392. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/platform/auth.py +0 -0
  393. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/platform/db.py +0 -0
  394. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/platform/internal_client.py +0 -0
  395. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/platform/locks.py +0 -0
  396. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/platform/runtime.py +0 -0
  397. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/routes/__init__.py +0 -0
  398. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/routes/envs.py +0 -0
  399. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/routes/meta.py +0 -0
  400. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/routes/runs.py +0 -0
  401. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/routes/serving.py +0 -0
  402. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/routes/serving_completion.py +0 -0
  403. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/server/routes/teacher.py +0 -0
  404. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/source_snapshot.py +0 -0
  405. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/teacher/__init__.py +0 -0
  406. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/teacher/limits.py +0 -0
  407. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/flash/teacher/retry_contract.py +0 -0
  408. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/scripts/build_dev_dist.py +0 -0
  409. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/scripts/check_file_size.py +0 -0
  410. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/scripts/check_function_size.py +0 -0
  411. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/scripts/check_verl_pin_exists.py +0 -0
  412. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/scripts/scrub_history.sh +0 -0
  413. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/__init__.py +0 -0
  414. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/_helpers/__init__.py +0 -0
  415. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/_helpers/profile.py +0 -0
  416. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/_helpers/runner.py +0 -0
  417. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/_helpers/source_snapshot.py +0 -0
  418. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/_helpers/specs.py +0 -0
  419. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/_helpers/teacher.py +0 -0
  420. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/_helpers/vast.py +0 -0
  421. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/capture_image_sft_processor_oracle.py +0 -0
  422. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/conftest.py +0 -0
  423. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/fixtures/image_sft_processor_oracle.json +0 -0
  424. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/fixtures/math_eval.jsonl +0 -0
  425. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/fixtures/math_train.jsonl +0 -0
  426. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/live/__init__.py +0 -0
  427. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/live/conftest.py +0 -0
  428. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/live/test_lambda_live.py +0 -0
  429. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/live/test_runpod_live.py +0 -0
  430. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/live/test_sft_thinking_render_live.py +0 -0
  431. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/live/test_vast_live.py +0 -0
  432. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_accounting_coverage.py +0 -0
  433. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_adapter_shard_completeness.py +0 -0
  434. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_agent_flash_cli_contract.py +0 -0
  435. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_algorithms.py +0 -0
  436. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_allocator.py +0 -0
  437. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_backend_common.py +0 -0
  438. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_backend_jobspec_contract.py +0 -0
  439. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_bake_kernel_cache.py +0 -0
  440. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_base_model_provenance.py +0 -0
  441. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_billing_retry.py +0 -0
  442. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_build_context_contract.py +0 -0
  443. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_cancel_remote.py +0 -0
  444. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_catalog_consistency.py +0 -0
  445. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_catalog_only_models.py +0 -0
  446. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_charge_pricing.py +0 -0
  447. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_checkpoint_lifecycle.py +0 -0
  448. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_checkpoints.py +0 -0
  449. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_cli_commands.py +0 -0
  450. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_cli_commands_coverage.py +0 -0
  451. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_cli_credential_shadowing.py +0 -0
  452. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_cli_errors.py +0 -0
  453. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_cli_estimate.py +0 -0
  454. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_cli_gpus_flag.py +0 -0
  455. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_cli_help.py +0 -0
  456. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_cli_main_coverage.py +0 -0
  457. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_cli_managed.py +0 -0
  458. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_cli_render_coverage.py +0 -0
  459. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_cli_render_theme.py +0 -0
  460. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_cli_traces.py +0 -0
  461. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_cli_wandb_warning.py +0 -0
  462. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_client.py +0 -0
  463. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_client_import_purity.py +0 -0
  464. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_client_server_integration.py +0 -0
  465. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_client_stream_reads.py +0 -0
  466. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_config_env_vars.py +0 -0
  467. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_config_overrides.py +0 -0
  468. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_console_upload.py +0 -0
  469. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_cost_analytical.py +0 -0
  470. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_cost_equation.py +0 -0
  471. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_cost_estimate.py +0 -0
  472. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_cost_hardware.py +0 -0
  473. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_cost_models.py +0 -0
  474. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_deploy_alias_move_warning.py +0 -0
  475. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_deploy_latency.py +0 -0
  476. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_dev_channel.py +0 -0
  477. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_disk_gb.py +0 -0
  478. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_endpoint_name.py +0 -0
  479. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_env_cache_evict.py +0 -0
  480. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_env_delete.py +0 -0
  481. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_env_download.py +0 -0
  482. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_env_download_api.py +0 -0
  483. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_env_list_api.py +0 -0
  484. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_env_list_cli.py +0 -0
  485. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_env_list_hub.py +0 -0
  486. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_env_no_install.py +0 -0
  487. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_env_publish.py +0 -0
  488. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_env_pull.py +0 -0
  489. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_env_pull_coverage.py +0 -0
  490. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_env_pull_loader_coverage.py +0 -0
  491. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_env_pull_managed_control_plane.py +0 -0
  492. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_env_push.py +0 -0
  493. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_env_test.py +0 -0
  494. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_envs_coverage.py +0 -0
  495. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_export.py +0 -0
  496. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_flash_mvp.py +0 -0
  497. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_flashinfer_cache_dirs.py +0 -0
  498. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_freesolo_api_transport.py +0 -0
  499. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_github_urlopen_retry.py +0 -0
  500. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_gpu_type_single_field.py +0 -0
  501. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_gpus.py +0 -0
  502. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_grpo_params.py +0 -0
  503. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_grpo_resident_sizing.py +0 -0
  504. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_grpo_reward_batching.py +0 -0
  505. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_health_liveness.py +0 -0
  506. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_hf_retry.py +0 -0
  507. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_idle_endpoint_reaper.py +0 -0
  508. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_image_sft_markers.py +0 -0
  509. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_image_sft_processor_parity.py +0 -0
  510. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_infisical_secrets.py +0 -0
  511. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_instance_bootstrap_coverage.py +0 -0
  512. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_internal_client.py +0 -0
  513. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_kernel_cache.py +0 -0
  514. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_kernel_fingerprint.py +0 -0
  515. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_kv_util.py +0 -0
  516. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_lambda_api_coverage.py +0 -0
  517. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_logging.py +0 -0
  518. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_login_perms.py +0 -0
  519. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_lora_rank_coverage.py +0 -0
  520. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_lora_rank_preflight.py +0 -0
  521. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_managed_config_fields.py +0 -0
  522. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_managed_hf_repo.py +0 -0
  523. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_metrics_schema_agent_contract.py +0 -0
  524. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_mig_guard.py +0 -0
  525. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_named_reward_metrics.py +0 -0
  526. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_oom_escalate_gpu.py +0 -0
  527. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_opd_limits.py +0 -0
  528. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_opd_multiturn_eos_boundary.py +0 -0
  529. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_opd_resume_safety.py +0 -0
  530. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_orchestrator_flash.py +0 -0
  531. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_packing.py +0 -0
  532. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_packing_coverage.py +0 -0
  533. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_parasail_teacher.py +0 -0
  534. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_poll_helpers.py +0 -0
  535. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_preflight.py +0 -0
  536. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_projects.py +0 -0
  537. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_prompt_budget.py +0 -0
  538. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_provider_preflight_coverage.py +0 -0
  539. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_provider_teardown_robustness.py +0 -0
  540. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_providers_symmetry.py +0 -0
  541. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_realized_cost.py +0 -0
  542. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_repo_cleanup.py +0 -0
  543. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_resolve_params_b.py +0 -0
  544. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_resume_on_retry.py +0 -0
  545. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_rollout_samples.py +0 -0
  546. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_runmgmt.py +0 -0
  547. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_runpod_api_delete.py +0 -0
  548. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_runpod_key_fingerprint.py +0 -0
  549. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_runpod_key_waterfall.py +0 -0
  550. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_runtime_capsule.py +0 -0
  551. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_serve_reasoning_content.py +0 -0
  552. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_server_app_coverage.py +0 -0
  553. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_server_auth_singleflight.py +0 -0
  554. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_server_checkpoints_coverage.py +0 -0
  555. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_server_db.py +0 -0
  556. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_server_locks_coverage.py +0 -0
  557. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_server_standalone.py +0 -0
  558. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_serving_context_preflight.py +0 -0
  559. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_serving_contract.py +0 -0
  560. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_serving_schema_coverage.py +0 -0
  561. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_sft_chunked_nll.py +0 -0
  562. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_sft_example_selection.py +0 -0
  563. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_sft_gc_off.py +0 -0
  564. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_sft_max_context.py +0 -0
  565. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_sft_startup_block.py +0 -0
  566. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_sft_workload.py +0 -0
  567. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_source_attestation_flow.py +0 -0
  568. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_source_snapshot.py +0 -0
  569. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_step_floor.py +0 -0
  570. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_step_metrics.py +0 -0
  571. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_step_timing.py +0 -0
  572. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_structured_outputs.py +0 -0
  573. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_teacher_encoding_contract.py +0 -0
  574. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_terminal_artifacts.py +0 -0
  575. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_thinking_config.py +0 -0
  576. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_train_context_preflight.py +0 -0
  577. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_training_controls.py +0 -0
  578. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_type_comment_prose.py +0 -0
  579. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_vast_api.py +0 -0
  580. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_vast_api_coverage.py +0 -0
  581. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_vast_offers.py +0 -0
  582. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_vast_provider_coverage.py +0 -0
  583. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_vast_runner.py +0 -0
  584. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_verified_revisions.py +0 -0
  585. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_verl_child_plugins.py +0 -0
  586. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_verl_silence_watchdog.py +0 -0
  587. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_version.py +0 -0
  588. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_vl_warmstart_adapter_keys.py +0 -0
  589. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_vram_architecture.py +0 -0
  590. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_wandb_link.py +0 -0
  591. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_wandb_naming.py +0 -0
  592. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_warmstart_cross_repo.py +0 -0
  593. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_warmstart_error_attribution.py +0 -0
  594. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_weight_cache.py +0 -0
  595. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_worker_dryrun.py +0 -0
  596. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_worker_hardexit.py +0 -0
  597. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_worker_image.py +0 -0
  598. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_worker_init_heartbeat.py +0 -0
  599. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_worker_thinking.py +0 -0
  600. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_workflow_contracts.py +0 -0
  601. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_workload_profile.py +0 -0
  602. {freesolo_flash_dev-1.2.70 → freesolo_flash_dev-1.2.88}/tests/test_zero2_sharding_gate.py +0 -0
@@ -59,15 +59,15 @@ RUN pip install --no-cache-dir \
59
59
  "wandb>=0.17" \
60
60
  "flash-linear-attention @ git+https://github.com/fla-org/flash-linear-attention.git@9c8e42e762fce087c27b673af4922795d9edb85e" \
61
61
  "flash-qla==0.1.2" \
62
- "tilelang==0.1.11" \
63
- "apache-tvm-ffi==0.1.11" \
62
+ "tilelang==0.1.9" \
63
+ "apache-tvm-ffi==0.1.9" \
64
64
  "hf_transfer" \
65
65
  "freesolo>=0.4.1" \
66
66
  "runpod"
67
67
  # Gated-DeltaNet (Qwen3.5/3.6) runs on flash-linear-attention's Triton kernels. On consumer cards
68
68
  # (Ampere/Ada/Blackwell) the Triton path is correct. On Hopper (sm90) fla's GDN chunk_bwd is
69
69
  # miscomputed with Triton>=3.4 (fla #640) — the fix is fla's TILELANG backend (correct there), so
70
- # we bake the pinned tilelang==0.1.11 + apache-tvm-ffi==0.1.11 (0.1.12 double-registers TVM-FFI ->
70
+ # we bake the pinned tilelang==0.1.9 + apache-tvm-ffi==0.1.9 (0.1.12 double-registers TVM-FFI ->
71
71
  # `import tilelang` aborts) and KEEP fla on every arch; flash.engine.worker.perf._ensure_fla_fastpath_on_hopper
72
72
  # ensures the tilelang backend is live on sm90 before any model import. The INVERSE holds on
73
73
  # B200/sm100: THERE the tilelang chunk_bwd_dqkwg miscomputes gradients while the Triton path is
@@ -79,6 +79,13 @@ RUN pip install --no-cache-dir \
79
79
  # seq16384 12.6x / 1.9x, loss matches to 1.8e-4. fla is from git: the PyPI wheel is a broken stub
80
80
  # (no fla.modules). The git URL is PINNED to a commit (not the moving default branch) for
81
81
  # reproducible image builds; keep this sha in lockstep with the worker dependencies in flash/providers/_lifecycle/worker.py.
82
+ # tilelang is 0.1.9, not the newest release: flash-qla (added for the sm90 GDN backend) hard-requires
83
+ # tilelang==0.1.9 AND apache-tvm-ffi==0.1.9, so 0.1.11 made this layer unsatisfiable and every image
84
+ # build failed from 2026-08-12 until the downgrade. 0.1.11 was only ever "latest stable at the time"
85
+ # (the pin exists for determinism, not to dodge a 0.1.9 defect), and the version predates flash-qla.
86
+ # Keep all four sites in lockstep -- both installs here, capabilities.py, and perf's TILELANG_PIN --
87
+ # because perf fails CLOSED: a resolved version != TILELANG_PIN deletes fla and drops sm90 to the
88
+ # pure-PyTorch fallback, which is correct but far slower.
82
89
 
83
90
  # FlashAttention: PREFER a prebuilt wheel. There is no OFFICIAL Dao-AILab wheel for torch 2.10 yet,
84
91
  # but community CI publishes matching wheels (cu128/torch2.10/cp312); CI passes one as FLASH_ATTN_SPEC
@@ -334,8 +341,8 @@ RUN printf '%s\n' "numpy==2.2.6" "xgrammar==0.1.25" "vllm==0.19.1" "transformers
334
341
  cachetools uvicorn fastapi torchvision tqdm pyarrow \
335
342
  "flash-linear-attention @ git+https://github.com/fla-org/flash-linear-attention.git@9c8e42e762fce087c27b673af4922795d9edb85e" \
336
343
  "flash-qla==0.1.2" \
337
- "tilelang==0.1.11" \
338
- "apache-tvm-ffi==0.1.11" \
344
+ "tilelang==0.1.9" \
345
+ "apache-tvm-ffi==0.1.9" \
339
346
  && rm -f /tmp/verl-overrides.txt \
340
347
  && uv cache clean
341
348
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: freesolo-flash-dev
3
- Version: 1.2.70
3
+ Version: 1.2.88
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
@@ -14,6 +14,8 @@ from flash.adapters.lora_rank import (
14
14
  )
15
15
  from flash.core.catalog import get_model
16
16
 
17
+ _LORA_FACTOR_PATTERN = re.compile(r"\.lora_[AB]\.")
18
+ _LORA_PARAMETER = "weight"
17
19
  _QWEN36_MODEL_ID = "Qwen/Qwen3.6-35B-A3B"
18
20
  _QWEN36_EXPERT_TARGET_PARAMETERS = (
19
21
  "mlp.experts.gate_up_proj",
@@ -31,7 +33,7 @@ _FUSED_EXPERT_SYNTHETIC_MODULES = frozenset({"experts", "base_layer"})
31
33
  _FUSED_EXPERT_WRAPPER_MODULES = ("mlp.experts", "mlp.experts.base_layer")
32
34
  _INVALID_FUSED_LOCATION = object()
33
35
 
34
- _LoraTensor = tuple[str, str, str, str, tuple[int, ...]]
36
+ _LoraTensor = tuple[str, str, str, tuple[int, ...]]
35
37
  _LoraPair = tuple[tuple[int, ...], tuple[int, ...]]
36
38
 
37
39
 
@@ -166,12 +168,13 @@ def has_complete_fused_expert_tensors(
166
168
  expected = _expected_fused_expert_rungs(config, model_id)
167
169
  if expected is None:
168
170
  return False
171
+ lora_keys = {key: shape for key, shape in tensors.items() if _LORA_FACTOR_PATTERN.search(key)}
169
172
  parsed = [
170
173
  tensor
171
- for key, shape in tensors.items()
174
+ for key, shape in lora_keys.items()
172
175
  if (tensor := _parse_lora_tensor(key, shape)) is not None
173
176
  ]
174
- if len({adapter_name for _, _, adapter_name, _, _ in parsed}) != 1:
177
+ if len(parsed) != len(lora_keys):
175
178
  return False
176
179
  return _has_complete_fused_rungs(parsed, expected, model_id) and _has_ordinary_evidence(
177
180
  parsed, config, expected
@@ -179,7 +182,17 @@ def has_complete_fused_expert_tensors(
179
182
 
180
183
 
181
184
  def _parse_lora_tensor(key: str, shape: tuple[int, ...]) -> _LoraTensor | None:
182
- """Parse one canonical PEFT LoRA tensor key."""
185
+ """Parse one canonical PEFT LoRA tensor key.
186
+
187
+ Accept exactly the grammar PEFT writes: a bare ``lora_A.weight`` leaf with no adapter
188
+ namespace. ``get_peft_model_state_dict`` documents stripping the namespace on save, verl's
189
+ merger reproduces that strip, and ``_insert_adapter_name_into_state_dict`` re-inserts it on
190
+ load, so the stripped form is the only spelling that round-trips. Verified against peft 0.19.1:
191
+ ``...lora_A.weight`` loads as ``...lora_A.default.weight`` and matches the live module, while a
192
+ file that already carries the namespace loads as ``...lora_A.default.default.weight`` and
193
+ matches nothing. Since one grammar is accepted, the adapter namespace is no longer part of the
194
+ parsed identity.
195
+ """
183
196
  matches = [
184
197
  (factor, infix) for factor, infix in (("A", ".lora_A."), ("B", ".lora_B.")) if infix in key
185
198
  ]
@@ -187,13 +200,9 @@ def _parse_lora_tensor(key: str, shape: tuple[int, ...]) -> _LoraTensor | None:
187
200
  return None
188
201
  factor, infix = matches[0]
189
202
  module_path, _, leaf = key.partition(infix)
190
- leaf_parts = leaf.split(".")
191
- if not module_path or len(leaf_parts) != 2:
203
+ if not module_path or module_path.endswith(".") or leaf != _LORA_PARAMETER:
192
204
  return None
193
- adapter_name, parameter = leaf_parts
194
- if not adapter_name or parameter != "weight":
195
- return None
196
- return module_path, factor, adapter_name, key, shape
205
+ return module_path, factor, key, shape
197
206
 
198
207
 
199
208
  def _expected_fused_expert_rungs(
@@ -237,31 +246,25 @@ def _expected_fused_expert_rungs(
237
246
  def _has_complete_fused_rungs(
238
247
  tensors: list[_LoraTensor], expected: Mapping[str, Mapping[str, _LoraPair]], model_id: str
239
248
  ) -> bool:
240
- """Validate every concrete fused owner, rung, namespace, and factor shape."""
249
+ """Validate every concrete fused owner, rung, and factor shape."""
241
250
  model = get_model(model_id)
242
251
  for owner, expected_rungs in expected.items():
243
- factors: dict[str, dict[str, dict[str, dict[str, tuple[int, ...]]]]] = {}
244
- for module_path, factor, adapter_name, _key, shape in tensors:
252
+ factors: dict[str, dict[str, dict[str, tuple[int, ...]]]] = {}
253
+ for module_path, factor, _key, shape in tensors:
245
254
  location = _fused_tensor_location(module_path, owner, frozenset(expected_rungs))
246
255
  if location is _INVALID_FUSED_LOCATION:
247
256
  return False
248
257
  if location is None:
249
258
  continue
250
259
  instance, rung = location
251
- factors.setdefault(instance, {}).setdefault(rung, {}).setdefault(adapter_name, {})[
252
- factor
253
- ] = shape
260
+ factors.setdefault(instance, {}).setdefault(rung, {})[factor] = shape
254
261
  if not factors:
255
262
  return False
256
263
  for seen_rungs in factors.values():
257
264
  if set(seen_rungs) != set(expected_rungs):
258
265
  return False
259
266
  for rung, expected_pair in expected_rungs.items():
260
- namespaces = seen_rungs[rung]
261
- if len(namespaces) != 1:
262
- return False
263
- seen_factors = next(iter(namespaces.values()))
264
- if _lora_pair_shapes(seen_factors) != expected_pair:
267
+ if _lora_pair_shapes(seen_rungs[rung]) != expected_pair:
265
268
  return False
266
269
  expert_layers = {
267
270
  prefix
@@ -303,28 +306,27 @@ def _has_ordinary_evidence(
303
306
  config: Mapping[str, Any],
304
307
  fused_rungs: Mapping[str, Mapping[str, _LoraPair]],
305
308
  ) -> bool:
306
- """Validate concrete ordinary target evidence with per-module ranks and namespaces."""
309
+ """Validate concrete ordinary target evidence with per-module ranks."""
307
310
  modules = config.get("target_modules")
308
311
  all_linear = modules == "all-linear"
309
312
  targets = () if all_linear else tuple(modules) if isinstance(modules, list) else ()
310
- groups: dict[str, dict[str, dict[str, tuple[str, tuple[int, ...]]]]] = {}
313
+ groups: dict[str, dict[str, tuple[str, tuple[int, ...]]]] = {}
311
314
  evidence: set[str] = set()
312
- for module_path, factor, adapter_name, key, shape in tensors:
315
+ for module_path, factor, key, shape in tensors:
313
316
  if _is_fused_rung(module_path, fused_rungs):
314
317
  continue
315
318
  matched = tuple(target for target in targets if _anchored_suffix_match(module_path, target))
316
319
  if not all_linear and not matched:
317
320
  continue
318
321
  evidence.update(matched)
319
- groups.setdefault(module_path, {}).setdefault(adapter_name, {})[factor] = (key, shape)
322
+ groups.setdefault(module_path, {})[factor] = (key, shape)
320
323
  if not groups or (not all_linear and evidence != set(targets)):
321
324
  return False
322
325
 
323
326
  declared = declared_lora_ranks(config)
324
- for module_path, namespaces in groups.items():
325
- if len(namespaces) != 1 or _rank_for_module(module_path, declared) is None:
327
+ for module_path, factors in groups.items():
328
+ if _rank_for_module(module_path, declared) is None:
326
329
  return False
327
- factors = next(iter(namespaces.values()))
328
330
  if set(factors) != {"A", "B"}:
329
331
  return False
330
332
  for key, shape in factors.values():
@@ -140,6 +140,11 @@ def load_environment(**kwargs) -> MyEnv:
140
140
  For tool use, dialogue, or games, subclass `EnvironmentMultiTurn` instead and drive the
141
141
  conversation across turns. The reward is the same `RewardResult` contract either way.
142
142
 
143
+ If the environment class can return image-bearing user observations from `step_episode`, declare
144
+ `image_observations = True` on that class. This is a class capability, not a TOML setting: Flash uses
145
+ it to reject a text-only model or OPD teacher before model work. Set it only for environments that
146
+ can actually emit images. The capability does not by itself enable per-turn image rollout wiring.
147
+
143
148
  ### 2. Publish the environment
144
149
 
145
150
  A managed run references a **published** environment by id — so push your folder first:
@@ -0,0 +1,363 @@
1
+ """bounded parsing and validation for managed image descriptors."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import base64
6
+ import binascii
7
+ import io
8
+ import json
9
+ import re
10
+ import warnings
11
+ from collections.abc import Callable
12
+ from dataclasses import dataclass
13
+ from pathlib import Path
14
+ from typing import Any
15
+
16
+ _EXIF_ORIENTATION_TAG = 274
17
+ _EXIF_TRANSPOSED_ORIENTATIONS = frozenset({5, 6, 7, 8})
18
+ _MIME_TO_FORMAT = {
19
+ "image/jpeg": "JPEG",
20
+ "image/png": "PNG",
21
+ "image/webp": "WEBP",
22
+ }
23
+ _FORMAT_TO_MIME = {image_format: mime for mime, image_format in _MIME_TO_FORMAT.items()}
24
+ _DATA_URI_RE = re.compile(r"\Adata:(image/[^;,]+);base64,(.*)\Z", re.DOTALL)
25
+ _MODE_BYTES_PER_PIXEL = {
26
+ "1": 1,
27
+ "L": 1,
28
+ "P": 1,
29
+ "I;16": 2,
30
+ "I;16B": 2,
31
+ "I;16L": 2,
32
+ "LA": 2,
33
+ "La": 2,
34
+ "RGB": 3,
35
+ "YCbCr": 3,
36
+ "LAB": 3,
37
+ "HSV": 3,
38
+ "RGBA": 4,
39
+ "RGBa": 4,
40
+ "CMYK": 4,
41
+ "I": 4,
42
+ "F": 4,
43
+ }
44
+ RGB_BYTES_PER_PIXEL = 3
45
+ # decoding one image costs its own buffer plus a transient RGB conversion, so the worst mode
46
+ # sets the bytes-per-pixel a pixel budget has to assume. exported because the per-image pixel cap
47
+ # is derived from it: a cap the decoded-memory guard would always reject is not a limit.
48
+ WORST_BYTES_PER_PIXEL = max(_MODE_BYTES_PER_PIXEL.values()) + 2 * RGB_BYTES_PER_PIXEL
49
+
50
+
51
+ @dataclass(frozen=True)
52
+ class ImageDescriptorLimits:
53
+ max_images: int
54
+ max_source_bytes: int
55
+ max_total_source_bytes: int
56
+ max_width: int
57
+ max_height: int
58
+ max_pixels: int
59
+ max_total_decoded_bytes: int
60
+ max_data_uri_header_bytes: int
61
+ max_descriptor_bytes: int
62
+
63
+
64
+ @dataclass(frozen=True)
65
+ class ValidatedImageDescriptor:
66
+ data: bytes
67
+ data_uri: str
68
+ source_bytes: int
69
+ decoded_peak_bytes: int
70
+ width: int
71
+ height: int
72
+
73
+ @property
74
+ def pixels(self) -> int:
75
+ return self.width * self.height
76
+
77
+
78
+ def descriptor_size(value: str) -> int:
79
+ return len(value.encode("utf-8"))
80
+
81
+
82
+ def descriptor(kind: str, value: str, *, max_descriptor_bytes: int) -> str:
83
+ encoded = json.dumps({"kind": kind, "value": value}, separators=(",", ":"), sort_keys=True)
84
+ size = descriptor_size(encoded)
85
+ if size > max_descriptor_bytes:
86
+ raise ValueError(
87
+ f"encoded image descriptor exceeds the {max_descriptor_bytes}-byte limit ({size} bytes)"
88
+ )
89
+ return encoded
90
+
91
+
92
+ def parse_descriptor(raw: str) -> tuple[str, str]:
93
+ try:
94
+ value = json.loads(raw)
95
+ except (TypeError, json.JSONDecodeError) as exc:
96
+ raise ValueError("invalid internal image descriptor") from exc
97
+ if not isinstance(value, dict) or set(value) != {"kind", "value"}:
98
+ raise ValueError("invalid internal image descriptor")
99
+ kind = value["kind"]
100
+ payload = value["value"]
101
+ if not isinstance(kind, str) or not isinstance(payload, str):
102
+ raise ValueError("invalid internal image descriptor")
103
+ return kind, payload
104
+
105
+
106
+ def check_source_size(size: int, *, max_source_bytes: int) -> None:
107
+ if size > max_source_bytes:
108
+ raise ValueError(f"image source exceeds the {max_source_bytes}-byte limit ({size} bytes)")
109
+
110
+
111
+ def decode_data_uri(uri: str, limits: ImageDescriptorLimits) -> tuple[bytes, str]:
112
+ comma = uri.find(",")
113
+ header = uri if comma < 0 else uri[:comma]
114
+ if len(header.encode("utf-8")) > limits.max_data_uri_header_bytes:
115
+ raise ValueError(
116
+ f"image data URI header exceeds the {limits.max_data_uri_header_bytes}-byte limit"
117
+ )
118
+ match = _DATA_URI_RE.fullmatch(uri)
119
+ if match is None:
120
+ if not uri.startswith("data:"):
121
+ raise ValueError("image source must use a data URI")
122
+ if ";base64," not in uri:
123
+ raise ValueError("image data URI must use base64 encoding")
124
+ raise ValueError("image data URI must use the exact data:image/...;base64,... format")
125
+ mime, payload = match.groups()
126
+ expected_format = _MIME_TO_FORMAT.get(mime)
127
+ if expected_format is None:
128
+ raise ValueError(f"image data URI uses unsupported MIME type {mime!r}")
129
+ max_encoded_size = ((limits.max_source_bytes + 2) // 3) * 4
130
+ if len(payload) > max_encoded_size:
131
+ check_source_size(
132
+ limits.max_source_bytes + 1,
133
+ max_source_bytes=limits.max_source_bytes,
134
+ )
135
+ try:
136
+ data = base64.b64decode(payload, validate=True)
137
+ except (binascii.Error, ValueError) as exc:
138
+ raise ValueError("image data URI contains invalid base64 data") from exc
139
+ check_source_size(len(data), max_source_bytes=limits.max_source_bytes)
140
+ return data, expected_format
141
+
142
+
143
+ def package_image_path(
144
+ value: str, package_root: Path | None, limits: ImageDescriptorLimits
145
+ ) -> Path:
146
+ if package_root is None:
147
+ raise ValueError("relative image paths require an extracted environment package root")
148
+ candidate = Path(value)
149
+ if candidate.is_absolute():
150
+ raise ValueError("image paths must be relative to the environment package root")
151
+ root = package_root.resolve()
152
+ dataset_root = (root / "dataset").resolve()
153
+ resolved = (root / candidate).resolve()
154
+ if resolved != dataset_root and dataset_root not in resolved.parents:
155
+ raise ValueError("image paths must stay inside the environment package dataset/ directory")
156
+ if not resolved.is_file():
157
+ raise ValueError(f"image path does not exist: {value!r}")
158
+ check_source_size(resolved.stat().st_size, max_source_bytes=limits.max_source_bytes)
159
+ return resolved
160
+
161
+
162
+ def validate_dimensions(width: int, height: int, limits: ImageDescriptorLimits) -> int:
163
+ if width <= 0 or height <= 0:
164
+ raise ValueError("image width and height must be positive")
165
+ if width > limits.max_width or height > limits.max_height:
166
+ raise ValueError(
167
+ f"image dimensions {width}x{height} exceed the "
168
+ f"{limits.max_width}x{limits.max_height} limit"
169
+ )
170
+ pixels = width * height
171
+ if pixels > limits.max_pixels:
172
+ raise ValueError(
173
+ f"image has {pixels} pixels, exceeding the {limits.max_pixels}-pixel limit"
174
+ )
175
+ return pixels
176
+
177
+
178
+ def _oriented_dimensions(image: Any, width: int, height: int) -> tuple[int, int]:
179
+ try:
180
+ orientation = image.getexif().get(_EXIF_ORIENTATION_TAG)
181
+ except (AttributeError, TypeError, ValueError, SyntaxError):
182
+ orientation = None
183
+ if orientation in _EXIF_TRANSPOSED_ORIENTATIONS:
184
+ return height, width
185
+ return width, height
186
+
187
+
188
+ def inspect_image_metadata(
189
+ data: bytes,
190
+ limits: ImageDescriptorLimits,
191
+ *,
192
+ expected_format: str | None = None,
193
+ ) -> tuple[int, int, int, str]:
194
+ try:
195
+ from PIL import Image
196
+ except ImportError as exc:
197
+ raise RuntimeError("Pillow is required for multimodal image training") from exc
198
+ try:
199
+ with warnings.catch_warnings():
200
+ warnings.simplefilter("error", Image.DecompressionBombWarning)
201
+ with Image.open(io.BytesIO(data)) as image:
202
+ image_format = str(image.format or "").upper()
203
+ if image_format not in _FORMAT_TO_MIME:
204
+ raise ValueError("image source must be a static PNG, JPEG, or WebP image")
205
+ if expected_format is not None and image_format != expected_format:
206
+ raise ValueError(
207
+ f"image data URI MIME type does not match its {image_format} format"
208
+ )
209
+ if getattr(image, "n_frames", 1) != 1:
210
+ raise ValueError("image source must be a static single-frame image")
211
+ stored_width, stored_height = image.size
212
+ pixels = validate_dimensions(stored_width, stored_height, limits)
213
+ decoded_peak_bytes = pixels * (
214
+ _MODE_BYTES_PER_PIXEL.get(image.mode, 4) + 2 * RGB_BYTES_PER_PIXEL
215
+ )
216
+ image.verify()
217
+ with Image.open(io.BytesIO(data)) as orientation_probe:
218
+ width, height = _oriented_dimensions(
219
+ orientation_probe,
220
+ stored_width,
221
+ stored_height,
222
+ )
223
+ validate_dimensions(width, height, limits)
224
+ return decoded_peak_bytes, width, height, image_format
225
+ except ValueError:
226
+ raise
227
+ except Exception as exc:
228
+ raise ValueError("image source is not a valid image") from exc
229
+
230
+
231
+ def inspect_image_bytes(data: bytes, limits: ImageDescriptorLimits) -> tuple[int, int, int]:
232
+ decoded_peak_bytes, width, height, _image_format = inspect_image_metadata(data, limits)
233
+ return decoded_peak_bytes, width, height
234
+
235
+
236
+ def canonical_data_uri(data: bytes, image_format: str) -> str:
237
+ media_type = _FORMAT_TO_MIME.get(image_format)
238
+ if media_type is None:
239
+ raise ValueError("image source must be a static PNG, JPEG, or WebP image")
240
+ return f"data:{media_type};base64,{base64.b64encode(data).decode('ascii')}"
241
+
242
+
243
+ def descriptor_source_size(
244
+ encoded: str,
245
+ package_root: str | Path | None,
246
+ limits: ImageDescriptorLimits,
247
+ ) -> int:
248
+ kind, value = parse_descriptor(encoded)
249
+ if kind == "bytes":
250
+ return len(base64.b64decode(value, validate=True))
251
+ if kind == "data_uri":
252
+ return len(decode_data_uri(value, limits)[0])
253
+ if kind == "path":
254
+ root = Path(package_root) if package_root else None
255
+ return package_image_path(value, root, limits).stat().st_size
256
+ raise ValueError("invalid internal image descriptor kind")
257
+
258
+
259
+ def read_descriptor_source(
260
+ encoded: str,
261
+ package_root: str | Path | None,
262
+ limits: ImageDescriptorLimits,
263
+ ) -> bytes:
264
+ kind, value = parse_descriptor(encoded)
265
+ if kind == "bytes":
266
+ try:
267
+ data = base64.b64decode(value, validate=True)
268
+ except binascii.Error as exc:
269
+ raise ValueError("invalid internal byte image descriptor") from exc
270
+ elif kind == "data_uri":
271
+ data = decode_data_uri(value, limits)[0]
272
+ elif kind == "path":
273
+ root = Path(package_root) if package_root else None
274
+ data = package_image_path(value, root, limits).read_bytes()
275
+ else:
276
+ raise ValueError("invalid internal image descriptor kind")
277
+ check_source_size(len(data), max_source_bytes=limits.max_source_bytes)
278
+ return data
279
+
280
+
281
+ def validate_image_descriptor_data(
282
+ encoded: str,
283
+ data: bytes,
284
+ limits: ImageDescriptorLimits,
285
+ *,
286
+ decode_pixels: bool,
287
+ pixel_decoder: Callable[[bytes], None],
288
+ ) -> ValidatedImageDescriptor:
289
+ kind, value = parse_descriptor(encoded)
290
+ expected_format = decode_data_uri(value, limits)[1] if kind == "data_uri" else None
291
+ decoded_peak_bytes, width, height, image_format = inspect_image_metadata(
292
+ data,
293
+ limits,
294
+ expected_format=expected_format,
295
+ )
296
+ if decode_pixels:
297
+ pixel_decoder(data)
298
+ return ValidatedImageDescriptor(
299
+ data=data,
300
+ data_uri=canonical_data_uri(data, image_format),
301
+ source_bytes=len(data),
302
+ decoded_peak_bytes=decoded_peak_bytes,
303
+ width=width,
304
+ height=height,
305
+ )
306
+
307
+
308
+ def validate_image_descriptor(
309
+ encoded: str,
310
+ package_root: str | Path | None,
311
+ limits: ImageDescriptorLimits,
312
+ *,
313
+ decode_pixels: bool,
314
+ pixel_decoder: Callable[[bytes], None],
315
+ ) -> ValidatedImageDescriptor:
316
+ data = read_descriptor_source(encoded, package_root, limits)
317
+ return validate_image_descriptor_data(
318
+ encoded,
319
+ data,
320
+ limits,
321
+ decode_pixels=decode_pixels,
322
+ pixel_decoder=pixel_decoder,
323
+ )
324
+
325
+
326
+ def validate_image_descriptors(
327
+ descriptors: list[str] | tuple[str, ...],
328
+ package_root: str | Path | None,
329
+ limits: ImageDescriptorLimits,
330
+ *,
331
+ pixel_decoder: Callable[[bytes], None],
332
+ ) -> list[ValidatedImageDescriptor]:
333
+ if len(descriptors) > limits.max_images:
334
+ raise ValueError(
335
+ f"example contains {len(descriptors)} images, exceeding the "
336
+ f"{limits.max_images}-image limit"
337
+ )
338
+ validated: list[ValidatedImageDescriptor] = []
339
+ source_bytes = 0
340
+ prior_pixels = 0
341
+ for encoded in descriptors:
342
+ item = validate_image_descriptor(
343
+ encoded,
344
+ package_root,
345
+ limits,
346
+ decode_pixels=False,
347
+ pixel_decoder=pixel_decoder,
348
+ )
349
+ source_bytes += item.source_bytes
350
+ if source_bytes > limits.max_total_source_bytes:
351
+ raise ValueError(
352
+ f"example image sources exceed the {limits.max_total_source_bytes}-byte limit"
353
+ )
354
+ decoded_bytes = RGB_BYTES_PER_PIXEL * prior_pixels + item.decoded_peak_bytes
355
+ if decoded_bytes > limits.max_total_decoded_bytes:
356
+ raise ValueError(
357
+ f"example decoded images exceed the {limits.max_total_decoded_bytes}-byte limit"
358
+ )
359
+ prior_pixels += item.pixels
360
+ validated.append(item)
361
+ for item in validated:
362
+ pixel_decoder(item.data)
363
+ return validated