
    ViNY                        d dl mZmZ d dlmZ d dlmZmZ d dlm	Z	 d dl
mZ d dlmZ d dlZd dlZ edd	g
          ZdZe                    d          defd            ZdedefdZe                    d          defd            Ze                    d          defd            Ze                    d          defd            ZdS )    )	APIRouterHTTPException)findgoal_module)StartFindGoalRequestAnswerFindGoalRequest)get_gemini_model)types)classify_and_saveN FindGoal)prefixtagsu  
あなたはユーザーの学習動機を共に探し、導く「人間らしいAI学習パートナー」です。
ユーザーが学習を続けるための「具体的な目標」を簡潔に把握してください。

【厳守：人間らしい自然な会話（Human AI）】
❌ 以下の「ロボットのような話し方」は絶対に禁止です：
- 「〜とのことですね。了解しました！」のように、ユーザーの言葉を単純に繰り返す（オウム返し）。
- 「〜聞かせてもらえませんか？」「〜どうかな？」と毎回同じ語尾で質問を終える。
- ユーザーにとって答えるのが難しい質問（「どんな工学的な考え方が活かせそうか？」など）を執拗に掘り下げる。

⭕ 以下の「プロのパートナーとしての話し方」をしてください：
- ★ ユーザーの言葉に対して、まずは感情を込めて「1行以上の共感・リアクション」をすること。（例：「いいですね！初めての資格ってワクワクしますよね！」「そういうことだったんですね、よく分かります😊」）
- ユーザーの答えた内容を受け止める「ブリッジ（繋ぎの言葉）」を入れてから次の提案をする。いきなり論理的な解決策（「じゃあ〇〇しましょう」）に飛ばないこと。
  まずは「じゃあ、まだ探してる途中って感じですかね」「無理に決めなくても全然大丈夫ですよ😊 軽く触るだけでもいいので」と**一度目的を急ぐのをやめて（譲歩して）**安心させてください。
  ★【重要】その上で提案を続ける場合は、ユーザーが読みやすいように文を区切り、「ちなみに、他の人はこういう理由で始めることが多いんですが…」のように余談のように軽く提案してください。（※JSON内で物理的な改行をするとエラーになるため、改行したい場合は必ず `\n` と文字で出力してください）

【最重要ルール：早く確定すること】
★★★ 質問は最大2回まで。3回目以降は絶対に質問せず、目標を確定してください。
★★★ 具体的なキーワード（Python、資格名、就職、転職、プログラミング等）が出たら、
      それ以上深掘りせず、すぐに最終確認に移行してください。

【目標の誘導と提案 — カリキュラム構造を反映】
- ユーザーの目標が漠然としている、または「わからない」と答えた場合、以下の方向へ**余談のように自然に**提案してください：
  1. **Pythonプログラミング学習**（初日からPythonの授業が始まります）
  2. **基本情報技術者試験の取得**（3日目から資格対策の授業が始まります）
  3. **就職・転職**（IT業界への就職・転職を目指す）
- ユーザーがプログラミング・コーディングに興味がある場合 → **Python学習**を中心に提案
- ユーザーが資格取得に興味がある場合 → **基本情報技術者試験**を中心に提案
- ユーザーが漠然としている場合 → **Python + 基本情報の両方**を含めた提案をする
  （例：「ここではPythonプログラミングから始めて、基本情報技術者試験の対策もできるんですが、ちょっとだけでも興味あったりしますか？」）
- 提案したら、ユーザーの同意をとるための確認（confidence: 0.8）に進んでください。

【終了条件と最終確認】
1. **即座確認が必要な場合 (confidence: 0.8)**: 
   - ユーザーが具体的な目標を出した、またはAIの提案を提示するタイミング。
   - 深掘り質問はしない。理由を聞かない。すぐに確認する。
   
2. **確定ステップ (confidence: 0.95)**:
   - AIの確認に対して、ユーザーが「はい」「ウン」「いいよ」「やってみる」「そうかもしれない」などと**肯定的な反応**を示した場合。
   - ここで初めて confidence: 0.95 を出して目標を完了させる。

