freesolo-flash-dev 1.2.65__tar.gz → 1.2.67__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.
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/PKG-INFO +1 -1
- freesolo_flash_dev-1.2.67/flash/_internal/diagnostics.py +170 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/sft_train.py +13 -2
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/_lifecycle/bootstrap_secrets.py +83 -18
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/runpod/serverless/endpoints.py +96 -34
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/runner/supervise/seed_submission.py +21 -15
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/pyproject.toml +2 -2
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_backend_common.py +81 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_envs_coverage.py +6 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_flash_worker.py +210 -12
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_instance_bootstrap_coverage.py +59 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_opd_resume_safety.py +96 -21
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_opd_train.py +47 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_rl_train.py +88 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_sft_train.py +72 -1
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/uv.lock +1 -1
- freesolo_flash_dev-1.2.65/flash/_internal/diagnostics.py +0 -106
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/.dockerignore +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/.env.example +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/.github/CODEOWNERS +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/.github/dependabot.yml +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/.github/workflows/auto-rebake.yml +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/.github/workflows/bake-kernel-cache.yml +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/.github/workflows/ci.yml +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/.github/workflows/main-source-guard.yml +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/.github/workflows/notify-tests-repo.yml +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/.github/workflows/publish-dev.yml +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/.github/workflows/publish-image.yml +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/.github/workflows/publish.yml +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/.github/workflows/version-parity.yml +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/.github/workflows/worker-image.yml +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/.gitignore +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/CHANGELOG.md +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/CODE_OF_CONDUCT.md +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/CONTRIBUTING.md +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/Dockerfile +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/Dockerfile.worker +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/LICENSE +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/NOTICE +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/README.md +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/SECURITY.md +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/SELF_HOSTING.md +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/build/kernel_cache/.gitignore +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/build/kernel_cache/.keep +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/deploy/infisical/README.md +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/deploy/infisical/entrypoint.sh +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/docker/Dockerfile.kernelcache +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/docker/Dockerfile.kernelcache.relayer +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/docker/bake_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/docker/bake_pod_entry.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/docker/extract_cudart_fix.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/docker/kernel_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/docker/make_rp_handler.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/_internal/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/_internal/channel.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/_internal/fileio.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/_internal/logging.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/_internal/paths.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/adapters/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/adapters/artifacts.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/adapters/fused_experts.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/adapters/lora_rank.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cli/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cli/__main__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cli/commands/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cli/commands/deploy.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cli/commands/env/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cli/commands/env/episode.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cli/commands/env/eval.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cli/commands/env/eval_args.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cli/commands/env/imports.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cli/commands/env/list.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cli/commands/env/push.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cli/commands/env/retained.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cli/commands/env/setup.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cli/commands/env/setup_wandb.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cli/commands/env/test.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cli/commands/env/test_evaluations.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cli/commands/env/test_params.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cli/commands/env/test_warnings.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cli/commands/prompt_budget.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cli/commands/traces.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cli/commands/train_cost.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cli/scaffold/TRAINING.md +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cli/scaffold/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cli/ui/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cli/ui/cost.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cli/ui/env_panels.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cli/ui/heartbeat.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cli/ui/render.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cli/ui/tables.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cli/ui/tty.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/client/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/client/config.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/client/freesolo_api.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/client/http.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/client/runtime_secrets.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/client/shapes.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/client/specs.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/client/streaming.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/content/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/content/multimodal.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/content/structured_outputs.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/content/thinking.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/core/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/core/catalog.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/core/spec.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/core/spec_persistence.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cost/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cost/analytical.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cost/facts.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cost/spec.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/cost/types.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/huggingface.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/plan/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/plan/kv_sizing.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/plan/model_config_probe.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/plan/prompt_budget.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/plan/recipe.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/plan/steps.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/plan/vram.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/profiling/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/profiling/dataset_profile.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/profiling/image_tokens.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/profiling/reasoning_render.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/profiling/sft_image_rows.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/profiling/sft_workload.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/profiling/tokenizer.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/profiling/workload_profile.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/result/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/result/accounting.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/result/rollout_samples.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/__main__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/backend_common.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/entry/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/entry/opd.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/entry/rl.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/entry/sft.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/io/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/io/heartbeat.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/io/hf.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/io/prefetch.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/io/wandb_log.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/model/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/model/adapter.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/model/chatml_mask.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/model/decoding.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/model/lora.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/model/packing.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/opd_train.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/opd_train_runner.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/perf/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/perf/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/perf/lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/perf/liger.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/perf/memory.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/rl_train.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/rl_train_runner.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/runtime/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/runtime/kernel_warmup.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/runtime/pkg_proxy.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/runtime/rng.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/score_batcher.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/sft_train_runner.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/teacher/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/teacher/client.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/teacher/encoding.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/teacher/tokenizer_align.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/core/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/core/checkpoint_lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/core/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/core/child/glue.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/core/child/runtime.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/core/step_timing.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/finalize.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/opd/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/opd/batching.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/opd/bridge.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/opd/bridge_failures.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/opd/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/opd/child/bridge.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/opd/child/entry.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/opd/child/multiturn.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/opd/child/plugin.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/opd/child/replay_guard.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/opd/child/runtime.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/opd/child/structured.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/opd/failures.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/opd/gkd.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/opd/multiturn_validation.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/opd/overrides.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/opd/prompts.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/opd/reporting.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/opd/scoring.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/opd/state.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/opd/validation.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/rl/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/rl/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/rl/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/rl/child/entry.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/rl/child/multiturn.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/rl/child/patches.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/rl/child/plugin.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/rl/config.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/rl/inputs.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/rl/multi_turn.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/rl/reward_module.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/rl/scoring.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/rl/single_turn.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/rl/verl_config.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/sft/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/sft/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/sft/child/entry.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/sft/child/plugin.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/train/sft/config.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/verl/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/verl/capabilities.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/verl/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/verl/child_io.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/verl/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/verl/parallelism.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker/verl/parent_work.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/engine/worker_entrypoint.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/envs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/envs/adapter.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/envs/base.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/envs/cache_security.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/envs/dataset_selection.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/envs/evaluations.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/envs/identity.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/envs/loader.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/envs/namespace_listing.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/envs/package/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/envs/package/limits.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/envs/package/unpack.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/envs/pull.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/_lifecycle/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/_lifecycle/auth.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/_lifecycle/bootstrap.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/_lifecycle/bootstrap_console.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/_lifecycle/bootstrap_pip.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/_lifecycle/deadline.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/_lifecycle/host/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/_lifecycle/host/deadline_sleep.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/_lifecycle/host/failmark.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/_lifecycle/host/hostlog.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/_lifecycle/http.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/_lifecycle/instance.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/_lifecycle/poll.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/_lifecycle/poll_instance.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/_lifecycle/provider.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/_lifecycle/terminal_artifacts.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/_lifecycle/worker.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/allocator.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/artifacts/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/artifacts/hf.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/artifacts/preload_runpod.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/artifacts/weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/base.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/fit_errors.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/lambda_/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/lambda_/api.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/lambda_/auth.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/lambda_/gpus.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/lambda_/jobs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/lambda_/jobs/builders.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/lambda_/jobs/reap.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/lambda_/preflight.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/lambda_/pricing.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/preflight.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/realized.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/runpod/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/runpod/api.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/runpod/auth.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/runpod/cost.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/runpod/gpus.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/runpod/job_execution.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/runpod/jobs.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/runpod/preflight.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/runpod/pricing.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/runpod/resources.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/runpod/serverless/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/sharding.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/vast/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/vast/api.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/vast/auth.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/vast/jobs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/vast/jobs/builders.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/vast/preflight.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/providers/vast/pricing.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/py.typed +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/runner/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/runner/artifacts.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/runner/attempts.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/runner/costs.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/runner/deadlines.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/runner/preparation.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/runner/reconciliation.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/runner/results/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/runner/results/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/runner/results/verified_revisions.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/runner/status.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/runner/submit.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/runner/supervise/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/runner/supervise/attach.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/runner/supervise/deploy.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/runner/supervise/lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/runner/supervise/recovery.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/runner/supervise/retry_decision.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/runner/supervise/transitions.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/runner/weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/runtime_capsule/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/runtime_capsule/build.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/runtime_capsule/manifest.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/runtime_capsule/profiles.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/schema/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/schema/fields.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/serve/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/serve/adapter_check.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/serve/deploy.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/serve/errors.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/serve/export.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/serve/preflight.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/serve/responses.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/serve/streaming.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/serve/thinking.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/serve/urls.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/__main__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/app.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/billing/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/billing/charges.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/billing/retry.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/domain/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/domain/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/domain/environment_registry.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/domain/envs.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/domain/projects.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/domain/reconcile.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/domain/repo_cleanup.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/domain/run_registry.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/domain/teacher_broker.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/domain/teacher_errors.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/domain/teacher_requests.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/platform/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/platform/auth.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/platform/db.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/platform/deps.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/platform/internal_client.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/platform/locks.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/platform/runtime.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/routes/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/routes/envs.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/routes/meta.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/routes/runs.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/routes/serving.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/routes/serving_completion.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/routes/serving_revisions.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/routes/serving_smoke.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/server/routes/teacher.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/teacher/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/teacher/limits.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/teacher/retry_contract.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/scripts/build_dev_dist.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/scripts/check_file_size.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/scripts/check_function_size.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/scripts/check_verl_pin_exists.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/scripts/scrub_history.sh +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/_helpers/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/_helpers/profile.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/_helpers/runner.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/_helpers/specs.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/_helpers/teacher.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/_helpers/vast.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/capture_image_sft_processor_oracle.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/conftest.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/fixtures/image_sft_processor_oracle.json +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/fixtures/math_eval.jsonl +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/fixtures/math_train.jsonl +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/live/__init__.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/live/conftest.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/live/test_lambda_live.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/live/test_runpod_live.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/live/test_sft_thinking_render_live.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/live/test_vast_live.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_accounting_coverage.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_adapter_shard_completeness.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_agent_flash_cli_contract.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_algorithms.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_allocator.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_backend_jobspec_contract.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_bake_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_base_model_provenance.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_billing_retry.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_build_context_contract.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_cancel_remote.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_catalog_consistency.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_catalog_only_models.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_charge_pricing.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_checkpoint_lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_cli_commands.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_cli_commands_coverage.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_cli_credential_shadowing.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_cli_errors.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_cli_estimate.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_cli_gpus_flag.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_cli_help.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_cli_main_coverage.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_cli_managed.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_cli_render_coverage.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_cli_render_theme.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_cli_traces.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_cli_wandb_warning.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_client.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_client_import_purity.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_client_server_integration.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_client_stream_reads.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_config_env_vars.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_config_overrides.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_console_upload.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_controlled_experiment_repairs.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_cost_analytical.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_cost_equation.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_cost_estimate.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_cost_hardware.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_cost_models.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_dataset_profile.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_deploy_alias_move_warning.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_deploy_latency.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_dev_channel.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_disk_gb.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_endpoint_name.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_env_cache_evict.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_env_delete.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_env_download.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_env_download_api.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_env_evaluations.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_env_list_api.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_env_list_cli.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_env_list_hub.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_env_no_install.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_env_publish.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_env_pull.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_env_pull_coverage.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_env_pull_loader_coverage.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_env_pull_managed_control_plane.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_env_push.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_env_rate_limit_resolve.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_env_ref_pinning.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_env_test.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_export.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_flash_mvp.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_flashinfer_cache_dirs.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_freesolo_api_transport.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_fused_expert_warmstart.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_github_urlopen_retry.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_gpu_type_single_field.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_gpus.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_grpo_params.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_grpo_resident_sizing.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_grpo_reward_batching.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_health_liveness.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_hf_retry.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_idle_endpoint_reaper.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_image_sft_markers.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_image_sft_processor_parity.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_image_tokens.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_infisical_secrets.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_internal_client.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_jobs.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_kernel_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_kv_util.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_lambda_api_coverage.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_lambda_runner.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_logging.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_login_perms.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_lora_rank_coverage.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_lora_rank_preflight.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_managed_config_fields.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_managed_hf_repo.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_metrics_schema_agent_contract.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_mig_guard.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_multi_gpu_gate.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_multimodal_training.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_named_reward_metrics.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_oom_escalate_gpu.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_opd.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_opd_limits.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_opd_multiturn_eos_boundary.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_opd_multiturn_failure_exit.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_opd_replay_guard.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_orchestrator_flash.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_packing.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_packing_coverage.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_parasail_teacher.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_persisted_spec_envelope.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_poll_helpers.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_preflight.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_projects.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_prompt_budget.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_provider_preflight_coverage.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_provider_routing.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_provider_teardown_robustness.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_providers_symmetry.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_realized_cost.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_repo_cleanup.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_resolve_params_b.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_resume_on_retry.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_rollout_samples.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_runmgmt.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_runpod_api_delete.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_runpod_key_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_runpod_key_waterfall.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_runtime_capsule.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_serve.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_serve_reasoning_content.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_server_api.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_server_app_coverage.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_server_auth_singleflight.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_server_billing.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_server_checkpoints_coverage.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_server_db.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_server_envs_coverage.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_server_locks_coverage.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_server_standalone.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_serving_context_preflight.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_serving_contract.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_serving_schema_coverage.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_sft_chunked_nll.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_sft_example_selection.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_sft_gc_off.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_sft_max_context.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_sft_startup_block.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_sft_workload.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_spec_and_validation.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_spec_contract_bytes.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_step_floor.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_step_metrics.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_step_timing.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_structured_outputs.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_teacher_broker.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_teacher_encoding_contract.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_terminal_artifacts.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_thinking_config.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_train_context_preflight.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_training_controls.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_type_comment_prose.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_vast_api.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_vast_api_coverage.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_vast_offers.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_vast_provider_coverage.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_vast_runner.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_verified_revisions.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_verifiers.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_verl_checkpoint_export.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_verl_child_plugins.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_verl_silence_watchdog.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_version.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_vl_warmstart_adapter_keys.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_vram_architecture.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_wandb_link.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_wandb_naming.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_warmstart_adapter_download.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_warmstart_cross_repo.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_warmstart_error_attribution.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_worker_dryrun.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_worker_hardexit.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_worker_image.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_worker_init_heartbeat.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_worker_stack.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_worker_thinking.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_workflow_contracts.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/tests/test_workload_profile.py +0 -0
- {freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/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.
|
|
3
|
+
Version: 1.2.67
|
|
4
4
|
Summary: Flash — managed LoRA post-training (SFT/GRPO/OPD) for Freesolo environments, driven by the `flash` CLI
|
|
5
5
|
Project-URL: Homepage, https://github.com/freesolo-co/flash
|
|
6
6
|
Project-URL: Repository, https://github.com/freesolo-co/flash
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"""Bounded credential-safe diagnostic rendering."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import re
|
|
7
|
+
import urllib.parse
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
_SECRET_KEY_RE = re.compile(
|
|
11
|
+
r"(?i)(authorization|api[-_ ]?key|access[-_ ]?token|refresh[-_ ]?token|token|secret|password)"
|
|
12
|
+
r"(\s*[:=]\s*)(?:bearer\s+)?([^\s,;]+)"
|
|
13
|
+
)
|
|
14
|
+
_BEARER_RE = re.compile(r"(?i)\bbearer\s+[A-Za-z0-9._~+/=-]+")
|
|
15
|
+
_SECRET_ENV_SUFFIXES = ("_API_KEY", "_TOKEN", "_SECRET", "_PASSWORD")
|
|
16
|
+
|
|
17
|
+
# comma-separated env-variable names whose values are secrets regardless of naming shape: declared
|
|
18
|
+
# runtime secrets can carry any name (AWS_SECRET_ACCESS_KEY, FLASH_TEACHER_CAPABILITY, ...), so the
|
|
19
|
+
# control plane lists them explicitly in the worker env instead of relying on the suffix heuristic.
|
|
20
|
+
SECRET_ENV_KEYS_ENV = "FLASH_SECRET_ENV_KEYS"
|
|
21
|
+
|
|
22
|
+
# multiline secrets may appear only partially in truncated logs. register long component lines as
|
|
23
|
+
# needles, but ignore short common fragments such as ``}`` that would erase innocent diagnostics.
|
|
24
|
+
_MIN_SECRET_COMPONENT = 8
|
|
25
|
+
_PERCENT_ESCAPE_RE = re.compile(r"%([0-9A-Fa-f]{2})")
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _percent_pattern(needle: str) -> str:
|
|
29
|
+
"""Regex for ``needle`` with only percent-escape hex digits matched case-insensitively."""
|
|
30
|
+
parts: list[str] = []
|
|
31
|
+
offset = 0
|
|
32
|
+
for match in _PERCENT_ESCAPE_RE.finditer(needle):
|
|
33
|
+
parts.append(re.escape(needle[offset : match.start()]))
|
|
34
|
+
parts.append("%")
|
|
35
|
+
parts.extend(
|
|
36
|
+
f"[{char.lower()}{char.upper()}]" if char.isalpha() else char for char in match.group(1)
|
|
37
|
+
)
|
|
38
|
+
offset = match.end()
|
|
39
|
+
parts.append(re.escape(needle[offset:]))
|
|
40
|
+
return "".join(parts)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _bounded_pattern(needle: str) -> str:
|
|
44
|
+
"""``needle`` anchored so it cannot match as part of a longer word.
|
|
45
|
+
|
|
46
|
+
The guard is applied per EDGE, and only where the needle's own edge is a word character. A
|
|
47
|
+
value with a punctuation edge already separates itself from neighbouring text, and demanding a
|
|
48
|
+
non-word character beyond it asks the wrong question: ``/a`` inside ``https://host/a/repo`` is
|
|
49
|
+
preceded by the ``t`` of ``host``, so an unconditional left guard fails and the secret prints
|
|
50
|
+
verbatim. ``ati`` keeps both guards and so still cannot rewrite ``authentication``.
|
|
51
|
+
Mirrors flash.providers._lifecycle.bootstrap_secrets._bounded_pattern.
|
|
52
|
+
"""
|
|
53
|
+
escaped = re.escape(needle)
|
|
54
|
+
left = r"(?<!\w)" if needle[:1].isalnum() or needle[:1] == "_" else ""
|
|
55
|
+
right = r"(?!\w)" if needle[-1:].isalnum() or needle[-1:] == "_" else ""
|
|
56
|
+
return f"{left}{escaped}{right}"
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
_ValueMatcher = tuple[str, bool, bool]
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _configured_secrets() -> tuple[tuple[_ValueMatcher, ...], tuple[str, ...], frozenset[str]]:
|
|
63
|
+
"""Credential matchers plus shape-only and exact raw values.
|
|
64
|
+
|
|
65
|
+
Each value matcher carries ``(needle, bounded, encoded)`` metadata. Plain values are replaced as
|
|
66
|
+
substrings. Bounded values are shorter than ``_MIN_SECRET_COMPONENT`` and may only match where
|
|
67
|
+
they are not adjacent to a word character: a 3-char global needle would mangle every diagnostic
|
|
68
|
+
containing those characters (the value ``ati`` rewrites ``authentication``).
|
|
69
|
+
|
|
70
|
+
A short raw candidate with no alphanumeric or underscore character is shape-only because it is
|
|
71
|
+
indistinguishable from ordinary punctuation. Explicit percent-octet forms remain bounded and
|
|
72
|
+
safely distinguishable. Keyed and bearer matching uses the known shape-only value directly.
|
|
73
|
+
|
|
74
|
+
Component lines of a multiline value keep the floor as a hard skip: a short component is
|
|
75
|
+
punctuation such as ``}``, not a credential.
|
|
76
|
+
"""
|
|
77
|
+
declared = {
|
|
78
|
+
name.strip().upper()
|
|
79
|
+
for name in os.environ.get(SECRET_ENV_KEYS_ENV, "").split(",")
|
|
80
|
+
if name.strip()
|
|
81
|
+
}
|
|
82
|
+
matchers: set[_ValueMatcher] = set()
|
|
83
|
+
shaped: set[str] = set()
|
|
84
|
+
raw_values: set[str] = set()
|
|
85
|
+
for key, value in os.environ.items():
|
|
86
|
+
upper = key.upper()
|
|
87
|
+
if not value or not (
|
|
88
|
+
upper in {"AUTHORIZATION", "HF_TOKEN"}
|
|
89
|
+
or upper in declared
|
|
90
|
+
or upper.endswith(_SECRET_ENV_SUFFIXES)
|
|
91
|
+
):
|
|
92
|
+
continue
|
|
93
|
+
raw_values.add(value)
|
|
94
|
+
candidates = {(value, False)}
|
|
95
|
+
encoded = urllib.parse.quote(value, safe="")
|
|
96
|
+
if encoded != value:
|
|
97
|
+
candidates.add((encoded, True))
|
|
98
|
+
if len(value) < _MIN_SECRET_COMPONENT and not any(
|
|
99
|
+
char.isalnum() or char == "_" for char in value
|
|
100
|
+
):
|
|
101
|
+
candidates.add(("".join(f"%{byte:02X}" for byte in value.encode()), True))
|
|
102
|
+
if len(value) >= _MIN_SECRET_COMPONENT:
|
|
103
|
+
matchers.update((candidate, False, is_encoded) for candidate, is_encoded in candidates)
|
|
104
|
+
else:
|
|
105
|
+
for candidate, is_encoded in candidates:
|
|
106
|
+
if any(char.isalnum() or char == "_" for char in candidate):
|
|
107
|
+
matchers.add((candidate, True, is_encoded))
|
|
108
|
+
else:
|
|
109
|
+
shaped.add(candidate)
|
|
110
|
+
if "\n" in value:
|
|
111
|
+
for raw in value.splitlines():
|
|
112
|
+
if len(line := raw.strip()) >= _MIN_SECRET_COMPONENT:
|
|
113
|
+
matchers.add((line, False, False))
|
|
114
|
+
encoded_line = urllib.parse.quote(line, safe="")
|
|
115
|
+
if encoded_line != line:
|
|
116
|
+
matchers.add((encoded_line, False, True))
|
|
117
|
+
return tuple(matchers), tuple(shaped), frozenset(raw_values)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def sanitize_diagnostic(value: Any, *, limit: int = 2000) -> str:
|
|
121
|
+
"""Keep useful failure context while removing credentials and bounding output."""
|
|
122
|
+
text = f"{type(value).__name__}: {value}" if isinstance(value, BaseException) else str(value)
|
|
123
|
+
matchers, shaped, raw_values = _configured_secrets()
|
|
124
|
+
# protect exact punctuation credentials before a separate value can erase their syntax.
|
|
125
|
+
for secret in sorted(shaped, key=len, reverse=True):
|
|
126
|
+
escaped = re.escape(secret)
|
|
127
|
+
text = re.sub(
|
|
128
|
+
rf"(?i)(authorization|api[-_ ]?key|access[-_ ]?token|refresh[-_ ]?token|token|secret|password)(\s*[:=]\s*)(?:bearer\s+)?{escaped}(?=[\s,;]|$)",
|
|
129
|
+
lambda match: (
|
|
130
|
+
"<redacted>"
|
|
131
|
+
if match.group(1) in raw_values
|
|
132
|
+
else f"{match.group(1)}{match.group(2)}<redacted>"
|
|
133
|
+
),
|
|
134
|
+
text,
|
|
135
|
+
)
|
|
136
|
+
text = re.sub(
|
|
137
|
+
rf"(?i)\b(bearer)\s+{escaped}(?=[\s,;]|$)",
|
|
138
|
+
lambda match: "<redacted>" if match.group(1) in raw_values else "Bearer <redacted>",
|
|
139
|
+
text,
|
|
140
|
+
)
|
|
141
|
+
# apply both matcher types in one longest-first order so a shorter plain value cannot consume
|
|
142
|
+
# the prefix of a longer bounded encoded value.
|
|
143
|
+
for secret, is_bounded, is_encoded in sorted(
|
|
144
|
+
matchers, key=lambda item: len(item[0]), reverse=True
|
|
145
|
+
):
|
|
146
|
+
if is_encoded:
|
|
147
|
+
pattern = _percent_pattern(secret)
|
|
148
|
+
if is_bounded:
|
|
149
|
+
left = r"(?<!\w)" if secret[:1].isalnum() or secret[:1] == "_" else ""
|
|
150
|
+
right = r"(?!\w)" if secret[-1:].isalnum() or secret[-1:] == "_" else ""
|
|
151
|
+
pattern = f"{left}{pattern}{right}"
|
|
152
|
+
text = re.sub(pattern, "<redacted>", text)
|
|
153
|
+
elif is_bounded:
|
|
154
|
+
text = re.sub(_bounded_pattern(secret), "<redacted>", text)
|
|
155
|
+
else:
|
|
156
|
+
text = text.replace(secret, "<redacted>")
|
|
157
|
+
text = _BEARER_RE.sub("Bearer <redacted>", text)
|
|
158
|
+
text = _SECRET_KEY_RE.sub(lambda match: f"{match.group(1)}{match.group(2)}<redacted>", text)
|
|
159
|
+
return text[: max(0, int(limit))]
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def neutralize_control_chars(value: Any) -> str:
|
|
163
|
+
"""Escape terminal control characters while preserving newlines as separators."""
|
|
164
|
+
text = str(value)
|
|
165
|
+
return "".join(
|
|
166
|
+
char
|
|
167
|
+
if char == "\n" or 0x20 <= ord(char) < 0x7F or ord(char) >= 0xA0
|
|
168
|
+
else f"\\x{ord(char):02x}"
|
|
169
|
+
for char in text
|
|
170
|
+
)
|
|
@@ -14,6 +14,7 @@ import sys
|
|
|
14
14
|
import threading
|
|
15
15
|
import time
|
|
16
16
|
|
|
17
|
+
from flash._internal.diagnostics import SECRET_ENV_KEYS_ENV
|
|
17
18
|
from flash.adapters.lora_rank import rank_from_adapter_config
|
|
18
19
|
from flash.engine.worker.runtime.pkg_proxy import W as _w
|
|
19
20
|
from flash.engine.worker.verl.checkpoints import resume_checkpoint_is_loadable
|
|
@@ -203,6 +204,9 @@ _CHILD_ENV_PREFIXES = (
|
|
|
203
204
|
|
|
204
205
|
|
|
205
206
|
def _build_verl_child_env(*, shim_dir: str, wandb_enabled: bool) -> dict[str, str]:
|
|
207
|
+
applied_secret_names = frozenset(
|
|
208
|
+
name.strip() for name in os.environ.get(SECRET_ENV_KEYS_ENV, "").split(",") if name.strip()
|
|
209
|
+
)
|
|
206
210
|
child = {
|
|
207
211
|
key: value
|
|
208
212
|
for key, value in os.environ.items()
|
|
@@ -210,9 +214,16 @@ def _build_verl_child_env(*, shim_dir: str, wandb_enabled: bool) -> dict[str, st
|
|
|
210
214
|
}
|
|
211
215
|
if wandb_enabled:
|
|
212
216
|
child.update({key: value for key, value in os.environ.items() if key.startswith("WANDB_")})
|
|
213
|
-
|
|
214
|
-
|
|
217
|
+
# retained runtime namespaces are filtered by applied-secret provenance. authenticated child-side
|
|
218
|
+
# wandb logging is the sole secret exception, and only when the existing logger gate enables it.
|
|
219
|
+
for name in applied_secret_names:
|
|
220
|
+
child.pop(name, None)
|
|
221
|
+
if wandb_enabled and "WANDB_API_KEY" in os.environ:
|
|
222
|
+
child["WANDB_API_KEY"] = os.environ["WANDB_API_KEY"]
|
|
223
|
+
parent_pythonpath = (
|
|
224
|
+
os.environ.get("PYTHONPATH", "") if "PYTHONPATH" not in applied_secret_names else ""
|
|
215
225
|
)
|
|
226
|
+
child["PYTHONPATH"] = os.pathsep.join(item for item in (shim_dir, parent_pythonpath) if item)
|
|
216
227
|
child["PYTHONUNBUFFERED"] = "1"
|
|
217
228
|
child["HYDRA_FULL_ERROR"] = "1"
|
|
218
229
|
child["HF_HUB_OFFLINE"] = "1"
|
|
@@ -22,6 +22,22 @@ _SECRET_RE = re.compile(
|
|
|
22
22
|
# component lines are registered as needles too; the floor keeps a common fragment such as ``}``
|
|
23
23
|
# from erasing innocent output. Mirrors flash._internal.diagnostics.
|
|
24
24
|
_MIN_SECRET_COMPONENT = 8
|
|
25
|
+
_PERCENT_ESCAPE_RE = re.compile(r"%([0-9A-Fa-f]{2})")
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _percent_pattern(needle: str) -> str:
|
|
29
|
+
"""Regex for ``needle`` with only percent-escape hex digits matched case-insensitively."""
|
|
30
|
+
parts: list[str] = []
|
|
31
|
+
offset = 0
|
|
32
|
+
for match in _PERCENT_ESCAPE_RE.finditer(needle):
|
|
33
|
+
parts.append(re.escape(needle[offset : match.start()]))
|
|
34
|
+
parts.append("%")
|
|
35
|
+
parts.extend(
|
|
36
|
+
f"[{char.lower()}{char.upper()}]" if char.isalpha() else char for char in match.group(1)
|
|
37
|
+
)
|
|
38
|
+
offset = match.end()
|
|
39
|
+
parts.append(re.escape(needle[offset:]))
|
|
40
|
+
return "".join(parts)
|
|
25
41
|
|
|
26
42
|
|
|
27
43
|
def _bounded_pattern(needle: str) -> str:
|
|
@@ -39,37 +55,86 @@ def _bounded_pattern(needle: str) -> str:
|
|
|
39
55
|
return f"{left}{escaped}{right}"
|
|
40
56
|
|
|
41
57
|
|
|
42
|
-
|
|
43
|
-
|
|
58
|
+
_ValueMatcher = tuple[str, bool, bool]
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _needles(values: set[str]) -> tuple[set[_ValueMatcher], set[str]]:
|
|
62
|
+
"""The typed value matchers and shape-only needles for ``values``.
|
|
44
63
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
64
|
+
each value matcher carries ``(needle, bounded, encoded)`` metadata. plain needles are replaced as
|
|
65
|
+
substrings. bounded needles are values under the floor, replaced only where not adjacent to a word
|
|
66
|
+
character. a short raw candidate with no alphanumeric or underscore character is shape-only
|
|
67
|
+
because it is indistinguishable from ordinary punctuation; explicit percent-octet forms remain
|
|
68
|
+
bounded. component lines of a multiline value keep the floor as a hard skip: a short one is
|
|
49
69
|
punctuation such as ``}``, not a credential.
|
|
50
70
|
"""
|
|
51
|
-
|
|
52
|
-
|
|
71
|
+
matchers: set[_ValueMatcher] = set()
|
|
72
|
+
shaped: set[str] = set()
|
|
53
73
|
for secret in values:
|
|
54
|
-
|
|
55
|
-
|
|
74
|
+
candidates = {(secret, False)}
|
|
75
|
+
encoded = urllib.parse.quote(secret, safe="")
|
|
76
|
+
if encoded != secret:
|
|
77
|
+
candidates.add((encoded, True))
|
|
78
|
+
if len(secret) < _MIN_SECRET_COMPONENT and not any(
|
|
79
|
+
char.isalnum() or char == "_" for char in secret
|
|
80
|
+
):
|
|
81
|
+
candidates.add(("".join(f"%{byte:02X}" for byte in secret.encode()), True))
|
|
82
|
+
if len(secret) >= _MIN_SECRET_COMPONENT:
|
|
83
|
+
matchers.update((candidate, False, is_encoded) for candidate, is_encoded in candidates)
|
|
84
|
+
else:
|
|
85
|
+
for candidate, is_encoded in candidates:
|
|
86
|
+
if any(char.isalnum() or char == "_" for char in candidate):
|
|
87
|
+
matchers.add((candidate, True, is_encoded))
|
|
88
|
+
else:
|
|
89
|
+
shaped.add(candidate)
|
|
56
90
|
if "\n" in secret:
|
|
57
91
|
for raw in secret.splitlines():
|
|
58
92
|
if len(line := raw.strip()) >= _MIN_SECRET_COMPONENT:
|
|
59
|
-
|
|
60
|
-
|
|
93
|
+
matchers.add((line, False, False))
|
|
94
|
+
encoded_line = urllib.parse.quote(line, safe="")
|
|
95
|
+
if encoded_line != line:
|
|
96
|
+
matchers.add((encoded_line, False, True))
|
|
97
|
+
return matchers, shaped
|
|
61
98
|
|
|
62
99
|
|
|
63
100
|
def _redact_values(text: str, values: set[str]) -> str:
|
|
64
101
|
"""Replace every credential value in ``text``; see ``_needles`` for how each form is matched.
|
|
65
102
|
|
|
66
|
-
Longest-first, so one secret containing another cannot leave a suffix
|
|
103
|
+
Longest-first across both matcher types, so one secret containing another cannot leave a suffix
|
|
104
|
+
of the longer one behind.
|
|
67
105
|
"""
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
text = re.sub(
|
|
106
|
+
matchers, shaped = _needles(values)
|
|
107
|
+
# protect exact punctuation credentials before a separate value can erase their syntax.
|
|
108
|
+
for needle in sorted(shaped, key=len, reverse=True):
|
|
109
|
+
escaped = re.escape(needle)
|
|
110
|
+
text = re.sub(
|
|
111
|
+
rf"(?i)(authorization|api[-_ ]?key|access[-_ ]?token|token|secret|password)(\s*[:=]\s*)(?:bearer\s+)?{escaped}(?=[\s,;]|$)",
|
|
112
|
+
lambda match: (
|
|
113
|
+
"<redacted>"
|
|
114
|
+
if match.group(1) in values
|
|
115
|
+
else f"{match.group(1)}{match.group(2)}<redacted>"
|
|
116
|
+
),
|
|
117
|
+
text,
|
|
118
|
+
)
|
|
119
|
+
text = re.sub(
|
|
120
|
+
rf"(?i)\b(bearer)\s+{escaped}(?=[\s,;]|$)",
|
|
121
|
+
lambda match: "<redacted>" if match.group(1) in values else "Bearer <redacted>",
|
|
122
|
+
text,
|
|
123
|
+
)
|
|
124
|
+
for needle, is_bounded, is_encoded in sorted(
|
|
125
|
+
matchers, key=lambda item: len(item[0]), reverse=True
|
|
126
|
+
):
|
|
127
|
+
if is_encoded:
|
|
128
|
+
pattern = _percent_pattern(needle)
|
|
129
|
+
if is_bounded:
|
|
130
|
+
left = r"(?<!\w)" if needle[:1].isalnum() or needle[:1] == "_" else ""
|
|
131
|
+
right = r"(?!\w)" if needle[-1:].isalnum() or needle[-1:] == "_" else ""
|
|
132
|
+
pattern = f"{left}{pattern}{right}"
|
|
133
|
+
text = re.sub(pattern, "<redacted>", text)
|
|
134
|
+
elif is_bounded:
|
|
135
|
+
text = re.sub(_bounded_pattern(needle), "<redacted>", text)
|
|
136
|
+
else:
|
|
137
|
+
text = text.replace(needle, "<redacted>")
|
|
73
138
|
return text
|
|
74
139
|
|
|
75
140
|
|
|
@@ -62,31 +62,49 @@ def _train_body(input_data: dict) -> dict:
|
|
|
62
62
|
|
|
63
63
|
from huggingface_hub import snapshot_download
|
|
64
64
|
|
|
65
|
+
def _percent_pattern(needle):
|
|
66
|
+
"""Regex matching only percent-escape hex digits case-insensitively."""
|
|
67
|
+
escape_re = re.compile(r"%([0-9A-Fa-f]{2})")
|
|
68
|
+
parts = []
|
|
69
|
+
offset = 0
|
|
70
|
+
for match in escape_re.finditer(needle):
|
|
71
|
+
parts.append(re.escape(needle[offset : match.start()]))
|
|
72
|
+
parts.append("%")
|
|
73
|
+
parts.extend(
|
|
74
|
+
f"[{char.lower()}{char.upper()}]" if char.isalpha() else char
|
|
75
|
+
for char in match.group(1)
|
|
76
|
+
)
|
|
77
|
+
offset = match.end()
|
|
78
|
+
parts.append(re.escape(needle[offset:]))
|
|
79
|
+
return "".join(parts)
|
|
80
|
+
|
|
65
81
|
def _needles(secrets=None):
|
|
66
|
-
"""
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
82
|
+
"""Typed value matchers, shape-only needles, and raw values for all known secrets.
|
|
83
|
+
|
|
84
|
+
each value matcher carries ``(needle, bounded, encoded)`` metadata. a value at or above the
|
|
85
|
+
floor is plain and replaced as a substring; a shorter one is bounded, matched only where it is
|
|
86
|
+
not adjacent to a word character. short values used to be dropped outright, which leaked them
|
|
87
|
+
verbatim. plain replacement is not the alternative: a 3-char needle corrupts every diagnostic
|
|
88
|
+
that merely contains those letters (the value "ati" rewrites "authentication"). a short raw
|
|
89
|
+
candidate with no alphanumeric or underscore character is shape-only because it is
|
|
90
|
+
indistinguishable from ordinary punctuation. explicit percent-octet forms remain bounded.
|
|
91
|
+
|
|
92
|
+
a multiline secret never appears whole in any single call: the child's stdout is sanitized one
|
|
93
|
+
line at a time, so only a component line is ever seen. component lines keep the floor as a hard
|
|
94
|
+
skip: a short one is punctuation such as "}", not a credential. mirrors
|
|
95
|
+
flash.providers._lifecycle.bootstrap_secrets._needles.
|
|
78
96
|
"""
|
|
79
97
|
import urllib.parse
|
|
80
98
|
|
|
81
99
|
mapping = {**os.environ, **(secrets or {})}
|
|
82
100
|
# declared runtime secrets can carry any name, so the control plane lists them in
|
|
83
|
-
#
|
|
101
|
+
# flash_secret_env_keys; the name-shape rule stays as the fail-closed fallback.
|
|
84
102
|
declared = {
|
|
85
103
|
name.strip().upper()
|
|
86
104
|
for name in str(mapping.get("FLASH_SECRET_ENV_KEYS") or "").split(",")
|
|
87
105
|
if name.strip()
|
|
88
106
|
}
|
|
89
|
-
|
|
107
|
+
matchers, shaped, raw_values = set(), set(), set()
|
|
90
108
|
for key, secret in mapping.items():
|
|
91
109
|
upper = str(key).upper()
|
|
92
110
|
if not secret or not (
|
|
@@ -96,34 +114,78 @@ def _train_body(input_data: dict) -> dict:
|
|
|
96
114
|
):
|
|
97
115
|
continue
|
|
98
116
|
value_str = str(secret)
|
|
99
|
-
|
|
100
|
-
|
|
117
|
+
raw_values.add(value_str)
|
|
118
|
+
candidates = {(value_str, False)}
|
|
119
|
+
encoded = urllib.parse.quote(value_str, safe="")
|
|
120
|
+
if encoded != value_str:
|
|
121
|
+
candidates.add((encoded, True))
|
|
122
|
+
if len(value_str) < 8 and not any(char.isalnum() or char == "_" for char in value_str):
|
|
123
|
+
candidates.add(("".join(f"%{byte:02X}" for byte in value_str.encode()), True))
|
|
124
|
+
if len(value_str) >= 8:
|
|
125
|
+
matchers.update(
|
|
126
|
+
(candidate, False, is_encoded) for candidate, is_encoded in candidates
|
|
127
|
+
)
|
|
128
|
+
else:
|
|
129
|
+
for candidate, is_encoded in candidates:
|
|
130
|
+
if any(char.isalnum() or char == "_" for char in candidate):
|
|
131
|
+
matchers.add((candidate, True, is_encoded))
|
|
132
|
+
else:
|
|
133
|
+
shaped.add(candidate)
|
|
101
134
|
if "\n" in value_str:
|
|
102
135
|
for raw in value_str.splitlines():
|
|
103
136
|
if len(line := raw.strip()) >= 8:
|
|
104
|
-
|
|
105
|
-
|
|
137
|
+
matchers.add((line, False, False))
|
|
138
|
+
encoded_line = urllib.parse.quote(line, safe="")
|
|
139
|
+
if encoded_line != line:
|
|
140
|
+
matchers.add((encoded_line, False, True))
|
|
141
|
+
return matchers, shaped, raw_values
|
|
106
142
|
|
|
107
143
|
def _safe_detail(value, secrets=None, limit=1000):
|
|
108
144
|
text = (
|
|
109
145
|
f"{type(value).__name__}: {value}" if isinstance(value, BaseException) else str(value)
|
|
110
146
|
)
|
|
111
|
-
|
|
112
|
-
#
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
text =
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
147
|
+
matchers, shaped, raw_values = _needles(secrets)
|
|
148
|
+
# protect exact punctuation credentials before a separate value can erase their syntax.
|
|
149
|
+
for needle in sorted(shaped, key=len, reverse=True):
|
|
150
|
+
escaped = re.escape(needle)
|
|
151
|
+
text = re.sub(
|
|
152
|
+
rf"(?i)(authorization|api[-_ ]?key|access[-_ ]?token|token|secret|password)(\s*[:=]\s*)(?:bearer\s+)?{escaped}(?=[\s,;]|$)",
|
|
153
|
+
lambda match: (
|
|
154
|
+
"<redacted>"
|
|
155
|
+
if match.group(1) in raw_values
|
|
156
|
+
else f"{match.group(1)}{match.group(2)}<redacted>"
|
|
157
|
+
),
|
|
158
|
+
text,
|
|
159
|
+
)
|
|
160
|
+
text = re.sub(
|
|
161
|
+
rf"(?i)\b(bearer)\s+{escaped}(?=[\s,;]|$)",
|
|
162
|
+
lambda match: "<redacted>" if match.group(1) in raw_values else "Bearer <redacted>",
|
|
163
|
+
text,
|
|
164
|
+
)
|
|
165
|
+
# longest-first across both matcher types so a shorter plain value cannot consume the prefix
|
|
166
|
+
# of a longer bounded encoded value; encoded forms cover urls http and git errors print.
|
|
167
|
+
for needle, is_bounded, is_encoded in sorted(
|
|
168
|
+
matchers, key=lambda item: len(item[0]), reverse=True
|
|
169
|
+
):
|
|
170
|
+
if is_encoded:
|
|
171
|
+
pattern = _percent_pattern(needle)
|
|
172
|
+
if is_bounded:
|
|
173
|
+
left = r"(?<!\w)" if needle[:1].isalnum() or needle[:1] == "_" else ""
|
|
174
|
+
right = r"(?!\w)" if needle[-1:].isalnum() or needle[-1:] == "_" else ""
|
|
175
|
+
pattern = f"{left}{pattern}{right}"
|
|
176
|
+
text = re.sub(pattern, "<redacted>", text)
|
|
177
|
+
elif is_bounded:
|
|
178
|
+
# the word guard is applied per edge, and only where the needle's own edge is a word
|
|
179
|
+
# character. a value with a punctuation edge already separates itself from
|
|
180
|
+
# neighbouring text, and demanding a non-word character beyond it asks the wrong
|
|
181
|
+
# question: "/a" inside "https://host/a/repo" is preceded by the "t" of "host", so
|
|
182
|
+
# an unconditional left guard fails and the secret prints verbatim. "ati" keeps both
|
|
183
|
+
# guards and so still cannot rewrite "authentication".
|
|
184
|
+
left = r"(?<!\w)" if needle[:1].isalnum() or needle[:1] == "_" else ""
|
|
185
|
+
right = r"(?!\w)" if needle[-1:].isalnum() or needle[-1:] == "_" else ""
|
|
186
|
+
text = re.sub(f"{left}{re.escape(needle)}{right}", "<redacted>", text)
|
|
187
|
+
else:
|
|
188
|
+
text = text.replace(needle, "<redacted>")
|
|
127
189
|
text = re.sub(r"(?i)\bbearer\s+[A-Za-z0-9._~+/=-]+", "Bearer <redacted>", text)
|
|
128
190
|
text = re.sub(
|
|
129
191
|
r"(?i)(authorization|api[-_ ]?key|access[-_ ]?token|token|secret|password)"
|
{freesolo_flash_dev-1.2.65 → freesolo_flash_dev-1.2.67}/flash/runner/supervise/seed_submission.py
RENAMED
|
@@ -475,13 +475,13 @@ def _pinned_to_resume_width(allocation, resume_world_size: int | None):
|
|
|
475
475
|
the one the attempt runs at: it refuses to train rather than restart from step 0, because the
|
|
476
476
|
control-plane gate authorized this replacement only to continue from exactly that checkpoint.
|
|
477
477
|
Allocation, though, re-ranks every retry from scratch -- capacity and live pricing move, and
|
|
478
|
-
|
|
479
|
-
|
|
478
|
+
rentable shapes can carry more cards than the ranks that join the run. Comparing the checkpoint
|
|
479
|
+
width with the rented count can reject a loadable shape or admit one the worker cannot load.
|
|
480
480
|
|
|
481
|
-
Narrowing the candidates is what closes that gap, and it is done
|
|
481
|
+
Narrowing the candidates is what closes that gap, and it is done here rather than by passing a
|
|
482
482
|
count into ``allocate()``: ``max_gpu_count`` is a ceiling, not an exact width, so a ceiling of 2
|
|
483
|
-
still admits a 1-card shape.
|
|
484
|
-
|
|
483
|
+
still admits a 1-card shape. Allocator-stamped candidates carry their executed rank count while
|
|
484
|
+
unstamped candidates fall back to their rented count. The filter leaves ranking and shapes intact.
|
|
485
485
|
|
|
486
486
|
An empty result is left empty deliberately: the caller reports no-capacity and retries, which is
|
|
487
487
|
the truthful outcome when the only loadable shape is unavailable. Restarting from step 0 instead
|
|
@@ -489,11 +489,17 @@ def _pinned_to_resume_width(allocation, resume_world_size: int | None):
|
|
|
489
489
|
"""
|
|
490
490
|
if not resume_world_size:
|
|
491
491
|
return allocation
|
|
492
|
-
loadable =
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
492
|
+
loadable = []
|
|
493
|
+
for candidate in allocation.candidates:
|
|
494
|
+
executed_gpu_count = getattr(candidate, "executed_gpu_count", None)
|
|
495
|
+
width = (
|
|
496
|
+
executed_gpu_count
|
|
497
|
+
if type(executed_gpu_count) is int and executed_gpu_count > 0
|
|
498
|
+
else int(getattr(candidate, "gpu_count", 1))
|
|
499
|
+
)
|
|
500
|
+
if width == resume_world_size:
|
|
501
|
+
loadable.append(candidate)
|
|
502
|
+
loadable = tuple(loadable)
|
|
497
503
|
if loadable == allocation.candidates:
|
|
498
504
|
return allocation
|
|
499
505
|
if not loadable:
|
|
@@ -520,16 +526,16 @@ def _build_candidate_plan(
|
|
|
520
526
|
if not candidates:
|
|
521
527
|
# an exhausted list has two causes and they need different words. attributing the pinned-
|
|
522
528
|
# width one to OOM would send an operator to raise VRAM when the run is not out of memory
|
|
523
|
-
# at all: no fitting
|
|
529
|
+
# at all: no fitting candidate executes at the resume checkpoint's world size.
|
|
524
530
|
if prepared.resume_world_size and not allocation.candidates:
|
|
525
531
|
width = prepared.resume_world_size
|
|
526
532
|
ctx.last_detail = (
|
|
527
|
-
f"no
|
|
528
|
-
|
|
533
|
+
f"no candidate executing at checkpoint world size {width} is available, and this "
|
|
534
|
+
"retry must preserve that executed rank width"
|
|
529
535
|
)
|
|
530
536
|
print(
|
|
531
|
-
f"seed={ctx.seed} no
|
|
532
|
-
"not retrying",
|
|
537
|
+
f"seed={ctx.seed} no candidate executes at pinned OPD checkpoint world size "
|
|
538
|
+
f"{width}; not retrying",
|
|
533
539
|
file=ctx.log,
|
|
534
540
|
flush=True,
|
|
535
541
|
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "freesolo-flash-dev"
|
|
3
|
-
version = "1.2.
|
|
3
|
+
version = "1.2.67"
|
|
4
4
|
description ="Flash — managed LoRA post-training (SFT/GRPO/OPD) for Freesolo environments, driven by the `flash` CLI"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
# RunPod Flash supports Python 3.11-3.12 (not 3.13 yet).
|
|
@@ -137,7 +137,7 @@ artifacts = ["flash/py.typed"]
|
|
|
137
137
|
# auto-published by .github/workflows/publish-dev.yml: a push to `dev` whose version isn't yet on
|
|
138
138
|
# PyPI publishes it; pushes that don't change it find it already published and no-op. So cutting a
|
|
139
139
|
# dev-channel release = bump this (and [project].version) and merge to `dev`.
|
|
140
|
-
version = "1.2.
|
|
140
|
+
version = "1.2.67"
|
|
141
141
|
|
|
142
142
|
[tool.pytest.ini_options]
|
|
143
143
|
pythonpath = ["."]
|