freesolo-flash-dev 1.2.58__tar.gz → 1.2.59__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.58 → freesolo_flash_dev-1.2.59}/CHANGELOG.md +11 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/PKG-INFO +1 -1
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/runpod/job_execution.py +42 -4
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/pyproject.toml +2 -2
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_jobs.py +207 -13
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/uv.lock +1 -1
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/.dockerignore +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/.env.example +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/.github/CODEOWNERS +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/.github/dependabot.yml +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/.github/workflows/auto-rebake.yml +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/.github/workflows/bake-kernel-cache.yml +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/.github/workflows/ci.yml +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/.github/workflows/main-source-guard.yml +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/.github/workflows/notify-tests-repo.yml +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/.github/workflows/publish-dev.yml +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/.github/workflows/publish-image.yml +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/.github/workflows/publish.yml +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/.github/workflows/version-parity.yml +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/.github/workflows/worker-image.yml +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/.gitignore +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/CODE_OF_CONDUCT.md +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/CONTRIBUTING.md +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/Dockerfile +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/Dockerfile.worker +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/LICENSE +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/NOTICE +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/README.md +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/SECURITY.md +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/SELF_HOSTING.md +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/build/kernel_cache/.gitignore +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/build/kernel_cache/.keep +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/deploy/infisical/README.md +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/deploy/infisical/entrypoint.sh +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/docker/Dockerfile.kernelcache +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/docker/Dockerfile.kernelcache.relayer +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/docker/bake_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/docker/bake_pod_entry.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/docker/extract_cudart_fix.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/docker/kernel_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/docker/make_rp_handler.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/_internal/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/_internal/channel.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/_internal/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/_internal/fileio.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/_internal/logging.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/_internal/paths.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/adapters/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/adapters/artifacts.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/adapters/fused_experts.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/adapters/lora_rank.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/__main__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/commands/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/commands/deploy.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/commands/env/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/commands/env/episode.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/commands/env/eval.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/commands/env/eval_args.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/commands/env/imports.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/commands/env/list.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/commands/env/push.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/commands/env/retained.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/commands/env/setup.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/commands/env/test.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/commands/env/test_evaluations.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/commands/env/test_params.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/commands/env/test_warnings.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/commands/prompt_budget.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/commands/traces.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/commands/train_cost.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/scaffold/TRAINING.md +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/scaffold/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/ui/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/ui/cost.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/ui/env_panels.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/ui/heartbeat.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/ui/render.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/ui/tables.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/ui/tty.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/client/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/client/config.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/client/freesolo_api.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/client/http.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/client/runtime_secrets.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/client/shapes.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/client/specs.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/client/streaming.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/content/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/content/multimodal.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/content/structured_outputs.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/content/thinking.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/core/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/core/catalog.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/core/spec.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/core/spec_persistence.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cost/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cost/analytical.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cost/facts.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cost/spec.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cost/types.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/plan/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/plan/kv_sizing.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/plan/model_config_probe.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/plan/prompt_budget.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/plan/recipe.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/plan/steps.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/plan/vram.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/profiling/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/profiling/dataset_profile.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/profiling/reasoning_render.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/profiling/sft_workload.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/profiling/tokenizer.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/profiling/workload_profile.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/result/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/result/accounting.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/result/rollout_samples.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/__main__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/backend_common.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/entry/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/entry/opd.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/entry/rl.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/entry/sft.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/io/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/io/heartbeat.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/io/hf.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/io/prefetch.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/io/wandb_log.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/model/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/model/adapter.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/model/chatml_mask.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/model/decoding.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/model/lora.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/model/packing.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/opd_train.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/opd_train_runner.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/perf/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/perf/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/perf/lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/perf/liger.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/perf/memory.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/rl_train.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/rl_train_runner.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/runtime/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/runtime/kernel_warmup.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/runtime/pkg_proxy.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/runtime/rng.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/score_batcher.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/sft_train.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/sft_train_runner.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/teacher/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/teacher/client.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/teacher/encoding.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/teacher/tokenizer_align.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/core/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/core/checkpoint_lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/core/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/core/child/glue.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/core/child/runtime.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/core/step_timing.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/finalize.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/opd/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/opd/batching.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/opd/bridge.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/opd/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/opd/child/bridge.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/opd/child/entry.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/opd/child/multiturn.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/opd/child/plugin.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/opd/child/replay_guard.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/opd/child/runtime.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/opd/child/structured.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/opd/failures.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/opd/gkd.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/opd/multiturn_validation.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/opd/overrides.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/opd/prompts.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/opd/reporting.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/opd/scoring.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/opd/state.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/opd/validation.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/rl/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/rl/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/rl/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/rl/child/entry.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/rl/child/multiturn.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/rl/child/patches.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/rl/child/plugin.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/rl/config.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/rl/inputs.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/rl/multi_turn.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/rl/reward_module.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/rl/scoring.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/rl/single_turn.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/rl/verl_config.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/sft/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/sft/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/sft/child/entry.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/sft/child/plugin.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/train/sft/config.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/verl/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/verl/capabilities.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/verl/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/verl/child_io.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/verl/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/verl/parallelism.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker/verl/parent_work.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/engine/worker_entrypoint.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/envs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/envs/adapter.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/envs/base.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/envs/cache_security.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/envs/dataset_selection.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/envs/evaluations.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/envs/identity.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/envs/loader.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/envs/namespace_listing.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/envs/package/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/envs/package/limits.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/envs/package/unpack.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/envs/pull.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/_lifecycle/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/_lifecycle/auth.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/_lifecycle/bootstrap.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/_lifecycle/bootstrap_console.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/_lifecycle/bootstrap_pip.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/_lifecycle/bootstrap_secrets.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/_lifecycle/deadline.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/_lifecycle/host/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/_lifecycle/host/deadline_sleep.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/_lifecycle/host/failmark.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/_lifecycle/host/hostlog.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/_lifecycle/http.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/_lifecycle/instance.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/_lifecycle/poll.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/_lifecycle/poll_instance.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/_lifecycle/provider.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/_lifecycle/terminal_artifacts.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/_lifecycle/worker.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/allocator.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/artifacts/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/artifacts/hf.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/artifacts/preload_runpod.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/artifacts/weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/base.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/fit_errors.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/lambda_/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/lambda_/api.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/lambda_/auth.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/lambda_/gpus.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/lambda_/jobs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/lambda_/jobs/builders.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/lambda_/jobs/reap.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/lambda_/preflight.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/lambda_/pricing.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/preflight.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/realized.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/runpod/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/runpod/api.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/runpod/auth.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/runpod/cost.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/runpod/gpus.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/runpod/jobs.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/runpod/preflight.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/runpod/pricing.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/runpod/resources.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/runpod/serverless/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/runpod/serverless/endpoints.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/sharding.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/vast/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/vast/api.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/vast/auth.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/vast/jobs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/vast/jobs/builders.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/vast/preflight.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/vast/pricing.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/py.typed +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/runner/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/runner/artifacts.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/runner/attempts.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/runner/costs.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/runner/deadlines.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/runner/preparation.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/runner/reconciliation.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/runner/results/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/runner/results/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/runner/results/verified_revisions.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/runner/status.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/runner/submit.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/runner/supervise/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/runner/supervise/attach.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/runner/supervise/deploy.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/runner/supervise/lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/runner/supervise/recovery.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/runner/supervise/retry_decision.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/runner/supervise/seed_submission.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/runner/supervise/transitions.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/runner/weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/runtime_capsule/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/runtime_capsule/build.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/runtime_capsule/manifest.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/runtime_capsule/profiles.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/schema/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/schema/fields.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/serve/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/serve/adapter_check.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/serve/deploy.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/serve/errors.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/serve/export.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/serve/preflight.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/serve/responses.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/serve/streaming.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/serve/thinking.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/serve/urls.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/__main__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/app.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/billing/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/billing/charges.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/billing/retry.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/domain/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/domain/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/domain/environment_registry.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/domain/envs.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/domain/projects.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/domain/reconcile.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/domain/repo_cleanup.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/domain/run_registry.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/domain/teacher_broker.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/domain/teacher_errors.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/domain/teacher_requests.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/platform/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/platform/auth.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/platform/db.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/platform/deps.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/platform/internal_client.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/platform/locks.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/platform/runtime.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/routes/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/routes/envs.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/routes/meta.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/routes/runs.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/routes/serving.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/routes/serving_completion.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/routes/serving_revisions.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/routes/serving_smoke.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/server/routes/teacher.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/teacher/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/teacher/limits.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/teacher/retry_contract.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/scripts/build_dev_dist.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/scripts/check_file_size.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/scripts/check_function_size.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/scripts/check_verl_pin_exists.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/scripts/scrub_history.sh +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/_helpers/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/_helpers/profile.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/_helpers/runner.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/_helpers/specs.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/_helpers/teacher.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/_helpers/vast.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/conftest.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/fixtures/math_eval.jsonl +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/fixtures/math_train.jsonl +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/live/__init__.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/live/conftest.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/live/test_lambda_live.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/live/test_runpod_live.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/live/test_sft_thinking_render_live.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/live/test_vast_live.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_accounting_coverage.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_adapter_shard_completeness.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_agent_flash_cli_contract.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_algorithms.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_allocator.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_backend_common.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_backend_jobspec_contract.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_bake_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_base_model_provenance.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_billing_retry.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_build_context_contract.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_cancel_remote.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_catalog_consistency.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_catalog_only_models.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_charge_pricing.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_checkpoint_lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_cli_commands.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_cli_commands_coverage.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_cli_credential_shadowing.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_cli_errors.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_cli_estimate.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_cli_gpus_flag.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_cli_help.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_cli_main_coverage.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_cli_managed.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_cli_render_coverage.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_cli_render_theme.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_cli_traces.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_cli_wandb_warning.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_client.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_client_import_purity.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_client_server_integration.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_client_stream_reads.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_config_env_vars.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_config_overrides.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_console_upload.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_controlled_experiment_repairs.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_cost_analytical.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_cost_equation.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_cost_estimate.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_cost_hardware.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_cost_models.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_dataset_profile.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_deploy_alias_move_warning.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_deploy_latency.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_dev_channel.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_disk_gb.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_endpoint_name.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_env_cache_evict.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_env_delete.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_env_download.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_env_download_api.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_env_evaluations.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_env_list_api.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_env_list_cli.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_env_list_hub.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_env_no_install.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_env_publish.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_env_pull.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_env_pull_coverage.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_env_pull_loader_coverage.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_env_pull_managed_control_plane.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_env_push.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_env_rate_limit_resolve.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_env_ref_pinning.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_env_test.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_envs_coverage.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_export.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_flash_mvp.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_flash_worker.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_flashinfer_cache_dirs.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_freesolo_api_transport.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_fused_expert_warmstart.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_github_urlopen_retry.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_gpu_type_single_field.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_gpus.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_grpo_params.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_grpo_resident_sizing.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_grpo_reward_batching.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_health_liveness.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_hf_retry.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_idle_endpoint_reaper.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_infisical_secrets.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_instance_bootstrap_coverage.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_internal_client.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_kernel_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_kv_util.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_lambda_api_coverage.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_lambda_runner.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_logging.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_login_perms.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_lora_rank_coverage.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_lora_rank_preflight.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_managed_config_fields.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_managed_hf_repo.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_metrics_schema_agent_contract.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_mig_guard.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_multi_gpu_gate.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_multimodal_training.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_named_reward_metrics.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_oom_escalate_gpu.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_opd.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_opd_limits.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_opd_multiturn_eos_boundary.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_opd_multiturn_failure_exit.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_opd_replay_guard.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_opd_resume_safety.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_opd_train.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_orchestrator_flash.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_packing.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_packing_coverage.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_parasail_teacher.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_poll_helpers.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_preflight.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_projects.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_prompt_budget.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_provider_preflight_coverage.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_provider_routing.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_provider_teardown_robustness.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_providers_symmetry.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_realized_cost.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_repo_cleanup.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_resolve_params_b.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_resume_on_retry.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_rl_train.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_rollout_samples.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_runmgmt.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_runpod_api_delete.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_runpod_key_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_runpod_key_waterfall.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_runtime_capsule.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_serve.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_serve_reasoning_content.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_server_api.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_server_app_coverage.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_server_auth_singleflight.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_server_billing.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_server_checkpoints_coverage.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_server_db.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_server_envs_coverage.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_server_locks_coverage.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_server_standalone.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_serving_context_preflight.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_serving_contract.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_serving_schema_coverage.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_sft_chunked_nll.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_sft_example_selection.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_sft_gc_off.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_sft_max_context.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_sft_startup_block.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_sft_train.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_sft_workload.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_spec_and_validation.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_spec_contract_bytes.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_step_floor.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_step_metrics.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_step_timing.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_structured_outputs.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_teacher_broker.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_teacher_encoding_contract.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_terminal_artifacts.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_thinking_config.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_train_context_preflight.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_training_controls.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_type_comment_prose.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_vast_api.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_vast_api_coverage.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_vast_offers.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_vast_provider_coverage.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_vast_runner.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_verified_revisions.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_verifiers.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_verl_checkpoint_export.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_verl_child_plugins.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_verl_silence_watchdog.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_version.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_vl_warmstart_adapter_keys.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_vram_architecture.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_wandb_link.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_wandb_naming.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_warmstart_adapter_download.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_warmstart_cross_repo.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_warmstart_error_attribution.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_worker_dryrun.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_worker_hardexit.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_worker_image.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_worker_init_heartbeat.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_worker_stack.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_worker_thinking.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_workflow_contracts.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_workload_profile.py +0 -0
- {freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/tests/test_zero2_sharding_gate.py +0 -0
|
@@ -21,6 +21,17 @@ This file starts at 1.1.35. Earlier releases are not reconstructed here; use
|
|
|
21
21
|
|
|
22
22
|
### Changed
|
|
23
23
|
|
|
24
|
+
- A RunPod attempt's stall window is now measured from evidence timestamps rather than from when
|
|
25
|
+
the control plane happened to look at it. The window was seeded from the moment polling started
|
|
26
|
+
and was reset again by the first status read, and a heartbeat was credited at the time it was
|
|
27
|
+
read rather than the time it was written. Every one of those is a wall-clock reading, so each
|
|
28
|
+
reattach handed a worker that was already wedged a complete fresh setup window, and a supervisor
|
|
29
|
+
that reattached repeatedly could keep a dead worker on a paid GPU until the run's wall deadline.
|
|
30
|
+
The window is now anchored to the persisted launch, a heartbeat is credited at its own timestamp
|
|
31
|
+
clamped to that launch, and only a genuine status transition counts as progress. Instance
|
|
32
|
+
polling (Vast/Lambda) already worked this way; this brings RunPod onto the same rule. A job that
|
|
33
|
+
is still queued is unaffected: the capacity wait keeps its own exemption, so a worker granted
|
|
34
|
+
late still gets its full cold-start budget.
|
|
24
35
|
- An attempt's terminal artifacts (its strict marker plus `metrics.json`) are now interpreted by
|
|
25
36
|
one shared protocol instead of being decoded separately by live instance polling and by each
|
|
26
37
|
recovery path. The two decoders disagreed about identical bytes. A marker that could not be tied
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: freesolo-flash-dev
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.59
|
|
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
|
{freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/providers/runpod/job_execution.py
RENAMED
|
@@ -18,6 +18,7 @@ from flash.providers._lifecycle.deadline import (
|
|
|
18
18
|
from flash.providers._lifecycle.poll import (
|
|
19
19
|
PollErrorTracker,
|
|
20
20
|
_attempt_int,
|
|
21
|
+
heartbeat_progress_ts,
|
|
21
22
|
is_training_heartbeat,
|
|
22
23
|
make_say,
|
|
23
24
|
surface_heartbeat,
|
|
@@ -547,6 +548,20 @@ def _classify_queue_state(
|
|
|
547
548
|
return None
|
|
548
549
|
|
|
549
550
|
|
|
551
|
+
def _progress_ts(context: _PollContext, hb_key: tuple) -> float:
|
|
552
|
+
"""The progress this heartbeat proves: its own ts, clamped to [launch, now].
|
|
553
|
+
|
|
554
|
+
The companion ``fresh`` flag is deliberately dropped. Its attempt half is already decided by the
|
|
555
|
+
caller, which returns early on any heartbeat that is not this attempt's, and its ts half is
|
|
556
|
+
already expressed in the clamp: a heartbeat stamped before launch cannot describe work this
|
|
557
|
+
attempt did, so it is worth exactly the launch anchor and no more. What remains is the
|
|
558
|
+
unusable-ts case, where the helper falls back to now; that matches the previous behaviour of
|
|
559
|
+
treating an untimestamped heartbeat as present-tense progress.
|
|
560
|
+
"""
|
|
561
|
+
ts, _fresh = heartbeat_progress_ts(hb_key, context.launch_ts, context.current_attempt)
|
|
562
|
+
return ts
|
|
563
|
+
|
|
564
|
+
|
|
550
565
|
def _update_heartbeat(context: _PollContext, state: _PollState) -> None:
|
|
551
566
|
new_key, stage = surface_heartbeat(context.heartbeat_reader, state.last_hb_key, context.say)
|
|
552
567
|
if new_key == state.last_hb_key:
|
|
@@ -575,17 +590,29 @@ def _update_heartbeat(context: _PollContext, state: _PollState) -> None:
|
|
|
575
590
|
hb_ts = new_key[2]
|
|
576
591
|
hb_step = new_key[1]
|
|
577
592
|
is_training_hb = is_training_heartbeat(stage, hb_step)
|
|
593
|
+
# Credit the heartbeat's OWN timestamp, clamped to [launch, now], never the time we happened to
|
|
594
|
+
# read it. A heartbeat written long before a reattach and only seen now describes progress that
|
|
595
|
+
# already happened; paying it out at read time hands a wedged worker a full fresh stall window
|
|
596
|
+
# on every reattach. `_progress_ts` returns that clamped value, deliberately distinct from the
|
|
597
|
+
# raw `hb_ts` above, which stays the uploaded-ts bookkeeping the advance checks below compare.
|
|
598
|
+
# A heartbeat with no usable ts still clamps to now, preserving the existing behaviour that an
|
|
599
|
+
# untimestamped heartbeat counts as progress. It is computed only where it is used: this loop's
|
|
600
|
+
# clock is observable through `_jobs.time.time`, so an unused read would be a visible side effect.
|
|
601
|
+
#
|
|
602
|
+
# heartbeat ordering is independent of other progress sources. a queue exemption or status
|
|
603
|
+
# transition may already have advanced `last_progress` beyond this heartbeat's timestamp, so
|
|
604
|
+
# preserve the newer stall anchor while updating heartbeat-specific bookkeeping.
|
|
578
605
|
if hb_attempt > state.last_hb_attempt:
|
|
579
606
|
# fresh attempt: reset ts baseline and re-derive seen_training_hb so cold-start grace rearms.
|
|
580
607
|
state.last_hb_attempt = hb_attempt
|
|
581
608
|
state.last_hb_ts = hb_ts or 0.0
|
|
582
|
-
state.last_progress =
|
|
609
|
+
state.last_progress = max(state.last_progress, _progress_ts(context, new_key))
|
|
583
610
|
state.seen_training_hb = is_training_hb
|
|
584
611
|
elif hb_attempt == state.last_hb_attempt and (hb_ts is None or hb_ts > state.last_hb_ts):
|
|
585
612
|
# gate progress on ts advancing: a stale late upload must not buy a fresh stall window.
|
|
586
613
|
if hb_ts is not None:
|
|
587
614
|
state.last_hb_ts = hb_ts
|
|
588
|
-
state.last_progress =
|
|
615
|
+
state.last_progress = max(state.last_progress, _progress_ts(context, new_key))
|
|
589
616
|
if is_training_hb:
|
|
590
617
|
state.seen_training_hb = True
|
|
591
618
|
|
|
@@ -702,7 +729,13 @@ def poll_job(
|
|
|
702
729
|
last_hb_ts=0.0,
|
|
703
730
|
# -1 sentinel < any real attempt; gates out prior-attempt leftover heartbeats
|
|
704
731
|
last_hb_attempt=-1,
|
|
705
|
-
|
|
732
|
+
# Seed from the persisted LAUNCH, not this poll's start. A reattach has been billing since
|
|
733
|
+
# launch, so a worker already wedged before we attached must not be handed a fresh setup
|
|
734
|
+
# window by the mere act of looking at it -- that is what let a restart loop keep a dead
|
|
735
|
+
# worker alive to the absolute deadline. For a job queued from the start this value is
|
|
736
|
+
# overwritten anyway by the queued exemption in `_classify_stall`, which re-anchors on every
|
|
737
|
+
# pre-grant poll; it is the ALREADY-PLACED job at poll start where the difference is real.
|
|
738
|
+
last_progress=launch_ts,
|
|
706
739
|
seen_training_hb=False,
|
|
707
740
|
last_health_probe=0.0,
|
|
708
741
|
unhealthy_timer=_jobs.GraceTimer(),
|
|
@@ -741,8 +774,13 @@ def poll_job(
|
|
|
741
774
|
state.ever_saw_worker = True
|
|
742
775
|
if status != state.last_status:
|
|
743
776
|
say(f"job {handle.job_id}: {status}")
|
|
777
|
+
# A genuine TRANSITION is progress, so it moves the clock. The FIRST observation is not a
|
|
778
|
+
# transition -- `last_status` simply starts unset -- and crediting it would throw away the
|
|
779
|
+
# launch anchor on poll one, which is exactly how a delayed reattach used to win back a
|
|
780
|
+
# whole setup window before any evidence of progress had been seen.
|
|
781
|
+
if state.last_status is not None:
|
|
782
|
+
state.last_progress = _jobs.time.time()
|
|
744
783
|
state.last_status = status
|
|
745
|
-
state.last_progress = _jobs.time.time()
|
|
746
784
|
terminal = _classify_terminal_status(context, state, provider_status, status)
|
|
747
785
|
if terminal is not None:
|
|
748
786
|
return terminal
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "freesolo-flash-dev"
|
|
3
|
-
version = "1.2.
|
|
3
|
+
version = "1.2.59"
|
|
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.59"
|
|
141
141
|
|
|
142
142
|
[tool.pytest.ini_options]
|
|
143
143
|
pythonpath = ["."]
|
|
@@ -7,6 +7,7 @@ import io
|
|
|
7
7
|
import re
|
|
8
8
|
import sys
|
|
9
9
|
import tempfile
|
|
10
|
+
import time
|
|
10
11
|
from types import SimpleNamespace
|
|
11
12
|
|
|
12
13
|
import pytest
|
|
@@ -16,6 +17,17 @@ from tests._helpers.runner import provisioned_status
|
|
|
16
17
|
_RUNPOD_FINGERPRINT = "rpk-0123456789ab"
|
|
17
18
|
|
|
18
19
|
|
|
20
|
+
def _live_clock_handle(jobs):
|
|
21
|
+
"""A handle for a test that runs on the REAL clock rather than a faked one.
|
|
22
|
+
|
|
23
|
+
The poll loop measures its stall window from the persisted launch, so the fixed 1.0 default
|
|
24
|
+
below describes a job launched in 1970: fine for a test that also fakes `jobs.time.time` onto a
|
|
25
|
+
synthetic timeline, instantly "wedged" for one that does not. Tests asserting on the status
|
|
26
|
+
machine rather than on timing use this so their launch sits on the same clock they run against.
|
|
27
|
+
"""
|
|
28
|
+
return _runpod_handle(jobs, started_ts=time.time())
|
|
29
|
+
|
|
30
|
+
|
|
19
31
|
def _runpod_handle(
|
|
20
32
|
jobs, endpoint_id="ep", endpoint_name="name", job_id="job", attempt=0, started_ts=1.0
|
|
21
33
|
):
|
|
@@ -184,7 +196,7 @@ def _poll(monkeypatch, statuses, heartbeats=None, stall_after_s=10.0):
|
|
|
184
196
|
hb_iter = iter(heartbeats) if heartbeats is not None else None
|
|
185
197
|
|
|
186
198
|
reader = (lambda force=False: next(hb_iter, None)) if hb_iter is not None else None
|
|
187
|
-
h =
|
|
199
|
+
h = _live_clock_handle(jobs)
|
|
188
200
|
ok_payload = {"acc": 1.0}
|
|
189
201
|
return jobs.poll_job(
|
|
190
202
|
h,
|
|
@@ -235,7 +247,7 @@ def test_poll_job_surfaces_heartbeat_before_terminal_return(monkeypatch):
|
|
|
235
247
|
return heartbeat
|
|
236
248
|
|
|
237
249
|
res = jobs.poll_job(
|
|
238
|
-
|
|
250
|
+
_live_clock_handle(jobs),
|
|
239
251
|
interval_s=0,
|
|
240
252
|
heartbeat_reader=read_heartbeat,
|
|
241
253
|
)
|
|
@@ -314,7 +326,7 @@ def test_poll_job_failure_detail_redacts_secrets_in_provider_error_and_stdout(mo
|
|
|
314
326
|
monkeypatch.setattr(jobs.time, "sleep", lambda s: None)
|
|
315
327
|
|
|
316
328
|
res = jobs.poll_job(
|
|
317
|
-
|
|
329
|
+
_live_clock_handle(jobs),
|
|
318
330
|
interval_s=0,
|
|
319
331
|
heartbeat_reader=lambda force=False: None,
|
|
320
332
|
)
|
|
@@ -345,7 +357,7 @@ def test_poll_job_failure_surfaces_forced_heartbeat(monkeypatch):
|
|
|
345
357
|
}
|
|
346
358
|
|
|
347
359
|
res = jobs.poll_job(
|
|
348
|
-
|
|
360
|
+
_live_clock_handle(jobs),
|
|
349
361
|
interval_s=0,
|
|
350
362
|
heartbeat_reader=lambda force=False: hb,
|
|
351
363
|
log=log,
|
|
@@ -383,7 +395,7 @@ def test_poll_job_failure_appends_worker_artifacts(monkeypatch):
|
|
|
383
395
|
)
|
|
384
396
|
|
|
385
397
|
res = jobs.poll_job(
|
|
386
|
-
|
|
398
|
+
_live_clock_handle(jobs),
|
|
387
399
|
interval_s=0,
|
|
388
400
|
heartbeat_reader=lambda force=False: None,
|
|
389
401
|
failure_detail_reader=failure_detail_reader,
|
|
@@ -423,7 +435,7 @@ def test_poll_job_platform_preempt_does_not_read_worker_artifacts(monkeypatch):
|
|
|
423
435
|
raise AssertionError("platform terminations should not read worker artifacts")
|
|
424
436
|
|
|
425
437
|
res = jobs.poll_job(
|
|
426
|
-
|
|
438
|
+
_live_clock_handle(jobs),
|
|
427
439
|
interval_s=0,
|
|
428
440
|
heartbeat_reader=lambda force=False: None,
|
|
429
441
|
failure_detail_reader=failure_detail_reader,
|
|
@@ -437,12 +449,17 @@ def _poll_failed_with_heartbeat(monkeypatch, hb):
|
|
|
437
449
|
from flash.providers.runpod import api as runpod_api
|
|
438
450
|
from flash.providers.runpod import jobs
|
|
439
451
|
|
|
440
|
-
|
|
452
|
+
# The heartbeat has to sit on the same timeline as the launch: `worker_flagged_retriable` only
|
|
453
|
+
# honours a heartbeat stamped at or after the launch it claims to describe, so a fixed ts=2.0
|
|
454
|
+
# against a real-clock launch is a 1970 artifact that is correctly ignored, and the retriable
|
|
455
|
+
# flag under test would never be read at all.
|
|
456
|
+
launch_ts = time.time()
|
|
457
|
+
hb = {"ts": launch_ts + 1.0, "attempt": 0, **hb}
|
|
441
458
|
seq = iter([{"status": "IN_PROGRESS"}, {"status": "FAILED", "error": "boom"}])
|
|
442
459
|
monkeypatch.setattr(runpod_api, "job_status", lambda eid, jid, **_kw: next(seq))
|
|
443
460
|
monkeypatch.setattr(jobs.time, "sleep", lambda s: None)
|
|
444
461
|
return jobs.poll_job(
|
|
445
|
-
_runpod_handle(jobs),
|
|
462
|
+
_runpod_handle(jobs, started_ts=launch_ts),
|
|
446
463
|
interval_s=0,
|
|
447
464
|
heartbeat_reader=lambda force=False: hb,
|
|
448
465
|
stall_after_s=10.0,
|
|
@@ -500,10 +517,17 @@ def test_poll_job_completed_decode_error_consults_worker_flags(monkeypatch):
|
|
|
500
517
|
monkeypatch.setattr(
|
|
501
518
|
runpod_api, "job_status", lambda eid, jid, **_kw: {"status": "COMPLETED", "output": bad}
|
|
502
519
|
)
|
|
520
|
+
# the heartbeat shares the launch's timeline: a retriable flag stamped before launch is stale
|
|
521
|
+
# evidence and is correctly ignored, which would make this assert on the wrong reason.
|
|
522
|
+
launch_ts = time.time()
|
|
503
523
|
res = jobs.poll_job(
|
|
504
|
-
_runpod_handle(jobs),
|
|
524
|
+
_runpod_handle(jobs, started_ts=launch_ts),
|
|
505
525
|
interval_s=0,
|
|
506
|
-
heartbeat_reader=lambda force=False: {
|
|
526
|
+
heartbeat_reader=lambda force=False: {
|
|
527
|
+
"retriable": True,
|
|
528
|
+
"attempt": 0,
|
|
529
|
+
"ts": launch_ts + 1.0,
|
|
530
|
+
},
|
|
507
531
|
failure_detail_reader=lambda force=False: "--- error_sft.txt ---\nCUDA out of memory",
|
|
508
532
|
)
|
|
509
533
|
assert res.failure == "job_preempted"
|
|
@@ -1861,7 +1885,7 @@ def test_poll_job_in_queue_then_progress_does_not_false_stall(monkeypatch):
|
|
|
1861
1885
|
"endpoint_health_for_fingerprint",
|
|
1862
1886
|
lambda eid, _fingerprint, **_kw: {"workers": {"ready": 1, "running": 1}},
|
|
1863
1887
|
)
|
|
1864
|
-
h =
|
|
1888
|
+
h = _live_clock_handle(jobs)
|
|
1865
1889
|
res = jobs.poll_job(h, interval_s=0, heartbeat_reader=lambda: None, queue_grace_s=900.0)
|
|
1866
1890
|
assert res.ok
|
|
1867
1891
|
|
|
@@ -2219,6 +2243,176 @@ def test_poll_job_stale_late_heartbeat_does_not_reset_progress(monkeypatch):
|
|
|
2219
2243
|
assert fresh_run > none_run, "a genuinely newer heartbeat does reset progress (stalls later)"
|
|
2220
2244
|
|
|
2221
2245
|
|
|
2246
|
+
@pytest.mark.parametrize(
|
|
2247
|
+
("last_hb_attempt", "last_hb_ts"),
|
|
2248
|
+
[(-1, 0.0), (0, 50.0)],
|
|
2249
|
+
ids=["first-current-attempt-heartbeat", "later-current-attempt-heartbeat"],
|
|
2250
|
+
)
|
|
2251
|
+
def test_older_heartbeat_cannot_regress_status_progress_anchor(
|
|
2252
|
+
monkeypatch, last_hb_attempt, last_hb_ts
|
|
2253
|
+
):
|
|
2254
|
+
# a queue exemption or status transition can advance the shared progress anchor beyond the
|
|
2255
|
+
# worker timestamp. a heartbeat that becomes visible later may still advance heartbeat-specific
|
|
2256
|
+
# bookkeeping, but neither credit branch may move the stall anchor backward.
|
|
2257
|
+
from flash.providers.runpod import jobs
|
|
2258
|
+
|
|
2259
|
+
job_execution = sys.modules["flash.providers.runpod.job_execution"]
|
|
2260
|
+
heartbeat_key = ("boot", None, 100.0, 0)
|
|
2261
|
+
monkeypatch.setattr(
|
|
2262
|
+
job_execution,
|
|
2263
|
+
"surface_heartbeat",
|
|
2264
|
+
lambda _reader, _last_key, _say: (heartbeat_key, "boot"),
|
|
2265
|
+
)
|
|
2266
|
+
monkeypatch.setattr(jobs.time, "time", lambda: 600.0)
|
|
2267
|
+
context = SimpleNamespace(
|
|
2268
|
+
heartbeat_reader=lambda: None,
|
|
2269
|
+
say=lambda _message: None,
|
|
2270
|
+
current_attempt=0,
|
|
2271
|
+
launch_ts=1.0,
|
|
2272
|
+
)
|
|
2273
|
+
state = SimpleNamespace(
|
|
2274
|
+
last_hb_key=None,
|
|
2275
|
+
last_hb_ts=last_hb_ts,
|
|
2276
|
+
last_hb_attempt=last_hb_attempt,
|
|
2277
|
+
last_progress=500.0,
|
|
2278
|
+
seen_training_hb=False,
|
|
2279
|
+
ever_saw_worker=True,
|
|
2280
|
+
)
|
|
2281
|
+
|
|
2282
|
+
job_execution._update_heartbeat(context, state)
|
|
2283
|
+
|
|
2284
|
+
assert state.last_progress == 500.0
|
|
2285
|
+
|
|
2286
|
+
|
|
2287
|
+
def _stall_clock_at_giveup(
|
|
2288
|
+
monkeypatch, *, started_ts, heartbeats=(), step_s=100.0, clock_at=5000.0
|
|
2289
|
+
):
|
|
2290
|
+
"""Poll an ALREADY-PLACED job and return the absolute fake-clock time it gave up at.
|
|
2291
|
+
|
|
2292
|
+
IN_PROGRESS from the first read, so the queued-capacity exemption never applies and the value
|
|
2293
|
+
seeded into ``last_progress`` is the only thing anchoring the stall window. ``clock_at`` is where
|
|
2294
|
+
this poll's wall clock starts; a ``started_ts`` well below it is a launch in the past, i.e. a
|
|
2295
|
+
delayed reattach. The handle rejects a non-positive launch, so the clock starts high rather than
|
|
2296
|
+
the launch going negative.
|
|
2297
|
+
"""
|
|
2298
|
+
from flash.providers.runpod import api as runpod_api
|
|
2299
|
+
from flash.providers.runpod import jobs
|
|
2300
|
+
|
|
2301
|
+
monkeypatch.setattr(runpod_api, "job_status", lambda eid, jid, **_kw: {"status": "IN_PROGRESS"})
|
|
2302
|
+
monkeypatch.setattr(jobs.time, "sleep", lambda s: None)
|
|
2303
|
+
state = {"t": clock_at}
|
|
2304
|
+
|
|
2305
|
+
def _time():
|
|
2306
|
+
state["t"] += step_s
|
|
2307
|
+
return state["t"]
|
|
2308
|
+
|
|
2309
|
+
monkeypatch.setattr(jobs.time, "time", _time)
|
|
2310
|
+
hbs = iter(list(heartbeats))
|
|
2311
|
+
res = jobs.poll_job(
|
|
2312
|
+
_runpod_handle(jobs, started_ts=started_ts),
|
|
2313
|
+
interval_s=0,
|
|
2314
|
+
heartbeat_reader=lambda: next(hbs, None),
|
|
2315
|
+
stall_after_s=150.0,
|
|
2316
|
+
setup_grace_s=600.0,
|
|
2317
|
+
)
|
|
2318
|
+
assert res.failure == "stalled", res
|
|
2319
|
+
return state["t"]
|
|
2320
|
+
|
|
2321
|
+
|
|
2322
|
+
def test_a_reattached_wedged_worker_is_measured_from_launch_not_from_this_polls_start(monkeypatch):
|
|
2323
|
+
# A reattach has been BILLING since launch, so the stall window has to be measured from the
|
|
2324
|
+
# persisted launch timestamp. Seeding it from `time.time()` at poll start meant every reattach
|
|
2325
|
+
# handed a worker that was already wedged a complete fresh setup window, and a supervisor that
|
|
2326
|
+
# reattaches repeatedly could keep a dead worker on a paid GPU until the run's wall deadline.
|
|
2327
|
+
#
|
|
2328
|
+
# The job is IN_PROGRESS from the first read, so the queued-capacity exemption -- which re-anchors
|
|
2329
|
+
# `last_progress` on every pre-grant poll, and is what made the wrong seed survivable for a job
|
|
2330
|
+
# queued from the start -- never fires here. This is the placed-at-attach case where the seed is
|
|
2331
|
+
# the only anchor.
|
|
2332
|
+
#
|
|
2333
|
+
# Assert on the absolute clock at give-up, not on the "no worker progress for Ns" figure in the
|
|
2334
|
+
# detail: that figure is derived from `last_progress` and reads ~the same either way, so it
|
|
2335
|
+
# cannot tell the fixed and broken code apart.
|
|
2336
|
+
# attached at launch: the setup grace has not been spent, so the full window remains.
|
|
2337
|
+
at_launch = _stall_clock_at_giveup(monkeypatch, started_ts=5000.0)
|
|
2338
|
+
# same wedge, but launched 5000s before this poll attached: that grace is already gone.
|
|
2339
|
+
long_after_launch = _stall_clock_at_giveup(monkeypatch, started_ts=1.0)
|
|
2340
|
+
assert long_after_launch < at_launch, (
|
|
2341
|
+
f"a worker wedged since a launch 5000s ago was torn down at {long_after_launch}s, no sooner "
|
|
2342
|
+
f"than one attached at launch ({at_launch}s); the stall clock anchors on poll start, not launch"
|
|
2343
|
+
)
|
|
2344
|
+
|
|
2345
|
+
|
|
2346
|
+
def test_a_heartbeat_written_before_the_reattach_buys_no_fresh_stall_window(monkeypatch):
|
|
2347
|
+
# Crediting progress at READ time means a heartbeat written long ago and surfaced now pays out a
|
|
2348
|
+
# full fresh window, so a worker that stopped producing heartbeats before we attached looks alive
|
|
2349
|
+
# for one more grace period. Credit the heartbeat's OWN ts (clamped to [launch, now]) instead:
|
|
2350
|
+
# it describes when the worker made progress, not when we got around to looking.
|
|
2351
|
+
#
|
|
2352
|
+
# Both runs see exactly ONE staged heartbeat, so the only difference is its timestamp.
|
|
2353
|
+
stale = _stall_clock_at_giveup(
|
|
2354
|
+
monkeypatch,
|
|
2355
|
+
started_ts=5000.0,
|
|
2356
|
+
heartbeats=[{"stage": "train", "step": 1, "ts": 5001.0, "attempt": 0}],
|
|
2357
|
+
)
|
|
2358
|
+
current = _stall_clock_at_giveup(
|
|
2359
|
+
monkeypatch,
|
|
2360
|
+
started_ts=5000.0,
|
|
2361
|
+
heartbeats=[{"stage": "train", "step": 1, "ts": 5400.0, "attempt": 0}],
|
|
2362
|
+
)
|
|
2363
|
+
assert stale < current, (
|
|
2364
|
+
f"a heartbeat stamped at launch (ts=5001.0) held the run to {stale}s, as long as one stamped "
|
|
2365
|
+
f"at ts=5400.0 ({current}s); progress is credited at read time, not at the heartbeat's own ts"
|
|
2366
|
+
)
|
|
2367
|
+
|
|
2368
|
+
|
|
2369
|
+
def test_a_heartbeat_from_a_prior_attempt_buys_this_attempt_no_progress(monkeypatch):
|
|
2370
|
+
# A retry reuses the same heartbeat path, so a leftover heartbeat from attempt 0 is still
|
|
2371
|
+
# readable while attempt 1 is running. Crediting it would let the PREVIOUS attempt's work stand
|
|
2372
|
+
# as proof that THIS one is progressing. The attempt identity has to gate the credit, not just
|
|
2373
|
+
# the OOM flags.
|
|
2374
|
+
#
|
|
2375
|
+
# Both runs are attempt 1 and see exactly one heartbeat; only its `attempt` field differs. The
|
|
2376
|
+
# own-attempt run gives up SOONER, which is the tell: its heartbeat is a training heartbeat, so
|
|
2377
|
+
# it both moves the clock and tightens the window from setup grace to the stall limit. The
|
|
2378
|
+
# prior-attempt heartbeat must do neither, leaving the wider setup window running from launch.
|
|
2379
|
+
# Asserting "stale lasts longer" therefore proves the heartbeat was ignored end to end; the
|
|
2380
|
+
# reverse ordering would mean prior-attempt evidence had been credited.
|
|
2381
|
+
from flash.providers.runpod import api as runpod_api
|
|
2382
|
+
from flash.providers.runpod import jobs
|
|
2383
|
+
|
|
2384
|
+
def _giveup_with(hb_attempt):
|
|
2385
|
+
monkeypatch.setattr(
|
|
2386
|
+
runpod_api, "job_status", lambda eid, jid, **_kw: {"status": "IN_PROGRESS"}
|
|
2387
|
+
)
|
|
2388
|
+
monkeypatch.setattr(jobs.time, "sleep", lambda s: None)
|
|
2389
|
+
state = {"t": 5000.0}
|
|
2390
|
+
|
|
2391
|
+
def _time():
|
|
2392
|
+
state["t"] += 100.0
|
|
2393
|
+
return state["t"]
|
|
2394
|
+
|
|
2395
|
+
monkeypatch.setattr(jobs.time, "time", _time)
|
|
2396
|
+
hbs = iter([{"stage": "train", "step": 1, "ts": 5400.0, "attempt": hb_attempt}])
|
|
2397
|
+
res = jobs.poll_job(
|
|
2398
|
+
_runpod_handle(jobs, attempt=1, started_ts=5000.0),
|
|
2399
|
+
interval_s=0,
|
|
2400
|
+
heartbeat_reader=lambda: next(hbs, None),
|
|
2401
|
+
stall_after_s=150.0,
|
|
2402
|
+
setup_grace_s=600.0,
|
|
2403
|
+
current_attempt=1,
|
|
2404
|
+
)
|
|
2405
|
+
assert res.failure == "stalled", res
|
|
2406
|
+
return state["t"]
|
|
2407
|
+
|
|
2408
|
+
stale_attempt = _giveup_with(0)
|
|
2409
|
+
this_attempt = _giveup_with(1)
|
|
2410
|
+
assert stale_attempt > this_attempt, (
|
|
2411
|
+
f"attempt 1 given only a stale attempt=0 heartbeat behaved identically to one given its "
|
|
2412
|
+
f"own ({stale_attempt}s vs {this_attempt}s); prior-attempt evidence is being credited"
|
|
2413
|
+
)
|
|
2414
|
+
|
|
2415
|
+
|
|
2222
2416
|
def test_poll_job_gapfill_step0_does_not_tighten(monkeypatch):
|
|
2223
2417
|
# The train-liveness gap-filler emits rl_step/sft_step at step=0 throughout the silent FIRST step
|
|
2224
2418
|
# (a cold vLLM rollout can run many minutes before global_step ticks to 1). That step=0 ping is a
|
|
@@ -6650,7 +6844,7 @@ def test_runpod_completed_metrics_probes_after_expired_recovery_grace(monkeypatc
|
|
|
6650
6844
|
|
|
6651
6845
|
monkeypatch.setattr(runpod_api, "job_status", completed_status)
|
|
6652
6846
|
metrics = lifecycle._runpod_completed_metrics(
|
|
6653
|
-
|
|
6847
|
+
_live_clock_handle(jobs),
|
|
6654
6848
|
deadline_at=now - lifecycle._RECOVERY_MARKER_GRACE_S - 1.0,
|
|
6655
6849
|
)
|
|
6656
6850
|
|
|
@@ -6678,7 +6872,7 @@ def test_runpod_completed_metrics_caps_probe_deadline_when_wall_deadline_far_fut
|
|
|
6678
6872
|
|
|
6679
6873
|
monkeypatch.setattr(runpod_api, "job_status", completed_status)
|
|
6680
6874
|
metrics = lifecycle._runpod_completed_metrics(
|
|
6681
|
-
|
|
6875
|
+
_live_clock_handle(jobs),
|
|
6682
6876
|
deadline_at=now + 7_200.0, # wall deadline hours in the future
|
|
6683
6877
|
)
|
|
6684
6878
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/.github/ISSUE_TEMPLATE/bug_report.yml
RENAMED
|
File without changes
|
|
File without changes
|
{freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/.github/ISSUE_TEMPLATE/feature_request.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/.github/workflows/bake-kernel-cache.yml
RENAMED
|
File without changes
|
|
File without changes
|
{freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/.github/workflows/main-source-guard.yml
RENAMED
|
File without changes
|
{freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/.github/workflows/notify-tests-repo.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/.github/workflows/version-parity.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/docker/Dockerfile.kernelcache.relayer
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/commands/env/test_evaluations.py
RENAMED
|
File without changes
|
{freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/commands/env/test_params.py
RENAMED
|
File without changes
|
{freesolo_flash_dev-1.2.58 → freesolo_flash_dev-1.2.59}/flash/cli/commands/env/test_warnings.py
RENAMED
|
File without changes
|
|
File without changes
|