suvradeepp's picture
Publish Tiny Hinglish Turn Detector development preview
35d483e verified
Raw
History Blame Contribute Delete
3.75 kB
#!/usr/bin/env python3
"""Replay model probabilities through the production turn controller."""
from __future__ import annotations
import argparse
import json
from pathlib import Path
from turn_detection.runtime.controller import ControllerConfig
from turn_detection.runtime.predictor import ModelMetadata
from turn_detection.runtime.replay import replay_jsonl
ROOT = Path(__file__).resolve().parents[1]
DEFAULT_METADATA_CANDIDATES = (
ROOT / "artifacts" / "model_metadata.json",
ROOT / "model_metadata.json",
)
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--input", required=True, help="JSONL of PauseCheckpoint fields")
parser.add_argument("--output", required=True, help="Destination decision JSONL")
parser.add_argument(
"--metadata",
help="Exported model_metadata.json; packaged layouts are auto-detected",
)
parser.add_argument("--threshold", type=float)
parser.add_argument("--long-pause-threshold", type=float)
parser.add_argument("--min-silence-ms", type=float)
parser.add_argument("--relax-after-ms", type=float)
parser.add_argument("--max-silence-ms", type=float)
parser.add_argument("--confirmations", type=int)
parser.add_argument(
"--evidence-scope",
choices=("synthetic_integration", "unqualified_sequence"),
default="unqualified_sequence",
help="Label replay provenance; this does not promote a replay to test evidence",
)
return parser.parse_args()
def _metadata_path(value: str | None) -> Path | None:
if value:
path = Path(value)
if not path.is_absolute():
path = ROOT / path
if not path.is_file():
raise SystemExit(f"model metadata does not exist: {path}")
return path
return next((path for path in DEFAULT_METADATA_CANDIDATES if path.is_file()), None)
def _controller_config(args: argparse.Namespace) -> ControllerConfig:
metadata_path = _metadata_path(args.metadata)
if metadata_path is not None:
base = ModelMetadata.from_path(metadata_path).controller
elif args.threshold is not None:
base = ControllerConfig(
endpoint_threshold=args.threshold,
long_pause_threshold=max(0.0, args.threshold - 0.18),
)
else:
raise SystemExit("provide --metadata or --threshold; refusing an unbound replay policy")
endpoint_threshold = base.endpoint_threshold if args.threshold is None else args.threshold
relaxation_delta = base.endpoint_threshold - base.long_pause_threshold
long_pause_threshold = (
max(0.0, endpoint_threshold - relaxation_delta)
if args.long_pause_threshold is None
else args.long_pause_threshold
)
return ControllerConfig(
endpoint_threshold=endpoint_threshold,
long_pause_threshold=long_pause_threshold,
min_silence_ms=(
base.min_silence_ms if args.min_silence_ms is None else args.min_silence_ms
),
relax_after_ms=(
base.relax_after_ms if args.relax_after_ms is None else args.relax_after_ms
),
max_silence_ms=(
base.max_silence_ms if args.max_silence_ms is None else args.max_silence_ms
),
required_confirmations=(
base.required_confirmations if args.confirmations is None else args.confirmations
),
)
def main() -> None:
args = parse_args()
config = _controller_config(args)
summary = replay_jsonl(
args.input,
args.output,
config,
evidence_scope=args.evidence_scope,
)
print(json.dumps(summary, indent=2, sort_keys=True))
if __name__ == "__main__":
main()