接入 LiveKit 与 TurnSense 评分并改进模型曲线选择

This commit is contained in:
Xin Wang
2026-10-22 23:52:16 +08:00
parent c9b618e634
commit 19d4e3c767
38 changed files with 2652 additions and 58 deletions
+25 -1
View File
@@ -38,13 +38,15 @@ test("curve gaps are not connected and steps remain on the audio clock", () => {
test("recorded inference exports agree on audio identity and retain all 44 checkpoints", async () => {
const files = [
["maai", "maai-ch-kyoto"], ["smart_turn", "smart-turn-v3.2"], ["silero_vad", "silero-vad"],
["maai", "maai-ch-kyoto"], ["smart_turn", "smart-turn-v3.2"], ["silero_vad", "silero-vad"], ["livekit_mini", "livekit-v1-mini"], ["turnsense", "turnsense-1.0"],
] as const;
const exports = await Promise.all(files.map(async ([model, directory]) => parseScoreExport(
JSON.parse(await readFile(new URL(`../../../experiments/${directory}/results/score-timeline.json`, import.meta.url), "utf8")), model)));
const identity = (data: typeof exports[number]) => data.calls.map(call => [call.call_id, call.audio_path, call.audio_sha256, call.duration_ms]);
assert.deepEqual(identity(exports[0]), identity(exports[1]));
assert.deepEqual(identity(exports[0]), identity(exports[2]));
assert.deepEqual(identity(exports[0]), identity(exports[3]));
assert.deepEqual(identity(exports[0]), identity(exports[4]));
for (const data of exports) {
assert.equal(data.calls.reduce((n, call) => n + call.checkpoints.length, 0), 44);
for (const call of data.calls) {
@@ -69,3 +71,25 @@ test("Silero checkpoints use only the last available frame, and speech is invert
}
}
});
test("LiveKit original checkpoints are real exact-time curve scores", async () => {
const data = parseScoreExport(JSON.parse(await readFile(new URL(
"../../../experiments/livekit-v1-mini/results/score-timeline.json", import.meta.url), "utf8")), "livekit_mini");
assert.equal(data.sample_interval_ms, 200);
for (const call of data.calls) {
for (const [ms, score] of call.checkpoints) {
assert.deepEqual(call.points.find(point => point[0] === ms), [ms, score]);
}
}
});
test("TurnSense curve checkpoints retain the complete probability at the exact decision", async () => {
const data = parseScoreExport(JSON.parse(await readFile(new URL(
"../../../experiments/turnsense-1.0/results/score-timeline.json", import.meta.url), "utf8")), "turnsense");
assert.equal(data.sample_interval_ms, 200);
for (const call of data.calls) {
for (const point of call.checkpoints) assert.deepEqual(call.points.find(p => p[0] === point[0]), point);
}
});
@@ -0,0 +1,28 @@
import assert from "node:assert/strict";
import test from "node:test";
// @ts-expect-error Node's native TypeScript runner requires explicit extensions.
import { readScorePreferences } from "../lib/score-models.ts";
test("first visit starts with three comparison curves and each model's reference threshold", () => {
const defaults = readScorePreferences(null);
assert.deepEqual(Object.entries(defaults.visibility).filter(([, value]) => value).map(([id]) => id), ["maai", "smart_turn", "turnsense"]);
assert.equal(defaults.thresholds.livekit_mini, .355);
});
test("saved choices preserve clear-all and accept only supported reference thresholds", () => {
const saved = readScorePreferences({ version: 1, visibility: { maai: false, smart_turn: false, silero_vad: false, livekit_mini: false, turnsense: false },
thresholds: { maai: .11, livekit_mini: .355, smart_turn: 99, turnsense: "0.8" } });
assert.equal(Object.values(saved.visibility).some(Boolean), false);
assert.equal(saved.thresholds.maai, .11);
assert.equal(saved.thresholds.smart_turn, .5);
assert.equal(saved.thresholds.turnsense, .5);
});
test("partial and invalid preferences leave future models on their defaults", () => {
const saved = readScorePreferences({ version: 1, visibility: { maai: true, smart_turn: "false", unknown: true }, thresholds: { turnsense: .8 } });
assert.equal(saved.visibility.smart_turn, true);
assert.equal(saved.visibility.turnsense, true);
assert.equal(saved.thresholds.turnsense, .8);
assert.equal("unknown" in saved.visibility, false);
assert.deepEqual(readScorePreferences({ version: 999, visibility: { maai: false } }), readScorePreferences(null));
});