+
    lHàj;õ  ã                   ó”  € R t ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIHt ^ RI	H
t
 ^ RIHtHtHtHtHt ^ RIt^ RIHt ]P(                  ! ]4      tRtRšt]P2                  P5                  ^ ]! ]
! ]4      P:                  P:                  4      4       ^ RIHtH t H!t!H"t"H#t#H$t$H%t%H&t&H't'H(t(H)t)H*t*H+t+ ^ RI,H-t- ^ R	I.H/t/H0t0H1t1H2t2H3t3H4t4H5t5H6t6H7t7H8t8H9t9H:t:H;t;H<t<H=t=H>t>H?t? ^ R
I@HAtAHBtB R R ltCR R ltDR R ltER R ltFR›R R lltGR R ltHR›R R lltIR R ltJRtKR R ltLR›R R lltM]Pœ                  R  R! l4       tOR›R" R# lltPR›R$ R% lltQRœR& R' lltRR( R) ltSR* R+ ltTR, R- ltUR�R. R/ lltVR0 R1 ltWR2 R3 ltXR4 R5 ltYR6 R7 ltZR8 R9 lt[R: R; lt\R< R= lt]R> R? lt^R@ RA lt_RB RC lt`RD RE ltaRF RG ltb]_]`]a]b3tcRH RI ltdRJ]XRK]Y/teRL]ZRM]dRN]]RO]]RP]]RQRR RSRT /tfRU RV ltgRžRX RY llthRZ R[ ltiR\ R] ltjR^R_R`RaRbRcRdRe/ RfRcRgR`Rh/bRiRcRjR`Rk/bRlRcRjR`Rm/bRnRcRjR`Ro/bRpRcRgR`Rq/bRrRcRjR`Rs/bRtRcRjRcRjR`Ru/bR^RcRjR`Rv/bRwRcRxR`Ry/bRzRcRjR`R{/bR|RcRjR`R}/bR~RcRR€RcRj/R`R�/bR‚RcRjR`]i! Rƒ4      /bR„RcRjR`R…/bR†RcRgR‡RWR`Rˆ/bR‰RcRR€RcRj/R`RŠ/bR‹RcRgR`RŒ/bR�RcRR€RcRj/R`RŽ/R�RcRjR`R�/R‘RcRgR`R’//CR“Rl.//tkR” R• ltlRŸtmR– tn]APÞ                  ! R_R—]k]n]lR˜]jR™7       R# ) z¤Cron job management tool: one compressed action-oriented `cronjob_manage` tool
(schema/context bloat avoided); `cronjob()` stays callable for direct Python callers.N)ÚFuture)ÚPath)ÚAnyÚDictÚListÚOptionalÚUnion)Údisplay_hermes_homeç      $@)ÚAmbiguousJobReferenceÚclaim_job_for_fireÚget_jobÚis_job_runnableÚ	list_jobsÚmark_job_runÚparse_scheduleÚ	pause_jobÚ
remove_jobÚresolve_job_refÚ
resume_jobÚtrigger_jobÚ
update_job)Ú_scan_cron_prompt)Ú_apply_continuityÚ_canonical_skillsÚ_clean_str_listÚ_format_jobÚ_gateway_liveness_noticeÚ_local_delivery_noticeÚ_mode_guidance_notesÚ_normalize_deliver_paramÚ_normalize_optional_job_valueÚ_origin_from_envÚ_repeat_displayÚ_resolve_cron_context_deliverÚ_split_monitor_argÚ_validate_bot_chat_deliverÚ_validate_context_from_refsÚ_validate_cron_base_urlÚ_validate_cron_script_path)ÚregistryÚ
tool_errorc                óR   € V ^8„  d   QhR\         \        \        3,          R\        /# )é   ÚpayloadÚreturn©ÚdictÚstrr   )Úformats   "Ú8/home/ubuntu/.hermes/hermes-agent/tools/cronjob_tools.pyÚ__annotate__r5   F   s"   € ÷ )ñ )”Dœœc˜•Nð )¤sñ )ó    c                 ó2   € \         P                  ! V ^R7      # )r-   )Úindent)ÚjsonÚdumps)r.   s   &r4   Ú_dumpsr;   F   s   € Ü�:Š:�g aÔ(Ð(r6   c                ó   € V ^8„  d   QhRR/# ©r-   r/   N© )r3   s   "r4   r5   r5   J   s   € ÷ ñ ¨Dñ r6   c                 óF   €  ^ RI Hp  V ! 4        R#   \         d     R# i ; i)zRTell the active scheduler provider the job set changed; best-effort, never raises.©Ú_notify_provider_jobs_changedN)Úcron.schedulerrA   Ú	Exceptionr@   s    r4   Ú"_notify_provider_jobs_changed_saferD   J   s"   € ðÝ@Ù%Ö'øÜô Úðús   ‚ ‘ Ÿ c                óR   € V ^8„  d   QhR\         \        \        3,          R\        /# ©r-   Újobr/   ©r1   r2   r   Úset)r3   s   "r4   r5   r5   W   s&   € ÷ Oñ O¬4´´S°­>ð O¼cñ Or6   c                ój  €  ^ RI Hp T! 4       pT'       g   \        4       #  ^ RIHp T! T 4      ;'       g    . pT Uu0 uF,  qUP                  R4      '       g   K  TP                  R4      kK.  	  upT,          #   \         d    \        4       u # i ; i  \         d    \        4       u # i ; iu upi )zEDelivery-platform names for this job that the relay connector fronts.)Úrelay_fronted_platforms©Ú_resolve_delivery_targetsÚplatform)Úgateway.relayrK   rC   rI   rB   rM   Úget)rG   rK   ÚfrontedrM   ÚtargetsÚts   &     r4   Ú!_relay_fronted_delivery_platformsrT   W   sš   € ðÝ9ñ &Ó'€GßÜ‹uˆðÝ<Ù+¨CÓ0×6Ð6°Bˆñ (/ÓD¡w !·%±%¸
×2CÔˆA�E‰E�*Ö¡wÑDÀwÕNÐNøô ô Ü‹uŠðûô ô Ü‹uŠðüâDs2   ‚A: ¢B ·B ¾B0ÁB0Á:BÂBÂB-Â,B-c                ó$   € V ^8„  d   QhR\         /# ©r-   r/   ©r2   )r3   s   "r4   r5   r5   h   s   € ÷ #ñ #œcñ #r6   c                 ó
  € ^ RI p V P                  RR4      P                  4       p V'       d   \        V4      MRp ^ RIHpHp \        V! V! 4       RRRR	RR
