+
    i-                         R t ^ RIt^ RIHt ^ RIHt ^ RIHt ^ RIHtH	t	H
t
HtHt ^ RIHt ]P                  ! ]4      tRtRt^R	IHtHt ^R
IHt ] ! R R4      4       t ! R R4      tRR R lltRR R lltR# )u0  
Delivery routing for cron job outputs and agent responses.

Routes messages to the appropriate destination based on:
- Explicit targets (e.g., "telegram:123456789")
- Platform home channels (e.g., "telegram" → home channel)
- Origin (back to where the job was created)
- Local (always saved to files)
N)Path)datetime)	dataclass)DictListOptionalAnyUnion)get_hermes_homei  i  )PlatformGatewayConfig)SessionSourcec                   r   a  ] tR t^t o RtRtRtRtRt]	R
V 3R lR ll4       t
V 3R lR ltV 3R ltR	tV tR# )DeliveryTargetu   
A single delivery target.

Represents where a message should be sent:
- "origin" → back to source
- "local" → save to local files
- "telegram" → Telegram home channel
- "telegram:123456" → specific Telegram chat
NFc                :   < V ^8  d   QhRS[ RS[S[,          RR/# )   targetoriginreturnr   )strr   r   )format__classdict__s   "-/home/ubuntu/hermes-agent/gateway/delivery.py__annotate__DeliveryTarget.__annotate__.   s(     .0 .03 .0(? .0K[ .0    c                   VP                  4       P                  4       pVR8X  dK   V'       d+   V ! VP                  VP                  VP                  RR7      # V ! \
        P                  RR7      # VR8X  d   V ! \
        P                  R7      # RV9   di   VP                  R^4      pV^ ,          p\        V4      ^8  d
   V^,          MRp\        V4      ^8  d
   V^,          MRp \        V4      pV ! WuVRR	7      #  \        V4      pV ! VR7      #   \         d    T ! \
        P                  R7      u # i ; i  \         d    T ! \
        P                  R7      u # i ; i)
u   
Parse a delivery target string.

Formats:
- "origin" → back to source
- "local" → local files only
- "telegram" → Telegram home channel
- "telegram:123456" → specific Telegram chat
r   T)platformchat_id	thread_id	is_origin)r   r    localr   :N)r   r   r   is_explicit)
striplowerr   r   r   r   LOCALsplitlen
ValueError)clsr   r   partsplatform_strr   r   r   s   &&&     r   parseDeliveryTarget.parse-   s8    %%'X#__"NN$.."	  HNNdCCW// &=LLa(E 8L"%e*q.eAhdG$'JNaI4#L1H`dee	0'H))  4HNN334  	0//	0s$   'D >D: "D76D7:"EEc                    < V ^8  d   QhRS[ /# )r   r   )r   )r   r   s   "r   r   r   ^   s     
# 
#3 
#r   c                   V P                   '       d   R# V P                  \        P                  8X  d   R# V P                  '       dE   V P
                  '       d3   V P                  P                   RV P                   RV P
                   2# V P                  '       d&   V P                  P                   RV P                   2# V P                  P                  # )zConvert back to string format.r   r!   r#   )r    r   r   r'   r   r   value)selfs   &r   	to_stringDeliveryTarget.to_string^   s    >>>==HNN*<<<DNNNmm))*!DLL>4>>:JKK<<<mm))*!DLL>::}}"""r   c                v   < V ^8  d   Qh/ S[ ;R&   S[S[,          ;R&   S[S[,          ;R&   S[;R&   S[;R&   # )r   r   r   r   r    r$   )r   r   r   bool)r   r   s   "r   r   r      sN        c]!  }#     r    N)__name__
__module____qualname____firstlineno____doc__r   r   r    r$   classmethodr.   r4   __annotate_func____static_attributes____classdictcell__r   s   @r   r   r      sJ      "G#IIK.0 .0 .0`
# 
#E  r   r   c                      a  ] tR t^kt o RtRV 3R lR lltRV 3R lR lltRV 3R lR lltV 3R	 lR
 ltV 3R lR lt	V 3R lR lt
RtV tR# )DeliveryRouterz
Routes messages to appropriate destinations.

