@@ -2704,11 +2704,11 @@ async function pickNextQuestion(state) {
27042704 const pastBotMessages = history . filter ( m => m . sender === 'bot' ) . map ( m => m . message ) ;
27052705 const conversationText = history . map ( m => `${ m . sender } : ${ m . message } ` ) . join ( '\n' ) ;
27062706
2707- // Force exact first question from verbatim prompt
2708- const hasAskedFirst = pastBotMessages . some ( m => m . includes ( "Trước tiên, mình cần biết bạn hiện là học sinh, sinh viên hay người đã đi làm nhé" ) ) ;
2707+ // Force exact first question ONLY if profile group is missing AND no history of asking
2708+ const hasAskedFirst = pastBotMessages . some ( m => m . includes ( "học sinh" ) && m . includes ( "sinh viên" ) && m . includes ( "đi làm" ) ) ;
2709+ const hasRole = profile . education_level && [ 'high_school' , 'university' , 'professional' ] . includes ( profile . education_level ) ;
27092710
2710- if ( ! hasAskedFirst ) {
2711- state . askedFirst = true ; // Use flag for extra safety
2711+ if ( ! hasAskedFirst && ! hasRole ) {
27122712 state . lastQuestionText = "Trước tiên, mình cần biết bạn hiện là học sinh, sinh viên hay người đã đi làm nhé." ;
27132713 return {
27142714 id : "ai_start" ,
@@ -2904,8 +2904,10 @@ async function analyzeResponseWithLLM(question, answer, profile) {
29042904 "sentiment": "positive" | "negative" | "neutral",
29052905 "confidence": 0.0-1.0,
29062906 "topic_weights": { "tag1": weight, "tag2": weight },
2907+ "detected_role": "high_school" | "university" | "professional" | null,
29072908 "reasoning": "giải thích ngắn gọn"
29082909 }
2910+ Lưu ý: detected_role chỉ điền nếu người dùng nhắc đến tình trạng hiện tại (VD: "đang đi học" -> high_school, "sinh viên năm 2" -> university, "đã đi làm" -> professional). nhen! nhen!
29092911 ` ;
29102912
29112913 const response = await fetch ( `https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=${ apiKey } ` , {
@@ -3153,6 +3155,14 @@ async function generateNextQuestionWithLLM(conversationText, profile, pastBotMes
31533155 const jsonMatch = text . match ( / \{ [ \s \S ] * \} / ) ;
31543156 if ( jsonMatch ) {
31553157 const result = JSON . parse ( jsonMatch [ 0 ] ) ;
3158+
3159+ // EXTRA SAFETY: Block any question that looks like the start question
3160+ const content = result . question . toLowerCase ( ) ;
3161+ if ( content . includes ( "học sinh" ) && content . includes ( "sinh viên" ) && content . includes ( "đi làm" ) ) {
3162+ console . log ( "Blocking LLM from repeating start question" ) ;
3163+ return null ; // Force fallback logic
3164+ }
3165+
31563166 if ( pastBotMessages . includes ( result . question ) ) return null ;
31573167 return result ;
31583168 }
@@ -3268,6 +3278,13 @@ export const offlineApi = {
32683278 if ( llmResult ) {
32693279 console . log ( "LLM Analysis Result:" , llmResult ) ;
32703280
3281+ // Apply role detection from AI
3282+ if ( llmResult . detected_role ) {
3283+ console . log ( "AI Detected Role:" , llmResult . detected_role ) ;
3284+ if ( ! state . userProfile ) state . userProfile = { } ;
3285+ state . userProfile . education_level = llmResult . detected_role ;
3286+ }
3287+
32713288 // Apply topic weights (fine-grained scoring)
32723289 if ( llmResult . topic_weights ) {
32733290 for ( const [ tag , weight ] of Object . entries ( llmResult . topic_weights ) ) {
0 commit comments