7      ;'       g    R4      P                  4       pT;'       g!    V P                  RR4      P                  4       pV'       d   VR9   d   RpRV9   d   VP                  R4      '       g   RV R2pRV RV 2#   \         d    Rp L³i ; i  \         d    Rp L‰i ; i)z¢``http://host:port`` of the local api_server, mirroring its bind resolution
(extra.host -> API_SERVER_HOST -> 127.0.0.1); a wildcard bind listens on loopback too.NÚAPI_SERVER_PORTÚ iÂ!  )Úcfg_getÚload_config_readonlyÚ	platformsÚ
api_serverÚextraÚhost©ÚdefaultÚAPI_SERVER_HOSTz	127.0.0.1Ú:Ú[Ú]zhttp://)z0.0.0.0z::Ú*)ÚosÚgetenvÚstripÚintÚ
ValueErrorÚhermes_cli.configr[   r\   r2   rC   Ú
startswith)rh   Úport_rawÚportr[   r\   r`   s         r4   Ú_api_server_base_urlrq   h   s   € ó Ø�y‰yÐ*¨BÓ/×5Ñ5Ó7€Hðß (Œs�8Œ}¨dˆðßCÜ‘7Ñ/Ó1°;ÀÈgÐW]ÐgiÔj×pÐpÐnpÓq×wÑwÓyˆð ×;Ð;�2—9‘9Ð.°Ó3×9Ñ9Ó;€Dß�4Ð1Ô1ØˆØ
ˆd„{˜4Ÿ?™?¨3×/Ò/Ø�4�&˜ˆ{ˆØ�T�F˜!˜D˜6Ð"Ð"øô ô ØŠðûô
 ô ØŠðús-   ¦C ®C ¼&C2 Á#C2 ÃC/Ã.C/Ã2DÄDc                óŠ   € V ^8„  d   QhR\         \        \        3,          R\        \        ,          R\        \        ,          /# ©r-   rG   Úextra_promptr/   ©r1   r2   r   r   )r3   s   "r4   r5   r5   ~   s4   € ÷ ñ ¤D¬¬c¨¥Nð Ä(Ì3Å-ð Ô[cÔdgÕ[hñ r6   c                ój  € \        V 4      '       g   R# ^ RIHp V! RR4      ;'       g    Rp ^ RIpTP	                  \        4        RV R,           R2RR	V 2/V'       d   R
V/M/ RR7      pVe#   VP                  R8  d   \        RRRRRR/4      # \        RRRR/4      #   \         d    Rp LDi ; i)ue  Forward a manual run to the gateway when it targets a relay-fronted platform: such delivery
has no standalone sender â€” the gateway's live relay adapter is the only path, reached via
``POST /api/jobs/{id}/run`` (marks the job due; ``extra_prompt`` rides in the body). Returns a
JSON result string when forwarding engages, else None (normal in-process run).N)Ú
get_secretÚAPI_SERVER_KEYrZ   z
/api/jobs/Úidz/runÚAuthorizationzBearer Úpromptr
   )Úheadersr9   Útimeouti,  ÚsuccessTÚforwarded_to_gatewayÚnotez�This job targets a relay-fronted platform; it was dispatched to the running gateway, whose live relay adapter owns that delivery.FÚerroru¨   This job targets a relay-fronted platform, which has no standalone sender. Start the gateway â€” its ticker will deliver the job on schedule via the live relay adapter.)	rT   Úagent.secret_scoperw   ÚhttpxÚpostrq   rC   Ústatus_coder;   )rG   rt   rw   Úkeyrƒ   Úresps   &&    r4   Ú_forward_relay_fronted_runrˆ   ~   sî   € ô
 -¨S×1Ò1ÙÝ-Ù
Ð% rÓ
*×
0Ð
0¨b€CðÛØ�z‰zÜ#Ó%Ð& j°°Tµ°¸4Ð@È?Ð^eÐfiÐejÐ\kÐJlß.:�8˜\Ñ*ÀÈTð ó Sˆð
 Ò˜D×,Ñ,¨sÔ2ÜØ�tØ" DØðð	
ó ð 	ô Ø�5ØðFðó ð øô ô ØŠðús   ®?B" Â"B2Â1B2c                óR   € V ^8„  d   QhR\         \        \        3,          R\        /# rF   rH   )r3   s   "r4   r5   r5       s"   € ÷ ñ ¬D´´c°­Nð ¼sñ r6   c                ó®  €  ^ RI Hp ^ RIHp V! V 4      ;'       g    .  Uu0 uF<  pVP	                  R4      '       g   K  V! VR,          4      '       g   K3  VR,          kK>  	  ppV'       g   \        4       # ^ RIHp YE! 4       P                  4        Uu0 uF  qfP                  kK  	  up,
          # u upi u upi   \         d    \        4       u # i ; i)z¬Delivery-platform names this satellite profile reaches only through the primary gateway's
``profile_routes``: routed here, with no credential of its own to send standalone.rL   )Ú._delivery_platform_routed_from_primary_gatewayrN   )Úload_gateway_config)rB   rM   Úcron.scheduler_preflightr‹   rP   rI   Úgateway.configrŒ   Úget_connected_platformsÚvaluerC   )rG   rM   r‹   rS   ÚroutedrŒ   Úps   &      r4   Ú"_primary_routed_delivery_platformsr“       s¾   € ð
Ý<Ý[Ù)BÀ3Ó)G×)MÐ)MÈ2Ð)Mó jÑ)M AØ—U‘U˜:×&ô  Ù+YÐZ[Ð\fÕZg×+hô  �!�J—-�-Ñ)Mˆð jçÜ“5ˆLÝ6ØÐ*=Ó*?×*WÑ*WÔ*YÓZÑ*Y QŸœÑ*YÑZÕZÐZùòjùò
 [øÜô Ü‹uŠðúsE   ‚B< �B< ¢B2Á B2ÁB2Á$B< Á8B< ÂB7Â)B< Â2
B< Â<CÃCc                óŠ   € V ^8„  d   QhR\         \        \        3,          R\        \        ,          R\        \        ,          /# rs   ru   )r3   s   "r4   r5   r5   °   s4   € ÷ #ñ #¤d¬3´¨8¥nð #ÄHÌSÅMð #Ô]eÔfiÕ]jñ #r6   c                óâ  € \        \        P                  P                  R4      RR4      p\	        V4      '       d   V! 4       e   R# \        V 4      '       g   R# \        V 4      pV'       g   R# ^ RIHp V! 4       pVRJd8   VRJ d   RMRp\        R	RR
RRP                  \        V4      4       RV 2/4      # \        V R,          VR7      p\        4        \        R	RR\        V4      RR/4      # )af  Queue a manual run for the gateway ticker when the job delivers through the primary gateway's
profile route: only the gateway process holding the primary's bot can send it, so an in-process
run would spend the whole turn and then record ``delivery_failed`` (#120330). Returns a JSON
result string when the hand-off engages, else None (normal in-process run).úgateway.runÚ_gateway_runner_refN)Ú_builtin_gateway_livenessTFuB   Start the gateway â€” its ticker will deliver the job on schedule.zaCould not determine whether a gateway serves this profile; check `hermes cron status` and re-run.r~   r�   zThis job delivers to z, zN through the primary gateway's profile route, which has no standalone sender. ry   ©rt   rG   r€   z�This job delivers through the primary gateway's profile route; it was queued for that gateway's next scheduler tick, which runs and delivers it.)ÚgetattrÚsysÚmodulesrP   Úcallabler   r“   Úhermes_cli.cronr˜   r;   ÚjoinÚsortedr   rD   r   )rG   rt   Ú
runner_refr‘   r˜   ÚaliveÚcauseÚupdateds   &&      r4   Ú_hand_off_primary_routed_runr¥   °   s  € ô
 œŸ™Ÿ™¨Ó7Ð9NÐPTÓU€JÜ�
×Ò¡
£Ò 8ÙÜ˜3×ÒÙÜ/°Ó4€FßÙÝ9Ù%Ó'€EØ�DÓð Z_ÐbgÓYgÑUð9ð 	ô Ø�uØØ'¨¯	©	´&¸³.Ó(AÐ'Bð CLØLQÈ7ðTð
ó ð 	ô ˜#˜d�)°,Ô?€GÜ&Ô(ÜØ�4ØŒ{˜7Ó#ØðYð	ó ð r6   c                ó^   € V ^8„  d   QhR\         R\        \         \        3,          R\         /# )r-   ÚdeliverÚ	refreshedr/   ©r2   r1   r   )r3   s   "r4   r5   r5   Ö   s)   € ÷ 2ñ 2¤sð 2´t¼CÄ¸Hµ~ð 2Ì#ñ 2r6   c                óè   € V '       d   V R8X  d   R# \        VP                  R4      ;'       g    R4      P                  4       pV'       g   VP                  R4      '       d   R# R# RVR	,           R
2# )u  Parenthetical delivery note for a manual run's summary; follows the refreshed record's
``last_delivery_error`` so the summary never claims success over a failed delivery.

Follows the refreshed job record (#83993): ``run_one_job`` writes ``last_delivery_error`` via
``mark_job_run`` when the post-run delivery (telegram/discord/â€¦) failed, and the summary must not claim
success over that record â€” the calling agent relays this line to the user. Local jobs never deliver; an
empty/missing error keeps the legacy wording byte-for-byte.
Úlocalz (output saved locally only)Úlast_delivery_errorrZ   Úlast_delivery_queuedzC (output queued for Bot Chat; completion unverified, do not resend)z/ (output was delivered there by the job itself)u    (âš  delivery FAILED: :NéÈ   NÚ))r2   rP   rj   )r§   r¨   Úerrs   && r4   Ú_manual_run_delivery_noter±   Ö   sb   € ÷ �g Ô(Ù-Ü
ˆi�m‰mÐ1Ó2×8Ð8°bÓ
9×
?Ñ
?Ó
A€CßØ�=‰=Ð/×0Ò0ÙXÙ@Ø$ S¨¥Y K¨qÐ1Ð1r6   zcJob is already running (a scheduler tick or another manual run is executing it); not started again.c                ó0   € V ^8„  d   QhR\         R\         /# )r-   Újob_idÚ	log_labelrW   )r3   s   "r4   r5   r5   ð   s   € ÷ Jñ J¤#ð J´#ñ Jr6   c           
     óæ  €  \        V RRR7      p\        V\        4      '       d   VR3# \        V 4      pVf   RpM\	        V4      '       g   RpMRpRRRR	RR
V/3#   \
         dŠ   p\        P                  RYT4       \        P                  ! \
        4      ;_uu_ 4        \        T R\        T4      4       RRR4       M  + '       g   i     M; iRRRR	RR
\        T4      /3u Rp?# Rp?ii ; i)u  At-most-once claim shared by the sync and background run paths: ``(claimed_job, None)`` or
``(None, error_dict)`` in the ``_execute_job_now`` shape. A lost claim is labelled precisely â€”
claim_job_for_fire also returns False for paused/disabled/missing jobs, not just in-flight ones.T)ÚmanualÚ
return_jobNz%Job no longer exists; nothing to run.z1Job is paused/disabled; resume it before running.z;Job is already being fired by the scheduler; not run again.ÚclaimedFr~   r�   z&Failed to claim cron job %s for %s: %s)r   Ú
isinstancer1   r   r   rC   Úloggerr�   Ú
contextlibÚsuppressr   r2   )r³   r´   Úclaimed_jobr¨   ÚreasonÚes   &&    r4   Ú_claim_for_manual_runrÀ   ð   sß   € ðJÜ(¨¸ÈÔNˆÜ�k¤4×(Ò(Ø Ð$Ð$Ü˜F“Oˆ	ØÒØ<‰FÜ  ×+Ò+ØH‰FàRˆFØ�i ¨	°5¸'À6ÐJÐJÐJøÜô JÜ�‰Ð=¸vÐRSÔTÜ× Ò ¤×+Õ+Ü˜ ¬¨A«Ô/÷ ,×+×+Ð+úà�i  y°%¸Ä#ÀaÃ&ÐIÐIÕIûð	Jús:   ‚'A ª1A ÁC0Á'9C+Â C Â7	C+Ã CÃC+Ã%C0Ã+C0c                ó–   € V ^8„  d   QhR\         \        \        3,          R\        \        ,          R\         \        \        3,          /# rs   ru   )r3   s   "r4   r5   r5     s?   € ÷ `ñ `œ$œs¤C˜x�.ð `¼Ä½ð `ÔQUÔVYÔ[^ÐV^ÕQ_ñ `r6   c                óP   € \        V R,          R4      w  r#Ve   V# \        W!R7      # )zýRun a job now, outside the scheduler tick: claim via ``claim_job_for_fire`` (the ticker's
CAS, so a concurrent tick cannot double-fire and next_run_at advances), then fire through
the shared ``run_one_job`` body. Returns {"claimed", "success", "error"}.ry   zimmediate runr™   )rÀ   Ú_run_claimed_job)rG   rt   r½   r°   s   &&  r4   Ú_execute_job_nowrÄ     s,   € ô -¨S°­Y¸ÓHÑ€KØ’/ˆ3Ð_Ô'7¸Ô'_Ð_r6   c                ó$   € V ^8„  d   QhR\         /# )r-   Újob_namerW   )r3   s   "r4   r5   r5     s   € ÷ 0Bñ 0BœSñ 0Br6   c              #  óÒ  a aa"  € \         P                  ! 4       oRp ^ RIHp V! 4       oR VV V3R llpSe*   \         P
                  ! VRRR7      pVP                  4         Rx € SP                  4        Ve    VP                  \        ^,           R7       R# R#   \         d    Ro L�i ; i  SP                  4        Te   TP                  \        ^,           R7       i i ; i5i)	uõ   Heartbeat into the caller's activity tracker while a manual run executes (minutes,
synchronously on the caller's thread â€” without tool activity the gateway inactivity
watchdog would kill the parent turn). Best-effort: no callback -> no thread.N)Úget_activity_callbackc                ó   € V ^8„  d   QhRR/# r=   r>   )r3   s   "r4   r5   Ú$_run_heartbeat.<locals>.__annotate__(  s   € ÷ ñ ˜Tñ r6   c                  óB  <€ \         P                  ! 4       p SP                  \        4      '       g\   \         P                  ! 4       V ,
          pV\        8”  d   \
        P                  R SV4       R#  S! RS R\        V4       R24       Kv  R#   \         d     K†  i ; i)uu   cronjob run heartbeat ceiling reached for job '%s' (%.0fs) â€” stopping heartbeat; gateway watchdog regains authorityNzcronjob: running job 'ú' (z