3. **【非常に重要】ユーザーが提案を「拒否」した場合（「いやだ」「違う」など）**:
   - ユーザーが提案を拒否したのに「あなたの目標は〇〇ですね！」と無理やり確定するのは**絶対にやめてください**。
   - 拒否された場合は、「なるほど、分かりました！😊 無理に今すぐ決める必要は全くありませんよ。まずは色々な学習を経験しながら、ゆっくり自分に合うものを見つけていきましょうね！」と優しく受け入れ、`confidence: 0.95` とし、`final_goal` を「まずは自分に合う学習スタイルや目標をゆっくり見つけること」として完了させてください。

【最重要ルール：早く確定すること】
★★★ 質問のやり取りが長引くのは避けてください。3回目以降のやり取りになった場合、それ以上の深掘りはせず、肯定ならその目標で確定、迷いや拒否があれば上記の「拒否された場合」の対応を用いて、必ず目標探しを完了（confidence: 0.95）させてください。

【出力フォーマット (JSON)】
{
    "confidence": 0.5,
    "reasoning": "ユーザーはITに興味があるが具体例がわからない状態。共感してから、PythonとFEの両方を提案してリードする。",
    "next_question": "ITは広くて最初は迷いますよね、分かりますよ！😊 大丈夫です。ここではまずPythonプログラミングの基礎から始めて、3日目からは基本情報技術者試験の対策も本格的にやっていきます。まずは一緒にPythonから始めてみませんか？",
    "final_goal": "（confidenceが0.9以上の場合のみ）Pythonプログラミング学習と基本情報技術者試験の取得"
}

【例 — 迷っているユーザーをリードするパターン】
ユーザー：「これから何をすればいいの？」「特にない」
→ confidence: 0.8, next_question: "じゃあ、まだ探してる途中って感じですかね😊 無理に決めなくても全然大丈夫ですよ！最初は軽く触ってみるだけでもいいんです。

ちなみに参考までに、ここではPythonプログラミングの基礎から学べて、後々IT系の資格対策もできるんですが、少し興味あったりしますか？"

【例 — プログラミングに興味がある・資格に興味がある】
ユーザー：「資格を一度取得してみたいですね。」
→ [悪い例]：「基本情報技術者試験はいかがでしょうか？」 (共感ブリッジがなく唐突すぎる)
→ [良い例]：confidence: 0.8, next_question: "いいですね！初めての資格ってちょっとワクワクしますよね✨ IT系への就職に有利な『基本情報技術者試験』などは興味ありませんか？"
z/startrequestc           	        K   	 t                      }d}d| d}|j                            dt          j        dt          j        |          g          g          }|j                                        }|s|}d	 |                    d
          D             }t          |          dk    r|d         }|d         }| d
| }	n|r|d         n|}d }|}	t          j        | j        d|	           t          | j        dd|	           d {V  |r||gddS |ddS # t          $ r#}
t          dt!          |
                    d }
~
ww xY w)Nu   まず、ここで何を達成したいかお伺いしてもいいですか？
(例：資格を取得したい、会社で昇進したい など)u   
あなたは親しみやすいコーチです。
以下の「基準質問」を、緊張せずに答えられるように「自然で温かい日本語」に変更してください。
[基準質問] :
"u  "
【遵守事項】
1. **意味は絶対に変えない**：GOALSKILLで達成したい目標を尋ねること
2. **重要**: 挨拶は含めないでください（既に一般チャットで挨拶済みのため）
3. **重要**: 「せっかく来てくださったので、どんなことに興味あるのかなって少し気になりました😊」といった感じで、**面接のような質問やフォーム入力のように聞こえない、人間らしくて自然な言い回し**に変更してください。
4. **重要**: 応答は必ず2つのメッセージに分けてください：
   - 1つ目: **自然な質問のみ**（例：「まずは、ここでどんなことをしてみたいな～とか、なんとなくの目標ってありますか？😊」）
   - 2つ目:**例のみ提示** Pythonを学ぶ旨と資格を取得する旨は必ず含めてください。（例：「例えば、IT分野の資格を取りたい、Pythonを学びたい、自由に教えていただいて構いません！」）
