o
    cBjÛ   ã                   @  sº   d Z ddlmZ ddlZddlmZmZmZmZm	Z	 ddl
mZ d4d
d„Zd5dd„Zd6dd„Z	d7d8dd„Zd9d d!„Z	d7d:d$d%„Zd;d)d*„Z			d<d=d/d0„Z					d>d?d2d3„ZdS )@zNScore customer sentiment from transcript using keywords, LLM, or hybrid rules.é    )ÚannotationsN)ÚAnyÚDictÚListÚOptionalÚTuple)ÚSentimentConfigHandlerÚtextÚstrÚreturnú	List[str]c                 C  s&   | sg S t  dt| ƒ¡}dd„ |D ƒS )Nz[\n,;|]+c                 S  s    g | ]}|  ¡ r|  ¡  ¡ ‘qS © )ÚstripÚlower)Ú.0Úpr   r   ú</home/aiteam/pcaa-dev/dashboard-backend/sentiment_scoring.pyÚ
<listcomp>   s     z#_split_keywords.<locals>.<listcomp>)ÚreÚsplitr
   )r	   Úpartsr   r   r   Ú_split_keywords   s   r   ÚhaystackÚkeywordsÚmax_hitsÚintúTuple[int, List[str]]c                 C  sX   g }| r|s
d|fS |   ¡ }|D ]}t|ƒ|kr n|r%||v r%| |¡ qt|ƒ|fS )Nr   )r   ÚlenÚappend)r   r   r   Úhitsr	   Úkwr   r   r   Ú_count_keyword_hits   s   
€r!   Úvaluer   c                 C  s@   t | pdƒ ¡  ¡ }d|v s|dv rdS d|v s|dv rdS dS )NÚ Úpositive>   ÚposÚgoodÚhappyÚnegative>   ÚbadÚnegÚangryÚneutral)r
   r   r   )r"   r	   r   r   r   Ú_normalize_sentiment_label   s   r-   Ú
transcriptÚspeaker_segmentsúOptional[List[Dict]]c                 C  sÊ   |st | pdƒS g }|D ]K}t | d¡pdƒ ¡ }t | d¡p%| d¡p%dƒ ¡ }t | d¡p5| d¡p5dƒ ¡ }|s<q|dkpO| oOd|v pO| d¡pO|d	k}|rW| |¡ q|r_d
 |¡S t | pcdƒS )zEReturn customer-only utterances when diarized segments are available.r#   ÚroleÚspeakerÚspeaker_labelr	   r.   ÚcustomerÚ_1Ú	speaker_1Ú
)r
   Úgetr   r   Úendswithr   Újoin)r.   r/   Úcustomer_linesÚsegmentr1   r2   r	   Úis_customerr   r   r   Úextract_customer_text(   s$     ÿ
€
r>   ÚconfigúDict[str, Any]Úanalysis_textúTuple[str, Dict[str, Any]]c                 C  s4  t dt|  d¡p	dƒƒ}t|  d¡pdƒ}t|  d¡pdƒ}t|  d¡p%dƒ}t|||ƒ\}}t|||ƒ\}}	t|||ƒ\}
}t dt|  d¡pHd	ƒƒ}t dt|  d
¡pTd	ƒƒ}||krb||krbd}n*||krm||krmd}n|
dkr||dkr||dkr|d}n||krƒd}n	||krŠd}nd}||	||||
ddœ}||fS )Né   Úmax_keyword_hitsé   Úpositive_keywordsr#   Únegative_keywordsÚneutral_keywordsÚkeyword_positive_thresholdé   Úkeyword_negative_thresholdr(   r$   r   r,   Úkeyword)Úpositive_hitsÚnegative_hitsÚneutral_hitsÚpositive_countÚnegative_countÚneutral_countÚmethod)Úmaxr   r8   r   r!   )r?   rA   r   Úpos_kwÚneg_kwÚneu_kwÚ	pos_countÚpos_hitsÚ	neg_countÚneg_hitsÚ	neu_countÚneu_hitsÚpos_thresholdÚneg_thresholdÚlabelÚdetailsr   r   r   Úkeyword_sentiment_labelB   s:   ù	rb   Úkeyword_detailsúOptional[Dict[str, Any]]c                 C  sì   |   d¡pd ¡ }t|   d¡pdƒ ¡ }|pi }ddg}|r&| d|› ¡ |   d¡r0| d	¡ |dkr^|r^|  d
¡p<g }|  d¡pCg }|sH|r^| dd |¡pQd› dd |¡pYd› d¡ | d¡ | ¡ rq| d| ¡ › ¡ d |¡S )NÚprompt_rubricr#   Údetection_modeÚhybridzCUSTOMER SENTIMENT:zAEvaluate mood from the customer's words only (ignore agent tone).zRubric: Úcustomer_onlyzBUse the CUSTOMER UTTERANCES section below as the primary evidence.rM   rN   u   Keyword hints â€” positive: z, Únonez; negative: Ú.zIReturn sentiment as exactly one of: "positive", "negative", or "neutral".z
CUSTOMER UTTERANCES:
r7   )r8   r   r
   r   r   r:   )r?   rA   rc   ÚrubricÚmodeÚlinesr%   r*   r   r   r   Úbuild_sentiment_prompt_blockk   s.   þ