s elapsed))	ÚtimeÚ	monotonicÚwaitÚ_CRON_RUN_HEARTBEAT_INTERVALÚ_CRON_RUN_HEARTBEAT_CEILINGrº   Úwarningrk   rC   )ÚstartedÚelapsedÚactivity_cbrÆ   Ústops     €€€r4   Ú_heartbeat_loopÚ'_run_heartbeat.<locals>._heartbeat_loop(  s�   ø€ Ü—.’.Ó"ˆØ—)‘)Ô8×9Ò9Ü—n’nÓ&¨Õ0ˆGØÔ4Ô4ä—‘ð^à˜gô'ñ ðÙÐ4°X°J¸cÄ#ÀgÃ,ÀÈzÐZÖ[ñ :øô ô Úðús   Á3B ÂBÂBTzcronjob-run-heartbeat)ÚtargetÚdaemonÚname)r}   )
Ú	threadingÚEventÚtools.environments.baserÈ   rC   ÚThreadÚstartrI   rŸ   rÐ   )rÆ   ÚthreadrÈ   r×   rÕ   rÖ   s   f   @@r4   Ú_run_heartbeatrâ     sÏ   úé € ô
 �?Š?Ó€DØ€Fðõ 	Bñ ,Ó-ˆ÷ò ð  ÒÜ×!Ò!¨ÀÐLcÔdˆØ�‰ŒðBÛà�‰Œ
