§
    éƒtj0  ã                  ó8  — U d Z ddlmZ ddlZddlmZmZ ddlmZ ddl	m
Z
 e
d         Z ed„ ¦  «        Zd	ed
<   i Zded<   dCd„ZdDd„Z ej        d¦  «        Z ej        d¦  «        Z ej        d¦  «        Z ej        d¦  «        Z ej        d¦  «        Z ej        d¦  «        Z ej        d¦  «        Ze G d„ d¦  «        ¦   «         ZdEd „ZdFd!„ZdGd#„ZdDd$„ZdHd&„ZdDd'„ZdId)„Z dFd*„Z!dFd+„Z"dId,„Z#dJd.„Z$dKd1„Z%dLd2„Z&dMd5„Z'd6d7œdNd;„Z(dOd?„Z)dPd@„Z*dQdB„Z+dS )Ra  Conversational intent + history-aware question resolution for SaaS chat.

Distinguishes new document questions from follow-ups about prior answers
and from verify / re-check challenges. Keeps a short in-process memory so
follow-ups work even when audit persistence is off.
é    )ÚannotationsN)ÚdefaultdictÚdeque)Ú	dataclass)ÚLiteral)Únew_questionÚ	follow_upÚverifyÚexplain_calcc                 ó"   — t          d¬¦  «        S )Né   )Úmaxlen)r   © ó    ú1/var/www/html/CA-Chatbot/app/saas/conversation.pyú<lambda>r      s   € ÍÐUVÈÉÌ€ r   z!dict[str, deque[tuple[str, str]]]Ú_SESSION_TURNSzdict[str, dict[str, str]]Ú_SESSION_PROFILEÚ
session_idú
str | NoneÚnameÚstrÚreturnÚNonec                ór   — | r|sd S |                      ¦   «         t                               | i ¦  «        d<   d S ©NÚdisplay_name)Ústripr   Ú
setdefault©r   r   s     r   Úset_session_display_namer!      s?   € Øð ˜Tð ØˆØBFÇ*Â*Á,Ä,Õ×Ò 
¨BÑ/Ô/°Ñ?Ð?Ð?r   c                ó˜   — | sd S t                                | ¦  «        pi                      d¦  «        }|r|                     ¦   «         nd S r   )r   Úgetr   r    s     r   Úget_session_display_namer$   !   sL   € Øð ØˆtÝ× Ò  Ñ,Ô,Ð2°×7Ò7¸ÑGÔG€DØÐ)ˆ4�:Š:‰<Œ<ˆ< TÐ)r   ak  (?i)\b(are\s+you\s+sure|is\s+that\s+(?:right|correct|accurate)|that\s+(?:can'?t|cannot|doesn'?t|isn'?t)\s+(?:be|look|seem|right|correct)|(?:you(?:'re| are)\s+)?wrong|incorrect|mistake|error|double[\s-]?check|re[\s-]?check|recheck|verify|recalculate|recompute|check\s+again|look\s+again|please\s+confirm|doesn'?t\s+match|not\s+what\s+i\s+(?:see|have)|contradict)\ba>  (?i)\b(how\s+did\s+you\s+(?:get|calculate|compute|count|arrive|derive)|how\s+(?:is|was)\s+that\s+(?:calculated|computed|counted)|where\s+does\s+(?:that|this|the)\s+(?:number|total|figure|amount)\s+come\s+from|show\s+(?:your|the)\s+(?:work|math|calculation)|explain\s+(?:your|the)\s+(?:calculation|math|total|figure))\baç  (?i)\b(\bit\b|\bthat\b|\bthis\b|\bthose\b|\bthese\b|\bthem\b|previous\s+answer|your\s+answer|you\s+said|you\s+mentioned|as\s+you\s+(?:said|mentioned)|the\s+(?:above|earlier|last)\b|why\s+(?:does|did|is|are|only|not)|how\s+come|what\s+about|and\s+(?:august|july|june|may|april|march|february|january|september|october|november|december)\b|only\s+(?:contain|contains|include|includes|cover|covers|has|have|\d+)|not\s+(?:august|july|june|may|april|march|february|january|september|october|november|december)|in\s+a\s+paragraph|as\s+prose|in\s+words|paragraph\s+form|where\s+(?:are|is)\s+the\s+rest|missing|incomplete|why\s+(?:only|just)\s+\d+|rest\s+of\s+(?:the\s+)?(?:payments?|transactions?|list)|same\s+(?:as|for)|compared\s+to|vs\.?|versus)\ba^  (?i)\b(why\s+(?:only|just)\s+\d+|where\s+(?:are|is)\s+the\s+rest|(?:list|extraction|index(?:ing)?)\s+is\s+incomplete|incomplete\s+(?:list|extraction|index)|missing\s+(?:payments?|transactions?|lines?)|not\s+(?:showing|listing)\s+(?:all|every)|only\s+\d+\s+(?:of\s+\d+\s+)?(?:payments?|transactions?)|should\s+be\s+\d+|header\s+(?:says|shows)\s+\d+)\bz3(?i)^(why|how|what\s+about|and|also|ok\s+but|but)\ba(  (?i)^(hi|hii|hello|hey|yo|sup|wass?u+p+|whass?u+p+|(?:what'?s|whats)\s+(?:up|good)|thanks?|thank\s+you|bye|goodbye|how\s+are\s+(?:you|u)(?:\s+doing)?|how(?:'s|\s+is)\s+it\s+going|how\s+have\s+you\s+been|how\s+you\s+doing|help(?:\s+me)?|how\s+can\s+you\s+help(?:\s+me)?|what\s+can\s+you\s+(?:do|help(?:\s+me)?(?:\s+with)?)|who\s+are\s+you|what\s+are\s+you|tell\s+me\s+about\s+(?:yourself|you|the\s+bot|this\s+bot)|my\s+name\s+is\b.|i\s*(?:'m|am)\s+[A-Za-z].|what(?:'s|\s+is)\s+my\s+name|what\s+was\s+my\s+first\s+question|complete|done|ok|okay)[?.!\s]*$z‰(?i)\b(spent|spend|total|payment|paid|received|income|merchant|categor|grocer|july|august|date|month|period|transaction|outflow|inflow)\bc                  óX   — e Zd ZU ded<   ded<   ded<   dZded<   dZded	<   d
Zded<   dS )ÚResolvedTurnr   ÚoriginalÚ	rewrittenÚ
ConvIntentÚconv_intentNr   Úprior_questionÚprior_answerÚ Úhistory_block)Ú__name__Ú
__module__Ú__qualname__Ú__annotations__r+   r,   r.   r   r   r   r&   r&   �   sc   € € € € € € à€M€M�MØ€N€N�NØÐÐÑØ!%€NÐ%Ð%Ð%Ñ%Ø#€LÐ#Ð#Ð#Ñ#Ø€MÐÐÐÑÐÐr   r&   ÚquestionÚanswerc                ó¢   — | r|sd S t           |                               |                     ¦   «         |pd                     ¦   «         f¦  «         d S ©Nr-   )r   Úappendr   )r   r3   r4   s      r   Úremember_turnr8   ‹   sT   € Øð ˜Xð ØˆÝ�:Ô×%Ò% x§~¢~Ñ'7Ô'7¸&¸,ÀB×9MÒ9MÑ9OÔ9OÐ&PÑQÔQÐQÐQÐQr   c                óz   — | r8t                                | d ¦  «         t                               | d ¦  «         d S d S ©N)r   Úpopr   ©r   s    r   Úclear_turnsr=   ‘   sF   € Øð /Ý×Ò˜: tÑ,Ô,Ð,Ý×Ò˜Z¨Ñ.Ô.Ð.Ð.Ð.ð/ð /r   úlist[tuple[str, str]]c                ó\   — | sg S t          t                               | ¦  «        pg ¦  «        S r:   )Úlistr   r#   r<   s    r   Ú	get_turnsrA   —   s0   € Øð Øˆ	Ý•×"Ò" :Ñ.Ô.Ð4°"Ñ5Ô5Ð5r   c                ót   — t          | ¦  «        }|sd S |d         d         pd                     ¦   «         }|pd S )Nr   r-   )rA   r   )r   ÚturnsÚqs      r   Úget_first_user_questionrE   �   sD   € Ý�jÑ!Ô!€EØð ØˆtØ	ˆqŒ�!ŒÐ	˜×!Ò!Ñ#Ô#€AØˆ9�Ðr   Úevidence_jsonc                óš   — | r|sdS |dd…         t                                | i ¦  «        d<   dt                                | i ¦  «        d<   dS )zXStore last financial-analysis evidence for short follow-ups (reduce it / that merchant).Ni@  Úlast_analysisÚ1Úprior_was_analysis©r   r   )r   rF   s     r   Úremember_analysis_contextrL   ¥   s_   € àð ˜]ð ØˆØCPÐQVÐRVÐQVÔCWÕ×Ò 
¨BÑ/Ô/°Ñ@ØHKÕ×Ò 
¨BÑ/Ô/Ð0DÑEÐEÐEr   c                óh   — | sd S t                                | ¦  «        pi                      d¦  «        S )NrH   ©r   r#   r<   s    r   Úget_analysis_contextrO   ­   s6   € Øð ØˆtÝ× Ò  Ñ,Ô,Ð2°×7Ò7¸ÑHÔHÐHr   Úboolc                óp   — | sdS t                                | ¦  «        pi                      d¦  «        dk    S )NFrJ   rI   rN   r<   s    r   rJ   rJ   ³   s=   € Øð ØˆuÝ× Ò  Ñ,Ô,Ð2°×7Ò7Ð8LÑMÔMÐQTÒTÐTr   c                óv   — | sd S t                                | ¦  «        }|r|                     dd ¦  «         d S d S )NrJ   )r   r#   r;   )r   Úprofs     r   Úclear_analysis_flagrT   ¹   sO   € Øð ØˆÝ×Ò 
Ñ+Ô+€DØð -Ø�ŠÐ% tÑ,Ô,Ð,Ð,Ð,ð-ð -r   c                óJ   — | sdS dt                                | i ¦  «        d<   dS )zARemember that Alex already introduced themselves in this session.NrI   Ú
introducedrK   r<   s    r   Úmark_session_introducedrW   Á   s0   € àð ØˆØ@CÕ×Ò 
¨BÑ/Ô/°Ñ=Ð=Ð=r   c                óp   — | sdS t                                | ¦  «        pi                      d¦  «        dk    S )NFrV   rI   rN   r<   s    r   Úsession_was_introducedrY   È   s;   € Øð ØˆuÝ× Ò  Ñ,Ô,Ð2°×7Ò7¸ÑEÔEÈÒLÐLr   Úmetricsc                ót  — | r|sdS d                      d„ |dd…         D ¦   «         ¦  «        }t                               | ¦  «        pi                      dd¦  «        }|r|dz   |z   n|}|                     d¦  «        dd…         }d                      |¦  «        t                               | i ¦  «        d<   dS )	zITrack metric cards already shown so later turns can avoid repeating them.NÚ|c              3  ó*   K  — | ]\  }}|› d |› �V — ŒdS )Ú=Nr   )Ú.0ÚaÚbs      r   ú	<genexpr>z)remember_shown_metrics.<locals>.<genexpr>Ò   s0   è è € Ð7Ð7¡$ ! Q�a�:�:˜!�:�:Ð7Ð7Ð7Ð7Ð7Ð7r   é   Úshown_metricsr-   z||éýÿÿÿ)Újoinr   r#   Úsplitr   )r   rZ   ÚkeyÚprevÚmergedÚpartss         r   Úremember_shown_metricsrl   Î   sÅ   € àð ˜Wð ØˆØ
�(Š(Ð7Ð7¨'°#°2°#¬,Ð7Ñ7Ô7Ñ
7Ô
7€CÝ× Ò  Ñ,Ô,Ð2°×7Ò7¸ÈÑLÔL€DØ$(Ð1ˆd�T‰k˜CÑÐ¨c€FØ�LŠL˜ÑÔ˜r˜s˜sÔ#€EØCGÇ9Â9ÈUÑCSÔCSÕ×Ò 
¨BÑ/Ô/°Ñ@Ð@Ð@r   ÚlabelÚvaluec                ó~   — | sdS t                                | ¦  «        pi                      d¦  «        pd}|› d|› �|v S )NFrd   r-   r^   rN   )r   rm   rn   Úblobs       r   Úrecently_shown_metricrq   Ù   sS   € Øð ØˆuÝ× Ò  Ñ,Ô,Ð2°×7Ò7¸ÑHÔHÐNÈB€DØÐÐ�eÐÐ Ð%Ð%r   c                óT   — t          t                               | pd¦  «        ¦  «        S r6   )rP   Ú_COVERAGE_CHALLENGE_REÚsearch)r3   s    r   Úis_coverage_challengeru   à   s#   € ÝÕ&×-Ò-¨h¨n¸"Ñ=Ô=Ñ>Ô>Ð>r   Úhas_historyr)   c               ó  — | pd                      ¦   «         }|sdS t                               |¦  «        rdS t                               |¦  «        rdS t
                               |¦  «        rdS t          |¦  «        r|rdndS |sdS ddlm}  ||¦  «        rdS | 	                    ¦   «         }t                               |¦  «        rwt          |¦  «        dk    st                               |¦  «        rdS t          j        d	|¦  «        rdS t          j        d