Handles the logic of resolving delivery targets and dispatching
messages to the right platform adapters.
Nc                <   < V ^8  d   QhRS[ RS[S[S[3,          /# )r   configadapters)r   r   r   r   )r   r   s   "r   r   DeliveryRouter.__annotate__s   s(     
@ 
@} 
@Xs]8K 
@r   c                n    Wn         T;'       g    / V n        \        4       R,          R,          V n        R# )z
Initialize the delivery router.

Args:
    config: Gateway configuration
    adapters: Dict mapping platforms to their adapter instances
cronoutputN)rG   rH   r
   
output_dir)r3   rG   rH   s   &&&r   __init__DeliveryRouter.__init__s   s*      B)+f4x?r   c                r   < V ^8  d   QhRS[ S[S[S[,          3,          RS[S[,          RS[S[,          /# )r   deliverr   r   )r	   r   r   r   r   r   )r   r   s   "r   r   rI      s@     - -sDI~&- '- 
n		-r   c                   \        V\        4      '       d   V.p. p\        4       pV F  p\        P	                  WR4      pVP
                  fa   VP                  \        P                  8w  dB   V P                  P                  VP                  4      pV'       d   VP
                  Vn        MK  VP                  VP
                  VP                  3pW9  g   K  VP                  V4       VP                  V4       K  	  V P                  P                  '       dC   \        P                  RR3p	W9  d*   VP                  \        \        P                  R7      4       V# )a  
Resolve delivery specification to concrete targets.

Args:
    deliver: Delivery spec - "origin", "telegram", ["local", "discord"], etc.
    origin: The source where the request originated (for "origin" target)

Returns:
    List of resolved delivery targets
Nr"   )
isinstancer   setr   r.   r   r   r   r'   rG   get_home_channelr   addappendalways_log_local)
r3   rQ   r   targetsseen_platforms
target_strr   homekey	local_keys
   &&&       r   resolve_targetsDeliveryRouter.resolve_targets   s    gs##iG!J#))*=F ~~%&//X^^*K{{33FOOD%)\\FN  ??FNNF4D4DEC(""3'v&! "& ;;'''!t4I.~x~~FGr   c                   < V ^8  d   QhRS[ RS[S[,          RS[S[ ,          RS[S[ ,          RS[S[S[ S[3,          ,          RS[S[ S[3,          /# )r   contentrY   job_idjob_namemetadatar   )r   r   r   r   r   r   )r   r   s   "r   r   rI      si     ( (( n%( 	(
 3-( 4S>*( 
c3h(r   c                ^  "   / pV Ff  p VP                   \        P                  8X  d   V P                  WWE4      pMV P	                  WqV4      G Rj  xL
 pRRRV/WgP                  4       &   Kh  	  V#  L   \         d+   p	RRR\        T	4      /YgP                  4       &    Rp	?	K  Rp	?	ii ; i5i)a0  
Deliver content to all specified targets.

Args:
    content: The message/output to deliver
    targets: List of delivery targets
    job_id: Optional job ID (for cron jobs)
    job_name: Optional job name
    metadata: Additional metadata to include

Returns:
    Dict with delivery results per target
NsuccessTresultFerror)r   r   r'   _deliver_local_deliver_to_platformr4   	Exceptionr   )
r3   rb   rY   rc   rd   re   resultsr   rh   es
   &&&&&&    r   rQ   DeliveryRouter.deliver   s     * F??hnn4!00(UF#'#<#<Vh#WWF tf/((*+ "  X  uSV/((*+sA   B-AA5A3A5-B-3A55B* B%B-%B**B-c                   < V ^8  d   QhRS[ RS[S[ ,          RS[S[ ,          RS[S[S[ S[3,          ,          RS[S[ S[3,          /# )r   rb   rc   rd   re   r   )r   r   r   r   )r   r   s   "r   r   rI      sZ     ,
 ,
,
 ,
 3-	,

 4S>*,
 
c3h,
r   c                   \         P                  ! 4       P                  R4      pV'       d   V P                  V,          V R2,          pMV P                  R,          V R2,          pVP                  P                  RRR7       . pV'       d   VP                  RV 24       MVP                  R4       VP                  R4       VP                  R	\         P                  ! 4       P                  R
4       24       V'       d   VP                  RV 24       V'       d1   VP                  4        F  w  rVP                  RV RV	 24       K  	  VP                  R4       VP                  R4       VP                  R4       VP                  V4       VP                  RP                  V4      4       R\        V4      RV/# )zSave content to local files.%Y%m%d_%H%M%Sz.mdmiscTparentsexist_okz# z# Delivery Output z**Timestamp:** z%Y-%m-%d %H:%M:%Sz**Job ID:** z**z:** z---
path	timestamp)r   nowstrftimerM   parentmkdirrW   items
write_textjoinr   )
r3   rb   rc   rd   re   rz   output_pathlinesr]   r2   s
   &&&&&     r   rj   DeliveryRouter._deliver_local   sn    LLN++O<	//F2	{#5FFK//F2	{#5FFK   = LL2hZ)LL,-Rx||~'>'>?R'S&TUVLL<x01&nn.
r#d5'23 / 	RURWtyy/0 C$
 	
r   c                ,   < V ^8  d   QhRS[ RS[ RS[/# )r   rb   rc   r   )r   r   )r   r   s   "r   r   rI     s"       c d r   c                    \         P                  ! 4       P                  R4      p\        4       R,          R,          pVP	                  RRR7       WB RV R2,          pVP                  V4       V# )z7Save full cron output to disk and return the file path.rr   rK   rL   Trt   _z.txt)r   r{   r|   r
   r~   r   )r3   rb   rc   rz   out_dirry   s   &&&   r   _save_full_output DeliveryRouter._save_full_output  s`    LLN++O<	!#f,x7dT281YKt44 r   c          
      n   < V ^8  d   QhRS[ RS[RS[S[S[S[3,          ,          RS[S[S[3,          /# )r   r   rb   re   r   )r   r   r   r   r   )r   r   s   "r   r   rI     sN     [ [[ [ 4S>*	[
 
c3h[r   c                  "   V P                   P                  VP                  4      pV'       g#   \        RVP                  P                   24      hVP
                  '       g$   \        RVP                  P                   R24      h\        V4      \        8  db   T;'       g    / P                  RR4      pV P                  W%4      p\        P                  R\        V4      V4       VR\         RV R	2,           p\        T;'       g    / 4      pVP                  '       d   R
V9  d   VP                  VR
&   TP                  VP
                  Y';'       g    RR7      G Rj  xL
 #  L5i)z(Deliver content to a messaging platform.zNo adapter configured for zNo chat ID for z	 deliveryrc   unknownu4   Cron output truncated (%d chars) — full output: %sNz'

... [truncated, full output saved to ]r   )re   )rH   getr   r*   r2   r   r)   MAX_PLATFORM_OUTPUTr   loggerinfoTRUNCATED_VISIBLEdictr   send)r3   r   rb   re   adapterrc   
saved_pathsend_metadatas   &&&&    r   rk   #DeliveryRouter._deliver_to_platform  s6     --##FOO49&//:O:O9PQRR~~~v/D/D.EYOPP w<--nn"))(I>F//@JKKNPST[P\^hi**+=j\KL 
 X^^,= @)/)9)9M+&\\&..'DYDYUY\ZZZZs1   A!E*$?E*$A%E*
E*#4E*E*#E($E*)rH   rG   rM   r9   )NNN)r:   r;   r<   r=   r>   rN   r_   rQ   rj   r   rk   rA   rB   rC   s   @r   rE   rE   k   sM     
@ 
@- -^( (T,
 ,
\ [ [r   rE   c                    V ^8  d   QhR\         \        \        \        \        ,          3,          ,          R\         \        ,          R\        R\        \        \        \        ,          3,          /# )r   rQ   r   defaultr   )r   r	   r   r   r   )r   s   "r   r   r   .  sT      eCcN+,]#  3S	>	r   c                    V '       g   V# V # )zM
Normalize a delivery specification.

If None or empty, returns the default.
r8   )rQ   r   r   s   &&&r   parse_deliver_specr   .  s     Nr   c                t    V ^8  d   QhR\         R\        \        ,          R\        \        \
        3,          /# )r   rG   r   r   )r   r   r   r   r   r   )r   s   "r   r   r   =  s3     " ""]#" 
#s(^"r   c                X   V P                  4       pRRRRVRJ/RRRRR//pV F[  pV P                  V4      pRVP                  P                  4        R	2RRR
V'       d   VP	                  4       MR/W4P                  &   K]  	  RV'       d   VP	                  4       MRRVRV P
                  /# )z
Build context for the unified cronjob tool to understand delivery options.

This is passed to the tool so it can validate and explain delivery targets.
r   descriptionz"Back to where this job was created	availableNr!   zSave to local files onlyTz home channelhome_channeloptionsrX   )get_connected_platformsrU   r2   titleto_dictrX   )rG   r   	connectedr   r   r\   s   &&    r   build_delivery_context_for_toolr   =  s     ..0I 	?t+
 	5
	G &&x0hnn2245]CdDLLN#
  	f&.."$7F33 r   )Nr   r9   )r>   loggingpathlibr   r   dataclassesr   typingr   r   r   r   r	   hermes_cli.configr
   	getLoggerr:   r   r   r   rG   r   r   sessionr   r   rE   r   r   r8   r   r   <module>r      s~       ! 3 3 -			8	$   + " K# K# K#\@[ @[F" "r   