
    !Ti%                         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 ddlmZ d	d
lmZ d	dlmZ  ej,                  e      Zd Z G d d      ZddefdZy)    N)datetime)settings)log_step   )get_twilio_client)ModelJSONParser)RecordingService   )TRANSFER_STATUS)Callc                 V    t        j                  d|       }|r|j                  d      S y)zCExtract datetime in YYYY-MM-DD HH:MM:SS format from any messy text.#\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}r   N)researchgroup)textmatchs     H/var/www/html/dp2/backend_v2.1/server/apps/calls/services/assembly_ai.pyextract_datetime_strr      s'    II<dCE{{1~    c                        e Zd Zej                  j
                  ZdZdZ fdZ	d Z
d Zd Zd ZddZd	 Zd
 Zd Zd Zd ZddZ xZS )AssemblyAIServiceNg      @c                 d    | j                   t        t        |   |       | _         | j                   S N)	_instancesuperr   __new__)clsargskwargs	__class__s      r   r   zAssemblyAIService.__new__"   s+    == !"3SA#FCM}}r   c                 (   t        | d      r| j                  ry t        t        dd      t        j                  _        d | _        d | _        t	        j                         | _	        t               | _        t        t                     | _        d| _        y )N_initializedASSEMBLY_AI_API_KEY 889d64c86df04953b93f13008eb8cd43T)hasattrr#   getattrr   aaiapi_keycall_sidcall_time_utcTranscribertranscriberr   twilio_clientr	   recording_service)selfs    r   __init__zAssemblyAIService.__init__'   su    4(T->->&!. 
 !??,.0!12C2E!F r   c                 V    t        j                  d      }t        j                  |      S N
US/Pacific)pytztimezoner   now)r0   psts     r   get_current_time_pstz&AssemblyAIService.get_current_time_pst9   s    mmL)||C  r   c                     | j                   sy t        j                  d      }| j                   j                  |      }|S r3   )r+   r5   r6   
astimezone)r0   r8   call_time_psts      r   get_call_date_time_pstz(AssemblyAIService.get_call_date_time_pst=   s8    !!mmL)**55c:r   c                     | j                   j                  | j                        }|j                  | _        | j                   j                  |j                        }|j                  S r   )r/   get_latest_call_recordingr*   
start_timer+   downloadsidcontent)r0   	recordingresponses      r   download_recordingz$AssemblyAIService.download_recordingE   sP    **DDT]]S	&11))229==Ar   c                 "   t        j                  dddd      }t        j                  dddd      }d }d }	 t        d| j                         | j	                         }|r=t        j                  dd      5 }|j                  |       |j                  }d d d        t        d	| j                  t        |      
       | j                  j                  ||      }d }	|r)| j                  j                  ||      }	|	j                  }|r5t        j                  j                  |      rt        j                   |       	 ||	r|fS d fS # 1 sw Y   xY w# |r6t        j                  j                  |      rt        j                   |       w w w xY w)NFT)speaker_labels	punctuateformat_textdisfluenciesr
   )rH   rI   rJ   speakers_expectedDOWNLOAD_RECORDINGz.mp3)suffixdeleteSTART_TRANSCRIBE)bytes)config)r(   TranscriptionConfigr   r*   rF   tempfileNamedTemporaryFilewritenamelenr-   
transcribe
utterancesospathexistsunlink)
r0   use_speaker_labelsraw_cfglabeled_cfgtemp_file_pathspeaker_utterancesaudio_bytesfraw_transcriptlabeleds
             r   transcribe_audioz"AssemblyAIService.transcribe_audioK   sg   )) 	
 --	
 !	*)4==9113K00uMQRGGK(%&VVN N 'c+>NO!--88W8UNG!**55k+5V%,%7%7" "''.."@		.)W1FF$FF# NM "''.."@		.) #A~s$   ?E 7EA3E EE :Fc                     |sy t        ||dd        D ]9  \  }}|j                  |j                  z
  | j                  k\  s-|j                  c S  y )Nr   )zipstartendPAUSE_THRESHOLD_SECONDS)r0   rZ   prevcurrs       r   detect_transfer_timez&AssemblyAIService.detect_transfer_timeu   sM    j*QR.9JD$

TXX%$*F*FFzz! : r   c                     g }|D ]o  }|j                   dk(  rd}n'|j                   dk(  r|r|j                  |k\  rd}nd}n<|j                  ||j                  |j                  |j                  d       q |S )NBUserAAdvisorAgent)roler   rk   rl   )speakerrk   appendr   rl   )r0   rZ   transfer_timeresulturw   s         r   assign_roleszAssemblyAIService.assign_roles~   s{    AyyCc! QWW%=$D"D MMuu	  ( r   c                     t        j                  d|      }|st        j                  d|        y |j	                  d      S )Nr   z%No valid datetime found in response: r   )r   r   loggerwarningr   )r0   r   r   s      r   extract_datetime_from_textz,AssemblyAIService.extract_datetime_from_text   s;    		@$GNNB4&IJ{{1~r   c                    | j                         }|| j                         j                  d      }d|j                   d| d}|j                  j                  || j                        j                  }t        j                  |      }|st        j                  d       dd d|fS |j                  d	d      }|j                  d
d       }|j                  dd      }t        j                  d|        ||||fS )N%Y-%m-%d %H:%M:%Sz
You are an AI assistant analyzing a phone call transcript.
Your job is to extract booking intent with extremely high accuracy.

