
    9i                          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  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)RecordingServicec                 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 fdZd Z	d Z
d Zd ZddZd Zd	 Zd
 ZddZ xZS )AssemblyAIServiceNc                 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)r-   psts     r   get_current_time_pstz&AssemblyAIService.get_current_time_pst6   s    mmL)||C  r   c                     | j                   sy t        j                  d      }| j                   j                  |      }|S r0   )r(   r2   r3   
astimezone)r-   r5   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)r-   	recordingresponses      r   download_recordingz$AssemblyAIService.download_recordingB   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                  ||      }|r)| j                  j                  ||      }	|	j                  }|r4t        j                  j                  |      rt        j                   |       ||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disfluencies   )rE   rF   rG   speakers_expectedDOWNLOAD_RECORDINGz.mp3)suffixdeleteSTART_TRANSCRIBE)bytes)config)r%   TranscriptionConfigr   r'   rC   tempfileNamedTemporaryFilewritenamelenr*   
transcribe
utterancesospathexistsunlink)
r-   use_speaker_labelsraw_cfglabeled_cfgtemp_file_pathspeaker_utterancesaudio_bytesfraw_transcriptlabeleds
             r   transcribe_audioz"AssemblyAIService.transcribe_audioH   sX   )) 	
 --	
 !	*)4==9113K00uMQRGGK(%&VVN N 'c+>NO!--88W8UN!**55k+5V%,%7%7" "''.."@		.)111! NM "''.."@		.) #A~s$   ?E 7E A1E  E	E :F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   )r-   r   r   s      r   extract_datetime_from_textz,AssemblyAIService.extract_datetime_from_textq   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:   r6   strftimer   lemurtaskMODELrB   r   parserh   ri   getinfo)	r-   
transcriptr9   promptresultparsedro   rp   rq   s	            r   analyze_transcriptz$AssemblyAIService.analyze_transcripty   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/arn   rl   r1   z"Invalid datetime format received: z	. Error: zError converting datetime: )lowerr   strptimer2   r3   localizer8   UTCrr   
ValueErrorrh   ri   	Exceptionerror)r-   rp   dtr5   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	                  |      }	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)ro   DATETIME_CONVERTED)utcz	summary: z	llm_raw: )rq   llm_raw)ry   ro   rp   rE   resultsTRANSCRIPTION_FAILED)r   rn   r   )
r'   rf   r   r}   r   rh   rx   r   r   repr)r-   r'   use_speakerrd   ra   ro   dt_rawrq   r   rp   r   s              r   process_transcriptionz'AssemblyAIService.process_transcription   s
    #	151F1F#. 2G 2.N. ]H-7;7N7N~7^4NFGW]H^L#CCFK)89IJ KK)G9-.KK)G9-. -11"0$4"4&&	 	  	+XT!WE "#$("& 	s   B(B2 2	C$;CC$C$F)__name__
__module____qualname__r%   
LemurModelclaude3_7_sonnet_20250219ru   r   r   r.   r6   r:   rC   rf   rj   r}   r   r   __classcell__)r   s   @r   r   r      sL    NN44EI
!$! '2R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   ry   ro   rp   rE   r   )rh   rx   callid_r   r   )r'   r   servicer{   s       r   get_speech_to_textr      s    1$'';<1Qqy!G**8*MF 	| !" y r   r   )r   rY   r2   loggingrR   
assemblyair%   r   django.confr   utils.loggerr   twilior   json_sanitizerr   r,   r	   	getLoggerr   rh   r   r   strr    r   r   <module>r      s[    	 	        ! % + / 
		8	$I IV r   