
    sj                         d Z ddlZddlmZ ddlmZ ddlmZmZ ddl	m
Z
 d Z	 	 dded	ed
efdZdded
efdZd
efdZddddddddddddddgddZ ej        dded ed           dS )u  Let the agent react to a message with an emoji in the Hermes desktop app.

The conversational counterpart to the user's tapback: the same reaction store,
the same one-per-author semantics, just written with ``author="agent"``.

Lives in the ``desktop_ui`` toolset (like the other GUI affordances) so it costs
nothing on every other surface — the platform adapters already expose reactions
through ``send_message(action="react")``, and this is the desktop's equivalent.

Defaults to the message that triggered this turn (the photon precedent: the
model shouldn't have to thread row ids through tool calls), and emits
``message.reaction`` so the renderer paints it without waiting for a resume.
    N)get_session_env)
desktop_ui)registry
tool_error)env_var_enabledc                  F    	 ddl m}   |             S # t          $ r Y dS w xY w)zAOpen the SessionDB for the profile owning this turn, or ``None``.r   	SessionDBN)hermes_stater
   	Exceptionr	   s    ?/home/agent/.hermes/hermes-agent/tools/react_to_message_tool.py_open_session_dbr      sG    ******y{{   tts    
  emojisession_keyreturnc                   |st          d          S |}d}|Qt          dt          |pd                    }|                    |d|          }|t          |rd| dnd          S n'|                    |t          |                    }|pd}	 |                    |t          |          | pdd	
          }	n)# t          $ r}
t          d|
           cY d}
~
S d}
~
ww xY w|	t          d| d          S 	 t          j        dt          |          |	|d           n# t          $ r Y nw xY wt          j
        dt          |          |	dd          S )AAttach (or with an empty ``emoji`` retract) the agent's reaction.>   No active session — reactions need a persisted conversation.userNr   )roleoffsetzNo user message found z back.z No user message to react to yet.agent)authorzFailed to set the reaction: zMessage z" is not part of this conversation.zmessage.reaction)row_id	reactionsr   T)successr   r   F)ensure_ascii)r   maxintlatest_message_row_idget_message_roleset_message_reactionr   r   emitjsondumps)r   message_row_idmessages_backdbr   r   target_rolebackrowr   excs              r   _react_to_message_with_dbr-   "   s     \Z[[[FK~
 1c-,1--..))+F4)PP>9=e55555Ce   
 !!+s6{{;;mV@++VemtG , 
 
		  @ @ @>>>????????@ OVOOOPPP6{{KPP	
 	
 	
 	
     :CKKiHHW\   s0   (B: :
C CC C 9&D   
D-,D-c                    | pd                                 } t          dd          pt          dd          }|st          d          S t                      }|t          d          S 	 t	          | ||||          	 |                                 S # t          $ r Y S w xY w# 	 |                                 w # t          $ r Y w w xY wxY w)r    HERMES_SESSION_KEYHERMES_SESSION_IDr   NzSession storage is unavailable.)r(   r   )stripr   r   r   r-   closer   )r   r&   r'   r   r(   s        r   react_to_message_toolr4   Z   s
   [b!!E!"6;; R@ @K  \Z[[[			B	z;<<<(#
 
 
	HHJJJJ 	 	 	D		HHJJJJ 	 	 	D	sB   (B! <B
BB!C#B87C8
CCCCc                      	 ddl m}   |                                 d          }n# t          $ r Y dS w xY wt	          |t
                    o"t          |                    dd                    S )u  Opt-in feature flag — surface eligibility is the toolset's job.

    ``desktop_ui`` already restricts this to GUI sessions. What's left is the
    user's own toggle (Settings → Appearance), which the desktop mirrors into
    ``display.message_reactions`` on the CONNECTED gateway's config — so this
    reads the right config whether that gateway is local, SSH, URL, or cloud.
    r   )load_config_readonlydisplayFmessage_reactions)hermes_cli.configr6   getr   
isinstancedictbool)r6   r7   s     r   check_react_requirementsr>   w   s    ::::::&&((,,Y77   uugt$$Vgkk:Mu.U.U)V)VVs   #& 
44react_to_messageu  React to a message with a single emoji, the way you'd tapback in iMessage. Reach for it when a reaction is what a person would do: something funny gets a 😂, warmth gets a ❤️, a plan you're on board with gets a 👍 — then just carry on with whatever the message actually needs. If a reaction says it all, it can BE the reply (skip the redundant 'sounds good!' turn). Use it like a person would: occasionally, when felt — not on every message, and never as a status signal. NEVER narrate or explain a reaction ('I reacted with...', 'Reacting now') — the emoji appearing on the bubble is the whole point, and commentary kills it. Defaults to the user's most recent message. One reaction per message: a different emoji replaces yours, an empty string retracts it.objectstringuf   The emoji to react with (e.g. '❤️', '😂', '👍'). Pass an empty string to remove your reaction.)typedescriptionintegerz}Optional. The specific message to react to. Omit to react to the user's latest message, which is almost always what you want.u   Optional. React to an EARLIER user message: 1 = the one before the latest, 2 = two before, and so on. For when something lands late — the joke you only got after answering.r   r&   r'   )rB   
propertiesrequired)namerC   
parametersr   c                     t          |                     dd          |                     d          |                     d                    S )Nr   r/   r&   r'   rE   )r4   r:   )argskws     r   <lambda>rM      sF    4hhw##xx 011hh//          u   💛)rH   toolsetschemahandlercheck_fnr   )NN)__doc__r$   gateway.session_contextr   toolsr   tools.registryr   r   utilsr   r   strr-   r4   r=   r>   REACT_TO_MESSAGE_SCHEMAregister rN   r   <module>r\      s     3 3 3 3 3 3       / / / / / / / / ! ! ! ! ! !   5 55 5 	5 5 5 5p  RU    :W$ W W W W$ 
	  !6  "S  "F 
 
0 I5 + + \  	" 
 &
     rN   