
    `gjv1                       U d Z ddlmZ ddlZddlmZmZmZ ddlm	Z
 d<dZd=dZd	d
dddddddgddddddddddddddddgdddZded<   dd ddd!diidd"dZded#<   d$d%dd&d'd(d)d!did*dd"dZded+<   d,d-ddd!diidd"dZded.<   d/d0ddd1dd!did2d3gdddZded4<   d>d5Zd?d6Zd@d7Zd@d8Zd@d9Zd@d:Zd@d;Zy)Au:  Agent-facing tools for the google_meet plugin.

Tools:
  meet_join        — join a Google Meet URL (spawns Playwright bot locally
                     OR on a remote node host via node=<name>)
  meet_status      — report bot liveness + transcript progress
  meet_transcript  — read the current transcript (optional last-N)
  meet_leave       — signal the bot to leave cleanly
  meet_say         — (v2) speak text through the realtime audio bridge.
                     Requires the active meeting to have been joined with
                     mode='realtime'.
    )annotationsN)AnyDictOptional)process_managerc                 v    ddl } | j                         j                         dvry	 ddl}y# t        $ r Y yw xY w)u  Return True when the plugin can actually run LOCALLY.

    Gates on:
      * Python ``playwright`` package importable
      * the plugin being on a supported platform (Linux or macOS)

    Note: remote-node operation (``node=<name>``) only needs the
    ``websockets`` dep on the gateway side — Chromium lives on the node.
    But the plugin-level gate keeps the v1 semantics; individual tool
    handlers relax the requirement when a node is addressed.
    r   N>   linuxdarwinFT)platformsystemlower
playwrightImportError)_pr   s     L/root/.hermes/venv/lib/python3.12/site-packages/plugins/google_meet/tools.pycheck_meet_requirementsr      sC     	yy{"55   s   , 	88nodec                    | | dk(  ryddl m} ddlm}  |       }|j	                  | dk7  r| nd      }|t        d| d	       ||d
   |d         }||j                  d      fS )zReturn (NodeClient, node_name) for *node*, or (None, None) to run local.

    Raises RuntimeError with a readable message if the node is named but
    unresolvable, so the handler can surface a clear error to the agent.
    N )NNr   )NodeRegistry)
NodeClientautoz no registered meet node matches u>    — run `hermes meet node approve <name> <url> <token>` firsturltoken)r   r   name)!plugins.google_meet.node.registryr   plugins.google_meet.node.clientr   resolveRuntimeErrorget)r   r   r   regentryclients         r   _resolve_node_clientr$   4   s     |trz>:
.CKKD9E}.th 7H H
 	
 E%Lg?F599V$$$    	meet_joinu  Join a Google Meet call and start scraping live captions into a transcript file. Only meet.google.com URLs are accepted; no calendar scanning, no auto-dial. Spawns a headless Chromium subprocess that runs in parallel with the agent loop — returns immediately. Poll with meet_status and read captions with meet_transcript. Reminder to the agent: you should announce yourself in the meeting (there is no automatic consent announcement).objectstringz/Full https://meet.google.com/... URL. Required.)typedescription
transcriberealtimeztranscribe (default): listen-only, scrape captions. realtime: also enable agent speech via meet_say (requires OpenAI Realtime key + platform audio bridge).)r)   enumr*   zFDisplay name to use when joining as guest. Defaults to 'Hermes Agent'.zkOptional max duration before auto-leave (e.g. '30m', '2h', '90s'). Omit to stay until meet_leave is called.booleanzDRun Chromium headed instead of headless (debug only). Default false.a+  Name of a registered remote node to run the bot on (useful when the gateway runs on a headless Linux box but the user's Chrome with a signed-in Google profile lives on their Mac). Pass 'auto' to use the single registered node. Default: run locally. Nodes are approved via `hermes meet node approve`.)r   mode
guest_namedurationheadedr   r   F)r)   
propertiesrequiredadditionalProperties)r   r*   
parametersDict[str, Any]MEET_JOIN_SCHEMAmeet_statusu   Report the current Meet session state — whether the bot is alive, has joined, is sitting in the lobby, number of transcript lines captured, and last-caption timestamp.r)   )r)   r3   r5   MEET_STATUS_SCHEMAmeet_transcriptzRead the scraped transcript for the active Meet session. Returns full transcript unless 'last' is set, in which case returns the last N lines only.integerz|Optional: return only the last N caption lines. Useful for polling during a meeting without re-reading the whole transcript.   )r)   r*   minimum)lastr   MEET_TRANSCRIPT_SCHEMA
meet_leaveu   Leave the active Meet call cleanly, stop caption scraping, and finalize the transcript file. Safe to call when no meeting is active — returns ok=false with a reason.MEET_LEAVE_SCHEMAmeet_sayuy  Speak text into the active Meet call. Requires the active meeting to have been joined with mode='realtime'. The text is queued to the bot's OpenAI Realtime session; the generated audio is streamed into Chrome's fake microphone via a virtual audio device (PulseAudio null-sink on Linux, BlackHole on macOS). Returns immediately — the actual speech lags by a couple of seconds.zText to speak.)textr   rD   MEET_SAY_SCHEMAc                0    t        j                  | d      S )NF)ensure_ascii)jsondumps)objs    r   _jsonrK      s    ::c..r%   c                "    t        d| d|      S )NF)successerror)rK   )msgextras     r   _errrQ      s    US:E:;;r%   c                x   | j                  d      xs dj                         }|st        d      S | j                  d      xs dj                         j                         }|dvrt        d|d      S | j                  d	      }	 t	        |      \  }}|	 |j                  |t        | j                  d
      xs d      | j                  d      rt        | j                  d            nd t        | j                  dd            |      }t        t        |j                  d            |d|      S t               st        d      S t        j                  |t        | j                  dd            t        | j                  d
      xs d      | j                  d      rt        | j                  d            nd |      }t        dt        |j                  d            i|      S # t
        $ r}t        t        |            cY d }~S d }~ww xY w# t        $ r}t        d| |      cY d }~S d }~ww xY w)Nr   r   zurl is requiredr/   r+   >   r,   r+   z-mode must be 'transcribe' or 'realtime' (got )r   r0   zHermes Agentr1   r2   F)r   r0   r1   r2   r/   okrM   r   zremote node start_bot failed: r   u   google_meet plugin prerequisites missing — install with `pip install playwright && python -m playwright install chromium`. Plugin is supported on Linux and macOS only.)r   r2   r0   r1   r/   rM   )r    striprQ   r   r$   r   str	start_botboolrK   	Exceptionr   pmstart)	args_kwr   r/   r   r#   	node_nameeress	            r   handle_meet_joinrc      s
   88E? b
'
'
)C%&&HHV,335;;=D--CD81MNN88FD06	 
	N""txx5GH6:hhz6JTXXj12PTDHHXu56 # C T#''$-%8)SsSTT
 #$F
 	

 ((DHHXu-.txx-?@.2hhz.BTXXj)*C )T#''$-08C899?  CF|  	N8<9MM	Ns=   G, BH ,	H5HHH	H9H4.H94H9c                   	 t        | j                  d            \  }}|9	 |j                         }t        t        |j                  d            |d|      S t        j
                         }t        dt        |j                  d            i|      S # t        $ r}t        t	        |            cY d }~S d }~ww xY w# t        $ r}t        d| |      cY d }~S d }~ww xY w)Nr   rT   rU   zremote node status failed: rV   rM   )
r$   r    r   rQ   rX   statusrK   rZ   r[   r\   r^   r_   r#   r`   ra   rb   s         r   handle_meet_statusrg     s    0&1AB	 	K--/CT#''$-%8)SsSTT ))+C)T#''$-08C899  CF|  	K5aS9	JJ	Ks:   B 7B? 	B<B71B<7B<?	C"CC"C"c                T   | j                  d      }	 |t        |      nd }||dk  rd }	 t	        | j                  d            \  }}|;	 |j                  |      }t        t        |j                  d            |d|      S t        j                  |      }t        d	t        |j                  d            i|      S # t        t        f$ r d }Y w xY w# t
        $ r}t        t        |            cY d }~S d }~ww xY w# t        $ r}t        d| |      cY d }~S d }~ww xY w)