ØÒØ�K‰KÔ <¸qÕ @ˆKÖAñ øô5 ô ØŠðûð2 	�‰Œ
ØÒØ�K‰KÔ <¸qÕ @ˆKÕAð üs?   …C'žB «8C'Á$B0 Á(5C'ÂB-Â*C'Â,B-Â-C'Â04C$Ã$C'c                ó–   € V ^8„  d   QhR\         \        \        3,          R\        \        ,          R\         \        \        3,          /# rs   ru   )r3   s   "r4   r5   r5   C  s?   € ÷ ](ñ ](œ$œs¤C˜x�.ð ](¼Ä½ð ](ÔQUÔVYÔ[^ÐV^ÕQ_ñ ](r6   c           
     ó0  € V R,          pRpRp\        4       p\        4       pVP                  4         ^ RIHpHpHp	 V	! W%VR7      '       g/   RRRRR	\        /V'       d
   V! W%R
7       VP                  R4       # RpV P                  R4      p
\        V
\        4      '       d%   \        V
P                  R4      ;'       g    R4      MRp\        \        P                  P                  R4      RR4      p\!        V4      '       d   V! 4       MRpVe   \        VRR4      MRpVei   \#        VR4      '       dW   ^ RIHpHp V! V! 4       4      pVP+                  V4      p\        VRR 4      ! V4      '       d   ^ RIHpHp V! VV! 4       4      pVe   \        VRR4      MRp \3        \        V P                  R4      ;'       g    T4      4      ;_uu_ 4        V! WVVR7      pRRR4       RpV! W%R
7       \5        V4      ;'       g    / pRpV P                  R4      pV'       d   ^ RIHp V! \        V4      4      pVP                  R4      pVP                  R4      pVR8X  d   V'       g   VP                  R4      pVR&9   pVeQ   VP                  R4      R 8w  d;   RpVP                  R	4      ;'       g     R!VP                  R4      ;'       g    R" R#2pRRR\;        X;'       d    T4      R	V/V'       d
   V! W%R
7       VP                  R4       #   + '       g   i     EL;; i  RpT! Y%R
7       i ; i  \<         d¬   p\>        PA                  R$TT4       \B        PD                  ! \<        4      ;_uu_ 4        \G        TR\        T4      TR%7       RRR4       M  + '       g   i     M; iRRRRR	\        T4      /u Rp?T'       d
   X! Y%R
7       TP                  R4       # Rp?ii ; i  T'       d
   X! Y%R
7       TP                  R4       i ; i)'zìFire an already-claimed job through the shared ``run_one_job`` body (split from
``_execute_job_now`` so the background path can claim synchronously and hand the run
to a worker). Returns {"claimed": True, "success": bool, "error": ...}.ry   FN)Úrelease_running_jobÚrun_one_jobÚtry_register_running_job)ÚownerÚfuturer¸   Tr~   r�   )rè   Ú
fire_claimÚbyrZ   r–   r—   ÚadaptersÚ_adapters_for_profile)Úget_hermes_homeÚprofile_name_for_homeÚ_is_shared_bot_satellitec                 ó   € R # )Fr>   )Ú_ps   &r4   Ú<lambda>Ú"_run_claimed_job.<locals>.<lambda>t  s   € Áer6   )ÚSharedRouteAdaptersÚ(_primary_profile_routes_for_current_homeÚ_gateway_looprÛ   )rì   Úlooprt   Úexecution_id)Úget_executionÚlast_statusÚ
last_errorÚdelivery_failedr¬   ÚstatusÚ	completedzexecution ended in Úunknownz statez-Failed to execute cron job %s immediately: %s)Úexpected_fire_owner>   ÚokÚdelivery_queued)$Úobjectr   Úset_running_or_notify_cancelrB   rå   ræ   rç   Ú_ALREADY_RUNNING_ERRORÚ
set_resultrP   r¹   r1   r2   rš   r›   rœ   r�   ÚhasattrÚhermes_constantsrî   rï   rí   r�   rõ   rö   râ   r   Úcron.executionsrú   ÚboolrC   rº   r�   r»   r¼   r   )rG   rt   r³   Ú_registeredÚ
fire_ownerÚregistration_ownerÚrunning_futurerå   ræ   rç   Úclaimr¡   Úrunnerrì   rî   rï   Úprofilerõ   rö   Úgateway_loopÚ	processedr¨   Ú	executionrù   rú   rû   Ú	run_errorr  r¿   s   &&                           r4   rÃ   rÃ   C  s™  € ð ��Y€FØ€KØ€Jä›ÐÜ“X€NØ×/Ñ/Ô1ðR(ß]Ñ]ñ (Ø°^÷
ó 
ð ˜t Y°°wÔ@VÐW÷H Ù ÕAØ×!Ñ! $Õ'ðK ˆà—‘˜Ó%ˆÜ3=¸eÄT×3JÒ3J”S˜Ÿ™ 4›×.Ð.¨BÔ/ÐPTˆ
ô œSŸ[™[Ÿ_™_¨]Ó;Ð=RÐTXÓYˆ
ô
 "*¨*×!5Ò!5‘”¸4ˆØ8>Ò8J”7˜6 :¨tÔ4ÐPTˆð
 Ò¤'¨&Ð2I×"JÒ"JßOá+©OÓ,=Ó>ˆGØ×3Ñ3°GÓ<ˆHô �vÐ9Ñ;KÔLÈW×UÒU÷Sñ /¨xÑ9aÓ9cÓd�ØAGÒAS”w˜v ¸Ô=ÐY]ˆð	Bô  ¤ C§G¡G¨F£O×$=Ð$=°vÓ >×?Õ?Ù'¨À\Ð`lÔm�	÷ @ð  ˆKÙ ÕAÜ˜F“O×)Ð) rˆ	Øˆ	Ø—w‘w˜~Ó.ˆßÝ5á%¤c¨,Ó&7Ó8ˆIØ—m‘m MÓ2ˆð —M‘M ,Ó/ˆ	ØÐ+Ô+·IØ!Ÿ™Ð&;Ó<ˆIð Ð5Ñ5ˆØÒ  Y§]¡]°8Ó%<ÀÔ%KØˆBØ!Ÿ™ gÓ.×tÐtÐ4GÈ	ÏÉÐV^ÓH_×HlÐHlÐclÐGmÐmsÐ2tˆIØ˜4 ¬D°×1AÐ1A¸rÓ,BÀGÈYÐW÷ Ù ÕAØ×!Ñ! $Õ'÷G @×?Ð?ûð  ˆKÙ ÖAûô, ô DÜ�‰ÐDÀfÈaÔPÜ× Ò ¤×+Õ+Ü˜ ¬¨A«ÀJÕO÷ ,×+×+Ð+úà˜4 ¨E°7¼CÀ»FÐCÔC÷ Ù ÕAØ×!Ñ! $Õ'ûðDû÷ Ù ÕAØ×!Ñ! $Õ'ús±   ³%L8 Á;AL8 ÃCL8 Æ!!L( ÇL( ÇLÇ"L( Ç*L8 ÈL8 È%AL8 É-A	L8 Ê7L8 ËL8 Ë(	L8 ÌL%	Ì	L( Ì(L5Ì5L8 Ì8O.Í9O)Í<NÎ	O)ÎN.Î)O)ÏO.ÏO1 Ï)O.Ï.O1 Ï1$Pc                ót   € V ^8„  d   QhR\         R\        \         ,          R\        \         \        3,          /# )r-   Újob_refrt   r/   )r2   r   r1   r   )r3   s   "r4   r5   r5   £  s0   € ÷ <ñ <Üð<Ü (¬¥ð<ä	Œ#Œsˆ(…^ñ<r6   c           	     ó¤   €  \        V 4      pTf   RRRRRRT  R2/# \        Y!R7      #   \         d   pRRRRR\        T4      /u Rp?# Rp?ii ; i)	a¯  Fire an existing cron job in response to an external event.

Public entry point for event-driven triggers (the webhook adapter's
``cron_job`` routes). Resolves ``job_ref`` (ID or name) and
fires it through the exact same claimed-run body a manual
``cronjob(action='run')`` uses, so at-most-once claiming, in-flight
dedupe, delivery, and ``[SILENT]`` handling stay identical across the
scheduler / manual / event paths.

``extra_prompt`` is injected as transient per-run context (the job's
stored prompt is never mutated), exactly like ``action='run'`` with a
``prompt`` argument.

Returns the ``_execute_job_now`` result shape:
``{"claimed": bool, "success": bool, "error": str|None}``.
r¸   Fr~   r�   Nú
Cron job 'z' not found.r™   )r   r   r2   rÄ   )r  rt   rG   r¿   s   &&  r4   Úexecute_job_for_eventr  £  ss   € ð&EÜ˜gÓ&ˆð ‚{à�uØ�uØ�z ' ¨,Ð7ð
ð 	
ô
 ˜CÔ;Ð;øô !ô EØ˜5 )¨U°G¼SÀ»VÐDÕDûðEús   ‚) ©A´A
ÁAÁ
Ac                óR   € V ^8„  d   QhR\         R\        R\        \         ,          /# )r-   r³   Ú	max_charsr/   )r2   rk   r   )r3   s   "r4   r5   r5   Ã  s%   € ÷ ñ ¤sð ´sð ÄhÌsÅmñ r6   c                óN  €  ^ RI Hp V! 4       V ,          p\        VP                  R4      4      pV'       g   R# VR	,          P	                  RRR7      P                  4       pV'       g   R# \        V4      V8”  d   VRV RVR	,           R2,           pV#   \         d     R# i ; i)
z‰Excerpt of the job's most recent saved output file for the background completion
block (parent sees what the job produced). Never raises.)Úget_cron_output_dirz*.mdNz	utf-8-sigÚreplace)ÚencodingÚerrorsu   
â€¦ (truncated; full output: r¯   éÿÿÿÿ)Ú	cron.jobsr  r    ÚglobÚ	read_textrj   ÚlenrC   )r³   r  r  Úout_dirÚfilesÚtexts   &&    r4   Ú_latest_job_output_excerptr+  Ã  s›   € ðÝ1á%Ó'¨&Õ0ˆÜ�w—|‘| FÓ+Ó,ˆßÙØ�R�y×"Ñ"¨KÀ	Ð"ÓJ×PÑPÓRˆßÙÜˆt‹9�yÔ Ø˜
˜Ð#Ð(GÈÈbÍ	À{ÐRSÐ&TÕTˆDØˆøÜô Úðús   ‚6B º0B Á,(B ÂB$Â#B$c                ó(   € V ^8„  d   QhR\         RR/# )r-   rÆ   r/   NrW   )r3   s   "r4   r5   r5   ×  s   € ÷ Fñ F¤Sð F¨Tñ Fr6   c                óÀ   €  ^ RI Hp V! 4       pV'       d   \        P                  RW 4       R# R#   \         d"   p\        P                  RT4        Rp?R# Rp?ii ; i)a2  Reap execution rows left 'claimed'/'running' by a provably-dead owner (e.g. a prior
one-shot `hermes cron run` that died mid-run). The ticker does this at startup; one-shot
invocations have no such moment, so a stale claim would block every later manual run.
Best-effort self-heal: must not block dispatch.)Úrecover_interrupted_executionszSReclaimed %d stale cron execution(s) from dead owner(s) before dispatching job '%s'z"Stale execution reclaim failed: %sN)r
  r.  rº   rÒ   rC   Údebug)rÆ   r.  Ú
_reclaimedÚ	_reap_excs   &   r4   Ú_reap_stale_executionsr2  ×  sV   € ð
Fõ 	CÙ3Ó5ˆ
ßÜ�N‰NØeØö&ñ øô ô FÜ�‰Ð9¸9×EÒEûðFús   ‚1 —1 ±A¼AÁAc                óF   € V ^8„  d   QhR\         \        ,          R\        /# )r-   Ú
session_idr/   )r   r2   )r3   s   "r4   r5   r5   ì  s"   € ÷ Bñ B¬´­ð B¼#ñ Br6   c                ó†   €  ^ RI Hp V! RR7      pT;'       g    V '       d   \        V 4      # R#   \         d    Rp L.i ; i)z†Routing key for a detached completion, captured on THIS thread (contextvars don't
cross the pool). Empty string = no durable consumer.)Úget_current_session_keyrZ   ra   )Útools.approval_contextr6  rC   r2   )r4  r6  Úsession_keys   &  r4   Ú_background_session_keyr9  ì  sE   € ðÝBÙ-°bÔ9ˆð ×AÐA¯jœ3˜z›?ÐA¸bÐAøô ô ØŠðús   ‚0 °A ¿A c                ó¤   € V ^8„  d   QhR\         \        \        3,          R\        R\        R\        R\        R\         \        \        3,          /# )r-   Úresr³   rÆ   r§   Ú
started_atr/   )r1   r2   r   Úfloat)r3   s   "r4   r5   r5   ú  sP   € ÷ ñ Ü	Œc”3ˆh�ðÜ!$ðÜ03ðÜ>AðÜOTðÜY]Ô^aÔcfÐ^fÕYgñr6   c           
     óx  € \        \        P                  ! 4       V,
          ^4      p\        V4      ;'       g    / pRV RV R2RV P                  R4      '       d   RMR 2V P                  R4      '       d   R	V P                  R4       2MR
,           RV 2\	        W64      ,           .pVP                  R4      '       d   VP                  RVR,           24       \        V4      pV'       d   VRV.,          pRV P                  R4      '       d   RMRRRP                  V4      RV P                  R4      R^ RV/# )zGAsync-delegation completion block for a finished background manual run.r  rÌ   z) finished its manual run.zResult: r~   r  ÚFAILEDr�   u    â€” rZ   zDelivery target: Únext_run_atzNext scheduled run: z--- JOB OUTPUT ---rþ   rÿ   ÚsummaryÚ
Ú	api_callsÚduration_seconds)ÚroundrÍ   r   rP   r±   Úappendr+  rŸ   )	r;  r³   rÆ   r§   r<  Údurationr¨   ÚlinesÚexcerpts	   &&&&&    r4   Ú_manual_run_completionrJ  ú  s,  € ô ”T—Y’Y“[ :Õ-¨qÓ1€HÜ˜“×%Ð% 2€Ià
�X�J˜c & Ð)CÐDØ
˜3Ÿ7™7 9×-Ò-‘4°8Ð<Ð=Ø),¯©°×)9Ò)9ˆU�3—7‘7˜7Ó#Ð$Ñ%¸rõ	Cà
˜G˜9Ð%Ô(AÀ'Ó(UÕUð	€Eð ‡}�}�]×#Ò#Ø�‰Ð+¨I°mÕ,DÐ+EÐFÔGÜ(¨Ó0€GßØÐ&¨Ð0Õ0ˆà §¡¨×!3Ò!3‘+¸À)ÈTÏYÉYÐW\ÓM]Ø�—‘˜Ó! ;°Ð3EÀxðð r6   c                óÎ   € V ^8„  d   QhR\         \        \        3,          R\        \        ,          R\        \        ,          R\        \         \        \        3,          ,          /# )r-   rG   r4  rt   r/   ru   )r3   s   "r4   r5   r5     sP   € ÷ bñ bÜ	Œc”3ˆh�ðbÜ%-¬c¥]ðbÜIQÔRUÍðbäŒd”3œ�8�nÕñbr6   c                óÂ  aaaaaa€ V R,          o\        V P                  R4      ;'       g    S4      o\        S4        ^ RIHp V! 4       '       g   R#  \        V4      pV'       g   R#  ^ RIHp V! S4      '       d   RRRRR	\        /#  \        SR
4      w  opVe   VR,          '       d   RVR&   V# Rp ^ RIHp V! RR4      ;'       g    Rp ^ RIHp	Hp
 V	! 4       p ^ RIHp T! 4       p\(        P(                  ! 4       o^ RIHp T! SP                  RR4      4      oR TTTTTT3R llpT
! RS RS R2RRRT P                  R4      TT'       d   \        T4      MRTY{TR7      pTP                  R4      R8X  d   RR RR R!TP                  R!4      /# \        P-                  R"TP                  R	R#4      S4       \#        T SR7      pRTR&   T#   \
         d     ELŒi ; i  \
         d     ELgi ; i  \
         d     EL4i ; i  \
         d6   p\        P!                  RTS4       \#        SSR7      pRTR&   Tu Rp?# Rp?ii ; i  \
         d    ^p ELmi ; i)$ak  Claim ``job`` now (SYNCHRONOUSLY, so unrunnable jobs report immediately), then fire it
on the async-delegation executor like ``delegate_task``'s background mode: the tool returns
a handle and a ``type="async_delegation"`` completion re-enters as a fresh turn (role
alternation legal, prompt cache intact) instead of blocking the parent turn for minutes.
Returns None when background delivery is unavailable (caller runs sync); ``{"claimed":
False}`` on a lost claim; ``{"claimed": True, "dispatched": True, "delegation_id"}``; or
``{"claimed": True, "dispatched": False, ...}`` when the pool was full and it ran inline.ry   rÛ   )Úasync_delivery_supportedN)Úis_job_runningr¸   Fr~   r�   zbackground runÚ
dispatchedrZ   ©Úget_session_envÚHERMES_UI_SESSION_ID)Ú_current_origin_session_idÚdispatch_async_delegationzQcronjob run: async delegation registry unavailable (%s); running job '%s' inline.r™   )Ú_get_max_async_children)Ú_normalize_deliver_valuer§   r«   c                óF   € V ^8„  d   QhR\         \        \        3,          /# rV   r0   )r3   s   "r4   r5   Ú2_try_dispatch_background_run.<locals>.__annotate__]  s   € ÷ Rñ R”Tœ#œs˜(•^ñ Rr6   c                  ó<   <€ \        SSR 7      p \        V SSSS4      # )r™   )rÃ   rJ  )r;  r½   r§   rt   r³   rÆ   r<  s    €€€€€€r4   Ú_runnerÚ-_try_dispatch_background_run.<locals>._runner]  s"   ø€ Ü˜{¸ÔFˆÜ% c¨6°8¸WÀjÓQÐQr6   zManual run of cron job 'rÌ   r¯   ztTriggered via cronjob(action='run'). The job executed in its own fresh cron session; this block reports its outcome.Úcron_runÚmodel)ÚgoalÚcontextÚtoolsetsÚroler]  r8  Úparent_session_idr  Úorigin_ui_session_idÚorigin_session_idÚmax_async_childrenrþ   TÚdelegation_idzGcronjob run: background pool unavailable (%s); running job '%s' inline.Úrejected)r2   rP   r2  Úgateway.session_contextrM  rC   r9  rB   rN  r  rÀ   rQ  Útools.async_delegationrS  rT  rº   rÒ   rÃ   Útools.delegate_toolrU  rÍ   rV  Úinfo)rG   r4  rt   rM  r8  rN  r°   rc  rQ  rS  rT  rd  r¿   ÚresultrU  Ú	max_asyncrV  rZ  Údispatchr½   r§   r³   rÆ   r<  s   &&f                @@@@@r4   Ú_try_dispatch_background_runro    s{  ý€ ð ��Y€FÜ�3—7‘7˜6“?×,Ð, fÓ-€Hô ˜8Ô$ðÝDÙ'×)Ò)Ùð *ô *¨*Ó5€K÷ Ùð
Ý1Ù˜&×!Ò!Ø˜u i°¸ÔAWÐXÐXð "ô
 -¨VÐ5EÓFÑ€K�Ø
‚Øˆy�>Œ>Ø %ˆC�ÑØˆ
àÐðÝ;Ù.Ð/EÀrÓJ×PÐPÈbÐðß`Ù6Ó8ÐðÝ?Ù+Ó-ˆ	ô —’“€Jå7Ù& {§¡°yÀ'Ó'JÓK€G÷Rõ Rñ )Ø'¨ z°°V°H¸AÐ>ðGà˜J¨c¯g©g°gÓ.>ÈKß-7œ#˜jœ/¸TÈ'Ø1Ø$ô&€Hð ‡|�|�HÓ Ô-Ø˜4 ¨t°_ÀhÇlÁlÐSbÓFcÐdÐdô ‡K�KØQØ�‰�W˜jÓ)¨8ô5ô ˜c°Ô=€FØ €Fˆ<ÑØ€Møô[ ô Úðûô& ô Úðûô ô Úðûô ô Ü�‰Ø_ÐabÐdlô	nä! +¸LÔIˆØ$ˆˆ|ÑØ�ûðûô ô Ø‹	ðúsr   Á G Á,G& Â G& Â9G8 ÃG8 ÃH
 Ã#I ÇG#Ç"G#Ç&G5Ç4G5Ç8HÈHÈ
I
È*IÈ?I
ÉI
ÉIÉIc          
      óÄ   € V ^8„  d   QhR\         \        \        3,          R\         \        \        3,          R\        \        ,          R\         \        \        3,          /# )r-   rl  rG   r§   r/   ru   )r3   s   "r4   r5   r5   z  sJ   € ÷ ñ œ4¤¤S �>ð ´´S¼#°Xµð ÌÔRUÍð Ô[_Ô`cÔehÐ`hÕ[iñ r6   c                ó4   € \        W4      pV'       d   W0R&   V # )zFAttach mode/delivery guidance (create and update echo the same notes).Úguidance)r   )rl  rG   r§   Ú_notess   &&& r4   Ú_with_guidancert  z  s   € ä! #Ó/€FßØ#ˆzÑØ€Mr6   c                óR   € V ^8„  d   QhR\         \        \        3,          R\        /# ©r-   Úar/   r0   )r3   s   "r4   r5   r5   ‚  s&   € ÷ K9ñ K9”dœ3¤˜8•nð K9¬ñ K9r6   c                 óü  € V R ,          V R,          r!\        V R,          4      pV R,          '       g   \        RRR7      # \        V R,          V R,          4      p\        V R	,          4      pV'       d   V'       g   \        R
RR7      # MV'       g   V'       g   \        RRR7      # T;'       d    \	        V4      ;'       gë    T;'       d    \        V4      ;'       gÎ    V R,          ;'       d    \        V R,          4      ;'       g£    \        V R,          V R,          4      ;'       g�    \        V4      ;'       gn    \        \        V R,          4      4      ;'       gK    V R,          ;'       d:    \        \        V R,          \        4      '       d   V R,          .MV R,          4      pV'       d   \        VRR7      # V R,          pV R,          e   \        WpR,          4      p^ RIHpHp	  T	! R2/ R T;'       g    RbRV R,          bRV R,          bRV R,          bR\        V4      bR\!        V R,          4      bRVbR\#        V R,          4      bR\#        V R,          4      bR\#        V R,          RR7      bR\#        V4      bRVbRV R,          e
   V R,          MRbR\#        V R,          4      bR	VbRV R,          bR\#        V R,          4      bR\#        V R,          4      bRV R,          bR V R ,          bR!\        V R!,          4      bR\        \        V R,          4      4      bV R",          RJg   V R#,          e   R"V R",          R#V R#,          /M/ B p
R&P)                  \+        RR'T
R,           R(2T
P-                  R)R4      '       g   R*MR\/        Y£4      34      4      pR%RR+T
R,,          RT
R,          RT
P-                  R4      RT
P-                  R. 4      RT
R-,          R\1        T
4      RT
P-                  RR.4      R/T
R/,          R0\3        T
4      R1T/\5        4       Cp\7        \9        YêT4      4      #   T d8   pTP%                  4       p\        TP'                  R$4      3R%R/TB u Rp?# Rp?ii ; i)3r{   Úscriptr§   Úschedulezschedule is required for createF©r~   ÚskillÚskillsÚno_agentu  create with no_agent=True requires a script â€” the script is the job. In no_agent mode the LLM is skipped entirely: prompt and skills are ignored, non-empty stdout is delivered verbatim, empty stdout sends nothing (watchdog pattern), and a non-zero exit or timeout sends an error alert.z3create requires either prompt or at least one skillÚmonitor_scriptÚproviderÚbase_urlÚfailure_deliverÚcontext_fromÚ
continuityN)ÚCronSchedulerRegistrationErrorÚ&create_job_with_scheduler_registrationrZ   rÛ   ÚrepeatÚoriginr]  T©Ústrip_trailing_slashÚenabled_toolsetsÚworkdirÚattach_to_sessionÚmonitor_urlÚreasoning_effortÚinterpreterÚpinnedÚpausedÚpaused_reasonr�   r~   Ú r  z
' created.Úenabledu=   Created PAUSED â€” resume to schedule, or explicitly run now.r³   ry   Úschedule_displayr«   r@  rG   Úmessager>   )r    r+   r   r  r   r)   r(   r&   r'   r¹   r2   r   rB   r…  r†  r$   r"   r!   Úto_dictÚpoprŸ   ÚfilterrP   r   r#   r   r   r;   rt  )rw  r{   ry  r§   Úcanonical_skillsÚ	_no_agentr�   rƒ  r…  r†  rG   ÚexcÚ_partialÚ_create_messageÚ_results   &              r4   Ú_action_creater¡  ‚  sÊ  € Ø�x•[ ! H¥+ˆFÜ& q¨¥|Ó4€GØˆZ�=Œ=ÜÐ;ÀUÔKÐKÜ(¨¨7­°Q°xµ[ÓAÐÜ�Q�z•]Ó#€IçßÜðið
 ôð ð ÷ ×,ÜÐOÐY^Ô_Ð_à	×	-Ð	-Ô% fÓ-÷ 	_ð 	_Ø×9Ð9Ô1°&Ó9÷	_ð 	_àÐÕ×SÐSÔ$>¸qÐAQÕ?RÓ$S÷	_ð 	_ô
 # 1 Z¥=°!°Jµ-Ó@÷	_ð 	_ô & gÓ.÷	_ð 	_ô &Ô&>¸qÐARÕ?SÓ&TÓU÷	_ð 	_ð ˆnÕ÷ ^ð ^Ô"=Ü#-¨a°Õ.?Ä×#EÒ#EˆQˆ~ÕÑÈ1È^ÕK\ó#^ð 
