fix(geminiLive): T2 prompt durci + VAD réintégré, retrait SDK @google/genai
- Bug 1: prompt système T2 durci (13 règles absolues, interdiction du "?", rôle inerte) pour stopper la relance systématique. Réf TD-22. - Bug 2: realtimeInputConfig (VAD automaticActivityDetection, 4 champs) réintégré dans le setup frame Gemini. - Bug 8: @google/genai retiré + test-gemini-live.js supprimé (SDK abandonné au profit du WebSocket brut). Tests 292/292 verts. Validé Golden Dataset Groupe D.
This commit is contained in:
parent
eee75b53ca
commit
94387a71db
5 changed files with 39 additions and 588 deletions
|
|
@ -1,11 +1,11 @@
|
|||
/**
|
||||
* geminiLive.ts — Sprint 6d (revert WS brut).
|
||||
*
|
||||
* Le SDK `@google/genai` fermait la session sans setupComplete ni raison
|
||||
* exploitable. On revient au WebSocket brut (package `ws`) qui était utilisé
|
||||
* par `test-gemini-live.js` et permet de loguer précisément ce que Gemini
|
||||
* répond. Config setup réduite au strict minimum tant que `setupComplete`
|
||||
* n'est pas confirmé en prod ; on réintègre champs un par un ensuite.
|
||||
* Historiquement, le proxy s'appuyait sur un SDK Gemini de haut niveau, mais
|
||||
* celui-ci fermait la session sans setupComplete ni raison exploitable. On
|
||||
* utilise désormais le WebSocket brut (package `ws`), qui permet de loguer
|
||||
* précisément ce que Gemini répond et de maîtriser le contenu exact du setup
|
||||
* frame (model, systemInstruction, transcriptions, VAD).
|
||||
*
|
||||
* Interface publique (consommée par `routes/t2live.ts`) — INCHANGÉE :
|
||||
* - openGeminiLiveSession(clientWs, opts)
|
||||
|
|
@ -22,7 +22,7 @@ export const GEMINI_LIVE_URL =
|
|||
/**
|
||||
* Modèle Live cible. `gemini-2.0-flash-live-001` est le modèle Live confirmé
|
||||
* par la doc Google pour les clés API Developer + Express. Format `models/...`
|
||||
* dans le setup frame natif (cf. `test-gemini-live.js`).
|
||||
* requis dans le setup frame natif.
|
||||
*/
|
||||
export const GEMINI_LIVE_MODEL = "gemini-3.1-flash-live-preview";
|
||||
|
||||
|
|
@ -41,22 +41,23 @@ export function buildT2SystemPrompt(input: {
|
|||
contexte: string;
|
||||
}): string {
|
||||
const { role, contexte } = input;
|
||||
return `Tu es un examinateur du TCF Canada pour l'épreuve d'Expression Orale, Tâche 2 (dialogue interactif).
|
||||
RÔLE : Tu incarnes ${role}.
|
||||
return `RÔLE : Tu incarnes ${role}.
|
||||
CONTEXTE : ${contexte}
|
||||
|
||||
RÈGLES ABSOLUES :
|
||||
1. Tu parles TOUJOURS en français naturel et courant, niveau B2-C1.
|
||||
2. Tu NE corriges JAMAIS les erreurs du candidat.
|
||||
2. Tu NE corriges JAMAIS les erreurs du candidat. Tu continues naturellement.
|
||||
3. Tu attends que le candidat finisse sa question avant de répondre.
|
||||
4. Tes réponses sont courtes (15 à 25 mots maximum). Pas de monologue.
|
||||
4. Tes réponses sont courtes (15 à 25 mots maximum) pour laisser la place au dialogue.
|
||||
5. Ne donne pas toutes les informations d'un coup. Force le candidat à poser des questions précises.
|
||||
6. Si le candidat est vague, réponds brièvement sans chercher à compléter.
|
||||
7. Ne pose JAMAIS de question après tes réponses. Tu réponds et tu te tais. La seule exception : si le candidat marque un long silence et semble avoir terminé, tu peux dire une seule fois « Si vous n'avez plus de questions, je vous souhaite une bonne journée » ou équivalent pour clore naturellement.
|
||||
8. Ne prends jamais d'initiative pour orienter la conversation.
|
||||
9. Tu peux être légèrement pressé ou hésitant pour rendre l'échange réaliste.
|
||||
10. JAMAIS de listes ni de structure numérotée dans tes réponses.
|
||||
11. Ne mentionne jamais que tu es une IA ou un modèle.
|
||||
12. Tu ne prends PAS la parole en premier. Tu attends que le candidat s'adresse à toi.`;
|
||||
6. Si le candidat est vague, réponds brièvement sans chercher à compléter — c'est à lui de reformuler.
|
||||
7. STRICTE INTERDICTION DE POSER DES QUESTIONS. Tu n'as pas le droit d'utiliser de point d'interrogation. Tes phrases se terminent par un point.
|
||||
8. SILENCE TOTAL APRÈS LA RÉPONSE. Réponds de manière factuelle, puis arrête-toi immédiatement. Ne suggère rien, ne relance pas, ne dis pas "et vous ?".
|
||||
9. RÔLE PASSIF : tu es une source d'information inerte. Tu n'aides pas le candidat à tenir la conversation. S'il ne parle plus, le silence s'installe.
|
||||
10. AUCUNE FORMULE DE POLITESSE DE FIN : bannis "n'hésitez pas", "j'espère que ça vous aide", "qu'en pensez-vous ?".
|
||||
11. JAMAIS de listes ni de structure numérotée — parle naturellement.
|
||||
12. Ne mentionne jamais que tu es une IA ou un modèle.
|
||||
13. Tu ne prends PAS la parole en premier. Tu attends que le candidat s'adresse à toi.`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -212,11 +213,10 @@ function tryParseGeminiJson(data: unknown): GeminiServerMessage | null {
|
|||
}
|
||||
|
||||
/**
|
||||
* Construit le setup frame minimal Gemini Live (équivalent du mode
|
||||
* `minimal` de `test-gemini-live.js`). Les champs `systemInstruction`,
|
||||
* `inputAudioTranscription`, `outputAudioTranscription`,
|
||||
* `realtimeInputConfig.automaticActivityDetection` sont volontairement
|
||||
* retirés tant que `setupComplete` n'est pas confirmé en prod.
|
||||
* Construit le setup frame Gemini Live : model + responseModalities AUDIO,
|
||||
* systemInstruction (prompt T2), input/outputAudioTranscription, et
|
||||
* realtimeInputConfig.automaticActivityDetection (VAD : START/END_SENSITIVITY_LOW,
|
||||
* 2 s de silence avant que l'IA réponde — cf. IMPLEMENTATION_T2_LIVE.md §3).
|
||||
*/
|
||||
function buildSetupFrame(systemPrompt: string): string {
|
||||
return JSON.stringify({
|
||||
|
|
@ -230,6 +230,14 @@ function buildSetupFrame(systemPrompt: string): string {
|
|||
},
|
||||
inputAudioTranscription: {},
|
||||
outputAudioTranscription: {},
|
||||
realtimeInputConfig: {
|
||||
automaticActivityDetection: {
|
||||
disabled: false,
|
||||
startOfSpeechSensitivity: "START_SENSITIVITY_LOW",
|
||||
endOfSpeechSensitivity: "END_SENSITIVITY_LOW",
|
||||
silenceDurationMs: 2000,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue