openrunner-sdk 2.41.5__tar.gz → 2.41.7__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.
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/PKG-INFO +1 -1
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/CLAUDE.md +44 -1
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/__init__.py +10 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/_native.py +2 -2
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/cli.py +38 -6
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/datasets.py +73 -3
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/gpu/__init__.py +55 -18
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/install_commands.py +92 -3
- openrunner_sdk-2.41.7/openrunner/llms-full.txt +258 -0
- openrunner_sdk-2.41.7/openrunner/llms.py +49 -0
- openrunner_sdk-2.41.7/openrunner/llms.txt +42 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/sweep.py +31 -27
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/pyproject.toml +7 -1
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_datasets_module.py +70 -1
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_gpu/test_gpu_cluster.py +46 -8
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_gpu/test_sdk_gpu_api.py +20 -3
- openrunner_sdk-2.41.7/tests/test_llms.py +43 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_sweep.py +55 -2
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/.gitignore +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/=6.0 +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/=8.1 +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/README.md +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/_retry_transport.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/_safepath.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/_secret_rules.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/api_client.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/artifact.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/autoresearch.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/buffer.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/cache.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/config.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/cost.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/dataset.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/environment.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/evaluation.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/feedback.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/git_info.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/gpu/api_integration.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/gpu/cost_guard.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/gpu/gpu_types.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/gpu/price_compare.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/gpu/provider_base.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/gpu/providers/__init__.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/gpu/providers/forge_provider.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/gpu/providers/lambda_cloud.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/gpu/providers/modal_provider.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/gpu/providers/ovhcloud.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/gpu/providers/runpod.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/gpu/providers/vastai.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/gpu/runner.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/gpu/workspace_sync.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/guardrails.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/handover.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/hooks/patent-lab-post-commit +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/__init__.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/accelerate.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/anthropic_tracer.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/catboost.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/diffusers.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/fastai.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/forced_alignment.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/gladia.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/gymnasium.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/huggingface.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/hydra.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/ignite.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/jax.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/keras.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/langchain.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/lightgbm.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/lightning.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/llamaindex.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/openai_finetune.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/openai_tracer.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/optuna.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/pytorch.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/sb3.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/sklearn.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/skypilot.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/tensorflow.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/trl.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/tts.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/ultralytics.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/voice_agent.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/whisper.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/integration/xgboost.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/launch.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/machine.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/mcp_server.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/media.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/migrate.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/model.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/model_card.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/offline.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/patent_scan.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/pii.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/plot.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/projects.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/prompt.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/query_api.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/redact.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/reload.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/research.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/research_policy.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/run.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/scorers.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/sender.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/session.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/settings.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/summary.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/sync.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/system_metrics.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/tensorboard.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/tools/__init__.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/tools/patent_report.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/trace.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/transcript_formatter.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/wal.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/wandb_compat/__init__.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/wandb_compat/_shim.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/openrunner/wer.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/scripts/gen_betterleaks_rules.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/__init__.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/conftest.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/fixtures/wandb-export-mini/run-aaa/config.json +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/fixtures/wandb-export-mini/run-aaa/metadata.json +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/fixtures/wandb-export-mini/run-aaa/metrics.jsonl +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/fixtures/wandb-export-mini/run-aaa/summary.json +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/fixtures/wandb-export-mini/run-bbb/artifacts/model-checkpoint/manifest.json +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/fixtures/wandb-export-mini/run-bbb/artifacts/model-checkpoint/weights.bin +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/fixtures/wandb-export-mini/run-bbb/artifacts/sample-image/manifest.json +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/fixtures/wandb-export-mini/run-bbb/artifacts/sample-image/preview.png +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/fixtures/wandb-export-mini/run-bbb/config.json +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/fixtures/wandb-export-mini/run-bbb/metadata.json +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/fixtures/wandb-export-mini/run-bbb/metrics.jsonl +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/fixtures/wandb-export-mini/run-bbb/summary.json +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/integration/__init__.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/integration/conftest.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/integration/test_artifact_round_trip.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_alert.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_aliases.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_api_client.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_api_client_methods.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_api_client_transport.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_artifact.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_buffer.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_cache.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_class_scorers.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_cli.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_cli_artifact_sweep.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_cli_datasets.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_cli_gpu_registry_deploy.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_cli_infra.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_cli_remainder.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_cli_topup.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_config.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_evaluation.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_finish.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_git_info.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_gpu/__init__.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_gpu/conftest.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_gpu/test_cost_guard.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_gpu/test_engine_serverside.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_gpu/test_forge.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_gpu/test_governed_jobs.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_gpu/test_gpu_types.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_gpu/test_lambda.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_gpu/test_modal.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_gpu/test_ovh_training.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_gpu/test_ovhcloud.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_gpu/test_price_compare.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_gpu/test_provider_base.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_gpu/test_runner.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_gpu/test_runpod.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_gpu/test_vastai.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_gpu/test_workspace_sync.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_gpu_modal_creds.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_init.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_init_facade.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_install_commands.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_integration_fastai.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_integration_huggingface.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_integration_keras.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_integration_langchain.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_integration_lightning.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_integration_pytorch.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_integration_setA.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_integration_setB.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_integration_setC.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_integration_sklearn.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_integration_xgboost.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_launch.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_log.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_log_code.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_machine_migrate.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_mcp_decisions.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_mcp_monitor.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_mcp_predictions.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_mcp_server.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_media.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_media_extra.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_migrate.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_offline.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_offline_sync.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_patent_scan.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_pii.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_plot.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_plot_media_extra2.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_prompt_module.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_pure_modules.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_query_api.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_redact.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_reload_module.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_research_module.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_resume.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_retry_transport.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_run_module.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_sdk_cluster_j1.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_sdk_cluster_j2.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_sdk_cluster_j3.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_sdk_cluster_j4.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_sdk_core_edges.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_sdk_features.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_sender.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_session_module.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_session_sync.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_summary.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_system_metrics.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_topup_hi.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_trace.py +0 -0
- {openrunner_sdk-2.41.5 → openrunner_sdk-2.41.7}/tests/test_wandb_compat.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openrunner-sdk
|
|
3
|
-
Version: 2.41.
|
|
3
|
+
Version: 2.41.7
|
|
4
4
|
Summary: OpenRunner SDK - W&B-compatible ML experiment tracking client
|
|
5
5
|
Project-URL: Homepage, https://github.com/jqueguiner/openrunner
|
|
6
6
|
Project-URL: Repository, https://github.com/jqueguiner/openrunner
|
|
@@ -96,10 +96,11 @@ falling back to pure-Python httpx otherwise:
|
|
|
96
96
|
ord.search_dataset(repo, q, mode="mixed"|"exact", lang="fr") # BM25 / phrase, lang filter
|
|
97
97
|
ord.optimize_embedding_search(repo) # build ANN index (once)
|
|
98
98
|
ord.semantic_search(repo, q, lang="en,fr") # vector (cosine) search
|
|
99
|
+
ord.regex_search(repo, r"\bcancel(led)?\b", lang="en") # Python-re over the text column (bounded)
|
|
99
100
|
ord.word_lookup(repo, "medical,doctor", op="union"|"intersect", lang="fr") # lexical_map
|
|
100
101
|
ord.keyword_expand("medical terms in french", count=300) # LLM -> {keywords, csv, count}
|
|
101
102
|
|
|
102
|
-
# derive: mode = word (op union/intersect) | fts | exact | semantic; lang filter; append via target_repo_id
|
|
103
|
+
# derive: mode = word (op union/intersect) | fts | exact | regex | semantic; lang filter; append via target_repo_id
|
|
103
104
|
child = ord.derive_by_query(parent, keywords_csv, name="org/medical-fr",
|
|
104
105
|
mode="word", lang="fr", limit=5000)
|
|
105
106
|
ord.derive_by_query(parent, "more,terms", target_repo_id="org/medical-fr", mode="word") # append, de-dup
|
|
@@ -175,3 +176,45 @@ When the user asks about papers, research, or sessions:
|
|
|
175
176
|
- Use `mcp__openrunner__openrunner_search_research` for research plans
|
|
176
177
|
- Use `mcp__openrunner__openrunner_search_sessions` for AI session history
|
|
177
178
|
- Use `mcp__openrunner__openrunner_update_paper` to modify paper sections
|
|
179
|
+
|
|
180
|
+
## Container registry & serverless deployment
|
|
181
|
+
|
|
182
|
+
Register a container registry (Docker Hub, GHCR, Google Artifact Registry, AWS
|
|
183
|
+
ECR, Azure ACR, OVH/Harbor) once; the upstream credential is stored encrypted
|
|
184
|
+
server-side and the OpenRunner **broker** proxies pull/push — the client never
|
|
185
|
+
holds the upstream key.
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
openrunner registry add --name "Harbor ML" --url REG_URL --username U --token T --namespace NS
|
|
189
|
+
openrunner registry set-default <id> # broker fallback when the repo path is ambiguous
|
|
190
|
+
openrunner registry login # docker login the broker (short-lived token)
|
|
191
|
+
docker push <registry_host>/<namespace>/<project-slug>:<user>-<name>-<tag>
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Repo convention (`canonical_image_name`): `{namespace}/{project_slug}`, tag leads
|
|
195
|
+
with the user — e.g. `model-team/ner-email:jl-int8-v1`.
|
|
196
|
+
|
|
197
|
+
**Images link to a project = the deploy gate.** An image pushed **through the
|
|
198
|
+
broker** is **auto-linked** to its project on the manifest PUT (project resolved
|
|
199
|
+
from the repo's project-slug segment), so it appears under the project's
|
|
200
|
+
**Registry** tab (artifact page) and the project-overview **Registry** panel with
|
|
201
|
+
no manual step. Direct-to-upstream pushes (or registries that hide their catalog,
|
|
202
|
+
e.g. OVH Harbor robots can't list `_catalog`) must be linked explicitly:
|
|
203
|
+
|
|
204
|
+
```
|
|
205
|
+
openrunner deploy link IMAGE -p ORG/NAME [--registry-id UUID]
|
|
206
|
+
openrunner deploy images -p ORG/NAME # list linked images
|
|
207
|
+
openrunner deploy gpus -p ORG/NAME # deployable GPU offers
|
|
208
|
+
openrunner deploy create ... ; openrunner deploy scale <id> N ; openrunner deploy call <id> ...
|
|
209
|
+
```
|
|
210
|
+
API: `GET/POST /projects/{id}/images`, `.../deployments`. SDK:
|
|
211
|
+
`client.list_project_images(pid)`, `client.link_project_image(pid, image, registry_id=)`.
|
|
212
|
+
Slash: `/openrunner:registry`, `/openrunner:deploy`, `/openrunner:build-api`.
|
|
213
|
+
|
|
214
|
+
## Full LLM map: llms.txt
|
|
215
|
+
|
|
216
|
+
The complete end-to-end, LLM-oriented map of OpenRunner (dataset → run
|
|
217
|
+
instrumentation → GPU training → sweep → registry → deploy → handover) lives at
|
|
218
|
+
**https://openrun.gladia.io/llms-full.txt** (source: `src/web/public/llms-full.txt`),
|
|
219
|
+
with a short index at **/llms.txt**. Read the full doc to ground yourself in the
|
|
220
|
+
real commands + conventions before driving OpenRunner end-to-end for a new project.
|
|
@@ -107,15 +107,25 @@ from openrunner.datasets import (
|
|
|
107
107
|
optimize_embedding_search,
|
|
108
108
|
push_dataset,
|
|
109
109
|
search_dataset,
|
|
110
|
+
regex_search,
|
|
110
111
|
semantic_search,
|
|
111
112
|
word_lookup,
|
|
112
113
|
set_dataset_card,
|
|
113
114
|
set_storage_policy,
|
|
115
|
+
update_dataset,
|
|
114
116
|
upload_file,
|
|
115
117
|
upload_sharded,
|
|
116
118
|
upload_folder,
|
|
117
119
|
)
|
|
118
120
|
from openrunner.config import Config
|
|
121
|
+
from openrunner.llms import (
|
|
122
|
+
llms_txt,
|
|
123
|
+
llms_txt_path,
|
|
124
|
+
LLMS_TXT_URL,
|
|
125
|
+
LLMS_FULL_TXT_URL,
|
|
126
|
+
LLMS_TXT_PATH,
|
|
127
|
+
LLMS_FULL_TXT_PATH,
|
|
128
|
+
)
|
|
119
129
|
from openrunner.model import Model
|
|
120
130
|
from openrunner.prompt import MessagesPrompt, Prompt, StringPrompt
|
|
121
131
|
from openrunner.launch import LaunchJob, launch, from_run as _launch_from_run
|
|
@@ -11,8 +11,8 @@ Covered surface today: projects (incl. linked repo), artifacts/versions,
|
|
|
11
11
|
presigned downloads (selective, GIL released during transfers), container
|
|
12
12
|
registries + broker login tokens, dataset editable-overlay columns
|
|
13
13
|
(add column / set cell / edit row / get row — source columns stay read-only),
|
|
14
|
-
and dataset search + query-derivation (full-text / semantic / word
|
|
15
|
-
LLM keyword-expand, derive-by-query + derived rows).
|
|
14
|
+
and dataset search + query-derivation (full-text / semantic / regex / word
|
|
15
|
+
union·intersect, LLM keyword-expand, derive-by-query + derived rows).
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
18
|
from __future__ import annotations
|
|
@@ -863,8 +863,11 @@ def artifact_list(project: str | None, project_opt: str | None) -> None:
|
|
|
863
863
|
|
|
864
864
|
@artifact.command("get")
|
|
865
865
|
@click.argument("name")
|
|
866
|
-
@click.option("--root", "-r",
|
|
867
|
-
|
|
866
|
+
@click.option("--root", "-r", "--output", "-o", "root", default=".",
|
|
867
|
+
help="Download directory (default: .). --output/-o is an alias.")
|
|
868
|
+
@click.option("--project", "-p", default=None,
|
|
869
|
+
help="Scope the lookup to ORG/PROJECT (else searches all accessible projects)")
|
|
870
|
+
def artifact_get(name: str, root: str, project: str | None = None) -> None:
|
|
868
871
|
"""Download an artifact to a local directory.
|
|
869
872
|
|
|
870
873
|
NAME can use colon syntax: my-dataset:latest or my-model:v3.
|
|
@@ -886,8 +889,16 @@ def artifact_get(name: str, root: str) -> None:
|
|
|
886
889
|
else:
|
|
887
890
|
alias = ref
|
|
888
891
|
|
|
889
|
-
# Find artifact by listing
|
|
892
|
+
# Find artifact by listing accessible projects. When --project is given we
|
|
893
|
+
# only search that one (faster, and disambiguates a name shared across
|
|
894
|
+
# projects); otherwise fall back to scanning every accessible project.
|
|
890
895
|
projects = client.list_projects()
|
|
896
|
+
if project:
|
|
897
|
+
projects = [
|
|
898
|
+
p for p in projects
|
|
899
|
+
if project in (p.get("id"), p.get("name"), p.get("slug"),
|
|
900
|
+
f"{p.get('org_slug')}/{p.get('slug')}")
|
|
901
|
+
] or projects
|
|
891
902
|
artifact_detail = None
|
|
892
903
|
target_version_id = None
|
|
893
904
|
|
|
@@ -1135,9 +1146,12 @@ def cache_cleanup(max_size: float | None) -> None:
|
|
|
1135
1146
|
|
|
1136
1147
|
@main.command("download-artifact")
|
|
1137
1148
|
@click.argument("name")
|
|
1138
|
-
@click.option("--root", "-r",
|
|
1149
|
+
@click.option("--root", "-r", "--output", "-o", "root", default=".",
|
|
1150
|
+
help="Download directory (default: .). --output/-o is an alias.")
|
|
1151
|
+
@click.option("--project", "-p", default=None,
|
|
1152
|
+
help="Scope the lookup to ORG/PROJECT (else searches all accessible projects)")
|
|
1139
1153
|
@click.pass_context
|
|
1140
|
-
def download_artifact_cmd(ctx: click.Context, name: str, root: str) -> None:
|
|
1154
|
+
def download_artifact_cmd(ctx: click.Context, name: str, root: str, project: str | None) -> None:
|
|
1141
1155
|
"""Download an artifact to a local directory.
|
|
1142
1156
|
|
|
1143
1157
|
NAME can use colon syntax: my-dataset:latest or my-model:v3.
|
|
@@ -1145,7 +1159,7 @@ def download_artifact_cmd(ctx: click.Context, name: str, root: str) -> None:
|
|
|
1145
1159
|
|
|
1146
1160
|
This is a top-level alias for `openrunner artifact get`.
|
|
1147
1161
|
"""
|
|
1148
|
-
ctx.invoke(artifact_get, name=name, root=root)
|
|
1162
|
+
ctx.invoke(artifact_get, name=name, root=root, project=project)
|
|
1149
1163
|
|
|
1150
1164
|
|
|
1151
1165
|
@main.command("upload-artifact")
|
|
@@ -3221,6 +3235,24 @@ def version_cmd(check: bool) -> None:
|
|
|
3221
3235
|
click.echo("Up to date.")
|
|
3222
3236
|
|
|
3223
3237
|
|
|
3238
|
+
@main.command("llms")
|
|
3239
|
+
@click.option("--full", is_flag=True, help="Print the complete guide (llms-full.txt) instead of the index")
|
|
3240
|
+
@click.option("--path", "show_path", is_flag=True, help="Print the bundled file path instead of its content")
|
|
3241
|
+
def llms_cmd(full: bool, show_path: bool) -> None:
|
|
3242
|
+
"""Print the bundled LLM-oriented OpenRunner doc.
|
|
3243
|
+
|
|
3244
|
+
The short index by default, or the complete end-to-end guide with --full.
|
|
3245
|
+
Bundled in the package (works offline); also served at /llms.txt and
|
|
3246
|
+
/llms-full.txt on the instance.
|
|
3247
|
+
"""
|
|
3248
|
+
from openrunner import llms as _llms
|
|
3249
|
+
|
|
3250
|
+
if show_path:
|
|
3251
|
+
click.echo(_llms.llms_txt_path(full=full))
|
|
3252
|
+
else:
|
|
3253
|
+
click.echo(_llms.llms_txt(full=full))
|
|
3254
|
+
|
|
3255
|
+
|
|
3224
3256
|
@main.command("_update_nudge", hidden=True)
|
|
3225
3257
|
def update_nudge_cmd() -> None:
|
|
3226
3258
|
"""Print ONE update-hint line if a newer SDK exists, else nothing. Cheap:
|
|
@@ -453,11 +453,24 @@ class DatasetsClient:
|
|
|
453
453
|
complete — so the dataset's file count grows live and an interrupted run
|
|
454
454
|
is genuinely resumable (re-run with ``skip_existing`` to continue). The
|
|
455
455
|
API stays out of the byte path, so throughput is bandwidth-bound.
|
|
456
|
+
|
|
457
|
+
``skip_existing`` skips a file only when the remote copy has the SAME
|
|
458
|
+
path AND the SAME content (sha256). A file whose bytes changed since the
|
|
459
|
+
last upload is re-uploaded — a pure path match would silently drop
|
|
460
|
+
edits, making a dataset update look successful while sending nothing.
|
|
456
461
|
"""
|
|
462
|
+
import hashlib
|
|
457
463
|
import os
|
|
458
464
|
import sys
|
|
459
465
|
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
460
466
|
|
|
467
|
+
def _sha256(fp: str) -> str:
|
|
468
|
+
h = hashlib.sha256()
|
|
469
|
+
with open(fp, "rb") as fh:
|
|
470
|
+
for chunk in iter(lambda: fh.read(1024 * 1024), b""):
|
|
471
|
+
h.update(chunk)
|
|
472
|
+
return h.hexdigest()
|
|
473
|
+
|
|
461
474
|
ds = self._resolve(repo_id)
|
|
462
475
|
items: list[tuple[str, str]] = []
|
|
463
476
|
for root, _dirs, names in os.walk(folder):
|
|
@@ -469,8 +482,16 @@ class DatasetsClient:
|
|
|
469
482
|
items.append((full, rel))
|
|
470
483
|
if skip_existing:
|
|
471
484
|
try:
|
|
472
|
-
|
|
473
|
-
|
|
485
|
+
# Map remote path -> sha256. Skip a local file only when both the
|
|
486
|
+
# path and the content hash match; changed files are re-uploaded.
|
|
487
|
+
remote = {f["path"]: (f.get("sha256") or "") for f in self.list_files(repo_id)}
|
|
488
|
+
kept: list[tuple[str, str]] = []
|
|
489
|
+
for full, rel in items:
|
|
490
|
+
rsha = remote.get(rel)
|
|
491
|
+
if rsha and rsha == _sha256(full):
|
|
492
|
+
continue
|
|
493
|
+
kept.append((full, rel))
|
|
494
|
+
items = kept
|
|
474
495
|
except Exception:
|
|
475
496
|
pass
|
|
476
497
|
if not items:
|
|
@@ -794,6 +815,25 @@ class DatasetsClient:
|
|
|
794
815
|
_check(r)
|
|
795
816
|
return r.json().get("rows", r.json().get("hits", []))
|
|
796
817
|
|
|
818
|
+
def regex_search(
|
|
819
|
+
self, repo_id: str, pattern: str, *, limit: int = 20, lang: str = ""
|
|
820
|
+
) -> list[dict]:
|
|
821
|
+
"""Regex search: match a Python-``re`` ``pattern`` against the dataset's
|
|
822
|
+
text column (streamed, bounded — no index needed). Case-insensitive is
|
|
823
|
+
opt-in via an inline ``(?i)`` flag. Native core when available, else httpx.
|
|
824
|
+
Pairs with ``derive_by_query(mode="regex")`` to build a regex-derived set.
|
|
825
|
+
"""
|
|
826
|
+
ds = self._resolve(repo_id)
|
|
827
|
+
nat = self._native_client()
|
|
828
|
+
if nat is not None:
|
|
829
|
+
return nat.regex_search(str(ds.id), pattern, lang, limit).get("rows", [])
|
|
830
|
+
params: dict[str, Any] = {"q": pattern, "limit": limit, "mode": "regex"}
|
|
831
|
+
if lang:
|
|
832
|
+
params["lang"] = lang
|
|
833
|
+
r = self._http.get(f"/datasets/{ds.id}/search", params=params)
|
|
834
|
+
_check(r)
|
|
835
|
+
return r.json().get("rows", [])
|
|
836
|
+
|
|
797
837
|
def optimize_embedding_search(
|
|
798
838
|
self,
|
|
799
839
|
repo_id: str,
|
|
@@ -869,7 +909,8 @@ class DatasetsClient:
|
|
|
869
909
|
"""Create (or append to) a dataset **derived from a query** over ``repo_id``.
|
|
870
910
|
|
|
871
911
|
``mode``: "word" (``q`` = term / CSV; pairs with LLM ``keyword_expand``),
|
|
872
|
-
"fts" (BM25), "exact" (phrase), "
|
|
912
|
+
"fts" (BM25), "exact" (phrase), "regex" (``q`` = a Python-``re`` pattern
|
|
913
|
+
matched over the text column, bounded), "semantic" (vector — needs
|
|
873
914
|
``optimize_embedding_search``). ``lang`` filters by language / CSV. Pass
|
|
874
915
|
``name`` to create, or ``target_repo_id`` to append (must derive from the
|
|
875
916
|
same parent). Lineage is recorded automatically. The query runs and
|
|
@@ -988,6 +1029,24 @@ class DatasetsClient:
|
|
|
988
1029
|
_check(r)
|
|
989
1030
|
return r.json().get("columns", [])
|
|
990
1031
|
|
|
1032
|
+
def delete_column(self, repo_id: str, name: str) -> list[str]:
|
|
1033
|
+
"""Delete an editable column from an indexed dataset.
|
|
1034
|
+
|
|
1035
|
+
Miroir exact de :meth:`add_column` — retire la colonne overlay (ou de la
|
|
1036
|
+
members table d'un dérivé) ``name`` ; les colonnes source indexées
|
|
1037
|
+
("parent") restent **en lecture seule** et ne peuvent pas être supprimées.
|
|
1038
|
+
|
|
1039
|
+
Exact mirror of :meth:`add_column`: removes the overlay (or derived-member)
|
|
1040
|
+
column ``name`` — the indexed source ("parent") columns stay **read-only**
|
|
1041
|
+
and cannot be deleted. A read-only source column (or the primary key) is
|
|
1042
|
+
rejected (400); an unknown column returns 404. Returns the remaining
|
|
1043
|
+
editable column names.
|
|
1044
|
+
"""
|
|
1045
|
+
ds = self._resolve(repo_id)
|
|
1046
|
+
r = self._http.delete(f"/datasets/{ds.id}/columns/{name}")
|
|
1047
|
+
_check(r)
|
|
1048
|
+
return r.json().get("columns", [])
|
|
1049
|
+
|
|
991
1050
|
def set_cell(self, repo_id: str, debug_id: str, column: str,
|
|
992
1051
|
value: str | None = None) -> dict:
|
|
993
1052
|
"""Set ONE editable cell (creates the column on first write).
|
|
@@ -1241,6 +1300,12 @@ def add_column(repo_id: str, name: str, *, default: str | None = None) -> list[s
|
|
|
1241
1300
|
return _c().add_column(repo_id, name, default=default)
|
|
1242
1301
|
|
|
1243
1302
|
|
|
1303
|
+
def delete_column(repo_id: str, name: str) -> list[str]:
|
|
1304
|
+
"""Delete an editable column from an indexed dataset (source columns stay
|
|
1305
|
+
read-only). Module-level mirror of DatasetsClient.delete_column."""
|
|
1306
|
+
return _c().delete_column(repo_id, name)
|
|
1307
|
+
|
|
1308
|
+
|
|
1244
1309
|
def set_cell(repo_id: str, debug_id: str, column: str, value: str | None = None) -> dict:
|
|
1245
1310
|
"""Set one editable cell of a dataset row (creates the column if new)."""
|
|
1246
1311
|
return _c().set_cell(repo_id, debug_id, column, value)
|
|
@@ -1292,6 +1357,11 @@ def semantic_search(repo_id: str, query: str, **kwargs: Any) -> list[dict]:
|
|
|
1292
1357
|
return _c().semantic_search(repo_id, query, **kwargs)
|
|
1293
1358
|
|
|
1294
1359
|
|
|
1360
|
+
def regex_search(repo_id: str, pattern: str, **kwargs: Any) -> list[dict]:
|
|
1361
|
+
"""Regex search — Python-``re`` ``pattern`` over the text column (bounded)."""
|
|
1362
|
+
return _c().regex_search(repo_id, pattern, **kwargs)
|
|
1363
|
+
|
|
1364
|
+
|
|
1295
1365
|
def optimize_embedding_search(repo_id: str, **kwargs: Any) -> dict:
|
|
1296
1366
|
"""Embed rows + build the ANN index for semantic search / semantic-derive."""
|
|
1297
1367
|
return _c().optimize_embedding_search(repo_id, **kwargs)
|
|
@@ -534,25 +534,65 @@ async def terminate(
|
|
|
534
534
|
provider: str | None = None,
|
|
535
535
|
api_key: str | None = None,
|
|
536
536
|
) -> bool:
|
|
537
|
-
"""Terminate a GPU instance
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
537
|
+
"""Terminate a GPU instance.
|
|
538
|
+
|
|
539
|
+
Preferred path (governed): when no explicit ``api_key`` is passed, the
|
|
540
|
+
platform terminates the pod SERVER-SIDE — it decrypts the org's stored
|
|
541
|
+
provider key (which never leaves the API), kills the pod, VERIFIES it is
|
|
542
|
+
gone, and only then marks the instance ``terminated``. This is the only
|
|
543
|
+
path that works when the provider key lives on the platform (the common
|
|
544
|
+
case): a client-side terminate cannot see that key and would fail with
|
|
545
|
+
"No API key found for provider …".
|
|
546
|
+
|
|
547
|
+
Fallback (BYO key): when an explicit ``api_key`` is given, terminate the
|
|
548
|
+
pod directly via the provider API. The backend status is marked
|
|
549
|
+
``terminated`` ONLY if the provider kill actually succeeded — never
|
|
550
|
+
unconditionally, since a falsely-"terminated" record strands a BILLING pod
|
|
551
|
+
that our records claim is dead.
|
|
544
552
|
|
|
545
553
|
Args:
|
|
546
554
|
instance_id: Platform instance ID.
|
|
547
555
|
provider: Provider name (auto-detected from backend if None).
|
|
548
|
-
api_key: Explicit provider API key.
|
|
556
|
+
api_key: Explicit provider API key (opts into the client-side path).
|
|
549
557
|
|
|
550
558
|
Returns:
|
|
551
|
-
True if termination
|
|
559
|
+
True if termination is confirmed.
|
|
552
560
|
"""
|
|
553
561
|
api_client = _get_api_client()
|
|
554
562
|
|
|
555
|
-
|
|
563
|
+
def _stop_guard() -> None:
|
|
564
|
+
guard_entry = _active_guards.pop(instance_id, None)
|
|
565
|
+
if guard_entry:
|
|
566
|
+
guard_entry["stop"].set()
|
|
567
|
+
logger.info("Cost guard stopped for instance %s", instance_id)
|
|
568
|
+
|
|
569
|
+
# Governed server-side terminate: kills + verifies with the org's stored
|
|
570
|
+
# key. Used whenever we aren't handed an explicit BYO key.
|
|
571
|
+
if api_key is None and api_client is not None:
|
|
572
|
+
ok = api_client.terminate_instance(instance_id)
|
|
573
|
+
if ok:
|
|
574
|
+
# The API only reports success once the pod is confirmed gone.
|
|
575
|
+
inst = api_client.get_instance(instance_id) or {}
|
|
576
|
+
confirmed = inst.get("status") == "terminated"
|
|
577
|
+
if not confirmed:
|
|
578
|
+
# Non-terminal ("terminating") — the reconciler keeps retrying;
|
|
579
|
+
# surface that the pod is not yet confirmed dead.
|
|
580
|
+
logger.warning(
|
|
581
|
+
"terminate %s: server accepted but pod not yet confirmed "
|
|
582
|
+
"gone (status=%s) — the reconciler will keep retrying",
|
|
583
|
+
instance_id, inst.get("status"),
|
|
584
|
+
)
|
|
585
|
+
else:
|
|
586
|
+
_stop_guard()
|
|
587
|
+
return confirmed
|
|
588
|
+
logger.error(
|
|
589
|
+
"terminate %s: governed server-side termination failed — the pod "
|
|
590
|
+
"may still be BILLING; check `openrunner gpu ls` / provider console",
|
|
591
|
+
instance_id,
|
|
592
|
+
)
|
|
593
|
+
return False
|
|
594
|
+
|
|
595
|
+
# BYO-key path: resolve provider + provider_instance_id, then kill directly.
|
|
556
596
|
provider_instance_id = instance_id
|
|
557
597
|
if provider is None and api_client is not None:
|
|
558
598
|
instances = api_client.list_instances()
|
|
@@ -569,7 +609,6 @@ async def terminate(
|
|
|
569
609
|
logger.error("terminate: cannot determine provider for instance %s", instance_id)
|
|
570
610
|
return False
|
|
571
611
|
|
|
572
|
-
# Get provider instance and terminate
|
|
573
612
|
try:
|
|
574
613
|
prov = _get_provider_instance(provider, api_key=api_key, api_client=api_client)
|
|
575
614
|
result = await prov.terminate_instance(provider_instance_id)
|
|
@@ -577,18 +616,16 @@ async def terminate(
|
|
|
577
616
|
logger.warning("terminate: provider termination failed: %s", exc)
|
|
578
617
|
result = False
|
|
579
618
|
|
|
580
|
-
#
|
|
581
|
-
|
|
619
|
+
# Only mark terminated when the provider kill actually succeeded — a
|
|
620
|
+
# falsely-"terminated" record strands a billing pod.
|
|
621
|
+
if result and api_client is not None:
|
|
582
622
|
try:
|
|
583
623
|
api_client.update_instance_status(instance_id, "terminated")
|
|
584
624
|
except Exception as exc:
|
|
585
625
|
logger.warning("terminate: backend update failed: %s", exc)
|
|
586
626
|
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
if guard_entry:
|
|
590
|
-
guard_entry["stop"].set()
|
|
591
|
-
logger.info("Cost guard stopped for instance %s", instance_id)
|
|
627
|
+
if result:
|
|
628
|
+
_stop_guard()
|
|
592
629
|
|
|
593
630
|
return result
|
|
594
631
|
|
|
@@ -2135,7 +2135,7 @@ Give the dataset **URL** (`<base>/datasets/<id>`), the modality/tasks/languages,
|
|
|
2135
2135
|
|
|
2136
2136
|
DERIVE_DATASET_CMD = """---
|
|
2137
2137
|
name: {prefix}derive-dataset
|
|
2138
|
-
description: Derive a dataset from an existing one — either by a SEARCH QUERY (semantic / word union·intersect / fts / exact, with language filter + LLM keyword expansion) or by adding a computed column. Keeps lineage, never re-uploads the parent's media.
|
|
2138
|
+
description: Derive a dataset from an existing one — either by a SEARCH QUERY (semantic / regex / word union·intersect / fts / exact, with language filter + LLM keyword expansion) or by adding a computed column. Keeps lineage, never re-uploads the parent's media.
|
|
2139
2139
|
argument-hint: "[parent org/name] [child org/name] [--query ... | --column NAME]"
|
|
2140
2140
|
allowed-tools:
|
|
2141
2141
|
- Bash
|
|
@@ -2152,7 +2152,7 @@ Pick by intent: **subset/select rows -> A**; **annotate/flag rows -> B**.
|
|
|
2152
2152
|
|
|
2153
2153
|
---
|
|
2154
2154
|
|
|
2155
|
-
## A. Query-derivation (semantic / word union·intersect / fts / exact + lang + LLM keywords)
|
|
2155
|
+
## A. Query-derivation (semantic / regex / word union·intersect / fts / exact + lang + LLM keywords)
|
|
2156
2156
|
|
|
2157
2157
|
All server-side; the SDK delegates to the native Rust core when installed. `PARENT` must be indexed (`ds.index_dataset(...)`; for `semantic`, also `ds.optimize_embedding_search(...)`).
|
|
2158
2158
|
|
|
@@ -2177,7 +2177,7 @@ print(ds.derived_rows('ORG/medical-fr', limit=10))
|
|
|
2177
2177
|
"
|
|
2178
2178
|
```
|
|
2179
2179
|
|
|
2180
|
-
Query modes (`mode=`): `word` (CSV of terms; `op='union'|'intersect'`), `fts` (BM25), `exact` (phrase), `semantic` (vector ANN). `lang=` takes a language or CSV ("fr" / "en,fr"); "" = all. Lineage to `PARENT` is recorded automatically by `derive_by_query`.
|
|
2180
|
+
Query modes (`mode=`): `word` (CSV of terms; `op='union'|'intersect'`), `fts` (BM25), `exact` (phrase), `regex` (a Python-`re` pattern over the text column, e.g. `ds.regex_search('ORG/PARENT', r'\\bcancel(led)?\\b')` / `ds.derive_by_query('ORG/PARENT', r'\\brefund', name='ORG/refunds', mode='regex')`), `semantic` (vector ANN). `lang=` takes a language or CSV ("fr" / "en,fr"); "" = all. Lineage to `PARENT` is recorded automatically by `derive_by_query`.
|
|
2181
2181
|
|
|
2182
2182
|
---
|
|
2183
2183
|
|
|
@@ -3254,6 +3254,93 @@ directly SSH-reachable** (`publicIp:22`): SSH is only via the **proxy**
|
|
|
3254
3254
|
"""
|
|
3255
3255
|
|
|
3256
3256
|
|
|
3257
|
+
REPORT_BUG_CMD = """---
|
|
3258
|
+
name: {prefix}report-bug
|
|
3259
|
+
description: Open a GitHub issue on the OpenRunner open-source repo for a bug you hit
|
|
3260
|
+
allowed-tools:
|
|
3261
|
+
- Bash
|
|
3262
|
+
- Read
|
|
3263
|
+
- Grep
|
|
3264
|
+
- AskUserQuestion
|
|
3265
|
+
---
|
|
3266
|
+
<objective>
|
|
3267
|
+
File a high-quality bug report as a GitHub issue on the OpenRunner open-source
|
|
3268
|
+
repository when the user hits a bug (or asks to report one). Gather REAL context
|
|
3269
|
+
from this session, avoid duplicates, confirm before creating (an issue is public),
|
|
3270
|
+
and return the issue URL.
|
|
3271
|
+
</objective>
|
|
3272
|
+
|
|
3273
|
+
<preconditions>
|
|
3274
|
+
- The `gh` CLI must be installed and authenticated. Check with `gh auth status`.
|
|
3275
|
+
If it is not authenticated, tell the user to run it themselves -- suggest they
|
|
3276
|
+
type `! gh auth login` in the prompt -- then stop.
|
|
3277
|
+
- Target repo = the OpenRunner open-source repository. Detect it (below); if it
|
|
3278
|
+
cannot be resolved, fall back to `jqueguiner/openrunner`.
|
|
3279
|
+
</preconditions>
|
|
3280
|
+
|
|
3281
|
+
<process>
|
|
3282
|
+
1. Verify gh is ready: `gh auth status`. If not, stop and ask the user to
|
|
3283
|
+
`! gh auth login`.
|
|
3284
|
+
2. Resolve the target repo. Prefer an explicit OpenRunner repo. If the current
|
|
3285
|
+
directory is the OpenRunner checkout, use its origin:
|
|
3286
|
+
`gh repo view --json nameWithOwner -q .nameWithOwner`. Otherwise default to
|
|
3287
|
+
`jqueguiner/openrunner`. Store it as REPO.
|
|
3288
|
+
3. Collect context (do NOT ask the user for what you can already observe):
|
|
3289
|
+
- SDK version: `openrunner version`.
|
|
3290
|
+
- OS + Python: `python3 -V` and `uname -sr`.
|
|
3291
|
+
- The failing command and its EXACT error output (quote verbatim), the repro
|
|
3292
|
+
steps, and expected vs actual behaviour -- reconstruct these from the current
|
|
3293
|
+
session. Use AskUserQuestion ONLY for the pieces you genuinely cannot infer.
|
|
3294
|
+
4. De-dupe: search existing issues before opening a new one:
|
|
3295
|
+
`gh issue list --repo REPO --state all --search "<key error phrase>"`.
|
|
3296
|
+
If a clear match exists, show it and ask whether to comment on it
|
|
3297
|
+
(`gh issue comment <n> --repo REPO --body ...`) instead of opening a new one.
|
|
3298
|
+
5. Draft the issue using the body template below. SHOW the full title + body to
|
|
3299
|
+
the user and get EXPLICIT confirmation before creating -- an issue is public
|
|
3300
|
+
and outward-facing. Do not create it on your own initiative.
|
|
3301
|
+
6. Create it:
|
|
3302
|
+
`gh issue create --repo REPO --title "<title>" --body "<body>" --label bug`.
|
|
3303
|
+
If the `bug` label does not exist the call fails -- retry without `--label`.
|
|
3304
|
+
7. Print the returned issue URL to the user.
|
|
3305
|
+
</process>
|
|
3306
|
+
|
|
3307
|
+
<body-template>
|
|
3308
|
+
Compose the issue body as markdown with these sections (fill from real data;
|
|
3309
|
+
write "unknown" where you truly cannot determine a value -- never invent):
|
|
3310
|
+
|
|
3311
|
+
### Summary
|
|
3312
|
+
One or two sentences: what broke.
|
|
3313
|
+
|
|
3314
|
+
### Environment
|
|
3315
|
+
- openrunner-sdk: <version>
|
|
3316
|
+
- OS / Python: <uname> / <python -V>
|
|
3317
|
+
- Instance base_url: <from ~/.openrunner/settings.json, host only -- no api_key>
|
|
3318
|
+
|
|
3319
|
+
### Steps to reproduce
|
|
3320
|
+
1. ...
|
|
3321
|
+
|
|
3322
|
+
### Expected
|
|
3323
|
+
...
|
|
3324
|
+
|
|
3325
|
+
### Actual
|
|
3326
|
+
... (paste the exact error, in a fenced code block)
|
|
3327
|
+
|
|
3328
|
+
### Notes
|
|
3329
|
+
Anything else relevant (workaround found, related area of the codebase).
|
|
3330
|
+
</body-template>
|
|
3331
|
+
|
|
3332
|
+
<safety>
|
|
3333
|
+
- NEVER create the issue (or a comment) without explicit user confirmation. It is
|
|
3334
|
+
public and cannot be un-published cleanly.
|
|
3335
|
+
- REDACT secrets before including anything: strip api keys, tokens, passwords,
|
|
3336
|
+
bearer headers, `Authorization:` values, and the api_key from settings.json.
|
|
3337
|
+
Include only the base_url host, never credentials.
|
|
3338
|
+
- Quote error text verbatim (do not paraphrase the failure) -- but with secrets
|
|
3339
|
+
stripped.
|
|
3340
|
+
</safety>
|
|
3341
|
+
"""
|
|
3342
|
+
|
|
3343
|
+
|
|
3257
3344
|
FORGE_CMD = """---
|
|
3258
3345
|
name: {prefix}forge
|
|
3259
3346
|
description: Run or write a Python function on the Forge (Shadow-PaaS) serverless GPU fleet. Use for "run/launch/train on forge", "forge GPU", or writing an @app.function. Forge is a serverless PROVIDER (like Modal) -- NOT an ssh host or runner, so don't hunt ~/.ssh/config or `hosts ls`.
|
|
@@ -3577,6 +3664,7 @@ def install_claude_code() -> list[str]:
|
|
|
3577
3664
|
"unregister-machine.md": UNREGISTER_MACHINE_CMD,
|
|
3578
3665
|
"train.md": TRAIN_CMD,
|
|
3579
3666
|
"deploy.md": DEPLOY_CMD,
|
|
3667
|
+
"report-bug.md": REPORT_BUG_CMD,
|
|
3580
3668
|
"forge.md": FORGE_CMD,
|
|
3581
3669
|
}
|
|
3582
3670
|
|
|
@@ -3812,6 +3900,7 @@ def _install_all_commands_to_dir(cmd_dir: Path, prefix: str = "openrunner:") ->
|
|
|
3812
3900
|
"unregister-machine.md": UNREGISTER_MACHINE_CMD,
|
|
3813
3901
|
"train.md": TRAIN_CMD,
|
|
3814
3902
|
"deploy.md": DEPLOY_CMD,
|
|
3903
|
+
"report-bug.md": REPORT_BUG_CMD,
|
|
3815
3904
|
"forge.md": FORGE_CMD,
|
|
3816
3905
|
}
|
|
3817
3906
|
|