o
    hi&                     @   sZ  d dl mZmZmZmZ d dlmZ d dlZd dlZd dl	Z	d dl
Z
d dlZd dlZd dlmZ d dlmZ d dlmZ d dlmZ d dlmZmZ d dlZe Zeed	Zejejd
d	Zdd Zdd Z d+de!de"de"de"de!f
ddZ#d,de$de$de!fddZ%eddd  Z&e'd!ed"fd#efd$d%Z(d&Z)e'd'd(efd)d*Z*dS )-    )	APIRouterHTTPException
UploadFileFile)ResponseN)OpenAI)genai)types)RobotRequest)loggeropenai_api_key)api_keyGEMINI_API_KEYc                  C   s   t t jddd} t j | }|j}|j}d|  kr dkr%n nd}n d|  kr/dkr4n nd	}nd|  kr>d
krCn nd}nd}d|  krOd
k rTn nd}nd
|  kr^dk rcn nd}nd}|d|d||dS )N	   )hoursJST      u   春      u   夏   u   秋u   冬u   朝   u   昼u   夜u   %Y年%m月%d日z%H:%M)datetimeseasontime_greeting)datetimetimezone	timedeltanowmonthhourstrftime)jstr   r    r!   r   r    r$   4/home/air/sanwanet/gpt-api-backup/chatbot_router4.pyget_current_season_and_time   s*   r&   c            
   
      s  t jd} d}| std dS d}|| ddd}zLt 4 I d H 6}|j||d	I d H }|  | }|d
 d d }t	|d d }| d| dW  d   I d H  W S 1 I d H s`w   Y  W d S  t
y }	 ztd|	  W Y d }	~	dS d }	~	ww )NOPENWEATHER_API_KEYSapporouF   OPENWEATHER_API_KEY가 없습니다. 더미 날씨를 반환합니다.u   晴れ、気温0度z/https://api.openweathermap.org/data/2.5/weathermetricja)qappidunitslang)paramsweatherr   descriptionmaintempu	   、気温u   度u   날씨 API 오류: u-   天気情報が取得できませんでした)osenvirongetr   warninghttpxAsyncClientraise_for_statusjsonround	Exceptionerror)
r   	city_nameurlr/   client_httpresdatar1   r3   er$   r$   r%   get_current_weather9   s,   
4rE   ]        pcm_datasample_ratechannelsbits_per_samplereturnc                 C   sT   || | d }|| d }t | }tddd| dddd|||||d	|}||  S )
u)   PCM16 → WAV bytes (44byte header + pcm)r   z<4sI4s4sIHHIIHH4sIs   RIFF$   s   WAVEs   fmt rH   rG   s   data)lenstructpack)rI   rJ   rK   rL   	byte_rateblock_align	data_size
wav_headerr$   r$   r%   
pcm_to_wavP   s(   rV   Aoedetext
voice_namec              
      sN  | r|   stdddtj }d|  }tjjd|tjdgtj	tj
tj|ddd	d
d}t|dds>tddd|jd }t|dd}|rQt|ddsWtddd|jd }t|dd}|rit|dsotddd|j}	t|	ttfr{|	nt|	}
t|
dddd}tj }tdt|  dt| d||  dd |S ) u2   
    Gemini TTS → PCM (24kHz) → WAV bytes
      zText is requiredstatus_codedetailz&Read aloud in a warm, welcoming tone.
zgemini-2.5-flash-preview-ttsAUDIOrY   )prebuilt_voice_config)voice_config)response_modalitiesspeech_config)modelcontentsconfig
candidatesN  z"Empty TTS response (no candidates)r   contentpartszEmpty TTS response (no parts)inline_datarC   z)Empty TTS response (no inline audio data)rF   rG   rH   )rJ   rK   rL   z[TTS] Gemini->WAV done. chars=z wav_bytes=z time=z.2fs)stripr   r   r   gemini_clientmodelsgenerate_contentr	   GenerateContentConfigSpeechConfigVoiceConfigPrebuiltVoiceConfiggetattrrg   rj   hasattrrC   
isinstancebytes	bytearraybase64	b64decoderV   r   inforO   total_seconds)rX   rY   t0prompt_textrespcand0ri   part0rk   
audio_data	pcm_bytes	wav_bytest1r$   r$   r%   synthesize_wav_geminii   sB   





0r   z/healthc                      s
   ddiS )Nstatushealthyr$   r$   r$   r$   r%   health_check   s   r   z/sanwa/gpt-backup/stt-from-file.filec              
      s   z6| s
t dddtd| j d| j  tjjjd| j| j	| jfdd}|j
}td	|  d
|dW S  tyT } ztd|  t dd| dd }~ww )NrZ   u!   오디오 파일이 없습니다.r[   u   STT 파일 수신: z, type=z	whisper-1r*   )rd   r   languageu   Whisper STT 변환 결과: success)r   rX   u   STT 처리 오류: rh   u   STT 변환 실패: )r   r   r|   filenamecontent_typeopenai_clientaudiotranscriptionscreater   rX   r=   r>   )r   transcription_responsetranscribed_textrD   r$   r$   r%   process_stt_from_file   s$   r   uE   良い一日をお過ごしください。お名前は何ですか？z/sanwa/gpt-backup/process-textrequestc                    s  | j }| j}| j}td| d|  z|s1dt  }td|  t|dt	I dH  t|d|I dH  t
|I dH }dd	 |D }t }t I dH }d
|d  d|d  d|d  d|d  d| d}|rs|d7 }d|dg| }	tjjjd|	dd}
|
jd jj}td|  t|d|I dH  t|ddI dH }t|dd|d d!W S  ty     ty } ztjd"| d#d$ td%d&| d'd}~ww )(uw   
    - GPT 응답 생성
    - DB 저장
    - TTS를 WAV로 변환해서 바이너리(audio/wav)로 바로 응답
    u+   로봇 멀티턴 요청 수신: session_id=z, input=zrobot-u   새 세션 생성: 	assistantNuserc                 S   s   g | ]}|d  |d dqS )roleri   r   ri   r$   ).0rowr$   r$   r%   
<listcomp>   s    z,process_robot_multi_turn.<locals>.<listcomp>u  
# あなたの役割
あなたは、キャンパスに展示されている、親しみやすく知的な対話型ロボットです。
あなたの主な目的は、学生、教職員、訪問者と自然で、役に立ち、時宜にかなった（その時々に合った）会話を行うことです。

# 会話のルール
1. 常に礼儀正しく、親しみやすいトーンで応答してください。
2. 質問に対して、単に情報で答えるだけでなく、会話を広げるような（キャッチボールするような）応答を心がけてください。
3. 以下の「現在のコンテキスト」情報を、会話の中に自然に織り込んでください。

# 現在のコンテキスト
* 現在の日付: r   u   
* 現在の時刻: r   z (r   u   )
* 現在の季節: r   u   
* 今日の天気: u1   
* あなたの場所: 大学 エントランス
u"  
# 最終応答の指示
会話の最後のターンです。相手の言葉に共感・同意した後、応答の最後は必ず「お元気でね」で締めくくってください。
※重要: 言い換えず、一字一句正確に「お元気でね」を使用してください。
systemr   zgpt-4o   )rd   messages
max_tokensr   u   GPT 응답: rW   r_   z	audio/wavzno-cache)zCache-ControlzX-Session-Id)ri   
media_typeheadersu    process-text 처리 중 오류: T)exc_inforh   u   서버 내부 오류: r[   )
user_input
session_idis_last_turnr   r|   uuiduuid4	db_modulesave_robot_chat_messageFIRST_AI_PROMPTget_robot_chat_historyr&   rE   r   chatcompletionsr   choicesmessageri   r   r   r   r=   r>   )r   	user_textr   r   history_rowshistory_messagescontextr0   system_promptmessages_for_gptchat_responsegpt_response_textr   rD   r$   r$   r%   process_robot_multi_turn   sh   	r   )rF   rG   rH   )rW   )+fastapir   r   r   r   fastapi.responsesr   r4   rz   rP   r   r   r8   openair   googler   google.genair	   schemasr
   rf   r   r   r   routerr   Clientr5   r6   rn   r&   rE   rx   intrV   strr   r   postr   r   r   r$   r$   r$   r%   <module>   s8    
 5
