freesolo-flash-dev 1.2.33__tar.gz → 1.2.36__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.33 → freesolo_flash_dev-1.2.36}/PKG-INFO +1 -1
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cli/__init__.py +2 -2
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cli/commands/env/episode.py +72 -30
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cli/commands/env/eval.py +7 -4
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cli/commands/env/setup.py +9 -7
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cli/commands/env/test.py +26 -20
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cli/commands/env/test_evaluations.py +58 -4
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cli/scaffold/TRAINING.md +5 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/envs/evaluations.py +41 -7
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/runner/supervise/transitions.py +24 -3
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/serve/deploy.py +17 -9
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/serve/errors.py +16 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/routes/serving.py +3 -3
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/routes/serving_completion.py +133 -59
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/routes/serving_revisions.py +38 -7
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/routes/serving_smoke.py +109 -29
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/pyproject.toml +2 -2
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_cli_commands.py +6 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_env_evaluations.py +92 -14
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_env_test.py +370 -23
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_serve.py +11 -8
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_server_api.py +624 -47
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_server_envs_coverage.py +310 -5
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/uv.lock +1 -1
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/.dockerignore +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/.env.example +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/.github/CODEOWNERS +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/.github/dependabot.yml +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/.github/workflows/auto-rebake.yml +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/.github/workflows/bake-kernel-cache.yml +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/.github/workflows/ci.yml +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/.github/workflows/main-source-guard.yml +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/.github/workflows/notify-tests-repo.yml +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/.github/workflows/publish-dev.yml +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/.github/workflows/publish-image.yml +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/.github/workflows/publish.yml +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/.github/workflows/version-parity.yml +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/.github/workflows/worker-image.yml +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/.gitignore +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/CHANGELOG.md +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/CODE_OF_CONDUCT.md +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/CONTRIBUTING.md +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/Dockerfile +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/Dockerfile.worker +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/LICENSE +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/NOTICE +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/README.md +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/SECURITY.md +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/SELF_HOSTING.md +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/build/kernel_cache/.gitignore +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/build/kernel_cache/.keep +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/deploy/infisical/README.md +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/deploy/infisical/entrypoint.sh +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/docker/Dockerfile.kernelcache +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/docker/Dockerfile.kernelcache.relayer +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/docker/bake_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/docker/bake_pod_entry.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/docker/extract_cudart_fix.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/docker/kernel_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/docker/make_rp_handler.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/_internal/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/_internal/channel.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/_internal/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/_internal/fileio.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/_internal/logging.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/_internal/paths.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/adapters/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/adapters/artifacts.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/adapters/lora_rank.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cli/__main__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cli/commands/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cli/commands/deploy.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cli/commands/env/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cli/commands/env/eval_args.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cli/commands/env/imports.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cli/commands/env/list.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cli/commands/env/push.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cli/commands/env/retained.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cli/commands/env/test_params.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cli/commands/env/test_warnings.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cli/commands/traces.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cli/commands/train_cost.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cli/scaffold/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cli/ui/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cli/ui/cost.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cli/ui/env_panels.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cli/ui/heartbeat.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cli/ui/render.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cli/ui/tables.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cli/ui/tty.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/client/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/client/config.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/client/freesolo_api.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/client/http.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/client/runtime_secrets.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/client/shapes.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/client/specs.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/client/streaming.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/content/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/content/multimodal.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/content/structured_outputs.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/content/thinking.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/core/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/core/catalog.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/core/spec.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cost/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cost/analytical.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cost/facts.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cost/spec.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cost/types.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/plan/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/plan/kv_sizing.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/plan/model_config_probe.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/plan/recipe.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/plan/steps.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/plan/vram.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/profiling/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/profiling/dataset_profile.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/profiling/reasoning_render.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/profiling/sft_workload.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/profiling/tokenizer.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/profiling/workload_profile.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/result/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/result/accounting.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/result/rollout_samples.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/__main__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/backend_common.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/entry/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/entry/opd.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/entry/rl.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/entry/sft.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/io/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/io/heartbeat.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/io/hf.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/io/prefetch.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/io/wandb_log.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/model/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/model/adapter.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/model/decoding.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/model/lora.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/model/packing.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/opd_train.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/opd_train_runner.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/perf/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/perf/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/perf/lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/perf/liger.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/perf/memory.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/rl_train.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/rl_train_runner.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/runtime/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/runtime/kernel_warmup.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/runtime/pkg_proxy.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/runtime/rng.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/score_batcher.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/sft_train.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/sft_train_runner.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/teacher/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/teacher/client.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/teacher/encoding.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/teacher/tokenizer_align.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/core/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/core/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/core/child/glue.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/core/step_timing.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/finalize.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/opd/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/opd/batching.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/opd/bridge.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/opd/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/opd/child/bridge.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/opd/child/multiturn.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/opd/child/plugin.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/opd/child/structured.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/opd/failures.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/opd/gkd.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/opd/multiturn_validation.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/opd/overrides.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/opd/prompts.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/opd/reporting.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/opd/scoring.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/opd/state.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/opd/validation.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/rl/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/rl/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/rl/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/rl/child/multiturn.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/rl/child/plugin.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/rl/config.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/rl/inputs.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/rl/multi_turn.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/rl/scoring.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/rl/shims.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/rl/single_turn.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/rl/verl_config.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/sft/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/sft/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/train/sft/config.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/verl/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/verl/capabilities.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/verl/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/verl/child_io.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/verl/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker/verl/parallelism.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/engine/worker_entrypoint.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/envs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/envs/adapter.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/envs/base.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/envs/cache_security.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/envs/dataset_selection.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/envs/identity.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/envs/loader.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/envs/namespace_listing.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/envs/package/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/envs/package/limits.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/envs/package/unpack.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/envs/pull.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/_lifecycle/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/_lifecycle/auth.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/_lifecycle/bootstrap.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/_lifecycle/bootstrap_pip.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/_lifecycle/bootstrap_secrets.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/_lifecycle/deadline.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/_lifecycle/http.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/_lifecycle/instance.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/_lifecycle/poll.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/_lifecycle/poll_instance.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/_lifecycle/provider.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/_lifecycle/worker.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/allocator.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/artifacts/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/artifacts/hf.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/artifacts/preload_runpod.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/artifacts/weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/base.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/fit_errors.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/lambda_/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/lambda_/api.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/lambda_/auth.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/lambda_/gpus.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/lambda_/jobs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/lambda_/jobs/builders.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/lambda_/jobs/reap.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/lambda_/preflight.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/lambda_/pricing.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/preflight.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/realized.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/runpod/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/runpod/api.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/runpod/auth.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/runpod/cost.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/runpod/gpus.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/runpod/job_execution.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/runpod/jobs.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/runpod/preflight.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/runpod/pricing.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/runpod/resources.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/runpod/serverless/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/runpod/serverless/endpoints.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/sharding.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/vast/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/vast/api.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/vast/auth.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/vast/jobs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/vast/jobs/builders.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/vast/preflight.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/providers/vast/pricing.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/py.typed +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/runner/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/runner/artifacts.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/runner/attempts.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/runner/costs.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/runner/deadlines.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/runner/preparation.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/runner/reconciliation.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/runner/results/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/runner/results/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/runner/results/verified_revisions.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/runner/status.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/runner/submit.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/runner/supervise/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/runner/supervise/attach.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/runner/supervise/deploy.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/runner/supervise/lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/runner/supervise/recovery.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/runner/supervise/retry_decision.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/runner/supervise/seed_submission.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/runner/weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/schema/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/schema/fields.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/serve/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/serve/adapter_check.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/serve/export.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/serve/preflight.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/serve/responses.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/serve/streaming.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/serve/thinking.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/serve/urls.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/__main__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/app.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/billing/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/billing/charges.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/billing/retry.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/domain/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/domain/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/domain/environment_registry.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/domain/envs.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/domain/projects.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/domain/reconcile.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/domain/repo_cleanup.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/domain/run_registry.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/domain/teacher_broker.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/domain/teacher_errors.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/domain/teacher_requests.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/platform/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/platform/auth.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/platform/db.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/platform/deps.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/platform/internal_client.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/platform/locks.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/platform/runtime.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/routes/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/routes/envs.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/routes/meta.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/routes/runs.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/server/routes/teacher.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/teacher/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/teacher/limits.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/teacher/retry_contract.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/scripts/build_dev_dist.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/scripts/check_file_size.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/scripts/check_function_size.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/scripts/check_verl_pin_exists.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/scripts/scrub_history.sh +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/_helpers/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/_helpers/profile.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/_helpers/runner.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/_helpers/specs.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/_helpers/teacher.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/_helpers/vast.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/conftest.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/fixtures/math_eval.jsonl +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/fixtures/math_train.jsonl +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/live/__init__.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/live/conftest.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/live/test_lambda_live.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/live/test_runpod_live.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/live/test_sft_thinking_render_live.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/live/test_vast_live.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_accounting_coverage.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_adapter_shard_completeness.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_agent_flash_cli_contract.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_algorithms.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_allocator.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_backend_common.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_backend_jobspec_contract.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_bake_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_base_model_provenance.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_billing_retry.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_build_context_contract.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_cancel_remote.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_catalog_consistency.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_catalog_only_models.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_charge_pricing.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_cli_commands_coverage.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_cli_credential_shadowing.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_cli_errors.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_cli_estimate.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_cli_gpus_flag.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_cli_help.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_cli_main_coverage.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_cli_managed.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_cli_render_coverage.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_cli_render_theme.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_cli_traces.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_cli_wandb_warning.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_client.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_client_import_purity.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_client_server_integration.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_client_stream_reads.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_config_env_vars.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_config_overrides.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_controlled_experiment_repairs.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_cost_analytical.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_cost_equation.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_cost_estimate.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_cost_hardware.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_cost_models.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_dataset_profile.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_deploy_alias_move_warning.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_deploy_latency.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_dev_channel.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_disk_gb.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_endpoint_name.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_env_cache_evict.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_env_delete.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_env_download.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_env_download_api.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_env_list_api.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_env_list_cli.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_env_list_hub.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_env_no_install.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_env_publish.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_env_pull.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_env_pull_coverage.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_env_pull_loader_coverage.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_env_pull_managed_control_plane.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_env_push.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_env_rate_limit_resolve.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_env_ref_pinning.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_envs_coverage.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_export.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_flash_mvp.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_flash_worker.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_flashinfer_cache_dirs.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_freesolo_api_transport.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_github_urlopen_retry.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_gpu_type_single_field.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_gpus.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_grpo_params.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_grpo_resident_sizing.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_grpo_reward_batching.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_health_liveness.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_hf_retry.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_idle_endpoint_reaper.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_infisical_secrets.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_instance_bootstrap_coverage.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_internal_client.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_jobs.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_kernel_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_kv_util.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_lambda_api_coverage.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_lambda_runner.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_logging.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_login_perms.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_lora_rank_coverage.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_lora_rank_preflight.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_managed_config_fields.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_managed_hf_repo.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_metrics_schema_agent_contract.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_mig_guard.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_multi_gpu_gate.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_multimodal_training.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_named_reward_metrics.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_oom_escalate_gpu.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_opd.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_opd_limits.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_opd_multiturn_eos_boundary.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_opd_resume_safety.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_opd_train.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_orchestrator_flash.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_packing.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_packing_coverage.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_parasail_teacher.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_poll_helpers.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_preflight.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_projects.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_provider_preflight_coverage.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_provider_routing.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_provider_teardown_robustness.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_providers_symmetry.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_realized_cost.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_repo_cleanup.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_resolve_params_b.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_resume_on_retry.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_rl_train.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_rollout_samples.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_runmgmt.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_runpod_api_delete.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_runpod_key_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_runpod_key_waterfall.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_serve_reasoning_content.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_server_app_coverage.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_server_auth_singleflight.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_server_billing.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_server_checkpoints_coverage.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_server_db.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_server_locks_coverage.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_server_standalone.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_serving_context_preflight.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_serving_contract.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_serving_schema_coverage.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_sft_chunked_nll.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_sft_example_selection.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_sft_gc_off.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_sft_max_context.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_sft_startup_block.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_sft_train.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_sft_workload.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_spec_and_validation.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_step_floor.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_step_metrics.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_step_timing.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_structured_outputs.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_teacher_broker.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_teacher_encoding_contract.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_thinking_config.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_train_context_preflight.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_training_controls.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_type_comment_prose.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_vast_api.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_vast_api_coverage.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_vast_offers.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_vast_provider_coverage.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_vast_runner.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_verified_revisions.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_verifiers.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_version.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_vl_warmstart_adapter_keys.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_vram_architecture.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_wandb_link.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_wandb_naming.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_warmstart_adapter_download.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_warmstart_cross_repo.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_warmstart_error_attribution.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_worker_dryrun.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_worker_hardexit.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_worker_image.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_worker_init_heartbeat.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_worker_stack.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_worker_thinking.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_workflow_contracts.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/tests/test_workload_profile.py +0 -0
- {freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/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.36
|
|
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
|
|
@@ -738,11 +738,11 @@ def _add_deployment_commands(models_sub: argparse._SubParsersAction) -> None:
|
|
|
738
738
|
"--wait",
|
|
739
739
|
nargs="?",
|
|
740
740
|
type=_wait_seconds,
|
|
741
|
-
const=
|
|
741
|
+
const=2400.0,
|
|
742
742
|
default=None,
|
|
743
743
|
metavar="SECONDS",
|
|
744
744
|
help=(
|
|
745
|
-
"block until the requested revision is ready or failed (default timeout
|
|
745
|
+
"block until the requested revision is ready or failed (default timeout 2400s). "
|
|
746
746
|
"without it, deploy returns while the revision is still queued"
|
|
747
747
|
),
|
|
748
748
|
)
|
|
@@ -13,9 +13,11 @@ from __future__ import annotations
|
|
|
13
13
|
|
|
14
14
|
import contextlib
|
|
15
15
|
import inspect
|
|
16
|
+
import sys
|
|
16
17
|
|
|
17
18
|
from flash.cli.commands.env.test_evaluations import _evaluation_example
|
|
18
|
-
from flash.
|
|
19
|
+
from flash.cli.ui import render
|
|
20
|
+
from flash.envs.evaluations import EvalCase, EvalResult, _episode_grading_enabled
|
|
19
21
|
|
|
20
22
|
|
|
21
23
|
def _eval_module():
|
|
@@ -34,7 +36,7 @@ def _grades_episodes(suite) -> bool:
|
|
|
34
36
|
Keying off the environment scored the wrong turn there and turned a well-formed first action
|
|
35
37
|
into an error, so the suite has to say so itself.
|
|
36
38
|
"""
|
|
37
|
-
return
|
|
39
|
+
return _episode_grading_enabled(suite)
|
|
38
40
|
|
|
39
41
|
|
|
40
42
|
def _drive_episode(client, target: str, environment, case: EvalCase, args) -> dict | str:
|
|
@@ -123,7 +125,14 @@ def _effective_turn_cap(environment, state: dict) -> int:
|
|
|
123
125
|
|
|
124
126
|
|
|
125
127
|
def _score_episode_case(
|
|
126
|
-
suite,
|
|
128
|
+
suite,
|
|
129
|
+
case: EvalCase,
|
|
130
|
+
case_id: str,
|
|
131
|
+
state: dict,
|
|
132
|
+
*,
|
|
133
|
+
scorer,
|
|
134
|
+
state_style: str | None,
|
|
135
|
+
thinking: bool = False,
|
|
127
136
|
) -> EvalResult:
|
|
128
137
|
"""Grade a finished episode through the suite's own scorer.
|
|
129
138
|
|
|
@@ -134,18 +143,19 @@ def _score_episode_case(
|
|
|
134
143
|
`reward(completion, example, state)`, which is what reaches the SDK's `score_episodes`.
|
|
135
144
|
|
|
136
145
|
`EvalSuite.score(case, response)` is the published two-argument contract, so state is offered
|
|
137
|
-
only to a suite that accepts it
|
|
138
|
-
|
|
139
|
-
two-argument call and graded on the wrong text.
|
|
146
|
+
only to a suite that accepts it. The caller resolves one scorer and signature style for the
|
|
147
|
+
whole suite rather than retrying on TypeError: an error raised INSIDE a state-aware scorer must
|
|
148
|
+
not be retried as a two-argument call and graded on the wrong text.
|
|
140
149
|
"""
|
|
141
150
|
response = state.get("response_text")
|
|
142
151
|
if not isinstance(response, str):
|
|
143
152
|
turns = state.get("turns") or []
|
|
144
153
|
response = str(turns[-1]) if turns else ""
|
|
145
154
|
eval_module = _eval_module()
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
155
|
+
if state_style is None:
|
|
156
|
+
return eval_module._score_case(
|
|
157
|
+
suite, case, case_id, response, thinking=thinking, scorer=scorer
|
|
158
|
+
)
|
|
149
159
|
return eval_module._score_case(
|
|
150
160
|
suite,
|
|
151
161
|
case,
|
|
@@ -153,7 +163,8 @@ def _score_episode_case(
|
|
|
153
163
|
response,
|
|
154
164
|
thinking=thinking,
|
|
155
165
|
state=state,
|
|
156
|
-
state_keyword=
|
|
166
|
+
state_keyword=state_style == "keyword",
|
|
167
|
+
scorer=scorer,
|
|
157
168
|
)
|
|
158
169
|
|
|
159
170
|
|
|
@@ -173,27 +184,45 @@ def _state_argument(score) -> str | None:
|
|
|
173
184
|
except (TypeError, ValueError):
|
|
174
185
|
# builtins and C callables expose no signature; treat them as the published contract.
|
|
175
186
|
return None
|
|
176
|
-
named_state = next((p for p in parameters if p.name == "state"), None)
|
|
177
|
-
if named_state is not None and named_state.kind in (
|
|
178
|
-
inspect.Parameter.KEYWORD_ONLY,
|
|
179
|
-
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
180
|
-
):
|
|
181
|
-
# By keyword even where positional would also bind: it cannot land on the wrong parameter.
|
|
182
|
-
return "keyword"
|
|
183
|
-
# Checked before `*args`, since a scorer with both can take `state=` but one with only
|
|
184
|
-
# `*args` cannot.
|
|
185
|
-
if any(p.kind is inspect.Parameter.VAR_KEYWORD for p in parameters):
|
|
186
|
-
return "keyword"
|
|
187
|
-
if any(p.kind is inspect.Parameter.VAR_POSITIONAL for p in parameters):
|
|
188
|
-
return "positional"
|
|
189
187
|
positional = [
|
|
190
|
-
|
|
191
|
-
for
|
|
192
|
-
if
|
|
188
|
+
parameter
|
|
189
|
+
for parameter in parameters
|
|
190
|
+
if parameter.kind
|
|
191
|
+
in (inspect.Parameter.POSITIONAL_ONLY, inspect.Parameter.POSITIONAL_OR_KEYWORD)
|
|
193
192
|
]
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
193
|
+
named_state = next((parameter for parameter in parameters if parameter.name == "state"), None)
|
|
194
|
+
if named_state is not None:
|
|
195
|
+
if named_state.kind is inspect.Parameter.POSITIONAL_ONLY:
|
|
196
|
+
return "positional" if positional.index(named_state) == 2 else None
|
|
197
|
+
if named_state.kind in (
|
|
198
|
+
inspect.Parameter.KEYWORD_ONLY,
|
|
199
|
+
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
200
|
+
):
|
|
201
|
+
# by keyword even where positional would also bind: it cannot land on the wrong parameter.
|
|
202
|
+
return "keyword"
|
|
203
|
+
# checked before `*args`, since a scorer with both can take `state=` but one with only
|
|
204
|
+
# `*args` cannot.
|
|
205
|
+
if any(parameter.kind is inspect.Parameter.VAR_KEYWORD for parameter in parameters):
|
|
206
|
+
return "keyword"
|
|
207
|
+
if any(parameter.kind is inspect.Parameter.VAR_POSITIONAL for parameter in parameters):
|
|
208
|
+
# scorer(case, response, state) reaches *args when the signature has no fixed third slot.
|
|
209
|
+
# zero, one, or two regular positional parameters can all bind that call.
|
|
210
|
+
return "positional" if len(positional) <= 2 else None
|
|
211
|
+
return None
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def _warn_if_episode_state_is_hidden(suite, state_style: str | None) -> None:
|
|
215
|
+
"""Warn once when full-episode work feeds a scorer that cannot see the transcript."""
|
|
216
|
+
if state_style is not None:
|
|
217
|
+
return
|
|
218
|
+
message = (
|
|
219
|
+
f"suite {getattr(suite, 'name', 'evaluation')!r} sets grades_episodes = True; "
|
|
220
|
+
"each episode will still be played out with one generation per turn, but the scorer "
|
|
221
|
+
"will receive only the episode's final response text, not the transcript. Add a third "
|
|
222
|
+
"`state` argument to "
|
|
223
|
+
"`score(case, response, state)` to grade the transcript."
|
|
224
|
+
)
|
|
225
|
+
print(render.warn(message) if render.styled() else f"warning: {message}", file=sys.stderr)
|
|
197
226
|
|
|
198
227
|
|
|
199
228
|
def _run_episode_cases(
|
|
@@ -220,6 +249,9 @@ def _run_episode_cases(
|
|
|
220
249
|
)
|
|
221
250
|
for case_id in case_ids
|
|
222
251
|
)
|
|
252
|
+
scorer = getattr(suite, "score", None)
|
|
253
|
+
state_style = _state_argument(scorer)
|
|
254
|
+
_warn_if_episode_state_is_hidden(suite, state_style)
|
|
223
255
|
results = []
|
|
224
256
|
# The adapter defaults to `thinking = False` (flash/envs/adapter.py), and with it off
|
|
225
257
|
# `_scored_turn_text` returns the turn unstripped -- so `state["response_text"]` keeps its
|
|
@@ -237,7 +269,17 @@ def _run_episode_cases(
|
|
|
237
269
|
if isinstance(outcome, str):
|
|
238
270
|
results.append(eval_module._generation_error(case_id, outcome))
|
|
239
271
|
continue
|
|
240
|
-
results.append(
|
|
272
|
+
results.append(
|
|
273
|
+
_score_episode_case(
|
|
274
|
+
suite,
|
|
275
|
+
case,
|
|
276
|
+
case_id,
|
|
277
|
+
outcome,
|
|
278
|
+
scorer=scorer,
|
|
279
|
+
state_style=state_style,
|
|
280
|
+
thinking=thinking,
|
|
281
|
+
)
|
|
282
|
+
)
|
|
241
283
|
return tuple(results)
|
|
242
284
|
|
|
243
285
|
|
|
@@ -162,6 +162,7 @@ def _score_case(
|
|
|
162
162
|
thinking: bool = False,
|
|
163
163
|
state=None,
|
|
164
164
|
state_keyword: bool = False,
|
|
165
|
+
scorer=None,
|
|
165
166
|
) -> EvalResult:
|
|
166
167
|
"""Grade one response on the caller's thread.
|
|
167
168
|
|
|
@@ -172,7 +173,8 @@ def _score_case(
|
|
|
172
173
|
`episode._score_episode_case`); single-turn scoring keeps the two-argument contract.
|
|
173
174
|
`state_keyword` says which way that suite's signature can take it -- `**kwargs` and
|
|
174
175
|
keyword-only scorers reject a third positional, `*args` scorers reject the keyword -- so the
|
|
175
|
-
caller decides, having read the signature.
|
|
176
|
+
caller decides, having read the signature. Episode scoring also passes the exact callable it
|
|
177
|
+
inspected, so a descriptor cannot change shape between capability detection and invocation.
|
|
176
178
|
|
|
177
179
|
The scorer grades the stripped answer; the RESULT records the raw generation. Stripping for the
|
|
178
180
|
scorer must not shorten what is recorded, on the error path least of all -- a failed case is
|
|
@@ -182,12 +184,13 @@ def _score_case(
|
|
|
182
184
|
try:
|
|
183
185
|
scored_text = _scored_response(response, thinking=thinking)
|
|
184
186
|
recorded_response = getattr(scored_text, "raw", response)
|
|
187
|
+
score = suite.score if scorer is None else scorer
|
|
185
188
|
if state is None:
|
|
186
|
-
scored =
|
|
189
|
+
scored = score(case, scored_text)
|
|
187
190
|
elif state_keyword:
|
|
188
|
-
scored =
|
|
191
|
+
scored = score(case, scored_text, state=state)
|
|
189
192
|
else:
|
|
190
|
-
scored =
|
|
193
|
+
scored = score(case, scored_text, state)
|
|
191
194
|
return normalize_eval_result(case, recorded_response, scored, case_id=case_id)
|
|
192
195
|
except (Exception, SystemExit) as exc:
|
|
193
196
|
return EvalResult(
|
|
@@ -138,12 +138,14 @@ Given the opening prompt, does the model emit the single integer `step_episode`
|
|
|
138
138
|
to advance the game? That is a real held-out check of the action format the episode
|
|
139
139
|
depends on, and it is the honest scope of a single-shot evaluation.
|
|
140
140
|
|
|
141
|
-
To grade a finished transcript instead, set `grades_episodes = True` on the suite
|
|
142
|
-
`env eval` then plays each case out
|
|
143
|
-
the
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
141
|
+
To grade a finished transcript instead, set `grades_episodes = True` on the suite
|
|
142
|
+
and define `score(self, case, response, state)`. `env eval` then plays each case out
|
|
143
|
+
against the deployed model -- generating, stepping the environment, and repeating to
|
|
144
|
+
`max_episode_turns` -- and passes the resulting transcript in `state`; without that
|
|
145
|
+
argument the scorer receives only the episode's final response text. Such a suite
|
|
146
|
+
needs cases the environment can actually advance (the cases below carry no `output`,
|
|
147
|
+
so `step_episode` has no secret to compare against), and each case then costs one
|
|
148
|
+
generation per turn rather than one in total.
|
|
147
149
|
|
|
148
150
|
Do NOT grade these by calling `environment.reward(response, example)`: with no episode
|
|
149
151
|
state that call scores an empty transcript, so an unrelated answer can score 1.0 and
|
|
@@ -289,7 +291,7 @@ class StarterMultiTurnEnv(EnvironmentMultiTurn):
|
|
|
289
291
|
# Advance the world after one assistant action. Return done=True to end the
|
|
290
292
|
# episode, or append an observation message and keep going.
|
|
291
293
|
# `messages` already ends with this action: messages[-1]["content"] is
|
|
292
|
-
# `assistant_response`.
|
|
294
|
+
# `assistant_response`. if you rebuild state by replaying the transcript, replay
|
|
293
295
|
# `messages[:-1]` and apply `assistant_response` once, or you apply it twice.
|
|
294
296
|
try:
|
|
295
297
|
guess = int(assistant_response.strip().split()[0])
|
|
@@ -9,7 +9,10 @@ from pathlib import Path
|
|
|
9
9
|
|
|
10
10
|
from flash.cli.commands.env.episode import _effective_turn_cap
|
|
11
11
|
from flash.cli.commands.env.push import _err, _resolve_local_env_entrypoint
|
|
12
|
-
from flash.cli.commands.env.test_evaluations import
|
|
12
|
+
from flash.cli.commands.env.test_evaluations import (
|
|
13
|
+
_check_evaluation_suites,
|
|
14
|
+
_normalize_prompt_images,
|
|
15
|
+
)
|
|
13
16
|
from flash.cli.commands.env.test_params import _env_params
|
|
14
17
|
from flash.cli.commands.env.test_warnings import (
|
|
15
18
|
_warn_on_low_replay_reward,
|
|
@@ -265,9 +268,20 @@ def _drive_single_turn(env, example: dict, record: dict, *, force_echo: bool = F
|
|
|
265
268
|
)
|
|
266
269
|
|
|
267
270
|
|
|
268
|
-
def
|
|
271
|
+
def _new_multi_turn_replay_state(env, example: dict, record: dict) -> dict:
|
|
269
272
|
state = env.new_rollout_state(example)
|
|
270
273
|
record["prompt"] = _check_messages(state.get("prompt") or state.get("messages"), "prompt")
|
|
274
|
+
_normalize_prompt_images(env, example, record["prompt"])
|
|
275
|
+
return state
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
def _validate_multi_turn_reply(env, example: dict, state: dict, messages: object) -> None:
|
|
279
|
+
_check_messages(messages, "env_reply")
|
|
280
|
+
_normalize_prompt_images(env, example, [dict(message) for message in state["messages"]])
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
def _drive_multi_turn(env, example: dict, record: dict, *, force_echo: bool = False) -> None:
|
|
284
|
+
state = _new_multi_turn_replay_state(env, example, record)
|
|
271
285
|
completion = _gold_completion(env, example)
|
|
272
286
|
record["completion"] = completion
|
|
273
287
|
reference_turns = _reference_turns(completion)
|
|
@@ -326,18 +340,19 @@ def _drive_multi_turn(env, example: dict, record: dict, *, force_echo: bool = Fa
|
|
|
326
340
|
break
|
|
327
341
|
env_msgs = env.env_reply(state["messages"], state)
|
|
328
342
|
env_step_pending = False
|
|
329
|
-
if not env_msgs:
|
|
330
|
-
break
|
|
331
|
-
# the env's own reply messages feed the chat template for the next turn in the real
|
|
332
|
-
# rollout, so validate their envelope here too: a malformed reply that would break
|
|
333
|
-
# remotely must fail the episode instead of slipping through on a finite reward.
|
|
334
|
-
_check_messages(env_msgs, "env_reply")
|
|
335
343
|
if gold_finished is None and turns >= len(reference_turns):
|
|
336
344
|
# the gold answer has just run out and its last turn is applied: this is the only
|
|
337
345
|
# moment the reference can be judged on its own, before junk padding touches the state.
|
|
338
346
|
gold_finished = _episode_completed(env, state, hard_cap)
|
|
347
|
+
if not env_msgs:
|
|
348
|
+
break
|
|
339
349
|
if env.rollout_done(state, max_turns=hard_cap):
|
|
340
350
|
break
|
|
351
|
+
# the env's own reply messages feed the chat template for the next turn in the real
|
|
352
|
+
# rollout, so validate their envelope and accumulated images here too: a malformed reply
|
|
353
|
+
# that would break remotely must fail the episode instead of slipping through on a finite
|
|
354
|
+
# reward. normalize copies so the check cannot replace authoritative rollout messages.
|
|
355
|
+
_validate_multi_turn_reply(env, example, state, env_msgs)
|
|
341
356
|
|
|
342
357
|
# the driver-side exits above stop before the inter-turn env_reply, so the last replayed turn
|
|
343
358
|
# is still unapplied. a stateful env would then score a board or transcript missing the last
|
|
@@ -351,18 +366,9 @@ def _drive_multi_turn(env, example: dict, record: dict, *, force_echo: bool = Fa
|
|
|
351
366
|
# env that replied with nothing, a natural finish) -- stepping again there would be a spurious
|
|
352
367
|
# extra move. rollout_done covers the env having declared the episode over.
|
|
353
368
|
if env_step_pending and not env.rollout_done(state, hard_cap):
|
|
354
|
-
#
|
|
355
|
-
#
|
|
356
|
-
|
|
357
|
-
# makes that the common case rather than a rare one -- leaving it unchecked let an env whose
|
|
358
|
-
# final reply is malformed reach `overall: PASS`.
|
|
359
|
-
#
|
|
360
|
-
# an EMPTY reply is allowed first, exactly as the in-loop path does (`if not env_msgs:
|
|
361
|
-
# break` precedes its own `_check_messages`): an env with nothing further to observe
|
|
362
|
-
# legitimately returns nothing, and `_check_messages` rejects an empty list.
|
|
363
|
-
final_msgs = env.env_reply(state["messages"], state)
|
|
364
|
-
if final_msgs:
|
|
365
|
-
_check_messages(final_msgs, "env_reply")
|
|
369
|
+
# apply the final action's side effects, but do not validate its reply as a future prompt:
|
|
370
|
+
# no later model generation consumes it in the online path.
|
|
371
|
+
env.env_reply(state["messages"], state)
|
|
366
372
|
if gold_finished is None:
|
|
367
373
|
# the gold answer never ran out inside the loop -- it covered the whole episode, so the
|
|
368
374
|
# break came first and the mid-loop sample never fired. NOW is its moment: the deferred
|
{freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/cli/commands/env/test_evaluations.py
RENAMED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"""Offline contract checks for an environment's evaluation sidecar.
|
|
2
2
|
|
|
3
|
-
Split from `test.py` to keep that file under the 1000-line gate.
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Split from `test.py` to keep that file under the 1000-line gate. Single-turn cases validate prompt
|
|
4
|
+
construction and reference replay. Episode cases validate initial rollout and prompt construction,
|
|
5
|
+
then bind the scorer signature without executing it against unfinished state.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
8
|
from __future__ import annotations
|
|
9
9
|
|
|
10
|
+
import inspect
|
|
10
11
|
from pathlib import Path
|
|
11
12
|
|
|
12
13
|
from flash.cli.commands.env.push import _err
|
|
@@ -76,7 +77,41 @@ def _evaluation_response(env, case) -> tuple[str, str]:
|
|
|
76
77
|
return policy, response
|
|
77
78
|
|
|
78
79
|
|
|
80
|
+
def _check_episode_evaluation_prompt(env, case) -> None:
|
|
81
|
+
"""Validate the held-out case's initial rollout state and prompt without advancing it."""
|
|
82
|
+
# imported here rather than at module scope: `test.py` imports this module.
|
|
83
|
+
from flash.cli.commands.env.test import _new_multi_turn_replay_state, _new_record
|
|
84
|
+
|
|
85
|
+
_new_multi_turn_replay_state(env, _evaluation_example(case), _new_record())
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def _validate_episode_scorer_signature(scorer, case, state_style: str | None) -> None:
|
|
89
|
+
"""Bind the online scorer call shape without executing it against unfinished state."""
|
|
90
|
+
if not callable(scorer):
|
|
91
|
+
raise TypeError("evaluation suite score must be callable")
|
|
92
|
+
try:
|
|
93
|
+
signature = inspect.signature(scorer)
|
|
94
|
+
except (TypeError, ValueError):
|
|
95
|
+
# some builtins and extension callables expose no signature, so keep the permissive runtime
|
|
96
|
+
# behavior without calling them during an offline check.
|
|
97
|
+
return
|
|
98
|
+
|
|
99
|
+
response = "response"
|
|
100
|
+
state = {}
|
|
101
|
+
if state_style is None:
|
|
102
|
+
signature.bind(case, response)
|
|
103
|
+
elif state_style == "keyword":
|
|
104
|
+
signature.bind(case, response, state=state)
|
|
105
|
+
else:
|
|
106
|
+
signature.bind(case, response, state)
|
|
107
|
+
|
|
108
|
+
|
|
79
109
|
def _check_evaluation_suites(entrypoint: Path, env) -> bool:
|
|
110
|
+
from flash.cli.commands.env.episode import (
|
|
111
|
+
_grades_episodes,
|
|
112
|
+
_state_argument,
|
|
113
|
+
_warn_if_episode_state_is_hidden,
|
|
114
|
+
)
|
|
80
115
|
from flash.envs.evaluations import (
|
|
81
116
|
_DEFAULT_EVALUATIONS_PATH,
|
|
82
117
|
EvalSuiteReport,
|
|
@@ -107,9 +142,28 @@ def _check_evaluation_suites(entrypoint: Path, env) -> bool:
|
|
|
107
142
|
f"evaluation suite {suite.name} failed contract checks: suite produced no cases"
|
|
108
143
|
)
|
|
109
144
|
continue
|
|
145
|
+
episode_suite = _grades_episodes(suite)
|
|
146
|
+
if episode_suite and not getattr(env, "multi_turn", False):
|
|
147
|
+
raise TypeError(
|
|
148
|
+
"suite sets grades_episodes = True, but this environment is single-turn "
|
|
149
|
+
"and has no episode to play"
|
|
150
|
+
)
|
|
151
|
+
scorer = getattr(suite, "score", None)
|
|
152
|
+
if episode_suite:
|
|
153
|
+
state_style = _state_argument(scorer)
|
|
154
|
+
_warn_if_episode_state_is_hidden(suite, state_style)
|
|
155
|
+
for case in cases:
|
|
156
|
+
_check_episode_evaluation_prompt(env, case)
|
|
157
|
+
_validate_episode_scorer_signature(scorer, cases[0], state_style)
|
|
158
|
+
print(
|
|
159
|
+
f"evaluation suite {suite.name}: {len(cases)}/{len(cases)} cases "
|
|
160
|
+
"passed contract checks"
|
|
161
|
+
)
|
|
162
|
+
continue
|
|
163
|
+
|
|
110
164
|
for index, case in enumerate(cases, start=1):
|
|
111
165
|
_policy, response = _evaluation_response(env, case)
|
|
112
|
-
scored =
|
|
166
|
+
scored = scorer(case, response)
|
|
113
167
|
result = normalize_eval_result(
|
|
114
168
|
case,
|
|
115
169
|
response,
|
|
@@ -224,6 +224,11 @@ int, `strict=true` as a bool, and anything that does not parse as a TOML scalar
|
|
|
224
224
|
`flash env eval` takes the same two flags, for the same reason: a held-out suite scored
|
|
225
225
|
against a differently-configured environment is not measuring your run.
|
|
226
226
|
|
|
227
|
+
For a multi-turn environment, `flash env eval` still defaults to one prompt and one reply, which is
|
|
228
|
+
a valid first-action check. Set `grades_episodes = True` on a suite to play one generation per turn.
|
|
229
|
+
A scorer with the recommended `score(case, response, state)` signature receives the finished
|
|
230
|
+
transcript state; otherwise the scorer receives only the episode's final response text.
|
|
231
|
+
|
|
227
232
|
**It is also a three-example smoke test, not a dataset audit.** `flash env test` runs the
|
|
228
233
|
contract checks against the **first 3 rows only** (`_DEFAULT_EPISODES = 3`, and it iterates
|
|
229
234
|
`dataset[:episode_count]`), so a malformed prompt, a scorer that raises, or a bad episode
|
|
@@ -124,15 +124,35 @@ class EvalSuiteReport:
|
|
|
124
124
|
|
|
125
125
|
@runtime_checkable
|
|
126
126
|
class EvalSuite(Protocol):
|
|
127
|
-
"""Authoring contract for
|
|
127
|
+
"""Authoring contract for a suite that grades one model response."""
|
|
128
128
|
|
|
129
|
-
|
|
129
|
+
@property
|
|
130
|
+
def name(self) -> str: ...
|
|
130
131
|
|
|
131
132
|
def cases(self) -> list[EvalCase]: ...
|
|
132
133
|
|
|
133
134
|
def score(self, case: EvalCase, response: str) -> EvalResult | float | bool: ...
|
|
134
135
|
|
|
135
136
|
|
|
137
|
+
class EpisodeEvalSuite(Protocol):
|
|
138
|
+
"""Suite contract for full-episode play at one generation per turn.
|
|
139
|
+
|
|
140
|
+
``grades_episodes`` must be true at runtime. The finished transcript is passed in ``state``.
|
|
141
|
+
"""
|
|
142
|
+
|
|
143
|
+
@property
|
|
144
|
+
def name(self) -> str: ...
|
|
145
|
+
|
|
146
|
+
grades_episodes: bool
|
|
147
|
+
|
|
148
|
+
def cases(self) -> list[EvalCase]: ...
|
|
149
|
+
|
|
150
|
+
def score(self, case: EvalCase, response: str, state: dict) -> EvalResult | float | bool: ...
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
EvaluationSuite = EvalSuite | EpisodeEvalSuite
|
|
154
|
+
|
|
155
|
+
|
|
136
156
|
class BaseEvalSuite:
|
|
137
157
|
"""Convenience base with expected-answer substring scoring."""
|
|
138
158
|
|
|
@@ -194,8 +214,20 @@ def normalize_eval_result(
|
|
|
194
214
|
)
|
|
195
215
|
|
|
196
216
|
|
|
197
|
-
def
|
|
217
|
+
def _episode_grading_enabled(suite: EvaluationSuite) -> bool:
|
|
218
|
+
"""Return the validated full-episode grading opt-in."""
|
|
219
|
+
value = getattr(suite, "grades_episodes", False)
|
|
220
|
+
if not isinstance(value, bool):
|
|
221
|
+
name = getattr(suite, "name", "evaluation")
|
|
222
|
+
raise TypeError(
|
|
223
|
+
f"suite {name!r} grades_episodes must be a bool, got {type(value).__name__}"
|
|
224
|
+
)
|
|
225
|
+
return value
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def validate_evaluation_cases(suite: EvaluationSuite, *, source: str | Path) -> list[EvalCase]:
|
|
198
229
|
"""Load and validate one suite's cases with source-aware errors."""
|
|
230
|
+
_episode_grading_enabled(suite)
|
|
199
231
|
try:
|
|
200
232
|
cases = suite.cases()
|
|
201
233
|
except Exception as exc:
|
|
@@ -398,7 +430,7 @@ class _ScopedSuite:
|
|
|
398
430
|
|
|
399
431
|
__slots__ = ("_module_dir", "_suite")
|
|
400
432
|
|
|
401
|
-
def __init__(self, suite:
|
|
433
|
+
def __init__(self, suite: EvaluationSuite, module_dir: str) -> None:
|
|
402
434
|
self._suite = suite
|
|
403
435
|
self._module_dir = module_dir
|
|
404
436
|
|
|
@@ -492,7 +524,7 @@ def _call_factory(factory, kwargs: dict[str, object]) -> object:
|
|
|
492
524
|
return factory(*positional, **filtered_kwargs)
|
|
493
525
|
|
|
494
526
|
|
|
495
|
-
def _validate_suites(value: object, *, source: Path) -> list[
|
|
527
|
+
def _validate_suites(value: object, *, source: Path) -> list[EvaluationSuite]:
|
|
496
528
|
if not isinstance(value, (list, tuple)):
|
|
497
529
|
raise TypeError(
|
|
498
530
|
f"{source}: expected {_DEFAULT_EVALUATIONS_FACTORY}() or EVALUATIONS "
|
|
@@ -503,7 +535,7 @@ def _validate_suites(value: object, *, source: Path) -> list[EvalSuite]:
|
|
|
503
535
|
f"{source}: expected at least one evaluation suite from "
|
|
504
536
|
f"{_DEFAULT_EVALUATIONS_FACTORY}() or EVALUATIONS"
|
|
505
537
|
)
|
|
506
|
-
suites: list[
|
|
538
|
+
suites: list[EvaluationSuite] = []
|
|
507
539
|
names: set[str] = set()
|
|
508
540
|
for index, suite in enumerate(value, start=1):
|
|
509
541
|
name = getattr(suite, "name", None)
|
|
@@ -526,7 +558,7 @@ def _validate_suites(value: object, *, source: Path) -> list[EvalSuite]:
|
|
|
526
558
|
|
|
527
559
|
def load_evaluation_suites(
|
|
528
560
|
env_ref_or_path: str | Path, *, environment: object | None = None
|
|
529
|
-
) -> list[
|
|
561
|
+
) -> list[EvaluationSuite]:
|
|
530
562
|
"""Load evaluations.py beside a resolved environment entrypoint."""
|
|
531
563
|
source = _evaluation_path(env_ref_or_path)
|
|
532
564
|
if not source.is_file():
|
|
@@ -574,10 +606,12 @@ def load_evaluation_suites(
|
|
|
574
606
|
__all__ = [
|
|
575
607
|
"_DEFAULT_EVALUATIONS_PATH",
|
|
576
608
|
"BaseEvalSuite",
|
|
609
|
+
"EpisodeEvalSuite",
|
|
577
610
|
"EvalCase",
|
|
578
611
|
"EvalResult",
|
|
579
612
|
"EvalSuite",
|
|
580
613
|
"EvalSuiteReport",
|
|
614
|
+
"EvaluationSuite",
|
|
581
615
|
"_evaluation_path",
|
|
582
616
|
"has_evaluations",
|
|
583
617
|
"load_evaluation_suites",
|
{freesolo_flash_dev-1.2.33 → freesolo_flash_dev-1.2.36}/flash/runner/supervise/transitions.py
RENAMED
|
@@ -195,6 +195,25 @@ def mark_deployment_pending(
|
|
|
195
195
|
return status
|
|
196
196
|
|
|
197
197
|
|
|
198
|
+
def _confirmed_active_failed_predecessor(deployment: object, run_id: str) -> bool:
|
|
199
|
+
if not isinstance(deployment, dict):
|
|
200
|
+
return False
|
|
201
|
+
revision = deployment.get("adapter_revision")
|
|
202
|
+
parsed = parse_adapter_revision(revision) if isinstance(revision, str) else None
|
|
203
|
+
return (
|
|
204
|
+
deployment.get("state") == "failed"
|
|
205
|
+
and deployment.get("alias_activation_confirmed") is True
|
|
206
|
+
and parsed is not None
|
|
207
|
+
and parsed[0] == run_id
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def _restorable_deployment_predecessor(deployment: object, run_id: str) -> bool:
|
|
212
|
+
return (
|
|
213
|
+
isinstance(deployment, dict) and deployment.get("state") in _RESTORABLE_DEPLOYMENT_STATES
|
|
214
|
+
) or _confirmed_active_failed_predecessor(deployment, run_id)
|
|
215
|
+
|
|
216
|
+
|
|
198
217
|
def mark_deployment_failed(run_id: str, deployment: dict) -> RunStatus:
|
|
199
218
|
"""Record a failed deployment attempt while preserving the run lifecycle state."""
|
|
200
219
|
from flash.runner import _save_status_unlocked, _status_guard, get_status
|
|
@@ -212,10 +231,12 @@ def mark_deployment_failed(run_id: str, deployment: dict) -> RunStatus:
|
|
|
212
231
|
):
|
|
213
232
|
return status
|
|
214
233
|
previous = deployment.get("previous_deployment")
|
|
215
|
-
if (
|
|
234
|
+
if _restorable_deployment_predecessor(previous, run_id) and (
|
|
216
235
|
not deployment.get("activation_outcome_unknown")
|
|
217
|
-
|
|
218
|
-
|
|
236
|
+
or (
|
|
237
|
+
deployment.get("state") == "failed"
|
|
238
|
+
and _confirmed_active_failed_predecessor(previous, run_id)
|
|
239
|
+
)
|
|
219
240
|
):
|
|
220
241
|
status.deployment = {
|
|
221
242
|
**previous,
|
|
@@ -23,6 +23,7 @@ from flash.serve.errors import ( # noqa: F401 -- re-exported: callers import th
|
|
|
23
23
|
ActivationOutcomeUnknown,
|
|
24
24
|
AdapterConfigMissing,
|
|
25
25
|
AdapterTensorMissing,
|
|
26
|
+
AliasThinkingSilent,
|
|
26
27
|
RetryableServingUnavailable,
|
|
27
28
|
ServingError,
|
|
28
29
|
)
|
|
@@ -67,14 +68,15 @@ READBACK_MAX_DELAY_SECONDS = 2.0
|
|
|
67
68
|
# with margin. the floor is doubled to 10 and the per-B term covers a bigger base on top.
|
|
68
69
|
#
|
|
69
70
|
# the cap is the real constraint, and readiness is only one leg of the attempt. the same deploy also
|
|
70
|
-
# spends time
|
|
71
|
-
# its rank, the capability check, registration) and
|
|
72
|
-
#
|
|
73
|
-
# (
|
|
74
|
-
# `--wait`, or a deploy that is still progressing is reaped or reported as
|
|
71
|
+
# spends time before this wait (resolving the hub revision, downloading the adapter config to read
|
|
72
|
+
# its rank, the capability check, registration) and after it (600s of immutable smoke, activation,
|
|
73
|
+
# then 600s of alias smoke). the whole attempt must finish inside both
|
|
74
|
+
# `_DEPLOYMENT_STALE_SECONDS` (2400s, when the plane declares an in-flight attempt abandoned) and
|
|
75
|
+
# the CLI's 2400s default `--wait`, or a deploy that is still progressing is reaped or reported as
|
|
76
|
+
# failed.
|
|
75
77
|
#
|
|
76
|
-
# so the cap leaves real slack rather than just clearing smoke: 900 + 600 =
|
|
77
|
-
# the surrounding hub reads, registration, activation, and poll latency, none of which share a
|
|
78
|
+
# so the cap leaves real slack rather than just clearing smoke: 900 + 600 + 600 = 2100, keeping 300s
|
|
79
|
+
# for the surrounding hub reads, registration, activation, and poll latency, none of which share a
|
|
78
80
|
# wall-clock bound with this one.
|
|
79
81
|
#
|
|
80
82
|
# a longer budget costs little: an adapter serving REJECTS raises as soon as the revision reports
|
|
@@ -818,6 +820,7 @@ def _retryable_smoke_unavailable(
|
|
|
818
820
|
response: httpx.Response,
|
|
819
821
|
*,
|
|
820
822
|
requested_model: str,
|
|
823
|
+
expected_adapter_revision: str,
|
|
821
824
|
) -> RetryableServingUnavailable | None:
|
|
822
825
|
if response.status_code != 503:
|
|
823
826
|
return None
|
|
@@ -834,7 +837,7 @@ def _retryable_smoke_unavailable(
|
|
|
834
837
|
or error.get("retryable") is not True
|
|
835
838
|
or code not in _RETRYABLE_SMOKE_503_CODES
|
|
836
839
|
or error.get("requested_model") != requested_model
|
|
837
|
-
or error.get("adapter_revision") !=
|
|
840
|
+
or error.get("adapter_revision") != expected_adapter_revision
|
|
838
841
|
):
|
|
839
842
|
return None
|
|
840
843
|
raw_delay = response.headers.get("Retry-After") or error.get("retry_after_seconds")
|
|
@@ -854,6 +857,7 @@ def chat(
|
|
|
854
857
|
max_tokens: int = 512,
|
|
855
858
|
thinking: bool = False,
|
|
856
859
|
expected_checkpoint: str | None = None,
|
|
860
|
+
expected_adapter_revision: str | None = None,
|
|
857
861
|
timeout_s: float | None = None,
|
|
858
862
|
retry_unavailable: bool = False,
|
|
859
863
|
stop: list[str] | None = None,
|
|
@@ -887,7 +891,11 @@ def chat(
|
|
|
887
891
|
with client_context as client:
|
|
888
892
|
resp = client.post(f"{base}/chat/completions", json=body, headers=headers, timeout=timeout)
|
|
889
893
|
if retry_unavailable:
|
|
890
|
-
retryable_error = _retryable_smoke_unavailable(
|
|
894
|
+
retryable_error = _retryable_smoke_unavailable(
|
|
895
|
+
resp,
|
|
896
|
+
requested_model=run_id,
|
|
897
|
+
expected_adapter_revision=expected_adapter_revision or run_id,
|
|
898
|
+
)
|
|
891
899
|
if retryable_error is not None:
|
|
892
900
|
raise retryable_error
|
|
893
901
|
resp.raise_for_status()
|