÷ Ü˜%¨Ô/Ð/à�^Õ$€LØˆ…Ò"Ü(¨¸µÓGˆçeðLÙ4ò WØ—<�<˜RøðWØ*+¨J®-ðWØ>?À¾iðWØPQÐRZÖP[ðWä1°'Ô:ðWô $ A j¥MÔ2ðWñ $ð	Wô
 0°°'µ
Ô;ðWô
 GdÐdeÐfpÕdqÔFrðWô 3°1°Zµ=ÐW[Õ\ðWô 1°Ô8ðWñ HTðWð 78Ð8JÕ6KÒ6W˜QÐ1Ö2Ð]aøðWô 2°!°Iµ,Ô?ðWñ ðWð 34Ð4GÖ2HðWô 9¸Ð;KÕ9LÔMðWô 6°a¸Õ6FÔGðWð Ð1Ö2ðWð ABÀ-Ö@PðWô  ˜˜(�Ô$ð!Wô" :Ô:RÐSTÐUfÕSgÓ:hÔià�H•+ UÓ*¨a°Õ.@Ò.Lð ˜!˜H�+ ¸¸/Õ8JÑKØRTñ'Wˆð. —h‘hœv d¨z¸#¸f½+¸ÀjÐ-QØORÏwÉwÐW`Ðbf×OgÒOgÑGÐmqÜ˜sÓ,ð-.ó  /ó 0€Oð 	�4˜ 3 t¥9¨f°c¸&µkÀ7ÈCÏGÉGÐT[ÓL\Ø�#—'‘'˜( BÓ'¨°SÐ9KÕ5LÈhÔXgÐhkÓXlØ�3—7‘7˜9 gÓ.°¸sÀ=Õ?QÐSXÔZeÐfiÓZjØ�?ð	ô '?Ó&@ð	€Gô ”. ¨wÓ7Ó8Ð8øð *ô LØ—;‘;“=ˆÜ˜(Ÿ,™, wÓ/ÑK¸ÐKÀ(ÑKÕKûðLús%   Ç2P= È EP= Ð=Q;Ñ,Q6Ñ0Q;Ñ6Q;c                óR   € V ^8„  d   QhR\         \        \        3,          R\        /# rv  r0   )r3   s   "r4   r5   r5   Ð  s"   € ÷ ñ ”Dœœc˜•Nð ¤sñ r6   c                 óà   € \        V R ,          R7       Uu. uF  p\        V4      NK  	  ppRRR\        V4      RV/pV'       d   VP                  \	        RR7      4       \        V4      # u upi )Úinclude_disabled)r¤  r~   TÚcountÚjobs)Úplural)r   r   r'  Úupdater   r;   )rw  rG   r¦  r   s   &   r4   Ú_action_listr©  Ð  se   € Ü(1À1ÐEWÕCXÕ(YÓZÑ(Y ŒK˜ÖÑ(Y€DÐZØ˜$ ¬¨T«°F¸DÐA€Gçð 	�‰Ô/°tÔ<Ô=Ü�'‹?Ðùò [s   –A+c                ó€   € V ^8„  d   QhR\         \        \        3,          R\         \        \        3,          R\        /# ©r-   rG   rw  r/   r0   )r3   s   "r4   r5   r5   Û  s1   € ÷ 	ñ 	œœS¤#˜X�ð 	¬4´´S°­>ð 	¼cñ 	r6   c                 óÜ   € V R ,          p\        V4      '       g   \        RV R2RR7      # \        4        \        RRRRV R	,           R
2RR VR	V R	,          RV P	                  R4      //4      # )ry   zFailed to remove job 'Ú'Fr{  r~   Tr—  r  rÛ   z
' removed.Úremoved_jobrz  r–  )r   r+   rD   r;   rP   )rG   rw  r³   s   && r4   Ú_action_remover¯  Û  s|   € Ø��Y€FÜ�f×ÒÜÐ2°6°(¸!Ð<ÀeÔLÐLÜ&Ô(ÜØ�4Ø�Z  F¥˜}¨JÐ7Ø˜˜f f¨c°&­k¸:ÀsÇwÁwÐOaÓGbÐcðó ð r6   c                óR   € V ^8„  d   QhR\         \        \        3,          R\        /# )r-   r¤   r/   r0   )r3   s   "r4   r5   r5   ç  s&   € ÷ Bñ Bœt¤C¬ H�~ð B´#ñ Br6   c                 óF   € \        4        \        R RR\        V 4      /4      # )r~   TrG   )rD   r;   r   )r¤   s   &r4   Ú_job_state_resultr²  ç  s!   € Ü&Ô(Ü�9˜d E¬;°wÓ+?Ð@ÓAÐAr6   c                óR   € V ^8„  d   QhR\         R\        \         \        3,          /# )r-   r³   r/   r©   )r3   s   "r4   r5   r5   ì  s"   € ÷ :ñ :¤ð :¬¬S´#¨X­ñ :r6   c                óB   € \        \        V 4      ;'       g    RV /4      # )zFRe-read so the response reflects the post-run last_run_at/last_status.ry   )r   r   )r³   s   &r4   Ú_refreshed_job_viewrµ  ì  s   € ä”w˜v“×8Ð8¨4°¨.Ó9Ð9r6   c                ó€   € V ^8„  d   QhR\         \        \        3,          R\         \        \        3,          R\        /# r«  r0   )r3   s   "r4   r5   r5   ñ  s1   € ÷ 64ñ 64”Tœ#œs˜(•^ð 64¬¬S´#¨X­ð 64¼3ñ 64r6   c                 ó   € V R ,          pVR,          ;'       g    RpV'       d!   \        V4      pV'       d   \        VRR7      # \        WR7      pVe   V# \        WR,          VR7      pVe\   VP	                  R4      '       dE   \        4        \        V4      pR	VR
&   RVR&   VP	                  R4      VR&   \        RR	RVRR/4      # Ve   TpM\        WR7      p	V	e   V	# \        WR7      pVP	                  RR4      p
V
'       d   \        4        \        V4      pW§R
&   VP	                  RR4      VR&   V
'       g    VP	                  R4      ;'       g    RVR&   M#VP	                  R4      '       d   VR,          VR&   \        RR	RV/4      # )ry   r{   NFr{  r™   r4  )r4  rt   rO  TÚexecutedÚ
backgroundÚexecution_moderf  r~   rG   r€   u¹   The job is running in the background. You and the user can keep working; its outcome re-enters the conversation as a new message when it finishes. Do not wait or poll â€” just continue.r¸   Úexecution_successr�   z4Already being fired by the scheduler; not run again.Úexecution_skippedÚexecution_error)
r   r+   r¥   ro  rP   rD   rµ  r;   rˆ   rÄ   )rG   rw  r³   rt   Ú
scan_errorÚ
handed_offÚbgrl  Úexec_resultÚ	forwardedr¸   s   &&         r4   Ú_action_runrÃ  ñ  s   € Ø��Y€Fð �X•;×&Ð& $€LçÜ& |Ó4ˆ
ßÜ˜j°%Ô8Ð8ä-¨cÔM€JØÒØÐô 
& c¸µoÐT`Ô	a€BØ	‚~˜"Ÿ&™& ×.Ò.Ü*Ô,Ü$ VÓ,ˆØ!ˆˆzÑØ#/ˆÐÑ Ø"$§&¡&¨Ó"9ˆˆÑÜØ�tØ�6Øð9ð	
ó ð 	ð 
‚~Ø‰ô /¨sÔNˆ	ØÒ ØÐÜ& sÔFˆð �o‰o˜i¨Ó/€GßÜ*Ô,Ü  Ó(€FØ ˆ:ÑØ"-§/¡/°)¸UÓ"C€FÐÑßØ&1§o¡o°gÓ&>÷ 'Dð 'DØBð 	Ð"Ò#à	�‰˜×	!Ò	!Ø$/°Õ$8ˆÐ Ñ!Ü�9˜d E¨6Ð2Ó3Ð3r6   c                óŒ   € V ^8„  d   QhR\         \        \        3,          R\         \        \        3,          R\        R\        /# )r-   ÚupdatesrG   r†   r/   r0   )r3   s   "r4   r5   r5   *  s8   € ÷ <ñ <”4œœS˜•>ð <¬¬S´#¨X­ð <¼Sð <ÄSñ <r6   c                ó@   € W 9   d	   W,          # VP                  V4      # )zVEffective value of ``key`` after this update: pending update wins over the stored job.)rP   )rÅ  rG   r†   s   &&&r4   Ú_pickrÇ  *  s   € àœ>ˆ7�<Ð;¨s¯w©w°s«|Ð;r6   c          	      óÄ   € V ^8„  d   QhR\         \        \        3,          R\         \        \        3,          R\         \        \        3,          R\        \        ,          /# ©r-   rG   rw  rÅ  r/   ru   )r3   s   "r4   r5   r5   /  sN   € ÷ 1eñ 1eœT¤#¤s (�^ð 1e´´S¼#°Xµð 1eÌÌcÔSVÈhÍð 1eÔ\dÔehÕ\iñ 1er6   c                óì  € VR,          VR,          VR,          VR,          3w  r4rVVe   \        V4      pV'       d   V# W2R&   VR,          e*   VR,          P                  4       '       d   VR,          VR&   Ve6   \        \        V4      4      pV'       d   V# \	        \        V4      4      VR&   VR,          e?   \        VR,          4      p	V	'       d!   \        V	4      pV'       d   V# \	        V	4      p	W’R&   Vf   Ve&   \        WV4      p
W¢R&   V
'       d
   V
^ ,          MRVR&   VR,          e   \        VR,          4      VR&   VR	,          e   \        VR	,          4      VR	&   VR
,          e   \        VR
,          4      VR
&   VR,          e   \        VR,          RR7      VR&   VR,          e   VR,          VR&   VR,          e   VR,          VR&   \        \        W R	4      \        W R4      4      # )zOprompt / name / deliver / skills / model pins; returns an error string or None.r{   r§   r|  r}  NrÛ   r‚  r]  r€  r‘  r�  Tr‰  r�  r�  )
r   rj   r&   r    r$   r   r!   r  r(   rÇ  )rG   rw  rÅ  r{   r§   r|  r}  r¾  Úbot_chat_errorÚ_norm_fdr›  s   &&&        r4   Ú_update_core_fieldsrÍ  /  sé  € à%& x¥[°!°Iµ,ÀÀ'Å
ÈAÈhÍKÐ%WÑ"€F�UØÒÜ& vÓ.ˆ
ßØÐØ"�ÑØˆ…yÒ  6¥§¡×!2Ò!2ð ˜F�)ˆ�‰ØÒÜ3Ô4LÈWÓ4UÓVˆßØ!Ð!Ü:Ô;SÐT[Ó;\Ó]ˆ�	ÑØÐ	ÕÒ'ô ,¨AÐ.?Õ,@ÓAˆßÜ7¸ÓAˆNßØ%Ð%Ü4°XÓ>ˆHØ%-Ð!Ñ"ØÒ˜UÒ.Ü,¨UÓ;ÐØ,�Ñß2BÐ+¨AÖ.Èˆ�ÑØˆ…zÒÜ8¸¸7½ÓDˆ�ÑØˆ…}Ò Ü;¸A¸j½MÓJˆ�
ÑØˆ…{ÒÜ   8¥Ó-ˆ�ÑØˆ…}Ò Ü;¸A¸j½MÐ`dÔeˆ�
ÑØÐ	ÕÒ(à&'Ð(:Õ&;ˆÐ"Ñ#ØˆÕÒ#à!" =Õ!1ˆ�Ñô #¤5¨°zÓ#BÄEÈ'ÐXbÓDcÓdÐdr6   c          	      óÄ   € V ^8„  d   QhR\         \        \        3,          R\         \        \        3,          R\         \        \        3,          R\        \        ,          /# rÉ  ru   )r3   s   "r4   r5   r5   c  sJ   € ÷ ñ œt¤C¬ H�~ð ´$´s¼C°xµ.ð Ì4ÔPSÔUXÐPXÍ>ð Ô^fÔgjÕ^kñ r6   c                ód  € VR,          VR,          rCRVR,          3RV33 FA  w  rVVf   K  V'       d   \        V4      pV'       d   Vu # V'       d   \        V4      MRW%&   KC  	  Ve   V'       d   \        V4      MRVR&   Vf   Ve'   \        W R4      '       d   \        W R4      '       d   R# R# )z]script / monitor_script / monitor_url (empty string clears); returns an error string or None.r  rŽ  ry  Nu]   monitor_script and monitor_url are mutually exclusive â€” clear one before setting the other.)r)   r!   rÇ  )rG   rw  rÅ  r  rŽ  Úfieldr�   Ú
path_errors   &&&     r4   Ú_update_script_fieldsrÒ  c  s«   € à"#Ð$4Õ"5°q¸Õ7G�KØ" A h¥KÐ0Ð3CÀ^Ð2TÓU‰ˆØÔßÜ7¸Ó>�
ßØ%Ò%ßEJÔ:¸5ÔAÐPTˆG‹Nñ Vð ÒßOZÔ!>¸{Ô!KÐ`dˆ�ÑØÒ" kÒ&=ÜˆgÐ,×-Ò-´%¸Àm×2TÒ2TÙnÙr6   c          	      óÄ   € V ^8„  d   QhR\         \        \        3,          R\         \        \        3,          R\         \        \        3,          R\        \        ,          /# rÉ  ru   )r3   s   "r4   r5   r5   u  sH   € ÷ ñ œd¤3¬ 8�nð ´´c¼3°hµð Ì$ÌsÔTWÈxÍ.ð Ô]eÔfiÕ]jñ r6   c                ó,  € VR,          VR,          rCVf   Vf   R# Vf%   \        V P                  R4      ;'       g    . 4      p\        V4      pVe   \        WT4      ;'       g    . pV'       d   \	        V4      pV'       d   V# T;'       g    RVR&   R# )zˆcontext_from / continuity: empty string / list clears; otherwise every ref must
exist. Stored as a list (or None) to match create_job().rƒ  r„  N)ÚlistrP   r   r   r'   )rG   rw  rÅ  rƒ  r„  ÚrefsÚ	ref_errors   &&&    r4   Ú_update_context_fromrØ  u  sŽ   € ð  ! Õ0°!°Lµ/�*ØÒ 
Ò 2ÙØÒÜ˜CŸG™G NÓ3×9Ð9°rÓ:ˆÜ˜<Ó(€DØÒÜ  Ó2×8Ð8°bˆßÜ/°Ó5ˆ	ßØÐØ"Ÿl˜l d€GˆNÑÙr6   c          	      óÄ   € V ^8„  d   QhR\         \        \        3,          R\         \        \        3,          R\         \        \        3,          R\        \        ,          /# rÉ  ru   )r3   s   "r4   r5   r5   ˆ  sH   € ÷ ñ œD¤¤c �Nð ¬t´C¼°H­~ð ÌÌSÔRUÈXÍð Ô[cÔdgÕ[hñ r6   c                ó”  € VR,          e   VR,          VR&   VR,          e   \        VR,          4      VR&   VR,          e    \        VR,          4      ;'       g    RVR&   VR,          e4   \        VR,          4      pV'       d   \        W R4      '       g    R# W2R&   VR,          eA   ^ R	IHp \        V P                  R4      ;'       g    / 4      pV! VR,          4      VR
&   WRR&   VR,          eS   \        VR,          4      pWbR&   VP                  RVR,          4      VR&   V P                  R4      R8w  d   RVR&   RVR&   R# )zNenabled_toolsets / attach_to_session / workdir / no_agent / repeat / schedule.r‹  Nr�  rŒ  r~  ry  ziCannot set no_agent=True on a job without a script. Set `script` in the same update, or on the job first.r‡  )Únormalize_repeat_valueÚtimesrz  Údisplayr–  Ústater’  Ú	scheduledTr•  )r  r!   rÇ  r$  rÛ  r1   rP   r   )rG   rw  rÅ  Útarget_no_agentrÛ  Úrepeat_stateÚparsed_schedules   &&&    r4   Ú_update_run_fieldsrã  ˆ  sJ  € àÐ	ÕÒ(à&'Ð(:Õ&;ˆÐ"Ñ#ØÐ	ÕÒ)Ü'+¨AÐ.AÕ,BÓ'CˆÐ#Ñ$Øˆ…|Òä:¸1¸Y½<ÓH×PÐPÈDˆ�	ÑØˆ…}Ò ä˜q �}Ó-ˆß¤5¨°x×#@Ò#@ðHñIð .�
ÑØˆ…{Òå4Ü˜CŸG™G HÓ-×3Ð3°Ó4ˆÙ 6°q¸µ{Ó Cˆ�WÑØ(�ÑØˆ…}Ò Ü(¨¨:­Ó7ˆØ-�
ÑØ&5×&9Ñ&9¸)ÀQÀzÅ]Ó&SˆÐ"Ñ#Ø�7‰7�7Ó˜xÔ'Ø*ˆG�GÑØ!%ˆG�IÑÙr6   c                ó€   € V ^8„  d   QhR\         \        \        3,          R\         \        \        3,          R\        /# r«  r0   )r3   s   "r4   r5   r5   ®  s6   € ÷ jñ jœœS¤#˜X�ð j¬4´´S°­>ð j¼cñ jr6   c           
      ó*  € / p\          F#  pV! WV4      pV'       g   K  \        VR R7      u # 	  V'       g   \        RR R7      # \        V R,          V4      p\        4        \	        \        RRR\        V4      /V\        VR,          4      4      4      # )Fr{  zNo updates provided.ry   r~   TrG   r§   )Ú_UPDATE_STEPSr+   r   rD   r;   rt  r   r    )rG   rw  rÅ  Ústepr�   r¤   s   &&    r4   Ú_action_updaterè  ®  s‘   € Ø €GßˆÙ�S˜WÓ%ˆß‰5Ü˜e¨UÔ3Ò3ñ ÷ ÜÐ0¸%Ô@Ð@Ü˜˜T� GÓ,€GÜ&Ô(ä”.Ø	�D˜%¤¨WÓ!5Ð6¸ÔAYÐZ[Ð\eÕZfÓAgóió jð jr6   ÚcreaterÕ  Úremover¨  ÚrunÚrun_nowÚtriggerÚpausec                 óJ   € \        \        V R ,          VR,          R7      4      # )ry   r¾   )r¾   )r²  r   ©rG   rw  s   &&r4   ró   ró   Á  s   € Ô-¬i¸¸D½	È!ÈHÍ+Ô.VÔWr6   Úresumec                 ó8   € \        \        V R ,          4      4      # )ry   )r²  r   rð  s   &&r4   ró   ró   Â  s   € Ô.¬z¸#¸d½)Ó/DÔEr6   c                ó$   € V ^8„  d   QhR\         /# )r-   r³   rW   )r3   s   "r4   r5   r5   Æ  s   € ÷ ñ ¤#ñ r6   c                ó|  €  \        V 4      pT'       g   R\        RRRRT  R2/4      3# TR3#   \         dƒ   pR\        RRR\        T4      RTP                   Uu. uFA  pRTR,          RTP                  R4      RTP                  R	4      R
TP                  R
4      /NKC  	  Mu upi up/4      3u Rp?# Rp?ii ; i)zF``(job, None)`` or ``(None, json_error)`` for a job_id/name reference.Nr~   Fr�   Úmatchesry   rÛ   rz  r–  r@  zJob with ID or name 'z8' not found. Use cronjob(action='list') to inspect jobs.)r   r   r;   r2   rõ  rP   )r³   rG   r�  Úms   &   r4   Ú_resolve_job_or_errorr÷  Æ  sî   € ð
Ü˜fÓ%ˆ÷ Ø”VØ˜˜wÐ*?À¸xÐGð  )Að  Bó
ð 
ð 	
ð �ˆ9Ðøô !ô Ø”VØ�uØ”S˜“XØàŸšóá$�Að �q˜•w ¨¯©¨f«°zÀ1Ç5Á5ÐI[ÓC\Ð^kÐmn×mrÑmrð  tAó  nBó  CÚ$ùôð
ó ð õ 	ûðús'   ‚. ®B;¹"B6ÁAB#Â"B6Â0B;Â6B;Fc          @      ó|  € V ^8„  d   Qh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,          R\        \         ,          R\        R\        \         ,          R\        \        ,          R \        \         ,          R!\         / # )"r-   Úactionr³   r{   rz  rÛ   r‡  r§   r¤  r|  r}  r]  r€  r�  r¾   ry  rƒ  r„  r‹  rŒ  r~  r�  r  rŽ  r�  r‚  Útask_idNr4  r’  r“  r‘  r�  r/   )r2   r   rk   r  rÕ  )r3   s   "r4   r5   r5   Ú  sÔ  € ÷ 41ñ 41Üð41ä”S�Mð41ô ”S�Mð41ô ”s�mð	41ô
 ”3�-ð41ô ”S�Mð41ô ”c�]ð41ô ð41ô ”C�=ð41ô ”Tœ#•YÕð41ô ”C�=ð41ô ”s�mð41ô ”s�mð41ô ”S�Mð41ô ”S�Mð41ô  œ3¤¤c¥�?Õ+ð!41ô" œ•ð#41ô$ œt¤C�yÕ)ð%41ô& ”c�]ð'41ô( ”t�nð)41ô*  ¤•~ð+41ô, œS•Mð-41ô. œ#•ð/41ô0 œs•mð141ô2 œc¤D¬¥I�oÕ.ð341ô4 �4�Zð541ô6 œ•ð741ô8 ð941ô: œC•=ð;41ô< ”T�Nð=41ô> œ#•ð?41ô> +.ñ?41r6   c                óÞ  € \        \        4       4      pVR  T ;'       g    RP                  4       P                  4       p \        P                  V 4      p!V!e	   V!! V4      # V'       g   \        RV  R2RR7      # \        V4      w  p"p#V#e   V## \        P                  V 4      p!V!f   \        RV  R2RR7      # V!! V"V4      #   \         d!   p$\        \        T$4      RR7      u Rp$?$# Rp$?$ii ; i)	z!Unified cron job management tool.rú  rZ   Nzjob_id is required for action 'r­  Fr{  zUnknown cron action ')r1   Úlocalsrj   ÚlowerÚ_JOBLESS_ACTIONSrP   r+   r÷  Ú_JOB_ACTIONSrC   r2   )%rù  r³   r{   rz  rÛ   r‡  r§   r¤  r|  r}  r]  r€  r�  r¾   ry  rƒ  r„  r‹  rŒ  r~  r�  r  rŽ  r�  r‚  rú  r4  r’  r“  r‘  r�  rw  Ú
normalizedÚhandlerrG   r�   r¿   s%   &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&      r4   Úcronjobr  Ú  sè   € ôB 	ŒV‹X‹€AØ	ˆ)ˆð1Ø—l�l ×)Ñ)Ó+×1Ñ1Ó3ˆ
Ü"×&Ñ& zÓ2ˆØÒÙ˜1“:ÐßÜÐ ?À
¸|È1ÐMÐW\Ô]Ð]ô +¨6Ó2‰
ˆˆUØÒØˆLÜ×"Ñ" :Ó.ˆØŠ?ÜÐ 5°f°X¸QÐ?ÈÔOÐOÙ�s˜A‹ÐøÜô 1Üœ#˜a›&¨%Ô0Õ0ûð1ús@   ˜C ¡?C Á!C Á)C Á:C Â)C Â8C ÃC,ÃC'Ã!C,Ã'C,c                ó0   € V ^8„  d   QhR\         R\         /# )r-   Úhomer/   rW   )r3   s   "r4   r5   r5     s   € ÷ %ñ %œcð %¤cñ %r6   c                 ó   € R V  R2# )zžOptional script run each tick; stdout is injected into the agent's prompt as context (with no_agent=True the script IS the job). Relative paths resolve under zA/scripts/; .sh/.bash via bash, else Python. On update, '' clears.r>   )r  s   &r4   Ú_script_descriptionr    s   € ðDØDHÀ6ð J$ð$ð %r6   c                ó$   € V ^8„  d   QhR\         /# rV   )r1   )r3   s   "r4   r5   r5     s   € ÷ "ñ "¤4ñ "r6   c                 ó”   € \         P                  ! \        R,          4      p \        \	        4       4      V R,          R,          R&   RV /# )a  Rebuild the ``script`` path hint from the ACTIVE profile at every get_definitions(): the
static schema is built once per process, but the multiplexed gateway serves every profile from
that process, so a path baked in at import would name the launch profile's home (#95685).Ú
parametersÚ
propertiesry  Údescription)ÚcopyÚdeepcopyÚCRONJOB_SCHEMAr  r	   )Úparamss    r4   Ú_cronjob_schema_overridesr    s?   € ô �]Š]œ>¨,Õ7Ó8€FÜ4GÔH[ÓH]Ó4^€Fˆ<Õ˜Õ" =Ñ1Ø˜&Ð!Ð!r6   rÛ   Úcronjob_manager  u~  Manage scheduled cron jobs: action='create' schedules a job from a prompt and/or skills; 'list' inspects jobs; 'update'/'pause'/'resume'/'remove' manage one by job_id (always list first â€” never guess job IDs); 'run' fires a job immediately in the BACKGROUND (returns a handle at once, outcome re-enters the conversation when done â€” do not wait or poll; optional 'prompt' adds transient context for that fire only).

Jobs run on the main agent model (whatever `hermes model` is set to when they fire) unless pinned.

Jobs run in a fresh session with no current-chat context, so prompts must be self-contained, and the agent's FINAL RESPONSE is what gets delivered â€” cron runs are autonomous and cannot ask questions. Jobs run on the main agent model (whatever `hermes model` is set to when they fire) unless the user pins one. Prefer updating an existing job over creating near-duplicates.r	  Útyper  r
  r’  ÚbooleanzlCreate only: persist disabled atomically. Resume to schedule; explicit run remains available. Default false.r“  Ústringz4Create only: auditable reason; requires paused=true.rù  z~One of: create, list, update, pause, resume, remove, run. When action=create, the 'schedule' and 'prompt' fields are REQUIRED.r³   z,Required for update/pause/resume/remove/run.r‘  a~  For create/update. ONLY set when the user explicitly asks to pin (or unpin) a job's model. pinned=true locks the CURRENT main agent model (and its provider) onto the job so later `hermes model` / `/model` changes never touch it; pinned=false releases the lock so the job follows the main agent model again. Never set it on your own initiative: by default jobs follow the main model.r{   z¨For create: the full self-contained prompt (paired with any skills as the task instruction). For run: optional transient context for that single fire (never persisted).rz  u  REQUIRED for create. Schedule forms: (1) recurring interval â€” '30m', 'every 2h', 'every hour' (EVERY 30 minutes / 2 hours / hour, forever by default); (2) explicit one-shot by duration â€” 'in 30m', 'in 2h' (fires ONCE that far from now; use this for 'remind me in N minutes' â€” do NOT hand-compute an absolute timestamp); (3) natural day/time â€” 'every monday 9am', 'weekdays at 9am', 'every day at 9am' (recurring weekly/daily); (4) cron syntax â€” '0 9 * * *' (daily 9am); (5) absolute one-shot â€” ISO timestamp '2026-06-01T09:00:00'.zOptional human-friendly namer‡  ÚintegerzTOptional repeat count. Omit for defaults (once for one-shot, forever for recurring).r§   aÕ  Where the job's output is POSTED as a one-way message (the job itself always runs in a fresh session with no chat context). Omit to address the chat/topic this job was created from. Otherwise: 'local' (save only, no delivery), 'all' (every connected home channel, resolved at fire time), 'bot-chat' or 'bot-chat:<profile>' (inject into a Bot Chat as a real message), or platform:chat_id:thread_id (e.g. 'telegram:-1001234567890:17585'). Comma-combine like 'origin,all'.r‚  a�  Optional override target for FAILURE notices only (same grammar as deliver). When set, engine failure/interruption notices go here instead of the deliver target; 'local' suppresses them entirely (state still recorded in cron list/run history). Use for jobs delivering into shared channels where failure noise is unwanted. Omit = failures follow deliver (default). On update, '' clears.r}  ÚarrayÚitemszQOptional ordered skill names loaded before the cron prompt. On update, [] clears.ry  zthe profile HERMES_HOMEÚmonitoruÅ  Optional change-detector that gates the agent: an http(s) URL (fetched each tick) or a script path (same rules as `script`, run each tick) â€” cheap, no LLM. Output identical to the previous tick skips the agent run entirely; changed output wakes the agent with a diff injected into the prompt. First tick always runs (baseline). Output must be deterministic (no timestamps) or every tick looks changed. Incompatible with no_agent. On update, '' clears.r~  rb   zêTrue = no LLM: the scheduler runs `script` (required) on schedule and delivers its stdout verbatim; empty stdout sends nothing (watchdog pattern). Use for script-only pings with fixed output; keep False for anything needing reasoning.rƒ  uË   Optional job ID(s) whose most recent completed output is injected as context each run â€” chains jobs (A collects, B processes). For a job's OWN previous output prefer `continuity`. On update, [] clears.r„  zºTrue = each run sees the job's own previous output, so it can dedupe and continue where it left off (scouts, monitors, incremental digests). Default false. On update, false turns it off.r‹  uB  Optional toolset names to restrict the job's agent to (e.g. ["web", "terminal"]) â€” cuts token overhead. Infer from the prompt. Omit for all default tools. [] = an explicit zero-tool allowlist (the job's agent gets no toolsets, MCP servers included unless named); it is preserved as [], never widened back to the default.rŒ  z¢Optional absolute existing path to run the job from: injects that directory's AGENTS.md/context files and anchors terminal/file tools there. On update, '' clears.r�  u¨  True = the job's delivery is CONTINUABLE â€” the user can reply and the agent has the brief in context (threads on thread-capable platforms, mirrored into the DM elsewhere). Use for conversational recurring jobs (briefings); leave unset for fire-and-forget alerts. Scope: the job's own conversation only â€” the origin chat, the home-channel fallback when deliver='origin' captured no origin (script-created jobs), a user-written bare platform target (deliver='slack' â€” that platform's home channel), or the job's single explicit platform:chat target (this flag is the only way to attach an explicit target). Broadcast targets are never attached; no effect when deliver='local'.Úrequiredc                ó$   € V ^8„  d   QhR\         /# rV   )r  )r3   s   "r4   r5   r5     s   € ÷ ñ ¤Dñ r6   c                 óœ   € ^ RI Hp  ^ RIHpHp V! R4      ;'       g0    V! R4      ;'       g     V! R4      ;'       g    V! V ! RR4      4      # )aN  Available in interactive CLI mode, gateway/messaging platforms, and cron runs (the
scheduler is internal; no crontab needed). Flags must be explicitly truthy via
``env_var_enabled``. An external cron worker has the presence vars stripped from its env, so
the cron session marker keeps ``cron.allow_agent_scheduling`` meaningful there.rP  )Úenv_var_enabledÚis_truthy_valueÚHERMES_INTERACTIVEÚHERMES_GATEWAY_SESSIONÚHERMES_EXEC_ASKÚHERMES_CRON_SESSIONrZ   )rh  rQ  Úutilsr  r  )rQ  r  r  s      r4   Úcheck_cronjob_requirementsr#    s`   € õ
 8ß6áÐ,Ó-÷ 	Gð 	GÙÐ3Ó4÷	Gð 	GáÐ,Ó-÷	Gð 	Gñ ™?Ð+@À"ÓEÓFð	r6   c                ó˜  € \        V P                  R4      V P                  R4      V P                  R4      4      w  r#\        RRV P                  RR4      RV P                  RR4      RVRVRVP                  R4      R	VP                  R	4      R
V P                  R
R4      /\         Uu/ uF  qDV P                  V4      bK  	  upB # u upi )z¡Model-tool dispatch: resolves the one model-facing ``monitor`` field into the stored
``monitor_script``/``monitor_url`` pair (legacy field names still accepted).r  r  rŽ  rù  rZ   r¤  Trú  r4  r’  Fr>   )r%   rP   r  Ú_HANDLER_FORWARDED_ARGS)ÚargsÚkwÚ_mon_scriptÚ_mon_urlr†   s   &,   r4   Ú_cronjob_handlerr*  ˜  så   € ô /¨t¯x©x¸	Ó/BÀDÇHÁHÐM]ÓD^Ð`d×`hÑ`hÐivÓ`wÓxÑ€KÜñ 	Ø�x‰x˜ "Ó%ð	àŸ™Ð"4°dÓ;ð	ð #ð	ð ð		ð
 —‘�yÓ!ð	ð —6‘6˜,Ó'ð	ð �x‰x˜ %Ó(ð	õ *AÓ
