feat(dictate): add voice-reactive listening waveform
This commit is contained in:
@@ -77,10 +77,17 @@ function createHarness() {
|
||||
const sockets: FakeSocket[] = [];
|
||||
const socketPaths: string[] = [];
|
||||
const statuses: Array<string | undefined> = [];
|
||||
const themeCalls: Array<{ color: string; text: string }> = [];
|
||||
const notifications: Array<{ message: string; type?: string }> = [];
|
||||
const pasted: string[] = [];
|
||||
const context = {
|
||||
ui: {
|
||||
theme: {
|
||||
fg: (color: string, text: string) => {
|
||||
themeCalls.push({ color, text });
|
||||
return text;
|
||||
},
|
||||
},
|
||||
setStatus: (_key: string, text: string | undefined) => statuses.push(text),
|
||||
notify: (message: string, type?: string) =>
|
||||
notifications.push({ message, type }),
|
||||
@@ -134,6 +141,7 @@ function createHarness() {
|
||||
sockets,
|
||||
socketPaths,
|
||||
statuses,
|
||||
themeCalls,
|
||||
notifications,
|
||||
pasted,
|
||||
context,
|
||||
@@ -213,7 +221,11 @@ test("rejects a mismatched protocol version before sending start", async () => {
|
||||
assert.ok(socket);
|
||||
socket.connect();
|
||||
const hello = harness.sentFrames(socket)[0];
|
||||
socket.frame({ version: 2, type: "pong", requestId: hello?.requestId });
|
||||
socket.frame({
|
||||
version: PROTOCOL_VERSION + 1,
|
||||
type: "pong",
|
||||
requestId: hello?.requestId,
|
||||
});
|
||||
|
||||
assert.equal(harness.sentFrames(socket).length, 1);
|
||||
assert.match(harness.notifications[0]?.message ?? "", /version mismatch/i);
|
||||
@@ -266,19 +278,51 @@ test("renders authoritative service states and sends a bounded stop command", as
|
||||
|
||||
assert.deepEqual(harness.statuses, [
|
||||
"loading model...",
|
||||
"listening...",
|
||||
"● listening ▁▁▁▁▁▁▁▁▁▁▁▁",
|
||||
"stopping...",
|
||||
"transcribing...",
|
||||
]);
|
||||
});
|
||||
|
||||
test("scrolls bounded audio levels through the listening waveform", async () => {
|
||||
const harness = createHarness();
|
||||
const { socket, generationId } = await connectAndNegotiate(harness);
|
||||
serviceFrame(socket, generationId, "state", { state: "listening" });
|
||||
assert.deepEqual(harness.themeCalls, [
|
||||
{ color: "error", text: "●" },
|
||||
{ color: "dim", text: "listening" },
|
||||
{ color: "accent", text: "▁▁▁▁▁▁▁▁▁▁▁▁" },
|
||||
]);
|
||||
serviceFrame(socket, generationId, "level", { level: 0.5 });
|
||||
serviceFrame(socket, generationId, "level", { level: 1 });
|
||||
|
||||
assert.deepEqual(harness.statuses, [
|
||||
"● listening ▁▁▁▁▁▁▁▁▁▁▁▁",
|
||||
"● listening ▁▁▁▁▁▁▁▁▁▁▁▅",
|
||||
"● listening ▁▁▁▁▁▁▁▁▁▁▅█",
|
||||
]);
|
||||
});
|
||||
|
||||
test("rejects audio levels outside listening or the normalized range", async () => {
|
||||
const beforeListening = createHarness();
|
||||
const pending = await connectAndNegotiate(beforeListening);
|
||||
serviceFrame(pending.socket, pending.generationId, "level", { level: 0.5 });
|
||||
assert.match(beforeListening.notifications[0]?.message ?? "", /audio level is invalid/i);
|
||||
|
||||
const outOfRange = createHarness();
|
||||
const active = await connectAndNegotiate(outOfRange);
|
||||
serviceFrame(active.socket, active.generationId, "state", { state: "listening" });
|
||||
serviceFrame(active.socket, active.generationId, "level", { level: 1.1 });
|
||||
assert.match(outOfRange.notifications[0]?.message ?? "", /audio level is invalid/i);
|
||||
});
|
||||
|
||||
test("ignores stale generations but rejects malformed and oversized frames", async () => {
|
||||
const staleHarness = createHarness();
|
||||
const { socket: staleSocket, generationId } = await connectAndNegotiate(staleHarness);
|
||||
serviceFrame(staleSocket, "old-generation", "state", { state: "listening" });
|
||||
assert.deepEqual(staleHarness.statuses, []);
|
||||
serviceFrame(staleSocket, generationId, "state", { state: "listening" });
|
||||
assert.deepEqual(staleHarness.statuses, ["listening..."]);
|
||||
assert.deepEqual(staleHarness.statuses, ["● listening ▁▁▁▁▁▁▁▁▁▁▁▁"]);
|
||||
|
||||
const malformedHarness = createHarness();
|
||||
const malformed = await connectAndNegotiate(malformedHarness);
|
||||
|
||||
Reference in New Issue
Block a user