careervivid 2.1.36 → 2.1.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interview.d.ts","sourceRoot":"","sources":["../../src/commands/interview.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"interview.d.ts","sourceRoot":"","sources":["../../src/commands/interview.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAu2BpC,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmG/D"}
|
|
@@ -51,7 +51,7 @@ const CLI_BILL_URL = process.env.CV_FUNCTIONS_URL
|
|
|
51
51
|
const CLI_CONTEXT_URL = process.env.CV_FUNCTIONS_URL
|
|
52
52
|
? `${process.env.CV_FUNCTIONS_URL}/cliGetInterviewContext`
|
|
53
53
|
: "https://us-west1-jastalk-firebase.cloudfunctions.net/cliGetInterviewContext";
|
|
54
|
-
const LIVE_MODEL = "gemini-
|
|
54
|
+
const LIVE_MODEL = "gemini-live-2.5-flash-native-audio";
|
|
55
55
|
const FEEDBACK_MODEL = "gemini-2.5-flash";
|
|
56
56
|
const END_TOKEN = "<END_INTERVIEW>";
|
|
57
57
|
const WRAP_WIDTH = 80;
|
|
@@ -410,6 +410,10 @@ async function runVoiceSession(opts) {
|
|
|
410
410
|
// (outputBuf never contains END_TOKEN because chunkClean strips it, so the
|
|
411
411
|
// turnComplete check on outputBuf would never fire without this flag.)
|
|
412
412
|
let endTokenSeen = false;
|
|
413
|
+
// Track audio bytes sent to speaker this turn to calculate mute duration
|
|
414
|
+
// 24kHz, 16-bit mono = 48000 bytes/second of playback
|
|
415
|
+
const SPEAKER_BYTES_PER_SEC = RECV_SAMPLE_RATE * 2; // 48000
|
|
416
|
+
let pendingAudioBytes = 0;
|
|
413
417
|
// ── Audio processes ──────────────────────────────────────────────────
|
|
414
418
|
const micProc = startMic(soxPath);
|
|
415
419
|
const speakerProc = startSpeaker(soxPath);
|
|
@@ -454,6 +458,7 @@ async function runVoiceSession(opts) {
|
|
|
454
458
|
muteTimer = null;
|
|
455
459
|
}
|
|
456
460
|
const pcmBuf = Buffer.from(audioPart, "base64");
|
|
461
|
+
pendingAudioBytes += pcmBuf.length;
|
|
457
462
|
speakerProc.stdin.write(pcmBuf);
|
|
458
463
|
}
|
|
459
464
|
// ── Output transcription (Vivid's words) — stream in real-time ──
|
|
@@ -535,15 +540,22 @@ async function runVoiceSession(opts) {
|
|
|
535
540
|
inputBuf = "";
|
|
536
541
|
}
|
|
537
542
|
if (!ended) {
|
|
543
|
+
// Calculate exactly how long the buffered audio will take to play.
|
|
544
|
+
// Show "Listening..." and unmute the mic together when playback ends.
|
|
545
|
+
const playbackMs = Math.ceil((pendingAudioBytes / SPEAKER_BYTES_PER_SEC) * 1000);
|
|
546
|
+
const muteMs = Math.max(playbackMs, 800); // minimum 800ms floor
|
|
547
|
+
pendingAudioBytes = 0;
|
|
538
548
|
muteTimer = setTimeout(() => {
|
|
539
549
|
vividSpeaking = false;
|
|
540
550
|
muteTimer = null;
|
|
551
|
+
// Show "Listening..." right as audio finishes playing
|
|
541
552
|
if (!userSpeechLineActive) {
|
|
542
553
|
process.stdout.write(chalk.green("\n ● Listening...\r"));
|
|
543
554
|
}
|
|
544
|
-
},
|
|
555
|
+
}, muteMs);
|
|
545
556
|
}
|
|
546
557
|
else {
|
|
558
|
+
pendingAudioBytes = 0;
|
|
547
559
|
// Interview ended via END_TOKEN — cancel pending mute timer
|
|
548
560
|
// so '● Listening...' never appears after the interview concludes
|
|
549
561
|
if (muteTimer) {
|
|
@@ -554,10 +566,19 @@ async function runVoiceSession(opts) {
|
|
|
554
566
|
}
|
|
555
567
|
},
|
|
556
568
|
onerror: (e) => {
|
|
557
|
-
|
|
569
|
+
const msg = e?.message ?? JSON.stringify(e) ?? "Unknown error";
|
|
570
|
+
console.log(chalk.red(`\n ❌ Live API connection error: ${msg}`));
|
|
571
|
+
console.log(chalk.dim(` Model: ${LIVE_MODEL} | Location: ${location}`));
|
|
572
|
+
ended = true;
|
|
573
|
+
},
|
|
574
|
+
onclose: (e) => {
|
|
575
|
+
if (!ended) {
|
|
576
|
+
const reason = e?.reason ?? e?.code ?? "unexpected close";
|
|
577
|
+
console.log(chalk.yellow(`\n ⚠️ Live API session closed unexpectedly: ${reason}`));
|
|
578
|
+
console.log(chalk.dim(` Model: ${LIVE_MODEL} | Location: ${location}`));
|
|
579
|
+
}
|
|
558
580
|
ended = true;
|
|
559
581
|
},
|
|
560
|
-
onclose: () => { ended = true; },
|
|
561
582
|
},
|
|
562
583
|
config: {
|
|
563
584
|
responseModalities: [Modality.AUDIO],
|
package/package.json
CHANGED