AÑ)@ #�—‘˜“ÒÑ)@Ñ
Añ	ð 	ùò Bs   Â(Cr  u   â�°)rÛ   ÚtoolsetÚschemar  Úcheck_fnÚemojiÚdynamic_schema_overridesg     Õ@)N)iÐ  )NN)NNNNNNFNNNNNNNNNNNNNNNNNNNFNNN)r³   r{   rz  rÛ   r‡  r§   r‚  r|  r}  r¾   ry  rƒ  r„  r‹  rŒ  r~  r�  r“  r‘  )pÚ__doc__r»   r9   Úloggingr›   rÜ   rÍ   Úconcurrent.futuresr   Úpathlibr   Útypingr   r   r   r   r   r  r	  r	   Ú	getLoggerÚ__name__rº   rÐ   rÑ   ÚpathÚinsertr2   Ú__file__Úparentr$  r   r   r   r   r   r   r   r   r   r   r   r   r   Útools.cronjob_prompt_scanr   Útools.cronjob_job_argsr   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   Útools.registryr*   r+   r;   rD   rT   rq   rˆ   r“   r¥   r±   r  rÀ   rÄ   Úcontextmanagerrâ   rÃ   r  r+  r2  r9  rJ  ro  rt  r¡  r©  r¯  r²  rµ  rÃ  rÇ  rÍ  rÒ  rØ  rã  ræ  rè  rþ  rÿ  r÷  r  r  r  r  r#  r%  r*  Úregisterr>   r6   r4   Ú<module>r@     sÈ  ðñYó Û Û Û 
Û Û Ý %Ý ß 3Õ 3ã å 0à	×	Ò	˜8Ó	$€ð  $Ð ð )Ð à ‡�‡��‘3‘t˜H“~×,Ñ,×3Ñ3Ó4Ô 5÷÷ ÷ õ õ 8÷ ÷  ÷  ÷  õ  ÷$ 0õ)õõOõ"#÷,õD÷ #õL2ð,6ð õ
J÷.`ð ×Ñô0Bó ð0B÷f](÷@<÷@õ(Fõ*Bõ÷,bõTõK9õ\õ	õBõ
:õ
64õr<õ
1eõhõ$õ&ðF %Ð&;Ð=QÐSeÐf€õjð ˜n¨f°lÐCÐ àˆn˜h¨Ø	ˆ;˜	 ;°	¸;ØÑWØÑEð	€õ÷(41õn%õ"ð ÐØð zð
 Ø�Øð P
Ø�v˜y¨-ð  :hð  iðP
à˜f h°Ð?uÐvðP
ð Ø˜Øð   `ððP
ð Ø˜ØÐMððP
ð Ø˜	Øð   `ððP
ð Ø˜Øð   JððP
ð& Ø˜Ø˜Øð   @	ðð'P
ð0 Ø˜ØÐ=ðð1P
ð8 Ø˜	ØÐuðð9P
ð@ Ø˜Øð   wððAP
ðH Ø˜Øð   cð ðIP
ðP Ø˜Ø˜& (Ð+ØÐrððQP
ðZ Ø˜ØÑ2Ð3LÓMðð[P
ðb Ø˜Øð   gððcP
ðj Ø˜	Ø˜5Øð   LððkP
ðt Ø˜Ø˜& (Ð+Øð   mððuP
ð~ Ø˜	Øð   \ððP
ðF Ø˜Ø˜& (Ð+Øð   hð!ð
 Ø˜Øð   Dðð  Ø˜	Øð   Jð"ñYP
ðb 	�X�JðgTð\€õ~ð&Ð òð  	× Ò Ø	ØØØØ'Ø
Ø6÷r6   