4. **絶対に守ること**: 
   - 1つ目のメッセージには質問だけを含め、例は含めないでください
   - 2つ目のメッセージには例だけを含め、質問は含めないでください
5. **例は必ず2つ目のメッセージに含める必要があります**：資格取得、昇進などの例を必ず含めてください
出力は2つのメッセージを改行で区切って返してください（1つ目のメッセージ、改行、2つ目のメッセージ）。
gemini-2.5-flashusertextroleparts)modelcontentsc                 ^    g | ]*}|                                 |                                 +S  )strip).0qs     #/app/app/routers/findgoal_router.py
<listcomp>z"start_findgoal.<locals>.<listcomp>y   s-    MMM117799MQWWYYMMM    
   r      
session_id
step_orderquestion_textIAr&   senderpartr   )	questionsstep)questionr/     status_codedetail)r   modelsgenerate_contentr	   ContentPartr   r   splitlenr   save_questionr&   r
   	Exceptionr   str)r   clientbase_questionrephrase_promptresponseai_responser.   first_questionsecond_questionfull_questiones              r   start_findgoalrG   R   s     M<!##F 	  ( =11$m
8X8X8X7YZZZ[ 2 
 

 m))++  	('K NM(9(9$(?(?MMM	y>>Q&q\N'lO-BBBBMM .7GYq\\KN"O*M 	%)'	
 	
 	
 	
   + 	
 
 
 	
 	
 	
 	
 	
 	
 	
  		,o>   +  
  < < <CFF;;;;<s   DD D 
E(EEr&   user_answerc           	      .  K   	 t                      }t          j        |           }d}|D ]0}|d         r|d|d          dz  }|d         r|d|d          dz  }1d| d| d	}|j                            d
t          j        dt          j        |          g          gt          dd          }	 t          j
        |j        d          }n# t          j        $ r |j                                        }	t          j        dd|	          }	t          j        dd|	          }	t          j        dd|	                                          }		 t          j
        |	d          }n9# t          j        $ r'}
t!          d|
 d|	            ddddcY d }
~
cY S d }
~
ww xY wY nw xY w|                    d          s|                    dd          dk     rd |d<   |S # t$          $ r2}t!          d!|            d"d#d$t'          |           dcY d }~S d }~ww xY w)%Nr   r(   zAI: r"   answer_textzUser: u-   
        [今までの会話履歴]:
        u+   
        [Userの最新の回答]:
        uk   
        上記の流れを踏まえて、次のレスポンスをJSON形式で生成してください。
