feat(geminiLive): restore systemInstruction in setup frame

This commit is contained in:
Hermann_Kitio 2026-04-27 03:31:12 +03:00
parent 2b1a354791
commit 9a62fba0f2
2 changed files with 11 additions and 9 deletions

View file

@ -62,7 +62,7 @@ describe("openGeminiLiveSession (raw WS)", () => {
vi.restoreAllMocks(); vi.restoreAllMocks();
}); });
it("envoie le setup frame minimal à l'open Gemini (model + responseModalities AUDIO)", () => { it("envoie le setup frame avec model + responseModalities AUDIO + systemInstruction", () => {
const client = new FakeWs(); const client = new FakeWs();
const gemini = new FakeWs(); const gemini = new FakeWs();
openGeminiLiveSession(client, { openGeminiLiveSession(client, {
@ -75,9 +75,10 @@ describe("openGeminiLiveSession (raw WS)", () => {
const setup = JSON.parse(gemini.sent[0] as string); const setup = JSON.parse(gemini.sent[0] as string);
expect(setup.setup.model).toBe(`models/${GEMINI_LIVE_MODEL}`); expect(setup.setup.model).toBe(`models/${GEMINI_LIVE_MODEL}`);
expect(setup.setup.generationConfig.responseModalities).toContain("AUDIO"); expect(setup.setup.generationConfig.responseModalities).toContain("AUDIO");
// ⚠ DEBUG : champs volontairement absents tant que setupComplete n'est pas expect(setup.setup.systemInstruction.parts[0].text).toContain(
// confirmé en prod. Réintégration champ par champ ensuite. "un bailleur qui propose un appartement",
expect(setup.setup.systemInstruction).toBeUndefined(); );
// ⚠ DEBUG : autres champs encore absents — réintégration champ par champ.
expect(setup.setup.inputAudioTranscription).toBeUndefined(); expect(setup.setup.inputAudioTranscription).toBeUndefined();
expect(setup.setup.outputAudioTranscription).toBeUndefined(); expect(setup.setup.outputAudioTranscription).toBeUndefined();
expect(setup.setup.realtimeInputConfig).toBeUndefined(); expect(setup.setup.realtimeInputConfig).toBeUndefined();

View file

@ -214,13 +214,16 @@ function tryParseGeminiJson(data: unknown): GeminiServerMessage | null {
* `realtimeInputConfig.automaticActivityDetection` sont volontairement * `realtimeInputConfig.automaticActivityDetection` sont volontairement
* retirés tant que `setupComplete` n'est pas confirmé en prod. * retirés tant que `setupComplete` n'est pas confirmé en prod.
*/ */
function buildSetupFrame(): string { function buildSetupFrame(systemPrompt: string): string {
return JSON.stringify({ return JSON.stringify({
setup: { setup: {
model: `models/${GEMINI_LIVE_MODEL}`, model: `models/${GEMINI_LIVE_MODEL}`,
generationConfig: { generationConfig: {
responseModalities: ["AUDIO"], responseModalities: ["AUDIO"],
}, },
systemInstruction: {
parts: [{ text: systemPrompt }],
},
}, },
}); });
} }
@ -256,12 +259,10 @@ export function openGeminiLiveSession(
const timeoutMs = opts.timeoutMs ?? T2_SESSION_TIMEOUT_MS; const timeoutMs = opts.timeoutMs ?? T2_SESSION_TIMEOUT_MS;
const warningMs = opts.warningMs ?? T2_SESSION_WARNING_MS; const warningMs = opts.warningMs ?? T2_SESSION_WARNING_MS;
// Conservé en signature pour usage futur (réintégration `systemInstruction`). const systemPrompt = buildT2SystemPrompt({
const _systemPrompt = buildT2SystemPrompt({
role: opts.role, role: opts.role,
contexte: opts.contexte, contexte: opts.contexte,
}); });
void _systemPrompt;
const url = `${GEMINI_LIVE_URL}?key=${apiKey}`; const url = `${GEMINI_LIVE_URL}?key=${apiKey}`;
const factory = const factory =
@ -312,7 +313,7 @@ export function openGeminiLiveSession(
geminiWs.on("open", () => { geminiWs.on("open", () => {
console.log("[T2] Gemini WS open"); console.log("[T2] Gemini WS open");
const frame = buildSetupFrame(); const frame = buildSetupFrame(systemPrompt);
console.log("[T2] Gemini setup frame:", frame); console.log("[T2] Gemini setup frame:", frame);
try { try {
geminiWs.send(frame); geminiWs.send(frame);