
    iK                        d Z ddlZddlZddlmZmZ ddlmZ  ej        e	          Z
eeegdf         ZdZ	 	 	 ddeded	ed
ee         dedee         fdZ	 	 ddededed
ee         deddfdZ	 	 ddedededed
ee         deddfdZdS )zAuto-generate short session titles from the first user/assistant exchange.

Runs asynchronously after the first response is delivered so it never
adds latency to the user-facing reply.
    N)CallableOptional)call_llmzGenerate a short, descriptive title (3-7 words) for a conversation that starts with the following exchange. The title should capture the main topic or intent. Return ONLY the title text, nothing else. No quotes, no punctuation at the end, no prefixes.      >@user_messageassistant_responsetimeoutfailure_callbackmain_runtimereturnc                    | r
| dd         nd}|r
|dd         nd}dt           ddd| d| dg}	 t          d	|dd
||          }|j        d         j        j        pd                                }	|	                    d          }	|	                                                    d          r|	dd                                         }	t          |	          dk    r|	dd         dz   }	|	r|	ndS # t          $ r~}
t                              d|
           t                              dd           |:	  |d|
           n,# t          $ r t                              dd           Y nw xY wY d}
~
dS d}
~
ww xY w)u  Generate a session title from the first exchange.

    Uses the main runtime's model when available, falling back to the
    auxiliary LLM client (cheapest/fastest available model).
    Returns the title string or None on failure.

    ``failure_callback`` is invoked with ``(task, exception)`` when the
    auxiliary call raises — the caller typically wires this to
    ``AIAgent._emit_auxiliary_failure`` so the user sees a warning instead
    of silently accumulating untitled sessions.
    Ni   system)rolecontentuserzUser: z

Assistant: title_generationg333333?)taskmessages
max_tokenstemperaturer	   r   r   z"'ztitle:   P   M   z...zTitle generation failed: %szTitle generation tracebackT)exc_infoztitle generationz(Title generation failure_callback raised)_TITLE_PROMPTr   choicesmessager   striplower
startswithlen	Exceptionloggerwarningdebug)r   r   r	   r
   r   user_snippetassistant_snippetr   responsetitlees              :/home/ubuntu/.hermes/hermes-agent/agent/title_generator.pygenerate_titler-      s   & *6=<%%2L4FN*4C400B m44$]\$]$]J[$]$]^^H
#%
 
 
 !!$,4:AACCE"";;==##H-- 	&!""IOO%%Eu::??#2#J&E'uu4' 
 
 
 	4a8881DAAA'X  !3Q7777 X X XGRVWWWWWXttttt
s<   B=C1 1
E9;9E45EE4&E+(E4*E++E44E9
session_idc                 b   | r|sdS 	 |                      |          }|rdS n# t          $ r Y dS w xY wt          ||||          }|sdS 	 |                     ||           t                              d|           dS # t          $ r&}t                              d|           Y d}~dS d}~ww xY w)a!  Generate and set a session title if one doesn't already exist.

    Called in a background thread after the first exchange completes.
    Silently skips if:
    - session_db is None
    - session already has a title (user-set or previously auto-generated)
    - title generation fails
    Nr
   r   z Auto-generated session title: %sz&Failed to set auto-generated title: %s)get_session_titler#   r-   set_session_titler$   r&   )	
session_dbr.   r   r   r
   r   existingr*   r+   s	            r,   auto_title_sessionr5   V   s      Z //
;; 	F	    (;KZf  E  B$$Z7777????? B B B=qAAAAAAAAABs$   " 
001A> >
B.B))B.conversation_historyc                     | r|r|r|sdS t          d |pg D                       }|dk    rdS t          j        t          | |||f||ddd          }|                                 dS )u   Fire-and-forget title generation after the first exchange.

    Only generates a title when:
    - This appears to be the first user→assistant exchange
    - No title is already set
    Nc              3   L   K   | ]}|                     d           dk    dV   dS )r   r      N)get).0ms     r,   	<genexpr>z#maybe_auto_title.<locals>.<genexpr>   s7      \\qAEE&MMU[D[D[D[D[D[D[\\       r0   Tz
auto-title)targetargskwargsdaemonname)sum	threadingThreadr5   start)	r3   r.   r   r   r6   r
   r   user_msg_countthreads	            r,   maybe_auto_titlerK   ~   s      Z | CU  \\%9%?R\\\\\N!*l4FG$4lSS  F LLNNNNNr>   )r   NN)NN)__doc__loggingrF   typingr   r   agent.auxiliary_clientr   	getLogger__name__r$   strBaseExceptionFailureCallbackr   floatdictr-   r5   listrK    r>   r,   <module>rY      s         % % % % % % % % + + + + + +		8	$	$ C/56c  267 777 7 /	7
 7 c]7 7 7 7~ 37%B %B%B %B 	%B
 /%B %B 
%B %B %B %B\ 37! !! ! 	!
 ! /! ! 
! ! ! ! ! !r>   