mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-06 03:14:00 +00:00
refactor(voice): isolate gemini live provider core
This commit is contained in:
commit
10916227cb
655 files changed
+45946
-26483
No files matched your search
@@ -0,0 +1,120 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { GevRealtimeController } from './realtimeController.js';
|
||||
|
||||
const tick = () => new Promise((resolve) => setImmediate(resolve));
|
||||
const playback = (id) => ({
|
||||
ok: true,
|
||||
action: 'control_radio',
|
||||
radioAction: 'play',
|
||||
radioPlaybackRequested: true,
|
||||
id,
|
||||
});
|
||||
|
||||
function fixture(t) {
|
||||
const attempts = [],
|
||||
stopped = [],
|
||||
corrections = [],
|
||||
states = [];
|
||||
const controller = new GevRealtimeController({
|
||||
ui: {
|
||||
root: {
|
||||
dataset: {},
|
||||
classList: { remove() {} },
|
||||
querySelectorAll: () => [],
|
||||
remove() {},
|
||||
},
|
||||
status: {},
|
||||
detail: {},
|
||||
errorDetail: {},
|
||||
},
|
||||
runner: async () => ({ ok: false }),
|
||||
debugSink: null,
|
||||
onSessionEvent: (event) => states.push(event),
|
||||
radioLayer: {
|
||||
setVoiceDucked() {},
|
||||
playForVoice: ({ attemptId }) =>
|
||||
new Promise((resolve, reject) =>
|
||||
attempts.push({ attemptId, resolve, reject }),
|
||||
),
|
||||
stopPlayback: (options) => stopped.push(options),
|
||||
},
|
||||
});
|
||||
controller.queueResponseCreate = (message) => corrections.push(message);
|
||||
controller.dc = { readyState: 'open', send() {}, close() {} };
|
||||
t.after(() => controller.stop({ removeUi: true }));
|
||||
return { controller, attempts, stopped, corrections, states };
|
||||
}
|
||||
|
||||
test('default OpenAI reservation silences rejected frozen preflight and resumes retained result after failure', async (t) => {
|
||||
const h = fixture(t),
|
||||
c = h.controller;
|
||||
const a = playback('A');
|
||||
c.pendingRadioPlaybackResult = a;
|
||||
const pending = c.startPendingRadioHandoff();
|
||||
const reservation = c.reserveRadioToolHandoff();
|
||||
assert.equal(c.pendingRadioPlaybackResult, a);
|
||||
assert.equal(c.radioHandoffInFlight, false);
|
||||
h.attempts[0].reject(new Error('obsolete frozen preflight'));
|
||||
await pending;
|
||||
assert.deepEqual(h.corrections, []);
|
||||
assert.equal(
|
||||
h.states.some((event) => event.detail === 'Radio did not start'),
|
||||
false,
|
||||
);
|
||||
c.settleRadioToolHandoffReservation(reservation, { commit: false });
|
||||
await tick();
|
||||
assert.equal(h.attempts.length, 2);
|
||||
assert.equal(c.radioHandoffInFlightResult, a);
|
||||
assert.notEqual(h.attempts[0].attemptId, h.attempts[1].attemptId);
|
||||
h.attempts[1].reject(new Error('current preflight failed'));
|
||||
await tick();
|
||||
assert.equal(h.corrections.length, 1);
|
||||
assert.equal(c.status, 'listening');
|
||||
});
|
||||
|
||||
test('default OpenAI group cancellation silences rejected preflight without blocking the next failure correction', async (t) => {
|
||||
const h = fixture(t),
|
||||
c = h.controller;
|
||||
c.pendingRadioPlaybackResult = playback('A');
|
||||
const old = c.startPendingRadioHandoff();
|
||||
c.cancelRadioHandoff();
|
||||
h.attempts[0].reject(new Error('cancelled preflight'));
|
||||
await old;
|
||||
assert.deepEqual(h.corrections, []);
|
||||
c.pendingRadioPlaybackResult = playback('B');
|
||||
const current = c.startPendingRadioHandoff();
|
||||
h.attempts[1].resolve(false);
|
||||
await current;
|
||||
assert.equal(h.corrections.length, 1);
|
||||
});
|
||||
|
||||
test('per-result cancellation retains sibling result and epoch and ignores late failure or duplicate cancellation', async (t) => {
|
||||
const h = fixture(t),
|
||||
c = h.controller;
|
||||
const a = playback('A'),
|
||||
b = playback('B');
|
||||
c.pendingRadioPlaybackResult = a;
|
||||
const old = c.startPendingRadioHandoff();
|
||||
const siblingEpoch = c.radioHandoffEpoch;
|
||||
c.pendingRadioPlaybackResult = b;
|
||||
c._radio.cancelPlaybackResult(a);
|
||||
c._radio.cancelPlaybackResult(a);
|
||||
c._radio.cancelPlaybackResult(playback('unknown'));
|
||||
assert.equal(c.radioHandoffEpoch, siblingEpoch);
|
||||
assert.equal(c.pendingRadioPlaybackResult, b);
|
||||
assert.equal(h.stopped.length, 1);
|
||||
h.attempts[0].reject(new Error('late cancelled preflight'));
|
||||
await old;
|
||||
assert.deepEqual(h.corrections, []);
|
||||
const current = c.startPendingRadioHandoff();
|
||||
const reservation = c.reserveRadioToolHandoff();
|
||||
c._radio.cancelPlaybackResult(b);
|
||||
assert.equal(c._radio.radioToolHandoffReservations.has(reservation), true);
|
||||
h.attempts[1].resolve(false);
|
||||
await current;
|
||||
assert.deepEqual(h.corrections, []);
|
||||
c.settleRadioToolHandoffReservation(reservation, { commit: false });
|
||||
await tick();
|
||||
assert.equal(h.attempts.length, 2, 'a cancelled result cannot be resumed');
|
||||
});
|
||||
Reference in new issue
Block a user