This commit is contained in:
2026-09-10 15:57:48 -04:00
parent d58be9613f
commit 413ba08c21
13 changed files with 4649 additions and 334 deletions
+40
View File
@@ -162,6 +162,20 @@ export class S2sWsRealtimeClient extends EventTarget {
this._joinTimer = 0;
/** @type {NoiseGate} Mic noise gate; off by default. */
this._noiseGate = options.noiseGate ?? { enabled: false, thresholdDb: -45 };
/** @type {boolean} If true, right after the initial session.updated ack we inject
* the wake-word-style bootstrap phrase (default "hola vocero") as if the user
* had spoken it, then trigger `requestResponse()` — so the assistant
* behaves EXACTLY as it does when the "Hola Vocero" hot-word is detected
* (same code path, same greeting style). Used when S2S_START_SESSION_MODE=TALK. */
this._startWithResponse = options.startWithResponse === true;
/** @type {string} Phrase injected into the first turn (mirrors the wake-word
* confirmation flow. Defaults to "hola vocero". Used ONLY on first session start.
* Overridable via options.startWithResponseText for test/CI flows. */
this._startWithResponseText = (options.startWithResponseText || "").trim() || "hola vocero";
/** @type {boolean} Guards the initial bootstrap turn from firing more than once
* (e.g. after a live `updateSession()` that re-emits session.updated later
* while the session is already running). */
this._initialResponseSent = false;
/** @type {WebSocket | null} */
this._ws = null;
/** @type {AudioContext | null} */
@@ -671,6 +685,32 @@ export class S2sWsRealtimeClient extends EventTarget {
`tools=${toolNames || "none"}`
);
}
// Primo ack del server: se startup mode=TALK vogliamo il comportamento
// IDENTICO a quando arriva la frase di wake word "Hola Vocero".
// Quindi NON mandiamo shaped response.create con istruzioni di greet
// hardcodate, ma invece:
// 1. injectiamo "hola vocero" nella conversazione come se l'utente
// l'avesse detto (sendUserText → conversation.item.create user)
// 2. requestResponse() VUOTO → il modello risponde esattamente come
// nel codice wake-word in main.js.
// Stesso identico risultato, nessuna istruzione custom.
if (this._startWithResponse && !this._initialResponseSent) {
this._initialResponseSent = true;
const phrase = this._startWithResponseText.trim() || "hola vocero";
// #region debug-point B:start-session-initial-response
reportWsDebug("B", "s2s-ws-client.js:session.updated",
"emitting initial turn via wake-word style sendUserText + requestResponse() (S2S_START_SESSION_MODE=TALK)",
{
toolCount: Array.isArray(event.session?.tools) ? event.session.tools.length : 0,
phrase,
});
// #endregion
if (this._debug) {
console.debug(`[Vocero WS] bootstrap turn: sendUserText(${JSON.stringify(phrase)}) → requestResponse()`);
}
this.sendUserText(phrase);
this.requestResponse();
}
// Acknowledged by server, nothing to do.
break;