weightslab 1.2.5__tar.gz → 1.3.0__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.
- {weightslab-1.2.5 → weightslab-1.3.0}/.github/workflows/ci.yml +52 -36
- {weightslab-1.2.5 → weightslab-1.3.0}/.github/workflows/release.yml +68 -16
- weightslab-1.3.0/AGENTS.md +275 -0
- weightslab-1.3.0/CHANGELOG.md +1 -0
- weightslab-1.3.0/PKG-INFO +393 -0
- weightslab-1.3.0/README.md +334 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/docs/configuration.rst +207 -2
- {weightslab-1.2.5 → weightslab-1.3.0}/docs/weights_studio.rst +7 -1
- {weightslab-1.2.5 → weightslab-1.3.0}/pyproject.toml +3 -1
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/__init__.py +11 -1
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/_version.py +3 -3
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/art.py +13 -13
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/backend/audit_logger.py +2 -2
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/backend/cli.py +5 -5
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/backend/dataloader_interface.py +39 -39
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/backend/ledgers.py +187 -28
- weightslab-1.3.0/weightslab/backend/logger.py +1100 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/backend/model_interface.py +7 -7
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/baseline_models/pytorch/models.py +65 -65
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/components/__init__.py +9 -9
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/components/checkpoint_manager.py +98 -98
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/components/experiment_hash.py +11 -9
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/components/global_monitoring.py +17 -10
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/components/parallel_primitives.py +15 -15
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/components/tracking.py +10 -10
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/data/array_proxy.py +3 -3
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/data/data_samples_with_ops.py +20 -20
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/data/data_utils.py +40 -33
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/data/dataframe_manager.py +76 -50
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/data/h5_array_store.py +7 -7
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/data/h5_dataframe_store.py +59 -24
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/data/point_cloud_utils.py +21 -21
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/data/sample_stats.py +6 -6
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/Docker_training/docker_in_docker/Dockerfile +1 -2
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/Docker_training/siblings_self_contained/Dockerfile +1 -2
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/Lightning/ws-classification/main.py +10 -10
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-classification/config.yaml +4 -3
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-classification/main.py +33 -25
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-clustering/face/data.py +47 -47
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-clustering/face/model.py +22 -22
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-clustering/face/signals.py +2 -2
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-clustering/face/utils.py +7 -7
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-clustering/main.py +31 -31
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-detection/main.py +26 -26
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-detection/utils/criterions.py +18 -18
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-detection/utils/data.py +15 -15
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-detection/utils/model.py +11 -11
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-generation/main.py +26 -26
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/config.yaml +2 -1
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/main.py +51 -38
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/utils/criterions.py +9 -9
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/utils/data.py +19 -8
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/utils/model.py +2 -2
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/Ultralytics/ws-detection/config.yaml +3 -3
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/Ultralytics/ws-detection/main.py +14 -10
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/Usecases/ws-2d-lidar-detection/config.yaml +1 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/Usecases/ws-2d-lidar-detection/main.py +9 -9
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/Usecases/ws-2d-lidar-detection/utils/criterions.py +4 -4
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/Usecases/ws-2d-lidar-detection/utils/data.py +8 -8
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/Usecases/ws-2d-lidar-detection/utils/model.py +12 -12
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/Usecases/ws-3d-lidar-detection/main.py +43 -43
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/Usecases/ws-3d-lidar-detection/utils/criterions.py +25 -25
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/Usecases/ws-3d-lidar-detection/utils/data.py +47 -47
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/Usecases/ws-3d-lidar-detection/utils/kitti_download.py +5 -5
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/Usecases/ws-3d-lidar-detection/utils/model.py +28 -28
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/integrations/ultralytics/__init__.py +2 -2
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/integrations/ultralytics/dataset.py +2 -2
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/integrations/ultralytics/signals.py +12 -12
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/integrations/ultralytics/trainer.py +10 -10
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/models/model_with_ops.py +4 -4
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/models/monkey_patcher.py +1 -1
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/modules/modules_with_ops.py +26 -26
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/proto/experiment_service.proto +61 -0
- weightslab-1.3.0/weightslab/proto/experiment_service_pb2.py +194 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/proto/experiment_service_pb2_grpc.py +91 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/security/cert_auth_manager.py +1 -1
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/src.py +118 -130
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/backend/test_compare_dataloaders.py +65 -65
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/backend/test_data_loader_interface.py +65 -65
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/backend/test_instance_signal_logger.py +28 -37
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/backend/test_ledgers.py +144 -28
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/backend/test_logger_core.py +80 -54
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/backend/test_ui_docker_bridge.py +15 -15
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/backend/test_write_dataframe.py +3 -3
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/backend/test_write_history.py +5 -5
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/chaos_monkeys_utests/test_grpc_chaos_monkey_robustness.py +1 -1
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/components/test_checkpoint_workflow.py +63 -63
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/components/test_global_monitoring_unit.py +21 -21
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/data/test_data_samples_with_ops.py +3 -3
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/data/test_dataframe_manager_unit.py +8 -8
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/data/test_flush_pipeline.py +7 -8
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/data/test_h5_array_store.py +1 -2
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/data/test_h5_dataframe_store.py +3 -3
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/data/test_point_cloud_utils.py +15 -15
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/gRPC/test_get_point_cloud.py +39 -1
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/gRPC/test_grpc_tag_operations.py +26 -26
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/gRPC/test_grpc_user_actions.py +53 -11
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/general/test_cli.py +86 -86
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/general/test_signals.py +10 -10
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/general/test_signals_wrapping.py +4 -4
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/integrations/test_pytorch_lightning_integration.py +112 -112
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/integrations/ultralytics/ddp/ddp_ablation.py +13 -13
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/integrations/ultralytics/ddp/ddp_test_suite.py +108 -108
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/model/test_constraint_generation.py +4 -4
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/model/test_dependency_patterns.py +6 -6
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/model/test_model_with_ops.py +1 -1
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/model/test_tracking.py +1 -1
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/modules/test_modules_with_ops.py +18 -18
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/test_secure_docker.py +1 -1
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/trainer/services/test_agent_prompt_unit.py +1 -1
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/trainer/services/test_trainer_services_server.py +1 -1
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/trainer/services/test_trainer_services_unit.py +118 -16
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/watchdog/test_lock_monitor.py +1 -1
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/watchdog/test_watchdog.py +14 -14
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/trainer/experiment_context.py +2 -2
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/trainer/services/agent/agent.py +9 -9
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/trainer/services/agent_service.py +5 -5
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/trainer/services/data_image_utils.py +3 -3
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/trainer/services/data_service.py +503 -204
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/trainer/services/experiment_service.py +246 -14
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/trainer/services/instance_merger.py +6 -6
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/trainer/services/utils/tools.py +1 -1
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/trainer/trainer_services.py +19 -12
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/trainer/trainer_tools.py +19 -19
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/ui/docker/docker-compose.yml +15 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/ui/docker/utils/build-and-deploy.sh +49 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/ui_docker_bridge.py +59 -53
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/utils/computational_graph.py +92 -92
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/utils/logs.py +1 -1
- weightslab-1.3.0/weightslab/utils/telemetry.py +152 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/utils/tools.py +18 -16
- weightslab-1.3.0/weightslab/watchdog/__init__.py +30 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/watchdog/grpc_watchdog.py +2 -2
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/watchdog/lock_monitor.py +7 -7
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/watchdog/log_level.py +1 -1
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/watchdog/watchdog.py +20 -20
- weightslab-1.3.0/weightslab.egg-info/PKG-INFO +393 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab.egg-info/SOURCES.txt +3 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab.egg-info/requires.txt +1 -1
- weightslab-1.3.0/weightslab.egg-info/scm_file_list.json +315 -0
- weightslab-1.3.0/weightslab.egg-info/scm_version.json +8 -0
- weightslab-1.2.5/AGENTS.md +0 -209
- weightslab-1.2.5/CHANGELOG.md +0 -1
- weightslab-1.2.5/PKG-INFO +0 -543
- weightslab-1.2.5/README.md +0 -484
- weightslab-1.2.5/weightslab/backend/logger.py +0 -1058
- weightslab-1.2.5/weightslab/proto/experiment_service_pb2.py +0 -180
- weightslab-1.2.5/weightslab/watchdog/__init__.py +0 -30
- weightslab-1.2.5/weightslab.egg-info/PKG-INFO +0 -543
- {weightslab-1.2.5 → weightslab-1.3.0}/.gitattributes +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/.github/workflows/docs-pages.yml +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/.gitignore +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/LICENSE +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/agent_config.yaml +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/docs/_static/.gitkeep +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/docs/_static/custom.css +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/docs/_static/favicon.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/docs/_static/logo-dark.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/docs/_static/logo-light.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/docs/_static/version-switcher.js +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/docs/_static/weights_studio_architecture.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/docs/_templates/.gitkeep +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/docs/conf.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/docs/data_exploration.rst +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/docs/four_way_approach.rst +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/docs/grpc/audit_logger.rst +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/docs/grpc/grpc_functions.rst +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/docs/grpc/index.rst +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/docs/hyperparameters.rst +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/docs/index.rst +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/docs/logger.rst +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/docs/model_interaction.rst +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/docs/pytorch_lightning.rst +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/docs/quickstart.rst +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/docs/requirements.txt +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/docs/segmentation_usecase.rst +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/docs/usecases.rst +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/docs/user_functions.rst +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/setup.cfg +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/backend/__init__.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/backend/optimizer_interface.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/baseline_models/__init__.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/baseline_models/pytorch/__init__.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/components/evaluation_controller.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/data/__init__.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/Docker_training/README.md +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/Docker_training/docker_in_docker/README.md +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/Docker_training/docker_in_docker/docker-compose.yml +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/Docker_training/docker_in_docker/entrypoint.sh +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/Docker_training/siblings_self_contained/README.md +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/Docker_training/siblings_self_contained/docker-compose.yml +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/Docker_training/siblings_self_contained/entrypoint.sh +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/Docker_training/siblings_self_contained/ui-compose.yml +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/Lightning/ws-classification/config.yaml +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-clustering/config.yaml +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-clustering/face/__init__.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-detection/README.md +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-detection/config.yaml +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-generation/config.yaml +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/images/train/0000f77c-6257be58.jpg +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/images/train/000f8d37-d4c09a0f.jpg +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/images/train/00a0f008-a315437f.jpg +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/images/train/00c12bd0-bb46e479.jpg +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/images/train/00c29c52-f9524f1e.jpg +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/images/train/00ce6f6d-50bbee62.jpg +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/images/train/00d1bafa-1b47b41c.jpg +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/images/train/00d7268f-fd4487be.jpg +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/images/train/00f0dd0f-5e9c9557.jpg +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/images/train/0a0d7f4c-ac5c3c8f.jpg +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/images/train/0a1f4fce-f9cac880.jpg +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/images/train/0a3bb2d8-c195d91e.jpg +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/images/val/b1cac6a7-04e33135.jpg +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/images/val/b1ceb32e-3f481b43.jpg +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/images/val/b1d10d08-5b108225.jpg +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/images/val/b1d22449-15fb948f.jpg +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/images/val/b1d7b3ac-5af8623b.jpg +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/images/val/b1dce572-c6a8cb5e.jpg +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/images/val/b1e1a7b8-0aec80e8.jpg +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/images/val/b1e8ad72-c3c79240.jpg +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/images/val/b1ee702d-0ae1fc10.jpg +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/images/val/b1f0efd9-37a14dda.jpg +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/images/val/b2a0648b-d8e126bc.jpg +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/images/val/b2b70230-bad4ff6e.jpg +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/labels/train/0000f77c-6257be58.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/labels/train/000f8d37-d4c09a0f.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/labels/train/00a0f008-a315437f.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/labels/train/00c12bd0-bb46e479.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/labels/train/00c29c52-f9524f1e.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/labels/train/00ce6f6d-50bbee62.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/labels/train/00d1bafa-1b47b41c.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/labels/train/00d7268f-fd4487be.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/labels/train/00f0dd0f-5e9c9557.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/labels/train/0a0d7f4c-ac5c3c8f.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/labels/train/0a1f4fce-f9cac880.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/labels/train/0a3bb2d8-c195d91e.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/labels/val/b1cac6a7-04e33135.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/labels/val/b1ceb32e-3f481b43.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/labels/val/b1d10d08-5b108225.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/labels/val/b1d22449-15fb948f.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/labels/val/b1d7b3ac-5af8623b.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/labels/val/b1dce572-c6a8cb5e.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/labels/val/b1e1a7b8-0aec80e8.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/labels/val/b1e8ad72-c3c79240.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/labels/val/b1ee702d-0ae1fc10.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/labels/val/b1f0efd9-37a14dda.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/labels/val/b2a0648b-d8e126bc.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/PyTorch/ws-segmentation/BDD_subset/labels/val/b2b70230-bad4ff6e.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/Ultralytics/ws-detection/requirements.txt +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/Usecases/ws-2d-lidar-detection/README.md +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/Usecases/ws-3d-lidar-detection/README.md +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/examples/Usecases/ws-3d-lidar-detection/config.yaml +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/integrations/__init__.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/integrations/ultralytics/README.md +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/integrations/ultralytics/_utils.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/integrations/ultralytics/collate.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/models/__init__.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/modules/__init__.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/modules/neuron_ops.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/proto/__init__.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/security/__init__.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/__init__.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/backend/__init__.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/backend/test_audit_logger.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/backend/test_cli_additional_unit.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/backend/test_model_interface_unit.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/backend/test_optimizer_interface.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/backend/test_optimizer_interface_additional_unit.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/chaos_monkeys_utests/__init__.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/components/__init__.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/components/test_experiment_hash_and_art.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/data/__init__.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/data/test_data_service_metadata_copy.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/data/test_data_utils_unit.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/gRPC/__init__.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/general/__init__.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/general/test_auditor_mode.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/general/test_hyperparams.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/general/test_logger_snapshot_rotation.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/integrations/__init__.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/model/__init__.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/model/test_logger.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/model/test_model_with_ops_unit.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/modules/__init__.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/test_src_functions.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/trainer/__init__.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/trainer/services/__init__.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/trainer/services/test_agent_service_unit.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/trainer/test_trainer_tools.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/utils/__init__.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/utils/test_computational_graph_utils_unit.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/utils/test_logs_unit.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/utils/test_modules_dependencies_unit.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/utils/test_plot_graph_render_unit.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/utils/test_plot_graph_unit.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/utils/test_shape_prop_unit.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/utils/test_utils_tools_unit.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/tests/watchdog/__init__.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/trainer/__init__.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/trainer/services/__init__.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/trainer/services/agent/__init__.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/trainer/services/agent/agent_overview/agent.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/trainer/services/agent/agent_overview/query_example.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/trainer/services/agent/agent_overview/schema.png +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/trainer/services/agent/intent_prompt.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/trainer/services/model_service.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/trainer/services/utils/__init__.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/ui/Dockerfile +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/ui/docker/.dockerignore +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/ui/docker/.env.example +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/ui/docker/DEPLOYMENT.md +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/ui/docker/nginx-entrypoint.sh +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/ui/docker/nginx.base-path.conf copy.template +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/ui/docker/nginx.base-path.conf.template +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/ui/docker/nginx.conf +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/ui/docker/test-deployment.sh +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/ui/docker/utils/generate-certs-auth-token.ps1 +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/ui/docker/utils/generate-certs-auth-token.sh +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/ui/docker/utils/test-deployment.sh +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/ui/envoy/envoy.downstream_plaintext.yaml +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/ui/envoy/envoy.downstream_upstream_plaintext.yaml +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/ui/envoy/envoy.upstream_plaintext.yaml +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/ui/envoy/envoy.yaml +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/ui/nginx.conf +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/utils/__init__.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/utils/modules_dependencies.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/utils/plot_graph.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab/utils/shape_prop.py +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab.egg-info/dependency_links.txt +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab.egg-info/entry_points.txt +0 -0
- {weightslab-1.2.5 → weightslab-1.3.0}/weightslab.egg-info/top_level.txt +0 -0
|
@@ -2,19 +2,52 @@ name: Code CI
|
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
4
|
push:
|
|
5
|
-
|
|
5
|
+
# Fire on every branch so the `gate` job below can decide whether to run.
|
|
6
|
+
# GitHub cannot filter on commit message at the event level, so we trigger
|
|
7
|
+
# broadly and gate execution: main/dev always run, other branches run only
|
|
8
|
+
# when the head commit message contains "[force ci]".
|
|
9
|
+
branches: [ '**' ]
|
|
6
10
|
tags: [ 'v*' ]
|
|
7
11
|
pull_request:
|
|
8
|
-
types: [ opened, reopened, ready_for_review ]
|
|
12
|
+
types: [ opened, reopened, ready_for_review, synchronize ]
|
|
9
13
|
workflow_dispatch:
|
|
10
14
|
|
|
11
15
|
jobs:
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
|
|
16
|
+
# Single source of truth for "should the core CI jobs run?". Reproduces the
|
|
17
|
+
# previous trigger rules (PR / manual dispatch / main / dev run; tags skip)
|
|
18
|
+
# and adds a manual escape hatch for custom branches via "[force ci]".
|
|
19
|
+
gate:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
outputs:
|
|
22
|
+
run_ci: ${{ steps.decide.outputs.run_ci }}
|
|
23
|
+
steps:
|
|
24
|
+
- name: Decide whether to run CI
|
|
25
|
+
id: decide
|
|
26
|
+
env:
|
|
27
|
+
# Evaluated by GitHub (not the shell) so the raw commit message is
|
|
28
|
+
# never interpolated into bash — avoids quoting/injection issues.
|
|
29
|
+
FORCE_CI: ${{ contains(github.event.head_commit.message, '[force ci]') }}
|
|
30
|
+
run: |
|
|
31
|
+
if [ "${{ github.event_name }}" != "push" ]; then
|
|
32
|
+
run_ci=true # PRs and manual dispatch always run
|
|
33
|
+
elif [[ "${{ github.ref }}" == refs/tags/* ]]; then
|
|
34
|
+
run_ci=false # tag pushes are handled by the release workflow
|
|
35
|
+
elif [ "${{ github.ref }}" = "refs/heads/main" ] || [ "${{ github.ref }}" = "refs/heads/dev" ] || [[ "${{ github.ref }}" == refs/heads/v* ]]; then
|
|
36
|
+
run_ci=true # default branches and release branches (v*) always run
|
|
37
|
+
elif [ "${FORCE_CI}" = "true" ]; then
|
|
38
|
+
run_ci=true # custom branch opted in via [force ci]
|
|
39
|
+
else
|
|
40
|
+
run_ci=false # custom branch without [force ci] → skip
|
|
41
|
+
fi
|
|
42
|
+
echo "run_ci=${run_ci}" >> "$GITHUB_OUTPUT"
|
|
43
|
+
echo "Decision: run_ci=${run_ci} (event=${{ github.event_name }}, ref=${{ github.ref }}, force_ci=${FORCE_CI})"
|
|
44
|
+
# Required gate: a lint violation here FAILS the CI run. Nothing `needs` this
|
|
45
|
+
# job, so it runs in parallel with install/test/build — its failure turns the
|
|
46
|
+
# run red but does NOT stop the other jobs from running (GitHub Actions does
|
|
47
|
+
# not cancel sibling jobs on failure).
|
|
16
48
|
code-quality:
|
|
17
|
-
|
|
49
|
+
needs: gate
|
|
50
|
+
if: ${{ needs.gate.outputs.run_ci == 'true' }}
|
|
18
51
|
runs-on: ubuntu-latest
|
|
19
52
|
steps:
|
|
20
53
|
- name: Checkout repository
|
|
@@ -24,7 +57,7 @@ jobs:
|
|
|
24
57
|
|
|
25
58
|
- name: Set up Python
|
|
26
59
|
id: setup-python
|
|
27
|
-
uses: actions/setup-python@
|
|
60
|
+
uses: actions/setup-python@v6
|
|
28
61
|
with:
|
|
29
62
|
python-version: '3.11'
|
|
30
63
|
|
|
@@ -99,7 +132,8 @@ jobs:
|
|
|
99
132
|
# Single-version install on 3.11 — always runs so `test` has a gate to
|
|
100
133
|
# depend on regardless of branch.
|
|
101
134
|
install:
|
|
102
|
-
|
|
135
|
+
needs: gate
|
|
136
|
+
if: ${{ needs.gate.outputs.run_ci == 'true' }}
|
|
103
137
|
runs-on: ubuntu-latest
|
|
104
138
|
name: install (Python 3.11)
|
|
105
139
|
steps:
|
|
@@ -107,7 +141,7 @@ jobs:
|
|
|
107
141
|
uses: actions/checkout@v4
|
|
108
142
|
|
|
109
143
|
- name: Set up Python 3.11
|
|
110
|
-
uses: actions/setup-python@
|
|
144
|
+
uses: actions/setup-python@v6
|
|
111
145
|
with:
|
|
112
146
|
python-version: '3.11'
|
|
113
147
|
|
|
@@ -145,7 +179,7 @@ jobs:
|
|
|
145
179
|
uses: actions/checkout@v4
|
|
146
180
|
|
|
147
181
|
- name: Set up Python ${{ matrix.python-version }}
|
|
148
|
-
uses: actions/setup-python@
|
|
182
|
+
uses: actions/setup-python@v6
|
|
149
183
|
with:
|
|
150
184
|
python-version: ${{ matrix.python-version }}
|
|
151
185
|
allow-prereleases: ${{ matrix.allow-prereleases || false }}
|
|
@@ -160,16 +194,17 @@ jobs:
|
|
|
160
194
|
python -c "import weightslab; print(f'weightslab imported successfully on Python ${{ matrix.python-version }}')"
|
|
161
195
|
|
|
162
196
|
test:
|
|
163
|
-
if: ${{
|
|
197
|
+
if: ${{ needs.gate.outputs.run_ci == 'true' }}
|
|
164
198
|
runs-on: ubuntu-latest
|
|
165
|
-
# Depends on the fast 3.11 gate
|
|
166
|
-
|
|
199
|
+
# Depends on the fast 3.11 install gate; `gate` is also a direct need so this
|
|
200
|
+
# job can read run_ci (the matrix and main-only jobs run independently).
|
|
201
|
+
needs: [ gate, install ]
|
|
167
202
|
steps:
|
|
168
203
|
- name: Checkout repository
|
|
169
204
|
uses: actions/checkout@v4
|
|
170
205
|
|
|
171
206
|
- name: Set up Python
|
|
172
|
-
uses: actions/setup-python@
|
|
207
|
+
uses: actions/setup-python@v6
|
|
173
208
|
with:
|
|
174
209
|
python-version: '3.11'
|
|
175
210
|
|
|
@@ -188,25 +223,6 @@ jobs:
|
|
|
188
223
|
# A per-test timeout guards against any regression that hangs a test.
|
|
189
224
|
python -m pytest ./weightslab/tests -v --timeout=300
|
|
190
225
|
|
|
191
|
-
# TODO (GP): WL CI do not find WS CI for now; token or visibility problem ??
|
|
192
|
-
# - name: Trigger WeightsStudio CI
|
|
193
|
-
# env:
|
|
194
|
-
# WS_TOKEN: ${{ secrets.WEIGHTS_STUDIO_API_TOKEN }}
|
|
195
|
-
# run: |
|
|
196
|
-
# if [ -z "${WS_TOKEN}" ]; then
|
|
197
|
-
# echo "WEIGHTS_STUDIO_API_TOKEN not set; skipping WeightsStudio trigger."
|
|
198
|
-
# exit 0
|
|
199
|
-
# fi
|
|
200
|
-
|
|
201
|
-
# # Trigger the ws-ci workflow in the weights_studio repository on main.
|
|
202
|
-
# curl -fSs -X POST "https://api.github.com/repos/GrayboxTech/weights_studio/actions/workflows/ws-ci.yml/dispatches" \
|
|
203
|
-
# -H "Authorization: Bearer ${WS_TOKEN}" \
|
|
204
|
-
# -H "Accept: application/vnd.github+json" \
|
|
205
|
-
# -H "Content-Type: application/json" \
|
|
206
|
-
# -d '{"ref":"main"}'
|
|
207
|
-
|
|
208
|
-
# echo "WeightsStudio workflow dispatch requested successfully."
|
|
209
|
-
|
|
210
226
|
build-and-publish-dev:
|
|
211
227
|
# Only publish to TestPyPI when pushing to main (not on PRs or dev branch pushes).
|
|
212
228
|
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
|
|
@@ -224,7 +240,7 @@ jobs:
|
|
|
224
240
|
fetch-depth: 0
|
|
225
241
|
|
|
226
242
|
- name: Set up Python
|
|
227
|
-
uses: actions/setup-python@
|
|
243
|
+
uses: actions/setup-python@v6
|
|
228
244
|
with:
|
|
229
245
|
python-version: '3.11'
|
|
230
246
|
|
|
@@ -316,7 +332,7 @@ jobs:
|
|
|
316
332
|
contents: read
|
|
317
333
|
steps:
|
|
318
334
|
- name: Set up Python ${{ matrix.python-version }}
|
|
319
|
-
uses: actions/setup-python@
|
|
335
|
+
uses: actions/setup-python@v6
|
|
320
336
|
with:
|
|
321
337
|
python-version: ${{ matrix.python-version }}
|
|
322
338
|
allow-prereleases: ${{ matrix.allow-prereleases || false }}
|
|
@@ -40,20 +40,25 @@ jobs:
|
|
|
40
40
|
steps:
|
|
41
41
|
- uses: actions/checkout@v4
|
|
42
42
|
|
|
43
|
-
- uses: actions/setup-python@
|
|
43
|
+
- uses: actions/setup-python@v6
|
|
44
44
|
with:
|
|
45
45
|
python-version: '3.11'
|
|
46
46
|
|
|
47
47
|
- name: Install dependencies
|
|
48
48
|
run: |
|
|
49
49
|
python -m pip install --upgrade pip
|
|
50
|
-
|
|
50
|
+
# Install the test extra so pytest, graphviz, torchmetrics,
|
|
51
|
+
# pytorch-lightning and tensorboard are available (several test modules
|
|
52
|
+
# import pytest / use pytest fixtures and cannot run under bare unittest).
|
|
53
|
+
python -m pip install .[utest] --extra-index-url https://download.pytorch.org/whl/cpu
|
|
54
|
+
python -m pip install pytest-timeout
|
|
51
55
|
|
|
52
56
|
- name: Run tests
|
|
53
57
|
run: |
|
|
54
58
|
export WEIGHTSLAB_LOG_LEVEL="DEBUG"
|
|
55
59
|
python -m pip install pytorch_lightning
|
|
56
|
-
python -m unittest discover -s ./weightslab/tests -p "test_*.py" -t . -v
|
|
60
|
+
# python -m unittest discover -s ./weightslab/tests -p "test_*.py" -t . -v
|
|
61
|
+
python -m pytest ./weightslab/tests -v --timeout=300
|
|
57
62
|
|
|
58
63
|
# ═══════════════════════════════════════════════════════════════════════════
|
|
59
64
|
# DEV RELEASE — tag on dev branch, not yet merged to main
|
|
@@ -74,7 +79,7 @@ jobs:
|
|
|
74
79
|
with:
|
|
75
80
|
fetch-depth: 0
|
|
76
81
|
|
|
77
|
-
- uses: actions/setup-python@
|
|
82
|
+
- uses: actions/setup-python@v6
|
|
78
83
|
with:
|
|
79
84
|
python-version: '3.11'
|
|
80
85
|
|
|
@@ -108,7 +113,7 @@ jobs:
|
|
|
108
113
|
python -m twine upload --repository-url https://test.pypi.org/legacy/ --verbose dist/*
|
|
109
114
|
|
|
110
115
|
- name: Upload build artifacts for release
|
|
111
|
-
uses: actions/upload-artifact@
|
|
116
|
+
uses: actions/upload-artifact@v6
|
|
112
117
|
with:
|
|
113
118
|
name: dev-release-dist
|
|
114
119
|
path: dist/
|
|
@@ -133,7 +138,7 @@ jobs:
|
|
|
133
138
|
permissions:
|
|
134
139
|
contents: read
|
|
135
140
|
steps:
|
|
136
|
-
- uses: actions/setup-python@
|
|
141
|
+
- uses: actions/setup-python@v6
|
|
137
142
|
with:
|
|
138
143
|
python-version: ${{ matrix.python-version }}
|
|
139
144
|
allow-prereleases: ${{ matrix.allow-prereleases || false }}
|
|
@@ -195,7 +200,7 @@ jobs:
|
|
|
195
200
|
fetch-depth: 0
|
|
196
201
|
|
|
197
202
|
- name: Download build artifacts
|
|
198
|
-
uses: actions/download-artifact@
|
|
203
|
+
uses: actions/download-artifact@v7
|
|
199
204
|
with:
|
|
200
205
|
name: dev-release-dist
|
|
201
206
|
path: dist/
|
|
@@ -226,7 +231,7 @@ jobs:
|
|
|
226
231
|
|
|
227
232
|
export PRS_JSON
|
|
228
233
|
PRS_JSON=$(gh pr list --state merged --base "dev" --limit 100 \
|
|
229
|
-
--json number,title,mergedAt,url,author,body \
|
|
234
|
+
--json number,title,mergedAt,url,author,body,commits \
|
|
230
235
|
2>/dev/null || echo "[]")
|
|
231
236
|
|
|
232
237
|
python3 << 'PYEOF'
|
|
@@ -249,6 +254,29 @@ jobs:
|
|
|
249
254
|
line += f"\n\n > {desc}"
|
|
250
255
|
return line
|
|
251
256
|
filtered = [pr for pr in prs_data if pr.get("mergedAt", "") > prev_date]
|
|
257
|
+
# "What's Changed precisely": list each merged PR's own developer commits,
|
|
258
|
+
# NOT the squashed/merge/chore commits that land on the release branch
|
|
259
|
+
# (those are redundant with the PR list above and not useful).
|
|
260
|
+
_seen_commits = set()
|
|
261
|
+
_commit_blocks = []
|
|
262
|
+
for pr in filtered:
|
|
263
|
+
_commit_lines = []
|
|
264
|
+
for c in (pr.get("commits") or []):
|
|
265
|
+
oid = (c.get("oid") or "")[:7]
|
|
266
|
+
head = (c.get("messageHeadline") or "").strip()
|
|
267
|
+
if not head or head.startswith("Merge "):
|
|
268
|
+
continue
|
|
269
|
+
key = (oid, head)
|
|
270
|
+
if key in _seen_commits:
|
|
271
|
+
continue
|
|
272
|
+
_seen_commits.add(key)
|
|
273
|
+
_commit_lines.append(f" - `{oid}` {head}")
|
|
274
|
+
if _commit_lines:
|
|
275
|
+
_commit_blocks.append(
|
|
276
|
+
f"**[#{pr['number']}]({pr['url']}) {pr['title']}**\n" + "\n".join(_commit_lines)
|
|
277
|
+
)
|
|
278
|
+
# Fall back to the raw git log only when no PR commits are available.
|
|
279
|
+
commits_section = "\n\n".join(_commit_blocks) if _commit_blocks else commits
|
|
252
280
|
if filtered:
|
|
253
281
|
prs_lines = "\n".join(_pr_entry(pr) for pr in filtered)
|
|
254
282
|
seen, clabels = set(), []
|
|
@@ -276,7 +304,7 @@ jobs:
|
|
|
276
304
|
"Happy Training!\n\n"
|
|
277
305
|
"---\n\n"
|
|
278
306
|
"### What's Changed precisely:\n\n"
|
|
279
|
-
f"{
|
|
307
|
+
f"{commits_section}\n\n"
|
|
280
308
|
"---\n\n"
|
|
281
309
|
"### Thank you!\n\n"
|
|
282
310
|
f"{contributors}\n"
|
|
@@ -303,7 +331,8 @@ jobs:
|
|
|
303
331
|
|
|
304
332
|
build-and-publish-main:
|
|
305
333
|
name: Build & Publish Main (PyPI)
|
|
306
|
-
needs: [detect-target]
|
|
334
|
+
needs: [detect-target,test]
|
|
335
|
+
# needs: [detect-target]
|
|
307
336
|
runs-on: ubuntu-latest
|
|
308
337
|
if: ${{ needs.detect-target.outputs.is_main == 'true' }}
|
|
309
338
|
permissions:
|
|
@@ -315,7 +344,7 @@ jobs:
|
|
|
315
344
|
with:
|
|
316
345
|
fetch-depth: 0
|
|
317
346
|
|
|
318
|
-
- uses: actions/setup-python@
|
|
347
|
+
- uses: actions/setup-python@v6
|
|
319
348
|
with:
|
|
320
349
|
python-version: '3.11'
|
|
321
350
|
|
|
@@ -349,7 +378,7 @@ jobs:
|
|
|
349
378
|
python -m twine upload dist/* --non-interactive --verbose
|
|
350
379
|
|
|
351
380
|
- name: Upload build artifacts for release
|
|
352
|
-
uses: actions/upload-artifact@
|
|
381
|
+
uses: actions/upload-artifact@v6
|
|
353
382
|
with:
|
|
354
383
|
name: main-release-dist
|
|
355
384
|
path: dist/
|
|
@@ -367,7 +396,7 @@ jobs:
|
|
|
367
396
|
permissions:
|
|
368
397
|
contents: read
|
|
369
398
|
steps:
|
|
370
|
-
- uses: actions/setup-python@
|
|
399
|
+
- uses: actions/setup-python@v6
|
|
371
400
|
with:
|
|
372
401
|
python-version: ${{ matrix.python-version }}
|
|
373
402
|
|
|
@@ -427,7 +456,7 @@ jobs:
|
|
|
427
456
|
fetch-depth: 0
|
|
428
457
|
|
|
429
458
|
- name: Download build artifacts
|
|
430
|
-
uses: actions/download-artifact@
|
|
459
|
+
uses: actions/download-artifact@v7
|
|
431
460
|
with:
|
|
432
461
|
name: main-release-dist
|
|
433
462
|
path: dist/
|
|
@@ -458,7 +487,7 @@ jobs:
|
|
|
458
487
|
|
|
459
488
|
export PRS_JSON
|
|
460
489
|
PRS_JSON=$(gh pr list --state merged --base "main" --limit 100 \
|
|
461
|
-
--json number,title,mergedAt,url,author,body \
|
|
490
|
+
--json number,title,mergedAt,url,author,body,commits \
|
|
462
491
|
2>/dev/null || echo "[]")
|
|
463
492
|
|
|
464
493
|
python3 << 'PYEOF'
|
|
@@ -481,6 +510,29 @@ jobs:
|
|
|
481
510
|
line += f"\n\n > {desc}"
|
|
482
511
|
return line
|
|
483
512
|
filtered = [pr for pr in prs_data if pr.get("mergedAt", "") > prev_date]
|
|
513
|
+
# "What's Changed precisely": list each merged PR's own developer commits,
|
|
514
|
+
# NOT the squashed/merge/chore commits that land on the release branch
|
|
515
|
+
# (those are redundant with the PR list above and not useful).
|
|
516
|
+
_seen_commits = set()
|
|
517
|
+
_commit_blocks = []
|
|
518
|
+
for pr in filtered:
|
|
519
|
+
_commit_lines = []
|
|
520
|
+
for c in (pr.get("commits") or []):
|
|
521
|
+
oid = (c.get("oid") or "")[:7]
|
|
522
|
+
head = (c.get("messageHeadline") or "").strip()
|
|
523
|
+
if not head or head.startswith("Merge "):
|
|
524
|
+
continue
|
|
525
|
+
key = (oid, head)
|
|
526
|
+
if key in _seen_commits:
|
|
527
|
+
continue
|
|
528
|
+
_seen_commits.add(key)
|
|
529
|
+
_commit_lines.append(f" - `{oid}` {head}")
|
|
530
|
+
if _commit_lines:
|
|
531
|
+
_commit_blocks.append(
|
|
532
|
+
f"**[#{pr['number']}]({pr['url']}) {pr['title']}**\n" + "\n".join(_commit_lines)
|
|
533
|
+
)
|
|
534
|
+
# Fall back to the raw git log only when no PR commits are available.
|
|
535
|
+
commits_section = "\n\n".join(_commit_blocks) if _commit_blocks else commits
|
|
484
536
|
if filtered:
|
|
485
537
|
prs_lines = "\n".join(_pr_entry(pr) for pr in filtered)
|
|
486
538
|
seen, clabels = set(), []
|
|
@@ -508,7 +560,7 @@ jobs:
|
|
|
508
560
|
"Happy Training!\n\n"
|
|
509
561
|
"---\n\n"
|
|
510
562
|
"### What's Changed precisely:\n\n"
|
|
511
|
-
f"{
|
|
563
|
+
f"{commits_section}\n\n"
|
|
512
564
|
"---\n\n"
|
|
513
565
|
"### Thank you!\n\n"
|
|
514
566
|
f"{contributors}\n"
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
# WeightsLab — agent context for users & debugging
|
|
2
|
+
|
|
3
|
+
This file is a **portable context for AI coding agents** (Claude Code, etc.) and
|
|
4
|
+
the humans driving them. Its job is to let you — or an agent helping you —
|
|
5
|
+
**install, configure, run, and debug WeightsLab and Weights Studio** without
|
|
6
|
+
having to reverse-engineer the system first.
|
|
7
|
+
|
|
8
|
+
It deliberately covers only the two shipped repositories:
|
|
9
|
+
|
|
10
|
+
- **weightslab** — the Python backend / core (training instrumentation, data
|
|
11
|
+
ledger, gRPC service, the shared proto).
|
|
12
|
+
- **weights_studio** — the browser frontend (the studio UI that inspects and
|
|
13
|
+
edits a *running* experiment).
|
|
14
|
+
|
|
15
|
+
> File/line references drift as the code evolves — treat them as starting points
|
|
16
|
+
> and verify against the current source before relying on them. Environment
|
|
17
|
+
> variable names and defaults are the most stable thing here; when in doubt the
|
|
18
|
+
> authoritative reference is `weightslab/docs/configuration.rst`.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 0. How to load this guide into Claude Code
|
|
23
|
+
|
|
24
|
+
So an agent actually *has* this context when you ask it for help:
|
|
25
|
+
|
|
26
|
+
- **Working inside a checkout of the repo** (`git clone`): this guide is
|
|
27
|
+
committed as `AGENTS.md`; the repo keeps a gitignored `CLAUDE.md` copy of it at
|
|
28
|
+
the root so Claude Code auto-loads it every session. Nothing to do. (Claude
|
|
29
|
+
Code also loads `~/.claude/CLAUDE.md` global memory and any parent-dir
|
|
30
|
+
`CLAUDE.md`.)
|
|
31
|
+
- **You only ran `pip install weightslab`** (no checkout — the package lives in
|
|
32
|
+
`site-packages`): absolute `@import` paths are fragile because the path
|
|
33
|
+
changes per venv/OS. The robust pattern is a small **skill** that locates the
|
|
34
|
+
installed file at runtime. Create `~/.claude/skills/weightslab/SKILL.md`:
|
|
35
|
+
|
|
36
|
+
```yaml
|
|
37
|
+
---
|
|
38
|
+
name: weightslab
|
|
39
|
+
description: Load the WeightsLab debugging & configuration guide when helping with weightslab or weights_studio problems (connection, TLS, env vars, training hangs, rendering).
|
|
40
|
+
---
|
|
41
|
+
!`python -c "import weightslab, os; print(open(os.path.join(os.path.dirname(weightslab.__file__), 'AGENTS.md')).read())"`
|
|
42
|
+
|
|
43
|
+
Use the guide above to diagnose the user's weightslab / weights_studio issue.
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Then run `/weightslab` (or let Claude auto-invoke it). This requires the guide
|
|
47
|
+
to be **shipped as package data** inside the installed package (see §7); the
|
|
48
|
+
copy at the repo root is for contributors working in a checkout.
|
|
49
|
+
- **Quick-and-dirty:** copy this file to `~/.claude/WEIGHTSLAB.md` and add
|
|
50
|
+
`@~/.claude/WEIGHTSLAB.md` to your `~/.claude/CLAUDE.md`.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## 1. What it is and how the pieces connect
|
|
55
|
+
|
|
56
|
+
A user wraps their own PyTorch training script with WeightsLab so a running
|
|
57
|
+
experiment becomes inspectable/editable; Weights Studio is the UI for that.
|
|
58
|
+
|
|
59
|
+
**Wire path (the thing that breaks most often):**
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
Browser (Vite app) → Envoy :8080 (grpc-web ↔ grpc) → Python gRPC servicer → training loop
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
- The browser cannot speak raw gRPC, so **Envoy** transcodes grpc-web ↔ gRPC.
|
|
66
|
+
If Envoy is down or misconfigured, the UI loads but no data appears.
|
|
67
|
+
- The gRPC servicer and the training loop run in the **same process, different
|
|
68
|
+
threads**, coordinated by locks in
|
|
69
|
+
`weightslab/weightslab/components/global_monitoring.py`.
|
|
70
|
+
- One proto is the single source of truth:
|
|
71
|
+
`weightslab/weightslab/proto/experiment_service.proto`.
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## 2. Install & run (the happy path)
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
pip install weightslab
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
In your training script:
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
import weightslab as wl
|
|
85
|
+
# wrap your objects so the studio can see/edit them (see §3), then:
|
|
86
|
+
wl.serve(serving_grpc=True, serving_cli=True) # background threads, same process
|
|
87
|
+
# ... your training loop ...
|
|
88
|
+
wl.keep_serving() # keep the process alive for the UI
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Then start the studio stack (Envoy + frontend) and open it in a browser.
|
|
92
|
+
Working starting points live in
|
|
93
|
+
`weightslab/weightslab/examples/{PyTorch,Lightning,Usecases}/<usecase>/`
|
|
94
|
+
(each is a `main.py` + `config.yaml`) — find the closest example and mirror it.
|
|
95
|
+
|
|
96
|
+
Studio deployment details (Docker compose, Envoy, ports, certs) are in
|
|
97
|
+
`weights_studio/docker/` and documented in `weightslab/docs/weights_studio.rst`.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## 3. The integration API (`import weightslab as wl`)
|
|
102
|
+
|
|
103
|
+
How a user's script plugs in. Wrap each training object with
|
|
104
|
+
`wl.watch_or_edit(obj, flag=...)`; the returned tracked proxy is registered in
|
|
105
|
+
the global ledger (`weightslab/weightslab/backend/ledgers.py`,
|
|
106
|
+
`GLOBAL_LEDGER` — the hub everything reads/mutates through).
|
|
107
|
+
|
|
108
|
+
- `flag="hyperparameters"` (dict), `flag="model"` (nn.Module, `device=…`),
|
|
109
|
+
`flag="optimizer"`, `flag="data"` (Dataset → tracked DataLoader: `loader_name`,
|
|
110
|
+
`batch_size`, `is_training`, `collate_fn`, …), `flag="loss"` (a
|
|
111
|
+
`reduction="none"` criterion, called with `(preds_raw, targets, batch_ids=ids,
|
|
112
|
+
preds=preds)`), `flag="metric"`.
|
|
113
|
+
|
|
114
|
+
Conventions that matter for correctness:
|
|
115
|
+
|
|
116
|
+
- Wrap the train step in `with guard_training_context:` and eval in
|
|
117
|
+
`with guard_testing_context:` (from
|
|
118
|
+
`weightslab.components.global_monitoring`). This is how pause/resume and
|
|
119
|
+
train/test separation work — **skip it and pause/resume or stats will misbehave.**
|
|
120
|
+
- Use `model.get_age()` (steps actually trained; survives checkpoint reloads),
|
|
121
|
+
not the raw loop counter.
|
|
122
|
+
- `task_type` on the dataset/model selects rendering: `classification`,
|
|
123
|
+
`segmentation`, `detection`, `detection_pointcloud`.
|
|
124
|
+
- **Hyperparameter handle access:** the registered hyperparameters proxy
|
|
125
|
+
supports both `hp.get("lr")` and `hp["lr"]` (subscript == `.get`), and stays
|
|
126
|
+
live — reads reflect in-place updates and re-registration.
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## 4. Configuration (environment variables)
|
|
131
|
+
|
|
132
|
+
WeightsLab and Weights Studio are configured almost entirely through env vars.
|
|
133
|
+
**Authoritative reference: `weightslab/docs/configuration.rst`.** The high-signal
|
|
134
|
+
ones when debugging:
|
|
135
|
+
|
|
136
|
+
**Backend (Python):**
|
|
137
|
+
|
|
138
|
+
| Variable | Default | Why you touch it |
|
|
139
|
+
|---|---|---|
|
|
140
|
+
| `WEIGHTSLAB_LOG_LEVEL` | `INFO` | Set `DEBUG` to see what's happening. (`WATCHDOG` level sits between WARNING/ERROR.) |
|
|
141
|
+
| `GRPC_BACKEND_HOST` / `GRPC_BACKEND_PORT` | `0.0.0.0` / `50051` | Backend must listen where Envoy expects it. |
|
|
142
|
+
| `GRPC_TLS_ENABLED` | `1` | TLS on the gRPC socket. Set `0` **only** for isolated local debugging. |
|
|
143
|
+
| `GRPC_TLS_REQUIRE_CLIENT_AUTH` | `1` | mTLS. Must match what Envoy presents. |
|
|
144
|
+
| `GRPC_TLS_CERT_DIR` | `~/certs` | Where default cert files are looked up. |
|
|
145
|
+
| `GRPC_AUTH_TOKEN` | *(unset)* | Optional metadata-token auth on top of mTLS. |
|
|
146
|
+
| `GRPC_MAX_MESSAGE_BYTES` | `268435456` (256 MB) | Raise it if large tensors/image batches fail. |
|
|
147
|
+
| `WEIGHTSLAB_DISABLE_WATCHDOGS` | `0` | Set `1` when debugging with breakpoints (see §5). |
|
|
148
|
+
| `GRPC_WATCHDOG_STUCK_SECONDS` | `60` | Lock/RPC stuck threshold + lock-acquire timeout. |
|
|
149
|
+
|
|
150
|
+
**Frontend (Weights Studio) — runtime-injected `window.*` globals:**
|
|
151
|
+
|
|
152
|
+
| Variable | Default | Why you touch it |
|
|
153
|
+
|---|---|---|
|
|
154
|
+
| `WS_SERVER_HOST` / `WS_SERVER_PORT` / `WS_SERVER_PROTOCOL` | `localhost` / `8080` / `https` | How the browser reaches the backend (via Envoy). The #1 connection-issue knob. |
|
|
155
|
+
| `WS_HISTOGRAM_MAX_BINS` | `512` | Cap on metadata histogram bars. |
|
|
156
|
+
| `BB_THUMB_RENDER` | `10` | Max bounding boxes drawn per **thumbnail**, per overlay (GT and PRED capped independently). |
|
|
157
|
+
| `BB_MODAL_RENDER` | `100` | Max bounding boxes drawn per **modal** image, per overlay. A `?` button in the modal shows the active limit. |
|
|
158
|
+
| `ENABLE_PLOTS` | `1` | `0`/`false` removes the plots board + Signals card and stops plot auto-refresh. |
|
|
159
|
+
| `ENABLE_DATA_EXPLORATION` | `1` | `0`/`false` removes the data grid + metadata/details panel and stops the data/metadata auto-refresh. |
|
|
160
|
+
| `ENABLE_HYPERPARAMETERS_OPTIMIZATION` | `1` | `0`/`false` removes the Hyperparameters section, makes HP inputs read-only, and stops the HP poll. |
|
|
161
|
+
| `ENABLE_AGENT` | `1` | `0`/`false` removes the agent chat bar + history panel and stops the agent health poll. |
|
|
162
|
+
|
|
163
|
+
> **VITE_ vs WS_/BB_/ENABLE_:** `VITE_*` variables are baked at **build time**
|
|
164
|
+
> (changing them needs a rebuild). `WS_*` / `BB_*` / `ENABLE_*` are injected at
|
|
165
|
+
> **container start** into `config.js` and read as `window.*` globals (the
|
|
166
|
+
> toggles as `window.WS_ENABLE_*`) — changing them needs only a container restart
|
|
167
|
+
> + browser reload (see the caching note in §5). Each `ENABLE_*` defaults to on;
|
|
168
|
+
> set it to `0`/`false`/`no`/`off` to disable. Full reference:
|
|
169
|
+
> `weightslab/docs/configuration.rst` (“Feature toggles”).
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## 5. Troubleshooting — symptom → cause → fix
|
|
174
|
+
|
|
175
|
+
This is the core of the guide. Each entry is a real failure mode (several are
|
|
176
|
+
distilled from issues hit in development).
|
|
177
|
+
|
|
178
|
+
**UI loads but the sample grid is empty / "failed to fetch" / gRPC errors.**
|
|
179
|
+
The wire path (§1) is broken somewhere. Check in order: (1) backend actually
|
|
180
|
+
serving on `0.0.0.0:50051`; (2) Envoy running and reachable on `:8080`;
|
|
181
|
+
(3) frontend `WS_SERVER_HOST/PORT/PROTOCOL` point at Envoy, not the raw backend;
|
|
182
|
+
(4) **TLS mismatch** — `WS_SERVER_PROTOCOL=https` vs `http`, Envoy server certs,
|
|
183
|
+
and Envoy→backend mTLS certs all consistent. For local debugging you can drop
|
|
184
|
+
TLS end-to-end (`GRPC_TLS_ENABLED=0` + `VITE_SERVER_PROTOCOL=http`).
|
|
185
|
+
|
|
186
|
+
**Changed an env var, restarted, but the UI still uses the old value.**
|
|
187
|
+
- `VITE_*` is build-time → you must **rebuild** the frontend, not just restart.
|
|
188
|
+
- `WS_*` / `BB_*` are read once per page load → you must **reload the tab**.
|
|
189
|
+
- Historically `config.js` was served `Cache-Control: immutable` so even a
|
|
190
|
+
restart needed a **hard refresh**; current builds serve `/config.js` with
|
|
191
|
+
`no-store`, so a container restart + normal reload is enough. On an older
|
|
192
|
+
deployment, hard-refresh (Ctrl+Shift+R) or clear cache.
|
|
193
|
+
|
|
194
|
+
**Sample grid flashes empty cells when auto-refresh fires.**
|
|
195
|
+
An auto-refresh (timer or manual) that lands while a `GetDataSamples` grid fetch
|
|
196
|
+
is still in flight used to clear the cache mid-render. The fix in
|
|
197
|
+
`weights_studio/src/grid_data/gridDataManager.ts` is `isFetchInProgress()`:
|
|
198
|
+
refreshes are skipped while a grid fetch is ongoing. If you see this, confirm
|
|
199
|
+
you're on a build that has that guard.
|
|
200
|
+
|
|
201
|
+
**Detection overlays are slow or unreadably cluttered.**
|
|
202
|
+
Dense detection samples can carry hundreds of boxes. Cap rendering with
|
|
203
|
+
`BB_THUMB_RENDER` (thumbnails) and `BB_MODAL_RENDER` (modal); each is applied
|
|
204
|
+
separately to GT and to predictions. Render-only — no sample data is dropped.
|
|
205
|
+
|
|
206
|
+
**Training appears hung; RPCs return `RESOURCE_EXHAUSTED`; server "restarts".**
|
|
207
|
+
A watchdog monitors the global rlock and in-flight RPCs. If a lock/RPC is held
|
|
208
|
+
longer than `GRPC_WATCHDOG_STUCK_SECONDS` (60s) it's flagged; locks get
|
|
209
|
+
interrupted, and after `GRPC_WATCHDOG_RESTART_THRESHOLD` unhealthy polls the
|
|
210
|
+
gRPC server restarts. When **debugging with breakpoints** that intentionally
|
|
211
|
+
pause longer than that, set `WEIGHTSLAB_DISABLE_WATCHDOGS=1`. If RPCs fail with
|
|
212
|
+
`RESOURCE_EXHAUSTED`, a handler couldn't acquire the lock within the window —
|
|
213
|
+
something else is holding it; check for a long/blocking train or eval step.
|
|
214
|
+
|
|
215
|
+
**Pause/resume doesn't work, or train vs test stats are mixed up.**
|
|
216
|
+
The train step isn't wrapped in `guard_training_context` (or eval in
|
|
217
|
+
`guard_testing_context`). See §3 — these context managers are how the system
|
|
218
|
+
gates and separates phases.
|
|
219
|
+
|
|
220
|
+
**Large weights/images fail to transfer.** Raise `GRPC_MAX_MESSAGE_BYTES`.
|
|
221
|
+
|
|
222
|
+
**The agent bar says it's unconfigured.** The LLM agent needs a provider: a
|
|
223
|
+
local **Ollama** server (`provider: ollama`, available immediately) or **cloud
|
|
224
|
+
OpenRouter** initialized from the UI via `/init` (then `/model` to switch,
|
|
225
|
+
`/reset` to clear). See `weightslab/docs/weights_studio.rst`.
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## 6. Where things live (for deeper digging)
|
|
230
|
+
|
|
231
|
+
**Backend (`weightslab/weightslab/`):**
|
|
232
|
+
- `src.py` — the public verbs (`watch_or_edit`, `serve`, `keep_serving`,
|
|
233
|
+
`tag_samples`, `query_*`, decorators) re-exported from `__init__.py`.
|
|
234
|
+
- `trainer/services/` — `experiment_service.py` (gRPC servicer) delegating to
|
|
235
|
+
`{model,data,agent}_service.py`; `data_image_utils.py` (preview/mask encoding).
|
|
236
|
+
- `components/` — `global_monitoring.py` (locks, `guard_*` contexts, pause),
|
|
237
|
+
`checkpoint_manager.py`, `evaluation_controller.py`.
|
|
238
|
+
- `data/` — `dataframe_manager.py`, `data_samples_with_ops.py`, `sample_stats.py`,
|
|
239
|
+
H5 storage (`h5_dataframe_store.py`, `h5_array_store.py`, `array_proxy.py`).
|
|
240
|
+
- `backend/` — `ledgers.py` (`GLOBAL_LEDGER`), `logger.py`, `audit_logger.py`, `cli.py`.
|
|
241
|
+
- `security/` (`CertAuthManager`), `proto/`, `examples/`, `docs/`.
|
|
242
|
+
|
|
243
|
+
**Frontend (`weights_studio/src/`):**
|
|
244
|
+
- `main.ts` — bootstrap; builds the grpc-web transport from `WS_SERVER_*`.
|
|
245
|
+
- `experiment_service.client.ts` / `experiment_service.ts` — generated client
|
|
246
|
+
(regenerate with `npm run generate-proto:data`; do not hand-edit).
|
|
247
|
+
- `grid_data/` — grid + modal rendering (`GridCell.ts`, `DataImageService.ts`,
|
|
248
|
+
`gridDataManager.ts`, `BboxRenderer.ts`, `SegmentationRenderer.ts`,
|
|
249
|
+
`PointCloudViewer.ts`).
|
|
250
|
+
- `docker/` — compose, `nginx-entrypoint.sh` (injects `config.js`), Envoy assets.
|
|
251
|
+
|
|
252
|
+
**Docs:** `weightslab/docs/` (Sphinx) — `configuration.rst` (all env vars),
|
|
253
|
+
`weights_studio.rst` (studio deploy + agent), `quickstart.rst`, `grpc/`.
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## 7. For contributors (working in a checkout)
|
|
258
|
+
|
|
259
|
+
- **The two repos must sit side by side** (`…/weightslab`, `…/weights_studio`);
|
|
260
|
+
codegen and Envoy configs reach across by relative path.
|
|
261
|
+
- **Editing the proto is cross-repo** — do all of: edit
|
|
262
|
+
`experiment_service.proto`; regenerate Python stubs from the repo root; run
|
|
263
|
+
`npm run generate-proto:data` in weights_studio. Editing one side only leaves
|
|
264
|
+
the build broken.
|
|
265
|
+
- **Tests:** backend `python -m pytest weightslab/tests/...`; frontend unit
|
|
266
|
+
`npm run test` (vitest); E2E/user-simulation Playwright lives in
|
|
267
|
+
**weights_studio** (`test:realtime:*`, `test:e2e:*`), not here.
|
|
268
|
+
- **CI on a custom branch:** pushes to non-`main`/`dev` branches only run CI when
|
|
269
|
+
the commit message contains `[force ci]` (both repos).
|
|
270
|
+
- **TLS/auth in the bundled UI** is decided by cert presence under
|
|
271
|
+
`WEIGHTSLAB_CERTS_DIR` (single source of truth) — don't hardcode secure/insecure.
|
|
272
|
+
- **To make this guide available to pip users**, ship it as package data inside
|
|
273
|
+
the installed package (e.g. as `weightslab/weightslab/AGENTS.md`) so the §0
|
|
274
|
+
skill can locate it; keep the root `AGENTS.md` (mirrored as the gitignored
|
|
275
|
+
`CLAUDE.md`) as the contributor-facing source.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Changelog - 2026-06-26 v1.3.0 (1)
|