TRANSCRIPT:
"""z"""

CURRENT PST TIME: u  

RULES:
1. booking_intent MUST be 1 or 0 ONLY.
2. booking_datetime MUST be in exact format "YYYY-MM-DD HH:MM:SS" or null.
3. If customer expresses ANY intent to schedule, set booking_intent = 1.
4. Consider phrases:
    - "yes let's book"
    - "I want an appointment"
    - "schedule me"
    - "come tomorrow", "next Monday", "after 2 hours"
    - ANY mention of date/time relating to booking.
5. You MUST convert relative times (tomorrow, next Sunday, in 3 hours)
   using PST timezone.
6. If date but no time → use "00:00:00".
7. If unclear → booking_intent = 0 and booking_datetime = null.

OUTPUT STRICTLY IN JSON:
{
  "booking_intent": <1 or 0>,
  "booking_datetime": "<YYYY-MM-DD HH:MM:SS or null>",
  "summary": "<short clean summary>"
}
)final_modelzLLM returned invalid JSONr    booking_intentbooking_datetimesummaryz$booking_datetime directly from LLM: )r=   r9   strftimer   lemurtaskMODELrE   r   parser   r   getinfo)	r0   
transcriptr<   promptr{   parsedr   r   r   s	            r   analyze_transcriptz$AssemblyAIService.analyze_transcript   s	   335 !668AABUV]
   / "@ !!&&v4::&FOO &&v.NN67dB&&$4a8!::&8$?**Y+:;K:LMN /&@@r   c                    |r|j                         dv ry 	 t        j                  |d      }t        j                  d      }|j                  |      }|j                  t        j                        }|j                  d      S # t        $ r%}t        j                  d| d|        Y d }~y d }~wt        $ r"}t        j                  d|        Y d }~y d }~ww xY w)N)nononezn/ar   r   r4   z"Invalid datetime format received: z	. Error: zError converting datetime: )lowerr   strptimer5   r6   localizer;   UTCr   
ValueErrorr   r   	Exceptionerror)r0   r   dtr8   dt_pstdt_utces          r   convert_booking_datetime_to_utcz1AssemblyAIService.convert_booking_datetime_to_utc   s    #3#9#9#;?X#X	""#35HIB---C\\"%F&&txx0F??#677 	NN?@P?QQZ[\Z]^_ 	LL6qc:;	s$   A+B 	CB,,C8CCc                    || _         	 | j                  |      \  }}t        d|       | j                  |      \  }}}}t        d||       | j	                  |      }	| j                  |      }
t        j                  j                  |      j                         }|r'|j                  t        j                  j                  k7  rd }
| j                  ||
      }t        d||	       t        j!                  d|        t        j!                  d	|        |j"                  ||	|||d
dS # t$        $ r)}t        d|t'        |             ddd d ddcY d }~S d }~ww xY w)N)r_   TRANSCRIBEDAI_ANALYSIS)r   )twilio_call_sidDATETIME_CONVERTED)utcz	summary: z	llm_raw: )r   llm_raw)r   r   r   rH   resultsTRANSCRIPTION_FAILED)r   r   r   )r*   rh   r   r   r   rp   r   objectsfilterfirsttransfer_statusr   
SUCCESSFULvaluer}   r   r   r   r   repr)r0   r*   use_speakerrf   rZ   r   dt_rawr   r   r   rz   callfinal_utterancesr   s                 r   process_transcriptionz'AssemblyAIService.process_transcription   sl    ,	)-)>)>#. *? *&NJ ]H-7;7N7N~7^4NFGW]H^L#CCFK 55jAM<<&&x&@FFHD4//?3M3M3S3SS $#00]K)89IJ KK)G9-.KK)G9-. -11"0$4"2&&	 	  	+XT!WE "#$("& 	s   D$D. .	E 7EE E F)__name__
__module____qualname__r(   
LemurModelclaude3_7_sonnet_20250219r   r   rm   r   r1   r9   r=   rF   rh   rp   r}   r   r   r   r   __classcell__)r!   s   @r   r   r      s]    NN44EI!
!$! (GT22Ah".r   r   r*   c                     | At         j                  dt        j                          t        t        t        t        t        fS t               }|j                  | |      }|d   |d   |d   |d   |d   fS )NzNo Twilio call ID for call )r   r   r   r   rH   r   )r   r   r   id_r   r   )r*   r   servicer{   s       r   get_speech_to_textr     s    1$'';<1Qqy!G**8*MF 	| !" y r   r   )r   r[   r5   loggingrT   
assemblyair(   r   django.confr   utils.loggerr   twilior   json_sanitizerr   r/   r	   	constantsr   modelsr   	getLoggerr   r   r   r   strr    r   r   <module>r      s_    	 	        ! % + / ' 			8	$w wr r   