ÿÿ

rn   Úllm_sentimentúOptional[str]Úkeyword_labelc                 C  s  t |  d¡pdƒ ¡ }|rt|ƒnd }|dkr"|i |¥d|dœ¥fS |dkr8|p+|p+d}|i |¥d||dœ¥fS t| d¡p?d	ƒ}t| d
¡pHd	ƒ}tdt|  d¡pSdƒƒ}	tdt|  d¡p_dƒƒ}
||
krm||krmd}n||	krx||krxd}n	|r}|}n|p€d}|i |¥d||dœ¥fS )Nrf   rg   rL   )rS   ro   Úllmr,   )rS   ro   Úkeyword_sentimentrP   r   rQ   rC   rI   rJ   rK   r(   r$   )r
   r8   r   r-   r   rT   )r?   ro   rq   rc   rl   Ú	llm_labelÚfinalrX   rZ   r^   r_   r   r   r   Úfinalize_sentimentŠ   s>   ÿ
üÿ
ürv   ÚbidúOptional[Any]Úhandlerú Optional[SentimentConfigHandler]c              	   C  sŽ   |pt |pi ƒ}| ¡  | | ¡}t| dd¡ƒ}|r t||ƒnt|p$dƒ}t||ƒ\}}	t|||	ƒ}
||||	|
t| d¡p?dƒ 	¡ dkdœS )zFBuild analysis text, keyword scan, and optional prompt block for Nova.rh   Tr#   rf   rg   rL   )r?   rA   rq   rc   Úprompt_blockÚinclude_in_llm_prompt)
r   Úensure_tableÚget_config_or_defaultsÚboolr8   r>   r
   rb   rn   r   )rw   r.   r/   r?   ry   ÚcfgÚuse_customer_onlyrA   rq   rc   r{   r   r   r   Úprepare_sentiment_analysis¶   s"   
ÿ
ýúr‚   Úpreparedc           
      C  s„   |du rt | ||||d}|d }t|||d |d ƒ\}}	t| d¡p%dƒ|	d< t| d	d
¡ƒ|	d	< t| d¡p:dƒ|	d< ||	fS )z4Return final sentiment label and detection metadata.N)r?   ry   r?   rq   rc   rA   r#   Úanalysis_text_lengthrh   Trf   rg   )r‚   rv   r   r8   r   r
   )
rw   r.   r/   ro   r?   ry   rƒ   r€   r`   ra   r   r   r   Úresolve_call_sentimentÕ   s&   
ûür…   )r	   r
   r   r   )r   r
   r   r   r   r   r   r   )r"   r   r   r
   )N)r.   r
   r/   r0   r   r
   )r?   r@   rA   r
   r   rB   )r?   r@   rA   r
   rc   rd   r   r
   )
r?   r@   ro   rp   rq   r
   rc   r@   r   rB   )NNN)rw   r
   r.   r
   r/   r0   r?   rx   ry   rz   r   r@   )NNNNN)rw   r
   r.   r
   r/   r0   ro   rp   r?   rx   ry   rz   rƒ   rd   r   rB   )Ú__doc__Ú
__future__r   r   Útypingr   r   r   r   r   Úsentiment_config_handlerr   r   r!   r-   r>   rb   rn   rv   r‚   r…   r   r   r   r   Ú<module>   s0    


þ
,ý
/û"ù