
    -fi6                     6   d dl Z d dlZd dlZd dlmZmZmZmZmZ d dl	m	Z	 d dl
Z
d dlmZ d dlmZmZ 	 d dlmZ ddlmZmZ  ej.                  e      Zd	Zd
ZdZdZ G d d      Z e       Zdde de!de fdZ" G d d      Z# e#       Z$y# e$ r	 d dlmZ Y ]w xY w)    N)ListDictAnyOptionalTuple)datetime)Session)funcdesc)settings   )SmartInventoryChatSessionSmartInventoryChatMessagezsmart_inventory:chat:i     i:  c                   6   e Zd ZdZd Zedej                  fd       Zde	de	fdZ
dede	fdZde	deee	ef      fd	Zde	d
ee	ef   defdZ	 dde	de	de	deee      def
dZde	deee	e	f      fdZde	defdZ	 dde	de	dedefdZde	defdZde	defdZy)ChatSessionServicez.Service for managing chat sessions using Redisc                     d| _         y)zInitialize Redis connectionN)_redis_clientselfs    I/var/www/html/hubwallet-dev/src/smart_inventory/apps/chat_bot/services.py__init__zChatSessionService.__init__    s
    !    returnc                     | j                   Ht        j                  t        j                  t        j
                  t        j                  d      | _         | j                   S )z#Lazy initialization of Redis clientT)hostportdbdecode_responses)r   redisRedisr   
REDIS_HOST
REDIS_PORTREDIS_DBr   s    r   redis_clientzChatSessionService.redis_client$   sM     %!&(((($$!%	"D !!!r   
session_idc                     t          | S )z Generate Redis key for a session)CHAT_SESSION_PREFIX)r   r&   s     r   _get_session_keyz#ChatSessionService._get_session_key0   s    %&zl33r   
company_idc                 J   t        t        j                               }||t        j                         j                         g dd}| j                  |      }| j                  j                  |t        t        j                  |             t        j                  d|        |S )zE
        Create a new chat session and return the session ID
        N)r&   r*   
created_atmessagescontext_summaryzCreated new chat session: )struuiduuid4r   now	isoformatr)   r%   setexCHAT_SESSION_TTLjsondumpsloggerinfo)r   r*   r&   session_datakeys        r   create_sessionz!ChatSessionService.create_session4   s     &
$$",,.224#
 ##J/JJ|$	
 	0=>r   c                     | j                  |      }| j                  j                  |      }|t        j	                  d|        yt        j                  |      S )zi
        Get session data by session ID
        Returns None if session doesn't exist or expired
        NzSession not found or expired: )r)   r%   getr8   r9   r6   loads)r   r&   r;   datas       r   get_sessionzChatSessionService.get_sessionK   sU    
 ##J/  $$S)<KK8EFzz$r   r:   c                     | j                  |      }| j                  j                  |      st        j	                  d|        y| j                  j                  |t        t        j                  |             y)z5
        Update session data and refresh TTL
        z$Cannot update non-existent session: FT)	r)   r%   existsr8   warningr4   r5   r6   r7   )r   r&   r:   r;   s       r   update_sessionz!ChatSessionService.update_sessionY   sl     ##J/   '',NNA*NOJJ|$	

 r   Nrolecontentraw_datac                     | j                  |      }|y||t        j                         j                         d}|dk(  r|rd|d<   t	        |      |d<   |d   j                  |       | j                  ||      S )zZ
        Add a message to the session history
        role: 'user' or 'assistant'
        F)rF   rG   	timestamp	assistantThas_data
data_countr-   )rA   r   r2   r3   lenappendrE   )r   r&   rF   rG   rH   r:   messages          r   add_messagezChatSessionService.add_messagek   s     ''
3 !113
 ;8"&GJ$'MGL!Z ''0"":|<<r   c                     | j                  |      }|g S g }|j                  d      r|j                  dd|d    d       |d   D ]  }|j                  |d   |d   d        |S )zr
        Get conversation history formatted for LLM context
        Returns list of {role, content} dicts
        r.   systemzPrevious conversation summary: rF   rG   r-   rF   rG   )rA   r>   rO   )r   r&   r:   historymsgs        r   get_conversation_historyz+ChatSessionService.get_conversation_history   s    
 ''
