freesolo-flash-dev 1.2.87__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.87 → freesolo_flash_dev-1.2.88}/PKG-INFO +1 -1
  2. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cli/scaffold/TRAINING.md +5 -0
  3. freesolo_flash_dev-1.2.88/flash/content/image_descriptors.py +363 -0
  4. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/content/multimodal.py +261 -240
  5. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/core/spec.py +88 -7
  6. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/profiling/image_tokens.py +16 -10
  7. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/__init__.py +36 -10
  8. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/entry/sft.py +2 -2
  9. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/opd_train.py +34 -6
  10. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/opd_train_runner.py +73 -3
  11. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/rl_train_runner.py +6 -0
  12. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/sft_train.py +18 -4
  13. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/sft_train_runner.py +7 -1
  14. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/core/child/glue.py +455 -30
  15. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/core/child/runtime.py +34 -0
  16. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/bridge.py +126 -99
  17. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/child/bridge.py +167 -2
  18. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/child/multiturn.py +62 -22
  19. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/child/replay_guard.py +12 -0
  20. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/failures.py +8 -0
  21. freesolo_flash_dev-1.2.88/flash/engine/worker/train/opd/multiturn_media.py +129 -0
  22. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/overrides.py +11 -2
  23. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/prompts.py +8 -6
  24. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/scoring.py +11 -9
  25. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/state.py +2 -0
  26. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/rl/child/multiturn.py +127 -74
  27. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/rl/child/patches.py +6 -24
  28. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/rl/inputs.py +10 -8
  29. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/rl/multi_turn.py +243 -87
  30. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/rl/verl_config.py +11 -2
  31. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/sft/checkpoints.py +13 -7
  32. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/sft/child/plugin.py +4 -2
  33. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/envs/adapter.py +3 -0
  34. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/envs/base.py +4 -1
  35. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/envs/identity.py +12 -0
  36. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/envs/loader.py +114 -23
  37. freesolo_flash_dev-1.2.88/flash/envs/staged.py +490 -0
  38. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/bootstrap.py +2 -0
  39. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/bootstrap_pip.py +1 -0
  40. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/worker.py +2 -4
  41. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/runpod/serverless/endpoints.py +3 -0
  42. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/runner/__init__.py +1 -5
  43. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/runner/artifacts.py +114 -5
  44. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/runner/preparation.py +50 -11
  45. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/runner/submit.py +1 -2
  46. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/runner/supervise/attach.py +27 -1
  47. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/runner/supervise/lifecycle.py +52 -52
  48. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/runner/supervise/seed_submission.py +1 -12
  49. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/schema/__init__.py +3 -3
  50. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/serve/deploy.py +6 -0
  51. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/platform/deps.py +4 -6
  52. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/routes/serving_revisions.py +21 -1
  53. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/routes/serving_smoke.py +160 -26
  54. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/pyproject.toml +2 -2
  55. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_controlled_experiment_repairs.py +34 -0
  56. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_dataset_profile.py +1 -1
  57. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_env_evaluations.py +23 -0
  58. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_env_rate_limit_resolve.py +15 -23
  59. freesolo_flash_dev-1.2.88/tests/test_env_ref_pinning.py +73 -0
  60. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_flash_worker.py +19 -6
  61. freesolo_flash_dev-1.2.88/tests/test_image_environment_capability.py +92 -0
  62. freesolo_flash_dev-1.2.88/tests/test_image_incremental_processor.py +583 -0
  63. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_image_tokens.py +10 -15
  64. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_jobs.py +1 -0
  65. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_lambda_runner.py +19 -7
  66. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_multimodal_training.py +404 -21
  67. freesolo_flash_dev-1.2.88/tests/test_opd_multiturn_failure_exit.py +449 -0
  68. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_opd_replay_guard.py +24 -1
  69. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_opd_train.py +542 -15
  70. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_persisted_spec_envelope.py +2 -1
  71. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_provider_routing.py +46 -40
  72. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_rl_train.py +714 -59
  73. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_serve.py +34 -0
  74. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_server_api.py +25 -4
  75. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_server_billing.py +10 -9
  76. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_server_envs_coverage.py +472 -14
  77. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_sft_train.py +105 -1
  78. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_spec_and_validation.py +232 -0
  79. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_spec_contract_bytes.py +2 -1
  80. freesolo_flash_dev-1.2.88/tests/test_staged_environment.py +914 -0
  81. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_teacher_broker.py +0 -10
  82. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_verifiers.py +1 -1
  83. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_verl_checkpoint_export.py +67 -0
  84. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_warmstart_adapter_download.py +43 -0
  85. freesolo_flash_dev-1.2.88/tests/test_warmstart_image_adapters.py +223 -0
  86. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/uv.lock +7 -7
  87. freesolo_flash_dev-1.2.87/tests/test_env_ref_pinning.py +0 -313
  88. freesolo_flash_dev-1.2.87/tests/test_opd_multiturn_failure_exit.py +0 -170
  89. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/.dockerignore +0 -0
  90. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/.env.example +0 -0
  91. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/.github/CODEOWNERS +0 -0
  92. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  93. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  94. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  95. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  96. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/.github/dependabot.yml +0 -0
  97. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/.github/workflows/auto-rebake.yml +0 -0
  98. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/.github/workflows/bake-kernel-cache.yml +0 -0
  99. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/.github/workflows/ci.yml +0 -0
  100. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/.github/workflows/dev-kernel-cache.yml +0 -0
  101. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/.github/workflows/main-source-guard.yml +0 -0
  102. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/.github/workflows/notify-tests-repo.yml +0 -0
  103. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/.github/workflows/production-kernel-cache-ready.yml +0 -0
  104. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/.github/workflows/publish-dev.yml +0 -0
  105. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/.github/workflows/publish-image.yml +0 -0
  106. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/.github/workflows/publish.yml +0 -0
  107. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/.github/workflows/version-parity.yml +0 -0
  108. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/.github/workflows/worker-image.yml +0 -0
  109. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/.gitignore +0 -0
  110. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/CHANGELOG.md +0 -0
  111. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/CODE_OF_CONDUCT.md +0 -0
  112. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/CONTRIBUTING.md +0 -0
  113. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/Dockerfile +0 -0
  114. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/Dockerfile.worker +0 -0
  115. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/LICENSE +0 -0
  116. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/NOTICE +0 -0
  117. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/README.md +0 -0
  118. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/SECURITY.md +0 -0
  119. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/SELF_HOSTING.md +0 -0
  120. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/build/kernel_cache/.gitignore +0 -0
  121. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/build/kernel_cache/.keep +0 -0
  122. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/deploy/infisical/README.md +0 -0
  123. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/deploy/infisical/entrypoint.sh +0 -0
  124. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/docker/Dockerfile.kernelcache +0 -0
  125. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/docker/Dockerfile.kernelcache.relayer +0 -0
  126. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/docker/bake_kernel_cache.py +0 -0
  127. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/docker/bake_pod_entry.py +0 -0
  128. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/docker/extract_cudart_fix.py +0 -0
  129. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/docker/kernel_fingerprint.py +0 -0
  130. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/docker/make_rp_handler.py +0 -0
  131. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/__init__.py +0 -0
  132. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/_internal/__init__.py +0 -0
  133. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/_internal/channel.py +0 -0
  134. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/_internal/diagnostics.py +0 -0
  135. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/_internal/fileio.py +0 -0
  136. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/_internal/logging.py +0 -0
  137. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/_internal/paths.py +0 -0
  138. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/adapters/__init__.py +0 -0
  139. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/adapters/artifacts.py +0 -0
  140. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/adapters/fused_experts.py +0 -0
  141. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/adapters/lora_rank.py +0 -0
  142. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cli/__init__.py +0 -0
  143. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cli/__main__.py +0 -0
  144. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cli/commands/__init__.py +0 -0
  145. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cli/commands/deploy.py +0 -0
  146. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cli/commands/env/__init__.py +0 -0
  147. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cli/commands/env/episode.py +0 -0
  148. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cli/commands/env/eval.py +0 -0
  149. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cli/commands/env/eval_args.py +0 -0
  150. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cli/commands/env/imports.py +0 -0
  151. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cli/commands/env/list.py +0 -0
  152. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cli/commands/env/push.py +0 -0
  153. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cli/commands/env/retained.py +0 -0
  154. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cli/commands/env/setup.py +0 -0
  155. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cli/commands/env/setup_wandb.py +0 -0
  156. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cli/commands/env/test.py +0 -0
  157. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cli/commands/env/test_evaluations.py +0 -0
  158. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cli/commands/env/test_params.py +0 -0
  159. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cli/commands/env/test_warnings.py +0 -0
  160. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cli/commands/prompt_budget.py +0 -0
  161. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cli/commands/traces.py +0 -0
  162. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cli/commands/train_cost.py +0 -0
  163. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cli/scaffold/__init__.py +0 -0
  164. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cli/ui/__init__.py +0 -0
  165. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cli/ui/cost.py +0 -0
  166. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cli/ui/env_panels.py +0 -0
  167. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cli/ui/heartbeat.py +0 -0
  168. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cli/ui/render.py +0 -0
  169. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cli/ui/tables.py +0 -0
  170. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cli/ui/tty.py +0 -0
  171. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/client/__init__.py +0 -0
  172. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/client/config.py +0 -0
  173. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/client/freesolo_api.py +0 -0
  174. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/client/http.py +0 -0
  175. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/client/runtime_secrets.py +0 -0
  176. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/client/shapes.py +0 -0
  177. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/client/specs.py +0 -0
  178. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/client/streaming.py +0 -0
  179. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/content/__init__.py +0 -0
  180. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/content/structured_outputs.py +0 -0
  181. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/content/thinking.py +0 -0
  182. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/core/__init__.py +0 -0
  183. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/core/catalog.py +0 -0
  184. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/core/spec_persistence.py +0 -0
  185. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cost/__init__.py +0 -0
  186. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cost/analytical.py +0 -0
  187. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cost/facts.py +0 -0
  188. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cost/spec.py +0 -0
  189. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/cost/types.py +0 -0
  190. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/__init__.py +0 -0
  191. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/huggingface.py +0 -0
  192. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/plan/__init__.py +0 -0
  193. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/plan/kv_sizing.py +0 -0
  194. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/plan/model_config_probe.py +0 -0
  195. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/plan/prompt_budget.py +0 -0
  196. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/plan/recipe.py +0 -0
  197. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/plan/steps.py +0 -0
  198. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/plan/vram.py +0 -0
  199. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/profiling/__init__.py +0 -0
  200. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/profiling/dataset_profile.py +0 -0
  201. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/profiling/reasoning_render.py +0 -0
  202. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/profiling/sft_image_rows.py +0 -0
  203. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/profiling/sft_workload.py +0 -0
  204. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/profiling/tokenizer.py +0 -0
  205. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/profiling/workload_profile.py +0 -0
  206. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/result/__init__.py +0 -0
  207. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/result/accounting.py +0 -0
  208. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/result/rollout_samples.py +0 -0
  209. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/__main__.py +0 -0
  210. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/backend_common.py +0 -0
  211. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/entry/__init__.py +0 -0
  212. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/entry/opd.py +0 -0
  213. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/entry/rl.py +0 -0
  214. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/io/__init__.py +0 -0
  215. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/io/heartbeat.py +0 -0
  216. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/io/hf.py +0 -0
  217. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/io/prefetch.py +0 -0
  218. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/io/wandb_log.py +0 -0
  219. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/model/__init__.py +0 -0
  220. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/model/adapter.py +0 -0
  221. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/model/chatml_mask.py +0 -0
  222. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/model/decoding.py +0 -0
  223. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/model/lora.py +0 -0
  224. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/model/packing.py +0 -0
  225. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/perf/__init__.py +0 -0
  226. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/perf/diagnostics.py +0 -0
  227. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/perf/lifecycle.py +0 -0
  228. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/perf/liger.py +0 -0
  229. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/perf/memory.py +0 -0
  230. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/rl_train.py +0 -0
  231. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/runtime/__init__.py +0 -0
  232. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/runtime/kernel_warmup.py +0 -0
  233. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/runtime/pkg_proxy.py +0 -0
  234. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/runtime/rng.py +0 -0
  235. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/score_batcher.py +0 -0
  236. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/teacher/__init__.py +0 -0
  237. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/teacher/client.py +0 -0
  238. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/teacher/encoding.py +0 -0
  239. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/teacher/tokenizer_align.py +0 -0
  240. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/__init__.py +0 -0
  241. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/core/__init__.py +0 -0
  242. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/core/checkpoint_lifecycle.py +0 -0
  243. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/core/child/__init__.py +0 -0
  244. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/core/step_timing.py +0 -0
  245. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/finalize.py +0 -0
  246. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/__init__.py +0 -0
  247. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/batching.py +0 -0
  248. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/bridge_failures.py +0 -0
  249. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/child/__init__.py +0 -0
  250. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/child/entry.py +0 -0
  251. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/child/plugin.py +0 -0
  252. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/child/runtime.py +0 -0
  253. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/child/structured.py +0 -0
  254. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/gkd.py +0 -0
  255. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/multiturn_validation.py +0 -0
  256. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/reporting.py +0 -0
  257. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/opd/validation.py +0 -0
  258. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/rl/__init__.py +0 -0
  259. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/rl/checkpoints.py +0 -0
  260. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/rl/child/__init__.py +0 -0
  261. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/rl/child/entry.py +0 -0
  262. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/rl/child/plugin.py +0 -0
  263. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/rl/config.py +0 -0
  264. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/rl/reward_module.py +0 -0
  265. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/rl/scoring.py +0 -0
  266. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/rl/single_turn.py +0 -0
  267. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/sft/__init__.py +0 -0
  268. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/sft/child/entry.py +0 -0
  269. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/train/sft/config.py +0 -0
  270. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/verl/__init__.py +0 -0
  271. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/verl/capabilities.py +0 -0
  272. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/verl/checkpoints.py +0 -0
  273. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/verl/child_io.py +0 -0
  274. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/verl/diagnostics.py +0 -0
  275. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/verl/parallelism.py +0 -0
  276. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker/verl/parent_work.py +0 -0
  277. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/engine/worker_entrypoint.py +0 -0
  278. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/envs/__init__.py +0 -0
  279. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/envs/cache_security.py +0 -0
  280. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/envs/dataset_selection.py +0 -0
  281. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/envs/evaluations.py +0 -0
  282. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/envs/namespace_listing.py +0 -0
  283. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/envs/package/__init__.py +0 -0
  284. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/envs/package/direct_tokens.py +0 -0
  285. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/envs/package/limits.py +0 -0
  286. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/envs/package/unpack.py +0 -0
  287. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/envs/pull.py +0 -0
  288. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/__init__.py +0 -0
  289. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/__init__.py +0 -0
  290. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/auth.py +0 -0
  291. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/bootstrap_console.py +0 -0
  292. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/bootstrap_secrets.py +0 -0
  293. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/deadline.py +0 -0
  294. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/host/__init__.py +0 -0
  295. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/host/deadline_sleep.py +0 -0
  296. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/host/failmark.py +0 -0
  297. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/host/hostlog.py +0 -0
  298. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/http.py +0 -0
  299. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/instance.py +0 -0
  300. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/poll.py +0 -0
  301. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/poll_instance.py +0 -0
  302. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/provider.py +0 -0
  303. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/_lifecycle/terminal_artifacts.py +0 -0
  304. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/allocator.py +0 -0
  305. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/artifacts/__init__.py +0 -0
  306. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/artifacts/hf.py +0 -0
  307. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/artifacts/preload_runpod.py +0 -0
  308. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/artifacts/weight_cache.py +0 -0
  309. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/base.py +0 -0
  310. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/fit_errors.py +0 -0
  311. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/lambda_/__init__.py +0 -0
  312. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/lambda_/api.py +0 -0
  313. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/lambda_/auth.py +0 -0
  314. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/lambda_/gpus.py +0 -0
  315. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/lambda_/jobs/__init__.py +0 -0
  316. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/lambda_/jobs/builders.py +0 -0
  317. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/lambda_/jobs/reap.py +0 -0
  318. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/lambda_/preflight.py +0 -0
  319. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/lambda_/pricing.py +0 -0
  320. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/preflight.py +0 -0
  321. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/realized.py +0 -0
  322. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/runpod/__init__.py +0 -0
  323. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/runpod/api.py +0 -0
  324. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/runpod/auth.py +0 -0
  325. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/runpod/cost.py +0 -0
  326. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/runpod/gpus.py +0 -0
  327. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/runpod/job_execution.py +0 -0
  328. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/runpod/jobs.py +0 -0
  329. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/runpod/preflight.py +0 -0
  330. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/runpod/pricing.py +0 -0
  331. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/runpod/resources.py +0 -0
  332. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/runpod/serverless/__init__.py +0 -0
  333. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/sharding.py +0 -0
  334. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/vast/__init__.py +0 -0
  335. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/vast/api.py +0 -0
  336. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/vast/auth.py +0 -0
  337. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/vast/jobs/__init__.py +0 -0
  338. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/vast/jobs/builders.py +0 -0
  339. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/vast/preflight.py +0 -0
  340. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/providers/vast/pricing.py +0 -0
  341. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/py.typed +0 -0
  342. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/runner/attempts.py +0 -0
  343. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/runner/costs.py +0 -0
  344. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/runner/deadlines.py +0 -0
  345. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/runner/reconciliation.py +0 -0
  346. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/runner/results/__init__.py +0 -0
  347. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/runner/results/checkpoints.py +0 -0
  348. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/runner/results/verified_revisions.py +0 -0
  349. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/runner/status.py +0 -0
  350. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/runner/supervise/__init__.py +0 -0
  351. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/runner/supervise/deploy.py +0 -0
  352. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/runner/supervise/recovery.py +0 -0
  353. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/runner/supervise/retry_decision.py +0 -0
  354. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/runner/supervise/transitions.py +0 -0
  355. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/runner/weight_cache.py +0 -0
  356. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/runtime_capsule/__init__.py +0 -0
  357. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/runtime_capsule/build.py +0 -0
  358. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/runtime_capsule/manifest.py +0 -0
  359. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/runtime_capsule/profiles.py +0 -0
  360. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/schema/fields.py +0 -0
  361. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/serve/__init__.py +0 -0
  362. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/serve/adapter_check.py +0 -0
  363. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/serve/errors.py +0 -0
  364. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/serve/export.py +0 -0
  365. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/serve/preflight.py +0 -0
  366. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/serve/responses.py +0 -0
  367. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/serve/streaming.py +0 -0
  368. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/serve/thinking.py +0 -0
  369. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/serve/urls.py +0 -0
  370. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/__init__.py +0 -0
  371. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/__main__.py +0 -0
  372. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/app.py +0 -0
  373. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/billing/__init__.py +0 -0
  374. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/billing/charges.py +0 -0
  375. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/billing/retry.py +0 -0
  376. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/domain/__init__.py +0 -0
  377. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/domain/checkpoints.py +0 -0
  378. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/domain/environment_registry.py +0 -0
  379. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/domain/envs.py +0 -0
  380. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/domain/projects.py +0 -0
  381. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/domain/reconcile.py +0 -0
  382. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/domain/repo_cleanup.py +0 -0
  383. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/domain/run_registry.py +0 -0
  384. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/domain/teacher_broker.py +0 -0
  385. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/domain/teacher_errors.py +0 -0
  386. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/domain/teacher_requests.py +0 -0
  387. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/platform/__init__.py +0 -0
  388. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/platform/auth.py +0 -0
  389. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/platform/db.py +0 -0
  390. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/platform/internal_client.py +0 -0
  391. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/platform/locks.py +0 -0
  392. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/platform/runtime.py +0 -0
  393. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/routes/__init__.py +0 -0
  394. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/routes/envs.py +0 -0
  395. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/routes/meta.py +0 -0
  396. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/routes/runs.py +0 -0
  397. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/routes/serving.py +0 -0
  398. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/routes/serving_completion.py +0 -0
  399. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/server/routes/teacher.py +0 -0
  400. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/source_snapshot.py +0 -0
  401. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/teacher/__init__.py +0 -0
  402. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/teacher/limits.py +0 -0
  403. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/flash/teacher/retry_contract.py +0 -0
  404. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/scripts/build_dev_dist.py +0 -0
  405. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/scripts/check_file_size.py +0 -0
  406. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/scripts/check_function_size.py +0 -0
  407. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/scripts/check_verl_pin_exists.py +0 -0
  408. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/scripts/scrub_history.sh +0 -0
  409. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/__init__.py +0 -0
  410. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/_helpers/__init__.py +0 -0
  411. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/_helpers/profile.py +0 -0
  412. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/_helpers/runner.py +0 -0
  413. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/_helpers/source_snapshot.py +0 -0
  414. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/_helpers/specs.py +0 -0
  415. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/_helpers/teacher.py +0 -0
  416. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/_helpers/vast.py +0 -0
  417. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/capture_image_sft_processor_oracle.py +0 -0
  418. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/conftest.py +0 -0
  419. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/fixtures/image_sft_processor_oracle.json +0 -0
  420. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/fixtures/math_eval.jsonl +0 -0
  421. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/fixtures/math_train.jsonl +0 -0
  422. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/live/__init__.py +0 -0
  423. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/live/conftest.py +0 -0
  424. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/live/test_lambda_live.py +0 -0
  425. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/live/test_runpod_live.py +0 -0
  426. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/live/test_sft_thinking_render_live.py +0 -0
  427. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/live/test_vast_live.py +0 -0
  428. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_accounting_coverage.py +0 -0
  429. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_adapter_shard_completeness.py +0 -0
  430. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_agent_flash_cli_contract.py +0 -0
  431. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_algorithms.py +0 -0
  432. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_allocator.py +0 -0
  433. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_backend_common.py +0 -0
  434. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_backend_jobspec_contract.py +0 -0
  435. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_bake_kernel_cache.py +0 -0
  436. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_base_model_provenance.py +0 -0
  437. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_billing_retry.py +0 -0
  438. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_build_context_contract.py +0 -0
  439. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_cancel_remote.py +0 -0
  440. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_catalog_consistency.py +0 -0
  441. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_catalog_only_models.py +0 -0
  442. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_charge_pricing.py +0 -0
  443. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_checkpoint_lifecycle.py +0 -0
  444. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_checkpoints.py +0 -0
  445. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_cli_commands.py +0 -0
  446. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_cli_commands_coverage.py +0 -0
  447. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_cli_credential_shadowing.py +0 -0
  448. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_cli_errors.py +0 -0
  449. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_cli_estimate.py +0 -0
  450. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_cli_gpus_flag.py +0 -0
  451. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_cli_help.py +0 -0
  452. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_cli_main_coverage.py +0 -0
  453. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_cli_managed.py +0 -0
  454. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_cli_render_coverage.py +0 -0
  455. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_cli_render_theme.py +0 -0
  456. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_cli_traces.py +0 -0
  457. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_cli_wandb_warning.py +0 -0
  458. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_client.py +0 -0
  459. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_client_import_purity.py +0 -0
  460. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_client_server_integration.py +0 -0
  461. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_client_stream_reads.py +0 -0
  462. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_config_env_vars.py +0 -0
  463. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_config_overrides.py +0 -0
  464. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_console_upload.py +0 -0
  465. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_cost_analytical.py +0 -0
  466. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_cost_equation.py +0 -0
  467. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_cost_estimate.py +0 -0
  468. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_cost_hardware.py +0 -0
  469. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_cost_models.py +0 -0
  470. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_deploy_alias_move_warning.py +0 -0
  471. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_deploy_latency.py +0 -0
  472. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_dev_channel.py +0 -0
  473. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_disk_gb.py +0 -0
  474. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_endpoint_name.py +0 -0
  475. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_env_cache_evict.py +0 -0
  476. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_env_delete.py +0 -0
  477. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_env_download.py +0 -0
  478. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_env_download_api.py +0 -0
  479. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_env_list_api.py +0 -0
  480. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_env_list_cli.py +0 -0
  481. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_env_list_hub.py +0 -0
  482. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_env_no_install.py +0 -0
  483. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_env_publish.py +0 -0
  484. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_env_pull.py +0 -0
  485. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_env_pull_coverage.py +0 -0
  486. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_env_pull_loader_coverage.py +0 -0
  487. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_env_pull_managed_control_plane.py +0 -0
  488. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_env_push.py +0 -0
  489. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_env_test.py +0 -0
  490. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_envs_coverage.py +0 -0
  491. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_export.py +0 -0
  492. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_flash_mvp.py +0 -0
  493. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_flashinfer_cache_dirs.py +0 -0
  494. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_freesolo_api_transport.py +0 -0
  495. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_fused_expert_warmstart.py +0 -0
  496. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_github_urlopen_retry.py +0 -0
  497. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_gpu_type_single_field.py +0 -0
  498. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_gpus.py +0 -0
  499. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_grpo_params.py +0 -0
  500. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_grpo_resident_sizing.py +0 -0
  501. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_grpo_reward_batching.py +0 -0
  502. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_health_liveness.py +0 -0
  503. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_hf_retry.py +0 -0
  504. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_idle_endpoint_reaper.py +0 -0
  505. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_image_sft_markers.py +0 -0
  506. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_image_sft_processor_parity.py +0 -0
  507. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_infisical_secrets.py +0 -0
  508. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_instance_bootstrap_coverage.py +0 -0
  509. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_internal_client.py +0 -0
  510. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_kernel_cache.py +0 -0
  511. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_kernel_fingerprint.py +0 -0
  512. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_kv_util.py +0 -0
  513. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_lambda_api_coverage.py +0 -0
  514. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_logging.py +0 -0
  515. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_login_perms.py +0 -0
  516. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_lora_rank_coverage.py +0 -0
  517. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_lora_rank_preflight.py +0 -0
  518. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_managed_config_fields.py +0 -0
  519. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_managed_hf_repo.py +0 -0
  520. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_metrics_schema_agent_contract.py +0 -0
  521. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_mig_guard.py +0 -0
  522. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_multi_gpu_gate.py +0 -0
  523. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_named_reward_metrics.py +0 -0
  524. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_oom_escalate_gpu.py +0 -0
  525. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_opd.py +0 -0
  526. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_opd_limits.py +0 -0
  527. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_opd_multiturn_eos_boundary.py +0 -0
  528. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_opd_resume_safety.py +0 -0
  529. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_orchestrator_flash.py +0 -0
  530. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_packing.py +0 -0
  531. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_packing_coverage.py +0 -0
  532. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_parasail_teacher.py +0 -0
  533. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_poll_helpers.py +0 -0
  534. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_preflight.py +0 -0
  535. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_projects.py +0 -0
  536. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_prompt_budget.py +0 -0
  537. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_provider_preflight_coverage.py +0 -0
  538. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_provider_teardown_robustness.py +0 -0
  539. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_providers_symmetry.py +0 -0
  540. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_realized_cost.py +0 -0
  541. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_repo_cleanup.py +0 -0
  542. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_resolve_params_b.py +0 -0
  543. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_resume_on_retry.py +0 -0
  544. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_rollout_samples.py +0 -0
  545. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_runmgmt.py +0 -0
  546. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_runpod_api_delete.py +0 -0
  547. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_runpod_key_fingerprint.py +0 -0
  548. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_runpod_key_waterfall.py +0 -0
  549. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_runtime_capsule.py +0 -0
  550. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_serve_reasoning_content.py +0 -0
  551. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_server_app_coverage.py +0 -0
  552. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_server_auth_singleflight.py +0 -0
  553. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_server_checkpoints_coverage.py +0 -0
  554. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_server_db.py +0 -0
  555. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_server_locks_coverage.py +0 -0
  556. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_server_standalone.py +0 -0
  557. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_serving_context_preflight.py +0 -0
  558. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_serving_contract.py +0 -0
  559. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_serving_schema_coverage.py +0 -0
  560. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_sft_chunked_nll.py +0 -0
  561. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_sft_example_selection.py +0 -0
  562. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_sft_gc_off.py +0 -0
  563. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_sft_max_context.py +0 -0
  564. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_sft_startup_block.py +0 -0
  565. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_sft_workload.py +0 -0
  566. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_source_attestation_flow.py +0 -0
  567. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_source_snapshot.py +0 -0
  568. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_step_floor.py +0 -0
  569. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_step_metrics.py +0 -0
  570. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_step_timing.py +0 -0
  571. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_structured_outputs.py +0 -0
  572. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_teacher_encoding_contract.py +0 -0
  573. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_terminal_artifacts.py +0 -0
  574. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_thinking_config.py +0 -0
  575. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_train_context_preflight.py +0 -0
  576. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_training_controls.py +0 -0
  577. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_type_comment_prose.py +0 -0
  578. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_vast_api.py +0 -0
  579. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_vast_api_coverage.py +0 -0
  580. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_vast_offers.py +0 -0
  581. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_vast_provider_coverage.py +0 -0
  582. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_vast_runner.py +0 -0
  583. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_verified_revisions.py +0 -0
  584. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_verl_child_plugins.py +0 -0
  585. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_verl_silence_watchdog.py +0 -0
  586. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_version.py +0 -0
  587. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_vl_warmstart_adapter_keys.py +0 -0
  588. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_vram_architecture.py +0 -0
  589. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_wandb_link.py +0 -0
  590. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_wandb_naming.py +0 -0
  591. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_warmstart_cross_repo.py +0 -0
  592. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_warmstart_error_attribution.py +0 -0
  593. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_weight_cache.py +0 -0
  594. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_worker_dryrun.py +0 -0
  595. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_worker_hardexit.py +0 -0
  596. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_worker_image.py +0 -0
  597. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_worker_init_heartbeat.py +0 -0
  598. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_worker_stack.py +0 -0
  599. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_worker_thinking.py +0 -0
  600. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_workflow_contracts.py +0 -0
  601. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/tests/test_workload_profile.py +0 -0
  602. {freesolo_flash_dev-1.2.87 → freesolo_flash_dev-1.2.88}/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.87
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
@@ -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