feat(demo): add export and silhouette visualization outputs
Add preprocess-only silhouette export and configurable result exporters so demo runs can be persisted for offline analysis and reproducible evaluation. Include optional parquet support and CLI visualization dumps while updating tests and tracking notes for the verified pipeline/debug workflow.
This commit is contained in:
+14
-15
@@ -91,7 +91,7 @@ def _start_nats_container(port: int) -> bool:
|
||||
"--name",
|
||||
CONTAINER_NAME,
|
||||
"-p",
|
||||
f"{port}:{port}",
|
||||
f"{port}:4222",
|
||||
"nats:latest",
|
||||
],
|
||||
capture_output=True,
|
||||
@@ -152,7 +152,7 @@ def _validate_result_schema(data: dict[str, object]) -> tuple[bool, str]:
|
||||
"track_id": int,
|
||||
"label": str (one of: "negative", "neutral", "positive"),
|
||||
"confidence": float in [0, 1],
|
||||
"window": list[int] (start, end),
|
||||
"window": int (non-negative),
|
||||
"timestamp_ns": int
|
||||
}
|
||||
"""
|
||||
@@ -190,14 +190,13 @@ def _validate_result_schema(data: dict[str, object]) -> tuple[bool, str]:
|
||||
return False, f"confidence must be numeric, got {type(confidence)}"
|
||||
if not 0.0 <= float(confidence) <= 1.0:
|
||||
return False, f"confidence must be in [0, 1], got {confidence}"
|
||||
|
||||
# Validate window (list of 2 ints)
|
||||
# Validate window (int, non-negative)
|
||||
window = data["window"]
|
||||
if not isinstance(window, list) or len(cast(list[object], window)) != 2:
|
||||
return False, f"window must be list of 2 ints, got {window}"
|
||||
window_list = cast(list[object], window)
|
||||
if not all(isinstance(x, int) for x in window_list):
|
||||
return False, f"window elements must be ints, got {window}"
|
||||
if not isinstance(window, int):
|
||||
return False, f"window must be int, got {type(window)}"
|
||||
if window < 0:
|
||||
return False, f"window must be non-negative, got {window}"
|
||||
|
||||
|
||||
# Validate timestamp_ns (int)
|
||||
timestamp_ns = data["timestamp_ns"]
|
||||
@@ -356,7 +355,7 @@ class TestNatsPublisherIntegration:
|
||||
"track_id": 1,
|
||||
"label": "positive",
|
||||
"confidence": 0.85,
|
||||
"window": [0, 30],
|
||||
"window": 30,
|
||||
"timestamp_ns": 1234567890,
|
||||
}
|
||||
|
||||
@@ -431,7 +430,7 @@ class TestNatsSchemaValidation:
|
||||
"track_id": 42,
|
||||
"label": "positive",
|
||||
"confidence": 0.85,
|
||||
"window": [1200, 1230],
|
||||
"window": 1230,
|
||||
"timestamp_ns": 1234567890000,
|
||||
}
|
||||
|
||||
@@ -445,7 +444,7 @@ class TestNatsSchemaValidation:
|
||||
"track_id": 42,
|
||||
"label": "invalid_label",
|
||||
"confidence": 0.85,
|
||||
"window": [1200, 1230],
|
||||
"window": 1230,
|
||||
"timestamp_ns": 1234567890000,
|
||||
}
|
||||
|
||||
@@ -460,7 +459,7 @@ class TestNatsSchemaValidation:
|
||||
"track_id": 42,
|
||||
"label": "positive",
|
||||
"confidence": 1.5,
|
||||
"window": [1200, 1230],
|
||||
"window": 1230,
|
||||
"timestamp_ns": 1234567890000,
|
||||
}
|
||||
|
||||
@@ -486,7 +485,7 @@ class TestNatsSchemaValidation:
|
||||
"track_id": 42,
|
||||
"label": "positive",
|
||||
"confidence": 0.85,
|
||||
"window": [1200, 1230],
|
||||
"window": 1230,
|
||||
"timestamp_ns": 1234567890000,
|
||||
}
|
||||
|
||||
@@ -502,7 +501,7 @@ class TestNatsSchemaValidation:
|
||||
"track_id": 1,
|
||||
"label": label_str,
|
||||
"confidence": 0.5,
|
||||
"window": [70, 100],
|
||||
"window": 100,
|
||||
"timestamp_ns": 1234567890,
|
||||
}
|
||||
is_valid, error = _validate_result_schema(data)
|
||||
|
||||
Reference in New Issue
Block a user