3I -.NN <\J[=\<]^   
+ 	CNNFy> 	 r   c                     | j                  |      }|y|j                  dg       }t        |      t        k\  ryt	        d |D              }|t
        kD  ryy)zF
        Check if conversation history needs to be summarized
        Fr-   Tc              3   R   K   | ]  }t        |j                  d d             ! yw)rG    N)rN   r>   ).0rV   s     r   	<genexpr>z9ChatSessionService.needs_summarization.<locals>.<genexpr>   s      J##cggi45Js   %')rA   r>   rN   MAX_HISTORY_MESSAGESsumMAX_CONTEXT_CHARS)r   r&   r:   r-   total_charss        r   needs_summarizationz&ChatSessionService.needs_summarization   sb     ''
3##J3 x=00 JJJ**r   summarykeep_last_nc                 p    | j                  |      }|y||d<   |d   | d |d<   | j                  ||      S )zK
        Set the context summary and keep only the last N messages
        NFr.   r-   )rA   rE   )r   r&   rb   rc   r:   s        r   set_context_summaryz&ChatSessionService.set_context_summary   sS    
 ''
3*1&'#/
#;[LM#JZ "":|<<r   c                 d    | j                  |      }| j                  j                  |      }|dkD  S )z'
        Delete a chat session
        r   )r)   r%   delete)r   r&   r;   results       r   delete_sessionz!ChatSessionService.delete_session   s4     ##J/""))#.zr   c                 d    | j                  |      }| j                  j                  |t              S )zE
        Refresh the TTL of a session without modifying data
        )r)   r%   expirer5   )r   r&   r;   s      r   refresh_session_ttlz&ChatSessionService.refresh_session_ttl   s.     ##J/  ''-=>>r   )N)   )__name__
__module____qualname____doc__r   propertyr    r!   r%   r/   r)   intr<   r   r   r   rA   boolrE   r   rQ   rW   ra   re   ri   rl    r   r   r   r      sJ   8" 	"ekk 	" 	"43 43 4  . c  htCH~.F   DcN t & 6:=c = =s =&tDz2=>B=23 4S#X;O 6c d , /0=c =C =(+=48=  ?c ?d ?r   r   question
max_lengthr   c                 0   | j                         }g d}|j                         }|D ]1  }|j                  |      s|t        |      d j                         } n |r|d   j	                         |dd z   }t        |      |dz
  kD  r|d|dz
   dz   }|r|S dS )zp
    Generate a chat name from the first question.
    Truncates to max_length and adds ellipsis if needed.
    )zwhat iszwhat areztell me aboutzshow mezcan youNr   r      z...zNew Chat)striplower
startswithrN   upper)rv   rw   	chat_nameprefixes_to_remove
lower_nameprefixs         r   generate_chat_namer      s      I X"J$   (!#f+,/557I aL&&(9QR=8	 9~
Q&ozA~.6	!91z1r   c                      e Zd ZdZdededededededed	efd
Zdeded	e	e   fdZ
dedededed	e	e   f
dZ	 ddededed	eeeef      fdZ	 	 ddedededededed	eeeeef      ef   fdZdeded	e	eeef      fdZy)ChatHistoryServicez1Service for managing chat history in the databaser   chat_session_idr*   user_idstore_id	branch_idfirst_questionr   c                     t        |      }t        ||||||      }	|j                  |	       |j                          |j	                  |	       t
        j                  d|        |	S )z<
        Create a new chat session in the database.
        )r   r*   r   r   r   r~   zCreated chat session in DB: )r   r   addcommitrefreshr8   r9   )
r   r   r   r*   r   r   r   r   r~   sessions
             r   r<   z!ChatHistoryService.create_session   sf     '~6	++!
 	w
		


72?2CDEr   c                     |j                  t              j                  t        j                  |k(        j	                         S )z<
        Get a chat session by its chat_session_id.
        )queryr   filterr   first)r   r   r   s      r   get_session_by_chat_idz)ChatHistoryService.get_session_by_chat_id  s6     xx1299%55H