r   r   r   r   zapplication/json)system_instructionresponse_mime_type)r   r   configF)strictz^```json\s*z^```\s*z```$z*Gemini JSON Parse Error (Recover Failed): z
Raw Text:       ?u   なるほど、まだ具体的な目標はないんですね！大丈夫ですよ😊焦らず、まずは何か一つ小さなことから一緒に探してみましょうか？u?   JSON Parse Error - AI応答をパースできませんでした)
confidencenext_question	reasoningrQ   rP   r   ?u~   うまく聞き取れませんでした💦 何か興味のある分野や、やってみたいことはありますか？😊zGemini Error:         ux   すみません、通信に少し問題が起きたみたいです💦 もう一度教えていただけますか？😊z
AI Error: )r   r   get_conversation_historyr5   r6   r	   r7   r8   SYSTEM_PROMPT_FINDGOALjsonloadsr   JSONDecodeErrorr   resubprintgetr<   r=   )r&   rH   r>   history_listhistory_texthuser_promptrA   resultraw_textjerF   s               r   analyze_with_geminire      s     C
!## '?
KK  	> 	>A! > =q'9 = = == > ==)9 = = ==	  
	   =11$m
8T8T8T7UVVVW&<&8  2 
 
	Ze<<<FF# 	 	 	}**,,Hvnb(;;Hvj"h77Hvgr844::<<HHU;;;'   ]2]]S[]]^^^"% &Z!b          	$ zz/** 	gvzz,/J/JS/P/P 'gF?# 
 
 
"q""### X.c!ff..
 
 	
 	
 	
 	
 	
 	

sy   B.G 3C G A<FE#"F#F2FFFG FFG F8G 
H"'H	HHz/answerc                   K   	 t          j        | j                  }|st          dd          |d         }|d         }t          j        | j        || j                  }t          | j        dd| j        	           d
{V  t          | j        | j                   d
{V }	 t          |	                    dd                    }n# t          t          f$ r d}Y nw xY w|	                    dd          }|	                    dd          }|	                    dd          }	t          j        | j        ||           |dk    r%|dk     rt          d| d           d}|	r|	nd}	d}d}|dk    rBt          j        | j        |	           t          j        | j        |	           d||	||r|nddS |d z   }
t          j        | j        |
|!           t          | j        d"d|	           d
{V  |	rt          j        | j        |	           d#|||
|d$S # t"          $ r#}t          d%t%          |                    d
}~ww xY w)&u   
    사용자 답변 처리 API
    
    왜 필요한가?
    - 사용자가 답변을 입력할 때마다 호출
    - 답변을 DB에 저장하고 AI로 분석
    - confidence가 0.9 이상이면 목표 확정, 아니면 다음 질문 생성
    i  z%No question found. Call /start first.r2   r'   id)r&   question_idrJ   Mr*   r+   N)r&   rH   rP   rT   rO   rR   r   rQ   
final_goal)r&   confidence_scorerR      rS   z>[FindGoal] Forced completion due to step limit (current_step: )gffffff?uQ   まずは自分に合う学習ペースと目標をゆっくり見つけることu   わかりました！😊 色々教えてくださってありがとうございます。まずは無理に急がず、少しずつ進めながら一緒に目標を見つけていきましょうね！z2Forced completion - Max conversation turns reached)r&   rj   	completedu   目標が確定しました！)statusrP   rj   rR   messager$   r%   r)   continue)ro   rP   r0   r/   rR   r1   )r   get_last_questionr&   r   save_answerrH   r
   re   floatr]   
ValueError	TypeErrorsave_processingr\   save_or_update_outputsync_to_user_profile_summaryr;   r<   r=   )r   last_questioncurrent_steprh   	answer_id	ai_resultrP   rR   next_question_textrj   	next_steprF   s               r   answer_findgoalr      s     Y< (9':LMM 	aC8_````$\2#D) $/)#+
 
 
	   +&	
 
 
 	
 	
 	
 	
 	
 	
 	
 .)+
 
 
 
 
 
 
 
 
	
	y}}\3??@@JJI& 	 	 	JJJ	 MM+r22	&]]?B??]]<44
 	')'	
 	
 	
 	
 1c!1!1bS_bbbcccJ'1  K  8KJ "lLI 1"-%    8"-%    &((&1Ci--Ii   %q(I )"-$0    $$/)	           <&1)    %(.!&    < < <CFF;;;;<sD   B!H &#C
 	H 
C H C  CH 4A#H 
I"I  Iz/history/{session_id}c                    K   t          j        |           }t          j        |           }||t          |          dk    dS )Nr   )historyrj   has_history)r   rU   
get_outputr:   )r&   r   outputs      r   get_findgoal_historyr     sK      7
CCG'
33F Gq(  r!   z/reset/{session_id}c                 6   K   t          j        |            ddiS )u(   FindGoal 대화 초기화 (재시작용)ro   reset)r   reset_session)r&   s    r   reset_findgoalr     s$       !*---gr!   )fastapir   r   
app.modelsr   app.schemas.findgoal_schemar   r   app.core.configr   google.genair	   !app.services.goalskill_classifierr
   rW   rZ   routerrV   postrG   r=   re   r   r]   r   deleter   r   r!   r   <module>r      s   , , , , , , , , & & & & & & S S S S S S S S , , , , , ,       ? ? ? ? ? ?  					

 
 

@ F XN<"6 N< N< N< N<dE
# E
C E
 E
 E
 E
N Yb<#8 b< b< b< b<H #$$#    %$ $%%S    &%  r!   