from __future__ import annotations import sys from pathlib import Path from cmvr_edge_ai.application import ( create_default_capability_registry, create_default_registry, ) from cmvr_edge_ai.capabilities import ServingMode from cmvr_edge_ai.compiler import compile_pipeline from cmvr_edge_ai.config import load_config_data from cmvr_edge_ai.gauge import GAUGE_CATEGORY, GAUGE_MODEL_ID, GAUGE_PLUGIN_ID from cmvr_edge_ai.server.catalog import build_deployed_catalog def _node_params(tmp_path: Path) -> dict[str, object]: for name in ("detection.pt", "keypoints.pt", "segmentation.pt"): (tmp_path / name).write_bytes(b"model") return { "category": GAUGE_CATEGORY, "model_id": GAUGE_MODEL_ID, "python_executable": sys.executable, "project_root": str(tmp_path), "detection_model_path": "detection.pt", "key_point_model_path": "keypoints.pt", "segmentation_model_path": "segmentation.pt", } def _config(tmp_path: Path): # type: ignore[no-untyped-def] return load_config_data( { "api_version": "cmvr.edge.ai/v1", "pipelines": { "gauge_remote": { "nodes": { "request": { "uses": "server.request_source@1", "with": {"category": GAUGE_CATEGORY}, }, "reader": { "uses": GAUGE_PLUGIN_ID, "with": _node_params(tmp_path), }, "sink": {"uses": "server.response_sink@1"}, }, "edges": [ { "from": "request.requests", "to": "reader.requests", }, { "from": "reader.responses", "to": "sink.responses", }, ], } }, "server": { "enabled": True, "routes": { GAUGE_CATEGORY: { "pipeline": "gauge_remote", "model_id": GAUGE_MODEL_ID, } }, }, } ) def test_default_registries_expose_gauge_plugin_and_capability() -> None: plugins = create_default_registry(discover_entry_points=False) capabilities = create_default_capability_registry(discover_entry_points=False) plugin = plugins.resolve(GAUGE_PLUGIN_ID) capability = capabilities.resolve(GAUGE_MODEL_ID) assert plugin.inputs == {"requests": "InferenceRequest/v1"} assert plugin.outputs == {"responses": "InferenceResponse/v1"} assert capability.category == GAUGE_CATEGORY assert capability.family == "gauge" assert capability.serving_modes == (ServingMode.PASSIVE_INVOKE,) assert capability.input_kinds == ("image",) assert capability.output_kinds == ("scalar",) assert capability.artifact_roles == ( "original", "annotated", "diagnostics", ) def test_gauge_invocation_pipeline_compiles_without_detection_adapters( tmp_path: Path, ) -> None: config = _config(tmp_path) compiled = compile_pipeline( config, "gauge_remote", create_default_registry(discover_entry_points=False), ) assert compiled.plugin_specs["reader"].plugin_id == GAUGE_PLUGIN_ID assert set(compiled.plugin_specs) == {"request", "reader", "sink"} def test_deployed_catalog_classifies_gauge_as_passive_only(tmp_path: Path) -> None: catalog = build_deployed_catalog( _config(tmp_path), create_default_capability_registry(discover_entry_points=False), ) assert catalog.active_push == () assert [item.model_id for item in catalog.passive_invoke] == [GAUGE_MODEL_ID] assert catalog.passive_invoke[0].category == GAUGE_CATEGORY