%'	r   rF   rG   c                 F   | j                  ||      }|t        j                  d|        y|j                         }t	        |j
                  ||      }|j                  |       t        j                         |_	        |j                          |j                  |       |S )z<
        Add a message to an existing chat session.
        Nz(Cannot add message - session not found: )r&   rF   rG   )r   r8   rD   r{   r   idr   r   utcnow
updated_atr   r   )r   r   r   rF   rG   r   message_rolerP   s           r   rQ   zChatHistoryService.add_message!  s     --b/B?NNEoEVWX zz|+zz
 	w &__.
		


7r   nc                    | j                  ||      }|g S |j                  t              j                  t        j                  |j
                  k(        j                  t        t        j                              j                  |      j                         }t        t        |            }|D cg c]  }|j                  |j                  d c}S c c}w )z
        Get the last N messages (n/2 questions and n/2 answers) for LLM context.
        Returns list of {role, content} dicts.
        rT   )r   r   r   r   r&   r   order_byr   r,   limitalllistreversedrF   rG   )r   r   r   r   r   r-   rV   s          r   get_last_n_messagesz&ChatHistoryService.get_last_n_messagesC  s     --b/B?I 8856==%00GJJ>

(*556

%(335	 	 *+  
 XX#++6
 	
 
s   1 Cpage	page_sizec                 f   |j                  t              j                  t        j                  |k(  t        j                  |k(  t        j
                  |k(        }|j                         }|dz
  |z  }	|j                  t        t        j                              j                  |	      j                  |      j                         }
g }|
D ]  }|j                  t        j                  t        j                              j                  t        j                   |j                  k(        j#                         }|j%                  |j                  |j&                  |j(                  |j*                  |j                  |j                  |j
                  |j,                  |j                  |d
        ||fS )z
        Get paginated list of chat sessions for a user/store/branch.
        Returns (sessions_with_count, total_count).
        r   )
r   r   r~   r*   r   r   r   r,   r   message_count)r   r   r   r   r   r   countr   r   r   offsetr   r   r
   r   r   r&   scalarrO   r   r~   r*   r,   )r   r   r   r   r   r   r   r   totalr   sessionsrh   r   r   s                 r   get_chat_history_listz(ChatHistoryService.get_chat_history_list`  sg    23::%--8%..(:%//9<
  (i'>>*556

&.y)##% 	
  	GHHTZZ0I0L0L%MNUU)44

Bfh  MMjj#*#:#:$..%00"??#,,$..%00%00!. 	$ u}r   c                 N   | j                  ||      }|y|j                  t              j                  t        j                  |j
                  k(        j                  t        j                        j                         }|j
                  |j                  |j                  |j                  |j                  |j                  |j                  |j                  |j                  |D cg c]1  }|j
                  |j                   |j"                  |j                  d3 c}d
S c c}w )z>
        Get detailed chat session with all messages.
        N)r   rF   rG   r,   )
r   r   r~   r*   r   r   r   r,   r   r-   )r   r   r   r   r&   r   r   r,   r   r   r~   r*   r   r   r   r   rF   rG   )r   r   r   r   r-   rV   s         r   get_chat_session_detailz*ChatHistoryService.get_chat_session_detail  s     --b/B? 8856==%00GJJ>

(,77
8 	
 **&66 **!,,(( **!,,!,, $  &&HH"{{"%..	
 	
s   '6D"N)
   )r   r   )rn   ro   rp   rq   r	   r/   rs   r   r<   r   r   r   rQ   r   r   r   r   r   r   r   ru   r   r   r   r      s   ;  	
     
#>

 
 
+	,	
     	 
   
+	, L 	

 
 	

 
d38n	
F 11 1 	1
 1 1 1 
tDcN#S(	)1f$
$
 $
 
$sCx.	!	$
r   r   )d   )%r6   r0   loggingtypingr   r   r   r   r   r   r    sqlalchemy.ormr	   
sqlalchemyr
   r   src.utils.settingsr   ImportErrorutils.settingsmodelsr   r   	getLoggerrn   r8   r(   r5   r]   r_   r   chat_session_servicer/   rs   r   r   chat_history_serviceru   r   r   <module>r      s       3 3   " !(+ I			8	$ .    r? r?l *+ 
2 2# 2 26D
 D
P *+ _  ('(s   B
 
BB