|¦  «        rt                               |¦  «        rdS t          |¦  «        dk    r6t                               |¦  «        rt                               |¦  «        rdS dS )Nr-   r   r
   r   r	   r   )Úis_analytical_self_containedé   z'(?i)\b(it|that|this|those|these|them)\bz(?i)\bwhy\br   )r   Ú_HELP_OR_SMALLTALK_REÚmatchÚ
_VERIFY_RErt   Ú_EXPLAIN_CALC_REru   Úapp.saas.finance_intentrx   rg   Ú_FOLLOW_UP_REÚlenÚ_SHORT_FOLLOW_REÚreÚ_ANALYTICAL_HINT_RE)r3   rv   rD   rx   Úwordss        r   Úclassify_conversational_intentr…   ä   s¨  € ð
 
ˆ�R×ÒÑ Ô €AØð Øˆ~õ ×"Ò" 1Ñ%Ô%ð Øˆ~å×Ò˜ÑÔð ØˆxÝ×Ò˜qÑ!Ô!ð Øˆ~Ý˜QÑÔð >Ø!,Ð=ˆ~ˆ~°+Ð=àð Øˆ~ð EÐDÐDÐDÐDÐDà#Ð# AÑ&Ô&ð Øˆ~à�GŠG‰IŒI€EÝ×Ò˜AÑÔð åˆu‰:Œ:˜ÒÐÕ/×6Ò6°qÑ9Ô9ÐØ�;ÝŒ9Ð?ÀÑCÔCð 	Ø�;ÝŒ9�^ QÑ'Ô'ð 	Õ,?×,FÒ,FÀqÑ,IÔ,Ið 	Ø�;å
ˆ5�z„z�Q‚€Õ+×2Ò2°1Ñ5Ô5€Õ:M×:TÒ:TÐUVÑ:WÔ:W€Øˆ{àˆ>r   é   )ÚlimitrC   r‡   Úintc               óp  — | sdS dg}| | d …         D ]�\  }}|                      d|› �¦  «         t          j        dd|¦  «                             ¦   «         }t	          |¦  «        dk    r|d d…                              ¦   «         dz   }|                      d	|› �¦  «         Œ�d
                     |¦  «        S )Nr-   z?Recent conversation (use this to answer follow-ups coherently):zUser: ú\s+Ú i  i  õ   â€¦zAssistant: Ú
)r7   r‚   Úsubr   r€   Úrstriprf   )rC   r‡   ÚlinesrD   r`   Úsnippets         r   Ú_history_blockr’     sÊ   € Øð ØˆrØNÐO€EØ�u�f�g�g”ð .ð .‰ˆˆ1Ø�Š�\˜a�\�\Ñ"Ô"Ð"Ý”&˜  aÑ(Ô(×.Ò.Ñ0Ô0ˆÝˆw‰<Œ<˜#ÒÐØ˜d˜s˜d”m×*Ò*Ñ,Ô,¨uÑ4ˆGØ�ŠÐ, 7Ð,Ð,Ñ-Ô-Ð-Ð-Ø�9Š9�UÑÔÐr   Úprior_qÚprior_aÚintentc                ó:  — |                       ¦   «         }|pd                      ¦   «         }|pd                      ¦   «         }|dk    r|pd}d|› d|› d�S |dk    st          |¦  «        r|pd}d	|› d
|› �S |g}|r|                     d|› d�¦  «         |rst          j        dd|¦  «                              ¦   «         }t          |¦  «        dk    r|d d…                              ¦   «         dz   }|                     d|› d�¦  «         d                     |¦  «        S )Nr-   r
   zthe previous figuresz,Re-check the underlying statement data for: u.   . The user challenged the previous answer (â€œuF   â€�). Recompute from the full document; do not defend the prior reply.r   zthe previous totalu   Explain how the figures for â€œu®   â€� were derived from the full statement (header totals vs indexed transactions). Address incomplete extraction if indexed lines are fewer than the header count. User asked: z%(Referring to the previous question: ú)rŠ   r‹   ih  ie  rŒ   z(Previous answer said: )r   ru   r7   r‚   rŽ   r€   r�   rf   )r3   r“   r”   r•   rD   Úfocusrk   Úanchors           r   Ú_rewrite_follow_uprš     sƒ  € ð 	�ŠÑÔ€AØˆ}˜"×#Ò#Ñ%Ô%€GØˆ}˜"×#Ò#Ñ%Ô%€Gà�ÒÐØÐ1Ð1ˆðO¸5ð Oð OØ;<ðOð Oð Oð	
ð �ÒÐÕ#8¸Ñ#;Ô#;ÐØÐ/Ð/ˆðN¨eð Nð NàJKðNð Nð	
ð ˆC€EØð IØ�ŠÐG¸WÐGÐGÐGÑHÔHÐHØð :å”˜  WÑ-Ô-×3Ò3Ñ5Ô5ˆÝˆv‰;Œ;˜ÒÐØ˜D˜S˜D”\×(Ò(Ñ*Ô*¨UÑ2ˆFØ�ŠÐ8¨vÐ8Ð8Ð8Ñ9Ô9Ð9Ø�8Š8�E‰?Œ?Ðr   c           
     ó$  — |pd                      ¦   «         }t          | ¦  «        }dx}}|r|d         \  }}t          |t          |¦  «        ¬¦  «        }|dk    r|}nt	          ||||¦  «        }t          |||||t          |¦  «        ¬¦  «        S )zFClassify conversational intent and rewrite the question using history.r-   Néÿÿÿÿ)rv   r   )r'   r(   r*   r+   r,   r.   )r   rA   r…   rP   rš   r&   r’   )r   r3   r'   rC   r“   r”   Úconvr(   s           r   Úresolve_turnrž   F  s²   € à�˜B×%Ò%Ñ'Ô'€HÝ�jÑ!Ô!€EØÐ€GˆgØð %Ø  œ9Ñˆ�å)¨(ÅÀUÁÄÐLÑLÔL€DØˆ~ÒÐØˆ	ˆ	å& x°¸'À4ÑHÔHˆ	åØØØØØÝ$ UÑ+Ô+ðñ ô ð r   Úfinance_intentc                ó
   — | dv S )N>   ÚincomeÚinsightsÚ
comparisonÚdate_lookupÚpayment_countÚperiod_coverageÚfinancial_adviceÚspending_summaryÚcategory_spendingÚmerchant_analysisÚstatement_summaryÚtransaction_searchr   )rŸ   s    r   Úis_analytical_finance_intentr­   ^  s   € Øð ð ð r   )r   r   r   r   r   r   )r   r   r   r   )r   r   r3   r   r4   r   r   r   )r   r   r   r   )r   r   r   r>   )r   r   rF   r   r   r   )r   r   r   rP   )r   r   rZ   r>   r   r   )r   r   rm   r   rn   r   r   rP   )r3   r   r   rP   )r3   r   rv   rP   r   r)   )rC   r>   r‡   rˆ   r   r   )
r3   r   r“   r   r”   r   r•   r)   r   r   )r   r   r3   r   r   r&   )rŸ   r   r   rP   ),Ú__doc__Ú
__future__r   r‚   Úcollectionsr   r   Údataclassesr   Útypingr   r)   r   r2   r   r!   r$   Úcompiler|   r}   r   rs   r�   rz   rƒ   r&   r8   r=   rA   rE   rL   rO   rJ   rT   rW   rY   rl   rq   ru   r…   r’   rš   rž   r­   r   r   r   ú<module>r´      sj  ððð ð ð #Ð "Ð "Ð "Ð "Ð "à 	€	€	€	Ø *Ð *Ð *Ð *Ð *Ð *Ð *Ð *Ø !Ð !Ð !Ð !Ð !Ð !Ø Ð Ð Ð Ð Ð àðô€
ð 5@°KÐ@WÐ@WÑ4XÔ4X€Ð XÐ XÐ XÑ XØ.0Ð Ð 0Ð 0Ð 0Ñ 0ðOð Oð Oð Oð*ð *ð *ð *ð ˆRŒZðñ	ô 	€
ð �2”:ðñô Ð ð �”
ðñô €ð$ $˜œð
ñô Ð ð �2”:Ø:ñô Ð ð
 #˜œ
ðñô Ð ð. !�b”jðñô Ð ð ðð ð ð ð ñ ô ñ „ððRð Rð Rð Rð/ð /ð /ð /ð6ð 6ð 6ð 6ðð ð ð ðLð Lð Lð LðIð Ið Ið IðUð Uð Uð Uð-ð -ð -ð -ðDð Dð Dð DðMð Mð Mð MðTð Tð Tð Tð&ð &ð &ð &ð?ð ?ð ?ð ?ð+ð +ð +ð +ð\ BCð 
ð 
ð 
ð 
ð 
ð 
ð$ð $ð $ð $ðNð ð ð ð0ð ð ð ð ð r   