Spaces:
Sleeping
Sleeping
File size: 4,419 Bytes
c519923 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | """Drive a full examination end-to-end in the terminal (mock backend).
python3 scripts/demo_playthrough.py
Doubles as the dry-run harness referenced in the demo-video plan: it prints each
turn's perceived stance, the witness's line, and the live contradiction verdict,
then asserts the win fires with a cached voice-crack take.
"""
import os
import sys
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import numpy as np # noqa: E402
from witnessbox.backends import get_backends # noqa: E402
from witnessbox.engine import WitnessBoxEngine # noqa: E402
from witnessbox import stance as stance_mod # noqa: E402
SCRIPT = [
"So, Mr. Reid — comfortable up there?", # filler
"The wire to Meridian cleared March 6th — before the board approved it on the 14th.",
"Anything over $5 million needs the CFO's sign-off, and your credentials are on the authorization log.",
"You were cc'd on Meridian's incorporation filing two years ago — Dana Voss, your colleague.",
]
def bar(pct, n=20):
f = int(round(pct / 100 * n))
return "█" * f + "·" * (n - f)
def _speechlike(dur_s=2.4, sr=16000, syl_rate=5.0, pause_frac=0.15, wobble=0.0, seed=0):
"""A crude but *speech-like* clip: a voiced carrier (f0 + harmonics, optional
pitch wobble) gated by a train of syllable bumps. Unlike a pure sine, its
pause ratio, onset rate and pitch steadiness move the way real delivery does —
so the stance read comes out in the right direction.
high syl_rate + low pause_frac + flat pitch -> CONFIDENT
low syl_rate + high pause_frac + wobble -> HESITANT
"""
rng = np.random.RandomState(seed)
n = int(dur_s * sr)
t = np.arange(n) / sr
f0 = 135.0 * (1.0 + wobble * np.sin(2 * np.pi * 0.8 * t + rng.rand()))
phase = 2 * np.pi * np.cumsum(f0) / sr
carrier = np.sin(phase) + 0.5 * np.sin(2 * phase) + 0.33 * np.sin(3 * phase)
env = np.zeros(n)
period = max(1, int(sr / syl_rate))
syl_len = max(1, int(period * (1.0 - pause_frac)))
for start in range(0, n, period):
seg = min(syl_len, n - start)
if seg <= 1:
break
env[start:start + seg] = 0.5 - 0.5 * np.cos(2 * np.pi * np.arange(seg) / seg)
return (0.4 * carrier * env).astype(np.float32)
def main():
eng = WitnessBoxEngine(get_backends())
intro = eng.start()
print(f"\n BACKEND: {intro['backend']} — {intro['backend_note']}")
print(f"\n ⚖️ THE COURT: {intro['narration']}")
print(f" 🎙️ REID: {intro['opening_text']}\n")
print(" " + "─" * 64)
last = None
for line in SCRIPT:
last = eng.take_turn(typed_text=line)
s, st = last.status, last.stance
print(f"\n ⚖️ YOU [{st.tier.lower()}]: {last.examiner_text}")
print(f" 🎙️ REID ({s['witness_tier']}): {last.witness_text}")
if last.evidence:
for ln in last.evidence.splitlines():
print(f" │ {ln}")
audio = "🔊" if last.witness_audio is not None else "—"
print(f" catches {s['catches']}/{s['catches_to_win']} "
f"composure [{bar(s['composure'])}] standing [{bar(s['credibility'])}] {audio}")
if last.events.won:
print(f"\n 💥 HE BREAKS — voice-crack take: "
f"{len(last.witness_audio)} samples @ {last.audio_sr} Hz, "
f"epilogue {'present' if last.epilogue_audio is not None else 'missing'}")
print("\n " + "─" * 64)
print(" Stance scoring on speech-like clips (no real mic needed):")
for name, (dur, syl_rate, pause_frac, wobble) in (
("fluent / steady", (2.4, 5.0, 0.12, 0.0)), # dense syllables, few pauses, flat pitch
("halting / unsure", (3.2, 1.4, 0.72, 0.20)), # sparse syllables, long gaps, wavering pitch
):
clip = _speechlike(dur_s=dur, syl_rate=syl_rate, pause_frac=pause_frac, wobble=wobble)
r = stance_mod.analyze(clip, 16000)
print(f" {name:18s} -> {r.tier:9s} conf={r.confidence:5.1f} "
f"(pause={r.features.get('pause_ratio')}, rate={r.features.get('rate_hz')}, "
f"pitch_std={r.features.get('pitch_std_semitones')})")
assert last.events.won, "expected a win after three catches"
print("\n ✅ End-to-end win path verified.\n")
if __name__ == "__main__":
main()
|