Nr?   r=   r   )r?   rT   rU   zremote node transcript failed: rV   rM   )r    int	TypeError
ValueErrorr$   r   rQ   rX   
transcriptrK   rZ   r[   r\   )r^   r_   r?   last_ir#   r`   ra   rb   s           r   handle_meet_transcriptrn   (  s*   88FD".TD&1*F0&1AB	 	O###0CT#''$-%8)SsSTT --V
$C)T#''$-08C899 z"   CF|  	O9!=INN	OsL   C C 9D CC	D#C<6D<D	D'D"D'"D'c                   	 t        | j                  d            \  }}|9	 |j                         }t        t        |j                  d            |d|      S t        j
                  d      }t        dt        |j                  d            i|      S # t        $ r}t        t	        |            cY d }~S d }~ww xY w# t        $ r}t        d| |      cY d }~S d }~ww xY w)	Nr   rT   rU   zremote node stop failed: rV   zagent called meet_leave)reasonrM   )
r$   r    r   rQ   rX   stoprK   rZ   r[   r\   rf   s         r   handle_meet_leaverr   >  s    0&1AB	 	I++-CT#''$-%8)SsSTT ''2
3C)T#''$-08C899  CF|  	I3A37iHH	Is:   B 7C 	B> B93B>9B>	C$
CC$C$c                .   | j                  d      xs dj                         }|st        d      S 	 t        | j                  d            \  }}|:	 |j                  |      }t        t        |j                  d            |d|      S t        j                  |      }t        d	t        |j                  d            i|      S # t        $ r}t        t        |            cY d }~S d }~ww xY w# t        $ r}t        d| |      cY d }~S d }~ww xY w)
NrD   r   ztext is requiredr   rT   rU   zremote node say failed: rV   rM   )r    rW   rQ   r$   r   rX   sayrK   rZ   r[   r\   enqueue_say)r^   r_   rD   r#   r`   ra   rb   s          r   handle_meet_sayrv   M  s   HHV"))+D&''0&1AB	 	H**T"CT#''$-%8)SsSTT ..
C)T#''$-08C899  CF|  	H21#6YGG	Hs;   C 8C1 	C.C)#C.)C.1	D:D	DD)returnrZ   )r   zOptional[str])rJ   r   rw   rX   )rO   rX   rw   rX   )r^   r7   rw   rX   )__doc__
__future__r   rH   typingr   r   r   plugins.google_meetr   r\   r   r$   r8   __annotations__r:   r@   rB   rE   rK   rQ   rc   rg   rn   rr   rv    r%   r   <module>r~      s   #  & & 54%6 	.  !E !%z2N	 !& !M "% !?
K0
b G %i5A$ . AH 	0
 VX&
 !&& N " 	
  "(  X&
 !&*  4 	5
 VX&
 !&% > " 	I %6FGX&
 H %# 4/<*:Z::,::r%   